MebesDirectory.mesa
Permute input text into MebesDirectory file, and command file
Created by Alan Paeth, PARC, August 2, 1982
Last Edited by: McCreight, July 31, 1985 6:15:26 pm PDT
DIRECTORY
Atom, BasicTime, Buttons, Commander, CommandTool, FS, IO, IOClasses, List, Process, Rope, TapeToolInternal, TIPUser, ViewerClasses;
MebesDirectory: CEDAR PROGRAM
IMPORTS Atom, BasicTime, Commander, CommandTool, FS, IO, IOClasses, List, Process, Rope =
BEGIN
variables
RunID: Rope.ROPE;
log: IO.STREAM;
favoriteDirectory: Rope.ROPE ← "/Cherry/MPChip/";
directoryPrefix: Rope.ROPE;
procedures/code
Letter: PROCEDURE [c: CHARACTER] RETURNS [BOOLEAN] =
BEGIN RETURN[c IN ['A..'Z]]; END;
Digit: PROCEDURE [c: CHARACTER] RETURNS [BOOLEAN] =
BEGIN RETURN[c IN ['0..'9]]; END;
AlphaNum: PROCEDURE [c: CHARACTER] RETURNS [BOOLEAN] =
BEGIN RETURN[Digit[c] OR Letter[c]]; END;
IsRun: PROC [ rope: Rope.ROPE ] RETURNS [ BOOL ] =
{RETURN[(rope.Length = 3) AND Digit[rope.Fetch[0]] AND AlphaNum[rope.Fetch[1]]
AND Letter[rope.Fetch[2]]]};
IsLayer: PROC [ rope: Rope.ROPE ] RETURNS [ BOOL ] =
{RETURN[(rope.Length = 5) AND Digit[rope.Fetch[0]] AND Digit[rope.Fetch[1]]
AND (rope.Fetch[2] = '-) AND Letter[rope.Fetch[3]]
AND AlphaNum[rope.Fetch[4]]]};
IsDie: PROC [ rope: Rope.ROPE ] RETURNS [ BOOL ] =
{RETURN[(rope.Length = 1) AND Letter[rope.Fetch[0]]]};
Abort: PROCEDURE [name: Rope.ROPE] =
BEGIN
log.PutF["... %g", IO.rope[name]];
ERROR ABORTED;
END;
FileServerName: PROCEDURE [die, layer: Rope.ROPE] RETURNS [ Rope.ROPE ] =
BEGIN
RETURN[IO.PutFR["%gMPC%g%g%g.mebes", IO.rope[directoryPrefix], IO.rope[RunID], IO.rope[die], IO.rope[IF layer.Length = 0 THEN "" ELSE Rope.Cat["-", layer]]]];
END;
LocalName: PROCEDURE [die, layer: Rope.ROPE] RETURNS [ Rope.ROPE ] =
BEGIN
RETURN[IO.PutFR["MPC%g%g%g.mebes", IO.rope[RunID], IO.rope[die], IO.rope[IF layer.Length = 0 THEN "" ELSE Rope.Cat["-", layer]]]];
END;
TapeHeaderName: PROCEDURE [die, layer: Rope.ROPE] RETURNS [ Rope.ROPE ] =
BEGIN
RETURN[IO.PutFR["MPC%g%g%g.%g ", IO.rope[RunID], IO.rope[die], IO.rope[layer.Substr[len: 2]], IO.rope[layer.Substr[start: 3]]]]; -- hyphen in layer becomes period
END;
Compare: PROC [ from, to: IO.STREAM, closeFrom, closeTo: BOOLTRUE ] RETURNS [ different: BOOL ] =
BEGIN
DO
IF from.GetChar[ ! IO.EndOfStream => GOTO CheckToLength ] # to.GetChar[ ! IO.EndOfStream => GOTO FoundDifference ] THEN GOTO FoundDifference;
REPEAT
CheckToLength => different ← NOT to.EndOf[];
FoundDifference => different ← TRUE;
ENDLOOP;
IF closeTo THEN to.Close[];
IF closeFrom THEN from.Close[];
END;
CopyToServer: PROC [localName, serverName: Rope.ROPENIL, fromStream: IO.STREAMNIL] =
BEGIN
serverPresent: BOOLFALSE;
localPresent: BOOLFALSE;
serverCreated, localCreated: BasicTime.GMT;
IF serverName # NIL THEN
BEGIN
serverPresent ← TRUE;
serverCreated ← FS.FileInfo[serverName
! FS.Error =>
IF error.code = $unknownFile THEN {serverPresent ← FALSE; CONTINUE} ELSE REJECT
].created;
END;
IF localName # NIL THEN
BEGIN
localPresent ← TRUE;
localCreated ← FS.FileInfo[localName
! FS.Error =>
IF error.code = $unknownFile THEN {localPresent ← FALSE; CONTINUE} ELSE REJECT
].created;
END;
IF fromStream # NIL THEN
BEGIN
different: BOOLTRUE;
fromStream.SetIndex[0];
IF localPresent THEN
BEGIN
different ← Compare[to: FS.StreamOpen[localName], from: fromStream, closeFrom: FALSE];
fromStream.SetIndex[0];
END;
IF different THEN
BEGIN
log.PutF["... creating local file %g", IO.rope[localName]];
IOClasses.Copy[from: fromStream, to: FS.StreamOpen[localName, $create], closeFrom: FALSE];
localPresent ← TRUE;
localCreated ← FS.FileInfo[localName].created;
END;
END;
SELECT TRUE FROM
localPresent AND serverName # NIL AND (NOT serverPresent OR BasicTime.Period[from: serverCreated, to: localCreated]>0) =>
BEGIN
log.PutF["... copying local file to %g", IO.rope[serverName]];
[] ← FS.Copy[
from: localName,
to: serverName,
wantedCreatedTime: localCreated
! FS.Error =>
{log.PutF[" ... copy failed because %g", IO.rope[error.explanation]]; GOTO Abort}
];
END;
ENDCASE => NULL;
EXITS
Abort => ERROR ABORTED;
END;
DoMebesDirectory: PROC [cmd: Commander.Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL] -- Commander.CommandProc -- =
BEGIN
MPCTokenProc: PROC [char: CHAR] RETURNS [IO.CharClass] -- IO.BreakProc -- =
{RETURN[SELECT char FROM
IN [IO.NUL .. IO.SP], ',, ':, '; => sepr,
'[, '], '(, '), '{, '}, '", '+, '*, '/, '@, '← => break,
'- => other,
ENDCASE => other]};
mebesTapeHeaderFile, filesToTape: IO.STREAM;
tech: Rope.ROPE;
dice: LIST OF Rope.ROPENIL;
layers: LIST OF Rope.ROPENIL;
now: BasicTime.Unpacked = BasicTime.Unpack[BasicTime.Now[]];
r: REF ANY;
tapeTool: TapeToolInternal.TapeTool ← NIL;
args: CommandTool.ArgumentVector = CommandTool.Parse[cmd];
updateServer: BOOLFALSE;
makeTape: BOOLFALSE;
log ← cmd.out;
BEGIN
ENABLE ABORTED => GOTO Punt;
open typescript, look for a command line, herald
log.PutRope["\nMebesDirectory 6.0 --- July 31, 1985 ..."];
RunID ← NIL;
IF args.argc<2 THEN
BEGIN
log.PutRope[cmd.procData.doc];
RETURN;
END;
FOR i: NAT IN [1..args.argc) DO
SELECT TRUE FROM
args[i].Equal["-updateServer", FALSE] => updateServer ← TRUE;
args[i].Equal["-makeTape", FALSE] => makeTape ← TRUE;
RunID = NIL AND IsRun[args[i]] => RunID ← args[i];
IsDie[args[i]] => dice ← CONS[args[i], dice];
IsLayer[args[i]] => layers ← CONS[args[i], layers];
ENDCASE =>
{log.PutF["... illegal argument \"%g\"...aborted", IO.rope[args[i]]]; RETURN};
ENDLOOP;
IF RunID = NIL THEN {log.PutRope["... no run id (e.g. 49A) ... aborted"]; RETURN};
directoryPrefix ← Rope.Cat[favoriteDirectory, RunID, "/"];
IF dice = NIL THEN
BEGIN
otherInput: IO.STREAM = FS.StreamOpen[IO.PutFR["%gDice.cm", IO.rope[directoryPrefix]]];
DO
t: Rope.ROPE = otherInput.GetTokenRope[MPCTokenProc ! IO.EndOfStream => EXIT].token;
IF NOT IsDie[t] THEN Abort[IO.PutFR["\"%g\" is improper die code, should be single capital letter", IO.rope[t]]];
dice ← CONS[t, dice];
ENDLOOP;
otherInput.Close[];
END;
TRUSTED {dice ← LOOPHOLE[List.Reverse[LOOPHOLE[dice]]]};
IF layers = NIL THEN
BEGIN
otherInput: IO.STREAMFS.StreamOpen[IO.PutFR["%gTech.cm", IO.rope[directoryPrefix]]];
tech ← otherInput.GetTokenRope[MPCTokenProc].token;
otherInput.Close[];
otherInput ← FS.StreamOpen[IO.PutFR["%gTechnology/%g-TapeLayers.cm", IO.rope[favoriteDirectory], IO.rope[tech]]];
DO
t: Rope.ROPE = otherInput.GetTokenRope[MPCTokenProc ! IO.EndOfStream => EXIT].token;
IF NOT IsLayer[t] THEN
Abort[IO.PutFR["\"%g\" is improper Mebes layer code, should be of form DD-AA", IO.rope[t]]];
layers ← CONS[t, layers];
ENDLOOP;
otherInput.Close[];
END;
TRUSTED {layers ← LOOPHOLE[List.Reverse[LOOPHOLE[layers]]]};
Create the Mebes tape header file ...
mebesTapeHeaderFile ← IO.ROS[];
mebesTapeHeaderFile.PutRope["\000\002\000"]; -- 2 is Cedar version, was 1 before
TRUSTED
{nFiles: [0..99] ← List.Length[LOOPHOLE[dice]]*List.Length[LOOPHOLE[layers]];
mebesTapeHeaderFile.PutChar[LOOPHOLE[nFiles]]
};
FOR i: LIST OF Rope.ROPE ← dice, i.rest WHILE i#NIL DO
FOR j: LIST OF Rope.ROPE ← layers, j.rest WHILE j#NIL DO
mebesTapeHeaderFile.PutRope[TapeHeaderName[i.first, j.first]];
ENDLOOP;
ENDLOOP;
mebesTapeHeaderFile.PutF["%02d%02d%02d\011",
IO.int[LOOPHOLE[now.month, CARDINAL] + 1],
IO.int[now.day],
IO.int[now.year MOD 100]];
pad 2048-byte block with 0's
FOR Bytecount: INT IN [mebesTapeHeaderFile.GetIndex..2048) DO
TRUSTED {mebesTapeHeaderFile.PutChar[LOOPHOLE[0, CHAR]]};
ENDLOOP;
CopyToServer[localName: IO.PutFR["MPC%g.mebes", IO.rope[RunID]], fromStream: IO.RIS[IO.RopeFromROS[mebesTapeHeaderFile]]];
Make a list of files to be transferred to the tape
filesToTape ← IO.ROS[];
filesToTape.PutRope[FileServerName["", ""]]; -- of the header file
FOR i: LIST OF Rope.ROPE ← dice, i.rest WHILE i#NIL DO
FOR j: LIST OF Rope.ROPE ← layers, j.rest WHILE j#NIL DO
filesToTape.PutF[" %g", IO.rope[FileServerName[i.first, j.first]]];
ENDLOOP;
ENDLOOP;
CopyToServer[localName: IO.PutFR["MPC%g.cedarTape", IO.rope[RunID]], fromStream: IO.RIS[IO.RopeFromROS[filesToTape]]];
Copy relevant local files to the server...
IF updateServer THEN
BEGIN
CopyToServer[
localName: IO.PutFR["MPC%g.cedarTape", IO.rope[RunID]],
serverName: IO.PutFR["%g/MPC%g.cedarTape", IO.rope[directoryPrefix], IO.rope[RunID]]];
CopyToServer[
localName: IO.PutFR["MPC%g.mebes", IO.rope[RunID]],
serverName: FileServerName["", ""]];
FOR i: LIST OF Rope.ROPE ← dice, i.rest WHILE i#NIL DO
FOR j: LIST OF Rope.ROPE ← layers, j.rest WHILE j#NIL DO
CopyToServer[localName: LocalName[i.first, j.first], serverName: FileServerName[i.first, j.first]];
ENDLOOP;
ENDLOOP;
END;
Copy files from the server to the tape...
IF makeTape AND (r ← Atom.GetProp[$TapeTool, $state]) # NIL AND (tapeTool ← NARROW[r]).open THEN
BEGIN
SetRope: PROC [ textViewer: ViewerClasses.Viewer, text: Rope.ROPE ] =
BEGIN
textViewer.class.set[textViewer, text, TRUE];
Process.Pause[Process.MsecToTicks[500]];
END;
PushButton: PROC [button: Buttons.Button] =
BEGIN
button.class.notify[button, LIST[ NEW[TIPUser.TIPScreenCoordsRec ← [mouseX: 1, mouseY: 1, color: button.column = color]], $Mark, $Hit ]];
END;
fileNames: IO.STREAM = IO.ROS[];
log.PutRope[".... generating tape"];
SetRope[tapeTool.blockingViewer, "2048"];
PushButton[tapeTool.RewindButton];
IOClasses.Copy[from: FS.StreamOpen[IO.PutFR["%gMPC%g.cedarTape", IO.rope[directoryPrefix], IO.rope[RunID]]],
to: fileNames, closeTo: FALSE];
SetRope[tapeTool.fileNameViewer, IO.RopeFromROS[fileNames]];
PushButton[tapeTool.WriteButton];
Process.Pause[Process.SecondsToTicks[1]];
WHILE tapeTool.active DO Process.Pause[Process.SecondsToTicks[1]] ENDLOOP;
log.PutRope[".... done (you can unload tape now)"];
END
ELSE log.PutRope[".... tape not generated... done"];
EXITS Punt => log.PutF[" ... aborted"];
END;
END;
Commander.Register["MebesDirectory", DoMebesDirectory, "\n.. makes a list of Mebes files, creates a Mebes tape label file, can write Mebes files to a file server, and can (with a cooperating TapeTool) write a Mebes tape. The format is\n\nMebesDirectory [-UpdateServer] [-MakeTape] [Die*] [Layer*] RunID\n\n where the items in [] are optional, and [x*] means any number of x's separated by spaces. Die takes the form of a single capital letter, Layer takes the form DD-AA (e.g., 20-PO), and RunId takes a form like 49A or 8BB. If any Die or Layer appears explicitly, the list in the command line overrides the MPC defaults.\n"];
END.-- of MebesDirectory