Program FindPasOrAsmError;

Uses
  Dos;

{ Error message filter.  This version supports the following:           }
{                                                                       }
{       Turbo Pascal                                                    }
{       Turbo Assembler                                                 }
{       Turbo C++                                                       }
{       Turbo Link                                                      }
{       Microsoft Macro Assembler 5.1                                   }
{       QuikByte Pascal & Linker                                        }
{        and possibly all Microsoft command line compilers              }

{ The output MUST go to the standard output device.  If the CRT unit is }
{ used the output will go directly to the screen or through the BIOS,   }
{ and not to the standard output.  XP will not be able to locate the    }
{ error messages if that occures.                                       }

Var
  Source : Text;
  Line   : String;
  Index  : Integer;
  FileName : String;
  LineNo   : String;
  Column   : Integer;
  Message  : String;
  Buffer   : Array[1..1024] of Char;
  Done     : Boolean;

Function Trim(Line : String) : String;

Begin
  While (Line[1] = ' ') AND (Length(Line) > 0) Do Delete(Line,1,1);
  While Line[Length(Line)] = ' ' Do Dec(Line[0]);
  Trim := Line;
End;

Procedure TurboPasFile;

Const
  ErrorStr = 'Error';

Begin
  Repeat
    ReadLn(Source,Line);
    Index := Pos(^M,Line);
    While Index > 0 Do
    Begin
      Delete(Line,1,Index);
      Index := Pos(^M,Line);
    End;
    Index := Pos(ErrorStr,Line);
  Until (Index <> 0) OR Eof(Source);
  If Index <> 0 THEN
  BEGIN
    Index := Pos('(',Line);
    If (Index = 0) or (Index > Pos(ErrorStr,Line))
      Then Writeln(', 0, 0, ',Line)
    Else Begin
      FileName := Copy(Line,1,Pred(Index));
      Delete(Line,1,Index);
      Index := Pos(')',Line);
      LineNo := Copy(Line,1,Pred(Index));
      Delete(Line,1,Index+2);
      Message := Line;
      ReadLn(Source,Line);
      ReadLn(Source,Line);
      Column := Pos('^',Line);
      WriteLn(FileName,',',LineNo,',',Column,',',Message);
    End;
  END;
End;

Procedure TurboAsmFile;

Const
  Errors : Array[1..3] of String[9] = ('**Error**','*Warning*','**Fatal**');

Var
  Loop : Integer;
  Temp : String;

Begin
  While Not Eof(Source) Do
  Begin
    Repeat
      ReadLn(Source,Line);
      Index := Pos(^M,Line);
      While Index > 0 Do
      Begin
        Delete(Line,1,Index);
        Index := Pos(^M,Line);
      End;
      Loop := 1;
      Repeat
        Index := Pos(Errors[Loop],Line);
        If Index = 0
          Then Inc(Loop)
        Else Begin
          Temp := Copy(Line,1,Length(Errors[Loop]));
          If Index > 1 Then Delete(Temp,1,Pred(Index));
          Delete(Line,1,Succ(Length(Errors[Loop])));
          Loop := 4;
        End;
      Until (Loop > 3) Or Eof(Source);
    Until (Index <> 0) OR Eof(Source);
    If Index <> 0 THEN
    BEGIN
      Index := Pos('(',Line);
      If Index = 0
        Then Begin
          FileName := '';
          LineNo := '0';
          Column := 0;
          Message := Trim(Line);
        End
      Else Begin
        FileName := Copy(Line,1,Pred(Index));
        Delete(Line,1,Index);
        Index := Pos(')',Line);
        LineNo := Copy(Line,1,Pred(Index));
        Delete(Line,1,Succ(Index));
        Message := Line;
        Column := 0;
      End;
      WriteLn(FileName,',',LineNo,',',Column,',',Temp,' ',Message);
    End;
  END;
End;

Procedure QuickBytePascal;

Begin
  Line := '';
  While (Not Eof(Source)) AND (Pos('QBPERR.EXE',Line) = 0) Do ReadLn(Source,Line);
  If Eof(Source) Then Halt;
  While Not Eof(Source) Do
  Begin
    ReadLn(Source,LIne);
    If Pos('):',Line) > 0 Then
    Begin
      Index := Pos('(',Line);
      Message := Copy(Line,1,Pred(Index)) + ', ';
      Delete(Line,1,Index);
      Index := Pos(')',Line);
      Message := Message + Copy(Line,1,Pred(Index)) + ', 1, ';
      Delete(Line,1,Index + 2);
      WriteLn(Message,Line);
    End;
  End;
