-- 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.