diff --git a/source/compiler/sc.h b/source/compiler/sc.h index f880a0e..5d76402 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -312,6 +312,15 @@ typedef struct s_valuepair { long second; } valuepair; +typedef struct s_builtinstring { + struct { + char name[sNAMEMAX+1]; + char value[_MAX_PATH]; + } *entries; + int count; + int size; +} builtinstring; + /* struct "symstate" is used to: * * synchronize the status of assignments between all "if" branches or "switch" * cases, so the compiler could detect unused assignments in all of those @@ -1032,6 +1041,7 @@ SC_VDECL int pc_isrecording; /* true if recording input */ SC_VDECL char *pc_recstr; /* recorded input */ SC_VDECL int pc_loopcond; /* equals to 'tFOR', 'tWHILE' or 'tDO' if the current expression is a loop condition, zero otherwise */ SC_VDECL int pc_numloopvars; /* number of variables used inside a loop condition */ +SC_VDECL builtinstring builtin_strings; SC_VDECL char *sc_tokens[]; diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 89c8983..976e552 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -121,6 +121,9 @@ static void testloopvariables(symstate *loopvars,int dowhile,int line); static void destructsymbols(symbol *root,int level); static constvalue *find_constval_byval(constvalue_root *table,cell val); static symbol *fetchlab(char *name); +static void remember_builtin_string(const char *name,const char *value); +static void register_builtin_string(void); +static void delete_builtin_string(void); static void statement(int *lastindent,int allow_decl); static void compound(int stmt_sameline,int starttok); static int test(int label,int parens,int invert); @@ -867,6 +870,7 @@ int pc_compile(int argc, char *argv[]) #endif delete_autolisttable(); delete_heaplisttable(); + delete_builtin_string(); if (errnum!=0) { if (strempty(errfname)) pc_printf("\n%d Error%s.\n",errnum,(errnum>1) ? "s" : ""); @@ -1341,8 +1345,18 @@ static void parseoptions(int argc,char **argv,char *oname,char *ename,char *pnam error(200,argv[arg],sNAMEMAX); /* symbol too long, truncated to sNAMEMAX chars */ } /* if */ strlcpy(str,argv[arg],i+1); /* str holds symbol name */ - i=atoi(ptr+1); - add_builtin_constant(str,i,sGLOBAL,0); + if (*(ptr+1)=='\"') { + char strval[_MAX_PATH]; + strlcpy(strval,ptr+2,sizeof(strval)); + int len=strlen(strval); + if (len>0 && strval[len-1]=='\"') + strval[len-1]='\0'; + remember_builtin_string(str,strval); + } + else { + i=atoi(ptr+1); + add_builtin_constant(str,i,sGLOBAL,0); + } } else if (oname) { strlcpy(str,argv[arg],arraysize(str)-2); /* -2 because default extension is ".p" */ set_extension(str,".p",FALSE); @@ -1705,6 +1719,8 @@ static void setstringconstants(void) add_builtin_string_constant("__time",timebuf,sGLOBAL); strftime(datebuf,arraysize(datebuf),"%d %b %Y",localtime(&now)); add_builtin_string_constant("__date",datebuf,sGLOBAL); + + register_builtin_string(); } static int getclassspec(int initialtok,int *fpublic,int *fstatic,int *fstock,int *fconst) @@ -5693,6 +5709,48 @@ SC_FUNC symbol *add_builtin_string_constant(char *name,const char *val, return sym; } +static void remember_builtin_string(const char *name,const char *value) +{ + builtinstring *tbl=&builtin_strings; + int newsize; + void *p; + + assert(tbl!=NULL); + if (tbl->count>=tbl->size) { + newsize=(tbl->size==0) ? 2 : tbl->size*2; + p=realloc(tbl->entries,newsize*sizeof(*tbl->entries)); + if (p==NULL) { + error(103); + return; + } + tbl->entries=p; + tbl->size=newsize; + } + strlcpy(tbl->entries[tbl->count].name,name,sizeof(tbl->entries[tbl->count].name)); + strlcpy(tbl->entries[tbl->count].value,value,sizeof(tbl->entries[tbl->count].value)); + tbl->count++; +} + +static void register_builtin_string(void) +{ + builtinstring *tbl=&builtin_strings; + + assert(tbl!=NULL); + for (int i=0; icount; ++i) { + add_builtin_string_constant(tbl->entries[i].name,tbl->entries[i].value,sGLOBAL); + } +} + +static void delete_builtin_string(void) { + builtinstring *tbl=&builtin_strings; + + assert(tbl!=NULL); + free(tbl->entries); + tbl->entries=NULL; + tbl->count=0; + tbl->size=0; +} + /* statement - The Statement Parser * * This routine is called whenever the parser needs to know what statement diff --git a/source/compiler/scvars.c b/source/compiler/scvars.c index d43604b..cf8a138 100644 --- a/source/compiler/scvars.c +++ b/source/compiler/scvars.c @@ -107,6 +107,7 @@ SC_VDEFINE int pc_isrecording=FALSE; /* true if recording input */ SC_VDEFINE char *pc_recstr=NULL; /* recorded input */ SC_VDEFINE int pc_loopcond=FALSE; /* true if the current expression is a loop condition */ SC_VDEFINE int pc_numloopvars=0; /* number of variables used inside a loop condition */ +SC_VDEFINE builtinstring builtin_strings={NULL, 0, 0}; SC_VDEFINE char *sc_tokens[] = { "*=", "/=", "%=", "+=", "-=", "<<=", ">>>=", ">>=", "&=", "^=", "|=",