Switch to indentation by space, not tab.
[m4/ericb.git] / m4 / symtab.c
blob2211a7cfa9c8c1ee6d6a933859dd3b41191fa4f1
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/>.
21 #include <config.h>
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
46 this module. */
48 #define M4_SYMTAB_DEFAULT_SIZE 2047
50 struct m4_symbol_table {
51 m4_hash *table;
54 static m4_symbol *symtab_fetch (m4_symbol_table*, const char *,
55 size_t);
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 *,
60 void *);
61 static void * arg_copy_CB (m4_hash *, const void *, void *,
62 m4_hash *);
65 /* -- SYMBOL TABLE MANAGEMENT --
67 These functions are used to manage a symbol table as a whole. */
69 m4_symbol_table *
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);
76 return symtab;
79 void
80 m4_symtab_delete (m4_symbol_table *symtab)
82 assert (symtab);
83 assert (symtab->table);
85 m4_symtab_apply (symtab, true, symbol_destroy_CB, NULL);
86 m4_hash_delete (symtab->table);
87 free (symtab);
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. */
96 void *
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;
103 assert (symtab);
104 assert (symtab->table);
105 assert (func);
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)
112 const m4_string *key
113 = (const m4_string *) m4_get_hash_iterator_key (place);
114 result = func (symtab, key->str, key->len, symbol, userdata);
116 if (result != NULL)
118 m4_free_hash_iterator (symtab->table, place);
119 break;
123 return result;
126 /* Ensure that NAME of length LEN exists in the table, creating an
127 entry if needed. */
128 static m4_symbol *
129 symtab_fetch (m4_symbol_table *symtab, const char *name, size_t len)
131 m4_symbol **psymbol;
132 m4_symbol *symbol;
133 m4_string key;
135 assert (symtab);
136 assert (name);
138 /* Safe to cast away const, since m4_hash_lookup doesn't modify
139 key. */
140 key.str = (char *) name;
141 key.len = len;
142 psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
143 if (psymbol)
145 symbol = *psymbol;
147 else
149 /* Use xmemdup0 rather than memdup so that debugging the symbol
150 table is easier. */
151 m4_string *new_key = (m4_string *) xmalloc (sizeof *new_key);
152 new_key->str = xmemdup0 (name, len);
153 new_key->len = len;
154 symbol = (m4_symbol *) xzalloc (sizeof *symbol);
155 m4_hash_insert (symtab->table, new_key, symbol);
158 return symbol;
161 /* Remove every symbol that references the given module from
162 the symbol table. */
163 void
164 m4__symtab_remove_module_references (m4_symbol_table *symtab,
165 m4_module *module)
167 m4_hash_iterator *place = 0;
169 assert (module);
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... */
178 if (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);
192 else
193 data = next;
196 /* Purge the live reference if necessary. */
197 if (SYMBOL_MODULE (symbol) == module)
199 const m4_string *key
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
211 the table entry. */
212 static void *
213 symbol_destroy_CB (m4_symbol_table *symtab, const char *name, size_t len,
214 m4_symbol *symbol, void *ignored M4_GNUC_UNUSED)
216 m4_string key;
217 key.str = xmemdup0 (name, len);
218 key.len = len;
220 symbol->traced = false;
222 while (m4_hash_lookup (symtab->table, &key))
223 m4_symbol_popdef (symtab, key.str, key.len);
225 free (key.str);
227 return NULL;
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
238 NULL. */
239 m4_symbol *
240 m4_symbol_lookup (m4_symbol_table *symtab, const char *name, size_t len)
242 m4_string key;
243 m4_symbol **psymbol;
245 /* Safe to cast away const, since m4_hash_lookup doesn't modify
246 key. */
247 key.str = (char *) name;
248 key.len = len;
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
260 association. */
261 m4_symbol *
262 m4_symbol_pushdef (m4_symbol_table *symtab, const char *name, size_t len,
263 m4_symbol_value *value)
265 m4_symbol *symbol;
267 assert (symtab);
268 assert (name);
269 assert (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));
277 return 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
282 symbol's VALUE. */
283 m4_symbol *
284 m4_symbol_define (m4_symbol_table *symtab, const char *name, size_t len,
285 m4_symbol_value *value)
287 m4_symbol *symbol;
289 assert (symtab);
290 assert (name);
291 assert (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));
302 return 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. */
308 void
309 m4_symbol_popdef (m4_symbol_table *symtab, const char *name, size_t len)
311 m4_string key;
312 m4_symbol **psymbol;
314 /* Safe to cast away const, since m4_hash_lookup doesn't modify
315 key. */
316 key.str = (char *) name;
317 key.len = len;
318 psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
320 assert (psymbol);
321 assert (*psymbol);
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))
329 m4_string *old_key;
330 DELETE (*psymbol);
331 old_key = (m4_string *) m4_hash_remove (symtab->table, &key);
332 free (old_key->str);
333 free (old_key);
337 /* Remove the top-most value from SYMBOL's stack. */
338 static void
339 symbol_popval (m4_symbol *symbol)
341 m4_symbol_value *stale;
343 assert (symbol);
345 stale = m4_get_symbol_value (symbol);
347 if (stale)
349 symbol->value = VALUE_NEXT (stale);
350 m4_symbol_value_delete (stale);
354 /* Create a new symbol value, with fields populated for default
355 behavior. */
356 m4_symbol_value *
357 m4_symbol_value_create (void)
359 m4_symbol_value *value = (m4_symbol_value *) xzalloc (sizeof *value);
360 VALUE_MAX_ARGS (value) = SIZE_MAX;
361 return value;
364 /* Remove VALUE from the symbol table, and mark it as deleted. If no
365 expansions are pending, reclaim its resources. */
366 void
367 m4_symbol_value_delete (m4_symbol_value *value)
369 if (VALUE_PENDING (value) > 0)
370 BIT_SET (VALUE_FLAGS (value), VALUE_DELETED_BIT);
371 else
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));
378 switch (value->type)
380 case M4_SYMBOL_TEXT:
381 free ((char *) m4_get_symbol_value_text (value));
382 break;
383 case M4_SYMBOL_PLACEHOLDER:
384 free ((char *) m4_get_symbol_value_placeholder (value));
385 break;
386 case M4_SYMBOL_VOID:
387 case M4_SYMBOL_FUNC:
388 break;
389 default:
390 assert (!"m4_symbol_value_delete");
391 abort ();
393 free (value);
397 /* Rename the entire stack of values associated with NAME and LEN1 to
398 NEWNAME and LEN2. */
399 m4_symbol *
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;
404 m4_symbol **psymbol;
405 m4_string key;
406 m4_string *pkey;
408 assert (symtab);
409 assert (name);
410 assert (newname);
412 /* Safe to cast away const, since m4_hash_lookup doesn't modify
413 key. */
414 key.str = (char *) name;
415 key.len = len1;
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);
420 if (psymbol)
422 symbol = *psymbol;
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));
427 free (pkey->str);
429 pkey->str = xmemdup0 (newname, len2);
430 pkey->len = len2;
431 m4_hash_insert (symtab->table, pkey, *psymbol);
433 /* else
434 NAME does not name a symbol in symtab->table! */
436 return symbol;
440 /* Callback used by m4_symbol_popdef () to release the memory used
441 by values in the arg_signature hash. */
442 static void *
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;
447 assert (name);
448 assert (hash);
450 if (SYMBOL_ARG_DEFAULT (token_arg))
451 DELETE (SYMBOL_ARG_DEFAULT (token_arg));
452 free (token_arg);
453 free (m4_hash_remove (hash, (const char *) name));
455 return NULL;
458 /* Copy the symbol SRC into DEST. Return true if builtin tokens were
459 flattened. */
460 bool
461 m4_symbol_value_copy (m4 *context, m4_symbol_value *dest, m4_symbol_value *src)
463 m4_symbol_value *next;
464 bool result = false;
466 assert (dest);
467 assert (src);
469 switch (dest->type)
471 case M4_SYMBOL_TEXT:
472 free ((char *) m4_get_symbol_value_text (dest));
473 break;
474 case M4_SYMBOL_PLACEHOLDER:
475 free ((char *) m4_get_symbol_value_placeholder (dest));
476 break;
477 case M4_SYMBOL_VOID:
478 case M4_SYMBOL_FUNC:
479 break;
480 default:
481 assert (!"m4_symbol_value_delete");
482 abort ();
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
492 the next pointer. */
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. */
499 switch (src->type)
501 case M4_SYMBOL_TEXT:
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),
507 len), len, age);
509 break;
510 case M4_SYMBOL_FUNC:
511 m4__set_symbol_value_builtin (dest, src->u.builtin);
512 break;
513 case M4_SYMBOL_PLACEHOLDER:
514 m4_set_symbol_value_placeholder (dest,
515 xstrdup (m4_get_symbol_value_placeholder
516 (src)));
517 break;
518 case M4_SYMBOL_COMP:
520 m4__symbol_chain *chain = src->u.u_c.chain;
521 size_t len;
522 char *str;
523 const m4_string_pair *quotes;
524 m4_obstack *obs = m4_arg_scratch (context);
525 while (chain)
527 switch (chain->type)
529 case M4__CHAIN_STR:
530 obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
531 break;
532 case M4__CHAIN_FUNC:
533 result = true;
534 break;
535 case M4__CHAIN_ARGV:
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)
539 result = true;
540 m4__arg_print (context, obs, chain->u.u_a.argv,
541 chain->u.u_a.index, quotes, true, NULL, NULL,
542 NULL, false, false);
543 break;
544 default:
545 assert (!"m4_symbol_value_copy");
546 abort ();
548 chain = chain->next;
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);
556 break;
557 default:
558 assert (!"m4_symbol_value_copy");
559 abort ();
561 if (VALUE_ARG_SIGNATURE (src))
562 VALUE_ARG_SIGNATURE (dest) = m4_hash_dup (VALUE_ARG_SIGNATURE (src),
563 arg_copy_CB);
564 return result;
567 static void *
568 arg_copy_CB (m4_hash *src, const void *name, void *arg, m4_hash *dest)
570 m4_hash_insert ((m4_hash *) dest, name, arg);
571 return NULL;
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. */
579 bool
580 m4_set_symbol_name_traced (m4_symbol_table *symtab, const char *name,
581 size_t len, bool traced)
583 m4_symbol *symbol;
584 bool result;
586 assert (symtab);
587 assert (name);
589 if (traced)
590 symbol = symtab_fetch (symtab, name, len);
591 else
593 m4_string key;
594 m4_symbol **psymbol;
596 /* Safe to cast away const, since m4_hash_lookup doesn't modify
597 key. */
598 key.str = (char *) name;
599 key.len = len;
600 psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
601 if (!psymbol)
602 return false;
603 symbol = *psymbol;
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. */
611 m4_string key;
612 m4_string *old_key;
613 assert (result);
614 free (symbol);
616 /* Safe to cast away const, since m4_hash_lookup doesn't modify
617 key. */
618 key.str = (char *) name;
619 key.len = len;
620 old_key = (m4_string *) m4_hash_remove (symtab->table, &key);
621 free (old_key->str);
622 free (old_key);
625 return result;
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. */
636 bool
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)
641 const char *text;
642 m4__symbol_chain *chain;
643 size_t len = maxlen ? *maxlen : SIZE_MAX;
644 bool result = false;
646 switch (value->type)
648 case M4_SYMBOL_TEXT:
649 if (m4_shipout_string_trunc (obs, m4_get_symbol_value_text (value),
650 m4_get_symbol_value_len (value), quotes,
651 &len))
652 result = true;
653 break;
654 case M4_SYMBOL_FUNC:
655 m4__builtin_print (obs, value->u.builtin, flatten, chainp, quotes,
656 module);
657 module = false;
658 break;
659 case M4_SYMBOL_PLACEHOLDER:
660 if (flatten)
662 if (quotes)
664 obstack_grow (obs, quotes->str1, quotes->len1);
665 obstack_grow (obs, quotes->str2, quotes->len2);
667 module = false;
669 else
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, '>');
678 break;
679 case M4_SYMBOL_COMP:
680 chain = value->u.u_c.chain;
681 assert (!module);
682 if (quotes)
683 obstack_grow (obs, quotes->str1, quotes->len1);
684 while (chain && !result)
686 switch (chain->type)
688 case M4__CHAIN_STR:
689 if (m4_shipout_string_trunc (obs, chain->u.u_s.str,
690 chain->u.u_s.len, NULL, &len))
691 result = true;
692 break;
693 case M4__CHAIN_FUNC:
694 m4__builtin_print (obs, chain->u.builtin, flatten, chainp,
695 quotes, module);
696 break;
697 case M4__CHAIN_ARGV:
698 if (m4__arg_print (context, obs, chain->u.u_a.argv,
699 chain->u.u_a.index,
700 m4__quote_cache (M4SYNTAX, NULL,
701 chain->quote_age,
702 chain->u.u_a.quotes),
703 chain->u.u_a.flatten, chainp, NULL, &len,
704 false, module))
705 result = true;
706 break;
707 default:
708 assert (!"m4__symbol_value_print");
709 abort ();
711 chain = chain->next;
713 if (quotes)
714 obstack_grow (obs, quotes->str2, quotes->len2);
715 break;
716 default:
717 assert (!"m4__symbol_value_print");
718 abort ();
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, '}');
728 if (maxlen)
729 *maxlen = len;
730 return result;
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. */
739 void
740 m4_symbol_print (m4 *context, m4_symbol *symbol, m4_obstack *obs,
741 const m4_string_pair *quotes, bool stack, size_t arg_length,
742 bool module)
744 m4_symbol_value *value;
745 size_t len = arg_length;
747 assert (symbol);
748 assert (obs);
750 value = m4_get_symbol_value (symbol);
751 m4__symbol_value_print (context, value, obs, quotes, false, NULL, &len,
752 module);
753 if (stack)
755 value = VALUE_NEXT (value);
756 while (value)
758 obstack_1grow (obs, ',');
759 obstack_1grow (obs, ' ');
760 len = arg_length;
761 m4__symbol_value_print (context, value, obs, quotes, false, NULL,
762 &len, module);
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
774 void
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
782 bool
783 m4_get_symbol_traced (m4_symbol *symbol)
785 assert (symbol);
786 return symbol->traced;
789 #undef m4_symbol_value_flatten_args
790 bool
791 m4_symbol_value_flatten_args (m4_symbol_value *value)
793 assert (value);
794 return BIT_TEST (value->flags, VALUE_FLATTEN_ARGS_BIT);
797 #undef m4_get_symbol_value
798 m4_symbol_value *
799 m4_get_symbol_value (m4_symbol *symbol)
801 assert (symbol);
802 return symbol->value;
805 #undef m4_is_symbol_value_text
806 bool
807 m4_is_symbol_value_text (m4_symbol_value *value)
809 assert (value);
810 return (value->type == M4_SYMBOL_TEXT);
813 #undef m4_is_symbol_value_func
814 bool
815 m4_is_symbol_value_func (m4_symbol_value *value)
817 assert (value);
818 return (value->type == M4_SYMBOL_FUNC);
821 #undef m4_is_symbol_value_placeholder
822 bool
823 m4_is_symbol_value_placeholder (m4_symbol_value *value)
825 assert (value);
826 return (value->type == M4_SYMBOL_PLACEHOLDER);
829 #undef m4_is_symbol_value_void
830 bool
831 m4_is_symbol_value_void (m4_symbol_value *value)
833 assert (value);
834 return (value->type == M4_SYMBOL_VOID);
837 #undef m4_get_symbol_value_text
838 const char *
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
846 size_t
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
854 unsigned int
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
862 m4_builtin_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
870 const m4_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
878 const char *
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
886 void
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. */
893 assert (!text[len]);
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
902 void
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
917 void
918 m4_set_symbol_value_placeholder (m4_symbol_value *value, const char *text)
920 assert (value);
921 assert (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. */
929 #ifdef DEBUG_SYM
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);
939 static void *
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);
952 if (!value)
953 fputs ("<!UNDEFINED!>", stderr);
954 else if (m4_is_symbol_value_void (value))
955 fputs ("<!VOID!>", stderr);
956 else
958 m4_obstack obs;
959 obstack_init (&obs);
960 m4__symbol_value_print (context, value, &obs, NULL, false, NULL, NULL,
961 true);
962 xfprintf (stderr, "%s", (char *) obstack_finish (&obs));
963 obstack_free (&obs, NULL);
965 fputc ('\n', stderr);
966 return NULL;
968 #endif /* DEBUG_SYM */