m4-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: 13-gary-refactor-symtab-semantics.patch


From: Gary V. Vaughan
Subject: FYI: 13-gary-refactor-symtab-semantics.patch
Date: Tue, 17 Jun 2003 16:23:10 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030529

Applied to HEAD.
--
  ())_.  Gary V. Vaughan    gary@(oranda.demon.co.uk|gnu.org)
  ( '/   Research Scientist http://www.oranda.demon.co.uk       ,_())____
  / )=   GNU Hacker         http://www.gnu.org/software/libtool  \'      `&
`(_~)_   Tech' Author       http://sources.redhat.com/autobook   =`---d__/
Index: ChangeLog
from  Gary V. Vaughan  <address@hidden>

        Still refactoring furiously.  This delta represents a change in
        semantics to symtab.c.  Instead of building temporary m4_tokens
        in the caller, and copying fields in the methods, we now create
        the actual m4_token for hashing in the caller so the methods just
        slot them in directly.  Also, this means that we don't lookup a
        symbol and get back an allocated but VOID token to copy fields
        into, we create the token we want to push and pass that to
        m4_symbol_define or m4_symbol_pushdef.  And that's it.  There are
        a few other small changes to stop knowledge of the implementation
        of symtab.c leaking out into other files.

        * m4/macro.c (expand_argument): Comment typo corrected.
        * m4/symtab.c (symtab_fetch): New function to fetch the address of
        an interned symbol.
        (m4_symbol_pushdef): Take an extra value parameter and use this
        directly as the new top of the value stack.  All callers changed
        to build a token and pass responsibility for memory in, rather
        than copying as we used to.
        (m4_symbol_define): Also use the new value parameter directly as a
        replacement for the top of the value stack.  All callers changed
        to build a token as above.
        (m4_set_symbol_traced): New function to set the traced bit on the
        named symbol, creating it if necessary.
        (symbol_popval): The guts of the old m4_symbol_popdef.
        (m4_symbol_popdef): Use it.
        * m4/builtin.c (m4_symbol_set_token): Removed,
        (m4__symbol_set_builtin, m4__symbol_set_macro): Removed and
        replaced...
        * m4/module.c (m4_set_module_builtin_table)
        (m4_set_module_macro_table): ...with these more orthogonal
        functions.
        * m4/m4module.h (m4_macro_pushdef, m4_macro_define)
        (m4_builtin_pushdef, m4_builtin_define): Removed.  No longer
        required.
        * m4/builtin.c (M4_ARG_SIGNATURE_DEFAULT_SIZE)
        (m4_arg_signature_parse): Moved...
        * m4/symtab.c: ...to here.
        * m4/input.c (m4_token_copy): Arghh... I'm amazed this didn't
        screw something up. Moved...
        * m4/symtab.c (m4_token_copy): ...to here, and fixed so that it
        actually does a proper deep copy of source to dest.

Index: m4/builtin.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/builtin.c,v
retrieving revision 1.19
diff -u -p -u -r1.19 builtin.c
--- m4/builtin.c 16 Jun 2003 16:29:06 -0000 1.19
+++ m4/builtin.c 17 Jun 2003 15:17:24 -0000
@@ -23,12 +23,6 @@
 #include "m4.h"
 #include "m4private.h"
 
-#define M4_ARG_SIGNATURE_DEFAULT_SIZE 7
-
-static m4_hash *m4_arg_signature_parse (const char *name, const char *param);
-
-
-
 /* Find the builtin, which has NAME.  If BP argument is supplied
    then search only in table BP.  */
 const m4_builtin *
@@ -69,132 +63,4 @@ m4_builtin_find_by_func (const m4_builti
     }
 
   return NULL;
