m4-commit
[Top][All Lists]
Advanced

[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);
     }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]