-- file PGSInterface.Mesa -- last modified by Satterthwaite, August 13, 1982 12:36 pm DIRECTORY CharIO: TYPE USING [CR, PutChar, PutString], 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], PGSConDefs: TYPE USING [], PGSOps: TYPE USING [PGSPhase, Generate, LockedSource, NoSource, BadSemantics], PGSParseData: TYPE, OSMiscOps: TYPE USING [FindFile], Runtime USING [GetBcdTime, GetTableBase], Stream: TYPE USING [Delete, Handle], Strings: TYPE USING [String, AppendString], Time: TYPE USING [Append, Unpack], TTY: TYPE USING [Handle, PutChar], UserTerminal: TYPE USING [CursorArray, GetCursorPattern, SetCursorPattern]; PGSInterface: PROGRAM IMPORTS CharIO, CommandUtil, Exec, FileStream, Heap, OSMiscOps, PGSOps, PGSParseData, Runtime, Stream, Strings, Time, TTY, UserTerminal EXPORTS PGSConDefs = { -- command interface tty: TTY.Handle; log: Stream.Handle ← NIL; commandStream: Stream.Handle ← NIL; CR: CHARACTER = CharIO.CR; LogChar: PROC [c: CHARACTER] = { IF log # NIL THEN CharIO.PutChar[log, c]; TTY.PutChar[tty, c]}; LogString: PROC [s: Strings.String] = { IF log # NIL THEN CharIO.PutString[log, s]; FOR i: CARDINAL IN [0..s.length) DO TTY.PutChar[tty, s[i]] ENDLOOP}; -- scratch region and scratch zone management zone: UNCOUNTED ZONE ← NIL; AcquireZone: PUBLIC PROC RETURNS [UNCOUNTED ZONE] = { RETURN [zone]}; -- parse table management tableSeg: LONG POINTER = Runtime.GetTableBase[LOOPHOLE[PGSParseData]]; AcquireTable: PUBLIC PROC RETURNS [LONG POINTER] = { RETURN [tableSeg]}; ReleaseTable: PUBLIC PROC = {}; -- 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: BOOLEAN ← 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: BOOLEAN; herald: STRING ← [50]; savedCursor: UserTerminal.CursorArray; commandObject: CommandUtil.CommandObject; commandLine: PACKED ARRAY [ 0.. 100) OF CHARACTER; zone ← Heap.Create[initial: 16, increment: 8]; Strings.AppendString[to:herald, from:"Cedar 3.3 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]; LogChar[CR]; LogString["Command: "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]; LogChar[CR]; LogString[" "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[tty, command.data[i]] ENDLOOP}; Exec.AddCommand["PGS.~"L, Main]; }.