-- File: [Cherry]<Thyme>System>C03>spErrors.mesa
-- Last editted:
-- Wilhelm March 30, 1982  8:36 AM, reformated by Barth and stored under
--   [Cherry]<Barth>Thyme>1.97> .
DIRECTORY spGlobals, CWF, IODefs, StreamDefs, StringDefs;
spErrors:  PROGRAM
  IMPORTS spGlobals, CWF, StreamDefs, StringDefs
  EXPORTS spGlobals =
  BEGIN
    OPEN spGlobals;

    ErrorSignal:  PUBLIC SIGNAL[error:  CARDINAL, s:  LONG STRING] = CODE;

    errCount:    CARDINAL ← 0;

    errMsgFile:  StreamDefs.StreamHandle ← NIL;
    triedOnce:   BOOLEAN ← FALSE;

    AnyErrors:  PUBLIC PROCEDURE RETURNS[BOOLEAN] =
      BEGIN
        RETURN[errCount > 0]
      END;

    printError:  PROCEDURE[err:  CARDINAL, warning:  BOOLEAN ← FALSE] =
      BEGIN
        errMsg:    STRING = [256];
        char:      CHARACTER;
        number:    CARDINAL ← 0;
        nonBlank:  BOOLEAN;
        first:     CARDINAL;

        IF errMsgFile = NIL AND ~triedOnce THEN
          BEGIN
            ENABLE StreamDefs.FileNameError =>
              BEGIN
                printSysWindow["Can't open thyme.errors."];
                errMsgFile ← NIL;
                triedOnce ← TRUE;
                GO TO out
              END;
            errMsgFile ← StreamDefs.NewByteStream["thyme.errors",
                                                  StreamDefs.Read]
          EXITS
            out => NULL
          END;
        errMsg.length ← 0;
        IF warning THEN
          BEGIN
            first ← 8;
            StringDefs.AppendString[errMsg, "Warning "]
          END
        ELSE
          BEGIN
            errCount ← errCount + 1;
            first ← 6;
            StringDefs.AppendString[errMsg, "Error "]
          END;
        IF errMsgFile # NIL THEN
          BEGIN
            errMsgFile.reset[errMsgFile];
            UNTIL number = err OR errMsgFile.endof[errMsgFile] DO
              errMsg.length ← first;
              char ← ' ;
              nonBlank ← FALSE;
              UNTIL char = IODefs.CR OR errMsgFile.endof[errMsgFile] DO
                char ← errMsgFile.get[errMsgFile];
                IF (char = ' OR char = IODefs.TAB)AND ~nonBlank THEN LOOP
                ELSE nonBlank ← TRUE;
                errMsg[errMsg.length] ← char;
                errMsg.length ← errMsg.length + 1
              ENDLOOP;
              number ← 0;
              FOR index:  CARDINAL IN [first..errMsg.length) DO
                char ← errMsg[index];
                IF char IN ['0..'9] THEN number ← number*10 + (char - '0)
                ELSE EXIT
              ENDLOOP
            ENDLOOP
          END;
        IF errMsgFile = NIL OR number # err THEN
          CWF.SWF1[errMsg, "Error %d.*n", @err];
        printSysWindow[errMsg];
      END;

    ErrorAtNB:  PUBLIC PROCEDURE[err:  CARDINAL, n:  nodePtr, b:  branchPtr]=
      BEGIN
        printSysWindow[makeStringNB[n, b, FALSE]];
        printError[err]
      END;

    ErrorStrings:  PUBLIC PROCEDURE[err:  CARDINAL, s1, s2:  LONG STRING] =
      BEGIN
        errLine:  STRING = [256];

        IF s2 = NIL THEN CWF.SWF1[errLine, "%s", s1]
        ELSE CWF.SWF2[errLine, "%s at %s", s1, s2];
        printSysWindow[errLine];
        printError[err]
      END;

    error:  PUBLIC PROCEDURE[err:  CARDINAL,
                             skip, warning:  BOOLEAN ← FALSE] =
      BEGIN
        i, cptr:  CARDINAL;
        errLine:  STRING = [256];
        line:     STRING;

        [line, cptr] ← GetLineAndCptr[];
        IF cptr > 0 THEN cptr ← cptr - 1;
        FOR i IN [0..cptr) DO
          errLine[i] ← line[i]
        ENDLOOP;
        errLine[cptr]     ← '<;
        errLine[cptr + 1] ← '>;
        FOR i IN [cptr..line.length) DO
          errLine[i + 2] ← line[i]
        ENDLOOP;
        errLine.length ← line.length + 2;
        IF errLine.length > 0 THEN
          IF errLine[errLine.length - 1] = IODefs.CR THEN
            errLine.length ← errLine.length - 1;
        printSysWindow[errLine];
        printError[err, warning];
        IF skip THEN 
          UNTIL item = semi OR item = eof OR item = rightC OR
                item = leftC DO
            next[]
          ENDLOOP
      END;

    error2:  PUBLIC PROCEDURE[err:  CARDINAL, n:  namePtr] =
      BEGIN
        errLine:  STRING = [256];

        CWF.SWF1[errLine, "%s", n↑.name];
        printSysWindow[errLine];
        printError[err];
      END;

  END.