End.mesa; written by S. McGregor
edited by McGregor, July 13, 1983 3:53 pm
edited by Maxwell, January 31, 1983 12:19 pm
Last Edited by: Pausch, August 26, 1983 12:17 pm
DIRECTORY
Atom USING [GetProp, RemProp],
Buttons USING [Create],
CedarSnapshot USING [Register, RollbackProc],
DCSFileTypes USING [tLeaderPage],
Directory USING [Error, ignore, Lookup],
File USING [Capability, GetAttributes, Type],
InputFocus USING [EnableInput],
Menus USING [Entry, EntryNotifyRecord],
MessageWindow USING [Append],
Process USING [Detach],
Rope USING [Cat, Fetch, Flatten, ROPE, Size, Substr],
Runtime USING [RunConfig --,SelfDestruct--],
TerminalMultiplex USING [PermitSwaps],
UserProfile USING [Boolean, Line],
ViewerClasses USING [NotifyProc, Viewer],
ViewerOps USING [CreateViewer],
ViewersSnapshot USING [Checkpoint, Notifier];
End: CEDAR PROGRAM
IMPORTS Atom, Buttons, CedarSnapshot, Directory, File, InputFocus, MessageWindow, Process, Rope, Runtime, TerminalMultiplex, UserProfile, ViewerOps, ViewersSnapshot
SHARES InputFocus =
BEGIN
makeCheck: BOOL ← UserProfile.Boolean["AutoCheckpoint", FALSE];
checkButton: BOOL ← UserProfile.Boolean["ClientCheckpoint", TRUE];
CheckForFile:
PROC [file: Rope.
ROPE]
RETURNS [found:
BOOL] =
TRUSTED
BEGIN
fName: LONG STRING ← LOOPHOLE[Rope.Flatten[file]];
found ← TRUE;
[] ← Directory.Lookup[fileName: fName, permissions: Directory.ignore
! Directory.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] ! ANY => CONTINUE];
ENDLOOP;
END;
PreRun: PROC = { Run["PreRun"] } ;
PostRun: CedarSnapshot.RollbackProc = TRUSTED { Process.Detach[ FORK Run["PostRun"]] } ;
Run:
PROC [key: Rope.
ROPE] =
BEGIN
TryToRun:
PROC[file: Rope.
ROPE]
RETURNS[
BOOL] =
TRUSTED {
name: LONG STRING ← LOOPHOLE[Rope.Flatten[file]];
fcap: File.Capability ← Directory.Lookup[fileName: name
! Directory.Error => GOTO NotFound];
type: File.Type ← File.GetAttributes[fcap].type;
Runtime.RunConfig[file: fcap,
offset: (IF type=DCSFileTypes.tLeaderPage THEN 1 ELSE 0),
codeLinks: TRUE ! ANY => CONTINUE];
RETURN[TRUE];
EXITS NotFound => RETURN[FALSE];
};
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 NOT TryToRun[file] THEN [] ← TryToRun[Rope.Cat[file,".bcd"]];
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 {
rollBackAction: Menus.EntryNotifyRecord ← [trigger: LIST[all], notifyData: LIST [$Rollback], guardResponse: "Restore state to previous checkpoint"];
rollBackEntry: Menus.Entry ~ [name: "RollBack", guarded: TRUE, actions: LIST[rollBackAction]];
[] ← Buttons.Create[entry: rollBackEntry, proc: ViewersSnapshot.Notifier];
};
IF checkButton
THEN {
checkPointAction: Menus.EntryNotifyRecord ← [trigger: LIST[all], notifyData: LIST [$CheckPoint], guardResponse: "Make a new checkpoint"];
checkPointEntry: Menus.Entry ~ [name: "Checkpoint", guarded: TRUE, actions: LIST [checkPointAction]];
[] ← Buttons.Create[entry: checkPointEntry, proc: ViewersSnapshot.Notifier];
};
TRUSTED {CedarSnapshot.Register[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.