-static unsigned GenHash (const void* Index);
-/* Generate the hash over an index. */
+static unsigned HT_GenHash (const void* Key);
+/* Generate the hash over a key. */
-static const void* GetIndex (void* Entry);
-/* Given a pointer to the user entry data, return a pointer to the index */
+static const void* HT_GetKey (void* Entry);
+/* Given a pointer to the user entry data, return a pointer to the key. */
-static HashNode* GetHashNode (void* Entry);
+static HashNode* HT_GetHashNode (void* Entry);
/* Given a pointer to the user entry data, return a pointer to the hash node */
-static int Compare (const void* Index1, const void* Index2);
-/* Compare two indices for equality */
+static int HT_Compare (const void* Key1, const void* Key2);
+/* Compare two keys for equality */
struct FileEntry {
HashNode Node;
unsigned Name; /* File name */
- unsigned Index; /* Index of entry */
+ unsigned Index; /* Index of entry */
unsigned long Size; /* Size of file */
unsigned long MTime; /* Time of last modification */
};
/* Hash table functions */
static const HashFunctions HashFunc = {
- GenHash,
- GetIndex,
- GetHashNode,
- Compare
+ HT_GenHash,
+ HT_GetKey,
+ HT_GetHashNode,
+ HT_Compare
};
/* Hash table, hashed by name */
-static unsigned GenHash (const void* Index)
-/* Generate the hash over an index. */
+static unsigned HT_GenHash (const void* Key)
+/* Generate the hash over a key. */
{
- return (*(const unsigned*)Index & HASHTAB_MASK);
+ return (*(const unsigned*)Key & HASHTAB_MASK);
}
-static const void* GetIndex (void* Entry)
+static const void* HT_GetKey (void* Entry)
/* Given a pointer to the user entry data, return a pointer to the index */
{
return &((FileEntry*) Entry)->Name;
-static HashNode* GetHashNode (void* Entry)
+static HashNode* HT_GetHashNode (void* Entry)
/* Given a pointer to the user entry data, return a pointer to the hash node */
{
return &((FileEntry*) Entry)->Node;
-static int Compare (const void* Index1, const void* Index2)
-/* Compare two indices for equality */
+static int HT_Compare (const void* Key1, const void* Key2)
+/* Compare two keys for equality */
{
- return (*(const unsigned*)Index1 == *(const unsigned*)Index2);
+ return (*(const unsigned*)Key1 == *(const unsigned*)Key2);
}
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* common */
#include "check.h"
#include "hashstr.h"
+#include "hashtab.h"
#include "xmalloc.h"
/* ca65 */
+/*****************************************************************************/
+/* Forwards */
+/*****************************************************************************/
+
+
+
+static unsigned HT_GenHash (const void* Key);
+/* Generate the hash over a key. */
+
+static const void* HT_GetKey (void* Entry);
+/* Given a pointer to the user entry data, return a pointer to the key */
+
+static HashNode* HT_GetHashNode (void* Entry);
+/* Given a pointer to the user entry data, return a pointer to the hash node */
+
+static int HT_Compare (const void* Key1, const void* Key2);
+/* Compare two keys for equality */
+
+
+
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Struct that describes an identifer (macro param, local list) */
-typedef struct IdDesc_ IdDesc;
-struct IdDesc_ {
- IdDesc* Next; /* Linked list */
+typedef struct IdDesc IdDesc;
+struct IdDesc {
+ IdDesc* Next; /* Linked list */
char Id [1]; /* Identifier, dynamically allocated */
};
/* Struct that describes a macro definition */
-typedef struct Macro_ Macro;
-struct Macro_ {
- Macro* Next; /* Next macro with same hash */
+typedef struct Macro Macro;
+struct Macro {
+ HashNode Node; /* Hash list node */
Macro* List; /* List of all macros */
unsigned LocalCount; /* Count of local symbols */
IdDesc* Locals; /* List of local symbols */
char Name [1]; /* Macro name, dynamically allocated */
};
+/* Hash table functions */
+static const HashFunctions HashFunc = {
+ HT_GenHash,
+ HT_GetKey,
+ HT_GetHashNode,
+ HT_Compare
+};
+
/* Macro hash table */
-#define HASHTAB_SIZE 117
-static Macro* MacroTab [HASHTAB_SIZE];
+static HashTable MacroTab = STATIC_HASHTABLE_INITIALIZER (117, &HashFunc);
/* Global macro data */
static Macro* MacroRoot = 0; /* List of all macros */
/* Structs that holds data for a macro expansion */
-typedef struct MacExp_ MacExp;
-struct MacExp_ {
- MacExp* Next; /* Pointer to next expansion */
- Macro* M; /* Which macro do we expand? */
- unsigned IfSP; /* .IF stack pointer at start of expansion */
+typedef struct MacExp MacExp;
+struct MacExp {
+ MacExp* Next; /* Pointer to next expansion */
+ Macro* M; /* Which macro do we expand? */
+ unsigned IfSP; /* .IF stack pointer at start of expansion */
TokNode* Exp; /* Pointer to current token */
- TokNode* Final; /* Pointer to final token */
+ TokNode* Final; /* Pointer to final token */
unsigned LocalStart; /* Start of counter for local symbol names */
- unsigned ParamCount; /* Number of actual parameters */
+ unsigned ParamCount; /* Number of actual parameters */
TokNode** Params; /* List of actual parameters */
- TokNode* ParamExp; /* Node for expanding parameters */
+ TokNode* ParamExp; /* Node for expanding parameters */
};
/* Number of active macro expansions */
+/*****************************************************************************/
+/* Hash table functions */
+/*****************************************************************************/
+
+
+
+static unsigned HT_GenHash (const void* Key)
+/* Generate the hash over a key. */
+{
+ return HashStr (Key);
+}
+
+
+
+static const void* HT_GetKey (void* Entry)
+/* Given a pointer to the user entry data, return a pointer to the index */
+{
+ return ((Macro*) Entry)->Name;
+}
+
+
+
+static HashNode* HT_GetHashNode (void* Entry)
+/* Given a pointer to the user entry data, return a pointer to the hash node */
+{
+ return &((Macro*) Entry)->Node;
+}
+
+
+
+static int HT_Compare (const void* Key1, const void* Key2)
+/* Compare two keys for equality */
+{
+ return (strcmp (Key1, Key2) == 0);
+}
+
+
+
/*****************************************************************************/
/* Code */
/*****************************************************************************/
-static Macro* NewMacro (const char* Name, unsigned HashVal, unsigned char Style)
+static Macro* NewMacro (const char* Name, unsigned char Style)
/* Generate a new macro entry, initialize and return it */
{
/* Allocate memory */
Macro* M = xmalloc (sizeof (Macro) + Len);
/* Initialize the macro struct */
+ InitHashNode (&M->Node, M);
M->LocalCount = 0;
M->Locals = 0;
M->ParamCount = 0;
M->TokRoot = 0;
M->TokLast = 0;
M->Style = Style;
- memcpy (M->Name, Name, Len);
- M->Name [Len] = '\0';
+ memcpy (M->Name, Name, Len+1);
/* Insert the macro into the global macro list */
M->List = MacroRoot;
MacroRoot = M;
/* Insert the macro into the hash table */
- M->Next = MacroTab [HashVal];
- MacroTab [HashVal] = M;
+ HT_Insert (&MacroTab, &M->Node);
/* Return the new macro struct */
return M;
-static Macro* MacFind (const char* Name, unsigned HashVal)
-/* Search for a macro in the hash table */
-{
- /* Search for the identifier */
- Macro* M = MacroTab [HashVal];
- while (M) {
- if (strcmp (Name, M->Name) == 0) {
- return M;
- }
- M = M->Next;
- }
- return 0;
-}
-
-
-
void MacDef (unsigned Style)
/* Parse a macro definition */
{
Macro* M;
TokNode* T;
- unsigned HashVal;
int HaveParams;
/* We expect a macro name here */
return;
}
- /* Generate the hash value */
- HashVal = HashStr (SVal) % HASHTAB_SIZE;
-
/* Did we already define that macro? */
- if (MacFind (SVal, HashVal) != 0) {
+ if (HT_Find (&MacroTab, SVal) != 0) {
/* Macro is already defined */
Error (ERR_SYM_ALREADY_DEFINED, SVal);
/* Skip tokens until we reach the final .endmacro */
}
/* Define the macro */
- M = NewMacro (SVal, HashVal, Style);
+ M = NewMacro (SVal, Style);
/* Switch to raw token mode and skip the macro name */
EnterRawTokenMode ();
/* Start expanding the macro in SVal */
{
/* Search for the macro */
- Macro* M = MacFind (SVal, HashStr (SVal) % HASHTAB_SIZE);
+ Macro* M = HT_FindEntry (&MacroTab, SVal);
CHECK (M != 0);
/* Call the apropriate subroutine */
int IsMacro (const char* Name)
/* Return true if the given name is the name of a macro */
{
- return MacFind (Name, HashStr (Name) % HASHTAB_SIZE) != 0;
+ return (HT_Find (&MacroTab, Name) != 0);
}
int IsDefine (const char* Name)
/* Return true if the given name is the name of a define style macro */
{
- Macro* M = MacFind (Name, HashStr (Name) % HASHTAB_SIZE);
+ Macro* M = HT_FindEntry (&MacroTab, Name);
return (M != 0 && M->Style == MAC_STYLE_DEFINE);
}