<> <> <> <> DIRECTORY Ascii, CD, CDCells, CDCommandOps, CDDirectory, CDMarks, CDOps, CDSequencer, CDSimpleOps, CDX, TerminalIO, Rope; CDCellCommands: CEDAR PROGRAM IMPORTS Ascii, CDX, CDOps, CDCells, CDCommandOps, CDDirectory, CDMarks, CDSequencer, CDSimpleOps, Rope, TerminalIO = BEGIN orientForTest: CD.Orientation _ 0; obCSystemForTest: CDX.CoordSystem _ interrestCoords; DrawCellComm: PROC [comm: CDSequencer.Command] = BEGIN name: Rope.ROPE; cellOb: CD.ObPtr; found: BOOLEAN; TerminalIO.WriteRope["Include cell; "]; DO name _ TerminalIO.RequestRope["type name\n"! TerminalIO.UserAbort => {GOTO aborted}]; [found, cellOb] _ CDDirectory.Fetch[comm.design, name]; IF found THEN { app: CD.ApplicationPtr = CDX.IncludeOb[design: comm.design, ob: cellOb, position: comm.pos, obCSystem: obCSystemForTest, orientation: orientForTest ].newApp; CDCommandOps.RedrawApplication[comm.design, app, FALSE]; TerminalIO.WriteRope[name]; TerminalIO.WriteRope[" inserted\n"]; RETURN }; TerminalIO.WriteRope[name]; TerminalIO.WriteRope[" not found\n"]; IF NOT TerminalIO.UserSaysYes[label: "another try ?" ! TerminalIO.UserAbort => {GOTO aborted}] THEN RETURN; ENDLOOP EXITS aborted => NULL; END; DeleteCell: PROC [comm: CDSequencer.Command] = BEGIN EachEntryCheck: CDDirectory.EachEntryAction -- PROC [name: Rope.ROPE, ob: CD.ObPtr] RETURNS [quit: BOOL_FALSE]-- = BEGIN IF ob.marked#mark AND ob#toDeleteOb THEN { -- an occurence of cellOb should not be marked CDMarks.MarkUnMarkedInclusiveChildren[comm.design, ob, mark]; IF toDeleteOb.marked=mark THEN { usedBy _ name; quit _ TRUE } }; END; <<-- DeleteCell>> name: Rope.ROPE_NIL; usedBy: Rope.ROPE_NIL; toDeleteOb: CD.ObPtr; found: BOOLEAN; mark: CDMarks.MarkRange; TerminalIO.WriteRope["delete cell; "]; name _ TerminalIO.RequestRope["type name\n"! TerminalIO.UserAbort => {GOTO aborted}]; [found, toDeleteOb] _ CDDirectory.Fetch[comm.design, name]; IF ~found THEN { TerminalIO.WriteRope[name]; TerminalIO.WriteRope[" not found\n"]; RETURN }; <<-- mark all entries (excluding toDeleteOb), and all their children>> <<-- test then if toDeleteOb is marked; if it is, it is a child and used >> mark _ CDMarks.GetNewMark[comm.design]; found _ CDDirectory.Enumerate[comm.design, EachEntryCheck].quit; CDMarks.ReleaseMark[comm.design, mark]; IF found THEN { TerminalIO.WriteRope[name]; TerminalIO.WriteRope[" is used by "]; TerminalIO.WriteRope[usedBy]; TerminalIO.WriteRope[" (and maybe others); not deleted\n"]; RETURN }; CDSimpleOps.FlushDeletedCache[comm.design]; IF CDDirectory.Remove[comm.design, name, toDeleteOb] THEN { TerminalIO.WriteRope[" deleted\n"]; } ELSE { TerminalIO.WriteRope[" not deleted; error in delete routine\n"]; } EXITS aborted => NULL; END; DisplayCellNames: PROC [comm: CDSequencer.Command] = BEGIN EachEntryDisplay: CDDirectory.EachEntryAction --[name: Rope.ROPE, ob: CD.ObPtr] RETURNS [quit: BOOL] -- = BEGIN quit _ FALSE; count _ count+1; IF comm.a=$RestricedDisplayCellNames THEN { IF Rope.Length[name]<=0 THEN RETURN ELSE { ch: CHAR = Rope.Fetch[name]; IF ~Ascii.Letter[ch] AND ~Ascii.Digit[ch] THEN RETURN } }; displayed _ displayed+1; WITH ob.specificRef SELECT FROM cp: CD.CellPtr => { TerminalIO.WriteRope[" "]; TerminalIO.WriteRope[cp.name]; }; ENDCASE => { TerminalIO.WriteRope[" ("]; TerminalIO.WriteRope[name]; TerminalIO.WriteRope[") "]; TerminalIO.WriteRope[CDOps.Info[ob]]; }; TerminalIO.WriteLn[]; END; count: INT _ 0; displayed: INT _ 0; TerminalIO.WriteRope["Display object names\n"]; IF CDDirectory.Enumerate[comm.design, EachEntryDisplay] THEN TerminalIO.WriteRope["stopped\n"]; TerminalIO.WriteInt[count]; TerminalIO.WriteRope[" objects counted "]; IF count#displayed THEN { TerminalIO.WriteInt[displayed]; TerminalIO.WriteRope[" displayed"]; }; TerminalIO.WriteLn[] END; CreateCellAndName: PROC [comm: CDSequencer.Command] = BEGIN done: BOOL; TerminalIO.WriteRope["Create cell "]; [done: done] _ CDCells.CreateCellSelected[comm.design]; IF ~done THEN TerminalIO.WriteRope[" not done\n"]; END; CreateCellDefaultName: PROC [comm: CDSequencer.Command] = BEGIN done: BOOL; TerminalIO.WriteRope["Create cell without name\n"]; [done: done] _ CDCells.CreateCellSelected[comm.design, "-no name-"]; IF ~done THEN TerminalIO.WriteRope[" not done\n"]; END; PushIntoCellS: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Push into cell "]; IF CDCells.PushInCellSelected[comm.design] THEN { TerminalIO.WriteRope[comm.design.actual.first.specific.name]; TerminalIO.WriteLn[] } ELSE TerminalIO.WriteRope["not done\n"]; END; PopFromCellMenu: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["pop\n"]; IF ~CDCells.PopFromCell[comm.design, interactive] THEN TerminalIO.WriteRope[" not done\n"]; END; PopFromCellFlush: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["pop and flush\n"]; IF ~CDCells.PopFromCell[comm.design, flush] THEN TerminalIO.WriteRope[" not done\n"]; END; PopFromCellReplace: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["pop and replace\n"]; IF ~CDCells.PopFromCell[comm.design, replace] THEN TerminalIO.WriteRope[" not done\n"]; END; PopFromCellNew: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["pop and new\n"]; IF ~CDCells.PopFromCell[comm.design, newcell] THEN TerminalIO.WriteRope[" not done\n"]; END; CompletelyDestroy: PROC [design: CD.Design, list: LIST OF CD.ObPtr] = BEGIN tem: LIST OF CD.ObPtr; IF list#NIL THEN { CDSimpleOps.FlushDeletedCache[design]; WHILE list#NIL DO IF list.first.p.inDirectory THEN list.first^ _ CD.ObjectDefinition[p: NIL]; list.first _ NIL; tem _ list; list _ list.rest; tem.rest _ NIL; ENDLOOP } END; CleanUpDirectory: PROC [comm: CDSequencer.Command] = BEGIN Doit: PROC [m: CDMarks.MarkRange, comm: CDSequencer.Command] = BEGIN RemoveIfNotMarked: PROC [name: Rope.ROPE, ob: CD.ObPtr] RETURNS [quit: BOOL_FALSE] = BEGIN IF ob.marked#m THEN { d: BOOL _ CDDirectory.Remove[design: comm.design, name: name, expectObject: ob]; IF d THEN removed _ CONS[ob, removed]; } END; ListNotMarked: PROC [name: Rope.ROPE, ob: CD.ObPtr] RETURNS [quit: BOOL_FALSE] = BEGIN IF ob.marked#m THEN { TerminalIO.WriteRope[" - "]; TerminalIO.WriteRope[name]; TerminalIO.WriteLn[]; cnt _ cnt + 1 } END; AlsoMarkNamedObjects: PROC[name: Rope.ROPE, ob: CD.ObPtr]RETURNS[quit: BOOL_FALSE] = BEGIN IF ob.marked#m THEN { ch: CHAR = IF Rope.Length[name]<=0 THEN 'A ELSE Rope.Fetch[name]; IF Ascii.Letter[ch] OR Ascii.Digit[ch] THEN { CDMarks.MarkUnMarkedInclusiveChildren[comm.design, ob, m]; } }; END; removed: LIST OF CD.ObPtr _ NIL; cnt: NAT _ 0; FOR l: LIST OF CD.PushRec _ comm.design.actual, l.rest WHILE l#NIL DO IF l.first.mightReplace#NIL THEN { CDMarks.MarkUnMarkedInclusiveChildren[comm.design, l.first.mightReplace.ob, m]; }; CDMarks.MarkUnMarkedInclusiveChildren[comm.design, l.first.dummyCell.ob, m]; ENDLOOP; IF comm.a=$DeleteUnUsedAutoObs THEN { TerminalIO.WriteRope[" restricted according name\n"]; [] _ CDDirectory.Enumerate[design: comm.design, action: AlsoMarkNamedObjects]; }; TerminalIO.WriteRope[" List of objects not used:\n"]; [] _ CDDirectory.Enumerate[design: comm.design, action: ListNotMarked]; TerminalIO.WriteRope[" "]; TerminalIO.WriteInt[cnt]; TerminalIO.WriteRope[" objects not used in design\n"]; IF cnt>0 THEN { IF TerminalIO.UserSaysYes[ label: "delete them?", text: " you may delete all the listed objects\n (deletion must be performed atomic)\n" ] THEN { TerminalIO.WriteRope[" **** start atomic\n"]; TerminalIO.WriteRope[" if for any reason it crashes while deleting,\n"]; TerminalIO.WriteRope[" the deleting process must be repeated before\n"]; TerminalIO.WriteRope[" the design is otherwise used\n"]; [] _ CDDirectory.Enumerate[design: comm.design, action: RemoveIfNotMarked]; TerminalIO.WriteRope[" **** end atomic\n finished successfully\n"]; CompletelyDestroy[comm.design, removed]; removed _ NIL; } ELSE TerminalIO.WriteRope[" not done\n"]; }; END; m: CDMarks.MarkRange _ 0; TerminalIO.WriteRope["Clean up directory\n"]; CDSimpleOps.FlushDeletedCache[comm.design]; m _ CDMarks.GetNewMark[comm.design ! CDMarks.PreviousMarkWasNotReleased => GOTO requestProblem]; Doit[m, comm ! UNWIND => IF m#0 THEN { CDMarks.ReleaseMark[comm.design, m]; m _ 0 } ]; IF m#0 THEN CDMarks.ReleaseMark[comm.design, m]; EXITS requestProblem => TerminalIO.WriteRope["**Mark not requested; not done\n"]; END; SetSimplification: PROC [comm: CDSequencer.Command] = BEGIN ap: CD.ApplicationPtr; multiple: BOOL; TerminalIO.WriteRope["Set cell simplification\n"]; [ap, multiple] _ CDOps.SelectedApplication[comm.design]; IF multiple THEN TerminalIO.WriteRope[" multiple selection; not done\n"] ELSE IF ap=NIL THEN TerminalIO.WriteRope[" no selection; not done\n"] ELSE { TerminalIO.WriteRope[ap.ob.p.describe[ap.ob]]; IF ISTYPE[ap.ob.specificRef, CD.CellPtr] THEN { cptr: CD.CellPtr ~ NARROW[ap.ob.specificRef]; TerminalIO.WriteRope[" [currently: simplification if height < "]; TerminalIO.WriteInt[cptr.simplifyOn]; cptr.simplifyOn _ MIN[ MAX[ TerminalIO.RequestInt[" pixels] type > "], 0], LAST[NAT] ]; TerminalIO.WriteRope[" done\n"] } ELSE TerminalIO.WriteRope[" not a cell; not done\n"]; } END; RenameSP: PROC [comm: CDSequencer.Command] = BEGIN RenameAppOb: PROC[design: CD.Design, ap: CD.ApplicationPtr] = BEGIN done: BOOL _ FALSE; IF ap=NIL THEN TerminalIO.WriteRope[" no object;\n"] ELSE { TerminalIO.WriteRope[ap.ob.p.describe[ap.ob]]; IF NOT ap.ob.p.inDirectory THEN TerminalIO.WriteRope[" object can not have name;\n"] ELSE { newName: Rope.ROPE _ TerminalIO.RequestRope[" new name > "]; IF Rope.IsEmpty[newName] THEN newName _ "-"; done _ CDDirectory.Rename[design, ap.ob, newName]; }; }; IF done THEN TerminalIO.WriteRope["done\n"] ELSE TerminalIO.WriteRope[" not done\n"] END; ap: CD.ApplicationPtr = CDCommandOps.TheApplication[comm]; IF ap#NIL THEN RenameAppOb[comm.design, ap] END; ReplaceComm: PROC [comm: CDSequencer.Command] = BEGIN name: Rope.ROPE; old, new: CD.ObPtr; found: BOOLEAN; TerminalIO.WriteRope["replace an entry allover in the design\n"]; name _ TerminalIO.RequestRope[" replace (name) > "]; [found, old] _ CDDirectory.Fetch[comm.design, name]; IF found THEN { name _ TerminalIO.RequestRope[" by (name) > "]; [found, new] _ CDDirectory.Fetch[comm.design, name]; }; IF ~found THEN { TerminalIO.WriteRope[" "]; TerminalIO.WriteRope[name]; TerminalIO.WriteRope[" not found\n"]; } ELSE { offset: CD.DesignPosition_ [0, 0]; TerminalIO.WriteRope[" do you want to specify an offset?\n"]; IF TerminalIO.UserSaysYes[label: "offset", default: FALSE] THEN { offset.x _ TerminalIO.RequestInt[" x in lambda >"]*CD.lambda; offset.y _ TerminalIO.RequestInt[" y in lambda >"]*CD.lambda; }; CDDirectory.ReplaceObject[design: comm.design, old: old, new: new, off: offset]; TerminalIO.WriteRope[" end replace\n"]; } END; CDSequencer.ImplementCommand[$PopMenu, PopFromCellMenu,, doQueue]; CDSequencer.ImplementCommand[$PopNew, PopFromCellNew,, doQueue]; CDSequencer.ImplementCommand[$PopFlush, PopFromCellFlush,, doQueue]; CDSequencer.ImplementCommand[$PopReplace, PopFromCellReplace,, doQueue]; CDSequencer.ImplementCommand[$PushS, PushIntoCellS,, doQueue]; CDSequencer.ImplementCommand[$CreateCellSAndName, CreateCellAndName]; CDSequencer.ImplementCommand[$CreateCellSUnNamed, CreateCellDefaultName]; CDSequencer.ImplementCommand[$DisplayCellNames, DisplayCellNames,, doQueue]; CDSequencer.ImplementCommand[$RestricedDisplayCellNames, DisplayCellNames,, doQueue]; CDSequencer.ImplementCommand[$DrawCell, DrawCellComm]; CDSequencer.ImplementCommand[$RemoveCell, DeleteCell,, doQueue]; CDSequencer.ImplementCommand[$DeleteUnUsedObjects, CleanUpDirectory,, doQueue]; CDSequencer.ImplementCommand[$DeleteUnUsedAutoObs, CleanUpDirectory,, doQueue]; CDSequencer.ImplementCommand[$CellSimplification, SetSimplification,, doQueue]; CDSequencer.ImplementCommand[$RenameS, RenameSP,, doQueue]; CDSequencer.ImplementCommand[$Replace, ReplaceComm]; END.