CDDirectoryOpsImpl.mesa (part of ChipNDale)
Copyright © 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, June 3, 1985 7:06:54 pm PDT
last edited by Christian Jacobi, July 5, 1985 2:30:27 pm PDT
CDDirectoryOpsImpl:
CEDAR
PROGRAM
IMPORTS Ascii, CDDirectory, CDMarks, CDSimpleOps, Rope, TerminalIO
EXPORTS CDDirectoryOps =
MarkUnMarkedFromTop:
PROC [design:
CD.Design, mark: CDMarks.MarkRange] =
BEGIN
FOR l:
LIST
OF
CD.PushRec ← design.actual, l.rest
WHILE l#
NIL
DO
IF l.first.mightReplace#
NIL
THEN {
CDMarks.MarkUnMarkedInclusiveChildren[design, l.first.mightReplace.ob, mark];
};
CDMarks.MarkUnMarkedInclusiveChildren[design, l.first.dummyCell.ob, mark];
ENDLOOP;
END;
RemoveObjectFromDirectory:
PUBLIC PROC [design:
CD.Design, ob:
CD.Object]
RETURNS [done:
BOOL ←
FALSE, msg: Rope.
ROPE ←
NIL] =
BEGIN
usedBy: Rope.ROPE←NIL;
name: Rope.ROPE;
toDeleteOb: CD.Object;
found: BOOL ;
DoitWithMark:
PROC [mark: CDMarks.MarkRange] =
BEGIN
EachEntryCheck: CDDirectory.EachEntryAction
-- PROC [name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOLLSE]-- =
BEGIN
IF ob.marked#mark
AND ob#toDeleteOb
THEN {
--an occurence of cellOb should not be marked
CDMarks.MarkUnMarkedInclusiveChildren[design, ob, mark];
IF toDeleteOb.marked=mark
THEN {
usedBy ← name;
quit ← TRUE
}
};
END;
MarkUnMarkedFromTop[design, mark];
IF toDeleteOb.marked=mark
THEN {
usedBy ← "top level";
found ← TRUE
}
ELSE
found ← CDDirectory.Enumerate[design, EachEntryCheck].quit;
END;
name ← CDDirectory.Name[ob];
[found, toDeleteOb] ← CDDirectory.Fetch[design, name];
IF ~found THEN RETURN [done ← FALSE, msg ← "object was not in directory"];
IF toDeleteOb#ob THEN RETURN [done ← FALSE, msg ← "naming problem"];
-- mark all entries (excluding toDeleteOb), and all their children
-- test then if toDeleteOb is marked; if it is, it is a child and used
CDMarks.DoWithMark[design, DoitWithMark];
IF found
THEN
RETURN [done ← FALSE, msg ← Rope.Cat["is used by ", usedBy, " (and maybe others)"]];
CDSimpleOps.FlushDeletedCache[design];
IF ~CDDirectory.Remove[design, name, toDeleteOb]
THEN
RETURN [done ← FALSE, msg ← "error in delete routine"];
RETURN [done ← TRUE, msg ← NIL];
END;
CleanUpDirectory:
PUBLIC PROC [design:
CD.Design, autoOnly:
BOOL ←
FALSE, askFirst:
BOOL←
FALSE] =
BEGIN
Doit:
PROC [mark: CDMarks.MarkRange] =
BEGIN
RemoveIfNotMarked:
PROC [name: Rope.
ROPE, ob:
CD.Object]
RETURNS [quit:
BOOL←
FALSE] =
BEGIN
IF ob.marked#mark
THEN {
d: BOOL ← CDDirectory.Remove[design: design, name: name, expectObject: ob];
IF d THEN removed ← CONS[ob, removed];
}
END;
ListNotMarked:
PROC [name: Rope.
ROPE, ob:
CD.Object]
RETURNS [quit:
BOOL←
FALSE] =
BEGIN
IF ob.marked#mark
THEN {
TerminalIO.WriteRope[" - "]; TerminalIO.WriteRope[name]; TerminalIO.WriteLn[];
cnt ← cnt + 1
}
END;
AlsoMarkNamedObjects:
PROC[name: Rope.
ROPE, ob:
CD.Object]
RETURNS [quit:
BOOL←
FALSE] =
BEGIN
IF ob.marked#mark
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[design, ob, mark];
}
};
END;
removed: LIST OF CD.Object ← NIL;
cnt: NAT ← 0;
MarkUnMarkedFromTop[design, mark];
IF autoOnly
THEN {
[] ← CDDirectory.Enumerate[design: design, action: AlsoMarkNamedObjects];
};
IF askFirst
THEN {
TerminalIO.WriteRope[" List of objects not used:\n"];
[] ← CDDirectory.Enumerate[design: design, action: ListNotMarked];
TerminalIO.WriteRope[" "];
TerminalIO.WriteInt[cnt];
TerminalIO.WriteRope[" objects not used in design\n"];
};
IF cnt>0
THEN {
IF askFirst
AND ~TerminalIO.UserSaysYes[
label: "delete them?",
text: " you may delete all the listed objects\n"
]
THEN {
removed ← NIL;
TerminalIO.WriteRope[" not done\n"];
RETURN
};
[] ← CDDirectory.Enumerate[design: design, action: RemoveIfNotMarked];
CompletelyDestroy[design, removed];
IF askFirst THEN TerminalIO.WriteRope[" deleted\n"];
};
removed ← NIL;
END;
CDSimpleOps.FlushDeletedCache[design];
CDMarks.DoWithMark[design, Doit ! CDMarks.MarkOccupied => GOTO requestProblem];
EXITS
requestProblem => TerminalIO.WriteRope["**Mark problem\n"];
END;
RenameNCleanUp:
PUBLIC PROC [design:
CD.Design, ob:
CD.Object, name: Rope.
ROPE] =
--tries hard to rename ob
--removes conflicting ob from directory if possible
--uses CDMarks
BEGIN
ob1: CD.Object;
IF ~ob.class.inDirectory THEN ERROR;
ob1 ← CDDirectory.Fetch[design, name].object;
IF ob1#
NIL
THEN {
IF ob1=ob THEN RETURN;
[] ← CDDirectory.Rename[design: design, object: ob1, newName: Rope.Cat[name, "@old"], fiddleName: TRUE];
};
[] ← CDDirectory.Rename[design: design, object: ob, newName: name, fiddleName: TRUE];
IF ob1#
NIL
THEN {
[] ← RemoveObjectFromDirectory[design: design, ob: ob1]
};
END;