autoconf
[Top][All Lists]
Advanced

[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-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]