CDCellCommands.mesa (part of ChipNDale)
Copyright © 1983, 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, July 11, 1983 3:42 pm
last edited by Christian Jacobi, April 11, 1985 1:49:52 pm PST
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�LSE]-- =
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.ROPENIL;
usedBy: Rope.ROPENIL;
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: BOOLFALSE] =
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: BOOLFALSE] =
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: BOOLFALSE] =
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: BOOLFALSE;
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.