DIRECTORY Atom USING [GetPName], CIFS USING [GetFC, Open, read], Commander USING [CommandProc, CommandObject, Enumerate, Lookup, Register, Handle], ConvertUnsafe USING [AppendRope], Exec USING [commandLine], File USING [Capability, nullCapability], FileIO USING [Open, OpenFailed], Generator USING [Handle, Produce], IO USING [AppendStreams, ChangeDeliverWhen, Close, CreateFilterCommentsStream, CR, DeliverWhenProc, EndOf, EveryThing, GetOutputStreamRope, LookupData, PeekChar, PutChar, PutF, PutRope, RemoveData, rope, ROPE, RIS, ROS, SetEcho, SetIndex, SP, StoreData, STREAM, BreakProc, CharProc, GetSequence, GetToken, GetRefAny, IDProc, SkipOver, WhiteSpace], List USING [DotCons, Nconc1, Sort], MessageWindow USING [Append], ProcessProps USING [AddPropList], CommandProcOps USING [PutProperty], Rope USING [Cat, Concat, Equal, Fetch, Find, IsEmpty, Length, Replace, Substr], RTFiles USING [GetMapList], Spell USING [GeneratorFromEnumerator, SpellingGenerator, IsAPattern, Modes], TTY USING [Handle], SymTab USING [Create, Fetch, Store, Ref], UnsafeStorage USING [GetSystemUZone], UserExec USING [Confirm, UserAborted, DoIt, AcquireResource, CommandProc, ExecHandle, GetMatchingFileList, GetStreams, GetTheOne, MethodProc, ReleaseResource, ErrorThisEvent, AcquireStreams, ReleaseStreams, TransformProc, HistoryEvent], UserExecExtras USING [CorrectionDisabled], UserExecPrivate USING [CommandRecord, commandString, EventFailed, ExecDeliverWhen, ExecPrivateRecord, GetExecFromStream, HistoryEventPrivateRecord, FileNotFound, methodList, MethodRecord, PrintCommand, RopeFromCMFile, RunBCDFile, StripComments, w, Zone, GetPrivateStuff], UserProfile USING [CallWhenProfileChanges, ProfileChangedProc, Token], VersionMapOps USING [SourceFileList, FindSource] ; UserExecRegCmdsImpl: CEDAR PROGRAM IMPORTS Atom, CIFS, Commander, CommandProcOps, ConvertUnsafe, Exec, FileIO, Generator, IO, List, MessageWindow, ProcessProps, Rope, RTFiles, Spell, SymTab, UnsafeStorage, UserExec, UserExecExtras, UserExecPrivate, UserProfile, VersionMapOps EXPORTS UserExec, UserExecPrivate = BEGIN OPEN IO; ExecPrivateRecord: PUBLIC TYPE = UserExecPrivate.ExecPrivateRecord; HistoryEventPrivateRecord: PUBLIC TYPE = UserExecPrivate.HistoryEventPrivateRecord; CallRegisteredProc: PUBLIC PROC [command: ROPE, event: UserExec.HistoryEvent, exec: UserExec.ExecHandle] RETURNS[handled: BOOLEAN _ TRUE] = { commandLineStream: STREAM = event.commandLineStream; registration: REF UserExecPrivate.CommandRecord _ GetRegistrationData[command]; commanderProc: Commander.CommandProc = Commander.Lookup[command].proc; nameOfBCD: ROPE; IF registration = NIL THEN RETURN[CallCommanderProc[command, event, exec]]; IF NOT Rope.Equal[registration.name, "_"] THEN SetUpCommandLine[event: event, exec: exec]; IF (nameOfBCD _ registration.nameOfBCD) # NIL AND commanderProc = dummyCommanderProc THEN -- check for commanderProc because the file may have been run and the command registered with commander directl, e.g. Walnut { doc: ROPE = registration.documentation; error: ROPE; notFound: BOOL _ FALSE; error _ UserExecPrivate.RunBCDFile[fileName: nameOfBCD, out: UserExec.GetStreams[exec].out ! UserExecPrivate.FileNotFound => { error _ Rope.Concat[nameOfBCD, " must be on your local disk to execute this command"]; notFound _ TRUE; CONTINUE; } ].error; IF notFound THEN TRUSTED { -- what errors to catch? lst: VersionMapOps.SourceFileList; cap: File.Capability _ File.nullCapability; MessageWindow.Append["Loading Version Map...", TRUE]; lst _ VersionMapOps.FindSource[short: nameOfBCD, mapList: RTFiles.GetMapList[]]; IF lst # NIL THEN { MessageWindow.Append[Rope.Cat["Loading ", lst.first.name, "..."]]; cap _ CIFS.GetFC[CIFS.Open[name: lst.first.name, mode: CIFS.read]]; }; IF cap # File.nullCapability THEN error _ UserExecPrivate.RunBCDFile[fileName: lst.first.name, fileCapability: cap, out: UserExec.GetStreams[exec].out].error; }; IF error # NIL THEN UserExecPrivate.EventFailed[event: event, msg: error, offender: nameOfBCD]; registration _ GetRegistrationData[name: registration.name]; registration.nameOfBCD _ NIL; IF registration.commandProc = NIL AND registration.transformProc = NIL AND registration.oldStyleProc = NIL AND Commander.Lookup[command].proc = dummyCommanderProc THEN { UserExec.GetStreams[exec].out.PutF["*n*m%g was run and did not register any commands*s\n", rope[nameOfBCD]]; RETURN[TRUE]; }; IF registration # NIL AND registration.documentation = NIL THEN registration.briefDocumentation _ registration.documentation _ doc; RETURN[CallRegisteredProc[command, event, exec]]; }; IF registration.commandProc # NIL THEN -- if there is a UserExec.commandProc, use it even though there is a commander CommandProc, because it may (probably) have more functionality { ok: BOOL; msg: ROPE; inner: Commander.CommandProc = { [ok, msg] _ registration.commandProc[event, exec, registration.clientData]; }; PushPropsAndCallProc[inner, command, event, exec]; IF NOT ok THEN ERROR UserExec.ErrorThisEvent[event, msg]; -- msg should be stored in history, even on success. } ELSE IF registration.oldStyleProc # NIL THEN { Done: PROC = {[] _ UserExec.ReleaseResource[$Exec]}; [] _ UserExec.AcquireResource[resource: $Exec, owner: registration.name, exec: exec]; TRUSTED { ENABLE UNWIND => Done[]; private: REF ExecPrivateRecord = exec.privateStuff; inner: Commander.CommandProc = TRUSTED { registration.oldStyleProc[] }; UserExecPrivate.w _ private.execDotW; UserExecPrivate.commandString.length _ 0; IF Rope.Length[event.commandLine] > UserExecPrivate.commandString.maxlength THEN -- long command file. make string larger. Exec.commandLine.s _ UserExecPrivate.commandString _ UnsafeStorage.GetSystemUZone[].NEW[StringBody[Rope.Length[event.commandLine]]]; ConvertUnsafe.AppendRope[to: UserExecPrivate.commandString, from: event.commandLine]; Exec.commandLine.i _ 0; PushPropsAndCallProc[inner, command, event, exec]; Done[]; }; } ELSE IF registration.transformProc # NIL THEN { input: ROPE = registration.transformProc[event, exec, registration.clientData]; privateEvent: REF UserExecPrivate.HistoryEventPrivateRecord = event.privateStuff; IF Rope.Equal[input, event.input] THEN ERROR UserExec.ErrorThisEvent[event: event, msg: "You are looping"]; privateEvent.showInput _ TRUE; UserExec.DoIt[input, exec, event]; } ELSE IF commanderProc # dummyCommanderProc THEN RETURN[CallCommanderProc[command, event, exec]] -- command had registrationData, but nothing to do. Occurs for commands obtained from catalogue which when run, register themselves with commander only, e.g. smodel ELSE RETURN[FALSE]; RETURN[TRUE]; }; SetUpCommandLine: PROC [event: UserExec.HistoryEvent, exec: UserExec.ExecHandle] = { commandLine: ROPE _ event.commandLine; pos: INT; commandLine _ ExpandCommandLine[line: commandLine, event: event, exec: exec]; WHILE (pos _ Rope.Find[s1: commandLine, s2: "\\"]) # -1 DO commandLine _ Rope.Replace[base: commandLine, start: pos, len: 1]; ENDLOOP; event.commandLine _ commandLine; [] _ RIS[rope: commandLine, oldStream: event.commandLineStream]; -- for commands registered by UserExec.RegisterCommand }; -- of SetUpCommandLine ExpandCommandLine: PUBLIC PROC [line: ROPE, modes: Spell.Modes _ NIL, event: UserExec.HistoryEvent, exec: UserExec.ExecHandle] RETURNS [ROPE] = { inRopeStream: STREAM; pos: INT; WHILE (pos _ Rope.Find[s1: line, s2: "@"]) # -1 AND (pos = 0 OR Rope.Fetch[line, pos - 1] # '\\) DO fileName: ROPE; inRopeStream _ RIS[rope: line, oldStream: inRopeStream]; inRopeStream.SetIndex[pos]; fileName _ IO.GetToken[inRopeStream, IO.IDProc]; line _ Rope.Replace[base: line, start: pos, len: Rope.Length[fileName], with: UserExecPrivate.RopeFromCMFile[file: fileName, event: event, exec: exec].contents]; ENDLOOP; line _ UserExecPrivate.StripComments[event, line]; IF Spell.IsAPattern[line] THEN { r: ROPE; asFile: BOOLEAN _ FALSE; inRopeStream _ RIS[rope: line, oldStream: inRopeStream]; WHILE Rope.Length[r _ IO.GetToken[inRopeStream, IO.IDProc]] # 0 DO IF Spell.IsAPattern[r] THEN {outRopeStream: STREAM = IO.ROS[]; FOR l: LIST OF ROPE _ -- IF ~asFile THEN LookupCommands[r, exec] ELSE-- UserExec.GetMatchingFileList[file: r, event: event, exec: exec, modes: modes], l.rest UNTIL l = NIL DO outRopeStream.PutRope[l.first]; IF l.rest # NIL THEN outRopeStream.PutChar[SP]; ENDLOOP; line _ Rope.Replace[base: line, start: Rope.Find[line, r], len: Rope.Length[r], with: outRopeStream.GetOutputStreamRope[]]; }; asFile _ TRUE; ENDLOOP; }; RETURN[line]; }; -- of ExpandCommandLine GetRestOfStream: PUBLIC PROC [in: STREAM, includeLast: BOOL _ TRUE] RETURNS[value: ROPE] = { value _ IO.GetSequence[in, IO.EveryThing]; IF NOT includeLast THEN value _ Rope.Substr[base: value, len: Rope.Length[value] - 1]; }; DoesUserMean: PUBLIC PROC [rope: ROPE, exec: UserExec.ExecHandle, intro: ROPE _ NIL] = { out: STREAM = UserExec.GetStreams[exec: exec].out; out.PutRope[IF intro = NIL THEN "perhaps you mean:\n" ELSE intro]; IF UserExec.Confirm[msg: rope, exec: exec] THEN UserExec.DoIt[rope, exec] ELSE UserExec.UserAborted[exec]; }; ReadQuietly: PUBLIC PROC [rope: ROPE, exec: UserExec.ExecHandle] = { in: STREAM; private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; private.continuation _ TRUE; -- tells exec not to increment event number and to reuse event. private.dontPrompt _ TRUE; IF NOT rope.IsEmpty[] THEN { in _ UserExec.AcquireStreams[exec: exec].in; [] _ in.SetEcho[NIL]; -- turn off echoing. in.StoreData[key: $Count, data: NEW[INT _ rope.Length[]]]; [] _ IO.ChangeDeliverWhen[in, StuffBufferDeliverWhen]; -- turns echoing back on as soon as all characters consumed. AppendStreams[in, RIS[rope]]; }; }; StuffBufferDeliverWhen: IO.DeliverWhenProc -- PROC[char: CHAR, stream: STREAM] RETURNS[BOOL] -- = { exec: UserExec.ExecHandle = UserExecPrivate.GetExecFromStream[stream]; count: REF INT; private: REF UserExecPrivate.ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; in, out: STREAM; [in, out] _ UserExec.GetStreams[exec: exec]; count _ NARROW[in.LookupData[$Count]]; count^ _ count^ - 1; IF count^ <= 0 THEN { [] _ IO.ChangeDeliverWhen[in, UserExecPrivate.ExecDeliverWhen]; [] _ in.SetEcho[out]; in.RemoveData[key: $Count]; UserExec.ReleaseStreams[exec: exec]; }; RETURN[FALSE]; }; RegisterCommand: PUBLIC PROC [name: ROPE, proc: UserExec.CommandProc, briefDoc, doc: ROPE _ NIL, clientData: REF ANY _ NIL] = { Register[name: name, proc: proc, briefDoc: briefDoc, doc: doc, clientData: clientData]; }; RegisterTransformation: PUBLIC PROC [name: ROPE, proc: UserExec.TransformProc, briefDoc, doc: ROPE _ NIL, clientData: REF ANY _ NIL]= { Register[name: name, transformProc: proc, briefDoc: briefDoc, doc: doc, clientData: clientData]; }; RegisterMethod: PUBLIC PROC [name: ROPE, proc: UserExec.MethodProc, doc: ROPE _ NIL, clientData: REF ANY _ NIL] = { r: REF UserExecPrivate.MethodRecord _ NIL; IF name # NIL THEN FOR lst: LIST OF REF UserExecPrivate.MethodRecord _ UserExecPrivate.methodList, lst.rest UNTIL lst = NIL DO IF Rope.Equal[lst.first.name, name] THEN {r _ lst.first; EXIT} ENDLOOP; IF r = NIL THEN TRUSTED { -- Loophole for polymorphism r _ UserExecPrivate.Zone.NEW[UserExecPrivate.MethodRecord _ []]; UserExecPrivate.methodList _ LOOPHOLE[List.Nconc1[LOOPHOLE[UserExecPrivate.methodList, LIST OF REF ANY], r]]; }; -- important that methods be executed in order defined r^ _ [proc: proc, name: name, doc: doc, clientData: clientData]; }; Register: PUBLIC PROC [ name: ROPE _ NIL, proc: UserExec.CommandProc _ NIL, oldStyleProc: UNSAFE PROCEDURE _ NIL, transformProc: UserExec.TransformProc _ NIL, briefDoc, doc: ROPE _ NIL, nameOfBCD: ROPE _ NIL, clientData: REF ANY _ NIL, fromCatalogue: BOOL _ FALSE ] = { i: INT _ Rope.Find[s1: name, s2: "."]; r: REF UserExecPrivate.CommandRecord; commanderProc: Commander.CommandProc; IF i # -1 THEN name _ Rope.Substr[name, 0, i]; -- old style registration was to register mumble.~ commanderProc _ Commander.Lookup[key: name].proc; Commander.Register[key: name, proc: IF commanderProc = NIL THEN dummyCommanderProc ELSE commanderProc, doc: briefDoc]; -- if happen to be registering a command with same name as one already registered in commander, leave the commander one alone so when run from command tool, it will continue to work the same as before r _ GetRegistrationData[name]; IF r = NIL THEN { r _ UserExecPrivate.Zone.NEW[UserExecPrivate.CommandRecord _ []]; RegisterData[name, r]; } ELSE IF (r.commandProc # NIL OR r.oldStyleProc # NIL) AND nameOfBCD # NIL THEN { -- command already registered with procedure is being reregistered indirectly with nameOfBCD. In this case, user should have to explicitly run the bcd. IF doc # NIL THEN r.documentation _ doc; RETURN; }; r^ _ [name: name, commandProc: proc, transformProc: transformProc, briefDocumentation: IF briefDoc = NIL THEN doc ELSE briefDoc, documentation: IF doc = NIL THEN briefDoc ELSE doc, oldStyleProc: oldStyleProc, nameOfBCD: nameOfBCD, clientData: clientData, fromCatalogue: fromCatalogue]; }; -- Register registrationTable: SymTab.Ref _ SymTab.Create[30, FALSE]; GetRegistrationData: PUBLIC PROC [name: ROPE] RETURNS[REF UserExecPrivate.CommandRecord] = { RETURN[NARROW[SymTab.Fetch[registrationTable, name].val, REF UserExecPrivate.CommandRecord]]; }; RegisterData: PUBLIC PROC [command: ROPE, val: REF ANY] = { [] _ SymTab.Store[x: registrationTable, key: command, val: val]; }; LookupCommand: PUBLIC PROC [name: ROPE, event: UserExec.HistoryEvent, exec: UserExec.ExecHandle _ NIL] RETURNS[fullName: ROPE] = { command: ROPE = name; out: STREAM; matches: LIST OF ROPE; matches _ LookupCommands[name, event, exec]; IF matches # NIL THEN TRUSTED { -- LOOPHOLE for polymorphism ENABLE UNWIND => IF out # NIL THEN UserExec.ReleaseStreams[exec]; IF matches.rest = NIL THEN RETURN[matches.first] ; out _ UserExec.AcquireStreams[exec].out; out.PutF["*n%g is ambiguous. It matches with:\n", rope[name]]; FOR l: LIST OF ROPE _ LOOPHOLE[List.Sort[LOOPHOLE[matches]]], l.rest UNTIL l = NIL DO [] _ UserExecPrivate.PrintCommand[name: l.first, event: event, exec: exec]; ENDLOOP; UserExec.ReleaseStreams[exec]; RETURN[NIL]; }; }; LookupCommands: PROC [command: ROPE, event: UserExec.HistoryEvent, exec: UserExec.ExecHandle _ NIL] RETURNS[val: LIST OF ROPE _ NIL] = { r: ROPE; search: PROC[name: ROPE, proc: Commander.CommandProc, doc: ROPE] RETURNS[stop: BOOL] = { IF Rope.Equal[s1: command, s2: name, case: FALSE] THEN { val _ LIST[name]; RETURN[TRUE]; } ELSE IF Rope.Find[s1: name, s2: command, case: FALSE] = 0 THEN val _ CONS[name, val]; RETURN[FALSE]; }; Correct: PROC = { ENABLE UNWIND => NULL; r _ UserExec.GetTheOne[unknown: command, generator: commandGenerator, event: event, exec: exec]; }; IF Commander.Lookup[command].proc # NIL THEN RETURN[LIST[command]] ELSE IF exec = NIL OR UserExecExtras.CorrectionDisabled[event: event] THEN RETURN[NIL]; [] _ Commander.Enumerate[search]; IF val # NIL THEN RETURN; Correct[]; RETURN[IF r # NIL THEN LIST[r] ELSE NIL]; }; CallCommanderProc: PROC[command: ROPE, event: UserExec.HistoryEvent, exec: UserExec.ExecHandle] RETURNS[handled: BOOL] = { commandProc: Commander.CommandProc = Commander.Lookup[command].proc; IF commandProc = NIL THEN RETURN[FALSE]; PushPropsAndCallProc[commandProc, command, event, exec]; RETURN[TRUE]; }; PushPropsAndCallProc: PROC [proc: Commander.CommandProc, command: ROPE, event: UserExec.HistoryEvent, exec: UserExec.ExecHandle] = { in, out: IO.STREAM; commanderHandle: Commander.Handle; inner: PROCEDURE = { proc[commanderHandle]; }; [in, out] _ UserExec.GetStreams[exec]; commanderHandle _ NEW[Commander.CommandObject _ [ in: in, out: out, err: out, commandLine: event.commandLine, command: command, propertyList: NIL ]]; CommandProcOps.PutProperty[handle: commanderHandle, key: $UserExec, val: exec, thisEventOnly: TRUE]; CommandProcOps.PutProperty[handle: commanderHandle, key: $HistoryEvent, val: event, thisEventOnly: TRUE]; ProcessProps.AddPropList[ LIST[List.DotCons[$CommanderHandle, commanderHandle]], inner]; }; dummyCommanderProc: PUBLIC Commander.CommandProc = { cmd.out.PutRope["This command can only be executed in a Work Area."]; }; LookupEnumerate: PROC [self: Generator.Handle] = { proc: PROC[name: ROPE, proc: Commander.CommandProc, doc: ROPE] RETURNS[stop: BOOL] = { RETURN[Generator.Produce[self, name]]; -- somebody terminated the generator. }; [] _ Commander.Enumerate[proc]; }; commandGenerator: PUBLIC Spell.SpellingGenerator _ Spell.GeneratorFromEnumerator[enumerator: LookupEnumerate, clientData: NIL]; GetRegisteredCommands: UserProfile.ProfileChangedProc = { GetCommands: PROC [name: ROPE, fromCatalogue: BOOL] = { GetRope: PROC RETURNS [ROPE] = { whiteSpace: IO.BreakProc = { RETURN[IF char = CR THEN break ELSE IO.WhiteSpace[char]] }; ref: REF ANY _ IO.GetRefAny[source ! ANY => GOTO Exit]; IF ref = NIL THEN RETURN[NIL]; IO.SkipOver[source, whiteSpace]; -- skips spaces, tabs, etc., but not CR. WITH ref SELECT FROM a: ATOM => RETURN[Atom.GetPName[a]]; r: ROPE => RETURN[r]; ENDCASE => ERROR; -- ERROR TO ERROR LOG. EXITS Exit => RETURN[NIL] }; source: STREAM _ NIL; IF name # NIL THEN { IF Rope.Find[name, "\n"] = -1 THEN -- r is name of file source _ FileIO.Open[fileName: name, accessOptions: read, createOptions: oldOnly ! FileIO.OpenFailed => IF why = fileNotFound THEN CONTINUE] ELSE source _ IO.RIS[name]; }; IF source # NIL THEN { source _ IO.CreateFilterCommentsStream[source]; WHILE NOT source.EndOf[] DO name, nameOfBCD, documentation: ROPE _ NIL; name _ GetRope[]; IF name = NIL THEN EXIT; IF source.PeekChar[] # CR THEN documentation _ GetRope[]; IF source.PeekChar[] # CR THEN nameOfBCD _ GetRope[]; IF nameOfBCD = NIL THEN nameOfBCD _ name; IF Rope.Find[s1: nameOfBCD, s2: "."] = -1 THEN nameOfBCD _ Rope.Concat[nameOfBCD, ".bcd"]; Register[name: name, briefDoc: documentation, doc: documentation, nameOfBCD: nameOfBCD, fromCatalogue: fromCatalogue]; ENDLOOP; IO.Close[source]; }; }; GetCommands["RegisteredCommands.Catalogue", TRUE]; GetCommands[UserProfile.Token["RegisteredCommands"], FALSE]; }; UserProfile.CallWhenProfileChanges[GetRegisteredCommands]; END. -- of UserExecRegCmdsImpl 0procedures and data relating to the handling of registered commands in the user exec Last Edited by: teitelman, May 13, 1983 2:43 pm connecting concrete and opaque types to access execDotW in CallRegisteredProc, continuation, dontPrompt, and deliverWhen in ReadQuietly, and deliverWhen in StuffBufferDeliverWhen, and currentEvent (to get dontCorrect) in LookupComand executing registered commands: CallRegisteredProc, SetUpCommandLine, ExpandCommandLine, DoesUserMean, StuffBuffer discard \\'s replace any @file with corresponding rope comments in the input line are stripped in Doit. reason for this check is to handle lines that were manufactured, e.g. by CommandsFrom. discard ^s when followed by CR pos _ 0; WHILE (pos _ Rope.Find[s1: line, s2: "^", pos1: pos]) # -1 DO IF Rope.Fetch[line, pos + 1] = CR AND pos # 1 AND Rope.Fetch[line, pos - 1] = SP THEN line _ Rope.Replace[base: line, start: pos, len: 2]; pos _ pos + 1; ENDLOOP; DoesUserMean: PUBLIC PROC [rope: ROPE, exec: UserExec.ExecHandle, intro: ROPE _ NIL] = { out: STREAM = UserExec.GetStreams[exec: exec].out; out.PutRope[IF intro = NIL THEN "perhaps you mean:\n" ELSE intro]; out.PutRope[rope]; ReadQuietly[rope, exec]; }; used to make what appears on the screen and input buffer agree. loads buffer with rope, turns off echoing, delivering, and allows characters to be read until no more left, at which point turns everything back on. turns echoing back on when all characters that were stuffed have been read. Registration: RegisterCommand, RegisterTransformation, RegisterMethod, Register compare: List.CompareProc -- [ref1: REF ANY, ref2: REF ANY] RETURNS [Environment.Comparison] -- = { RETURN[Rope.Compare[ s1: NARROW[ref1, REF UserExecPrivate.CommandRecord].name, s2: NARROW[ref2, REF UserExecPrivate.CommandRecord].name, case: FALSE]]; }; { SortCommands: ENTRY PROCEDURE = TRUSTED { -- Loophole for polymorphism ENABLE UNWIND => NULL; UserExecPrivate.commandList _ LOOPHOLE[List.Sort[LOOPHOLE[UserExecPrivate.commandList], compare]] }; SortCommands[]; }; Lookup Dealing With Commander Initialization Edited on March 24, 1983 11:49 am, by Teitelman any error coming out of running registered command, included aborted, was causing it to attempt to load version maps. changes to: CallRegisteredProc, CallRegisteredProc Edited on March 25, 1983 1:43 pm, by Teitelman changes to: GetCommands (local of GetRegisteredCommands) added .bcd to name obtained from registered commands catalogue when no extension specified., UserProfile, END Edited on April 7, 1983 3:22 pm, by Teitelman changes to: RegisterCommanderProc, CommanderProcRecord, CallCommanderProc, END, DIRECTORY, IMPORTS, CallRegisteredProc, LookupGenerate, CallRegisteredProc, IsACommanderProc (local of CallRegisteredProc), RegisterCommanderStuff, register (local of RegisterCommanderStuff), RegisterCommanderStuff, UserProfile, DIRECTORY, IMPORTS, IsACommanderProc (local of CallRegisteredProc), CallRegisteredProc, DIRECTORY, CallRegisteredProc, RegisterCommanderStuff, register (local of RegisterCommanderStuff), EndOps, UserProfile, DIRECTORY, IMPORTS, UserProfile, register (local of RegisterCommanderStuff), register (local of RegisterCommanderStuff Edited on April 19, 1983 2:57 pm, by Teitelman changes to: CallRegisteredProc, CallCommanderProc, registrationTable, GetRegistrationData, Register, proc (local of LookupEnumerate), Register, LookupCommand, DIRECTORY, LookupCommand, DIRECTORY, Register, GetRegistrationData, RegisterData, DIRECTORY, IMPORTS, CallCommanderPro Edited on April 21, 1983 12:47 am, by Teitelman changes to: DIRECTORY, IMPORTS, CallCommanderProc, CallRegisteredProc, inner (local of CallCommanderProc), IMPORTS, CallCommanderProc, inner (local of CallRegisteredProc), CallRegisteredProc, CallCommanderProc, inner (local of CallRegisteredProc), CallRegisteredProc, inner (local of CallRegisteredProc), inner (local of PushPropsAndCallProc), PushPropsAndCallProc, inner (local of CallCommanderProc), CallCommanderProc Edited on May 3, 1983 8:35 pm, by Teitelman changes to: CallRegisteredProc Edited on May 13, 1983 2:43 pm, by Teitelman changes to: DoesUserMean ΚO– "cedar" style˜JšΟcT™TJ™/šΟk ˜ Jšœžœ ˜Jšžœžœ˜Jšœ žœC˜RJšœžœ˜#Jšœžœ˜Jšœžœ˜(Jšœžœ˜ Jšœ žœ˜"JšžœžœGžœ{žœžœžœžœ žœW˜ΫJšœžœ˜%Jšœžœ ˜Jšœ žœ˜!Jšœžœ˜#JšœžœE˜OJšœžœ˜JšœžœB˜MJšžœžœ ˜Jšœžœ˜)Jšœžœ˜%Jšœ žœή˜μJšœžœ˜*Jšœžœϊ˜Jšœ žœ5˜FJšœžœ˜0J˜J˜—JšΠblœž œ˜%J˜JšžœPžœœ˜υJ˜Jšžœ˜"J˜Jšž œžœ˜headšœ$™$šΟnœžœžœ%˜CJ™Ε—š œžœžœ-˜SJ™——š  œ   ΡnprR™qš œžœžœ žœ;žœ žœžœ˜Jšœžœ˜4Jšœžœ>˜OJ˜FJšœ žœ˜Jšžœžœžœžœ*˜KJšžœžœ$žœ.˜\š žœ(žœžœ$žœoœ ˜Χšœ˜Jšœžœ˜'Jšœžœ˜ Jšœ žœžœ˜šœ~˜~JšœV˜VJšœ žœ˜Jšžœ˜ J˜ —šžœ žœžœ˜3Jšœ"˜"Jšœ+˜+Jšœ/žœ˜5JšœP˜Pšžœžœžœ˜JšœB˜BJšœžœžœ"žœ˜CJšœ˜—Jšžœžœ}˜žJšœ˜—Jšžœ žœžœL˜_Jšœ<˜˜TJšœ žœ˜&Jšœžœ˜ JšœM˜MJš ™ šžœ3ž˜:JšœB˜BJšžœ˜—Jšœ ˜ Jšœžœ96˜wJšœ˜—J˜š œžœžœžœžœ;žœžœ˜‘Jšœžœ˜Jšœžœ˜ J˜Jš)™)šžœ+žœ žœ"ž˜cJšœ žœ˜Jšœžœ&˜8J˜J˜0Jšœ‘˜‘Jšžœ˜—J˜J˜2Jšœ‡™‡J˜Jš™J™šžœ6ž™=Jš žœžœžœ žœžœžœ5™ŠJ™Jšžœ™—šžœž˜šœ˜Jšœžœ˜Jšœžœžœ˜Jšœžœ&˜8šžœ;ž˜Bšžœž˜Jšœžœžœžœ˜"šžœžœžœžœ1œXžœžœž˜―J˜Jšžœ žœžœžœ˜/Jšžœ˜—J˜{J˜—Jšœ žœ˜Jšžœ˜—Jšžœ˜——Jšžœ˜Jšœ˜J˜J˜—š œžœžœžœžœžœžœžœ˜\Jšœ*˜*Jšžœžœ žœ?˜VJ˜—J˜š   œžœžœžœ$žœžœ™XJš£œžœ £ œ™2Jš œ žœ žœžœžœ™BJ™J™J™—J˜š   œžœžœžœ$žœžœ˜XJš£œžœ £ œ˜2Jš œ žœ žœžœžœ˜BJšžœ)žœ˜IJšžœ˜ J˜—˜JšœΤ™Τ—J˜š  œžœžœžœ ˜DJš£œžœ˜ Jšœ žœ;˜GJšœžœ?˜\Jšœžœ˜šžœžœž˜Jš£œ £œ˜,Jšœžœ˜,Jšœ žœžœ˜:Jšžœ0<˜sJšœžœ˜J˜—J˜—˜JšK™K—š  œžœžœ žœžœžœž˜cJšœF˜FJšœžœžœ˜Jšœ žœK˜WJš£œ£œžœ˜Jšœ£œ£œ £ œ ˜,Jšœžœ˜&J˜šžœ žœ˜Jšžœ9˜@Jšœ˜Jšœ˜Jšœ £œ ˜$J˜—Jšžœžœ˜Jšžœ˜——šœΠprA™Oš œžœžœžœ-žœžœžœžœžœ˜€J˜WJ˜—J˜š œž œžœ/žœžœžœžœžœ˜ˆJ˜`J˜—J˜š œžœžœžœ"žœžœžœžœžœ˜tJšœžœ žœ˜*šžœžœž˜š žœžœžœžœEžœžœž˜kJšžœ"žœžœ˜>Jšžœ˜ ——šžœžœž˜Jšžœ˜&Jšœžœ$˜@Jšœžœ žœžœžœžœžœ 6˜§—J˜@J˜—J˜š œžœžœ˜Jšœžœžœ˜Jšœžœ˜!Jšœžœž œžœ˜%Jšœ(žœ˜,Jšœžœžœ˜Jšœ žœžœ˜Jšœ žœžœžœ˜Jšœžœž˜J˜š œΠckEœ™dšžœ™Jšœžœžœ%™9Jšœžœžœ%™9Jšœžœ™—J™—Jšœžœ!˜'Jšœžœ˜%J˜%Jšžœžœ!2˜aJšœ2˜2Jš œ$žœžœžœžœ!Θ˜ΐJšœ˜šžœžœžœ˜Jšœžœ%˜AJšœ˜J˜—šžœžœžœžœžœ žœž—ž˜ιJšžœžœžœ˜(Jšžœ˜Jšœ˜—JšœWžœ žœžœžœžœžœžœ žœn˜šœ™š   œžœž œžœ™FJšžœžœžœ™Jšœžœ žœ(™aJšœ™—šœ™Jšœ™——Jšœ ˜J˜—J˜Jš œ!žœ˜9J˜š  œž œžœžœžœ#˜\Jšžœžœ,žœ!˜]Jšœ˜J˜—š   œžœžœ žœžœžœ˜;Jšœ@˜@J˜——™š   œž œžœ<žœžœ žœ˜‚Jšœ žœ˜Jšœžœ˜ Jšœ žœžœžœ˜J˜,šžœ žœž˜Jšžœ˜'Jš žœžœžœžœžœ £œ˜AJšžœžœžœžœ˜3Jš£œ £œ ˜(Jšœ>˜>šžœžœžœžœžœ žœžœžœž˜UJ˜KJšžœ˜—Jšœ £œ˜Jšžœžœ˜ J˜—J˜—J˜š œžœ žœ<žœžœžœžœžœžœ˜ˆJšœžœ˜š  œžœžœ$žœžœžœ˜Xšžœ)žœžœ˜8Jšœžœ˜Jšž ˜ Jšœ˜—Jš žœžœ(žœžœžœ ˜VJšžœžœ˜Jšœ˜—š œžœ˜Jšžœžœžœ˜Jšœ`˜`J˜—Jš žœ"žœžœžœžœ ˜BJš žœžœžœžœ1žœž œ˜WJšœ!˜!Jšžœžœžœžœ˜Jšœ ˜ Jšžœžœžœžœžœžœžœ˜)J˜——™–Š -- [event: UserExec.HistoryEvent, exec: UserExec.ExecHandle, clientData: REF ANY _ NIL] RETURNS [ok: BOOLEAN _ TRUE, msg: ROPE _ NIL] -- š  œžœ žœ;žœ žœ˜{J˜DJš žœžœžœžœžœ˜(J˜8Jšžœžœ˜ J˜—J˜š œžœ(žœ>˜„Jšœ žœž˜Jšœ"˜"š œž œ˜Jšœ˜J˜—J˜&šœžœ˜1J˜J˜J˜Jšœž˜J˜—Jšœ^žœ˜dJšœcžœ˜išœ˜Jšžœ2˜6Jšœ ˜ —J˜J˜—J˜š œžœ˜4JšœE˜EJšœ˜—J˜š œžœ˜2š  œžœžœ$žœžœžœ˜VJšžœ!%˜LJšœ˜—Jšœ˜J˜J˜—Jš œžœbžœ˜—™š œ%˜:š  œžœžœžœ˜7š œžœžœžœ˜!š  œ˜Jš žœžœžœžœžœ˜8J˜—Jš œžœžœžœžœ˜7Jš žœžœžœžœžœ˜Jšœ"(˜Jšžœžœž˜Jšœžœžœ˜$Jšœžœžœ˜Jšžœžœ˜(—Jšž˜Jšœžœžœ˜J˜—Jšœžœžœ˜šžœžœž˜šžœžœ˜7˜RJšœžœžœžœ˜9——Jšžœ žœžœ˜J˜—šžœ žœž˜Jšœ žœ$˜/šžœžœž˜Jšœ žœžœ˜+J˜Jšžœžœžœžœ˜Jšžœžœžœ˜9Jšžœžœžœ˜5Jšžœ žœžœ˜)šžœ(˜*Jšžœ,˜0—J˜vJšžœ˜—J˜J˜—J˜—J˜Jšœ,žœ˜2Jšœ5žœ˜?J˜—J˜J˜:—˜J˜—Jšžœ˜J™J™™/J™uJšœ Οr&™2—™.Jšœ ¦ œ}¦™¦—™-Jš œ ¦ œ¦"œ"¦Kœ¦Uœ"¦@œ"¦ œ!™ϋ—™.Jšœ ¦]œ¦‘™•—™/Jšœ ¦@œ¦#œ¦.œ¦œ¦œ ¦œ¦™£—J™J™J™J™J™™+Jšœ ¦™—™,Jšœ ¦ ™—J™—…—Fμlk