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:
@@ -156,3 +156,29 @@ void CheckInputStack (void)
|
|||||||
Error ("Open %s", IStack->Desc);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Opaque pointer to an input stack */
|
||||||
|
typedef void* InputStack;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -63,6 +74,15 @@ void CheckInputStack (void);
|
|||||||
** stuff on the input stack.
|
** 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 */
|
/* End of istack.h */
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ struct CharSource {
|
|||||||
token_t Tok; /* Last token */
|
token_t Tok; /* Last token */
|
||||||
int C; /* Last character */
|
int C; /* Last character */
|
||||||
int SkipN; /* For '\r\n' line endings, skip '\n\ if next */
|
int SkipN; /* For '\r\n' line endings, skip '\n\ if next */
|
||||||
|
InputStack IStack; /* Saved input stack */
|
||||||
const CharSourceFunctions* Func; /* Pointer to function table */
|
const CharSourceFunctions* Func; /* Pointer to function table */
|
||||||
union {
|
union {
|
||||||
InputFile File; /* File data */
|
InputFile File; /* File data */
|
||||||
@@ -321,6 +322,9 @@ static void UseCharSource (CharSource* S)
|
|||||||
S->Tok = CurTok.Tok;
|
S->Tok = CurTok.Tok;
|
||||||
S->C = C;
|
S->C = C;
|
||||||
|
|
||||||
|
/* Remember the current input stack */
|
||||||
|
S->IStack = RetrieveInputStack ();
|
||||||
|
|
||||||
/* Use the new input source */
|
/* Use the new input source */
|
||||||
S->Next = Source;
|
S->Next = Source;
|
||||||
Source = S;
|
Source = S;
|
||||||
@@ -349,6 +353,9 @@ static void DoneCharSource (void)
|
|||||||
CurTok.Tok = Source->Tok;
|
CurTok.Tok = Source->Tok;
|
||||||
C = Source->C;
|
C = Source->C;
|
||||||
|
|
||||||
|
/* Restore the old input source */
|
||||||
|
RestoreInputStack (Source->IStack);
|
||||||
|
|
||||||
/* Remember the last stacked input source */
|
/* Remember the last stacked input source */
|
||||||
S = Source->Next;
|
S = Source->Next;
|
||||||
|
|
||||||
@@ -1521,7 +1528,7 @@ CharAgain:
|
|||||||
/* In case of the main file, do not close it, but return EOF. */
|
/* In case of the main file, do not close it, but return EOF. */
|
||||||
if (Source && Source->Next) {
|
if (Source && Source->Next) {
|
||||||
DoneCharSource ();
|
DoneCharSource ();
|
||||||
goto Again;
|
goto Restart;
|
||||||
} else {
|
} else {
|
||||||
CurTok.Tok = TOK_EOF;
|
CurTok.Tok = TOK_EOF;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user