-- MCrossRefOutput.mesa -- kap&wsh 16-Mar-80 13:12 -- pdr September 20, 1982 1:09 pm DIRECTORY Ascii USING[CR], Atom USING[GetPName], FileIO USING[Open], IO USING[Handle, PutChar, Close, Put, card, PutRope], Convert USING[ValueToRope], Inline USING[LowHalf], MCrossRefDefs, MCrossSorter USING[Enumerate], Rope USING[ROPE, Size, Fetch, Concat]; ------------------------------------------------------------------ MCrossRefOutput: PROGRAM IMPORTS Atom, FileIO, IO, Convert, Inline, MCrossSorter, Rope EXPORTS MCrossRefDefs = BEGIN OPEN MCrossRefDefs; outputStream: IO.Handle ← NIL; linePosition: CARDINAL ← 0; linesTabPosition: CARDINAL ← 0; tabPosition: PUBLIC CARDINAL; CurrentPageNumber: CARDINAL ← 0; WantNewLine: BOOLEAN ← FALSE; originalOutputFileName: Rope.ROPE; outputFileName: Rope.ROPE; maxLinesPerOutputFile: LONG CARDINAL = 7000; linesInThisOutputFile: LONG CARDINAL; thisExtension: CARDINAL ← 0; execTS: IO.Handle; SetMCrossOutputStream: PUBLIC PROCEDURE[fileName: Rope.ROPE] = {outputFileName ← originalOutputFileName ← fileName; outputStream ← FileIO.Open [fileName: outputFileName, accessOptions: overwrite]; linesInThisOutputFile ← 0}; SetNextMCrossOutputStream: PROCEDURE = {IF thisExtension = 0 THEN IO.PutRope[execTS, "\n"]; IO.PutRope[execTS, "***** "]; IO.PutRope[execTS, outputFileName]; IO.PutRope[execTS, " is filled. The "]; IF thisExtension # 0 THEN IO.PutRope[execTS, "next "]; IO.PutRope[execTS, "overflow file is named "]; thisExtension ← thisExtension + 1; DestroyMCrossOutputStream[]; outputFileName ← Rope.Concat[originalOutputFileName, Convert.ValueToRope[[signed[signed: thisExtension]]]]; outputStream ← FileIO.Open [fileName: outputFileName, accessOptions: overwrite]; linesInThisOutputFile ← 0; IO.PutRope[execTS, outputFileName]; IO.PutRope[execTS, "\n"]}; DestroyMCrossOutputStream: PUBLIC PROCEDURE = {IO.Close[outputStream]; outputStream ← NIL}; OutputLine: PUBLIC PROCEDURE [s: Rope.ROPE] = {OutputString[s]; outputStream.PutChar[Ascii.CR]; linesInThisOutputFile ← linesInThisOutputFile + 1}; OutputString: PUBLIC PROCEDURE [s: Rope.ROPE] = {FOR i: INT IN [0..Rope.Size[s]) DO outputStream.PutChar[Rope.Fetch[s,i]]; ENDLOOP}; OutputChar: PUBLIC PROCEDURE [ch: CHARACTER] = {outputStream.PutChar[ch]}; OutputRefCoord: PUBLIC PROCEDURE [coord: Coord] = {ln: LineNumberRange ← coord.ln; page: CARDINAL ← (ln-1)/Gacha8linesPerPage + 1; line: CARDINAL ← ln MOD Gacha8linesPerPage; NumberSize: CARDINAL ← 0; stringPosition : CARDINAL ← 0; i : CARDINAL← 0; -- loop index for spacing IF line = 0 THEN line ← Gacha8linesPerPage;--fix up MOD hiccup IF CurrentPageNumber # page THEN {IF CurrentPageNumber # 0 THEN {OutputLine[""]; FOR i IN [0..tabPosition) DO OutputChar[' ]; ENDLOOP}; WantNewLine ← FALSE; -- wipe out old value linePosition ← tabPosition; OutputString["Page: "]; CurrentPageNumber ← page; NumberSize ← SELECT page FROM IN [0..9] => 1, IN [10..99] => 2, IN [100..999] => 3, ENDCASE => 4; linesTabPosition ← stringPosition ← NumberSize + 14; IO.Put[outputStream, IO.card[page]]; OutputString[" Lines: "]} ELSE -- not a new page number { IF WantNewLine THEN {OutputLine[""]; linePosition ← tabPosition + linesTabPosition; FOR i IN [0..linePosition) DO OutputChar[' ] ENDLOOP; WantNewLine ← FALSE} ELSE {stringPosition ← stringPosition + 2; OutputString[", "]}}; NumberSize ← SELECT line FROM IN [0..9] => 1, IN [10..99] => 2, ENDCASE => 3; stringPosition ← stringPosition + NumberSize; IO.Put[outputStream, IO.card[line]]; IF coord.defn THEN {OutputString["[D]"]; stringPosition ← stringPosition + 3}; linePosition ← linePosition + stringPosition; IF linePosition + stringPosition >= Gacha8charsPerLine THEN WantNewLine ← TRUE}; -- END OutputRefCoord -- Here to print the XRef; PrintXREF: PUBLIC PROCEDURE[tsStream: IO.Handle] = { execTS ← tsStream; OutputLine[""]; OutputLine["***** Cross Reference *****"]; OutputLine[""]; [] ← MCrossSorter.Enumerate[OutputToken, increasing]}; OutputToken: PROC[t: TokenHandle] RETURNS[stop: BOOLEAN] = { f: fileNHandle; x: XRefHandle; OutputString[Atom.GetPName[t.name]]; FOR f ← t.fileNHead, f.next UNTIL f = NIL DO -- for each file fNameString: Rope.ROPE = Atom.GetPName[f.name]; OutputLine[""]; OutputString[" "]; -- indent file names OutputString[fNameString]; -- filename OutputString[": "]; linePosition ← Inline.LowHalf[Rope.Size[fNameString]] + 5; FOR j: CARDINAL IN [linePosition..tabPosition) DO OutputChar[' ]; ENDLOOP; CurrentPageNumber ← 0; -- force new page number FOR x ← f.xrefHead, x.next UNTIL x = NIL DO -- For each ref in a file FOR j: CARDINAL IN [1..x.nRefs] DO OutputRefCoord[x.coords[j]]; ENDLOOP; ENDLOOP; -- For each ref in a file ENDLOOP; -- for each file OutputLine[""]; IF linesInThisOutputFile >= maxLinesPerOutputFile THEN { nextOutputFileName: Rope.ROPE ← NIL; OutputLine[""]; OutputString[" ***** Cross Reference continued on "]; nextOutputFileName ← Rope.Concat[originalOutputFileName, Convert.ValueToRope[[signed[signed: thisExtension + 1]]]]; OutputLine[nextOutputFileName]; SetNextMCrossOutputStream[]; OutputLine[""]; OutputLine[""]; OutputString[" ***** Cross Reference continued from "]; IF thisExtension = 1 THEN nextOutputFileName ← originalOutputFileName ELSE nextOutputFileName ← Rope.Concat[originalOutputFileName, Convert.ValueToRope[[signed[signed: thisExtension - 1]]]]; OutputLine[nextOutputFileName]; OutputLine[""]; OutputLine[""]; OutputLine[""]}; RETURN[FALSE]}; END.