Store IF depth relative to each fstack context

This disallows starting/ending an IF inside an
INCLUDEd file or a macro expansion
This commit is contained in:
Rangi
2021-01-08 16:28:51 -05:00
committed by Eldred Habert
parent 62bea23c49
commit cab9cb06a3
12 changed files with 64 additions and 21 deletions

View File

@@ -31,6 +31,7 @@ struct Context {
struct Context *parent;
struct FileStackNode *fileInfo;
struct LexerState *lexerState;
uint32_t nIFDepth;
uint32_t uniqueID;
struct MacroArgs *macroArgs; /* Macro args are *saved* here */
uint32_t nbReptIters;
@@ -47,7 +48,22 @@ size_t nMaxRecursionDepth;
static unsigned int nbIncPaths = 0;
static char const *includePaths[MAXINCPATHS];
char const *dumpNodeAndParents(struct FileStackNode const *node)
uint32_t fstk_GetIFDepth(void)
{
return contextStack->nIFDepth;
}
void fstk_IncIFDepth(void)
{
contextStack->nIFDepth++;
}
void fstk_DecIFDepth(void)
{
contextStack->nIFDepth--;
}
static const char *dumpNodeAndParents(struct FileStackNode const *node)
{
char const *name;
@@ -200,6 +216,10 @@ bool fstk_FindFile(char const *path, char **fullPath, size_t *size)
bool yywrap(void)
{
if (contextStack->nIFDepth != 0)
fatalerror("Ended block with %" PRIu32 " unterminated IF construct%s\n",
contextStack->nIFDepth, contextStack->nIFDepth == 1 ? "" : "s");
if (contextStack->fileInfo->type == NODE_REPT) { /* The context is a REPT block, which may loop */
struct FileStackReptNode *fileInfo = (struct FileStackReptNode *)contextStack->fileInfo;
@@ -283,6 +303,7 @@ static void newContext(struct FileStackNode *fileInfo)
fileInfo->referenced = false;
fileInfo->lineNo = lexer_GetLineNo();
context->fileInfo = fileInfo;
context->nIFDepth = 0;
context->forName = NULL;
/*
* Link new entry to its parent so it's reachable later
@@ -429,7 +450,7 @@ static bool newReptContext(int32_t reptLineNo, char *body, size_t size)
contextStack->lexerState = lexer_OpenFileView(body, size, reptLineNo);
if (!contextStack->lexerState)
fatalerror("Failed to set up lexer for rept block\n");
fatalerror("Failed to set up lexer for REPT block\n");
lexer_SetStateAtEOL(contextStack->lexerState);
contextStack->uniqueID = macro_UseNewUniqueID();
return true;
@@ -521,6 +542,7 @@ void fstk_Init(char const *mainPath, size_t maxRecursionDepth)
context->parent = NULL;
context->lexerState = state;
context->nIFDepth = 0;
context->uniqueID = 0;
macro_SetUniqueID(0);
context->nbReptIters = 0;

View File

@@ -1966,7 +1966,7 @@ static int skipIfBlock(bool toEndc)
{
dbgPrint("Skipping IF block (toEndc = %s)\n", toEndc ? "true" : "false");
lexer_SetMode(LEXER_NORMAL);
int startingDepth = nIFDepth;
int startingDepth = fstk_GetIFDepth();
int token;
bool atLineStart = lexerState->atLineStart;
@@ -1990,7 +1990,7 @@ static int skipIfBlock(bool toEndc)
token = readIdentifier(c);
switch (token) {
case T_POP_IF:
nIFDepth++;
fstk_IncIFDepth();
break;
case T_POP_ELIF:
@@ -1999,10 +1999,10 @@ static int skipIfBlock(bool toEndc)
break;
/* fallthrough */
case T_POP_ENDC:
if (nIFDepth == startingDepth)
if (fstk_GetIFDepth() == startingDepth)
goto finish;
if (token == T_POP_ENDC)
nIFDepth--;
fstk_DecIFDepth();
}
}
atLineStart = false;
@@ -2087,11 +2087,11 @@ static int yylex_SKIP_TO_ENDR(void)
break;
case T_POP_IF:
nIFDepth++;
fstk_IncIFDepth();
break;
case T_POP_ENDC:
nIFDepth--;
fstk_DecIFDepth();
}
}
atLineStart = false;

View File

@@ -46,7 +46,7 @@ const size_t cldefine_entrysize = 2 * sizeof(void *);
char **cldefines;
clock_t nStartClock, nEndClock;
uint32_t nTotalLines, nIFDepth;
uint32_t nTotalLines;
#if defined(YYDEBUG) && YYDEBUG
extern int yydebug;
@@ -488,7 +488,6 @@ int main(int argc, char *argv[])
nStartClock = clock();
nTotalLines = 0;
nIFDepth = 0;
sym_Init(now);
sym_SetExportAll(exportall);
@@ -502,10 +501,6 @@ int main(int argc, char *argv[])
if (dependfile)
fclose(dependfile);
if (nIFDepth != 0)
errx(1, "Unterminated IF construct (%" PRIu32 " levels)!",
nIFDepth);
sect_CheckUnionClosed();
double timespent;

View File

@@ -563,7 +563,7 @@ conditional : if
;
if : T_POP_IF const T_NEWLINE {
nIFDepth++;
fstk_IncIFDepth();
executeElseBlock = !$2;
if (executeElseBlock)
lexer_SetMode(LEXER_SKIP_TO_ELIF);
@@ -571,7 +571,7 @@ if : T_POP_IF const T_NEWLINE {
;
elif : T_POP_ELIF const T_NEWLINE {
if (nIFDepth <= 0)
if (fstk_GetIFDepth() == 0)
fatalerror("Found ELIF outside an IF construct\n");
if (!executeElseBlock) {
@@ -585,7 +585,7 @@ elif : T_POP_ELIF const T_NEWLINE {
;
else : T_POP_ELSE T_NEWLINE {
if (nIFDepth <= 0)
if (fstk_GetIFDepth() == 0)
fatalerror("Found ELSE outside an IF construct\n");
if (!executeElseBlock)
@@ -594,10 +594,10 @@ else : T_POP_ELSE T_NEWLINE {
;
endc : T_POP_ENDC T_NEWLINE {
if (nIFDepth <= 0)
if (fstk_GetIFDepth() == 0)
fatalerror("Found ENDC outside an IF construct\n");
nIFDepth--;
fstk_DecIFDepth();
executeElseBlock = false;
}
;