/* 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 semicolon 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(long number,...) { static char *prefix[3]={ "error", "fatal error", "warning" }; static int lastline,errorcount; static short lastfile; char *msg,*pre,*filename; va_list argptr; char string[256]; int notice; /* split the error field between the real error/warning number and an optional * "notice" number */ notice=number >> (sizeof(long)*4); number&=((unsigned long)~0) >> (sizeof(long)*4); assert(number>0 && number<300); /* 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<100 || 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) { errline=-1; errfile=-1; return 0; } /* if */ } /* if */ if (number<100){ assert(number>0 && number<sizearray(errmsg)); msg=errmsg[number]; pre=prefix[0]; errflag=TRUE; /* set errflag (skip rest of erroneous expression) */ errnum++; } else if (number<200) { assert((number-100)>=0 && (number-100)<sizearray(fatalmsg)); msg=fatalmsg[number-100]; pre=prefix[1]; errnum++; /* a fatal error also counts as an error */ } else { assert((number-200)>=0 && (number-200)<sizearray(warnmsg)); msg=warnmsg[number-200]; pre=prefix[2]; warnnum++; } /* if */ strexpand(string,(unsigned char *)msg,sizeof string-2,SCPACK_TABLE); if (notice>0) { int len; assert(notice<sizearray(noticemsg)); strcat(string,"; "); len=strlen(string); strexpand(string+len,(unsigned char *)noticemsg[notice],sizeof string-len-1,SCPACK_TABLE); } /* if */ strcat(string,"\n"); if (errline>0) errstart=errline; /* forced error position, set single line destination */ else errline=fline; /* normal error, errstart may (or may not) have been marked, endpoint is current line */ if (errstart>errline) errstart=errline; /* special case: error found at end of included file */ if (errfile>=0) { filename=get_inputfile(errfile);/* forced filename */ } else { filename=inpfname; /* current file */ if (filename==NULL || strlen(filename)==0) filename=get_sourcefile(0); if (filename==NULL || strlen(filename)==0) filename="(none)"; } /* if */ assert(filename!=NULL); va_start(argptr,number); if (strlen(errfname)==0) { int start= (errstart==errline) ? -1 : errstart; if (pc_error((int)number,string,filename,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: ",filename,errstart,errline,pre,(int)number); else fprintf(fp,"%s(%d) : %s %03d: ",filename,errline,pre,(int)number); vfprintf(fp,string,argptr); fclose(fp); } /* if */ } /* if */ va_end(argptr); if (number>=100 && 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; errfile=-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(107); /* too many error/warning messages on one line */ return 0; }
ErrorReport ErrorReport::create_va(int number, int fileno, int lineno, va_list ap) { ErrorReport report; report.number = number; report.fileno = fileno; report.lineno = lineno; if (report.fileno >= 0) report.filename = get_inputfile(report.fileno); else report.filename = inpfname; if (number < FIRST_FATAL_ERROR || (number >= 200 && sc_warnings_are_errors)) report.type = ErrorType::Error; else if (number < 200) report.type = ErrorType::Fatal; else report.type = ErrorType::Warning; /* also check for disabled warnings */ if (report.type == ErrorType::Warning) { int index=(report.number-200)/8; int mask=1 << ((report.number-200)%8); if ((warndisable[index] & mask)!=0) report.type = ErrorType::Suppressed; } const char* prefix = ""; switch (report.type) { case ErrorType::Error: prefix = "error"; break; case ErrorType::Fatal: prefix = "fatal error"; break; case ErrorType::Warning: case ErrorType::Suppressed: prefix = "warning"; break; } const char* format = nullptr; if (report.number < FIRST_FATAL_ERROR) format = errmsg[report.number - 1]; else if (report.number < 200) format = fatalmsg[report.number - FIRST_FATAL_ERROR]; else format = warnmsg[report.number - 200]; char msg[1024]; ke::SafeVsprintf(msg, sizeof(msg), format, ap); char base[1024]; ke::SafeSprintf(base, sizeof(base), "%s(%d) : %s %03d: ", report.filename, report.lineno, prefix, report.number); char full[2048]; ke::SafeSprintf(full, sizeof(full), "%s%s", base, msg); report.message = full; return report; }