End;

Procedure Microsoft;

Begin
  While Not Eof(Source) Do
  Begin
    ReadLn(Source,Line);
    If Pos('LINK :',Line) = 1
      Then WriteLn(',0,0,',Line)
    Else If Pos('):',Line) > 0 Then
    Begin
      Index := Pos('(',Line);
      Message := Copy(Line,1,Pred(Index)) + ', ';
      Delete(Line,1,Index);
      Index := Pos(')',Line);
      Message := Message + Copy(Line,1,Pred(Index)) + ', 1, ';
      Delete(Line,1,Index + 2);
      WriteLn(Message,Line);
    End;
  End;
End;

Procedure TurboLink;

Var
  Temp : String;

Const
  Errors  : Array[1..3] of String[8] = ('Error:','Fatal:','Warning:');

Begin
  While Not Eof(Source) Do
  Begin
    ReadLn(Source,Line);
    Index := 0;
    Repeat
      Inc(Index);
    Until (Pos(Errors[Index],Line) <> 0) Or (Index > 3);
    If Index <= 3 Then WriteLn(' , 0, 0, ',Line);
  End;
End;

Procedure TurboC_PlusPlus;

Const
  MaxErrMsg = 2;
  Errors  : Array[1..MaxErrMsg] of String[7] = ('Error','Warning');
  NewError: Array[1..MaxErrMsg] of String[9] = ('**Error**','*Warning*');

Var
  Index, Loop : Integer;
  Temp : String;
  IsError : Boolean;

Begin
  While Not Eof(Source) Do
    Begin
      Repeat
        ReadLn(Source,Line);
        If Pos('Turbo Link',Line) = 1 Then
        Begin
          TurboLink;
          Exit;
        End;
        Index := Pos(' ',Line);
        Temp := Copy(Line,1,Index-1);
        IsError := False;
        Loop := 1;
        While (Not IsError) AND (Loop <= MaxErrMsg) Do
          If Temp = Errors[Loop] Then
            IsError := True
          Else
            Inc(Loop);
        If IsError Then
          Begin
            Delete(Line,1,Index);
            Line := Trim(Line);
            Index := Pos(' ',Line);
            If Index > 0 Then
            Begin
              Temp := Copy(Line,1,Pred(Index)) + ', ';
              Delete(Line,1,Index);
              Index := Pos(':',Line);
              Temp := Temp + Copy(Line,1,Pred(Index)) + ', 0, ';
              Delete(Line,1,Index);
              Writeln(Temp,Trim(Line));
            End;
          End;
      Until Eof(Source);
    End;
End;

Begin
  If ParamCount = 0 Then Halt;
  Assign(Source,ParamStr(ParamCount));
  SetTextBuf(Source,Buffer);
  {$I-}
  Reset(Source);
  {$I-}
  If IoResult <> 0 Then
  Begin
    WriteLn(', , , Error in FERROR when opening file!');
    Halt(1);
  End;
  Repeat
    Done := True;
    ReadLn(Source,Line);
    If Pos('Turbo Pascal',Line) <> 0             { Turbo Pascal       }
      Then TurboPasFile
    Else If Pos('Turbo Assembler',Line) <> 0     { Turbo Assembler    }
      Then TurboAsmFile
    Else If Pos('QuikByte Pascal',Line) <> 0     { Quick Byte Pascal  }
      Then QuickBytePascal
    Else If Pos('Macro Assembler',Line) <> 0     { Microsoft MASM     }
      Then Microsoft
    Else If Pos('Turbo C',Line) <> 0           { Turbo C/C++        }
      Then TurboC_PlusPlus
    Else If Pos('Turbo Link',Line) <> 0          { Turbo Link         }
      Then TurboLink
    Else If Pos('Microsoft',Line) <> 0           { All Microsoft?     }
      Then Microsoft
    Else Done := False;
  Until Done or Eof(Source);
  If Not Done Then WriteLn(', , , Unrecognized compiler output!');
  If TextRec(Source).Mode = FmInput Then Close(Source);
End.
