autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Use newer m4_map_args_{w,sep}


From: Eric Blake
Subject: Re: Use newer m4_map_args_{w,sep}
Date: Tue, 11 Nov 2008 19:11:14 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Paolo Bonzini <bonzini <at> gnu.org> writes:

> > is now converted to AS_ECHO.  And while reviewing, I noticed some other
> > simplifications (rather than choosing between m4_expand or m4_quote based
> > on $1 in the second macro, I blindly call m4_expand in the first macro),
> > so here's the updated patch I'm planning on installing, after I run the
> > full testsuite:
> 
> You can also change the meaning of the first argument of _AC_DEFINE*,
> which does not make much sense with the new implementation, and use it
> with m4_indir to avoid using m4_cond.

Good idea.  Here's what I'm committing; differences from the previous proposal 
include a more thorough testsuite, falling back to here-docs if the string 
contains a \, and a slicker choice of $1 to invoke an appropriate callback 
routine.

In testing, this exposes some shell ambiguities with here-docs, where foo is 
unset:

1.
cat <<EOF
${foo-"a b"}
EOF

2.
cat <<EOF
${foo-\"a b\"}
EOF

              1       2
zsh 4.3.4     a b     zsh: parse error
bash 3.2.39   a b     \"a b\"
ash           a b     \"a b\"
pdksh         a b     "a b"
/bin/sh       "a b"   \"a b\"
ksh           "a b"   \"a b\"


POSIX states that within parameter substitution, the word portion of the 
${parameter-word} is subject to tilde expansion, parameter expansion, command 
substitution, and arithmetic expansion, but not quote removal.  It also states 
that within here-docs, \ before " does not behave like \ within "" except 
inside ${}, ``, and $().

But obviously, the POSIX rules are a bit ambiguous.  It seems that bash 
performs quote removal of unquoted "", pdksh performs \ quote removal on " 
inside ${}, and zsh chokes.  I guess I like either pdksh or ksh's behavior (in 
bash, there's no way to output exactly '"a b"' on an unset variable, while in 
ksh, you can use ${foo-a b}).  It certainly made writing a testcase 
interesting; I'm not sure what (if anything) to document in the manual, though.


From: Eric Blake <address@hidden>
Date: Tue, 11 Nov 2008 10:33:37 -0700
Subject: [PATCH] Reduce forks in AC_DEFINE.

* lib/autoconf/general.m4 (_AC_DEFINE_Q_PRINT): New macro.
(_AC_DEFINE_Q): Use it to avoid forks for all AC_DEFINE and most
AC_DEFINE_UNQUOTED.
* tests/torture.at (Substitute and define special characters):
(Define to a 2000-byte string): Enhance tests to cover
AC_DEFINE_UNQUOTED.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog               |   10 ++++++++++
 lib/autoconf/general.m4 |   42 ++++++++++++++++++++++++++++++++----------
 tests/torture.at        |   36 ++++++++++++++++++++++++++++++------
 3 files changed, 72 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b28abcd..fc611ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-11-11  Eric Blake  <address@hidden>
