summaryrefslogtreecommitdiff
path: root/modules/README
blob: b8f8169ca6073941bf39373943478c69f18de2c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
This directory contains all bundled modules for GNU m4.

Dynamic modules are only available if the host operating system provides
one (or more!) of libltdl's required APIs.

Implementation details are in ../m4/module.c

A module is a compiled shared object, i.e., modules are written in C and
then compiled.  The compiled file can then be loaded into a running m4
process by calling m4 with the module name listed on the command line,
or by calling the builtin "include". This gives GNU m4 potential access
to any system feature with a C interface.

Modules are searched for in M4PATH, if set, else in a module directory
defined at configure time, $prefix/lib/m4/ by default.  Extra directories
can also be added to the search patch by specifying them on the command
line with the `-I' or `-B' options.

A module extends GNU m4 by defining new builtins, It can define builtins
with the same names as existing builtins, which will shadow the existing
builtins, making them temporarily unavailable.  A module cannot redefine
internal functions of GNU m4, such as the input parser or argument handling
(yet!).

Each module should include the installed header file,
`$prefix/include/m4module.h'.  This will define all the necessary macros,
type declarations and function prototypes required to implement a module.

The module system uses libtool's libltdl for dynamic module loading, and
that in turn requires that any non-static symbols in the module to be
be in their own namespace to avoid namespace clashes with symbols
exported from other modules (which may be loaded too!).  This is usually
done by `#define'ing these symbols to libltdl's naming scheme at the top
of the file.  The scheme is to prefix each symbol with the module name,
followed by `_LTX_' and then the original symbol name.  For example,
to export "m4_macro_table" in a source file which will become part of
a module, "mymod", we would add the following to the top of the source file:
`#define m4_macro_table mymod_LTX_m4_macro_table'.  See the included modules
for more examples.

Each module *must* define one or more entry points from the following:
"m4_builtin_table", "m4_macro_table" and "m4_init_module".  The symbol
"m4_builtin_table" is a pointer to a table of "m4_builtin" (defined in
m4module.h), listing each new builtin that it implements.  The symbol
"m4_macro_table", is a pointer to a table of "m4_macro", listing each
text macro initialised by the module.  These tables end with an
entry where name == NULL.

If a module defines the symbol "m4_init_module", it is supposed to be a
function with a prototype of "void m4_init_module (struct obstack *obs)",
and it will be called as soon as the module is loaded.  Any non-finished
object left on the obstack will be the expansion of the call of the
builtin "include".  The obstack pointer might be NULL (in the future).

If a module defines the symbol "m4_finish_module", it is supposed to be
a function with a prototype of "void m4_finish_module (void)", and it
will be called just before the module is unloaded or GNU m4 exits.  This
will allow a module to clean up before exit.  There is no way of
communicating information to the user, as GNU m4 exits immediately
afterwards.

No other symbols will be used by GNU m4.  All other symbols within the
module are private and should be declared `static' so that they will not
be accessible to GNU m4 or to other modules.

Modules are allowed to call external functions already defined within
the GNU m4module library.  These have prototypes in m4module.h.

Loading and unloading of modules, and symbol namespace resolution
strategies are illustrated by shadow.c and shadow.m4.

To try the demos, compile with `make' and run them with the commands as:

    tests/m4 doc/examples/time.m4

or in the case of time2.m4

    tests/m4 -I tests time -I doc/examples time2.m4

========================================================================

Copyright (C) 2000-2001, 2006, 2010, 2013-2014, 2017 Free Software
Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the ``GNU Free
Documentation License'' file as part of this distribution.