DIRECTORY CD, CDBasics, CDCells, CDCellsInteractions, CDDirectory, CDImports, CDInstances, CDLayers, CDOps, CDProperties, CDRects, CDSatellites, CDViewer, CDViewHighlight, Core, CoreGeometry, CoreOps, ExtractOps, IO, PW, RefTab, Rope, Sinix, SinixCMosB, Sisyph, TerminalIO, ViewerClasses, ViewerOps; ExtractOpsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDCellsInteractions, CDDirectory, CDImports, CDInstances, CDLayers, CDOps, CDProperties, CDRects, CDSatellites, CDViewer, CDViewHighlight, CoreGeometry, CoreOps, IO, PW, RefTab, Rope, Sinix, SinixCMosB, Sisyph, TerminalIO, ViewerOps EXPORTS ExtractOps SHARES CDImports, SinixCMosB = BEGIN OPEN ExtractOps; HighlightInstance: PUBLIC PROC [instance: CoreGeometry.Instance] RETURNS [hinstance: CD.Instance] = { hinstance _ CDInstances.NewInst[ CDRects.CreateRect[CD.InterestSize[instance.obj], CD.shadeLayer], [CDBasics.MapPoint[CD.InterestBase[instance.obj], instance.trans], instance.trans.orient] ]; }; HighlightInstanceList: PUBLIC PROC [instances: CoreGeometry.Instances] RETURNS [hinstances: CD.InstanceList _ NIL] = { WHILE instances#NIL DO hinstances _ CONS [HighlightInstance[instances.first], hinstances]; instances _ instances.rest; ENDLOOP; }; HighlightDesign: PUBLIC PROC [design: CD.Design, highlight: CD.Instance _ NIL, viewer: ViewerClasses.Viewer _ NIL, label: Rope.ROPE _ NIL] = { bbox: CD.Rect _ IF highlight=NIL THEN [0, 0, 0, 0] ELSE CDInstances.InstRectO[highlight]; DoHighlightDesign[design, highlight, bbox, viewer, label]; }; HighlightDesignList: PUBLIC PROC [design: CD.Design, highlight: CD.InstanceList _ NIL, viewer: ViewerClasses.Viewer _ NIL, label: Rope.ROPE _ NIL] = { bbox: CD.Rect _ CDInstances.BoundingRectO[highlight]; DoHighlightDesign[design, highlight, bbox, viewer, label]; }; DoHighlightDesign: PROC [design: CD.Design, highlight: REF, bbox: CD.Rect, viewer: ViewerClasses.Viewer _ NIL, label: Rope.ROPE _ NIL] = { IF viewer=NIL THEN viewer _ FindViewer[design, label]; CDViewHighlight.ShowInstance[v: viewer, instOrList: highlight]; IF highlight#NIL THEN { ViewerOps.OpenIcon[viewer]; IF CDBasics.NonEmpty[bbox] THEN CDViewer.ShowPosition[viewer, [bbox.x1, bbox.y1]]; CDOps.ImmediateRedraw[design, bbox, FALSE]; }; }; FindViewer: PUBLIC PROC [design: CD.Design, label: Rope.ROPE _ NIL] RETURNS [viewer: ViewerClasses.Viewer] = { viewer _ CDViewer.LastViewer[]; IF CDViewer.DesignOf[viewer]#design THEN { viewers: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; IF viewers=NIL THEN { viewer _ CDViewer.CreateViewer[design]; IF label#NIL THEN ViewerOps.SetViewer[viewer: viewer, data: label, op: $Label]; } ELSE viewer _ viewers.first; }; }; ExtractCDInstance: PUBLIC PROC [instance: CD.Instance, design: CD.Design, mode: Sinix.Mode] RETURNS [result: REF, props: Core.Properties] = { userData: REF = IF mode.userData#NIL THEN mode.userData[design] ELSE NIL; [] _ CDSatellites.GetSatellites[design]; -- enforces the strong invariant in object, one level deep CDProperties.PutInstanceProp[instance, Sinix.satellitesProp, CDSatellites.GetSatelliteRopes[instance]]; [result, props] _ Sinix.Extract[obj: instance.ob, mode: mode, properties: instance.properties, userData: userData]; }; ExtractCDInstanceAndReport: PUBLIC PROC [instance: CD.Instance, design: CD.Design, mode: Sinix.Mode] RETURNS [result: REF _ NIL, props: Core.Properties _ NIL] = { [result, props] _ ExtractCDInstance[instance, design, mode ! Sinix.FusionPropMismatch => { TerminalIO.PutF["*** Extraction failed in cell %g.\n", IO.rope[name]]; IF prop=CoreOps.nameProp THEN TerminalIO.PutF["*** Two wires that do not have the same name are fused: %g and %g.\n", IO.rope[NARROW [value1]], IO.rope[NARROW [value2]]] ELSE TerminalIO.PutF["*** Two wires that do not have the same %g property value are fused: %g and %g.\n", IO.atom[prop], IO.refAny[value1], IO.refAny[value2]]; GOTO Failed; }; Sinix.FusionStructureMismatch => { TerminalIO.PutF["*** Extraction failed in cell %g.\n *** Two wires with mismatching structures are fused: ", IO.rope[name]]; CoreOps.Print[wire1, TerminalIO.TOS[]]; TerminalIO.PutF["\nand: "]; CoreOps.Print[wire2, TerminalIO.TOS[]]; TerminalIO.PutF["\n.\n"]; HighLightWireGeometry[design, mode, name, LIST [wire1, wire2]]; GOTO Failed; }; Sinix.StructureMismatch => { TerminalIO.PutF["CoreCDUser: Extraction failed in cell %g.\n CoreCDUser: Actual: ", IO.rope[name]]; CoreOps.Print[actual, TerminalIO.TOS[]]; TerminalIO.PutF["\nand subPublic: "]; CoreOps.Print[subPublic, TerminalIO.TOS[]]; TerminalIO.PutF["\nhave mismatching structures for the index %g.\n", IO.int[index]]; HighLightWireGeometry[design, mode, name, LIST [actual]]; GOTO Failed; }; Sinix.FusionByNameMismatch => { TerminalIO.PutF["CoreCDUser: Extraction failed in cell %g.\n", IO.rope[name]]; TerminalIO.PutF["CoreCDUser: Fusion by name problem: %g.\n", IO.rope[msg]]; HighLightWireGeometry[design, mode, name, LIST [wire]]; GOTO Failed; }; Sinix.StructuralLoop => { TerminalIO.PutF["CoreCDUser: Extraction failed in cell %g.\n", IO.rope[name]]; TerminalIO.PutF["CoreCDUser: Probably a structural loop in wire: %g.\n", IO.rope[CoreOps.GetShortWireName[wire]]]; HighLightWireGeometry[design, mode, name, LIST [wire]]; -- be careful not to be recursive! GOTO Failed; }; ]; EXITS Failed => NULL; }; HighLightWireGeometry: PROC [design: CD.Design, mode: Sinix.Mode, name: Rope.ROPE, wires: LIST OF Core.Wire] = { IF name=NIL THEN RETURN; -- no highlight done FOR insts: CD.InstanceList _ CDOps.InstList[design], insts.rest WHILE insts#NIL DO AddGeometry: PROC [w: Core.Wire] = { IF CoreOps.Member[ws, w] THEN RETURN; -- to avoid infinite recursion, for example ws _ CONS [w, ws]; FOR gs: CoreGeometry.Instances _ CoreGeometry.GetGeometry[mode.decoration, w], gs.rest WHILE gs#NIL DO IF NOT CoreGeometry.Intersect[CD.InterestRect[insts.first.ob], gs.first] THEN LOOP; geometry _ CONS [CoreGeometry.Transform[insts.first.trans, gs.first], geometry]; ENDLOOP; FOR i: NAT IN [0 .. w.size) DO AddGeometry[w[i]] ENDLOOP; }; geometry: CoreGeometry.Instances _ NIL; ws: LIST OF Core.Wire _ NIL; IF NOT Rope.Equal[PW.Name[insts.first.ob], name] THEN LOOP; WHILE wires#NIL DO AddGeometry[wires.first]; wires _ wires.rest ENDLOOP; IF geometry=NIL THEN RETURN; HighlightDesignList[design, HighlightInstanceList[geometry]]; TerminalIO.PutF["Highlight of the culprits done.\n"]; ENDLOOP; }; ExtractCDInstanceCellTypeAndReport: PUBLIC PROC [instance: CD.Instance, design: CD.Design, mode: Sinix.Mode] RETURNS [root: Core.CellType _ NIL] = { result: REF ANY _ ExtractCDInstanceAndReport[instance, design, mode].result; IF ISTYPE[result, Core.CellType] THEN root _ NARROW[result] ELSE TerminalIO.PutRope["CoreCDUser: CD instance extracts to something other than a Core cell type"]; }; EnumerateSelectedInstances: PUBLIC PROC [design: CD.Design, eachInstance: EachSelectedInstanceProc] RETURNS [quit: BOOL _ FALSE] = { ThisInstance: CDCells.InstEnumerator = { IF inst.selected THEN { IF design.actual.first.mightReplace=NIL THEN quit _ eachInstance[[inst.ob]] ELSE { trans: CD.Transformation _ design.actual.first.mightReplace.trans; quit _ eachInstance[[inst.ob, [CDBasics.DeMapPoint[inst.trans.off, trans], CDBasics.DecomposeOrient[itemInWorld: inst.trans.orient, cellInWorld: trans.orient]]]]; }; }; }; quit _ CDCells.EnumerateInstances[design.actual.first.dummyCell.ob, ThisInstance]; }; SameCDInstance: PUBLIC PROC [cdInstance: CD.Instance, cdInstanceTrans: CD.Transformation, coreInstance: CoreGeometry.Instance] RETURNS [BOOL] = { RETURN [ SameCDObject[cdInstance.ob, coreInstance.obj] AND CDBasics.DeMapPoint[cdInstance.trans.off, cdInstanceTrans]=coreInstance.trans.off AND CDBasics.DecomposeOrient[itemInWorld: cdInstance.trans.orient, cellInWorld: cdInstanceTrans.orient]=coreInstance.trans.orient ]; }; SameCDObject: PUBLIC PROC [cdObject, coreObject: CD.Object] RETURNS [BOOL] = { DO IF cdObject=coreObject THEN RETURN[TRUE]; IF CDCells.IsCell[cdObject] OR NOT cdObject.class.composed THEN RETURN[FALSE]; cdObject _ CDDirectory.Expand1[cdObject].new; ENDLOOP; }; IsSchematic: PUBLIC PROC [design: CD.Design, object: CD.Object] RETURNS [BOOL] = { IsSuffix: PROC [self, suffix: Rope.ROPE] RETURNS [BOOL] ~ { startFrom: INT = Rope.Length[self]-Rope.Length[suffix]; IF startFrom<0 THEN RETURN [FALSE]; -- suffix longer than self RETURN [Rope.Run[s1: self, pos1: startFrom, s2: suffix, pos2: 0]=Rope.Length[suffix]]; }; name: Rope.ROPE = CDDirectory.Name[object, design]; SELECT TRUE FROM IsSuffix[name, ".sch"] => RETURN [TRUE]; IsSuffix[name, ".icon"] => RETURN [TRUE]; IsSuffix[name, ".mask"] => RETURN [FALSE]; ENDCASE => { -- general case, take an educated guess based on non-comment layers Answer: TYPE = {yes, no, dontknow}; Schema: PROC [object: CD.Object] RETURNS [answer: Answer _ dontknow] = { SELECT TRUE FROM CDRects.IsSimpleRect[object] => SELECT TRUE FROM CD.LayerTechnology[object.layer]#NIL => answer _ no; -- definitely layout CDLayers.Kind[object.layer]=paint => answer _ yes; -- definitely schematic ENDCASE => answer _ dontknow; -- some highlight or similar funny layer CDCells.IsCell[object] => { EachInstance: CDCells.InstEnumerator = { answer _ Schema[inst.ob]; quit _ answer#dontknow; }; IF RefTab.Fetch[visitedCells, object].found THEN answer _ dontknow ELSE { IF NOT RefTab.Insert[visitedCells, object, NIL] THEN ERROR; [] _ CDCells.EnumerateInstances[object, EachInstance]; }; }; object.class.composed => answer _ Schema[CDDirectory.Expand1[object].new]; ENDCASE => answer _ dontknow; }; visitedCells: RefTab.Ref _ RefTab.Create[]; RETURN[NOT Schema[object]=no]; }; }; GetExtractMode: PUBLIC PROC [design: CD.Design, object: CD.Object] RETURNS [mode: Sinix.Mode] = { mode _ IF IsSchematic[design, object] THEN Sisyph.mode ELSE SinixCMosB.mode; }; PopTop: PUBLIC PROC [design: CD.Design] = { WHILE CDCells.IsPushedIn[design] DO [] _ CDCellsInteractions.PopFromCell[design, interactive]; ENDLOOP; }; GetTopInstances: PUBLIC PROC [design: CD.Design] RETURNS [topInstances: TopInstanceLists _ NIL] = { GetInstances: PROC [design: CD.Design] = { theseInstances: CD.InstanceList _ NIL; stack: LIST OF CD.PushRec _ NIL; trail: LIST OF CD.PushRec _ NIL; FOR stack _ design.actual, stack.rest UNTIL stack.rest=NIL DO trail _ stack; ENDLOOP; theseInstances _ stack.first.specific.contents; IF trail#NIL THEN theseInstances _ CONS [trail.first.mightReplace, theseInstances]; FOR cl: LIST OF CDImports.Cache _ CDImports.GetCacheList[design].list, cl.rest UNTIL cl=NIL DO IF RefTab.Insert[processedDesigns, cl.first.importee, $Done] THEN GetInstances[cl.first.importee]; ENDLOOP; topInstances _ CONS[[design, theseInstances], topInstances]; }; processedDesigns: RefTab.Ref _ RefTab.Create[]; GetInstances[design]; }; FindSameInstance: PUBLIC PROC [design: CD.Design, cellInstance: CD.Instance, cellTransform: CD.Transformation] RETURNS [worldInstance: CD.Instance] = { cellInstanceTransform: CD.Transformation _ CDBasics.ComposeTransform[cellInstance.trans, cellTransform]; FOR worldInstances: CD.InstanceList _ design.actual.first.specific.contents, worldInstances.rest UNTIL worldInstances=NIL DO IF worldInstances.first.ob=cellInstance.ob AND worldInstances.first.trans=cellInstanceTransform THEN { worldInstance _ worldInstances.first; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; }; END. 2ExtractOpsImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Barth, October 14, 1987 4:14:55 pm PDT Jean-Marc Frailong December 7, 1987 4:56:27 pm PST to be replaced by a PushByName one day The design is passed only to recover the name ... Return TRUE iff self ends with suffix Κ Ν˜code– "Cedar" stylešœ™K– "Cedar" style™˜OK˜—Kšœ˜K˜—Kšœ˜K˜—šžœœœ œœœ œ˜Kš œ œœœœœœ˜IKšœ)Οc:˜cKšœg˜gKšœs˜sK˜K˜—šžœœœ œœœ œœœ˜’šœ=˜=šœ˜Jšœ7œ ˜Fšœ˜Jš œYœœ œœ ˜Jšœfœ œœ˜Ÿ—Jšœ˜ J˜—šœ"˜"Jšœmœ ˜|Jšœ œ˜'Jšœ˜Jšœ œ˜'Jšœ˜Jšœ*œ˜?Jšœ˜ J˜—šœ˜JšœVœ ˜eJšœ!œ˜(Jšœ%˜%Jšœ$œ˜+JšœEœ ˜TJšœ*œ ˜9Jšœ˜ J˜—šœ˜Jšœ@œ ˜OJšœ>œ ˜LJšœ*œ ˜7Jšœ˜ J˜—šœ˜Jšœ@œ ˜OJšœJœ'˜sJšœ*œ Ÿ"˜ZJšœ˜ J˜—Jšœ˜—Jšœ œ˜Jšœ˜J˜—š žœœ œ&œ œœ˜pJš œœœœŸ˜-Jšœ&™&š œœ3œœ˜Ršž œœ˜$JšœœœŸ+˜QJšœœ ˜šœTœœ˜fJš œœœ)œœ˜SJšœ œB˜QJšœ˜—Jš œœœœœ˜9J˜—Jšœ#œ˜'Jšœœœ œ˜Jš œœ œœœ˜;Jšœœœ.œ˜HJšœ œœœ˜Kšœ=˜=Jšœ5˜5Jšœ˜—J˜J˜—šž"œœœ œœœœ˜”Kšœœœ=˜LKšœœœœ˜;Kšœa˜eK˜K˜—šžœœœ œ1œœœ˜„šž œ˜(šœœ˜Kšœ"œœ˜Kšœ˜Kšœœ9˜BKšœ’˜’K˜—K˜—K˜—KšœR˜RKšœ˜K™—šžœœœœœ6œœ˜‘šœ˜Kšœ.œ˜2KšœRœ˜VKšœ}˜}Kšœ˜—K˜K˜—š ž œœœœ œœ˜Nš˜Kšœœœœ˜)Kš œœœœœœ˜NKšœ-˜-Kšœ˜—K˜K˜—šž œœœ œœ œœ˜RK™1š žœœœœœ˜;Kšœœ™%Kšœ œ)˜7Kš œ œœœŸ˜>KšœP˜VK˜—Kšœ œ$˜3šœœ˜Kšœœœ˜(Kšœœœ˜)Kšœœœ˜*šœŸC˜PKšœœ˜#šžœœ œ œ ˜Hšœœ˜šœ œœ˜0KšœœŸ˜IKšœ3Ÿ˜JKšœŸ(˜F—šœ˜šž œ˜(Kšœ˜Kšœ˜K˜—Kšœ*œ˜Bšœ˜Kš œœ%œœœ˜;Kšœ6˜6K˜—K˜—KšœJ˜JKšœ˜—K˜—K˜+Kšœœ˜Kšœ˜——K˜K˜—š žœœœ œœ œ˜aKšœœœ œ˜LK˜K˜—šžœœœ œ ˜+šœ˜#Kšœ:˜:Kšœ˜—K˜K˜—š žœœœ œ œ#œ˜cšž œœ œ ˜*Kšœœœ˜&Kš œœœœ œ˜ Kš œœœœ œ˜ šœ#œ œ˜=Kšœ˜Kšœ˜—Kšœ/˜/Kšœœœœ,˜Sš œœœ@œœ˜^Kšœ;œ!˜bKšœ˜—Kšœœ)˜