DIRECTORY Commander, Core, CoreFlat, CoreOps, FS, HashTable, IO, PlotGraph, Rope, SpiceOps, TerminalIO; SpiceOutputViewImpl: CEDAR PROGRAM IMPORTS Commander, CoreFlat, CoreOps, FS, HashTable, IO, PlotGraph, Rope, SpiceOps, TerminalIO EXPORTS SpiceOps ~ BEGIN ConvData: TYPE ~ SpiceOps.ConvData; ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ PlotGraph.VEC; VecList: TYPE ~ LIST OF VEC; DisplayList: TYPE = LIST OF DisplayListRec; DisplayListRec: TYPE = RECORD [ graph: PlotGraph.Graph, list: VecList ]; matchingPattern: ROPE = "0**** "; transientAnalysis: ROPE = "TRANSIENT ANALYSIS"; inputListing: ROPE _ "INPUT LISTING"; patternLength: INT = Rope.Length[matchingPattern]; CR: ROPE = "\n"; leftPar: ROPE = "("; rigthPar: ROPE = ")"; window: PlotGraph.Rectangle _ [0.0, 0.0, 100.0, 5.0]; DisplaySpiceListing: PUBLIC PROC [listingFile: Rope.ROPE] ~ { plot: PlotGraph.Plot; convData: ConvData; msg: Rope.ROPE; stream: IO.STREAM; stream _ FS.StreamOpen[listingFile ! FS.Error => { msg _ error.explanation; CONTINUE }]; IF msg # NIL THEN { TerminalIO.PutRopes["Couldn't open ", listingFile, ": "]; TerminalIO.PutRopes[msg, ".\n"]; RETURN; }; IF stream=NIL THEN RETURN; SearchListingFile[stream, inputListing]; convData _ TryToRemember[stream]; SearchListingFile[stream, transientAnalysis]; plot _ PlotGraph.CreatePlot[IF convData#NIL THEN CoreOps.GetCellTypeName[convData.rootCell] ELSE listingFile]; ReadFirstLine[stream, plot]; IF convData#NIL THEN ChangeNames[plot, convData.rootCell, convData.invTable]; FillPlot[stream, plot]; PlotGraph.RefreshPlot[plot: plot, within: window, eraseFirst: TRUE] }; ChangeNames: PROC [plot: PlotGraph.Plot, cellType: Core.CellType, nameTable: HashTable.Table] ~ { FOR iAxis: PlotGraph.AxisList _ plot.axis, iAxis.rest UNTIL iAxis=NIL DO wire: CoreFlat.FlatWire _ NARROW[HashTable.Fetch[nameTable, iAxis.first.name].value]; IF wire#NIL THEN iAxis.first.name _ CoreFlat.WirePathRope[cellType, wire^]; ENDLOOP; }; TryToRemember: PROC [stream: IO.STREAM] RETURNS [convData: ConvData] ~ { id: ROPE; i0, l: INT _ 0; FOR iLine: NAT IN [0..60] UNTIL l>i0 DO -- until we find a good line in the first page id _ IO.GetLineRope[stream]; -- should be "* 12345: myCell..." i0 _ Rope.Index[id, 0, "*"]+2; l _ Rope.Index[id, i0, ":"]-i0; ENDLOOP; IF l>i0 THEN id _ Rope.Substr[id, i0, l]; -- id="12345" convData _ NARROW[HashTable.Fetch[SpiceOps.pendingSimulations, id].value]; }; SpiceDisplayCmd: Commander.CommandProc ~ { fName: ROPE; fName _ IO.GetTokenRope[IO.RIS[cmd.commandLine], IO.IDProc ! IO.EndOfStream => CONTINUE].token; IF Rope.Find[fName, "."]=-1 THEN fName _ Rope.Concat[fName, ".spo"]; DisplaySpiceListing[fName]; }; SearchListingFile: PUBLIC PROC [stream: IO.STREAM, partName: ROPE] ~ { DO l: ROPE _ IO.GetLineRope[stream]; IF Rope.Equal[Rope.Substr[l, 0, patternLength], matchingPattern] THEN IF Rope.Find[l, partName]> 0 THEN EXIT; ENDLOOP; [] _ IO.GetLineRope[stream]; -- blank line [] _ IO.GetLineRope[stream]; -- *****... line [] _ IO.GetLineRope[stream]; -- blank line [] _ IO.GetLineRope[stream]; -- blank line [] _ IO.GetLineRope[stream]; -- blank line }; SpaceInsideLine: IO.BreakProc ~ { IF (char = IO.CR) OR (char = '() OR (char = ')) THEN RETURN [break]; IF (char = IO.TAB) OR (char = IO.LF) OR (char = IO.SP) THEN RETURN [sepr]; RETURN[other]; }; ReadFirstLine: PUBLIC PROC [stream: IO.STREAM, plot: PlotGraph.Plot] ~ { displayList: DisplayList; nLines: INT _ 0; base, height: REAL; token: ROPE _ IO.GetTokenRope[stream, SpaceInsideLine].token; -- gets "TIME" token _ IO.GetTokenRope[stream, SpaceInsideLine].token; -- 1st output UNTIL Rope.Equal[token, CR] DO name: ROPE; graph: PlotGraph.Graph _ NEW[PlotGraph.GraphRec _ [class: gClass]]; SELECT TRUE FROM Rope.Equal[token, "V"] => {base _ 0.0; height _ 5.0}; Rope.Equal[token, "I"] => {base _ 0.005; height _ 0.01; name _ "Current in "}; ENDCASE => ERROR; IF ~Rope.Equal[IO.GetTokenRope[stream, SpaceInsideLine].token, leftPar] THEN ERROR; name _ Rope.Cat[name, IO.GetTokenRope[stream, SpaceInsideLine].token, " "]; IF ~Rope.Equal[IO.GetTokenRope[stream, SpaceInsideLine].token, rigthPar] THEN ERROR; nLines _ nLines+1; plot.axis _ CONS[NEW[PlotGraph.AxisRec _ [ graphs: LIST[graph], bounds: [0.0, base, 100.0, height], name: name, style: analog, axisData: [axisData, axisData] ]], plot.axis]; displayList _ CONS[[graph: graph], displayList]; token _ IO.GetTokenRope[stream, SpaceInsideLine].token; ENDLOOP; plot.data _ displayList; }; MyGetReal: PROC [stream: IO.STREAM] RETURNS [r: REAL] ~ { r _ IO.GetReal[stream]; IF IO.PeekChar[stream]#'. THEN RETURN; [] _ IO.GetTokenRope[stream, SpaceInsideLine]; IF r=0.0 THEN IF ~Rope.Equal[IO.GetTokenRope[stream, SpaceInsideLine].token, "e+00"] THEN ERROR; }; ReadValues: PUBLIC PROC [stream: IO.STREAM, nVal: INT] RETURNS [vecList: VecList] ~ { time: REAL _ MyGetReal[stream]*1.e9; THROUGH [1..nVal] DO vecList _ CONS[[time, MyGetReal[stream]], vecList]; ENDLOOP; IF ~Rope.Equal[IO.GetTokenRope[stream, SpaceInsideLine].token, CR] THEN ERROR; }; FillPlot: PROC [stream: IO.STREAM, plot: PlotGraph.Plot] ~ { nVal: INT _ 0; displayList: DisplayList _ NARROW[plot.data]; [] _ IO.GetTokenRope[stream, SpaceInsideLine]; [] _ IO.GetTokenRope[stream, SpaceInsideLine]; -- skip 2 lines plot.lowerBounds _ [1.0e24, 1.0e24]; plot.upperBounds _ [-1.0e24, -1.0e24]; FOR iAxis: PlotGraph.AxisList _ plot.axis, iAxis.rest UNTIL iAxis=NIL DO nVal _ nVal+1; ENDLOOP; DO vecList: VecList; IF IO.PeekChar[stream]#IO.SP THEN RETURN; vecList _ ReadValues[stream, nVal]; FOR iDisplayList: DisplayList _ displayList, iDisplayList.rest UNTIL iDisplayList=NIL DO plot.lowerBounds.x _ MIN[plot.lowerBounds.x, vecList.first.x]; plot.lowerBounds.y _ MIN[plot.lowerBounds.y, vecList.first.y]; plot.upperBounds.x _ MAX[plot.upperBounds.x, vecList.first.x]; plot.upperBounds.y _ MAX[plot.upperBounds.y, vecList.first.y]; iDisplayList.first.list _ CONS[vecList.first, iDisplayList.first.list]; vecList _ vecList.rest; ENDLOOP; ENDLOOP; }; Enum: PROC [plot: PlotGraph.Plot, graph: PlotGraph.Graph, bounds: PlotGraph.Rectangle, eachPoint: PlotGraph.PointProc, data: REF ANY _ NIL] RETURNS [invalidEnumeration: BOOL _ FALSE] ~ { quit: BOOLEAN _ FALSE; displayList: DisplayList _ NARROW[plot.data]; FOR iDisplayList: DisplayList _ displayList, iDisplayList.rest UNTIL iDisplayList=NIL OR quit DO IF iDisplayList.first.graph=graph THEN FOR iVecList: VecList _ iDisplayList.first.list, iVecList.rest UNTIL iVecList=NIL DO quit _ eachPoint[iVecList.first.x, iVecList.first.y, data] ENDLOOP; ENDLOOP; }; gClass: PlotGraph.GraphClass _ NEW[PlotGraph.GraphClassRec _ [ insert: NIL, delete: NIL, enumerate: Enum ]]; axisData: PlotGraph.AxisData _ [1.0, TRUE, FALSE]; Commander.Register[key: "SpiceOps", proc: SpiceDisplayCmd, doc: "Display files sent by Spice"]; END. SpiceOutputViewImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Christian LeCocq March 25, 1987 10:01:45 am PST Description of what this module does. Public never put a catch phrase in an initialization ! PROC [cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL] I/Os Description of the procedure. for transient analysis the next line is : " TIME V(1) V(2)"... which is where the data begins. PROC [char: CHAR] RETURNS [CharClass] Description of the procedure. the extra space is needed in order to recognize the wire name - see SpiceInputGenImpl.NextInstanceId which generates rope numbers. Tries to cope with 0 being written as 0. e+00, which is 2 tokens for IO. Description of the procedure. Display Κ ώ˜codešœ™Kšœ Οmœ1™žœ˜CK˜K˜—š  œžœP˜ašžœ3žœžœž˜HKšœžœ5˜UKšžœžœžœ;˜KKšžœ˜—K˜K˜—š   œžœ žœžœžœ˜HJšœžœ˜ Jšœžœ˜š žœžœžœ žœžœΟc.˜VKšœžœ‘!˜>Kšœ˜Kšœ˜Kšžœ˜—Kšžœžœ‘ ˜7Kšœ žœ9˜JK˜K˜—š œ˜*Kš žœžœ žœžœžœžœ™?Kšœžœ˜ Kš œžœžœžœžœžœ˜_Kšžœžœ$˜DKšœ˜K˜K˜——™š  œžœžœ žœžœ žœ˜FK™šž˜Kšœžœžœ˜!šžœ?ž˜EKšžœžœžœ˜'—Kšžœ˜—Kšœžœ‘ ˜*Kšœžœ‘˜-Kšœžœ‘ ˜*Kšœžœ‘ ˜*Kšœžœ‘ ˜*šœ+™+Kšœ$™$—K™K˜K™—š œžœ˜!Jšžœžœžœ ™%Jšžœ žœžœžœ žœ žœžœ ˜DJšžœ žœžœžœ žœžœžœ žœžœžœžœ˜JJšžœ˜Jšœ˜J˜—š   œžœžœ žœžœ˜HK™Kšœ˜Kšœžœ˜Kšœžœ˜Kšœžœžœ.‘˜LKšœžœ.‘ ˜Ešžœžœž˜Kšœžœ˜ Kšœžœ'˜Cšžœžœž˜Kšœ5˜5KšœN˜NKšžœžœ˜—Kšžœ žœ7žœžœ˜Sšœžœ3˜KKšœ‚™‚—Kšžœ žœ8žœžœ˜TKšœ˜šœ žœžœ˜*Kšœžœ˜Kšœ#˜#Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜—Kšœžœ˜0Kšœžœ-˜7Kšžœ˜—Kšœ˜K˜K˜—š   œžœ žœžœžœžœ˜9Kšœ&Οb œ™JKšœžœž˜Kšžœžœžœžœ˜&Kšœžœ'˜.Kš žœžœžœ žœ6žœžœ˜`K˜K˜—š  œžœžœ žœžœžœžœ˜UK™Kšœžœ˜$šžœ ž˜Kšœ žœ%˜3Kšžœ˜—Kš žœ žœ-žœžœžœ˜N˜K™——š œžœ žœžœ˜Kšœ$˜$Kšœ&˜&šžœ3žœžœž˜HKšœ˜Kšžœ˜—šž˜Kšœ˜Kš žœžœžœžœžœžœ˜)Kšœ#˜#šžœ<žœžœž˜XKšœžœ&˜>Kšœžœ&˜>Kšœžœ&˜>Kšœžœ&˜>Kšœžœ)˜GKšœ˜Kšžœ˜—Kšžœ˜—K˜——™šΠbnœžœsžœžœžœžœžœžœ˜ΊKšœžœžœ˜Kšœžœ ˜-šžœ<žœžœž˜`šžœž˜&šžœ<žœ žœž˜TKšœ:˜:Kšžœ˜——Kšžœ˜—K˜K˜—šœžœ˜>Kšœžœ˜ Kšœžœ˜ Kšœ˜K˜—Kšœ%žœžœ˜2K•StartOfExpansionx[key: ROPE, proc: Commander.CommandProc, doc: ROPE _ NIL, clientData: REF ANY _ NIL, interpreted: BOOL _ TRUE]šœ_˜_K˜K™—K˜Kšžœ˜—…—v'x