DIRECTORY CD, CDCells, CDCleanUp, CDDirectory, CDExtras, CDMenus, CDProperties, CDSequencer, TerminalIO; CDCleanUpImpl: CEDAR PROGRAM IMPORTS CDDirectory, CDCells, CDExtras, CDMenus, CDProperties, TerminalIO EXPORTS CDCleanUp SHARES CD, CDDirectory = BEGIN EnumeratePossibleRoots: PROC [design: CD.Design, proc: CDDirectory.EnumerateObjectsProc, x: REF_NIL, inclDir: BOOL_TRUE] = BEGIN EachEntry: CDDirectory.EachEntryAction = {proc[ob, x]}; FOR pushed: LIST OF CD.PushRec _ design.actual, pushed.rest WHILE pushed#NIL DO FOR list: LIST OF CD.Instance _ pushed.first.specific.contents, list.rest WHILE list#NIL DO proc[list.first.ob, x]; ENDLOOP; ENDLOOP; IF inclDir THEN [] _ CDDirectory.Enumerate[design, EachEntry]; END; ReplaceFunnys: PUBLIC PROC [design: CD.Design, key: REF_NIL] = BEGIN realKey: REF ~ IF key=NIL THEN NEW[INT] ELSE key; DirtyExpand: PROC [ob: CD.Object] = { WHILE ob.class.internalWrite=NIL DO new: CD.Object _ CDDirectory.ExpandHard[ob, NIL, NIL]; own: REF _ CDProperties.GetPropFromObject[ob, $OwnerDesign]; IF new=NIL THEN EXIT; CDProperties.AppendProps[looser: new.properties, winner: ob.properties, putOnto: new]; ob^ _ new^; --real dirty-- CDProperties.PutPropOnObject[ob, $OwnerDesign, own]; ENDLOOP; }; DoIt: CDDirectory.EnumerateObjectsProc = { IF me.class.inDirectory AND CDProperties.GetPropFromObject[me, realKey]#x THEN { CDProperties.PutProp[me, realKey, x]; DirtyExpand[me]; CDDirectory.EnumerateChildObjects[me, DoIt, x]; }; }; EnumeratePossibleRoots[design, DoIt, NEW[INT]]; IF key=NIL THEN CDExtras.RemoveProperties[design, realKey]; END; PreTag: PROC [design: CD.Design, tag: REF, key: REF] = BEGIN DoIt: CDDirectory.EnumerateObjectsProc = { IF me.class.inDirectory AND CDProperties.GetPropFromObject[me, key]#x THEN { CDProperties.PutProp[me, key, x]; IF CDProperties.GetPropFromObject[me, $OwnerDesign]=NIL THEN { [] _ CDDirectory.Include[design, me]; } ELSE IF CDDirectory.Fetch[design, CDDirectory.Name[me]].object#me THEN { new: CD.Object _ CDDirectory.Another[me, NIL, design]; IF new=NIL THEN new _ CDDirectory.ExpandHard[me, NIL, design]; CDProperties.PutProp[me, tag, new]; IF new#NIL THEN me _ new ELSE TerminalIO.WriteF["**** %g is fishy\n", [rope[CDDirectory.Name[me]]]]; }; CDDirectory.EnumerateChildObjects[me, DoIt, x]; }; }; EnumeratePossibleRoots[design, DoIt, NEW[INT]]; END; ReplaceTaggedOneLevel: PROC [design: CD.Design, ob: CD.Object, tag: REF] = { ForCells: PROC [cell: CD.Object, tag: REF] = INLINE { FOR list: LIST OF CD.Instance _ NARROW[cell.specificRef, CD.CellPtr].contents, list.rest WHILE list#NIL DO WITH CDProperties.GetPropFromObject[list.first.ob, tag] SELECT FROM ob: CD.Object => list.first.ob _ ob; ENDCASE => NULL; ENDLOOP; }; --ForCells ForNonCells: PROC [design: CD.Design, ob: CD.Object, tag: REF] = { replaces: CDDirectory.ReplaceList _ NIL; FindReplaces: CDDirectory.EnumerateObjectsProc = { WITH CDProperties.GetPropFromObject[me, tag] SELECT FROM new: CD.Object => { replaces _ CONS[NEW[CDDirectory.ReplaceRec_[old: me, oldSize: me.size, new: new, newSize: new.size, off: [0, 0]]], replaces]; }; ENDCASE => NULL; }; --FindReplaces CDDirectory.EnumerateChildObjects[ob, FindReplaces, NIL]; IF replaces#NIL THEN [] _ CDDirectory.ObToDirectoryProcs[ob].replaceDirectChilds[ob, design, replaces]; }; --ForNonCells IF CDCells.IsCell[ob] THEN ForCells[ob, tag] ELSE ForNonCells[design, ob, tag]; }; --ReplaceTaggedOneLevel ReplaceTagged: PUBLIC PROC [design: CD.Design, replaceBy: REF, key: REF_NIL] = BEGIN myVal: REF ~ NEW[INT]; realKey: REF ~ IF key=NIL THEN NEW[INT] ELSE key; DoChilds: CDDirectory.EnumerateObjectsProc = { IF me.class.inDirectory AND CDProperties.GetPropFromObject[me, realKey]#x THEN { CDProperties.PutProp[me, realKey, x]; ReplaceTaggedOneLevel[design, me, replaceBy]; CDDirectory.EnumerateChildObjects[me, DoChilds, x]; }; }; --DoChilds EachEntry: CDDirectory.EachEntryAction = { WITH CDProperties.GetPropFromObject[ob, replaceBy] SELECT FROM new: CD.Object => { removed: BOOL _ CDDirectory.Remove[design, name, ob]; IF ~removed THEN DoChilds[ob, myVal]; [] _ CDDirectory.Include[design, new]; ob _ new; }; ENDCASE => NULL; DoChilds[ob, myVal]; }; --EachEntry FOR pushed: LIST OF CD.PushRec _ design.actual, pushed.rest WHILE pushed#NIL DO FOR list: LIST OF CD.Instance _ pushed.first.specific.contents, list.rest WHILE list#NIL DO WITH CDProperties.GetPropFromObject[list.first.ob, replaceBy] SELECT FROM ob: CD.Object => { list.first.ob _ ob; DoChilds[ob, myVal]; } ENDCASE => NULL; ENDLOOP; ENDLOOP; [] _ CDDirectory.Enumerate[design, EachEntry]; IF key=NIL THEN CDExtras.RemoveProperties[design, realKey]; END; --ReplaceTagged CleanUp: PUBLIC PROC [design: CD.Design] = BEGIN myKey: REF ~ NEW[INT]; replaceBy: REF ~ NEW[INT]; design.actual.first.deletedList _ NIL; --so deleted unclean objects can not be undeleted ReplaceFunnys[design, myKey]; PreTag[design, replaceBy, myKey]; ReplaceTagged[design, replaceBy, myKey]; CDExtras.RemoveProperties[design, myKey]; CDExtras.RemoveProperties[design, replaceBy]; END; CleanupCommand: PROC [comm: CDSequencer.Command] = BEGIN n: INT; TerminalIO.WriteRope["cleanup directory\n"]; n _ comm.design.cellDirectory.size; CleanUp[comm.design]; IF n = comm.design.cellDirectory.size THEN TerminalIO.WriteF["design was ok; has %g entries in directory\n", [integer[n]]] ELSE TerminalIO.WriteF["design was not ok; previously had %g; now has %g entries in directory\n", [integer[n]], [integer[comm.design.cellDirectory.size]]]; END; CDMenus.ImplementEntryCommand[$SpecialMenu, "check directory", CleanupCommand]; END. fCDCleanUpImpl.mesa Copyright (C) 1986 by Xerox Corporation. All rights reserved. by Ch. Jacobi, January 29, 1986 5:31:20 pm PST last edited Ch. Jacobi, March 11, 1986 1:18:07 pm PST --real dirty, but it never happens because internalWrite is never NIL, except... --uses globals: realKey --figures out whether objects should be replaced because they are in different designs: --such objects will be taken or copied, included in the directory and put onto the tag property --uses globals: design, tag, key --ForNonCells --ReplaceTaggedOneLevel --globals: design, realKey --x: visit key --ReplaceTagged Κγ˜šœ™Icodešœ>™>Kšœ.™.Kšœ5™5—J˜šΟk ˜ Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ K˜ Kšœ˜K˜ Kšœ ˜ Kšœ ˜ —K˜šΠbl œœœ˜KšœB˜IKšœ ˜Kšœœ˜—Kš˜K˜šΟnœœ œ4œœ œœ˜zKš˜JšΟb œ.˜7š œ œœœ&œœ˜Oš œœœœ6œœ˜[Jšœ˜Jšœ˜—Jšœ˜—Jšœ œ/˜>Kšœ˜—J˜š Ÿ œœœ œœœ˜>Jš˜Jšœ œœœœœœœ˜1J˜šŸ œœœ ˜%šœœ˜#JšœQ™QJšœœ%œœ˜6Jšœœ4˜Kšœ%˜%K˜—šœœ;œ˜HKšœœ"œ ˜6Kšœœœ"œ ˜>Jšœ#˜#Kšœœœ ˜KšœG˜KK˜—Jšœ/˜/Jšœ˜—J˜—J˜Jšœ%œœ˜/Kšœ˜—K˜š Ÿœœ œ œœ˜LK˜š Ÿœœœœœ˜6šœœœœ œœœœ˜jšœ4œ˜CKšœœ˜$Kšœœ˜—Kšœ˜—Kšœ‘ ˜ K˜—š Ÿ œœ œ œœ˜BKšœ$œ˜(K˜š  œ&˜2šœ)œ˜8šœœ ˜Kšœ œœj˜}K˜—Kšœœ˜—Kšœ‘˜—J™Kšœ ™ Kšœ4œ˜9šœ œœ˜KšœR˜R—Kšœ‘ ˜—K˜Kšœ™Kšœœœ˜OKšœ‘˜—K˜š Ÿ œ œ œœœœ˜NKš˜Kšœœœœ˜Jšœ œœœœœœœ˜1K˜š œ&˜.Kšœ™Kšœ™šœœ/œ˜QKšœ%˜%Kšœ-˜-Kšœ3˜3Kšœ˜—Kšœ‘ ˜ —K˜š  œ!˜*šœ/œ˜>šœœ ˜Kšœ œ(˜5Kšœ œ˜%Kšœ&˜&K˜ K˜—Kšœœ˜—Kšœ˜Kšœ‘ ˜—K˜Jšœ™š œ œœœ&œœ˜Oš œœœœ6œœ˜[šœ:œ˜Išœœ ˜Kšœ˜Kšœ˜K˜—Kšœœ˜—Kšœ˜—Kšœ˜—Kšœ.˜.Jšœœœ,˜;Kšœ‘˜K™—šŸœ œ œ ˜*Jš˜Jšœœœœ˜Jšœ œœœ˜Kšœ'‘1˜XJšœ˜Jšœ!˜!Jšœ(˜(Jšœ)˜)Jšœ-˜-Jšœ˜J˜—šΠbnœœ˜2Kš˜Kšœœ˜Kšœ,˜,Kšœ#˜#Kšœ˜šœ$œ˜+KšœO˜O—š˜Kšœ–˜–—Kšœ˜—K˜KšœO˜OJšœ˜J˜J˜J˜—…—ΰ )