<> <> <> <> <> <> DIRECTORY BasicTime USING [GMT, Now, Period], CD USING [Design, Instance, InstanceList, Layer, Position, Technology], CDCommandOps USING [CallWithResource], CDInstances USING [OnlySelected], CDLayers USING [CurrentLayer], CDMenus USING [CreateEntry], CDOps USING [InstList, LayerName, ObjectInfo], CDOrient USING [MapPoint], CDProperties USING [GetTechnologyProp], CDSequencer USING [Command, CommandRec, ImplementCommand], IO USING [EndOfStream, Error, GetInt, int, PutFR1, RIS, STREAM], PrincOpsUtils USING [], Process USING [priorityBackground, SetPriority], Rope USING [Cat, ROPE], SX USING [TechHandle], SXAccess USING [], SXAccessInternal USING [Analyze], SXAtoms USING [analyzeAndRoseSelected, analyzeAndThymeSelected, analyzeSelected, highlightKeyboardCoordsNode, highlightPointedNode, rosePrint, spinifex, thymePrint], SXHighlightNode USING [HighlightNode], TerminalIO USING [RequestRope, WriteRope]; SXAccessImpl: CEDAR PROGRAM IMPORTS BasicTime, CDCommandOps, CDInstances, CDLayers, CDMenus, CDOps, CDOrient, CDProperties, CDSequencer, IO, Process, Rope, SXAccessInternal, SXAtoms, SXHighlightNode, TerminalIO EXPORTS SXAccess = BEGIN timing: BOOL _ FALSE; <> <> design: PUBLIC CD.Design _ NIL; formatKey: PUBLIC REF _ NIL; invocation: PUBLIC REF _ NIL; stopFlag: PUBLIC REF BOOL _ NIL; sxTech: PUBLIC REF SX.TechHandle _ NIL; CallingRec: TYPE = RECORD [ design: CD.Design, hierarchyRoots: CD.InstanceList, formatKey: REF, stopFlag: REF BOOL]; Analyze: PUBLIC PROC [design: CD.Design, hierarchyRoots: CD.InstanceList, formatKey: REF, stopFlag: REF BOOL _ NIL] RETURNS [skipped: BOOL _ FALSE] = BEGIN <> ik: REF CallingRec; comm: CDSequencer.Command; IF (stopFlag = NIL) THEN stopFlag _ NEW [BOOL _ FALSE]; ik _ NEW [CallingRec _ [design: design, hierarchyRoots: hierarchyRoots, formatKey: formatKey, stopFlag: stopFlag]]; comm _ NEW [CDSequencer.CommandRec _ [key: $SX, design: design, ref: ik]]; skipped _ CDCommandOps.CallWithResource [PseudoCommand, comm, $SX, stopFlag]; IF skipped THEN TerminalIO.WriteRope ["** analysis skipped\n"] END; -- Analyze PseudoCommand: PROC [comm: CDSequencer.Command] = BEGIN GetSXTech: PROC [technology: CD.Technology] RETURNS [th: REF SX.TechHandle] = BEGIN WITH CDProperties.GetTechnologyProp [technology, SXAtoms.spinifex] SELECT FROM x: REF SX.TechHandle => th _ x; ENDCASE => th _ NIL; IF th = NIL THEN TerminalIO.WriteRope ["Technology not implemented for Spinifex\n"] END; callParameters: REF CallingRec = NARROW [comm.ref]; design _ callParameters.design; formatKey _ callParameters.formatKey; invocation _ NEW [INT]; stopFlag _ callParameters.stopFlag; stopFlag^ _ FALSE; sxTech _ GetSXTech [design.technology]; IF (sxTech # NIL) THEN ProtectedAnalyze [callParameters.hierarchyRoots]; design _ NIL; invocation _ NIL; formatKey _ NIL; sxTech _ NIL END; -- PseudoCommand ProtectedAnalyze: PROC [hierarchyRoots: CD.InstanceList] = BEGIN SXAccessInternal.Analyze[hierarchyRoots] END; <> AnalyzeComm: PROCEDURE [comm: CDSequencer.Command] = BEGIN stopFlag: REF BOOL _ NEW [BOOL_FALSE]; ProtectedAnalyzeComm: PROCEDURE [comm: CDSequencer.Command] = BEGIN startTime, stopTime: BasicTime.GMT; -- for internal use selected: CD.InstanceList _ CDInstances.OnlySelected [CDOps.InstList[comm.design]]; IF selected=NIL THEN TerminalIO.WriteRope [ "No selection.\n"] ELSE { skipped: BOOL; format: REF ANY; SELECT comm.key FROM SXAtoms.analyzeAndThymeSelected => { TerminalIO.WriteRope ["Analysis and Thyme format extraction of\n"]; format _ SXAtoms.thymePrint; }; SXAtoms.analyzeAndRoseSelected => { TerminalIO.WriteRope ["Analysis and Rosemary format extraction of\n"]; format _ SXAtoms.rosePrint; }; ENDCASE => { TerminalIO.WriteRope ["Analysis of\n"]; format _ NIL; }; FOR list: CD.InstanceList _ selected, list.rest WHILE list#NIL DO TerminalIO.WriteRope [Rope.Cat[" ", CDOps.ObjectInfo[list.first.ob], "\n"]]; ENDLOOP; TRUSTED {Process.SetPriority [Process.priorityBackground]}; startTime _ BasicTime.Now []; skipped _ Analyze [design: comm.design, hierarchyRoots: selected, formatKey: format, stopFlag: stopFlag]; stopTime _ BasicTime.Now []; IF skipped THEN TerminalIO.WriteRope ["Analysis skipped.\n"] ELSE TerminalIO.WriteRope ["Analysis complete.\n"]; IF timing THEN TerminalIO.WriteRope [Rope.Cat ["Total elapsed time: ", TimeToRope [startTime, stopTime], "\n"]] } END; -- ProtectedAnalyzeComm TerminalIO.WriteRope ["Spinifex.\n"]; [] _ CDCommandOps.CallWithResource [ProtectedAnalyzeComm, comm, $Spinifex, stopFlag] END; -- AnalyzeComm TimeToRope: PROC [from, to: BasicTime.GMT] RETURNS [time: Rope.ROPE] ~ BEGIN <> tmp: Rope.ROPE; sec: INT = BasicTime.Period [from, to]; min: INT = sec / 60; h: INT = min / 60; tmp _ IO.PutFR1 [value: IO.int [h]]; time _ SELECT h FROM = 0 => "00", < 10 => Rope.Cat ["0", tmp], ENDCASE => tmp; tmp _ IO.PutFR1 [value: IO.int [min MOD 60]]; time _ Rope.Cat [time, ":", SELECT min FROM = 0 => "00", < 10 => Rope.Cat ["0", tmp], ENDCASE => tmp]; tmp _ IO.PutFR1 [value: IO.int [sec MOD 60]]; time _ Rope.Cat [time, ":", SELECT sec FROM = 0 => "00", < 10 => Rope.Cat ["0", tmp], ENDCASE => tmp] END; -- TimeToRope HighLightNode: PROCEDURE [comm: CDSequencer.Command] = BEGIN layer: CD.Layer = CDLayers.CurrentLayer [comm.design]; layerName: Rope.ROPE = CDOps.LayerName [layer]; TerminalIO.WriteRope [Rope.Cat ["Highlight Node (", layerName, ", pointed)\n"]]; TRUSTED {Process.SetPriority[Process.priorityBackground]}; SXHighlightNode.HighlightNode [comm.design, comm.pos, layer] END; HighLightNodeFromKeyboard: PROCEDURE [comm: CDSequencer.Command] = BEGIN ENABLE { IO.Error => { TerminalIO.WriteRope [" Invalid Coords (Format is: x y )\n"]; ERROR ABORTED }; IO.EndOfStream => { TerminalIO.WriteRope [" Invalid Coords (Format is: x y )\n"]; ERROR ABORTED }; }; coords: CD.Position _ [0,0]; layer: CD.Layer = CDLayers.CurrentLayer [comm.design]; layerName: Rope.ROPE = CDOps.LayerName [layer]; prompt: Rope.ROPE = Rope.Cat ["Highlight node on layer ", layerName, " as selected on control panel.\n Enter coords of node relative to currently pushed cell > "]; inLine: IO.STREAM ~ IO.RIS [TerminalIO.RequestRope [prompt]]; coords.x _ IO.GetInt[inLine] * comm.design.technology.lambda; coords.y _ IO.GetInt[inLine] * comm.design.technology.lambda; TRUSTED {Process.SetPriority [Process.priorityBackground]}; <> BEGIN a: CD.Instance ~ comm.design.actual.first.mightReplace; IF (a # NIL) THEN coords _ CDOrient.MapPoint [coords, a.ob.size, a.orientation, a.location] END; SXHighlightNode.HighlightNode [comm.design, coords, layer] END; -- HighLightNodeFromKeyboard <> CDSequencer.ImplementCommand [key: SXAtoms.analyzeSelected, proc: AnalyzeComm, queue: doQueue]; CDSequencer.ImplementCommand [key: SXAtoms.analyzeAndThymeSelected, proc: AnalyzeComm, queue: doQueue]; CDSequencer.ImplementCommand [key: SXAtoms.analyzeAndRoseSelected, proc: AnalyzeComm, queue: doQueue]; CDSequencer.ImplementCommand [key: SXAtoms.highlightPointedNode, proc: HighLightNode, queue: doQueue]; CDSequencer.ImplementCommand [key: SXAtoms.highlightKeyboardCoordsNode, proc: HighLightNodeFromKeyboard, queue: doQueue]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "Extract & DRC (Spinifex)", key: SXAtoms.analyzeSelected]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "Spinifex for Thyme", key: SXAtoms.analyzeAndThymeSelected]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "Spinifex for Rosemary", key: SXAtoms.analyzeAndRoseSelected]; CDMenus.CreateEntry [menu: $RectProgramMenu, entry: "Highlight Node (Spinifex)", key: SXAtoms.highlightPointedNode]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "Highlight Node at Coords (Spinifex)", key: SXAtoms.highlightKeyboardCoordsNode]; TerminalIO.WriteRope ["Spinifex layout analysis package loaded.\n"] END. <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <>