-- file CrossPGSInterface.mesa -- last modified by Satterthwaite, January 12, 1983 8:53 am DIRECTORY CommandUtil: TYPE USING [ PairList, Echo, Failed, FreePairList, FreeString, Parse, CommandPtr, CommandObject], Exec: TYPE USING [AddCommand, commandLine, w], FileStream: TYPE USING [Create, SetLength], Heap: TYPE USING [Create, Delete], OSMiscOps: TYPE USING [FindFile], PGSConDefs: TYPE USING [], PGSOps: TYPE USING [PGSPhase, Generate, LockedSource, NoSource, BadSemantics], Runtime USING [GetBcdTime], Stream: TYPE USING [Delete, Handle, PutChar], Strings: TYPE USING [String, AppendString], Time: TYPE USING [Append, Unpack], TTY: TYPE USING [Handle, PutChar], UserTerminal: TYPE USING [CursorArray, GetCursorPattern, SetCursorPattern]; CrossPGSInterface: PROGRAM IMPORTS CommandUtil, Exec, FileStream, Heap, OSMiscOps, PGSOps, Runtime, Stream, Strings, Time, TTY, UserTerminal EXPORTS PGSConDefs = { -- command interface tty: TTY.Handle; log: Stream.Handle ← NIL; commandStream: Stream.Handle ← NIL; CR: CHAR = '\n; LogChar: PROC [c: CHAR] = { IF log # NIL THEN log.PutChar[c]; tty.PutChar[c]}; LogString: PROC [s: Strings.String] = { FOR i: CARDINAL IN [0..s.length) DO LogChar[s[i]] ENDLOOP}; -- scratch region and scratch zone management zone: PUBLIC UNCOUNTED ZONE ← NIL; -- cursor management preCursor: UserTerminal.CursorArray = [ 0, 0, 0, 0, 76b, 146b, 300b, 4300b, 76336b, 4304b, 314b, 164b, 0, 0, 0, 0]; pgsCursor: UserTerminal.CursorArray = [ 37000b, 63000b, 140000b, 140010b, 157174b, 142010b, 146000b, 72000b, 0b, 177777b, 111111b, 177777b, 111111b, 177777b, 111111b, 177777b]; StartPhase: PROC [phase: PGSOps.PGSPhase] RETURNS [goOn: BOOL ← TRUE] = { SELECT phase FROM $format => UserTerminal.SetCursorPattern[preCursor]; $lalr => UserTerminal.SetCursorPattern[pgsCursor]; ENDCASE}; -- * * * * * * HERE IT BEGINS * * * * * * Main: PROC = { source: Strings.String; args, results: CommandUtil.PairList; switches: Strings.String; ok, warnings: BOOL; herald: STRING ← [50]; savedCursor: UserTerminal.CursorArray; commandObject: CommandUtil.CommandObject; commandLine: PACKED ARRAY [0.. 100) OF CHAR; zone ← Heap.Create[initial:16, increment:8]; Strings.AppendString[to:herald, from:"Cedar Trinity Cross PGS of "L]; Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]]; herald.length ← herald.length - 3; tty ← Exec.w; log ← FileStream.Create[OSMiscOps.FindFile["pgs.log"L, write]]; FileStream.SetLength[log, 0]; LogString[herald]; LogChar[CR]; savedCursor ← UserTerminal.GetCursorPattern[]; -- set up command stream BEGIN commandObject.data ← @commandLine; BuildCommand[@commandObject]; LogString["\nCommand: "L]; EchoCommand[@commandObject]; [source, args, results, switches] ← CommandUtil.Parse[ s: @commandObject, opX: 0, resultX: 2+("mesa"L).length ! CommandUtil.Failed => GO TO badSyntax]; CommandUtil.Echo[log, source, args, results, switches]; IF source = NIL THEN GO TO noOp; [ok, warnings] ← PGSOps.Generate[source, args, results, switches, StartPhase, TRUE ! PGSOps.NoSource => GO TO noSource; PGSOps.LockedSource => GO TO lockedSource; PGSOps.BadSemantics => GO TO badSemantics]; LogString["\n "L]; LogString[SELECT TRUE FROM ~ok => "Errors logged, bad output"L, warnings => "Warnings logged"L, ENDCASE => "Completed successfully"L]; EXITS noOp => NULL; noSource => LogString[" -- Cannot be opened"L]; lockedSource => LogString[" -- Cannot be modified"L]; badSyntax => LogString["Unparsable command"L]; badSemantics => LogString[" -- Illegal command"L]; END; source ← CommandUtil.FreeString[source]; args ← CommandUtil.FreePairList[args]; results ← CommandUtil.FreePairList[results]; switches ← CommandUtil.FreeString[switches]; Heap.Delete[zone]; zone ← NIL; LogChar[CR]; LogChar[CR]; Stream.Delete[log]; log ← NIL; UserTerminal.SetCursorPattern[savedCursor]}; BuildCommand: PROC [command: CommandUtil.CommandPtr] = { command.pos ← command.len ← 0; FOR i: CARDINAL IN [Exec.commandLine.i .. Exec.commandLine.s.length) DO IF command.len >= 100 THEN EXIT; command.data[command.len] ← Exec.commandLine.s[i]; command.len ← command.len + 1; ENDLOOP}; EchoCommand: PROC [command: CommandUtil.CommandPtr] = { first: CARDINAL ← command.pos; last: CARDINAL ← command.len; WHILE first < command.len AND command.data[first] = ' DO first ← first+1 ENDLOOP; WHILE last > command.pos AND command.data[last-1] = CR DO last ← last-1 ENDLOOP; FOR i: CARDINAL IN [first .. last) DO tty.PutChar[command.data[i]] ENDLOOP}; Exec.AddCommand["CrossPGS.~"L, Main]; }.