<> <> <> DIRECTORY Ascii USING[CR], Atom USING[GetPName], Basics USING[LowHalf], FS USING[StreamOpen], IO USING[STREAM, PutChar, Close, Put, card, PutRope, int, PutR], MCrossRefDefs, MCrossSorter USING[Enumerate], Rope USING[ROPE, Size, Fetch, Concat]; <<---------------------------------------------------------------->> MCrossRefOutput: PROGRAM IMPORTS Atom, FS, Rope, Basics, IO, MCrossSorter EXPORTS MCrossRefDefs = BEGIN OPEN MCrossRefDefs; outputStream: IO.STREAM _ 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.STREAM; SetMCrossOutputStream: PUBLIC PROC[fileName: Rope.ROPE] = { outputFileName _ originalOutputFileName _ fileName; outputStream _ FS.StreamOpen[fileName: outputFileName, accessOptions: create]; linesInThisOutputFile _ 0; }; SetNextMCrossOutputStream: PROC = {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, IO.PutR[IO.int[thisExtension]]]; outputStream _ FS.StreamOpen[fileName: outputFileName, accessOptions: create]; linesInThisOutputFile _ 0; IO.PutRope[execTS, outputFileName]; IO.PutRope[execTS, "\n"]}; DestroyMCrossOutputStream: PUBLIC PROC = {IO.Close[outputStream]; outputStream _ NIL}; OutputLine: PUBLIC PROC [s: Rope.ROPE] = {OutputString[s]; outputStream.PutChar[Ascii.CR]; linesInThisOutputFile _ linesInThisOutputFile + 1}; OutputString: PUBLIC PROC [s: Rope.ROPE] = {FOR i: INT IN [0..Rope.Size[s]) DO outputStream.PutChar[Rope.Fetch[s,i]]; ENDLOOP}; OutputChar: PUBLIC PROC [ch: CHARACTER] = {outputStream.PutChar[ch]}; OutputRefCoord: PUBLIC PROC [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 <> PrintXREF: PUBLIC PROC[tsStream: IO.STREAM] = { 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 _ Basics.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, IO.PutR[IO.int[thisExtension + 1]]]; OutputLine[nextOutputFileName]; SetNextMCrossOutputStream[]; OutputLine[""]; OutputLine[""]; OutputString[" ***** Cross Reference continued from "]; IF thisExtension = 1 THEN nextOutputFileName _ originalOutputFileName ELSE nextOutputFileName _ Rope.Concat[originalOutputFileName, IO.PutR[IO.int[thisExtension - 1]]]; OutputLine[nextOutputFileName]; OutputLine[""]; OutputLine[""]; OutputLine[""]}; RETURN[FALSE]}; END.