ExpertPageList.mesa
Christophe Cuenod April 13, 1989 4:31:55 pm PDT
Reads a .pinlist file and generates a .pagelist file (gives the pages where a ref des appears)
DIRECTORY
Basics USING [CompareInt, Comparison],
Commander USING [CommandProc, Register],
IO USING [BreakProc, Close, EndOf, GetLineRope, GetTokenRope, int, PutF, RIS, rope, STREAM],
ExpertPinRead USING [PinInfo, PinInfoList, PinTable, ReadPinFile],
FS USING [Error, FileInfo, StreamOpen],
List USING [Compare, CompareProc, Comparison, LORA, Merge, Sort, UniqueSort],
Rope USING [Cat, Compare, Equal, Fetch, Length, ROPE, Substr],
SymTab USING [Create, Fetch, EachPairAction, Pairs, Ref, Store];
ExpertPageList:
CEDAR
PROGRAM
IMPORTS Basics, Commander, ExpertPinRead, List, FS, IO, Rope, SymTab =
BEGIN
ROPE: TYPE = Rope.ROPE;
Entry: TYPE = REF EntryRep;
EntryRep:
TYPE =
RECORD [
refDes: ROPE,
part: ROPE
];
PartTable: TYPE = SymTab.Ref;
RefDesList: TYPE = List.LORA;
PageList: TYPE = List.LORA;
PositionTable: TYPE = SymTab.Ref;
RefInt: TYPE = REF INT;
TokenProc1:
IO.BreakProc ~ {
-- Takes any character different from SP for the name
IF char = ' THEN RETURN [sepr];
RETURN [other];
};
IsNext:
PROC [r1, r2:
ROPE]
RETURNS [next:
BOOL ←
FALSE] ~ {
comp: List.Comparison;
x1, x2, mul: INT;
len1: INT ← Rope.Length[r1];
len2: INT ← Rope.Length[r2];
x1 ← 0;
mul ← 1;
WHILE len1 # 0
AND '0 <= Rope.Fetch[r1, len1-1]
AND Rope.Fetch[r1, len1-1] <= '9
DO
x1 ← x1 + mul * (Rope.Fetch[r1, len1-1] - '0);
len1 ← len1 - 1;
mul ← mul * 10;
ENDLOOP;
x2 ← 0;
mul ← 1;
WHILE len2 # 0
AND '0 <= Rope.Fetch[r2, len2-1]
AND Rope.Fetch[r2, len2-1] <= '9
DO
x2 ← x2 + mul * (Rope.Fetch[r2, len2-1] - '0);
len2 ← len2 - 1;
mul ← mul * 10;
ENDLOOP;
r1 ← Rope.Substr[r1, 0, len1];
r2 ← Rope.Substr[r2, 0, len2];
comp ← Rope.Compare[r1, r2, FALSE];
IF comp # equal THEN RETURN;
IF (x1 + 1) = x2 THEN next ← TRUE;
};
Compare: List.CompareProc ~ {
comp: List.Comparison;
x1, x2, mul: INT;
r1, r2: ROPE;
len1, len2: INT;
IF
ISTYPE[ref1, Entry]
THEN {
entry1: Entry ← NARROW[ref1];
entry2: Entry ← NARROW[ref2];
RETURN Compare[entry1.refDes, entry2.refDes];
};
r1 ← NARROW[ref1];
r2 ← NARROW[ref2];
len1 ← Rope.Length[r1];
len2 ← Rope.Length[r2];
x1 ← 0;
mul ← 1;
WHILE len1 # 0
AND '0 <= Rope.Fetch[r1, len1-1]
AND Rope.Fetch[r1, len1-1] <= '9
DO
x1 ← x1 + mul * (Rope.Fetch[r1, len1-1] - '0);
len1 ← len1 - 1;
mul ← mul * 10;
ENDLOOP;
x2 ← 0;
mul ← 1;
WHILE len2 # 0
AND '0 <= Rope.Fetch[r2, len2-1]
AND Rope.Fetch[r2, len2-1] <= '9
DO
x2 ← x2 + mul * (Rope.Fetch[r2, len2-1] - '0);
len2 ← len2 - 1;
mul ← mul * 10;
ENDLOOP;
r1 ← Rope.Substr[r1, 0, len1];
r2 ← Rope.Substr[r2, 0, len2];
comp ← Rope.Compare[r1, r2, FALSE];
IF comp # equal THEN RETURN Rope.Compare[r1, r2, FALSE];
RETURN Basics.CompareInt[x1, x2];
};
ReadPartFile:
PROC [file:
ROPE]
RETURNS [completeEntryList: List.
LORA] ~ {
x: List.LORA;
line, refDes: ROPE;
inLine: IO.STREAM;
in: IO.STREAM ← FS.StreamOpen[file];
x ← NIL;
WHILE
NOT
IO.EndOf[in]
DO
line ← IO.GetLineRope[in];
inLine ← IO.RIS[line];
refDes ← IO.GetTokenRope[inLine, TokenProc1].token;
x ← CONS[refDes, x];
ENDLOOP;
completeEntryList ← List.Sort[x, Compare];
};
Merge:
PROC [pageList: PageList, page:
INT]
RETURNS [newPageList: PageList] ~ {
tempPageList, tempPageList2: PageList;
refPage: RefInt ← NEW [INT];
refPage^ ← page;
tempPageList ← CONS[refPage, NIL];
tempPageList2 ← List.Merge[pageList, tempPageList, List.Compare];
newPageList ← List.UniqueSort[tempPageList2];
};
ExpertPageListProc: Commander.CommandProc =
BEGIN
FileExistence:
PROC [fileName:
ROPE]
RETURNS [found:
BOOLEAN ←
TRUE] ~ {
[] ←
FS.FileInfo[fileName !
FS.Error => {
IF error.group = user
THEN {
IO.PutF[cmd.out, "%g\n", IO.rope[error.explanation]];
found ← FALSE;
CONTINUE;
};
}];
};
Pages: SymTab.EachPairAction ~ {
FOR l: ExpertPinRead.PinInfoList ←
NARROW[val], l.rest
UNTIL l =
NIL
DO
newPageList: PageList;
pinInfo: ExpertPinRead.PinInfo ← l.first;
refDes: ROPE ← pinInfo.refDes;
pageNumber: INT ← pinInfo.pageNumber;
IF SymTab.Fetch[positionTable, refDes].found
THEN {
pageList: PageList ← NARROW[SymTab.Fetch[positionTable, refDes].val];
newPageList ← Merge[pageList, pageNumber];
}
ELSE {
refPage: RefInt ← NEW [INT];
refPage^ ← pageNumber;
newPageList ← CONS[refPage, NIL];
};
[] ← SymTab.Store[positionTable, refDes, newPageList];
ENDLOOP;
};
out: IO.STREAM;
refDes, savedRefDes1, savedRefDes2: ROPE;
pageList: PageList;
refPage: RefInt;
page, savedPage, savedPage2: INT;
completeEntryList: List.LORA;
positionTable: PositionTable;
pinTable: ExpertPinRead.PinTable;
stream: IO.STREAM ← IO.RIS[cmd.commandLine];
file: ROPE ← IO.GetTokenRope[stream].token;
pinListFile: ROPE ← Rope.Cat[file, ".pinlist"];
partListFile: ROPE ← Rope.Cat[file, ".partlist"];
pageListFile: ROPE ← Rope.Cat[file, ".pagelist"];
IF NOT FileExistence[pinListFile] THEN GO TO fail;
IF NOT FileExistence[partListFile] THEN GO TO fail;
IO.PutF[cmd.out, "Reading %g\n", IO.rope[pinListFile]];
pinTable ← ExpertPinRead.ReadPinFile[pinListFile];
IO.PutF[cmd.out, "Reading %g\n", IO.rope[partListFile]];
completeEntryList ← ReadPartFile[partListFile];
IO.PutF[cmd.out, "Sorting the page numbers\n"];
positionTable ← SymTab.Create[];
[] ← SymTab.Pairs[pinTable, Pages];
IO.PutF[cmd.out, "Writing %g\n", IO.rope[pageListFile]];
out ← FS.StreamOpen[pageListFile, $create];
IO.PutF[out, "%g\n\tShows on which page each part appears\n\n", IO.rope[pageListFile]];
savedPage ← 0;
savedPage2 ← 0;
FOR l: List.
LORA ← completeEntryList, l.rest
UNTIL l =
NIL
DO
refDes ← NARROW[l.first];
pageList ← NARROW[SymTab.Fetch[positionTable, refDes].val];
refPage ← NARROW[pageList.first];
page ← refPage^;
IF page = savedPage
AND IsNext[savedRefDes2, refDes]
AND pageList.rest =
NIL
THEN {
savedRefDes2 ← refDes;
}
ELSE {
IF savedPage # 0
THEN {
IF Rope.Equal[savedRefDes1, savedRefDes2]
THEN {
IO.PutF[out, "%g\t\tpage %g", IO.rope[savedRefDes1], IO.int[savedPage]];
}
ELSE {
IO.PutF[out, "%g-%g\tpage %g", IO.rope[savedRefDes1], IO.rope[savedRefDes2], IO.int[savedPage]];
};
IF savedPage2 # 0
THEN {
IO.PutF[out, ", %g\n", IO.int[savedPage2]];
}
ELSE {
IO.PutF[out, "\n"];
};
};
savedRefDes1 ← refDes;
savedRefDes2 ← refDes;
savedPage ← page;
IF pageList.rest #
NIL
THEN {
refPage ← NARROW[pageList.rest.first];
savedPage2 ← refPage^;
}
ELSE {
savedPage2 ← 0;
};
};
ENDLOOP;
IF Rope.Equal[savedRefDes1, savedRefDes2]
THEN {
IO.PutF[out, "%g\t\tpage %g\n", IO.rope[savedRefDes1], IO.int[savedPage]];
}
ELSE {
IO.PutF[out, "%g-%g\tpage %g\n", IO.rope[savedRefDes1], IO.rope[savedRefDes2], IO.int[savedPage]];
};
IF savedPage2 # 0
THEN {
IO.PutF[out, ", %g\n", IO.int[savedPage2]];
}
ELSE {
IO.PutF[out, "\n"];
};
IO.Close[out];
EXITS fail => result ← $Failed;
END;
Commander.Register[
key: "ExpertPageList", proc: ExpertPageListProc, doc: "Read a .pinlist file and generates a .pagelist file\n"];
END.