<> <> <> <> DIRECTORY CD, CDCells, CDDirectory, CDCommandOps, CDInstances, CDOrient, CDProperties, Rope, CDUtil; CDUtilImpl: CEDAR PROGRAM IMPORTS CD, CDCells, CDCommandOps, CDDirectory, CDInstances, CDOrient, CDProperties, Rope EXPORTS CDUtil = BEGIN InstRec: TYPE = CDUtil.InstRec; Direction: TYPE = CDUtil.Direction; CreateSimpleCell: PUBLIC PROC [design: CD.Design, contents: LIST OF InstRec, cellName: Rope.ROPE _ NIL, direction: Direction _ right, alignHigh: BOOL _ FALSE] RETURNS [CD.Object] = BEGIN r: CD.Rect _ [0, 0, 0, 0]; c: CD.Object = CDCells.CreateEmptyCell[]; inst: CD.Instance; pos: CD.Position _ [0, 0]; IF Rope.IsEmpty[cellName] THEN cellName _ "-SimpleCell"; NARROW[c.specificRef, CD.CellPtr].name _ cellName; FOR list: LIST OF InstRec _ contents, list.rest WHILE list#NIL DO sz: CD.Position; IF list.first.ob=NIL THEN LOOP; sz _ CDOrient.OrientedSize[CD.InterestSize[list.first.ob], list.first.orient]; SELECT direction FROM right => {pos.x _ r.x2}; left => {pos.x _ r.x1-sz.x}; up => {pos.y _ r.y2}; down => {pos.y _ r.y1-sz.y}; none => {pos _ [0, 0]}; ENDCASE => ERROR; IF alignHigh THEN SELECT direction FROM right, left => {pos.y _ -sz.y}; up, down => {pos.x _ -sz.x}; none => {pos _ [-sz.x, -sz.y]}; ENDCASE => ERROR; inst _ CDCells.IncludeOb[cell: c, ob: list.first.ob, position: [pos.x+list.first.dX, pos.y+list.first.dY], orientation: list.first.orient, cellCSystem: cdCoords, obCSystem: interrestCoords, mode: dontPropagate ].newInst; r _ CDInstances.InstRectI[inst]; IF list.first.properties#NIL THEN CDProperties.AppendProps[inst.properties, list.first.properties, inst]; IF ~Rope.IsEmpty[list.first.name] THEN CDProperties.PutInstanceProp[inst, $InstanceName, list.first.name]; ENDLOOP; [] _ CDCells.RepositionCell[c, NIL]; IF design#NIL THEN [] _ CDDirectory.Include[design, c]; RETURN[c] END; PartialCopy: PUBLIC PROC [ob: CD.Object, design: CD.Design, instances: LIST OF Rope.ROPE_NIL, remove: BOOL_TRUE, prop: ATOM _ $InstanceName, name: Rope.ROPE_NIL] RETURNS [copy: CD.Object_NIL] = <<--copy the object; creates a cell >> <<--remove TRUE: >> <<--all the instances with property prop are and a value in instances are removed >> <<--remove FALSE: >> <<--only the instances with property prop are and a value in instances are copied >> BEGIN ExpandToCell: PROC [ob: CD.Object, from: CD.Design] RETURNS [cell: CD.Object] = { <<--returns cell; however we dont care if cell is in design or not...>> tm, cm: CDDirectory.DMode; cell _ ob; IF ~CDCells.IsCell[cell] THEN { [cell, tm, cm] _ CDDirectory.Expand[ob, from, from]; IF cell=NIL OR ~CDCells.IsCell[cell] THEN RETURN [NIL]; IF cm#included THEN IF ~ CDDirectory.ReplaceChildren[cell, from] THEN RETURN [NIL] } }; ShouldCopy: PROC[i: CD.Instance] RETURNS [copy: BOOL_TRUE] = { <<--accesses parameters of CopyInst>> ref: REF = CDProperties.GetInstanceProp[i, prop]; IF ref#NIL THEN { val: Rope.ROPE = CDCommandOps.ToRope[ref]; FOR rl: LIST OF Rope.ROPE _ instances, rl.rest WHILE rl#NIL DO IF Rope.Equal[val, rl.first] THEN RETURN [copy _ ~remove]; ENDLOOP }; copy _ remove }; cell: CD.Object _ ExpandToCell[ob, design]; --don't care if top level in design; we copy anyway IF cell#NIL THEN { newList: CD.InstanceList _ NIL; cp, newCp: CD.CellPtr; copy _ CDCells.CreateEmptyCell[]; cp _ NARROW[cell.specificRef]; newCp _ NARROW[copy.specificRef]; copy.size _ cell.size; CDProperties.CopyProps[cell.properties, copy]; newCp^ _ cp^; FOR il: CD.InstanceList _ cp.contents, il.rest WHILE il#NIL DO IF ShouldCopy[il.first] THEN { i: CD.Instance _ NEW[CD.InstanceRep _ il.first^]; CDProperties.CopyProps[i.properties, i]; newList _ CONS[i, newList]; }; ENDLOOP; newCp.contents _ newList; <<--interest rect: by luck, the right thing happens even without coding>> [] _ CDCells.RepositionCell[copy, NIL]; IF design#NIL THEN [] _ CDDirectory.Include[design, copy, name]; }; END; END.