1 /*****************************************************************************/
5 /* Preprocessor macro table for the cc65 C compiler */
9 /* (C) 2000-2011, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
49 /*****************************************************************************/
51 /*****************************************************************************/
55 /* The macro hash table */
56 #define MACRO_TAB_SIZE 211
57 static Macro* MacroTab[MACRO_TAB_SIZE];
61 /*****************************************************************************/
63 /*****************************************************************************/
67 Macro* NewMacro (const char* Name)
68 /* Allocate a macro structure with the given name. The structure is not
69 ** inserted into the macro table.
72 /* Get the length of the macro name */
73 unsigned Len = strlen(Name);
75 /* Allocate the structure */
76 Macro* M = (Macro*) xmalloc (sizeof(Macro) + Len);
78 /* Initialize the data */
81 M->ArgCount = -1; /* Flag: Not a function like macro */
83 InitCollection (&M->FormalArgs);
84 SB_Init (&M->Replacement);
86 memcpy (M->Name, Name, Len+1);
88 /* Return the new macro */
94 void FreeMacro (Macro* M)
95 /* Delete a macro definition. The function will NOT remove the macro from the
96 ** table, use UndefineMacro for that.
101 for (I = 0; I < CollCount (&M->FormalArgs); ++I) {
102 xfree (CollAtUnchecked (&M->FormalArgs, I));
104 DoneCollection (&M->FormalArgs);
105 SB_Done (&M->Replacement);
111 void DefineNumericMacro (const char* Name, long Val)
112 /* Define a macro for a numeric constant */
116 /* Make a string from the number */
117 sprintf (Buf, "%ld", Val);
119 /* Handle as text macro */
120 DefineTextMacro (Name, Buf);
125 void DefineTextMacro (const char* Name, const char* Val)
126 /* Define a macro for a textual constant */
128 /* Create a new macro */
129 Macro* M = NewMacro (Name);
131 /* Set the value as replacement text */
132 SB_CopyStr (&M->Replacement, Val);
134 /* Insert the macro into the macro table */
140 void InsertMacro (Macro* M)
141 /* Insert the given macro into the macro table. */
143 /* Get the hash value of the macro name */
144 unsigned Hash = HashStr (M->Name) % MACRO_TAB_SIZE;
146 /* Insert the macro */
147 M->Next = MacroTab[Hash];
153 int UndefineMacro (const char* Name)
154 /* Search for the macro with the given name and remove it from the macro
155 ** table if it exists. Return 1 if a macro was found and deleted, return
159 /* Get the hash value of the macro name */
160 unsigned Hash = HashStr (Name) % MACRO_TAB_SIZE;
162 /* Search the hash chain */
164 Macro* M = MacroTab[Hash];
166 if (strcmp (M->Name, Name) == 0) {
171 MacroTab[Hash] = M->Next;
176 /* Delete the macro */
194 Macro* FindMacro (const char* Name)
195 /* Find a macro with the given name. Return the macro definition or NULL */
197 /* Get the hash value of the macro name */
198 unsigned Hash = HashStr (Name) % MACRO_TAB_SIZE;
200 /* Search the hash chain */
201 Macro* M = MacroTab[Hash];
203 if (strcmp (M->Name, Name) == 0) {
218 int FindMacroArg (Macro* M, const char* Arg)
219 /* Search for a formal macro argument. If found, return the index of the
220 ** argument. If the argument was not found, return -1.
224 for (I = 0; I < CollCount (&M->FormalArgs); ++I) {
225 if (strcmp (CollAtUnchecked (&M->FormalArgs, I), Arg) == 0) {
237 void AddMacroArg (Macro* M, const char* Arg)
238 /* Add a formal macro argument. */
240 /* Check if we have a duplicate macro argument, but add it anyway.
241 ** Beware: Don't use FindMacroArg here, since the actual argument array
242 ** may not be initialized.
245 for (I = 0; I < CollCount (&M->FormalArgs); ++I) {
246 if (strcmp (CollAtUnchecked (&M->FormalArgs, I), Arg) == 0) {
248 Error ("Duplicate macro parameter: '%s'", Arg);
253 /* Add the new argument */
254 CollAppend (&M->FormalArgs, xstrdup (Arg));
260 int MacroCmp (const Macro* M1, const Macro* M2)
261 /* Compare two macros and return zero if both are identical. */
265 /* Argument count must be identical */
266 if (M1->ArgCount != M2->ArgCount) {
270 /* Compare the arguments */
271 for (I = 0; I < M1->ArgCount; ++I) {
272 if (strcmp (CollConstAt (&M1->FormalArgs, I),
273 CollConstAt (&M2->FormalArgs, I)) != 0) {
278 /* Compare the replacement */
279 return SB_Compare (&M1->Replacement, &M2->Replacement);
284 void PrintMacroStats (FILE* F)
285 /* Print macro statistics to the given text file. */
290 fprintf (F, "\n\nMacro Hash Table Summary\n");
291 for (I = 0; I < MACRO_TAB_SIZE; ++I) {
292 fprintf (F, "%3u : ", I);
296 fprintf (F, "%s ", M->Name);
301 fprintf (F, "empty\n");