End.mesa; written by S. McGregor
edited by McGregor, March 2, 1983 8:21 am
edited by Maxwell, January 31, 1983 12:19 pm
edited by Paul Rovner, June 16, 1983 9:07 am
edited by Doug Wyatt, December 8, 1983 5:14 pm
DIRECTORY
Atom USING [GetProp, RemProp],
Booting USING [RegisterProcs, RollbackProc],
FS USING [OpenFile, Open, FileInfo, Error],
InputFocus USING [EnableInput],
MessageWindow USING [Append],
Process USING [Detach],
Rope USING [Cat, Fetch, ROPE, Size, Substr, Find],
RuntimeError USING [UNCAUGHT],
Loader USING [Instantiate, Start],
UserProfile USING [Boolean, Line],
ViewerClasses USING [Viewer],
ViewerOps USING [CreateViewer];
End: CEDAR PROGRAM
IMPORTS Atom, Booting, FS, InputFocus, Loader, MessageWindow, Process, Rope, RuntimeError, UserProfile, ViewerOps
SHARES InputFocus =
BEGIN
makeCheck: BOOL ← UserProfile.Boolean["AutoCheckpoint", FALSE];
checkButton: BOOL ← UserProfile.Boolean["ClientCheckpoint", TRUE];
CheckForFile: PROC [file: Rope.ROPE] RETURNS [found: BOOL ← TRUE] = TRUSTED BEGIN
[] ← FS.FileInfo[name: file ! FS.Error => {found ← FALSE; CONTINUE}];
END;
GetToken: PUBLIC PROC [rope: Rope.ROPE, offset: INT ← 0, thruEnd: BOOLFALSE]
RETURNS [token: Rope.ROPE, newOffset: INT] = BEGIN
size: INT = Rope.Size[rope];
start: INT;
Sep: PROC [c: CHARACTER] RETURNS [BOOL] = INLINE BEGIN
RETURN[SELECT c FROM
' , ',, 11C, 15C, 0C => TRUE,
ENDCASE => FALSE];
END;
IF offset>=size THEN RETURN["", offset];
WHILE offset<size AND Sep[Rope.Fetch[rope, offset]] DO
offset ← offset+1;
ENDLOOP;
start ← offset;
DO IF offset>=size THEN EXIT;
IF Sep[Rope.Fetch[rope, offset]] THEN EXIT;
offset ← offset+1;
ENDLOOP;
RETURN[Rope.Substr[rope, start, IF thruEnd THEN size
ELSE offset-start], offset];
END;
Preload: PROC = BEGIN
files: Rope.ROPE ← UserProfile.Line["PreLoad"];
file: Rope.ROPE;
offset: LONG INTEGER ← 0;
DO
[file, offset] ← GetToken[files, offset];
IF Rope.Size[file]=0 THEN EXIT;
IF CheckForFile[file] THEN [] ← ViewerOps.CreateViewer[$Text, [name: file, file: file]];
ENDLOOP;
END;
PreRun: PROC = { Run["PreRun"] } ;
PostRun: Booting.RollbackProc = TRUSTED { Process.Detach[FORK Run["PostRun"]] };
Run: PROC [key: Rope.ROPE] = BEGIN
TryToRun: PROC[file: Rope.ROPE] = TRUSTED {
fcap: FS.OpenFile ← FS.Open[file ! FS.Error => GOTO NotFound];
Loader.Start[Loader.Instantiate[fcap ! RuntimeError.UNCAUGHT => CONTINUE].cm
! RuntimeError.UNCAUGHT => CONTINUE];
RETURN;
EXITS NotFound => NULL;
};
files: Rope.ROPE ← UserProfile.Line[key];
file: Rope.ROPE;
offset: LONG INTEGER ← 0;
DO
[file, offset] ← GetToken[files, offset];
IF Rope.Size[file]=0 THEN EXIT;
IF Rope.Find[file, "."] = -1 THEN file ← Rope.Cat[file,".bcd"];
TryToRun[file];
ENDLOOP;
END;
ProcessRegistry: PROC = BEGIN
see EndOps.mesa for adding something to the registry
registerList: LIST OF REF PROCNARROW[Atom.GetProp[$EndOps, $Registry]];
FOR l: LIST OF REF PROCNARROW[Atom.GetProp[$EndOps, $Registry]], l.rest UNTIL l=NIL DO
l.first^[! ANY => CONTINUE];
ENDLOOP;
Atom.RemProp[$EndOps, $Registry]; -- flush registry now that we're done with it
END;
IF makeCheck OR checkButton THEN
[] ← Buttons.Create[info: [name: "RollBack"], proc: ViewersSnapshot.MRollBack, fork: TRUE,
guarded: TRUE, documentation: "Restore state to previous checkpoint"];
IF checkButton THEN
[] ← Buttons.Create[info: [name: "Checkpoint"], proc: ViewersSnapshot.MCheckpoint, fork: TRUE,
guarded: TRUE, documentation: "Make a new checkpoint"];
Booting.RegisterProcs[r: PostRun];
PreRun[];
Preload[];
ProcessRegistry[];
TRUSTED {TerminalMultiplex.PermitSwaps[]};  permit use of the second logical terminal
InputFocus.EnableInput[]; -- start up the input machinery
IF makeCheck THEN [] ← ViewersSnapshot.Checkpoint[] ELSE
MessageWindow.Append["Ready."];
Runtime.SelfDestruct[];
END.