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