251cced1f8
Various minor things done to project files Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way) Updated regex project file and makefile --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401971
229 lines
6.6 KiB
C
229 lines
6.6 KiB
C
/* Pawn compiler - Error message system
|
|
* In fact a very simple system, using only 'panic mode'.
|
|
*
|
|
* Copyright (c) ITB CompuPhase, 1997-2006
|
|
*
|
|
* This software is provided "as-is", without any express or implied warranty.
|
|
* In no event will the authors be held liable for any damages arising from
|
|
* the use of this software.
|
|
*
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute it
|
|
* freely, subject to the following restrictions:
|
|
*
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
* claim that you wrote the original software. If you use this software in
|
|
* a product, an acknowledgment in the product documentation would be
|
|
* appreciated but is not required.
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
* misrepresented as being the original software.
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
*
|
|
* Version: $Id$
|
|
*/
|
|
#include <assert.h>
|
|
#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
|
|
#include <io.h>
|
|
#endif
|
|
#if defined LINUX || defined __GNUC__
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h> /* ANSI standardized variable argument list functions */
|
|
#include <string.h>
|
|
#if defined FORTIFY
|
|
#include <alloc/fortify.h>
|
|
#endif
|
|
#include "sc.h"
|
|
|
|
#if defined _MSC_VER
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4125) /* decimal digit terminates octal escape sequence */
|
|
#endif
|
|
|
|
#include "sc5.scp"
|
|
|
|
#if defined _MSC_VER
|
|
#pragma warning(pop)
|
|
#endif
|
|
|
|
#define NUM_WARNINGS (sizeof warnmsg / sizeof warnmsg[0])
|
|
static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */
|
|
|
|
static int errflag;
|
|
static int errstart; /* line number at which the instruction started */
|
|
static int errline; /* forced line number for the error message */
|
|
|
|
/* error
|
|
*
|
|
* Outputs an error message (note: msg is passed optionally).
|
|
* If an error is found, the variable "errflag" is set and subsequent
|
|
* errors are ignored until lex() finds a semicolumn or a keyword
|
|
* (lex() resets "errflag" in that case).
|
|
*
|
|
* Global references: inpfname (reffered to only)
|
|
* fline (reffered to only)
|
|
* fcurrent (reffered to only)
|
|
* errflag (altered)
|
|
*/
|
|
SC_FUNC int error(int number,...)
|
|
{
|
|
static char *prefix[3]={ "error", "fatal error", "warning" };
|
|
static int lastline,errorcount;
|
|
static short lastfile;
|
|
char *msg,*pre;
|
|
va_list argptr;
|
|
char string[128];
|
|
|
|
/* errflag is reset on each semicolon.
|
|
* In a two-pass compiler, an error should not be reported twice. Therefore
|
|
* the error reporting is enabled only in the second pass (and only when
|
|
* actually producing output). Fatal errors may never be ignored.
|
|
*/
|
|
if ((errflag || sc_status!=statWRITE) && (number<120 || number>=200))
|
|
return 0;
|
|
|
|
/* also check for disabled warnings */
|
|
if (number>=200) {
|
|
int index=(number-200)/8;
|
|
int mask=1 << ((number-200)%8);
|
|
if ((warndisable[index] & mask)!=0)
|
|
return 0;
|
|
} /* if */
|
|
|
|
if (number<120){
|
|
msg=errmsg[number-1];
|
|
pre=prefix[0];
|
|
errflag=TRUE; /* set errflag (skip rest of erroneous expression) */
|
|
errnum++;
|
|
} else if (number<200){
|
|
msg=fatalmsg[number-120];
|
|
pre=prefix[1];
|
|
errnum++; /* a fatal error also counts as an error */
|
|
} else {
|
|
msg=warnmsg[number-200];
|
|
pre=prefix[2];
|
|
warnnum++;
|
|
} /* if */
|
|
|
|
strexpand(string,(unsigned char *)msg,sizeof string,SCPACK_TABLE);
|
|
|
|
assert(errstart<=fline);
|
|
if (errline>0)
|
|
errstart=errline;
|
|
else
|
|
errline=fline;
|
|
assert(errstart<=errline);
|
|
va_start(argptr,number);
|
|
if (strlen(errfname)==0) {
|
|
int start= (errstart==errline) ? -1 : errstart;
|
|
if (pc_error(number,string,inpfname,start,errline,argptr)) {
|
|
if (outf!=NULL) {
|
|
pc_closeasm(outf,TRUE);
|
|
outf=NULL;
|
|
} /* if */
|
|
longjmp(errbuf,3); /* user abort */
|
|
} /* if */
|
|
} else {
|
|
FILE *fp=fopen(errfname,"a");
|
|
if (fp!=NULL) {
|
|
if (errstart>=0 && errstart!=errline)
|
|
fprintf(fp,"%s(%d -- %d) : %s %03d: ",inpfname,errstart,errline,pre,number);
|
|
else
|
|
fprintf(fp,"%s(%d) : %s %03d: ",inpfname,errline,pre,number);
|
|
vfprintf(fp,string,argptr);
|
|
fclose(fp);
|
|
} /* if */
|
|
} /* if */
|
|
va_end(argptr);
|
|
|
|
if (number>=120 && number<200 || errnum>25){
|
|
if (strlen(errfname)==0) {
|
|
va_start(argptr,number);
|
|
pc_error(0,"\nCompilation aborted.",NULL,0,0,argptr);
|
|
va_end(argptr);
|
|
} /* if */
|
|
if (outf!=NULL) {
|
|
pc_closeasm(outf,TRUE);
|
|
outf=NULL;
|
|
} /* if */
|
|
longjmp(errbuf,2); /* fatal error, quit */
|
|
} /* if */
|
|
|
|
errline=-1;
|
|
/* check whether we are seeing many errors on the same line */
|
|
if ((errstart<0 && lastline!=fline) || lastline<errstart || lastline>fline || fcurrent!=lastfile)
|
|
errorcount=0;
|
|
lastline=fline;
|
|
lastfile=fcurrent;
|
|
if (number<200)
|
|
errorcount++;
|
|
if (errorcount>=3)
|
|
error(127); /* too many error/warning messages on one line */
|
|
|
|
return 0;
|
|
}
|
|
|
|
SC_FUNC void errorset(int code,int line)
|
|
{
|
|
switch (code) {
|
|
case sRESET:
|
|
errflag=FALSE; /* start reporting errors */
|
|
break;
|
|
case sFORCESET:
|
|
errflag=TRUE; /* stop reporting errors */
|
|
break;
|
|
case sEXPRMARK:
|
|
errstart=fline; /* save start line number */
|
|
break;
|
|
case sEXPRRELEASE:
|
|
errstart=-1; /* forget start line number */
|
|
errline=-1;
|
|
break;
|
|
case sSETPOS:
|
|
errline=line;
|
|
break;
|
|
} /* switch */
|
|
}
|
|
|
|
/* sc_enablewarning()
|
|
* Enables or disables a warning (errors cannot be disabled).
|
|
* Initially all warnings are enabled. The compiler does this by setting bits
|
|
* for the *disabled* warnings and relying on the array to be zero-initialized.
|
|
*
|
|
* Parameter enable can be:
|
|
* o 0 for disable
|
|
* o 1 for enable
|
|
* o 2 for toggle
|
|
*/
|
|
int pc_enablewarning(int number,int enable)
|
|
{
|
|
int index;
|
|
unsigned char mask;
|
|
|
|
if (number<200)
|
|
return FALSE; /* errors and fatal errors cannot be disabled */
|
|
number -= 200;
|
|
if (number>=NUM_WARNINGS)
|
|
return FALSE;
|
|
|
|
index=number/8;
|
|
mask=(unsigned char)(1 << (number%8));
|
|
switch (enable) {
|
|
case 0:
|
|
warndisable[index] |= mask;
|
|
break;
|
|
case 1:
|
|
warndisable[index] &= (unsigned char)~mask;
|
|
break;
|
|
case 2:
|
|
warndisable[index] ^= mask;
|
|
break;
|
|
} /* switch */
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#undef SCPACK_TABLE
|