* src/Makefile.am (m4_LDADD): Add any gnulib dependent libraries.
[m4/ericb.git] / src / macro.c
blob4543cf4fc36c710515e6526b06765c6f6c9429f9
1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2006 Free Software
4 Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA
22 /* This file contains the functions, that performs the basic argument
23 parsing and macro expansion. */
25 #include "m4.h"
27 static void expand_macro (symbol *);
28 static void expand_token (struct obstack *, token_type, token_data *);
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 /*----------------------------------------------------------------------.
37 | This function read all input, and expands each token, one at a time. |
38 `----------------------------------------------------------------------*/
40 void
41 expand_input (void)
43 token_type t;
44 token_data td;
46 while ((t = next_token (&td)) != TOKEN_EOF)
47 expand_token ((struct obstack *) NULL, t, &td);
51 /*------------------------------------------------------------------------.
52 | Expand one token, according to its type. Potential macro names |
53 | (TOKEN_WORD) are looked up in the symbol table, to see if they have a |
54 | macro definition. If they have, they are expanded as macros, otherwise |
55 | the text are just copied to the output. |
56 `------------------------------------------------------------------------*/
58 static void
59 expand_token (struct obstack *obs, token_type t, token_data *td)
61 symbol *sym;
63 switch (t)
64 { /* TOKSW */
65 case TOKEN_EOF:
66 case TOKEN_MACDEF:
67 break;
69 case TOKEN_OPEN:
70 case TOKEN_COMMA:
71 case TOKEN_CLOSE:
72 case TOKEN_SIMPLE:
73 case TOKEN_STRING:
74 shipout_text (obs, TOKEN_DATA_TEXT (td), strlen (TOKEN_DATA_TEXT (td)));
75 break;
77 case TOKEN_WORD:
78 sym = lookup_symbol (TOKEN_DATA_TEXT (td), SYMBOL_LOOKUP);
79 if (sym == NULL || SYMBOL_TYPE (sym) == TOKEN_VOID
80 || (SYMBOL_TYPE (sym) == TOKEN_FUNC
81 && SYMBOL_BLIND_NO_ARGS (sym)
82 && peek_token () != TOKEN_OPEN))
84 #ifdef ENABLE_CHANGEWORD
85 shipout_text (obs, TOKEN_DATA_ORIG_TEXT (td),
86 strlen (TOKEN_DATA_ORIG_TEXT (td)));
87 #else
88 shipout_text (obs, TOKEN_DATA_TEXT (td),
89 strlen (TOKEN_DATA_TEXT (td)));
90 #endif
92 else
93 expand_macro (sym);
94 break;
96 default:
97 M4ERROR ((warning_status, 0,
98 "INTERNAL ERROR: bad token type in expand_token ()"));
99 abort ();
104 /*-------------------------------------------------------------------------.
105 | This function parses one argument to a macro call. It expects the first |
106 | left parenthesis, or the separating comma to have been read by the |
107 | caller. It skips leading whitespace, and reads and expands tokens, |
108 | until it finds a comma or an right parenthesis at the same level of |
109 | parentheses. It returns a flag indicating whether the argument read are |
110 | the last for the active macro call. The argument are build on the |
111 | obstack OBS, indirectly through expand_token (). |
112 `-------------------------------------------------------------------------*/
114 static boolean
115 expand_argument (struct obstack *obs, token_data *argp)
117 token_type t;
118 token_data td;
119 char *text;
120 int paren_level;
121 const char *file = current_file;
122 int line = current_line;
124 TOKEN_DATA_TYPE (argp) = TOKEN_VOID;
126 /* Skip leading white space. */
129 t = next_token (&td);
131 while (t == TOKEN_SIMPLE && isspace (to_uchar (*TOKEN_DATA_TEXT (&td))));
133 paren_level = 0;
135 while (1)
138 switch (t)
139 { /* TOKSW */
140 case TOKEN_COMMA:
141 case TOKEN_CLOSE:
142 if (paren_level == 0)
144 /* The argument MUST be finished, whether we want it or not. */
145 obstack_1grow (obs, '\0');
146 text = obstack_finish (obs);
148 if (TOKEN_DATA_TYPE (argp) == TOKEN_VOID)
150 TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
151 TOKEN_DATA_TEXT (argp) = text;
153 return (boolean) (t == TOKEN_COMMA);
155 /* fallthru */
156 case TOKEN_OPEN:
157 case TOKEN_SIMPLE:
158 text = TOKEN_DATA_TEXT (&td);
160 if (*text == '(')
161 paren_level++;
162 else if (*text == ')')
163 paren_level--;
164 expand_token (obs, t, &td);
165 break;
167 case TOKEN_EOF:
168 /* current_file changed to "" if we see TOKEN_EOF, use the
169 previous value we stored earlier. */
170 M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, line,
171 "ERROR: end of file in argument list"));
172 break;
174 case TOKEN_WORD:
175 case TOKEN_STRING:
176 expand_token (obs, t, &td);
177 break;
179 case TOKEN_MACDEF:
180 if (obstack_object_size (obs) == 0)
182 TOKEN_DATA_TYPE (argp) = TOKEN_FUNC;
183 TOKEN_DATA_FUNC (argp) = TOKEN_DATA_FUNC (&td);
185 break;
187 default:
188 M4ERROR ((warning_status, 0,
189 "INTERNAL ERROR: bad token type in expand_argument ()"));
190 abort ();
193 t = next_token (&td);
197 /*-------------------------------------------------------------------------.
198 | Collect all the arguments to a call of the macro SYM. The arguments are |
199 | stored on the obstack ARGUMENTS and a table of pointers to the arguments |
200 | on the obstack ARGPTR. |
201 `-------------------------------------------------------------------------*/
203 static void
204 collect_arguments (symbol *sym, struct obstack *argptr,
205 struct obstack *arguments)
207 token_data td;
208 token_data *tdp;
209 boolean more_args;
210 boolean groks_macro_args = SYMBOL_MACRO_ARGS (sym);
212 TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
213 TOKEN_DATA_TEXT (&td) = SYMBOL_NAME (sym);
214 tdp = (token_data *) obstack_copy (arguments, &td, sizeof (td));
215 obstack_grow (argptr, &tdp, sizeof (tdp));
217 if (peek_token () == TOKEN_OPEN)
219 next_token (&td); /* gobble parenthesis */
222 more_args = expand_argument (arguments, &td);
224 if (!groks_macro_args && TOKEN_DATA_TYPE (&td) == TOKEN_FUNC)
226 TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
227 TOKEN_DATA_TEXT (&td) = "";
229 tdp = (token_data *)
230 obstack_copy (arguments, &td, sizeof (td));
231 obstack_grow (argptr, &tdp, sizeof (tdp));
233 while (more_args);
238 /*------------------------------------------------------------------------.
239 | The actual call of a macro is handled by call_macro (). call_macro () |
240 | is passed a symbol SYM, whose type is used to call either a builtin |
241 | function, or the user macro expansion function expand_user_macro () |
242 | (lives in builtin.c). There are ARGC arguments to the call, stored in |
243 | the ARGV table. The expansion is left on the obstack EXPANSION. Macro |
244 | tracing is also handled here. |
245 `------------------------------------------------------------------------*/
247 void
248 call_macro (symbol *sym, int argc, token_data **argv,
249 struct obstack *expansion)
251 switch (SYMBOL_TYPE (sym))
253 case TOKEN_FUNC:
254 (*SYMBOL_FUNC (sym)) (expansion, argc, argv);
255 break;
257 case TOKEN_TEXT:
258 expand_user_macro (expansion, sym, argc, argv);
259 break;
261 default:
262 M4ERROR ((warning_status, 0,
263 "INTERNAL ERROR: bad symbol type in call_macro ()"));
264 abort ();
268 /*-------------------------------------------------------------------------.
269 | The macro expansion is handled by expand_macro (). It parses the |
270 | arguments, using collect_arguments (), and builds a table of pointers to |
271 | the arguments. The arguments themselves are stored on a local obstack. |
272 | Expand_macro () uses call_macro () to do the call of the macro. |
274 | Expand_macro () is potentially recursive, since it calls expand_argument |
275 | (), which might call expand_token (), which might call expand_macro (). |
276 `-------------------------------------------------------------------------*/
278 static void
279 expand_macro (symbol *sym)
281 struct obstack arguments;
282 struct obstack argptr;
283 token_data **argv;
284 int argc;
285 struct obstack *expansion;
286 const char *expanded;
287 boolean traced;
288 int my_call_id;
290 SYMBOL_PENDING_EXPANSIONS (sym)++;
291 expansion_level++;
292 if (expansion_level > nesting_limit)
293 M4ERROR ((EXIT_FAILURE, 0,
294 "ERROR: recursion limit of %d exceeded, use -L<N> to change it",
295 nesting_limit));
297 macro_call_id++;
298 my_call_id = macro_call_id;
300 traced = (boolean) ((debug_level & DEBUG_TRACE_ALL) || SYMBOL_TRACED (sym));
302 obstack_init (&argptr);
303 obstack_init (&arguments);
305 if (traced && (debug_level & DEBUG_TRACE_CALL))
306 trace_prepre (SYMBOL_NAME (sym), my_call_id);
308 collect_arguments (sym, &argptr, &arguments);
310 argc = obstack_object_size (&argptr) / sizeof (token_data *);
311 argv = (token_data **) obstack_finish (&argptr);
313 if (traced)
314 trace_pre (SYMBOL_NAME (sym), my_call_id, argc, argv);
316 expansion = push_string_init ();
317 call_macro (sym, argc, argv, expansion);
318 expanded = push_string_finish ();
320 if (traced)
321 trace_post (SYMBOL_NAME (sym), my_call_id, argc, argv, expanded);
323 --expansion_level;
324 --SYMBOL_PENDING_EXPANSIONS (sym);
326 if (SYMBOL_DELETED (sym))
327 free_symbol (sym);
329 obstack_free (&arguments, NULL);
330 obstack_free (&argptr, NULL);