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
Last Edited by: Wyatt, October 14, 1983 7:45 pm
DIRECTORY
Buttons USING [Create],
CedarSnapshot USING [Register, RollbackProc],
DCSFileTypes USING [tLeaderPage],
Directory USING [Error, ignore, Lookup],
EndOps USING [ProcessRegistry],
File USING [Capability, GetAttributes, Type],
InputFocus USING [EnableInput],
Menus USING [Action, ActionRec, allTriggers, Entry, EntryRec],
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 Buttons, CedarSnapshot, Directory, EndOps, 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 STRINGLOOPHOLE[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: 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] ! 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 STRINGLOOPHOLE[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;
IF makeCheck OR checkButton THEN {
rollBackAction: Menus.Action = NEW[Menus.ActionRec ← [
triggers: Menus.allTriggers, input: LIST [$Rollback],
guardResponse: "Restore state to previous checkpoint"
]];
rollBackEntry: Menus.Entry = NEW[Menus.EntryRec ← [
name: "RollBack", guarded: TRUE, actions: LIST[rollBackAction]
]];
[] ← Buttons.Create[entry: rollBackEntry, proc: ViewersSnapshot.Notifier];
};
IF checkButton THEN {
checkPointAction: Menus.Action = NEW[Menus.ActionRec ← [
triggers: Menus.allTriggers, input: LIST [$CheckPoint],
guardResponse: "Make a new checkpoint"
]];
checkPointEntry: Menus.Entry = NEW[Menus.EntryRec ← [
name: "Checkpoint", guarded: TRUE, actions: LIST[checkPointAction]
]];
[] ← Buttons.Create[entry: checkPointEntry, proc: ViewersSnapshot.Notifier];
};
TRUSTED {CedarSnapshot.Register[r: PostRun]};
PreRun[];
Preload[];
EndOps.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.