MCrossRefOutput.mesa
kap&wsh 16-Mar-80 13:12
pdr September 20, 1982 1:09 pm
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: BOOLEANFALSE;
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
Here to print the XRef;
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.ROPENIL;
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.