-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I'm forwarding this mail to the autoconf list to remind me to take time in the near future to turn it into a good texinfo flow. According to Bruno Haible on 2/2/2007 8:52 AM: > Hello Eric, > > Thanks for writing some doc about this. Indeed this area is well understood > only by very few people. The current documentation on this topic is too > much hand-waving: > > It is, however, in certain cases necessary or convenient to leave out > ^^^^^^^^^^^^^^^^ > quotes for some arguments, and there is nothing wrong in doing it. It > just makes life a bit harder, if you are not careful. For consistency, > ^^^^^^^^^^^^^^^^^^^^^^ > this manual follows the rule of thumb that each layer of parentheses > ^^^^^^^^^^^^^ > introduces another layer of single quoting, except when showing the > consequences of quoting rules. > > Yes, I think this example can teach the people. You can simplify the two > pieces of code a bit: > > changequote([,]) > define([gl_STRING_MODULE_INDICATOR], > [ > dnl comment > GNULIB_]translit([$1],[a-z./-],[A-Z___])[=1 > ]) > gl_STRING_MODULE_INDICATOR([strcase]) > > and > > changequote([,]) > define([gl_STRING_MODULE_INDICATOR], > [ > dnl comment > GNULIB_[]translit([$1],[a-z./-],[A-Z___])=1 > ]) > gl_STRING_MODULE_INDICATOR([strcase]) > > (No need to mention AC_DEFUN or AC_REQUIRE here.) > >> Here's the macro in question, with your version vs. my version (simplified >> a bit to shorten this email), followed by a use of it: >> >> AC_DEFUN([gl_STRING_MODULE_INDICATOR], >> [ >> dnl comment >> AC_REQUIRE([gl_STRING_MODULE_INDICATOR_DEFAULTS]) >> - GNULIB_]translit([$1],[a-z./-],[A-Z___])[=1 >> + GNULIB_[]m4_translit([$1],[a-z./-],[A-Z___])=1 >> ]) >> gl_STRING_MODULE_INDICATOR([strcase]) >> >> With your version, m4 parses (whitespace added for clarity): >> >> AC_DEFUN ( [gl_STRING_MODULE_INDICATOR] , [long string...] translit >> >> at which point it sees a macro name, so it starts a nested parse, >> >> translit ( [$1] , [a-z./-] , [A-Z___] ) >> >> so now it has collected arguments to the nested macro, and performs quote >> removal, so that it executes: >> >> translit($1,a-z./-,A-Z___) => $1 >> >> since neither $ nor 1 appear in the range a-z./-, they are both copied to >> the output of translit. Now, that result is substituted back into the >> outer parse: >> >> $1 [=1] ) >> >> now it has collected arguments to the outer macro, and performs quote >> removal, so that it executes AC_DEFUN and results in defining >> gl_STRING_MODULE_INDICATOR to be: >> >> dnl comment >> AC_REQUIRE([gl_STRING_MODULE_INDICATOR_DEFAULTS]) >> GNULIB_$1=1 >> >> Next, it parses the use of this new macro: >> >> gl_STRING_MODULE_INDICATOR ( [strcase] ) >> >> and performs parameter substitution up front, resulting in: >> >> dnl comment >> AC_REQUIRE([gl_STRING_MODULE_INDICATOR_DEFAULTS]) >> GNULIB_strcase=1 >> >> Then it performs a rescan of the expansion. The dnl comment is discarded, >> the AC_REQUIRE works its magic, and since GNULIB_strcase is not the name >> of a recognized macro, it is copied literally to the output, for the >> overall output of: >> >> GNULIB_strcase=1 >> >> >> On the other hand, my version does: >> >> AC_DEFUN ( [gl_STRING_MODULE_INDICATOR] , [longer string...] ) >> >> and results in defining gl_STRING_MODULE_INDICATOR to be: >> >> dnl comment >> AC_REQUIRE([gl_STRING_MODULE_INDICATOR_DEFAULTS]) >> GNULIB_[]m4_translit([$1],[a-z./-],[A-Z___])=1 >> >> Next, it parses the use of this new macro: >> >> gl_STRING_MODULE_INDICATOR ( [strcase] ) >> >> and performs parameter substitution up front, resulting in: >> >> dnl comment >> AC_REQUIRE([gl_STRING_MODULE_INDICATOR_DEFAULTS]) >> GNULIB_[]m4_translit([strcase],[a-z./-],[A-Z___])=1 >> >> On the rescan, the dnl macro is recognized and the commend discarded, the >> AC_REQUIRE macro does its magic, then m4 sees the following tokens: >> >> GNULIB_ [] m4_translit >> >> GNULIB_ is not a macro name, so it is output literally, and the empty >> string does not affect output, but m4_translit is a macro, so we start yet >> another macro collection phase (but this time it is not nested, since we >> already expanded gl_STRING_MODULE_INDICATOR): >> >> m4_translit ( [strcase] , [a-z./-] , [A-Z___] ) >> >> The result of the translit is STRCASE, and we resume scanning the final >> three tokens, since STRCASE is not a macro name: >> >> STRCASE = 1 >> >> resulting in the overall output line: >> >> GNULIB_STRCASE=1 > > Exactly. One needs to read/understand such a step-by-step analysis once > in one's life, if one wants to understand the macros. It is instructive! > > Bruno > - -- Don't work too hard, make some time for fun as well! Eric Blake ebb9@xxxxxxx -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFFw57w84KuGfSFAYARAn5YAJ9v7s88CsvdPXbhefj4+xZTjgjc3ACdHbya DXHDzcH+pJ1nmCTkQWnIEVs= =7uaK -----END PGP SIGNATURE----- _______________________________________________ Autoconf mailing list Autoconf@xxxxxxx http://lists.gnu.org/mailman/listinfo/autoconf