1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2005
3 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "m4private.h"
23 #define DEBUG_SYM /* Define this to see runtime debug info. */
26 /* This file handles all the low level work around the symbol table. The
27 symbol table is an abstract hash table type implemented in hash.c. Each
28 symbol is represented by `struct m4_symbol', which is stored in the hash
29 table keyed by the symbol name. As a special case, to facilitate the
30 "pushdef" and "popdef" builtins, the value stored against each key is a
31 stack of `m4_symbol_value'. All the value entries for a symbol name are
32 simply ordered on the stack by age. The most recently pushed definition
33 will then always be the first found.
35 Also worthy of mention is the way traced symbols are managed: the trace
36 bit is associated with a particular symbol name. If a symbol is
37 undefined and then redefined, it does not lose its trace bit (in GNU
38 mode). This is achieved by not removing traced symbol names from the
39 symbol table, even if their value stack is empty. That way, when the
40 name is given a new value, it is pushed onto the empty stack, and the
41 trace bit attached to the name was never lost. There is a small amount
42 of fluff in these functions to make sure that such symbols (with empty
43 value stacks) are invisible to the users of this module. */
45 #define M4_SYMTAB_DEFAULT_SIZE 2047
47 struct m4_symbol_table
{
49 bool *nuke_trace_bit
; /* default: &(context->no_gnu_ext_opt) */
52 static m4_symbol
*symtab_fetch (m4_symbol_table
*, const char *);
53 static void symbol_popval (m4_symbol
*symbol
);
54 static void * symbol_destroy_CB (m4_symbol_table
*symtab
, const char *name
,
55 m4_symbol
*symbol
, void *ignored
);
56 static void * arg_destroy_CB (m4_hash
*hash
, const void *name
,
57 void *arg
, void *ignored
);
58 static void * arg_copy_CB (m4_hash
*src
, const void *name
,
59 void *arg
, m4_hash
*dest
);
63 /* -- SYMBOL TABLE MANAGEMENT --
65 These functions are used to manage a symbol table as a whole. */
68 m4_symtab_create (size_t size
, bool *nuke_trace_bit
)
70 m4_symbol_table
*symtab
= xmalloc (sizeof *symtab
);
72 symtab
->table
= m4_hash_new (size
? size
: M4_SYMTAB_DEFAULT_SIZE
,
73 m4_hash_string_hash
, m4_hash_string_cmp
);
74 symtab
->nuke_trace_bit
= nuke_trace_bit
;
79 m4_symtab_delete (m4_symbol_table
*symtab
)
82 assert (symtab
->table
);
84 m4_symtab_apply (symtab
, symbol_destroy_CB
, NULL
);
85 m4_hash_delete (symtab
->table
);
90 m4_symtab_apply (m4_symbol_table
*symtab
,
91 m4_symtab_apply_func
*func
, void *userdata
)
93 m4_hash_iterator
*place
= NULL
;
97 assert (symtab
->table
);
100 while ((place
= m4_get_hash_iterator_next (symtab
->table
, place
)))
102 result
= (*func
) (symtab
,
103 (const char *) m4_get_hash_iterator_key (place
),
104 (m4_symbol
*) m4_get_hash_iterator_value (place
),
115 symtab_fetch (m4_symbol_table
*symtab
, const char *name
)
123 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, name
);
130 symbol
= xzalloc (sizeof *symbol
);
131 m4_hash_insert (symtab
->table
, xstrdup (name
), symbol
);
137 /* Remove every symbol that references the given module handle from
140 m4__symtab_remove_module_references (m4_symbol_table
*symtab
, lt_dlhandle handle
)
142 m4_hash_iterator
*place
= 0;
146 /* Traverse each symbol name in the hash table. */
147 while ((place
= m4_get_hash_iterator_next (symtab
->table
, place
)))
149 m4_symbol
*symbol
= (m4_symbol
*) m4_get_hash_iterator_value (place
);
150 m4_symbol_value
*data
= m4_get_symbol_value (symbol
);
152 /* For symbols that have token data... */
155 /* Purge any shadowed references. */
156 while (VALUE_NEXT (data
))
158 m4_symbol_value
*next
= VALUE_NEXT (data
);
160 if (VALUE_HANDLE (next
) == handle
)
162 VALUE_NEXT (data
) = VALUE_NEXT (next
);
164 if (next
->type
== M4_SYMBOL_TEXT
)
165 free (m4_get_symbol_value_text (next
));
172 /* Purge the live reference if necessary. */
173 if (SYMBOL_HANDLE (symbol
) == handle
)
174 m4_symbol_popdef (symtab
, m4_get_hash_iterator_key (place
));
180 /* This callback is used exclusively by m4_symtab_delete(), to cleanup
181 the memory used by the symbol table. As such, the trace bit is reset
182 on every symbol so that m4_symbol_popdef() doesn't try to preserve
185 symbol_destroy_CB (m4_symbol_table
*symtab
, const char *name
, m4_symbol
*symbol
,
188 char *key
= xstrdup ((char *) name
);
190 m4_set_symbol_traced (symbol
, false);
192 while (key
&& m4_hash_lookup (symtab
->table
, key
))
193 m4_symbol_popdef (symtab
, key
);
202 /* -- SYMBOL MANAGEMENT --
204 The following functions manipulate individual symbols within
205 an existing table. */
207 /* Return the symbol associated to NAME, or else NULL. */
209 m4_symbol_lookup (m4_symbol_table
*symtab
, const char *name
)
211 m4_symbol
**psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, name
);
213 /* If just searching, return status of search -- if only an empty
214 struct is returned, that is treated as a failed lookup. */
215 return (psymbol
&& m4_get_symbol_value (*psymbol
)) ? *psymbol
: 0;
219 /* Insert NAME into the symbol table. If there is already a symbol
220 associated with NAME, push the new VALUE on top of the value stack
221 for this symbol. Otherwise create a new association. */
223 m4_symbol_pushdef (m4_symbol_table
*symtab
, const char *name
, m4_symbol_value
*value
)
231 symbol
= symtab_fetch (symtab
, name
);
232 VALUE_NEXT (value
) = m4_get_symbol_value (symbol
);
233 symbol
->value
= value
;
235 assert (m4_get_symbol_value (symbol
));
240 /* Return the symbol associated with NAME in the symbol table, creating
241 a new symbol if necessary. In either case set the symbol's VALUE. */
243 m4_symbol_define (m4_symbol_table
*symtab
,
244 const char *name
, m4_symbol_value
*value
)
252 symbol
= symtab_fetch (symtab
, name
);
253 if (m4_get_symbol_value (symbol
))
254 symbol_popval (symbol
);
256 VALUE_NEXT (value
) = m4_get_symbol_value (symbol
);
257 symbol
->value
= value
;
259 assert (m4_get_symbol_value (symbol
));
264 /* Pop the topmost value stack entry from the symbol associated with
265 NAME, deleting it from the table entirely if that was the last
266 remaining value in the stack. */
268 m4_symbol_popdef (m4_symbol_table
*symtab
, const char *name
)
270 m4_symbol
**psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, name
);
274 assert (symtab
->nuke_trace_bit
);
276 symbol_popval (*psymbol
);
278 /* Only remove the hash table entry if the last value in the
279 symbol value stack was successfully removed. */
280 if (!m4_get_symbol_value (*psymbol
))
281 if (*symtab
->nuke_trace_bit
|| !m4_get_symbol_traced (*psymbol
))
284 free (m4_hash_remove (symtab
->table
, name
));
289 symbol_popval (m4_symbol
*symbol
)
291 m4_symbol_value
*stale
;
295 stale
= m4_get_symbol_value (symbol
);
299 symbol
->value
= VALUE_NEXT (stale
);
301 if (VALUE_ARG_SIGNATURE (stale
))
303 m4_hash_apply (VALUE_ARG_SIGNATURE (stale
), arg_destroy_CB
, NULL
);
304 m4_hash_delete (VALUE_ARG_SIGNATURE (stale
));
306 if (m4_is_symbol_value_text (stale
))
307 free (m4_get_symbol_value_text (stale
));
313 m4_symbol_rename (m4_symbol_table
*symtab
, const char *name
, const char *rename
)
315 m4_symbol
*symbol
= NULL
;
322 /* Use a low level hash fetch, so we can save the symbol value when
323 removing the symbol name from the symbol table. */
324 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, name
);
330 /* Remove the old name from the symbol table. */
331 free (m4_hash_remove (symtab
->table
, name
));
332 assert (!m4_hash_lookup (symtab
->table
, name
));
334 m4_hash_insert (symtab
->table
, xstrdup (rename
), *psymbol
);
337 NAME does not name a symbol in symtab->table! */
343 /* Callback used by m4_symbol_popdef () to release the memory used
344 by values in the arg_signature hash. */
346 arg_destroy_CB (m4_hash
*hash
, const void *name
, void *arg
, void *ignored
)
348 struct m4_symbol_arg
*token_arg
= (struct m4_symbol_arg
*) arg
;
353 if (SYMBOL_ARG_DEFAULT (token_arg
))
354 DELETE (SYMBOL_ARG_DEFAULT (token_arg
));
356 free (m4_hash_remove (hash
, (const char *) name
));
362 m4_symbol_value_copy (m4_symbol_value
*dest
, m4_symbol_value
*src
)
364 m4_symbol_value
*next
;
369 if (m4_is_symbol_value_text (dest
))
370 free (m4_get_symbol_value_text (dest
));
372 if (VALUE_ARG_SIGNATURE (dest
))
374 m4_hash_apply (VALUE_ARG_SIGNATURE (dest
), arg_destroy_CB
, NULL
);
375 m4_hash_delete (VALUE_ARG_SIGNATURE (dest
));
378 /* Copy the valuecontents over, being careful to preserve
380 next
= VALUE_NEXT (dest
);
381 bcopy (src
, dest
, sizeof (m4_symbol_value
));
382 VALUE_NEXT (dest
) = next
;
384 /* Caller is supposed to free text token strings, so we have to
385 copy the string not just its address in that case. */
386 if (m4_is_symbol_value_text (src
))
387 m4_set_symbol_value_text (dest
, xstrdup (m4_get_symbol_value_text (src
)));
389 if (VALUE_ARG_SIGNATURE (src
))
390 VALUE_ARG_SIGNATURE (dest
) = m4_hash_dup (VALUE_ARG_SIGNATURE (src
),
395 arg_copy_CB (m4_hash
*src
, const void *name
, void *arg
, m4_hash
*dest
)
397 m4_hash_insert ((m4_hash
*) dest
, name
, arg
);
402 m4_set_symbol_name_traced (m4_symbol_table
*symtab
, const char *name
)
409 symbol
= symtab_fetch (symtab
, name
);
411 return m4_set_symbol_traced (symbol
, true);
415 /* Define these functions at the end, so that calls in the file use the
416 faster macro version from m4module.h. */
418 /* Pop all values from the symbol associated with NAME. */
419 #undef m4_symbol_delete
421 m4_symbol_delete (m4_symbol_table
*symtab
, const char *name
)
423 while (m4_symbol_lookup (symtab
, name
))
424 m4_symbol_popdef (symtab
, name
);
427 #undef m4_get_symbol_traced
429 m4_get_symbol_traced (m4_symbol
*symbol
)
432 return symbol
->traced
;
435 #undef m4_set_symbol_traced
437 m4_set_symbol_traced (m4_symbol
*symbol
, bool value
)
440 return symbol
->traced
= value
;
443 #undef m4_symbol_value_create
445 m4_symbol_value_create (void)
447 return xzalloc (sizeof (m4_symbol_value
));
450 #undef m4_get_symbol_value
452 m4_get_symbol_value (m4_symbol
*symbol
)
455 return symbol
->value
;
458 #undef m4_is_symbol_value_text
460 m4_is_symbol_value_text (m4_symbol_value
*value
)
463 return (value
->type
== M4_SYMBOL_TEXT
);
466 #undef m4_is_symbol_value_func
468 m4_is_symbol_value_func (m4_symbol_value
*value
)
471 return (value
->type
== M4_SYMBOL_FUNC
);
474 #undef m4_is_symbol_value_void
476 m4_is_symbol_value_void (m4_symbol_value
*value
)
479 return (value
->type
== M4_SYMBOL_VOID
);
482 #undef m4_get_symbol_value_text
484 m4_get_symbol_value_text (m4_symbol_value
*value
)
487 return value
->u
.text
;
490 #undef m4_get_symbol_value_func
492 m4_get_symbol_value_func (m4_symbol_value
*value
)
495 return value
->u
.func
;
498 #undef m4_set_symbol_value_text
500 m4_set_symbol_value_text (m4_symbol_value
*value
, char *text
)
505 value
->type
= M4_SYMBOL_TEXT
;
506 value
->u
.text
= text
;
509 #undef m4_set_symbol_value_func
511 m4_set_symbol_value_func (m4_symbol_value
*value
, m4_builtin_func
*func
)
516 value
->type
= M4_SYMBOL_FUNC
;
517 value
->u
.func
= func
;
524 static void *symtab_dump (m4_symbol_table
*symtab
);
525 static void dump_symbol_CB (m4_symbol_table
*symtab
, const char *name
,
526 m4_symbol
*symbol
, void *userdata
);
528 symtab_dump (m4_symbol_table
*symtab
)
530 return symtab_apply (symtab
, dump_symbol_CB
, NULL
);
533 static void *dump_symbol_CB (m4_symbol_table
*symtab
, const char *name
,
534 m4_symbol
*symbol
, void *ignored
)
536 m4_symbol_value
*value
= m4_get_symbol_value (symbol
);
537 int flags
= value
? SYMBOL_FLAGS (symbol
) : 0;
538 lt_dlhandle handle
= value
? SYMBOL_HANDLE (symbol
) : 0;
539 const char * module_name
= handle
? m4_get_module_name (handle
) : "NONE";
540 const m4_builtin
*bp
;
542 fprintf (stderr
, "%10s: (%d%s) %s=",
543 handle
? m4_get_module_name (handle
) : "NONE",
544 value
? VALUE_FLAGS (value
) : 0,
545 m4_get_symbol_traced (symbol
) ? "!" : "", name
);
548 fputs ("<!UNDEFINED!>", stderr
);
553 fputs (m4_get_symbol_text (symbol
), stderr
);
557 bp
= m4_builtin_find_by_func (handle
, m4_get_symbol_func (symbol
));
558 fprintf (stderr
, "<%s>",
559 bp
? bp
->name
: "!ERROR!");
562 fputs ("<!VOID!>", stderr
);
565 fputc ('\n', stderr
);
567 #endif /* DEBUG_SYM */