Programming in M4sugar

M4 by itself provides only a small, but sufficient, set of all-purpose macros. M4sugar introduces additional generic macros. Its name was coined by Lars J. Aas: "Readability And Greater Understanding Stands 4 M4sugar".

Redefined M4 Macros

With a few exceptions, all the M4 native macros are moved in the m4_ pseudo-namespace, e.g., M4sugar renames define as m4_define etc.

Some M4 macros are redefined, and are slightly incompatible with their native equivalent.

function>dnl/function> This macro kept its original name: no m4_dnl is defined.

function>m4_defn/function> (macro) Contrary to the M4 builtin, this macro fails if macro is not defined. See m4_undefine.

function>m4_exit/function> (exit-status) This macro corresponds to m4exit.

function>m4_if/function> (comment) function>m4_if/function> (string-1, string-2, equal, [not-equal]) function>m4_if/function> (string-1, string-2, equal, ...) This macro corresponds to ifelse.

function>m4_undefine/function> (macro) Contrary to the M4 builtin, this macro fails if macro is not defined. Use

m4_ifdef([macro], [m4_undefine([macro])])

to recover the behavior of the builtin.

function>m4_bpatsubst/function> (string, regexp, [replacement]) This macro corresponds to patsubst. The name m4_patsubst is kept for future versions of M4sh, on top of gnu M4 which will provide extended regular expression syntax via epatsubst.

function>m4_popdef/function> (macro) Contrary to the M4 builtin, this macro fails if macro is not defined. See m4_undefine.

function>m4_bregexp/function> (string, regexp, [replacement]) This macro corresponds to regexp. The name m4_regexp is kept for future versions of M4sh, on top of gnu M4 which will provide extended regular expression syntax via eregexp.

function>m4_wrap/function> (text) This macro corresponds to m4wrap.

You are encouraged to end text with [], so that there are no risks that two consecutive invocations of m4_wrap result in an unexpected pasting of tokens, as in

m4_define([foo], [Foo])
m4_define([bar], [Bar])
m4_define([foobar], [FOOBAR])
m4_wrap([bar])
m4_wrap([foo])
=>FOOBAR

Evaluation Macros

The following macros give some control over the order of the evaluation by adding or removing levels of quotes. They are meant for hard core M4 programmers.

function>m4_dquote/function> (arg1, ...) Return the arguments as a quoted list of quoted arguments.

function>m4_quote/function> (arg1, ...) Return the arguments as a single entity, i.e., wrap them into a pair of quotes.

The following example aims at emphasizing the difference between (i), not using these macros, (ii), using m4_quote, and (iii), using m4_dquote.

$ cat example.m4
# Over quote, so that quotes are visible.
m4_define([show], [$[]1 = [$1], $[]@ = [$@]])
m4_divert(0)dnl
show(a, b)
show(m4_quote(a, b))
show(m4_dquote(a, b))
$ autom4te -l m4sugar example.m4
$1 = a, $@ = [a],[b]
$1 = a,b, $@ = [a,b]
$1 = [a],[b], $@ = [[a],[b]]

Forbidden Patterns

M4sugar provides a means to define suspicious patterns, patterns describing tokens which should not be found in the output. For instance, if an Autoconf configure script includes tokens such as AC_DEFINE, or dnl, then most probably something went wrong (typically a macro was not evaluated because of over quotation).

M4sugar forbids all the tokens matching ^m4_ and ^dnl$.

function>m4_pattern_forbid/function> (pattern) Declare no token matching pattern must be found in the output. Comments are not checked; this can be a problem if, for instance, you have some macro left unexpanded after an #include. No consensus is currently found in the Autoconf community, as some people consider it should be valid to name macros in comments (which doesn't makes sense to the author of this documentation, as #-comments should document the output, not the input, documented vy dnl-comments).

Of course, you might encounter exceptions to these generic rules, for instance you might have to refer to $m4_flags.

function>m4_pattern_allow/function> (pattern) Any token matching pattern is allowed, including if it matches an m4_pattern_forbid pattern.