[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: fewer forks in AC_DEFINE [was: Use newer m4_map_args_{w,sep}]
From: |
Eric Blake |
Subject: |
Re: fewer forks in AC_DEFINE [was: Use newer m4_map_args_{w,sep}] |
Date: |
Thu, 20 Nov 2008 06:39:56 -0700 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.18) Gecko/20081105 Thunderbird/2.0.0.18 Mnenhy/0.7.5.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
According to Ralf Wildenhues on 11/19/2008 11:01 PM:
> Please use appropriate language quoting. Unlike your code, your readers
> cannot deal well with underquoted parentheses. IOW, please make the
> above sentence either
> * lib/m4sugar/m4sugar.m4 (_m4_expand): Tolerate unquoted
> unbalanced `)'.
Yes, that looks nicer. I'll rebase the patch accordingly before pushing.
>> +creative shell comments to supply the balance. Note that you should use
>> +the quadrigraph @samp{@@%:@@} and not a literal @samp{#}, because the
>> +latter hides the @samp{(} inside an m4 comment, and you would still be
>> +presenting m4 with unbalanced parentheses.
>
> But not the human reader of the macro text! IIUC then as the code
> is capable, we *can* use `in #(', which is much more readable than
> `in @:@('. I've never knowingly added the extra opening parenthesis
> in order to help M4, only ever in order to help paren matching
> algorithms in $EDITORs.
Hmm. Yet it was your message in
http://lists.gnu.org/archive/html/autoconf-patches/2006-05/msg00168.html
that caused Paul to have to do just that in commit e07dd (note that he had
to replace 'case "$ac_try" in #((' with 'case "(($ac_try" in').
Just because m4_expand can handle #( doesn't mean that other macros can;
you still have a bug if you do:
dnl plus: pasteable, balanced in editor, human-readable
dnl minus: broken as m4 argument
m4_define([do_case], [case bar in #(
*) ;;
esac])
AC_CHECK_FUNCS(foo,,do_case)
But not if you do:
dnl plus: expansion works as m4 argument, balanced in editor
dnl minus: not human-readable, not pasteable
m4_define([do_case], [case bar in @%:@(
*) ;;
esac])
dnl plus: expansion works as m4 argument, human-readable
dnl minus: not balanced in editor, not pasteable
m4_define([do_case], [case bar in
*[)] ;;
esac])
dnl plus: expansion works as m4 argument, human-readable, pasteable
dnl minus: not balanced in editor, no embedded macros allowed
m4_define([do_case], [[case bar in
*) ;;
esac]])
So, I will reword this paragraph to mention all of the possibilities, each
with their strengths and drawbacks.
>> In addition to the previously discussed idea of making m4_expand supply and
>> chomp a trailing newline, in order to handle what would otherwise be an
>> unterminated comment, I managed to figure out a way to handle underquoted
>> shell
>> case statements. Kudos to you if you manage to figure out my trick on the
>> first read of the new m4_expand implementation.
>
> Well yeah, with changequote you tread along the path to the dark side.
> And no, I don't really understand.
Here's a single-stepped example. The first argument to _m4_expand is
always the original argument, the second is the number of open '(' to add
if an unbalance is detected, the third is supposed to be the expansion of
$1 surrounded in special delimiters, and the fourth is supposed to be a
marker (conveniently matching most of the end delimiter) to detect
problems with the third parameter. On the first iteration:
'm4_expand([a)), b])' expands to:
'_m4_expand([a)), b], [(], -=<{(a)), b)}>=-, [}>=-])'
Argument collection stops once the parens are balanced, so this calls
_m4_expand with three arguments:
'_m4_expand([a)), b], [(], [-=<{(a)])'
and leaves some slop:
', b)}>=-, [}>=-])'
The first pass of _m4_expand notes that the marker in $4 is not present,
so it adds an open paren and recurses, by expanding $1 again (yes, this
means that side effects in $1 occur more than once, but only if $1 expands
to unbalanced unquoted `)'). On the second iteration, we have:
'_m4_expand([a)), b], [((], -=<{((a)), b)}>=-, [}>=-])m4_ignore('
Argument collection again stops at balanced parens, where we call
_m4_expand with four arguments:
'_m4_expand([a)), b], [((], [-=<{((a))], [b])'
and prepending to the slop:
'}>=-, [}>=-])m4_ignore('
Oops, [b] is still not the marker, so we go to a third iteration:
'_m4_expand([a)), b], [(((], -=<{(((a)), b)}>=-, [}>=-])m4_ignore(('
Parentheses are now balanced, so we invoke _m4_expand with the marker as
the fourth argument:
'_m4_expand([a)), b], [(((], [-=<{(((a)), b)}>=-], [}>=-])'
while prepending to the slop:
'm4_ignore(('
Pre-patch, the changequote was always 5 and 5 characters. But now that we
noted that we had to add extra '(' to get balance in the expansion of $1,
the changequote must consume those extra '('. Hence, we change quotes to:
'-=<{(((' and ')}>=-'
at which point $3 is a quoted string, whose contents are the expansion of
the $1 passed to m4_expand. All that remains is to undo the changequote,
then take care of the slop, which is now:
'm4_ignore((' '}>=-, [}>=-])m4_ignore(' ', b)}>=-, [}>=-])'
Oddly enough, that is just enough parens and ( to balance out the
leftovers in the failed expansions of $1 in the first and second
iteration. It is parsed as an inner 'm4_ignore([], [b])' that ignores its
two arguments, then an outer:
'm4_ignore([(}>=- [}>=-])}>=-], [}>=-])'
that also ignores its two arguments.
Slick, huh?
>
> I do wonder when quadrigraphs for `(' and `)' will finally be added,
> though.
Already done :(. In 2.63.
- --
Don't work too hard, make some time for fun as well!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkklaKwACgkQ84KuGfSFAYBgVwCg2OUPe0iM7ILpf5lCfLjr9W02
ZfsAni+1VrICiVVuwcthvzHhnEMAe+cJ
=gZDk
-----END PGP SIGNATURE-----
- Re: Use newer m4_map_args_{w,sep}, (continued)
- m4_chomp [was: Use newer m4_map_args_{w,sep}], Eric Blake, 2008/11/13
- Re: m4_chomp [was: Use newer m4_map_args_{w,sep}], Paolo Bonzini, 2008/11/14
- Re: m4_chomp [was: Use newer m4_map_args_{w,sep}], Eric Blake, 2008/11/14
- Re: m4_chomp [was: Use newer m4_map_args_{w,sep}], Paolo Bonzini, 2008/11/14
- Re: m4_chomp [was: Use newer m4_map_args_{w,sep}], Eric Blake, 2008/11/14
- Re: m4_chomp, Eric Blake, 2008/11/14
- fewer forks in AC_DEFINE [was: Use newer m4_map_args_{w,sep}], Eric Blake, 2008/11/19
- Re: fewer forks in AC_DEFINE [was: Use newer m4_map_args_{w,sep}], Ralf Wildenhues, 2008/11/20
- Re: fewer forks in AC_DEFINE [was: Use newer m4_map_args_{w,sep}],
Eric Blake <=
- Re: fewer forks in AC_DEFINE, Ralf Wildenhues, 2008/11/20
- Re: fewer forks in AC_DEFINE, Eric Blake, 2008/11/20
- case statement style (was: fewer forks in AC_DEFINE), Eric Blake, 2008/11/20
- Re: case statement style, Ralf Wildenhues, 2008/11/21
- Re: case statement style, Eric Blake, 2008/11/21
- Re: case statement style, Eric Blake, 2008/11/21
- Re: fewer forks in AC_DEFINE [was: Use newer m4_map_args_{w,sep}], Eric Blake, 2008/11/20