m4: Inhibiting Invocation

1 
1 4.2 Preventing macro invocation
1 ===============================
1 
1 An innovation of the 'm4' language, compared to some of its predecessors
1 (like Strachey's 'GPM', for example), is the ability to recognize macro
1 calls without resorting to any special, prefixed invocation character.
1 While generally useful, this feature might sometimes be the source of
1 spurious, unwanted macro calls.  So, GNU 'm4' offers several mechanisms
1 or techniques for inhibiting the recognition of names as macro calls.
1 
1    First of all, many builtin macros cannot meaningfully be called
1 without arguments.  As a GNU extension, for any of these macros,
1 whenever an opening parenthesis does not immediately follow their name,
1 the builtin macro call is not triggered.  This solves the most usual
1 cases, like for 'include' or 'eval'.  Later in this document, the
1 sentence "This macro is recognized only with parameters" refers to this
1 specific provision of GNU M4, also known as a blind builtin macro.  For
1 the builtins defined by POSIX that bear this disclaimer, POSIX
1 specifically states that invoking those builtins without arguments is
1 unspecified, because many other implementations simply invoke the
1 builtin as though it were given one empty argument instead.
1 
1      $ m4
1      eval
1      =>eval
1      eval(`1')
1      =>1
1 
1    There is also a command line option ('--prefix-builtins', or '-P',
1 ⇒Invoking m4 Operation modes.) that renames all builtin macros
1 with a prefix of 'm4_' at startup.  The option has no effect whatsoever
1 on user defined macros.  For example, with this option, one has to write
1 'm4_dnl' and even 'm4_m4exit'.  It also has no effect on whether a macro
1 requires parameters.
1 
1      $ m4 -P
1      eval
1      =>eval
1      eval(`1')
1      =>eval(1)
1      m4_eval
1      =>m4_eval
1      m4_eval(`1')
1      =>1
1 
1    Another alternative is to redefine problematic macros to a name less
1 likely to cause conflicts, using ⇒Definitions.
1 
1    If your version of GNU 'm4' has the 'changeword' feature compiled in,
1 it offers far more flexibility in specifying the syntax of macro names,
1 both builtin or user-defined.  ⇒Changeword, for more information
1 on this experimental feature.
1 
1    Of course, the simplest way to prevent a name from being interpreted
1 as a call to an existing macro is to quote it.  The remainder of this
1 section studies a little more deeply how quoting affects macro
1 invocation, and how quoting can be used to inhibit macro invocation.
1 
1    Even if quoting is usually done over the whole macro name, it can
1 also be done over only a few characters of this name (provided, of
1 course, that the unquoted portions are not also a macro).  It is also
1 possible to quote the empty string, but this works only _inside_ the
1 name.  For example:
1 
1      `divert'
1      =>divert
1      `d'ivert
1      =>divert
1      di`ver't
1      =>divert
1      div`'ert
1      =>divert
1 
1 all yield the string 'divert'.  While in both:
1 
1      `'divert
1      =>
1      divert`'
1      =>
1 
1 the 'divert' builtin macro will be called, which expands to the empty
1 string.
1 
1    The output of macro evaluations is always rescanned.  In the
1 following example, the input 'x`'y' yields the string 'bCD', exactly as
1 if 'm4' has been given 'substr(ab`'cde, `1', `3')' as input:
1 
1      define(`cde', `CDE')
1      =>
1      define(`x', `substr(ab')
1      =>
1      define(`y', `cde, `1', `3')')
1      =>
1      x`'y
1      =>bCD
1 
1    Unquoted strings on either side of a quoted string are subject to
1 being recognized as macro names.  In the following example, quoting the
1 empty string allows for the second 'macro' to be recognized as such:
1 
1      define(`macro', `m')
1      =>
1      macro(`m')macro
1      =>mmacro
1      macro(`m')`'macro
1      =>mm
1 
1    Quoting may prevent recognizing as a macro name the concatenation of
1 a macro expansion with the surrounding characters.  In this example:
1 
1      define(`macro', `di$1')
1      =>
1      macro(`v')`ert'
1      =>divert
1      macro(`v')ert
1      =>
1 
1 the input will produce the string 'divert'.  When the quotes were
1 removed, the 'divert' builtin was called instead.
1