-- MungeStats.mesa -- Edited by Sweet, February 3, 1981 11:06 AM DIRECTORY AltoFileDefs, InlineDefs, IODefs, ImageDefs, MiscDefs, SegmentDefs, StreamDefs, StringDefs; Munge: PROGRAM IMPORTS ImageDefs, InlineDefs, IODefs, MiscDefs, SegmentDefs, StreamDefs, StringDefs = BEGIN OPEN IODefs, StringDefs, StreamDefs; in1, in2: StreamHandle; line1: STRING _ [200]; line2: STRING _ [200]; token1: STRING _ [40]; token2: STRING _ [40]; beforeFile: STRING _ [40]; afterFile: STRING _ [40]; n1, n2: CARDINAL; commandStream: StreamHandle; SetUpCommands: PROCEDURE = BEGIN cfa: POINTER TO AltoFileDefs.CFA _ MiscDefs.CommandLineCFA[]; cfile: SegmentDefs.FileHandle _ SegmentDefs.InsertFile[@cfa.fp,Read]; commandStream _ NIL; commandStream _ CreateByteStream[cfile,Read ! SegmentDefs.InvalidFP => CONTINUE]; IF commandStream # NIL THEN BEGIN JumpToFA[commandStream,@cfa.fa]; WHILE commandStream.get[commandStream ! StreamError => GOTO nocommands] <= SP DO NULL ENDLOOP; SetIndex[commandStream,ModifyIndex[GetIndex[commandStream],-1]]; EXITS nocommands => BEGIN commandStream.destroy[commandStream]; commandStream _ NIL END; END; END; ReadName: PROCEDURE [s: STRING] = BEGIN c: CHARACTER; IF commandStream = NIL THEN ReadID[s] ELSE BEGIN s.length _ 0; DO IF (c_commandStream.get[commandStream ! StreamError => GOTO endoffile]) <= SP THEN BEGIN IF s.length # 0 THEN RETURN END ELSE BEGIN StringDefs.AppendChar[s,c]; WriteChar[c] END; REPEAT endoffile => BEGIN commandStream.destroy[commandStream]; commandStream _ NIL END; ENDLOOP; END; END; ReadLines: PROC RETURNS [BOOLEAN] = BEGIN line1.length _ n1 _ 0; line2.length _ n2 _ 0; DO line1[n1] _ in1.get[in1 ! StreamError => EXIT]; IF line1[n1] = CR THEN IF n1 = 0 THEN LOOP ELSE EXIT; n1 _ n1 + 1; ENDLOOP; line1.length _ n1; DO line2[n2] _ in2.get[in2 ! StreamError => EXIT]; IF line2[n2] = CR THEN IF n2 = 0 THEN LOOP ELSE EXIT; n2 _ n2 + 1; ENDLOOP; line2.length _ n2; RETURN [n1*n2 # 0]; END; Scan: PROC = BEGIN token1.length _ 0; WHILE n1 < line1.length AND (line1[n1] = SP OR line1[n1] = TAB) DO n1 _ n1 + 1; ENDLOOP; WHILE n1 < line1.length AND ~(line1[n1] = SP OR line1[n1] = TAB) DO AppendChar[token1, line1[n1]]; n1 _ n1 + 1; ENDLOOP; token2.length _ 0; WHILE n2 < line2.length AND (line2[n2] = SP OR line2[n2] = TAB) DO n2 _ n2 + 1; ENDLOOP; WHILE n2 < line2.length AND ~(line2[n2] = SP OR line2[n2] = TAB) DO AppendChar[token2, line2[n2]]; n2 _ n2 + 1; ENDLOOP; END; sourceChars, obj1, obj2: LONG INTEGER; tSource, tObj1, tObj2, dSource, dObj1, dObj2: LONG INTEGER _ 0; Decimal7: NumberFormat = [base: 10, unsigned: FALSE, zerofill: FALSE, columns: 7]; Decimal8: NumberFormat = [base: 10, unsigned: FALSE, zerofill: FALSE, columns: 8]; Decimal5: NumberFormat = [base: 10, unsigned: FALSE, zerofill: FALSE, columns: 5]; Decimal2Z: NumberFormat = [base: 10, unsigned: TRUE, zerofill: TRUE, columns: 2]; RJ: PROC [s: STRING, cols: CARDINAL] = BEGIN THROUGH (s.length..cols] DO WriteChar[SP] ENDLOOP; WriteString[s]; END; LJ: PROC [s: STRING, cols: CARDINAL] = BEGIN WriteString[s]; THROUGH (s.length..cols] DO WriteChar[SP] ENDLOOP; END; WriteLongNumber: PROC [n: LONG INTEGER, fmt: NumberFormat] = BEGIN s: STRING = [20]; c: CARDINAL; f: CHARACTER = IF fmt.zerofill THEN '0 ELSE SP; AppendLongNumber[s, (IF fmt.unsigned THEN n ELSE ABS[n]), fmt.base]; c _ s.length; IF ~fmt.unsigned AND n < 0 THEN BEGIN c _ c + 1; IF fmt.zerofill THEN WriteChar['-]; END; THROUGH (c..fmt.columns] DO WriteChar[SP] ENDLOOP; IF ~fmt.unsigned AND n < 0 AND ~fmt.zerofill THEN WriteChar['-]; WriteString[s]; END; Results: PROC [sou, c1, c2: LONG INTEGER] = BEGIN delta, t: LONG INTEGER; it: INTEGER; WriteLongNumber[sou, Decimal8]; WriteLongNumber[c1, Decimal8]; WriteLongNumber[c2, Decimal8]; delta _ c2 - c1; WriteLongNumber[delta, Decimal7]; t _ (delta * 10000) / c1; it _ InlineDefs.LowHalf[t]; IF it = 0 THEN RJ["0", 5] ELSE BEGIN IF it IN (-100..0) THEN RJ["-", 5] ELSE WriteNumber[it / 100, Decimal5]; WriteChar['.]; WriteNumber[ABS[it] MOD 100, Decimal2Z]; END; IF c1 / 512 # c2 / 512 THEN WriteChar['*]; WriteChar[CR]; END; Dashes: PROC [s: STRING] RETURNS [BOOLEAN] = BEGIN d: CARDINAL _ 0; FOR i: CARDINAL IN [0..s.length) DO IF s[i] = '- THEN d _ d + 1 ELSE d _ 0; IF d = 3 THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; END; DoIt: PROC = BEGIN DO BEGIN tSource _ 0; tObj1 _ 0; tObj2 _ 0; dSource _ 0; dObj1 _ 0; dObj2 _ 0; WriteChar[CR]; WriteChar[CR]; WriteChar[CR]; WriteString["file 1: "L]; ReadName[beforeFile]; IF beforeFile.length = 0 THEN ImageDefs.StopMesa[]; in1 _ NewByteStream[beforeFile, Read ! SegmentDefs.FileNameError => GO TO cantFind]; WriteChar[CR]; WriteString["file 2: "L]; ReadName[afterFile]; in2 _ NewByteStream[afterFile, Read ! SegmentDefs.FileNameError => { in1.destroy[in1]; GO TO cantFind}]; WriteChar[CR]; WriteChar[CR]; LJ["MODULE", 35]; RJ["source", 8]; RJ["obj/1", 8]; RJ["obj/2", 8]; RJ["diff", 7]; RJ["%", 5]; WriteChar[CR]; WriteChar[CR]; DO IF ~ReadLines[] THEN GO TO badFormat; IF Dashes[line1] THEN EXIT; ENDLOOP; WHILE ReadLines[] DO IF Dashes[line1] OR Dashes[line2] THEN EXIT; n1 _ n2 _ 0; Scan[]; IF ~EqualStrings[token1, token2] THEN GO TO unequalNames; LJ[token1, 35]; Scan[]; sourceChars _ StringToLongNumber[token1, 10]; Scan[]; Scan[]; obj1 _ StringToLongNumber[token1, 10]; obj2 _ StringToLongNumber[token2, 10]; Results[sourceChars, obj1, obj2]; tSource _ tSource + sourceChars; tObj1 _ tObj1 + obj1; tObj2 _ tObj2 + obj2; IF obj1 # obj2 THEN BEGIN dSource _ dSource + sourceChars; dObj1 _ dObj1 + obj1; dObj2 _ dObj2 + obj2; END; REPEAT unequalNames => { WriteChar[CR]; WriteString[token1]; WriteString[" (from 1) and "]; WriteString[token2]; WriteLine[" (from 2) should be equal"]}; ENDLOOP; in1.destroy[in1]; in2.destroy[in2]; LJ["", 35]; Results[tSource, tObj1, tObj2]; LJ["", 35]; Results[dSource, dObj1, dObj2]; beforeFile.length _ 0; StringDefs.AppendString[beforeFile, afterFile]; EXITS badFormat => WriteLine[" can't find start of stats"]; cantFind => WriteLine[" file not found"]; END; ENDLOOP; END; SetUpCommands[]; DoIt[]; END.