[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
m4sugar doc example [Was: enforcing the use of string.h related modules]
From: |
Eric Blake |
Subject: |
m4sugar doc example [Was: enforcing the use of string.h related modules] |
Date: |
Fri, 02 Feb 2007 13:28:32 -0700 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.9) Gecko/20061207 Thunderbird/1.5.0.9 Mnenhy/0.7.4.666 |
-----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 address@hidden
-----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-----
- m4sugar doc example [Was: enforcing the use of string.h related modules],
Eric Blake <=