1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989-1994, 2006-2007, 2009-2014, 2016-2017, 2020-2021
4 Free Software Foundation, Inc.
6 This file is part of GNU M4.
8 GNU M4 is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU M4 is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>.
22 /* This file contains the functions, that performs the basic argument
23 parsing and macro expansion. */
27 static void expand_macro (symbol *);
28 static void expand_token (struct obstack *, token_type, token_data *, int);
30 /* Current recursion level in expand_macro (). */
31 int expansion_level = 0;
33 /* The number of the current call of expand_macro (). */
34 static int macro_call_id = 0;
36 /* The shared stack of collected arguments for macro calls; as each
37 argument is collected, it is finished and its location stored in
38 argv_stack. Normally, this stack can be used simultaneously by
39 multiple macro calls; the exception is when an outer macro has
40 generated some text, then calls a nested macro, in which case the
41 nested macro must use a local stack to leave the unfinished text
42 alone. Too bad obstack.h does not provide an easy way to reopen a
43 finished object for further growth, but in practice this does not
45 static struct obstack argc_stack;
47 /* The shared stack of pointers to collected arguments for macro
48 calls. This object is never finished; we exploit the fact that
49 obstack_blank_fast is documented to take a negative size to reduce
51 static struct obstack argv_stack;
53 /*----------------------------------------------------------------------.
54 | This function read all input, and expands each token, one at a time. |
55 `----------------------------------------------------------------------*/
64 obstack_init (&argc_stack);
65 obstack_init (&argv_stack);
67 while ((t = next_token (&td, &line)) != TOKEN_EOF)
68 expand_token ((struct obstack *) NULL, t, &td, line);
70 obstack_free (&argc_stack, NULL);
71 obstack_free (&argv_stack, NULL);
75 /*----------------------------------------------------------------.
76 | Expand one token, according to its type. Potential macro names |
77 | (TOKEN_WORD) are looked up in the symbol table, to see if they |
78 | have a macro definition. If they have, they are expanded as |
79 | macros, otherwise the text is just copied to the output. |
80 `----------------------------------------------------------------*/
83 expand_token (struct obstack *obs, token_type t, token_data *td, int line)
98 shipout_text (obs, TOKEN_DATA_TEXT (td), strlen (TOKEN_DATA_TEXT (td)),
103 sym = lookup_symbol (TOKEN_DATA_TEXT (td), SYMBOL_LOOKUP);
104 if (sym == NULL || SYMBOL_TYPE (sym) == TOKEN_VOID
105 || (SYMBOL_TYPE (sym) == TOKEN_FUNC
106 && SYMBOL_BLIND_NO_ARGS (sym)
107 && peek_token () != TOKEN_OPEN))
109 #ifdef ENABLE_CHANGEWORD
110 shipout_text (obs, TOKEN_DATA_ORIG_TEXT (td),
111 strlen (TOKEN_DATA_ORIG_TEXT (td)), line);
113 shipout_text (obs, TOKEN_DATA_TEXT (td),
114 strlen (TOKEN_DATA_TEXT (td)), line);
122 M4ERROR ((warning_status, 0,
123 "INTERNAL ERROR: bad token type in expand_token ()"));
129 /*-------------------------------------------------------------------.
130 | This function parses one argument to a macro call. It expects the |
131 | first left parenthesis, or the separating comma, to have been read |
132 | by the caller. It skips leading whitespace, and reads and expands |
133 | tokens, until it finds a comma or an right parenthesis at the same |
134 | level of parentheses. It returns a flag indicating whether the |
135 | argument read is the last for the active macro call. The argument |
136 | is built on the obstack OBS, indirectly through expand_token (). |
137 `-------------------------------------------------------------------*/
140 expand_argument (struct obstack *obs, token_data *argp)
146 const char *file = current_file;
147 int line = current_line;
149 TOKEN_DATA_TYPE (argp) = TOKEN_VOID;
151 /* Skip leading white space. */
154 t = next_token (&td, NULL);
156 while (t == TOKEN_SIMPLE && c_isspace (*TOKEN_DATA_TEXT (&td)));
167 if (paren_level == 0)
169 /* The argument MUST be finished, whether we want it or not. */
170 obstack_1grow (obs, '\0');
171 text = (char *) obstack_finish (obs);
173 if (TOKEN_DATA_TYPE (argp) == TOKEN_VOID)
175 TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
176 TOKEN_DATA_TEXT (argp) = text;
178 return t == TOKEN_COMMA;
183 text = TOKEN_DATA_TEXT (&td);
187 else if (*text == ')')
189 expand_token (obs, t, &td, line);
193 /* current_file changed to "" if we see TOKEN_EOF, use the
194 previous value we stored earlier. */
195 m4_failure_at_line (0, file, line,
196 _("ERROR: end of file in argument list"));
200 expand_token (obs, t, &td, line);
204 if (obstack_object_size (obs) == 0)
206 TOKEN_DATA_TYPE (argp) = TOKEN_FUNC;
207 TOKEN_DATA_FUNC (argp) = TOKEN_DATA_FUNC (&td);
212 M4ERROR ((warning_status, 0,
213 "INTERNAL ERROR: bad token type in expand_argument ()"));
217 t = next_token (&td, NULL);
221 /*-------------------------------------------------------------.
222 | Collect all the arguments to a call of the macro SYM. The |
223 | arguments are stored on the obstack ARGUMENTS and a table of |
224 | pointers to the arguments on the obstack ARGPTR. |
225 `-------------------------------------------------------------*/
228 collect_arguments (symbol *sym, struct obstack *argptr,
229 struct obstack *arguments)
234 bool groks_macro_args = SYMBOL_MACRO_ARGS (sym);
236 TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
237 TOKEN_DATA_TEXT (&td) = SYMBOL_NAME (sym);
238 tdp = (token_data *) obstack_copy (arguments, &td, sizeof td);
239 obstack_ptr_grow (argptr, tdp);
241 if (peek_token () == TOKEN_OPEN)
243 next_token (&td, NULL); /* gobble parenthesis */
246 more_args = expand_argument (arguments, &td);
248 if (!groks_macro_args && TOKEN_DATA_TYPE (&td) == TOKEN_FUNC)
250 TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
251 TOKEN_DATA_TEXT (&td) = (char *) "";
253 tdp = (token_data *) obstack_copy (arguments, &td, sizeof td);
254 obstack_ptr_grow (argptr, tdp);
261 /*-------------------------------------------------------------------.
262 | The actual call of a macro is handled by call_macro (). |
263 | call_macro () is passed a symbol SYM, whose type is used to call |
264 | either a builtin function, or the user macro expansion function |
265 | expand_user_macro () (lives in builtin.c). There are ARGC |
266 | arguments to the call, stored in the ARGV table. The expansion is |
267 | left on the obstack EXPANSION. Macro tracing is also handled |
269 `-------------------------------------------------------------------*/
272 call_macro (symbol *sym, int argc, token_data **argv,
273 struct obstack *expansion)
275 switch (SYMBOL_TYPE (sym))
278 (*SYMBOL_FUNC (sym)) (expansion, argc, argv);
282 expand_user_macro (expansion, sym, argc, argv);
287 M4ERROR ((warning_status, 0,
288 "INTERNAL ERROR: bad symbol type in call_macro ()"));
293 /*-------------------------------------------------------------------.
294 | The macro expansion is handled by expand_macro (). It parses the |
295 | arguments, using collect_arguments (), and builds a table of |
296 | pointers to the arguments. The arguments themselves are stored on |
297 | a local obstack. Expand_macro () uses call_macro () to do the |
298 | call of the macro. |
300 | Expand_macro () is potentially recursive, since it calls |
301 | expand_argument (), which might call expand_token (), which might |
302 | call expand_macro (). |
303 `-------------------------------------------------------------------*/
306 expand_macro (symbol *sym)
308 struct obstack arguments; /* Alternate obstack if argc_stack is busy. */
309 unsigned argv_base; /* Size of argv_stack on entry. */
310 bool use_argc_stack = true; /* Whether argc_stack is safe. */
313 struct obstack *expansion;
314 const char *expanded;
318 /* Report errors at the location where the open parenthesis (if any)
319 was found, but after expansion, restore global state back to the
320 location of the close parenthesis. This is safe since we
321 guarantee that macro expansion does not alter the state of
322 current_file/current_line (dnl, include, and sinclude are special
323 cased in the input engine to ensure this fact). */
324 const char *loc_open_file = current_file;
325 int loc_open_line = current_line;
326 const char *loc_close_file;
329 SYMBOL_PENDING_EXPANSIONS (sym)++;
331 if (nesting_limit > 0 && expansion_level > nesting_limit)
332 m4_failure (0, _("recursion limit of %d exceeded, use -L<N> to change it"),
336 my_call_id = macro_call_id;
338 traced = (debug_level & DEBUG_TRACE_ALL) || SYMBOL_TRACED (sym);
340 argv_base = obstack_object_size (&argv_stack);
341 if (obstack_object_size (&argc_stack) > 0)
343 /* We cannot use argc_stack if this is a nested invocation, and an
344 outer invocation has an unfinished argument being
346 obstack_init (&arguments);
347 use_argc_stack = false;
350 if (traced && (debug_level & DEBUG_TRACE_CALL))
351 trace_prepre (SYMBOL_NAME (sym), my_call_id);
353 collect_arguments (sym, &argv_stack,
354 use_argc_stack ? &argc_stack : &arguments);
356 argc = ((obstack_object_size (&argv_stack) - argv_base)
357 / sizeof (token_data *));
358 argv = (token_data **) ((uintptr_t) obstack_base (&argv_stack) + argv_base);
360 loc_close_file = current_file;
361 loc_close_line = current_line;
362 current_file = loc_open_file;
363 current_line = loc_open_line;
366 trace_pre (SYMBOL_NAME (sym), my_call_id, argc, argv);
368 expansion = push_string_init ();
369 call_macro (sym, argc, argv, expansion);
370 expanded = push_string_finish ();
373 trace_post (SYMBOL_NAME (sym), my_call_id, argc, expanded);
375 current_file = loc_close_file;
376 current_line = loc_close_line;
379 --SYMBOL_PENDING_EXPANSIONS (sym);
381 if (SYMBOL_DELETED (sym))
385 obstack_free (&argc_stack, argv[0]);
387 obstack_free (&arguments, NULL);
388 obstack_blank_fast (&argv_stack, -argc * sizeof (token_data *));