30 |
static void expand_macro (m4 *context, const char *name, |
static void expand_macro (m4 *context, const char *name, |
31 |
m4_symbol *symbol); |
m4_symbol *symbol); |
32 |
static void expand_token (m4 *context, struct obstack *obs, |
static void expand_token (m4 *context, struct obstack *obs, |
33 |
m4__token_type type, m4_token *token); |
m4__token_type type, m4_symbol_value *token); |
34 |
static boolean expand_argument (m4 *context, struct obstack *obs, |
static boolean expand_argument (m4 *context, struct obstack *obs, |
35 |
m4_token *argp); |
m4_symbol_value *argp); |
36 |
|
|
37 |
/* Current recursion level in expand_macro (). */ |
/* Current recursion level in expand_macro (). */ |
38 |
int m4_expansion_level = 0; |
int m4_expansion_level = 0; |
45 |
m4_expand_input (m4 *context) |
m4_expand_input (m4 *context) |
46 |
{ |
{ |
47 |
m4__token_type type; |
m4__token_type type; |
48 |
m4_token token; |
m4_symbol_value token; |
49 |
|
|
50 |
while ((type = m4_next_token (&token)) != M4_TOKEN_EOF) |
while ((type = m4__next_token (&token)) != M4_TOKEN_EOF) |
51 |
expand_token (context, (struct obstack *) NULL, type, &token); |
expand_token (context, (struct obstack *) NULL, type, &token); |
52 |
} |
} |
53 |
|
|
58 |
the text are just copied to the output. */ |
the text are just copied to the output. */ |
59 |
static void |
static void |
60 |
expand_token (m4 *context, struct obstack *obs, |
expand_token (m4 *context, struct obstack *obs, |
61 |
m4__token_type type, m4_token *token) |
m4__token_type type, m4_symbol_value *token) |
62 |
{ |
{ |
63 |
m4_symbol *symbol; |
m4_symbol *symbol; |
64 |
char *text = xstrdup (TOKEN_TEXT (token)); |
char *text = xstrdup (VALUE_TEXT (token)); |
65 |
|
|
66 |
switch (type) |
switch (type) |
67 |
{ /* TOKSW */ |
{ /* TOKSW */ |
84 |
|
|
85 |
symbol = m4_symbol_lookup (M4SYMTAB, textp); |
symbol = m4_symbol_lookup (M4SYMTAB, textp); |
86 |
if (symbol == NULL |
if (symbol == NULL |
87 |
|| SYMBOL_TYPE (symbol) == M4_TOKEN_VOID |
|| SYMBOL_TYPE (symbol) == M4_SYMBOL_VOID |
88 |
|| (SYMBOL_TYPE (symbol) == M4_TOKEN_FUNC |
|| (SYMBOL_TYPE (symbol) == M4_SYMBOL_FUNC |
89 |
&& BIT_TEST (SYMBOL_FLAGS (symbol), TOKEN_BLIND_ARGS_BIT) |
&& BIT_TEST (SYMBOL_FLAGS (symbol), VALUE_BLIND_ARGS_BIT) |
90 |
&& !M4_IS_OPEN (m4_peek_input ()))) |
&& !M4_IS_OPEN (m4_peek_input ()))) |
91 |
{ |
{ |
92 |
m4_shipout_text (obs, text, strlen (text)); |
m4_shipout_text (obs, text, strlen (text)); |
114 |
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 |
115 |
obstack OBS, indirectly through expand_token (). */ |
obstack OBS, indirectly through expand_token (). */ |
116 |
static boolean |
static boolean |
117 |
expand_argument (m4 *context, struct obstack *obs, m4_token *argp) |
expand_argument (m4 *context, struct obstack *obs, m4_symbol_value *argp) |
118 |
{ |
{ |
119 |
m4__token_type type; |
m4__token_type type; |
120 |
m4_token token; |
m4_symbol_value token; |
121 |
char *text; |
char *text; |
122 |
int paren_level = 0; |
int paren_level = 0; |
123 |
const char *current_file = m4_current_file; |
const char *current_file = m4_current_file; |
124 |
int current_line = m4_current_line; |
int current_line = m4_current_line; |
125 |
|
|
126 |
TOKEN_TYPE (argp) = M4_TOKEN_VOID; |
VALUE_TYPE (argp) = M4_SYMBOL_VOID; |
127 |
|
|
128 |
/* Skip leading white space. */ |
/* Skip leading white space. */ |
129 |
do |
do |
130 |
{ |
{ |
131 |
type = m4_next_token (&token); |
type = m4__next_token (&token); |
132 |
} |
} |
133 |
while (type == M4_TOKEN_SPACE); |
while (type == M4_TOKEN_SPACE); |
134 |
|
|
137 |
switch (type) |
switch (type) |
138 |
{ /* TOKSW */ |
{ /* TOKSW */ |
139 |
case M4_TOKEN_SIMPLE: |
case M4_TOKEN_SIMPLE: |
140 |
text = TOKEN_TEXT (&token); |
text = VALUE_TEXT (&token); |
141 |
if ((M4_IS_COMMA (*text) || M4_IS_CLOSE (*text)) && paren_level == 0) |
if ((M4_IS_COMMA (*text) || M4_IS_CLOSE (*text)) && paren_level == 0) |
142 |
{ |
{ |
143 |
|
|
145 |
obstack_1grow (obs, '\0'); |
obstack_1grow (obs, '\0'); |
146 |
text = obstack_finish (obs); |
text = obstack_finish (obs); |
147 |
|
|
148 |
if (TOKEN_TYPE (argp) == M4_TOKEN_VOID) |
if (VALUE_TYPE (argp) == M4_SYMBOL_VOID) |
149 |
{ |
{ |
150 |
TOKEN_TYPE (argp) = M4_TOKEN_TEXT; |
VALUE_TYPE (argp) = M4_SYMBOL_TEXT; |
151 |
TOKEN_TEXT (argp) = text; |
VALUE_TEXT (argp) = text; |
152 |
} |
} |
153 |
return (boolean) (M4_IS_COMMA (*TOKEN_TEXT (&token))); |
return (boolean) (M4_IS_COMMA (*VALUE_TEXT (&token))); |
154 |
} |
} |
155 |
|
|
156 |
if (M4_IS_OPEN (*text)) |
if (M4_IS_OPEN (*text)) |
173 |
|
|
174 |
case M4_TOKEN_MACDEF: |
case M4_TOKEN_MACDEF: |
175 |
if (obstack_object_size (obs) == 0) |
if (obstack_object_size (obs) == 0) |
176 |
m4_token_copy (argp, &token); |
m4_symbol_value_copy (argp, &token); |
177 |
break; |
break; |
178 |
|
|
179 |
default: |
default: |
182 |
abort (); |
abort (); |
183 |
} |
} |
184 |
|
|
185 |
type = m4_next_token (&token); |
type = m4__next_token (&token); |
186 |
} |
} |
187 |
} |
} |
188 |
|
|
199 |
{ |
{ |
200 |
struct obstack arguments; |
struct obstack arguments; |
201 |
struct obstack argptr; |
struct obstack argptr; |
202 |
m4_token **argv; |
m4_symbol_value **argv; |
203 |
int argc; |
int argc; |
204 |
struct obstack *expansion; |
struct obstack *expansion; |
205 |
const char *expanded; |
const char *expanded; |
225 |
|
|
226 |
collect_arguments (context, name, symbol, &argptr, &arguments); |
collect_arguments (context, name, symbol, &argptr, &arguments); |
227 |
|
|
228 |
argc = obstack_object_size (&argptr) / sizeof (m4_token *); |
argc = obstack_object_size (&argptr) / sizeof (m4_symbol_value *); |
229 |
argv = (m4_token **) obstack_finish (&argptr); |
argv = (m4_symbol_value **) obstack_finish (&argptr); |
230 |
|
|
231 |
if (traced) |
if (traced) |
232 |
m4_trace_pre (name, my_call_id, argc, argv); |
m4_trace_pre (name, my_call_id, argc, argv); |
254 |
struct obstack *argptr, struct obstack *arguments) |
struct obstack *argptr, struct obstack *arguments) |
255 |
{ |
{ |
256 |
int ch; /* lookahead for ( */ |
int ch; /* lookahead for ( */ |
257 |
m4_token token; |
m4_symbol_value token; |
258 |
m4_token *tokenp; |
m4_symbol_value *tokenp; |
259 |
boolean more_args; |
boolean more_args; |
260 |
boolean groks_macro_args; |
boolean groks_macro_args; |
261 |
|
|
262 |
groks_macro_args = BIT_TEST (SYMBOL_FLAGS (symbol), TOKEN_MACRO_ARGS_BIT); |
groks_macro_args = BIT_TEST (SYMBOL_FLAGS (symbol), VALUE_MACRO_ARGS_BIT); |
263 |
|
|
264 |
TOKEN_TYPE (&token) = M4_TOKEN_TEXT; |
VALUE_TYPE (&token) = M4_SYMBOL_TEXT; |
265 |
TOKEN_TEXT (&token) = (char *) name; |
VALUE_TEXT (&token) = (char *) name; |
266 |
tokenp = (m4_token *) obstack_copy (arguments, (void *) &token, |
tokenp = (m4_symbol_value *) obstack_copy (arguments, (void *) &token, |
267 |
sizeof (token)); |
sizeof (token)); |
268 |
obstack_grow (argptr, (void *) &tokenp, sizeof (tokenp)); |
obstack_grow (argptr, (void *) &tokenp, sizeof (tokenp)); |
269 |
|
|
270 |
ch = m4_peek_input (); |
ch = m4_peek_input (); |
271 |
if (M4_IS_OPEN(ch)) |
if (M4_IS_OPEN(ch)) |
272 |
{ |
{ |
273 |
m4_next_token (&token); /* gobble parenthesis */ |
m4__next_token (&token); /* gobble parenthesis */ |
274 |
do |
do |
275 |
{ |
{ |
276 |
more_args = expand_argument (context, arguments, &token); |
more_args = expand_argument (context, arguments, &token); |
277 |
|
|
278 |
if (!groks_macro_args && TOKEN_TYPE (&token) == M4_TOKEN_FUNC) |
if (!groks_macro_args && VALUE_TYPE (&token) == M4_SYMBOL_FUNC) |
279 |
{ |
{ |
280 |
TOKEN_TYPE (&token) = M4_TOKEN_TEXT; |
VALUE_TYPE (&token) = M4_SYMBOL_TEXT; |
281 |
TOKEN_TEXT (&token) = ""; |
VALUE_TEXT (&token) = ""; |
282 |
} |
} |
283 |
tokenp = (m4_token *) |
tokenp = (m4_symbol_value *) |
284 |
obstack_copy (arguments, (void *) &token, sizeof (token)); |
obstack_copy (arguments, (void *) &token, sizeof (token)); |
285 |
obstack_grow (argptr, (void *) &tokenp, sizeof (tokenp)); |
obstack_grow (argptr, (void *) &tokenp, sizeof (tokenp)); |
286 |
} |
} |
297 |
the obstack EXPANSION. Macro tracing is also handled here. */ |
the obstack EXPANSION. Macro tracing is also handled here. */ |
298 |
void |
void |
299 |
m4_call_macro (m4_symbol *symbol, m4 *context, struct obstack *expansion, |
m4_call_macro (m4_symbol *symbol, m4 *context, struct obstack *expansion, |
300 |
int argc, m4_token **argv) |
int argc, m4_symbol_value **argv) |
301 |
{ |
{ |
302 |
switch (SYMBOL_TYPE (symbol)) |
switch (SYMBOL_TYPE (symbol)) |
303 |
{ |
{ |
304 |
case M4_TOKEN_FUNC: |
case M4_SYMBOL_FUNC: |
305 |
(*SYMBOL_FUNC (symbol)) (context, expansion, argc, argv); |
(*SYMBOL_FUNC (symbol)) (context, expansion, argc, argv); |
306 |
break; |
break; |
307 |
|
|
308 |
case M4_TOKEN_TEXT: |
case M4_SYMBOL_TEXT: |
309 |
m4_process_macro (symbol, context, expansion, argc, argv); |
m4_process_macro (symbol, context, expansion, argc, argv); |
310 |
break; |
break; |
311 |
|
|
312 |
case M4_TOKEN_VOID: |
case M4_SYMBOL_VOID: |
313 |
M4ERROR ((warning_status, 0, |
M4ERROR ((warning_status, 0, |
314 |
"INTERNAL ERROR: Bad symbol type in call_macro ()")); |
"INTERNAL ERROR: Bad symbol type in call_macro ()")); |
315 |
abort (); |
abort (); |
323 |
as usual. */ |
as usual. */ |
324 |
void |
void |
325 |
m4_process_macro (m4_symbol *symbol, m4 *context, struct obstack *obs, |
m4_process_macro (m4_symbol *symbol, m4 *context, struct obstack *obs, |
326 |
int argc, m4_token **argv) |
int argc, m4_symbol_value **argv) |
327 |
{ |
{ |
328 |
const unsigned char *text; |
const unsigned char *text; |
329 |
int i; |
int i; |
383 |
|
|
384 |
if (*endp) |
if (*endp) |
385 |
{ |
{ |
386 |
struct m4_token_arg **arg |
struct m4_symbol_arg **arg |
387 |
= (struct m4_token_arg **) |
= (struct m4_symbol_arg **) |
388 |
m4_hash_lookup (SYMBOL_ARG_SIGNATURE (symbol), key); |
m4_hash_lookup (SYMBOL_ARG_SIGNATURE (symbol), key); |
389 |
|
|
390 |
if (arg) |
if (arg) |
391 |
{ |
{ |
392 |
i = TOKEN_ARG_INDEX (*arg); |
i = SYMBOL_ARG_INDEX (*arg); |
393 |
|
|
394 |
if (i < argc) |
if (i < argc) |
395 |
m4_shipout_string (obs, M4ARG (i), 0, FALSE); |
m4_shipout_string (obs, M4ARG (i), 0, FALSE); |