m4
This chapter describes the differences between this implementation of
m4
, and the implementation found under UNIX, notably System V,
Release 3.
There are also differences in BSD flavors of m4
. No attempt
is made to summarize these here.
m4
This version of m4
contains a few facilities, that do not exist
in System V m4
. These extra facilities are all suppressed by
using the `-G' command line option, unless overridden by other
command line options.
$
n notation for macro arguments, n can contain
several digits, while the System V m4
only accepts one digit.
This allows macros in GNU m4
to take any number of arguments, and
not only nine (see section Arguments to macros).
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 Searching for include files).
undivert
can be non-numeric, in which case the named
file will be included uninterpreted in the output (see section Undiverting output).
format
builtin, which
is modeled after the C library function printf
(see section Formatted output).
regexp
(see section Searching for regular expressions) and patsubst
(see section Substituting text by regular expression) builtins.
m4
with
esyscmd
(see section Reading the output of commands).
builtin
(see section Indirect call of builtins).
indir
(see section Indirect call of macros).
__file__
and __line__
(see section Printing error messages).
dumpdef
and macro tracing can be
controlled with debugmode
(see section Controlling debugging output).
debugfile
(see section Saving debugging output).
In addition to the above extensions, GNU m4
implements the
following command line options: `-F', `-G', `-I',
`-L', `-R', `-V', `-W', `-d',
`-l', `-o' and `-t'. See section Invoking m4
, for a
description of these options.
Also, the debugging and tracing facilities in GNU m4
are much
more extensive than in most other versions of m4
.
m4
not in GNU m4
The version of m4
from System V contains a few facilities that
have not been implemented in GNU m4
yet.
m4
supports multiple arguments to defn
. This is
not implemented in GNU m4
. Its usefulness is unclear to me.
There are a few other incompatibilities between this implementation of
m4
, and the System V version.
m4
implements sync lines differently from System V m4
,
when text is being diverted. GNU m4
outputs the sync lines when
the text is being diverted, and System V m4
when the diverted
text is being brought back.
The problem is which lines and filenames should be attached to text that
is being, or has been, diverted. System V m4
regards all the
diverted text as being generated by the source line containing the
undivert
call, whereas GNU m4
regards the diverted text as
being generated at the time it is diverted.
I expect the sync line option to be used mostly when using m4
as
a front end to a compiler. If a diverted line causes a compiler error,
the error messages should most probably refer to the place where the
diversion were made, and not where it was inserted again.
m4
makes no attempt at prohiting autoreferential definitions
like:
define(`x', `x') define(`x', `x ')There is nothing inherently wrong with defining `x' to return `x'. The wrong thing is to expand `x' unquoted. In
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 leave 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.
m4
without `-G' option will define the macro
__gnu__
to expand to the empty string.
On UNIX systems, GNU m4
without the `-G' option will define
the macro __unix__
, otherwise the macro unix
. Both will
expand to the empty string.