procedures and data relating to the handling of registered commands in the user exec
Last Edited by: teitelman, May 13, 1983 2:43 pm
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;
connecting concrete and opaque types
ExecPrivateRecord: PUBLIC TYPE = UserExecPrivate.ExecPrivateRecord;
to access execDotW in CallRegisteredProc, continuation, dontPrompt, and deliverWhen in ReadQuietly, and deliverWhen in StuffBufferDeliverWhen, and currentEvent (to get dontCorrect) in LookupComand
HistoryEventPrivateRecord: PUBLIC TYPE = UserExecPrivate.HistoryEventPrivateRecord;
executing registered commands: CallRegisteredProc, SetUpCommandLine, ExpandCommandLine, DoesUserMean, StuffBuffer
CallRegisteredProc: PUBLIC PROC [command: ROPE, event: UserExec.HistoryEvent, exec: UserExec.ExecHandle] RETURNS[handled: BOOLEANTRUE] = {
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: BOOLFALSE;
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];
discard \\'s
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;
replace any @file with corresponding rope
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];
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;
IF Spell.IsAPattern[line] THEN
{
r: ROPE;
asFile: BOOLEANFALSE;
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: BOOLTRUE] 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: ROPENIL] = {
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];
};
DoesUserMean: PUBLIC PROC [rope: ROPE, exec: UserExec.ExecHandle, intro: ROPENIL] = {
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];
};
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.
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]];
};
};
turns echoing back on when all characters that were stuffed have been read.
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];
};
Registration: RegisterCommand, RegisterTransformation, RegisterMethod, Register
RegisterCommand: PUBLIC PROC [name: ROPE, proc: UserExec.CommandProc, briefDoc, doc: ROPENIL, clientData: REF ANYNIL] = {
Register[name: name, proc: proc, briefDoc: briefDoc, doc: doc, clientData: clientData];
};
RegisterTransformation: PUBLIC PROC [name: ROPE, proc: UserExec.TransformProc, briefDoc, doc: ROPENIL, clientData: REF ANYNIL]= {
Register[name: name, transformProc: proc, briefDoc: briefDoc, doc: doc, clientData: clientData];
};
RegisterMethod: PUBLIC PROC [name: ROPE, proc: UserExec.MethodProc, doc: ROPENIL, clientData: REF ANYNIL] = {
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: ROPENIL,
proc: UserExec.CommandProc ← NIL,
oldStyleProc: UNSAFE PROCEDURENIL,
transformProc: UserExec.TransformProc ← NIL,
briefDoc, doc: ROPENIL,
nameOfBCD: ROPENIL,
clientData: REF ANYNIL,
fromCatalogue: BOOLFALSE
] = {
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]];
};
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];
{
SortCommands: ENTRY PROCEDURE = TRUSTED { -- Loophole for polymorphism
ENABLE UNWIND => NULL;
UserExecPrivate.commandList ← LOOPHOLE[List.Sort[LOOPHOLE[UserExecPrivate.commandList], compare]]
};
SortCommands[];
};
}; -- 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];
};
Lookup
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 ROPELOOPHOLE[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 ROPENIL] = {
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];
};
Dealing With Commander
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];
Initialization
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: STREAMNIL;
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: ROPENIL;
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
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