DIRECTORY
BcdDefs: TYPE USING [VersionStamp],
IO: TYPE USING [PutChar, PutDecimal, PutString],
Exec: TYPE USING [CommandLine, AddCommand, commandLine, w],
IO: TYPE USING [Create, GetLeaderProperties],
UnsafeStorage: TYPE USING [GetSystemUZone],
OSMiscOps: TYPE USING [FileError, FindFile, GenerateUniqueId],
PGSConDefs: TYPE USING [],
Runtime: TYPE USING [GetBcdTime],
IO: TYPE USING [Handle, Delete],
ConvertUnsafe:
TYPE
USING [
String, SubStringDescriptor, AppendChar, AppendString, EquivalentSubStrings],
TableCommand: TYPE USING [CompileStrings, MakeModule],
Time: TYPE USING [Append, Current, Unpack],
TTY: TYPE USING [Handle, PutChar, PutDecimal],
UserTerminal: TYPE USING [CursorArray, GetCursorPattern, SetCursorPattern];
TableControl:
PROGRAM
IMPORTS
IO, Exec, IO, UnsafeStorage, OSMiscOps, Runtime, IO, ConvertUnsafe,
TableCommand, Time, TTY, UserTerminal
EXPORTS TableCommand, PGSConDefs = {
cursor control
savedCursor: UserTerminal.CursorArray;
TableCursor: UserTerminal.CursorArray = [
177777b, 177777b, 177777b, 160007b,
160007b, 160007b, 160007b, 160007b, 160007b, 160007b, 160007b, 160007b,
160007b, 177777b, 177777b, 177777b];
OS interface
zone: PUBLIC UNCOUNTED ZONE;
Rubout: ERROR = CODE;
CommandEnded:
PROC
RETURNS [
BOOL] = {
RETURN [command.i >= command.s.Length[]]};
CommandChar:
PROC
RETURNS [char:
CHAR] = {
IF command.i < command.s.Length[]
THEN {
char ← command.s[command.i]; command.i ← command.i+1}
ELSE char ← '\000;
RETURN};
ReadCommand:
PROC [command: Rope.
ROPE]
RETURNS [name, switches: Rope.
ROPE, BOOL] = {
input: Rope.ROPE ← [80];
i: CARDINAL;
c: CHAR;
activeString: Rope.ROPE ← name;
DO
IF CommandEnded[] THEN EXIT;
c ← CommandChar[];
SELECT c
FROM
' => IF input.Length[] # 0 THEN EXIT;
IO.CR => EXIT;
ENDCASE => ConvertUnsafe.AppendChar[input, c];
ENDLOOP;
i ← name.Length[] ← switches.Length[] ← 0;
WHILE i < input.Length[] AND input[i] = ' DO i ← i+1 ENDLOOP;
--parse command--
FOR i
IN [i..input.Length[])
DO
SELECT (c←input[i])
FROM
'/ => activeString ← switches;
' , IO.CR => EXIT;
ENDCASE => ConvertUnsafe.AppendChar[activeString,c];
ENDLOOP;
FOR i
IN [0..switches.Length[])
DO
-- convert all to lower case
IF (c←switches[i]) IN ['A..'Z] THEN switches[i] ← VAL[(c.ORD -'A.ORD) + 'a.ORD];
ENDLOOP;
RETURN [name.Length[] # 0 OR switches.Length[] # 0]};
ExtensionIs:
PROC [name, ext: Rope.
ROPE]
RETURNS [
BOOL] = {
RETURN[Rope.Find[s1: name, s2: ext, case: FALSE] > -1]};
GenerateVersion:
PUBLIC
PROC
RETURNS [version: BcdDefs.VersionStamp] = {
RETURN [OSMiscOps.GenerateUniqueId[]]};
WriteHerald:
PROC[stream:
IO.
STREAM] = {
stream.PutRope["Cedar 3.3 Table Compiler of "];
stream.Put[IO.time[Runtime.GetBcdTime[]], IO.char[IO.CR]];
stream.PutRope[IO.rope["TableCompiler.log -- "] IO.time[], IO.char[IO.CR]]};
warningsLogged: PUBLIC BOOL;
seterrstream, resetoutstream: PUBLIC PROC = {NULL};
outeol:
PUBLIC
PROC [n:
INTEGER] = {
THROUGH [1..n] DO log.PutChar['\n] ENDLOOP};
outstring: PUBLIC PROC [string: Rope.ROPE] = log.PutRope;
sourceName: PUBLIC Rope.ROPE ← NIL;
pgsVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, Runtime.GetBcdTime[]];
sourceVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, 0];
objectVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, 0];
Main: SAFE PROC [Commander.Handle] = TRUSTED {
input: {strings, binary}; -- compiling strings
compact: BOOL;
dStar: BOOL;
rootName: Rope.ROPE;
interfaceName: Rope.ROPE;
formatName: Rope.ROPE;
bcdName: Rope.ROPE;
GetCommand:
PROC = {
file: Rope.ROPE;
sw: Rope.ROPE;
i: CARDINAL;
c: CHAR;
done: BOOL ← FALSE;
sense: BOOL;
GetSwitch:
PROC
RETURNS [c:
CHAR] = {
sense ← TRUE;
WHILE i < sw.Length[]
DO
c ← sw.Fetch[i]; i ← i + 1;
IF c = '- OR c = '~ THEN sense ← ~sense ELSE EXIT;
ENDLOOP;
RETURN};
sourceName ← NIL;
dStar ← TRUE;
[file, sw] ← ReadCommand[cmd.commandLine];
IF sw.Length[] = 0 AND file.Length[] = 0 THEN RETURN;
CommandUtil.SetExtension[file, "mesa"];
IF ExtensionIs[file, ".mesa"]
THEN {input ← $strings; compact ← TRUE}
ELSE input ← $binary;
i ← 0;
WHILE i < sw.Length[]
DO
SELECT (c←GetSwitch[])
FROM
'a => dStar ← ~sense;
'c => compact ← sense;
'm => input ← $binary;
's => {input ← $strings; compact ← FALSE};
't => {input ← $strings; compact ← TRUE};
'g => done ← TRUE;
ENDCASE => GO TO barf;
REPEAT
barf => ERROR Rubout;
ENDLOOP;
sourceName ← file;
WHILE ~done
AND ReadCommand[file, sw]
DO
[file, sw] ← ReadCommand[cmd.commandLine]
i ← 0;
WHILE i < sw.Length[]
DO
SELECT (c←GetSwitch[])
FROM
'f => formatName ← file ← CommandUtil.SetExtension[file, "format"];
'i => interfaceName ← file ← CommandUtil.SetExtension[file, "bcd"];
'o => bcdName ← file ← CommandUtil.SetExtension[file, "bcd"];
'g => done ← TRUE;
ENDCASE => ERROR Rubout;
ENDLOOP;
ENDLOOP};
LogCommand:
PROC = {
SELECT input
FROM
$strings => {
log.PutRope["\nCompiling "]; log.PutRope[sourceName];
log.PutRope[", exporting "]; log.PutRope[rootName];
log.PutRope[" to "]; log.PutRope[interfaceName];
IF bcdName.Length[] # 0 THEN {log.PutRope[", BCD to "]; log.PutRope[bcdName]};
log.PutRope["\nRecord format on "]; log.PutRope[formatName]};
$binary => {
log.PutRope["\nProcessing "]; log.PutRope[sourceName];
log.PutRope[", exporting "]; log.PutRope[rootName];
log.PutRope[" to "]; log.PutRope[interfaceName];
IF bcdName.Length[] # 0 THEN {log.PutRope[", BCD to "]; log.PutRope[bcdName]}};
ENDCASE;
log.PutChar[IO.CR]};
initialization
zone ← UnsafeStorage.GetSystemUZone[];
command ← Exec.commandLine;
log ← FileIO.Open["TableCompiler.log", write];
WriteHerald[];
main loop
DO
BEGIN
ENABLE
OSMiscOps.FileError => {
log.PutRope["Can't open "]; log.PutRope[name]; log.PutChar[IO.CR];
GO TO FileFault};
GetCommand[ ! Rubout => {GOTO Abort}];
IF sourceName = NIL THEN EXIT;
rootName.Length[] ← 0;
FOR i:
CARDINAL
IN [0..sourceName.Length[])
DO
IF sourceName[i] = '. THEN EXIT;
ConvertUnsafe.AppendChar[rootName, sourceName[i]];
ENDLOOP;
IF interfaceName.Length[] = 0 THEN ConvertUnsafe.AppendString[interfaceName, "SELF"];
IF formatName.Length[] = 0
THEN {
ConvertUnsafe.AppendString[formatName, rootName];
ConvertUnsafe.AppendString[formatName, "Format."]};
LogCommand[];
IF bcdName.Length[] = 0
THEN {
ConvertUnsafe.AppendString[bcdName, rootName];
ConvertUnsafe.AppendString[bcdName, ".bcd"]};
savedCursor ← UserTerminal.GetCursorPattern[];
UserTerminal.SetCursorPattern[TableCursor];
SELECT input
FROM
$strings => {
nChars, nStrings: CARDINAL;
[nStrings, nChars] ← TableCommand.CompileStrings[
inputFile: sourceName,
interfaceId: interfaceName,
formatId: formatName,
moduleId: bcdName,
compact: compact,
altoCode: ~dStar];
log.PutRope["ConvertUnsafe: "]; log.Put[IO.int[[nStrings]];
log.PutRope[", characters: "]; log.Put[IO.int[[nChars]];
log.PutChar[IO.CR]};
$binary =>
TableCommand.MakeModule[
inputFile: sourceName,
interfaceId: interfaceName,
moduleId: bcdName,
altocode: ~dStar];
ENDCASE;
log.PutChar[IO.CR];
UserTerminal.SetCursorPattern[savedCursor];
EXITS
FileFault => NULL;
Abort => log.PutChar['?];
END;
IF sourceName # NIL THEN zone.FREE[@sourceName];
ENDLOOP;
IF log # NIL THEN IO.Delete[log];
zone ← NIL};
Commander.Register["TableCompiler", Main, NIL];
}.