-- BLControl.mesa -- Last edited by Satterthwaite on January 6, 1983 2:19 pm DIRECTORY CharIO: TYPE USING [PutChar, PutLine, PutString], CommandUtil: TYPE USING [ CommandObject, CopyString, Echo, Failed, FreePairList, FreeString, GetNth, ListLength, PairList, Parse, SetExtension], Exec: TYPE USING [AddCommand, commandLine, w], ExecOps: TYPE USING [CheckForAbort, Command], ListerOps: TYPE USING [ListFiles, ListBcd, ListRTBcd, ListStamps, ListVersion], OSMiscOps: TYPE USING [BcdCreateTime], Runtime: TYPE USING [CallDebugger], Stream: TYPE USING [ Handle, Object, PutByteProcedure, DeleteProcedure, Delete], Strings: TYPE USING [ AppendString, EquivalentSubString, String, SubStringDescriptor], Time: TYPE USING [Append, AppendCurrent, Current, Unpack], TTY: TYPE USING [PutChar]; BLControl: PROGRAM IMPORTS CharIO, CommandUtil, Exec, ExecOps, ListerOps, OSMiscOps, Runtime, Stream, Strings, Time, TTY = { EquivalentString: PROC [s1, s2: Strings.String] RETURNS [BOOL] = { ss1: Strings.SubStringDescriptor ← [base: s1, offset: 0, length: s1.length]; ss2: Strings.SubStringDescriptor ← [base: s2, offset: 0, length: s2.length]; RETURN [Strings.EquivalentSubString[@ss1, @ss2]]}; -- 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[VAL[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; IF outputName # NIL THEN { PutString[s, "\nListing "L]; PutString[s, inputName]; 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 Bcd 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..root.length) DO IF root[i] = '. THEN {root.length ← i; EXIT}; ENDLOOP}; -- switches StandardDefaults: PACKED ARRAY CHAR ['a..'z] OF BOOL = [ FALSE, -- a TRUE, -- b Bcd (only) FALSE, -- c FALSE, -- d Call debugger on error FALSE, -- e FALSE, -- f Files (only) FALSE, -- g FALSE, -- h FALSE, -- i FALSE, -- j FALSE, -- k FALSE, -- l Links FALSE, -- m FALSE, -- n FALSE, -- o Ordered (with /r only) FALSE, -- p FALSE, -- q FALSE, -- r RTBcd (only) FALSE, -- s Stamps (only) FALSE, -- t FALSE, -- u FALSE, -- v Version (only) FALSE, -- w FALSE, -- x FALSE, -- y FALSE];-- z -- v > b > r > f > s; others are unused -- 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 = INLINE {RepeatCommand[log]}; Finalize: PROC = INLINE {}; startTime: LONG CARDINAL; localSwitches ← defaultSwitches; [inputName, commandArgs, results, switches] ← CommandUtil.Parse[ s: @theCommand, opX: 2+("bcd"L).length, resultX: 2+("bl"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]; 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[VAL[(c.ORD-'A.ORD) + 'a.ORD]] ← sense; sense ← TRUE}; '! => {Runtime.CallDebugger[NIL]; sense ← TRUE}; ENDCASE; i ← i+1; ENDLOOP; switches ← CommandUtil.FreeString[switches]}; startTime ← Time.Current[]; SELECT TRUE FROM localSwitches['v] => NULL; -- for now ENDCASE => { IF outputName = NIL THEN outputName ← CommandUtil.CopyString[rootName, 2+("bl"L).length]; outputName ← CommandUtil.SetExtension[outputName, "bl"L]}; Initialize[]; BEGIN ENABLE UNWIND => {Finalize[]}; SELECT TRUE FROM localSwitches['v] => ListerOps.ListVersion[rootName]; localSwitches['s] => ListerOps.ListStamps[rootName, outputName]; localSwitches['f] => ListerOps.ListFiles[rootName, outputName]; localSwitches['r] => ListerOps.ListRTBcd[rootName, outputName, localSwitches['o]]; localSwitches['b] => ListerOps.ListBcd[rootName, outputName, localSwitches['l]]; ENDCASE; 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[VAL[(c.ORD-'A.ORD) + 'a.ORD]] ← 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 Binder initialization Init: PROC = { Exec.AddCommand["bl"L, DoCommand]; Exec.AddCommand["BcdLister"L, DoCommand]}; Init[]; }.