+
+       Reduce forks in AC_DEFINE.
+       * lib/autoconf/general.m4 (_AC_DEFINE_Q_PRINT): New macro.
+       (_AC_DEFINE_Q): Use it to avoid forks for all AC_DEFINE and most
+       AC_DEFINE_UNQUOTED.
+       * tests/torture.at (Substitute and define special characters):
+       (Define to a 2000-byte string): Enhance tests to cover
+       AC_DEFINE_UNQUOTED.
+
 2008-11-10  Eric Blake  <address@hidden>
 
        Work around <=m4-1.4.9 bug in m4_format.
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 15377cb..d60e302 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -2060,18 +2060,41 @@ m4_define([AC_DEFINE_TRACE],
 # Set VARIABLE to VALUE, verbatim, or 1.  Remember the value
 # and if VARIABLE is affected the same VALUE, do nothing, else
 # die.  The third argument is used by autoheader.
-m4_define([AC_DEFINE], [_AC_DEFINE_Q([\], $@)])
+m4_define([AC_DEFINE], [_AC_DEFINE_Q([_$0], $@)])
+
+# _AC_DEFINE(STRING)
+# ------------------
+# Append the pre-expanded STRING and a newline to confdefs.h, as if by
+# a quoted here-doc.
+m4_define([_AC_DEFINE],
+[AS_ECHO(["AS_ESCAPE([[$1]])"]) >>confdefs.h])
 
 
 # AC_DEFINE_UNQUOTED(VARIABLE, [VALUE], [DESCRIPTION])
 # ----------------------------------------------------
-# Similar, but perform shell substitutions $ ` \ once on VALUE.
-m4_define([AC_DEFINE_UNQUOTED], [_AC_DEFINE_Q([], $@)])
-
+# Similar, but perform shell substitutions $ ` \ once on VALUE, as
+# in an unquoted here-doc.
+m4_define([AC_DEFINE_UNQUOTED], [_AC_DEFINE_Q([_$0], $@)])
 
-# _AC_DEFINE_Q(QUOTE, VARIABLE, [VALUE], [DESCRIPTION])
+# _AC_DEFINE_UNQUOTED(STRING)
+# ---------------------------
+# Append the pre-expanded STRING and a newline to confdefs.h, as if
+# with an unquoted here-doc, but avoiding a fork in the common case of
+# no backslash, no command substitution, and no complex variable
+# substitution.
+m4_define([_AC_DEFINE_UNQUOTED],
+[m4_if(m4_bregexp([$1], [\\\|`\|\$(\|\${]), [-1],
+       [AS_ECHO(["AS_ESCAPE([$1], [""])"]) >>confdefs.h],
+       [cat >>confdefs.h <<_ACEOF
+[$1]
+_ACEOF])])
+
+
+# _AC_DEFINE_Q(MACRO, VARIABLE, [VALUE], [DESCRIPTION])
 # -----------------------------------------------------
 # Internal function that performs common elements of AC_DEFINE{,_UNQUOTED}.
+# MACRO must take one argument, which is the fully expanded string to
+# append to confdefs.h as if by a possibly-quoted here-doc.
 #
 # m4_index is roughly 5 to 8 times faster than m4_bpatsubst, so we use
 # m4_format rather than regex to grab prefix up to first ().  AC_name
@@ -2086,13 +2109,12 @@ m4_define([_AC_DEFINE_Q],
 ])], [-1], [],
        [AS_LITERAL_IF([$3], [m4_bregexp([[$3]], [[^\\]
 ], [-])])], [], [],
-       [m4_warn([syntax], [AC_DEFINE]m4_ifval([$1], [], [[_UNQUOTED]])dnl
-[: `$3' is not a valid preprocessor define value])])]dnl
+       [m4_warn([syntax], [AC_DEFINE]m4_if([$1], [_AC_DEFINE], [],
+   [[_UNQUOTED]])[: `$3' is not a valid preprocessor define value])])]dnl
 [m4_ifval([$4], [AH_TEMPLATE(AC_name, [$4])])]dnl
 [_m4_popdef([AC_name])]dnl
-[cat >>confdefs.h <<$1_ACEOF
address@hidden:@define] $2 m4_if([$#], 2, 1, [$3], [], [/**/], [$3])
-_ACEOF
+[$1(m4_expand(address@hidden:@define] $2 ]m4_if([$#], 2, 1,
+   [$3], [], [/**/], [[$3]])))
 ])
 
 
diff --git a/tests/torture.at b/tests/torture.at
index 586d0f8..20ac0a2 100644
--- a/tests/torture.at
+++ b/tests/torture.at
@@ -756,16 +756,19 @@ AT_CLEANUP
 ## ------------------------------ ##
 
 AT_SETUP([Define to a 2000-byte string])
+AT_KEYWORDS([AC@&address@hidden AC@&address@hidden)
 
 AT_CONFIGURE_AC(
 [[
-AC_DEFINE([foo], ]m4_for([n], 1, 100,, ....................)[, [desc])
+AC_DEFINE_UNQUOTED([foo], ]m4_for([n], 1, 100,, ....................)[, [desc])
+AC_DEFINE([fooq], ]m4_for([n], 1, 100,, ....................)[, [desc])
 ]])
 
 AT_CHECK_AUTOCONF
 AT_CHECK_AUTOHEADER
 AT_CHECK_CONFIGURE
 AT_CHECK_DEFINES(address@hidden:@define foo m4_for([n], 1, 100,, 
....................)
address@hidden:@define fooq m4_for([n], 1, 100,, ....................)
 ])
 AT_CLEANUP
 
@@ -777,6 +780,7 @@ AT_CLEANUP
 # Use characters special to the shell, sed, awk, and M4.
 
 AT_SETUP([Substitute and define special characters])
+AT_KEYWORDS([AC@&address@hidden AC@&address@hidden)
 
 AT_DATA([Foo.in], address@hidden@
 @bar@@notsubsted@@baz@ stray @ and more@@@baz@
@@ -800,7 +804,8 @@ AT_DATA([Zardoz.in], address@hidden@
 ])
 
 AT_CONFIGURE_AC(
-[[foo="AS@&address@hidden([[X*'[]+ ",& &`\($foo \& \\& \\\& \\\\& \ \\ \\\ 
!]])"
+[[foo="AS@&address@hidden([[X*'[]+ ", & &`\($foo \& \\& \\\& \\\\& \ \\ \\\ 
!]])"
+#"
 bar="@foo@ @baz@"
 baz=bla
 ( for i in 0 1 2 3; do
@@ -824,8 +829,17 @@ AC_SUBST([baz])
 AC_SUBST([zardoz])
 file=File
 AC_SUBST_FILE([file])
-AC_DEFINE([foo], [[X*'[]+ ",& &`\($foo !]], [Awful value.])
-AC_DEFINE([bar], [[%!_!# X]], [Value that is used as special delimiter.])
+AC_DEFINE([fooq], [[X*'[]+ ", & &`\($foo !]], [Awful value.])
+AC_DEFINE([barq], [[%!_!# X]], [Value that is used as special delimiter.])
+AC_DEFINE_UNQUOTED([foo], [[X*'[]+ ", & &\`\\(\$foo !]], [Awful value.])
+AC_DEFINE_UNQUOTED([bar], [[%!_!# X]], [Value that is used as special 
delimiter.])
+AC_DEFINE_UNQUOTED([unq1], [$baz], [unquoted, test 1])
+AC_DEFINE_UNQUOTED([unq2], [\$baz], [unquoted, test 2])
+AC_DEFINE_UNQUOTED([unq3], ["$baz"], [unquoted, test 3])
+AC_DEFINE_UNQUOTED([unq4], [${baz+set}], [unquoted, test 4])
+AC_DEFINE_UNQUOTED([unq5], ["${baz+`echo "a b"`}"], [unquoted, test 5])
+AC_DEFINE_UNQUOTED([unq6], [`echo hi`], [unquoted, test 6])
+AC_DEFINE_UNQUOTED([unq7], ['\"'], [unquoted, test 7])
 AC_PROG_AWK
 AC_CONFIG_FILES([Foo Zardoz])]])
 
@@ -834,7 +848,7 @@ AT_CHECK_AUTOHEADER
 # Check both awk and the result of AC_PROG_AWK
 for awk_arg in FOO= AWK=awk; do
   AT_CHECK_CONFIGURE([$awk_arg])
-  AT_CHECK([cat Foo], 0, [[X*'[]+ ",& &`\($foo \& \\& \\\& \\\\& \ \\ \\\ !
+  AT_CHECK([cat Foo], 0, [[X*'[]+ ", & &`\($foo \& \\& \\\& \\\\& \ \\ \\\ !
 @foo@ @baz@@address@hidden stray @ and more@@bla
 address@hidden@ @address@hidden@baz
 address@hidden@ @address@hidden
@@ -849,7 +863,16 @@ address@hidden@
 ]])
   AT_CHECK([cmp allowed-chars Zardoz])
   AT_CHECK_DEFINES([[#define bar %!_!# X
-#define foo X*'[]+ ",& &`\($foo !
+#define barq %!_!# X
+#define foo X*'[]+ ", & &`\($foo !
+#define fooq X*'[]+ ", & &`\($foo !
+#define unq1 bla
+#define unq2 $baz
+#define unq3 "bla"
+#define unq4 set
+#define unq5 "a b"
+#define unq6 hi
+#define unq7 '\"'
 ]])
 done
 AT_CLEANUP
@@ -900,6 +923,7 @@ AT_CLEANUP
 ## ------------------ ##
 
 AT_SETUP([Define a newline])
+AT_KEYWORDS([AC@&address@hidden AC@&address@hidden)
 AT_CONFIGURE_AC([[AC_DEFINE([foo], [one
 two], [This spans two lines.])
 ]])
-- 
1.6.0.2








reply via email to

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