DIRECTORY Basics USING [LowHalf], BasicTime USING [Now], Commander USING [CommandProc, Register], CommandTool USING [ParseToList], Convert USING [CardFromRope, Error], FileNames USING [CurrentWorkingDirectory], FS USING [ComponentPositions, EnumerateForNames, ExpandName, NameProc, Error, StreamOpen], IO USING [Close, EndOfStream, Error, GetCard, GetReal, GetRopeLiteral, int, PutF, PutFR, STREAM], List USING [DReverse], Plot USING [AddVector, CreateViewer, Curves, PlotSpec, PlotSpecRec, RealSequence, RopeSequence, Vector], Real USING [LargestNumber, SmallestNormalizedNumber], Rope USING [Cat, Equal, Fetch, Find, IsEmpty, Length, ROPE, Substr], ViewerClasses USING [Viewer]; SimplePlotHack: CEDAR PROGRAM IMPORTS Basics, BasicTime, Commander, CommandTool, Convert, FileNames, FS, IO, List, Plot, Rope = { OPEN IO, Plot; RopeList: TYPE = LIST OF Rope.ROPE; DataError: SIGNAL[reason: Rope.ROPE _ NIL] = CODE; SPlot: Commander.CommandProc = { argList: RopeList; length: NAT; [argList, length] _ CommandTool.ParseToList[cmd]; IF length <= 0 THEN msg _ "To plot data in files, type: SPlot " ELSE { wDir: Rope.ROPE _ FileNames.CurrentWorkingDirectory[]; nPlots: NAT _ 0; maxPlots: NAT _ 12; allVersions: BOOL _ FALSE; FOR arg: RopeList _ argList, arg.rest UNTIL arg = NIL OR msg # NIL DO IF arg.first.Fetch[0] = '- THEN { IF arg.first.Length[] >= 2 THEN SELECT arg.first.Fetch[1] FROM 'A, 'a => allVersions _ TRUE; 'H, 'h => allVersions _ FALSE; IN ['0..'9] => { max: NAT _ Convert.CardFromRope[arg.first.Substr[1] ! Convert.Error => max _ maxPlots]; -- don't change it maxPlots _ max; }; ENDCASE; -- simply ignors illegal switches } ELSE { fileList: RopeList _ FileListFrom[arg.first, wDir, allVersions]; FOR file: RopeList _ fileList, file.rest UNTIL file = NIL OR msg # NIL DO msg _ IF nPlots >= maxPlots THEN IO.PutFR["Note: max. %g plots for each command.", IO.int[maxPlots]] ELSE SimplePlot[file.first, nPlots # 0, cmd.out]; nPlots _ nPlots + 1; ENDLOOP; }; ENDLOOP; }; }; -- SPlot FileListFrom: PROC [pattern, wDir: Rope.ROPE _ NIL, allVersions: BOOL _ FALSE] RETURNS [fileList: RopeList _ NIL] = { root, lastRoot: Rope.ROPE _ NIL; LinkIt: FS.NameProc -- PROC [fullFName] RETURNS [continue: BOOL] -- = { excl: INT _ fullFName.Find["!"]; continue _ TRUE; IF fullFName.Substr[excl-6, 6].Equal[".press", FALSE] THEN RETURN; IF ~allVersions THEN { root _ fullFName.Substr[0, excl]; IF root.Equal[lastRoot, FALSE] THEN { fileList.first _ fullFName; RETURN; }; lastRoot _ root; }; fileList _ CONS[fullFName, fileList]; }; -- LinkIt FS.EnumerateForNames[pattern, LinkIt, wDir]; TRUSTED {fileList _ LOOPHOLE[List.DReverse[LOOPHOLE[fileList]]]}; }; -- FileListFrom SimplePlot: PROC[file: Rope.ROPE _ NIL, iconic: BOOL _ TRUE, out: IO.STREAM] RETURNS[msg: Rope.ROPE _ NIL] = { s: IO.STREAM _ NIL; viewer: ViewerClasses.Viewer; curves: Curves _ NIL; plotSpec: PlotSpec; ok: BOOL _ TRUE; fullName, status: Rope.ROPE _ NIL; xmin, xmax, ymin, ymax: REAL; IF file.IsEmpty[] THEN RETURN["No file name."]; [fullName, ]_ FS.ExpandName[file, FileNames.CurrentWorkingDirectory[]]; s _ FS. StreamOpen[fullName ! FS.Error => {status _ error.explanation; ok _ FALSE; CONTINUE} ]; IF ok THEN { ENABLE { DataError => { msg _ reason; ok _ FALSE; CONTINUE; }; IO.EndOfStream => { msg _ Rope.Cat["End of file reached", status]; ok _ FALSE; CONTINUE; }; IO.Error => { msg _ Rope.Cat[ SELECT ec FROM SyntaxError => "Syntax error", Overflow => "Overflow in input conversion" ENDCASE => IO.PutFR["IO Error # %g", IO.int[LOOPHOLE[ec, CARDINAL]]], status]; ok _ FALSE; CONTINUE; }; ABORTED => { msg _ "SPlot aborted. ... "; ok _ FALSE; CONTINUE; }; }; nVector: CARDINAL; r: REAL; plotSpec _ NEW[PlotSpecRec _ [file: fullName, time: BasicTime.Now[]]]; out.PutF[Rope.Cat["Reading ", fullName, "\n"]]; status _ " in getting the title."; plotSpec.title _ s.GetRopeLiteral[]; status _ " in getting the number of curves."; plotSpec.nCurvesMax _ Basics.LowHalf[s.GetCard[]]; plotSpec.legendEntries _ NEW[RopeSequence[plotSpec.nCurvesMax]]; FOR i: CARDINAL IN [0..plotSpec.nCurvesMax) DO status _ IO.PutFR[" in getting the name for curve #%g.", IO.int[i+1]]; plotSpec.legendEntries[i] _ s.GetRopeLiteral[]; ENDLOOP; status _ " in getting the number of rows."; nVector _ Basics.LowHalf[s.GetCard[]]; xmin _ ymin _ Real.LargestNumber; xmax _ ymax _ Real.SmallestNormalizedNumber; FOR i: CARDINAL IN [0..nVector) DO vector: Vector _ NEW[RealSequence[plotSpec.nCurvesMax + 1]]; FOR j: CARDINAL IN [0..plotSpec.nCurvesMax] DO ENABLE { IO.Error => { msg _ Rope.Cat[ SELECT ec FROM SyntaxError => "Syntax error", Overflow => "Overflow" ENDCASE => IO.PutFR["IO Error # %g", IO.int[LOOPHOLE[ec, CARDINAL]]], IO.PutFR[" in getting the %g-th number on the %g-th row in the table.", IO.int[j+1], IO.int[i+1]]]; GOTO exit; }; IO.EndOfStream => { msg _ Rope.Cat[ "End of file reached", IO.PutFR[" in getting the %g-th number on the %g-th row in the table.", IO.int[j+1], IO.int[i+1]]]; GOTO exit; }; }; vector[j] _ r _ s.GetReal[]; IF j # 0 THEN { ymax _ MAX[ymax, r]; ymin _ MIN[ymin, r]; }; ENDLOOP; IF i = 0 THEN xmin _ vector[0] ELSE IF i+1 = nVector THEN xmax _ vector[0]; curves _ CONS[vector, curves]; out.PutF["."]; REPEAT exit => ok _ FALSE; ENDLOOP; }; IF ok THEN { cv: Curves _ NIL; IF ymax = ymin THEN { IF ymax = 0.0 THEN { ymax _ 1.0; ymin _ -1.0 } ELSE { ymax _ ymax + ABS[ymax]; ymin _ ymin - ABS[ymin]; }; }; IF xmax = xmin THEN { IF xmax = 0.0 THEN { xmax _ 1.0; xmin _ -1.0 } ELSE { xmax _ xmax + ABS[xmax]; xmin _ xmin - ABS[xmin]; }; }; out.PutF[" plotting ... "]; plotSpec.bounds _ [xmin, ymin, xmax, ymax]; viewer _ CreateViewer[spec: plotSpec, iconic: iconic]; FOR c: Curves _ curves, c.rest UNTIL c = NIL DO cv _ CONS[c.first, cv]; ENDLOOP; FOR c: Curves _ cv, c.rest UNTIL c = NIL DO AddVector[viewer, c.first]; ENDLOOP; out.PutF["done.\n"]; }; IF s # NIL THEN s.Close[]; }; -- SimplePlot Commander.Register[ "SPlot", SPlot, "SPlot , use a simple minded plot routine to plot data in the data files that have the following special format: -- comment nodes are ignored. -- carriage returns are treated the same as spaces. -- a text string enclosed by double quotes. <xmin> <ymin> <xmax> <ymax> -- four real numbers. <number of curves> -- Curves are functions of x. <names of the curves> -- Each name is a text string enclosed by double quotes. <number of rows> -- Each row in the table below has a leading x value followed by the corresponding y values. -- If there are n curves then the table for m different x values will be an m x n+1 matrix as follows. x1 y1(x1) y2(x1) y3(x1) ... yn(x1) x2 y1(x2) y2(x2) y3(x2) ... yn(x2) ... ... ... ... ... ... ... ... ... ... ... ... ... ... xm y1(xm) y2(xm) y3(xm) ... yn(xm) "]; }. ���Ψ��SimplePlotHack.mesa Last Edited by: SChen, June 15, 1985 7:37:41 pm PDT Sweetsun Chen, August 2, 1985 1:07:43 pm PDT set plotSpec c.first is the last one just added to the list, so we should reverse the order. Κo��˜�Jšœ™šœ3™3Icode™,—J˜�šΟk ˜ Jšœœ ˜Jšœ œ˜Jšœ œ˜(Jšœ œ˜ Jšœœ˜$Jšœ œ˜*JšœœR˜ZJšœœQœ˜aJšœœ ˜Jšœœ^˜hJšœœ+˜5Jšœœ,œ ˜DJšœœ ˜J˜�—šœœ˜Jšœ@œœ˜c—J˜�Jšœœ˜J˜�Jš œ œœœœ˜#J˜�Jš œ œœœœ˜2J˜�šœ ˜ Jšœ˜Jšœœ˜ Jšœ1˜1Jšœ œ3˜Fšœ˜Jšœ œ'˜6Jšœœ˜Jšœ œ˜Jšœ œœ˜š œ#œœœœ˜Ešœœ˜!šœœœ˜>Jšœœ˜Jšœœ˜šœ˜šœœ+˜3Jšœ$Οc˜6—J˜J˜—Jšœž!˜*—J˜—šœ˜Jšœ@˜@š œ&œœœœ˜Išœœ˜ Jšœ0œ˜CJšœ-˜1—Jšœ˜Jšœ˜—J˜—Jšœ˜—Jšœ˜—Jšœž˜ J˜�—šΟn œœœœœœœœ˜uJšœœœ˜ š œœ žΠckž  ž  žœ˜GJšœœ˜ Jšœ œ˜Jšœ-œœœ˜Bšœœ˜J˜!šœœœ˜%Jšœ˜Jšœ˜J˜—Jšœ˜J˜—Jšœ œ˜%Jšœžœ˜ —J˜�Jšœ*˜,Jšœ œœ˜AJšœž˜—J˜�šŸ œœ œœ œœœœ˜LJšœ œœ˜!Jšœœœœ˜J˜Jšœœ˜J˜Jšœœœ˜Jšœœœ˜"Jšœœ˜Jšœœœ˜/Jšœœ8˜HJš œœœ,œœ˜_šœœ˜ šœ˜˜Jšœ ˜ Jšœœ˜ Jšœ˜ J˜—šœ˜Jšœ.˜.Jšœœ˜ Jšœ˜ J˜—šœ ˜ šœ˜šœ˜J˜J˜*Jš œœœœœ˜E—J˜—Jšœœ˜ Jšœ˜ J˜—šœ˜ Jšœ˜Jšœœ˜ Jšœ˜ J˜—J˜—Jšœ ™ Jšœ œ˜Jšœœ˜Jšœ œ8˜FJ˜�Jšœ/˜/J˜"Jšœ$˜$J˜�J˜-Jšœ2˜2J˜�Jšœœ$˜@šœœœ˜.Jšœ œ.œ ˜FJšœ/˜/Jšœ˜—J˜�J˜+Jšœ&˜&J˜�Jšœ!˜!Jšœ,˜,šœœœ˜"Jšœœ(˜<šœœœ˜.šœ˜šœ ˜ šœ˜šœ˜J˜J˜Jš œœœœœ˜E—šœE˜GJšœ œ ˜——Jšœ˜ J˜—šœ˜šœ˜Jšœ˜šœE˜GJšœ œ ˜——Jšœ˜ J˜—J˜—Jšœ˜šœœ˜Jšœœ ˜Jšœœ ˜J˜—Jšœ˜—Jšœœ˜Jšœœœ˜,Jšœ œ˜J˜š˜Jšœ œ˜—Jšœ˜—J˜—J˜�šœœ˜ Jšœ œ˜šœ œ˜Jšœ œ˜.Jšœœœ ˜;J˜—šœ œ˜Jšœ œ˜.Jšœœœ ˜;J˜—J˜�J˜J˜+Jšœ6˜6J™Ošœœœ˜/Jšœœ˜Jšœ˜—šœœœ˜+Jšœ˜Jšœ˜—J˜J˜J˜�—Jšœœœ ˜Jšœž ˜—J˜�šœ˜Jšœ˜JšœΏ˜Ώ—J˜�J˜J˜�—�…—����n��#΅��