Stage 1: convert m4_symbol_value** into new object.
[m4.git] / m4 / macro.c
blobc4ba1af3e6747cedbf07128580250aa217190887
1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2006, 2007
3 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 /* This file contains the functions that perform the basic argument
22 parsing and macro expansion. */
24 #include <config.h>
26 #include <stdarg.h>
28 #include "m4private.h"
30 #include "intprops.h"
32 static m4_macro_args *collect_arguments (m4 *, const char *, m4_symbol *,
33 m4_obstack *, unsigned int,
34 m4_obstack *);
35 static void expand_macro (m4 *, const char *, m4_symbol *);
36 static void expand_token (m4 *, m4_obstack *, m4__token_type,
37 m4_symbol_value *, int);
38 static bool expand_argument (m4 *, m4_obstack *, m4_symbol_value *,
39 const char *);
40 static void process_macro (m4 *, m4_symbol_value *, m4_obstack *, int,
41 m4_macro_args *);
43 static void trace_prepre (m4 *, const char *, size_t,
44 m4_symbol_value *);
45 static void trace_pre (m4 *, const char *, size_t, int,
46 m4_macro_args *);
47 static void trace_post (m4 *, const char *, size_t, int,
48 m4_macro_args *, m4_input_block *, bool);
50 static void trace_format (m4 *, const char *, ...)
51 M4_GNUC_PRINTF (2, 3);
52 static void trace_header (m4 *, size_t);
53 static void trace_flush (m4 *);
56 /* Current recursion level in expand_macro (). */
57 static size_t expansion_level = 0;
59 /* The number of the current call of expand_macro (). */
60 static size_t macro_call_id = 0;
62 /* The shared stack of collected arguments for macro calls; as each
63 argument is collected, it is finished and its location stored in
64 argv_stack. This stack can be used simultaneously by multiple
65 macro calls, using obstack_regrow to handle partial objects
66 embedded in the stack. */
67 static struct obstack argc_stack;
69 /* The shared stack of pointers to collected arguments for macro
70 calls. This object is never finished; we exploit the fact that
71 obstack_blank is documented to take a negative size to reduce the
72 size again. */
73 static struct obstack argv_stack;
75 /* This function reads all input, and expands each token, one at a time. */
76 void
77 m4_macro_expand_input (m4 *context)
79 m4__token_type type;
80 m4_symbol_value token;
81 int line;
83 obstack_init (&argc_stack);
84 obstack_init (&argv_stack);
86 while ((type = m4__next_token (context, &token, &line, NULL))
87 != M4_TOKEN_EOF)
88 expand_token (context, (m4_obstack *) NULL, type, &token, line);
90 obstack_free (&argc_stack, NULL);
91 obstack_free (&argv_stack, NULL);
95 /* Expand one token, according to its type. Potential macro names
96 (M4_TOKEN_WORD) are looked up in the symbol table, to see if they have a
97 macro definition. If they have, they are expanded as macros, otherwise
98 the text are just copied to the output. */
99 static void
100 expand_token (m4 *context, m4_obstack *obs,
101 m4__token_type type, m4_symbol_value *token, int line)
103 m4_symbol *symbol;
104 const char *text = (m4_is_symbol_value_text (token)
105 ? m4_get_symbol_value_text (token) : NULL);
107 switch (type)
108 { /* TOKSW */
109 case M4_TOKEN_EOF:
110 case M4_TOKEN_MACDEF:
111 break;
113 case M4_TOKEN_OPEN:
114 case M4_TOKEN_COMMA:
115 case M4_TOKEN_CLOSE:
116 case M4_TOKEN_SIMPLE:
117 case M4_TOKEN_STRING:
118 case M4_TOKEN_SPACE:
119 m4_shipout_text (context, obs, text, strlen (text), line);
120 break;
122 case M4_TOKEN_WORD:
124 const char *textp = text;
126 if (m4_has_syntax (M4SYNTAX, to_uchar (*textp), M4_SYNTAX_ESCAPE))
127 ++textp;
129 symbol = m4_symbol_lookup (M4SYMTAB, textp);
130 assert (!symbol || !m4_is_symbol_void (symbol));
131 if (symbol == NULL
132 || (symbol->value->type == M4_SYMBOL_FUNC
133 && BIT_TEST (SYMBOL_FLAGS (symbol), VALUE_BLIND_ARGS_BIT)
134 && !m4__next_token_is_open (context)))
136 m4_shipout_text (context, obs, text, strlen (text), line);
138 else
139 expand_macro (context, textp, symbol);
141 break;
143 default:
144 assert (!"INTERNAL ERROR: bad token type in expand_token ()");
145 abort ();
150 /* This function parses one argument to a macro call. It expects the
151 first left parenthesis or the separating comma to have been read by
152 the caller. It skips leading whitespace, then reads and expands
153 tokens, until it finds a comma or a right parenthesis at the same
154 level of parentheses. It returns a flag indicating whether the
155 argument read is the last for the active macro call. The arguments
156 are built on the obstack OBS, indirectly through expand_token ().
157 Report errors on behalf of CALLER. */
158 static bool
159 expand_argument (m4 *context, m4_obstack *obs, m4_symbol_value *argp,
160 const char *caller)
162 m4__token_type type;
163 m4_symbol_value token;
164 int paren_level = 0;
165 const char *file = m4_get_current_file (context);
166 int line = m4_get_current_line (context);
168 argp->type = M4_SYMBOL_VOID;
170 /* Skip leading white space. */
173 type = m4__next_token (context, &token, NULL, caller);
175 while (type == M4_TOKEN_SPACE);
177 while (1)
179 switch (type)
180 { /* TOKSW */
181 case M4_TOKEN_COMMA:
182 case M4_TOKEN_CLOSE:
183 if (paren_level == 0)
185 /* FIXME - For now, we match the behavior of the branch,
186 except we don't issue warnings. But in the future,
187 we want to allow concatenation of builtins and
188 text. */
189 if (argp->type == M4_SYMBOL_FUNC
190 && obstack_object_size (obs) == 0)
191 return type == M4_TOKEN_COMMA;
192 obstack_1grow (obs, '\0');
193 VALUE_MODULE (argp) = NULL;
194 m4_set_symbol_value_text (argp, obstack_finish (obs));
195 return type == M4_TOKEN_COMMA;
197 /* fallthru */
198 case M4_TOKEN_OPEN:
199 case M4_TOKEN_SIMPLE:
200 if (type == M4_TOKEN_OPEN)
201 paren_level++;
202 else if (type == M4_TOKEN_CLOSE)
203 paren_level--;
204 expand_token (context, obs, type, &token, line);
205 break;
207 case M4_TOKEN_EOF:
208 m4_error_at_line (context, EXIT_FAILURE, 0, file, line, caller,
209 _("end of file in argument list"));
210 break;
212 case M4_TOKEN_WORD:
213 case M4_TOKEN_SPACE:
214 case M4_TOKEN_STRING:
215 expand_token (context, obs, type, &token, line);
216 break;
218 case M4_TOKEN_MACDEF:
219 if (argp->type == M4_SYMBOL_VOID && obstack_object_size (obs) == 0)
220 m4_symbol_value_copy (argp, &token);
221 else
222 argp->type = M4_SYMBOL_TEXT;
223 break;
225 default:
226 assert (!"INTERNAL ERROR: bad token type in expand_argument ()");
227 abort ();
230 type = m4__next_token (context, &token, NULL, caller);
235 /* The macro expansion is handled by expand_macro (). It parses the
236 arguments, using collect_arguments (), and builds a table of pointers to
237 the arguments. The arguments themselves are stored on a local obstack.
238 Expand_macro () uses call_macro () to do the call of the macro.
240 Expand_macro () is potentially recursive, since it calls expand_argument
241 (), which might call expand_token (), which might call expand_macro ().
243 NAME points to storage on the token stack, so it is only valid
244 until a call to collect_arguments parses more tokens. SYMBOL is
245 the result of the symbol table lookup on NAME. */
246 static void
247 expand_macro (m4 *context, const char *name, m4_symbol *symbol)
249 char *argc_base = NULL; /* Base of argc_stack on entry. */
250 unsigned int argc_size; /* Size of argc_stack on entry. */
251 unsigned int argv_size; /* Size of argv_stack on entry. */
252 m4_macro_args *argv;
253 int argc;
254 m4_obstack *expansion;
255 m4_input_block *expanded;
256 bool traced;
257 bool trace_expansion = false;
258 size_t my_call_id;
259 m4_symbol_value *value;
261 /* Report errors at the location where the open parenthesis (if any)
262 was found, but after expansion, restore global state back to the
263 location of the close parenthesis. This is safe since we
264 guarantee that macro expansion does not alter the state of
265 current_file/current_line (dnl, include, and sinclude are special
266 cased in the input engine to ensure this fact). */
267 const char *loc_open_file = m4_get_current_file (context);
268 int loc_open_line = m4_get_current_line (context);
269 const char *loc_close_file;
270 int loc_close_line;
272 /* Grab the current value of this macro, because it may change while
273 collecting arguments. Likewise, grab any state needed during
274 tracing. */
275 value = m4_get_symbol_value (symbol);
276 traced = (m4_is_debug_bit (context, M4_DEBUG_TRACE_ALL)
277 || m4_get_symbol_traced (symbol));
278 if (traced)
279 trace_expansion = m4_is_debug_bit (context, M4_DEBUG_TRACE_EXPANSION);
281 /* Prepare for macro expansion. */
282 VALUE_PENDING (value)++;
283 expansion_level++;
284 if (m4_get_nesting_limit_opt (context) > 0
285 && expansion_level > m4_get_nesting_limit_opt (context))
286 m4_error (context, EXIT_FAILURE, 0, NULL, _("\
287 recursion limit of %zu exceeded, use -L<N> to change it"),
288 m4_get_nesting_limit_opt (context));
290 macro_call_id++;
291 my_call_id = macro_call_id;
293 argc_size = obstack_object_size (&argc_stack);
294 argv_size = obstack_object_size (&argv_stack);
295 if (0 < argc_size)
296 argc_base = obstack_finish (&argc_stack);
298 if (traced && m4_is_debug_bit (context, M4_DEBUG_TRACE_CALL))
299 trace_prepre (context, name, my_call_id, value);
301 argv = collect_arguments (context, name, symbol, &argv_stack, argv_size,
302 &argc_stack);
303 argc = argv->argc;
304 /* Calling collect_arguments invalidated name, but we copied it as
305 argv[0]. */
306 name = argv->argv0;
308 loc_close_file = m4_get_current_file (context);
309 loc_close_line = m4_get_current_line (context);
310 m4_set_current_file (context, loc_open_file);
311 m4_set_current_line (context, loc_open_line);
313 if (traced)
314 trace_pre (context, name, my_call_id, argc, argv);
316 expansion = m4_push_string_init (context);
317 m4_macro_call (context, value, expansion, argc, argv);
318 expanded = m4_push_string_finish ();
320 if (traced)
321 trace_post (context, name, my_call_id, argc, argv, expanded,
322 trace_expansion);
324 m4_set_current_file (context, loc_close_file);
325 m4_set_current_line (context, loc_close_line);
327 --expansion_level;
328 --VALUE_PENDING (value);
329 if (BIT_TEST (VALUE_FLAGS (value), VALUE_DELETED_BIT))
330 m4_symbol_value_delete (value);
332 /* TODO - pay attention to argv->inuse. */
333 if (0 < argc_size)
334 obstack_regrow (&argc_stack, argc_base, argc_size);
335 else
336 obstack_free (&argc_stack, (void *) name);
337 obstack_blank (&argv_stack, argv_size - obstack_object_size (&argv_stack));
340 /* Collect all the arguments to a call of the macro SYMBOL (called
341 NAME). The arguments are stored on the obstack ARGUMENTS and a
342 table of pointers to the arguments on the obstack ARGPTR. ARGPTR
343 is an incomplete object, currently occupying ARGV_BASE bytes.
344 Return the object describing all of the macro arguments. */
345 static m4_macro_args *
346 collect_arguments (m4 *context, const char *name, m4_symbol *symbol,
347 m4_obstack *argptr, unsigned argv_base,
348 m4_obstack *arguments)
350 m4_symbol_value token;
351 m4_symbol_value *tokenp;
352 bool more_args;
353 bool groks_macro_args;
354 m4_macro_args args;
355 m4_macro_args *argv;
357 groks_macro_args = BIT_TEST (SYMBOL_FLAGS (symbol), VALUE_MACRO_ARGS_BIT);
359 args.argc = 1;
360 args.inuse = false;
361 args.argv0 = (char *) obstack_copy0 (arguments, name, strlen (name));
362 args.arraylen = 0;
363 obstack_grow (argptr, &args, offsetof (m4_macro_args, array));
364 name = args.argv0;
366 if (m4__next_token_is_open (context))
368 m4__next_token (context, &token, NULL, name); /* gobble parenthesis */
371 more_args = expand_argument (context, arguments, &token, name);
373 if (!groks_macro_args && m4_is_symbol_value_func (&token))
375 VALUE_MODULE (&token) = NULL;
376 m4_set_symbol_value_text (&token, "");
378 tokenp = (m4_symbol_value *) obstack_copy (arguments, &token,
379 sizeof token);
380 obstack_ptr_grow (argptr, tokenp);
381 args.arraylen++;
382 args.argc++;
384 while (more_args);
386 argv = (m4_macro_args *) ((char *) obstack_base (argptr) + argv_base);
387 argv->argc = args.argc;
388 argv->arraylen = args.arraylen;
389 return argv;
393 /* The actual call of a macro is handled by m4_macro_call ().
394 m4_macro_call () is passed a SYMBOL, whose type is used to
395 call either a builtin function, or the user macro expansion
396 function process_macro (). There are ARGC arguments to
397 the call, stored in the ARGV table. The expansion is left on
398 the obstack EXPANSION. Macro tracing is also handled here. */
399 void
400 m4_macro_call (m4 *context, m4_symbol_value *value, m4_obstack *expansion,
401 int argc, m4_macro_args *argv)
403 if (m4_bad_argc (context, argc, argv->argv0,
404 VALUE_MIN_ARGS (value), VALUE_MAX_ARGS (value),
405 BIT_TEST (VALUE_FLAGS (value),
406 VALUE_SIDE_EFFECT_ARGS_BIT)))
407 return;
408 if (m4_is_symbol_value_text (value))
409 process_macro (context, value, expansion, argc, argv);
410 else if (m4_is_symbol_value_func (value))
411 m4_get_symbol_value_func (value) (context, expansion, argc, argv);
412 else if (m4_is_symbol_value_placeholder (value))
413 m4_warn (context, 0, M4ARG (0),
414 _("builtin `%s' requested by frozen file not found"),
415 m4_get_symbol_value_placeholder (value));
416 else
418 assert (!"INTERNAL ERROR: bad symbol type in m4_macro_call ()");
419 abort ();
423 /* This function handles all expansion of user defined and predefined
424 macros. It is called with an obstack OBS, where the macros expansion
425 will be placed, as an unfinished object. SYMBOL points to the macro
426 definition, giving the expansion text. ARGC and ARGV are the arguments,
427 as usual. */
428 static void
429 process_macro (m4 *context, m4_symbol_value *value, m4_obstack *obs,
430 int argc, m4_macro_args *argv)
432 const char *text;
433 int i;
435 for (text = m4_get_symbol_value_text (value); *text != '\0';)
437 char ch;
439 if (!m4_has_syntax (M4SYNTAX, to_uchar (*text), M4_SYNTAX_DOLLAR))
441 obstack_1grow (obs, *text);
442 text++;
443 continue;
445 ch = *text++;
446 switch (*text)
448 case '0': case '1': case '2': case '3': case '4':
449 case '5': case '6': case '7': case '8': case '9':
450 /* FIXME - multidigit arguments should convert over to ${10}
451 syntax instead of $10; see
452 http://lists.gnu.org/archive/html/m4-discuss/2006-08/msg00028.html
453 for more discussion. */
454 if (m4_get_posixly_correct_opt (context) || !isdigit(text[1]))
456 i = *text++ - '0';
458 else
460 char *endp;
461 i = (int) strtol (text, &endp, 10);
462 text = endp;
464 if (i < argc)
465 m4_shipout_string (context, obs, M4ARG (i), 0, false);
466 break;
468 case '#': /* number of arguments */
469 m4_shipout_int (obs, argc - 1);
470 text++;
471 break;
473 case '*': /* all arguments */
474 case '@': /* ... same, but quoted */
475 m4_dump_args (context, obs, 1, argv, ",", *text == '@');
476 text++;
477 break;
479 default:
480 if (m4_get_posixly_correct_opt (context)
481 || !VALUE_ARG_SIGNATURE (value))
483 obstack_1grow (obs, ch);
485 else
487 size_t len = 0;
488 const char *endp;
489 const char *key;
491 for (endp = ++text;
492 *endp && m4_has_syntax (M4SYNTAX, to_uchar (*endp),
493 (M4_SYNTAX_OTHER | M4_SYNTAX_ALPHA
494 | M4_SYNTAX_NUM));
495 ++endp)
497 ++len;
499 key = xstrndup (text, len);
501 if (*endp)
503 struct m4_symbol_arg **arg
504 = (struct m4_symbol_arg **)
505 m4_hash_lookup (VALUE_ARG_SIGNATURE (value), key);
507 if (arg)
509 i = SYMBOL_ARG_INDEX (*arg);
511 if (i < argc)
512 m4_shipout_string (context, obs, M4ARG (i), 0, false);
513 else
515 assert (!"INTERNAL ERROR: out of range reference");
516 abort ();
520 else
522 m4_error (context, 0, 0, M4ARG (0),
523 _("unterminated parameter reference: %s"),
524 key);
527 text = *endp ? 1 + endp : endp;
529 free ((char *) key);
530 break;
532 break;
539 /* The rest of this file contains the functions for macro tracing output.
540 All tracing output for a macro call is collected on an obstack TRACE,
541 and printed whenever the line is complete. This prevents tracing
542 output from interfering with other debug messages generated by the
543 various builtins. */
545 /* Tracing output is formatted here, by a simplified printf-to-obstack
546 function trace_format (). Understands only %s, %d, %zu (size_t
547 value). */
548 static void
549 trace_format (m4 *context, const char *fmt, ...)
551 va_list args;
552 char ch;
553 const char *s;
555 va_start (args, fmt);
557 while (true)
559 while ((ch = *fmt++) != '\0' && ch != '%')
560 obstack_1grow (&context->trace_messages, ch);
562 if (ch == '\0')
563 break;
565 switch (*fmt++)
567 case 's':
568 s = va_arg (args, const char *);
569 break;
571 case 'd':
573 int d = va_arg (args, int);
574 char nbuf[INT_BUFSIZE_BOUND (int)];
576 sprintf (nbuf, "%d", d);
577 s = nbuf;
579 break;
581 case 'z':
582 ch = *fmt++;
583 assert (ch == 'u');
585 size_t z = va_arg (args, size_t);
586 char nbuf[INT_BUFSIZE_BOUND (size_t)];
588 sprintf (nbuf, "%zu", z);
589 s = nbuf;
591 break;
593 default:
594 abort ();
595 break;
598 obstack_grow (&context->trace_messages, s, strlen (s));
601 va_end (args);
604 /* Format the standard header attached to all tracing output lines. */
605 static void
606 trace_header (m4 *context, size_t id)
608 trace_format (context, "m4trace:");
609 if (m4_get_current_line (context))
611 if (m4_is_debug_bit (context, M4_DEBUG_TRACE_FILE))
612 trace_format (context, "%s:", m4_get_current_file (context));
613 if (m4_is_debug_bit (context, M4_DEBUG_TRACE_LINE))
614 trace_format (context, "%d:", m4_get_current_line (context));
616 trace_format (context, " -%zu- ", expansion_level);
617 if (m4_is_debug_bit (context, M4_DEBUG_TRACE_CALLID))
618 trace_format (context, "id %zu: ", id);
621 /* Print current tracing line, and clear the obstack. */
622 static void
623 trace_flush (m4 *context)
625 char *line;
627 obstack_1grow (&context->trace_messages, '\n');
628 obstack_1grow (&context->trace_messages, '\0');
629 line = obstack_finish (&context->trace_messages);
630 if (m4_get_debug_file (context))
631 fputs (line, m4_get_debug_file (context));
632 obstack_free (&context->trace_messages, line);
635 /* Do pre-argument-collction tracing for macro NAME. Used from
636 expand_macro (). */
637 static void
638 trace_prepre (m4 *context, const char *name, size_t id, m4_symbol_value *value)
640 bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
641 const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
642 const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
643 size_t arg_length = m4_get_max_debug_arg_length_opt (context);
644 bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
646 trace_header (context, id);
647 trace_format (context, "%s ... = ", name);
648 m4_symbol_value_print (value, &context->trace_messages,
649 quote, lquote, rquote, arg_length, module);
650 trace_flush (context);
653 /* Format the parts of a trace line, that can be made before the macro is
654 actually expanded. Used from expand_macro (). */
655 static void
656 trace_pre (m4 *context, const char *name, size_t id,
657 int argc, m4_macro_args *argv)
659 int i;
661 trace_header (context, id);
662 trace_format (context, "%s", name);
664 if ((argc > 1) && m4_is_debug_bit (context, M4_DEBUG_TRACE_ARGS))
666 bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
667 const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
668 const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
669 size_t arg_length = m4_get_max_debug_arg_length_opt (context);
670 bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
672 trace_format (context, "(");
673 for (i = 1; i < argc; i++)
675 if (i != 1)
676 trace_format (context, ", ");
678 m4_symbol_value_print (argv->array[i - 1], &context->trace_messages,
679 quote, lquote, rquote, arg_length, module);
681 trace_format (context, ")");
685 /* Format the final part of a trace line and print it all. Used from
686 expand_macro (). */
687 static void
688 trace_post (m4 *context, const char *name, size_t id,
689 int argc, m4_macro_args *argv, m4_input_block *expanded,
690 bool trace_expansion)
692 if (trace_expansion)
694 trace_format (context, " -> ");
695 m4_input_print (context, &context->trace_messages, expanded);
698 trace_flush (context);