/*****************************************************************************/
/* */
-/* macrotab.h */
+/* macrotab.h */
/* */
-/* Preprocessor macro table for the cc65 C compiler */
+/* Preprocessor macro table for the cc65 C compiler */
/* */
/* */
/* */
-/* (C) 2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2000-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include <string.h>
/* common */
-#include "hashstr.h"
+#include "hashfunc.h"
#include "xmalloc.h"
/* cc65 */
/*****************************************************************************/
-/* data */
+/* data */
/*****************************************************************************/
/* The macro hash table */
-#define MACRO_TAB_SIZE 211
+#define MACRO_TAB_SIZE 211
static Macro* MacroTab[MACRO_TAB_SIZE];
-/* A table that holds the count of macros that start with a specific character.
- * It is used to determine quickly, if an identifier may be a macro or not
- * without calculating the hash over the name.
- */
-static unsigned short MacroFlagTab[256];
-
/*****************************************************************************/
-/* code */
+/* code */
/*****************************************************************************/
Macro* NewMacro (const char* Name)
/* Allocate a macro structure with the given name. The structure is not
- * inserted into the macro table.
- */
+** inserted into the macro table.
+*/
{
/* Get the length of the macro name */
unsigned Len = strlen(Name);
Macro* M = (Macro*) xmalloc (sizeof(Macro) + Len);
/* Initialize the data */
- M->Next = 0;
- M->ArgCount = -1; /* Flag: Not a function like macro */
- M->MaxArgs = 0;
- M->FormalArgs = 0;
- M->ActualArgs = 0;
- M->Replacement = 0;
+ M->Next = 0;
+ M->Expanding = 0;
+ M->ArgCount = -1; /* Flag: Not a function like macro */
+ M->MaxArgs = 0;
+ InitCollection (&M->FormalArgs);
+ SB_Init (&M->Replacement);
+ M->Variadic = 0;
memcpy (M->Name, Name, Len+1);
/* Return the new macro */
void FreeMacro (Macro* M)
/* Delete a macro definition. The function will NOT remove the macro from the
- * table, use UndefineMacro for that.
- */
+** table, use UndefineMacro for that.
+*/
{
- int I;
+ unsigned I;
- for (I = 0; I < M->ArgCount; ++I) {
- xfree (M->FormalArgs[I]);
+ for (I = 0; I < CollCount (&M->FormalArgs); ++I) {
+ xfree (CollAtUnchecked (&M->FormalArgs, I));
}
- xfree (M->FormalArgs);
- xfree (M->ActualArgs);
- xfree (M->Replacement);
+ DoneCollection (&M->FormalArgs);
+ SB_Done (&M->Replacement);
xfree (M);
}
-void AddNumericMacro (const char* Name, long Val)
-/* Add a macro for a numeric constant */
+void DefineNumericMacro (const char* Name, long Val)
+/* Define a macro for a numeric constant */
{
char Buf[64];
sprintf (Buf, "%ld", Val);
/* Handle as text macro */
- AddTextMacro (Name, Buf);
+ DefineTextMacro (Name, Buf);
}
-void AddTextMacro (const char* Name, const char* Val)
-/* Add a macro for a textual constant */
+void DefineTextMacro (const char* Name, const char* Val)
+/* Define a macro for a textual constant */
{
/* Create a new macro */
Macro* M = NewMacro (Name);
/* Set the value as replacement text */
- M->Replacement = xstrdup (Val);
+ SB_CopyStr (&M->Replacement, Val);
/* Insert the macro into the macro table */
InsertMacro (M);
void InsertMacro (Macro* M)
-/* Insert the given macro into the macro table. This call will also allocate
- * the ActualArgs parameter array.
- */
+/* Insert the given macro into the macro table. */
{
- unsigned Hash;
-
- /* Allocate the ActualArgs parameter array */
- if (M->ArgCount > 0) {
- M->ActualArgs = (char const**) xmalloc (M->ArgCount * sizeof(char*));
- }
-
/* Get the hash value of the macro name */
- Hash = HashStr (M->Name) % MACRO_TAB_SIZE;
+ unsigned Hash = HashStr (M->Name) % MACRO_TAB_SIZE;
/* Insert the macro */
M->Next = MacroTab[Hash];
MacroTab[Hash] = M;
-
- /* Increment the number of macros starting with this char */
- MacroFlagTab[(unsigned)(unsigned char)M->Name[0]]++;
}
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.
- */
+** table if it exists. Return 1 if a macro was found and deleted, return
+** 0 otherwise.
+*/
{
/* Get the hash value of the macro name */
unsigned Hash = HashStr (Name) % MACRO_TAB_SIZE;
Macro* L = 0;
Macro* M = MacroTab[Hash];
while (M) {
- if (strcmp (M->Name, Name) == 0) {
-
- /* Found it */
- if (L == 0) {
- /* First in chain */
- MacroTab[Hash] = M->Next;
- } else {
- L->Next = M->Next;
- }
-
- /* Decrement the number of macros starting with this char */
- MacroFlagTab[(unsigned)(unsigned char)M->Name[0]]--;
-
- /* Delete the macro */
- FreeMacro (M);
-
- /* Done */
- return 1;
- }
-
- /* Next macro */
- L = M;
- M = M->Next;
+ if (strcmp (M->Name, Name) == 0) {
+
+ /* Found it */
+ if (L == 0) {
+ /* First in chain */
+ MacroTab[Hash] = M->Next;
+ } else {
+ L->Next = M->Next;
+ }
+
+ /* Delete the macro */
+ FreeMacro (M);
+
+ /* Done */
+ return 1;
+ }
+
+ /* Next macro */
+ L = M;
+ M = M->Next;
}
/* Not found */
/* Search the hash chain */
Macro* M = MacroTab[Hash];
while (M) {
- if (strcmp (M->Name, Name) == 0) {
- /* Found it */
- return M;
- }
+ if (strcmp (M->Name, Name) == 0) {
+ /* Found it */
+ return M;
+ }
- /* Next macro */
- M = M->Next;
+ /* Next macro */
+ M = M->Next;
}
/* Not found */
-int IsMacro (const char* Name)
-/* Return true if the given name is the name of a macro, return false otherwise */
-{
- return FindMacro(Name) != 0;
-}
-
-
-
-int MaybeMacro (unsigned char C)
-/* Return true if the given character may be the start of the name of an
- * existing macro, return false if not.
- */
+int FindMacroArg (Macro* M, const char* Arg)
+/* Search for a formal macro argument. If found, return the index of the
+** argument. If the argument was not found, return -1.
+*/
{
- return (MacroFlagTab[C] > 0);
-}
-
-
-
-const char* FindMacroArg (Macro* M, const char* Arg)
-/* Search for a formal macro argument. If found, return the actual
- * (replacement) argument. If the argument was not found, return NULL.
- */
-{
- int I;
- for (I = 0; I < M->ArgCount; ++I) {
- if (strcmp (M->FormalArgs[I], Arg) == 0) {
- /* Found */
- return M->ActualArgs[I];
- }
+ unsigned I;
+ for (I = 0; I < CollCount (&M->FormalArgs); ++I) {
+ if (strcmp (CollAtUnchecked (&M->FormalArgs, I), Arg) == 0) {
+ /* Found */
+ return I;
+ }
}
+
/* Not found */
- return 0;
+ return -1;
}
/* Add a formal macro argument. */
{
/* Check if we have a duplicate macro argument, but add it anyway.
- * Beware: Don't use FindMacroArg here, since the actual argument array
- * may not be initialized.
- */
- int I;
- for (I = 0; I < M->ArgCount; ++I) {
- if (strcmp (M->FormalArgs[I], Arg) == 0) {
- /* Found */
- Error ("Duplicate macro parameter: `%s'", Arg);
- break;
- }
- }
-
- /* Check if we have enough room available, otherwise expand the array
- * that holds the formal argument list.
- */
- if (M->ArgCount >= (int) M->MaxArgs) {
- /* We must expand the array */
- char** OldArgs = M->FormalArgs;
- M->MaxArgs += 10;
- M->FormalArgs = (char**) xmalloc (M->MaxArgs * sizeof(char*));
- memcpy (M->FormalArgs, OldArgs, M->ArgCount * sizeof (char*));
- xfree (OldArgs);
+ ** Beware: Don't use FindMacroArg here, since the actual argument array
+ ** may not be initialized.
+ */
+ unsigned I;
+ for (I = 0; I < CollCount (&M->FormalArgs); ++I) {
+ if (strcmp (CollAtUnchecked (&M->FormalArgs, I), Arg) == 0) {
+ /* Found */
+ Error ("Duplicate macro parameter: '%s'", Arg);
+ break;
+ }
}
/* Add the new argument */
- M->FormalArgs[M->ArgCount++] = xstrdup (Arg);
+ CollAppend (&M->FormalArgs, xstrdup (Arg));
+ ++M->ArgCount;
}
/* Argument count must be identical */
if (M1->ArgCount != M2->ArgCount) {
- return 1;
+ return 1;
}
/* Compare the arguments */
for (I = 0; I < M1->ArgCount; ++I) {
- if (strcmp (M1->FormalArgs[I], M2->FormalArgs[I]) != 0) {
- return 1;
- }
+ if (strcmp (CollConstAt (&M1->FormalArgs, I),
+ CollConstAt (&M2->FormalArgs, I)) != 0) {
+ return 1;
+ }
}
/* Compare the replacement */
- return strcmp (M1->Replacement, M2->Replacement);
+ return SB_Compare (&M1->Replacement, &M2->Replacement);
}
fprintf (F, "\n\nMacro Hash Table Summary\n");
for (I = 0; I < MACRO_TAB_SIZE; ++I) {
- fprintf (F, "%3u : ", I);
- M = MacroTab [I];
- if (M) {
- while (M) {
- fprintf (F, "%s ", M->Name);
- M = M->Next;
- }
- fprintf (F, "\n");
- } else {
- fprintf (F, "empty\n");
- }
+ fprintf (F, "%3u : ", I);
+ M = MacroTab [I];
+ if (M) {
+ while (M) {
+ fprintf (F, "%s ", M->Name);
+ M = M->Next;
+ }
+ fprintf (F, "\n");
+ } else {
+ fprintf (F, "empty\n");
+ }
}
}
-
-
-