GNU M4, Version 1.4.19: by Ren e Seindal, Fran Cois Pinard, Gary V. Vaughan, and Eric Blake
GNU M4, Version 1.4.19: by Ren e Seindal, Fran Cois Pinard, Gary V. Vaughan, and Eric Blake
19
A powerful macro processor
Edition 1.4.19, 28 May 2021
Table of Contents
2 Invoking m4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1 Command line options for operation modes . . . . . . . . . . . . . . . . . . . . . 7
2.2 Command line options for preprocessor features . . . . . . . . . . . . . . . . . 8
2.3 Command line options for limits control . . . . . . . . . . . . . . . . . . . . . . . 10
2.4 Command line options for frozen state . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5 Command line options for debugging . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6 Specifying input files on the command line . . . . . . . . . . . . . . . . . . . . . 12
8 Input control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.1 Deleting whitespace in input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.2 Changing the quote characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
8.3 Changing the comment delimiters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
8.4 Changing the lexical structure of words . . . . . . . . . . . . . . . . . . . . . . . . 68
8.5 Saving text until end of input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
9 File inclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
9.1 Including named files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
9.2 Searching for include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
1.1 Introduction to m4
m4 is a macro processor, in the sense that it copies its input to the output, expanding
macros as it goes. Macros are either builtin or user-defined, and can take any number
of arguments. Besides just doing macro expansion, m4 has builtin functions for including
named files, running shell commands, doing integer arithmetic, manipulating text in various
ways, performing recursion, etc.. . . m4 can be used either as a front-end to a compiler, or
as a macro processor in its own right.
The m4 macro processor is widely available on all UNIXes, and has been standardized by
POSIX. Usually, only a small percentage of users are aware of its existence. However, those
who find it often become committed users. The popularity of GNU Autoconf, which requires
GNU m4 for generating configure scripts, is an incentive for many to install it, while these
people will not themselves program in m4. GNU m4 is mostly compatible with the System
V, Release 4 version, except for some minor differences. See Chapter 16 [Compatibility],
page 109, for more details.
Some people find m4 to be fairly addictive. They first use m4 for simple problems, then
take bigger and bigger challenges, learning how to write complex sets of m4 macros along
the way. Once really addicted, users pursue writing of sophisticated m4 applications even to
solve simple problems, devoting more time debugging their m4 scripts than doing real work.
Beware that m4 may be dangerous for the health of compulsive programmers.
Once you’ve got a precise problem, send e-mail to [email protected]. Please include the
version number of m4 you are using. You can get this information with the command m4
--version. Also provide details about the platform you are executing on.
Non-bug suggestions are always welcome as well. If you have questions about things
that are unclear in the documentation or are just obscure features, please report them too.
All macro arguments in m4 are strings, but some are given special interpretation, e.g., as
numbers, file names, regular expressions, etc. The documentation for each macro will state
6 GNU M4 1.4.19 macro processor
how the parameters are interpreted, and what happens if the argument cannot be parsed
according to the desired interpretation. Unless specified otherwise, a parameter specified
to be a number is parsed as a decimal, even if the argument has leading zeros; and parsing
the empty string as a number results in 0 rather than an error, although a warning will be
issued.
This document consistently writes and uses builtin, without a hyphen, as if it were an
English word. This is how the builtin primitive is spelled within m4.
7
2 Invoking m4
The format of the m4 command is:
m4 [option...] [file...]
All options begin with ‘-’, or if long option names are used, with ‘--’. A long option
name need not be written completely, any unambiguous prefix is sufficient. POSIX requires
m4 to recognize arguments intermixed with files, even when POSIXLY_CORRECT is set in the
environment. Most options take effect at startup regardless of their position, but some are
documented below as taking effect after any files that occurred earlier in the command line.
The argument -- is a marker to denote the end of options.
With short options, options that do not take arguments may be combined into a single
command line argument with subsequent options, options with mandatory arguments may
be provided either as a single command line argument or as two arguments, and options
with optional arguments must be provided as a single argument. In other words, m4 -
QPDfoo -d a -df is equivalent to m4 -Q -P -D foo -d -df -- ./a, although the latter form
is considered canonical.
With long options, options with mandatory arguments may be provided with an equal
sign (‘=’) in a single argument, or as two arguments, and options with optional arguments
must be provided as a single argument. In other words, m4 --def foo --debug a is equiva-
lent to m4 --define=foo --debug= -- ./a, although the latter form is considered canonical
(not to mention more robust, in case a future version of m4 introduces an option named
--default).
m4 understands the following options, grouped by functionality.
-P
--prefix-builtins
Internally modify all builtin macro names so they all start with the prefix
‘m4_’. For example, using this option, one should write ‘m4_define’ instead of
‘define’, and ‘m4___file__’ instead of ‘__file__’. This option has no effect
if -R is also specified.
-Q
--quiet
--silent Suppress warnings, such as missing or superfluous arguments in macro calls, or
treating the empty string as zero.
--warn-macro-sequence[=regexp]
Issue a warning if the regular expression regexp has a non-empty match in
any macro definition (either by define or pushdef). Empty matches are ig-
nored; therefore, supplying the empty string as regexp disables any warning.
If the optional regexp is not supplied, then the default regular expression is
‘\$\({[^}]*}\|[0-9][0-9]+\)’ (a literal ‘$’ followed by multiple digits or by
an open brace), since these sequences will change semantics in the default op-
eration of GNU M4 2.0 (due to a change in how more than 9 arguments in a
macro definition will be handled, see Section 5.2 [Arguments], page 26). Provid-
ing an alternate regular expression can provide a useful reverse lookup feature
of finding where a macro is defined to have a given definition.
-W regexp
--word-regexp=regexp
Use regexp as an alternative syntax for macro names. This experimental option
will not be present in all GNU m4 implementations (see Section 8.4 [Change-
word], page 68).
-D name[=value]
--define=name[=value]
This enters name into the symbol table. If ‘=value’ is missing, the value is
taken to be the empty string. The value can be any string, and the macro can
be defined to take arguments, just as if it was defined from within the input.
This option may be given more than once; order with respect to file names is
significant, and redefining the same name loses the previous value.
Chapter 2: Invoking m4 9
-I directory
--include=directory
Make m4 search directory for included files that are not found in the current
working directory. See Section 9.2 [Search Path], page 74, for more details.
This option may be given more than once.
-s
--synclines
Generate synchronization lines, for use by the C preprocessor or other similar
tools. Order is significant with respect to file names. This option is useful, for
example, when m4 is used as a front end to a compiler. Source file name and
line number information is conveyed by directives of the form ‘#line linenum
"file"’, which are inserted as needed into the middle of the output. Such
directives mean that the following line originated or was expanded from the
contents of input file file at line linenum. The ‘"file"’ part is often omitted
when the file name did not change from the previous directive.
Synchronization directives are always given on complete lines by themselves.
When a synchronization discrepancy occurs in the middle of an output line, the
associated synchronization directive is delayed until the next newline that does
not occur in the middle of a quoted string or comment.
define(`twoline', `1
2')
⇒#line 2 "stdin"
⇒
changecom(`/*', `*/')
⇒
define(`comment', `/*1
2*/')
⇒#line 5
⇒
dnl no line
hello
⇒#line 7
⇒hello
twoline
⇒1
⇒#line 8
⇒2
comment
⇒/*1
⇒2*/
one comment `two
three'
⇒#line 10
⇒one /*1
⇒2*/ two
⇒three
10 GNU M4 1.4.19 macro processor
goodbye
⇒#line 12
⇒goodbye
-U name
--undefine=name
This deletes any predefined meaning name might have. Obviously, only prede-
fined macros can be deleted in this way. This option may be given more than
once; undefining a name that does not have a definition is silently ignored.
Order is significant with respect to file names.
-g
--gnu Enable all the extensions in this implementation. In this release of M4, this op-
tion is always on by default; it is currently only useful when overriding a prior
use of --traditional. However, having GNU behavior as default makes it
impossible to write a strictly POSIX-compliant client that avoids all incompat-
ible GNU M4 extensions, since such a client would have to use the non-POSIX
command-line option to force full POSIX behavior. Thus, a future version of
M4 will be changed to implicitly use the option --traditional if the environ-
ment variable POSIXLY_CORRECT is set. Projects that intentionally use GNU
extensions should consider using --gnu to state their intentions, so that the
project will not mysteriously break if the user upgrades to a newer M4 and has
POSIXLY_CORRECT set in their environment.
-G
--traditional
Suppress all the extensions made in this implementation, compared to the Sys-
tem V version. See Chapter 16 [Compatibility], page 109, for a list of these.
-H num
--hashsize=num
Make the internal hash table for symbol lookup be num entries big. For better
performance, the number should be prime, but this is not checked. The default
is 65537 entries. It should not be necessary to increase this value, unless you
define an excessive number of macros.
-L num
--nesting-limit=num
Artificially limit the nesting of macro calls to num levels, stopping program
execution if this limit is ever exceeded. When not specified, nesting defaults
to unlimited on platforms that can detect stack overflow, and to 1024 levels
otherwise. A value of zero means unlimited; but then heavily nested code could
potentially cause a stack overflow.
Chapter 2: Invoking m4 11
The precise effect of this option is more correctly associated with textual nesting
than dynamic recursion. It has been useful when some complex m4 input was
generated by mechanical means, and also in diagnosing recursive algorithms
that do not scale well. Most users never need to change this option from its
default.
This option does not have the ability to break endless rescanning loops, since
these do not necessarily consume much memory or stack space. Through clever
usage of rescanning loops, one can request complex, time-consuming computa-
tions from m4 with useful results. Putting limitations in this area would break
m4 power. There are many pathological cases: ‘define(`a', `a')a’ is only the
simplest example (but see Chapter 16 [Compatibility], page 109). Expecting
GNU m4 to detect these would be a little like expecting a compiler system to
detect and diagnose endless loops: it is a quite hard problem in general, if not
undecidable!
-B num
-S num
-T num These options are present for compatibility with System V m4, but do nothing
in this implementation. They may disappear in future releases, and issue a
warning to that effect.
-N num
--diversions=num
These options are present only for compatibility with previous versions of GNU
m4, and were controlling the number of possible diversions which could be used
at the same time. They do nothing, because there is no fixed limit anymore.
They may disappear in future releases, and issue a warning to that effect.
-F file
--freeze-state=file
Once execution is finished, write out the frozen state on the specified file. It is
conventional, but not required, for file to end in ‘.m4f’.
-R file
--reload-state=file
Before execution starts, recover the internal state from the specified frozen file.
The options -D, -U, and -t take effect after state is reloaded, but before the
input files are read.
-d[flags]
--debug[=flags]
Set the debug-level according to the flags flags. The debug-level controls the
format and amount of information presented by the debugging functions. See
Section 7.3 [Debug Levels], page 58, for more details on the format and meaning
of flags. If omitted, flags defaults to ‘aeq’.
--debugfile[=file]
-o file
--error-output=file
Redirect dumpdef output, debug messages, and trace output to the named file.
Warnings, error messages, and errprint output are still printed to standard
error. If these options are not used, or if file is unspecified (only possible for
--debugfile), debug output goes to standard error; if file is the empty string,
debug output is discarded. See Section 7.4 [Debug Output], page 60, for more
details. The option --debugfile may be given more than once, and order is
significant with respect to file names. The spellings -o and --error-output
are misleading and inconsistent with other GNU tools; for now they are silently
accepted as synonyms of --debugfile and only recognized once, but in a future
version of M4, using them will cause a warning to be issued.
-l num
--arglength=num
Restrict the size of the output generated by macro tracing to num characters
per trace line. If unspecified or zero, output is unlimited. See Section 7.3
[Debug Levels], page 58, for more details.
-t name
--trace=name
This enables tracing for the macro name, at any point where it is defined. name
need not be defined when this option is given. This option may be given more
than once, and order is significant with respect to file names. See Section 7.2
[Trace], page 55, for more details.
The text ‘bar’ can then be redefined over multiple uses of foo:
$ m4 -Dbar=hello foo -Dbar=world foo
⇒hello
⇒world
If none of the input files invoked m4exit (see Section 14.3 [M4exit], page 103), the exit
status of m4 will be 0 for success, 1 for general failure (such as problems with reading an
input file), and 63 for version mismatch (see Section 15.1 [Using frozen files], page 105).
If you need to read a file whose name starts with a -, you can specify it as ‘./-file’,
or use -- to mark the end of options.
15
⇒
⇒ GNULIB_strcase=1
⇒
Oops – the argument did not get capitalized. And although the manual is not able
to easily show it, both lines that appear empty actually contain two trailing spaces. By
stepping through the parse, it is easy to see what happened. First, m4 sees the token
‘changequote’, which it recognizes as a macro, followed by ‘(’, ‘[’, ‘,’, ‘]’, and ‘)’ to
form the argument list. The macro expands to the empty string, but changes the quoting
characters to something more useful for generating shell code (unbalanced ‘`’ and ‘'’ appear
all the time in shell scripts, but unbalanced ‘[]’ tend to be rare). Also in the first line, m4
sees the token ‘dnl’, which it recognizes as a builtin macro that consumes the rest of the
line, resulting in no output for that line.
The second line starts a macro definition. m4 sees the token ‘define’, which it recognizes
as a macro, followed by a ‘(’, ‘[gl_STRING_MODULE_INDICATOR]’, and ‘,’. Because an
unquoted comma was encountered, the first argument is known to be the expansion of
the single-quoted string token, or ‘gl_STRING_MODULE_INDICATOR’. Next, m4 sees ‘NL’, ‘
’, and ‘ ’, but this whitespace is discarded as part of argument collection. Then comes a
rather lengthy single-quoted string token, ‘[NL dnl commentNL GNULIB_]’. This is
followed by the token ‘translit’, which m4 recognizes as a macro name, so a nested macro
expansion has started.
The arguments to the translit are found by the tokens ‘(’, ‘[$1]’, ‘,’, ‘[a-z]’, ‘,’,
‘[A-Z]’, and finally ‘)’. All three string arguments are expanded (or in other words, the
quotes are stripped), and since neither ‘$’ nor ‘1’ need capitalization, the result of the macro
is ‘$1’. This expansion is rescanned, resulting in the two literal characters ‘$’ and ‘1’.
Scanning of the outer macro resumes, and picks up with ‘[=1NL ]’, and finally ‘)’.
The collected pieces of expanded text are concatenated, with the end result that the macro
‘gl_STRING_MODULE_INDICATOR’ is now defined to be the sequence ‘NL dnl commentNL
GNULIB_$1=1NL ’. Once again, ‘dnl’ is recognized and avoids a newline in the output.
The final line is then parsed, beginning with ‘ ’ and ‘ ’ that are output literally. Then
‘gl_STRING_MODULE_INDICATOR’ is recognized as a macro name, with an argument list of
‘(’, ‘[strcase]’, and ‘)’. Since the definition of the macro contains the sequence ‘$1’,
that sequence is replaced with the argument ‘strcase’ prior to starting the rescan. The
rescan sees ‘NL’ and four spaces, which are output literally, then ‘dnl’, which discards
the text ‘ commentNL’. Next comes four more spaces, also output literally, and the token
‘GNULIB_strcase’, which resulted from the earlier parameter substitution. Since that is
not a macro name, it is output literally, followed by the literal tokens ‘=’, ‘1’, ‘NL’, and
two more spaces. Finally, the original ‘NL’ seen after the macro invocation is scanned and
output literally.
Now for a corrected approach. This rearranges the use of newlines and whitespace so
that less whitespace is output (which, although harmless to shell scripts, can be visually
unappealing), and fixes the quoting issues so that the capitalization occurs when the macro
‘gl_STRING_MODULE_INDICATOR’ is invoked, rather then when it is defined. It also adds
another layer of quoting to the first argument of translit, to ensure that the output will
be rescanned as a string rather than a potential uppercase macro name needing further
expansion.
18 GNU M4 1.4.19 macro processor
changequote([,])dnl
define([gl_STRING_MODULE_INDICATOR],
[dnl comment
GNULIB_[]translit([[$1]], [a-z], [A-Z])=1dnl
])dnl
gl_STRING_MODULE_INDICATOR([strcase])
⇒ GNULIB_STRCASE=1
The parsing of the first line is unchanged. The second line sees the name of the macro
to define, then sees the discarded ‘NL’ and two spaces, as before. But this time, the
next token is ‘[dnl commentNL GNULIB_[]translit([[$1]], [a-z], [A-Z])=1dnlNL]’,
which includes nested quotes, followed by ‘)’ to end the macro definition and ‘dnl’ to skip
the newline. No early expansion of translit occurs, so the entire string becomes the
definition of the macro.
The final line is then parsed, beginning with two spaces that are output literally, and
an invocation of gl_STRING_MODULE_INDICATOR with the argument ‘strcase’. Again, the
‘$1’ in the macro definition is substituted prior to rescanning. Rescanning first encounters
‘dnl’, and discards ‘ commentNL’. Then two spaces are output literally. Next comes the
token ‘GNULIB_’, but that is not a macro, so it is output literally. The token ‘[]’ is an
empty string, so it does not affect output. Then the token ‘translit’ is encountered.
This time, the arguments to translit are parsed as ‘(’, ‘[[strcase]]’, ‘,’, ‘ ’, ‘[a-z]’,
‘,’, ‘ ’, ‘[A-Z]’, and ‘)’. The two spaces are discarded, and the translit results in the desired
result ‘[STRCASE]’. This is rescanned, but since it is a string, the quotes are stripped and
the only output is a literal ‘STRCASE’. Then the scanner sees ‘=’ and ‘1’, which are output
literally, followed by ‘dnl’ which discards the rest of the definition of gl_STRING_MODULE_
INDICATOR. The newline at the end of output is the literal ‘NL’ that appeared after the
invocation of the macro.
The order in which m4 expands the macros can be further explored using the trace
facilities of GNU m4 (see Section 7.2 [Trace], page 55).
19
has to write m4_dnl and even m4_m4exit. It also has no effect on whether a macro requires
parameters.
$ m4 -P
eval
⇒eval
eval(`1')
⇒eval(1)
m4_eval
⇒m4_eval
m4_eval(`1')
⇒1
Another alternative is to redefine problematic macros to a name less likely to cause
conflicts, using Chapter 5 [Definitions], page 25.
If your version of GNU m4 has the changeword feature compiled in, it offers far more flex-
ibility in specifying the syntax of macro names, both builtin or user-defined. See Section 8.4
[Changeword], page 68, for more information on this experimental feature.
Of course, the simplest way to prevent a name from being interpreted as a call to an
existing macro is to quote it. The remainder of this section studies a little more deeply how
quoting affects macro invocation, and how quoting can be used to inhibit macro invocation.
Even if quoting is usually done over the whole macro name, it can also be done over
only a few characters of this name (provided, of course, that the unquoted portions are not
also a macro). It is also possible to quote the empty string, but this works only inside the
name. For example:
`divert'
⇒divert
`d'ivert
⇒divert
di`ver't
⇒divert
div`'ert
⇒divert
all yield the string ‘divert’. While in both:
`'divert
⇒
divert`'
⇒
the divert builtin macro will be called, which expands to the empty string.
The output of macro evaluations is always rescanned. In the following example, the input
‘x`'y’ yields the string ‘bCD’, exactly as if m4 has been given ‘substr(ab`'cde, `1', `3')’
as input:
define(`cde', `CDE')
⇒
define(`x', `substr(ab')
⇒
Chapter 4: How to invoke macros 21
⇒
⇒whitespace from expansion kept
macro(`unquoted trailing whitespace kept'
)
⇒unquoted trailing whitespace kept
⇒
Normally m4 will issue warnings if a builtin macro is called with an inappropriate number
of arguments, but it can be suppressed with the --quiet command line option (or --silent,
or -Q, see Section 2.1 [Invoking m4], page 7). For user defined macros, there is no check of
the number of arguments given.
$ m4
index(`abc')
error m4:stdin:1: Warning: too few arguments to builtin `index'
⇒0
index(`abc',)
⇒0
index(`abc', `b', `ignored')
error m4:stdin:3: Warning: excess arguments to builtin `index' ignored
⇒1
$ m4 -Q
index(`abc')
⇒0
index(`abc',)
⇒0
index(`abc', `b', `ignored')
⇒1
Macros are expanded normally during argument collection, and whatever commas,
quotes and parentheses that might show up in the resulting expanded text will serve to
define the arguments as well. Thus, if foo expands to ‘, b, c’, the macro call
bar(a foo, d)
is a macro call with four arguments, which are ‘a ’, ‘b’, ‘c’ and ‘d’. To understand why the
first argument contains whitespace, remember that unquoted leading whitespace is never
part of an argument, but trailing whitespace always is.
It is possible for a macro’s definition to change during argument collection, in which case
the expansion uses the definition that was in effect at the time the opening ‘(’ was seen.
define(`f', `1')
⇒
f(define(`f', `2'))
⇒1
f
⇒2
It is an error if the end of file occurs while collecting arguments.
hello world
⇒hello world
define(
Chapter 4: How to invoke macros 23
^D
error m4:stdin:2: ERROR: end of file in argument list
Taking a very simple example, if foo expands to ‘bar’, and bar expands to ‘Hello’, the
input
$ m4 -Dbar=Hello -Dfoo=bar
foo
⇒Hello
will expand first to ‘bar’, and when this is reread and expanded, into ‘Hello’.
25
⇒
foo
⇒This is macro foo.
The ‘foo’ in the expansion text is not expanded, since it is a quoted string, and not a name.
GNU m4 allows the number following the ‘$’ to consist of one or more digits, allowing
macros to have any number of arguments. The extension of accepting multiple digits is
incompatible with POSIX, and is different than traditional implementations of m4, which
only recognize one digit. Therefore, future versions of GNU M4 will phase out this feature.
To portably access beyond the ninth argument, you can use the argn macro documented
later (see Section 6.3 [Shift], page 41).
POSIX also states that ‘$’ followed immediately by ‘{’ in a macro definition is
implementation-defined. This version of M4 passes the literal characters ‘${’ through
unchanged, but M4 2.0 will implement an optional feature similar to sh, where ‘${11}’
expands to the eleventh argument, to replace the current recognition of ‘$11’. Meanwhile,
if you want to guarantee that you will get a literal ‘${’ in output when expanding a macro,
even when you upgrade to M4 2.0, you can use nested quoting to your advantage:
define(`foo', `single quoted $`'{1} output')
⇒
define(`bar', ``double quoted $'`{2} output'')
⇒
foo(`a', `b')
⇒single quoted ${1} output
bar(`a', `b')
⇒double quoted ${2} output
To help you detect places in your M4 input files that might change in behavior due to
the changed behavior of M4 2.0, you can use the --warn-macro-sequence command-line
option (see Section 2.1 [Invoking m4], page 7) with the default regular expression. This
will add a warning any time a macro definition includes ‘$’ followed by multiple digits, or
by ‘{’. The warning is not enabled by default, because it triggers a number of warnings in
Autoconf 2.61 (and Autoconf uses -E to treat warnings as errors), and because it will still
be possible to restore older behavior in M4 2.0.
$ m4 --warn-macro-sequence
define(`foo', `$001 ${1} $1')
error m4:stdin:1: Warning: definition of `foo' contains sequence `$001'
error m4:stdin:1: Warning: definition of `foo' contains sequence `${1}'
⇒
foo(`bar')
⇒bar ${1} bar
nargs ( . . . ) [Composite]
Expands to a count of the number of arguments supplied.
define(`nargs', `$#')
⇒
nargs
⇒0
nargs()
⇒1
nargs(`arg1', `arg2', `arg3')
⇒3
nargs(`commas can be quoted, like this')
⇒1
nargs(arg1#inside comments, commas do not separate arguments
still arg1)
⇒1
nargs((unquoted parentheses, like this, group arguments))
⇒1
Remember that ‘#’ defaults to the comment character; if you forget quotes to inhibit the
comment behavior, your macro definition may not end where you expected.
dnl Attempt to define a macro to just `$#'
define(underquoted, $#)
oops)
⇒
underquoted
⇒0)
⇒oops
The notation $* can be used in the expansion text to denote all the actual arguments,
unquoted, with commas in between. For example
define(`echo', `$*')
⇒
echo(arg1, arg2, arg3 , arg4)
⇒arg1,arg2,arg3 ,arg4
Often each argument should be quoted, and the notation $@ handles that. It is just like
$*, except that it quotes each argument. A simple example of that is:
define(`echo', `$@')
⇒
echo(arg1, arg2, arg3 , arg4)
⇒arg1,arg2,arg3 ,arg4
Where did the quotes go? Of course, they were eaten, when the expanded text were
reread by m4. To show the difference, try
define(`echo1', `$*')
⇒
define(`echo2', `$@')
⇒
define(`foo', `This is macro `foo'.')
Chapter 5: How to define new macros 29
⇒
echo1(foo)
⇒This is macro This is macro foo..
echo1(`foo')
⇒This is macro foo.
echo2(foo)
⇒This is macro foo.
echo2(`foo')
⇒foo
See Section 7.2 [Trace], page 55, if you do not understand this. As another example of the
difference, remember that comments encountered in arguments are passed untouched to the
macro, and that quoting disables comments.
define(`echo1', `$*')
⇒
define(`echo2', `$@')
⇒
define(`foo', `bar')
⇒
echo1(#foo'foo
foo)
⇒#foo'foo
⇒bar
echo2(#foo'foo
foo)
⇒#foobar
⇒bar'
A ‘$’ sign in the expansion text, that is not followed by anything m4 understands, is
simply copied to the macro expansion, as any other text is.
define(`foo', `$$$ hello $$$')
⇒
foo
⇒$$$ hello $$$
If you want a macro to expand to something like ‘$12’, the judicious use of nested quoting
can put a safe character between the $ and the next character, relying on the rescanning to
remove the nested quote. This will prevent m4 from interpreting the $ sign as a reference
to an argument.
define(`foo', `no nested quote: $1')
⇒
foo(`arg')
⇒no nested quote: arg
define(`foo', `nested quote around $: `$'1')
⇒
foo(`arg')
⇒nested quote around $: $1
define(`foo', `nested empty quote after $: $`'1')
30 GNU M4 1.4.19 macro processor
⇒
foo(`arg')
⇒nested empty quote after $: $1
define(`foo', `nested quote around next character: $`1'')
⇒
foo(`arg')
⇒nested quote around next character: $1
define(`foo', `nested quote around both: `$1'')
⇒
foo(`arg')
⇒nested quote around both: arg
Its normal use is best understood through an example, which shows how to rename
undefine to zap:
define(`zap', defn(`undefine'))
⇒
zap(`undefine')
⇒
undefine(`zap')
⇒undefine(zap)
In this way, defn can be used to copy macro definitions, and also definitions of builtin
macros. Even if the original macro is removed, the other name can still be used to access
the definition.
The fact that macro definitions can be transferred also explains why you should use $0,
rather than retyping a macro’s name in its definition:
define(`foo', `This is `$0'')
⇒
define(`bar', defn(`foo'))
⇒
bar
⇒This is bar
Macros used as string variables should be referred through defn, to avoid unwanted
expansion of the text:
define(`string', `The macro dnl is very useful
')
⇒
string
⇒The macro
defn(`string')
⇒The macro dnl is very useful
⇒
However, it is important to remember that m4 rescanning is purely textual. If an un-
balanced end-quote string occurs in a macro definition, the rescan will see that embedded
32 GNU M4 1.4.19 macro processor
quote as the termination of the quoted string, and the remainder of the macro’s definition
will be rescanned unquoted. Thus it is a good idea to avoid unbalanced end-quotes in macro
definitions or arguments to macros.
define(`foo', a'a)
⇒
define(`a', `A')
⇒
define(`echo', `$@')
⇒
foo
⇒A'A
defn(`foo')
⇒aA'
echo(foo)
⇒AA'
On the other hand, it is possible to exploit the fact that defn can concatenate multiple
macros prior to the rescanning phase, in order to join the definitions of macros that, in
isolation, have unbalanced quotes. This is particularly useful when one has used several
macros to accumulate text that M4 should rescan as a whole. In the example below, note
how the use of defn on l in isolation opens a string, which is not closed until the next line;
but used on l and r together results in nested quoting.
define(`l', `<[>')define(`r', `<]>')
⇒
changequote(`[', `]')
⇒
defn([l])defn([r])
])
⇒<[>]defn([r])
⇒)
defn([l], [r])
⇒<[>][<]>
Using defn to generate special tokens for builtin macros outside of expected contexts
can sometimes trigger warnings. But most of the time, such tokens are silently converted
to the empty string.
$ m4 -d
defn(`defn')
⇒
define(defn(`divnum'), `cannot redefine a builtin token')
error m4:stdin:2: Warning: define: invalid macro name ignored
⇒
divnum
⇒0
len(defn(`divnum'))
⇒0
Also note that defn with multiple arguments can only join text macros, not builtins,
although a future version of GNU M4 may lift this restriction.
Chapter 5: How to define new macros 33
$ m4 -d
define(`a', `A')define(`AA', `b')
⇒
traceon(`defn', `define')
⇒
defn(`a', `divnum', `a')
error m4:stdin:3: Warning: cannot concatenate builtin `divnum'
error m4trace: -1- defn(`a', `divnum', `a') -> ``A'`A''
⇒AA
define(`mydivnum', defn(`divnum', `divnum'))mydivnum
error m4:stdin:4: Warning: cannot concatenate builtin `divnum'
error m4:stdin:4: Warning: cannot concatenate builtin `divnum'
error m4trace: -2- defn(`divnum', `divnum')
error m4trace: -1- define(`mydivnum', `')
⇒
traceoff(`defn', `define')
⇒
⇒
popdef(`foo')
⇒
foo
⇒Expansion three.
popdef(`foo', `foo')
⇒
foo
⇒Expansion one.
popdef(`foo')
⇒
foo
⇒foo
If a macro with several definitions is redefined with define, the topmost definition is
replaced with the new definition. If it is removed with undefine, all the definitions are
removed, and not only the topmost one. However, POSIX allows other implementations
that treat define as replacing an entire stack of definitions with a single new definition,
so to be portable to other implementations, it may be worth explicitly using popdef and
pushdef rather than relying on the GNU behavior of define.
define(`foo', `Expansion one.')
⇒
foo
⇒Expansion one.
pushdef(`foo', `Expansion two.')
⇒
foo
⇒Expansion two.
define(`foo', `Second expansion two.')
⇒
foo
⇒Second expansion two.
undefine(`foo')
⇒
foo
⇒foo
Local variables within macros are made with pushdef and popdef. At the start of the
macro a new definition is pushed, within the macro it is manipulated and at the end it is
popped, revealing the former definition.
It is possible to temporarily redefine a builtin with pushdef and defn.
This can be used even if name has been given another definition that has covered the
original, or been undefined so that no macro maps to the builtin.
pushdef(`define', `hidden')
⇒
undefine(`undefine')
⇒
define(`foo', `bar')
⇒hidden
foo
⇒foo
builtin(`define', `foo', defn(`divnum'))
⇒
foo
⇒0
builtin(`define', `foo', `BAR')
⇒
foo
⇒BAR
undefine(`foo')
⇒undefine(foo)
foo
⇒BAR
builtin(`undefine', `foo')
⇒
foo
⇒foo
The name argument only matches the original name of the builtin, even when the
--prefix-builtins option (or -P, see Section 2.1 [Invoking m4], page 7) is in effect. This
is different from indir, which only tracks current macro names.
$ m4 -P
m4_builtin(`divnum')
⇒0
m4_builtin(`m4_divnum')
error m4:stdin:2: undefined builtin `m4_divnum'
⇒
m4_indir(`divnum')
error m4:stdin:3: undefined macro `divnum'
⇒
m4_indir(`m4_divnum')
⇒0
37
Note that indir and builtin can be used to invoke builtins without arguments, even
when they normally require parameters to be recognized; but it will provoke a warning, and
result in a void expansion.
builtin
⇒builtin
builtin()
error m4:stdin:2: undefined builtin `'
⇒
builtin(`builtin')
error m4:stdin:3: Warning: too few arguments to builtin `builtin'
⇒
builtin(`builtin',)
error m4:stdin:4: undefined builtin `'
⇒
builtin(`builtin', ``'
')
error m4:stdin:5: undefined builtin ``'
error '
⇒
indir(`index')
error m4:stdin:7: Warning: too few arguments to builtin `index'
⇒
39
⇒
ifelse(`foo', `bar')
error m4:stdin:2: Warning: too few arguments to builtin `ifelse'
⇒
Using three or four arguments provides decision points.
ifelse(`foo', `bar', `true')
⇒
ifelse(`foo', `foo', `true')
⇒true
define(`foo', `bar')
⇒
ifelse(foo, `bar', `true', `false')
⇒true
ifelse(foo, `foo', `true', `false')
⇒false
Notice how the first argument was used unquoted; it is common to compare the expansion
of a macro with a string. With this macro, you can now reproduce the behavior of blind
builtins, where the macro is recognized only with arguments.
define(`foo', `ifelse(`$#', `0', ``$0'', `arguments:$#')')
⇒
foo
⇒foo
foo()
⇒arguments:1
foo(`a', `b', `c')
⇒arguments:3
For an example of a way to make defining blind macros easier, see Section 6.7 [Compo-
sition], page 51.
The macro ifelse can take more than four arguments. If given more than four argu-
ments, ifelse works like a case or switch statement in traditional programming languages.
If string-1 and string-2 are equal, ifelse expands into equal-1, otherwise the procedure is
repeated with the first three arguments discarded. This calls for an example:
ifelse(`foo', `bar', `third', `gnu', `gnats')
error m4:stdin:1: Warning: excess arguments to builtin `ifelse' ignored
⇒gnu
ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth')
⇒
ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth', `seventh')
⇒seventh
ifelse(`foo', `bar', `3', `gnu', `gnats', `6', `7', `8')
error m4:stdin:4: Warning: excess arguments to builtin `ifelse' ignored
⇒7
Naturally, the normal case will be slightly more advanced than these examples. A
common use of ifelse is in macros implementing loops of various kinds.
Chapter 6: Conditionals, loops, and recursion 41
6.3 Recursion in m4
There is no direct support for loops in m4, but macros can be recursive. There is no limit on
the number of recursion levels, other than those enforced by your hardware and operating
system.
Loops can be programmed using recursion and the conditionals described previously.
There is a builtin macro, shift, which can, among other things, be used for iterating
through the actual arguments to a macro:
reverse ( . . . ) [Composite]
Takes any number of arguments, and reverses their order.
It is implemented as:
define(`reverse', `ifelse(`$#', `0', , `$#', `1', ``$1'',
`reverse(shift($@)), `$1'')')
⇒
reverse
⇒
reverse(`foo')
⇒foo
reverse(`foo', `bar', `gnats', `and gnus')
⇒and gnus, gnats, bar, foo
While not a very interesting macro, it does show how simple loops can be made with
shift, ifelse and recursion. It also shows that shift is usually used with ‘$@’. Another
example of this is an implementation of a short-circuiting conditional operator.
Here is the implementation of cond, along with a demonstration of how it can short-
circuit the side effects in side. Notice how all the unquoted side effects happen regardless
of how many comparisons are made with ifelse, compared with only the relevant effects
with cond.
define(`cond',
`ifelse(`$#', `1', `$1',
`ifelse($1, `$2', `$3',
`$0(shift(shift(shift($@))))')')')dnl
define(`side', `define(`counter', incr(counter))$1')dnl
define(`example1',
`define(`counter', `0')dnl
ifelse(side(`$1'), `yes', `one comparison: ',
side(`$1'), `no', `two comparisons: ',
side(`$1'), `maybe', `three comparisons: ',
`side(`default answer: ')')counter')dnl
define(`example2',
`define(`counter', `0')dnl
cond(`side(`$1')', `yes', `one comparison: ',
`side(`$1')', `no', `two comparisons: ',
`side(`$1')', `maybe', `three comparisons: ',
`side(`default answer: ')')counter')dnl
example1(`yes')
⇒one comparison: 3
example1(`no')
⇒two comparisons: 3
example1(`maybe')
⇒three comparisons: 3
example1(`feeling rather indecisive today')
⇒default answer: 4
example2(`yes')
⇒one comparison: 1
example2(`no')
⇒two comparisons: 2
example2(`maybe')
⇒three comparisons: 3
example2(`feeling rather indecisive today')
⇒default answer: 4
Another common task that requires iteration is joining a list of arguments into a single
string.
Here are some examples of its usage, based on the implementation m4-1.4.19/examples/
join.m4 distributed in this package:
$ m4 -I examples
include(`join.m4')
⇒
join,join(`-'),join(`-', `'),join(`-', `', `')
⇒,,,
joinall,joinall(`-'),joinall(`-', `'),joinall(`-', `', `')
⇒,,,-
join(`-', `1')
⇒1
join(`-', `1', `2', `3')
⇒1-2-3
join(`', `1', `2', `3')
⇒123
join(`-', `', `1', `', `', `2', `')
⇒1-2
joinall(`-', `', `1', `', `', `2', `')
⇒-1---2-
join(`,', `1', `2', `3')
⇒1,2,3
define(`nargs', `$#')dnl
nargs(join(`,', `1', `2', `3'))
⇒1
Examining the implementation shows some interesting points about several m4 program-
ming idioms.
$ m4 -I examples
undivert(`join.m4')dnl
⇒divert(`-1')
⇒# join(sep, args) - join each non-empty ARG into a single
⇒# string, with each element separated by SEP
⇒define(`join',
⇒`ifelse(`$#', `2', ``$2'',
⇒ `ifelse(`$2', `', `', ``$2'_')$0(`$1', shift(shift($@)))')')
⇒define(`_join',
⇒`ifelse(`$#$2', `2', `',
⇒ `ifelse(`$2', `', `', ``$1$2'')$0(`$1', shift(shift($@)))')')
⇒# joinall(sep, args) - join each ARG, including empty ones,
⇒# into a single string, with each element separated by SEP
⇒define(`joinall', ``$2'_$0(`$1', shift($@))')
⇒define(`_joinall',
⇒`ifelse(`$#', `2', `', ``$1$3'$0(`$1', shift(shift($@)))')')
⇒divert`'dnl
First, notice that this implementation creates helper macros _join and _joinall. This
division of labor makes it easier to output the correct number of separator instances: join
and joinall are responsible for the first argument, without a separator, while _join and
44 GNU M4 1.4.19 macro processor
_joinall are responsible for all remaining arguments, always outputting a separator when
outputting an argument.
Next, observe how join decides to iterate to itself, because the first arg was empty, or
to output the argument and swap over to _join. If the argument is non-empty, then the
nested ifelse results in an unquoted ‘_’, which is concatenated with the ‘$0’ to form the
next macro name to invoke. The joinall implementation is simpler since it does not have
to suppress empty arg; it always executes once then defers to _joinall.
Another important idiom is the idea that separator is reused for each iteration.
Each iteration has one less argument, but rather than discarding ‘$1’ by iterating with
$0(shift($@)), the macro discards ‘$2’ by using $0(`$1', shift(shift($@))).
Next, notice that it is possible to compare more than one condition in a single ifelse
test. The test of ‘$#$2’ against ‘2’ allows _join to iterate for two separate reasons—either
there are still more than two arguments, or there are exactly two arguments but the last
argument is not empty.
Finally, notice that these macros require exactly two arguments to terminate recursion,
but that they still correctly result in empty output when given no args (i.e., zero or one
macro argument). On the first pass when there are too few arguments, the shift results
in no output, but leaves an empty string to serve as the required second argument for the
second pass. Put another way, ‘`$1', shift($@)’ is not the same as ‘$@’, since only the
former guarantees at least two arguments.
Sometimes, a recursive algorithm requires adding quotes to each element, or treating
multiple arguments as a single element:
quote ( . . . ) [Composite]
dquote ( . . . ) [Composite]
dquote_elt ( . . . ) [Composite]
Takes any number of arguments, and adds quoting. With quote, only one level of
quoting is added, effectively removing whitespace after commas and turning multiple
arguments into a single string. With dquote, two levels of quoting are added, one
around each element, and one around the list. And with dquote_elt, two levels of
quoting are added around each element.
It is implemented as:
define(`argn', `ifelse(`$1', 1, ``$2'',
`argn(decr(`$1'), shift(shift($@)))')')
⇒
argn(`1', `a')
⇒a
define(`foo', `argn(`11', $@)')
⇒
foo(`a', `b', `c', `d', `e', `f', `g', `h', `i', `j', `k', `l')
⇒k
46 GNU M4 1.4.19 macro processor
general use. They lack even basic error handling for cases like start less than end, end not
numeric, or iterator not being a macro name. See if you can improve these macros; or see
Section 17.2 [Answers], page 115).
As an example, this displays each word in a list inside of a sentence, using an imple-
mentation of foreach distributed as m4-1.4.19/examples/foreach.m4, and foreachq in
m4-1.4.19/examples/foreachq.m4.
$ m4 -I examples
include(`foreach.m4')
⇒
foreach(`x', (foo, bar, foobar), `Word was: x
')dnl
⇒Word was: foo
⇒Word was: bar
⇒Word was: foobar
include(`foreachq.m4')
⇒
foreachq(`x', `foo, bar, foobar', `Word was: x
')dnl
⇒Word was: foo
⇒Word was: bar
⇒Word was: foobar
It is possible to be more complex; each element of the paren-list or quote-list can itself
be a list, to pass as further arguments to a helper macro. This example generates a shell
case statement:
$ m4 -I examples
include(`foreach.m4')
⇒
define(`_case', ` $1)
$2=" $1";;
')dnl
define(`_cat', `$1$2')dnl
case $`'1 in
⇒case $1 in
48 GNU M4 1.4.19 macro processor
⇒)
foreachq(`x', ```a'', ``(b'', ``c)''', `x
')dnl
⇒a
⇒(b
⇒c)
Obviously, foreachq did a better job; here is its implementation:
$ m4 -I examples
undivert(`foreachq.m4')dnl
⇒include(`quote.m4')dnl
⇒divert(`-1')
⇒# foreachq(x, `item_1, item_2, ..., item_n', stmt)
⇒# quoted list, simple version
⇒define(`foreachq', `pushdef(`$1')_foreachq($@)popdef(`$1')')
⇒define(`_arg1', `$1')
⇒define(`_foreachq', `ifelse(quote($2), `', `',
⇒ `define(`$1', `_arg1($2)')$3`'$0(`$1', `shift($2)', `$3')')')
⇒divert`'dnl
Notice that _foreachq had to use the helper macro quote defined earlier (see Section 6.3
[Shift], page 41), to ensure that the embedded ifelse call does not go haywire if a list
element contains a comma. Unfortunately, this implementation of foreachq has its own
severe flaw. Whereas the foreach implementation was linear, this macro is quadratic in the
number of list elements, and is much more likely to trip up the limit set by the command
line option --nesting-limit (or -L, see Section 2.3 [Invoking m4], page 10). Additionally,
this implementation does not expand ‘defn(`iterator')’ very well, when compared with
foreach.
$ m4 -I examples
include(`foreach.m4')include(`foreachq.m4')
⇒
foreach(`name', `(`a', `b')', ` defn(`name')')
⇒ a b
foreachq(`name', ``a', `b'', ` defn(`name')')
⇒ _arg1(`a', `b') _arg1(shift(`a', `b'))
It is possible to have robust iteration with linear behavior and sane iterator contents for
either list style. See if you can learn from the best elements of both of these implementations
to create robust macros (or see Section 17.3 [Answers], page 117).
first, while stack_foreach_lifo visits the current definition first. action should not
modify or dereference macro. There are a few special macros, such as defn, which
cannot be used as the macro parameter.
A sample implementation of these macros is distributed in the file m4-1.4.19/examples/
stack.m4.
$ m4 -I examples
include(`stack.m4')
⇒
pushdef(`a', `1')pushdef(`a', `2')pushdef(`a', `3')
⇒
define(`show', ``$1'
')
⇒
stack_foreach(`a', `show')dnl
⇒1
⇒2
⇒3
stack_foreach_lifo(`a', `show')dnl
⇒3
⇒2
⇒1
Now for the implementation. Note the definition of a helper macro, _stack_reverse,
which destructively swaps the contents of one stack of definitions into the reverse order in
the temporary macro ‘tmp-$1’. By calling the helper twice, the original order is restored
back into the macro ‘$1’; since the operation is destructive, this explains why ‘$1’ must
not be modified or dereferenced during the traversal. The caller can then inject additional
code to pass the definition currently being visited to ‘$2’. The choice of helper names is
intentional; since ‘-’ is not valid as part of a macro name, there is no risk of conflict with
a valid macro name, and the code is guaranteed to use defn where necessary. Finally, note
that any macro used in the traversal of a pushdef stack, such as pushdef or defn, cannot
be handled by stack_foreach, since the macro would temporarily be undefined during the
algorithm.
$ m4 -I examples
undivert(`stack.m4')dnl
⇒divert(`-1')
⇒# stack_foreach(macro, action)
⇒# Invoke ACTION with a single argument of each definition
⇒# from the definition stack of MACRO, starting with the oldest.
⇒define(`stack_foreach',
⇒`_stack_reverse(`$1', `tmp-$1')'dnl
⇒`_stack_reverse(`tmp-$1', `$1', `$2(defn(`$1'))')')
⇒# stack_foreach_lifo(macro, action)
⇒# Invoke ACTION with a single argument of each definition
⇒# from the definition stack of MACRO, starting with the newest.
⇒define(`stack_foreach_lifo',
⇒`_stack_reverse(`$1', `tmp-$1', `$2(defn(`$1'))')'dnl
Chapter 6: Conditionals, loops, and recursion 51
⇒`_stack_reverse(`tmp-$1', `$1')')
⇒define(`_stack_reverse',
⇒`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0($@)')')
⇒divert`'dnl
Defining a macro to define another macro can be a bit tricky. We want to use a literal
‘$#’ in the argument to the nested define. However, if ‘$’ and ‘#’ are adjacent in the
definition of define_blind, then it would be expanded as the number of arguments to
define_blind rather than the intended number of arguments to name. The solution is to
pass the difficult characters through extra arguments to a helper macro _define_blind.
When composing macros, it is a common idiom to need a helper macro to concatenate
text that forms parameters in the composed macro, rather than interpreting the text as a
parameter of the composing macro.
As for the limitation against using defn, there are two reasons. If a macro was previously
defined with define_blind, then it can safely be renamed to a new blind macro using plain
define; using define_blind to rename it just adds another layer of ifelse, occupying
memory and slowing down execution. And if a macro is a builtin, then it would result in an
attempt to define a macro consisting of both text and a builtin token; this is not supported,
and the builtin token is flattened to an empty string.
With that explanation, here’s the definition, and some sample usage. Notice that
define_blind is itself a blind macro.
$ m4 -d
define(`define_blind', `ifelse(`$#', `0', ``$0'',
`_$0(`$1', `$2', `$'`#', `$'`0')')')
⇒
define(`_define_blind', `define(`$1',
`ifelse(`$3', `0', ``$4'', `$2')')')
⇒
define_blind
⇒define_blind
define_blind(`foo', `arguments were $*')
⇒
foo
⇒foo
foo(`bar')
⇒arguments were bar
52 GNU M4 1.4.19 macro processor
define(`blah', defn(`foo'))
⇒
blah
⇒blah
blah(`a', `b')
⇒arguments were a,b
defn(`blah')
⇒ifelse(`$#', `0', ``$0'', `arguments were $*')
Another interesting composition tactic is argument currying, or factoring a macro that
takes multiple arguments for use in a context that provides exactly one argument.
curry (macro, . . . ) [Composite]
Expand to a macro call that takes exactly one argument, then appends that argument
to the original arguments and invokes macro with the resulting list of arguments.
A demonstration of currying makes the intent of this macro a little more obvious. The
macro stack_foreach mentioned earlier is an example of a context that provides exactly
one argument to a macro name. But coupled with currying, we can invoke reverse with
two arguments for each definition of a macro stack. This example uses the file m4-1.4.19/
examples/curry.m4 included in the distribution.
$ m4 -I examples
include(`curry.m4')include(`stack.m4')
⇒
define(`reverse', `ifelse(`$#', `0', , `$#', `1', ``$1'',
`reverse(shift($@)), `$1'')')
⇒
pushdef(`a', `1')pushdef(`a', `2')pushdef(`a', `3')
⇒
stack_foreach(`a', `:curry(`reverse', `4')')
⇒:1, 4:2, 4:3, 4
curry(`curry', `reverse', `1')(`2')(`3')
⇒3, 2, 1
Now for the implementation. Notice how curry leaves off with a macro name but no
open parenthesis, while still in the middle of collecting arguments for ‘$1’. The macro
_curry is the helper macro that takes one argument, then adds it to the list and finally
supplies the closing parenthesis. The use of a comma inside the shift call allows currying
to also work for a macro that takes one argument, although it often makes more sense to
invoke that macro directly rather than going through curry.
$ m4 -I examples
undivert(`curry.m4')dnl
⇒divert(`-1')
⇒# curry(macro, args)
⇒# Expand to a macro call that takes one argument, then invoke
⇒# macro(args, extra).
⇒define(`curry', `$1(shift($@,)_$0')
⇒define(`_curry', ``$1')')
⇒divert`'dnl
Chapter 6: Conditionals, loops, and recursion 53
Unfortunately, with M4 1.4.x, curry is unable to handle builtin tokens, which are silently
flattened to the empty string when passed through another text macro. This limitation will
be lifted in a future release of M4.
Putting the last few concepts together, it is possible to copy or rename an entire stack
of macro definitions.
When writing macros for m4, they often do not work as intended on the first try (as is the
case with most programming languages). Fortunately, there is support for macro debugging
in m4.
⇒
traceon(`foo')
⇒
foo
⇒foo
defn(`foo')
⇒
define(`foo', `bar')
⇒
foo
error m4trace: -1- foo -> `bar'
⇒bar
undefine(`foo')
⇒
ifdef(`foo', `yes', `no')
⇒no
indir(`foo')
error m4:stdin:9: undefined macro `foo'
⇒
define(`foo', `blah')
⇒
foo
error m4trace: -1- foo -> `blah'
⇒blah
traceoff
⇒
foo
⇒blah
Tracing even works on builtins. However, defn (see Section 5.5 [Defn], page 31) does
not transfer tracing status.
$ m4 -d
traceon(`traceon')
⇒
traceon(`traceoff')
error m4trace: -1- traceon(`traceoff')
⇒
traceoff(`traceoff')
error m4trace: -1- traceoff(`traceoff')
⇒
traceoff(`traceon')
⇒
traceon(`eval', `m4_divnum')
⇒
define(`m4_eval', defn(`eval'))
⇒
define(`m4_divnum', defn(`divnum'))
58 GNU M4 1.4.19 macro processor
⇒
eval(divnum)
error m4trace: -1- eval(`0') -> `0'
⇒0
m4_eval(m4_divnum)
error m4trace: -2- m4_divnum -> `0'
⇒0
See Section 7.3 [Debug Levels], page 58, for information on controlling the details of
the display. The format of the trace output is not specified by POSIX, and varies between
implementations of m4.
t In trace output, trace all macro calls made in this invocation of m4, regardless
of the settings of traceon.
x In trace output, add a unique ‘macro call id’ to each line of the trace output.
This is useful in connection with the ‘c’ flag above.
V A shorthand for all of the above flags.
If no flags are specified with the -d option, the default is ‘aeq’. The examples throughout
this manual assume the default flags.
There is a builtin macro debugmode, which allows on-the-fly control of the debugging
output format:
debugmode ([flags]) [Builtin]
The argument flags should be a subset of the letters listed above. As special cases, if
the argument starts with a ‘+’, the flags are added to the current debug flags, and if
it starts with a ‘-’, they are removed. If no argument is present, all debugging flags
are cleared (as if no -d was given), and with an empty argument the flags are reset
to the default of ‘aeq’.
The expansion of debugmode is void.
$ m4
define(`foo', `FOO')
⇒
traceon(`foo')
⇒
debugmode()
⇒
foo
error m4trace: -1- foo -> `FOO'
⇒FOO
debugmode
⇒
foo
error m4trace: -1- foo
⇒FOO
debugmode(`+l')
⇒
foo
error m4trace:8: -1- foo
⇒FOO
The following example demonstrates the behavior of length truncation, when specified on
the command line. Note that each argument and the final result are individually truncated.
Also, the special tokens for builtin functions are not truncated.
$ m4 -d -l 6
define(`echo', `$@')debugmode(`+t')
⇒
echo(`1', `long string')
error m4trace: -1- echo(`1', `long s...') -> ``1',`l...'
60 GNU M4 1.4.19 macro processor
⇒1,long string
indir(`echo', defn(`changequote'))
error m4trace: -2- defn(`change...')
error m4trace: -1- indir(`echo', <changequote>) -> ``''
⇒
This example shows the effects of the debug flags that are not related to macro tracing.
$ m4 -dip -I examples
error m4debug: input read from stdin
include(`foo')dnl
error m4debug: path search for `foo' found `examples/foo'
error m4debug: input read from examples/foo
⇒bar
error m4debug: input reverted to stdin, line 1
^D
error m4debug: input exhausted
8 Input control
This chapter describes various builtin macros for controlling the input to m4.
dnl [Builtin]
All characters, up to and including the next newline, are discarded without performing
any macro expansion. A warning is issued if the end of the file is encountered without
a newline.
The expansion of dnl is void.
It is often used in connection with define, to remove the newline that follows the call
to define. Thus
define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
foo
⇒Macro foo.
The input up to and including the next newline is discarded, as opposed to the way
comments are treated (see Section 3.3 [Comments], page 15).
Usually, dnl is immediately followed by an end of line or some other whitespace. GNU
m4 will produce a warning diagnostic if dnl is followed by an open parenthesis. In this
case, dnl will collect and process all arguments, looking for a matching close parenthesis.
All predictable side effects resulting from this collection will take place. dnl will return no
output. The input following the matching close parenthesis up to and including the next
newline, on whatever line containing it, will still be discarded.
dnl(`args are ignored, but side effects occur',
define(`foo', `like this')) while this text is ignored: undefine(`foo')
error m4:stdin:1: Warning: excess arguments to builtin `dnl' ignored
See how `foo' was defined, foo?
⇒See how foo was defined, like this?
If the end of file is encountered without a newline character, a warning is issued and dnl
stops consuming input.
m4wrap(`m4wrap(`2 hi
')0 hi dnl 1 hi')
⇒
define(`hi', `HI')
⇒
^D
error m4:stdin:1: Warning: end of file treated as newline
⇒0 HI 2 HI
62 GNU M4 1.4.19 macro processor
foo
⇒Macro `FOO'.
`foo'
⇒`Macro `FOO'.'
changequote(`,)
⇒
foo
⇒Macro FOO.
There is no way in m4 to quote a string containing an unmatched begin-quote, except
using changequote to change the current quotes.
If the quotes should be changed from, say, ‘[’ to ‘[[’, temporary quote characters have to
be defined. To achieve this, two calls of changequote must be made, one for the temporary
quotes and one for the new quotes.
Macros are recognized in preference to the begin-quote string, so if a prefix of start can be
recognized as part of a potential macro name, the quoting mechanism is effectively disabled.
Unless you use changeword (see Section 8.4 [Changeword], page 68), this means that start
should not begin with a letter, digit, or ‘_’ (underscore). However, even though quoted
strings are not recognized, the quote characters can still be discerned in macro expansion
and in trace output.
define(`echo', `$@')
⇒
define(`hi', `HI')
⇒
changequote(`q', `Q')
⇒
q hi Q hi
⇒q HI Q HI
echo(hi)
⇒qHIQ
changequote
⇒
changequote(`-', `EOF')
⇒
- hi EOF hi
⇒ hi HI
changequote
⇒
changequote(`1', `2')
⇒
hi1hi2
⇒hi1hi2
hi 1hi2
⇒HI hi
Quotes are recognized in preference to argument collection. In particular, if start is
a single ‘(’, then argument collection is effectively disabled. For portability with other
implementations, it is a good idea to avoid ‘(’, ‘,’, and ‘)’ as the first character in start.
64 GNU M4 1.4.19 macro processor
define(`echo', `$#:$@:')
⇒
define(`hi', `HI')
⇒
changequote(`(',`)')
⇒
echo(hi)
⇒0::hi
changequote
⇒
changequote(`((', `))')
⇒
echo(hi)
⇒1:HI:
echo((hi))
⇒0::hi
changequote
⇒
changequote(`,', `)')
⇒
echo(hi,hi)bye)
⇒1:HIhibye:
However, if you are not worried about portability, using ‘(’ and ‘)’ as quoting characters
has an interesting property—you can use it to compute a quoted string containing the
expansion of any quoted text, as long as the expansion results in both balanced quotes
and balanced parentheses. The trick is realizing expand uses ‘$1’ unquoted, to trigger
its expansion using the normal quoting characters, but uses extra parentheses to group
unquoted commas that occur in the expansion without consuming whitespace following
those commas. Then _expand uses changequote to convert the extra parentheses back
into quoting characters. Note that it takes two more changequote invocations to restore
the original quotes. Contrast the behavior on whitespace when using ‘$*’, via quote, to
attempt the same task.
changequote(`[', `]')dnl
define([a], [1, (b)])dnl
define([b], [2])dnl
define([quote], [[$*]])dnl
define([expand], [_$0(($1))])dnl
define([_expand],
[changequote([(], [)])$1changequote`'changequote(`[', `]')])dnl
expand([a, a, [a, a], [[a, a]]])
⇒1, (2), 1, (2), a, a, [a, a]
quote(a, a, [a, a], [[a, a]])
⇒1,(2),1,(2),a, a,[a, a]
⇒q hi Q HI
changecom(`1', `2')
⇒
hi1hi2
⇒hello
hi 1hi2
⇒HI 1hi2
define(`echo', `$#:$*:$@:')
⇒
define(`hi', `HI')
⇒
changecom(`(',`)')
⇒
echo(hi)
⇒0:::(hi)
changecom
⇒
changecom(`((', `))')
⇒
echo(hi)
⇒1:HI:HI:
echo((hi))
⇒0:::((hi))
changecom(`,', `)')
⇒
echo(hi,hi)bye)
⇒1:HI,hi)bye:HI,hi)bye:
changecom
⇒
echo(hi,`,`'hi',hi)
⇒3:HI,,HI,HI:HI,,`'hi,HI:
echo(hi,`,`'hi',hi`'changecom(`,,', `hi'))
⇒3:HI,,`'hi,HI:HI,,`'hi,HI:
changecom(`/*', `*/')
⇒
/*dangling comment
^D
error m4:stdin:2: ERROR: end of file in comment
68 GNU M4 1.4.19 macro processor
⇒
m4 now requires a ‘#’ mark at the beginning of every macro invocation, so one can use
m4 to preprocess plain text without losing various words like ‘divert’.
In m4, macro substitution is based on text, while in TEX, it is based on tokens.
changeword can throw this difference into relief. For example, here is the same idea
represented in TEX and m4. First, the TEX version:
\def\a{\message{Hello}}
\catcode`\@=0
\catcode`\\=12
@a
@bye
⇒Hello
Then, the m4 version:
ifdef(`changeword', `', `errprint(` skipping: no changeword support
')m4exit(`77')')dnl
define(`a', `errprint(`Hello')')dnl
changeword(`@\([_a-zA-Z0-9]*\)')
⇒
@a
⇒errprint(Hello)
In the TEX example, the first line defines a macro a to print the message ‘Hello’. The
second line defines @ to be usable instead of \ as an escape character. The third line defines
\ to be a normal printing character, not an escape. The fourth line invokes the macro a.
So, when TEX is run on this file, it displays the message ‘Hello’.
When the m4 example is passed through m4, it outputs ‘errprint(Hello)’. The reason
for this is that TEX does lexical analysis of macro definition when the macro is defined. m4
just stores the text, postponing the lexical analysis until the macro is used.
You should note that using changeword will slow m4 down by a factor of about seven,
once it is changed to something other than the default regular expression. You can invoke
changeword with the empty string to restore the default word definition, and regain the
parsing speed.
⇒define(`_m4wrap', defn(`m4wrap'))dnl
⇒define(`m4wrap',
⇒`ifdef(`m4wrap'_m4wrap_level,
⇒ `define(`m4wrap'_m4wrap_level,
⇒ `$1'defn(`m4wrap'_m4wrap_level))',
⇒ `_m4wrap(`define(`_m4wrap_level', incr(_m4wrap_level))dnl
⇒m4wrap'_m4wrap_level)dnl
⇒define(`m4wrap'_m4wrap_level, `$1')')')dnl
include(`wraplifo.m4')
⇒
m4wrap(`a`'m4wrap(`c
', `d')')m4wrap(`b')
⇒
^D
⇒bac
Here is an example of implementing a factorial function using m4wrap:
define(`f', `ifelse(`$1', `0', `Answer: 0!=1
', eval(`$1>1'), `0', `Answer: $2$1=eval(`$2$1')
', `m4wrap(`f(decr(`$1'), `$2$1*')')')')
⇒
f(`10')
⇒
^D
⇒Answer: 10*9*8*7*6*5*4*3*2*1=3628800
Invocations of m4wrap at the same recursion level are concatenated and rescanned as
usual:
define(`aa', `AA
')
⇒
m4wrap(`a')m4wrap(`a')
⇒
^D
⇒AA
however, the transition between recursion levels behaves like an end of file condition between
two input files.
m4wrap(`m4wrap(`)')len(abc')
⇒
^D
error m4:stdin:1: ERROR: end of file in argument list
73
9 File inclusion
m4 allows you to include named files at any point in the input.
The fact that include and sinclude expand to the contents of the file can be used to
define macros that operate on entire files. Here is an example, which defines ‘bar’ to expand
to the contents of incl.m4:
$ m4 -I examples
define(`bar', include(`incl.m4'))
⇒
This is `bar': >>bar<<
⇒This is bar: >>Include file start
⇒foo
⇒Include file end
⇒<<
This use of include is not trivial, though, as files can contain quotes, commas, and
parentheses, which can interfere with the way the m4 parser works. GNU m4 seamlessly
concatenates the file contents with the next character, even if the included file ended in the
middle of a comment, string, or macro call. These conditions are only treated as end of file
errors if specified as input files on the command line.
In GNU m4, an alternative method of reading files is using undivert (see Section 10.2
[Undivert], page 76) on a named file.
When all the m4 input will have been processed, all existing diversions are automatically
undiverted, in numerical order.
divert(`1')
This text is diverted.
divert
⇒
This text is not diverted.
⇒This text is not diverted.
^D
⇒
⇒This text is diverted.
Several calls of divert with the same argument do not overwrite the previous diverted
text, but append to it. Diversions are printed after any wrapped text is expanded.
define(`text', `TEXT')
⇒
divert(`1')`diverted text.'
divert
⇒
76 GNU M4 1.4.19 macro processor
divert(`1')
This text is also diverted but not appended.
divert(`0')undivert(`1')dnl
⇒
⇒This text is also diverted but not appended.
Attempts to undivert the current diversion are silently ignored. Thus, when the current
diversion is not 0, the current diversion does not get rearranged among the other diversions.
divert(`1')one
divert(`2')two
divert(`3')three
divert(`2')undivert`'dnl
divert`'undivert`'dnl
⇒two
⇒one
⇒three
GNU m4 allows named files to be undiverted. Given a non-numeric argument, the con-
tents of the file named will be copied, uninterpreted, to the current output. This comple-
ments the builtin include (see Section 9.1 [Include], page 73). To illustrate the difference,
assume the file foo contains:
$ cat foo
bar
then
define(`bar', `BAR')
⇒
undivert(`foo')
⇒bar
⇒
include(`foo')
⇒BAR
⇒
If the file is not found (or cannot be read), an error message is issued, and the expansion
is void. It is possible to intermix files and diversion numbers.
divert(`1')diversion one
divert(`2')undivert(`foo')dnl
divert(`3')diversion three
divert`'dnl
undivert(`1', `2', `foo', `3')dnl
⇒diversion one
⇒bar
⇒bar
⇒diversion three
divnum [Builtin]
Expands to the number of the current diversion.
Initial divnum
⇒Initial 0
divert(`1')
Diversion one: divnum
divert(`2')
Diversion two: divnum
^D
⇒
⇒Diversion one: 1
⇒
⇒Diversion two: 2
ERE, Extended Regular Expressions is not available, but will be added in GNU M4
2.0.
If replacement is omitted, regexp expands to the index of the first match of regexp
in string. If regexp does not match anywhere in string, it expands to -1.
If replacement is supplied, and there was a match, regexp changes the expansion to
this argument, with ‘\n’ substituted by the text matched by the nth parenthesized
sub-expression of regexp, up to nine sub-expressions. The escape ‘\&’ is replaced by
the text of the entire regular expression matched. For all other characters, ‘\’ treats
the next character literally. A warning is issued if there were fewer sub-expressions
than the ‘\n’ requested, or if there is a trailing ‘\’. If there was no match, regexp
expands to the empty string.
The macro regexp is recognized only with parameters.
regexp(`GNUs not Unix', `\<[a-z]\w+')
⇒5
regexp(`GNUs not Unix', `\<Q\w*')
⇒-1
regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
⇒*** Unix *** nix ***
regexp(`GNUs not Unix', `\<Q\w*', `*** \& *** \1 ***')
⇒
Here are some more examples on the handling of backslash:
regexp(`abc', `\(b\)', `\\\10\a')
⇒\b0a
regexp(`abc', `b', `\1\')
error m4:stdin:2: Warning: sub-expression 1 not present
error m4:stdin:2: Warning: trailing \ ignored in replacement
⇒
regexp(`abc', `\(\(d\)?\)\(c\)', `\1\2\3\4\5\6')
error m4:stdin:3: Warning: sub-expression 4 not present
error m4:stdin:3: Warning: sub-expression 5 not present
error m4:stdin:3: Warning: sub-expression 6 not present
⇒c
Omitting regexp evokes a warning, but still produces output; contrast this with an empty
regexp argument.
regexp(`abc')
error m4:stdin:1: Warning: too few arguments to builtin `regexp'
⇒0
regexp(`abc', `')
⇒0
regexp(`abc', `', `\\def')
⇒\def
While regexp replaces the whole input with the replacement as soon as there is a match,
patsubst replaces each occurrence of a match and preserves non-matching pieces:
define(`patreg',
`patsubst($@)
regexp($@)')dnl
patreg(`bar foo baz Foo', `foo\|Foo', `FOO')
⇒bar FOO baz FOO
⇒FOO
patreg(`aba abb 121', `\(.\)\(.\)\1', `\2\1\2')
⇒bab abb 212
⇒bab
Omitting regexp evokes a warning, but still produces output; contrast this with an empty
regexp argument.
patsubst(`abc')
error m4:stdin:1: Warning: too few arguments to builtin `patsubst'
⇒abc
patsubst(`abc', `')
⇒abc
patsubst(`abc', `', `\\-')
⇒\-a\-b\-c\-
All binary operators, except exponentiation, are left associative. C operators that per-
form variable assignment, such as ‘+=’ or ‘--’, are not implemented, since eval only operates
on constants, not variables. Attempting to use them results in an error. However, since
traditional implementations treated ‘=’ as an undocumented alias for ‘==’ as opposed to
an assignment operator, this usage is supported as a special case. Be aware that a future
version of GNU M4 may support assignment semantics as an extension when POSIX mode
is not requested, and that using ‘=’ to check equality is not portable.
eval(`2 = 2')
error m4:stdin:1: Warning: recommend ==, not =, for equality operator
⇒1
eval(`++0')
error m4:stdin:2: invalid operator in eval: ++0
⇒
eval(`0 |= 1')
error m4:stdin:3: invalid operator in eval: 0 |= 1
⇒
Note that some older m4 implementations use ‘^’ as an alternate operator for the expo-
nentiation, although POSIX requires the C behavior of bitwise exclusive-or. The precedence
of the negation operators, ‘~’ and ‘!’, was traditionally lower than equality. The unary op-
erators could not be used reliably more than once on the same term without intervening
parentheses. The traditional precedence of the equality operators ‘==’ and ‘!=’ was identi-
cal instead of lower than the relational operators such as ‘<’, even through GNU M4 1.4.8.
Starting with version 1.4.9, GNU M4 correctly follows POSIX precedence rules. M4 scripts
designed to be portable between releases must be aware that parentheses may be required
to enforce C precedence rules. Likewise, division by zero, even in the unused branch of a
short-circuiting operator, is not always well-defined in other implementations.
Following are some examples where the current version of M4 follows C precedence rules,
but where older versions and some other implementations of m4 require explicit parentheses
to get the correct result:
eval(`1 == 2 > 0')
⇒1
eval(`(1 == 2) > 0')
⇒0
Chapter 12: Macros for doing arithmetic 91
eval(`! 0 * 2')
⇒2
eval(`! (0 * 2)')
⇒1
eval(`1 | 1 ^ 1')
⇒1
eval(`(1 | 1) ^ 1')
⇒0
eval(`+ + - ~ ! ~ 0')
⇒1
eval(`2 || 1 / 0')
⇒1
eval(`0 || 1 / 0')
error m4:stdin:9: divide by zero in eval: 0 || 1 / 0
⇒
eval(`0 && 1 % 0')
⇒0
eval(`2 && 1 % 0')
error m4:stdin:11: modulo by zero in eval: 2 && 1 % 0
⇒
As a GNU extension, the operator ‘**’ performs integral exponentiation. The operator
is right-associative, and if evaluated, the exponent must be non-negative, and at least one
of the arguments must be non-zero, or a warning is issued.
eval(`2 ** 3 ** 2')
⇒512
eval(`(2 ** 3) ** 2')
⇒64
eval(`0 ** 1')
⇒0
eval(`2 ** 0')
⇒1
eval(`0 ** 0')
⇒
error m4:stdin:5: divide by zero in eval: 0 ** 0
eval(`4 ** -2')
error m4:stdin:6: negative exponent in eval: 4 ** -2
⇒
Within expression, (but not radix or width), numbers without a special prefix are deci-
mal. A simple ‘0’ prefix introduces an octal number. ‘0x’ introduces a hexadecimal number.
As GNU extensions, ‘0b’ introduces a binary number. ‘0r’ introduces a number expressed
in any radix between 1 and 36: the prefix should be immediately followed by the decimal
expression of the radix, a colon, then the digits making the number. For radix 1, leading
zeros are ignored, and all remaining digits must be ‘1’; for all other radices, the digits are
‘0’, ‘1’, ‘2’, . . . . Beyond ‘9’, the digits are ‘a’, ‘b’ . . . up to ‘z’. Lower and upper case
letters can be used interchangeably in numbers prefixes and as number digits.
92 GNU M4 1.4.19 macro processor
Parentheses may be used to group subexpressions whenever needed. For the relational
operators, a true relation returns 1, and a false relation return 0.
Here are a few examples of use of eval.
eval(`-3 * 5')
⇒-15
eval(`-99 / 10')
⇒-9
eval(`-99 % 10')
⇒-9
eval(`99 % -10')
⇒9
eval(index(`Hello world', `llo') >= 0)
⇒1
eval(`0r1:0111 + 0b100 + 0r3:12')
⇒12
define(`square', `eval(`($1) ** 2')')
⇒
square(`9')
⇒81
square(square(`5')` + 1')
⇒676
define(`foo', `666')
⇒
eval(`foo / 6')
error m4:stdin:11: bad expression in eval: foo / 6
⇒
eval(foo / 6)
⇒111
As the last two lines show, eval does not handle macro names, even if they expand to
a valid expression (or part of a valid expression). Therefore all macros must be expanded
before they are passed to eval.
Some calculations are not portable to other implementations, since they have undefined
semantics in C, but GNU m4 has well-defined behavior on overflow. When shifting, an out-
of-range shift amount is implicitly brought into the range of 32-bit signed integers using an
implicit bit-wise and with 0x1f).
define(`max_int', eval(`0x7fffffff'))
⇒
define(`min_int', incr(max_int))
⇒
eval(min_int` < 0')
⇒1
eval(max_int` > 0')
⇒1
ifelse(eval(min_int` / -1'), min_int, `overflow occurred')
⇒overflow occurred
min_int
93
⇒-2147483648
eval(`0x80000000 % -1')
⇒0
eval(`-4 >> 1')
⇒-2
eval(`-4 >> 33')
⇒-2
If radix is specified, it specifies the radix to be used in the expansion. The default radix
is 10; this is also the case if radix is the empty string. A warning results if the radix is
outside the range of 1 through 36, inclusive. The result of eval is always taken to be signed.
No radix prefix is output, and for radices greater than 10, the digits are lower case. The
width argument specifies the minimum output width, excluding any negative sign. The
result is zero-padded to extend the expansion to the requested width. A warning results if
the width is negative. If radix or width is out of bounds, the expansion of eval is empty.
eval(`666', `10')
⇒666
eval(`666', `11')
⇒556
eval(`666', `6')
⇒3030
eval(`666', `6', `10')
⇒0000003030
eval(`-666', `6', `10')
⇒-0000003030
eval(`10', `', `0')
⇒10
`0r1:'eval(`10', `1', `11')
⇒0r1:01111111111
eval(`10', `16')
⇒a
eval(`1', `37')
error m4:stdin:9: radix 37 in builtin `eval' out of range
⇒
eval(`1', , `-1')
error m4:stdin:10: negative width to builtin `eval'
⇒
eval()
error m4:stdin:11: empty string treated as 0 in builtin `eval'
⇒0
95
When GNU extensions are in effect (that is, when you did not use the -G option, see
Section 2.3 [Invoking m4], page 10), GNU m4 will define the macro __gnu__ to expand to
the empty string.
$ m4
__gnu__
⇒
__gnu__(`ignored')
⇒
Extensions are ifdef(`__gnu__', `active', `inactive')
⇒Extensions are active
$ m4 -G
__gnu__
⇒__gnu__
__gnu__(`ignored')
⇒__gnu__(ignored)
Extensions are ifdef(`__gnu__', `active', `inactive')
⇒Extensions are inactive
On UNIX systems, GNU m4 will define __unix__ by default, or unix when the -G option
is specified.
96 GNU M4 1.4.19 macro processor
It tells m4 to read all of its input before executing the wrapped text, then hand a valid
(albeit emptied) pipe as standard input for the cat subcommand. Therefore, you should
be careful when using standard input (either by specifying no files, or by passing ‘-’ as a
file name on the command line, see Section 2.6 [Invoking m4], page 12), and also invoking
subcommands via syscmd or esyscmd that consume data from standard input. When
standard input is a seekable file, the subprocess will pick up with the next character not
yet processed by m4; when it is a pipe or other non-seekable file, there is no guarantee how
much data will already be buffered by m4 and thus unavailable to the child.
sysval [Builtin]
Expands to the exit status of the last shell command run with syscmd or esyscmd.
Expands to 0 if no command has been run yet.
sysval
⇒0
syscmd(`false')
⇒
98 GNU M4 1.4.19 macro processor
sysval
⇒0
esyscmd([kill -9 $$])
⇒
sysval
⇒2304
If you try this next example, you will most likely get different output for the two file
names, since the replacement characters are randomly chosen:
$ m4
define(`tmp', `oops')
⇒
maketemp(`/tmp/fooXXXXXX')
⇒/tmp/fooa07346
ifdef(`mkstemp', `define(`maketemp', defn(`mkstemp'))',
`define(`mkstemp', defn(`maketemp'))dnl
errprint(`warning: potentially insecure maketemp implementation
')')
⇒
mkstemp(`doc')
100 GNU M4 1.4.19 macro processor
⇒docQv83Uw
Unless you use the --traditional command line option (or -G, see Section 2.3 [Invoking
m4], page 10), the GNU version of maketemp is secure. This means that using the same
template to multiple calls will generate multiple files. However, we recommend that you use
the new mkstemp macro, introduced in GNU M4 1.4.8, which is secure even in traditional
mode. Also, as of M4 1.4.11, the secure implementation quotes the resulting file name,
so that you are guaranteed to know what file was created even if the random file name
happens to match an existing macro. Notice that this example is careful to use defn to
avoid unintended expansion of ‘foo’.
$ m4
define(`foo', `errprint(`oops')')
⇒
syscmd(`rm -f foo-??????')sysval
⇒0
define(`file1', maketemp(`foo-XXXXXX'))dnl
ifelse(esyscmd(`echo \` foo-?????? \''), ` foo-?????? ',
`no file', `created')
⇒created
define(`file2', maketemp(`foo-XX'))dnl
define(`file3', mkstemp(`foo-XXXXXX'))dnl
ifelse(len(defn(`file1')), len(defn(`file2')),
`same length', `different')
⇒same length
ifelse(defn(`file1'), defn(`file2'), `same', `different file')
⇒different file
ifelse(defn(`file2'), defn(`file3'), `same', `different file')
⇒different file
ifelse(defn(`file1'), defn(`file3'), `same', `different file')
⇒different file
syscmd(`rm 'defn(`file1') defn(`file2') defn(`file3'))
⇒
sysval
⇒0
101
__file__ [Builtin]
__line__ [Builtin]
__program__ [Builtin]
Expand to the quoted name of the current input file, the current input line number
in that file, and the quoted name of the current invocation of m4.
errprint(__program__:__file__:__line__: `input error
')
error m4:stdin:1: input error
⇒
Line numbers start at 1 for each file. If the file was found due to the -I option or
M4PATH environment variable, that is reflected in the file name. The syncline option (-s, see
Section 2.2 [Invoking m4], page 8), and the ‘f’ and ‘l’ flags of debugmode (see Section 7.3
102 GNU M4 1.4.19 macro processor
[Debug Levels], page 58), also use this notion of current file and line. Redefining the three
location macros has no effect on syncline, debug, warning, or error message output.
This example reuses the file incl.m4 mentioned earlier (see Section 9.1 [Include],
page 73):
$ m4 -I examples
define(`foo', ``$0' called at __file__:__line__')
⇒
foo
⇒foo called at stdin:2
include(`incl.m4')
⇒Include file start
⇒foo called at examples/incl.m4:2
⇒Include file end
⇒
The location of macros invoked during the rescanning of macro expansion text corre-
sponds to the location in the file where the expansion was triggered, regardless of how many
newline characters the expansion text contains. As of GNU M4 1.4.8, the location of text
wrapped with m4wrap (see Section 8.5 [M4wrap], page 70) is the point at which the m4wrap
was invoked. Previous versions, however, behaved as though wrapped text came from line
0 of the file “”.
define(`echo', `$@')
⇒
define(`foo', `echo(__line__
__line__)')
⇒
echo(__line__
__line__)
⇒4
⇒5
m4wrap(`foo
')
⇒
foo(errprint(__line__
__line__
))
error 8
error 9
⇒8
⇒8
__line__
⇒11
m4wrap(`__line__
')
⇒
^D
⇒12
Chapter 14: Miscellaneous builtin macros 103
⇒6
⇒6
The __program__ macro behaves like ‘$0’ in shell terminology. If you invoke m4 through
an absolute path or a link with a different spelling, rather than by relying on a PATH search
for plain ‘m4’, it will affect how __program__ expands. The intent is that you can use it to
produce error messages with the same formatting that m4 produces internally. It can also
be used within syscmd (see Section 13.2 [Syscmd], page 96) to pick the same version of m4
that is currently running, rather than whatever version of m4 happens to be first in PATH.
It was first introduced in GNU M4 1.4.6.
of changeword. Currently, m4wrap and sysval also have problems. Also, interactions
for some options of m4, being used in one call and not in the next, have not been fully
analyzed yet. On the other end, you may be confident that stacks of pushdef definitions
are handled correctly, as well as undefined or renamed builtins, and changed strings for
quotes or comments. And future releases of GNU M4 will improve on the utility of frozen
files.
When an m4 run is to be frozen, the automatic undiversion which takes place at end of
execution is inhibited. Instead, all positively numbered diversions are saved into the frozen
file. The active diversion number is also transmitted.
A frozen file to be reloaded need not reside in the current directory. It is looked up the
same way as an include file (see Section 9.2 [Search Path], page 74).
If the frozen file was generated with a newer version of m4, and contains directives that
an older m4 cannot parse, attempting to load the frozen file with option -R will cause m4 to
exit with status 63 to indicate version mismatch.
may appear more than once for the same name, and its order, along with ‘T’,
is important. If omitted, you will have no access to any builtins.
Q len1 , len2 NL str1 str2 NL
Uses str1 and str2 as the begin-quote and end-quote strings. If omitted, then
‘`’ and ‘'’ are the quote delimiters.
T len1 , len2 NL str1 str2 NL
Defines, though pushdef, a definition for str1 expanding to the text given by
str2. This directive may appear more than once for the same name, and its
order, along with ‘F’, is important.
V number NL
Confirms the format of the file. m4 1.4.19 only creates and understands frozen
files where number is 1. This directive must be the first non-comment in the
file, and may not appear more than once.
109
This chapter describes the many of the differences between this implementation of m4, and
of other implementations found under UNIX, such as System V Release 4, Solaris, and BSD
flavors. In particular, it lists the known differences and extensions to POSIX. However, the
list is not necessarily comprehensive.
At the time of this writing, POSIX 2001 (also known as IEEE Std 1003.1-2001) is
the latest standard, although a new version of POSIX is under development and includes
several proposals for modifying what m4 is required to do. The requirements for m4 are
shared between SUSv3 and POSIX, and can be viewed at https://www.opengroup.org/
onlinepubs/000095399/utilities/m4.html.
• Files included with include and sinclude are sought in a user specified search path,
if they are not found in the working directory. The search path is specified by the -I
option and the M4PATH environment variable (see Section 9.2 [Search Path], page 74).
• Arguments to undivert can be non-numeric, in which case the named file will be
included uninterpreted in the output (see Section 10.2 [Undivert], page 76).
• Formatted output is supported through the format builtin, which is modeled after the
C library function printf (see Section 11.7 [Format], page 86).
• Searches and text substitution through basic regular expressions are supported by the
regexp (see Section 11.3 [Regexp], page 81) and patsubst (see Section 11.6 [Patsubst],
page 84) builtins. Some BSD implementations use extended regular expressions instead.
• The output of shell commands can be read into m4 with esyscmd (see Section 13.3
[Esyscmd], page 97).
• There is indirect access to any builtin macro with builtin (see Section 5.8 [Builtin],
page 35).
• Macros can be called indirectly through indir (see Section 5.7 [Indir], page 34).
• The name of the program, the current input file, and the current input line number are
accessible through the builtins __program__, __file__, and __line__ (see Section 14.2
[Location], page 101).
• The format of the output from dumpdef and macro tracing can be controlled with
debugmode (see Section 7.3 [Debug Levels], page 58).
• The destination of trace and debug output can be controlled with debugfile (see
Section 7.4 [Debug Output], page 60).
• The maketemp (see Section 13.5 [Mkstemp], page 99) macro behaves like mkstemp,
creating a new file with a unique name on every invocation, rather than following the
insecure behavior of replacing the trailing ‘X’ characters with the m4 process id.
• POSIX only requires support for the command line options -s, -D, and -U, so all other
options accepted by GNU M4 are extensions. See Chapter 2 [Invoking m4], page 7, for
a description of these options.
The debugging and tracing facilities in GNU m4 are much more extensive than in most
other versions of m4.
• POSIX requires an application to exit with non-zero status if it wrote an error message
to stderr. This has not yet been consistently implemented for the various builtins that
are required to issue an error (such as eval (see Section 12.2 [Eval], page 89) when an
argument cannot be parsed).
• Some traditional implementations only allow reading standard input once, but GNU
m4 correctly handles multiple instances of ‘-’ on the command line.
• POSIX requires m4wrap (see Section 8.5 [M4wrap], page 70) to act in FIFO (first-in,
first-out) order, but GNU m4 currently uses LIFO order. Furthermore, POSIX states
that only the first argument to m4wrap is saved for later evaluation, but GNU m4 saves
and processes all arguments, with output separated by spaces.
• POSIX states that builtins that require arguments, but are called without arguments,
have undefined behavior. Traditional implementations simply behave as though empty
strings had been passed. For example, a`'define`'b would expand to ab. But GNU
m4 ignores certain builtins if they have missing arguments, giving adefineb for the
above example.
• Traditional implementations handle define(`f',`1') (see Section 5.1 [Define],
page 25) by undefining the entire stack of previous definitions, and if doing
undefine(`f') first. GNU m4 replaces just the top definition on the stack, as if doing
popdef(`f') followed by pushdef(`f',`1'). POSIX allows either behavior.
• POSIX 2001 requires syscmd (see Section 13.2 [Syscmd], page 96) to evaluate command
output for macro expansion, but this was a mistake that is anticipated to be corrected
in the next version of POSIX. GNU m4 follows traditional behavior in syscmd where
output is not rescanned, and provides the extension esyscmd that does scan the output.
• At one point, POSIX required changequote(arg) (see Section 8.2 [Changequote],
page 62) to use newline as the close quote, but this was a bug, and the next ver-
sion of POSIX is anticipated to state that using empty strings or just one argument
is unspecified. Meanwhile, the GNU m4 behavior of treating an empty end-quote de-
limiter as ‘'’ is not portable, as Solaris treats it as repeating the start-quote delimiter,
and BSD treats it as leaving the previous end-quote delimiter unchanged. For pre-
dictable results, never call changequote with just one argument, or with empty strings
for arguments.
• At one point, POSIX required changecom(arg,) (see Section 8.3 [Changecom],
page 65) to make it impossible to end a comment, but this is a bug, and the next
version of POSIX is anticipated to state that using empty strings is unspecified.
Meanwhile, the GNU m4 behavior of treating an empty end-comment delimiter
as newline is not portable, as BSD treats it as leaving the previous end-comment
delimiter unchanged. It is also impossible in BSD implementations to disable
comments, even though that is required by POSIX. For predictable results, never call
changecom with empty strings for arguments.
• Most implementations of m4 give macros a higher precedence than comments when pars-
ing, meaning that if the start delimiter given to changecom (see Section 8.3 [Change-
com], page 65) starts with a macro name, comments are effectively disabled. POSIX
does not specify what the precedence is, so this version of GNU m4 parser recognizes
comments, then macros, then quoted strings.
112 GNU M4 1.4.19 macro processor
• Traditional implementations allow argument collection, but not string and comment
processing, to span file boundaries. Thus, if a.m4 contains ‘len(’, and b.m4 contains
‘abc)’, m4 a.m4 b.m4 outputs ‘3’ with traditional m4, but gives an error message that
the end of file was encountered inside a macro with GNU m4. On the other hand,
traditional implementations do end of file processing for files included with include or
sinclude (see Section 9.1 [Include], page 73), while GNU m4 seamlessly integrates the
content of those files. Thus include(`a.m4')include(`b.m4') will output ‘3’ instead
of giving an error.
• Traditional m4 treats traceon (see Section 7.2 [Trace], page 55) without arguments as a
global variable, independent of named macro tracing. Also, once a macro is undefined,
named tracing of that macro is lost. On the other hand, when GNU m4 encounters
traceon without arguments, it turns tracing on for all existing definitions at the time,
but does not trace future definitions; traceoff without arguments turns tracing off
for all definitions regardless of whether they were also traced by name; and tracing by
name, such as with -tfoo at the command line or traceon(`foo') in the input, is an
attribute that is preserved even if the macro is currently undefined.
Additionally, while POSIX requires trace output, it makes no demands on the for-
matting of that output. Parsing trace output is not guaranteed to be reliable, even
between different releases of GNU M4; however, the intent is that any future changes
in trace output will only occur under the direction of additional debugmode flags (see
Section 7.3 [Debug Levels], page 58).
• POSIX requires eval (see Section 12.2 [Eval], page 89) to treat all operators with the
same precedence as C. However, earlier versions of GNU m4 followed the traditional
behavior of other m4 implementations, where bitwise and logical negation (‘~’ and
‘!’) have lower precedence than equality operators; and where equality operators (‘==’
and ‘!=’) had the same precedence as relational operators (such as ‘<’). Use explicit
parentheses to ensure proper precedence. As extensions to POSIX, GNU m4 gives well-
defined semantics to operations that C leaves undefined, such as when overflow occurs,
when shifting negative numbers, or when performing division by zero. POSIX also
requires ‘=’ to cause an error, but many traditional implementations allowed it as an
alias for ‘==’.
• POSIX 2001 requires translit (see Section 11.5 [Translit], page 83) to treat each
character of the second and third arguments literally. However, it is anticipated that
the next version of POSIX will allow the GNU m4 behavior of treating ‘-’ as a range
operator.
• POSIX requires m4 to honor the locale environment variables of LANG, LC_ALL, LC_
CTYPE, LC_MESSAGES, and NLSPATH, but this has not yet been implemented in GNU
m4.
• POSIX states that only unquoted leading newlines and blanks (that is, space and tab)
are ignored when collecting macro arguments. However, this appears to be a bug in
POSIX, since most traditional implementations also ignore all whitespace (formfeed,
carriage return, and vertical tab). GNU m4 follows tradition and ignores all leading
unquoted whitespace.
• A strictly-compliant POSIX client is not allowed to use command-line arguments not
specified by POSIX. However, since this version of M4 ignores POSIXLY_CORRECT and
Chapter 16: Compatibility with other versions of m4 113
enables the option --gnu by default (see Section 2.3 [Invoking m4], page 10), a client
desiring to be strictly compliant has no way to disable GNU extensions that conflict
with POSIX when directly invoking the compiled m4. A future version of GNU M4 will
honor the environment variable POSIXLY_CORRECT, implicitly enabling --traditional
if it is set, in order to allow a strictly-compliant client. In the meantime, a client
needing strict POSIX compliance can use the workaround of invoking a shell script
wrapper, where the wrapper then adds --traditional to the arguments passed to the
compiled m4.
one might use macros to hold strings, as we do for variables in other programming
languages, further checking them with:
ifelse(defn(`holder'), `value', ...)
In cases like this one, an interdiction for a macro to hold its own name would be
a useless limitation. Of course, this leaves more rope for the GNU m4 user to hang
himself! Rescanning hangs may be avoided through careful programming, a little like
for endless loops in traditional programming languages.
115
$ m4 -I examples
include(`forloop3.m4')
⇒
undivert(`forloop3.m4')dnl
⇒divert(`-1')
⇒# forloop_arg(from, to, macro) - invoke MACRO(value) for
⇒# each value between FROM and TO, without define overhead
⇒define(`forloop_arg', `ifelse(eval(`($1) <= ($2)'), `1',
⇒ `_forloop(`$1', eval(`$2'), `$3(', `)')')')
⇒# forloop(var, from, to, stmt) - refactored to share code
⇒define(`forloop', `ifelse(eval(`($2) <= ($3)'), `1',
⇒ `pushdef(`$1')_forloop(eval(`$2'), eval(`$3'),
⇒ `define(`$1',', `)$4')popdef(`$1')')')
⇒define(`_forloop',
⇒ `$3`$1'$4`'ifelse(`$1', `$2', `',
⇒ `$0(incr(`$1'), `$2', `$3', `$4')')')
⇒divert`'dnl
forloop(`i', `1', `3', ` i')
⇒ 1 2 3
define(`echo', `$@')
⇒
forloop_arg(`1', `3', ` echo')
⇒ 1 2 3
include(`curry.m4')
⇒
forloop_arg(`1', `3', `curry(`pushdef', `a')')
⇒
a
⇒3
popdef(`a')a
⇒2
popdef(`a')a
⇒1
popdef(`a')a
⇒a
Of course, it is possible to make even more improvements, such as adding an optional
step argument, or allowing iteration through descending sequences. GNU Autoconf provides
some of these additional bells and whistles in its m4_for macro.
⇒
foreachq(`x', ``1', `2', `3', `4'', `x
')dnl
⇒1
error m4trace: -3- shift(`1', `2', `3', `4')
error m4trace: -2- shift(`1', `2', `3', `4')
⇒2
error m4trace: -4- shift(`1', `2', `3', `4')
error m4trace: -3- shift(`2', `3', `4')
error m4trace: -3- shift(`1', `2', `3', `4')
error m4trace: -2- shift(`2', `3', `4')
⇒3
error m4trace: -5- shift(`1', `2', `3', `4')
error m4trace: -4- shift(`2', `3', `4')
error m4trace: -3- shift(`3', `4')
error m4trace: -4- shift(`1', `2', `3', `4')
error m4trace: -3- shift(`2', `3', `4')
error m4trace: -2- shift(`3', `4')
⇒4
error m4trace: -6- shift(`1', `2', `3', `4')
error m4trace: -5- shift(`2', `3', `4')
error m4trace: -4- shift(`3', `4')
error m4trace: -3- shift(`4')
Each successive iteration was adding more quoted shift invocations, and the entire list
contents were passing through every iteration. In general, when recursing, it is a good idea
to make the recursion use fewer arguments, rather than adding additional quoted uses of
shift. By doing so, m4 uses less memory, invokes fewer macros, is less likely to run into
machine limits, and most importantly, performs faster. The fixed version of foreachq can
be found in m4-1.4.19/examples/foreachq2.m4:
$ m4 -I examples
include(`foreachq2.m4')
⇒
undivert(`foreachq2.m4')dnl
⇒include(`quote.m4')dnl
⇒divert(`-1')
⇒# foreachq(x, `item_1, item_2, ..., item_n', stmt)
⇒# quoted list, improved version
⇒define(`foreachq', `pushdef(`$1')_$0($@)popdef(`$1')')
⇒define(`_arg1q', ``$1'')
⇒define(`_rest', `ifelse(`$#', `1', `', `dquote(shift($@))')')
⇒define(`_foreachq', `ifelse(`$2', `', `',
⇒ `define(`$1', _arg1q($2))$3`'$0(`$1', _rest($2), `$3')')')
⇒divert`'dnl
traceon(`shift')debugmode(`aq')
⇒
foreachq(`x', ``1', `2', `3', `4'', `x
Chapter 17: Correct version of some examples 119
')dnl
⇒1
error m4trace: -3- shift(`1', `2', `3', `4')
⇒2
error m4trace: -3- shift(`2', `3', `4')
⇒3
error m4trace: -3- shift(`3', `4')
⇒4
Note that the fixed version calls unquoted helper macros in _foreachq to trim elements
immediately; those helper macros in turn must re-supply the layer of quotes lost in the macro
invocation. Contrast the use of _arg1q, which quotes the first list element, with _arg1 of the
earlier implementation that returned the first list element directly. Additionally, by calling
the helper method immediately, the ‘defn(`iterator')’ no longer contains unexpanded
macros.
The astute m4 programmer might notice that the solution above still uses more mem-
ory and macro invocations, and thus more time, than strictly necessary. Note that ‘$2’,
which contains an arbitrarily long quoted list, is expanded and rescanned three times per
iteration of _foreachq. Furthermore, every iteration of the algorithm effectively unboxes
then reboxes the list, which costs a couple of macro invocations. It is possible to rewrite
the algorithm for a bit more speed by swapping the order of the arguments to _foreachq
in order to operate on an unboxed list in the first place, and by using the fixed-length ‘$#’
instead of an arbitrary length list as the key to end recursion. The result is an overhead
of six macro invocations per loop (excluding any macros in text), instead of eight. This
alternative approach is available as m4-1.4.19/examples/foreach3.m4:
$ m4 -I examples
include(`foreachq3.m4')
⇒
undivert(`foreachq3.m4')dnl
⇒divert(`-1')
⇒# foreachq(x, `item_1, item_2, ..., item_n', stmt)
⇒# quoted list, alternate improved version
⇒define(`foreachq', `ifelse(`$2', `', `',
⇒ `pushdef(`$1')_$0(`$1', `$3', `', $2)popdef(`$1')')')
⇒define(`_foreachq', `ifelse(`$#', `3', `',
⇒ `define(`$1', `$4')$2`'$0(`$1', `$2',
⇒ shift(shift(shift($@))))')')
⇒divert`'dnl
traceon(`shift')debugmode(`aq')
⇒
foreachq(`x', ``1', `2', `3', `4'', `x
')dnl
⇒1
error m4trace: -4- shift(`x', `x
error ', `', `1', `2', `3', `4')
error m4trace: -3- shift(`x
error ', `', `1', `2', `3', `4')
120 GNU M4 1.4.19 macro processor
$ m4 -I examples
include(`foreachq4.m4')
⇒
undivert(`foreachq4.m4')dnl
⇒include(`forloop2.m4')dnl
⇒divert(`-1')
⇒# foreachq(x, `item_1, item_2, ..., item_n', stmt)
⇒# quoted list, version based on forloop
⇒define(`foreachq',
⇒`ifelse(`$2', `', `', `_$0(`$1', `$3', $2)')')
⇒define(`_foreachq',
⇒`pushdef(`$1', forloop(`$1', `3', `$#',
⇒ `$0_(`1', `2', indir(`$1'))')`popdef(
⇒ `$1')')indir(`$1', $@)')
⇒define(`_foreachq_',
⇒``define(`$$1', `$$3')$$2`''')
⇒divert`'dnl
traceon(`shift')debugmode(`aq')
⇒
foreachq(`x', ``1', `2', `3', `4'', `x
')dnl
⇒1
⇒2
⇒3
⇒4
For yet another approach, the improved version of foreach, available in m4-1.4.19/
examples/foreach2.m4, simply overquotes the arguments to _foreach to begin with, using
dquote_elt. Then _foreach can just use _arg1 to remove the extra layer of quoting that
was added up front:
$ m4 -I examples
include(`foreach2.m4')
⇒
undivert(`foreach2.m4')dnl
⇒include(`quote.m4')dnl
⇒divert(`-1')
⇒# foreach(x, (item_1, item_2, ..., item_n), stmt)
⇒# parenthesized list, improved version
⇒define(`foreach', `pushdef(`$1')_$0(`$1',
⇒ (dquote(dquote_elt$2)), `$3')popdef(`$1')')
⇒define(`_arg1', `$1')
⇒define(`_foreach', `ifelse(`$2', `(`')', `',
⇒ `define(`$1', _arg1$2)$3`'$0(`$1', (dquote(shift$2)), `$3')')')
⇒divert`'dnl
traceon(`shift')debugmode(`aq')
⇒
foreach(`x', `(`1', `2', `3', `4')', `x
122 GNU M4 1.4.19 macro processor
')dnl
error m4trace: -4- shift(`1', `2', `3', `4')
error m4trace: -4- shift(`2', `3', `4')
error m4trace: -4- shift(`3', `4')
⇒1
error m4trace: -3- shift(``1'', ``2'', ``3'', ``4'')
⇒2
error m4trace: -3- shift(``2'', ``3'', ``4'')
⇒3
error m4trace: -3- shift(``3'', ``4'')
⇒4
error m4trace: -3- shift(``4'')
It is likewise possible to write a variant of foreach that performs in linear time on M4
1.4.x; the easiest method is probably writing a version of foreach that unboxes its list,
then invokes _foreachq as previously defined in foreachq4.m4.
In summary, recursion over list elements is trickier than it appeared at first glance,
but provides a powerful idiom within m4 processing. As a final demonstration, both list
styles are now able to handle several scenarios that would wreak havoc on one or both of
the original implementations. This points out one other difference between the list styles.
foreach evaluates unquoted list elements only once, in preparation for calling _foreach,
similary for foreachq as provided by foreachq3.m4 or foreachq4.m4. But foreachq, as
provided by foreachq2.m4, evaluates unquoted list elements twice while visiting the first
list element, once in _arg1q and once in _rest. When deciding which list style to use,
one must take into account whether repeating the side effects of unquoted list elements will
have any detrimental effects.
$ m4 -I examples
include(`foreach2.m4')
⇒
include(`foreachq2.m4')
⇒
dnl 0-element list:
foreach(`x', `', `<x>') / foreachq(`x', `', `<x>')
⇒ /
dnl 1-element list of empty element
foreach(`x', `()', `<x>') / foreachq(`x', ``'', `<x>')
⇒<> / <>
dnl 2-element list of empty elements
foreach(`x', `(`',`')', `<x>') / foreachq(`x', ``',`'', `<x>')
⇒<><> / <><>
dnl 1-element list of a comma
foreach(`x', `(`,')', `<x>') / foreachq(`x', ``,'', `<x>')
⇒<,> / <,>
dnl 2-element list of unbalanced parentheses
foreach(`x', `(`(', `)')', `<x>') / foreachq(`x', ``(', `)'', `<x>')
⇒<(><)> / <(><)>
define(`ab', `oops')dnl using defn(`iterator')
Chapter 17: Correct version of some examples 123
⇒<active>
b
⇒0
popdef(`b')
⇒
b
⇒1
pushdef(`c', `1')pushdef(`c', `2')
⇒
stack_foreach_sep_lifo(`c', `', `', `, ')
⇒2, 1
undivert(`stack_sep.m4')dnl
⇒divert(`-1')
⇒# stack_foreach_sep(macro, pre, post, sep)
⇒# Invoke PRE`'defn`'POST with a single argument of each definition
⇒# from the definition stack of MACRO, starting with the oldest, and
⇒# separated by SEP between definitions.
⇒define(`stack_foreach_sep',
⇒`_stack_reverse_sep(`$1', `tmp-$1')'dnl
⇒`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4`'')')
⇒# stack_foreach_sep_lifo(macro, pre, post, sep)
⇒# Like stack_foreach_sep, but starting with the newest definition.
⇒define(`stack_foreach_sep_lifo',
⇒`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4`'')'dnl
⇒`_stack_reverse_sep(`tmp-$1', `$1')')
⇒define(`_stack_reverse_sep',
⇒`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
⇒ `$1', `$2', `$4$3')')')
⇒divert`'dnl
⇒
cleardivert
⇒
undivert
⇒one
⇒
define(`cleardivert',
`pushdef(`_num', divnum)divert(`-1')ifelse(`$#', `0',
`undivert`'', `undivert($@)')divert(_num)popdef(`_num')')
⇒
divert(`2')two
divert
⇒
cleardivert
⇒
undivert
⇒
⇒_capitalize(`active')
define(`A', `OOPS')
⇒
capitalize(active)
⇒OOPSct1
capitalize(`active')
⇒OOPSctive
First, when capitalize is called with more than one argument, it was throwing away
later arguments, whereas upcase and downcase used ‘$*’ to collect them all. The fix is
simple: use ‘$*’ consistently.
Next, with single-quoting, capitalize outputs a single character, a set of quotes, then
the rest of the characters, making it impossible to invoke Active after the fact, and allowing
the alternate macro A to interfere. Here, the solution is to use additional quoting in the
helper macros, then pass the final over-quoted output string through _arg1 to remove the
extra quoting and finally invoke the concatenated portions as a single string.
Finally, when passed a double-quoted string, the nested macro _capitalize is never
invoked because it ended up nested inside quotes. This one is the toughest to fix. In short,
we have no idea how many levels of quotes are in effect on the substring being altered by
patsubst. If the replacement string cannot be expressed entirely in terms of literal text
and backslash substitutions, then we need a mechanism to guarantee that the helper macros
are invoked outside of quotes. In other words, this sounds like a job for changequote (see
Section 8.2 [Changequote], page 62). By changing the active quoting characters, we can
guarantee that replacement text injected by patsubst always occurs in the middle of a
string that has exactly one level of over-quoting using alternate quotes; so the replacement
text closes the quoted string, invokes the helper macros, then reopens the quoted string. In
turn, that means the replacement text has unbalanced quotes, necessitating another round
of changequote.
In the fixed version below, (also shipped as m4-1.4.19/examples/capitalize2.m4),
capitalize uses the alternate quotes of ‘<<[’ and ‘]>>’ (the longer strings are chosen so as
to be less likely to appear in the text being converted). The helpers _to_alt and _from_
alt merely reduce the number of characters required to perform a changequote, since the
definition changes twice. The outermost pair means that patsubst and _capitalize_alt
are invoked with alternate quoting; the innermost pair is used so that the third argument
to patsubst can contain an unbalanced ‘]>>’/‘<<[’ pair. Note that upcase and downcase
must be redefined as _upcase_alt and _downcase_alt, since they contain nested quotes
but are invoked with the alternate quoting scheme in effect.
$ m4 -I examples
include(`capitalize2.m4')dnl
define(`active', `act1, ive')dnl
define(`Active', `Act2, Ive')dnl
define(`ACTIVE', `ACT3, IVE')dnl
define(`A', `OOPS')dnl
capitalize(active; `active'; ``active''; ```actIVE''')
⇒Act1,Ive; Act2, Ive; Active; `Active'
undivert(`capitalize2.m4')dnl
⇒divert(`-1')
Chapter 17: Correct version of some examples 129
⇒# upcase(text)
⇒# downcase(text)
⇒# capitalize(text)
⇒# change case of text, improved version
⇒define(`upcase', `translit(`$*', `a-z', `A-Z')')
⇒define(`downcase', `translit(`$*', `A-Z', `a-z')')
⇒define(`_arg1', `$1')
⇒define(`_to_alt', `changequote(`<<[', `]>>')')
⇒define(`_from_alt', `changequote(<<[`]>>, <<[']>>)')
⇒define(`_upcase_alt', `translit(<<[$*]>>, <<[a-z]>>, <<[A-Z]>>)')
⇒define(`_downcase_alt', `translit(<<[$*]>>, <<[A-Z]>>, <<[a-z]>>)')
⇒define(`_capitalize_alt',
⇒ `regexp(<<[$1]>>, <<[^\(\w\)\(\w*\)]>>,
⇒ <<[_upcase_alt(<<[<<[\1]>>]>>)_downcase_alt(<<[<<[\2]>>]>>)]>>)')
⇒define(`capitalize',
⇒ `_arg1(_to_alt()patsubst(<<[<<[$*]>>]>>, <<[\w+]>>,
⇒ _from_alt()`]>>_$0_alt(<<[\&]>>)<<['_to_alt())_from_alt())')
⇒divert`'dnl
Preamble
The GNU General Public License is a free, copyleft license for software and other kinds of
works.
The licenses for most software and other practical works are designed to take away your
freedom to share and change the works. By contrast, the GNU General Public License is
intended to guarantee your freedom to share and change all versions of a program—to make
sure it remains free software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to any other work
released this way by its authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General
Public Licenses are designed to make sure that you have the freedom to distribute copies
of free software (and charge for them if you wish), that you receive source code or can get
it if you want it, that you can change the software or use pieces of it in new free programs,
and that you know you can do these things.
To protect your rights, we need to prevent others from denying you these rights or asking
you to surrender the rights. Therefore, you have certain responsibilities if you distribute
copies of the software, or if you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or for a fee, you
must pass on to the recipients the same freedoms that you received. You must make sure
that they, too, receive or can get the source code. And you must show them these terms so
they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert copy-
right on the software, and (2) offer you this License giving you legal permission to copy,
distribute and/or modify it.
For the developers’ and authors’ protection, the GPL clearly explains that there is no
warranty for this free software. For both users’ and authors’ sake, the GPL requires that
modified versions be marked as changed, so that their problems will not be attributed
erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified versions of the
software inside them, although the manufacturer can do so. This is fundamentally incom-
patible with the aim of protecting users’ freedom to change the software. The systematic
132 GNU M4 1.4.19 macro processor
pattern of such abuse occurs in the area of products for individuals to use, which is pre-
cisely where it is most unacceptable. Therefore, we have designed this version of the GPL
to prohibit the practice for those products. If such problems arise substantially in other
domains, we stand ready to extend this provision to those domains in future versions of the
GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States should not
allow patents to restrict development and use of software on general-purpose computers, but
in those that do, we wish to avoid the special danger that patents applied to a free program
could make it effectively proprietary. To prevent this, the GPL assures that patents cannot
be used to render the program non-free.
The precise terms and conditions for copying, distribution and modification follow.
A separable portion of the object code, whose source code is excluded from the Cor-
responding Source as a System Library, need not be included in conveying the object
code work.
A “User Product” is either (1) a “consumer product”, which means any tangible per-
sonal property which is normally used for personal, family, or household purposes, or
(2) anything designed or sold for incorporation into a dwelling. In determining whether
a product is a consumer product, doubtful cases shall be resolved in favor of coverage.
For a particular product received by a particular user, “normally used” refers to a
typical or common use of that class of product, regardless of the status of the par-
ticular user or of the way in which the particular user actually uses, or expects or is
expected to use, the product. A product is a consumer product regardless of whether
136 GNU M4 1.4.19 macro processor
the product has substantial commercial, industrial or non-consumer uses, unless such
uses represent the only significant mode of use of the product.
“Installation Information” for a User Product means any methods, procedures, autho-
rization keys, or other information required to install and execute modified versions of a
covered work in that User Product from a modified version of its Corresponding Source.
The information must suffice to ensure that the continued functioning of the modified
object code is in no case prevented or interfered with solely because modification has
been made.
If you convey an object code work under this section in, or with, or specifically for
use in, a User Product, and the conveying occurs as part of a transaction in which
the right of possession and use of the User Product is transferred to the recipient in
perpetuity or for a fixed term (regardless of how the transaction is characterized),
the Corresponding Source conveyed under this section must be accompanied by the
Installation Information. But this requirement does not apply if neither you nor any
third party retains the ability to install modified object code on the User Product (for
example, the work has been installed in ROM).
The requirement to provide Installation Information does not include a requirement
to continue to provide support service, warranty, or updates for a work that has been
modified or installed by the recipient, or for the User Product in which it has been
modified or installed. Access to a network may be denied when the modification itself
materially and adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided, in accord with
this section must be in a format that is publicly documented (and with an implementa-
tion available to the public in source code form), and must require no special password
or key for unpacking, reading or copying.
7. Additional Terms.
“Additional permissions” are terms that supplement the terms of this License by mak-
ing exceptions from one or more of its conditions. Additional permissions that are
applicable to the entire Program shall be treated as though they were included in this
License, to the extent that they are valid under applicable law. If additional permis-
sions apply only to part of the Program, that part may be used separately under those
permissions, but the entire Program remains governed by this License without regard
to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any
additional permissions from that copy, or from any part of it. (Additional permissions
may be written to require their own removal in certain cases when you modify the
work.) You may place additional permissions on material, added by you to a covered
work, for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you add to a covered
work, you may (if authorized by the copyright holders of that material) supplement
the terms of this License with terms:
a. Disclaiming warranty or limiting liability differently from the terms of sections 15
and 16 of this License; or
Appendix A: How to make copies of the overall M4 package 137
been terminated and not permanently reinstated, you do not qualify to receive new
licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy of the
Program. Ancillary propagation of a covered work occurring solely as a consequence of
using peer-to-peer transmission to receive a copy likewise does not require acceptance.
However, nothing other than this License grants you permission to propagate or modify
any covered work. These actions infringe copyright if you do not accept this License.
Therefore, by modifying or propagating a covered work, you indicate your acceptance
of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives a license
from the original licensors, to run, modify and propagate that work, subject to this
License. You are not responsible for enforcing compliance by third parties with this
License.
An “entity transaction” is a transaction transferring control of an organization, or
substantially all assets of one, or subdividing an organization, or merging organizations.
If propagation of a covered work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever licenses to the work
the party’s predecessor in interest had or could give under the previous paragraph, plus
a right to possession of the Corresponding Source of the work from the predecessor in
interest, if the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights granted or
affirmed under this License. For example, you may not impose a license fee, royalty, or
other charge for exercise of rights granted under this License, and you may not initiate
litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent
claim is infringed by making, using, selling, offering for sale, or importing the Program
or any portion of it.
11. Patents.
A “contributor” is a copyright holder who authorizes use under this License of the
Program or a work on which the Program is based. The work thus licensed is called
the contributor’s “contributor version”.
A contributor’s “essential patent claims” are all patent claims owned or controlled by
the contributor, whether already acquired or hereafter acquired, that would be infringed
by some manner, permitted by this License, of making, using, or selling its contributor
version, but do not include claims that would be infringed only as a consequence of
further modification of the contributor version. For purposes of this definition, “con-
trol” includes the right to grant patent sublicenses in a manner consistent with the
requirements of this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license
under the contributor’s essential patent claims, to make, use, sell, offer for sale, import
and otherwise run, modify and propagate the contents of its contributor version.
In the following three paragraphs, a “patent license” is any express agreement or com-
mitment, however denominated, not to enforce a patent (such as an express permission
to practice a patent or covenant not to sue for patent infringement). To “grant” such
Appendix A: How to make copies of the overall M4 package 139
The terms of this License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License, section 13,
concerning interaction through a network will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the GNU
General Public License from time to time. Such new versions will be similar in spirit
to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies that
a certain numbered version of the GNU General Public License “or any later version”
applies to it, you have the option of following the terms and conditions either of that
numbered version or of any later version published by the Free Software Foundation.
If the Program does not specify a version number of the GNU General Public License,
you may choose any version ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of the GNU
General Public License can be used, that proxy’s public statement of acceptance of a
version permanently authorizes you to choose that version for the Program.
Later license versions may give you additional or different permissions. However, no
additional obligations are imposed on any author or copyright holder as a result of your
choosing to follow a later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PER-
MITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN
WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE
THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EX-
PRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFEC-
TIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, IN-
CIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUS-
TAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAM-
AGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot be given
local legal effect according to their terms, reviewing courts shall apply local law that
Appendix A: How to make copies of the overall M4 package 141
most closely approximates an absolute waiver of all civil liability in connection with
the Program, unless a warranty or assumption of liability accompanies a copy of the
Program in return for a fee.
You should have received a copy of the GNU General Public License
along with this program. If not, see https://www.gnu.org/licenses/.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like this when it
starts in an interactive mode:
program Copyright (C) year name of author
This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’.
This is free software, and you are welcome to redistribute it
under certain conditions; type ‘show c’ for details.
The hypothetical commands ‘show w’ and ‘show c’ should show the appropriate parts of
the General Public License. Of course, your program’s commands might be different; for a
GUI interface, you would use an “about box”.
You should also get your employer (if you work as a programmer) or school, if any, to
sign a “copyright disclaimer” for the program, if necessary. For more information on this,
and how to apply and follow the GNU GPL, see https://www.gnu.org/licenses/.
The GNU General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may consider it more
useful to permit linking proprietary applications with the library. If this is what you want
to do, use the GNU Lesser General Public License instead of this License. But first, please
read https://www.gnu.org/licenses/why-not-lgpl.html.
143
textbook of mathematics, a Secondary Section may not explain any mathematics.) The
relationship could be a matter of historical connection with the subject or with related
matters, or of legal, commercial, philosophical, ethical or political position regarding
them.
The “Invariant Sections” are certain Secondary Sections whose titles are designated, as
being those of Invariant Sections, in the notice that says that the Document is released
under this License. If a section does not fit the above definition of Secondary then it is
not allowed to be designated as Invariant. The Document may contain zero Invariant
Sections. If the Document does not identify any Invariant Sections then there are none.
The “Cover Texts” are certain short passages of text that are listed, as Front-Cover
Texts or Back-Cover Texts, in the notice that says that the Document is released under
this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may
be at most 25 words.
A “Transparent” copy of the Document means a machine-readable copy, represented
in a format whose specification is available to the general public, that is suitable for
revising the document straightforwardly with generic text editors or (for images com-
posed of pixels) generic paint programs or (for drawings) some widely available drawing
editor, and that is suitable for input to text formatters or for automatic translation to
a variety of formats suitable for input to text formatters. A copy made in an otherwise
Transparent file format whose markup, or absence of markup, has been arranged to
thwart or discourage subsequent modification by readers is not Transparent. An image
format is not Transparent if used for any substantial amount of text. A copy that is
not “Transparent” is called “Opaque”.
Examples of suitable formats for Transparent copies include plain ASCII without
markup, Texinfo input format, LaTEX input format, SGML or XML using a publicly
available DTD, and standard-conforming simple HTML, PostScript or PDF designed
for human modification. Examples of transparent image formats include PNG, XCF
and JPG. Opaque formats include proprietary formats that can be read and edited
only by proprietary word processors, SGML or XML for which the DTD and/or pro-
cessing tools are not generally available, and the machine-generated HTML, PostScript
or PDF produced by some word processors for output purposes only.
The “Title Page” means, for a printed book, the title page itself, plus such following
pages as are needed to hold, legibly, the material this License requires to appear in the
title page. For works in formats which do not have any title page as such, “Title Page”
means the text near the most prominent appearance of the work’s title, preceding the
beginning of the body of the text.
The “publisher” means any person or entity that distributes copies of the Document
to the public.
A section “Entitled XYZ” means a named subunit of the Document whose title either
is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in
another language. (Here XYZ stands for a specific section name mentioned below, such
as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve
the Title” of such a section when you modify the Document means that it remains a
section “Entitled XYZ” according to this definition.
Appendix B: How to make copies of this manual 145
The Document may include Warranty Disclaimers next to the notice which states that
this License applies to the Document. These Warranty Disclaimers are considered to
be included by reference in this License, but only as regards disclaiming warranties:
any other implication that these Warranty Disclaimers may have is void and has no
effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or
noncommercially, provided that this License, the copyright notices, and the license
notice saying this License applies to the Document are reproduced in all copies, and
that you add no other conditions whatsoever to those of this License. You may not use
technical measures to obstruct or control the reading or further copying of the copies
you make or distribute. However, you may accept compensation in exchange for copies.
If you distribute a large enough number of copies you must also follow the conditions
in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly
display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of
the Document, numbering more than 100, and the Document’s license notice requires
Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all
these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify you as the publisher
of these copies. The front cover must present the full title with all words of the title
equally prominent and visible. You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve the title of the
Document and satisfy these conditions, can be treated as verbatim copying in other
respects.
If the required texts for either cover are too voluminous to fit legibly, you should put
the first ones listed (as many as fit reasonably) on the actual cover, and continue the
rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100,
you must either include a machine-readable Transparent copy along with each Opaque
copy, or state in or with each Opaque copy a computer-network location from which
the general network-using public has access to download using public-standard network
protocols a complete Transparent copy of the Document, free of added material. If
you use the latter option, you must take reasonably prudent steps, when you begin
distribution of Opaque copies in quantity, to ensure that this Transparent copy will
remain thus accessible at the stated location until at least one year after the last time
you distribute an Opaque copy (directly or through your agents or retailers) of that
edition to the public.
It is requested, but not required, that you contact the authors of the Document well
before redistributing any large number of copies, to give them a chance to provide you
with an updated version of the Document.
4. MODIFICATIONS
146 GNU M4 1.4.19 macro processor
You may copy and distribute a Modified Version of the Document under the conditions
of sections 2 and 3 above, provided that you release the Modified Version under precisely
this License, with the Modified Version filling the role of the Document, thus licensing
distribution and modification of the Modified Version to whoever possesses a copy of
it. In addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct from that of the
Document, and from those of previous versions (which should, if there were any,
be listed in the History section of the Document). You may use the same title as
a previous version if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities responsible for
authorship of the modifications in the Modified Version, together with at least five
of the principal authors of the Document (all of its principal authors, if it has fewer
than five), unless they release you from this requirement.
C. State on the Title page the name of the publisher of the Modified Version, as the
publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications adjacent to the other
copyright notices.
F. Include, immediately after the copyright notices, a license notice giving the public
permission to use the Modified Version under the terms of this License, in the form
shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections and required Cover
Texts given in the Document’s license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled “History”, Preserve its Title, and add to it an item
stating at least the title, year, new authors, and publisher of the Modified Version
as given on the Title Page. If there is no section Entitled “History” in the Docu-
ment, create one stating the title, year, authors, and publisher of the Document
as given on its Title Page, then add an item describing the Modified Version as
stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for public access to
a Transparent copy of the Document, and likewise the network locations given in
the Document for previous versions it was based on. These may be placed in the
“History” section. You may omit a network location for a work that was published
at least four years before the Document itself, or if the original publisher of the
version it refers to gives permission.
K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title
of the section, and preserve in the section all the substance and tone of each of the
contributor acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered in their text and
in their titles. Section numbers or the equivalent are not considered part of the
section titles.
M. Delete any section Entitled “Endorsements”. Such a section may not be included
in the Modified Version.
Appendix B: How to make copies of this manual 147
follow the rules of this License for verbatim copying of each of the documents in all
other respects.
You may extract a single document from such a collection, and distribute it individu-
ally under this License, provided you insert a copy of this License into the extracted
document, and follow this License in all other respects regarding verbatim copying of
that document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate and independent
documents or works, in or on a volume of a storage or distribution medium, is called
an “aggregate” if the copyright resulting from the compilation is not used to limit the
legal rights of the compilation’s users beyond what the individual works permit. When
the Document is included in an aggregate, this License does not apply to the other
works in the aggregate which are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document,
then if the Document is less than one half of the entire aggregate, the Document’s Cover
Texts may be placed on covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form. Otherwise they
must appear on printed covers that bracket the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may distribute translations
of the Document under the terms of section 4. Replacing Invariant Sections with
translations requires special permission from their copyright holders, but you may
include translations of some or all Invariant Sections in addition to the original versions
of these Invariant Sections. You may include a translation of this License, and all the
license notices in the Document, and any Warranty Disclaimers, provided that you
also include the original English version of this License and the original versions of
those notices and disclaimers. In case of a disagreement between the translation and
the original version of this License or a notice or disclaimer, the original version will
prevail.
If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “His-
tory”, the requirement (section 4) to Preserve its Title (section 1) will typically require
changing the actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly
provided under this License. Any attempt otherwise to copy, modify, sublicense, or
distribute it is void, and will automatically terminate your rights under this License.
However, if you cease all violation of this License, then your license from a particular
copyright holder is reinstated (a) provisionally, unless and until the copyright holder
explicitly and finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means prior to 60 days
after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently if
the copyright holder notifies you of the violation by some reasonable means, this is the
first time you have received notice of violation of this License (for any work) from that
Appendix B: How to make copies of this manual 149
copyright holder, and you cure the violation prior to 30 days after your receipt of the
notice.
Termination of your rights under this section does not terminate the licenses of parties
who have received copies or rights from you under this License. If your rights have
been terminated and not permanently reinstated, receipt of a copy of some or all of the
same material does not give you any rights to use it.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of the GNU Free
Documentation License from time to time. Such new versions will be similar in spirit
to the present version, but may differ in detail to address new problems or concerns.
See https://www.gnu.org/licenses/.
Each version of the License is given a distinguishing version number. If the Document
specifies that a particular numbered version of this License “or any later version”
applies to it, you have the option of following the terms and conditions either of that
specified version or of any later version that has been published (not as a draft) by
the Free Software Foundation. If the Document does not specify a version number of
this License, you may choose any version ever published (not as a draft) by the Free
Software Foundation. If the Document specifies that a proxy can decide which future
versions of this License can be used, that proxy’s public statement of acceptance of a
version permanently authorizes you to choose that version for the Document.
11. RELICENSING
“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide
Web server that publishes copyrightable works and also provides prominent facilities
for anybody to edit those works. A public wiki that anybody can edit is an example of
such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the
site means any set of copyrightable works thus published on the MMC site.
“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license pub-
lished by Creative Commons Corporation, a not-for-profit corporation with a principal
place of business in San Francisco, California, as well as future copyleft versions of that
license published by that same organization.
“Incorporate” means to publish or republish a Document, in whole or in part, as part
of another Document.
An MMC is “eligible for relicensing” if it is licensed under this License, and if all works
that were first published under this License somewhere other than this MMC, and
subsequently incorporated in whole or in part into the MMC, (1) had no cover texts
or invariant sections, and (2) were thus incorporated prior to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the site under
CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is
eligible for relicensing.
150 GNU M4 1.4.19 macro processor
E
__file__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 errprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
__gnu__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 esyscmd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
__line__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 eval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
__os2__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
__program__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 exch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
__unix__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
__windows__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
F
fatal_error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
A foreach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
argn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 foreachq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 forloop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
array_set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
I
B ifdef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
builtin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 ifelse. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
include . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
incr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
C index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
capitalize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 indir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
changecom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
changequote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
changeword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
J
cleardivert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
cond . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 joinall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
curry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
L
len . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
D
debugfile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 M
debugmode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
decr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 m4exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
define. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 m4wrap. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
define_blind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 maketemp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
defn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 mkstemp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
divert. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
divnum. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
dnl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 N
downcase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 nargs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
dquote. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
dquote_elt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
dumpdef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 O
os2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
152 GNU M4 1.4.19 macro processor
P sysval. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
patsubst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
popdef. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
pushdef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
T
traceoff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
traceon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Q translit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
quote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
U
R undefine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
undivert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
regexp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
rename. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
upcase. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
reverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
S W
shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
sinclude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
stack_foreach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
stack_foreach_lifo . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
stack_foreach_sep . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
stack_foreach_sep_lifo . . . . . . . . . . . . . . . . . . . . . 124
substr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
syscmd. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
A C
argument currying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 call of builtins, indirect . . . . . . . . . . . . . . . . . . . . . . . . 35
arguments to macros . . . . . . . . . . . . . . . . . . . . . . . 21, 26 call of macros, indirect . . . . . . . . . . . . . . . . . . . . . . . . . 34
arguments to macros, special . . . . . . . . . . . . . . . . . . . 27 case statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
arguments, joining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 changing comment delimiters . . . . . . . . . . . . . . . . . . . 65
arguments, more than nine . . . . . . . . . . . . 27, 45, 120 changing quote delimiters . . . . . . . . . . . . . . . . . . . . . . 62
changing syntax. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
arguments, quoted macro . . . . . . . . . . . . . . . . . . . . . . 23
characters, translating . . . . . . . . . . . . . . . . . . . . . . . . . 83
arguments, reversing . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
command line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
command line, file names on the. . . . . . . . . . . . . . . . 12
arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 command line, macro definitions on the. . . . . . . . . . 8
avoiding quadratic behavior . . . . . . . . . . . . . . . . . . . 118 command line, options . . . . . . . . . . . . . . . . . . . . . . . . . . 7
commands, exit status from shell . . . . . . . . . . . . . . . 97
commands, running shell . . . . . . . . . . . . . . . . . . . . . . . 95
comment delimiters, changing . . . . . . . . . . . . . . . . . . 65
B comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
basic regular expressions. . . . . . . . . . . . . . . . . . . . 81, 84 comments, copied to output . . . . . . . . . . . . . . . . . . . . 66
blind macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19, 40, 51 comparing strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
bug reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
builtins, indirect call of . . . . . . . . . . . . . . . . . . . . . . . . 35 composing macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
concatenating arguments . . . . . . . . . . . . . . . . . . . . . . . 42
builtins, special tokens . . . . . . . . . . . . . . . . . . . . . . . . . 32
conditional, short-circuiting . . . . . . . . . . . . . . . . . . . . 41
conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
controlling debugging output . . . . . . . . . . . . . . . . . . . 58
copying macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
counting loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
currying arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Appendix C: Indices of concepts and macros 153
D G
debugging macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 General Public License (GPL), GNU . . . . . . . . . . 131
debugging output, controlling . . . . . . . . . . . . . . . . . . 58 GNU extensions . . 19, 25, 27, 34, 35, 59, 60, 74, 76,
debugging output, saving. . . . . . . . . . . . . . . . . . . . . . . 60 78, 81, 84, 86, 91, 97, 100, 105, 109
decrement operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 GNU Free Documentation License . . . . . . . . . . . . 143
deferring expansion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 GNU General Public License . . . . . . . . . . . . . . . . . . 131
deferring output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 GNU M4, history of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
defining new macros . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 GPL, GNU General Public License . . . . . . . . . . . . 131
definition stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33, 49
definitions, displaying macro . . . . . . . . . . . . . . . . 31, 55
deleting macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
deleting whitespace in input . . . . . . . . . . . . . . . . . . . . 61 H
delimiters, changing . . . . . . . . . . . . . . . . . . . . . . . . 62, 65 history of m4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
discarding diverted text . . . . . . . . . . . . . . . . . . . . . . . . 79
discarding input . . . . . . . . . . . . . . . . . . . . . . . . 39, 61, 76
displaying macro definitions . . . . . . . . . . . . . . . . . . . . 55
diversion numbers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 I
diverted text, discarding . . . . . . . . . . . . . . . . . . . . . . . 79 included files, search path for . . . . . . . . . . . . . . . . . . 74
diverting output to files . . . . . . . . . . . . . . . . . . . . . . . . 75 inclusion, of files . . . . . . . . . . . . . . . . . . . . . . . . 73, 76, 78
dumping into frozen file . . . . . . . . . . . . . . . . . . . . . . . 105 increment operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
indirect call of builtins . . . . . . . . . . . . . . . . . . . . . . . . . 35
indirect call of macros. . . . . . . . . . . . . . . . . . . . . . . . . . 34
E initialization, frozen state . . . . . . . . . . . . . . . . . . . . . 105
error messages, printing . . . . . . . . . . . . . . . . . . . . . . . 101 input location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9, 101
errors, fatal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 input tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
evaluation, of integer expressions . . . . . . . . . . . . . . . 89 input, discarding. . . . . . . . . . . . . . . . . . . . . . . . 39, 61, 76
examples, understanding . . . . . . . . . . . . . . . . . . . . . . . . 5 input, saving . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
executing shell commands . . . . . . . . . . . . . . . . . . . . . . 95 integer arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
exit status from shell commands . . . . . . . . . . . . . . . 97 integer expression evaluation . . . . . . . . . . . . . . . . . . . 89
exiting from m4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 invoking m4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
expansion of macros . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 invoking macros. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
expansion, deferring . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 iterating over lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
expansion, tracing macro . . . . . . . . . . . . . . . . . . . . . . . 55
expressions, evaluation of integer . . . . . . . . . . . . . . . 89
expressions, regular. . . . . . . . . . . . . . . . . . . . . . . . . 81, 84 J
extracting substrings . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
joining arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
F
fast loading of frozen files . . . . . . . . . . . . . . . . . . . . . 105 L
fatal errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 length of strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
FDL, GNU Free Documentation License . . . . . . 143 lexical structure of words. . . . . . . . . . . . . . . . . . . . . . . 68
file format, frozen file . . . . . . . . . . . . . . . . . . . . . . . . . 106 License, code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
file inclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73, 76, 78 License, manual. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
file names, on the command line. . . . . . . . . . . . . . . . 12 limit, nesting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
files, diverting output to . . . . . . . . . . . . . . . . . . . . . . . 75 literal output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
files, names of temporary. . . . . . . . . . . . . . . . . . . . . . . 99 local variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
for each loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 location, input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9, 101
for loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
formatted output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 loops, counting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Free Documentation License (FDL), GNU . . . . . 143 loops, list iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
frozen file format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
frozen files for fast loading . . . . . . . . . . . . . . . . . . . . 105
154 GNU M4 1.4.19 macro processor
M Q
M4PATH. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 quadratic behavior, avoiding . . . . . . . . . . . . . . . . . . 118
macro composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 quote delimiters, changing. . . . . . . . . . . . . . . . . . . . . . 62
macro definitions, on the command line. . . . . . . . . . 8 quote manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
macro expansion, tracing . . . . . . . . . . . . . . . . . . . . . . . 55 quoted macro arguments . . . . . . . . . . . . . . . . . . . . . . . 23
macro invocation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 quoted string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
macro, blind . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19, 40, 51 quoting rule of thumb . . . . . . . . . . . . . . . . . . . . . . . . . . 23
macros, arguments to. . . . . . . . . . . . . . . . . . . . . . . 21, 26
macros, copying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
macros, debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 R
macros, displaying definitions . . . . . . . . . . . . . . . 31, 55 recursive macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
macros, expansion of . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 redefinition of macros, temporary . . . . . . . . . . . . . . 33
macros, how to define new . . . . . . . . . . . . . . . . . . . . . 25 regular expressions. . . . . . . . . . . . . . . . . . . . . . 68, 81, 84
macros, how to delete . . . . . . . . . . . . . . . . . . . . . . . . . . 30 reloading a frozen file . . . . . . . . . . . . . . . . . . . . . . . . . 105
macros, how to rename. . . . . . . . . . . . . . . . . . . . . . . . . 31 renaming macros . . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 53
macros, indirect call of . . . . . . . . . . . . . . . . . . . . . . . . . 34 reporting bugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
macros, quoted arguments to . . . . . . . . . . . . . . . . . . . 23 rescanning . . . . . . . . . . . . . . . . . . . . . 11, 20, 29, 31, 113
macros, recursive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 reversing arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
macros, special arguments to . . . . . . . . . . . . . . . . . . . 27 rule of thumb, quoting . . . . . . . . . . . . . . . . . . . . . . . . . 23
macros, temporary redefinition of . . . . . . . . . . . . . . 33 running shell commands . . . . . . . . . . . . . . . . . . . . . . . 95
manipulating quotes . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
messages, printing error . . . . . . . . . . . . . . . . . . . . . . . 101
more than nine arguments . . . . . . . . . . . . . 27, 45, 120 S
multibranches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 saving debugging output . . . . . . . . . . . . . . . . . . . . . . . 60
saving input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
search path for included files . . . . . . . . . . . . . . . . . . . 74
N shell commands, exit status from . . . . . . . . . . . . . . . 97
names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 shell commands, running . . . . . . . . . . . . . . . . . . . . . . . 95
short-circuiting conditional . . . . . . . . . . . . . . . . . . . . . 41
nesting limit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
special arguments to macros . . . . . . . . . . . . . . . . . . . 27
nine arguments, more than . . . . . . . . . . . . 27, 45, 120
stack, macro definition . . . . . . . . . . . . . . . . . . . . . 33, 49
numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
standard error, output to . . . . . . . . . . . . . . . . . . 55, 101
status of shell commands . . . . . . . . . . . . . . . . . . . . . . . 97
status, setting m4 exit . . . . . . . . . . . . . . . . . . . . . . . . . 103
O string, quoted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
options, command line . . . . . . . . . . . . . . . . . . . . . . . . . . 7 strings, length of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
output, diverting to files . . . . . . . . . . . . . . . . . . . . . . . 75 substitution by regular expression . . . . . . . . . . . . . . 84
output, formatted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 substrings, extracting . . . . . . . . . . . . . . . . . . . . . . . . . . 82
output, literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 substrings, locating . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
output, saving debugging. . . . . . . . . . . . . . . . . . . . . . . 60 suggestions, reporting . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
overview of m4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 suppressing warnings . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
switch statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
synchronization lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
syntax, changing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
P
pattern substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
platform macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 T
positional parameters, more than nine . . . . . . . . . . 27 temporary file names . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
POSIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 temporary redefinition of macros . . . . . . . . . . . . . . . 33
POSIXLY_CORRECT. . . . . . . . . . . . . . . . . . . . . . . . . . . 7, 112 TMPDIR. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
preprocessor features . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
printing error messages . . . . . . . . . . . . . . . . . . . . . . . 101 tokens, builtin macro. . . . . . . . . . . . . . . . . . . . . . . . . . . 32
pushdef stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33, 49 tokens, special . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
tracing macro expansion . . . . . . . . . . . . . . . . . . . . . . . 55
translating characters . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Appendix C: Indices of concepts and macros 155
U V
variables, local . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
undefining macros. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 W
UNIX commands, exit status from . . . . . . . . . . . . . 97 warnings, suppressing . . . . . . . . . . . . . . . . . . . . . . . . . . 22
words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
UNIX commands, running . . . . . . . . . . . . . . . . . . . . . 95 words, lexical structure of . . . . . . . . . . . . . . . . . . . . . . 68