autoconf: Quotation and Nested Macros

1 
1 8.1.4 Quotation and Nested Macros
1 ---------------------------------
1 
1 The examples below use the following macros:
1 
1      define([car], [$1])
1      define([active], [ACT, IVE])
1      define([array], [int tab[10]])
1 
1    Each additional embedded macro call introduces other possible
1 interesting quotations:
1 
1      car(active)
1      =>ACT
1      car([active])
1      =>ACT, IVE
1      car([[active]])
1      =>active
1 
1    In the first case, the top level looks for the arguments of `car',
1 and finds `active'.  Because M4 evaluates its arguments before applying
1 the macro, `active' is expanded, which results in:
1 
1      car(ACT, IVE)
1      =>ACT
1 
1 In the second case, the top level gives `active' as first and only
1 argument of `car', which results in:
1 
1      active
1      =>ACT, IVE
1 
1 i.e., the argument is evaluated _after_ the macro that invokes it.  In
1 the third case, `car' receives `[active]', which results in:
1 
1      [active]
1      =>active
1 
1 exactly as we already saw above.
1 
1    The example above, applied to a more realistic example, gives:
1 
1      car(int tab[10];)
1      =>int tab10;
1      car([int tab[10];])
1      =>int tab10;
1      car([[int tab[10];]])
1      =>int tab[10];
1 
1 Huh?  The first case is easily understood, but why is the second wrong,
1 and the third right?  To understand that, you must know that after M4
1 expands a macro, the resulting text is immediately subjected to macro
1 expansion and quote removal.  This means that the quote removal occurs
1 twice--first before the argument is passed to the `car' macro, and
1 second after the `car' macro expands to the first argument.
1 
1    As the author of the Autoconf macro `car', you then consider it to
1 be incorrect that your users have to double-quote the arguments of
1 `car', so you "fix" your macro.  Let's call it `qar' for quoted car:
1 
1      define([qar], [[$1]])
1 
1 and check that `qar' is properly fixed:
1 
1      qar([int tab[10];])
1      =>int tab[10];
1 
1 Ahhh!  That's much better.
1 
1    But note what you've done: now that the result of `qar' is always a
1 literal string, the only time a user can use nested macros is if she
1 relies on an _unquoted_ macro call:
1 
1      qar(active)
1      =>ACT
1      qar([active])
1      =>active
1 
1 leaving no way for her to reproduce what she used to do with `car':
1 
1      car([active])
1      =>ACT, IVE
1 
1 Worse yet: she wants to use a macro that produces a set of `cpp' macros:
1 
1      define([my_includes], [#include <stdio.h>])
1      car([my_includes])
1      =>#include <stdio.h>
1      qar(my_includes)
1      error-->EOF in argument list
1 
1    This macro, `qar', because it double quotes its arguments, forces
1 its users to leave their macro calls unquoted, which is dangerous.
1 Commas and other active symbols are interpreted by M4 before they are
1 given to the macro, often not in the way the users expect.  Also,
1 because `qar' behaves differently from the other macros, it's an
1 exception that should be avoided in Autoconf.
1