<> <> <> <> 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 = "%% "; <> 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: STREAM _ NIL; 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: ROPE _ NIL] 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]; <> cmd.propertyList _ Commander.PutProperty[ key: promptKey, val: defaultPrompt, aList: cmd.propertyList]; <<>> <> 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: ROPE _ NIL; name: ROPE; f: File.Capability; length: INT; unboundImports: BOOL _ FALSE; 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"]; }; <
> Init[]; END. March 27, 1983 3:27 pm, Stewart, Created from ChatImpl April 20, 1983 8:26 pm, Russ Atkinson, added Process Props stuff