summaryrefslogtreecommitdiff
path: root/m4/symtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'm4/symtab.c')
-rw-r--r--m4/symtab.c968
1 files changed, 0 insertions, 968 deletions
diff --git a/m4/symtab.c b/m4/symtab.c
deleted file mode 100644
index b04b55e7..00000000
--- a/m4/symtab.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2001, 2005-2008, 2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include "m4private.h"
-
-/* Define this to see runtime debug info. Implied by DEBUG. */
-/*#define DEBUG_SYM */
-
-/* This file handles all the low level work around the symbol table. The
- symbol table is an abstract hash table type implemented in hash.c. Each
- symbol is represented by `struct m4_symbol', which is stored in the hash
- table keyed by the symbol name. As a special case, to facilitate the
- "pushdef" and "popdef" builtins, the value stored against each key is a
- stack of `m4_symbol_value'. All the value entries for a symbol name are
- simply ordered on the stack by age. The most recently pushed definition
- will then always be the first found.
-
- Also worthy of mention is the way traced symbols are managed: the
- trace bit is associated with a particular symbol name. If a symbol
- is undefined and then redefined, it does not lose its trace bit.
- This is achieved by not removing traced symbol names from the
- symbol table, even if their value stack is empty. That way, when
- the name is given a new value, it is pushed onto the empty stack,
- and the trace bit attached to the name was never lost. There is a
- small amount of fluff in these functions to make sure that such
- symbols (with empty value stacks) are invisible to the users of
- this module. */
-
-#define M4_SYMTAB_DEFAULT_SIZE 2047
-
-struct m4_symbol_table {
- m4_hash *table;
-};
-
-static m4_symbol *symtab_fetch (m4_symbol_table*, const char *,
- size_t);
-static void symbol_popval (m4_symbol *);
-static void * symbol_destroy_CB (m4_symbol_table *, const char *,
- size_t, m4_symbol *, void *);
-static void * arg_destroy_CB (m4_hash *, const void *, void *,
- void *);
-static void * arg_copy_CB (m4_hash *, const void *, void *,
- m4_hash *);
-
-
-/* -- SYMBOL TABLE MANAGEMENT --
-
- These functions are used to manage a symbol table as a whole. */
-
-m4_symbol_table *
-m4_symtab_create (size_t size)
-{
- m4_symbol_table *symtab = (m4_symbol_table *) xmalloc (sizeof *symtab);
-
- symtab->table = m4_hash_new (size ? size : M4_SYMTAB_DEFAULT_SIZE,
- m4_hash_string_hash, m4_hash_string_cmp);
- return symtab;
-}
-
-void
-m4_symtab_delete (m4_symbol_table *symtab)
-{
- assert (symtab);
- assert (symtab->table);
-
- m4_symtab_apply (symtab, true, symbol_destroy_CB, NULL);
- m4_hash_delete (symtab->table);
- free (symtab);
-}
-
-/* For every symbol in SYMTAB, execute the callback FUNC with the name
- and value of the symbol being visited, and the opaque parameter
- USERDATA. Skip undefined symbols that are placeholders for
- traceon, unless INCLUDE_TRACE is true. If FUNC returns non-NULL,
- abort the iteration and return the same result; otherwise return
- NULL when iteration completes. */
-void *
-m4_symtab_apply (m4_symbol_table *symtab, bool include_trace,
- m4_symtab_apply_func *func, void *userdata)
-{
- m4_hash_iterator *place = NULL;
- void * result = NULL;
-
- assert (symtab);
- assert (symtab->table);
- assert (func);
-
- while ((place = m4_get_hash_iterator_next (symtab->table, place)))
- {
- m4_symbol *symbol = m4_get_hash_iterator_value (place);
- if (symbol->value || include_trace)
- {
- const m4_string *key
- = (const m4_string *) m4_get_hash_iterator_key (place);
- result = func (symtab, key->str, key->len, symbol, userdata);
- }
- if (result != NULL)
- {
- m4_free_hash_iterator (symtab->table, place);
- break;
- }
- }
-
- return result;
-}
-
-/* Ensure that NAME of length LEN exists in the table, creating an
- entry if needed. */
-static m4_symbol *
-symtab_fetch (m4_symbol_table *symtab, const char *name, size_t len)
-{
- m4_symbol **psymbol;
- m4_symbol *symbol;
- m4_string key;
-
- assert (symtab);
- assert (name);
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
- if (psymbol)
- {
- symbol = *psymbol;
- }
- else
- {
- /* Use xmemdup0 rather than memdup so that debugging the symbol
- table is easier. */
- m4_string *new_key = (m4_string *) xmalloc (sizeof *new_key);
- new_key->str = xmemdup0 (name, len);
- new_key->len = len;
- symbol = (m4_symbol *) xzalloc (sizeof *symbol);
- m4_hash_insert (symtab->table, new_key, symbol);
- }
-
- return symbol;
-}
-
-/* Remove every symbol that references the given module from
- the symbol table. */
-void
-m4__symtab_remove_module_references (m4_symbol_table *symtab,
- m4_module *module)
-{
- m4_hash_iterator *place = 0;
-
- assert (module);
-
- /* Traverse each symbol name in the hash table. */
- while ((place = m4_get_hash_iterator_next (symtab->table, place)))
- {
- m4_symbol *symbol = (m4_symbol *) m4_get_hash_iterator_value (place);
- m4_symbol_value *data = m4_get_symbol_value (symbol);
-
- /* For symbols that have token data... */
- if (data)
- {
- /* Purge any shadowed references. */
- while (VALUE_NEXT (data))
- {
- m4_symbol_value *next = VALUE_NEXT (data);
-
- if (VALUE_MODULE (next) == module)
- {
- VALUE_NEXT (data) = VALUE_NEXT (next);
-
- assert (next->type != M4_SYMBOL_PLACEHOLDER);
- m4_symbol_value_delete (next);
- }
- else
- data = next;
- }
-
- /* Purge the live reference if necessary. */
- if (SYMBOL_MODULE (symbol) == module)
- {
- const m4_string *key
- = (const m4_string *) m4_get_hash_iterator_key (place);
- m4_symbol_popdef (symtab, key->str, key->len);
- }
- }
- }
-}
-
-
-/* This callback is used exclusively by m4_symtab_delete(), to cleanup
- the memory used by the symbol table. As such, the trace bit is reset
- on every symbol so that m4_symbol_popdef() doesn't try to preserve
- the table entry. */
-static void *
-symbol_destroy_CB (m4_symbol_table *symtab, const char *name, size_t len,
- m4_symbol *symbol, void *ignored M4_GNUC_UNUSED)
-{
- m4_string key;
- key.str = xmemdup0 (name, len);
- key.len = len;
-
- symbol->traced = false;
-
- while (m4_hash_lookup (symtab->table, &key))
- m4_symbol_popdef (symtab, key.str, key.len);
-
- free (key.str);
-
- return NULL;
-}
-
-
-
-/* -- SYMBOL MANAGEMENT --
-
- The following functions manipulate individual symbols within
- an existing table. */
-
-/* Return the symbol associated to NAME of length LEN, or else
- NULL. */
-m4_symbol *
-m4_symbol_lookup (m4_symbol_table *symtab, const char *name, size_t len)
-{
- m4_string key;
- m4_symbol **psymbol;
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
-
- /* If just searching, return status of search -- if only an empty
- struct is returned, that is treated as a failed lookup. */
- return (psymbol && m4_get_symbol_value (*psymbol)) ? *psymbol : NULL;
-}
-
-
-/* Insert NAME of length LEN into the symbol table. If there is
- already a symbol associated with NAME, push the new VALUE on top of
- the value stack for this symbol. Otherwise create a new
- association. */
-m4_symbol *
-m4_symbol_pushdef (m4_symbol_table *symtab, const char *name, size_t len,
- m4_symbol_value *value)
-{
- m4_symbol *symbol;
-
- assert (symtab);
- assert (name);
- assert (value);
-
- symbol = symtab_fetch (symtab, name, len);
- VALUE_NEXT (value) = m4_get_symbol_value (symbol);
- symbol->value = value;
-
- assert (m4_get_symbol_value (symbol));
-
- return symbol;
-}
-
-/* Return the symbol associated with NAME of length LEN in the symbol
- table, creating a new symbol if necessary. In either case set the
- symbol's VALUE. */
-m4_symbol *
-m4_symbol_define (m4_symbol_table *symtab, const char *name, size_t len,
- m4_symbol_value *value)
-{
- m4_symbol *symbol;
-
- assert (symtab);
- assert (name);
- assert (value);
-
- symbol = symtab_fetch (symtab, name, len);
- if (m4_get_symbol_value (symbol))
- symbol_popval (symbol);
-
- VALUE_NEXT (value) = m4_get_symbol_value (symbol);
- symbol->value = value;
-
- assert (m4_get_symbol_value (symbol));
-
- return symbol;
-}
-
-/* Pop the topmost value stack entry from the symbol associated with
- NAME of length LEN, deleting it from the table entirely if that was
- the last remaining value in the stack. */
-void
-m4_symbol_popdef (m4_symbol_table *symtab, const char *name, size_t len)
-{
- m4_string key;
- m4_symbol **psymbol;
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
-
- assert (psymbol);
- assert (*psymbol);
-
- symbol_popval (*psymbol);
-
- /* Only remove the hash table entry if the last value in the
- symbol value stack was successfully removed. */
- if (!m4_get_symbol_value (*psymbol) && !m4_get_symbol_traced (*psymbol))
- {
- m4_string *old_key;
- DELETE (*psymbol);
- old_key = (m4_string *) m4_hash_remove (symtab->table, &key);
- free (old_key->str);
- free (old_key);
- }
-}
-
-/* Remove the top-most value from SYMBOL's stack. */
-static void
-symbol_popval (m4_symbol *symbol)
-{
- m4_symbol_value *stale;
-
- assert (symbol);
-
- stale = m4_get_symbol_value (symbol);
-
- if (stale)
- {
- symbol->value = VALUE_NEXT (stale);
- m4_symbol_value_delete (stale);
- }
-}
-
-/* Create a new symbol value, with fields populated for default
- behavior. */
-m4_symbol_value *
-m4_symbol_value_create (void)
-{
- m4_symbol_value *value = (m4_symbol_value *) xzalloc (sizeof *value);
- VALUE_MAX_ARGS (value) = SIZE_MAX;
- return value;
-}
-
-/* Remove VALUE from the symbol table, and mark it as deleted. If no
- expansions are pending, reclaim its resources. */
-void
-m4_symbol_value_delete (m4_symbol_value *value)
-{
- if (VALUE_PENDING (value) > 0)
- BIT_SET (VALUE_FLAGS (value), VALUE_DELETED_BIT);
- else
- {
- if (VALUE_ARG_SIGNATURE (value))
- {
- m4_hash_apply (VALUE_ARG_SIGNATURE (value), arg_destroy_CB, NULL);
- m4_hash_delete (VALUE_ARG_SIGNATURE (value));
- }
- switch (value->type)
- {
- case M4_SYMBOL_TEXT:
- DELETE (value->u.u_t.text);
- break;
- case M4_SYMBOL_PLACEHOLDER:
- DELETE (value->u.u_t.text);
- break;
- case M4_SYMBOL_VOID:
- case M4_SYMBOL_FUNC:
- break;
- default:
- assert (!"m4_symbol_value_delete");
- abort ();
- }
- free (value);
- }
-}
-
-/* Rename the entire stack of values associated with NAME and LEN1 to
- NEWNAME and LEN2. */
-m4_symbol *
-m4_symbol_rename (m4_symbol_table *symtab, const char *name, size_t len1,
- const char *newname, size_t len2)
-{
- m4_symbol *symbol = NULL;
- m4_symbol **psymbol;
- m4_string key;
- m4_string *pkey;
-
- assert (symtab);
- assert (name);
- assert (newname);
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len1;
- /* Use a low level hash fetch, so we can save the symbol value when
- removing the symbol name from the symbol table. */
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
-
- if (psymbol)
- {
- symbol = *psymbol;
-
- /* Remove the old name from the symbol table. */
- pkey = (m4_string *) m4_hash_remove (symtab->table, &key);
- assert (pkey && !m4_hash_lookup (symtab->table, &key));
- free (pkey->str);
-
- pkey->str = xmemdup0 (newname, len2);
- pkey->len = len2;
- m4_hash_insert (symtab->table, pkey, *psymbol);
- }
- /* else
- NAME does not name a symbol in symtab->table! */
-
- return symbol;
-}
-
-
-/* Callback used by m4_symbol_popdef () to release the memory used
- by values in the arg_signature hash. */
-static void *
-arg_destroy_CB (m4_hash *hash, const void *name, void *arg, void *ignored)
-{
- struct m4_symbol_arg *token_arg = (struct m4_symbol_arg *) arg;
-
- assert (name);
- assert (hash);
-
- if (SYMBOL_ARG_DEFAULT (token_arg))
- DELETE (SYMBOL_ARG_DEFAULT (token_arg));
- free (token_arg);
- free (m4_hash_remove (hash, (const char *) name));
-
- return NULL;
-}
-
-/* Copy the symbol SRC into DEST. Return true if builtin tokens were
- flattened. */
-bool
-m4_symbol_value_copy (m4 *context, m4_symbol_value *dest, m4_symbol_value *src)
-{
- m4_symbol_value *next;
- bool result = false;
-
- assert (dest);
- assert (src);
-
- switch (dest->type)
- {
- case M4_SYMBOL_TEXT:
- DELETE (dest->u.u_t.text);
- break;
- case M4_SYMBOL_PLACEHOLDER:
- DELETE (dest->u.u_t.text);
- break;
- case M4_SYMBOL_VOID:
- case M4_SYMBOL_FUNC:
- break;
- default:
- assert (!"m4_symbol_value_delete");
- abort ();
- }
-
- if (VALUE_ARG_SIGNATURE (dest))
- {
- m4_hash_apply (VALUE_ARG_SIGNATURE (dest), arg_destroy_CB, NULL);
- m4_hash_delete (VALUE_ARG_SIGNATURE (dest));
- }
-
- /* Copy the value contents over, being careful to preserve
- the next pointer. */
- next = VALUE_NEXT (dest);
- memcpy (dest, src, sizeof (m4_symbol_value));
- VALUE_NEXT (dest) = next;
-
- /* Caller is supposed to free text token strings, so we have to
- copy the string not just its address in that case. */
- switch (src->type)
- {
- case M4_SYMBOL_TEXT:
- {
- size_t len = m4_get_symbol_value_len (src);
- unsigned int age = m4_get_symbol_value_quote_age (src);
- m4_set_symbol_value_text (dest,
- xmemdup0 (m4_get_symbol_value_text (src),
- len), len, age);
- }
- break;
- case M4_SYMBOL_FUNC:
- m4__set_symbol_value_builtin (dest, src->u.builtin);
- break;
- case M4_SYMBOL_PLACEHOLDER:
- m4_set_symbol_value_placeholder (dest,
- xstrdup (m4_get_symbol_value_placeholder
- (src)));
- break;
- case M4_SYMBOL_COMP:
- {
- m4__symbol_chain *chain = src->u.u_c.chain;
- size_t len;
- char *str;
- const m4_string_pair *quotes;
- m4_obstack *obs = m4_arg_scratch (context);
- while (chain)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
- break;
- case M4__CHAIN_FUNC:
- result = true;
- break;
- case M4__CHAIN_ARGV:
- quotes = m4__quote_cache (M4SYNTAX, NULL, chain->quote_age,
- chain->u.u_a.quotes);
- if (chain->u.u_a.has_func && !chain->u.u_a.flatten)
- result = true;
- m4__arg_print (context, obs, chain->u.u_a.argv,
- chain->u.u_a.index, quotes, true, NULL, NULL,
- NULL, false, false);
- break;
- default:
- assert (!"m4_symbol_value_copy");
- abort ();
- }
- chain = chain->next;
- }
- obstack_1grow (obs, '\0');
- len = obstack_object_size (obs);
- str = xcharalloc (len);
- memcpy (str, obstack_finish (obs), len);
- m4_set_symbol_value_text (dest, str, len - 1, 0);
- }
- break;
- default:
- assert (!"m4_symbol_value_copy");
- abort ();
- }
- if (VALUE_ARG_SIGNATURE (src))
- VALUE_ARG_SIGNATURE (dest) = m4_hash_dup (VALUE_ARG_SIGNATURE (src),
- arg_copy_CB);
- return result;
-}
-
-static void *
-arg_copy_CB (m4_hash *src, const void *name, void *arg, m4_hash *dest)
-{
- m4_hash_insert ((m4_hash *) dest, name, arg);
- return NULL;
-}
-
-/* Set the tracing status of the symbol NAME of length LEN to TRACED.
- This takes a name, rather than a symbol, since we hide macros that
- are traced but otherwise undefined from normal lookups, but still
- can affect their tracing status. Return true iff the macro was
- previously traced. */
-bool
-m4_set_symbol_name_traced (m4_symbol_table *symtab, const char *name,
- size_t len, bool traced)
-{
- m4_symbol *symbol;
- bool result;
-
- assert (symtab);
- assert (name);
-
- if (traced)
- symbol = symtab_fetch (symtab, name, len);
- else
- {
- m4_string key;
- m4_symbol **psymbol;
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
- if (!psymbol)
- return false;
- symbol = *psymbol;
- }
-
- result = symbol->traced;
- symbol->traced = traced;
- if (!traced && !m4_get_symbol_value (symbol))
- {
- /* Free an undefined entry once it is no longer traced. */
- m4_string key;
- m4_string *old_key;
- assert (result);
- free (symbol);
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- old_key = (m4_string *) m4_hash_remove (symtab->table, &key);
- free (old_key->str);
- free (old_key);
- }
-
- return result;
-}
-
-/* Grow OBS with a text representation of VALUE. If QUOTES, then use
- it to surround a text definition. If FLATTEN, builtins are
- converted to empty quotes; if CHAINP, *CHAINP is updated with macro
- tokens; otherwise, builtins are represented by their name. If
- MAXLEN, then truncate text definitions to *MAXLEN, and adjust by
- how many characters are printed. If MODULE, then include which
- module defined a builtin. Return true if the output was truncated.
- QUOTES and MODULE do not count against the truncation length. */
-bool
-m4__symbol_value_print (m4 *context, m4_symbol_value *value, m4_obstack *obs,
- const m4_string_pair *quotes, bool flatten,
- m4__symbol_chain **chainp, size_t *maxlen, bool module)
-{
- const char *text;
- m4__symbol_chain *chain;
- size_t len = maxlen ? *maxlen : SIZE_MAX;
- bool result = false;
-
- switch (value->type)
- {
- case M4_SYMBOL_TEXT:
- if (m4_shipout_string_trunc (obs, m4_get_symbol_value_text (value),
- m4_get_symbol_value_len (value), quotes,
- &len))
- result = true;
- break;
- case M4_SYMBOL_FUNC:
- m4__builtin_print (obs, value->u.builtin, flatten, chainp, quotes,
- module);
- module = false;
- break;
- case M4_SYMBOL_PLACEHOLDER:
- if (flatten)
- {
- if (quotes)
- {
- obstack_grow (obs, quotes->str1, quotes->len1);
- obstack_grow (obs, quotes->str2, quotes->len2);
- }
- module = false;
- }
- else
- {
- text = m4_get_symbol_value_placeholder (value);
- obstack_1grow (obs, '<');
- obstack_1grow (obs, '<');
- obstack_grow (obs, text, strlen (text));
- obstack_1grow (obs, '>');
- obstack_1grow (obs, '>');
- }
- break;
- case M4_SYMBOL_COMP:
- chain = value->u.u_c.chain;
- assert (!module);
- if (quotes)
- obstack_grow (obs, quotes->str1, quotes->len1);
- while (chain && !result)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- if (m4_shipout_string_trunc (obs, chain->u.u_s.str,
- chain->u.u_s.len, NULL, &len))
- result = true;
- break;
- case M4__CHAIN_FUNC:
- m4__builtin_print (obs, chain->u.builtin, flatten, chainp,
- quotes, module);
- break;
- case M4__CHAIN_ARGV:
- if (m4__arg_print (context, obs, chain->u.u_a.argv,
- chain->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL,
- chain->quote_age,
- chain->u.u_a.quotes),
- chain->u.u_a.flatten, chainp, NULL, &len,
- false, module))
- result = true;
- break;
- default:
- assert (!"m4__symbol_value_print");
- abort ();
- }
- chain = chain->next;
- }
- if (quotes)
- obstack_grow (obs, quotes->str2, quotes->len2);
- break;
- default:
- assert (!"m4__symbol_value_print");
- abort ();
- }
-
- if (module && VALUE_MODULE (value))
- {
- obstack_1grow (obs, '{');
- text = m4_get_module_name (VALUE_MODULE (value));
- obstack_grow (obs, text, strlen (text));
- obstack_1grow (obs, '}');
- }
- if (maxlen)
- *maxlen = len;
- return result;
-}
-
-/* Grow OBS with a text representation of SYMBOL. If QUOTES, then use
- it to surround each text definition. If STACK, then append all
- pushdef'd values, rather than just the top. If ARG_LENGTH is less
- than SIZE_MAX, then truncate text definitions to that length. If
- MODULE, then include which module defined a builtin. QUOTES and
- MODULE do not count toward truncation. */
-void
-m4_symbol_print (m4 *context, m4_symbol *symbol, m4_obstack *obs,
- const m4_string_pair *quotes, bool stack, size_t arg_length,
- bool module)
-{
- m4_symbol_value *value;
- size_t len = arg_length;
-
- assert (symbol);
- assert (obs);
-
- value = m4_get_symbol_value (symbol);
- m4__symbol_value_print (context, value, obs, quotes, false, NULL, &len,
- module);
- if (stack)
- {
- value = VALUE_NEXT (value);
- while (value)
- {
- obstack_1grow (obs, ',');
- obstack_1grow (obs, ' ');
- len = arg_length;
- m4__symbol_value_print (context, value, obs, quotes, false, NULL,
- &len, module);
- value = VALUE_NEXT (value);
- }
- }
-}
-
-
-/* Define these functions at the end, so that calls in the file use the
- faster macro version from m4module.h. */
-
-/* Pop all values from the symbol associated with NAME. */
-#undef m4_symbol_delete
-void
-m4_symbol_delete (m4_symbol_table *symtab, const char *name, size_t len)
-{
- while (m4_symbol_lookup (symtab, name, len))
- m4_symbol_popdef (symtab, name, len);
-}
-
-#undef m4_get_symbol_traced
-bool
-m4_get_symbol_traced (m4_symbol *symbol)
-{
- assert (symbol);
- return symbol->traced;
-}
-
-#undef m4_symbol_value_flatten_args
-bool
-m4_symbol_value_flatten_args (m4_symbol_value *value)
-{
- assert (value);
- return BIT_TEST (value->flags, VALUE_FLATTEN_ARGS_BIT);
-}
-
-#undef m4_get_symbol_value
-m4_symbol_value *
-m4_get_symbol_value (m4_symbol *symbol)
-{
- assert (symbol);
- return symbol->value;
-}
-
-#undef m4_is_symbol_value_text
-bool
-m4_is_symbol_value_text (m4_symbol_value *value)
-{
- assert (value);
- return (value->type == M4_SYMBOL_TEXT);
-}
-
-#undef m4_is_symbol_value_func
-bool
-m4_is_symbol_value_func (m4_symbol_value *value)
-{
- assert (value);
- return (value->type == M4_SYMBOL_FUNC);
-}
-
-#undef m4_is_symbol_value_placeholder
-bool
-m4_is_symbol_value_placeholder (m4_symbol_value *value)
-{
- assert (value);
- return (value->type == M4_SYMBOL_PLACEHOLDER);
-}
-
-#undef m4_is_symbol_value_void
-bool
-m4_is_symbol_value_void (m4_symbol_value *value)
-{
- assert (value);
- return (value->type == M4_SYMBOL_VOID);
-}
-
-#undef m4_get_symbol_value_text
-const char *
-m4_get_symbol_value_text (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_TEXT);
- return value->u.u_t.text;
-}
-
-#undef m4_get_symbol_value_len
-size_t
-m4_get_symbol_value_len (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_TEXT);
- return value->u.u_t.len;
-}
-
-#undef m4_get_symbol_value_quote_age
-unsigned int
-m4_get_symbol_value_quote_age (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_TEXT);
- return value->u.u_t.quote_age;
-}
-
-#undef m4_get_symbol_value_func
-m4_builtin_func *
-m4_get_symbol_value_func (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_FUNC);
- return value->u.builtin->builtin.func;
-}
-
-#undef m4_get_symbol_value_builtin
-const m4_builtin *
-m4_get_symbol_value_builtin (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_FUNC);
- return &value->u.builtin->builtin;
-}
-
-#undef m4_get_symbol_value_placeholder
-const char *
-m4_get_symbol_value_placeholder (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_PLACEHOLDER);
- return value->u.u_t.text;
-}
-
-#undef m4_set_symbol_value_text
-void
-m4_set_symbol_value_text (m4_symbol_value *value, const char *text, size_t len,
- unsigned int quote_age)
-{
- assert (value && text);
- /* In practice, it is easier to debug when we guarantee a
- terminating NUL, even when there are embedded NULs. */
- assert (!text[len]);
-
- value->type = M4_SYMBOL_TEXT;
- value->u.u_t.text = text;
- value->u.u_t.len = len;
- value->u.u_t.quote_age = quote_age;
-}
-
-#undef m4__set_symbol_value_builtin
-void
-m4__set_symbol_value_builtin (m4_symbol_value *value,
- const m4__builtin *builtin)
-{
- assert (value && builtin);
-
- value->type = M4_SYMBOL_FUNC;
- value->u.builtin = builtin;
- VALUE_MODULE (value) = builtin->module;
- VALUE_FLAGS (value) = builtin->builtin.flags;
- VALUE_MIN_ARGS (value) = builtin->builtin.min_args;
- VALUE_MAX_ARGS (value) = builtin->builtin.max_args;
-}
-
-#undef m4_set_symbol_value_placeholder
-void
-m4_set_symbol_value_placeholder (m4_symbol_value *value, const char *text)
-{
- assert (value);
- assert (text);
-
- value->type = M4_SYMBOL_PLACEHOLDER;
- value->u.u_t.text = text;
- value->u.u_t.len = SIZE_MAX; /* len is not tracked for placeholders. */
-}
-
-
-#ifdef DEBUG_SYM
-
-static void *dump_symbol_CB (m4_symbol_table *symtab, const char *name,
- m4_symbol *symbol, void *userdata);
-static M4_GNUC_UNUSED void *
-symtab_dump (m4 *context, m4_symbol_table *symtab)
-{
- return m4_symtab_apply (symtab, true, dump_symbol_CB, context);
-}
-
-static void *
-dump_symbol_CB (m4_symbol_table *symtab, const char *name,
- m4_symbol *symbol, void *ptr)
-{
- m4 * context = (m4 *) ptr;
- m4_symbol_value *value = m4_get_symbol_value (symbol);
- int flags = value ? SYMBOL_FLAGS (symbol) : 0;
- m4_module * module = value ? SYMBOL_MODULE (symbol) : NULL;
- const char * module_name = module ? m4_get_module_name (module) : "NONE";
-
- xfprintf (stderr, "%10s: (%d%s) %s=", module_name, flags,
- m4_get_symbol_traced (symbol) ? "!" : "", name);
-
- if (!value)
- fputs ("<!UNDEFINED!>", stderr);
- else if (m4_is_symbol_value_void (value))
- fputs ("<!VOID!>", stderr);
- else
- {
- m4_obstack obs;
- obstack_init (&obs);
- m4__symbol_value_print (context, value, &obs, NULL, false, NULL, NULL,
- true);
- xfprintf (stderr, "%s", (char *) obstack_finish (&obs));
- obstack_free (&obs, NULL);
- }
- fputc ('\n', stderr);
- return NULL;
-}
-#endif /* DEBUG_SYM */