-}
-
-m4_symbol *
-m4_symbol_set_token (m4 *context, const char *name, m4_symbol_type type,
-                    m4_token *token,
-                    m4_symbol *(*getter) (m4_symtab *, const char *),
-                    m4_symbol *(*setter) (m4_symbol *, m4_token *))
-{
-  const char *openp  = NULL;
-  const char *params = NULL;
-  m4_symbol *symbol;
-  size_t len;
-
-  assert (name);
-  assert (!token || (TOKEN_TYPE (token) == type));
-  assert (getter);
-  assert (setter);
-
-  if (!no_gnu_extensions)
-    {
-      /* If name contains an open paren, then parse before that paren
-        as the actual name, and the rest as a formal parameter list.  */
-      len = 0;
-      for (openp = name; *openp && !M4_IS_OPEN (*openp); ++openp)
-       ++len;
-
-      if (*openp)
-       {
-         name   = xstrzdup (name, len);
-         params = 1+ openp;
-       }
-    }
-
-  /* Get a symbol table entry for the name.  */
-  symbol = (*getter) (M4SYMTAB, name);
-
-  if (symbol)
-    {
-      m4_token empty;
-
-      if (!token)
-       {
-         bzero (&empty, sizeof (m4_token));
-         TOKEN_TYPE (&empty) = type;
-         switch (type)
-           {
-           case M4_TOKEN_TEXT:
-             TOKEN_TEXT (&empty) = "";
-             break;
-
-           case M4_TOKEN_FUNC:
-           case M4_TOKEN_VOID:
-             break;
-           }
-
-         token = &empty;
-       }
-
-      if (params)
-       {
-         /* Make a hash table to map formal parameter names to
-            argv offsets, and store that in the symbol's token.  */
-         TOKEN_ARG_SIGNATURE (token) = m4_arg_signature_parse (name, params);
-       }
-
-      (*setter) (symbol, token);
-    }
-
-  /* If we split name on open paren, free the copied substring.  */
-  if (params)
-    xfree ((char *) name);
-
-  return symbol;
-}
-
-static m4_hash *
-m4_arg_signature_parse (const char *name, const char *params)
-{
-  m4_hash *arg_signature;
-  const char *commap;
-  int offset;
-
-  assert (params);
-
-  arg_signature = m4_hash_new (M4_ARG_SIGNATURE_DEFAULT_SIZE,
-                       m4_hash_string_hash, m4_hash_string_cmp);
-
-  for (offset = 1; *params && !M4_IS_CLOSE (*params); ++offset)
-    {
-      size_t len = 0;
-
-      /* Skip leading whitespace.  */
-      while (M4_IS_SPACE (*params))
-       ++params;
-
-      for (commap = params; *commap && M4_IS_IDENT (*commap); ++commap)
-       ++len;
-
-      /* Skip trailing whitespace.  */
-      while (M4_IS_SPACE (*commap))
-       ++commap;
-
-      if (!M4_IS_COMMA (*commap) && !M4_IS_CLOSE (*commap))
-       M4ERROR ((EXIT_FAILURE, 0,
-                 _("Error: %s: syntax error in parameter list at char `%c'"),
-                 name, *commap));
-
-      /* Skip parameter delimiter.  */
-      if (M4_IS_COMMA (*commap))
-       ++commap;
-
-      if (len)
-       {
-         struct m4_token_arg *arg = XCALLOC (struct m4_token_arg, 1);
-
-         TOKEN_ARG_INDEX (arg) = offset;
-
-         m4_hash_insert (arg_signature, xstrzdup (params, len), arg);
-
-         params = commap;
-       }
-    }
-
-  if (!M4_IS_CLOSE (*commap))
-    M4WARN ((warning_status, 0,
-            _("Warning: %s: unterminated parameter list"), name));
-
-  return arg_signature;
 }
Index: m4/input.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/input.c,v
retrieving revision 1.24
diff -u -p -u -r1.24 input.c
--- m4/input.c 13 Jun 2003 13:05:45 -0000 1.24
+++ m4/input.c 17 Jun 2003 15:17:24 -0000
@@ -953,16 +953,6 @@ m4_next_token (m4_token *td)
   return type;
 }
 
-void
-m4_token_copy (m4_token *dest, m4_token *src)
-{
-  TOKEN_TYPE (dest)    = TOKEN_TYPE (src);
-  TOKEN_FUNC (dest)    = TOKEN_FUNC (src);
-  TOKEN_HANDLE (dest)   = TOKEN_HANDLE (src);
-  TOKEN_FLAGS (dest)    = TOKEN_FLAGS (src);
-  TOKEN_MIN_ARGS (dest) = TOKEN_MIN_ARGS (src);
-  TOKEN_MAX_ARGS (dest) = TOKEN_MAX_ARGS (src);
-}
 
 
 #ifdef DEBUG_INPUT
