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:
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];
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: 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];
out.PutRope[rope];
ReadQuietly[rope, exec];
};
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];
};
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:
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
] = {
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]]
};
}; -- 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
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];
};
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: 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
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