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, Match, 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 { -- try for unique prefix (i.e. allow abbreviations, patterns) lst: LIST OF ROPE _ NIL; p: PROC[name: ROPE, proc: Commander.CommandProc, doc: ROPE] RETURNS[stop: BOOL _ FALSE] = { IF Rope.Match[ pattern: Rope.Concat[command.command, "*"], object: name, case: FALSE ] THEN lst _ CONS[name, lst]; }; [] _ Commander.Enumerate[p]; IF lst = NIL THEN { command.err.PutF[". . . %g: command not found\n", IO.rope[command.command]]; RETURN; }; IF lst.rest # NIL THEN { -- ambiguous prefix command.err.PutF[". . . %g: command ambiguous ( ", IO.rope[command.command]]; FOR x: LIST OF ROPE _ lst, x.rest UNTIL x = NIL DO command.err.PutRope[x.first]; command.err.PutRope[" "]; ENDLOOP; command.err.PutRope[")\n"]; RETURN; } ELSE { command.command _ lst.first; commandProc _ Commander.Lookup[lst.first].proc -- this will succeed }; }; IF commandProc = NIL THEN ERROR; {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 CommandToolImpl.mesa Larry Stewart, April 21, 1983 4:57 pm Russ Atkinson, April 20, 1983 8:25 pm Paul Rovner, June 2, 1983 2:44 pm Useful Types very first propery makes the list NON-NIL subsequent properties will never change the first cell main program for Commander Ê Á˜J˜šœ™Jšœ%™%J™%Jšœ!™!—J˜šÏk ˜ Jšœœ˜#J˜ J˜ Jšœœ˜)Jšœ œ˜*Jšœ˜Jšœœ˜Jšœœ˜Jšœœ˜)Jšœ œ˜Jšœœ6˜CJšœ œ˜!Jšœœ>˜QJšœœ(œ ˜@Jšœœ˜J˜—šœœ˜š˜Jšœ.œ<˜p—Jšœ ˜Jšœ˜Jšœ œ ˜Jšœ œ ˜Jšœœ ˜—J˜šœ ™ Jšœ œœ˜+Jšœœœ˜Jšœœœœ˜J˜—šœ œ˜0Jšœ˜Jšœœ˜Jšœ œ˜Jšœœœ˜šœœ˜šœ˜Jšœ ˜ J˜J˜—Jšœ˜—šœœ˜JšœY˜Y—Jšœœœ ˜šœœ˜%J˜ J˜ Jšœ ˜ Jšœ˜J˜—Jšœ œœ$˜4Jšœ!˜!Jšœœœ˜(šœ˜Jšœ˜JšœG˜G—Jšœ˜Jšœ˜šœ<œ˜KJšœœ˜Jšœ˜$—J˜—J˜šÏnœœ œœ˜=šœ?œ˜Nš œœœœœ˜šœœœœœœœ˜6šœœ˜Jšœ"˜"Jšœ˜—Jšœ˜——Jšœ˜—J˜—J˜šž œœœ œœœœ œ˜`Jšœœ˜ Jšœœ˜ Jšœ˜Jšœœœ˜Jšœœœ˜šœœ˜%Jšœœœ˜J˜ J˜ Jšœ˜J˜Jšœ2œ˜6J˜—Jšœ˜JšœC˜IJ˜—J˜šžœœœ ˜;šœœ˜Jšœ#˜#šœ-˜-šœ˜ Jšœ(œœ˜9Jšœ˜ J˜—šœ˜ Jšœ(œœ˜9Jšœ˜ J˜—Jšœ˜—Jšœ5˜5šœ˜šœÏc=˜EJš œœœœœ˜šœœœ$œ˜;Jšœ œ˜šœ ˜Jšœ+˜+Jšœ ˜ Jšœ˜ Jšœ˜—Jšœœ ˜Jšœ˜—Jšœ˜šœœ˜Jšœ2œ˜LJšœ˜J˜—šœ ˜šœŸ˜Jšœ3œ˜Mš œœœœœœ˜2Jšœ˜Jšœ˜Jšœ˜—Jšœ˜Jšœ˜J˜—šŸœ˜Jšœ˜Jšœ0Ÿ˜DJ˜——J˜—Jšœœœœ˜ šœœ˜ šœ˜ Jšœ(œœ˜9Jšœ˜ J˜šœ˜ Jšœ(œœ˜9Jšœ˜ J˜—J˜—Jšœ*˜*Jšœ˜Jšœ)˜)J˜——J˜—šœ˜Jšœ4˜8Jšœ˜—J˜—J˜šžœœœ˜Jšœœ˜5Jšœ$˜$Jšœ6˜6J˜Jšœ.˜5šœ4˜4Jšœ˜Jšœ˜Jšœ1œ˜8Jšœœ˜ Jšœ!˜!Jšœ˜—J˜J™)šœ)˜)Jšœ=˜=—J™J™6šœ)˜)JšœH˜H—J˜Jšœ&œ˜,Jšœ#˜*J˜—J˜šœ1˜1Jšœ ˜ J˜—J˜šœ*˜*Jšœ ˜ J˜—J˜šœœ˜&Jšœœœ˜.Jšœ œ˜Jšœœœ˜"Jšœœœ˜Jšœœ˜ J˜Jšœœ˜ Jšœœœ˜J˜šœœ˜Jšœ,˜,Jšœ˜J˜—Jšœ˜Jšœ˜Jšœ œ;œ œ(˜†Jšœ˜šœ œ˜Jšœ(œ˜:Jšœ˜J˜—šœ˜ šœ˜šœ˜šœ˜J˜$J˜)J˜.J˜*J˜,Jšœœ˜—Jšœ˜ Jšœ˜—˜šœ˜J˜/J˜>Jšœ)˜0—Jšœ˜ Jšœ˜—J˜—Jšœ;˜;Jšœ$˜$šœœœ˜šœ?œ˜KJšœ˜Jšœ˜ Jšœ˜—Jšœœ1˜GJ˜—Jšœœœ˜#Jšœœœ+˜