1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2005, 2006,
3 2007, 2008 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 *);
55 static void symbol_popval (m4_symbol
*symbol
);
56 static void * symbol_destroy_CB (m4_symbol_table
*symtab
,
58 m4_symbol
*symbol
, void *ignored
);
59 static void * arg_destroy_CB (m4_hash
*hash
, const void *name
,
60 void *arg
, void *ignored
);
61 static void * arg_copy_CB (m4_hash
*src
, const void *name
,
62 void *arg
, m4_hash
*dest
);
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
= 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
)
111 result
= func (symtab
, (const char *) m4_get_hash_iterator_key (place
),
116 m4_free_hash_iterator (symtab
->table
, place
);
124 /* Ensure that NAME exists in the table, creating an entry if needed. */
126 symtab_fetch (m4_symbol_table
*symtab
, const char *name
)
134 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, name
);
141 symbol
= xzalloc (sizeof *symbol
);
142 m4_hash_insert (symtab
->table
, xstrdup (name
), symbol
);
148 /* Remove every symbol that references the given module from
151 m4__symtab_remove_module_references (m4_symbol_table
*symtab
,
154 m4_hash_iterator
*place
= 0;
158 /* Traverse each symbol name in the hash table. */
159 while ((place
= m4_get_hash_iterator_next (symtab
->table
, place
)))
161 m4_symbol
*symbol
= (m4_symbol
*) m4_get_hash_iterator_value (place
);
162 m4_symbol_value
*data
= m4_get_symbol_value (symbol
);
164 /* For symbols that have token data... */
167 /* Purge any shadowed references. */
168 while (VALUE_NEXT (data
))
170 m4_symbol_value
*next
= VALUE_NEXT (data
);
172 if (VALUE_MODULE (next
) == module
)
174 VALUE_NEXT (data
) = VALUE_NEXT (next
);
176 assert (next
->type
!= M4_SYMBOL_PLACEHOLDER
);
177 m4_symbol_value_delete (next
);
183 /* Purge the live reference if necessary. */
184 if (SYMBOL_MODULE (symbol
) == module
)
185 m4_symbol_popdef (symtab
, m4_get_hash_iterator_key (place
));
191 /* This callback is used exclusively by m4_symtab_delete(), to cleanup
192 the memory used by the symbol table. As such, the trace bit is reset
193 on every symbol so that m4_symbol_popdef() doesn't try to preserve
196 symbol_destroy_CB (m4_symbol_table
*symtab
, const char *name
,
197 m4_symbol
*symbol
, void *ignored
)
199 char *key
= xstrdup ((char *) name
);
201 symbol
->traced
= false;
203 while (key
&& m4_hash_lookup (symtab
->table
, key
))
204 m4_symbol_popdef (symtab
, key
);
213 /* -- SYMBOL MANAGEMENT --
215 The following functions manipulate individual symbols within
216 an existing table. */
218 /* Return the symbol associated to NAME, or else NULL. */
220 m4_symbol_lookup (m4_symbol_table
*symtab
, const char *name
)
222 m4_symbol
**psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, name
);
224 /* If just searching, return status of search -- if only an empty
225 struct is returned, that is treated as a failed lookup. */
226 return (psymbol
&& m4_get_symbol_value (*psymbol
)) ? *psymbol
: NULL
;
230 /* Insert NAME into the symbol table. If there is already a symbol
231 associated with NAME, push the new VALUE on top of the value stack
232 for this symbol. Otherwise create a new association. */
234 m4_symbol_pushdef (m4_symbol_table
*symtab
, const char *name
,
235 m4_symbol_value
*value
)
243 symbol
= symtab_fetch (symtab
, name
);
244 VALUE_NEXT (value
) = m4_get_symbol_value (symbol
);
245 symbol
->value
= value
;
247 assert (m4_get_symbol_value (symbol
));
252 /* Return the symbol associated with NAME in the symbol table, creating
253 a new symbol if necessary. In either case set the symbol's VALUE. */
255 m4_symbol_define (m4_symbol_table
*symtab
,
256 const char *name
, m4_symbol_value
*value
)
264 symbol
= symtab_fetch (symtab
, name
);
265 if (m4_get_symbol_value (symbol
))
266 symbol_popval (symbol
);
268 VALUE_NEXT (value
) = m4_get_symbol_value (symbol
);
269 symbol
->value
= value
;
271 assert (m4_get_symbol_value (symbol
));
276 /* Pop the topmost value stack entry from the symbol associated with
277 NAME, deleting it from the table entirely if that was the last
278 remaining value in the stack. */
280 m4_symbol_popdef (m4_symbol_table
*symtab
, const char *name
)
282 m4_symbol
**psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, name
);
287 symbol_popval (*psymbol
);
289 /* Only remove the hash table entry if the last value in the
290 symbol value stack was successfully removed. */
291 if (!m4_get_symbol_value (*psymbol
) && !m4_get_symbol_traced (*psymbol
))
294 free (m4_hash_remove (symtab
->table
, name
));
298 /* Remove the top-most value from SYMBOL's stack. */
300 symbol_popval (m4_symbol
*symbol
)
302 m4_symbol_value
*stale
;
306 stale
= m4_get_symbol_value (symbol
);
310 symbol
->value
= VALUE_NEXT (stale
);
311 m4_symbol_value_delete (stale
);
315 /* Remove VALUE from the symbol table, and mark it as deleted. If no
316 expansions are pending, reclaim its resources. */
318 m4_symbol_value_delete (m4_symbol_value
*value
)
320 if (VALUE_PENDING (value
) > 0)
321 BIT_SET (VALUE_FLAGS (value
), VALUE_DELETED_BIT
);
324 if (VALUE_ARG_SIGNATURE (value
))
326 m4_hash_apply (VALUE_ARG_SIGNATURE (value
), arg_destroy_CB
, NULL
);
327 m4_hash_delete (VALUE_ARG_SIGNATURE (value
));
332 free ((char *) m4_get_symbol_value_text (value
));
334 case M4_SYMBOL_PLACEHOLDER
:
335 free ((char *) m4_get_symbol_value_placeholder (value
));
341 assert (!"m4_symbol_value_delete");
349 m4_symbol_rename (m4_symbol_table
*symtab
, const char *name
,
352 m4_symbol
*symbol
= NULL
;
359 /* Use a low level hash fetch, so we can save the symbol value when
360 removing the symbol name from the symbol table. */
361 psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
, name
);
367 /* Remove the old name from the symbol table. */
368 free (m4_hash_remove (symtab
->table
, name
));
369 assert (!m4_hash_lookup (symtab
->table
, name
));
371 m4_hash_insert (symtab
->table
, xstrdup (newname
), *psymbol
);
374 NAME does not name a symbol in symtab->table! */
380 /* Callback used by m4_symbol_popdef () to release the memory used
381 by values in the arg_signature hash. */
383 arg_destroy_CB (m4_hash
*hash
, const void *name
, void *arg
, void *ignored
)
385 struct m4_symbol_arg
*token_arg
= (struct m4_symbol_arg
*) arg
;
390 if (SYMBOL_ARG_DEFAULT (token_arg
))
391 DELETE (SYMBOL_ARG_DEFAULT (token_arg
));
393 free (m4_hash_remove (hash
, (const char *) name
));
399 m4_symbol_value_copy (m4_symbol_value
*dest
, m4_symbol_value
*src
)
401 m4_symbol_value
*next
;
409 free ((char *) m4_get_symbol_value_text (dest
));
411 case M4_SYMBOL_PLACEHOLDER
:
412 free ((char *) m4_get_symbol_value_placeholder (dest
));
418 assert (!"m4_symbol_value_delete");
422 if (VALUE_ARG_SIGNATURE (dest
))
424 m4_hash_apply (VALUE_ARG_SIGNATURE (dest
), arg_destroy_CB
, NULL
);
425 m4_hash_delete (VALUE_ARG_SIGNATURE (dest
));
428 /* Copy the value contents over, being careful to preserve
430 next
= VALUE_NEXT (dest
);
431 memcpy (dest
, src
, sizeof (m4_symbol_value
));
432 VALUE_NEXT (dest
) = next
;
434 /* Caller is supposed to free text token strings, so we have to
435 copy the string not just its address in that case. */
440 size_t len
= m4_get_symbol_value_len (src
);
441 unsigned int age
= m4_get_symbol_value_quote_age (src
);
442 m4_set_symbol_value_text (dest
,
443 xmemdup (m4_get_symbol_value_text (src
),
448 /* Nothing further to do. */
450 case M4_SYMBOL_PLACEHOLDER
:
451 m4_set_symbol_value_placeholder (dest
,
452 xstrdup (m4_get_symbol_value_placeholder
457 m4__symbol_chain
*chain
= src
->u
.u_c
.chain
;
463 /* TODO for now, only text links are supported. */
464 assert (chain
->type
== M4__CHAIN_STR
);
465 len
+= chain
->u
.u_s
.len
;
468 p
= str
= xcharalloc (len
+ 1);
469 chain
= src
->u
.u_c
.chain
;
472 memcpy (p
, chain
->u
.u_s
.str
, chain
->u
.u_s
.len
);
473 p
+= chain
->u
.u_s
.len
;
477 m4_set_symbol_value_text (dest
, str
, len
, 0);
481 assert (!"m4_symbol_value_copy");
484 if (VALUE_ARG_SIGNATURE (src
))
485 VALUE_ARG_SIGNATURE (dest
) = m4_hash_dup (VALUE_ARG_SIGNATURE (src
),
490 arg_copy_CB (m4_hash
*src
, const void *name
, void *arg
, m4_hash
*dest
)
492 m4_hash_insert ((m4_hash
*) dest
, name
, arg
);
496 /* Set the tracing status of the symbol NAME to TRACED. This takes a
497 name, rather than a symbol, since we hide macros that are traced
498 but otherwise undefined from normal lookups, but still can affect
499 their tracing status. Return true iff the macro was previously
502 m4_set_symbol_name_traced (m4_symbol_table
*symtab
, const char *name
,
512 symbol
= symtab_fetch (symtab
, name
);
515 m4_symbol
**psymbol
= (m4_symbol
**) m4_hash_lookup (symtab
->table
,
522 result
= symbol
->traced
;
523 symbol
->traced
= traced
;
524 if (!traced
&& !m4_get_symbol_value (symbol
))
526 /* Free an undefined entry once it is no longer traced. */
529 free (m4_hash_remove (symtab
->table
, name
));
535 /* Grow OBS with a text representation of VALUE. If QUOTES, then use
536 it to surround a text definition. If MAXLEN, then truncate text
537 definitions to *MAXLEN, and adjust by how many characters are
538 printed. If MODULE, then include which module defined a builtin.
539 Return true if the output was truncated. QUOTES and MODULE do not
540 count against the truncation length. */
542 m4_symbol_value_print (m4_symbol_value
*value
, m4_obstack
*obs
,
543 const m4_string_pair
*quotes
, size_t *maxlen
,
547 const m4_builtin
*bp
;
548 m4__symbol_chain
*chain
;
549 size_t len
= maxlen
? *maxlen
: SIZE_MAX
;
555 if (m4_shipout_string_trunc (obs
, m4_get_symbol_value_text (value
),
556 m4_get_symbol_value_len (value
), quotes
,
561 bp
= m4_get_symbol_value_builtin (value
);
562 obstack_1grow (obs
, '<');
563 obstack_grow (obs
, bp
->name
, strlen (bp
->name
));
564 obstack_1grow (obs
, '>');
566 case M4_SYMBOL_PLACEHOLDER
:
567 text
= m4_get_symbol_value_placeholder (value
);
568 obstack_1grow (obs
, '<');
569 obstack_1grow (obs
, '<');
570 obstack_grow (obs
, text
, strlen (text
));
571 obstack_1grow (obs
, '>');
572 obstack_1grow (obs
, '>');
575 chain
= value
->u
.u_c
.chain
;
577 obstack_grow (obs
, quotes
->str1
, quotes
->len1
);
578 while (chain
&& !result
)
583 if (m4_shipout_string_trunc (obs
, chain
->u
.u_s
.str
,
584 chain
->u
.u_s
.len
, NULL
, &len
))
588 if (m4_arg_print (obs
, chain
->u
.u_a
.argv
, chain
->u
.u_a
.index
,
589 chain
->u
.u_a
.quotes
, &len
, module
))
593 assert (!"m4_symbol_value_print");
599 obstack_grow (obs
, quotes
->str2
, quotes
->len2
);
603 assert (!"m4_symbol_value_print");
607 if (module
&& VALUE_MODULE (value
))
609 obstack_1grow (obs
, '{');
610 text
= m4_get_module_name (VALUE_MODULE (value
));
611 obstack_grow (obs
, text
, strlen (text
));
612 obstack_1grow (obs
, '}');
619 /* Grow OBS with a text representation of SYMBOL. If QUOTES, then use
620 it to surround each text definition. If STACK, then append all
621 pushdef'd values, rather than just the top. If ARG_LENGTH is less
622 than SIZE_MAX, then truncate text definitions to that length. If
623 MODULE, then include which module defined a builtin. QUOTES and
624 MODULE do not count toward truncation. */
626 m4_symbol_print (m4_symbol
*symbol
, m4_obstack
*obs
,
627 const m4_string_pair
*quotes
, bool stack
, size_t arg_length
,
630 m4_symbol_value
*value
;
631 size_t len
= arg_length
;
636 value
= m4_get_symbol_value (symbol
);
637 m4_symbol_value_print (value
, obs
, quotes
, &len
, module
);
640 value
= VALUE_NEXT (value
);
643 obstack_1grow (obs
, ',');
644 obstack_1grow (obs
, ' ');
646 m4_symbol_value_print (value
, obs
, quotes
, &len
, module
);
647 value
= VALUE_NEXT (value
);
653 /* Define these functions at the end, so that calls in the file use the
654 faster macro version from m4module.h. */
656 /* Pop all values from the symbol associated with NAME. */
657 #undef m4_symbol_delete
659 m4_symbol_delete (m4_symbol_table
*symtab
, const char *name
)
661 while (m4_symbol_lookup (symtab
, name
))
662 m4_symbol_popdef (symtab
, name
);
665 #undef m4_get_symbol_traced
667 m4_get_symbol_traced (m4_symbol
*symbol
)
670 return symbol
->traced
;
673 #undef m4_symbol_value_create
675 m4_symbol_value_create (void)
677 m4_symbol_value
*value
= xzalloc (sizeof (m4_symbol_value
));
678 VALUE_MAX_ARGS (value
) = SIZE_MAX
;
682 #undef m4_symbol_value_groks_macro
684 m4_symbol_value_groks_macro (m4_symbol_value
*value
)
687 return BIT_TEST (value
->flags
, VALUE_MACRO_ARGS_BIT
);
690 #undef m4_get_symbol_value
692 m4_get_symbol_value (m4_symbol
*symbol
)
695 return symbol
->value
;
698 #undef m4_is_symbol_value_text
700 m4_is_symbol_value_text (m4_symbol_value
*value
)
703 return (value
->type
== M4_SYMBOL_TEXT
);
706 #undef m4_is_symbol_value_func
708 m4_is_symbol_value_func (m4_symbol_value
*value
)
711 return (value
->type
== M4_SYMBOL_FUNC
);
714 #undef m4_is_symbol_value_placeholder
716 m4_is_symbol_value_placeholder (m4_symbol_value
*value
)
719 return (value
->type
== M4_SYMBOL_PLACEHOLDER
);
722 #undef m4_is_symbol_value_void
724 m4_is_symbol_value_void (m4_symbol_value
*value
)
727 return (value
->type
== M4_SYMBOL_VOID
);
730 #undef m4_get_symbol_value_text
732 m4_get_symbol_value_text (m4_symbol_value
*value
)
734 assert (value
&& value
->type
== M4_SYMBOL_TEXT
);
735 return value
->u
.u_t
.text
;
738 #undef m4_get_symbol_value_len
740 m4_get_symbol_value_len (m4_symbol_value
*value
)
742 assert (value
&& value
->type
== M4_SYMBOL_TEXT
);
743 return value
->u
.u_t
.len
;
746 #undef m4_get_symbol_value_quote_age
748 m4_get_symbol_value_quote_age (m4_symbol_value
*value
)
750 assert (value
&& value
->type
== M4_SYMBOL_TEXT
);
751 return value
->u
.u_t
.quote_age
;
754 #undef m4_get_symbol_value_func
756 m4_get_symbol_value_func (m4_symbol_value
*value
)
758 assert (value
&& value
->type
== M4_SYMBOL_FUNC
);
759 return value
->u
.builtin
->func
;
762 #undef m4_get_symbol_value_builtin
764 m4_get_symbol_value_builtin (m4_symbol_value
*value
)
766 assert (value
&& value
->type
== M4_SYMBOL_FUNC
);
767 return value
->u
.builtin
;
770 #undef m4_get_symbol_value_placeholder
772 m4_get_symbol_value_placeholder (m4_symbol_value
*value
)
774 assert (value
&& value
->type
== M4_SYMBOL_PLACEHOLDER
);
775 return value
->u
.u_t
.text
;
778 #undef m4_set_symbol_value_text
780 m4_set_symbol_value_text (m4_symbol_value
*value
, const char *text
, size_t len
,
781 unsigned int quote_age
)
783 assert (value
&& text
);
784 /* In practice, it is easier to debug when we guarantee a
785 terminating NUL, even when there are embedded NULs. */
788 value
->type
= M4_SYMBOL_TEXT
;
789 value
->u
.u_t
.text
= text
;
790 value
->u
.u_t
.len
= len
;
791 value
->u
.u_t
.quote_age
= quote_age
;
794 #undef m4_set_symbol_value_builtin
796 m4_set_symbol_value_builtin (m4_symbol_value
*value
, const m4_builtin
*builtin
)
801 value
->type
= M4_SYMBOL_FUNC
;
802 value
->u
.builtin
= builtin
;
805 #undef m4_set_symbol_value_placeholder
807 m4_set_symbol_value_placeholder (m4_symbol_value
*value
, const char *text
)
812 value
->type
= M4_SYMBOL_PLACEHOLDER
;
813 value
->u
.u_t
.text
= text
;
814 value
->u
.u_t
.len
= SIZE_MAX
; /* len is not tracked for placeholders. */
820 static void *dump_symbol_CB (m4_symbol_table
*symtab
, const char *name
,
821 m4_symbol
*symbol
, void *userdata
);
822 static M4_GNUC_UNUSED
void *
823 symtab_dump (m4_symbol_table
*symtab
)
825 return m4_symtab_apply (symtab
, true, dump_symbol_CB
, NULL
);
829 dump_symbol_CB (m4_symbol_table
*symtab
, const char *name
,
830 m4_symbol
*symbol
, void *ignored
)
832 m4_symbol_value
*value
= m4_get_symbol_value (symbol
);
833 int flags
= value
? SYMBOL_FLAGS (symbol
) : 0;
834 m4_module
* module
= value
? SYMBOL_MODULE (symbol
) : NULL
;
835 const char * module_name
= module
? m4_get_module_name (module
) : "NONE";
837 xfprintf (stderr
, "%10s: (%d%s) %s=", module_name
, flags
,
838 m4_get_symbol_traced (symbol
) ? "!" : "", name
);
841 fputs ("<!UNDEFINED!>", stderr
);
842 else if (m4_is_symbol_value_void (value
))
843 fputs ("<!VOID!>", stderr
);
848 m4_symbol_value_print (value
, &obs
, false, NULL
, NULL
, SIZE_MAX
, true);
849 xfprintf (stderr
, "%s", (char *) obstack_finish (&obs
));
850 obstack_free (&obs
, NULL
);
852 fputc ('\n', stderr
);
855 #endif /* DEBUG_SYM */