1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2005, 2006,
3 2007, 2008, 2010 Free Software Foundation, Inc.
5 This file is part of GNU M4.
7 GNU M4 is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU M4 is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "m4private.h"
25 /* Define this to see runtime debug info. Implied by DEBUG. */
26 /*#define DEBUG_SYM */
28 /* This file handles all the low level work around the symbol table. The
29 symbol table is an abstract hash table type implemented in hash.c. Each
30 symbol is represented by `struct m4_symbol', which is stored in the hash
31 table keyed by the symbol name. As a special case, to facilitate the
32 "pushdef" and "popdef" builtins, the value stored against each key is a
33 stack of `m4_symbol_value'. All the value entries for a symbol name are
34 simply ordered on the stack by age. The most recently pushed definition
35 will then always be the first found.
37 Also worthy of mention is the way traced symbols are managed: the
38 trace bit is associated with a particular symbol name. If a symbol
39 is undefined and then redefined, it does not lose its trace bit.
40 This is achieved by not removing traced symbol names from the
41 symbol table, even if their value stack is empty. That way, when
42 the name is given a new value, it is pushed onto the empty stack,
43 and the trace bit attached to the name was never lost. There is a
44 small amount of fluff in these functions to make sure that such
45 symbols (with empty value stacks) are invisible to the users of
48 #define M4_SYMTAB_DEFAULT_SIZE 2047
50 struct m4_symbol_table
{
54 static m4_symbol
*symtab_fetch (m4_symbol_table
*, const char *,
56 static void symbol_popval (m4_symbol
*);
57 static void * symbol_destroy_CB (m4_symbol_table
*, const char *,
58 size_t, m4_symbol
*, void *);
59 static void * arg_destroy_CB (m4_hash
*, const void *, void *,
61 static void * arg_copy_CB (m4_hash
*, const void *, void *,
65 /* -- SYMBOL TABLE MANAGEMENT --
67 These functions are used to manage a symbol table as a whole. */
70 m4_symtab_create (size_t size
)
72 m4_symbol_table
*symtab
= (m4_symbol_table
*) xmalloc (sizeof *symtab
);
74 symtab
->table
= m4_hash_new (size
? size
: M4_SYMTAB_DEFAULT_SIZE
,
75 m4_hash_string_hash
, m4_hash_string_cmp
);
80 m4_symtab_delete (m4_symbol_table
*symtab
)
83 assert (symtab
->table
);
85 m4_symtab_apply (symtab
, true, symbol_destroy_CB
, NULL
);
86 m4_hash_delete (symtab
->table
);
90 /* For every symbol in SYMTAB, execute the callback FUNC with the name
91 and value of the symbol being visited, and the opaque parameter
92 USERDATA. Skip undefined symbols that are placeholders for
93 traceon, unless INCLUDE_TRACE is true. If FUNC returns non-NULL,
94 abort the iteration and return the same result; otherwise return
95 NULL when iteration completes. */
97 m4_symtab_apply (m4_symbol_table
*symtab
, bool include_trace
,
98 m4_symtab_apply_func
*func
, void *userdata
)
100 m4_hash_iterator
*place
= NULL
;
101 void * result
= NULL
;
104 assert (symtab
->table
);
107 while ((place
= m4_get_hash_iterator_next (symtab
->table
, place
)))
109 m4_symbol
*symbol
= m4_get_hash_iterator_value (place
);
110 if (symbol
->value
|| include_trace
)
113 = (const m4_string
*) m4_get_hash_iterator_key (place
);
114 result
= func (symtab
, key
->str
, key
->len
, symbol
, userdata
);
118 m4_free_hash_iterator (symtab
->table
, place
);
126 /* Ensure that NAME of length LEN exists in the table, creating an
129 symtab_fetch (m4_symbol_table
*symtab
, const char *name
, size_t len
)
138 /* Safe to cast away const, since m4_hash_lookup doesn't modify
140 key
.str
= (char *) name
;
142 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, &key
);
149 /* Use xmemdup0 rather than memdup so that debugging the symbol
151 m4_string
*new_key
= (m4_string
*) xmalloc (sizeof *new_key
);
152 new_key
->str
= xmemdup0 (name
, len
);
154 symbol
= (m4_symbol
*) xzalloc (sizeof *symbol
);
155 m4_hash_insert (symtab
->table
, new_key
, symbol
);
161 /* Remove every symbol that references the given module from
164 m4__symtab_remove_module_references (m4_symbol_table
*symtab
,
167 m4_hash_iterator
*place
= 0;
171 /* Traverse each symbol name in the hash table. */
172 while ((place
= m4_get_hash_iterator_next (symtab
->table
, place
)))
174 m4_symbol
*symbol
= (m4_symbol
*) m4_get_hash_iterator_value (place
);
175 m4_symbol_value
*data
= m4_get_symbol_value (symbol
);
177 /* For symbols that have token data... */
180 /* Purge any shadowed references. */
181 while (VALUE_NEXT (data
))
183 m4_symbol_value
*next
= VALUE_NEXT (data
);
185 if (VALUE_MODULE (next
) == module
)
187 VALUE_NEXT (data
) = VALUE_NEXT (next
);
189 assert (next
->type
!= M4_SYMBOL_PLACEHOLDER
);
190 m4_symbol_value_delete (next
);
196 /* Purge the live reference if necessary. */
197 if (SYMBOL_MODULE (symbol
) == module
)
200 = (const m4_string
*) m4_get_hash_iterator_key (place
);
201 m4_symbol_popdef (symtab
, key
->str
, key
->len
);
208 /* This callback is used exclusively by m4_symtab_delete(), to cleanup
209 the memory used by the symbol table. As such, the trace bit is reset
210 on every symbol so that m4_symbol_popdef() doesn't try to preserve
213 symbol_destroy_CB (m4_symbol_table
*symtab
, const char *name
, size_t len
,
214 m4_symbol
*symbol
, void *ignored M4_GNUC_UNUSED
)
217 key
.str
= xmemdup0 (name
, len
);
220 symbol
->traced
= false;
222 while (m4_hash_lookup (symtab
->table
, &key
))
223 m4_symbol_popdef (symtab
, key
.str
, key
.len
);
232 /* -- SYMBOL MANAGEMENT --
234 The following functions manipulate individual symbols within
235 an existing table. */
237 /* Return the symbol associated to NAME of length LEN, or else
240 m4_symbol_lookup (m4_symbol_table
*symtab
, const char *name
, size_t len
)
245 /* Safe to cast away const, since m4_hash_lookup doesn't modify
247 key
.str
= (char *) name
;
249 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, &key
);
251 /* If just searching, return status of search -- if only an empty
252 struct is returned, that is treated as a failed lookup. */
253 return (psymbol
&& m4_get_symbol_value (*psymbol
)) ? *psymbol
: NULL
;
257 /* Insert NAME of length LEN into the symbol table. If there is
258 already a symbol associated with NAME, push the new VALUE on top of
259 the value stack for this symbol. Otherwise create a new
262 m4_symbol_pushdef (m4_symbol_table
*symtab
, const char *name
, size_t len
,
263 m4_symbol_value
*value
)
271 symbol
= symtab_fetch (symtab
, name
, len
);
272 VALUE_NEXT (value
) = m4_get_symbol_value (symbol
);
273 symbol
->value
= value
;
275 assert (m4_get_symbol_value (symbol
));
280 /* Return the symbol associated with NAME of length LEN in the symbol
281 table, creating a new symbol if necessary. In either case set the
284 m4_symbol_define (m4_symbol_table
*symtab
, const char *name
, size_t len
,
285 m4_symbol_value
*value
)
293 symbol
= symtab_fetch (symtab
, name
, len
);
294 if (m4_get_symbol_value (symbol
))
295 symbol_popval (symbol
);
297 VALUE_NEXT (value
) = m4_get_symbol_value (symbol
);
298 symbol
->value
= value
;
300 assert (m4_get_symbol_value (symbol
));
305 /* Pop the topmost value stack entry from the symbol associated with
306 NAME of length LEN, deleting it from the table entirely if that was
307 the last remaining value in the stack. */
309 m4_symbol_popdef (m4_symbol_table
*symtab
, const char *name
, size_t len
)
314 /* Safe to cast away const, since m4_hash_lookup doesn't modify
316 key
.str
= (char *) name
;
318 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, &key
);
323 symbol_popval (*psymbol
);
325 /* Only remove the hash table entry if the last value in the
326 symbol value stack was successfully removed. */
327 if (!m4_get_symbol_value (*psymbol
) && !m4_get_symbol_traced (*psymbol
))
331 old_key
= (m4_string
*) m4_hash_remove (symtab
->table
, &key
);
337 /* Remove the top-most value from SYMBOL's stack. */
339 symbol_popval (m4_symbol
*symbol
)
341 m4_symbol_value
*stale
;
345 stale
= m4_get_symbol_value (symbol
);
349 symbol
->value
= VALUE_NEXT (stale
);
350 m4_symbol_value_delete (stale
);
354 /* Create a new symbol value, with fields populated for default
357 m4_symbol_value_create (void)
359 m4_symbol_value
*value
= (m4_symbol_value
*) xzalloc (sizeof *value
);
360 VALUE_MAX_ARGS (value
) = SIZE_MAX
;
364 /* Remove VALUE from the symbol table, and mark it as deleted. If no
365 expansions are pending, reclaim its resources. */
367 m4_symbol_value_delete (m4_symbol_value
*value
)
369 if (VALUE_PENDING (value
) > 0)
370 BIT_SET (VALUE_FLAGS (value
), VALUE_DELETED_BIT
);
373 if (VALUE_ARG_SIGNATURE (value
))
375 m4_hash_apply (VALUE_ARG_SIGNATURE (value
), arg_destroy_CB
, NULL
);
376 m4_hash_delete (VALUE_ARG_SIGNATURE (value
));
381 free ((char *) m4_get_symbol_value_text (value
));
383 case M4_SYMBOL_PLACEHOLDER
:
384 free ((char *) m4_get_symbol_value_placeholder (value
));
390 assert (!"m4_symbol_value_delete");
397 /* Rename the entire stack of values associated with NAME and LEN1 to
400 m4_symbol_rename (m4_symbol_table
*symtab
, const char *name
, size_t len1
,
401 const char *newname
, size_t len2
)
403 m4_symbol
*symbol
= NULL
;
412 /* Safe to cast away const, since m4_hash_lookup doesn't modify
414 key
.str
= (char *) name
;
416 /* Use a low level hash fetch, so we can save the symbol value when
417 removing the symbol name from the symbol table. */
418 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, &key
);
424 /* Remove the old name from the symbol table. */
425 pkey
= (m4_string
*) m4_hash_remove (symtab
->table
, &key
);
426 assert (pkey
&& !m4_hash_lookup (symtab
->table
, &key
));
429 pkey
->str
= xmemdup0 (newname
, len2
);
431 m4_hash_insert (symtab
->table
, pkey
, *psymbol
);
434 NAME does not name a symbol in symtab->table! */
440 /* Callback used by m4_symbol_popdef () to release the memory used
441 by values in the arg_signature hash. */
443 arg_destroy_CB (m4_hash
*hash
, const void *name
, void *arg
, void *ignored
)
445 struct m4_symbol_arg
*token_arg
= (struct m4_symbol_arg
*) arg
;
450 if (SYMBOL_ARG_DEFAULT (token_arg
))
451 DELETE (SYMBOL_ARG_DEFAULT (token_arg
));
453 free (m4_hash_remove (hash
, (const char *) name
));
458 /* Copy the symbol SRC into DEST. Return true if builtin tokens were
461 m4_symbol_value_copy (m4
*context
, m4_symbol_value
*dest
, m4_symbol_value
*src
)
463 m4_symbol_value
*next
;
472 free ((char *) m4_get_symbol_value_text (dest
));
474 case M4_SYMBOL_PLACEHOLDER
:
475 free ((char *) m4_get_symbol_value_placeholder (dest
));
481 assert (!"m4_symbol_value_delete");
485 if (VALUE_ARG_SIGNATURE (dest
))
487 m4_hash_apply (VALUE_ARG_SIGNATURE (dest
), arg_destroy_CB
, NULL
);
488 m4_hash_delete (VALUE_ARG_SIGNATURE (dest
));
491 /* Copy the value contents over, being careful to preserve
493 next
= VALUE_NEXT (dest
);
494 memcpy (dest
, src
, sizeof (m4_symbol_value
));
495 VALUE_NEXT (dest
) = next
;
497 /* Caller is supposed to free text token strings, so we have to
498 copy the string not just its address in that case. */
503 size_t len
= m4_get_symbol_value_len (src
);
504 unsigned int age
= m4_get_symbol_value_quote_age (src
);
505 m4_set_symbol_value_text (dest
,
506 xmemdup0 (m4_get_symbol_value_text (src
),
511 m4__set_symbol_value_builtin (dest
, src
->u
.builtin
);
513 case M4_SYMBOL_PLACEHOLDER
:
514 m4_set_symbol_value_placeholder (dest
,
515 xstrdup (m4_get_symbol_value_placeholder
520 m4__symbol_chain
*chain
= src
->u
.u_c
.chain
;
523 const m4_string_pair
*quotes
;
524 m4_obstack
*obs
= m4_arg_scratch (context
);
530 obstack_grow (obs
, chain
->u
.u_s
.str
, chain
->u
.u_s
.len
);
536 quotes
= m4__quote_cache (M4SYNTAX
, NULL
, chain
->quote_age
,
537 chain
->u
.u_a
.quotes
);
538 if (chain
->u
.u_a
.has_func
&& !chain
->u
.u_a
.flatten
)
540 m4__arg_print (context
, obs
, chain
->u
.u_a
.argv
,
541 chain
->u
.u_a
.index
, quotes
, true, NULL
, NULL
,
545 assert (!"m4_symbol_value_copy");
550 obstack_1grow (obs
, '\0');
551 len
= obstack_object_size (obs
);
552 str
= xcharalloc (len
);
553 memcpy (str
, obstack_finish (obs
), len
);
554 m4_set_symbol_value_text (dest
, str
, len
- 1, 0);
558 assert (!"m4_symbol_value_copy");
561 if (VALUE_ARG_SIGNATURE (src
))
562 VALUE_ARG_SIGNATURE (dest
) = m4_hash_dup (VALUE_ARG_SIGNATURE (src
),
568 arg_copy_CB (m4_hash
*src
, const void *name
, void *arg
, m4_hash
*dest
)
570 m4_hash_insert ((m4_hash
*) dest
, name
, arg
);
574 /* Set the tracing status of the symbol NAME of length LEN to TRACED.
575 This takes a name, rather than a symbol, since we hide macros that
576 are traced but otherwise undefined from normal lookups, but still
577 can affect their tracing status. Return true iff the macro was
578 previously traced. */
580 m4_set_symbol_name_traced (m4_symbol_table
*symtab
, const char *name
,
581 size_t len
, bool traced
)
590 symbol
= symtab_fetch (symtab
, name
, len
);
596 /* Safe to cast away const, since m4_hash_lookup doesn't modify
598 key
.str
= (char *) name
;
600 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, &key
);
606 result
= symbol
->traced
;
607 symbol
->traced
= traced
;
608 if (!traced
&& !m4_get_symbol_value (symbol
))
610 /* Free an undefined entry once it is no longer traced. */
616 /* Safe to cast away const, since m4_hash_lookup doesn't modify
618 key
.str
= (char *) name
;
620 old_key
= (m4_string
*) m4_hash_remove (symtab
->table
, &key
);
628 /* Grow OBS with a text representation of VALUE. If QUOTES, then use
629 it to surround a text definition. If FLATTEN, builtins are
630 converted to empty quotes; if CHAINP, *CHAINP is updated with macro
631 tokens; otherwise, builtins are represented by their name. If
632 MAXLEN, then truncate text definitions to *MAXLEN, and adjust by
633 how many characters are printed. If MODULE, then include which
634 module defined a builtin. Return true if the output was truncated.
635 QUOTES and MODULE do not count against the truncation length. */
637 m4__symbol_value_print (m4
*context
, m4_symbol_value
*value
, m4_obstack
*obs
,
638 const m4_string_pair
*quotes
, bool flatten
,
639 m4__symbol_chain
**chainp
, size_t *maxlen
, bool module
)
642 m4__symbol_chain
*chain
;
643 size_t len
= maxlen
? *maxlen
: SIZE_MAX
;
649 if (m4_shipout_string_trunc (obs
, m4_get_symbol_value_text (value
),
650 m4_get_symbol_value_len (value
), quotes
,
655 m4__builtin_print (obs
, value
->u
.builtin
, flatten
, chainp
, quotes
,
659 case M4_SYMBOL_PLACEHOLDER
:
664 obstack_grow (obs
, quotes
->str1
, quotes
->len1
);
665 obstack_grow (obs
, quotes
->str2
, quotes
->len2
);
671 text
= m4_get_symbol_value_placeholder (value
);
672 obstack_1grow (obs
, '<');
673 obstack_1grow (obs
, '<');
674 obstack_grow (obs
, text
, strlen (text
));
675 obstack_1grow (obs
, '>');
676 obstack_1grow (obs
, '>');
680 chain
= value
->u
.u_c
.chain
;
683 obstack_grow (obs
, quotes
->str1
, quotes
->len1
);
684 while (chain
&& !result
)
689 if (m4_shipout_string_trunc (obs
, chain
->u
.u_s
.str
,
690 chain
->u
.u_s
.len
, NULL
, &len
))
694 m4__builtin_print (obs
, chain
->u
.builtin
, flatten
, chainp
,
698 if (m4__arg_print (context
, obs
, chain
->u
.u_a
.argv
,
700 m4__quote_cache (M4SYNTAX
, NULL
,
702 chain
->u
.u_a
.quotes
),
703 chain
->u
.u_a
.flatten
, chainp
, NULL
, &len
,
708 assert (!"m4__symbol_value_print");
714 obstack_grow (obs
, quotes
->str2
, quotes
->len2
);
717 assert (!"m4__symbol_value_print");
721 if (module
&& VALUE_MODULE (value
))
723 obstack_1grow (obs
, '{');
724 text
= m4_get_module_name (VALUE_MODULE (value
));
725 obstack_grow (obs
, text
, strlen (text
));
726 obstack_1grow (obs
, '}');
733 /* Grow OBS with a text representation of SYMBOL. If QUOTES, then use
734 it to surround each text definition. If STACK, then append all
735 pushdef'd values, rather than just the top. If ARG_LENGTH is less
736 than SIZE_MAX, then truncate text definitions to that length. If
737 MODULE, then include which module defined a builtin. QUOTES and
738 MODULE do not count toward truncation. */
740 m4_symbol_print (m4
*context
, m4_symbol
*symbol
, m4_obstack
*obs
,
741 const m4_string_pair
*quotes
, bool stack
, size_t arg_length
,
744 m4_symbol_value
*value
;
745 size_t len
= arg_length
;
750 value
= m4_get_symbol_value (symbol
);
751 m4__symbol_value_print (context
, value
, obs
, quotes
, false, NULL
, &len
,
755 value
= VALUE_NEXT (value
);
758 obstack_1grow (obs
, ',');
759 obstack_1grow (obs
, ' ');
761 m4__symbol_value_print (context
, value
, obs
, quotes
, false, NULL
,
763 value
= VALUE_NEXT (value
);
769 /* Define these functions at the end, so that calls in the file use the
770 faster macro version from m4module.h. */
772 /* Pop all values from the symbol associated with NAME. */
773 #undef m4_symbol_delete
775 m4_symbol_delete (m4_symbol_table
*symtab
, const char *name
, size_t len
)
777 while (m4_symbol_lookup (symtab
, name
, len
))
778 m4_symbol_popdef (symtab
, name
, len
);
781 #undef m4_get_symbol_traced
783 m4_get_symbol_traced (m4_symbol
*symbol
)
786 return symbol
->traced
;
789 #undef m4_symbol_value_flatten_args
791 m4_symbol_value_flatten_args (m4_symbol_value
*value
)
794 return BIT_TEST (value
->flags
, VALUE_FLATTEN_ARGS_BIT
);
797 #undef m4_get_symbol_value
799 m4_get_symbol_value (m4_symbol
*symbol
)
802 return symbol
->value
;
805 #undef m4_is_symbol_value_text
807 m4_is_symbol_value_text (m4_symbol_value
*value
)
810 return (value
->type
== M4_SYMBOL_TEXT
);
813 #undef m4_is_symbol_value_func
815 m4_is_symbol_value_func (m4_symbol_value
*value
)
818 return (value
->type
== M4_SYMBOL_FUNC
);
821 #undef m4_is_symbol_value_placeholder
823 m4_is_symbol_value_placeholder (m4_symbol_value
*value
)
826 return (value
->type
== M4_SYMBOL_PLACEHOLDER
);
829 #undef m4_is_symbol_value_void
831 m4_is_symbol_value_void (m4_symbol_value
*value
)
834 return (value
->type
== M4_SYMBOL_VOID
);
837 #undef m4_get_symbol_value_text
839 m4_get_symbol_value_text (m4_symbol_value
*value
)
841 assert (value
&& value
->type
== M4_SYMBOL_TEXT
);
842 return value
->u
.u_t
.text
;
845 #undef m4_get_symbol_value_len
847 m4_get_symbol_value_len (m4_symbol_value
*value
)
849 assert (value
&& value
->type
== M4_SYMBOL_TEXT
);
850 return value
->u
.u_t
.len
;
853 #undef m4_get_symbol_value_quote_age
855 m4_get_symbol_value_quote_age (m4_symbol_value
*value
)
857 assert (value
&& value
->type
== M4_SYMBOL_TEXT
);
858 return value
->u
.u_t
.quote_age
;
861 #undef m4_get_symbol_value_func
863 m4_get_symbol_value_func (m4_symbol_value
*value
)
865 assert (value
&& value
->type
== M4_SYMBOL_FUNC
);
866 return value
->u
.builtin
->builtin
.func
;
869 #undef m4_get_symbol_value_builtin
871 m4_get_symbol_value_builtin (m4_symbol_value
*value
)
873 assert (value
&& value
->type
== M4_SYMBOL_FUNC
);
874 return &value
->u
.builtin
->builtin
;
877 #undef m4_get_symbol_value_placeholder
879 m4_get_symbol_value_placeholder (m4_symbol_value
*value
)
881 assert (value
&& value
->type
== M4_SYMBOL_PLACEHOLDER
);
882 return value
->u
.u_t
.text
;
885 #undef m4_set_symbol_value_text
887 m4_set_symbol_value_text (m4_symbol_value
*value
, const char *text
, size_t len
,
888 unsigned int quote_age
)
890 assert (value
&& text
);
891 /* In practice, it is easier to debug when we guarantee a
892 terminating NUL, even when there are embedded NULs. */
895 value
->type
= M4_SYMBOL_TEXT
;
896 value
->u
.u_t
.text
= text
;
897 value
->u
.u_t
.len
= len
;
898 value
->u
.u_t
.quote_age
= quote_age
;
901 #undef m4__set_symbol_value_builtin
903 m4__set_symbol_value_builtin (m4_symbol_value
*value
,
904 const m4__builtin
*builtin
)
906 assert (value
&& builtin
);
908 value
->type
= M4_SYMBOL_FUNC
;
909 value
->u
.builtin
= builtin
;
910 VALUE_MODULE (value
) = builtin
->module
;
911 VALUE_FLAGS (value
) = builtin
->builtin
.flags
;
912 VALUE_MIN_ARGS (value
) = builtin
->builtin
.min_args
;
913 VALUE_MAX_ARGS (value
) = builtin
->builtin
.max_args
;
916 #undef m4_set_symbol_value_placeholder
918 m4_set_symbol_value_placeholder (m4_symbol_value
*value
, const char *text
)
923 value
->type
= M4_SYMBOL_PLACEHOLDER
;
924 value
->u
.u_t
.text
= text
;
925 value
->u
.u_t
.len
= SIZE_MAX
; /* len is not tracked for placeholders. */
931 static void *dump_symbol_CB (m4_symbol_table
*symtab
, const char *name
,
932 m4_symbol
*symbol
, void *userdata
);
933 static M4_GNUC_UNUSED
void *
934 symtab_dump (m4
*context
, m4_symbol_table
*symtab
)
936 return m4_symtab_apply (symtab
, true, dump_symbol_CB
, context
);
940 dump_symbol_CB (m4_symbol_table
*symtab
, const char *name
,
941 m4_symbol
*symbol
, void *ptr
)
943 m4
* context
= (m4
*) ptr
;
944 m4_symbol_value
*value
= m4_get_symbol_value (symbol
);
945 int flags
= value
? SYMBOL_FLAGS (symbol
) : 0;
946 m4_module
* module
= value
? SYMBOL_MODULE (symbol
) : NULL
;
947 const char * module_name
= module
? m4_get_module_name (module
) : "NONE";
949 xfprintf (stderr
, "%10s: (%d%s) %s=", module_name
, flags
,
950 m4_get_symbol_traced (symbol
) ? "!" : "", name
);
953 fputs ("<!UNDEFINED!>", stderr
);
954 else if (m4_is_symbol_value_void (value
))
955 fputs ("<!VOID!>", stderr
);
960 m4__symbol_value_print (context
, value
, &obs
, NULL
, false, NULL
, NULL
,
962 xfprintf (stderr
, "%s", (char *) obstack_finish (&obs
));
963 obstack_free (&obs
, NULL
);
965 fputc ('\n', stderr
);
968 #endif /* DEBUG_SYM */