<> <> <> <> <> DIRECTORY Ascii, CD, CDBasics, CDCells, CDCommandOps, CDDirectory, CDDirectoryOps, CDInstances, CDMarks, CDMenus, CDOps, CDSequencer, IO, Real, Rope, RopeList, TerminalIO; CDCellCommands: CEDAR PROGRAM IMPORTS Ascii, CD, CDOps, CDCells, CDCommandOps, CDDirectory, CDDirectoryOps, CDInstances, CDMarks, CDMenus, CDSequencer, IO, Real, Rope, RopeList, TerminalIO = BEGIN orientForTest: CD.Orientation _ 0; obCSystemForTest: CDCells.CoordSystem _ interrestCoords; DrawCellComm: PROC [comm: CDSequencer.Command] = BEGIN name: Rope.ROPE; cellOb: CD.Object; TerminalIO.WriteRope["Include cell; "]; DO name _ TerminalIO.RequestRope["type name\n"]; cellOb _ CDDirectory.Fetch[comm.design, name].object; IF cellOb#NIL THEN { inst: CD.Instance = CDCells.IncludeOb[design: comm.design, ob: cellOb, position: comm.pos, obCSystem: obCSystemForTest, orientation: orientForTest ].newInst; CDOps.RedrawInstance[comm.design, inst, FALSE]; TerminalIO.WriteRopes[name, " inserted\n"]; RETURN }; TerminalIO.WriteRopes[name, " not found\n"]; IF NOT TerminalIO.Confirm[choice: "another try ?" ] THEN RETURN; ENDLOOP END; RemoveObComm: PROC [comm: CDSequencer.Command] = BEGIN name, msg: Rope.ROPE_NIL; done: BOOL; ob: CD.Object; TerminalIO.WriteRope["remove object from directory; "]; name _ TerminalIO.RequestRope["type name\n"]; ob _ CDDirectory.Fetch[comm.design, name].object; IF ob=NIL THEN { TerminalIO.WriteRopes[name, " not found\n"]; RETURN }; [done, msg] _ CDDirectoryOps.RemoveIfUnused[comm.design, ob]; TerminalIO.WriteRope[msg]; IF ~done THEN TerminalIO.WriteRope[" not "]; TerminalIO.WriteRope["done\n"]; END; DisplayCellNames: PROC [comm: CDSequencer.Command] = BEGIN EachEntry: CDDirectory.EachEntryAction --[name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOL] -- = BEGIN quit _ FALSE; count _ count+1; IF comm.key=$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 => list _ CONS[cp.name, list]; ENDCASE => list _ CONS[Rope.Cat[name, " [", CDOps.ObjectInfo[ob], "]"], list]; END; list: LIST OF Rope.ROPE _ NIL; count: INT _ 0; displayed: INT _ 0; TerminalIO.WriteRope["Display object names\n"]; [] _ CDDirectory.Enumerate[comm.design, EachEntry]; list _ RopeList.Sort[list, RopeList.Compare]; FOR l: LIST OF Rope.ROPE _ list, l.rest WHILE l#NIL DO TerminalIO.WriteRopes[" ", l.first, "\n"]; ENDLOOP; TerminalIO.WriteF[" %g objects counted ", IO.int[count]]; IF count#displayed THEN TerminalIO.WriteF[" %g displayed", IO.int[displayed]]; TerminalIO.WriteLn[] END; CreateCellAndName: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Create cell "]; IF ~CDCells.CreateCellSelected[comm.design].done THEN TerminalIO.WriteRope[" not done\n"]; END; CreateCellDefaultName: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Create cell without name\n"]; IF ~CDCells.CreateCellSelected[comm.design, "-no name-"].done THEN TerminalIO.WriteRope[" not done\n"]; END; PushIntoCellS: PROC [comm: CDSequencer.Command] = BEGIN VExpand: PROC [me: CD.Object, design: CD.Design] RETURNS [ob: CD.Object] = { ob _ CDDirectory.ExpandComplete[me, design, design]; IF ob=NIL THEN TerminalIO.WriteRope["expand failed\n"] ELSE TerminalIO.WriteRope["object expanded\n"]; }; inst: CD.Instance _ CDCommandOps.TheInstance[comm: comm, text: "Push into cell "]; IF inst#NIL THEN { WHILE ~CDCells.IsCell[inst.ob] DO TerminalIO.WriteRopes[CDOps.ObjectInfo[inst.ob], " is not cell;"]; IF ~ inst.ob.class.inDirectory THEN CDSequencer.Quit[" not done"]; SELECT TerminalIO.RequestSelection[label: "convert to cell?", choice: LIST["all instances", "this instance"], text: " convert to cell?\n", default: 1] FROM 1 => {--all instances ob: CD.Object _ VExpand[inst.ob, comm.design]; IF ob=NIL THEN RETURN; CDSequencer.MarkChanged[comm.design]; CDDirectory.ReplaceObject[design: comm.design, old: inst.ob, new: ob] }; 2 => {--this instance ob: CD.Object _ VExpand[inst.ob, comm.design]; IF ob=NIL THEN RETURN; CDSequencer.MarkChanged[comm.design]; inst.ob _ ob; }; ENDCASE => CDSequencer.Quit["no expansion; not done"]; ENDLOOP; IF CDCells.PushInCellInstance[comm.design, inst] THEN TerminalIO.WriteRope["done\n"] ELSE TerminalIO.WriteRope["not done\n"]; }; END; ExpandComm: PROC [comm: CDSequencer.Command] = BEGIN others: CD.InstanceList _ NIL; cnt: INT _ 0; someOb: CD.Object _ NIL; ExpandInclude: PROC [inst: CD.Instance, ob: CD.Object] = { <<--replace the instance by an instance of the expanded object ob >> <<--and include the instance into "others" >> cp: CD.CellPtr _ NARROW[ob.specificRef]; include: CD.InstanceList _ CDInstances.ComposedList[cp.contents, inst.location, inst.ob.size, inst.orientation]; FOR il: CD.InstanceList _ include, il.rest WHILE il#NIL DO il.first.selected _ TRUE; others _ CONS[il.first, others]; ENDLOOP; someOb _ inst.ob; cnt _ cnt+1; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[inst]]; }; Dont: PROC [inst: CD.Instance, msg: Rope.ROPE] = { others _ CONS[inst, others]; inst.selected _ FALSE; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[inst]]; TerminalIO.WriteRopes[CDOps.ObjectInfo[inst.ob], " "]; TerminalIO.WriteRopes[msg, "; deselected\n"]; }; selected: CD.InstanceList _ NIL; TerminalIO.WriteRope["expand\n"]; [selected, others] _ CDInstances.SplitSelected[CDOps.InstList[comm.design]]; FOR il: CD.InstanceList _ selected, il.rest WHILE il#NIL DO IF ~il.first.ob.class.inDirectory THEN Dont[il.first, "atomic, can not be expanded"] ELSE { ob: CD.Object _ il.first.ob; WHILE ob#NIL AND ~CDCells.IsCell[ob] DO ob _ CDDirectory.ExpandComplete[ob, comm.design, comm.design]; IF ob=il.first.ob THEN ob _ NIL; --to exit loop IF ob#NIL AND CDCells.IsCell[ob] THEN { TerminalIO.WriteRopes[CDOps.ObjectInfo[il.first.ob], " converted to cell\n"]; [] _ CDDirectoryOps.RemoveIfUnused[comm.design, ob]; } ENDLOOP; IF ob#NIL AND CDCells.IsCell[ob] THEN ExpandInclude[il.first, ob] ELSE Dont[il.first, "can not be converted to cell to expand"] } ENDLOOP; IF cnt>0 THEN CDOps.SetInstList[comm.design, others]; IF cnt=1 AND someOb#NIL THEN TerminalIO.WriteRopes[CDOps.ObjectInfo[someOb], " expanded"] ELSE TerminalIO.WriteF1["%g objects expanded\n", IO.int[cnt]]; 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; CleanUpDirectoryComm: PROC [comm: CDSequencer.Command] = BEGIN autoOnly: BOOL _ comm.key#$DeleteUnUsedObjects; TerminalIO.WriteRope["Prune directory\n"]; CDDirectoryOps.PruneDirectory[design: comm.design, autoOnly: autoOnly, askFirst: TRUE]; END; DrawWithBorder: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Draw cell(s) with border\n"]; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected THEN { CDCells.SetBorder[l.first.ob, TRUE]; CDOps.RedrawInstance[comm.design, l.first, FALSE]; } ENDLOOP; END; DrawWithoutBorder: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Draw cell(s) without border\n"]; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected THEN { CDCells.SetBorder[l.first.ob, FALSE]; CDOps.RedrawInstance[comm.design, l.first]; } ENDLOOP; END; SetSimplification: PROC [comm: CDSequencer.Command] = BEGIN inst: CD.Instance; multiple: BOOL; TerminalIO.WriteRope["Set cell simplification #\n"]; [inst, multiple] _ CDOps.SelectedInstance[comm.design]; IF multiple THEN TerminalIO.WriteRope[" multiple selection; not done\n"] ELSE IF inst=NIL THEN TerminalIO.WriteRope[" no selection; not done\n"] ELSE { TerminalIO.WriteRope[inst.ob.class.describe[inst.ob]]; IF ISTYPE[inst.ob.specificRef, CD.CellPtr] THEN { cptr: CD.CellPtr ~ NARROW[inst.ob.specificRef]; h: CD.Number _ MAX[1, inst.ob.size.y]; TerminalIO.WriteF[" [currently: simplification if height < %g pixels", [integer[Real.Round[cptr.simplifyOn*h]]]]; cptr.simplifyOn _ MIN[MAX[TerminalIO.RequestInt[" pixels] type > "], 0], LAST[NAT]]/h; CDOps.RedrawInstance[comm.design, inst]; TerminalIO.WriteRope[" done\n"]; } ELSE TerminalIO.WriteRope[" not a cell; not done\n"]; } END; RenameComm: PROC [comm: CDSequencer.Command] = BEGIN RenameOnInst: PROC[design: CD.Design, inst: CD.Instance] = BEGIN done: BOOL _ FALSE; IF inst=NIL THEN TerminalIO.WriteRope[" no object;\n"] ELSE { TerminalIO.WriteRope[inst.ob.class.describe[inst.ob]]; IF ~inst.ob.class.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, inst.ob, newName]; }; }; IF done THEN TerminalIO.WriteRope["done\n"] ELSE TerminalIO.WriteRope[" not done\n"] END; inst: CD.Instance = CDCommandOps.TheInstance[comm]; IF inst#NIL THEN RenameOnInst[comm.design, inst] END; ReplaceComm: PROC [comm: CDSequencer.Command] = BEGIN newName, oldName: Rope.ROPE; old, new: CD.Object; found: BOOL; offset: CD.Position _ [0, 0]; lambda: CD.Number _ comm.design.technology.lambda; TerminalIO.WriteRope["replace an entry allover in the design\n"]; oldName _ TerminalIO.RequestRope[" replace (name) > "]; [found, old] _ CDDirectory.Fetch[comm.design, oldName]; IF ~found THEN {TerminalIO.WriteRopes[" ", oldName, " not found\n"]; RETURN}; newName _ TerminalIO.RequestRope[" by (name) > "]; [found, new] _ CDDirectory.Fetch[comm.design, newName]; IF ~found THEN {TerminalIO.WriteRopes[" ", newName, " not found\n"]; RETURN}; TerminalIO.WriteRope[" do you want to specify an offset?\n"]; SELECT TerminalIO.RequestSelection[label: "offset", choice: LIST["lambda", "ints", "none"]] FROM 1 => { offset.x _ TerminalIO.RequestInt[" x in lambda >"]*lambda; offset.y _ TerminalIO.RequestInt[" y in lambda >"]*lambda; }; 2 => { offset.x _ TerminalIO.RequestInt[" x in ints >"]; offset.y _ TerminalIO.RequestInt[" y in ints >"]; }; ENDCASE => offset _ [0, 0]; CDDirectory.ReplaceObject[design: comm.design, old: old, new: new, off: offset]; SELECT TerminalIO.RequestSelection[label: "cleanup ?", choice: LIST["remove replaced ob from dir", "remove replaced ob from dir and rename other", "no"]] FROM 1 => [] _ CDDirectoryOps.RemoveIfUnused[comm.design, old]; 2 => CDDirectoryOps.RenameNRemove[comm.design, new, oldName]; ENDCASE => NULL; TerminalIO.WriteRope[" end replace\n"]; END; <<>> <<--**PushByName ************************>> foundAndStop: SIGNAL = CODE; HandleRec: TYPE = RECORD [ stopFlag: REF BOOL _ NIL, iDidIt: BOOL _ FALSE, gMark: CDMarks.MarkRange, cell: CD.Object _ NIL, drawStack: CD.InstanceList _ NIL ]; MyDrawChild: CD.DrawProc = BEGIN IF inst.ob.class.inDirectory THEN { h: REF HandleRec _ NARROW[pr.devicePrivate]; IF inst.ob=h.cell THEN { h.drawStack _ CONS[inst, h.drawStack]; h.iDidIt _ TRUE; SIGNAL foundAndStop }; WITH inst.ob.specificRef SELECT FROM cp: CD.CellPtr => { IF inst.ob.marked#h.gMark THEN { inst.ob.marked _ h.gMark; h.drawStack _ CONS[inst, h.drawStack]; inst.ob.class.drawMe[inst: inst, pos: inst.location, orient: inst.orientation, pr: pr]; h.drawStack _ h.drawStack.rest; }; }; ENDCASE => NULL; } END; PushNamedComm: PROC [comm: CDSequencer.Command] = BEGIN name: Rope.ROPE; design: CD.Design _ comm.design; h: REF HandleRec = NEW[HandleRec_[ stopFlag: NEW[BOOL], gMark: 0 ]]; myDrawRef: CD.DrawRef _ CD.CreateDrawRef[[ design: design, interestClip: CDBasics.universe, drawChild: MyDrawChild, devicePrivate: h ]]; pushStack: CD.InstanceList _ NIL; --will be draw stack in reversed order MyDrawWithMark: PROC [mark: CDMarks.MarkRange] = BEGIN h.gMark _ mark; <<--draw only from pushed in cell point in hierarchy>> design.actual.first.dummyCell.ob.class.drawMe[inst: design.actual.first.dummyCell, pos: [0, 0], orient: CD.original, pr: myDrawRef ! foundAndStop => CONTINUE]; END; ReverseInstanceList: PROC [list: CD.InstanceList] RETURNS[val: CD.InstanceList] = { val _ NIL; UNTIL list = NIL DO val _ CONS[list.first, val]; list _ list.rest; ENDLOOP; RETURN[val]; }; TerminalIO.WriteRope["Push into cell by name\n"]; <<--get name, find if cell really exists>> WITH comm.data SELECT FROM r: Rope.ROPE => { TerminalIO.WriteRopes["Push into cell", r, "\n"]; name _ r; }; ENDCASE => { TerminalIO.WriteRope["Push into cell by name\n"]; name _ TerminalIO.RequestRope["cell name >"]; }; h.cell _ CDDirectory.Fetch[design, name].object; IF h.cell=NIL THEN { TerminalIO.WriteRopes["design does not have object ", name, "\n"]; RETURN }; <<--if we are already pushed in, it would not harm the program, >> <<--but it is checked because it would confuse the designer>> FOR pl: LIST OF CD.PushRec _ design.actual, pl.rest WHILE pl#NIL DO IF pl.first.mightReplace#NIL AND pl.first.mightReplace.ob=h.cell THEN { TerminalIO.WriteRope["design is already pushed in\n"]; RETURN } ENDLOOP; <<--check if a path to the cell exists, and build the path >> CDMarks.DoWithMark[comm.design, MyDrawWithMark ! CDMarks.MarkOccupied => GOTO markError ]; IF ~h.iDidIt THEN { TerminalIO.WriteRope["not found in accessible position\n"]; RETURN }; <<--there is a path>> <<--make pushStack in push order; (reverse order as drawStack)>> pushStack _ ReverseInstanceList[h.drawStack]; <> <> <<--do the pushes>> WHILE pushStack#NIL DO <<--select exclusively the application we want to push in>> <<--pushing in makes a copy of the application list! check for the right object>> inst: CD.Instance _ NIL; CDSequencer.CheckAborted[design]; FOR il: CD.InstanceList _ CDOps.InstList[design], il.rest WHILE il#NIL DO IF il.first.ob=pushStack.first.ob THEN { inst _ il.first; EXIT }; REPEAT FINISHED => { TerminalIO.WriteRope["finding cell failed\n"]; RETURN } ENDLOOP; IF ~CDCells.PushInCellInstance[design, inst] THEN { TerminalIO.WriteRope["push failed\n"]; CDSequencer.ExecuteCommand[$ResetScaleTop, design, dontQueue, comm]; RETURN }; pushStack _ pushStack.rest ENDLOOP; <<--we are successully pushed in>> <<--position the viewer>> CDSequencer.ExecuteCommand[$ResetScaleTop, design, dontQueue, comm]; TerminalIO.WriteRope["done\n"]; <<--help the garbage collector>> h.drawStack _ NIL; myDrawRef.viewerPrivate _ NIL; myDrawRef _ NIL; pushStack _ NIL; EXITS markError => TerminalIO.WriteRope["**inconsistent use of mark\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[$ExpandS, ExpandComm]; 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, RemoveObComm,, doQueue]; CDSequencer.ImplementCommand[$DeleteUnUsedObjects, CleanUpDirectoryComm,, doQueue]; CDSequencer.ImplementCommand[$DeleteUnUsedAutoObs, CleanUpDirectoryComm,, doQueue]; CDSequencer.ImplementCommand[$CellSimplification, SetSimplification,, doQueue]; CDSequencer.ImplementCommand[$RenameS, RenameComm,, doQueue]; CDSequencer.ImplementCommand[$Replace, ReplaceComm]; CDSequencer.ImplementCommand[$DrawWithoutBorder, DrawWithoutBorder]; CDSequencer.ImplementCommand[$DrawWithBorder, DrawWithBorder]; CDSequencer.ImplementCommand[$PushNamed, PushNamedComm]; CDMenus.CreateEntry[$CellMenu, "create", $CreateCellSAndName]; CDMenus.CreateEntry[$CellMenu, "expand", $ExpandS]; CDMenus.CreateEntry[$CellMenu, "push in", $PushS]; CDMenus.CreateEntry[$CellMenu, "pop out", $PopMenu]; CDMenus.CreateEntry[$CellMenu, "transform to", $TransformToCellS]; CDMenus.CreateEntry[$CellMenu, "border on sel.", $DrawWithBorder]; CDMenus.CreateEntry[$CellMenu, "border off sel.", $DrawWithoutBorder]; CDMenus.CreateEntry[$CellMenu, "push named", $PushNamed]; CDMenus.CreateEntry[$CellMenu, " DIRECTORY", $DirectoryMenu]; CDMenus.CreateEntry[$DirectoryMenu, "list subset dir", $RestricedDisplayCellNames]; CDMenus.CreateEntry[$DirectoryMenu, "list complete dir", $DisplayCellNames]; CDMenus.CreateEntry[$DirectoryMenu, "prune subset dir", $DeleteUnUsedAutoObs]; CDMenus.CreateEntry[$DirectoryMenu, "prune complete dir", $DeleteUnUsedObjects]; CDMenus.CreateEntry[$DirectoryMenu, "remove ob from dir", $RemoveCell]; CDMenus.CreateEntry[$DirectoryMenu, "replace ob", $Replace]; CDMenus.CreateEntry[$DirectoryMenu, "list imports", $DisplayImports]; CDMenus.CreateEntry[$DirectoryMenu, "list importee's ob", $DisplayImportedEntries]; CDMenus.CreateEntry[$DirectoryMenu, " CELLS", $CellMenu]; END.