DIRECTORY Atom, CD, CDApplications, CDCells, CDCommands, CDDirectory, CDExtras, CDInline, CDMarks, CDOps, CDProperties, IO, Process, Rope, SymTab; CDExtrasImpl: CEDAR MONITOR IMPORTS Atom, CD, CDApplications, CDCells, CDCommands, CDDirectory, CDInline, CDMarks, CDOps, CDProperties, IO, Process, Rope, SymTab EXPORTS CDExtras SHARES CD = BEGIN Skip: PUBLIC PROC[CD.Rect] = {}; DecomposeRect: PUBLIC PROC [r, test: CD.Rect, inside, outside: PROC[CD.Rect]_Skip] = BEGIN IF r.x1 Leave[]; pair: REF Pair _ NEW[Pair]; pair^ _ [p, x, pair]; Enter[]; MyEnum[me, pair]; Leave[]; END; MyEnum: PROC [me: CD.ObPtr, x: REF] = BEGIN pair: REF Pair _ NARROW[x]; v: REF _ Atom.GetPropFromList[me.properties, $CDExtrasImplsTouched]; IF v=pair.key THEN RETURN; -- already visited me.properties _ Atom.PutPropOnList[me.properties, $CDExtrasImplsTouched, pair.key]; IF me.p.hasChildren THEN CDDirectory.EnumerateChildObjects[me, MyEnum, x]; pair.p[me, pair.x]; -- call clients enumerator proc END; EnumerateDesignObjects: PUBLIC PROC [design: CD.Design, p: CDDirectory.EnumerateObjectsProc, x: REF] = BEGIN ENABLE UNWIND => Leave[]; pair: REF Pair _ NEW[Pair]; EachCell: SymTab.EachPairAction --[key: Key, val: Val] RETURNS [quit: BOOLEAN] -- = BEGIN quit _ FALSE; MyEnum[NARROW[val, CD.ObPtr], pair] END; pair^ _ [p, x, pair]; Enter[]; [] _ SymTab.Pairs[design.cellDirectory, EachCell]; FOR l: LIST OF CD.PushRec _ design.actual, l.rest WHILE l#NIL DO MyEnum[l.first.dummyCell.ob, pair]; IF l.first.mightReplace#NIL THEN MyEnum[l.first.mightReplace.ob, pair]; ENDLOOP; Leave[]; END; BoundingBox: PUBLIC PROC [design: CD.Design] RETURNS [r: CD.DesignRect _ CDInline.empty] = BEGIN FOR l: LIST OF CD.PushRec _ design.actual, l.rest WHILE l#NIL DO r _ CDInline.Surround[r, CDApplications.BoundingRect[ NARROW[l.first.dummyCell.ob.specificRef, CD.CellPtr].contents ]] ENDLOOP; END; TrailingChar: PROC [base: Rope.ROPE, char: CHAR] RETURNS [INT] = { len: INT _ Rope.Length[base]; pos: INT _ len; WHILE pos > 0 DO SELECT Rope.Fetch[base, pos _ pos - 1] FROM char => RETURN [pos]; '!, '], '>, '/ => EXIT; ENDCASE; ENDLOOP; RETURN [len]; }; AppendExt: PUBLIC PROC [name, defaultExt: Rope.ROPE] RETURNS [Rope.ROPE] = BEGIN bang: INT _ TrailingChar[name, '!]; result: Rope.ROPE _ name.Substr[len: bang]; dot: INT _ TrailingChar[result, '.]; IF ~Rope.IsEmpty[defaultExt] AND (dot >= Rope.Length[result]) THEN { dot2: INT _ TrailingChar[defaultExt, '.]; IF dot2 >= Rope.Length[defaultExt] THEN result _ result.Cat[".", defaultExt] ELSE result _ result.Concat[defaultExt.Substr[dot2]] }; IF bang < Rope.Length[name] THEN { result _ result.Concat[name.Substr[bang]] }; RETURN [result] END; PushedCellName: PUBLIC PROC [design: CD.Design] RETURNS [Rope.ROPE] = {RETURN [ IF design=NIL OR design.actual=NIL THEN "erronous" ELSE IF design.actual.rest=NIL THEN "top level" ELSE IF design.actual.first.specific=NIL THEN "erronous" ELSE IF design.actual.first.specific.name#NIL THEN design.actual.first.specific.name ELSE "unnamed cell" ] }; RPEachChildren: CDDirectory.EnumerateObjectsProc --PROC [me: ObPtr, x: REF]-- = BEGIN IF ~me.p.hasChildren THEN CDProperties.PutPropOnObject[onto: me, prop: x, val: NIL] END; RemoveProps: PROC [design: CD.Design, key: REF] = BEGIN RPEachDirectoryEntry: CDDirectory.EachEntryAction = BEGIN CDProperties.PutPropOnObject[onto: ob, prop: key, val: NIL]; IF ob.p.hasChildren THEN CDDirectory.EnumerateChildObjects[me: ob, p: RPEachChildren, x: key] END; TRUSTED{Process.SetPriority[Process.priorityBackground]}; [] _ CDDirectory.Enumerate[design: design, action: RPEachDirectoryEntry]; END; RemoveProperties: PUBLIC PROC [design: CD.Design, key: REF] = BEGIN TRUSTED {Process.Detach[FORK RemoveProps[design, key]]} END; ToLambda: PUBLIC PROC [n: CD.Number] RETURNS [Rope.ROPE] = BEGIN r: Rope.ROPE _ IO.PutFR[format: " %g", v1: IO.int[n / CD.lambda]]; IF n MOD CD.lambda # 0 THEN r _ Rope.Cat[r, IO.PutFR[format: "+%g", v1: IO.int[n MOD CD.lambda]], IO.PutFR[format: "/%g", v1: IO.int[CD.lambda]] ] ; RETURN [r]; END; PopToTopLevel: PUBLIC PROC [design: CD.Design] = BEGIN WHILE design.actual.rest#NIL DO IF NOT CDCells.PopFromCell[design, newcell] THEN EXIT ENDLOOP; IF design.actual.rest#NIL THEN ERROR END; Cellize: PUBLIC PROC [design: CD.Design, name: Rope.ROPE_NIL] RETURNS [cell: CD.ObPtr_NIL, pos: CD.DesignPosition] = BEGIN done: BOOL; al: CD.ApplicationList; PopToTopLevel[design]; CDCommands.SelectAll[design]; IF (al_CDOps.AppList[design])#NIL THEN { IF al.rest=NIL AND ISTYPE[al.first.ob.specificRef, CD.CellPtr] AND al.first.orientation=CD.original THEN { cell _ al.first.ob; IF name#NIL THEN [] _ CDDirectory.Rename[design, cell, name]; done _ TRUE } ELSE { IF name=NIL THEN name _ design.name; IF name=NIL THEN name _ "no named design"; [done, cell] _ CDCells.CreateCellSelected[design, name]; }; IF done THEN { pos _ CDOps.AppList[design].first.location; } ELSE cell _ NIL }; CDOps.SetAppList[design, NIL] END; SkipAt: PROC [n: Rope.ROPE] RETURNS [Rope.ROPE] = BEGIN RETURN [Rope.Substr[base: n, len: Rope.SkipTo[s: n, skip: "@"]]] END; MergeIn: PUBLIC PROC [design: CD.Design, from: CD.Design, name: Rope.ROPE_NIL, fullDirectory: BOOL_TRUE] RETURNS [ob: CD.ObPtr_NIL, pos: CD.DesignPosition] = BEGIN m: CDMarks.MarkRange; IncludeOneEntry: CDDirectory.EachEntryAction = { IF fullDirectory OR ob.marked=m THEN { IF NOT CDDirectory.Remove[design: from, name: name, expectObject: ob] THEN ERROR; [] _ CDDirectory.Include[design: design, object: ob, alternateName: SkipAt[name]] } }; IF design=from THEN RETURN; IF design.technology#from.technology THEN RETURN WITH ERROR CD.Error[callingError, "MergIn design has different technology"]; [ob, pos] _ Cellize[from, name]; IF ob#NIL THEN { IF ~fullDirectory THEN { m _ CDMarks.GetNewMark[from]; CDMarks.MarkUnMarkedInclusiveChildren[from, ob, m]; }; [] _ CDDirectory.Enumerate[design: from, action: IncludeOneEntry]; CDOps.ResetDesign[from]; } ELSE ob _ NIL END; MergeInObjects: PUBLIC PROC [design: CD.Design, from: CD.Design, objects: LIST OF CD.ObPtr] = BEGIN m: CDMarks.MarkRange = CDMarks.GetNewMark[from]; IncludeOneEntry: CDDirectory.EachEntryAction = { IF ob.marked=m THEN { IF NOT CDDirectory.Remove[design: from, name: name, expectObject: ob] THEN ERROR; [] _ CDDirectory.Include[design: design, object: ob, alternateName: SkipAt[name]] } }; IF design=from THEN RETURN; IF design.technology#from.technology THEN RETURN WITH ERROR CD.Error[callingError, "MergInObjects design has different technology"]; FOR l: LIST OF CD.ObPtr _ objects, l.rest WHILE l#NIL DO CDMarks.MarkUnMarkedInclusiveChildren[from, l.first, m]; ENDLOOP; [] _ CDDirectory.Enumerate[design: from, action: IncludeOneEntry]; CDOps.ResetDesign[from]; END; END. ðCDExtrasImpl.mesa (part of Chipndale) by Christian Jacobi September 8, 1983 9:45 am last edited by Christian Jacobi December 8, 1983 3:47 pm --create a dummy cell object which contains the whole design. --On future changes of the design, the dummy object may or may not --get obsolete. --enumerate me and its children objects --mark visited --enumerate my children first --position of last "char", only before '!, '], '>, '/ considered --defaultExt is appended to name, if name does not already has an extension --copy extension --put version number back --RemoveProps --tries to remove the propertiy "key" from all objects of "design"; --may be delayed or incomplete --(only from objects, not applications...) --if "design" is pushed in, it will be popped out, either by flushing, --replacing cells or creating new cells --makes a single "cell" of of the "design", removes all applications; --pos: if "cell" is included at position "pos" in an empty design we would get "design" again --if "design" is pushed in, it will be popped out, either by flushing, --replacing cells or creating new cells --skip everything after and inclusive first "@" --"from" is transfered to an object, and is included (transitive) to "design"'s directory --"from" then may be resetted (preserving the rule: any object is in at most one directory) --the caller is assumed to have the locks of both designs --if "from" is pushed in, it's merged copy will be popped out, either by flushing, --replacing or creating new cells --"name" replaces "from"'s design name for the new created object, but it is a hint only --"pos": if "ob" is included at position "pos" in an empty design we would get "from" again --"fullDirectory": whether all objects of "from"'s directory are merged to design, --or only those used by "from"'s top level --the "from"'s object's may change name to avoid conflicts with "design"'s directory --ob gets nil if "from" is empty --technologies must be compatible --[name: Rope.ROPE, ob: CD.ObPtr] RETURNS [quit: BOOL_FALSE]-- IF ~fullDirectory THEN CDMarks.ReturnMark[from]; --"objects" which are in "from"'s directory are transferrerd (transitive) to "design"'s directory --"from" then may be resetted (preserving the rule: any object is in at most one directory) --the caller is assumed to have the locks of both designs --the object's may change name to avoid conflicts with "design"'s directory --technologies must be compatible --[name: Rope.ROPE, ob: CD.ObPtr] RETURNS [quit: BOOL_FALSE]-- CDMarks.ReturnMark[from] Ê ˜Jšœ,™,Jšœ0™0Jšœ:™:J˜šÏk ˜ J˜Jšœ˜J˜J˜J˜ J˜ J˜ J˜ J˜J˜J˜ J˜J˜J˜J˜J˜—šÏb œœœ˜Jšœeœ˜†Jšœ ˜Jšœœ˜ —Jš˜J˜JšÏnœœœœ ˜ J˜š Ÿ œœœ œœœ˜TJš˜šœ˜Jš˜Jšœ!œ˜@Jšœœœ˜Jšœ˜—šœ˜Jš˜Jšœ œ)œ˜NJšœœœ˜Jšœ˜—šœ˜Jš˜šœ œœ˜BJ˜ —Jšœœœ˜Jšœ˜—šœ˜Jš˜šœ œœ˜BJšœœ˜—Jšœœœ˜Jšœ˜—šœ œœ˜7Jšœœœ˜1—Jšœ˜J˜—š Ÿœœœ œ œœ ˜FJšœ=™=JšœB™Bšœ™Jš˜Jšœœ#˜-Jšœœ œ˜.š œœœœ!œœ˜@JšœœF˜ZJšœ˜—Jšœ ˜Jšœ˜J˜——Jš œœœ*œœ˜LJ˜Jšœ#œœ˜0Jšœ œœ˜J˜J˜šŸœœœ˜Jš˜Jš œ œœœœ#˜DJšœœ˜ Jšœ˜J˜—šŸœœœ˜Jš˜Jšœœ˜Jšœ˜J˜J˜—š Ÿœœœœ0œ˜bJšœ'™'Jšœœœ ˜Jšœœœ˜J˜J˜J˜J˜Jšœ˜J˜—šŸœœœ œ˜)Jš˜Jšœœœ˜Jšœœ>˜DJšœ œœÏc˜-Jšœ™J˜SJšœ™Jšœœ2˜JJšœ ˜3Jšœ˜J˜—š Ÿœœœ œ1œ˜fJšœœœ ˜Jšœœœ˜J˜šžœ 1œ˜SJš˜Jšœœ˜ Jšœœœ˜#Jšœ˜J˜—J˜J˜J˜2š œœœœ!œœ˜@J˜#Jšœœœ'˜GJšœ˜—J˜Jšœ˜J˜—šŸ œœœ œ ˜-Jšœœ˜-Jš˜š œœœœ!œœ˜@˜5Jšœ#œ˜@—Jšœ˜—Jšœ˜J˜—š Ÿ œœ œœœœ˜BJšœA™AJšœœ˜Jšœœ˜šœ ˜šœ!˜+Jšœœ˜Jšœœ˜Jšœ˜—Jšœ˜—Jšœ˜ J˜J˜—š Ÿ œœœœœœ˜JJšœK™KJš˜Jšœœ˜#Jšœ œ˜+Jšœœ˜$šœœœ˜DJšœ™Jšœœ ˜)Jšœ!œ%˜LJšœ0˜4J˜—šœœ˜"Jšœ™Jšœ)˜)J˜—Jšœ ˜Jšœ˜—J˜š Ÿœ œ œ œœ˜Ešœœ˜ Jš œœœœœ ˜3Jšœœœœ ˜/Jšœœœœ ˜8Jšœœ#œœ"˜TJšœ˜—J˜—J˜šžœ# œ˜OJš˜šœ˜Jšœ5œ˜9—Jšœ˜—J˜šŸ œœ œœ˜1Jš˜J˜šžœ˜3Jšœ˜Jšœ7œ˜<šœœ˜JšœE˜E—Jšœ˜—J˜Jšœ ™ Jšœ2˜9JšœI˜IJšœ˜—J˜šŸœ œ œœ˜=JšœC™CJšœ™Jšœ*™*Jš˜Jšœœ˜7Jšœ˜—J˜š Ÿœœœœ œœ˜:Jš˜Jš œœœœ œ ˜Bšœœœ œ˜šœ˜Jšœœœœ ˜6Jšœœœ ˜.Jšœ˜——Jšœ˜ Jšœ˜—J˜šŸ œ œ œ ˜0JšœG™GJšœ'™'Jš˜šœœ˜Jšœœ&œ˜5Jšœ˜—Jšœœœ˜$Jšœ˜J˜—šŸœ œ œœœœœœœ˜tJšœF™FJšœ]™]JšœG™GJšœ'™'Jš˜Jšœœ˜ Jšœœ˜Jšœ˜Jšœ˜šœœœ˜(šœ œœœœ œœ œ˜jJšœ˜Jšœœœ-˜=Jšœ˜ J˜—šœ˜Jšœœœ˜$Jšœœœ˜*Jšœ8˜8J˜—šœœ˜Jšœ+˜+J˜—Jšœ˜Jšœ˜—Jšœœ˜Jšœ˜J˜—š Ÿœœ œœœ˜1Jšœ/™/Jš˜Jšœ:˜@Jšœ˜J˜—šŸœœœ œœœœœœœœœœ˜JšœY™YJšœ[™[Jšœ9™9JšœS™SJšœ!™!JšœX™XJšœ[™[JšœR™RJšœ*™*JšœT™TJ™ Jšœ!™!Jš˜Jšœ˜šžœ!˜0Jšœ>™>šœœ œ˜&Jšœœ@œœ˜QJšœQ˜QJ˜—Jšœ˜—Jšœ œœ˜šœ#œ˜*Jšœœœœ?˜S—Jšœ ˜ šœœœ˜šœœ˜Jšœ˜Jšœ3˜3J˜—JšœB˜BJšœœ™1J˜J˜—Jšœ˜ Jšœ˜—J˜šŸœœœ œœœœœ ˜]Jšœa™aJšœ[™[Jšœ9™9JšœK™KJšœ!™!Jš˜Jšœ0˜0šžœ!˜0Jšœ>™>šœ ˜Jšœœ@œœ˜QJšœQ˜QJ˜—Jšœ˜—Jšœ œœ˜šœ#œ˜*JšœœœœF˜Z—š œœœœœœ˜8Jšœ8˜8Jš˜—JšœB˜BJšœ˜Jšœ™Jšœ˜—J˜Jšœ˜J˜J˜J˜J˜J˜—…— 7¥