27 |
#include "m4private.h" |
#include "m4private.h" |
28 |
|
|
29 |
static void collect_arguments (m4 *context, const char *name, |
static void collect_arguments (m4 *context, const char *name, |
30 |
m4_symbol *symbol, struct obstack *argptr, |
m4_symbol *symbol, m4_obstack *argptr, |
31 |
struct obstack *arguments); |
m4_obstack *arguments); |
32 |
static void expand_macro (m4 *context, const char *name, |
static void expand_macro (m4 *context, const char *name, |
33 |
m4_symbol *symbol); |
m4_symbol *symbol); |
34 |
static void expand_token (m4 *context, struct obstack *obs, |
static void expand_token (m4 *context, m4_obstack *obs, |
35 |
m4__token_type type, m4_symbol_value *token); |
m4__token_type type, m4_symbol_value *token); |
36 |
static boolean expand_argument (m4 *context, struct obstack *obs, |
static boolean expand_argument (m4 *context, m4_obstack *obs, |
37 |
m4_symbol_value *argp); |
m4_symbol_value *argp); |
38 |
|
|
39 |
|
static void process_macro (m4 *context, m4_symbol *symbol, |
40 |
|
m4_obstack *expansion, int argc, |
41 |
|
m4_symbol_value **argv); |
42 |
|
|
43 |
static void trace_prepre (m4 *context, const char *, int); |
static void trace_prepre (m4 *context, const char *, int); |
44 |
static void trace_pre (m4 *context, const char *, int, int, |
static void trace_pre (m4 *context, const char *, int, int, |
45 |
m4_symbol_value **); |
m4_symbol_value **); |
46 |
static void trace_post (m4 *context, const char *, int, int, |
static void trace_post (m4 *context, const char *, int, int, |
47 |
m4_symbol_value **, const char *); |
m4_symbol_value **, const char *); |
48 |
static void trace_format (m4 *, const char *, ...) |
static void trace_format (m4 *context, const char *fmt, ...) |
49 |
M4_GNUC_PRINTF(2, 3); |
M4_GNUC_PRINTF(2, 3); |
50 |
static void trace_header (m4 *, int); |
static void trace_header (m4 *, int); |
51 |
static void trace_flush (m4 *); |
static void trace_flush (m4 *); |
52 |
|
|
53 |
|
|
54 |
/* Current recursion level in expand_macro (). */ |
/* Current recursion level in expand_macro (). */ |
55 |
int m4_expansion_level = 0; |
static int expansion_level = 0; |
56 |
|
|
57 |
/* The number of the current call of expand_macro (). */ |
/* The number of the current call of expand_macro (). */ |
58 |
static int macro_call_id = 0; |
static int macro_call_id = 0; |
59 |
|
|
60 |
/* This function reads all input, and expands each token, one at a time. */ |
/* This function reads all input, and expands each token, one at a time. */ |
61 |
void |
void |
62 |
m4_expand_input (m4 *context) |
m4_macro_expand_input (m4 *context) |
63 |
{ |
{ |
64 |
m4__token_type type; |
m4__token_type type; |
65 |
m4_symbol_value token; |
m4_symbol_value token; |
66 |
|
|
67 |
while ((type = m4__next_token (context, &token)) != M4_TOKEN_EOF) |
while ((type = m4__next_token (context, &token)) != M4_TOKEN_EOF) |
68 |
expand_token (context, (struct obstack *) NULL, type, &token); |
expand_token (context, (m4_obstack *) NULL, type, &token); |
69 |
} |
} |
70 |
|
|
71 |
|
|
74 |
macro definition. If they have, they are expanded as macros, otherwise |
macro definition. If they have, they are expanded as macros, otherwise |
75 |
the text are just copied to the output. */ |
the text are just copied to the output. */ |
76 |
static void |
static void |
77 |
expand_token (m4 *context, struct obstack *obs, |
expand_token (m4 *context, m4_obstack *obs, |
78 |
m4__token_type type, m4_symbol_value *token) |
m4__token_type type, m4_symbol_value *token) |
79 |
{ |
{ |
80 |
m4_symbol *symbol; |
m4_symbol *symbol; |
133 |
the last for the active macro call. The arguments are built on the |
the last for the active macro call. The arguments are built on the |
134 |
obstack OBS, indirectly through expand_token (). */ |
obstack OBS, indirectly through expand_token (). */ |
135 |
static boolean |
static boolean |
136 |
expand_argument (m4 *context, struct obstack *obs, m4_symbol_value *argp) |
expand_argument (m4 *context, m4_obstack *obs, m4_symbol_value *argp) |
137 |
{ |
{ |
138 |
m4__token_type type; |
m4__token_type type; |
139 |
m4_symbol_value token; |
m4_symbol_value token; |
217 |
static void |
static void |
218 |
expand_macro (m4 *context, const char *name, m4_symbol *symbol) |
expand_macro (m4 *context, const char *name, m4_symbol *symbol) |
219 |
{ |
{ |
220 |
struct obstack arguments; |
m4_obstack arguments; |
221 |
struct obstack argptr; |
m4_obstack argptr; |
222 |
m4_symbol_value **argv; |
m4_symbol_value **argv; |
223 |
int argc; |
int argc; |
224 |
struct obstack *expansion; |
m4_obstack *expansion; |
225 |
const char *expanded; |
const char *expanded; |
226 |
boolean traced; |
boolean traced; |
227 |
int my_call_id; |
int my_call_id; |
228 |
|
|
229 |
m4_expansion_level++; |
expansion_level++; |
230 |
if (m4_expansion_level > m4_get_nesting_limit_opt (context)) |
if (expansion_level > m4_get_nesting_limit_opt (context)) |
231 |
M4ERROR ((EXIT_FAILURE, 0, _("\ |
M4ERROR ((EXIT_FAILURE, 0, _("\ |
232 |
ERROR: Recursion limit of %d exceeded, use -L<N> to change it"), |
ERROR: Recursion limit of %d exceeded, use -L<N> to change it"), |
233 |
m4_get_nesting_limit_opt (context))); |
m4_get_nesting_limit_opt (context))); |
255 |
expansion = m4_push_string_init (context); |
expansion = m4_push_string_init (context); |
256 |
if (!m4_bad_argc (context, argc, argv, |
if (!m4_bad_argc (context, argc, argv, |
257 |
SYMBOL_MIN_ARGS (symbol), SYMBOL_MAX_ARGS (symbol))) |
SYMBOL_MIN_ARGS (symbol), SYMBOL_MAX_ARGS (symbol))) |
258 |
m4_call_macro (context, symbol, expansion, argc, argv); |
m4_macro_call (context, symbol, expansion, argc, argv); |
259 |
expanded = m4_push_string_finish (); |
expanded = m4_push_string_finish (); |
260 |
|
|
261 |
if (traced) |
if (traced) |
262 |
trace_post (context, name, my_call_id, argc, argv, expanded); |
trace_post (context, name, my_call_id, argc, argv, expanded); |
263 |
|
|
264 |
--m4_expansion_level; |
--expansion_level; |
265 |
|
|
266 |
obstack_free (&arguments, NULL); |
obstack_free (&arguments, NULL); |
267 |
obstack_free (&argptr, NULL); |
obstack_free (&argptr, NULL); |
272 |
to the arguments on the obstack ARGPTR. */ |
to the arguments on the obstack ARGPTR. */ |
273 |
static void |
static void |
274 |
collect_arguments (m4 *context, const char *name, m4_symbol *symbol, |
collect_arguments (m4 *context, const char *name, m4_symbol *symbol, |
275 |
struct obstack *argptr, struct obstack *arguments) |
m4_obstack *argptr, m4_obstack *arguments) |
276 |
{ |
{ |
277 |
int ch; /* lookahead for ( */ |
int ch; /* lookahead for ( */ |
278 |
m4_symbol_value token; |
m4_symbol_value token; |
308 |
} |
} |
309 |
|
|
310 |
|
|
311 |
/* The actual call of a macro is handled by m4_call_macro (). |
/* The actual call of a macro is handled by m4_macro_call (). |
312 |
m4_call_macro () is passed a SYMBOL, whose type is used to |
m4_macro_call () is passed a SYMBOL, whose type is used to |
313 |
call either a builtin function, or the user macro expansion |
call either a builtin function, or the user macro expansion |
314 |
function m4_process_macro (). There are ARGC arguments to |
function process_macro (). There are ARGC arguments to |
315 |
the call, stored in the ARGV table. The expansion is left on |
the call, stored in the ARGV table. The expansion is left on |
316 |
the obstack EXPANSION. Macro tracing is also handled here. */ |
the obstack EXPANSION. Macro tracing is also handled here. */ |
317 |
void |
void |
318 |
m4_call_macro (m4 *context, m4_symbol *symbol, struct obstack *expansion, |
m4_macro_call (m4 *context, m4_symbol *symbol, m4_obstack *expansion, |
319 |
int argc, m4_symbol_value **argv) |
int argc, m4_symbol_value **argv) |
320 |
{ |
{ |
321 |
if (m4_is_symbol_text (symbol)) |
if (m4_is_symbol_text (symbol)) |
322 |
{ |
{ |
323 |
m4_process_macro (context, symbol, expansion, argc, argv); |
process_macro (context, symbol, expansion, argc, argv); |
324 |
} |
} |
325 |
else if (m4_is_symbol_func (symbol)) |
else if (m4_is_symbol_func (symbol)) |
326 |
{ |
{ |
339 |
will be placed, as an unfinished object. SYMBOL points to the macro |
will be placed, as an unfinished object. SYMBOL points to the macro |
340 |
definition, giving the expansion text. ARGC and ARGV are the arguments, |
definition, giving the expansion text. ARGC and ARGV are the arguments, |
341 |
as usual. */ |
as usual. */ |
342 |
void |
static void |
343 |
m4_process_macro (m4 *context, m4_symbol *symbol, struct obstack *obs, |
process_macro (m4 *context, m4_symbol *symbol, m4_obstack *obs, |
344 |
int argc, m4_symbol_value **argv) |
int argc, m4_symbol_value **argv) |
345 |
{ |
{ |
346 |
const unsigned char *text; |
const unsigned char *text; |
347 |
int i; |
int i; |
526 |
trace_format (context, "%s:", m4_current_file); |
trace_format (context, "%s:", m4_current_file); |
527 |
if (m4_is_debug_bit (context, M4_DEBUG_TRACE_LINE)) |
if (m4_is_debug_bit (context, M4_DEBUG_TRACE_LINE)) |
528 |
trace_format (context, "%d:", m4_current_line); |
trace_format (context, "%d:", m4_current_line); |
529 |
trace_format (context, " -%d- ", m4_expansion_level); |
trace_format (context, " -%d- ", expansion_level); |
530 |
if (m4_is_debug_bit (context, M4_DEBUG_TRACE_CALLID)) |
if (m4_is_debug_bit (context, M4_DEBUG_TRACE_CALLID)) |
531 |
trace_format (context, "id %d: ", id); |
trace_format (context, "id %d: ", id); |
532 |
} |
} |