CommandToolImpl.mesa
Larry Stewart, April 21, 1983 4:57 pm
Paul Rovner, April 18, 1983 4:27 pm
Russ Atkinson, April 20, 1983 8:25 pm
DIRECTORY
Buttons USING [ButtonProc, Create],
Commander,
CommandTool,
ConvertUnsafe USING [AppendRope, ToRope],
Directory USING [Error, GetProps, Lookup],
IO,
File USING [Capability],
List USING [AList, DotCons],
Loader USING [Error, Start, Instantiate],
PrincOps USING [ControlModule],
Process USING [Priority, GetPriority, SetPriority, priorityNormal],
ProcessProps USING [AddPropList],
ReadEvalPrint USING [ClientProc, CreateViewerEvaluator, Handle, IsACR, MainLoop],
Rope USING [Compare, Concat, Find, Length, ROPE, Substr],
UECP USING [Argv, Parse];
CommandToolImpl: CEDAR MONITOR
IMPORTS
Buttons, Commander, ConvertUnsafe, Directory, IO, List, Loader, Process, ProcessProps, ReadEvalPrint, Rope, UECP
EXPORTS CommandTool
= BEGIN
promptKey: ROPE = "prompt";
initPrompt: ROPE = "%% ";
defaultPrompt: ROPE = "%% ";
Useful Types
ProcCellRef: TYPE = REF Commander.ProcCell;
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
EachCommand: PUBLIC ReadEvalPrint.ClientProc = {
cmd: Commander.Handle;
propertyList: List.AList ← NIL;
cStream: STREAM;
err: STREAMNIL;
WITH h.clientData SELECT FROM
cth: Commander.Handle => {
propertyList ← cth.propertyList;
err ← cth.err;
};
ENDCASE;
IF propertyList = NIL THEN
propertyList ← Commander.PutProperty[key: promptKey, val: h.prompt, aList: propertyList];
IF err = NIL THEN err ← h.out;
cmd ← NEW[Commander.CommandObject ← [
in: h.in,
out: h.out,
err: err,
propertyList: propertyList
]];
cStream ← IO.RIS[rope: command, oldStream: cStream];
cmd.command ← cStream.GetToken[];
IF cmd.command.Length[] = 0 THEN RETURN;
cmd.commandLine ← Rope.Substr[
base: command,
start: Rope.Find[s1: command, s2: cmd.command] + cmd.command.Length[]];
ExecuteCommand[cmd];
h.in.ResetUserAbort[];
WITH Commander.GetProperty[key: promptKey, aList: propertyList] SELECT FROM
rope: ROPE => h.prompt ← rope;
ENDCASE => h.prompt ← defaultPrompt;
};
CallList: PROC [property: REF ANY, cmd: Commander.Handle] = {
WITH Commander.GetProperty[key: property, aList: cmd.propertyList] SELECT FROM
list: LIST OF REF ANY =>
FOR l: LIST OF REF ANY ← list, l.rest WHILE l # NIL DO
WITH l.first SELECT FROM
cpc: ProcCellRef => cpc.proc[cmd];
ENDCASE;
ENDLOOP;
ENDCASE;
};
DoCommand: PUBLIC PROC [command: ROPE, commandLine, in: ROPENIL] RETURNS [out, err: ROPE] = {
outS: STREAM;
errS: STREAM;
cmd: Commander.Handle;
outS ← IO.ROS[];
errS ← IO.ROS[];
cmd ← NEW[Commander.CommandObject ← [
in: IO.RIS[in],
out: outS,
err: errS,
commandLine: commandLine,
command: command,
propertyList: Commander.PutProperty[$Junk, $Junk, NIL]
]];
ExecuteCommand[cmd];
RETURN[out: outS.GetOutputStreamRope[], err: errS.GetOutputStreamRope[]];
};
ExecuteCommand: PUBLIC PROC [command: Commander.Handle] = {
innerExecute: PROC = {
commandProc: Commander.CommandProc;
CallList[property: $PreLookup, cmd: command !
ABORTED => {
command.err.PutRope[". . . Aborted\n" ! ANY => CONTINUE];
CONTINUE;
};
UNWIND => {
command.err.PutRope[". . . Unwound\n" ! ANY => CONTINUE];
CONTINUE;
};
];
commandProc ← Commander.Lookup[command.command].proc;
IF commandProc = NIL
THEN
command.err.PutF[". . . %g: command not found\n", IO.rope[command.command]]
ELSE {
ENABLE {
ABORTED => {
command.err.PutRope[". . . Aborted\n" ! ANY => CONTINUE];
CONTINUE;
};
UNWIND => {
command.err.PutRope[". . . Unwound\n" ! ANY => CONTINUE];
CONTINUE;
};
};
CallList[property: $Before, cmd: command];
commandProc[cmd: command];
CallList[property: $After, cmd: command];
};
};
ProcessProps.AddPropList[
LIST[List.DotCons[key: $CommanderHandle, val: command]],
innerExecute];
};
Create: PUBLIC PROC = {
cmd: Commander.Handle ← NEW[Commander.CommandObject];
readEvalPrint: ReadEvalPrint.Handle;
oldPriority: Process.Priority ← Process.GetPriority[];
TRUSTED{Process.SetPriority[Process.priorityNormal]};
readEvalPrint ← ReadEvalPrint.CreateViewerEvaluator[
clientProc: EachCommand,
prompt: initPrompt,
info: [name: "Commander", column: right, iconic: FALSE],
edited: TRUE,
deliverWhen: ReadEvalPrint.IsACR,
clientData: cmd];
very first propery makes the list NON-NIL
cmd.propertyList ← Commander.PutProperty[
key: promptKey, val: defaultPrompt, aList: cmd.propertyList];
subsequent properties will never change the first cell
cmd.propertyList ← Commander.PutProperty[
key: $ReadEvalPrintHandle, val: readEvalPrint, aList: cmd.propertyList];
ReadEvalPrint.MainLoop[readEvalPrint, TRUE];
TRUSTED{Process.SetPriority[oldPriority]};
};
CreateCommanderButtonProc: Buttons.ButtonProc = {
Create[];
};
CreateCommander: Commander.CommandProc = {
Create[];
};
Run: Commander.CommandProc = TRUSTED {
argv: UECP.Argv ← UECP.Parse[cmd.commandLine];
bcdName: ROPE;
stringBCDName: LONG STRING ← [50];
error: ROPENIL;
name: ROPE;
f: File.Capability;
length: INT;
unboundImports: BOOLFALSE;
cm: PrincOps.ControlModule;
IF argv.argc # 2 THEN {
cmd.out.PutRope["Usage: Run bcdFileName\n"];
RETURN;
};
bcdName ← argv[1];
length ← Rope.Length[bcdName];
IF length < 5 OR Rope.Compare[Rope.Substr[bcdName, length - 4, 4], ".bcd", FALSE] # equal THEN bcdName ← Rope.Concat[bcdName, ".bcd"];
length ← Rope.Length[bcdName];
IF length > 50 THEN {
cmd.out.PutF["Run %g: name too long\n", IO.rope[bcdName]];
RETURN;
};
TRUSTED {
ENABLE {
Loader.Error => {
SELECT type FROM
invalidBcd => error ← "Invalid Bcd";
fileNotFound => error ← "File Not Found";
versionMismatch => error ← "Version Mismatch";
loadStateFull => error ← "LoadState Full";
insufficientVM => error ← "Insufficient VM";
ENDCASE => ERROR;
CONTINUE;
};
Directory.Error => {
SELECT type FROM
invalidFileName => error ← "Illegal file name";
fileNotFound => error ← "Couldn't find a runnable file named";
ENDCASE => error ← "Directory.Lookup failed on";
CONTINUE;
};
};
ConvertUnsafe.AppendRope[to: stringBCDName, from: bcdName];
f ← Directory.Lookup[stringBCDName];
IF error=NIL THEN {
[cm, unboundImports] ← Loader.Instantiate[file: f, offset: 1 ! ABORTED => {
error ← "Execution Aborted in";
CONTINUE;
}];
IF unboundImports THEN cmd.out.PutRope["There are unbound imports.\n"];
};
IF error=NIL THEN Loader.Start[cm];
IF error=NIL THEN [] ← Directory.GetProps[f, stringBCDName];
IF error=NIL THEN name ← ConvertUnsafe.ToRope[stringBCDName];
};
cmd.out.PutF["%g: %g\n", IO.rope[IF error = NIL THEN "Loaded and ran" ELSE error], IO.rope[IF error = NIL THEN name ELSE bcdName]];
};
Init: PROC = {
[] ← Buttons.Create[info: [name: "Cmd"], proc: CreateCommanderButtonProc, fork: FALSE, documentation: "Create a Commander viewer"];
Commander.Register[key: "Commander", proc: CreateCommander, doc: "Create a new Commander Tool"];
Commander.Register[key: "Run", proc: Run, doc: "Run xxx.bcd - Load and Start a .bcd"];
};
main program for Commander
Init[];
END.
March 27, 1983 3:27 pm, Stewart, Created from ChatImpl
April 20, 1983 8:26 pm, Russ Atkinson, added Process Props stuff