diff --git a/compiler/libpc300/sc.h b/compiler/libpc300/sc.h index 0678fd86..26a13e46 100755 --- a/compiler/libpc300/sc.h +++ b/compiler/libpc300/sc.h @@ -148,6 +148,7 @@ typedef struct s_symbol { } dim; /* for 'dimension', both functions and arrays */ constvalue *states; /* list of state function addresses */ int fnumber; /* static global variables: file number in which the declaration is visible */ + int lnumber; /* line number (in the current source file) for the declaration */ struct s_symbol **refer; /* referrer list, functions that "use" this symbol */ int numrefers; /* number of entries in the referrer list */ char *documentation; /* optional documentation string */ @@ -407,6 +408,8 @@ typedef struct s_stringpair { #define sFORCESET 1 /* force error flag on */ #define sEXPRMARK 2 /* mark start of expression */ #define sEXPRRELEASE 3 /* mark end of expression */ +#define sSETLINE 4 /* set line number for the error */ +#define sSETFILE 5 /* set file number for the error */ typedef enum s_regid { sPRI, /* indicates the primary register */ @@ -651,7 +654,7 @@ SC_FUNC void outval(cell val,int newline); /* function prototypes in SC5.C */ SC_FUNC int error(int number,...) INVISIBLE; -SC_FUNC void errorset(int code); +SC_FUNC void errorset(int code, int line); /* function prototypes in SC6.C */ SC_FUNC int assemble(FILE *fout,FILE *fin); @@ -684,6 +687,9 @@ SC_FUNC void delete_substtable(void); SC_FUNC stringlist *insert_sourcefile(char *string); SC_FUNC char *get_sourcefile(int index); SC_FUNC void delete_sourcefiletable(void); +SC_FUNC stringlist *insert_inputfile(char *string); +SC_FUNC char *get_inputfile(int index); +SC_FUNC void delete_inputfiletable(void); SC_FUNC stringlist *insert_docstring(char *string); SC_FUNC char *get_docstring(int index); SC_FUNC void delete_docstring(int index); @@ -780,8 +786,8 @@ SC_VDECL cell sc_stksize; /* stack size */ SC_VDECL cell sc_amxlimit; /* abstract machine size limit */ SC_VDECL int freading; /* is there an input file ready for reading? */ SC_VDECL int fline; /* the line number in the current file */ -SC_VDECL short fnumber; /* number of files in the file table (debugging) */ -SC_VDECL short fcurrent; /* current file being processed (debugging) */ +SC_VDECL short fnumber; /* number of files in the input file table */ +SC_VDECL short fcurrent; /* current file being processed */ SC_VDECL short sc_intest; /* true if inside a test */ SC_VDECL int sideeffect; /* true if an expression causes a side-effect */ SC_VDECL int stmtindent; /* current indent of the statement */ diff --git a/compiler/libpc300/sc1.c b/compiler/libpc300/sc1.c index 45fef4ea..424d36a2 100755 --- a/compiler/libpc300/sc1.c +++ b/compiler/libpc300/sc1.c @@ -461,8 +461,8 @@ int pc_compile(int argc, char *argv[]) /* set global variables to their initial value */ binf=NULL; initglobals(); - errorset(sRESET); - errorset(sEXPRRELEASE); + errorset(sRESET,0); + errorset(sEXPRRELEASE,0); lexinit(); /* make sure that we clean up on a fatal error; do this before the first @@ -597,7 +597,7 @@ int pc_compile(int argc, char *argv[]) sc_packstr=lcl_packstr; sc_needsemicolon=lcl_needsemicolon; sc_tabsize=lcl_tabsize; - errorset(sRESET); + errorset(sRESET,0); /* reset the source file */ inpf=inpf_org; freading=TRUE; @@ -662,7 +662,7 @@ int pc_compile(int argc, char *argv[]) sc_packstr=lcl_packstr; sc_needsemicolon=lcl_needsemicolon; sc_tabsize=lcl_tabsize; - errorset(sRESET); + errorset(sRESET,0); /* reset the source file */ inpf=inpf_org; freading=TRUE; @@ -671,7 +671,8 @@ int pc_compile(int argc, char *argv[]) lexinit(); /* clear internal flags of lex() */ sc_status=statWRITE; /* allow to write --this variable was reset by resetglobals() */ writeleader(&glbtab); - insert_dbgfile(inpfname); + insert_dbgfile(inpfname); /* attach to debug information */ + insert_inputfile(inpfname); /* save for the error system */ if (strlen(incfname)>0) { if (strcmp(incfname,sDEF_PREFIX)==0) plungefile(incfname,FALSE,TRUE); /* parse "default.inc" (again) */ @@ -752,6 +753,7 @@ cleanup: delete_aliastable(); delete_pathtable(); delete_sourcefiletable(); + delete_inputfiletable(); delete_dbgstringtable(); #if !defined NO_DEFINE delete_substtable(); @@ -790,7 +792,7 @@ cleanup: #endif int pc_addconstant(char *name,cell value,int tag) { - errorset(sFORCESET); /* make sure error engine is silenced */ + errorset(sFORCESET,0); /* make sure error engine is silenced */ sc_status=statIDLE; add_constant(name,value,sGLOBAL,tag); return 1; @@ -3635,7 +3637,7 @@ static int declargs(symbol *sym) } /* for */ sym->usage|=uPROTOTYPED; - errorset(sRESET); /* reset error flag (clear the "panic mode")*/ + errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/ return argcnt; } @@ -4344,17 +4346,23 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst) switch (sym->ident) { case iLABEL: if (testlabs) { - if ((sym->usage & uDEFINE)==0) + if ((sym->usage & uDEFINE)==0) { error(19,sym->name); /* not a label: ... */ - else if ((sym->usage & uREAD)==0) + } else if ((sym->usage & uREAD)==0) { + errorset(sSETFILE,sym->fnumber); + errorset(sSETLINE,sym->lnumber); error(203,sym->name); /* symbol isn't used: ... */ + } /* if */ } /* if */ break; case iFUNCTN: if ((sym->usage & (uDEFINE | uREAD | uNATIVE | uSTOCK))==uDEFINE) { funcdisplayname(symname,sym->name); - if (strlen(symname)>0) + if (strlen(symname)>0) { + errorset(sSETFILE,sym->fnumber); + errorset(sSETLINE,sym->lnumber); error(203,symname); /* symbol isn't used ... (and not native/stock) */ + } /* if */ } /* if */ if ((sym->usage & uPUBLIC)!=0 || strcmp(sym->name,uMAINFUNC)==0) entry=TRUE; /* there is an entry point */ @@ -4363,21 +4371,31 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst) insert_dbgsymbol(sym); break; case iCONSTEXPR: - if (testconst && (sym->usage & uREAD)==0) + if (testconst && (sym->usage & uREAD)==0) { + errorset(sSETFILE,sym->fnumber); + errorset(sSETLINE,sym->lnumber); error(203,sym->name); /* symbol isn't used: ... */ + } /* if */ break; default: /* a variable */ if (sym->parent!=NULL) break; /* hierarchical data type */ - if ((sym->usage & (uWRITTEN | uREAD | uSTOCK))==0) - error(203,sym->name); /* symbol isn't used (and not stock) */ - else if ((sym->usage & (uREAD | uSTOCK | uPUBLIC))==0) + if ((sym->usage & (uWRITTEN | uREAD | uSTOCK))==0) { + errorset(sSETFILE,sym->fnumber); + errorset(sSETLINE,sym->lnumber); + error(203,sym->name,sym->lnumber); /* symbol isn't used (and not stock) */ + } else if ((sym->usage & (uREAD | uSTOCK | uPUBLIC))==0) { + errorset(sSETFILE,sym->fnumber); + errorset(sSETLINE,sym->lnumber); error(204,sym->name); /* value assigned to symbol is never used */ #if 0 // ??? not sure whether it is a good idea to force people use "const" - else if ((sym->usage & (uWRITTEN | uPUBLIC | uCONST))==0 && sym->ident==iREFARRAY) + } else if ((sym->usage & (uWRITTEN | uPUBLIC | uCONST))==0 && sym->ident==iREFARRAY) { + errorset(sSETFILE,sym->fnumber); + errorset(sSETLINE,sym->lnumber); error(214,sym->name); /* make array argument "const" */ #endif + } /* if */ /* also mark the variable (local or global) to the debug information */ if ((sym->usage & (uWRITTEN | uREAD))!=0 && (sym->usage & uNATIVE)==0) insert_dbgsymbol(sym); @@ -4385,6 +4403,8 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst) sym=sym->next; } /* while */ + errorset(sEXPRRELEASE, 0); /* clear error data */ + errorset(sRESET, 0); return entry; } @@ -4595,7 +4615,7 @@ static void statement(int *lastindent,int allow_decl) error(36); /* empty statement */ return; } /* if */ - errorset(sRESET); + errorset(sRESET,0); tok=lex(&val,&st); if (tok!='{') { @@ -4722,6 +4742,7 @@ static void compound(int stmt_sameline) int indent=-1; cell save_decl=declared; int count_stmt=0; + int block_start=fline; /* save line where the compound block started */ /* if there is more text on this line, we should adjust the statement indent */ if (stmt_sameline) { @@ -4749,7 +4770,7 @@ static void compound(int stmt_sameline) nestlevel+=1; /* increase compound statement level */ while (matchtoken('}')==0){ /* repeat until compound statement is closed */ if (!freading){ - needtoken('}'); /* gives error: "expected token }" */ + error(30,block_start); /* compound block not closed at end of file */ break; } else { if (count_stmt>0 && (lastst==tRETURN || lastst==tBREAK || lastst==tCONTINUE)) @@ -4787,7 +4808,7 @@ static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr, assert(stgidx==0); } /* if */ index=stgidx; - errorset(sEXPRMARK); + errorset(sEXPRMARK,0); do { /* on second round through, mark the end of the previous expression */ if (index!=stgidx) @@ -4802,7 +4823,7 @@ static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr, } while (comma && matchtoken(',')); /* more? */ if (mark_endexpr) markexpr(sEXPR,NULL,0); /* optionally, mark the end of the expression */ - errorset(sEXPRRELEASE); + errorset(sEXPRRELEASE,0); if (localstaging) { stgout(index); stgset(FALSE); /* stop staging */ @@ -4819,7 +4840,7 @@ SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr) stgset(TRUE); /* start stage-buffering */ stgget(&index,&cidx); /* mark position in code generator */ - errorset(sEXPRMARK); + errorset(sEXPRMARK,0); ident=expression(val,tag,symptr,FALSE); stgdel(index,cidx); /* scratch generated code */ stgset(FALSE); /* stop stage-buffering */ @@ -4832,7 +4853,7 @@ SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr) if (symptr!=NULL) *symptr=NULL; } /* if */ - errorset(sEXPRRELEASE); + errorset(sEXPRRELEASE,0); return (ident==iCONSTEXPR); } diff --git a/compiler/libpc300/sc2.c b/compiler/libpc300/sc2.c index a5bf8039..01c79ca7 100755 --- a/compiler/libpc300/sc2.c +++ b/compiler/libpc300/sc2.c @@ -156,15 +156,17 @@ static char *extensions[] = { ".inc", ".p", ".pawn" }; PUSHSTK_I(fline); inpfname=duplicatestring(name);/* set name of include file */ if (inpfname==NULL) - error(103); /* insufficient memory */ - inpf=fp; /* set input file pointer to include file */ + error(103); /* insufficient memory */ + inpf=fp; /* set input file pointer to include file */ fnumber++; - fline=0; /* set current line number to 0 */ + fline=0; /* set current line number to 0 */ fcurrent=fnumber; - icomment=0; /* not in a comment */ - insert_dbgfile(inpfname); - setfiledirect(inpfname); - listline=-1; /* force a #line directive when changing the file */ + icomment=0; /* not in a comment */ + insert_dbgfile(inpfname); /* attach to debug information */ + insert_inputfile(inpfname); /* save for the error system */ + assert(sc_status == statFIRST || strcmp(get_inputfile(fcurrent), inpfname) == 0); + setfiledirect(inpfname); /* (optionally) set in the list file */ + listline=-1; /* force a #line directive when changing the file */ sc_is_utf8=(short)scan_utf8(inpf,name); return TRUE; } @@ -320,6 +322,7 @@ static void readline(unsigned char *line) inpf=(FILE *)POPSTK_P(); insert_dbgfile(inpfname); setfiledirect(inpfname); + assert(sc_status==statFIRST || strcmp(get_inputfile(fcurrent),inpfname)==0); listline=-1; /* force a #line directive when changing the file */ } /* if */ @@ -894,7 +897,7 @@ static int command(void) assert(iflevel>=0); if (iflevel==0) { error(26); /* no matching #if */ - errorset(sRESET); + errorset(sRESET,0); } else { /* check for earlier #else */ if ((ifstack[iflevel-1] & HANDLED_ELSE)==HANDLED_ELSE) { @@ -902,7 +905,7 @@ static int command(void) error(61); /* #elseif directive may not follow an #else */ else error(60); /* multiple #else directives between #if ... #endif */ - errorset(sRESET); + errorset(sRESET,0); } else { assert(iflevel>0); /* if there has been a "parse mode" on this level, set "skip mode", @@ -946,7 +949,7 @@ static int command(void) ret=CMD_IF; if (iflevel==0){ error(26); /* no matching "#if" */ - errorset(sRESET); + errorset(sRESET,0); } else { iflevel--; if (iflevelusage |= (char)usage; + if ((usage & uWRITTEN) != 0) + sym->lnumber=fline; /* check if (global) reference must be added to the symbol */ if ((usage & (uREAD | uWRITTEN))!=0) { /* only do this for global symbols */ @@ -2715,6 +2721,7 @@ SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,i entry.compound=0; /* may be overridden later */ entry.states=NULL; entry.fnumber=-1; /* assume global visibility (ignored for local symbols) */ + entry.lnumber=fline; entry.numrefers=1; entry.refer=refer; entry.parent=NULL; diff --git a/compiler/libpc300/sc5.c b/compiler/libpc300/sc5.c index 05bd9088..83cbb3f8 100755 --- a/compiler/libpc300/sc5.c +++ b/compiler/libpc300/sc5.c @@ -51,7 +51,9 @@ static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */ static int errflag; +static int errfile; static int errstart; /* line number at which the instruction started */ +static int errline; /* forced line number for the error message */ /* error * @@ -70,7 +72,7 @@ SC_FUNC int error(int number,...) static char *prefix[3]={ "error", "fatal error", "warning" }; static int lastline,errorcount; static short lastfile; - char *msg,*pre; + char *msg,*pre,*filename; va_list argptr; char string[128]; @@ -107,11 +109,22 @@ static short lastfile; strexpand(string,(unsigned char *)msg,sizeof string,SCPACK_TABLE); - assert(errstart<=fline); + 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 */ + assert(filename!=NULL); + va_start(argptr,number); if (strlen(errfname)==0) { - int start= (errstart==fline) ? -1 : errstart; - if (pc_error(number,string,inpfname,start,fline,argptr)) { + 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; @@ -121,10 +134,10 @@ static short lastfile; } else { FILE *fp=fopen(errfname,"a"); if (fp!=NULL) { - if (errstart>=0 && errstart!=fline) - fprintf(fp,"%s(%d -- %d) : %s %03d: ",inpfname,errstart,fline,pre,number); + if (errstart>=0 && errstart!=errline) + fprintf(fp,"%s(%d -- %d) : %s %03d: ",filename,errstart,errline,pre,number); else - fprintf(fp,"%s(%d) : %s %03d: ",inpfname,fline,pre,number); + fprintf(fp,"%s(%d) : %s %03d: ",filename,errline,pre,number); vfprintf(fp,string,argptr); fclose(fp); } /* if */ @@ -144,6 +157,8 @@ static short lastfile; 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) || lastlinefline || fcurrent!=lastfile) errorcount=0; @@ -157,7 +172,7 @@ static short lastfile; return 0; } -SC_FUNC void errorset(int code) +SC_FUNC void errorset(int code,int line) { switch (code) { case sRESET: @@ -171,6 +186,15 @@ SC_FUNC void errorset(int code) break; case sEXPRRELEASE: errstart=-1; /* forget start line number */ + errline=-1; + errfile=-1; + break; + case sSETLINE: + errstart=-1; /* force error line number, forget start line */ + errline=line; + break; + case sSETFILE: + errfile=line; break; } /* switch */ } diff --git a/compiler/libpc300/sclist.c b/compiler/libpc300/sclist.c index 57c82702..54658e04 100755 --- a/compiler/libpc300/sclist.c +++ b/compiler/libpc300/sclist.c @@ -356,7 +356,7 @@ SC_FUNC void delete_substtable(void) #endif /* !defined NO_SUBST */ -/* ----- input file list ----------------------------------------- */ +/* ----- input file list (explicit files)------------------------- */ static stringlist sourcefiles = {NULL, NULL}; SC_FUNC stringlist *insert_sourcefile(char *string) @@ -376,6 +376,28 @@ SC_FUNC void delete_sourcefiletable(void) } +/* ----- parsed file list (explicit + included files) ------------ */ +static stringlist inputfiles = {NULL, NULL}; + +SC_FUNC stringlist *insert_inputfile(char *string) +{ + if (sc_status!=statFIRST) + return insert_string(&inputfiles,string); + return NULL; +} + +SC_FUNC char *get_inputfile(int index) +{ + return get_string(&inputfiles,index); +} + +SC_FUNC void delete_inputfiletable(void) +{ + delete_stringtable(&inputfiles); + assert(inputfiles.next==NULL); +} + + /* ----- documentation tags -------------------------------------- */ #if !defined SC_LIGHT static stringlist docstrings = {NULL, NULL}; diff --git a/plugins/ns/nscommands.sma b/plugins/ns/nscommands.sma index 26367967..15c39f00 100755 --- a/plugins/ns/nscommands.sma +++ b/plugins/ns/nscommands.sma @@ -14,7 +14,7 @@ #include #include -#pragma tabsize 0 +#pragma tabsize 4 new g_TeamOneAck[12]; new g_TeamTwoAck[12];