diff --git a/source/compiler/sc.h b/source/compiler/sc.h index 48d43fdc..3ef806a4 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -155,8 +155,10 @@ typedef struct s_symbol { } array; } dim; /* for 'dimension', both functions and arrays */ constvalue *states; /* list of state function/state variable ids + addresses */ - int fnumber; /* static global variables: file number in which the declaration is visible */ + int fnumber; /* file number where is declared */ int lnumber; /* line number (in the current source file) for the declaration */ + int lnumber_decl; /* line number where starts the declaration (ignore prototype) */ + int lnumber_end; /* line number for the end of 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 */ @@ -193,6 +195,7 @@ typedef struct s_symbol { * 3 (uCONST) the variable is constant (may not be assigned to) * 4 (uPUBLIC) the variable is public * 6 (uSTOCK) the variable is discardable (without warning) + * 7 (uSTATIC) the variable is static * * FUNCTION * bits: 0 (uDEFINE) the function is defined ("implemented") in the source file @@ -204,6 +207,7 @@ typedef struct s_symbol { * 6 (uSTOCK) the function is discardable (without warning) * 7 (uMISSING) the function is not implemented in this source file * 8 (uFORWARD) the function is explicitly forwardly declared + * 9 (uSTATIC) the function is static * * CONSTANT * bits: 0 (uDEFINE) the symbol is defined in the source file @@ -212,6 +216,7 @@ typedef struct s_symbol { * 3 (uPREDEF) the constant is pre-defined and should be kept between passes * 5 (uENUMROOT) the constant is the "root" of an enumeration * 6 (uENUMFIELD) the constant is a field in a named enumeration + * 7 (uSTATIC) the function is static */ #define uDEFINE 0x001 #define uREAD 0x002 @@ -227,6 +232,7 @@ typedef struct s_symbol { #define uENUMFIELD 0x040 #define uMISSING 0x080 #define uFORWARD 0x100 +#define uSTATIC 0x200 /* uRETNONE is not stored in the "usage" field of a symbol. It is * used during parsing a function, to detect a mix of "return;" and * "return value;" in a few special cases. @@ -560,7 +566,7 @@ SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag); SC_FUNC symbol *add_builtin_constant(char *name,cell val,int vclass,int tag); SC_FUNC symbol *add_builtin_string_constant(char *name,const char *val,int vclass); SC_FUNC void exporttag(int tag); -SC_FUNC void sc_attachdocumentation(symbol *sym); +SC_FUNC void sc_attachdocumentation(symbol *sym,int onlylastblock); SC_FUNC void emit_parse_line(void); /* function prototypes in SC2.C */ diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index b1ad703a..ea5fc34f 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -165,7 +165,8 @@ static int wq[wqTABSZ]; /* "while queue", internal stack for nested loop static int *wqptr; /* pointer to next entry */ #if !defined SC_LIGHT static char sc_rootpath[_MAX_PATH]; - static char *sc_documentation=NULL;/* main documentation */ + static char *pc_globaldoc=NULL;/* main documentation */ + static char *pc_recentdoc=NULL; /* documentation from the most recent comment block */ #endif #if defined __WIN32__ || defined _WIN32 || defined _Windows static HWND hwndFinish = 0; @@ -643,9 +644,9 @@ int pc_compile(int argc, char *argv[]) if (strlen(reportname)>0) fclose(frep); } /* if */ - if (sc_documentation!=NULL) { - free(sc_documentation); - sc_documentation=NULL; + if (pc_globaldoc!=NULL) { + free(pc_globaldoc); + pc_globaldoc=NULL; } /* if */ } /* if */ #endif @@ -784,8 +785,10 @@ int pc_compile(int argc, char *argv[]) #endif #if !defined SC_LIGHT delete_docstringtable(); - if (sc_documentation!=NULL) - free(sc_documentation); + if (pc_globaldoc!=NULL) + free(pc_globaldoc); + if (pc_recentdoc!=NULL) + free(pc_recentdoc); #endif delete_autolisttable(); delete_heaplisttable(); @@ -949,7 +952,8 @@ static void initglobals(void) wqptr=wq; /* initialize while queue pointer */ #if !defined SC_LIGHT - sc_documentation=NULL; + pc_globaldoc=NULL; + pc_recentdoc=NULL; sc_makereport=FALSE; /* do not generate a cross-reference report */ #endif } @@ -1832,7 +1836,7 @@ static void aligndata(int numbytes) * appends documentation comments to the passed-in symbol, or to a global * string if "sym" is NULL. */ -void sc_attachdocumentation(symbol *sym) +void sc_attachdocumentation(symbol *sym,int onlylastblock) { int line; size_t length; @@ -1850,6 +1854,43 @@ void sc_attachdocumentation(symbol *sym) */ // assert(sym==NULL || sym->documentation==NULL || sym->states!=NULL); + if (pc_recentdoc!=NULL) { + /* either copy the most recent comment block to the current symbol, or + * append it to the global documentation + */ + length=strlen(pc_recentdoc); + if (onlylastblock) { + assert(sym!=NULL); + str=sym->documentation; + } else { + str=pc_globaldoc; + } /* if */ + /* set the documentation, or append it to it */ + if (str!=NULL) + length+=strlen(str)+1+4; /* plus 4 for "
" */ + doc=(char*)malloc((length+1)*sizeof(char)); + if (doc!=NULL) { + if (str!=NULL) { + strcpy(doc,str); + free(str); + strcat(doc,""); + } else { + *doc='\0'; + } /* if */ + strcat(doc,pc_recentdoc); + if (onlylastblock) { + sym->documentation=doc; + /* force adding the new strings (if any) to the global data */ + sym=NULL; + } else { + pc_globaldoc=doc; + } /* if */ + } /* if */ + /* remove the "recent block" string */ + free(pc_recentdoc); + pc_recentdoc=NULL; + } /* if */ + /* first check the size */ length=0; for (line=0; (str=get_docstring(line))!=NULL && *str!=sDOCSEP; line++) { @@ -1857,24 +1898,20 @@ void sc_attachdocumentation(symbol *sym) length++; /* count 1 extra for a separating space */ length+=strlen(str); } /* for */ - if (sym==NULL && sc_documentation!=NULL) { - length += strlen(sc_documentation) + 1 + 4; /* plus 4 for "" */ - assert(length>strlen(sc_documentation)); - } /* if */ if (length>0) { /* allocate memory for the documentation */ if (sym!=NULL && sym->documentation!=NULL) - length+=strlen(sym->documentation) + 1 + 4;/* plus 4 for "" */ + length+=strlen(sym->documentation)+1+4; /* plus 4 for "" */ doc=(char*)malloc((length+1)*sizeof(char)); if (doc!=NULL) { /* initialize string or concatenate */ - if (sym==NULL && sc_documentation!=NULL) { - strcpy(doc,sc_documentation); - strcat(doc,""); - } else if (sym!=NULL && sym->documentation!=NULL) { + if (sym!=NULL && sym->documentation!=NULL) { + size_t len; strcpy(doc,sym->documentation); - strcat(doc,""); + len=strlen(doc); + if ((len>0 && doc[len-1]!='>') || ((str=get_docstring(0))!=NULL && *str!=sDOCSEP && *str!='<')) + strcat(doc,""); free(sym->documentation); sym->documentation=NULL; } else { @@ -1882,7 +1919,7 @@ void sc_attachdocumentation(symbol *sym) } /* if */ /* collect all documentation */ while ((str=get_docstring(0))!=NULL && *str!=sDOCSEP) { - if (doc[0]!='\0') + if (doc[0]!='\0' && str[0]!='<') strcat(doc," "); strcat(doc,str); delete_docstring(0); @@ -1896,9 +1933,8 @@ void sc_attachdocumentation(symbol *sym) assert(sym->documentation==NULL); sym->documentation=doc; } else { - if (sc_documentation!=NULL) - free(sc_documentation); - sc_documentation=doc; + assert(pc_recentdoc==NULL); + pc_recentdoc=doc; } /* if */ } /* if */ } else { @@ -1914,7 +1950,7 @@ static void insert_docstring_separator(void) insert_docstring(sep); } #else - #define sc_attachdocumentation(s) (void)(s) + #define sc_attachdocumentation(s,f) (void)(s,f) #define insert_docstring_separator() #endif @@ -1981,6 +2017,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst char *str; int dim[sDIMEN_MAX]; int numdim; + int linenum; short filenum; symbol *sym; constvalue *enumroot; @@ -1992,6 +2029,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst insert_docstring_separator(); /* see comment in newfunc() */ filenum=fcurrent; /* save file number at the start of the declaration */ do { + linenum=fline; /* save line number at the start of the declaration */ size=1; /* single size (no array) */ numdim=0; /* no dimensions */ ident=iVARIABLE; @@ -2208,8 +2246,11 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst if (fstock) sym->usage|=uSTOCK; if (fstatic) - sym->fnumber=filenum; - sc_attachdocumentation(sym);/* attach any documenation to the variable */ + sym->usage|=uSTATIC; + sym->fnumber=filenum; + sym->lnumber_decl=linenum; + sym->lnumber_end=fline; + sc_attachdocumentation(sym,TRUE);/* attach any documentation to the variable */ if (sc_status==statSKIP) { sc_status=statWRITE; code_idx=cidx; @@ -2852,8 +2893,12 @@ static void decl_const(int vclass) /* add_constant() checks for duplicate definitions */ check_tagmismatch(tag,exprtag,FALSE,symbolline); sym=add_constant(constname,val,vclass,tag); - if (sym!=NULL) - sc_attachdocumentation(sym);/* attach any documenation to the constant */ + if (sym!=NULL) { + sym->fnumber = fcurrent; + sym->lnumber_decl = symbolline; + sym->lnumber_end = symbolline; + sc_attachdocumentation(sym,TRUE);/* attach any documentation to the constant */ + } } while (matchtoken(',')); /* enddo */ /* more? */ needtoken(tTERM); } @@ -2900,6 +2945,7 @@ static void decl_enum(int vclass,int fstatic) /* get increment and multiplier */ increment=1; multiplier=1; + if (matchtoken('(')) { if (matchtoken(taADD)) { constexpr(&increment,NULL,NULL); @@ -2919,7 +2965,11 @@ static void decl_enum(int vclass,int fstatic) if (enumsym!=NULL) { enumsym->usage |= uENUMROOT; if (fstatic) - enumsym->fnumber=filenum; + enumsym->usage|=uSTATIC; + enumsym->fnumber=filenum; + enumsym->lnumber_decl=fline; + + sc_attachdocumentation(enumsym,FALSE); /* attach any documentation to the enumeration */ } /* start a new list for the element names */ if ((enumroot=(constvalue*)malloc(sizeof(constvalue)))==NULL) @@ -2969,9 +3019,13 @@ static void decl_enum(int vclass,int fstatic) sym->parent=enumsym; if (enumsym) enumsym->child=sym; - if (fstatic) - sym->fnumber=filenum; + sym->usage|=uSTATIC; + sym->fnumber=filenum; + sym->lnumber_decl=fline; + sym->lnumber_end=fline; + + sc_attachdocumentation(sym,FALSE); /* attach any documenation to item */ /* add the constant to a separate list as well */ if (enumroot!=NULL) { @@ -2989,11 +3043,11 @@ static void decl_enum(int vclass,int fstatic) /* set the enum name to the "next" value (typically the last value plus one) */ if (enumsym!=NULL) { assert((enumsym->usage & uENUMROOT)!=0); + enumsym->lnumber_end=fline; enumsym->addr=value; /* assign the constant list */ assert(enumroot!=NULL); enumsym->dim.enumlist=enumroot; - sc_attachdocumentation(enumsym); /* attach any documenation to the enumeration */ } /* if */ } @@ -3400,7 +3454,7 @@ SC_FUNC void check_tagmismatch(int formaltag,int actualtag,int allowcoerce,int e { if (!matchtag(formaltag,actualtag,allowcoerce)) { constvalue *tagsym; - char formal_tagname[sNAMEMAX+3]="none (\"_\"),",actual_tagname[sNAMEMAX+2]="none (\"_\")"; /* two extra characters for quotes */ + char formal_tagname[sNAMEMAX+4]="none (\"_\"),",actual_tagname[sNAMEMAX+3]="none (\"_\")"; /* two extra characters for quotes */ if(formaltag!=0) { tagsym=find_tag_byval(formaltag); sprintf(formal_tagname,"\"%s\",", (tagsym!=NULL) ? tagsym->name : "-unknown-"); @@ -3422,7 +3476,7 @@ SC_FUNC void check_tagmismatch_multiple(int formaltags[],int numtags,int actualt if (!checktag(formaltags, numtags, actualtag)) { int i; constvalue *tagsym; - char formal_tagnames[sLINEMAX]="",actual_tagname[sNAMEMAX+2]="none (\"_\")"; + char formal_tagnames[sLINEMAX]="",actual_tagname[sNAMEMAX+3]="none (\"_\")"; int notag_allowed=FALSE,add_comma=FALSE; for (i=0; i