1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 23:29:39 +00:00

Fixed handling adjacent macro expansions that should not concatenate.

Example: F()G /* expansion results of F() shall not be concatenated with G */
This commit is contained in:
acqn 2022-08-22 14:34:50 +08:00
parent c7ff416ce9
commit 9f8bfb859c

View File

@ -97,8 +97,16 @@
/* Current PP if stack */
static PPIfStack* PPStack;
/* Struct for rescan */
typedef struct RescanInputStack RescanInputStack;
struct RescanInputStack {
Collection Lines;
Collection LastTokLens;
StrBuf* PrevTok;
};
/* Input backup for rescan */
static Collection* CurRescanStack;
static RescanInputStack* CurRescanStack;
/* Intermediate input buffers */
static StrBuf* PLine; /* Buffer for macro expansion */
@ -168,6 +176,16 @@ static MacroExp* InitMacroExp (MacroExp* E);
static void DoneMacroExp (MacroExp* E);
/* Cleanup after use of a MacroExp structure */
static int CheckPastePPTok (StrBuf* Target, unsigned TokLen, char Next);
/* Return 1 if the last pp-tokens from Source could be concatenated with any
** characters from Appended to form a new valid one.
*/
static void LazyCheckNextPPTok (const StrBuf* Prev, unsigned LastTokLen);
/* Memorize the previous pp-token(s) to later check for potential pp-token
** concatenation.
*/
/*****************************************************************************/
@ -705,22 +723,69 @@ static void DoneMacroExp (MacroExp* E)
/*****************************************************************************/
/* Code */
/* Rescan input stack */
/*****************************************************************************/
static void PushRescanLine (RescanInputStack* RIS, StrBuf* L, unsigned LastTokLen)
/* Push an input line to the rescan input stack */
{
CollAppend (&RIS->Lines, L);
/* Abuse the pointer to store an unsigned */
CollAppend (&RIS->LastTokLens, (void*)(uintptr_t)LastTokLen);
}
static void PopRescanLine (void)
/* Pop and free a rescan input line if it reaches the end */
{
if (CurC == '\0' && CollCount (CurRescanStack) > 1) {
FreeStrBuf (CollPop (CurRescanStack));
InitLine (CollLast (CurRescanStack));
if (CurC == '\0' && CollCount (&CurRescanStack->Lines) > 1) {
FreeStrBuf (CollPop (&CurRescanStack->Lines));
InitLine (CollLast (&CurRescanStack->Lines));
CollPop (&CurRescanStack->LastTokLens);
}
}
static void InitRescanInputStack (RescanInputStack* RIS)
/* Init a RescanInputStack struct */
{
InitCollection (&RIS->Lines);
InitCollection (&RIS->LastTokLens);
RIS->PrevTok = 0;
}
static void DoneRescanInputStack (RescanInputStack* RIS)
/* Free a RescanInputStack struct. RIS must be non-NULL. */
{
/* Free pushed input lines */
while (CollCount (&RIS->Lines) > 1) {
FreeStrBuf (CollPop (&RIS->Lines));
}
/* Switch back to the old input stack */
InitLine (CollPop (&RIS->Lines));
/* Free any remaining pp-tokens used for concatenation check */
FreeStrBuf (RIS->PrevTok);
/* Done */
DoneCollection (&RIS->Lines);
DoneCollection (&RIS->LastTokLens);
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static int MacName (char* Ident)
/* Get a macro symbol name into Ident. If we have an error, print a
** diagnostic message and clear the line.
@ -881,31 +946,7 @@ static int SkipWhitespace (int SkipLines)
int Skipped = 0;
int NewLine = 0;
if (CurRescanStack != 0 &&
CollCount (CurRescanStack) > 1 &&
Line == CollConstLast (CurRescanStack)) {
/* Rescanning */
while (1) {
if (IsSpace (CurC)) {
NextChar ();
Skipped = 1;
} else if (CurC == '/' && NextC == '*') {
OldStyleComment ();
Skipped = 1;
} else if (IS_Get (&Standard) >= STD_C99 && CurC == '/' && NextC == '/') {
NewStyleComment ();
Skipped = 1;
} else if (CurC == '\0') {
/* End of line, switch back input */
PopRescanLine ();
break;
} else {
/* No more white space */
break;
}
}
}
/* Rescanning */
while (1) {
if (IsSpace (CurC)) {
NextChar ();
@ -916,14 +957,51 @@ static int SkipWhitespace (int SkipLines)
} else if (CurC == '/' && NextC == '/') {
NewStyleComment ();
Skipped = 1;
} else if (CurC == '\0' && SkipLines) {
/* End of line, read next */
if (NextLine () != 0) {
++PendingNewLines;
NewLine = 1;
Skipped = 0;
} else if (CurC == '\0') {
/* End of line */
if (CurRescanStack != 0 &&
CollCount (&CurRescanStack->Lines) > 1 &&
Line == CollLast (&CurRescanStack->Lines)) {
unsigned LastTokLen = (unsigned)(uintptr_t)CollLast (&CurRescanStack->LastTokLens);
/* Check for potentially merged tokens */
if (Skipped == 0 && LastTokLen != 0) {
/* Get the following input */
StrBuf* Next = CollAtUnchecked (&CurRescanStack->Lines,
CollCount (&CurRescanStack->Lines) - 2);
char C = SB_Peek (Next);
/* We cannot check right now if the next pp-token may be a
** macro.
*/
if (IsIdent (C)) {
/* Memorize the previous pp-token and check it later */
LazyCheckNextPPTok (Line, LastTokLen);
} else if (C != '\0' && !IsSpace (C)) {
/* If the two adjacent pp-tokens could be put together
** to form a new one, we have to separate them with an
** additional space.
*/
Skipped = CheckPastePPTok (Line, LastTokLen, SB_Peek (Next));
}
}
/* switch back to previous input */
PopRescanLine ();
} else if (SkipLines) {
/* Read next line */
if (NextLine () != 0) {
++PendingNewLines;
NewLine = 1;
Skipped = 0;
} else {
/* End of input */
break;
}
} else {
/* End of input */
break;
}
} else {
@ -931,6 +1009,7 @@ static int SkipWhitespace (int SkipLines)
break;
}
}
return Skipped != 0 ? Skipped : -(NewLine != 0);
}
@ -1131,6 +1210,68 @@ static int GetPunc (char* S)
static int CheckPastePPTok (StrBuf* Source, unsigned TokLen, char Next)
/* Return 1 if the last pp-tokens from Source could be concatenated with any
** characters from Appended to form a new valid one.
*/
{
char C;
unsigned NewTokLen;
StrBuf* OldSource;
StrBuf Src = AUTO_STRBUF_INITIALIZER;
StrBuf Buf = AUTO_STRBUF_INITIALIZER;
if (TokLen == 0 || IsBlank (SB_LookAtLast (Source))) {
return 0;
}
PRECONDITION (SB_GetLen (Source) >= TokLen);
/* Special casing "..", "/ /" and "/ *" that are not pp-tokens but still
** need be separated.
*/
C = SB_LookAt (Source, SB_GetLen (Source) - TokLen);
if ((C == '.' && Next == '.') || (C == '/' && (Next == '/' || Next == '*'))) {
return 1;
}
SB_CopyBuf (&Src, SB_GetConstBuf (Source) + SB_GetLen (Source) - TokLen, TokLen);
SB_AppendChar (&Src, Next);
SB_Reset (&Src);
OldSource = InitLine (&Src);
if (IsPPNumber (CurC, NextC)) {
/* PP-number */
CopyPPNumber (&Buf);
} else if (IsQuotedString ()) {
/* Quoted string */
CopyQuotedString (&Buf);
} else {
ident Ident;
if (GetPunc (Ident)) {
/* Punctuator */
SB_CopyStr (&Buf, Ident);
} else if (IsSym (Ident)) {
/* Identifier */
SB_CopyStr (&Buf, Ident);
}
}
NewTokLen = SB_GetLen (&Buf);
SB_Done (&Buf);
SB_Done (&Src);
/* Restore old source */
InitLine (OldSource);
/* Return if concatenation succeeded */
return NewTokLen != TokLen;
}
static int TryPastePPTok (StrBuf* Target,
StrBuf* Appended,
unsigned FirstTokLen,
@ -1150,10 +1291,18 @@ static int TryPastePPTok (StrBuf* Target,
return 1;
}
/* Since we need to concatenate the token sequences, remove the
** last whitespace that was added to target, since it must come
** from the input.
*/
if (IsBlank (SB_LookAtLast (Target))) {
SB_Drop (Target, 1);
}
PRECONDITION (SB_GetLen (Target) >= FirstTokLen &&
SB_GetLen (Appended) >= SecondTokLen);
/* Special casing "..", "//" and "/*" */
/* Special casing "..", "/ /" and "/ *" */
if (FirstTokLen == 1) {
char C = SB_LookAt (Target, SB_GetLen (Target) - FirstTokLen);
char N = SB_LookAt (Appended, 0);
@ -1163,7 +1312,7 @@ static int TryPastePPTok (StrBuf* Target,
if ((C == '.' && N == '.') || (C == '/' && (N == '/' || N == '*'))) {
SB_AppendChar (Target, ' ');
SB_Append (Target, Appended);
PPWarning ("Pasting formed '%c%c', an invalid preprocessing token", C, N);
PPWarning ("Pasting formed \"%c%c\", an invalid preprocessing token", C, N);
return 0;
}
@ -1206,7 +1355,7 @@ static int TryPastePPTok (StrBuf* Target,
NextChar ();
}
SB_Terminate (&Buf);
PPWarning ("Pasting formed '%s', an invalid preprocessing token",
PPWarning ("Pasting formed \"%s\", an invalid preprocessing token",
SB_GetConstBuf (&Buf));
/* Add a space between the tokens to avoid problems in rescanning */
@ -1242,6 +1391,85 @@ static int TryPastePPTok (StrBuf* Target,
static void SeparatePPTok (StrBuf* Target, char Next)
/* Add a space to target if the previous pp-token could be concatenated with
** the following character.
*/
{
if (CurRescanStack->PrevTok != 0) {
unsigned Len = SB_GetLen (CurRescanStack->PrevTok) - SB_GetIndex (CurRescanStack->PrevTok);
/* Check for pp-token pasting */
if (CheckPastePPTok (CurRescanStack->PrevTok, Len, Next)) {
SB_AppendChar (Target, ' ');
}
FreeStrBuf (CurRescanStack->PrevTok);
CurRescanStack->PrevTok = 0;
}
}
static void LazyCheckNextPPTok (const StrBuf* Prev, unsigned LastTokLen)
/* Memorize the previous pp-token(s) to later check for potential pp-token
** concatenation.
*/
{
char C;
int CheckEllipsis = 0;
unsigned NewIndex = SB_GetLen (Prev) - LastTokLen;
PRECONDITION (SB_GetLen (Prev) >= LastTokLen);
/* Check for some special cases */
C = SB_AtUnchecked (Prev, NewIndex);
/* We may exclude certain punctuators for speedups. As newer C standards
** could add more punctuators such as "[[", "]]", "::" and so on, this
** check might need changes accordingly.
*/
if (C == '[' || C == ']' || C == '(' || C == ')' ||
C == '{' || C == '}' || C == '~' || C == '?' ||
C == ':' || C == ';' || C == ',') {
/* These punctuators cannot be concatenated */
return;
}
/* Special check for .. */
if (NewIndex > 0 &&
C == '.' &&
SB_AtUnchecked (Prev, NewIndex - 1) == '.') {
/* Save the preceding '.' as well */
CheckEllipsis = 1;
}
if (CurRescanStack->PrevTok != 0) {
unsigned OldIndex = SB_GetIndex (CurRescanStack->PrevTok);
unsigned OldLen = SB_GetLen (CurRescanStack->PrevTok) - OldIndex;
unsigned NewLen = SB_GetLen (Prev) - NewIndex;
if (OldLen == NewLen &&
strncmp (SB_GetConstBuf (CurRescanStack->PrevTok) + OldIndex - CheckEllipsis,
SB_GetConstBuf (Prev) + NewIndex - CheckEllipsis,
OldLen + CheckEllipsis) == 0) {
/* Same pp-token, keep using the old one */
} else {
/* Logic error */
SB_Terminate (CurRescanStack->PrevTok);
Internal ("Unchecked pp-token concatenation: \"%s\"",
SB_GetConstBuf (CurRescanStack->PrevTok) + SB_GetIndex (CurRescanStack->PrevTok));
}
} else {
/* Memorize the current line */
CurRescanStack->PrevTok = NewStrBuf ();
SB_CopyBuf (CurRescanStack->PrevTok,
SB_GetConstBuf (Prev) + NewIndex - CheckEllipsis,
LastTokLen + CheckEllipsis);
SB_Reset (CurRescanStack->PrevTok);
}
}
static int CheckExtraTokens (const char* Name)
/* Check for extra tokens at the end of the directive. Return 1 if there are
** extra tokens, otherwise 0.
@ -1315,7 +1543,7 @@ static unsigned ReadMacroArgs (unsigned NameIdx, MacroExp* E, const Macro* M, in
((CurC == ',' && !ME_IsNextArgVariadic (E, M)) || CurC == ')')) {
/* End of actual argument. Remove whitespace from the end. */
while (IsSpace (SB_LookAtLast (&Arg.Tokens))) {
while (IsBlank (SB_LookAtLast (&Arg.Tokens))) {
SB_Drop (&Arg.Tokens, 1);
}
@ -1467,9 +1695,10 @@ static unsigned ReadMacroArgs (unsigned NameIdx, MacroExp* E, const Macro* M, in
static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, Macro* M, unsigned IdentCount)
static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, Macro* M, unsigned* IdentCount)
/* Argument substitution according to ISO/IEC 9899:1999 (E), 6.10.3.1ff.
** Return the count of identifiers and right parentheses in the result.
** Return the length of the last pp-token in the result and output the count
** of identifiers and right parentheses in the result to *IdentCount.
*/
{
unsigned Idx = NameIdx;
@ -1495,7 +1724,7 @@ static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, M
** required by the standard but just to match up with other major C
** compilers.
*/
ME_HandleSemiNestedMacro (NameIdx, NameIdx + IdentCount, E);
ME_HandleSemiNestedMacro (NameIdx, NameIdx + *IdentCount, E);
/* Substitution loop */
while (CurC != '\0') {
@ -1518,6 +1747,11 @@ static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, M
/* Get the corresponding actual argument */
const MacroExp* A = ME_GetOriginalArg (E, ParamIdx);
/* Separate with a white space if necessary */
if (CheckPastePPTok (Target, TokLen, SB_Peek (&A->Tokens))) {
SB_AppendChar (Target, ' ');
}
/* For now we need no placemarkers */
SB_Append (Target, &A->Tokens);
@ -1533,6 +1767,11 @@ static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, M
/* Get the corresponding macro-replaced argument */
const MacroExp* A = ME_GetReplacedArg (E, ParamIdx);
/* Separate with a white space if necessary */
if (CheckPastePPTok (Target, TokLen, SB_Peek (&A->Tokens))) {
SB_AppendChar (Target, ' ');
}
/* Append the replaced string */
SB_Append (Target, &A->Tokens);
@ -1568,7 +1807,7 @@ static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, M
}
/* Squeeze and add the skipped whitespace back for consistency */
if (HaveSpace) {
if (HaveSpace && !IsBlank (SB_LookAtLast (Target))) {
SB_AppendChar (Target, ' ');
}
@ -1577,20 +1816,11 @@ static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, M
} else if (CurC == '#' && NextC == '#') {
/* ## operator. */
/* ## operator */
NextChar ();
NextChar ();
SkipWhitespace (0);
/* Since we need to concatenate the token sequences, remove the
** last whitespace that was added to target, since it must come
** from the input.
*/
if (IsBlank (SB_LookAtLast (Target))) {
SB_Drop (Target, 1);
HaveSpace = 0;
}
/* If the next token is an identifier which is a macro argument,
** replace it, otherwise just add it.
*/
@ -1661,7 +1891,7 @@ static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, M
/* Keep the whitespace for consistency */
HaveSpace = SkipWhitespace (0);
if (HaveSpace) {
if (HaveSpace && !IsBlank (SB_LookAtLast (Target))) {
SB_AppendChar (Target, ' ');
}
@ -1720,23 +1950,24 @@ static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, M
** '/' characters would be parsed wrongly as division operators.
*/
HaveSpace = SkipWhitespace (0);
if (HaveSpace) {
SB_AppendChar (&Buf, ' ');
}
if (NeedPaste) {
unsigned Len = SB_GetLen (&Buf);
/* Concatenate pp-tokens */
if (TryPastePPTok (Target, &Buf, TokLen, Len)) {
TokLen += Len - HaveSpace;
TokLen += Len;
} else {
TokLen = Len - HaveSpace;
TokLen = Len;
}
} else {
/* Just append the token */
SB_Append (Target, &Buf);
TokLen = SB_GetLen (&Buf) - HaveSpace;
TokLen = SB_GetLen (&Buf);
}
if (HaveSpace && !IsBlank (SB_LookAtLast (Target))) {
SB_AppendChar (Target, ' ');
}
}
@ -1745,26 +1976,36 @@ static unsigned SubstMacroArgs (unsigned NameIdx, StrBuf* Target, MacroExp* E, M
SB_Done (&Buf);
/* Remove the macro name itself together with the arguments (if any) */
ME_RemoveToken (Idx, 1 + IdentCount, E);
ME_RemoveToken (Idx, 1 + *IdentCount, E);
/* Hide this macro for the whole result of this expansion */
ME_HideMacro (NameIdx, Idx - NameIdx, E, M);
/* Switch back the input */
UseInputStack (OldInputStack);
InitLine (OldSource);
SB_SetIndex (&M->Replacement, OldIndex);
/* Return the count of substituted identifiers and right parentheses */
return Idx - NameIdx;
/* Set the count of identifiers and right parentheses in the result */
*IdentCount = Idx - NameIdx;
/* Return the length of the last pp-token */
return TokLen;
}
static unsigned ExpandMacro (unsigned Idx, StrBuf* Target, MacroExp* E, Macro* M, int MultiLine)
/* Expand a macro into Target. Return the count of identifiers and right
** parentheses in the result of the expansion.
/* Expand a macro into Target. Return the length of the last pp-token in the
** result of the expansion.
*/
{
/* Count of identifiers and right parentheses */
unsigned Count = 0;
unsigned Count = 0; /* Count of identifiers and right parentheses */
unsigned Len = 0; /* Length of the last pp-token in the result */
/* Disable previous pp-token spacing checking */
StrBuf* PrevTok = CurRescanStack->PrevTok;
CurRescanStack->PrevTok = 0;
#if DEV_CC65_DEBUG
static unsigned V = 0;
@ -1779,7 +2020,7 @@ static unsigned ExpandMacro (unsigned Idx, StrBuf* Target, MacroExp* E, Macro* M
if ((E->Flags & MES_ERROR) == 0) {
/* Replace macro parameters with arguments handling the # and ## operators */
Count = SubstMacroArgs (Idx, Target, E, M, Count);
Len = SubstMacroArgs (Idx, Target, E, M, &Count);
} else {
SB_CopyStr (Target, M->Name);
}
@ -1789,15 +2030,17 @@ static unsigned ExpandMacro (unsigned Idx, StrBuf* Target, MacroExp* E, Macro* M
ME_ClearArgs (E);
}
/* Hide this macro for the whole result of this expansion */
ME_HideMacro (Idx, Count, E, M);
#if DEV_CC65_DEBUG
printf ("Expanded (%u) %s to %d ident(s) at %u: %s\n",
V--, M->Name, Count, Idx, SB_GetConstBuf (Target));
#endif
return Count;
/* Reenable previous pp-token concatenation checking */
FreeStrBuf (CurRescanStack->PrevTok);
CurRescanStack->PrevTok = PrevTok;
/* Return the length of the last pp-token in the expansion result */
return Len;
}
@ -1811,13 +2054,13 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
StrBuf* TmpTarget = NewStrBuf ();
/* Remember the current input and switch to Source */
StrBuf* OldSource = InitLine (Source);
Collection RescanStack = AUTO_COLLECTION_INITIALIZER;
Collection* OldRescanStack = CurRescanStack;
StrBuf* OldSource = InitLine (Source);
RescanInputStack RescanStack;
RescanInputStack* OldRescanStack = CurRescanStack;
InitRescanInputStack (&RescanStack);
PushRescanLine (&RescanStack, Line, 0);
CurRescanStack = &RescanStack;
CollAppend (CurRescanStack, Line);
/* Loop substituting macros */
while (CurC != '\0') {
@ -1839,6 +2082,10 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
NextChar ();
SkipWhitespace (0);
}
/* Add a space to separate the result if necessary */
SeparatePPTok (Target, '0');
if (IsSym (Ident)) {
/* Eat the identifier */
ME_RemoveToken (Count, 1, E);
@ -1864,7 +2111,8 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
/* Check if it's an expandable macro */
if (M != 0 && ME_CanExpand (Count, E, M)) {
int MultiLine = (ModeFlags & MSM_MULTILINE) != 0;
int MultiLine = (ModeFlags & MSM_MULTILINE) != 0;
unsigned LastTokLen;
/* Check if this is a function-like macro */
if (M->ParamCount >= 0) {
@ -1878,7 +2126,8 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
/* No expansion */
++Count;
/* Just keep the macro name */
/* Add a space to separate the macro name if necessary */
SeparatePPTok (Target, M->Name[0]);
SB_AppendStr (Target, M->Name);
/* Keep tracking pp-token lengths */
@ -1929,10 +2178,10 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
*/
if (MultiLine && OLine == 0) {
OLine = TmpTarget;
ExpandMacro (Count, TmpTarget, E, M, MultiLine);
LastTokLen = ExpandMacro (Count, TmpTarget, E, M, MultiLine);
OLine = 0;
} else {
ExpandMacro (Count, TmpTarget, E, M, MultiLine);
LastTokLen = ExpandMacro (Count, TmpTarget, E, M, MultiLine);
}
/* Check for errors in expansion */
@ -1947,7 +2196,7 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
/* Start rescanning from the temporary result */
SB_Reset (TmpTarget);
InitLine (TmpTarget);
CollAppend (CurRescanStack, TmpTarget);
PushRescanLine (CurRescanStack, TmpTarget, LastTokLen);
/* Switch the buffers */
TmpTarget = NewStrBuf ();
@ -1961,6 +2210,9 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
/* An unexpandable identifier. Keep it. */
++Count;
/* Add a space to separate the macro name if necessary */
SeparatePPTok (Target, Ident[0]);
SB_AppendStr (Target, Ident);
/* Keep tracking pp-token lengths */
@ -1973,7 +2225,12 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
}
}
} else {
unsigned LastLen = SB_GetLen (Target);
unsigned LastLen;
/* Add a space to separate the macro name if necessary */
SeparatePPTok (Target, CurC);
LastLen = SB_GetLen (Target);
if ((ModeFlags & MSM_TOK_HEADER) != 0 && (CurC == '<' || CurC == '\"')) {
CopyHeaderNameToken (Target);
@ -1994,6 +2251,14 @@ static unsigned ReplaceMacros (StrBuf* Source, StrBuf* Target, MacroExp* E, unsi
++Count;
}
SB_AppendStr (Target, Ident);
/* If an identifier follows immediately, it could be a macro
** expanded later that occasionally need a space to separate.
*/
if (IsIdent (CurC)) {
/* Memorize the previous pp-token and check it later */
LazyCheckNextPPTok (Target, strlen (Ident));
}
} else {
SB_AppendChar (Target, CurC);
NextChar ();
@ -2014,7 +2279,7 @@ Loop:
/* Switch back to the previous input stream if we have finished
** rescanning the current one.
*/
if (CurC == '\0' && CollCount (CurRescanStack) > 1) {
if (CurC == '\0' && CollCount (&CurRescanStack->Lines) > 1) {
/* Check for rescan sequence end and pp-token pasting */
Skipped = SkipWhitespace (0) || Skipped;
}
@ -2038,18 +2303,12 @@ Loop:
/* Sanity check */
if ((E->Flags & MES_ERROR) == 0) {
CHECK (CollCount (CurRescanStack) == 1);
CHECK (CollCount (&CurRescanStack->Lines) == 1);
}
/* Switch back to the old input stack */
while (CollCount (CurRescanStack) > 1) {
FreeStrBuf (CollPop (CurRescanStack));
}
CurRescanStack = OldRescanStack;
/* Done with the current input stack */
CHECK (CollCount (&RescanStack) == 1);
DoneCollection (&RescanStack);
DoneRescanInputStack (CurRescanStack);
CurRescanStack = OldRescanStack;
/* Switch back the input */
InitLine (OldSource);