23 |
#include "m4.h" |
#include "m4.h" |
24 |
#include "m4private.h" |
#include "m4private.h" |
25 |
|
|
26 |
static void expand_macro (m4_symbol *); |
static void expand_macro (const char *name, m4_symbol *); |
27 |
static void expand_token (struct obstack *, m4_token_t, m4_token_data *); |
static void expand_token (struct obstack *, m4_token_t, m4_token_data *); |
28 |
|
|
29 |
/* Current recursion level in expand_macro (). */ |
/* Current recursion level in expand_macro (). */ |
52 |
expand_token (struct obstack *obs, m4_token_t t, m4_token_data *td) |
expand_token (struct obstack *obs, m4_token_t t, m4_token_data *td) |
53 |
{ |
{ |
54 |
m4_symbol *symbol; |
m4_symbol *symbol; |
55 |
char *text = M4_TOKEN_DATA_TEXT (td); |
char *text = xstrdup (M4_TOKEN_DATA_TEXT (td)); |
56 |
|
|
57 |
switch (t) |
switch (t) |
58 |
{ /* TOKSW */ |
{ /* TOKSW */ |
67 |
break; |
break; |
68 |
|
|
69 |
case M4_TOKEN_WORD: |
case M4_TOKEN_WORD: |
70 |
if (M4_IS_ESCAPE(*text)) |
{ |
71 |
text++; |
char *p = text; |
72 |
|
|
73 |
symbol = m4_lookup_symbol (text, M4_SYMBOL_LOOKUP); |
if (M4_IS_ESCAPE(*p)) |
74 |
if (symbol == NULL || M4_SYMBOL_TYPE (symbol) == M4_TOKEN_VOID |
++p; |
75 |
|| (M4_SYMBOL_TYPE (symbol) == M4_TOKEN_FUNC |
|
76 |
&& M4_SYMBOL_BLIND_NO_ARGS (symbol) |
symbol = m4_lookup_symbol (p, M4_SYMBOL_LOOKUP); |
77 |
&& !M4_IS_OPEN(m4_peek_input ()))) |
if (symbol == NULL || M4_SYMBOL_TYPE (symbol) == M4_TOKEN_VOID |
78 |
{ |
|| (M4_SYMBOL_TYPE (symbol) == M4_TOKEN_FUNC |
79 |
m4_shipout_text (obs, M4_TOKEN_DATA_TEXT (td), |
&& M4_SYMBOL_BLIND_NO_ARGS (symbol) |
80 |
strlen (M4_TOKEN_DATA_TEXT (td))); |
&& !M4_IS_OPEN(m4_peek_input ()))) |
81 |
} |
{ |
82 |
else |
m4_shipout_text (obs, M4_TOKEN_DATA_TEXT (td), |
83 |
expand_macro (symbol); |
strlen (M4_TOKEN_DATA_TEXT (td))); |
84 |
|
} |
85 |
|
else |
86 |
|
expand_macro (p, symbol); |
87 |
|
} |
88 |
break; |
break; |
89 |
|
|
90 |
default: |
default: |
92 |
_("INTERNAL ERROR: Bad token type in expand_token ()"))); |
_("INTERNAL ERROR: Bad token type in expand_token ()"))); |
93 |
abort (); |
abort (); |
94 |
} |
} |
95 |
|
|
96 |
|
XFREE (text); |
97 |
} |
} |
98 |
|
|
99 |
|
|
187 |
stored on the obstack ARGUMENTS and a table of pointers to the arguments |
stored on the obstack ARGUMENTS and a table of pointers to the arguments |
188 |
on the obstack ARGPTR. */ |
on the obstack ARGPTR. */ |
189 |
static void |
static void |
190 |
collect_arguments (m4_symbol *symbol, struct obstack *argptr, |
collect_arguments (const char *name, m4_symbol *symbol, |
191 |
struct obstack *arguments) |
struct obstack *argptr, struct obstack *arguments) |
192 |
{ |
{ |
193 |
int ch; /* lookahead for ( */ |
int ch; /* lookahead for ( */ |
194 |
m4_token_data td; |
m4_token_data td; |
197 |
boolean groks_macro_args = M4_SYMBOL_MACRO_ARGS (symbol); |
boolean groks_macro_args = M4_SYMBOL_MACRO_ARGS (symbol); |
198 |
|
|
199 |
M4_TOKEN_DATA_TYPE (&td) = M4_TOKEN_TEXT; |
M4_TOKEN_DATA_TYPE (&td) = M4_TOKEN_TEXT; |
200 |
M4_TOKEN_DATA_TEXT (&td) = M4_SYMBOL_NAME (symbol); |
M4_TOKEN_DATA_TEXT (&td) = (char *) name; |
201 |
tdp = (m4_token_data *) obstack_copy (arguments, (void *) &td, sizeof (td)); |
tdp = (m4_token_data *) obstack_copy (arguments, (void *) &td, sizeof (td)); |
202 |
obstack_grow (argptr, (void *) &tdp, sizeof (tdp)); |
obstack_grow (argptr, (void *) &tdp, sizeof (tdp)); |
203 |
|
|
259 |
Expand_macro () is potentially recursive, since it calls expand_argument |
Expand_macro () is potentially recursive, since it calls expand_argument |
260 |
(), which might call expand_token (), which might call expand_macro (). */ |
(), which might call expand_token (), which might call expand_macro (). */ |
261 |
static void |
static void |
262 |
expand_macro (m4_symbol *symbol) |
expand_macro (const char *name, m4_symbol *symbol) |
263 |
{ |
{ |
264 |
struct obstack arguments; |
struct obstack arguments; |
265 |
struct obstack argptr; |
struct obstack argptr; |
285 |
obstack_init (&arguments); |
obstack_init (&arguments); |
286 |
|
|
287 |
if (traced && (debug_level & M4_DEBUG_TRACE_CALL)) |
if (traced && (debug_level & M4_DEBUG_TRACE_CALL)) |
288 |
m4_trace_prepre (M4_SYMBOL_NAME (symbol), my_call_id); |
m4_trace_prepre (name, my_call_id); |
289 |
|
|
290 |
collect_arguments (symbol, &argptr, &arguments); |
collect_arguments (name, symbol, &argptr, &arguments); |
291 |
|
|
292 |
argc = obstack_object_size (&argptr) / sizeof (m4_token_data *); |
argc = obstack_object_size (&argptr) / sizeof (m4_token_data *); |
293 |
argv = (m4_token_data **) obstack_finish (&argptr); |
argv = (m4_token_data **) obstack_finish (&argptr); |
294 |
|
|
295 |
if (traced) |
if (traced) |
296 |
m4_trace_pre (M4_SYMBOL_NAME (symbol), my_call_id, argc, argv); |
m4_trace_pre (name, my_call_id, argc, argv); |
297 |
|
|
298 |
expansion = m4_push_string_init (); |
expansion = m4_push_string_init (); |
299 |
m4_call_macro (symbol, argc, argv, expansion); |
m4_call_macro (symbol, argc, argv, expansion); |
300 |
expanded = m4_push_string_finish (); |
expanded = m4_push_string_finish (); |
301 |
|
|
302 |
if (traced) |
if (traced) |
303 |
m4_trace_post (M4_SYMBOL_NAME (symbol), my_call_id, argc, argv, expanded); |
m4_trace_post (name, my_call_id, argc, argv, expanded); |
304 |
|
|
305 |
--m4_expansion_level; |
--m4_expansion_level; |
306 |
|
|