DIRECTORY Ascii, CD, CDDirectory, CDDirectoryOps, CDMarks, CDSequencer USING [MarkChanged], CDSimpleOps, TerminalIO, Rope; CDDirectoryOpsImpl: CEDAR PROGRAM IMPORTS Ascii, CDDirectory, CDMarks, CDSequencer, CDSimpleOps, Rope, TerminalIO EXPORTS CDDirectoryOps = BEGIN 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; RemoveIfUnused: 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: BOOL_FALSE]-- = BEGIN IF ob.marked#mark AND ob#toDeleteOb THEN { 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"]; 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; CompletelyDestroy: PROC [design: CD.Design, list: LIST OF CD.Object] = BEGIN tem: LIST OF CD.Object; IF list#NIL THEN { CDSimpleOps.FlushDeletedCache[design]; WHILE list#NIL DO IF list.first.class.inDirectory THEN list.first^.properties _ NIL; list.first _ NIL; tem _ list; list _ list.rest; tem.rest _ NIL; ENDLOOP } END; PruneDirectory: 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.Confirm[label: "delete listed objects", choice: " yes"] THEN { removed _ NIL; TerminalIO.WriteRope[" not done\n"]; RETURN }; CDSequencer.MarkChanged[design]; [] _ 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; RenameNRemove: PUBLIC PROC [design: CD.Design, ob: CD.Object, name: Rope.ROPE] = 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 [] _ RemoveIfUnused[design: design, ob: ob1]; END; END. CDDirectoryOpsImpl.mesa (part of ChipNDale) Copyright c 1985 by Xerox Corporation. All rights reserved. by Christian Jacobi, June 3, 1985 7:06:54 pm PDT last edited by Christian Jacobi, March 14, 1986 6:30:55 pm PST Last Edited by: Jacobi July 15, 1986 12:05:35 pm PDT --an occurence of cellOb should not be marked -- mark all entries (excluding toDeleteOb), and all their children -- test then if toDeleteOb is marked; if it is, it is a child and used list.first^ _ CD.ObjectRep[class: NIL]; this used to kill caching modules Κψ˜codešœ-™-Kšœ Οmœ1™