-- GLControl.mesa -- Last edited by Satterthwaite on September 16, 1982 8:40 am DIRECTORY CharIO: TYPE USING [PutChar, PutLine, PutString], CommandUtil: TYPE USING [ CommandObject, CopyString, Echo, Failed, FreePairList, FreeString, --GetNth,-- ListLength, PairList, Parse], Exec: TYPE USING [AddCommand, commandLine, w], ExecOps: TYPE USING [CheckForAbort, Command], ListerOps: TYPE USING [ListGlobals], OSMiscOps: TYPE USING [BcdCreateTime], Runtime: TYPE USING [CallDebugger], Stream: TYPE USING [ Handle, Object, PutByteProcedure, DeleteProcedure, Delete], Strings: TYPE USING [AppendString, String], Time: TYPE USING [Append, AppendCurrent, Current, Unpack], TTY: TYPE USING [PutChar]; GLControl: PROGRAM IMPORTS CharIO, CommandUtil, Exec, ExecOps, ListerOps, OSMiscOps, Runtime, Stream, Strings, Time, TTY = { -- command gathering and logging log: Stream.Handle ← NIL; logStreamObject: Stream.Object; SetLogStream: PROC = { logStreamObject ← [ options: TRASH, getByte: TRASH, putByte: PutTTY, getWord: TRASH, putWord: TRASH, get: TRASH, put: TRASH, setSST: TRASH, sendAttention: TRASH, waitAttention: TRASH, delete: NullDelete]; log ← @logStreamObject}; PutTTY: Stream.PutByteProcedure = {(Exec.w).PutChar['\000 + byte]}; NullDelete: Stream.DeleteProcedure = {}; LogString: PROC [s: Strings.String] = {CharIO.PutString[log, s]}; LogChar: PROC [c: CHAR] = {CharIO.PutChar[log, c]}; renamedOutput: BOOL ← FALSE; RepeatCommand: PROC [s: Stream.Handle] = { OPEN CharIO; PutString[s, "\nListing "L]; PutString[s, inputName]; IF renamedOutput THEN { PutString[s, ", output to "L]; PutString[s, outputName]}; PutChar[s, '\n]}; WriteHerald: PROC [s: Stream.Handle, id: Strings.String] = { OPEN Time, CharIO; herald: STRING ← [60]; Strings.AppendString[herald, "Cedar 3.4 Global Lister of "L]; Time.Append[herald, Time.Unpack[[OSMiscOps.BcdCreateTime[]]]]; herald.length ← herald.length-3; PutLine[s, herald]; IF id # NIL THEN {PutString[s, id]; PutString[s, " -- "L]}; herald.length ← 0; Time.AppendCurrent[herald]; PutLine[s, herald]}; -- file name bookkeeping inputName, outputName, rootName: Strings.String ← NIL; commandArgs: CommandUtil.PairList; FileRoot: PROC [s: Strings.String] RETURNS [root: Strings.String] = { root ← CommandUtil.CopyString[s, 0]; FOR i: CARDINAL DECREASING IN [0..s.length) DO IF s[i] = '. THEN {s.length ← i; EXIT}; ENDLOOP}; -- switches StandardDefaults: PACKED ARRAY CHAR ['a..'z] OF BOOL = [ FALSE, -- a FALSE, -- b FALSE, -- c FALSE, -- d Call debugger on error FALSE, -- e FALSE, -- f FALSE, -- g FALSE, -- h FALSE, -- i FALSE, -- j FALSE, -- k FALSE, -- l FALSE, -- m FALSE, -- n FALSE, -- o FALSE, -- p FALSE, -- q FALSE, -- r FALSE, -- s FALSE, -- t output to Typescript FALSE, -- u FALSE, -- v FALSE, -- w FALSE, -- x FALSE, -- y FALSE];-- z -- Exec interfaces DoCommand: PROC = { theCommand: CommandUtil.CommandObject ← [ pos: Exec.commandLine.i, len: Exec.commandLine.s.length, -- data: @Exec.commandLine.s.text]; data: LOOPHOLE[Exec.commandLine.s + StringBody[0].SIZE]]; results: CommandUtil.PairList; switches: Strings.String; defaultSwitches: PACKED ARRAY CHAR ['a..'z] OF BOOL ← StandardDefaults; localSwitches: PACKED ARRAY CHAR ['a..'z] OF BOOL; SetLogStream[]; WriteHerald[log, NIL]; -- main loop DO { Initialize: PROC = { IF localSwitches['t] THEN LogChar['\n] ELSE RepeatCommand[log]}; Finalize: PROC = {}; startTime: LONG CARDINAL; localSwitches ← defaultSwitches; renamedOutput ← FALSE; [inputName, commandArgs, results, switches] ← CommandUtil.Parse[ s: @theCommand, opX: 2+("bcd"L).length, resultX: 2+("gl"L).length ! CommandUtil.Failed => {GO TO badSyntax}]; IF inputName = NIL AND switches = NIL THEN EXIT; -- done listing LogString["\nCommand: "L]; CommandUtil.Echo[ d: log, operator: inputName, argList: commandArgs, resultList: results, switches: switches]; IF inputName = NIL THEN GO TO globalSwitches; SELECT CommandUtil.ListLength[results] FROM 0 => NULL; -- 1 => { -- outputName ← CommandUtil.GetNth[list: results, n: 0]; -- renamedOutput ← TRUE} ENDCASE => GO TO badSemantics; rootName ← FileRoot[inputName]; IF switches # NIL THEN { i: CARDINAL ← 0; sense: BOOL ← TRUE; WHILE i < switches.length DO c: CHAR = switches[i]; SELECT c FROM '-, '~ => sense ← ~sense; IN ['a..'z] => {localSwitches[c] ← sense; sense ← TRUE}; IN ['A..'Z] => {localSwitches[c + ('a-'A)] ← sense; sense ← TRUE}; '! => {Runtime.CallDebugger[NIL]; sense ← TRUE}; ENDCASE; i ← i+1; ENDLOOP; switches ← CommandUtil.FreeString[switches]}; startTime ← Time.Current[]; Initialize[]; BEGIN ENABLE UNWIND => {Finalize[]}; ListerOps.ListGlobals[rootName, localSwitches['t]]; END; Finalize[]; IF ExecOps.CheckForAbort[] THEN EXIT; EXITS globalSwitches => { sense: BOOL ← TRUE; results ← CommandUtil.FreePairList[results]; FOR i: CARDINAL IN [0..switches.length) DO c: CHAR = switches[i]; SELECT c FROM '-, '~ => sense ← ~sense; '! => Runtime.CallDebugger[NIL]; IN ['a..'z] => {defaultSwitches[c] ← sense; sense ← TRUE}; IN ['A..'Z] => {defaultSwitches[c + ('a-'A)] ← sense; sense ← TRUE}; ENDCASE => EXIT; ENDLOOP; switches ← CommandUtil.FreeString[switches]}; badSemantics => { results ← CommandUtil.FreePairList[results]; LogString["\n -- Illegal command"L]}}; inputName ← CommandUtil.FreeString[inputName]; outputName ← CommandUtil.FreeString[outputName]; commandArgs ← CommandUtil.FreePairList[commandArgs]; rootName ← CommandUtil.FreeString[rootName]; REPEAT badSyntax => {LogString["-- Illegal syntax"L]}; ENDLOOP; Stream.Delete[log]; log ← NIL}; -- global lister initialization Init: PROC = { Exec.AddCommand["gl"L, DoCommand]; Exec.AddCommand["GlobalLister"L, DoCommand]}; Init[]; }.