Fix behavior of .INCLUDE within a macro or .REPEAT. In the original code

.INCLUDE was executed after expansion of the macro or .REPEAT - which was
wrong and caused all sorts of unexpected behavior. Related issues/PRs
are #231, #1473, #2159 and maybe others.

Note: After this change error messages for nested macro/.include statements
may be wrong. This is an unrelated bug that was always there and got exposed
by this fix. The bug needs to be addressed in a separate PR.
This commit is contained in:
Kugel Fuhr 2024-09-01 19:58:07 +02:00
parent b688cfa0c0
commit b2aceaea24
3 changed files with 55 additions and 2 deletions

View File

@ -156,3 +156,29 @@ void CheckInputStack (void)
Error ("Open %s", IStack->Desc);
}
}
InputStack RetrieveInputStack (void)
/* Retrieve the current input stack. This will also clear it. Used when
** including a file. The current input stack is stored together with the old
** input file and restored when the file is closed.
*/
{
/* We do not touch the counter so input sources are counted across
** includes.
*/
InputStack S = IStack;
IStack = 0;
return S;
}
void RestoreInputStack (InputStack S)
/* Restore an old input stack that was retrieved by RetrieveInputStack(). */
{
CHECK (IStack == 0);
IStack = S;
}

View File

@ -38,6 +38,17 @@
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Opaque pointer to an input stack */
typedef void* InputStack;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@ -63,6 +74,15 @@ void CheckInputStack (void);
** stuff on the input stack.
*/
InputStack RetrieveInputStack (void);
/* Retrieve the current input stack. This will also clear it. Used when
** including a file. The current input stack is stored together with the old
** input file and restored when the file is closed.
*/
void RestoreInputStack (InputStack S);
/* Restore an old input stack that was retrieved by RetrieveInputStack(). */
/* End of istack.h */

View File

@ -113,6 +113,7 @@ struct CharSource {
token_t Tok; /* Last token */
int C; /* Last character */
int SkipN; /* For '\r\n' line endings, skip '\n\ if next */
InputStack IStack; /* Saved input stack */
const CharSourceFunctions* Func; /* Pointer to function table */
union {
InputFile File; /* File data */
@ -321,6 +322,9 @@ static void UseCharSource (CharSource* S)
S->Tok = CurTok.Tok;
S->C = C;
/* Remember the current input stack */
S->IStack = RetrieveInputStack ();
/* Use the new input source */
S->Next = Source;
Source = S;
@ -347,7 +351,10 @@ static void DoneCharSource (void)
/* Restore the old token */
CurTok.Tok = Source->Tok;
C = Source->C;
C = Source->C;
/* Restore the old input source */
RestoreInputStack (Source->IStack);
/* Remember the last stacked input source */
S = Source->Next;
@ -1521,7 +1528,7 @@ CharAgain:
/* In case of the main file, do not close it, but return EOF. */
if (Source && Source->Next) {
DoneCharSource ();
goto Again;
goto Restart;
} else {
CurTok.Tok = TOK_EOF;
}