[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Changes to m4/m4/macro.c,v
From: |
Eric Blake |
Subject: |
Changes to m4/m4/macro.c,v |
Date: |
Wed, 25 Oct 2006 12:45:46 +0000 |
CVSROOT: /sources/m4
Module name: m4
Changes by: Eric Blake <ericb> 06/10/25 12:45:45
Index: m4/macro.c
===================================================================
RCS file: /sources/m4/m4/m4/macro.c,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -b -r1.59 -r1.60
--- m4/macro.c 12 Oct 2006 21:14:50 -0000 1.59
+++ m4/macro.c 25 Oct 2006 12:45:45 -0000 1.60
@@ -55,6 +55,19 @@
/* The number of the current call of expand_macro (). */
static size_t macro_call_id = 0;
+/* The shared stack of collected arguments for macro calls; as each
+ argument is collected, it is finished and its location stored in
+ argv_stack. This stack can be used simultaneously by multiple
+ macro calls, using obstack_regrow to handle partial objects
+ embedded in the stack. */
+static struct obstack argc_stack;
+
+/* The shared stack of pointers to collected arguments for macro
+ calls. This object is never finished; we exploit the fact that
+ obstack_blank is documented to take a negative size to reduce the
+ size again. */
+static struct obstack argv_stack;
+
/* This function reads all input, and expands each token, one at a time. */
void
m4_macro_expand_input (m4 *context)
@@ -62,8 +75,14 @@
m4__token_type type;
m4_symbol_value token;
+ obstack_init (&argc_stack);
+ obstack_init (&argv_stack);
+
while ((type = m4__next_token (context, &token)) != M4_TOKEN_EOF)
expand_token (context, (m4_obstack *) NULL, type, &token);
+
+ obstack_free (&argc_stack, NULL);
+ obstack_free (&argv_stack, NULL);
}
@@ -76,10 +95,8 @@
m4__token_type type, m4_symbol_value *token)
{
m4_symbol *symbol;
- /* Copy name, since expand_macro can consume additional tokens,
- invalidating the current token. */
char *text = (m4_is_symbol_value_text (token)
- ? xstrdup (m4_get_symbol_value_text (token)) : NULL);
+ ? m4_get_symbol_value_text (token) : NULL);
switch (type)
{ /* TOKSW */
@@ -121,8 +138,6 @@
assert (!"INTERNAL ERROR: bad token type in expand_token ()");
abort ();
}
-
- free (text);
}
@@ -214,12 +229,17 @@
Expand_macro () uses call_macro () to do the call of the macro.
Expand_macro () is potentially recursive, since it calls expand_argument
- (), which might call expand_token (), which might call expand_macro (). */
+ (), which might call expand_token (), which might call expand_macro ().
+
+ NAME points to storage on the token stack, so it is only valid
+ until a call to collect_arguments parses more tokens. SYMBOL is
+ the result of the symbol table lookup on NAME. */
static void
expand_macro (m4 *context, const char *name, m4_symbol *symbol)
{
- m4_obstack arguments;
- m4_obstack argptr;
+ char *argc_base; /* Base of argc_stack on entry. */
+ unsigned int argc_size; /* Size of argc_stack on entry. */
+ unsigned int argv_size; /* Size of argv_stack on entry. */
m4_symbol_value **argv;
int argc;
m4_obstack *expansion;
@@ -261,16 +281,22 @@
macro_call_id++;
my_call_id = macro_call_id;
- obstack_init (&argptr);
- obstack_init (&arguments);
+ argc_size = obstack_object_size (&argc_stack);
+ argv_size = obstack_object_size (&argv_stack);
+ if (0 < argc_size)
+ argc_base = obstack_finish (&argc_stack);
if (traced && m4_is_debug_bit (context, M4_DEBUG_TRACE_CALL))
trace_prepre (context, name, my_call_id, value);
- collect_arguments (context, name, symbol, &argptr, &arguments);
+ collect_arguments (context, name, symbol, &argv_stack, &argc_stack);
- argc = obstack_object_size (&argptr) / sizeof (m4_symbol_value *);
- argv = (m4_symbol_value **) obstack_finish (&argptr);
+ argc = ((obstack_object_size (&argv_stack) - argv_size)
+ / sizeof (m4_symbol_value *));
+ argv = (m4_symbol_value **) (obstack_base (&argv_stack) + argv_size);
+ /* Calling collect_arguments invalidated name, but we copied it as
+ argv[0]. */
+ name = m4_get_symbol_value_text (argv[0]);
loc_close_file = m4_get_current_file (context);
loc_close_line = m4_get_current_line (context);
@@ -296,8 +322,11 @@
if (BIT_TEST (VALUE_FLAGS (value), VALUE_DELETED_BIT))
m4_symbol_value_delete (value);
- obstack_free (&arguments, NULL);
- obstack_free (&argptr, NULL);
+ if (0 < argc_size)
+ obstack_regrow (&argc_stack, argc_base, argc_size);
+ else
+ obstack_free (&argc_stack, argv[0]);
+ obstack_blank (&argv_stack, -argc * sizeof (m4_symbol_value *));
}
/* Collect all the arguments to a call of the macro SYMBOL (called NAME).
@@ -314,10 +343,10 @@
groks_macro_args = BIT_TEST (SYMBOL_FLAGS (symbol), VALUE_MACRO_ARGS_BIT);
- m4_set_symbol_value_text (&token, (char *) name);
- tokenp = (m4_symbol_value *) obstack_copy (arguments, (void *) &token,
- sizeof (token));
- obstack_grow (argptr, (void *) &tokenp, sizeof (tokenp));
+ tokenp = (m4_symbol_value *) obstack_alloc (arguments, sizeof *tokenp);
+ m4_set_symbol_value_text (tokenp, (char *) obstack_copy0 (arguments, name,
+ strlen (name)));
+ obstack_ptr_grow (argptr, tokenp);
if (m4__next_token_is_open (context))
{
@@ -330,9 +359,9 @@
{
m4_set_symbol_value_text (&token, "");
}
- tokenp = (m4_symbol_value *)
- obstack_copy (arguments, (void *) &token, sizeof (token));
- obstack_grow (argptr, (void *) &tokenp, sizeof (tokenp));
+ tokenp = (m4_symbol_value *) obstack_copy (arguments, &token,
+ sizeof token);
+ obstack_ptr_grow (argptr, tokenp);
}
while (more_args);
}