From 376eb9725eff7a8b23d889c35e9ca6b9822dcc15 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 4 Jul 2014 21:16:39 -0700 Subject: [PATCH 1/5] Add support for new-style declarations in local variables. --- plugins/nextmap.sp | 45 +++-- sourcepawn/compiler/sc.h | 1 + sourcepawn/compiler/sc1.c | 382 ++++++++++++++++++++------------------ 3 files changed, 223 insertions(+), 205 deletions(-) diff --git a/plugins/nextmap.sp b/plugins/nextmap.sp index 9a4278ed..27c23a73 100644 --- a/plugins/nextmap.sp +++ b/plugins/nextmap.sp @@ -45,7 +45,6 @@ public Plugin myinfo = url = "http://www.sourcemod.net/" }; - int g_MapPos = -1; Handle g_MapList = INVALID_HANDLE; int g_MapListSerial = -1; @@ -54,7 +53,7 @@ int g_CurrentMapStartTime; public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { - decl String:game[128]; + char game[128]; GetGameFolderName(game, sizeof(game)); if (StrEqual(game, "left4dead", false) @@ -84,7 +83,7 @@ public void OnPluginStart() RegConsoleCmd("listmaps", Command_List); // Set to the current map so OnMapStart() will know what to do - decl String:currentMap[64]; + char currentMap[64]; GetCurrentMap(currentMap, 64); SetNextMap(currentMap); } @@ -96,7 +95,7 @@ public void OnMapStart() public void OnConfigsExecuted() { - decl String:lastMap[64], String:currentMap[64]; + char lastMap[64], currentMap[64]; GetNextMap(lastMap, sizeof(lastMap)); GetCurrentMap(currentMap, 64); @@ -113,9 +112,9 @@ public Action Command_List(int client, int args) { PrintToConsole(client, "Map Cycle:"); - new mapCount = GetArraySize(g_MapList); - decl String:mapName[32]; - for (new i = 0; i < mapCount; i++) + int mapCount = GetArraySize(g_MapList); + char mapName[32]; + for (int i = 0; i < mapCount; i++) { GetArrayString(g_MapList, i, mapName, sizeof(mapName)); PrintToConsole(client, "%s", mapName); @@ -139,15 +138,15 @@ void FindAndSetNextMap() } } - new mapCount = GetArraySize(g_MapList); - decl String:mapName[32]; + int mapCount = GetArraySize(g_MapList); + char mapName[32]; if (g_MapPos == -1) { - decl String:current[64]; + char current[64]; GetCurrentMap(current, 64); - for (new i = 0; i < mapCount; i++) + for (int i = 0; i < mapCount; i++) { GetArrayString(g_MapList, i, mapName, sizeof(mapName)); if (strcmp(current, mapName, false) == 0) @@ -171,15 +170,15 @@ void FindAndSetNextMap() public Action Command_MapHistory(int client, int args) { - new mapCount = GetMapHistorySize(); + int mapCount = GetMapHistorySize(); - decl String:mapName[32]; - decl String:changeReason[100]; - decl String:timeString[100]; - decl String:playedTime[100]; - new startTime; + char mapName[32]; + char changeReason[100]; + char timeString[100]; + char playedTime[100]; + int startTime; - new lastMapStartTime = g_CurrentMapStartTime; + int lastMapStartTime = g_CurrentMapStartTime; PrintToConsole(client, "Map History:\n"); PrintToConsole(client, "Map : Started : Played Time : Reason for ending"); @@ -187,7 +186,7 @@ public Action Command_MapHistory(int client, int args) GetCurrentMap(mapName, sizeof(mapName)); PrintToConsole(client, "%02i. %s (Current Map)", 0, mapName); - for (new i=0; i 0) { diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index 716d9674..9f660d7c 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -263,6 +263,7 @@ typedef struct svalue_s { #define DECLFLAG_VARIABLE 0x04 // The declaration is for a variable. #define DECLFLAG_ENUMROOT 0x08 // Multi-dimensional arrays should have an enumroot. #define DECLFLAG_MAYBE_FUNCTION 0x10 // Might be a named function. +#define DECLFLAG_DYNAMIC_ARRAYS 0x20 // Dynamic arrays are allowed. #define DECLMASK_NAMED_DECL (DECLFLAG_ARGUMENT | DECLFLAG_VARIABLE | DECLFLAG_MAYBE_FUNCTION) typedef struct { diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index 0679a5fb..a9ae861d 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -94,7 +94,7 @@ static void dumplits(void); static void dumpzero(int count); static void declglb(declinfo_t *decl,int fpublic,int fstatic,int stock); static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct); -static int declloc(int fstatic); +static void declloc(int tokid); static void dodelete(); static void decl_const(int table); static void declstruct(); @@ -2107,171 +2107,97 @@ static void declglb(declinfo_t *decl,int fpublic,int fstatic,int fstock) * global references: declared (altered) * funcstatus (referred to only) */ -static int declloc(int fstatic) +static void declloc(int tokid) { - int ident,tag; - int idxtag[sDIMEN_MAX]; - char name[sNAMEMAX+1]; symbol *sym; - constvalue *enumroot=NULL; - cell val,size; + cell val; char *str; value lval = {0}; int cur_lit=0; - int dim[sDIMEN_MAX]; - int numdim; - int fconst; int staging_start; int slength = 0; + int fstatic = (tokid == tSTATIC); + declinfo_t decl; + + const int declflags = DECLFLAG_VARIABLE | DECLFLAG_ENUMROOT | DECLFLAG_DYNAMIC_ARRAYS; + + parse_decl(&decl, declflags); + + for (;;) { + typeinfo_t *type = &decl.type; - fconst=matchtoken(tCONST); - do { - ident=iVARIABLE; - size=1; slength=0; - numdim=0; /* no dimensions */ - tag=pc_addtag(NULL); - if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */ - error(20,str); /* invalid symbol name */ - assert(strlen(str)<=sNAMEMAX); - strcpy(name,str); /* save symbol name */ - if (name[0]==PUBLIC_CHAR) - error(56,name); /* local variables cannot be public */ + + if (decl.name[0]==PUBLIC_CHAR) + error(56, decl.name); /* local variables cannot be public */ + /* Note: block locals may be named identical to locals at higher * compound blocks (as with standard C); so we must check (and add) * the "nesting level" of local variables to verify the * multi-definition of symbols. */ - if ((sym=findloc(name))!=NULL && sym->compound==nestlevel) - error(21,name); /* symbol already defined */ + if ((sym=findloc(decl.name))!=NULL && sym->compound==nestlevel) + error(21, decl.name); /* symbol already defined */ + /* Although valid, a local variable whose name is equal to that * of a global variable or to that of a local variable at a lower * level might indicate a bug. */ - if (((sym=findloc(name))!=NULL && sym->compound!=nestlevel) || findglb(name,sGLOBAL)!=NULL) - error(219,name); /* variable shadows another symbol */ - if (matchtoken('[')) { - int _index; - cell _code; - int dim_ident; - symbol *dim_sym; - value dim_val; - int all_constant = 1; - int _staging = staging; - - if (!_staging) - stgset(TRUE); - stgget(&_index, &_code); - - do { - if (numdim == sDIMEN_MAX) { - error(53); /* exceeding maximum number of dimensions */ - return (all_constant ? iARRAY : iREFARRAY); - } else if (numdim) { /* if */ - /* If we have a dimension on the stack, push it */ - pushreg(sPRI); - } - if (matchtoken(']')) { - idxtag[numdim] = 0; - dim[numdim] = 0; - numdim++; - continue; - } - dim_ident = doexpr2(TRUE,FALSE,FALSE,FALSE,&idxtag[numdim],&dim_sym,0,&dim_val); - if (dim_ident == iVARIABLE || dim_ident == iEXPRESSION || dim_ident == iARRAYCELL) { - all_constant = 0; - dim[numdim] = 0; - } else if (dim_ident == iCONSTEXPR) { - dim[numdim] = dim_val.constval; - /* :TODO: :URGENT: Make sure this still works */ - if (dim_sym && dim_sym->usage & uENUMROOT) - enumroot = dim_sym->dim.enumlist; - idxtag[numdim] = dim_sym ? dim_sym->tag : 0; - #if INT_MAX < LONG_MAX - if (dim[numdim] > INT_MAX) - error(165); /* overflow, exceeding capacity */ - #endif - } else { - error(29); /* invalid expression, assumed 0 */ - } - numdim++; - needtoken(']'); - } while (matchtoken('[')); - if (all_constant) { - /* Change the last dimension to be based on chars instead if we have a string */ - if (tag == pc_tag_string && numdim && dim[numdim-1]) { - slength = dim[numdim-1]; - dim[numdim-1] = (dim[numdim-1] + sizeof(cell)-1) / sizeof(cell); - } - /* Scrap the code generated */ - ident = iARRAY; - stgdel(_index, _code); - } else { - if (tag == pc_tag_string && numdim) { - stradjust(sPRI); - } - pushreg(sPRI); - /* No idea why this is here, but it throws away dimension info which - would otherwise be used by addvariable2 below. - memset(dim, 0, sizeof(int)*sDIMEN_MAX); - */ - ident = iREFARRAY; - genarray(numdim, autozero); - } - stgout(_index); - if (!_staging) - stgset(FALSE); + if (((sym=findloc(decl.name)) != NULL && sym->compound != nestlevel) || + findglb(decl.name,sGLOBAL) != NULL) + { + error(219, decl.name); /* variable shadows another symbol */ } - if (getstates(name)) - error(88,name); /* local variables may not have states */ - if (ident==iARRAY || fstatic) { + + slength = fix_char_size(&decl); + + if (type->ident == iARRAY || fstatic) { if (sc_alignnext) { aligndata(sc_dataalign); sc_alignnext=FALSE; } /* if */ cur_lit=litidx; /* save current index in the literal table */ - if (numdim && !dim[numdim-1]) - size = 0; - initials(ident,tag,&size,dim,numdim,enumroot); - if (tag == pc_tag_string && (numdim == 1) && !dim[numdim-1]) { + if (type->numdim && !type->dim[type->numdim-1]) + type->size = 0; + initials(type->ident,type->tag,&type->size,type->dim,type->numdim,type->enumroot); + if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1]) slength = glbstringread; - } - if (size==0) - return ident; /* error message already given */ - if (numdim==1) - dim[0]=(int)size; + if (type->size == 0) + return; + if (type->numdim == 1) + type->dim[0] = type->size; } /* reserve memory (on the stack) for the variable */ if (fstatic) { /* write zeros for uninitialized fields */ - while (litidxsize) litadd(0); - sym=addvariable2(name,(cur_lit+glb_declared)*sizeof(cell),ident,sSTATIC, - tag,dim,numdim,idxtag,slength); - } else if (ident!=iREFARRAY) { - declared+=(int)size; /* variables are put on stack, adjust "declared" */ - sym=addvariable2(name,-declared*sizeof(cell),ident,sLOCAL,tag, - dim,numdim,idxtag,slength); - if (ident==iVARIABLE) { + sym=addvariable2(decl.name,(cur_lit+glb_declared)*sizeof(cell),type->ident,sSTATIC, + type->tag,type->dim,type->numdim,type->idxtag,slength); + } else if (type->ident!=iREFARRAY) { + declared+=type->size; /* variables are put on stack, adjust "declared" */ + sym=addvariable2(decl.name,-declared*sizeof(cell),type->ident,sLOCAL,type->tag, + type->dim,type->numdim,type->idxtag,slength); + if (type->ident == iVARIABLE) { assert(!staging); stgset(TRUE); /* start stage-buffering */ assert(stgidx==0); staging_start=stgidx; } /* if */ - markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */ - modstk(-(int)size*sizeof(cell)); - markstack(MEMUSE_STATIC, size); + markexpr(sLDECL,decl.name,-declared*sizeof(cell)); /* mark for better optimization */ + modstk(-type->size * sizeof(cell)); + markstack(MEMUSE_STATIC, type->size); assert(curfunc!=NULL); assert((curfunc->usage & uNATIVE)==0); if (curfunc->x.stacksizex.stacksize=declared+1; /* +1 for PROC opcode */ - } else if (ident==iREFARRAY) { + } else if (type->ident == iREFARRAY) { declared+=1; /* one cell for address */ - sym=addvariable(name,-declared*sizeof(cell),ident,sLOCAL,tag,dim,numdim,idxtag); + sym=addvariable(decl.name,-declared*sizeof(cell),type->ident,sLOCAL,type->tag,type->dim,type->numdim,type->idxtag); //markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */ /* genarray() pushes the address onto the stack, so we don't need to call modstk() here! */ markheap(MEMUSE_DYNAMIC, 0); - markstack(MEMUSE_STATIC, 1); + markstack(MEMUSE_STATIC, 1); assert(curfunc != NULL && ((curfunc->usage & uNATIVE) == 0)); if (curfunc->x.stacksizex.stacksize=declared+1; /* +1 for PROC opcode */ @@ -2280,14 +2206,14 @@ static int declloc(int fstatic) * to initialize it */ assert(sym!=NULL); /* we declared it, it must be there */ sym->compound=nestlevel; /* for multiple declaration/shadowing check */ - if (fconst) + if (type->usage & uCONST) sym->usage|=uCONST; if (!fstatic) { /* static variables already initialized */ - if (ident==iVARIABLE) { + if (type->ident == iVARIABLE) { /* simple variable, also supports initialization */ - int ctag = tag; /* set to "tag" by default */ + int ctag = type->tag; /* set to "tag" by default */ int explicit_init=FALSE;/* is the variable explicitly initialized? */ - int cident=ident; + int cident = type->ident; if (matchtoken('=')) { if (!autozero) error(10); @@ -2302,7 +2228,7 @@ static int declloc(int fstatic) lval.sym=sym; lval.ident=iVARIABLE; lval.constval=0; - lval.tag=tag; + lval.tag=type->tag; check_userop(NULL,ctag,lval.tag,2,NULL,&ctag); store(&lval); markexpr(sEXPR,NULL,0); /* full expression ends after the store */ @@ -2311,16 +2237,16 @@ static int declloc(int fstatic) stgout(staging_start); stgset(FALSE); if (!matchtag_string(cident, ctag)) - matchtag(tag,ctag,TRUE); + matchtag(type->tag,ctag,TRUE); /* if the variable was not explicitly initialized, reset the * "uWRITTEN" flag that store() set */ if (!explicit_init) sym->usage &= ~uWRITTEN; - } else if (ident!=iREFARRAY) { + } else if (type->ident != iREFARRAY) { /* an array */ assert(cur_lit>=0 && cur_lit<=litidx && litidx<=litmax); - assert(size>0 && size>=sym->dim.array.length); - assert(numdim>1 || size==sym->dim.array.length); + assert(type->size > 0 && type->size >= sym->dim.array.length); + assert(type->numdim > 1 || type->size == sym->dim.array.length); if (autozero) { /* final literal values that are zero make no sense to put in the literal * pool, because values get zero-initialized anyway; we check for this, @@ -2329,8 +2255,8 @@ static int declloc(int fstatic) while (litidx>cur_lit && litq[litidx-1]==0) litidx--; /* if the array is not completely filled, set all values to zero first */ - if (litidx-cur_litsize && (ucell)type->size < CELL_MAX) + fillarray(sym, type->size * sizeof(cell), 0); } if (cur_litnumdim == sDIMEN_MAX) { - error(53); - return; + int was_staging = staging; + if (!was_staging) + stgset(TRUE); + stgget(&staging_index, &staging_ptr); + + type->size = 0; + + do { + if (type->numdim == sDIMEN_MAX) { + error(53); + return; + } + + if (type->numdim > 0) { + // Push the last dimension size, which is in PRI. + pushreg(sPRI); + } + + if (matchtoken(']')) { + ldconst(0, sPRI); + type->idxtag[type->numdim] = 0; + type->dim[type->numdim] = 0; + type->numdim++; + continue; + } + + value val; + symbol *sym; + int ident = doexpr2( + TRUE, FALSE, FALSE, FALSE, + &type->idxtag[type->numdim], + &sym, 0, &val + ); + + if (ident == iVARIABLE || ident == iEXPRESSION || ident == iARRAYCELL) { + type->size = -1; + type->dim[type->numdim] = 0; + } else if (ident == iCONSTEXPR) { + if (val.constval > 0) { + if (type->size != -1) + type->size = val.constval; + type->dim[type->numdim] = val.constval; + } else { + error(9); + } + if (sym && sym->usage & uENUMROOT) + type->enumroot = sym->dim.enumlist; + type->idxtag[type->numdim] = sym ? sym->tag : 0; + } else { + error(29); + } + + type->numdim++; + needtoken(']'); + } while (matchtoken('[')); + + if (type->size >= 0) { + // Everything was constant. Drop the emitted assembly. + type->ident = iARRAY; + stgdel(staging_index, staging_ptr); + } else { + if (type->tag == pc_tag_string) + stradjust(sPRI); + pushreg(sPRI); + genarray(type->numdim, autozero); + type->ident = iREFARRAY; + type->size = 0; } - type->size = needsub(&type->idxtag[type->numdim], enumrootp); - if (type->size > INT_MAX) - error(165); + stgout(staging_index); + if (!was_staging) + stgset(FALSE); + } else { + do { + cell size; - type->dim[type->numdim++] = type->size; - } while (matchtoken('[')); + if (type->numdim == sDIMEN_MAX) { + error(53); + return; + } + + type->size = needsub(&type->idxtag[type->numdim], enumrootp); + if (type->size > INT_MAX) + error(165); + + type->dim[type->numdim++] = type->size; + } while (matchtoken('[')); + + type->ident = iARRAY; + } - type->ident = iARRAY; decl->has_postdims = TRUE; } @@ -6449,36 +6464,27 @@ static void statement(int *lastindent,int allow_decl) case 0: /* nothing */ break; + case tINT: + case tVOID: + case tCHAR: + case tOBJECT: + lexpush(); + // Fall-through. + case tDECL: + case tSTATIC: case tNEW: - if (allow_decl) { - autozero=1; - declloc(FALSE); - lastst=tNEW; - } else { - error(3); /* declaration only valid in a block */ - } /* if */ + if (!allow_decl) { + error(3); + break; + } + autozero = (tok != tDECL); + lastst = (tok == tDECL) ? tDECL : tNEW; + declloc(tok); break; case tDELETE: dodelete(); lastst=tDELETE; break; - case tDECL: - if (allow_decl) { - autozero=0; - declloc(FALSE); - lastst=tDECL; - } else { - error(3); /* declaration only valid in a block */ - } /* if */ - break; - case tSTATIC: - if (allow_decl) { - declloc(TRUE); - lastst=tNEW; - } else { - error(3); /* declaration only valid in a block */ - } /* if */ - break; case '{': case tBEGIN: save=fline; @@ -6893,17 +6899,29 @@ static int dofor(void) endtok= matchtoken('(') ? ')' : tDO; if (matchtoken(';')==0) { /* new variable declarations are allowed here */ - if (matchtoken(tNEW)) { - /* The variable in expr1 of the for loop is at a - * 'compound statement' level of it own. - */ - nestlevel++; - autozero=1; - declloc(FALSE); /* declare local variable */ - } else { - doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 1 */ - needtoken(';'); - } /* if */ + token_t tok; + + switch (lextok(&tok)) { + case tINT: + case tCHAR: + case tOBJECT: + case tVOID: + lexpush(); + // Fallthrough. + case tNEW: + /* The variable in expr1 of the for loop is at a + * 'compound statement' level of it own. + */ + nestlevel++; + autozero=1; + declloc(tFOR); /* declare local variable */ + break; + default: + lexpush(); + doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 1 */ + needtoken(';'); + break; + } } /* if */ /* Adjust the "declared" field in the "while queue", in case that * local variables were declared in the first expression of the From 79d9a49d2872844f4ac41a3b6caf67e244720083 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 4 Jul 2014 22:46:55 -0700 Subject: [PATCH 2/5] Fix compiler bug. --- AMBuildScript | 1 - sourcepawn/compiler/sc1.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AMBuildScript b/AMBuildScript index 892e849a..dffad09e 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -163,7 +163,6 @@ class SMConfig(object): '-fno-strict-aliasing', '-Wall', '-Werror', - '-Wno-uninitialized', '-Wno-unused', '-Wno-switch', '-Wno-format', diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index a9ae861d..20af2c98 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -4881,11 +4881,12 @@ static cell fix_char_size(declinfo_t *decl) static symbol *funcstub(int tokid, declinfo_t *decl, const int *thistag) { - int tok,fpublic; + int tok; char *str; cell val,size; symbol *sym,*sub; int fnative = (tokid == tNATIVE || tokid == tMETHODMAP); + int fpublic = (tokid == tPUBLIC); lastst=0; litidx=0; /* clear the literal pool */ From 386b178ef39f53b21410865403eaf57c88f722ff Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 4 Jul 2014 23:00:00 -0700 Subject: [PATCH 3/5] Fix uninitialized variable warning. --- sourcepawn/compiler/sc1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index 20af2c98..fe2fa2c2 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -7262,7 +7262,7 @@ static void doreturn(void) if (!matchtag_string(ident, tag)) matchtag(curfunc->tag,tag,TRUE); if (ident==iARRAY || ident==iREFARRAY) { - int dim[sDIMEN_MAX],numdim; + int dim[sDIMEN_MAX], numdim = 0; cell arraysize; assert(sym!=NULL); if (sub!=NULL) { From 9a2bdd37921476041a2066441dcc33a2a8f325d0 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 4 Jul 2014 23:10:23 -0700 Subject: [PATCH 4/5] Add -Wno-sometimes-uninitialized. --- AMBuildScript | 1 + 1 file changed, 1 insertion(+) diff --git a/AMBuildScript b/AMBuildScript index dffad09e..1f6bd262 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -192,6 +192,7 @@ class SMConfig(object): cxx.cxxflags += ['-Wno-deprecated-register'] else: cxx.cxxflags += ['-Wno-deprecated'] + cxx.cflags += ['-Wno-sometimes-uninitialized'] cxx.linkflags += ['-m32'] cxx.cxxflags += [ From f62769108ce0099d6dec12df83c5f1167880862f Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 4 Jul 2014 23:53:16 -0700 Subject: [PATCH 5/5] Fix some local declarations not working. --- plugins/sounds.sp | 21 +++++++++++---------- sourcepawn/compiler/sc1.c | 24 ++++++++++++++++++++++++ sourcepawn/compiler/sc2.c | 4 ---- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/plugins/sounds.sp b/plugins/sounds.sp index f09b65d8..2ff2c93d 100644 --- a/plugins/sounds.sp +++ b/plugins/sounds.sp @@ -35,7 +35,7 @@ #include -public Plugin:myinfo = +public Plugin myinfo = { name = "Sound Commands", author = "AlliedModders LLC", @@ -44,7 +44,7 @@ public Plugin:myinfo = url = "http://www.sourcemod.net/" }; -public OnPluginStart( ) +public void OnPluginStart() { LoadTranslations("common.phrases"); LoadTranslations("sounds.phrases"); @@ -52,7 +52,7 @@ public OnPluginStart( ) RegAdminCmd("sm_play", Command_Play, ADMFLAG_GENERIC, "sm_play <#userid|name> "); } -public Action:Command_Play(client, args) +public Action Command_Play(int client, int args) { if (args < 2) { @@ -60,11 +60,11 @@ public Action:Command_Play(client, args) return Plugin_Handled; } - new String:Arguments[PLATFORM_MAX_PATH + 65]; + char Arguments[PLATFORM_MAX_PATH + 65]; GetCmdArgString(Arguments, sizeof(Arguments)); - decl String:Arg[65]; - new len = BreakString(Arguments, Arg, sizeof(Arg)); + char Arg[65]; + int len = BreakString(Arguments, Arg, sizeof(Arg)); /* Make sure it does not go out of bound by doing "sm_play user "*/ if (len == -1) @@ -77,7 +77,7 @@ public Action:Command_Play(client, args) if (Arguments[len] == '"') { len++; - new FileLen = TrimString(Arguments[len]) + len; + int FileLen = TrimString(Arguments[len]) + len; if (Arguments[FileLen - 1] == '"') { @@ -85,8 +85,9 @@ public Action:Command_Play(client, args) } } - decl String:target_name[MAX_TARGET_LENGTH]; - decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml; + char target_name[MAX_TARGET_LENGTH]; + char target_list[MAXPLAYERS], target_count; + bool tn_is_ml; if ((target_count = ProcessTargetString( Arg, @@ -102,7 +103,7 @@ public Action:Command_Play(client, args) return Plugin_Handled; } - for (new i = 0; i < target_count; i++) + for (int i = 0; i < target_count; i++) { ClientCommand(target_list[i], "playgamesound \"%s\"", Arguments[len]); LogAction(client, target_list[i], "\"%L\" played sound on \"%L\" (file \"%s\")", client, target_list[i], Arguments[len]); diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index fe2fa2c2..52fbeb8e 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -3361,6 +3361,8 @@ static int reparse_new_decl(declinfo_t *decl, int flags) decl->type.numdim = 0; decl->type.size = 0; decl->type.enumroot = NULL; + decl->type.ident = iVARIABLE; + decl->type.size = 0; decl->has_postdims = FALSE; if (matchtoken('[')) parse_old_array_dims(decl, flags); @@ -6461,6 +6463,28 @@ static void statement(int *lastindent,int allow_decl) *lastindent=stmtindent; indent_nowarn=FALSE; /* if warning was blocked, re-enable it */ } /* if */ + + if (tok == tSYMBOL) { + // We reaaaally don't have enough lookahead for this, so we cheat and try + // to determine whether this is probably a declaration. + int is_decl = FALSE; + if (matchtoken('[')) { + if (lexpeek(']')) + is_decl = TRUE; + lexpush(); + } else if (lexpeek(tSYMBOL)) { + is_decl = TRUE; + } + + if (is_decl) { + lexpush(); + autozero = TRUE; + lastst = tNEW; + declloc(tNEW); + return; + } + } + switch (tok) { case 0: /* nothing */ diff --git a/sourcepawn/compiler/sc2.c b/sourcepawn/compiler/sc2.c index 32d3fa19..33eb0629 100644 --- a/sourcepawn/compiler/sc2.c +++ b/sourcepawn/compiler/sc2.c @@ -2319,10 +2319,6 @@ SC_FUNC int matchtoken(int token) */ SC_FUNC int tokeninfo(cell *val,char **str) { - /* if the token was pushed back, tokeninfo() returns the token and - * parameters of the *next* token, not of the *current* token. - */ - assert(sTokenBuffer->depth == 0); *val = current_token()->value; *str = current_token()->str; return current_token()->id;