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:
BOOL ←
FALSE]
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 PROC ← NARROW[Atom.GetProp[$EndOps, $Registry]];
FOR l:
LIST
OF
REF
PROC ←
NARROW[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.