/*
 *  MODULE  : error.c
{*  last modification:  10.11.92  16:04   }
 *  used for error reporting
 *  uli 06.03.91 : new style headers.
 *  uli 06.03.91 : ERRMESS changed to ERRmess
 *  uli 08.03.91 : ERRmess changed to errfnam()
 *  uli 16.04.91 : Fatal errors modified.
 *  uli 13.05.91 : <stdlib.h> included.
 *  uli 14.06.91 : Warnings of #expr added.
 *  uli 17.06.91 : checkerror deleted.
 *  uli 08.08.91 : Warning 172 added.
 *  uli 12.08.91 : Warning 173 added.
 *  uli 09.01.92 : ov_abort added.
 *  PJ  10.11.92 : on_print_check added.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include            "impor.t"
#include "option.h"
#include "sysutil.h"

#include            "expor.t"
#include "error.h"

#include            "implemen.t"

local FILE * errfile = NULL ;      /* error message file */

#ifdef LINT_ARGS
global void errput  ( short int errnr ,postype pos ,char * addstr )
#else
global void errput (errnr, pos, addstr)
short int errnr ;
postype pos ;
char * addstr ;
#endif
 BEGIN(errput)
   char * prefix ;
   char * cpy = NULL ;  /* copy of addstr */

   ++mescount ;
   if (errnr <  ERRORLIMIT and not on_warning)  return ;
   if (errnr >= FATALLIMIT)  prefix = "Fatal error" ; else

   if (errnr >= CHECKLIMIT)

   { /* PJ 10.11.92
           Option dependent check error message
     */

     if ( on_print_check ) prefix = "Check error"; else return;

     /* PJ 10.11.92 END */

   }
   else
     if (errnr >= ERRORLIMIT)  prefix = "Error" ; else
     if (errnr >= WARNGLIMIT)  prefix = "Warning" ; else
                               prefix = "Info" ;

   fprintf (lstfile, "%s %4d in line %4d col %2d  ",  prefix,
	    errnr, pos.line, pos.col ) ;

   if (errnr >= FATALLIMIT)
    switch (errnr)          /* display fatals */
     begin
       case 30000 :
	 fprintf (lstfile, "Insufficient memory. Compilation abort.\n");
       break ;
       case 30001 :
	 fprintf (lstfile,
	"Error in writing file %s  -- Probably disk is full. Compilation abort.\n",
	 addstr);
       break ;
       case 30002 :
	 fprintf (lstfile, "Cannot open file %s for writing.\n", addstr);
       break ;
       case 30003 :
	 fprintf (lstfile, "Cannot open Module %s\n", addstr);
       break ;
       default : ;
     end ;

   if (errnr >= ERRORLIMIT)  ++errcount ;
   else
    switch (errnr)          /* display warnings */
     begin
       case 101 :
	  fprintf (lstfile, "Local priority definition.") ;
       break ;
       case 102 :
	  fprintf (lstfile, "GLOBAL in the use clause of a program is ignored.") ;
       break ;
       case 111 :
	  fprintf (lstfile, "':' expected in case-statement.") ;
       break ;
       case 120 :
	  fprintf (lstfile, "Implicit type conversion of subarray.") ;
       break ;
       case 131 :
	  fprintf (lstfile, "In standard Pascal this parameter must be a variable.") ;
       break ;
       case 171 :
	  fprintf (lstfile, "Further Parameters ignored.") ;
       break ;
       case 172 :
	  fprintf (lstfile, "Argument is not compatible with TEXT.") ;
       break ;
       case 173 :
	  fprintf (lstfile, "Sizeof returns the size of the descriptor only.") ;
       break ;
       case 201 :
	  fprintf (lstfile, "Implicit type conversion of array.") ;
       break ;
       case 202 :
	  fprintf (lstfile, "Real constant without rounding directive.") ;
       break ;
       case 451 :
	  fprintf (lstfile, "Circle-USE.") ;
       break ;
       default : ;
     end ;
   fprintf (lstfile, "\n") ;

   if  (errfile==NULL)
    begin                       /* initialize errmess */
     if  (addstr)
      begin                                /* save addstr */
	cpy = (char*) malloc (strlen(addstr)+1) ;
	if (cpy)   strcpy (cpy, addstr) , addstr = cpy ;
      end ;

     if  ((errfile = fopen (errfnam(), "w")) != NULL )
       fprintf (errfile, "%s\n", srcfnam()) ;
     else
       fprintf (stderr, "Cannot open file %s for output.\n", errfnam()) ,
       finish (-3) ;
    end

   if  (addstr)
     fprintf (errfile, "%d %d %d %s\n",
	      (int)errnr, (int)pos.line, (int)pos.col, addstr) ;
   else
     fprintf (errfile, "%d %d %d\n", (int)errnr, (int)pos.line, (int)pos.col) ;
   if  (cpy)   free (cpy) ;
   if  (ov_abort  and  errcount >= ov_abort)
    begin
      fprintf (stderr, "Compilation aborted due to '+a' option.\n") ;
      finish (errcount) ;
    end ;
 END /* errput */