Index: m4/m4module.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4module.h,v
retrieving revision 1.47
diff -u -p -u -r1.47 m4module.h
--- m4/m4module.h 16 Jun 2003 16:29:06 -0000 1.47
+++ m4/m4module.h 17 Jun 2003 15:17:24 -0000
@@ -60,12 +60,13 @@ typedef struct {
 
 /* --- CONTEXT MANAGEMENT --- */
 
-extern m4 *m4_create (void);
-extern void m4_delete (m4 *);
-extern m4_symtab *m4_get_symtab (m4 *);
+extern m4 *      m4_create     (void);
+extern void      m4_delete     (m4 *);
+extern m4_symtab *m4_get_symtab        (m4 *);
 
 #define M4SYMTAB       (m4_get_symtab (context))
 
+
 
 /* --- MODULE MANAGEMENT --- */
 
@@ -75,15 +76,21 @@ typedef void m4_module_finish_func (m4 *
 extern lt_dlhandle  m4_module_load   (m4 *, const char*, struct obstack*);
 extern void        m4_module_unload (m4 *, const char*, struct obstack*);
 
-extern const char  *m4_get_module_name     (lt_dlhandle);
-extern m4_builtin  *m4_get_module_builtin_table (lt_dlhandle);
-extern m4_macro           *m4_get_module_macro_table   (lt_dlhandle);
+extern const char  *m4_get_module_name         (lt_dlhandle);
+extern m4_builtin  *m4_get_module_builtin_table        (lt_dlhandle);
+extern m4_macro           *m4_get_module_macro_table   (lt_dlhandle);
+
+extern void    m4_set_module_macro_table   (m4 *context, lt_dlhandle handle,
+                                            const m4_macro *table);
+extern void    m4_set_module_builtin_table (m4 *context, lt_dlhandle handle,
+                                            const m4_builtin *table);
 
 
 /* --- SYMBOL TABLE MANAGEMENT --- */
 
 
-typedef int m4_symtab_apply_func (m4_symtab *symtab, const void *key, void 
*value, void *data);
+typedef int m4_symtab_apply_func (m4_symtab *symtab, const void *key,
+                                 void *value, void *data);
 
 extern m4_symtab *m4_symtab_create  (size_t);
 extern void      m4_symtab_delete  (m4_symtab*);
@@ -92,9 +99,10 @@ extern int     m4_symtab_apply   (m4_symta
 #define m4_symtab_apply(symtab, func, userdata)                                
\
  (m4_hash_apply ((m4_hash*)(symtab), (m4_hash_apply_func*)(func), (userdata)))
 
+
 extern m4_symbol *m4_symbol_lookup  (m4_symtab*, const char *);
-extern m4_symbol *m4_symbol_pushdef (m4_symtab*, const char *);
-extern m4_symbol *m4_symbol_define  (m4_symtab*, const char *);
+extern m4_symbol *m4_symbol_pushdef (m4_symtab*, const char *, m4_token *);
+extern m4_symbol *m4_symbol_define  (m4_symtab*, const char *, m4_token *);
 extern void       m4_symbol_popdef  (m4_symtab*, const char *);
 extern void       m4_symbol_delete  (m4_symtab*, const char *);
 
@@ -102,6 +110,8 @@ extern void       m4_symbol_delete  (m4_
        while (m4_symbol_lookup ((symtab), (name)))                     \
            m4_symbol_popdef ((symtab), (name));        } M4_STMT_END
 
+extern void      m4_set_symbol_traced (m4_symtab*, const char *);
+
 
 /* Various different token types.  */
 typedef enum {
@@ -126,39 +136,10 @@ typedef enum {
 
 /* --- MACRO (and builtin) MANAGEMENT --- */
 
-extern m4_symbol *m4_symbol_set_token (m4 *context, const char *name,
-                       m4_symbol_type type, m4_token *token,
-                       m4_symbol *(*getter) (m4_symtab *, const char *),
-                       m4_symbol *(*setter) (m4_symbol *, m4_token *));
-
-extern void      m4_set_module_macro_table   (m4 *context, lt_dlhandle handle,
-                                           const m4_macro *table);
-extern void      m4_set_module_builtin_table (m4 *context, lt_dlhandle handle,
-                                           const m4_builtin *table);
-
 extern const m4_builtin *m4_builtin_find_by_name (
                                const m4_builtin *, const char *);
 extern const m4_builtin *m4_builtin_find_by_func (
                                const m4_builtin *, m4_builtin_func *);
-
-
-/* These 2 functions are not part of the documented API, but we need to
-   declare them here so that the macros below will work.  */
-extern m4_symbol *m4__symbol_set_builtin (m4_symbol*, m4_token*);
-extern m4_symbol *m4__symbol_set_macro  (m4_symbol*, m4_token*);
-
-#define m4_macro_pushdef(context, name, macro)                             \
-       m4_symbol_set_token ((context), (name), M4_TOKEN_TEXT, (macro),     \
-                        m4_symbol_pushdef, m4__symbol_set_macro)
-#define m4_macro_define(context, name, macro)                              \
-       m4_symbol_set_token ((context), (name), M4_TOKEN_TEXT, (macro),     \
-                        m4_symbol_define, m4__symbol_set_macro)
-#define m4_builtin_pushdef(context, name, builtin)                         \
-       m4_symbol_set_token ((context), (name), M4_TOKEN_FUNC, (builtin),   \
-                        m4_symbol_pushdef, m4__symbol_set_builtin)
-#define m4_builtin_define(context, name, builtin)                          \
-       m4_symbol_set_token ((context), (name), M4_TOKEN_FUNC, (builtin),   \
-                        m4_symbol_define, m4__symbol_set_builtin)
 
 extern m4__token_type  m4_token_get_type (m4_token *);
 extern char           *m4_token_text     (m4_token *);
Index: m4/macro.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/macro.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 macro.c
--- m4/macro.c 16 Jun 2003 10:43:45 -0000 1.25
+++ m4/macro.c 17 Jun 2003 15:17:24 -0000
@@ -111,7 +111,7 @@ expand_token (m4 *context, struct obstac
    caller.  It skips leading whitespace, and reads and expands tokens,
    until it finds a comma or a right parenthesis at the same level of
    parentheses.  It returns a flag indicating whether the argument read is
-   the last for the active macro call.  The arguments are build on the
+   the last for the active macro call.  The arguments are built on the
    obstack OBS, indirectly through expand_token ().     */
 static boolean
 expand_argument (m4 *context, struct obstack *obs, m4_token *argp)
Index: m4/module.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/module.c,v
retrieving revision 1.20
diff -u -p -u -r1.20 module.c
--- m4/module.c 16 Jun 2003 16:29:06 -0000 1.20
+++ m4/module.c 17 Jun 2003 15:17:24 -0000
@@ -121,19 +121,25 @@ m4_set_module_builtin_table (m4 *context
                             const m4_builtin *table)
 {
   const m4_builtin *bp;
-  m4_token token;
 
   assert (handle);
   assert (table);
 
-  bzero (&token, sizeof (m4_token));
-  TOKEN_TYPE (&token)          = M4_TOKEN_FUNC;
-  TOKEN_HANDLE (&token)                = handle;
-
   for (bp = table; bp->name != NULL; bp++)
     {
-      int flags = 0;
-      char *name;
+      m4_token *token = XCALLOC (m4_token, 1);
+      char *   name;
+
+      TOKEN_TYPE (token)       = M4_TOKEN_FUNC;
+      TOKEN_FUNC (token)       = bp->func;
+      TOKEN_HANDLE (token)     = handle;
+      TOKEN_MIN_ARGS (token)   = bp->min_args;
+      TOKEN_MAX_ARGS (token)   = bp->max_args;
+
+      if (bp->groks_macro_args)
+       BIT_SET (TOKEN_FLAGS (token), TOKEN_MACRO_ARGS_BIT);
+      if (bp->blind_if_no_args)
+       BIT_SET (TOKEN_FLAGS (token), TOKEN_BLIND_ARGS_BIT);
 
       if (prefix_all_builtins)
        {
@@ -146,15 +152,8 @@ m4_set_module_builtin_table (m4 *context
       else
        name = (char *) bp->name;
 
-      if (bp->groks_macro_args) BIT_SET (flags, TOKEN_MACRO_ARGS_BIT);
-      if (bp->blind_if_no_args) BIT_SET (flags, TOKEN_BLIND_ARGS_BIT);
-
-      TOKEN_FUNC (&token)      = bp->func;
-      TOKEN_FLAGS (&token)     = flags;
-      TOKEN_MIN_ARGS (&token)  = bp->min_args;
-      TOKEN_MAX_ARGS (&token)  = bp->max_args;
 
-      m4_builtin_pushdef (context, name, &token);
+      m4_symbol_pushdef (M4SYMTAB, name, token);
 
       if (prefix_all_builtins)
        xfree (name);
@@ -174,19 +173,20 @@ m4_get_module_macro_table (lt_dlhandle h
 }
 
 void
-m4_set_module_macro_table (m4 *context, lt_dlhandle handle, const m4_macro 
*table)
+m4_set_module_macro_table (m4 *context, lt_dlhandle handle,
+                          const m4_macro *table)
 {
   const m4_macro *mp;
-  m4_token token;
-
-  bzero (&token, sizeof (m4_token));
-  TOKEN_TYPE (&token)          = M4_TOKEN_TEXT;
-  TOKEN_HANDLE (&token)                = handle;
 
   for (mp = table; mp->name != NULL; mp++)
     {
-      TOKEN_TEXT (&token)      = (char *) mp->value;
-      m4_macro_pushdef (context, mp->name, &token);
+      m4_token *token = XCALLOC (m4_token, 1);
+
+      TOKEN_TYPE (token)       = M4_TOKEN_TEXT;
+      TOKEN_TEXT (token)       = xstrdup (mp->value);
+      TOKEN_HANDLE (token)     = handle;
+
+      m4_symbol_pushdef (M4SYMTAB, mp->name, token);
     }
 }
 
Index: m4/symtab.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/symtab.c,v
retrieving revision 1.36
diff -u -p -u -r1.36 symtab.c
--- m4/symtab.c 16 Jun 2003 16:29:06 -0000 1.36
+++ m4/symtab.c 17 Jun 2003 15:17:24 -0000
@@ -42,12 +42,16 @@
    of fluff in these functions to make sure that such symbols (with empty
    value stacks) are invisible to the users of this module.  */
 
-#define M4_SYMTAB_DEFAULT_SIZE 2047
+#define M4_SYMTAB_DEFAULT_SIZE         2047
+#define M4_ARG_SIGNATURE_DEFAULT_SIZE  7
 
-static int     symbol_destroy          (m4_hash *hash, const void *name,
+static m4_symbol *symtab_fetch         (m4_symtab*, const char *);
+static void      symbol_popval         (m4_symbol *symbol);
+static int       symbol_destroy        (m4_hash *hash, const void *name,
                                         void *symbol, void *ignored);
-static int     arg_destroy             (m4_hash *hash, const void *name,
+static int       arg_destroy           (m4_hash *hash, const void *name,
                                         void *arg, void *ignored);
+static m4_hash *  arg_signature_parse  (const char *name, const char *param);
 
 
 
@@ -71,6 +75,28 @@ m4_symtab_delete (m4_symtab *symtab)
   m4_hash_delete ((m4_hash *) symtab);
 }
 
+static m4_symbol *
+symtab_fetch (m4_symtab *symtab, const char *name)
+{
+  m4_symbol **psymbol;
+  m4_symbol *symbol;
+
+  assert (symtab);
+  assert (name);
+
+  psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab, name);
+  if (psymbol)
+    {
+      symbol = *psymbol;
+    }
+  else
+    {
+      symbol = XCALLOC (m4_symbol, 1);
+      m4_hash_insert ((m4_hash *) symtab, xstrdup (name), symbol);
+    }
+
+  return symbol;
+}
 
 /* Remove every symbol that references the given module handle from
    the symbol table.  */
@@ -155,46 +181,60 @@ m4_symbol_lookup (m4_symtab *symtab, con
 
 
 /* Insert NAME into the symbol table.  If there is already a symbol
-   associated with NAME, push the new value on top of the value stack
+   associated with NAME, push the new VALUE on top of the value stack
    for this symbol.  Otherwise create a new association.  */
 m4_symbol *
-m4_symbol_pushdef (m4_symtab *symtab, const char *name)
+m4_symbol_pushdef (m4_symtab *symtab, const char *name, m4_token *value)
 {
-  m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,
-                                                      name);
-
-  m4_symbol *symbol = 0;
-  m4_token *value   = XCALLOC (m4_token, 1);
+  m4_symbol *symbol;
 
-  if (psymbol)
-    {
-      symbol = *psymbol;
-      TOKEN_NEXT (value) = SYMBOL_TOKEN (symbol);
-    }
-  else
-    symbol = XCALLOC (m4_symbol, 1);
+  assert (symtab);
+  assert (name);
+  assert (value);
 
+  symbol               = symtab_fetch (symtab, name);
+  TOKEN_NEXT (value)   = SYMBOL_TOKEN (symbol);
   SYMBOL_TOKEN (symbol)        = value;
-  SYMBOL_TYPE (symbol) = M4_TOKEN_VOID;
 
-  if (!psymbol)
-    m4_hash_insert ((m4_hash *) symtab, xstrdup (name), symbol);
+  assert (SYMBOL_TOKEN (symbol));
 
   return symbol;
 }
 
-
 /* Return the symbol associated with NAME in the symbol table, creating
-   a new symbol if necessary.  */
+   a new symbol if necessary.  In either case set the symbol's VALUE.  */
 m4_symbol *
-m4_symbol_define (m4_symtab *symtab, const char *name)
+m4_symbol_define (m4_symtab *symtab, const char *name, m4_token *value)
 {
-  m4_symbol *symbol = m4_symbol_lookup (symtab, name);
+  m4_symbol *symbol;
 
-  if (symbol)
-    return symbol;
+  assert (symtab);
+  assert (name);
+  assert (value);
 
-  return m4_symbol_pushdef (symtab, name);
+  symbol = symtab_fetch (symtab, name);
+  if (SYMBOL_TOKEN (symbol))
+    symbol_popval (symbol);
+
+  TOKEN_NEXT (value)   = SYMBOL_TOKEN (symbol);
+  SYMBOL_TOKEN (symbol)        = value;
+
+  assert (SYMBOL_TOKEN (symbol));
+
+  return symbol;
+}
+
+void
+m4_set_symbol_traced (m4_symtab *symtab, const char *name)
+{
+  m4_symbol *symbol;
+
+  assert (symtab);
+  assert (name);
+
+  symbol = symtab_fetch (symtab, name);
+
+  SYMBOL_TRACED (symbol) = TRUE;
 }
 
 
@@ -206,16 +246,34 @@ m4_symbol_popdef (m4_symtab *symtab, con
 {
   m4_symbol **psymbol  = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,
                                                         name);
-  m4_token  *stale     = NULL;
-
   assert (psymbol);
   assert (*psymbol);
 
-  stale = SYMBOL_TOKEN (*psymbol);
+  symbol_popval (*psymbol);
+
+  /* Only remove the hash table entry if the last value in the
+     symbol value stack was successfully removed.  */
+  if (!SYMBOL_TOKEN (*psymbol))
+    if (no_gnu_extensions || !SYMBOL_TRACED (*psymbol))
+      {
+       XFREE (*psymbol);
+       xfree (m4_hash_remove ((m4_hash *) symtab, name));
+      }
+}
+
+
+static void
+symbol_popval (m4_symbol *symbol)
+{
+  m4_token  *stale;
+
+  assert (symbol);
+
+  stale = SYMBOL_TOKEN (symbol);
 
   if (stale)
     {
-      SYMBOL_TOKEN (*psymbol) = TOKEN_NEXT (stale);
+      SYMBOL_TOKEN (symbol) = TOKEN_NEXT (stale);
 
       if (TOKEN_ARG_SIGNATURE (stale))
        {
@@ -226,18 +284,8 @@ m4_symbol_popdef (m4_symtab *symtab, con
        XFREE (TOKEN_TEXT (stale));
       XFREE (stale);
     }
-
-  /* Only remove the hash table entry if the last value in the
-     symbol value stack was successfully removed.  */
-  if (!SYMBOL_TOKEN (*psymbol))
-    if (no_gnu_extensions || !SYMBOL_TRACED (*psymbol))
-      {
-       XFREE (*psymbol);
-       xfree (m4_hash_remove ((m4_hash *) symtab, name));
-      }
 }
 
-
 /* Callback used by m4_symbol_popdef () to release the memory used
    by values in the arg_signature hash.  */
 static int
@@ -256,67 +304,162 @@ arg_destroy (m4_hash *hash, const void *
   return 0;
 }
 
-
-/* Set the type and value of a symbol according to the passed
-   arguments.  This function is usually passed a newly pushdef()d symbol
-   that is already interned in the symbol table.  The traced bit should
-   be appropriately set by the caller.  */
+#if 0
 m4_symbol *
-m4__symbol_set_builtin (m4_symbol *symbol, m4_token *token)
+m4_symbol_push_token (m4_symtab *symtab, const char *name, m4_token *token)
 {
-  assert (symbol);
+  m4_token *next;
+
+  assert (symtab);
+  assert (name);
   assert (token);
-  assert (TOKEN_FUNC (token));
-  assert (TOKEN_HANDLE (token));
-  assert (TOKEN_TYPE (token) == M4_TOKEN_FUNC);
-
-  if (SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT)
-    xfree (SYMBOL_TEXT (symbol));
-
-  SYMBOL_TYPE (symbol)         = TOKEN_TYPE (token);
-  SYMBOL_FUNC (symbol)         = TOKEN_FUNC (token);
-  SYMBOL_HANDLE (symbol)       = TOKEN_HANDLE (token);
-  SYMBOL_FLAGS (symbol)                = TOKEN_FLAGS (token);
-  SYMBOL_ARG_SIGNATURE (symbol)        = TOKEN_ARG_SIGNATURE (token);
-  SYMBOL_MIN_ARGS (symbol)     = TOKEN_MIN_ARGS (token);
-  SYMBOL_MAX_ARGS (symbol)     = TOKEN_MAX_ARGS (token);
+
+  /* If it's a function, it must have come from a module.  */
+  assert ((TOKEN_TYPE (token) != M4_TOKEN_FUNC) || TOKEN_HANDLE (token));
+
+#if M4PARAMS
+  const char *openp  = NULL;
+  const char *params = NULL;
+
+  if (!no_gnu_extensions)
+    {
+      /* If name contains an open paren, then parse before that paren
+        as the actual name, and the rest as a formal parameter list.  */
+      size_t len = 0;
+      for (openp = name; *openp && !M4_IS_OPEN (*openp); ++openp)
+       ++len;
+
+      if (*openp)
+       {
+         name   = xstrzdup (name, len);
+         params = 1+ openp;
+       }
+    }
+
+  if (params)
+    {
+      /* Make a hash table to map formal parameter names to
+        argv offsets, and store that in the symbol's token.  */
+      TOKEN_ARG_SIGNATURE (token) = arg_signature_parse (name, params);
+    }
+#endif
+
+  SYMBOL_TOKEN (symbol) = token;
+
+#if M4PARAMS
+  /* If we split name on open paren, free the copied substring.  */
+  if (params)
+    xfree ((char *) name);
+#endif
 
   return symbol;
 }
+#endif
 
-/* ...and similarly for macro valued symbols.  */
-m4_symbol *
-m4__symbol_set_macro (m4_symbol *symbol, m4_token *token)
+void
+m4_token_copy (m4_token *dest, m4_token *src)
 {
-  assert (symbol);
-  assert (TOKEN_TEXT (token));
-  assert (TOKEN_TYPE (token) == M4_TOKEN_TEXT);
+  m4_token *next;
 
-  if (SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT)
-    xfree (SYMBOL_TEXT (symbol));
+  assert (dest);
+  assert (src);
 
-  SYMBOL_TYPE (symbol)         = TOKEN_TYPE (token);
-  SYMBOL_TEXT (symbol)                 = xstrdup (TOKEN_TEXT (token));
-  SYMBOL_HANDLE (symbol)       = TOKEN_HANDLE (token);
-  SYMBOL_FLAGS (symbol)                = TOKEN_FLAGS (token);
-  SYMBOL_ARG_SIGNATURE (symbol)        = TOKEN_ARG_SIGNATURE (token);
-  SYMBOL_MIN_ARGS (symbol)     = TOKEN_MIN_ARGS (token);
-  SYMBOL_MAX_ARGS (symbol)     = TOKEN_MAX_ARGS (token);
+  if (TOKEN_TYPE (dest) == M4_TOKEN_TEXT)
+    xfree (TOKEN_TEXT (dest));
 
-  return symbol;
+#if M4PARAMS
+  if (TOKEN_ARG_SIGNATURE (dest))
+    {
+      m4_hash_apply (TOKEN_ARG_SIGNATURE (dest), arg_destroy, NULL);
+      m4_hash_delete (TOKEN_ARG_SIGNATURE (dest));
+    }
+#endif
+
+  /* Copy the token contents over, being careful to preserve
+     the next pointer.  */
+  next = TOKEN_NEXT (dest);
+  bcopy (src, dest, sizeof (m4_token));
+  TOKEN_NEXT (dest) = next;
+
+  /* Caller is supposed to free text token strings, so we have to
+     copy the string not just its address in that case.  */
+  if (TOKEN_TYPE (src) == M4_TOKEN_TEXT)
+    TOKEN_TEXT (dest) = xstrdup (TOKEN_TEXT (src));
+
+#if M4PARAMS
+  if (TOKEN_ARG_SIGNATURE (src))
+    TOKEN_ARG_SIGNATURE (dest) = m4_hash_dup (TOKEN_ARG_SIGNATURE (token));
+#endif
 }
 
+#if M4PARAMS
+static m4_hash *
+arg_signature_parse (const char *name, const char *params)
+{
+  m4_hash *arg_signature;
+  const char *commap;
+  int offset;
+
+  assert (params);
+
+  arg_signature = m4_hash_new (M4_ARG_SIGNATURE_DEFAULT_SIZE,
+                       m4_hash_string_hash, m4_hash_string_cmp);
+
+  for (offset = 1; *params && !M4_IS_CLOSE (*params); ++offset)
+    {
+      size_t len = 0;
+
+      /* Skip leading whitespace.  */
+      while (M4_IS_SPACE (*params))
+       ++params;
+
+      for (commap = params; *commap && M4_IS_IDENT (*commap); ++commap)
+       ++len;
+
+      /* Skip trailing whitespace.  */
+      while (M4_IS_SPACE (*commap))
+       ++commap;
+
+      if (!M4_IS_COMMA (*commap) && !M4_IS_CLOSE (*commap))
+       M4ERROR ((EXIT_FAILURE, 0,
+                 _("Error: %s: syntax error in parameter list at char `%c'"),
+                 name, *commap));
+
+      /* Skip parameter delimiter.  */
+      if (M4_IS_COMMA (*commap))
+       ++commap;
+
+      if (len)
+       {
+         struct m4_token_arg *arg = XCALLOC (struct m4_token_arg, 1);
+
+         TOKEN_ARG_INDEX (arg) = offset;
+
+         m4_hash_insert (arg_signature, xstrzdup (params, len), arg);
+
+         params = commap;
+       }
+    }
+
+  if (!M4_IS_CLOSE (*commap))
+    M4WARN ((warning_status, 0,
+            _("Warning: %s: unterminated parameter list"), name));
+
+  return arg_signature;
+}
+#endif
 
 
 
 #ifdef DEBUG_SYM
 
-static int  symtab_print_list (const void *name, void *symbol, void *ignored);
-static void symtab_debug      (void)
-static void symtab_dump              (void);
+static int  symtab_print_list (m4_hash *hash, const void *name, void *symbol,
+                              void *ignored);
+static void symtab_debug      (m4_symtab *symtab);
+static void symtab_dump              (m4_symtab *symtab);
 
 static void
-symtab_dump (void)
+symtab_dump (m4_symtab *symtab)
 {
   m4_hash_iterator *place = 0;
 
@@ -385,9 +528,9 @@ symtab_debug (m4_symtab *symtab)
        printf (_("Name `%s' is unknown\n"), text);
 
       if (delete)
-       (void) m4_symbol_delete (symtab, text);
+       m4_symbol_delete (symtab, text);
       else
-       (void) m4_symbol_define (symtab, text);
+       symtab_fetch (symtab, text);
     }
   m4_symtab_apply (symtab, symtab_print_list, NULL);
 }
Index: modules/m4.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/m4.c,v
retrieving revision 1.40
diff -u -p -u -r1.40 m4.c
--- modules/m4.c 16 Jun 2003 16:29:06 -0000 1.40
+++ modules/m4.c 17 Jun 2003 15:17:24 -0000
@@ -148,28 +148,23 @@ M4INIT_HANDLER (m4)
 
 M4BUILTIN_HANDLER (define)
 {
-  if (TOKEN_TYPE (argv[1]) != M4_TOKEN_TEXT)
-    return;
-
-  if (argc == 2)
+  if (TOKEN_TYPE (argv[1]) == M4_TOKEN_TEXT)
     {
-      m4_macro_define (context, M4ARG (1), NULL);
-      return;
-    }
+      m4_token *token = XCALLOC (m4_token, 1);
 
-  switch (TOKEN_TYPE (argv[2]))
-    {
-    case M4_TOKEN_TEXT:
-      m4_macro_define (context, M4ARG (1), argv[2]);
-      return;
-
-    case M4_TOKEN_FUNC:
-      m4_builtin_define (context, M4ARG (1), argv[2]);
-      return;
-    }
+      if (argc == 2)
+       {
+         TOKEN_TYPE (token) = M4_TOKEN_TEXT;
+         TOKEN_TEXT (token) = xstrdup ("");
+       }
+      else
+       {
+         m4_token_copy (token, argv[2]);
+         TOKEN_NEXT (token) = NULL;
+       }
 
-  /*NOTREACHED*/
-  assert (0);
+      m4_symbol_define (M4SYMTAB, M4ARG (1), token);
+    }
 }
 
 M4BUILTIN_HANDLER (undefine)
@@ -183,28 +178,23 @@ M4BUILTIN_HANDLER (undefine)
 
 M4BUILTIN_HANDLER (pushdef)
 {
-  if (TOKEN_TYPE (argv[1]) != M4_TOKEN_TEXT)
-    return;
-
-  if (argc == 2)
+  if (TOKEN_TYPE (argv[1]) == M4_TOKEN_TEXT)
     {
-      m4_macro_pushdef (context, M4ARG (1), NULL);
-      return;
-    }
+      m4_token *token = XCALLOC (m4_token, 1);
 
-  switch (TOKEN_TYPE (argv[2]))
-    {
-    case M4_TOKEN_TEXT:
-      m4_macro_pushdef (context, M4ARG (1), argv[2]);
-      return;
-
-    case M4_TOKEN_FUNC:
-      m4_builtin_pushdef (context, M4ARG (1), argv[2]);
-      return;
-    }
+      if (argc == 2)
+       {
+         TOKEN_TYPE (token) = M4_TOKEN_TEXT;
+         TOKEN_TEXT (token) = xstrdup ("");
+       }
+      else
+       {
+         m4_token_copy (token, argv[2]);
+         TOKEN_NEXT (token) = NULL;
+       }
 
-  /*NOTREACHED*/
-  assert (0);
+      m4_symbol_pushdef (M4SYMTAB, M4ARG (1), token);
+    }
 }
 
 M4BUILTIN_HANDLER (popdef)
Index: src/freeze.c
===================================================================
RCS file: /cvsroot/m4/m4/src/freeze.c,v
retrieving revision 1.27
diff -u -p -u -r1.27 freeze.c
--- src/freeze.c 16 Jun 2003 16:29:06 -0000 1.27
+++ src/freeze.c 17 Jun 2003 15:17:24 -0000
@@ -473,23 +473,20 @@ reload_frozen_state (m4 *context, const 
 
          if (bp)
            {
-             m4_token token;
-             int flags = 0;
+             m4_token *token = XCALLOC (m4_token, 1);
 
              if (bp->groks_macro_args)
-               BIT_SET (flags, TOKEN_MACRO_ARGS_BIT);
+               BIT_SET (TOKEN_FLAGS (token), TOKEN_MACRO_ARGS_BIT);
              if (bp->blind_if_no_args)
-               BIT_SET (flags, TOKEN_BLIND_ARGS_BIT);
+               BIT_SET (TOKEN_FLAGS (token), TOKEN_BLIND_ARGS_BIT);
 
-             bzero (&token, sizeof (m4_token));
-             TOKEN_TYPE (&token)       = M4_TOKEN_FUNC;
-             TOKEN_FUNC (&token)       = bp->func;
-             TOKEN_HANDLE (&token)     = handle;
-             TOKEN_FLAGS (&token)      = flags;
-             TOKEN_MIN_ARGS (&token)   = bp->min_args;
-             TOKEN_MAX_ARGS (&token)   = bp->max_args;
+             TOKEN_TYPE (token)        = M4_TOKEN_FUNC;
+             TOKEN_FUNC (token)        = bp->func;
+             TOKEN_HANDLE (token)      = handle;
+             TOKEN_MIN_ARGS (token)    = bp->min_args;
+             TOKEN_MAX_ARGS (token)    = bp->max_args;
 
-             m4_builtin_pushdef (context, string[0], &token);
+             m4_symbol_pushdef (M4SYMTAB, string[0], token);
            }
          else
            M4ERROR ((warning_status, 0,
@@ -658,7 +655,7 @@ reload_frozen_state (m4 *context, const 
 
        /* Enter a macro having an expansion text as a definition.  */
        {
-         m4_token token;
+         m4_token *token = XCALLOC (m4_token, 1);
          lt_dlhandle handle = 0;
 
          if (number[2] > 0)
@@ -666,13 +663,12 @@ reload_frozen_state (m4 *context, const 
              if (strcmp (m4_get_module_name (handle), string[2]) == 0)
                break;
 
-         bzero (&token, sizeof (m4_token));
-         TOKEN_TYPE (&token)           = M4_TOKEN_TEXT;
-         TOKEN_TEXT (&token)           = string[1];
-         TOKEN_HANDLE (&token)         = handle;
-         TOKEN_MAX_ARGS (&token)       = -1;
+         TOKEN_TYPE (token)            = M4_TOKEN_TEXT;
+         TOKEN_TEXT (token)            = xstrdup (string[1]);
+         TOKEN_HANDLE (token)          = handle;
+         TOKEN_MAX_ARGS (token)        = -1;
 
-         m4_macro_pushdef (context, string[0], &token);
+         m4_symbol_pushdef (M4SYMTAB, string[0], token);
        }
        break;
 
Index: src/main.c
===================================================================
RCS file: /cvsroot/m4/m4/src/main.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 main.c
--- src/main.c 16 Jun 2003 10:43:45 -0000 1.38
+++ src/main.c 17 Jun 2003 15:17:24 -0000
@@ -420,11 +420,6 @@ warranty; not even for MERCHANTABILITY o
   /* Handle deferred command line macro definitions.  Must come after
      initialisation of the symbol table.  */
   {
-    m4_token token;
-
-    bzero (&token, sizeof (token));
-    TOKEN_TYPE (&token)                = M4_TOKEN_TEXT;
-
     defines = head;
 
     while (defines != NULL)
@@ -436,13 +431,19 @@ warranty; not even for MERCHANTABILITY o
        switch (defines->code)
          {
          case 'D':
-           macro_value = strchr (defines->macro, '=');
-           if (macro_value == NULL)
-             macro_value = "";
-           else
-             *macro_value++ = '\0';
-           TOKEN_TEXT (&token) = macro_value;
-           m4_macro_define (context, defines->macro, &token);
+           {
+             m4_token *token = XCALLOC (m4_token, 1);
+
+             macro_value = strchr (defines->macro, '=');
+             if (macro_value == NULL)
+               macro_value = "";
+             else
+               *macro_value++ = '\0';
+             TOKEN_TEXT (token) = xstrdup (macro_value);
+             TOKEN_TYPE (token) = M4_TOKEN_TEXT;
+
+             m4_symbol_pushdef (M4SYMTAB, defines->macro, token);
+           }
            break;
 
          case 'U':
@@ -450,8 +451,7 @@ warranty; not even for MERCHANTABILITY o
            break;
 
          case 't':
-           symbol = m4_symbol_define (M4SYMTAB, defines->macro);
-           SYMBOL_TRACED (symbol) = TRUE;
+           m4_set_symbol_traced (M4SYMTAB, defines->macro);
            break;
 
          case 'm':

reply via email to

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