TableControl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Satterthwaite on January 10, 1983 4:42 pm
Maxwell, August 10, 1983 3:36 pm
Doug Wyatt, April 2, 1984 4:31:03 pm PST
Russ Atkinson (RRA) March 19, 1985 10:05:15 am PST
DIRECTORY
BasicTime USING [GMT, Now, ToPupTime],
BcdDefs USING [VersionStamp],
Commander USING [CommandProc, Register],
CommandUtil USING [Failed, GetRootName, KeyValue, ListLength, PairList, Parse, SetExtension],
FS USING [Error, GetInfo, OpenFileFromStream, StreamOpen],
IO USING [Close, int, PutChar, PutF, PutRope, RIS, rope, STREAM, time],
IOClasses USING [CreateDribbleOutputStream],
Loader USING [BCDBuildTime],
OSMiscOps USING [GenerateUniqueId],
PGSConDefs USING [],
Rope USING [Concat, Fetch, Find, Length, ROPE],
TableCommand USING [CompileStrings, MakeModule];
TableControl: PROGRAM
IMPORTS BasicTime, Commander, CommandUtil, FS, IO, IOClasses, Loader, OSMiscOps, Rope, TableCommand
EXPORTS TableCommand, PGSConDefs
= {
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
bcdTime: BasicTime.GMT ~ Loader.BCDBuildTime[Main];
cursor control
savedCursor: UserTerminal.CursorArray;
TableCursor: UserTerminal.CursorArray = [
177777b, 177777b, 177777b, 160007b,
160007b, 160007b, 160007b, 160007b,
160007b, 160007b, 160007b, 160007b,
160007b, 177777b, 177777b, 177777b];
PGSConDefs error logging interface
warningsLogged: PUBLIC BOOLFALSE;
log: STREAMNIL;
seterrstream: PUBLIC PROC = { };
resetoutstream: PUBLIC PROC = { };
outeol: PUBLIC PROC [n: INTEGER] = { THROUGH[0..n) DO log.PutChar['\n] ENDLOOP };
outstring: PUBLIC PROC [string: ROPE] = { log.PutRope[string] };
version identification
sourceName: PUBLIC ROPENIL;
pgsVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, BasicTime.ToPupTime[bcdTime]];
sourceVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, 0];
objectVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, 0];
Command line parsing
[bcd: bcdName, format: formatName] ← sourceFile[interface: interfaceName]/switches
ExtensionIs: PROC [name, ext: ROPE] RETURNS [BOOL] = {
index: INT ~ Rope.Find[s1: name, s2: ext, case: FALSE];
RETURN[index>0 AND index=(name.Length[]-ext.Length[])];
};
CreateTime: PUBLIC PROC[s: IO.STREAM] RETURNS[INT] = {
created: BasicTime.GMT ~ FS.GetInfo[FS.OpenFileFromStream[s]].created;
RETURN[LOOPHOLE[BasicTime.ToPupTime[created]]];
};
GenerateVersion: PUBLIC PROC RETURNS [version: BcdDefs.VersionStamp] = {
RETURN [OSMiscOps.GenerateUniqueId[]];
};
WriteHerald: PROC[stream: IO.STREAM] = {
stream.PutF["Cedar 5.1 Table Compiler of %g\n", IO.time[bcdTime]];
};
BadSemantics: ERROR = CODE;
Main: Commander.CommandProc = TRUSTED {
PROC [cmd: Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL]
cmdStream: STREAM ~ IO.RIS[cmd.commandLine];
DoCommand: PROC[source: ROPE, args, results: CommandUtil.PairList, sw: ROPE] ~ {
input: {strings, binary} ← $binary;
compact: BOOLFALSE;
dStar: BOOLTRUE;
rootName: ROPENIL;
interfaceName: ROPENIL;
formatName: ROPENIL;
bcdName: ROPENIL;
GetCommand: PROC ~ {
sourceName ← CommandUtil.SetExtension[source, "mesa"];
IF ExtensionIs[sourceName, ".mesa"] THEN { input ← $strings; compact ← TRUE };
IF args#NIL THEN {
k: CARDINAL ← CommandUtil.ListLength[args]; name: ROPE;
IF (name ← CommandUtil.KeyValue["interface", args])#NIL THEN { k ← k - 1;
interfaceName ← CommandUtil.SetExtension[name, "bcd"] };
IF k # 0 THEN ERROR BadSemantics;
};
IF results#NIL THEN {
k: CARDINAL ← CommandUtil.ListLength[results]; name: ROPE;
IF (name ← CommandUtil.KeyValue["bcd", results])#NIL THEN { k ← k - 1;
interfaceName ← CommandUtil.SetExtension[name, "bcd"] };
IF (name ← CommandUtil.KeyValue["format", results])#NIL THEN { k ← k - 1;
formatName ← CommandUtil.SetExtension[name, "format"] };
IF k # 0 THEN ERROR BadSemantics;
};
IF sw#NIL THEN {
sense: BOOLTRUE;
FOR i: INT IN[0..sw.Length[]) DO
char: CHAR ← sw.Fetch[i];
IF char IN['A..'Z] THEN char ← char+('a-'A); -- convert to lower case
SELECT char FROM
'-, '~ => { sense ← ~sense; LOOP };
'a => dStar ← ~sense;
'c => compact ← sense;
'm => input ← $binary;
's => {input ← $strings; compact ← FALSE};
't => {input ← $strings; compact ← TRUE};
ENDCASE => ERROR BadSemantics;
sense ← TRUE;
ENDLOOP;
};
};
LogCommand: PROC = {
log.PutF["\n%g %g, exporting %g to %g",
IO.rope[IF input=$strings THEN "Compiling" ELSE "Processing"],
IO.rope[sourceName], IO.rope[rootName], IO.rope[interfaceName]];
IF bcdName=NIL THEN log.PutChar['\n]
ELSE log.PutF[", BCD to %g\n", IO.rope[bcdName]];
IF input=$strings THEN log.PutF["Record format on %g\n", IO.rope[formatName]];
};
GetCommand[];
rootName ← CommandUtil.GetRootName[sourceName];
IF interfaceName=NIL THEN interfaceName ← "SELF";
IF formatName=NIL THEN formatName ← rootName.Concat[".format"];
LogCommand[];
IF bcdName=NIL THEN bcdName ← rootName.Concat[".bcd"];
SELECT input FROM
$strings => {
nChars, nStrings: CARDINAL;
[nStrings, nChars] ← TableCommand.CompileStrings[inputFile: sourceName,
interfaceId: interfaceName, formatId: formatName, moduleId: bcdName,
compact: compact, altoCode: ~dStar];
log.PutF["Strings: %g, characters: %g\n", IO.int[nStrings], IO.int[nChars]];
};
$binary => {
TableCommand.MakeModule[inputFile: sourceName,
interfaceId: interfaceName, moduleId: bcdName,
altocode: ~dStar];
};
ENDCASE => ERROR;
log.PutChar['\n];
};
initialization
logFile: STREAMFS.StreamOpen["TableCompiler.log", $create];
logFile.PutF["TableCompiler.log -- %g\n\n", IO.time[BasicTime.Now[]]];
log ← IOClasses.CreateDribbleOutputStream[cmd.out, logFile];
WriteHerald[log];
main loop
DO
source, switches: ROPE; args, results: CommandUtil.PairList;
[source, args, results, switches] ← CommandUtil.Parse[s: cmdStream
! CommandUtil.Failed => { log.PutRope[" -- Unparsable command"]; LOOP }];
IF source=NIL THEN EXIT;
DoCommand[source, args, results, switches !
BadSemantics => { log.PutRope[" -- Illegal command"]; CONTINUE };
FS.Error => { log.PutRope[error.explanation]; CONTINUE };
];
ENDLOOP;
logFile.Close[]; log ← NIL;
};
Commander.Register[key: "TableCompiler", proc: Main, doc: "Table compiler."];
}.