<> <> <> DIRECTORY Atom USING [GetProp, RemProp], Buttons USING [ButtonProc, Create], CedarSnapshot USING [Register, RollbackProc], DCSFileTypes USING [tLeaderPage], Directory USING [Error, ignore, Lookup], File USING [Capability, GetAttributes, Type], InputFocus USING [EnableInput], 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 [Viewer], ViewerOps USING [CreateViewer], ViewersSnapshot USING [Checkpoint, MCheckpoint, MRollBack]; 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 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 <> 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"]; 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."]; <> END.