]> git.sur5r.net Git - cc65/blobdiff - src/cc65/macrotab.c
Changed most "backticks" (grave accents) into apostrophes.
[cc65] / src / cc65 / macrotab.c
index 632142c76d8a67542d1f8c46f95148666539c3ec..09f0db50a1d8cb9593dc4ad5dd7876f39b654dd0 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                               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 <stdio.h>
 #include <string.h>
 
-#include "../common/hashstr.h"
-#include "../common/xmalloc.h"
+/* common */
+#include "hashfunc.h"
+#include "xmalloc.h"
 
+/* cc65 */
 #include "error.h"
 #include "macrotab.h"
 
 
 
 /*****************************************************************************/
-/*                                  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);
 
     /* Allocate the structure */
-    Macro* M = xmalloc (sizeof(Macro) + Len);
+    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 */
@@ -96,24 +93,23 @@ Macro* NewMacro (const char* Name)
 
 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];
 
@@ -121,19 +117,19 @@ void AddNumericMacro (const char* Name, long Val)
     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);
@@ -142,35 +138,23 @@ void AddTextMacro (const char* Name, const char* Val)
 
 
 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 = 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;
@@ -179,29 +163,26 @@ int UndefineMacro (const char* Name)
     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 */
@@ -219,13 +200,13 @@ Macro* FindMacro (const char* Name)
     /* 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 */
@@ -234,72 +215,68 @@ Macro* FindMacro (const char* Name)
 
 
 
-int IsMacro (const char* Name)
-/* Return true if the given name is the name of a macro, return false otherwise */
+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 FindMacro(Name) != 0;
-}
-
-
+    unsigned I;
+    for (I = 0; I < CollCount (&M->FormalArgs); ++I) {
+        if (strcmp (CollAtUnchecked (&M->FormalArgs, I), Arg) == 0) {
+            /* Found */
+            return I;
+        }
+    }
 
-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.
- */
-{
-    return (MacroFlagTab[C] > 0);
+    /* Not found */
+    return -1;
 }
 
 
 
-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.
- */
+void AddMacroArg (Macro* M, const char* Arg)
+/* Add a formal macro argument. */
 {
-    int I;
-    for (I = 0; I < M->ArgCount; ++I) {
-       if (strcmp (M->FormalArgs[I], Arg) == 0) {
-           /* Found */
-           return M->ActualArgs[I];
-       }
+    /* 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.
+    */
+    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;
+        }
     }
-    /* Not found */
-    return 0;
+
+    /* Add the new argument */
+    CollAppend (&M->FormalArgs, xstrdup (Arg));
+    ++M->ArgCount;
 }
 
 
 
-void AddMacroArg (Macro* M, const char* Arg)
-/* Add a formal macro argument. */
+int MacroCmp (const Macro* M1, const Macro* M2)
+/* Compare two macros and return zero if both are identical. */
 {
-    /* 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 (ERR_DUPLICATE_MACRO_ARG, Arg);
-           break;
-       }
+
+    /* Argument count must be identical */
+    if (M1->ArgCount != M2->ArgCount) {
+        return 1;
     }
 
-    /* Check if we have enough room available, otherwise expand the array
-     * that holds the formal argument list.
-     */
-    if (M->ArgCount >= M->MaxArgs) {
-       /* We must expand the array */
-       char** OldArgs = M->FormalArgs;
-       M->MaxArgs += 10;
-       M->FormalArgs = xmalloc (M->MaxArgs * sizeof(char*));
-       memcpy (M->FormalArgs, OldArgs, M->ArgCount * sizeof (char*));
-       xfree (OldArgs);
+    /* Compare the arguments */
+    for (I = 0; I < M1->ArgCount; ++I) {
+        if (strcmp (CollConstAt (&M1->FormalArgs, I),
+                    CollConstAt (&M2->FormalArgs, I)) != 0) {
+            return 1;
+        }
     }
 
-    /* Add the new argument */
-    M->FormalArgs[M->ArgCount++] = xstrdup (Arg);
+    /* Compare the replacement */
+    return SB_Compare (&M1->Replacement, &M2->Replacement);
 }
 
 
@@ -312,19 +289,16 @@ void PrintMacroStats (FILE* F)
 
     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");
+        }
     }
 }
-
-
-