#ifdef OLD

#ifdef LINT_ARGS
global void checkerror  ( postype pos )
#else
global void checkerror (pos)
postype pos ;
#endif
 BEGIN(checkerror)
   fprintf (lstfile, "Check in line %4d col %2d: ", pos.line, pos.col ) ;
   ++mescount ;
   ++errcount ;
 END /* checkerror */

#endif



							/*------------------*/
#ifdef LINT_ARGS
global void memerror  ( postype pos )
#else
global void memerror (pos)                              /*  m e m e r r o r */
postype pos ;
#endif
BEGIN(memerror)
    fprintf (stderr, "Insufficient memory. Compilation abort.\n");
    errput (30000, pos, (char*)0) ;
    finish(-999);
END /* memerror */                                      /*  m e m e r r o r */
							/*------------------*/


							/*------------------*/
#ifdef LINT_ARGS
global void dskerror  ( postype pos ,char * addstr )
#else
global void dskerror (pos, addstr)                      /*  d s k e r r o r */
postype pos ;
char * addstr ;
#endif
BEGIN(dskerror)
    fprintf (stderr,
     "Error in writing file %s  -- Probably disk is full. Compilation abort.\n"
     , addstr);
    errput (30001, pos, addstr) ;
    finish(-998);
END /* dskerror */                                      /*  d s k e r r o r */
							/*------------------*/



/*
 *  former MODULE  : print.c
 *  used for internal dump.
 *  last modification: 08.02.90  18:50
*/

local char LINE[132] = {0};  /* output buffer */
local shortint spaces = 0;   /* number of leading blanks to be generated */


#ifdef LINT_ARGS
global void incspaces ( void)
#else
global void incspaces()
#endif
BEGIN(incspaces)
 spaces++;
END /* incspaces */


#ifdef LINT_ARGS
global void decspaces ( void)
#else
global void decspaces()
#endif
BEGIN(decspaces)
 spaces--;
END /* decspaces */


#ifdef LINT_ARGS
global void print ( char *str)
#else
global void print(str)
char *str;
#endif
BEGIN(print)
 if  (str == (char*) 0)   return ;
 if (strlen(LINE)+strlen(str)+spaces>130) then printline();
 strcat(LINE,str);
END /* print */


#ifdef LINT_ARGS
global void printint ( longint i )
#else
global void printint(i)
longint i ;
#endif
BEGIN(printint)
  char num [100];

  sprintf(num,"%ld",i);
  print(num);
END /* printint */


#ifdef LINT_ARGS
global void printchar ( char ch )
#else
global void printchar(ch)
char ch ;
#endif
BEGIN(printchar)
  char ch2 [2] ;

  print("'");
  if (ch=='\'')  print ("''") ;
  else   ch2[0]=ch, ch2[1] = '\0', print (ch2) ;
  print("'");
END /* printchar */


#ifdef LINT_ARGS
global void printline ( void)
#else
global void printline()
#endif
BEGIN(printline)
 /* shortint ch='s' ;  * char of srcfile to merge */
 register shortint l;

 for (l=1; l<=spaces;l++)  fprintf (lstfile, " ");
 fprintf (lstfile, "%s\n",LINE); LINE[0]='\0';
END /* printline */


#ifdef LINT_ARGS
global shortint checkline ( void)
#else
global shortint checkline()
#endif
BEGIN(checkline)
 RETURN(strlen(LINE));
END /* checkline */
