m4-patches
[Top][All Lists]
Advanced

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

FYI: 11-gary-eliminate-global-symtab.patch


From: Gary V. Vaughan
Subject: FYI: 11-gary-eliminate-global-symtab.patch
Date: Mon, 16 Jun 2003 11:47:06 +0100
User-agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.3) Gecko/20030312

commited 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>

        Begin work on lifting the curse of the global variables.  To start
        with create a `struct m4' context container, and replace
        `m4__symtab' with `context->symtab' throughout.  This means
        initialising a context container in main, and adjusting many
        functions between main and the module entry points so that the
        container gets passed through.  It would have been nice to
        defer this until after 1.5, but it has a major effect on the
        user's module writing ABI, so it needs to be addressed now - at
        least in the areas that impact the ABI.  An interrelatated change
        in the symtab API removes the dependency on a global symbol table,
        and instead focuses on a passed table (from the context
        container).

        * TODO: Reminders for finishing context functionality.
        * m4/Makefile.am (libm4_la_SOURCES): Add m4.c.
        * m4/m4.c: New file. Manage new struct m4 objects to eliminate
        global variables and eventually allow m4 to be reentrant.
        * m4/m4private.h (m4): Define the new structure here...
        (M4_SYMTAB, m4_get_symtab): ...so we can have fast accessors that
        don't carry the overhead of a function call.
        * m4/m4module.h: Prototype extern functions from m4/m4.c.
        (m4): Declare type for new struct m4 objects.
        (M4SYMTAB): User macro to ease finding the symbol table for the
        current context for module developers.
        (m4_symbol_token): Renamed to m4_symbol_set_token which contains a
        verb.
        (M4_BUILTIN, m4_builtin_func, M4_BUILTIN_HANDLER)
        (m4_builtin_define, m4_builtin_pushdef, m4_builtin_table_install)
        (m4_call_macro, m4_dump_symbols, m4_expand_input)
        (M4_FINISH_HANDLER, M4_INIT_HANDLE, m4_macro_define)
        (m4_macro_pushdef, m4_macro_table_install, m4_module_load)
        (m4_module_unload, m4_process_macro, m4_symbol_set_token): Add an
        m4* context parameter. Changed definitions and all callers.
        (m4_symtab): Alias for m4_hash to decouple the
        m4_symtab api from m4_hash.
        (m4_symtab_apply, m4_symtab_apply_func): Use m4_symtab instead of
        m4_hash.
        (m4_symtab_create): New function to return an initialised
        m4_symtab.
        (m4_symtab_delete): New function to delete an m4_symtab's memory.
        (m4_symbol_define, m4_symbol_delete, m4_symbol_lookup)
        (m4_symbol_popdef, m4_symbol_pushdef): Add an m4_symtab parameter
        instead of simply using the global m4__symtab.  Changed
        definitions and all callers.
        * m4/m4private.h (m4__symtab_remove_module_references): Ditto.
        * m4/symtab.c (m4__symtab_init, m4__symtab_exit): Removed.
        * src/main.c (main): Create a context and use that instead of the
        former global m4__symtab.

Index: TODO
===================================================================
RCS file: /cvsroot/m4/m4/TODO,v
retrieving revision 1.9
diff -u -p -u -r1.9 TODO
--- TODO 12 Oct 2001 19:57:29 -0000 1.9
+++ TODO 16 Jun 2003 10:40:45 -0000
@@ -88,6 +88,10 @@ for any of these ideas or if you have ot
     the internals:  we should enable attaching these values to text macros
     too.
 
+  + The context parameter is just a placeholder for formerly global state.
+    We should be making the library reentrant so that multiple instances
+    of m4 can be run in the same process at the same time.
+
 * MODULE SPECIFIC ISSUES
 
   + Some way of linking a module statically is needed, for systems
@@ -107,6 +111,10 @@ for any of these ideas or if you have ot
     set of builtins for autoload from the installed module directory on first
     use.  A new cli parameter would inhibit initialisation from this script,
     so that customised m4 interpreters could be built on the fly!
+
+  + The module loader needs to differentiate between modules that are in
+    memory and modules that are loaded (i.e. visible) from various context
+    structures.
 
   + The perl module should only be built if a suitable perl interpreter
     is found on the build machine.
Index: m4/Makefile.am
===================================================================
RCS file: /cvsroot/m4/m4/m4/Makefile.am,v
retrieving revision 1.15
diff -u -p -u -r1.15 Makefile.am
--- m4/Makefile.am 30 May 2003 15:13:31 -0000 1.15
+++ m4/Makefile.am 16 Jun 2003 10:40:48 -0000
@@ -37,7 +37,7 @@ EXTRA_DIST = $(EXTRA_HEADERS) obstack.c
 
 lib_LTLIBRARIES                = libm4.la
 libm4_la_SOURCES       = builtin.c debug.c error.c hash.c \
-                         input.c ltdl.c macro.c module.c output.c \
+                         input.c ltdl.c m4.c macro.c module.c output.c \
                          path.c regex.c symtab.c syntax.c utility.c
 libm4_la_LIBADD                = $(LTLIBOBJS) $(LTLIBINTL) $(LIBADD_DL)
 
Index: m4/builtin.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/builtin.c,v
retrieving revision 1.17
diff -u -p -u -r1.17 builtin.c
--- m4/builtin.c 13 Jun 2003 13:05:45 -0000 1.17
+++ m4/builtin.c 16 Jun 2003 10:40:48 -0000
@@ -72,9 +72,10 @@ m4_builtin_find_by_func (const m4_builti
 }
 
 m4_symbol *
-m4_symbol_token (const char *name, m4_symbol_type type, m4_token *token,
-                m4_symbol *(*getter) (const char *name),
-                m4_symbol *(*setter) (m4_symbol *, m4_token *))
+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;
@@ -102,7 +103,7 @@ m4_symbol_token (const char *name, m4_sy
     }
 
   /* Get a symbol table entry for the name.  */
