<> <> <> <> DIRECTORY Atom, CedarProcess, CD, CDInstances, CDCells, CDSimpleOps, CDDirectory, CDExtras, CDBasics, CDMarks, CDOps, CDPrivate, CDProperties, IO, Process, Rope, SymTab, TerminalIO; CDExtrasImpl: CEDAR MONITOR IMPORTS Atom, CedarProcess, CD, CDInstances, CDCells, CDSimpleOps, CDDirectory, CDBasics, CDMarks, CDOps, CDProperties, IO, Process, Rope, SymTab, TerminalIO EXPORTS CDExtras SHARES CD = BEGIN MergeIn: PROC [design: CD.Design, from: CD.Design, name: Rope.ROPE_NIL, fullDirectory: BOOL_TRUE] RETURNS [ob: CD.Object, pos: CD.Position]; <<--"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>> <<>> MergeInObjects: PROC [design: CD.Design, from: CD.Design, objects: LIST OF CD.Object]; <<--"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>> <<>> Cellize: PUBLIC PROC [design: CD.Design, name: Rope.ROPE_NIL] RETURNS [cell: CD.Object_NIL, pos: CD.Position] = <<--makes a single "cell" of of the "design", removes all instances; >> <<--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>> BEGIN done: BOOL; il: CD.InstanceList; PopToTopLayer[design]; CDSimpleOps.SelectAll[design]; IF (il_CDOps.InstList[design])#NIL THEN { IF il.rest=NIL AND ISTYPE[il.first.ob.specificRef, CD.CellPtr] AND il.first.orientation=CD.original THEN { cell _ il.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.InstList[design].first.location; } ELSE cell _ NIL }; CDOps.SetInstList[design, NIL] END; SkipAt: PROC [n: Rope.ROPE] RETURNS [Rope.ROPE] = <<--skip everything after and inclusive first "@">> 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.Object_NIL, pos: CD.Position] = <<--"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 layer>> <<--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>> BEGIN m: CDMarks.MarkRange; IncludeOneEntry: CDDirectory.EachEntryAction = { <<--[name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOL_FALSE]-->> 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]; IF ~fullDirectory THEN CDMarks.ReleaseMark[from, m]; CDOps.ResetDesign[from]; } ELSE ob _ NIL END; MergeInObjects: PUBLIC PROC [design: CD.Design, from: CD.Design, objects: LIST OF CD.Object] = <<--"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>> BEGIN m: CDMarks.MarkRange = CDMarks.GetNewMark[from]; IncludeOneEntry: CDDirectory.EachEntryAction = { <<--[name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOL_FALSE]-->> 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.Object _ 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.