DIRECTORY CD, CDEnvironment, CDIO, CDOps, CDDrawQueue, CDPanel, CDProperties, CDSequencer, CDValue, CDVPrivate, CDViewer, CedarProcess, Commander, CommandTool, FileNames, InterminalBackdoor USING [terminal], IO, Process, Rope, RuntimeError USING [UNCAUGHT], Terminal, TerminalDefs, TerminalIO, TokenIO, UserProfile, ViewerClasses, ViewerOps; CDIOCommands: CEDAR MONITOR IMPORTS CD, CDDrawQueue, CDEnvironment, CDIO, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, CDVPrivate, CedarProcess, CommandTool, FileNames, InterminalBackdoor, IO, Process, Rope, RuntimeError, Terminal, TerminalIO, UserProfile, ViewerOps SHARES CDSequencer = BEGIN OpenCommand: Commander.CommandProc = { v: ViewerClasses.Viewer; name: IO.ROPE _ CommandTool.ArgN[cmd, 1]; design: CD.Design _ GetDesign[name, cmd]; IF design=NIL THEN {cmd.out.PutRope[openDoc]; RETURN[$Failure]}; v _ CDViewer.ViewersOf[design].first; IF v.iconic THEN ViewerOps.OpenIcon[v]}; GetDesign: PUBLIC PROC [name: IO.ROPE, cmd: Commander.Handle _ NIL] RETURNS [design: CD.Design] = { design _ CDViewer.FindDesign[name]; IF design#NIL OR name.Length[]=0 THEN RETURN[design]; [] _ CommandTool.DoCommandRope[IO.PutFR["CDRead %g",IO.rope[name]], NIL, cmd]; design _ CDViewer.FindDesign[name]}; ReadCommand: Commander.CommandProc = { ENABLE TerminalIO.UserAbort => GOTO UserAbrt; LoadAllImports: PROC [design: CD.Design] = { p: CDSequencer.CommandProc _ CDSequencer.FetchCommand[$UnqueuedLoadAllImps].proc; IF p#NIL THEN CDSequencer.ExecuteProc[p, design, dontQueue]; }; design: CD.Design; tech: CD.Technology_NIL; name: Rope.ROPE _ NIL; char: CHAR; loadImports: BOOL _ UserProfile.Boolean["ChipnDale.AutoLoadImports", TRUE]; panelOn, panelOff, saveOn, saveOff, alreadyTried, readonly: BOOL _ FALSE; result _ $Failure; FOR list: LIST OF Rope.ROPE _ CommandTool.ParseToList[cmd, FALSE, ' ].list, list.rest WHILE list#NIL DO IF Rope.IsEmpty[list.first] THEN {msg _ "empty parameter"; RETURN}; char _ Rope.Fetch[list.first, 0]; SELECT TRUE FROM char='- OR char='+ => {--a switch SELECT TRUE FROM Rope.Equal[list.first, "-X", FALSE] => loadImports _ FALSE; Rope.Equal[list.first, "+X", FALSE] => loadImports _ TRUE; Rope.Equal[list.first, "-P", FALSE] => panelOff _ TRUE; Rope.Equal[list.first, "+P", FALSE] => panelOn _ TRUE; Rope.Equal[list.first, "-S", FALSE] => saveOff _ TRUE; Rope.Equal[list.first, "+S", FALSE] => saveOn _ TRUE; Rope.Equal[list.first, "-R", FALSE] => readonly _ FALSE; Rope.Equal[list.first, "+R", FALSE] => readonly _ TRUE; ENDCASE => {msg _ Rope.Cat["unknown switch ", list.first]; RETURN}; }; char='^ => {--a technology n: Rope.ROPE _ Rope.Substr[list.first, 1, Rope.Length[list.first]]; IF list.rest#NIL OR name#NIL THEN {msg _ "unknown option(s)"; RETURN}; tech _ CDEnvironment.LoadTechnology[NIL, n]; IF tech=NIL THEN {msg _ "technology not loaded"; RETURN}; design _ CDOps.CreateDesign[tech]; alreadyTried _ TRUE }; ENDCASE => {--maybe a file name IF name#NIL THEN {msg _ "too many names or options"; RETURN}; name _ list.first; }; ENDLOOP; IF ~alreadyTried THEN design _ CDIO.ReadDesign[name]; IF design=NIL THEN msg _ "read not done" ELSE { panel: BOOL _ UserProfile.Boolean["ChipNDale.OpenPanel", TRUE]; IF loadImports THEN LoadAllImports[design]; IF panelOff THEN panel _ FALSE; IF panelOn THEN panel _ TRUE; IF readonly THEN { ref: REF; ref _ CDValue.Fetch[design, $CDxFromFile, design]; CDValue.Store[design, $CDxCachedFile, ref]; ref _ CDValue.Fetch[design, $CDxFileCreated, design]; CDValue.Store[design, $CDxCachedCreated, ref]; CDOps.SetMutability[design, readonly]; } ELSE CDOps.SetMutability[design, editable]; [] _ CDViewer.CreateViewer[design, panel]; result _ design; msg _ Rope.Concat["design ", CD.DesignName[design]]; IF saveOff THEN CDProperties.PutDesignProp[design, $CDxDontBackgroundSave, $TRUE]; IF saveOn THEN CDProperties.PutDesignProp[design, $CDxDontBackgroundSave, NIL]; IF ~readonly AND CDProperties.GetDesignProp[design, $CDxDontBackgroundSave]=$TRUE THEN msg _ Rope.Concat[msg, " [background saving for this design is disabled]"] }; TerminalIO.PutRopes[msg, "\n"]; EXITS UserAbrt => {result _ $Failure; msg _ "aborted"}; }; CacheWriteDesignComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["write cache design to a file; NOT the truth\n"]; IF CDIO.WriteDesign[design: comm.design, truth: FALSE] THEN {CDSequencer.SetEdited[comm.design, FALSE]; TerminalIO.PutRope["done\n"]} ELSE TerminalIO.PutRope["not done\n"]; }; TruthWriteDesignComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["write design to a file\n"]; IF CDIO.WriteDesign[design: comm.design] THEN {CDSequencer.SetEdited[comm.design, FALSE]; TerminalIO.PutRope["done\n"]} ELSE TerminalIO.PutRope["not done\n"]; }; savedKey: REF Rope.ROPE _ NEW[Rope.ROPE _ "saved as"]; --unique, not saved on files TruthSaveDesignComm: PROC [comm: CDSequencer.Command] = { from: REF _ CDValue.Fetch[comm.design, savedKey, design]; wDir: Rope.ROPE _ CDEnvironment.GetWorkingDirectory[comm.design]; name: Rope.ROPE _ CDEnvironment.MakeName[CDIO.MakeShortName[comm.design], "dale", wDir]; IF Rope.Match[pattern: "///temp/ChipNDale/*", object: wDir, case: FALSE] THEN { TerminalIO.PutRope["design uses special working directory; "]; TerminalIO.PutRope["for your own protection: use general output instead of save\n"]; TruthWriteDesignComm[comm]; RETURN; }; IF from=NIL THEN from _ CDValue.Fetch[comm.design, $CDxFromFile, design]; TerminalIO.PutRope["save design\n"]; WITH from SELECT FROM r: Rope.ROPE => { nameFromFile: Rope.ROPE _ CDEnvironment.MakeName[FileNames.GetShortName[r], "dale", wDir]; IF ~Rope.Equal[name, nameFromFile, FALSE] THEN SELECT TerminalIO.RequestSelection[ header: "design name and file name differ !", choice: LIST[ Rope.Concat["use ", name], Rope.Concat["use ", nameFromFile], "get name interactively"] ] FROM 1 => { IF ~Rope.IsEmpty[name] THEN CDValue.Store[comm.design, savedKey, name] }; 2 => name _ nameFromFile; 3 => name _ NIL; ENDCASE => {TerminalIO.PutRope["not done\n"]; RETURN}; }; ENDCASE => NULL; IF CDIO.WriteDesign[design: comm.design, to: name] THEN {CDSequencer.SetEdited[comm.design, FALSE]; TerminalIO.PutRope["done\n"]} ELSE TerminalIO.PutRope["not done\n"]; }; EmergencySaveDesign: ENTRY PROC [design: CD.Design, key: REF] = { ENABLE { RuntimeError.UNCAUGHT => GOTO oops; UNWIND => NULL; }; IF ~design.edited OR CDProperties.GetProp[design, $cdioPrivate]=key THEN IF ~design.changedSinceSaving THEN RETURN; CDProperties.PutProp[design, $cdioPrivate, key]; Process.PauseMsec[100]; -- give detached Flush processes a chance IF CDIO.WriteDesign[design: design, emergency: TRUE] THEN TerminalIO.PutF["%lWARNING: Saved without synchronisation;%l (an other process might have clobbered the IO). \nCopy the file and CHECK it.\n", [rope["b"]], [rope[" "]]]; EXITS oops => NULL; }; EmergencySaveProcess: PROC = { unique: REF; SaveAllViewers: PROC [] = { SaveOneViewer: ViewerOps.EnumProc = { design: CD.Design = CDViewer.DesignOf[v].design; -- is not monitored IF design=NIL THEN RETURN; IF v.newVersion OR design.changedSinceSaving THEN TRUSTED { Process.Detach[FORK EmergencySaveDesign[design, unique]] } }; unique _ NEW[REF]; ViewerOps.EnumerateViewers[SaveOneViewer]; ViewerOps.EnumerateViewers[SaveOneViewer]; --a second try agains disk errors... }; virtual: Terminal.Virtual _ InterminalBackdoor.terminal; CedarProcess.SetPriority[CedarProcess.Priority[foreground]]; DO -- for ever Process.PauseMsec[1000]; IF Terminal.GetKeys[virtual][TerminalDefs.ESC]=down AND Terminal.GetKeys[virtual][TerminalDefs.LF]=down THEN StopAllDrawing[]; IF Terminal.GetKeys[virtual][TerminalDefs.Spare3]=down AND Terminal.GetKeys[virtual][LeftShift]=down THEN { StopAllDrawing[]; IF Terminal.GetKeys[virtual][RightShift]=down THEN { SaveAllViewers[]; WHILE Terminal.GetKeys[virtual][TerminalDefs.Spare3]=down OR Terminal.GetKeys[virtual][RightShift]=down OR Terminal.GetKeys[virtual][LeftShift]=down DO Process.PauseMsec[100]; ENDLOOP; } } ENDLOOP; }; StopAllDrawing: PROC [] = { ENABLE RuntimeError.UNCAUGHT => GOTO exit; FOR l: LIST OF CDVPrivate.VRef _ CDVPrivate.allVRefs, l.rest WHILE l#NIL DO IF l.first.ct#NIL THEN CDDrawQueue.Flush[l.first.ct] ENDLOOP; EXITS exit => NULL; }; StopDrawingCommand: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["Stop drawing (better use )\n"]; StopAllDrawing[]; }; doc: Rope.ROPE = "Read a ChipNDale design; options: \n (|name|^technology) interactive / file name / new design\n (+X|-X) load imports\n (+S|-S) background saving\n (+P|-P) control panel\n (+R|-R) read only design"; openDoc: Rope.ROPE = "Open a ChipNDale design; (read if not present)"; CDEnvironment.RegisterCommander[key: "CDRead", proc: ReadCommand, doc: doc]; CDEnvironment.RegisterCommander[key: "CDOpen", proc: OpenCommand, doc: openDoc]; CDSequencer.ImplementCommand[$OutputDesign, TruthWriteDesignComm,, doQueue]; CDSequencer.ImplementCommand[$CachedOutputDesign, CacheWriteDesignComm,, doQueue]; CDSequencer.ImplementCommand[$SaveDesign, TruthSaveDesignComm,, doQueue]; CDSequencer.ImplementCommand[$StopAllDrawing, StopDrawingCommand,, dontQueue]; CDPanel.Button[tech: NIL, button: [text: "save"], command: $SaveDesign, topLine: TRUE]; TRUSTED {Process.Detach[FORK EmergencySaveProcess[]]}; END. ŠCDIOCommands.mesa Copyright (C) 1984, 1986, 1987 Xerox Corporation. All rights reserved. Created by: Christian Jacobi, February 8, 1984 9:41 am Last Edited by: Christian Jacobi, August 19, 1987 5:34:04 pm PDT Don Curry January 26, 1989 2:48:22 pm PST --we dont want to import fancy imports; io is logically deeper in hierachy --parse input --read design --fix up design --checks the magic keyboard commands which still work --when the tip table processes are wedged. --This non standard enumeration is chosen so it won't wedge when the standard one would --I checked the implementation: ViewerOps.EnumerateViewers was really not monitored Ê ƒ– "cedar" style˜code™K™GK™6K™@K™)K˜—šÏk ˜ Kšœ˜K˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ K˜ Kšœ ˜ Kšœœ ˜$Kšœ˜Kšœ˜Kšœ˜Kšœ œœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ —K˜šÏn œœ˜KšœœœÓ˜ÿKšœ˜—Kš˜K˜K˜šÐbn œ˜&Jšœ˜Jšœœœ˜+Jšœœ˜)Jšœœœœ ˜@Jšœ%˜%Jšœ œ˜(—š ž œœœœœ˜CJšœ œ ˜Jšœ#˜#Jš œœœœœ ˜5Jšœœœ œ˜NJšœ$˜$J˜—K˜šŸ œ˜&Kšœœ ˜-šžœœ œ ˜,KšÏcJ™JJšœQ˜QKšœœœ/˜