diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index 5b611599..91a2ff1c 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -464,6 +464,7 @@ enum TokenKind { tSYMBOL, tLABEL, tSTRING, + tPENDING_STRING, /* string, but not yet dequeued */ tEXPR, /* for assigment to "lastst" only (see SC1.C) */ tENDLESS, /* endless loop, for assigment to "lastst" only */ tEMPTYBLOCK, /* empty blocks for AM bug 4825 */ @@ -960,4 +961,14 @@ enum FatalError { FATAL_ERRORS_TOTAL }; +struct AutoDisableLiteralQueue +{ + public: + AutoDisableLiteralQueue(); + ~AutoDisableLiteralQueue(); + + private: + bool prev_value_; +}; + #endif /* SC_H_INCLUDED */ diff --git a/sourcepawn/compiler/sc1.cpp b/sourcepawn/compiler/sc1.cpp index 03885ac1..959fb02d 100644 --- a/sourcepawn/compiler/sc1.cpp +++ b/sourcepawn/compiler/sc1.cpp @@ -2716,6 +2716,13 @@ static cell initarray(int ident,int tag,int dim[],int numdim,int cur, totalsize+=dsize; if (*errorfound || !matchtoken(',')) abortparse=TRUE; + { + // We need this since, lex() could add a string to the literal queue, + // which totally messes up initvector's state tracking. What a mess. + AutoDisableLiteralQueue disable; + if (lexpeek('}')) + abortparse=TRUE; + } } /* for */ needtoken('}'); assert(counteddim!=NULL); diff --git a/sourcepawn/compiler/sc2.cpp b/sourcepawn/compiler/sc2.cpp index 18e356f6..d02a082a 100644 --- a/sourcepawn/compiler/sc2.cpp +++ b/sourcepawn/compiler/sc2.cpp @@ -69,6 +69,18 @@ static double pow10(double d) } #endif +static bool sLiteralQueueDisabled = false; + +AutoDisableLiteralQueue::AutoDisableLiteralQueue() + : prev_value_(sLiteralQueueDisabled) +{ + sLiteralQueueDisabled = true; +} + +AutoDisableLiteralQueue::~AutoDisableLiteralQueue() +{ + sLiteralQueueDisabled = prev_value_; +} /* pushstk & popstk * @@ -1969,7 +1981,7 @@ const char *sc_tokens[] = { "#endscript", "#error", "#file", "#if", "#include", "#line", "#pragma", "#tryinclude", "#undef", ";", ";", "-integer value-", "-rational value-", "-identifier-", - "-label-", "-string-" + "-label-", "-string-", "-string-" }; static full_token_t *advance_token_ptr() @@ -2136,7 +2148,12 @@ int lex(cell *lexvalue,char **lexsym) || (*lptr==sc_ctrlchar && *(lptr+1)=='!' && *(lptr+2)=='\"') /* packed raw string */ #endif ) - { + { + if (sLiteralQueueDisabled) { + tok->id = tPENDING_STRING; + tok->end = tok->start; + return tok->id; + } int stringflags,segmentflags; char *cat; tok->id = tSTRING; @@ -2261,6 +2278,11 @@ int lex(cell *lexvalue,char **lexsym) */ void lexpush(void) { + if (current_token()->id == tPENDING_STRING) { + // Don't push back fake tokens. + return; + } + assert(sTokenBuffer->depth < MAX_TOKEN_DEPTH); sTokenBuffer->depth++; if (sTokenBuffer->cursor == 0) @@ -2484,6 +2506,7 @@ static void chk_grow_litq(void) */ void litadd(cell value) { + assert(!sLiteralQueueDisabled); chk_grow_litq(); assert(litidx=0 && pos<=litidx);