MobErrors.mesa
Copyright Ó 1985, 1989, 1991, 1992 by Xerox Corporation. All rights reserved.
Satterthwaite on May 20, 1986 4:19:33 pm PDT
Lewis on 23-Jan-81 10:41:54
Maxwell, August 4, 1983 11:25 am
Paul Rovner, September 22, 1983 10:11 pm
Russ Atkinson (RRA) March 7, 1985 0:14:19 am PST
Andy Litman May 31, 1988 8:03:11 pm PDT
JKF July 22, 1989 3:47:26 pm PDT
DIRECTORY
Alloc USING [Bounds],
Ascii USING [CR, LF],
MobComData USING [data],
MobControlDefs USING [nullSourceIndex],
MobDefs USING [FTIndex, FTNull, fttype, MTIndex, MTNull, mttype, NameRecord, NullName, sstype, sttype, VersionStamp, NullVersion, Link],
MobErrorDefs USING [ErrorClass, InterfaceId, ExportItemName, ImportItemName],
ConvertUnsafe USING [SubString, ToRope],
MobHashOps USING [SubStringForHash],
IO USING [card, EndOfStream, GetChar, PutChar, PutF1, PutRope, SetIndex, STREAM],
Rope USING [ROPE],
MobSymbols USING [HTIndex, HTNull, STIndex, stNull],
Table USING [Base];
MobErrors: PROGRAM
IMPORTS Alloc, MobErrorDefs, ConvertUnsafe, MobHashOps, IO, MobComData
EXPORTS MobErrorDefs = {
OPEN MobSymbols, MobDefs, MobErrorDefs, MobComData;
SubString: TYPE~ConvertUnsafe.SubString;
GetModule: PUBLIC SIGNAL RETURNS[errorMti: MTIndex, linkOffset: CARDINAL, link: MobDefs.Link] ~ CODE;
GetSti: PUBLIC SIGNAL RETURNS[errorSti: STIndex] ~ CODE;
StreamIndex: TYPE~INT; -- FileStream.FileByteIndex
PrintTextLine: PROC[origin: StreamIndex] ~ {
start, lineIndex: StreamIndex ¬ origin;
char: CHAR;
THROUGH [1..100] UNTIL lineIndex=0 DO
lineIndex ¬ lineIndex-1;
(data.sourceStream).SetIndex[lineIndex];
char ¬ (data.sourceStream).GetChar[];
IF char = Ascii.CR OR char = Ascii.LF THEN EXIT;
start ¬ lineIndex;
ENDLOOP;
(data.sourceStream).SetIndex[start];
THROUGH [1..100] DO
char ¬ (data.sourceStream).GetChar[ ! IO.EndOfStream => EXIT];
SELECT char FROM
Ascii.CR, Ascii.LF, '\032 => EXIT;
ENDCASE => (data.errorStream).PutChar[char];
ENDLOOP;
WriteCR[data.errorStream]; RETURN};
WriteCR: PROC[stream: IO.STREAM] = {
IO.PutChar[stream, '\012]};
WriteChar: PROC[char: CHAR] ~ INLINE {(data.errorStream).PutChar[char]};
WriteRope: PROC[s: Rope.ROPE] ~ {(data.errorStream).PutRope[s]};
WriteString: PROC[s: STRING] ~ {(data.errorStream).PutRope[ConvertUnsafe.ToRope[s]]};
Space: PROC ~ INLINE {(data.errorStream).PutChar[' ]};
ErrorLog: PROC [class: ErrorClass] ~ {
IF data.textIndex # MobControlDefs.nullSourceIndex THEN {
WriteRope[", at "];
WriteName[data.currentName];
(data.errorStream).PutF1["[%d]", IO.card[data.textIndex]];
WriteCR[data.errorStream];
PrintTextLine[data.textIndex]};
SELECT class FROM
$error => {data.errors ¬ TRUE; data.nErrors ¬ data.nErrors+1};
$warning => {data.warnings ¬ TRUE; data.nWarnings ¬ data.nWarnings+1};
ENDCASE};
Prefix: PROC [class: ErrorClass] ~ {
WriteCR[data.errorStream];
IF class = $warning THEN WriteRope["Warning: "]};
WriteNameBase: PROC [name: NameRecord, s: LONG STRING] ~ {
offset: CARDINAL~name+1;
length: CARDINAL~s[name].ORD;
IF (offset + length) > s.length THEN RETURN;
FOR i: CARDINAL IN [offset..offset+MIN[length,100]) DO WriteChar[s.text[i]] ENDLOOP};
WriteName: PROC [name: NameRecord] ~ {
WriteNameBase[name, Alloc.Bounds[data.table, sstype].base]};
WriteVersion: PROC [v: VersionStamp, paren: BOOL¬FALSE] ~ {
IF paren THEN WriteRope["(version "];
IF v = MobDefs.NullVersion THEN WriteRope["<null version>"]
ELSE {
StampDigits: CARDINAL ~ 2*VersionStamp.BYTES;
str: PACKED ARRAY [0..StampDigits) OF [0..16) ~ LOOPHOLE[v];
digit: STRING~"0123456789abcdef";
WriteChar['"];
FOR i: NAT IN [0..StampDigits) DO WriteChar[digit[str[i]]] ENDLOOP;
WriteChar['"]};
IF paren THEN WriteChar[')]};
WriteHti: PROC [hti: HTIndex] ~ {
IF hti # HTNull THEN {
ss: SubString;
ss ¬ MobHashOps.SubStringForHash[hti];
FOR i: CARDINAL IN [ss.offset..ss.offset+ss.length) DO WriteChar[ss.base[i]] ENDLOOP}};
HtiForSti: PROC [sti: STIndex] RETURNS [HTIndex] ~ {
RETURN [IF sti = stNull THEN HTNull ELSE (data.table).Bounds[sttype].base[sti].hti]};
ModuleName: PROC [mti: MTIndex] RETURNS [NameRecord] ~ {
RETURN [IF mti = MTNull THEN NullName ELSE (data.table).Bounds[mttype].base[mti].name]};
Error: PUBLIC PROC [class: ErrorClass, s: STRING] ~ {
Prefix[class]; WriteString[s];
ErrorLog[class]};
ErrorSti: PUBLIC PROC [class: ErrorClass, s: STRING, sti: STIndex] ~ {
Prefix[class]; WriteHti[HtiForSti[sti]]; Space[]; WriteString[s];
ErrorLog[class]};
ErrorHti: PUBLIC PROC [class: ErrorClass, s: STRING, hti: HTIndex] ~ {
sti: STIndex~(SIGNAL GetSti[]);
Prefix[class]; WriteHti[hti]; Space[]; WriteString[s];
IF sti # stNull THEN {WriteRope[" (in "]; WriteHti[HtiForSti[sti]]; WriteChar[')]};
ErrorLog[class]};
ErrorName: PUBLIC PROC [class: ErrorClass, s: STRING, name: NameRecord] ~ {
Prefix[class];
WriteName[name]; Space[]; WriteString[s];
ErrorLog[class]};
ErrorItem: PUBLIC PROC [class: ErrorClass, s: STRING, export: InterfaceId, ep: CARDINAL] ~ {
sti: STIndex~(SIGNAL GetSti[]);
printed: BOOL¬FALSE;
ftb: Table.Base~(data.table).Bounds[fttype].base;
PrintItem: PROC [s: SubString] ~ {
FOR i: CARDINAL IN [s.offset .. s.offset+s.length) DO WriteChar[s.base[i]] ENDLOOP;
printed ¬ TRUE};
Prefix[class];
MobErrorDefs.ExportItemName[export~export, ep~ep, userProc~PrintItem];
IF ~printed THEN (data.errorStream).PutF1["(item %d)", IO.card[ep]];
WriteRope[" in interface "];
IF export.name # NullName THEN WriteName[export.name]
ELSE IF export.fti # FTNull THEN {WriteRope["from file "]; WriteName[ftb[export.fti].name]}
ELSE WriteRope["(unknown)"];
Space[]; WriteString[s];
IF sti # stNull THEN {WriteRope[" (in "]; WriteHti[HtiForSti[sti]]; WriteChar[')]};
ErrorLog[class]};
ErrorModule: PUBLIC PROC [class: ErrorClass, s: STRING, mti: MTIndex] ~ {
sti: STIndex~(SIGNAL GetSti[]);
Prefix[class]; WriteName[ModuleName[mti]]; Space[]; WriteString[s];
IF sti # stNull THEN {WriteRope[" (in "]; WriteHti[HtiForSti[sti]]; WriteChar[')]};
ErrorLog[class]};
ErrorInterface: PUBLIC PROC [
class: ErrorClass, s: STRING, import: InterfaceId, ep: CARDINAL] ~ {
mti: MTIndex;
linkOffset: CARDINAL;
link: MobDefs.Link;
printed: BOOL¬FALSE;
ftb: Table.Base~(data.table).Bounds[fttype].base;
PrintItem: PROC [s: SubString] ~ {
FOR i: CARDINAL IN [s.offset .. s.offset+s.length) DO WriteChar[s.base[i]] ENDLOOP;
printed ¬ TRUE};
[mti, linkOffset, link] ¬ SIGNAL GetModule[];
Prefix[class];
IF mti # MTNull THEN
MobErrorDefs.ImportItemName[
import~import, ep~ep,
clientMti~mti, linkOffset~linkOffset, link~link,
userProc~PrintItem];
IF ~printed THEN (data.errorStream).PutF1["(item %d)", IO.card[ep]];
WriteRope[" from "];
IF import.name # NullName THEN WriteName[import.name]
ELSE IF import.fti # FTNull THEN {
WriteRope[" file "]; WriteName[ftb[import.fti].name]}
ELSE WriteRope["(unknown)"];
Space[]; WriteString[s];
IF mti # MTNull THEN {
WriteRope[" (imported by "]; WriteName[ModuleName[mti]]; WriteChar[')]};
ErrorLog[class]};
ErrorNameBase: PUBLIC PROC [
class: ErrorClass, s: STRING, name: NameRecord, base: LONG STRING] ~ {
Prefix[class]; WriteNameBase[name, base]; Space[]; WriteString[s];
ErrorLog[class]};
Error2Versions: PUBLIC PROC [
class: ErrorClass, fileName: NameRecord, v1, v2: VersionStamp] ~ {
ftb: Table.Base~(data.table).Bounds[fttype].base;
Prefix[class];
WriteName[fileName];
WriteRope[" is referenced in two versions: "];
WriteVersion[v1]; WriteRope[" and "]; WriteVersion[v2];
ErrorLog[class]};
ErrorFile: PUBLIC PROC [class: ErrorClass, s: STRING, fti: FTIndex] ~ {
ftb: Table.Base~(data.table).Bounds[fttype].base;
Prefix[class]; WriteName[ftb[fti].name]; Space[]; WriteString[s];
ErrorLog[class]};
Error2Files: PUBLIC PROC [class: ErrorClass, s: STRING, ft1, ft2: FTIndex] ~ {
ftb: Table.Base~(data.table).Bounds[fttype].base;
Prefix[class];
WriteName[ftb[ft1].name]; WriteVersion[ftb[ft1].version, TRUE];
Space[]; WriteString[s]; Space[];
WriteName[ftb[ft2].name]; WriteVersion[ftb[ft2].version, TRUE];
ErrorLog[class]};
}.