[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[SCM] GNU M4 source repository branch, master, updated. cvs-readonly-306
From: |
Gary V. Vaughan |
Subject: |
[SCM] GNU M4 source repository branch, master, updated. cvs-readonly-306-g7781a59 |
Date: |
Fri, 20 Sep 2013 15:20:12 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU M4 source repository".
http://git.sv.gnu.org/gitweb/?p=m4.git;a=commitdiff;h=7781a595d8236fe0cc6bd2f2fdd2d67c5707eb50
The branch, master has been updated
via 7781a595d8236fe0cc6bd2f2fdd2d67c5707eb50 (commit)
via 7b5142a2fd0939e5209e1d375843b8e9d94eb114 (commit)
via af658bcf69e62f75ec6ea084ccd84fe052e8e367 (commit)
via 1d0cc3149668703ee990fdd562582dccc73c8864 (commit)
via b466ccc6137f2255220c87f74baf86a67884a3d8 (commit)
via aeb92bcb25e253b55650961f341640f93ec3b54e (commit)
via 9114cb2e988dabdf4c8561f62eb448aa24117574 (commit)
from 8cb4718e3308c3bc0d917403132601fae3d428b7 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 7781a595d8236fe0cc6bd2f2fdd2d67c5707eb50
Author: Gary V. Vaughan <address@hidden>
Date: Fri Sep 20 21:54:01 2013 +0700
modules: speed up multiple includes of the same module.
* m4/module.c (m4_module_load): If we already have the module
loaded, reuse that. Otherwise, open the module afresh and
register it's builtins and macros on success.
Signed-off-by: Gary V. Vaughan <address@hidden>
commit 7b5142a2fd0939e5209e1d375843b8e9d94eb114
Author: Gary V. Vaughan <address@hidden>
Date: Fri Sep 20 21:20:05 2013 +0700
modules: simplify module lookup by name.
* m4/m4private.h (m4:namemap): New field for hash table to lookup
module structures by name string.
* m4/m4.c (hashfn): Hash function for plain strings.
(m4_create): Initialise namemap field to a hash table using hashfn
for inserting and looking up keys.
* m4/module.c (m4__module_find): Replace the fussy libltdl
twiddling with a hash lookup in m4:namemap.
Add a new context parameter. Adjust all callers.
Signed-off-by: Gary V. Vaughan <address@hidden>
commit af658bcf69e62f75ec6ea084ccd84fe052e8e367
Author: Gary V. Vaughan <address@hidden>
Date: Fri Sep 20 18:17:02 2013 +0700
modules: store loaded modules in context struct.
* m4/m4private.h (struct m4_module): Add a next pointer.
(struct m4): Add a module list pointer.
* m4/module.c (m4__module_open): Initialise the next pointer and
update the list head when a new module is successfully opened.
(m4_module_next): Replace the ugly libltdl twiddling with a
straight forward module list traversal one-liner!
Add a context parameter. Adjust all callers.
Signed-off-by: Gary V. Vaughan <address@hidden>
commit 1d0cc3149668703ee990fdd562582dccc73c8864
Author: Gary V. Vaughan <address@hidden>
Date: Fri Sep 20 17:26:42 2013 +0700
modules: store module name in the module struct.
* m4/m4private.h (m4_module): Add name field.
* m4/module.c (m4__module_open): Save the name field.
* m4/path.c (m4_load_filename): Pass the raw filename to
m4_module_load.
* m4/module.c (m4_get_module_name): Replace all the ltdl
twiddling with returning the saved name field.
Signed-off-by: Gary V. Vaughan <address@hidden>
commit b466ccc6137f2255220c87f74baf86a67884a3d8
Author: Gary V. Vaughan <address@hidden>
Date: Fri Sep 20 16:01:31 2013 +0700
modules: allow only a single function access point.
Exporting non-function symbols barely works on Windows, so change
the module loading API to use a single function access point which
is then responsible for calling back to install symbols and macros.
* m4/m4module.h, m4/m4module.c (m4_install_builtins)
(m4_install_macros): New APIs for saving builtins and macros into
the module struct.
* m4/m4module.c (install_macro_table, install_builtin_table):
Adjust accordingly.
(m4__module_open): Simplify accordingly.
* m4/m4private.h (BUILTIN_SYMBOL, MACRO_SYMBOL): Remove.
* modules/gnu.c, modules/import.c, modules/m4.c, modules/modtest.c,
modules/mpeval.c, modules/shadow.c, modules/time.c,
modules/traditional.c (m4_builtin_table, m4_macro_table): Make
static, and remove LTX symbol mangling macros.
(M4INIT_HANDLER): Call m4_install_builtins and/or m4_install_macros.
* tests/options.at: Now that init_func is always called, adjust
expected debug output.
Signed-off-by: Gary V. Vaughan <address@hidden>
commit aeb92bcb25e253b55650961f341640f93ec3b54e
Author: Gary V. Vaughan <address@hidden>
Date: Fri Sep 20 12:00:02 2013 +0700
modules: remove support for module unload and refcount.
Module management is horrifically more complex than it needs to
be for the simple purpose of providing a means to implement new
builtins using C. Fussing about reference counting or needing to
maintain and test a facility to unload modules is an easy 600
lines to cut as a start at simplification.
* src/main.c (main): Don't call m4__module_exit to unload all
modules just prior to exiting the application.
* m4/m4private.h (FINISH_SYMBOL, m4_module:refcount)
(m4__module_exit, m4_module_refcount): Remove.
(m4__module_next): Rename from this...
* m4/m4module.h (m4_module_next): ...to this. Adjust all callers.
(M4FINISH_HANDLER, m4_module_finish_func, m4_module_makeresident)
(m4_module_refcount, m4_module_unload, m4_module_exit): Remove.
* m4/m4module.c (m4__module_next): Rename from this...
(m4_module_next): ...to this.
(module_remove, m4_module_makeresident, m4_module_unload)
(m4_module_exit, m4_module_refcount): Remove.
* modules/load.c: Remove.
(m4modules): Move from here...
* modules/gnu.c (m4modules): ...to here. Update all callers.
(M4FINISH_HANDLER(gnu)): Remove.
* modules/m4.c (M4INIT_HANDLER(m4)): Remove.
* modules/modtest.c (M4FINISH_HANDLER(modtest)): Remove.
* modules/shadow.c (M4INIT_HANDLER(shadow)): Rewrite to work
without refcount.
* Makefile.am (pkglib_LTLIBRARIES): Remove modules/load.la.
(modules_load_la_LDFLAGS, modules_load_la_LIBADD): Remove.
* tests/modules.at: Remove references to load module, and
tests of unload builtin.
* tests/options.at: Remove obsolute finish hook and module unload
trace output.
* doc/m4.texi (Unload, Refcount): Remove.
(M4modules): Change module reference from load to gnu.
Signed-off-by: Gary V. Vaughan <address@hidden>
commit 9114cb2e988dabdf4c8561f62eb448aa24117574
Author: Gary V. Vaughan <address@hidden>
Date: Fri Sep 20 09:52:03 2013 +0700
refactor: remove dead M4MODPATH code.
* m4/m4private.h (USER_MODULE_PATH_ENV): Remove.
* m4/module.c: Correct doc-comment header details.
(m4__module_init): Remove PKGLIBEXECDIR and M4MODPATH handling.
Move configmake.h include from here...
* m4/path.c: ...to here.
(m4__include_init): Append PKGLIBDIR to search path.
Signed-off-by: Gary V. Vaughan <address@hidden>
-----------------------------------------------------------------------
Summary of changes:
Makefile.am | 4 -
doc/m4.texi | 82 +---------
m4/builtin.c | 12 +-
m4/m4.c | 15 ++
m4/m4module.h | 24 +--
m4/m4private.h | 20 +--
m4/module.c | 447 +++++++++++--------------------------------------
m4/path.c | 6 +-
modules/gnu.c | 62 ++++---
modules/import.c | 8 +-
modules/load.c | 126 --------------
modules/m4.c | 14 +--
modules/modtest.c | 21 +--
modules/mpeval.c | 16 +-
modules/shadow.c | 17 +-
modules/stdlib.c | 14 +-
modules/time.c | 13 +-
modules/traditional.c | 10 +-
src/freeze.c | 18 +-
src/main.c | 1 -
tests/modules.at | 247 ++-------------------------
tests/options.at | 6 +-
22 files changed, 253 insertions(+), 930 deletions(-)
delete mode 100644 modules/load.c
diff --git a/Makefile.am b/Makefile.am
index 7920b9d..e9807a0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -160,7 +160,6 @@ pkgmodinclude_HEADERS = modules/m4.h
pkglib_LTLIBRARIES = \
modules/gnu.la \
- modules/load.la \
modules/m4.la \
modules/traditional.la
@@ -169,9 +168,6 @@ modules_gnu_la_LDFLAGS = $(module_ldflags)
modules_gnu_la_LIBADD = $(module_libadd)
EXTRA_DIST += $(EXTRA_modules_gnu_la_SOURCES)
-modules_load_la_LDFLAGS = $(module_ldflags)
-modules_load_la_LIBADD = $(module_libadd)
-
EXTRA_modules_m4_la_SOURCES = modules/evalparse.c
modules_m4_la_LDFLAGS = $(module_ldflags)
modules_m4_la_LIBADD = $(module_libadd)
diff --git a/doc/m4.texi b/doc/m4.texi
index 7def990..77c3a5f 100644
--- a/doc/m4.texi
+++ b/doc/m4.texi
@@ -235,8 +235,6 @@ Diverting and undiverting output
Extending M4 with dynamic runtime modules
* M4modules:: Listing loaded modules
-* Unload:: Removing loaded modules
-* Refcount:: Tracking module references
* Standard Modules:: Standard bundled modules
Macros for text handling
@@ -6669,8 +6667,8 @@ extensions by configuring the distribution with
@kbd{./configure
--with-modules=m4}. For a binary built with that option to understand
code that uses GNU extensions, you must then run @kbd{m4 gnu}.
It is also possible to build a @emph{fatter} binary with additional
-modules preloaded: adding, say, the @code{load} module usingr
- @kbd{./configure --with-modules="m4 gnu load"}.
+modules preloaded: adding, say, the @code{load} module using
address@hidden/configure --with-modules="m4 gnu load"}.
GNU M4 now has a facility for defining additional builtins without
recompiling the sources. In actual fact, all of the builtins provided
@@ -6686,15 +6684,13 @@ two modes of startup.
@menu
* M4modules:: Listing loaded modules
-* Unload:: Removing loaded modules
-* Refcount:: Tracking module references
* Standard Modules:: Standard bundled modules
@end menu
@node M4modules
@section Listing loaded modules
address@hidden {Builtin (load)} m4modules
address@hidden {Builtin (gnu)} m4modules
Expands to a quoted ordered list of currently loaded modules,
with the most recently loaded module at the front of the list. Loading
a module multiple times will not affect the order of this list, the
@@ -6704,78 +6700,10 @@ position depends on when the module was @emph{first}
loaded.
For example, if GNU @code{m4} is started with the
@option{load} module, @code{m4modules} will yield the following:
address@hidden options: load -
@example
-$ @kbd{m4 load -}
-m4modules
address@hidden,gnu,m4
address@hidden example
-
address@hidden Unload
address@hidden Removing loaded modules
-
address@hidden {Builtin (load)} unload (@var{module-name})
-Any loaded modules that can be listed by the @code{m4modules} macro can be
-removed by naming them as the @var{module-name} parameter of the
address@hidden macro. Unloading a module consists of removing all of the
-macros it provides from the internal table of visible macros, and
-running the module's finalization method (if any).
-
-The macro @code{unload} is recognized only with parameters.
address@hidden deffn
-
address@hidden options: mpeval load -
address@hidden
-$ @kbd{m4 mpeval load -}
-m4modules
address@hidden,mpeval,gnu,m4
-unload(`mpeval')
address@hidden
-m4modules
address@hidden,gnu,m4
address@hidden example
-
address@hidden Refcount
address@hidden Tracking module references
-
address@hidden {Builtin (load)} refcount (@var{module-name})
-This macro expands to an integer representing the number of times
address@hidden has been loaded but not yet unloaded. No warning is
-issued, even if @var{module-name} does not represent a valid module.
-
-The macro @code{refcount} is recognized only with parameters.
address@hidden deffn
-
-This example demonstrates tracking the reference count of the gnu
-module.
-
address@hidden options: load -
address@hidden
-$ @kbd{m4 load -}
-m4modules
address@hidden,gnu,m4
-refcount(`gnu')
address@hidden
-m4modules
address@hidden,gnu,m4
-include(`gnu')
address@hidden
-refcount(`gnu')
address@hidden
-unload(`gnu')
address@hidden
-m4modules
address@hidden,gnu,m4
-refcount(`gnu')
address@hidden
-unload(`gnu')
address@hidden
+$ @kbd{m4}
m4modules
address@hidden,m4
-refcount(`gnu')
address@hidden
-refcount(`NoSuchModule')
address@hidden
address@hidden,m4
@end example
@node Standard Modules
diff --git a/m4/builtin.c b/m4/builtin.c
index 51f636e..b495e5c 100644
--- a/m4/builtin.c
+++ b/m4/builtin.c
@@ -39,9 +39,9 @@ compare_builtin_name_CB (const void *name, const void *b)
symbol value, suitable for use in the symbol table or for an
argument to m4_push_builtin. */
m4_symbol_value * M4_GNUC_PURE
-m4_builtin_find_by_name (m4_module *module, const char *name)
+m4_builtin_find_by_name (m4 *context, m4_module *module, const char *name)
{
- m4_module *cur = module ? module : m4__module_next (NULL);
+ m4_module *cur = module ? module : m4_module_next (context, NULL);
m4__builtin *bp;
do
@@ -55,7 +55,7 @@ m4_builtin_find_by_name (m4_module *module, const char *name)
return token;
}
}
- while (!module && (cur = m4__module_next (cur)));
+ while (!module && (cur = m4_module_next (context, cur)));
return NULL;
}
@@ -65,9 +65,9 @@ m4_builtin_find_by_name (m4_module *module, const char *name)
malloc'd symbol value, suitable for use in the symbol table or for
an argument to m4_push_builtin. */
m4_symbol_value * M4_GNUC_PURE
-m4_builtin_find_by_func (m4_module *module, m4_builtin_func *func)
+m4_builtin_find_by_func (m4 *context, m4_module *module, m4_builtin_func *func)
{
- m4_module *cur = module ? module : m4__module_next (NULL);
+ m4_module *cur = module ? module : m4_module_next (context, NULL);
size_t i;
do
@@ -81,7 +81,7 @@ m4_builtin_find_by_func (m4_module *module, m4_builtin_func
*func)
return token;
}
}
- while (!module && (cur = m4__module_next (cur)));
+ while (!module && (cur = m4_module_next (context, cur)));
return 0;
}
diff --git a/m4/m4.c b/m4/m4.c
index 0497799..d916665 100644
--- a/m4/m4.c
+++ b/m4/m4.c
@@ -20,9 +20,21 @@
#include <config.h>
+#include "bitrotate.h"
#include "m4private.h"
#define DEFAULT_NESTING_LIMIT 1024
+#define DEFAULT_NAMEMAP_SIZE 61
+
+static size_t
+hashfn (const void *ptr)
+{
+ const char *s = (const char *) ptr;
+ size_t val = DEFAULT_NAMEMAP_SIZE;
+ while (*s)
+ val = rotl_sz (val, 7) + to_uchar (*s++);
+ return val;
+}
m4 *
@@ -33,6 +45,9 @@ m4_create (void)
context->symtab = m4_symtab_create (0);
context->syntax = m4_syntax_create ();
+ context->namemap =
+ m4_hash_new (DEFAULT_NAMEMAP_SIZE, hashfn, (m4_hash_cmp_func *) strcmp);
+
context->debug_file = stderr;
obstack_init (&context->trace_messages);
diff --git a/m4/m4module.h b/m4/m4module.h
index 8c249f0..038a428 100644
--- a/m4/m4module.h
+++ b/m4/m4module.h
@@ -122,17 +122,6 @@ struct m4_string_pair
void name ## _LTX_m4_init_module \
(m4 *context, m4_module *module, m4_obstack *obs)
-/* Declare a prototype, then begin the implementation of the function
- "<NAME>_LTX_m4_init_module", which will automatically be registered
- as the cleanup function for module NAME. Note that NAME is
- intentionally used literally, rather than subjected to macro
- expansion. */
-#define M4FINISH_HANDLER(name) \
- void name ## _LTX_m4_finish_module \
- (m4 *, m4_module *, m4_obstack *); \
- void name ## _LTX_m4_finish_module \
- (m4 *context, m4_module *module, m4_obstack *obs)
-
/* Declare a variable S of type "<S>_func" to be a pointer to the
function named S imported from the module M, or NULL if the import
fails. Note that M and S are intentionally used literally rather
@@ -243,17 +232,16 @@ m4_context_opt_bit_table
/* --- MODULE MANAGEMENT --- */
typedef void m4_module_init_func (m4 *, m4_module *, m4_obstack *);
-typedef void m4_module_finish_func (m4 *, m4_module *, m4_obstack *);
extern m4_module * m4_module_load (m4 *, const char *, m4_obstack *);
-extern const char * m4_module_makeresident (m4_module *);
-extern int m4_module_refcount (const m4_module *);
-extern void m4_module_unload (m4 *, const char *, m4_obstack *);
extern void * m4_module_import (m4 *, const char *, const char *,
m4_obstack *);
+extern void m4_install_builtins (m4*, m4_module *, const m4_builtin*);
+extern void m4_install_macros (m4*, m4_module *, const m4_macro*);
+
extern const char * m4_get_module_name (const m4_module *);
-extern void m4__module_exit (m4 *);
+extern m4_module * m4_module_next (m4*, m4_module *);
@@ -342,8 +330,8 @@ extern void m4_set_symbol_value_placeholder
(m4_symbol_value *,
/* --- BUILTIN MANAGEMENT --- */
-extern m4_symbol_value *m4_builtin_find_by_name (m4_module *, const char *);
-extern m4_symbol_value *m4_builtin_find_by_func (m4_module *,
+extern m4_symbol_value *m4_builtin_find_by_name (m4 *, m4_module *, const
char *);
+extern m4_symbol_value *m4_builtin_find_by_func (m4 *, m4_module *,
m4_builtin_func *);
diff --git a/m4/m4private.h b/m4/m4private.h
index 7dc207a..926df58 100644
--- a/m4/m4private.h
+++ b/m4/m4private.h
@@ -59,6 +59,8 @@ typedef unsigned int bool_bitfield;
struct m4 {
m4_symbol_table * symtab;
m4_syntax_table * syntax;
+ m4_module * modules;
+ m4_hash * namemap;
const char * current_file; /* Current input file. */
int current_line; /* Current input line. */
@@ -173,33 +175,23 @@ extern void m4__builtin_print (m4_obstack *, const
m4__builtin *, bool,
/* --- MODULE MANAGEMENT --- */
-#define USER_MODULE_PATH_ENV "M4MODPATH"
-#define BUILTIN_SYMBOL "m4_builtin_table"
-#define MACRO_SYMBOL "m4_macro_table"
#define INIT_SYMBOL "m4_init_module"
-#define FINISH_SYMBOL "m4_finish_module"
/* Representation of a loaded m4 module. */
struct m4_module
{
+ const char *name; /* Name of the module. */
lt_dlhandle handle; /* All ltdl module information. */
- int refcount; /* Count of loads not matched by unload. */
m4__builtin *builtins; /* Sorted array of builtins. */
+ m4_macro *macros; /* Unsorted array of macros. */
size_t builtins_len; /* Number of builtins. */
+ m4_module *next;
};
extern void m4__module_init (m4 *context);
extern m4_module * m4__module_open (m4 *context, const char *name,
m4_obstack *obs);
-extern void m4__module_exit (m4 *context);
-extern m4_module * m4__module_next (m4_module *);
-extern m4_module * m4__module_find (const char *name);
-
-/* Fast macro versions of symbol table accessor functions, that also
- have an identically named function exported in m4module.h. */
-#ifdef NDEBUG
-# define m4_module_refcount(M) ((M)->refcount)
-#endif
+extern m4_module * m4__module_find (m4 *context, const char *name);
/* --- SYMBOL TABLE MANAGEMENT --- */
diff --git a/m4/module.c b/m4/module.c
index 6256bca..39cd2d2 100644
--- a/m4/module.c
+++ b/m4/module.c
@@ -20,7 +20,6 @@
#include <config.h>
-#include "configmake.h"
#include "m4private.h"
#include "xvasprintf.h"
@@ -40,76 +39,55 @@
* libdld or lt_dlpreload from libtool if shared libraries are not
* available on the host machine.
*
- * An M4 module will usually define an external symbol called
- * `m4_builtin_table'. This symbol points to a table of `m4_builtin'.
- * The table is saved as libltdl caller data and each definition therein
- * is added to the symbol table.
+ * An M4 module will usually define an external symbol named after the
+ * basename of the loadable module:
*
- * To load a module, call m4_module_load(), which uses the libltdl
- * API to find the module in the module search path. The search
- * path is initialized from the environment variable M4MODPATH, followed
- * by the configuration time default where the modules shipped with M4
- * itself are installed. Libltdl reads the libtool .la file to
- * get the real library name (which can be system dependent), returning
- * NULL on failure or else a libtool module handle for the newly mapped
- * vm segment containing the module code. If the module is not already
- * loaded, m4_module_load() retrieves its value for the symbol
- * `m4_builtin_table', which is installed using set_module_builtin_table().
+ * void
+ * mymod_LTX_m4_init_module (m4 *context, m4_module *module,
+ * m4_obstack *obs)
*
- * In addition to builtin functions, you can also define static macro
- * expansions in the `m4_macro_table' symbol. If you define this symbol
- * in your modules, it should be an array of `m4_macro's, mapping macro
- * names to the expansion text. Any macros defined in `m4_macro_table'
- * are installed into the M4 symbol table with set_module_macro_table().
+ * The function is only called the first time the module is included
+ * and generally uses either `m4_install_builtins' or
+ * `m4_install_macros' (or both!) to register whatever builtins and
+ * macros are provided by the module.
*
- * Each time a module is loaded, the module function prototyped as
- * "M4INIT_HANDLER (<module name>)" is called, if defined. Any value
- * stored in OBS by this function becomes the expansion of the macro
- * which called it. Before M4 exits, all modules are unloaded and the
- * function prototyped as "M4FINISH_HANDLER (<module name>)" is called,
- * if defined. It is safe to load the same module several times: the
- * init and finish functions will also be called multiple times in this
- * case.
- *
- * To unload a module, use m4_module_unload(). which uses
- * m4__symtab_remove_module_references() to remove the builtins defined by
- * the unloaded module from the symbol table. If the module has been
- * loaded several times with calls to m4_module_load, then the module will
- * not be unloaded until the same number of calls to m4_module_unload()
- * have been made (nor will the symbol table be purged).
+ * To load a module, call m4_module_load(), which searches for the
+ * module in directories from M4PATH. The search path is initialized
+ * from the environment variable M4PATH, followed by the configuration
+ * time default where the modules shipped with M4 itself are installed.
+ * `m4_module_load' returns NULL on failure, or else an opaque module
+ * handle for the newly mapped vm segment containing the module code.
+ * If the module is not already loaded, m4_module_load() the builtins
+ * and macros registered by `mymod_LTX_m4_init_module' are installed
+ * into the symbol table using `install_builtin_table' and `install_
+ * macro_table' respectively.
**/
#define MODULE_SELF_NAME "!myself!"
static const char* module_dlerror (void);
-static int module_remove (m4 *context, m4_module *module,
- m4_obstack *obs);
static void install_builtin_table (m4*, m4_module *);
static void install_macro_table (m4*, m4_module *);
-static int m4__module_interface (lt_dlhandle handle,
- const char *id_string);
+static int compare_builtin_CB (const void *a, const void *b);
+static int m4__module_interface (lt_dlhandle handle,
+ const char *id_string);
static lt_dlinterface_id iface_id = NULL;
const char *
m4_get_module_name (const m4_module *module)
{
- const lt_dlinfo *info;
-
- assert (module && module->handle);
-
- info = lt_dlgetinfo (module->handle);
-
- return info ? info->name : NULL;
+ assert (module);
+ return module->name;
}
void *
m4_module_import (m4 *context, const char *module_name,
const char *symbol_name, m4_obstack *obs)
{
- m4_module * module = m4__module_find (module_name);
+ m4_module * module = m4__module_find (context, module_name);
void * symbol_address = NULL;
/* Try to load the module if it is not yet available (errors are
@@ -132,6 +110,36 @@ m4_module_import (m4 *context, const char *module_name,
return symbol_address;
}
+void
+m4_install_builtins (m4 *context, m4_module *module, const m4_builtin *bp)
+{
+ assert (context);
+ assert (module);
+ assert (bp);
+
+ const m4_builtin *tmp;
+ m4__builtin *builtin;
+ for (tmp = bp; tmp->name; tmp++)
+ module->builtins_len++;
+ module->builtins = (m4__builtin *) xnmalloc (module->builtins_len,
+ sizeof *module->builtins);
+ for (builtin = module->builtins; bp->name != NULL; bp++, builtin++)
+ {
+ /* Sanity check that builtins meet the required interface. */
+ assert (bp->min_args <= bp->max_args);
+ assert (bp->min_args > 0 ||
+ (bp->flags & (M4_BUILTIN_BLIND|M4_BUILTIN_SIDE_EFFECT)) == 0);
+ assert (bp->max_args ||
+ (bp->flags & M4_BUILTIN_FLATTEN_ARGS) == 0);
+ assert ((bp->flags & ~M4_BUILTIN_FLAGS_MASK) == 0);
+ memcpy (&builtin->builtin, bp, sizeof *bp);
+ builtin->builtin.name = xstrdup (bp->name);
+ builtin->module = module;
+ }
+ qsort (module->builtins, module->builtins_len,
+ sizeof *module->builtins, compare_builtin_CB);
+}
+
static void
install_builtin_table (m4 *context, m4_module *module)
{
@@ -159,6 +167,16 @@ install_builtin_table (m4 *context, m4_module *module)
m4_get_module_name (module));
}
+void
+m4_install_macros (m4 *context, m4_module *module, const m4_macro *mp)
+{
+ assert (context);
+ assert (module);
+ assert (mp);
+
+ module->macros = (m4_macro *) mp;
+}
+
static void
install_macro_table (m4 *context, m4_module *module)
{
@@ -167,7 +185,7 @@ install_macro_table (m4 *context, m4_module *module)
assert (context);
assert (module);
- mp = (const m4_macro *) lt_dlsym (module->handle, MACRO_SYMBOL);
+ mp = module->macros;
if (mp)
{
@@ -196,57 +214,22 @@ install_macro_table (m4 *context, m4_module *module)
m4_module *
m4_module_load (m4 *context, const char *name, m4_obstack *obs)
{
- m4_module *module = m4__module_open (context, name, obs);
-
- if (module && module->refcount == 1)
- {
- install_builtin_table (context, module);
- install_macro_table (context, module);
- }
-
- return module;
-}
-
-/* Make the module MODULE resident. Return NULL on success, or a
- pre-translated error string on failure. */
-const char *
-m4_module_makeresident (m4_module *module)
-{
- assert (module);
- return lt_dlmakeresident (module->handle) ? module_dlerror () : NULL;
-}
-
-/* Unload a module. */
-void
-m4_module_unload (m4 *context, const char *name, m4_obstack *obs)
-{
- m4_module * module = NULL;
- int errors = 0;
-
- assert (context);
-
- if (name)
- module = m4__module_find (name);
-
+ m4_module *module = m4__module_find (context, name);
+
if (!module)
{
- const char *error_msg = _("module not loaded");
+ module = m4__module_open (context, name, obs);
- lt_dlseterror (lt_dladderror (error_msg));
- ++errors;
+ if (module)
+ {
+ install_builtin_table (context, module);
+ install_macro_table (context, module);
+ }
}
- else
- errors = module_remove (context, module, obs);
- if (errors)
- {
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("cannot unload module `%s': %s"),
- name ? name : MODULE_SELF_NAME, module_dlerror ());
- }
+ return module;
}
-
static int
m4__module_interface (lt_dlhandle handle, const char *id_string)
@@ -259,51 +242,24 @@ m4__module_interface (lt_dlhandle handle, const char
*id_string)
return 0;
/* A valid m4 module must provide at least one of these symbols. */
- return !(lt_dlsym (handle, INIT_SYMBOL)
- || lt_dlsym (handle, FINISH_SYMBOL)
- || lt_dlsym (handle, BUILTIN_SYMBOL)
- || lt_dlsym (handle, MACRO_SYMBOL));
+ return !(lt_dlsym (handle, INIT_SYMBOL));
}
-/* Return successive loaded modules that pass the interface test registered
- with the interface id. */
+/* Return successive loaded modules. */
m4_module *
-m4__module_next (m4_module *module)
+m4_module_next (m4 *context, m4_module *module)
{
- lt_dlhandle handle = module ? module->handle : NULL;
- assert (iface_id);
-
- /* Resident modules still show up in the lt_dlhandle_iterate loop
- after they have been unloaded from m4. */
- do
- {
- handle = lt_dlhandle_iterate (iface_id, handle);
- if (!handle)
- return NULL;
- module = (m4_module *) lt_dlcaller_get_data (iface_id, handle);
- }
- while (!module);
- assert (module->handle == handle);
- return module;
+ return module ? module->next : context->modules;
}
/* Return the first loaded module that passes the registered interface test
and is called NAME. */
m4_module *
-m4__module_find (const char *name)
+m4__module_find (m4 *context, const char *name)
{
- lt_dlhandle handle;
- m4_module *module;
- assert (iface_id);
-
- handle = lt_dlhandle_fetch (iface_id, name);
- if (!handle)
- return NULL;
- module = (m4_module *) lt_dlcaller_get_data (iface_id, handle);
- if (module)
- assert (module->handle == handle);
- return module;
+ m4_module **pmodule = (m4_module **) m4_hash_lookup (context->namemap, name);
+ return pmodule ? *pmodule : NULL;
}
@@ -346,19 +302,6 @@ m4__module_init (m4 *context)
}
}
- if (!errors)
- errors = lt_dlsetsearchpath (PKGLIBEXECDIR);
-
- /* If the user set M4MODPATH, then use that as the start of the module
- search path. */
- if (!errors)
- {
- char *path = getenv (USER_MODULE_PATH_ENV);
-
- if (path)
- errors = lt_dlinsertsearchdir (lt_dlgetsearchpath (), path);
- }
-
/* Couldn't initialize the module system; diagnose and exit. */
if (errors)
m4_error (context, EXIT_FAILURE, 0, NULL,
@@ -443,45 +386,14 @@ m4__module_open (m4 *context, const char *name,
m4_obstack *obs)
{
void *old;
const char *err;
- const m4_builtin *bp;
module = (m4_module *) xzalloc (sizeof *module);
+ module->name = xstrdup (name);
module->handle = handle;
+ module->next = context->modules;
- /* TODO - change module interface to return function pointer
- that supplies both table and length of table, rather than
- returning data pointer that must have a sentinel
- entry? */
- bp = (m4_builtin *) lt_dlsym (module->handle, BUILTIN_SYMBOL);
- if (bp)
- {
- const m4_builtin *tmp;
- m4__builtin *builtin;
- for (tmp = bp; tmp->name; tmp++)
- module->builtins_len++;
- module->builtins =
- (m4__builtin *) xnmalloc (module->builtins_len,
- sizeof *module->builtins);
- for (builtin = module->builtins; bp->name != NULL;
- bp++, builtin++)
- {
- /* Sanity check that builtins meet the required
- interface. */
- assert (bp->min_args <= bp->max_args);
- assert (bp->min_args > 0
- || (bp->flags & (M4_BUILTIN_BLIND
- | M4_BUILTIN_SIDE_EFFECT)) == 0);
- assert (bp->max_args
- || (bp->flags & M4_BUILTIN_FLATTEN_ARGS) == 0);
- assert ((bp->flags & ~M4_BUILTIN_FLAGS_MASK) == 0);
-
- memcpy (&builtin->builtin, bp, sizeof *bp);
- builtin->builtin.name = xstrdup (bp->name);
- builtin->module = module;
- }
- }
- qsort (module->builtins, module->builtins_len,
- sizeof *module->builtins, compare_builtin_CB);
+ context->modules = module;
+ m4_hash_insert (context->namemap, xstrdup (name), module);
/* clear out any stale errors, since we have to use
lt_dlerror to distinguish between success and
@@ -493,25 +405,22 @@ m4__module_open (m4 *context, const char *name,
m4_obstack *obs)
if (err)
m4_error (context, EXIT_FAILURE, 0, NULL,
_("unable to load module `%s': %s"), name, err);
- }
- /* Find and run any initializing function in the opened module,
- each time the module is opened. */
- module->refcount++;
- init_func = (m4_module_init_func *) lt_dlsym (handle, INIT_SYMBOL);
- if (init_func)
- {
- init_func (context, module, obs);
+ /* Find and run any initializing function in the opened module,
+ the first time the module is opened. */
+ init_func = (m4_module_init_func *) lt_dlsym (handle, INIT_SYMBOL);
+ if (init_func)
+ {
+ init_func (context, module, obs);
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: init hook called"), name);
- }
- else if (!lt_dlsym (handle, FINISH_SYMBOL)
- && !lt_dlsym (handle, BUILTIN_SYMBOL)
- && !lt_dlsym (handle, MACRO_SYMBOL))
- {
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("module `%s' has no entry points"), name);
+ m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
+ _("module %s: init hook called"), name);
+ }
+ else
+ {
+ m4_error (context, EXIT_FAILURE, 0, NULL,
+ _("module `%s' has no entry point"), name);
+ }
}
m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
@@ -527,39 +436,6 @@ m4__module_open (m4 *context, const char *name, m4_obstack
*obs)
return module;
}
-void
-m4__module_exit (m4 *context)
-{
- m4_module * module = m4__module_next (NULL);
- int errors = 0;
-
- while (module && !errors)
- {
- m4_module *pending = module;
-
- /* If we are about to unload the final reference, move on to the
- next module before we unload the current one. */
- if (pending->refcount <= 1)
- module = m4__module_next (module);
-
- errors = module_remove (context, pending, NULL);
- }
-
- assert (iface_id); /* need to have called m4__module_init */
- lt_dlinterface_free (iface_id);
- iface_id = NULL;
-
- if (!errors)
- errors = lt_dlexit ();
-
- if (errors)
- {
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("cannot unload all modules: %s"), module_dlerror ());
- }
-}
-
-
/* FIXME - libtool doesn't expose lt_dlerror strings for translation. */
static const char *
@@ -572,126 +448,3 @@ module_dlerror (void)
return dlerror;
}
-
-/* Close one reference to the module MODULE, and output to OBS any
- information from the finish hook of the module. If no references
- to MODULE remain, also remove all symbols and other memory
- associated with the module. */
-static int
-module_remove (m4 *context, m4_module *module, m4_obstack *obs)
-{
- const lt_dlinfo * info;
- int errors = 0;
- const char * name;
- lt_dlhandle handle;
- bool last_reference = false;
- bool resident = false;
- m4_module_finish_func * finish_func;
-
- assert (module && module->handle);
-
- /* Be careful when closing myself. */
- handle = module->handle;
- name = m4_get_module_name (module);
- name = xstrdup (name ? name : MODULE_SELF_NAME);
-
- info = lt_dlgetinfo (handle);
- resident = info->is_resident;
-
- /* Only do the actual close when the number of calls to close this
- module is equal to the number of times it was opened. */
-#ifdef DEBUG_MODULES
- if (info->ref_count > 1)
- {
- xfprintf (stderr, "module %s: now has %d libtool references.",
- name, info->ref_count - 1);
- }
-#endif /* DEBUG_MODULES */
-
- if (module->refcount-- == 1)
- {
- /* Remove the table references only when ref_count is *exactly*
- 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 (M4SYMTAB, module);
-
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: symbols unloaded"), name);
- last_reference = true;
- }
-
- finish_func = (m4_module_finish_func *) lt_dlsym (handle, FINISH_SYMBOL);
- if (finish_func)
- {
- finish_func (context, module, obs);
-
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: finish hook called"), name);
- }
-
- if (last_reference && resident)
- {
- /* Special case when closing last reference to resident module -
- we need to remove the association of the m4_module wrapper
- with the dlhandle, because we are about to free the wrapper,
- but the module will still show up in lt_dlhandle_iterate.
- Still call lt_dlclose to reduce the ref count, but ignore the
- failure about not closing a resident module. */
- void *old = lt_dlcaller_set_data (iface_id, handle, NULL);
- if (!old)
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("unable to close module `%s': %s"), name,
- module_dlerror());
- assert (old == module);
- lt_dlclose (handle);
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: resident module not closed"), name);
- }
- else
- {
- errors = lt_dlclose (handle);
- /* Ignore the error expected if the module was resident. */
- if (resident)
- errors = 0;
- if (!errors)
- {
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: closed"), name);
- }
- }
-
- if (errors)
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("cannot close module `%s': %s"), name, module_dlerror ());
- if (last_reference)
- {
- size_t i;
- for (i = 0; i < module->builtins_len; i++)
- DELETE (module->builtins[i].builtin.name);
- free (module->builtins);
- free (module);
- }
-
- DELETE (name);
-
- return errors;
-}
-
-
-/* Below here are the accessor functions behind fast macros. Declare
- them last, so the rest of the file can use the macros. */
-
-/* Return the current refcount, or times that module MODULE has been
- opened. */
-#undef m4_module_refcount
-int
-m4_module_refcount (const m4_module *module)
-{
- const lt_dlinfo *info;
- assert (module);
- info = lt_dlgetinfo (module->handle);
- assert (info);
- assert (module->refcount <= info->ref_count);
- return module->refcount;
-}
diff --git a/m4/path.c b/m4/path.c
index 37115d0..9437e93 100644
--- a/m4/path.c
+++ b/m4/path.c
@@ -30,6 +30,7 @@
#include "m4private.h"
+#include "configmake.h"
#include "dirname.h"
#include "filenamecat.h"
@@ -298,7 +299,7 @@ m4_load_filename (m4 *context, const m4_call_info *caller,
&& suffix
&& (STREQ (suffix, LT_MODULE_EXT) || STREQ (suffix, ".la")))
{
- m4_module_load (context, filepath, obs);
+ m4_module_load (context, filename, obs);
}
else
{
@@ -338,6 +339,9 @@ m4__include_init (m4 *context)
assert (info);
if (info->list_end == NULL)
search_path_add (info, "", false);
+
+ /* Non-core modules installation directory. */
+ search_path_add (info, PKGLIBDIR, false);
}
#ifdef DEBUG_INCL
diff --git a/modules/gnu.c b/modules/gnu.c
index c69862e..96c7547 100644
--- a/modules/gnu.c
+++ b/modules/gnu.c
@@ -32,11 +32,6 @@
#include "spawn-pipe.h"
#include "wait-process.h"
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table gnu_LTX_m4_builtin_table
-#define m4_macro_table gnu_LTX_m4_macro_table
-
-
/* Maintain each of the builtins implemented in this modules along
with their details in a single table for easy maintenance.
@@ -58,6 +53,7 @@
BUILTIN (patsubst, false, true, true, 2, 4 ) \
BUILTIN (regexp, false, true, true, 2, 4 ) \
BUILTIN (renamesyms, false, true, false, 2, 3 ) \
+ BUILTIN (m4modules, false, false, false, 0, 0 ) \
BUILTIN (m4symbols, true, false, false, 0, -1 ) \
BUILTIN (syncoutput, false, true, false, 1, 1 ) \
@@ -69,7 +65,7 @@
/* Generate a table for mapping m4 symbol names to handler functions. */
-const m4_builtin m4_builtin_table[] =
+static const m4_builtin m4_builtin_table[] =
{
#define BUILTIN(handler, macros, blind, side, min, max) \
M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
@@ -82,7 +78,7 @@ const m4_builtin m4_builtin_table[] =
/* A table for mapping m4 symbol names to simple expansion text. */
-const m4_macro m4_macro_table[] =
+static const m4_macro m4_macro_table[] =
{
/* name text min max */
#if UNIX
@@ -101,6 +97,13 @@ const m4_macro m4_macro_table[] =
};
+M4INIT_HANDLER (gnu)
+{
+ m4_install_builtins (context, module, m4_builtin_table);
+ m4_install_macros (context, module, m4_macro_table);
+}
+
+
/* Regular expressions. Reuse re_registers among multiple
re_pattern_buffer allocations to reduce malloc usage. */
@@ -352,25 +355,6 @@ regexp_substitute (m4 *context, m4_obstack *obs, const
m4_call_info *caller,
}
-/* Reclaim memory used by this module. */
-M4FINISH_HANDLER(gnu)
-{
- int i;
- for (i = 0; i < REGEX_CACHE_SIZE; i++)
- if (regex_cache[i].str)
- {
- free (regex_cache[i].str);
- regfree (regex_cache[i].pat);
- free (regex_cache[i].pat);
- free (regex_cache[i].regs.start);
- free (regex_cache[i].regs.end);
- }
- /* If this module was preloaded, then we need to explicitly reset
- the memory in case it gets reloaded. */
- memset (®ex_cache, 0, sizeof regex_cache);
-}
-
-
/**
* __file__
@@ -433,7 +417,7 @@ M4BUILTIN_HANDLER (builtin)
name = M4ARG (2);
len = M4ARGLEN (2);
if (len == strlen (name))
- value = m4_builtin_find_by_name (NULL, name);
+ value = m4_builtin_find_by_name (context, NULL, name);
if (value)
{
m4_push_builtin (context, obs, value);
@@ -451,7 +435,7 @@ M4BUILTIN_HANDLER (builtin)
name = M4ARG (1);
len = M4ARGLEN (1);
if (len == strlen (name))
- value = m4_builtin_find_by_name (NULL, name);
+ value = m4_builtin_find_by_name (context, NULL, name);
if (value == NULL)
{
if (m4_is_debug_bit (context, M4_DEBUG_TRACE_DEREF))
@@ -1016,6 +1000,28 @@ M4BUILTIN_HANDLER (renamesyms)
}
+/**
+ * m4modules()
+ **/
+M4BUILTIN_HANDLER (m4modules)
+{
+ /* The expansion of this builtin is a comma separated list of
+ loaded modules. */
+ m4_module *module = m4_module_next (context, NULL);
+
+ if (module)
+ do
+ {
+ m4_shipout_string (context, obs, m4_get_module_name (module), SIZE_MAX,
+ true);
+
+ if ((module = m4_module_next (context, module)))
+ obstack_1grow (obs, ',');
+ }
+ while (module);
+}
+
+
/* Implementation of "m4symbols". It builds up a table of pointers to
symbols, sorts it and ships out the symbol names. */
diff --git a/modules/import.c b/modules/import.c
index ebce6e4..679a50d 100644
--- a/modules/import.c
+++ b/modules/import.c
@@ -41,7 +41,7 @@
builtin_functions
#undef BUILTIN
-const m4_builtin m4_builtin_table[] =
+static const m4_builtin m4_builtin_table[] =
{
#define BUILTIN(handler, macros, blind, side, min, max) \
M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
@@ -53,6 +53,12 @@ const m4_builtin m4_builtin_table[] =
};
+M4INIT_HANDLER (import)
+{
+ m4_install_builtins (context, module, m4_builtin_table);
+}
+
+
typedef bool export_test_func (const char *);
typedef bool no_such_func (const char *);
diff --git a/modules/load.c b/modules/load.c
deleted file mode 100644
index 0b0eb1b..0000000
--- a/modules/load.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2000, 2005-2008, 2010, 2013 Free Software Foundation,
- Inc.
-
- This file is part of GNU M4.
-
- GNU M4 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 3 of the License, or
- (at your option) any later version.
-
- GNU M4 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-/* This module needs private symbols, and may not compile correctly if
- m4private.h isn't included. */
-#include "m4private.h"
-
-
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table load_LTX_m4_builtin_table
-#define m4_macro_table load_LTX_m4_macro_table
-
-
-/* Maintain each of the builtins implemented in this modules along
- with their details in a single table for easy maintenance.
-
- function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (m4modules, false, false, false, 0, 0 ) \
- BUILTIN (refcount, false, true, false, 1, 1 ) \
- BUILTIN (unload, false, true, false, 1, 1 ) \
-
-
-/* Generate prototypes for each builtin handler function. */
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
- builtin_functions
-#undef BUILTIN
-
-
-/* Generate a table for mapping m4 symbol names to handler functions. */
-const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-
-/* A table for mapping m4 symbol names to simple expansion text. */
-const m4_macro m4_macro_table[] =
-{
- /* name text min max */
- { "__load__", "", 0, 0 },
- { NULL, NULL, 0, 0 },
-};
-
-
-/* This module cannot be safely unloaded from memory, incase the unload
- is triggered by the unload builtin, and the module is removed while
- unload is in progress. */
-M4INIT_HANDLER (load)
-{
- const char *err = m4_module_makeresident (module);
- if (err)
- m4_error (context, 0, 0, NULL, _("cannot make module `%s' resident: %s"),
- m4_get_module_name (module), err);
-}
-
-
-
-/* Loading an external module at runtime.
- The following functions provide the implementation for each
- of the m4 builtins declared in `m4_builtin_table[]' above. */
-
-/**
- * m4modules()
- **/
-M4BUILTIN_HANDLER (m4modules)
-{
- /* The expansion of this builtin is a comma separated list of
- loaded modules. */
- m4_module *module = m4__module_next (NULL);
-
- if (module)
- do
- {
- m4_shipout_string (context, obs, m4_get_module_name (module), SIZE_MAX,
- true);
-
- if ((module = m4__module_next (module)))
- obstack_1grow (obs, ',');
- }
- while (module);
-}
-
-/**
- * refcount(module)
- **/
-M4BUILTIN_HANDLER (refcount)
-{
- m4_module *module = m4__module_find (M4ARG (1));
- m4_shipout_int (obs, module ? m4_module_refcount (module) : 0);
-}
-
-/**
- * unload(MODULE-NAME)
- **/
-M4BUILTIN_HANDLER (unload)
-{
- /* Remove all builtins and macros installed by the named module,
- and then unload the module from memory entirely. */
- m4_module_unload (context, M4ARG(1), obs);
-}
diff --git a/modules/m4.c b/modules/m4.c
index 64abdae..ecae4c3 100644
--- a/modules/m4.c
+++ b/modules/m4.c
@@ -39,8 +39,6 @@
#include <modules/m4.h>
/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table m4_LTX_m4_builtin_table
-
#define m4_set_sysval m4_LTX_m4_set_sysval
#define m4_sysval_flush m4_LTX_m4_sysval_flush
#define m4_dump_symbols m4_LTX_m4_dump_symbols
@@ -127,16 +125,9 @@ const m4_builtin m4_builtin_table[] =
};
-
-/* This module cannot be safely unloaded from memory, incase the unload
- is triggered by m4exit, and the module is removed while m4exit is in
- progress. */
M4INIT_HANDLER (m4)
{
- const char *err = m4_module_makeresident (module);
- if (err)
- m4_error (context, 0, 0, NULL, _("cannot make module `%s' resident: %s"),
- m4_get_module_name (module), err);
+ m4_install_builtins (context, module, m4_builtin_table);
}
@@ -840,9 +831,6 @@ M4BUILTIN_HANDLER (m4exit)
if (exit_code != EXIT_SUCCESS)
m4_set_exit_failure (exit_code);
- /* Ensure any module exit callbacks are executed. */
- m4__module_exit (context);
-
/* Change debug stream back to stderr, to force flushing debug
stream and detect any errors. */
m4_debug_set_output (context, me, NULL);
diff --git a/modules/modtest.c b/modules/modtest.c
index 5febf08..75450f7 100644
--- a/modules/modtest.c
+++ b/modules/modtest.c
@@ -29,9 +29,6 @@
#endif
/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table modtest_LTX_m4_builtin_table
-#define m4_macro_table modtest_LTX_m4_macro_table
-
#define export_test modtest_LTX_export_test
extern bool export_test (const char *foo);
@@ -44,7 +41,7 @@ extern bool export_test (const char *foo);
builtin_functions
#undef BUILTIN
-const m4_builtin m4_builtin_table[] =
+static const m4_builtin m4_builtin_table[] =
{
#define BUILTIN(handler, macros, blind, side, min, max) \
M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
@@ -55,7 +52,7 @@ const m4_builtin m4_builtin_table[] =
{ NULL, NULL, 0, 0, 0 },
};
-const m4_macro m4_macro_table[] =
+static const m4_macro m4_macro_table[] =
{
/* name text min max */
{ "__test__", "`modtest'", 0, 0 },
@@ -73,18 +70,8 @@ M4INIT_HANDLER (modtest)
{
const char *s = "Test module loaded.\n";
- /* Don't depend on OBS so that the traces are the same when used
- directly, or via a frozen file. */
- fputs (s, stderr);
-}
-
-
-/**
- * modtest()
- **/
-M4FINISH_HANDLER (modtest)
-{
- const char *s = "Test module unloaded.\n";
+ m4_install_builtins (context, module, m4_builtin_table);
+ m4_install_macros (context, module, m4_macro_table);
/* Don't depend on OBS so that the traces are the same when used
directly, or via a frozen file. */
diff --git a/modules/mpeval.c b/modules/mpeval.c
index 7928a28..49afd76 100644
--- a/modules/mpeval.c
+++ b/modules/mpeval.c
@@ -32,11 +32,6 @@
# include <gmp.h>
#endif
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table mpeval_LTX_m4_builtin_table
-#define m4_macro_table mpeval_LTX_m4_macro_table
-
-
/* Maintain each of the builtins implemented in this modules along
with their details in a single table for easy maintenance.
@@ -106,7 +101,7 @@
/* Generate a table for mapping m4 symbol names to handler functions. */
-const m4_builtin m4_builtin_table[] =
+static const m4_builtin m4_builtin_table[] =
{
#define BUILTIN(handler, macros, blind, side, min, max) \
M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
@@ -119,7 +114,7 @@ const m4_builtin m4_builtin_table[] =
/* A table for mapping m4 symbol names to simple expansion text. */
-const m4_macro m4_macro_table[] =
+static const m4_macro m4_macro_table[] =
{
/* name text min max */
{ "__mpeval__", "", 0, 0 },
@@ -127,6 +122,13 @@ const m4_macro m4_macro_table[] =
};
+M4INIT_HANDLER (mpeval)
+{
+ m4_install_builtins (context, module, m4_builtin_table);
+ m4_install_macros (context, module, m4_macro_table);
+}
+
+
/* GMP defines mpq_t as a 1-element array of struct. Therefore, `mpq_t'
is not compatible with `const mpq_t'. */
typedef mpq_t number;
diff --git a/modules/shadow.c b/modules/shadow.c
index 16260f1..5382993 100644
--- a/modules/shadow.c
+++ b/modules/shadow.c
@@ -28,10 +28,6 @@
# include "m4private.h"
#endif
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table shadow_LTX_m4_builtin_table
-#define m4_macro_table shadow_LTX_m4_macro_table
-
/* function macros blind side minargs maxargs */
#define builtin_functions \
BUILTIN (shadow, false, false, false, 0, -1 ) \
@@ -42,7 +38,7 @@
builtin_functions
#undef BUILTIN
-const m4_builtin m4_builtin_table[] =
+static const m4_builtin m4_builtin_table[] =
{
#define BUILTIN(handler, macros, blind, side, min, max) \
M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
@@ -53,7 +49,7 @@ const m4_builtin m4_builtin_table[] =
{ NULL, NULL, 0, 0, 0 },
};
-const m4_macro m4_macro_table[] =
+static const m4_macro m4_macro_table[] =
{
/* name text min max */
{ "__test__", "`shadow'", 0, 0 },
@@ -65,11 +61,12 @@ const m4_macro m4_macro_table[] =
M4INIT_HANDLER (shadow)
{
const char *s = "Shadow module loaded.";
- int refcount = m4_module_refcount (module);
- /* Only display the message on first load. */
- if (obs && refcount == 1)
- obstack_grow (obs, s, strlen (s));
+ if (obs)
+ obstack_grow (obs, s, strlen (s));
+
+ m4_install_builtins (context, module, m4_builtin_table);
+ m4_install_macros (context, module, m4_macro_table);
}
diff --git a/modules/stdlib.c b/modules/stdlib.c
index d8f839c..b01326d 100644
--- a/modules/stdlib.c
+++ b/modules/stdlib.c
@@ -36,12 +36,9 @@
# include "m4private.h"
#endif
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table stdlib_LTX_m4_builtin_table
-
/* function macros blind side minargs maxargs */
#define builtin_functions \
- BUILTIN (getcwd, false, false, false, 0, 0 ) \
+ BUILTIN (getcwd, false, false, false, 0, 0 ) \
BUILTIN (getenv, false, true, false, 1, 1 ) \
BUILTIN (getlogin, false, false, false, 0, 0 ) \
BUILTIN (getpid, false, false, false, 0, 0 ) \
@@ -61,7 +58,7 @@
builtin_functions
#undef BUILTIN
-const m4_builtin m4_builtin_table[] =
+static const m4_builtin m4_builtin_table[] =
{
#define BUILTIN(handler, macros, blind, side, min, max) \
M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
@@ -71,6 +68,13 @@ const m4_builtin m4_builtin_table[] =
{ NULL, NULL, 0, 0, 0 },
};
+
+
+M4INIT_HANDLER (stdlib)
+{
+ m4_install_builtins (context, module, m4_builtin_table);
+}
+
/**
* getcwd()
diff --git a/modules/time.c b/modules/time.c
index 573d14d..39db75f 100644
--- a/modules/time.c
+++ b/modules/time.c
@@ -34,9 +34,6 @@
# include "m4private.h"
#endif
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table time_LTX_m4_builtin_table
-
/* function macros blind side minargs maxargs */
#define builtin_functions \
BUILTIN (currenttime, false, false, false, 0, 0 ) \
@@ -61,7 +58,7 @@
# endif
#undef BUILTIN
-const m4_builtin m4_builtin_table[] =
+static const m4_builtin m4_builtin_table[] =
{
#define BUILTIN(handler, macros, blind, side, min, max) \
M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
@@ -77,6 +74,14 @@ const m4_builtin m4_builtin_table[] =
{ NULL, NULL, 0, 0, 0 },
};
+
+
+M4INIT_HANDLER (time)
+{
+ m4_install_builtins (context, module, m4_builtin_table);
+}
+
+
/**
* currenttime()
diff --git a/modules/traditional.c b/modules/traditional.c
index cb9a32b..88a4966 100644
--- a/modules/traditional.c
+++ b/modules/traditional.c
@@ -28,11 +28,8 @@
# include "m4private.h"
#endif
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_macro_table traditional_LTX_m4_macro_table
-
/* A table for mapping m4 symbol names to simple expansion text. */
-const m4_macro m4_macro_table[] =
+static const m4_macro m4_macro_table[] =
{
/* name text min max */
#if UNIX
@@ -47,3 +44,8 @@ const m4_macro m4_macro_table[] =
{ "__traditional__", "", 0, 0 },
{ NULL, NULL, 0, 0 },
};
+
+M4INIT_HANDLER (traditional)
+{
+ m4_install_macros (context, module, m4_macro_table);
+}
diff --git a/src/freeze.c b/src/freeze.c
index 9f36e8c..3b1fdd9 100644
--- a/src/freeze.c
+++ b/src/freeze.c
@@ -33,7 +33,7 @@
static void produce_mem_dump (FILE *, const char *, size_t);
static void produce_resyntax_dump (m4 *, FILE *);
static void produce_syntax_dump (FILE *, m4_syntax_table *, char);
-static void produce_module_dump (FILE *, m4_module *);
+static void produce_module_dump (m4 *, FILE *, m4_module *);
static void produce_symbol_dump (m4 *, FILE *, m4_symbol_table *);
static void *dump_symbol_CB (m4_symbol_table *, const char *,
size_t, m4_symbol *, void *);
@@ -148,17 +148,17 @@ produce_debugmode_state (FILE *file, int flags)
}
/* The modules must be dumped in the order in which they will be
- reloaded from the frozen file. libltdl stores handles in a push
+ reloaded from the frozen file. We store handles in a push
down stack, so we need to dump them in the reverse order to that. */
static void
-produce_module_dump (FILE *file, m4_module *module)
+produce_module_dump (m4 *context, FILE *file, m4_module *module)
{
const char *name = m4_get_module_name (module);
size_t len = strlen (name);
- module = m4__module_next (module);
+ module = m4_module_next (context, module);
if (module)
- produce_module_dump (file, module);
+ produce_module_dump (context, file, module);
xfprintf (file, "M%zu\n", len);
produce_mem_dump (file, name, len);
@@ -322,7 +322,7 @@ produce_frozen_state (m4 *context, const char *name)
produce_debugmode_state (file, m4_get_debug_level_opt (context));
/* Dump all loaded modules. */
- produce_module_dump (file, m4__module_next (NULL));
+ produce_module_dump (context, file, m4_module_next (context, NULL));
/* Dump all symbols. */
produce_symbol_dump (context, file, M4SYMTAB);
@@ -711,9 +711,9 @@ ill-formed frozen file, invalid builtin %s encountered"),
ill-formed frozen file, invalid module %s encountered"),
quotearg_style_mem (locale_quoting_style,
string[2], number[2]));
- module = m4__module_find (string[2]);
+ module = m4__module_find (context, string[2]);
}
- token = m4_builtin_find_by_name (module, string[1]);
+ token = m4_builtin_find_by_name (context, module, string[1]);
if (token == NULL)
{
@@ -966,7 +966,7 @@ ill-formed frozen file, version 2 directive `%c'
encountered"), 'T');
ill-formed frozen file, invalid module %s encountered"),
quotearg_style_mem (locale_quoting_style,
string[2], number[2]));
- module = m4__module_find (string[2]);
+ module = m4__module_find (context, string[2]);
}
m4_set_symbol_value_text (token, xmemdup0 (string[1], number[1]),
diff --git a/src/main.c b/src/main.c
index 1e3e706..5330545 100644
--- a/src/main.c
+++ b/src/main.c
@@ -744,7 +744,6 @@ main (int argc, char *const *argv, char *const *envp)
Strictly, we don't need to do this, but it makes leak detection
a whole lot easier! */
- m4__module_exit (context);
m4_output_exit ();
m4_input_exit ();
diff --git a/tests/modules.at b/tests/modules.at
index 623f531..dddba9e 100644
--- a/tests/modules.at
+++ b/tests/modules.at
@@ -51,14 +51,14 @@ test3
# First generate the `expout' ouput by running over the sources before
# freezing.
-AT_CHECK_M4([-I "$abs_builddir" load frozen.m4 unfrozen.m4],
+AT_CHECK_M4([-I "$abs_builddir" frozen.m4 unfrozen.m4],
[0], [stdout], [stderr])
mv stdout expout
mv stderr experr
# Now freeze the first source file.
-AT_CHECK_M4([-I "$abs_builddir" load -F frozen.m4f frozen.m4],
+AT_CHECK_M4([-I "$abs_builddir" -F frozen.m4f frozen.m4],
[0], [], [ignore])
# Now rerun the original sequence, but using the frozen file.
@@ -68,33 +68,6 @@ AT_CHECK_M4([-I "$abs_builddir" -R frozen.m4f unfrozen.m4],
AT_CLEANUP([frozen.m4f])
-## ------------------ ##
-## module test macros ##
-## ------------------ ##
-
-AT_SETUP([module test macros])
-AT_CHECK_DYNAMIC_MODULE
-AT_CHECK_GMP
-
-AT_DATA([in], [[include(`mpeval')
--__load__-__mpeval__-
-unload(`mpeval')
--__load__-__mpeval__-
-unload(`load')
--__load__-__mpeval__-
-]])
-
-AT_CHECK_M4([load in], [0], [[
----
-
---__mpeval__-
-
--__load__-__mpeval__-
-]])
-
-AT_CLEANUP
-
-
## ---------------------------- ##
## Exercising the test module. ##
## ---------------------------- ##
@@ -108,10 +81,9 @@ m4_define([AT_CHECK_M4_MODTEST],
AT_CHECK_DYNAMIC_MODULE
AT_DATA([input.m4],
-[[include(`modtest')
-test
+[[test
Dumpdef: dumpdef(`test').
-unload(`modtest')
+include(`modtest')
test
Dumpdef: dumpdef(`test').
]])
@@ -122,18 +94,16 @@ dnl carry over to the next AT_SETUP.
m4_ifval([$2], [$2
export m4_substr([$2], [0], m4_index([$2], [=]))])
-AT_CHECK_M4([load $3 input.m4], [0],
-[[
-Test module called.
+AT_CHECK_M4([$3 input.m4], [0],
+[[test
Dumpdef: .
-test
+Test module called.
Dumpdef: .
]],
-[[Test module loaded.
+[[m4:input.m4:2: warning: dumpdef: undefined macro 'test'
+Test module loaded.
test: <test>
-Test module unloaded.
-m4:input.m4:6: warning: dumpdef: undefined macro 'test'
]])
AT_CLEANUP
@@ -196,26 +166,6 @@ dumpdef(`test')
dumpdef(`shadow')
test
shadow
-
-# Unloading Modtest will unshadow the test definition in Shadow
-unload(`modtest')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# Unloading Shadow once has no effect (we loaded it twice)
-unload(`shadow')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# Unloading Shadow again will revert to copying `test' and the local
-# `shadow' macro.
-unload(`shadow')
-test
-shadow
]])
AT_DATA([[expout]],
@@ -252,26 +202,6 @@ Shadow::shadow called.
Test module called.
Shadow::shadow called.
-
-# Unloading Modtest will unshadow the test definition in Shadow
-
-
-
-Shadow::test called.
-Shadow::shadow called.
-
-# Unloading Shadow once has no effect (we loaded it twice)
-
-
-
-Shadow::test called.
-Shadow::shadow called.
-
-# Unloading Shadow again will revert to copying `test' and the local
-# `shadow' macro.
-
-local::test
-local::shadow
]])
AT_DATA([[experr]],
@@ -282,88 +212,15 @@ test: <test>
shadow: <shadow>
test: <test>
shadow: <shadow>
-Test module unloaded.
-test: <test>
-shadow: <shadow>
-test: <test>
-shadow: <shadow>
]])
-AT_CHECK_M4([-I "$abs_builddir" load input.m4], [0],
+AT_CHECK_M4([-I "$abs_builddir" input.m4], [0],
[expout], [experr])
AT_CLEANUP
-## ------ ##
-## unload ##
-## ------ ##
-
-AT_SETUP([modules: unload])
-AT_CHECK_DYNAMIC_MODULE
-
-AT_DATA([[input.m4]],
-[[test
-__test__
-include(`modtest')
-test
-__test__
-include(`shadow')
-test
-__test__
-unload(`modtest')
-test
-__test__
-include(`modtest')
-test
-__test__
-unload(`modtest')
-test
-__test__
-unload(`shadow')
-test
-__test__
-]])
-
-AT_DATA([[expout]],
-[[test
-__test__
-
-Test module called.
-modtest
-Shadow module loaded.
-Shadow::test called.
-shadow
-
-Shadow::test called.
-shadow
-
-Test module called.
-modtest
-
-Shadow::test called.
-shadow
-
-test
-__test__
-]])
-
-AT_DATA([[experr]],
-[[Test module loaded.
-Test module unloaded.
-Test module loaded.
-Test module unloaded.
-]])
-
-
-AT_CHECK_M4([-I "$abs_builddir" load input.m4],
- [0], [expout], [experr])
-
-AT_CLEANUP
-
-
-
## ----------------------- ##
## module symbol importing ##
## ----------------------- ##
@@ -382,7 +239,6 @@ AT_DATA([[input.m4]],
[[import
include(`import')
import
-unload(`modtest')
import
symbol_fail
module_fail
@@ -392,7 +248,6 @@ AT_DATA([[expout]],
[[import
import::import called.
-
import::import called.
import::symbol_fail called.
]])
@@ -401,17 +256,15 @@ AT_DATA([[experr]],
[[Test module loaded.
TRUE
-Test module unloaded.
-Test module loaded.
TRUE
-m4:input.m4:6: cannot load symbol `no_such' from module `modtest'
-m4:input.m4:7: cannot open module `no_such'
+m4:input.m4:5: cannot load symbol `no_such' from module `modtest'
+m4:input.m4:6: cannot open module `no_such'
]])
ls "$abs_builddir"
-AT_CHECK_M4([-I "$abs_builddir" load input.m4],
+AT_CHECK_M4([-I "$abs_builddir" input.m4],
[1], [expout], [experr])
AT_CLEANUP
@@ -454,7 +307,6 @@ m4:input.m4:2: warning: __test__: extra arguments ignored:
1 > 0
m4:input.m4:3: warning: __test__: extra arguments ignored: 2 > 0
m4:input.m4:4: warning: onearg: too few arguments: 0 < 1
m4:input.m4:6: warning: onearg: extra arguments ignored: 2 > 1
-Test module unloaded.
]])
AT_CLEANUP
@@ -474,8 +326,6 @@ AT_DATA([[input.m4]],
[[test
include(`shadow')
test
-unload(`shadow')
-test
include(`shadow')
test
]])
@@ -485,8 +335,6 @@ AT_DATA([[expout]],
Shadow module loaded.
Shadow::test called.
-test
-Shadow module loaded.
Shadow::test called.
]])
@@ -496,74 +344,7 @@ m4trace: -1- test -> `Shadow::`test' called.'
]])
-AT_CHECK_M4([-I "$abs_builddir" load -t test input.m4],
+AT_CHECK_M4([-I "$abs_builddir" -t test input.m4],
[0], [expout], [experr])
AT_CLEANUP
-
-
-## ----------------- ##
-## unload gnu module ##
-## ----------------- ##
-
-AT_SETUP([unload gnu module])
-AT_CHECK_DYNAMIC_MODULE
-
-dnl Ensure that the gnu module does not leak memory. I don't know how
-dnl to portably artificially limit the heap to cause an out-of-memory
-dnl condition in the case of a leak, but examining the run of this test
-dnl in a debugger can show whether it is leaking.
-AT_DATA([input.m4], [[divert(-1)
-define(`forloop',
- `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
-define(`_forloop',
- `$4`'ifelse($1, `$3', `',
- `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
-forloop(`i', `1', `5000', `unload(`gnu')include(`gnu')regexp(`123',
`\(4\)?2')')
-]])
-
-AT_CHECK_M4([load input.m4], [0])
-
-AT_CLEANUP
-
-
-## ------------------ ##
-## unload load module ##
-## ------------------ ##
-
-AT_SETUP([unload load module])
-AT_CHECK_DYNAMIC_MODULE
-
-dnl Ensure that the load module can be unloaded and reloaded (obviously,
-dnl it can't reload itself; the reload occurs on the command line). Since
-dnl the module must be resident (after all, the `unload' builtin had better
-dnl not unmap the memory for the code it is currently executing), make sure
-dnl that resident modules are handled gracefully.
-AT_DATA([in1.m4], [[__load__ 1
-unload(`load') 2
-__load__ 3
-]])
-
-AT_DATA([in2.m4], [[__load__ 4
-include(`load') 5
-__load__ 6
-unload(`load') 7
-__load__ 8
-unload(`load') 9
-__load__ 10
-]])
-
-AT_CHECK_M4([load in1.m4 load in2.m4], [0],
-[[ 1
- 2
-__load__ 3
- 4
- 5
- 6
- 7
- 8
- 9
-__load__ 10
-]])
-
-AT_CLEANUP
diff --git a/tests/options.at b/tests/options.at
index 921c6fe..8503f8f 100644
--- a/tests/options.at
+++ b/tests/options.at
@@ -427,6 +427,7 @@ m4debug: module m4: init hook called
m4debug: module m4: opened
m4debug: module m4: builtins loaded
m4debug: module gnu: opening file
+m4debug: module gnu: init hook called
m4debug: module gnu: opened
m4debug: module gnu: builtins loaded
m4debug: module gnu: macros loaded
@@ -451,11 +452,6 @@ m4debug: input from m4wrap recursion level 1
m4trace:nested:1: -1- id 6: divnum ... = <divnum>{m4}
m4trace:nested:1: -1- id 6: divnum -> `0'
m4debug: input from m4wrap exhausted
-m4debug: module gnu: symbols unloaded
-m4debug: module gnu: finish hook called
-m4debug: module gnu: closed
-m4debug: module m4: symbols unloaded
-m4debug: module m4: resident module not closed
]])
dnl Test addition and subtraction of flags.
hooks/post-receive
--
GNU M4 source repository
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] GNU M4 source repository branch, master, updated. cvs-readonly-306-g7781a59,
Gary V. Vaughan <=