-  symbol = (*getter) (name);
+  symbol = (*getter) (M4SYMTAB, name);
 
   if (symbol)
     {
@@ -148,14 +149,14 @@ m4_arg_signature_parse (const char *name
 {
   m4_hash *arg_signature;
   const char *commap;
-  int index;
+  int offset;
 
   assert (params);
 
   arg_signature = m4_hash_new (M4_ARG_SIGNATURE_DEFAULT_SIZE,
                        m4_hash_string_hash, m4_hash_string_cmp);
 
-  for (index = 1; *params && !M4_IS_CLOSE (*params); ++index)
+  for (offset = 1; *params && !M4_IS_CLOSE (*params); ++offset)
     {
       size_t len = 0;
 
@@ -183,7 +184,7 @@ m4_arg_signature_parse (const char *name
        {
          struct m4_token_arg *arg = XCALLOC (struct m4_token_arg, 1);
 
-         TOKEN_ARG_INDEX (arg) = index;
+         TOKEN_ARG_INDEX (arg) = offset;
 
          m4_hash_insert (arg_signature, xstrzdup (params, len), arg);
 
@@ -199,7 +200,8 @@ m4_arg_signature_parse (const char *name
 }
 
 void
-m4_builtin_table_install (lt_dlhandle handle, const m4_builtin *table)
+m4_builtin_table_install (m4 *context, lt_dlhandle handle,
+                         const m4_builtin *table)
 {
   const m4_builtin *bp;
   m4_token token;
@@ -235,7 +237,7 @@ m4_builtin_table_install (lt_dlhandle ha
       TOKEN_MIN_ARGS (&token)  = bp->min_args;
       TOKEN_MAX_ARGS (&token)  = bp->max_args;
 
-      m4_builtin_pushdef (name, &token);
+      m4_builtin_pushdef (context, name, &token);
 
       if (prefix_all_builtins)
        xfree (name);
@@ -243,7 +245,7 @@ m4_builtin_table_install (lt_dlhandle ha
 }
 
 void
-m4_macro_table_install (lt_dlhandle handle, const m4_macro *table)
+m4_macro_table_install (m4 *context, lt_dlhandle handle, const m4_macro *table)
 {
   const m4_macro *mp;
   m4_token token;
@@ -255,6 +257,6 @@ m4_macro_table_install (lt_dlhandle hand
   for (mp = table; mp->name != NULL; mp++)
     {
       TOKEN_TEXT (&token)      = (char *) mp->value;
-      m4_macro_pushdef (mp->name, &token);
+      m4_macro_pushdef (context, mp->name, &token);
     }
 }
Index: m4/m4.c
===================================================================
RCS file: m4/m4.c
diff -N m4/m4.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/m4.c 16 Jun 2003 10:40:48 -0000
@@ -0,0 +1,52 @@
+/* GNU m4 -- A simple macro processor
+   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 2001
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307  USA
+*/
+
+#include "m4private.h"
+
+m4 *
+m4_create (void)
+{
+  m4 *context = XMALLOC (m4, 1);
+
+  M4_SYMTAB (context) = m4_symtab_create (0);
+
+  return context;
+}
+
+void
+m4_delete (m4 *context)
+{
+  assert (context);
+
+  if (M4_SYMTAB (context))
+    m4_symtab_delete (M4_SYMTAB (context));
+
+  xfree (context);
+
+}
+
+#undef m4_get_symtab
+m4_symtab *
+m4_get_symtab (m4 *context)
+{
+  assert (context);
+
+  return m4_get_symtab (context);
+}
Index: m4/m4module.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4module.h,v
retrieving revision 1.45
diff -u -p -u -r1.45 m4module.h
--- m4/m4module.h 13 Jun 2003 13:54:36 -0000 1.45
+++ m4/m4module.h 16 Jun 2003 10:40:48 -0000
@@ -30,12 +30,14 @@ BEGIN_C_DECLS
 
 /* Various declarations.  */
 
+typedef struct m4              m4;
 typedef struct m4_module_data  m4_module_data;
 typedef struct m4_symbol       m4_symbol;
 typedef struct m4_token                m4_token;
+typedef struct m4_hash         m4_symtab;
 
 
-typedef void m4_builtin_func (struct obstack *, int, m4_token **);
+typedef void m4_builtin_func (m4 *, struct obstack *, int, m4_token **);
 typedef void *m4_module_func (const char *);
 
 typedef struct {
@@ -57,13 +59,22 @@ typedef struct {
 
 
 
+/* --- CONTEXT MANAGEMENT --- */
+
+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 --- */
 
-typedef void m4_module_init_func   (lt_dlhandle, struct obstack*);
-typedef void m4_module_finish_func (lt_dlhandle, struct obstack*);
+typedef void m4_module_init_func   (m4 *, lt_dlhandle, struct obstack*);
+typedef void m4_module_finish_func (m4 *, lt_dlhandle, struct obstack*);
 
-extern lt_dlhandle  m4_module_load   (const char*, struct obstack*);
-extern void        m4_module_unload (const char*, struct obstack*);
+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_module_name     (lt_dlhandle);
 extern m4_builtin  *m4_module_builtins (lt_dlhandle);
@@ -73,20 +84,24 @@ extern m4_macro        *m4_module_macros   (
 /* --- SYMBOL TABLE MANAGEMENT --- */
 
 
-typedef struct m4_symtab m4_symtab;
-
-typedef int m4_symtab_apply_func (m4_hash *hash, const void *key, void *value, 
void *data);
-
-extern int       m4_symtab_apply       (m4_symtab_apply_func*, void*);
-
-extern m4_symbol *m4_symbol_lookup     (const char *);
-extern m4_symbol *m4_symbol_pushdef    (const char *);
-extern m4_symbol *m4_symbol_define     (const char *);
-extern void       m4_symbol_popdef     (const char *);
-extern void       m4_symbol_delete     (const char *);
+typedef int m4_symtab_apply_func (m4_symtab *symtab, const void *key, void 
*value, void *data);
 
-#define m4_symbol_delete(name)                                         \
-       while (m4_symbol_lookup (name)) m4_symbol_popdef (name)
+extern m4_symtab *m4_symtab_create  (size_t);
+extern void      m4_symtab_delete  (m4_symtab*);
+extern int       m4_symtab_apply   (m4_symtab*, m4_symtab_apply_func*, void*);
+
+#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 void       m4_symbol_popdef  (m4_symtab*, const char *);
+extern void       m4_symbol_delete  (m4_symtab*, const char *);
+
+#define m4_symbol_delete(symtab, name)                 M4_STMT_START { \
+       while (m4_symbol_lookup ((symtab), (name)))                     \
+           m4_symbol_popdef ((symtab), (name));        } M4_STMT_END
 
 
 /* Various different token types.  */
@@ -112,15 +127,15 @@ typedef enum {
 
 /* --- MACRO (and builtin) MANAGEMENT --- */
 
-extern m4_symbol *m4_symbol_token (const char *name, m4_symbol_type type,
-                       m4_token *token,
-                       m4_symbol *(*getter) (const char *name),
+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_macro_table_install (lt_dlhandle handle,
-                                         const m4_macro *table);
-extern void      m4_builtin_table_install (lt_dlhandle handle,
-                                        const m4_builtin *table);
+extern void      m4_macro_table_install   (m4 *context, lt_dlhandle handle,
+                                           const m4_macro *table);
+extern void      m4_builtin_table_install (m4 *context, lt_dlhandle handle,
+                                           const m4_builtin *table);
 
 extern const m4_builtin *m4_builtin_find_by_name (
                                const m4_builtin *, const char *);
@@ -133,17 +148,17 @@ extern const m4_builtin *m4_builtin_find
 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(name, macro)                                  \
-       m4_symbol_token ((name), M4_TOKEN_TEXT, (macro),                \
+#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(name, macro)                                   \
-       m4_symbol_token ((name), M4_TOKEN_TEXT, (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(name, builtin)                              \
-       m4_symbol_token ((name), M4_TOKEN_FUNC, (builtin),              \
+#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(name, builtin)                               \
-       m4_symbol_token ((name), M4_TOKEN_FUNC, (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 *);
@@ -154,23 +169,23 @@ extern m4_builtin_func *m4_token_func       
 
 #define M4BUILTIN(name)                                        \
   static void CONC(builtin_, name)                             \
-       (struct obstack *, int , m4_token **);
+   (m4 *context, struct obstack *obs, int argc, m4_token **argv);
 
 #define M4BUILTIN_HANDLER(name)                                \
-  static void CONC(builtin_, name) (obs, argc, argv)           \
-       struct obstack *obs; int argc; m4_token **argv;
+  static void CONC(builtin_, name)                             \
+   (m4 *context, struct obstack *obs, int argc, m4_token **argv)
 
 #define M4INIT_HANDLER(name)                                   \
   void CONC(name, CONC(_LTX_, m4_init_module))                         \
-       (lt_dlhandle handle, struct obstack *obs);              \
+       (m4 *context, lt_dlhandle handle, struct obstack *obs); \
   void CONC(name, CONC(_LTX_, m4_init_module))                         \
-       (lt_dlhandle handle, struct obstack *obs)
+       (m4 *context, lt_dlhandle handle, struct obstack *obs)
 
 #define M4FINISH_HANDLER(name)                                 \
   void CONC(name, CONC(_LTX_, m4_finish_module))               \
-       (lt_dlhandle handle, struct obstack *obs);              \
+       (m4 *context, lt_dlhandle handle, struct obstack *obs); \
   void CONC(name, CONC(_LTX_, m4_finish_module))               \
-       (lt_dlhandle handle, struct obstack *obs)
+       (m4 *context, lt_dlhandle handle, struct obstack *obs)
 
 /* Error handling.  */
 #define M4ERROR(Arglist) (error Arglist)
@@ -332,9 +347,13 @@ extern int m4_sysval;
 extern int m4_expansion_level;
 
 extern const char *m4_expand_ranges (const char *s, struct obstack *obs);
-extern void m4_expand_input (void);
-extern void m4_call_macro (m4_symbol *, int, m4_token **, struct obstack *);
-extern void m4_process_macro (struct obstack *obs, m4_symbol *symbol, int 
argc, m4_token **argv);
+extern void       m4_expand_input  (m4 *context);
+extern void       m4_call_macro    (m4_symbol *symbol, m4 *context,
+                                    struct obstack *obs, int argc,
+                                    m4_token **argv);
+extern void       m4_process_macro (m4_symbol *symbol, m4 *context,
+                                    struct obstack *obs, int argc,
+                                    m4_token **argv);
 
 
 
@@ -481,7 +500,7 @@ struct m4_dump_symbol_data
 };
 
 extern int m4_dump_symbol (const void *name, void *symbol, void *data);
-extern void m4_dump_symbols (struct m4_dump_symbol_data *data, int argc, 
m4_token **argv, boolean complain);
+extern void m4_dump_symbols (m4 *context, struct m4_dump_symbol_data *data, 
int argc, m4_token **argv, boolean complain);
 
 
 
Index: m4/m4private.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4private.h,v
retrieving revision 1.20
diff -u -p -u -r1.20 m4private.h
--- m4/m4private.h 13 Jun 2003 13:05:45 -0000 1.20
+++ m4/m4private.h 16 Jun 2003 10:40:48 -0000
@@ -27,6 +27,19 @@
 #include <assert.h>
 #include <m4module.h>
 
+
+
+/* --- CONTEXT MANAGEMENT --- */
+
+struct m4 {
+  m4_symtab *symtab;
+};
+
+#define M4_SYMTAB(context) ((context)->symtab)
+
+#define m4_get_symtab(context) ((context)->symtab)
+
+
 
 /* --- MODULE MANAGEMENT --- */
 
@@ -37,21 +50,17 @@
 #define FINISH_SYMBOL          "m4_finish_module"
 
 extern void        m4__module_init (void);
-extern lt_dlhandle  m4__module_open (const char *name, struct obstack *obs);
-extern void        m4__module_exit (void);
+extern lt_dlhandle  m4__module_open (m4 *context, const char *name,
+                                    struct obstack *obs);
+extern void        m4__module_exit (m4 *context);
 
 
 
 /* --- SYMBOL TABLE MANAGEMENT --- */
 
-extern m4_hash *m4__symtab;
-
-#define m4_symtab_apply(func, data)                            \
-       m4_hash_apply (m4__symtab, (m4_hash_apply_func *)(func), (data))
-
-extern void    m4__symtab_init                         (void);
-extern void    m4__symtab_remove_module_references     (lt_dlhandle);
-extern void    m4__symtab_exit                         (void);
+extern void    m4__symtab_init                     (void);
+extern void    m4__symtab_remove_module_references (m4_symtab*, lt_dlhandle);
+extern void    m4__symtab_exit                     (void);
 
 
 /* TRUE iff strlen(rquote) == strlen(lquote) == 1 */
Index: m4/macro.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/macro.c,v
retrieving revision 1.24
diff -u -p -u -r1.24 macro.c
--- m4/macro.c 13 Jun 2003 13:05:45 -0000 1.24
+++ m4/macro.c 16 Jun 2003 10:40:50 -0000
@@ -24,8 +24,15 @@
 #include "m4.h"
 #include "m4private.h"
 
-static void expand_macro (const char *name, m4_symbol *);
-static void expand_token (struct obstack *, m4__token_type, m4_token *);
+static void    collect_arguments (m4 *context, const char *name,
+                                 m4_symbol *symbol, struct obstack *argptr,
+                                 struct obstack *arguments);
+static void    expand_macro      (m4 *context, const char *name,
+                                 m4_symbol *symbol);
+static void    expand_token      (m4 *context, struct obstack *obs,
+                                 m4__token_type type, m4_token *token);
+static boolean expand_argument   (m4 *context, struct obstack *obs,
+                                 m4_token *argp);
 
 /* Current recursion level in expand_macro ().  */
 int m4_expansion_level = 0;
@@ -35,13 +42,13 @@ static int macro_call_id = 0;
 
 /* This function reads all input, and expands each token, one at a time.  */
 void
-m4_expand_input (void)
+m4_expand_input (m4 *context)
 {
   m4__token_type type;
   m4_token token;
 
   while ((type = m4_next_token (&token)) != M4_TOKEN_EOF)
-    expand_token ((struct obstack *) NULL, type, &token);
+    expand_token (context, (struct obstack *) NULL, type, &token);
 }
 
 
@@ -50,7 +57,8 @@ m4_expand_input (void)
    macro definition.  If they have, they are expanded as macros, otherwise
    the text are just copied to the output.  */
 static void
-expand_token (struct obstack *obs, m4__token_type type, m4_token *token)
+expand_token (m4 *context, struct obstack *obs,
+             m4__token_type type, m4_token *token)
 {
   m4_symbol *symbol;
   char *text = xstrdup (TOKEN_TEXT (token));
@@ -74,7 +82,7 @@ expand_token (struct obstack *obs, m4__t
        if (M4_IS_ESCAPE(*textp))
          ++textp;
 
-       symbol = m4_symbol_lookup (textp);
+       symbol = m4_symbol_lookup (M4SYMTAB, textp);
        if (symbol == NULL
            || SYMBOL_TYPE (symbol) == M4_TOKEN_VOID
            || (SYMBOL_TYPE (symbol) == M4_TOKEN_FUNC
@@ -84,7 +92,7 @@ expand_token (struct obstack *obs, m4__t
            m4_shipout_text (obs, text, strlen (text));
          }
        else
-         expand_macro (textp, symbol);
+         expand_macro (context, textp, symbol);
       }
       break;
 
@@ -106,7 +114,7 @@ expand_token (struct obstack *obs, m4__t
    the last for the active macro call.  The arguments are build on the
    obstack OBS, indirectly through expand_token ().     */
 static boolean
-expand_argument (struct obstack *obs, m4_token *argp)
+expand_argument (m4 *context, struct obstack *obs, m4_token *argp)
 {
   m4__token_type type;
   m4_token token;
@@ -149,7 +157,7 @@ expand_argument (struct obstack *obs, m4
            paren_level++;
          else if (M4_IS_CLOSE (*text))
            paren_level--;
-         expand_token (obs, type, &token);
+         expand_token (context, obs, type, &token);
          break;
 
        case M4_TOKEN_EOF:
@@ -160,7 +168,7 @@ expand_argument (struct obstack *obs, m4
        case M4_TOKEN_WORD:
        case M4_TOKEN_SPACE:
        case M4_TOKEN_STRING:
-         expand_token (obs, type, &token);
+         expand_token (context, obs, type, &token);
          break;
 
        case M4_TOKEN_MACDEF:
@@ -178,11 +186,71 @@ expand_argument (struct obstack *obs, m4
     }
 }
 
+
+/* The macro expansion is handled by expand_macro ().  It parses the
+   arguments, using collect_arguments (), and builds a table of pointers to
+   the arguments.  The arguments themselves are stored on a local obstack.
+   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 ().  */
+static void
+expand_macro (m4 *context, const char *name, m4_symbol *symbol)
+{
+  struct obstack arguments;
+  struct obstack argptr;
+  m4_token **argv;
+  int argc;
+  struct obstack *expansion;
+  const char *expanded;
+  boolean traced;
+  int my_call_id;
+
+  m4_expansion_level++;
+  if (m4_expansion_level > nesting_limit)
+    M4ERROR ((EXIT_FAILURE, 0, _("\
+ERROR: Recursion limit of %d exceeded, use -L<N> to change it"),
+             nesting_limit));
+
+  macro_call_id++;
+  my_call_id = macro_call_id;
+
+  traced = (boolean) ((debug_level & M4_DEBUG_TRACE_ALL) || SYMBOL_TRACED 
(symbol));
+
+  obstack_init (&argptr);
+  obstack_init (&arguments);
+
+  if (traced && (debug_level & M4_DEBUG_TRACE_CALL))
+    m4_trace_prepre (name, my_call_id);
+
+  collect_arguments (context, name, symbol, &argptr, &arguments);
+
+  argc = obstack_object_size (&argptr) / sizeof (m4_token *);
+  argv = (m4_token **) obstack_finish (&argptr);
+
+  if (traced)
+    m4_trace_pre (name, my_call_id, argc, argv);
+
+  expansion = m4_push_string_init ();
+  if (!m4_bad_argc (argc, argv,
+                   SYMBOL_MIN_ARGS (symbol), SYMBOL_MAX_ARGS (symbol)))
+    m4_call_macro (symbol, context, expansion, argc, argv);
+  expanded = m4_push_string_finish ();
+
+  if (traced)
+    m4_trace_post (name, my_call_id, argc, argv, expanded);
+
+  --m4_expansion_level;
+
+  obstack_free (&arguments, NULL);
+  obstack_free (&argptr, NULL);
+}
+
 /* Collect all the arguments to a call of the macro SYMBOL (called NAME).
    The arguments are stored on the obstack ARGUMENTS and a table of pointers
    to the arguments on the obstack ARGPTR.  */
 static void
-collect_arguments (const char *name, m4_symbol *symbol,
+collect_arguments (m4 *context, const char *name, m4_symbol *symbol,
                   struct obstack *argptr, struct obstack *arguments)
 {
   int ch;                      /* lookahead for ( */
@@ -205,7 +273,7 @@ collect_arguments (const char *name, m4_
       m4_next_token (&token);          /* gobble parenthesis */
       do
        {
-         more_args = expand_argument (arguments, &token);
+         more_args = expand_argument (context, arguments, &token);
 
          if (!groks_macro_args && TOKEN_TYPE (&token) == M4_TOKEN_FUNC)
            {
@@ -219,7 +287,6 @@ collect_arguments (const char *name, m4_
       while (more_args);
     }
 }
-
 
 
 /* The actual call of a macro is handled by m4_call_macro ().
@@ -229,17 +296,17 @@ collect_arguments (const char *name, m4_
    the call, stored in the ARGV table.  The expansion is left on
    the obstack EXPANSION.  Macro tracing is also handled here.  */
 void
-m4_call_macro (m4_symbol *symbol, int argc, m4_token **argv,
-              struct obstack *expansion)
+m4_call_macro (m4_symbol *symbol, m4 *context, struct obstack *expansion,
+              int argc, m4_token **argv)
 {
   switch (SYMBOL_TYPE (symbol))
     {
     case M4_TOKEN_FUNC:
-      (*SYMBOL_FUNC (symbol)) (expansion, argc, argv);
+      (*SYMBOL_FUNC (symbol)) (context, expansion, argc, argv);
       break;
 
     case M4_TOKEN_TEXT:
-      m4_process_macro (expansion, symbol, argc, argv);
+      m4_process_macro (symbol, context, expansion, argc, argv);
       break;
 
     case M4_TOKEN_VOID:
@@ -249,73 +316,14 @@ m4_call_macro (m4_symbol *symbol, int ar
     }
 }
 
-/* The macro expansion is handled by expand_macro ().  It parses the
-   arguments, using collect_arguments (), and builds a table of pointers to
-   the arguments.  The arguments themselves are stored on a local obstack.
-   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 ().  */
-static void
-expand_macro (const char *name, m4_symbol *symbol)
-{
-  struct obstack arguments;
-  struct obstack argptr;
-  m4_token **argv;
-  int argc;
-  struct obstack *expansion;
-  const char *expanded;
-  boolean traced;
-  int my_call_id;
-
-  m4_expansion_level++;
-  if (m4_expansion_level > nesting_limit)
-    M4ERROR ((EXIT_FAILURE, 0, _("\
-ERROR: Recursion limit of %d exceeded, use -L<N> to change it"),
-             nesting_limit));
-
-  macro_call_id++;
-  my_call_id = macro_call_id;
-
-  traced = (boolean) ((debug_level & M4_DEBUG_TRACE_ALL) || SYMBOL_TRACED 
(symbol));
-
-  obstack_init (&argptr);
-  obstack_init (&arguments);
-
-  if (traced && (debug_level & M4_DEBUG_TRACE_CALL))
-    m4_trace_prepre (name, my_call_id);
-
-  collect_arguments (name, symbol, &argptr, &arguments);
-
-  argc = obstack_object_size (&argptr) / sizeof (m4_token *);
-  argv = (m4_token **) obstack_finish (&argptr);
-
-  if (traced)
-    m4_trace_pre (name, my_call_id, argc, argv);
-
-  expansion = m4_push_string_init ();
-  if (!m4_bad_argc (argc, argv,
-                   SYMBOL_MIN_ARGS (symbol), SYMBOL_MAX_ARGS (symbol)))
-    m4_call_macro (symbol, argc, argv, expansion);
-  expanded = m4_push_string_finish ();
-
-  if (traced)
-    m4_trace_post (name, my_call_id, argc, argv, expanded);
-
-  --m4_expansion_level;
-
-  obstack_free (&arguments, NULL);
-  obstack_free (&argptr, NULL);
-}
-
 /* This function handles all expansion of user defined and predefined
    macros.  It is called with an obstack OBS, where the macros expansion
    will be placed, as an unfinished object.  SYMBOL points to the macro
    definition, giving the expansion text.  ARGC and ARGV are the arguments,
    as usual.  */
 void
-m4_process_macro (struct obstack *obs, m4_symbol *symbol, int argc,
-                 m4_token **argv)
+m4_process_macro (m4_symbol *symbol, m4 *context, struct obstack *obs,
+                 int argc, m4_token **argv)
 {
   const unsigned char *text;
   int i;
Index: m4/module.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/module.c,v
retrieving revision 1.18
diff -u -p -u -r1.18 module.c
--- m4/module.c 13 Jun 2003 13:05:45 -0000 1.18
+++ m4/module.c 16 Jun 2003 10:40:50 -0000
@@ -80,8 +80,10 @@
 #define MODULE_SELF_NAME       "!myself!"
 
 static const char*  module_dlerror (void);
-static int         module_remove  (lt_dlhandle handle, struct obstack *obs);
-static void        module_close   (lt_dlhandle handle, struct obstack *obs);
+static int         module_remove  (m4 *context, lt_dlhandle handle,
+                                   struct obstack *obs);
+static void        module_close   (m4 *context, lt_dlhandle handle,
+                                   struct obstack *obs);
 
 static lt_dlcaller_id caller_id = 0;
 
@@ -122,9 +124,9 @@ m4_module_macros (lt_dlhandle handle)
 }
 
 lt_dlhandle
-m4_module_load (const char *name, struct obstack *obs)
+m4_module_load (m4 *context, const char *name, struct obstack *obs)
 {
-  const lt_dlhandle handle = m4__module_open (name, obs);
+  const lt_dlhandle handle = m4__module_open (context, name, obs);
 
   /* If name is not set we are getting a reflective handle, but we
      might need to display an error message later so we set an appropriate
@@ -150,7 +152,7 @@ m4_module_load (const char *name, struct
          /* Install the macro functions.  */
          if (bp)
            {
-             m4_builtin_table_install (handle, bp);
+             m4_builtin_table_install (context, handle, bp);
 #ifdef DEBUG_MODULES
              M4_DEBUG_MESSAGE1("module %s: builtins loaded", name);
 #endif /* DEBUG_MODULES */
@@ -159,7 +161,7 @@ m4_module_load (const char *name, struct
          /* Install the user macros. */
          if (mp)
            {
-             m4_macro_table_install (handle, mp);
+             m4_macro_table_install (context, handle, mp);
 #ifdef DEBUG_MODULES
              M4_DEBUG_MESSAGE1("module %s: macros loaded", name);
 #endif /* DEBUG_MODULES */
@@ -172,7 +174,7 @@ m4_module_load (const char *name, struct
 
 /* Unload a module.  */
 void
-m4_module_unload (const char *name, struct obstack *obs)
+m4_module_unload (m4 *context, const char *name, struct obstack *obs)
 {
   lt_dlhandle  handle  = 0;
   int          errors  = 0;
@@ -192,7 +194,7 @@ m4_module_unload (const char *name, stru
       ++errors;
     }
   else
-    errors = module_remove (handle, obs);
+    errors = module_remove (context, handle, obs);
 
   if (errors)
     {
@@ -278,7 +280,7 @@ m4__module_init (void)
    it is searched for in the module path.  The module is unloaded in
    case of error.  */
 lt_dlhandle
-m4__module_open (const char *name, struct obstack *obs)
+m4__module_open (m4 *context, const char *name, struct obstack *obs)
 {
   lt_dlhandle          handle          = lt_dlopenext (name);
   m4_module_init_func  *init_func      = 0;
@@ -303,7 +305,7 @@ m4__module_open (const char *name, struc
       init_func = (m4_module_init_func *) lt_dlsym (handle, INIT_SYMBOL);
       if (init_func)
        {
-         (*init_func) (handle, obs);
+         (*init_func) (context, handle, obs);
 
 #ifdef DEBUG_MODULES
          M4_DEBUG_MESSAGE1("module %s: init hook called", name);
@@ -364,7 +366,7 @@ m4__module_open (const char *name, struc
 }
 
 void
-m4__module_exit (void)
+m4__module_exit (m4 *context)
 {
   lt_dlhandle  handle  = lt_dlhandle_next (0);
   int          errors  = 0;
@@ -388,7 +390,7 @@ m4__module_exit (void)
       if (info->ref_count <= 1)
        handle = lt_dlhandle_next (pending);
 
-      errors = module_remove (pending, 0);
+      errors = module_remove (context, pending, 0);
     }
 
   if (!errors)
@@ -416,10 +418,10 @@ module_dlerror (void)
 }
 
 static void
-module_close (lt_dlhandle handle, struct obstack *obs)
+module_close (m4 *context, lt_dlhandle handle, struct obstack *obs)
 {
   m4_module_finish_func *finish_func;
-  char                 *name;
+  const char           *name;
   int                   errors         = 0;
 
   assert (handle);
@@ -433,7 +435,7 @@ module_close (lt_dlhandle handle, struct
 
   if (finish_func)
     {
-      (*finish_func) (handle, obs);
+      (*finish_func) (context, handle, obs);
 
 #ifdef DEBUG_MODULES
       M4_DEBUG_MESSAGE1("module %s: finish hook called", name);
@@ -473,11 +475,11 @@ module_close (lt_dlhandle handle, struct
                name, module_dlerror ()));
     }
 
-  xfree (name);
+  xfree ((void *) name);
 }
 
 static int
-module_remove (lt_dlhandle handle, struct obstack *obs)
+module_remove (m4 *context, lt_dlhandle handle, struct obstack *obs)
 {
   const lt_dlinfo *info;
   int             errors       = 0;
@@ -513,7 +515,7 @@ module_remove (lt_dlhandle handle, struc
         equal to 1.  If module_close is called again on a
         resident module after the references have already been
         removed, we needn't try to remove them again!  */
-      m4__symtab_remove_module_references (handle);
+      m4__symtab_remove_module_references (M4SYMTAB, handle);
 
 #ifdef DEBUG_MODULES
       M4_DEBUG_MESSAGE1("module %s: symbols unloaded", name);
@@ -521,7 +523,7 @@ module_remove (lt_dlhandle handle, struc
     }
 
   if (!errors)
-    module_close (handle, obs);
+    module_close (context, handle, obs);
 
   return errors;
 }
Index: m4/symtab.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/symtab.c,v
retrieving revision 1.34
diff -u -p -u -r1.34 symtab.c
--- m4/symtab.c 13 Jun 2003 13:54:36 -0000 1.34
+++ m4/symtab.c 16 Jun 2003 10:40:52 -0000
@@ -49,34 +49,40 @@ static int  symbol_destroy          (m4_hash *has
 static int     arg_destroy             (m4_hash *hash, const void *name,
                                         void *arg, void *ignored);
 
-/* Pointer to symbol table.  */
-m4_hash *m4__symtab = 0;
-
-
 
 
 /* -- SYMBOL TABLE MANAGEMENT --
 
    These functions are used to manage a symbol table as a whole.  */
 
+m4_symtab *
+m4_symtab_create (size_t size)
+{
+  return (m4_symtab *) m4_hash_new (size ? size : M4_SYMTAB_DEFAULT_SIZE,
+                                   m4_hash_string_hash, m4_hash_string_cmp);
+}
+
 void
-m4__symtab_init (void)
+m4_symtab_delete (m4_symtab *symtab)
 {
-  m4__symtab = m4_hash_new (M4_SYMTAB_DEFAULT_SIZE,
-                           m4_hash_string_hash, m4_hash_string_cmp);
+  assert (symtab);
+
+  m4_hash_apply  ((m4_hash *) symtab, symbol_destroy, NULL);
+  m4_hash_delete ((m4_hash *) symtab);
 }
 
+
 /* Remove every symbol that references the given module handle from
    the symbol table.  */
 void
-m4__symtab_remove_module_references (lt_dlhandle handle)
+m4__symtab_remove_module_references (m4_symtab *symtab, lt_dlhandle handle)
 {
   m4_hash_iterator *place = 0;
 
   assert (handle);
 
    /* Traverse each symbol name in the hash table.  */
-  while ((place = m4_hash_iterator_next (m4__symtab, place)))
+  while ((place = m4_hash_iterator_next (symtab, place)))
     {
       m4_symbol *symbol = (m4_symbol *) m4_hash_iterator_value (place);
       m4_token  *data   = SYMBOL_TOKEN (symbol);
@@ -103,19 +109,11 @@ m4__symtab_remove_module_references (lt_
 
          /* Purge the live reference if necessary.  */
          if (SYMBOL_HANDLE (symbol) == handle)
-           m4_symbol_popdef (m4_hash_iterator_key (place));
+           m4_symbol_popdef (symtab, m4_hash_iterator_key (place));
        }
     }
 }
 
-/* Release all of the memory used by the symbol table.  */
-void
-m4__symtab_exit (void)
-{
-  m4_hash_apply  (m4__symtab, symbol_destroy, NULL);
-  m4_hash_delete (m4__symtab);
-  m4_hash_exit   ();
-}
 
 /* This callback is used exclusively by m4__symtab_exit(), to cleanup
    the memory used by the symbol table.  As such, the trace bit is reset
@@ -129,7 +127,7 @@ symbol_destroy (m4_hash *hash, const voi
   SYMBOL_TRACED ((m4_symbol *) symbol) = FALSE;
 
   while (key && m4_hash_lookup (hash, key))
-    m4_symbol_popdef (key);
+    m4_symbol_popdef ((m4_symtab *) hash, key);
 
   XFREE (key);
 
@@ -145,9 +143,10 @@ symbol_destroy (m4_hash *hash, const voi
 
 /* Return the symbol associated to NAME, or else NULL.  */
 m4_symbol *
-m4_symbol_lookup (const char *name)
+m4_symbol_lookup (m4_symtab *symtab, const char *name)
 {
-  m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4__symtab, name);
+  m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,
+                                                      name);
 
   /* If just searching, return status of search -- if only an empty
      struct is returned, that is treated as a failed lookup.  */
@@ -159,9 +158,10 @@ m4_symbol_lookup (const char *name)
    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 (const char *name)
+m4_symbol_pushdef (m4_symtab *symtab, const char *name)
 {
-  m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4__symtab, name);
+  m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,
+                                                      name);
 
   m4_symbol *symbol = 0;
   m4_token *value   = XCALLOC (m4_token, 1);
@@ -178,7 +178,7 @@ m4_symbol_pushdef (const char *name)
   SYMBOL_TYPE (symbol) = M4_TOKEN_VOID;
 
   if (!psymbol)
-    m4_hash_insert (m4__symtab, xstrdup (name), symbol);
+    m4_hash_insert ((m4_hash *) symtab, xstrdup (name), symbol);
 
   return symbol;
 }
@@ -187,14 +187,14 @@ m4_symbol_pushdef (const char *name)
 /* Return the symbol associated with NAME in the symbol table, creating
    a new symbol if necessary.  */
 m4_symbol *
-m4_symbol_define (const char *name)
+m4_symbol_define (m4_symtab *symtab, const char *name)
 {
-  m4_symbol *symbol = m4_symbol_lookup (name);
+  m4_symbol *symbol = m4_symbol_lookup (symtab, name);
 
   if (symbol)
     return symbol;
 
-  return m4_symbol_pushdef (name);
+  return m4_symbol_pushdef (symtab, name);
 }
 
 
@@ -202,9 +202,10 @@ m4_symbol_define (const char *name)
    NAME, deleting it from the table entirely if that was the last
    remaining value in the stack.  */
 void
-m4_symbol_popdef (const char *name)
+m4_symbol_popdef (m4_symtab *symtab, const char *name)
 {
-  m4_symbol **psymbol  = (m4_symbol **) m4_hash_lookup (m4__symtab, name);
+  m4_symbol **psymbol  = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,
+                                                        name);
   m4_token  *stale     = NULL;
 
   assert (psymbol);
@@ -232,7 +233,7 @@ m4_symbol_popdef (const char *name)
     if (no_gnu_extensions || !SYMBOL_TRACED (*psymbol))
       {
        XFREE (*psymbol);
-       xfree (m4_hash_remove (m4__symtab, name));
+       xfree (m4_hash_remove ((m4_hash *) symtab, name));
       }
 }
 
@@ -319,7 +320,7 @@ symtab_dump (void)
 {
   m4_hash_iterator *place = 0;
 
-  while ((place = m4_hash_iterator_next (m4__symtab, place)))
+  while ((place = m4_hash_iterator_next ((m4_hash *) symtab, place)))
     {
       const char   *symbol_name        = (const char *) m4_hash_iterator_key 
(place);
       m4_symbol           *symbol      = m4_hash_iterator_value (place);
@@ -357,7 +358,7 @@ symtab_dump (void)
 }
 
 static void
-symtab_debug (void)
+symtab_debug (m4_symtab *symtab)
 {
   m4__token_type type;
   m4_token token;
@@ -378,21 +379,22 @@ symtab_debug (void)
       else
        delete = 0;
 
-      symbol = m4_symbol_lookup (text);
+      symbol = m4_symbol_lookup (symtab, text);
 
       if (symbol == NULL)
        printf (_("Name `%s' is unknown\n"), text);
 
       if (delete)
-       (void) m4_symbol_delete (text);
+       (void) m4_symbol_delete (symtab, text);
       else
-       (void) m4_symbol_define (text);
+       (void) m4_symbol_define (symtab, text);
     }
-  m4_symtab_apply (symtab_print_list, NULL);
+  m4_symtab_apply (symtab, symtab_print_list, NULL);
 }
 
 static int
-symtab_print_list (const void *name, void *symbol, void *ignored)
+symtab_print_list (m4_hash *hash, const void *name, void *symbol,
+                  void *ignored)
 {
   printf ("\tname %s, addr %#x, flags: %d %s\n",
          (char *) name, (unsigned) symbol,
@@ -404,19 +406,20 @@ symtab_print_list (const void *name, voi
 #endif /* DEBUG_SYM */
 
 /* Define these functions at the end, so that calls in the file use the
-   faster macro version from m4private.h.  */
+   faster macro version from m4module.h.  */
 #undef m4_symtab_apply
 int
-m4_symtab_apply (m4_symtab_apply_func *func, void *userdata)
+m4_symtab_apply (m4_symtab *symtab, m4_symtab_apply_func *func, void *userdata)
 {
-  return m4_hash_apply (m4__symtab, (m4_hash_apply_func *) func, userdata);
+  return m4_hash_apply ((m4_hash *) symtab, (m4_hash_apply_func *) func,
+                       userdata);
 }
 
 /* Pop all values from the symbol associated with NAME.  */
 #undef m4_symbol_delete
 void
-m4_symbol_delete (const char *name)
+m4_symbol_delete (m4_symtab *symtab, const char *name)
 {
-  while (m4_symbol_lookup (name))
-    m4_symbol_popdef (name);
+  while (m4_symbol_lookup (symtab, name))
+    m4_symbol_popdef (symtab, name);
 }
Index: m4/utility.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/utility.c,v
retrieving revision 1.24
diff -u -p -u -r1.24 utility.c
--- m4/utility.c 13 Jun 2003 13:05:46 -0000 1.24
+++ m4/utility.c 16 Jun 2003 10:40:52 -0000
@@ -240,7 +240,7 @@ m4_dump_symbol (const void *name, void *
 /* If there are no arguments, build a sorted list of all defined
    symbols, otherwise, only the specified symbols.  */
 void
-m4_dump_symbols (struct m4_dump_symbol_data *data, int argc,
+m4_dump_symbols (m4 *context, struct m4_dump_symbol_data *data, int argc,
                 m4_token **argv, boolean complain)
 {
   data->base = (const char **) obstack_base (data->obs);
@@ -248,7 +248,7 @@ m4_dump_symbols (struct m4_dump_symbol_d
 
   if (argc == 1)
     {
-      m4_symtab_apply (m4_dump_symbol, data);
+      m4_symtab_apply (M4SYMTAB, m4_dump_symbol, data);
     }
   else
     {
@@ -257,7 +257,7 @@ m4_dump_symbols (struct m4_dump_symbol_d
 
       for (i = 1; i < argc; i++)
        {
-         symbol = m4_symbol_lookup (M4ARG (i));
+         symbol = m4_symbol_lookup (M4SYMTAB, M4ARG (i));
          if (symbol != NULL && SYMBOL_TYPE (symbol) != M4_TOKEN_VOID)
            m4_dump_symbol (M4ARG (i), symbol, data);
          else if (complain)
Index: modules/evalparse.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/evalparse.c,v
retrieving revision 1.6
diff -u -p -u -r1.6 evalparse.c
--- modules/evalparse.c 13 Oct 2001 08:55:43 -0000 1.6
+++ modules/evalparse.c 16 Jun 2003 10:40:55 -0000
@@ -770,7 +770,7 @@ simple_term (eval_token et, number *v1)
 
 /* Main entry point, called from "eval" and "mpeval" builtins.  */
 void
-m4_evaluate (struct obstack *obs, int argc, m4_token **argv)
+m4_evaluate (m4 *context, struct obstack *obs, int argc, m4_token **argv)
 {
   int          radix   = 10;
   int          min     = 1;
Index: modules/gnu.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/gnu.c,v
retrieving revision 1.19
diff -u -p -u -r1.19 gnu.c
--- modules/gnu.c 13 Oct 2001 08:54:53 -0000 1.19
+++ modules/gnu.c 16 Jun 2003 10:40:55 -0000
@@ -27,7 +27,6 @@
 #  include <stdlib.h>
 #endif
 
-/* Need this here so that `M4_SCOPE' is defined before use.  */
 #include "m4module.h"
 
 #if HAVE_ERRNO_H
@@ -143,7 +142,7 @@ M4BUILTIN_HANDLER (builtin)
     M4ERROR ((warning_status, 0,
              _("Undefined name %s"), name));
   else
-    (*bp->func) (obs, argc - 1, argv + 1);
+    (*bp->func) (context, obs, argc - 1, argv + 1);
 }
 
 
@@ -160,12 +159,12 @@ M4BUILTIN_HANDLER (indir)
   m4_symbol *symbol;
   const char *name = M4ARG (1);
 
-  symbol = m4_symbol_lookup (name);
+  symbol = m4_symbol_lookup (M4SYMTAB, name);
   if (symbol == NULL)
     M4ERROR ((warning_status, 0,
              _("Undefined name `%s'"), name));
   else
-    m4_call_macro (symbol, argc - 1, argv + 1, obs);
+    m4_call_macro (symbol, context, obs, argc - 1, argv + 1);
 }
 
 /* Change the current input syntax.  The function set_syntax () lives
@@ -456,7 +455,7 @@ M4BUILTIN_HANDLER (symbols)
 
   obstack_init (&data_obs);
   data.obs = &data_obs;
-  m4_dump_symbols (&data, argc, argv, FALSE);
+  m4_dump_symbols (context, &data, argc, argv, FALSE);
 
   for (; data.size > 0; --data.size, data.base++)
     {
Index: modules/load.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/load.c,v
retrieving revision 1.8
diff -u -p -u -r1.8 load.c
--- modules/load.c 12 Oct 2001 19:57:29 -0000 1.8
+++ modules/load.c 16 Jun 2003 10:40:55 -0000
@@ -113,7 +113,7 @@ M4BUILTIN_HANDLER (load)
 {
   /* Load the named module and install the builtins and macros
      exported by that module.  */
-  m4_module_load (M4ARG(1), obs);
+  m4_module_load (context, M4ARG(1), obs);
 }
 
 /**
@@ -123,5 +123,5 @@ M4BUILTIN_HANDLER (unload)
 {
   /* Remove all builtins and macros installed by the named module,
      and then unload the module from memory entirely.  */
-  m4_module_unload (M4ARG(1), obs);
+  m4_module_unload (context, M4ARG(1), obs);
 }
Index: modules/m4.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/m4.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 m4.c
--- modules/m4.c 13 Jun 2003 13:54:36 -0000 1.38
+++ modules/m4.c 16 Jun 2003 10:40:57 -0000
@@ -153,18 +153,18 @@ M4BUILTIN_HANDLER (define)
 
   if (argc == 2)
     {
-      m4_macro_define (M4ARG (1), NULL);
+      m4_macro_define (context, M4ARG (1), NULL);
       return;
     }
 
   switch (TOKEN_TYPE (argv[2]))
     {
     case M4_TOKEN_TEXT:
-      m4_macro_define (M4ARG (1), argv[2]);
+      m4_macro_define (context, M4ARG (1), argv[2]);
       return;
 
     case M4_TOKEN_FUNC:
-      m4_builtin_define (M4ARG (1), argv[2]);
+      m4_builtin_define (context, M4ARG (1), argv[2]);
       return;
     }
 
@@ -174,11 +174,11 @@ M4BUILTIN_HANDLER (define)
 
 M4BUILTIN_HANDLER (undefine)
 {
-  if (!m4_symbol_lookup (M4ARG (1)))
+  if (!m4_symbol_lookup (M4SYMTAB, M4ARG (1)))
     M4WARN ((warning_status, 0,
             _("Warning: %s: undefined name: %s"), M4ARG (0), M4ARG (1)));
   else
-    m4_symbol_delete (M4ARG (1));
+    m4_symbol_delete (M4SYMTAB, M4ARG (1));
 }
 
 M4BUILTIN_HANDLER (pushdef)
@@ -188,18 +188,18 @@ M4BUILTIN_HANDLER (pushdef)
 
   if (argc == 2)
     {
-      m4_macro_pushdef (M4ARG (1), NULL);
+      m4_macro_pushdef (context, M4ARG (1), NULL);
       return;
     }
 
   switch (TOKEN_TYPE (argv[2]))
     {
     case M4_TOKEN_TEXT:
-      m4_macro_pushdef (M4ARG (1), argv[2]);
+      m4_macro_pushdef (context, M4ARG (1), argv[2]);
       return;
 
     case M4_TOKEN_FUNC:
-      m4_builtin_pushdef (M4ARG (1), argv[2]);
+      m4_builtin_pushdef (context, M4ARG (1), argv[2]);
       return;
     }
 
@@ -209,11 +209,11 @@ M4BUILTIN_HANDLER (pushdef)
 
 M4BUILTIN_HANDLER (popdef)
 {
-  if (!m4_symbol_lookup (M4ARG (1)))
+  if (!m4_symbol_lookup (M4SYMTAB, M4ARG (1)))
     M4WARN ((warning_status, 0,
             _("Warning: %s: undefined name: %s"), M4ARG (0), M4ARG (1)));
   else
-    m4_symbol_popdef (M4ARG (1));
+    m4_symbol_popdef (M4SYMTAB, M4ARG (1));
 }
 
 
@@ -227,7 +227,7 @@ M4BUILTIN_HANDLER (ifdef)
   m4_symbol *symbol;
   const char *result;
 
-  symbol = m4_symbol_lookup (M4ARG (1));
+  symbol = m4_symbol_lookup (M4SYMTAB, M4ARG (1));
 
   if (symbol)
     result = M4ARG (2);
@@ -292,11 +292,11 @@ M4BUILTIN_HANDLER (dumpdef)
   const m4_builtin *bp;
 
   data.obs = obs;
-  m4_dump_symbols (&data, argc, argv, TRUE);
+  m4_dump_symbols (context, &data, argc, argv, TRUE);
 
   for (; data.size > 0; --data.size, data.base++)
     {
-      m4_symbol *symbol = m4_symbol_lookup (data.base[0]);
+      m4_symbol *symbol = m4_symbol_lookup (M4SYMTAB, data.base[0]);
 
       fprintf (stderr, "%s:\t", data.base[0]);
       assert (SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT
@@ -332,7 +332,7 @@ M4BUILTIN_HANDLER (defn)
 {
   m4_symbol *symbol;
 
-  symbol = m4_symbol_lookup (M4ARG (1));
+  symbol = m4_symbol_lookup (M4SYMTAB, M4ARG (1));
   if (symbol == NULL)
     {
       M4WARN ((warning_status, 0,
@@ -556,7 +556,7 @@ M4BUILTIN_HANDLER (m4exit)
     exit_code = 0;
 
   /* Ensure any module exit callbacks are executed.  */
-  m4__module_exit ();
+  m4__module_exit (context);
 
   exit (exit_code);
 }
@@ -594,12 +594,12 @@ M4BUILTIN_HANDLER (traceon)
   int i;
 
   if (argc == 1)
-    m4_symtab_apply (set_trace, (void *) obs);
+    m4_symtab_apply (M4SYMTAB, set_trace, (void *) obs);
   else
     for (i = 1; i < argc; i++)
       {
        const char *name = M4ARG (i);
-       m4_symbol *symbol = m4_symbol_lookup (name);
+       m4_symbol *symbol = m4_symbol_lookup (M4SYMTAB, name);
        if (symbol != NULL)
          set_trace (NULL, NULL, symbol, (char *) obs);
        else
@@ -614,12 +614,12 @@ M4BUILTIN_HANDLER (traceoff)
   int i;
 
   if (argc == 1)
-    m4_symtab_apply (set_trace, NULL);
+    m4_symtab_apply (M4SYMTAB, set_trace, NULL);
   else
     for (i = 1; i < argc; i++)
       {
        const char *name = M4ARG (i);
-       m4_symbol *symbol = m4_symbol_lookup (name);
+       m4_symbol *symbol = m4_symbol_lookup (M4SYMTAB, name);
        if (symbol != NULL)
          set_trace (NULL, NULL, symbol, NULL);
        else
Index: src/freeze.c
===================================================================
RCS file: /cvsroot/m4/m4/src/freeze.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 freeze.c
--- src/freeze.c 13 Jun 2003 13:05:46 -0000 1.25
+++ src/freeze.c 16 Jun 2003 10:40:57 -0000
@@ -189,7 +189,7 @@ produce_symbol_dump (FILE *file, m4_hash
 }
 
 void
-produce_frozen_state (const char *name)
+produce_frozen_state (m4 *context, const char *name)
 {
   FILE *file;
 
@@ -254,7 +254,7 @@ produce_frozen_state (const char *name)
   produce_module_dump (file, lt_dlhandle_next (0));
 
   /* Dump all symbols.  */
-  produce_symbol_dump (file, m4__symtab);
+  produce_symbol_dump (file, M4SYMTAB);
 
   /* Let diversions be issued from output.c module, its cleaner to have this
      piece of code there.  */
@@ -321,7 +321,7 @@ decode_char (FILE *in)
 /* We are seeking speed, here.  */
 
 void
-reload_frozen_state (const char *name)
+reload_frozen_state (m4 *context, const char *name)
 {
   FILE *file;
   int version;
@@ -489,7 +489,7 @@ reload_frozen_state (const char *name)
              TOKEN_MIN_ARGS (&token)   = bp->min_args;
              TOKEN_MAX_ARGS (&token)   = bp->max_args;
 
-             m4_builtin_pushdef (string[0], &token);
+             m4_builtin_pushdef (context, string[0], &token);
            }
          else
            M4ERROR ((warning_status, 0,
@@ -517,7 +517,7 @@ reload_frozen_state (const char *name)
        GET_STRING (file, string[0], allocated[0], number[0]);
        VALIDATE ('\n');
 
-       m4__module_open (string[0], NULL);
+       m4__module_open (context, string[0], NULL);
 
        break;
 
@@ -672,7 +672,7 @@ reload_frozen_state (const char *name)
          TOKEN_HANDLE (&token)         = handle;
          TOKEN_MAX_ARGS (&token)       = -1;
 
-         m4_macro_pushdef (string[0], &token);
+         m4_macro_pushdef (context, string[0], &token);
        }
        break;
 
Index: src/m4.h
===================================================================
RCS file: /cvsroot/m4/m4/src/m4.h,v
retrieving revision 1.11
diff -u -p -u -r1.11 m4.h
--- src/m4.h 30 Sep 2001 22:26:57 -0000 1.11
+++ src/m4.h 16 Jun 2003 10:41:00 -0000
@@ -105,7 +105,7 @@ void stackovf_exit (void);
 
 /* File: freeze.c --- frozen state files.  */
 
-void produce_frozen_state (const char *);
-void reload_frozen_state  (const char *);
+void produce_frozen_state (m4 *context, const char *);
+void reload_frozen_state  (m4 *context, const char *);
 
 #endif /* M4_H */
Index: src/main.c
===================================================================
RCS file: /cvsroot/m4/m4/src/main.c,v
retrieving revision 1.37
diff -u -p -u -r1.37 main.c
--- src/main.c 13 Jun 2003 13:05:46 -0000 1.37
+++ src/main.c 16 Jun 2003 10:41:00 -0000
@@ -213,6 +213,8 @@ main (int argc, char *const *argv, char 
   FILE *fp;
   char *filename;
 
+  m4 *context;
+
   int exit_status;
 
   program_name = argv[0];
@@ -228,7 +230,8 @@ main (int argc, char *const *argv, char 
   m4__module_init ();
   m4_debug_init ();
   m4_include_init ();
-  m4__symtab_init ();
+
+  context = m4_create ();
 
 #ifdef USE_STACKOVF
   setup_stackovf_trap (argv, envp, stackovf_handler);
@@ -387,13 +390,13 @@ warranty; not even for MERCHANTABILITY o
 
   if (frozen_file_to_read)
     {
-      reload_frozen_state (frozen_file_to_read);
+      reload_frozen_state (context, frozen_file_to_read);
     }
   else
     {
       m4_syntax_init ();
-      m4_module_load ("m4", 0);
-      m4_module_load (no_gnu_extensions ? "traditional" : "gnu", 0);
+      m4_module_load (context, "m4", 0);
+      m4_module_load (context, no_gnu_extensions ? "traditional" : "gnu", 0);
     }
 
   /* Import environment variables as macros.  The definition are
@@ -439,20 +442,20 @@ warranty; not even for MERCHANTABILITY o
            else
              *macro_value++ = '\0';
            TOKEN_TEXT (&token) = macro_value;
-           m4_macro_define (defines->macro, &token);
+           m4_macro_define (context, defines->macro, &token);
            break;
 
          case 'U':
-           m4_symbol_delete (defines->macro);
+           m4_symbol_delete (M4SYMTAB, defines->macro);
            break;
 
          case 't':
-           symbol = m4_symbol_define (defines->macro);
+           symbol = m4_symbol_define (M4SYMTAB, defines->macro);
            SYMBOL_TRACED (symbol) = TRUE;
            break;
 
          case 'm':
-           m4_module_load (defines->macro, 0);
+           m4_module_load (context, defines->macro, 0);
            break;
 
          default:
@@ -482,7 +485,7 @@ warranty; not even for MERCHANTABILITY o
   if (optind == argc)
     {
       m4_push_file (stdin, "stdin");
-      m4_expand_input ();
+      m4_expand_input (context);
     }
   else
     for (; optind < argc; optind++)
@@ -504,17 +507,17 @@ warranty; not even for MERCHANTABILITY o
                xfree (filename);
              }
          }
-       m4_expand_input ();
+       m4_expand_input (context);
       }
 #undef NEXTARG
 
   /* Now handle wrapup text.  */
 
   while (m4_pop_wrapup ())
-    m4_expand_input ();
+    m4_expand_input (context);
 
   if (frozen_file_to_write)
-    produce_frozen_state (frozen_file_to_write);
+    produce_frozen_state (context, frozen_file_to_write);
   else
     {
       m4_make_diversion (0);
@@ -526,12 +529,16 @@ warranty; not even for MERCHANTABILITY o
      anything left when we're done: it was caused by a memory leak.
      Strictly, we don't need to do this, but it makes leak detection
      a whole lot easier!  */
-  m4__module_exit ();
-  m4__symtab_exit ();
+
+  m4__module_exit (context);
   m4_syntax_exit ();
   m4_output_exit ();
   m4_input_exit ();
   m4_debug_exit ();
+
+  m4_delete (context);
+
+  m4_hash_exit ();
 
 #ifdef USE_STACKOVF
   stackovf_exit ();
Index: src/stackovf.c
===================================================================
RCS file: /cvsroot/m4/m4/src/stackovf.c,v
retrieving revision 1.9
diff -u -p -u -r1.9 stackovf.c
--- src/stackovf.c 30 Sep 2001 22:26:57 -0000 1.9
+++ src/stackovf.c 16 Jun 2003 10:41:00 -0000
@@ -343,7 +343,7 @@ setup_stackovf_trap (char *const *argv, 
     ss.ss_flags = 0;
     if (sigaltstack (&ss, (stack_t *) 0) < 0)
       {
-       xfree (stackbuf);
+       xfree ((void *) stackbuf);
        error (1, errno, "sigaltstack");
       }
   }
@@ -414,7 +414,7 @@ Error - Do not know how to catch signals
 void
 stackovf_exit (void)
 {
-  XFREE (stackbuf);
+  XFREE ((void *) stackbuf);
 }
 
 #endif /* USE_STACKOVF */

reply via email to

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