CDCellCommands.mesa (part of ChipNDale)
Copyright © 1983, 1986 by Xerox Corporation. All rights reserved.
by Christian Jacobi, July 11, 1983 3:42 pm
last edited by Christian Jacobi, February 25, 1986 2:44:59 pm PST
DIRECTORY
Ascii,
CD,
CDCells,
CDCommandOps,
CDDirectory,
CDDirectoryOps,
CDInstances,
CDMenus,
CDOps,
CDProperties,
CDSequencer,
IO,
Rope,
RopeList,
TerminalIO;
CDCellCommands:
CEDAR
PROGRAM
IMPORTS Ascii, CDOps, CDCells, CDCommandOps, CDDirectory, CDDirectoryOps, CDInstances, CDMenus, CDProperties, CDSequencer, IO, Rope, RopeList, TerminalIO =
BEGIN
orientForTest: CD.Orientation ← 0;
obCSystemForTest: CDCells.CoordSystem ← interrestCoords;
DrawCellComm:
PROC [comm: CDSequencer.Command] =
BEGIN
name: Rope.ROPE;
cellOb: CD.Object;
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 {
inst:
CD.Instance = CDCells.IncludeOb[design: comm.design,
ob: cellOb,
position: comm.pos,
obCSystem: obCSystemForTest,
orientation: orientForTest
].newInst;
CDCommandOps.RedrawInstance[comm.design, inst, FALSE];
TerminalIO.WriteRopes[name, " inserted\n"];
RETURN
};
TerminalIO.WriteRopes[name, " not found\n"];
IF NOT TerminalIO.Confirm[choice: "another try ?" ! TerminalIO.UserAbort => {GOTO aborted}] 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"];
[done, ob] ← CDDirectory.Fetch[comm.design, name];
IF ~done
OR ob=
NIL
THEN {
TerminalIO.WriteRopes[name, " not found\n"];
RETURN
};
[done, msg] ← CDDirectoryOps.RemoveObjectFromDirectory[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.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 => list ← CONS[cp.name, list];
ENDCASE => list ← CONS[Rope.Cat[name, " [", CDOps.Info[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
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
Expand:
PROC [inst:
CD.Instance]
RETURNS [ob:
CD.Object] =
BEGIN
ob ← CDDirectory.Expand[inst.ob, comm.design, comm.design];
IF ob=NIL THEN TerminalIO.WriteRope["expand failed\n"]
ELSE TerminalIO.WriteRope["object expanded\n"];
END;
inst: CD.Instance ← CDCommandOps.TheInstance[comm: comm, text: "Push into cell "];
IF inst#
NIL
THEN {
WHILE ~CDCells.IsCell[inst.ob]
DO
TerminalIO.WriteRopes[CDOps.Info[inst.ob], " is not cell;"];
IF ~ inst.ob.class.inDirectory THEN CDSequencer.QuitCommand[" 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 ← Expand[inst];
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 ← Expand[inst];
IF ob=NIL THEN RETURN;
CDSequencer.MarkChanged[comm.design];
inst.ob ← ob;
};
ENDCASE => CDSequencer.QuitCommand["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.ComposedCopy[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.Info[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.Expand[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.Info[il.first.ob], " converted to cell\n"];
[] ← CDDirectoryOps.RemoveObjectFromDirectory[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.Info[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;
TerminalIO.WriteRope["Clean up directory\n"];
autoOnly ← comm.a#$DeleteUnUsedObjects;
CDDirectoryOps.CleanUpDirectory[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
AND l.first.ob.class.inDirectory
THEN {
CDProperties.PutProp[l.first.ob, $border, $T];
CDCommandOps.RedrawInstance[comm.design, l.first];
}
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
AND l.first.ob.class.inDirectory
THEN {
CDProperties.PutProp[l.first.ob, $border, NIL];
CDCommandOps.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];
TerminalIO.WriteRope[" [currently: simplification if height < "];
TerminalIO.WriteInt[cptr.simplifyOn];
cptr.simplifyOn ← MIN[MAX[TerminalIO.RequestInt[" pixels] type > "], 0], LAST[NAT]];
CDCommandOps.RedrawInstance[comm.design, inst];
TerminalIO.WriteRope[" done\n"];
}
ELSE TerminalIO.WriteRope[" not a cell; not done\n"];
}
END;
RenameComm:
PROC [comm: CDSequencer.Command] =
BEGIN
RenameAppOb:
PROC[design:
CD.Design, ap:
CD.Instance] =
BEGIN
done: BOOL ← FALSE;
IF ap=NIL THEN TerminalIO.WriteRope[" no object;\n"]
ELSE {
TerminalIO.WriteRope[ap.ob.class.describe[ap.ob]];
IF NOT ap.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, ap.ob, newName];
};
};
IF done THEN TerminalIO.WriteRope["done\n"] ELSE TerminalIO.WriteRope[" not done\n"]
END;
ap: CD.Instance = CDCommandOps.TheInstance[comm];
IF ap#NIL THEN RenameAppOb[comm.design, ap]
END;
ReplaceComm:
PROC [comm: CDSequencer.Command] =
BEGIN
newName, oldName: Rope.ROPE;
old, new: CD.Object;
found: BOOLEAN;
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.RemoveObjectFromDirectory[comm.design, old];
2 => CDDirectoryOps.RenameNCleanUp[comm.design, new, oldName];
ENDCASE => NULL;
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[$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];
CDMenus.CreateEntry[$CellMenu, "border on sel.", $DrawWithBorder];
CDMenus.CreateEntry[$CellMenu, "border off sel.", $DrawWithoutBorder];
END.