1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-15 02:29:32 +00:00

Modified way to keep undefined macro handling more consistent.

This commit is contained in:
acqn 2022-08-18 22:51:23 +08:00
parent 7971eec3cc
commit 47d5e74a6e
3 changed files with 70 additions and 80 deletions

View File

@ -56,6 +56,9 @@
#define MACRO_TAB_SIZE 211
static Macro* MacroTab[MACRO_TAB_SIZE];
/* The undefined macros list head */
static Macro* UndefinedMacrosListHead;
/*****************************************************************************/
@ -173,10 +176,11 @@ void InsertMacro (Macro* M)
int UndefineMacro (const char* Name)
/* Search for the macro with the given name and remove it from the macro
** table if it exists. Return 1 if a macro was found and deleted, return
** 0 otherwise.
Macro* UndefineMacro (const char* Name)
/* Search for the macro with the given name, if it exists, remove it from
** the defined macro table and insert it to a list for pending deletion.
** Return the macro if it was found and removed, return 0 otherwise.
** To safely free the removed macro, use FreeUndefinedMacros().
*/
{
/* Get the hash value of the macro name */
@ -196,11 +200,12 @@ int UndefineMacro (const char* Name)
L->Next = M->Next;
}
/* Delete the macro */
FreeMacro (M);
/* Add this macro to pending deletion list */
M->Next = UndefinedMacrosListHead;
UndefinedMacrosListHead = M;
/* Done */
return 1;
return M;
}
/* Next macro */
@ -214,6 +219,23 @@ int UndefineMacro (const char* Name)
void FreeUndefinedMacros (void)
/* Free all undefined macros */
{
Macro* Next;
while (UndefinedMacrosListHead != 0) {
Next = UndefinedMacrosListHead->Next;
/* Delete the macro */
FreeMacro (UndefinedMacrosListHead);
UndefinedMacrosListHead = Next;
}
}
Macro* FindMacro (const char* Name)
/* Find a macro with the given name. Return the macro definition or NULL */
{

View File

@ -97,12 +97,16 @@ void DefineTextMacro (const char* Name, const char* Val);
void InsertMacro (Macro* M);
/* Insert the given macro into the macro table. */
int UndefineMacro (const char* Name);
/* Search for the macro with the given name and remove it from the macro
** table if it exists. Return 1 if a macro was found and deleted, return
** 0 otherwise.
Macro* UndefineMacro (const char* Name);
/* Search for the macro with the given name, if it exists, remove it from
** the defined macro table and insert it to a list for pending deletion.
** Return the macro if it was found and removed, return 0 otherwise.
** To safely free the removed macro, use FreeUndefinedMacros().
*/
void FreeUndefinedMacros (void);
/* Free all undefined macros */
Macro* FindMacro (const char* Name);
/* Find a macro with the given name. Return the macro definition or NULL */

View File

@ -90,7 +90,6 @@ typedef struct MacroExp MacroExp;
struct MacroExp {
Collection ActualArgs; /* Actual arguments */
StrBuf Replacement; /* Replacement with arguments substituted */
Macro* M; /* The macro we're handling */
};
@ -193,12 +192,11 @@ static pptoken_t FindPPToken (const char* Ident)
static MacroExp* InitMacroExp (MacroExp* E, Macro* M)
static MacroExp* InitMacroExp (MacroExp* E)
/* Initialize a MacroExp structure */
{
InitCollection (&E->ActualArgs);
SB_Init (&E->Replacement);
E->M = M;
return E;
}
@ -244,11 +242,11 @@ static StrBuf* ME_GetActual (MacroExp* E, unsigned Index)
static int ME_ArgIsVariadic (const MacroExp* E)
static int ME_ArgIsVariadic (const MacroExp* E, const Macro* M)
/* Return true if the next actual argument we will add is a variadic one */
{
return (E->M->Variadic &&
E->M->ArgCount == (int) CollCount (&E->ActualArgs) + 1);
return (M->Variadic &&
M->ArgCount == (int) CollCount (&E->ActualArgs) + 1);
}
@ -524,7 +522,7 @@ static int MacName (char* Ident)
static void ReadMacroArgs (MacroExp* E, int MultiLine)
static void ReadMacroArgs (MacroExp* E, const Macro* M, int MultiLine)
/* Identify the arguments to a macro call as-is */
{
int MissingParen = 0;
@ -576,7 +574,7 @@ static void ReadMacroArgs (MacroExp* E, int MultiLine)
}
SB_AppendChar (&Arg, CurC);
NextChar ();
} else if (CurC == ',' && ME_ArgIsVariadic (E)) {
} else if (CurC == ',' && ME_ArgIsVariadic (E, M)) {
/* It's a comma, but we're inside a variadic macro argument, so
** just copy it and proceed.
*/
@ -591,7 +589,7 @@ static void ReadMacroArgs (MacroExp* E, int MultiLine)
/* If this is not the single empty argument for a macro with
** an empty argument list, remember it.
*/
if (CurC != ')' || SB_NotEmpty (&Arg) || E->M->ArgCount > 0) {
if (CurC != ')' || SB_NotEmpty (&Arg) || M->ArgCount > 0) {
ME_AppendActual (E, &Arg);
}
@ -607,7 +605,7 @@ static void ReadMacroArgs (MacroExp* E, int MultiLine)
}
} else if (CurC == '\0') {
/* End of input inside macro argument list */
PPError ("Unterminated argument list invoking macro '%s'", E->M->Name);
PPError ("Unterminated argument list invoking macro '%s'", M->Name);
MissingParen = 1;
ClearLine ();
break;
@ -619,7 +617,7 @@ static void ReadMacroArgs (MacroExp* E, int MultiLine)
}
/* Compare formal and actual argument count */
if (CollCount (&E->ActualArgs) != (unsigned) E->M->ArgCount) {
if (CollCount (&E->ActualArgs) != (unsigned) M->ArgCount) {
if (!MissingParen) {
/* Argument count mismatch */
@ -628,7 +626,7 @@ static void ReadMacroArgs (MacroExp* E, int MultiLine)
/* Be sure to make enough empty arguments available */
SB_Clear (&Arg);
while (CollCount (&E->ActualArgs) < (unsigned) E->M->ArgCount) {
while (CollCount (&E->ActualArgs) < (unsigned) M->ArgCount) {
ME_AppendActual (E, &Arg);
}
}
@ -639,7 +637,7 @@ static void ReadMacroArgs (MacroExp* E, int MultiLine)
static void MacroArgSubst (MacroExp* E)
static void MacroArgSubst (MacroExp* E, Macro* M)
/* Argument substitution according to ISO/IEC 9899:1999 (E), 6.10.3.1ff */
{
ident Ident;
@ -650,9 +648,9 @@ static void MacroArgSubst (MacroExp* E)
/* Remember the current input and switch to the macro replacement. */
int OldIndex = SB_GetIndex (&E->M->Replacement);
SB_Reset (&E->M->Replacement);
OldSource = InitLine (&E->M->Replacement);
int OldIndex = SB_GetIndex (&M->Replacement);
SB_Reset (&M->Replacement);
OldSource = InitLine (&M->Replacement);
/* Argument handling loop */
while (CurC != '\0') {
@ -661,7 +659,7 @@ static void MacroArgSubst (MacroExp* E)
if (IsSym (Ident)) {
/* Check if it's a macro argument */
if ((ArgIdx = FindMacroArg (E->M, Ident)) >= 0) {
if ((ArgIdx = FindMacroArg (M, Ident)) >= 0) {
/* A macro argument. Get the corresponding actual argument. */
Arg = ME_GetActual (E, ArgIdx);
@ -720,7 +718,7 @@ static void MacroArgSubst (MacroExp* E)
if (IsSym (Ident)) {
/* Check if it's a macro argument */
if ((ArgIdx = FindMacroArg (E->M, Ident)) >= 0) {
if ((ArgIdx = FindMacroArg (M, Ident)) >= 0) {
/* Get the corresponding actual argument and add it. */
SB_Append (&E->Replacement, ME_GetActual (E, ArgIdx));
@ -733,7 +731,7 @@ static void MacroArgSubst (MacroExp* E)
}
}
} else if (CurC == '#' && E->M->ArgCount >= 0) {
} else if (CurC == '#' && M->ArgCount >= 0) {
/* A # operator within a macro expansion of a function like
** macro. Read the following identifier and check if it's a
@ -741,7 +739,7 @@ static void MacroArgSubst (MacroExp* E)
*/
NextChar ();
SkipWhitespace (0);
if (!IsSym (Ident) || (ArgIdx = FindMacroArg (E->M, Ident)) < 0) {
if (!IsSym (Ident) || (ArgIdx = FindMacroArg (M, Ident)) < 0) {
PPError ("'#' is not followed by a macro parameter");
} else {
/* Make a valid string from Replacement */
@ -767,7 +765,7 @@ static void MacroArgSubst (MacroExp* E)
/* Switch back the input */
InitLine (OldSource);
SB_SetIndex (&E->M->Replacement, OldIndex);
SB_SetIndex (&M->Replacement, OldIndex);
}
@ -783,65 +781,28 @@ static void ExpandMacro (StrBuf* Target, Macro* M, int MultiLine)
#endif
/* Initialize our MacroExp structure */
InitMacroExp (&E, M);
InitMacroExp (&E);
/* Check if this is a function like macro */
if (E.M->ArgCount >= 0) {
/* Since the macro could be undefined or redefined during its argument
** parsing, we make a clone of the current one and stick to it.
*/
if (MultiLine) {
E.M = CloneMacro (E.M);
}
if (M->ArgCount >= 0) {
/* Read the actual macro arguments (with the enclosing parentheses) */
ReadMacroArgs (&E, MultiLine);
/* Replace macro arguments handling the # and ## operators */
MacroArgSubst (&E);
/* Do macro replacement on the macro that already has the parameters
** substituted.
*/
if (MultiLine) {
/* Check if the macro was undefined or redefined */
M = FindMacro (E.M->Name);
if (M == 0 || MacroCmp (E.M, M) != 0) {
/* Use the cloned macro */
M = E.M;
}
}
/* Forbide repeated expansion of the same macro in use */
M->Expanding = 1;
MacroReplacement (&E.Replacement, Target, 0);
M->Expanding = 0;
} else {
/* Handle # and ## operators for object like macros */
MacroArgSubst (&E);
/* Do macro replacement on the macro that already has the parameters
** substituted.
*/
M->Expanding = 1;
MacroReplacement (&E.Replacement, Target, 0);
M->Expanding = 0;
ReadMacroArgs (&E, M, MultiLine);
}
/* Replace macro arguments handling the # and ## operators */
MacroArgSubst (&E, M);
/* Forbide repeated expansion of the same macro in use */
M->Expanding = 1;
MacroReplacement (&E.Replacement, Target, 0);
M->Expanding = 0;
#if 0
printf ("Done with %s(%u)\n", E.M->Name, V--);
#endif
/* Free cloned macro */
if (MultiLine && E.M->ArgCount >= 0) {
FreeMacro (E.M);
E.M = 0;
}
/* Free memory allocated for the macro expansion structure */
DoneMacroExp (&E);
}
@ -1662,6 +1623,9 @@ void Preprocess (void)
printf ("%s:%u: %.*s\n", GetCurrentFile (), GetCurrentLine (),
(int) SB_GetLen (Line), SB_GetConstBuf (Line));
}
/* Free all undefined macros */
FreeUndefinedMacros ();
}