autoconf-patches
[Top][All Lists]
Advanced

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

fewer forks in AC_DEFINE [was: Use newer m4_map_args_{w,sep}]


From: Eric Blake
Subject: fewer forks in AC_DEFINE [was: Use newer m4_map_args_{w,sep}]
Date: Wed, 19 Nov 2008 22:58:45 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> > While I disagree with Ralf that this kind of incompatibilities are "more
> > common than we'd like" in Autoconf git, I do think this is a showstopper
> > for this patch, unfortunately.
> 
> Ouch.  The patch is not dead yet, just stalled.  I have an (untested) idea
> for a macro that will strip trailing newlines
...
> once the expansion is obtained, we can
> safely remove the newline since AS_ECHO provides its own and since
> m4_expand's output is properly quoted to no longer worry about raw #.

Here, then, is the 5-patch series that unstalls this idea, and makes AC_DEFINE 
produce faster configure files.  I will probably apply it tomorrow, since it 
seems to pass everything I've thrown at it.

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.

> >>  ** The autoconf macros AC_DEFINE and AC_DEFINE_UNQUOTED now output
> >>     fewer blank lines.
> >
> > It is not clear whether "output" refers to the configure or to the
> > config.h file here.
> 
> Good point.  I'll add the phrase 'to the configure file' at the end.

It turns out that with the m4_expand improvements, no change in semantics to 
AC_DEFINE occurred, after all.  So I didn't need this particular NEWS item.

Eric Blake (5):
      Remove _m4_index.
      Add m4_chomp, m4_esyscmd_s.
      Improve m4_expand robustness, part 1.
      Improve m4_expand robustness, part 2.
      Reduce forks in AC_DEFINE.

$ git fetch git://repo.or.cz/autoconf/ericb.git curry


>From d0fd67b82a383a382c629eb5b320eea4f119d8fc Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 12 Nov 2008 21:10:35 -0700
Subject: [PATCH] Remove _m4_index.

* lib/m4sugar/m4sugar.m4 (_m4_index): Delete; it is more efficient
to make callers guarantee a match.
(m4_init): Adjust caller.
* lib/autoconf/status.m4 (_AC_CONFIG_COMPUTE_DEST): Likewise.
* lib/autoconf/general.m4 (_AC_DEFINE_Q): Likewise.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog               |    9 +++++++++
 lib/autoconf/general.m4 |    5 +++--
 lib/autoconf/status.m4  |    5 +++--
 lib/m4sugar/m4sugar.m4  |   20 +-------------------
 4 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a98941a..6db2bc8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2008-11-19  Eric Blake  <address@hidden>
 
+       Remove _m4_index.
+       * lib/m4sugar/m4sugar.m4 (_m4_index): Delete; it is more efficient
+       to make callers guarantee a match.
+       (m4_init): Adjust caller.
+       * lib/autoconf/status.m4 (_AC_CONFIG_COMPUTE_DEST): Likewise.
+       * lib/autoconf/general.m4 (_AC_DEFINE_Q): Likewise.
+
+2008-11-19  Eric Blake  <address@hidden>
+
        Improve testsuite generation.
        * tests/local.at (AT_DATA_M4SUGAR, AT_DATA_M4SH)
        (AT_DATA_AUTOCONF): Escape all quadrigraphs, not just @&address@hidden  
Use
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 2f40f82..3603cb7 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -2078,9 +2078,10 @@ m4_define([AC_DEFINE_UNQUOTED], [_AC_DEFINE_Q([], $@)])
 # is defined with over-quotation, so that we can avoid m4_defn; this
 # is only safe because the name should not contain $.
 #
-# Use _m4_index to avoid a bug in m4_format in older m4.
+# Guarantee a match in m4_index, so as to avoid a bug with precision
+# -1 in m4_format in older m4.
 m4_define([_AC_DEFINE_Q],
-[m4_pushdef([AC_name], m4_format([[[%.*s]]], _m4_index([$2], [(]), [$2]))]dnl
+[m4_pushdef([AC_name], m4_format([[[%.*s]]], m4_index([$2(], [(]), [$2]))]dnl
 [AC_DEFINE_TRACE(AC_name)]dnl
 [m4_cond([m4_index([$3], [
 ])], [-1], [],
diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4
index fe78358..bfd7a79 100644
--- a/lib/autoconf/status.m4
+++ b/lib/autoconf/status.m4
@@ -247,9 +247,10 @@ m4_define([_AC_CONFIG_FOOS],
 # _AC_CONFIG_COMPUTE_DEST(STRING)
 # -------------------------------
 # Compute the DEST from STRING by stripping any : and following
-# characters.  Use _m4_index to avoid a bug in m4_format in older m4.
+# characters.  Guarantee a match in m4_index, so as to avoid a bug
+# with precision -1 in m4_format in older m4.
 m4_define([_AC_CONFIG_COMPUTE_DEST],
-[m4_format([[%.*s]], _m4_index([$1], [:]), [$1])])
+[m4_format([[%.*s]], m4_index([$1:], [:]), [$1])])
 
 # _AC_CONFIG_REGISTER(MODE, TAG, [COMMANDS])
 # ------------------------------------------
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 8884714..7671f0f 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -625,22 +625,6 @@ m4_define([m4_dumpdefs],
        [m4_map_args([$0], $@)])])
 
 
-# _m4_index(HAYSTACK, NEEDLE)
-# ---------------------------
-# Like the original, except return -2 instead of -1 if NEEDLE is not
-# present in HAYSTACK.  That way, it can be used to work around a bug
-# in m4 1.4.9 and earlier where m4_format did not accept a precision
-# of -1; this macro can be safely used in the idiom:
-#   m4_format([[%.*s]], _m4_index([$1],[$2]), [$1])
-# to grab the prefix of $1 up to but excluding $2, if it was present,
-# otherwise the entire $1.
-m4_define([_m4_index],
-[$0_(m4_index($@))])
-
-m4_define([_m4_index_],
-[m4_if([$1], [-1], [-2], [$1])])
-
-
 # m4_popdef(NAME)
 # ---------------
 # Like the original, except guarantee a warning when using something which is
@@ -2991,8 +2975,7 @@ m4_pattern_forbid([^dnl$])
 
 # If __m4_version__ is defined, we assume that we are being run by M4
 # 1.6 or newer, and thus that $@ recursion is linear and debugmode(d)
-# is available for faster checks of dereferencing undefined macros,
-# and we don't need to worry about _m4_format bugs with _m4_index.
+# is available for faster checks of dereferencing undefined macros.
 # But if it is missing, we assume we are being run by M4 1.4.x, that
 # $@ recursion is quadratic, and that we need foreach-based
 # replacement macros.  Use the raw builtin to avoid tripping up
@@ -3001,7 +2984,6 @@ m4_pattern_forbid([^dnl$])
 m4_ifdef([__m4_version__],
 [m4_debugmode([+d])
 m4_define([m4_defn], _m4_defn([_m4_defn]))
-m4_define([_m4_index], _m4_defn([m4_index]))
 m4_define([m4_popdef], _m4_defn([_m4_popdef]))
 m4_define([m4_undefine], _m4_defn([_m4_undefine]))],
 [m4_builtin([include], [m4sugar/foreach.m4])])
-- 
1.6.0.4


>From 932578997ed707142bf0ddc0e6974243773e4b49 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 12 Nov 2008 21:45:42 -0700
Subject: [PATCH] Add m4_chomp, m4_esyscmd_s.

* lib/m4sugar/m4sugar.m4 (m4_esyscmd_e, m4_chomp, m4_chomp_all):
New macros.
* doc/autoconf.texi (Redefined M4 Macros) <m4_esyscmd_s>: Document
them.
(Text processing Macros) <m4_chomp>: Likewise.
* NEWS: Likewise.
* tests/m4sugar.at (m4@&address@hidden): New test.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog              |    9 +++++++++
 NEWS                   |    4 ++--
 doc/autoconf.texi      |   19 +++++++++++++++++++
 lib/m4sugar/m4sugar.m4 |   34 ++++++++++++++++++++++++++++++++++
 tests/m4sugar.at       |   28 ++++++++++++++++++++++++++++
 5 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6db2bc8..09da955 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2008-11-19  Eric Blake  <address@hidden>
 
+       Add m4_chomp, m4_esyscmd_s.
+       * lib/m4sugar/m4sugar.m4 (m4_esyscmd_e, m4_chomp, m4_chomp_all):
+       New macros.
+       * doc/autoconf.texi (Redefined M4 Macros) <m4_esyscmd_s>: Document
+       them.
+       (Text processing Macros) <m4_chomp>: Likewise.
+       * NEWS: Likewise.
+       * tests/m4sugar.at (m4@&address@hidden): New test.
+
        Remove _m4_index.
        * lib/m4sugar/m4sugar.m4 (_m4_index): Delete; it is more efficient
        to make callers guarantee a match.
diff --git a/NEWS b/NEWS
index 6ef0725..297b3ea 100644
--- a/NEWS
+++ b/NEWS
@@ -23,8 +23,8 @@ GNU Autoconf NEWS - User visible changes.
    `autoreconf -I dir' option.
 
 ** The following documented m4sugar macros are new:
-   m4_curry  m4_default_quoted  m4_map_args  m4_map_args_pair
-   m4_set_map
+   m4_chomp  m4_curry  m4_default_quoted  m4_esyscmd_s  m4_map_args
+   m4_map_args_pair  m4_set_map
 
 ** The following m4sugar macros are documented now:
    m4_copy  m4_dumpdefs  m4_rename
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index f06a545..1aaa1e5 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10440,6 +10440,14 @@ Redefined M4 Macros
 silently does nothing if @var{name} is undefined.
 @end defmac
 
address@hidden m4_esyscmd_s (@var{command})
address@hidden
+Like @code{m4_esyscmd}, this macro expands to the result of running
address@hidden in a shell.  The difference is that any trailing newlines
+are removed, so that the output behaves more like shell command
+substitution.
address@hidden defmac
+
 @defmac m4_exit (@var{exit-status})
 @msindex{exit}
 This macro corresponds to @code{m4exit}.
@@ -11392,6 +11400,17 @@ Text processing Macros
 @end example
 @end defmac
 
address@hidden m4_chomp (@var{string})
address@hidden m4_chomp_all (@var{string})
address@hidden
address@hidden
+Output @var{string} in quotes, but without a trailing newline.  The
+macro @code{m4_chomp} is slightly faster, and removes at most one
+newline; the macro @code{m4_chomp_all} removes all consecutive trailing
+newlines.  Unlike @code{m4_flatten}, embedded newlines are left intact,
+and backslash does not influence the result.
address@hidden defmac
+
 @defmac m4_combine (@ovar{separator}, @var{prefix-list}, @ovar{infix}, @
   @var{suffix-1}, @ovar{suffix-2}, @dots{})
 @msindex{combine}
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 7671f0f..e432aad 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -624,6 +624,13 @@ m4_define([m4_dumpdefs],
        [$#], [1], [m4_stack_foreach_lifo([$1], [m4_dumpdef([$1])m4_ignore])],
        [m4_map_args([$0], $@)])])
 
+# m4_esyscmd_s(COMMAND)
+# ---------------------
+# Like m4_esyscmd, except strip any trailing newlines, thus behaving
+# more like shell command substitution.
+m4_define([m4_esyscmd_s],
+[m4_chomp_all(m4_esyscmd([$1]))])
+
 
 # m4_popdef(NAME)
 # ---------------
@@ -822,6 +829,8 @@ m4_define([m4_echo], address@hidden)
 # with balanced quotes (use quadrigraphs to get around this).  The input
 # is not likely to have unbalanced -=<{(/)}>=- quotes, and it is possible
 # to have unbalanced (), provided it was specified with proper [] quotes.
+# Likewise, ARG must either avoid unquoted comments, or must be sure
+# to include the trailing newline to end the comment.
 #
 # Exploit that extra () will group unquoted commas and the following
 # whitespace, then convert () to [].  m4_bpatsubst can't handle newlines
@@ -2089,6 +2098,31 @@ m4_define([_m4_split],
               -=<{(]$3[)}>=-)]m4_changequote([, ])])
 
 
+# m4_chomp(STRING)
+# m4_chomp_all(STRING)
+# --------------------
+# Return STRING quoted, but without a trailing newline.  m4_chomp
+# removes at most one newline, while m4_chomp_all removes all
+# consecutive trailing newlines.  Embedded newlines are not touched,
+# and a trailing backslash-newline leaves the backslash.
+#
+# m4_bregexp is slower than m4_index, and we don't always want to
+# remove all newlines; hence the two variants.  m4_bregexp is
+# line-oriented, so we must change characters to give a nicer pattern
+# to match.  Both versions must guarantee a match, to avoid bugs with
+# precision -1 in m4_format in older m4.  Inline m4_defn and 255
+# spaces for speed.
+m4_define([m4_chomp],
+[m4_format([[%.*s]], m4_index(m4_translit([$1], [
+]]m4_dquote(_m4_defn([m4_cr_all]))[, [/]]m4_format([%255s], [])[)[-/-],
+  [/-]), [$1])])
+
+m4_define([m4_chomp_all],
+[m4_format([[%.*s]], m4_bregexp(m4_translit([$1], [
+]]m4_dquote(_m4_defn([m4_cr_all]))[, [/]]m4_format([%255s], [])[),
+  [/*$]), [$1])])
+
+
 # m4_flatten(STRING)
 # ------------------
 # If STRING contains end of lines, replace them with spaces.  If there
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index 5a90493..d1ee1fe 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -871,6 +871,34 @@ $1$#$@
 
 AT_CLEANUP
 
+## -------------- ##
+## m4_esyscmd_s.  ##
+## -------------- ##
+
+AT_SETUP([m4@&address@hidden)
+AT_KEYWORDS([m4@&address@hidden m4@&address@hidden)
+
+AT_CHECK_M4SUGAR_TEXT(
+[[m4_define([world], [WORLD])dnl
+m4_chomp([abc])
+m4_chomp([world
+
+])
+m4_esyscmd_s([echo hello world])
+m4_esyscmd_s([echo '[goodbye,
+cruel world
+
+]'])
+]], [[abc
+world
+
+hello WORLD
+goodbye,
+cruel world
+]])
+
+AT_CLEANUP
+
 ## ---------- ##
 ## M4 Loops.  ##
 ## ---------- ##
-- 
1.6.0.4


>From 2ed869be9c045ce31934f9d64eb85ea23e378c62 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 19 Nov 2008 09:00:55 -0700
Subject: [PATCH] Improve m4_expand robustness, part 1.

* lib/m4sugar/m4sugar.m4 (_m4_expand): Tolerate unquoted
unbalanced ).
* tests/m4sugar.at (m4@&address@hidden): New test.
* doc/autoconf.texi (Limitations of Builtins): Document why
quadrigraph, and not #, should be used as strategic shell
comment.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog              |   10 ++++++++++
 doc/autoconf.texi      |    8 ++++++--
 lib/m4sugar/m4sugar.m4 |   15 +++++++++++++--
 tests/m4sugar.at       |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 75 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 09da955..cd00910 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2008-11-19  Eric Blake  <address@hidden>
 
+       Improve m4_expand robustness, part 1.
+       * lib/m4sugar/m4sugar.m4 (_m4_expand): Tolerate unquoted
+       unbalanced ).
+       * tests/m4sugar.at (m4@&address@hidden): New test.
+       * doc/autoconf.texi (Limitations of Builtins): Document why
+       quadrigraph, and not #, should be used as strategic shell
+       comment.
+
+2008-11-19  Eric Blake  <address@hidden>
+
        Add m4_chomp, m4_esyscmd_s.
        * lib/m4sugar/m4sugar.m4 (m4_esyscmd_e, m4_chomp, m4_chomp_all):
        New macros.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 1aaa1e5..4f13900 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -14895,10 +14895,14 @@ Limitations of Builtins
 The leading @samp{(} can be omitted safely.  In contexts where
 unbalanced parentheses cause other problems, such as when using a case
 statement as an argument to an Autoconf macro, you can also resort to
-creative shell comments to supply the balance:
+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.  The macro @code{AS_CASE}
+takes care of this automatically.
 
 @example
-case $file_name in #(
+case $file_name in @@%:@@(
   *.c) echo "C source code";;
 esac
 @end example
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index e432aad..9efe0ae 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -835,9 +835,20 @@ m4_define([m4_echo], address@hidden)
 # Exploit that extra () will group unquoted commas and the following
 # whitespace, then convert () to [].  m4_bpatsubst can't handle newlines
 # inside $1, and m4_substr strips quoting.  So we (ab)use m4_changequote.
-m4_define([m4_expand], [_$0(-=<{($1)}>=-)])
+#
+# Thanks to shell case statements, too many people are prone to pass
+# underquoted ), so we try to detect that by passing a marker as a
+# fourth argument; if the marker is not present, then we encountered
+# an early ), and we re-expand the first argument, but this time with
+# one more ( in the second argument and in the open-quote delimiter.
+# We must also ignore the slop from the previous try.  The final macro
+# is thus half line-noise, half art.
+m4_define([m4_expand], [_$0([$1], [(], -=<{($1)}>=-, [}>=-])])
+
 m4_define([_m4_expand],
-[m4_changequote([-=<{(], [)}>=-])$1m4_changequote([, ])])
+[m4_if([$4], [}>=-],
+       [m4_changequote([-=<{$2], [)}>=-])$3m4_changequote([, ])],
+       [$0([$1], [($2], -=<{($2$1)}>=-, [}>=-])m4_ignore$2])])
 
 
 # m4_ignore(ARGS)
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index d1ee1fe..1af6149 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -676,6 +676,52 @@ one
 AT_CLEANUP
 
 
+## ----------- ##
+## m4_expand.  ##
+## ----------- ##
+
+AT_SETUP([m4@&address@hidden)
+
+AT_CHECK_M4SUGAR_TEXT(
+[[m4_define([active], [ACTIVE])dnl
+m4_expand([#active
+active])
+m4_expand([[active]])
+dnl properly quoted case statements
+m4_expand([case a in @%:@(
+  *) echo active, ;;
+esac
+case b in
+  *[)] echo active, ;;
+esac])
+dnl unbalanced underquoted ), but we manage anyway (gasp!)
+m4_expand([case c in #(
+  *) echo active, ;;
+esac
+case d in
+  *) echo active, ;;
+esac])
+]],
+[[#active
+ACTIVE
+active
+case a in #(
+  *) echo ACTIVE, ;;
+esac
+case b in
+  *) echo ACTIVE, ;;
+esac
+case c in #(
+  *) echo ACTIVE, ;;
+esac
+case d in
+  *) echo ACTIVE, ;;
+esac
+]])
+
+AT_CLEANUP
+
+
 ## -------------- ##
 ## m4_text_wrap.  ##
 ## -------------- ##
-- 
1.6.0.4


>From 81b942fbde1c9fa78269edb3bbfbdb4ee04423db Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 19 Nov 2008 11:38:18 -0700
Subject: [PATCH] Improve m4_expand robustness, part 2.

* lib/m4sugar/m4sugar.m4 (m4_expand): Support unterminated
comments, by wrapping old implementation...
(_m4_expand): ...as this, and renaming old core...
(_m4_expand_): ...to this.
(m4_text_box): Use lighter-weight _m4_expand.
* lib/m4sugar/m4sh.m4 (_AS_DETECT_EXPAND)
(_AS_DETECT_BETTER_SHELL, AS_FUNCTION_DESCRIBE): Likewise.
* lib/autotest/general.m4 (AT_KEYWORDS): Likewise.
* tests/m4sugar.at (m4@&address@hidden): Enhance test.
* tests/autotest.at (AT_CHECK_AT_TITLE_CHAR): Likewise.
* doc/autoconf.texi (Evaluation Macros) <m4_expand>: Mention new
functionality.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog               |   14 +++++++++++
 doc/autoconf.texi       |   15 ++++++++++--
 lib/autotest/general.m4 |    3 +-
 lib/m4sugar/m4sh.m4     |    8 +++---
 lib/m4sugar/m4sugar.m4  |   56 ++++++++++++++++++++++++++--------------------
 tests/autotest.at       |    7 +++--
 tests/m4sugar.at        |   10 ++++++++
 7 files changed, 78 insertions(+), 35 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cd00910..7b00d77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2008-11-19  Eric Blake  <address@hidden>
 
+       Improve m4_expand robustness, part 2.
+       * lib/m4sugar/m4sugar.m4 (m4_expand): Support unterminated
+       comments, by wrapping old implementation...
+       (_m4_expand): ...as this, and renaming old core...
+       (_m4_expand_): ...to this.
+       (m4_text_box): Use lighter-weight _m4_expand.
+       * lib/m4sugar/m4sh.m4 (_AS_DETECT_EXPAND)
+       (_AS_DETECT_BETTER_SHELL, AS_FUNCTION_DESCRIBE): Likewise.
+       * lib/autotest/general.m4 (AT_KEYWORDS): Likewise.
+       * tests/m4sugar.at (m4@&address@hidden): Enhance test.
+       * tests/autotest.at (AT_CHECK_AT_TITLE_CHAR): Likewise.
+       * doc/autoconf.texi (Evaluation Macros) <m4_expand>: Mention new
+       functionality.
+
        Improve m4_expand robustness, part 1.
        * lib/m4sugar/m4sugar.m4 (_m4_expand): Tolerate unquoted
        unbalanced ).
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 4f13900..ba1c5ee 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -11163,12 +11163,15 @@ Evaluation Macros
 Return the expansion of @var{arg} as a quoted string.  Whereas
 @code{m4_quote} is designed to collect expanded text into a single
 argument, @code{m4_expand} is designed to perform one level of expansion
-on quoted text.  The distinction is in the treatment of whitespace
+on quoted text.  One distinction is in the treatment of whitespace
 following a comma in the original @var{arg}.  Any time multiple
 arguments are collected into one with @code{m4_quote}, the M4 argument
 collection rules discard the whitespace.  However, with @code{m4_expand},
 whitespace is preserved, even after the expansion of macros contained in
address@hidden
address@hidden  Additionally, @code{m4_expand} is able to expand text that
+would involve an unterminated comment, whereas expanding that same text
+as the argument to @code{m4_quote} runs into difficulty in finding the
+end of the argument.
 
 @example
 m4_define([active], [ACT, IVE])dnl
@@ -11181,11 +11184,17 @@ Evaluation Macros
 @result{}ACT, IVE,ACT, IVE
 m4_expand([active2, active2])
 @result{}ACT, IVE, ACT, IVE
+m4_expand([# m4_echo])
address@hidden m4_echo
+m4_quote(# m4_echo)
+)
address@hidden m4_echo)
address@hidden
 @end example
 
 Note that @code{m4_expand} cannot handle an @var{arg} that expands to
 literal unbalanced quotes, but that quadrigraphs can be used when
-unbalanced output is necessary.  Likewise, unbalanced parentheses must
+unbalanced output is necessary.  Likewise, unbalanced parentheses should
 be supplied with double quoting or a quadrigraph.
 
 @example
diff --git a/lib/autotest/general.m4 b/lib/autotest/general.m4
index 704dbbf..10ab5d9 100644
--- a/lib/autotest/general.m4
+++ b/lib/autotest/general.m4
@@ -1597,7 +1597,8 @@ m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])])
 m4_define([AT_capture_files], [])
 m4_define([AT_line], AT_LINE)
 m4_define([AT_xfail], [at_xfail=no])
-m4_define([AT_description], m4_expand([$1]))
+m4_define([AT_description], m4_chomp(m4_expand([$1
+])))
 m4_define([AT_ordinal], m4_incr(AT_ordinal))
 m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal]))
 m4_divert_push([TEST_GROUPS])dnl
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index 8863c82..e4c0420 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -165,7 +165,7 @@ $1], [^], address@hidden:@ ])])])
 # we must piece-meal the assignment of VAR such that $LINENO expansion
 # occurs in a single line.
 m4_define([_AS_DETECT_EXPAND],
-[$1="m4_bpatsubst(m4_dquote(AS_ESCAPE(m4_expand(m4_set_contents([$2], [
+[$1="m4_bpatsubst(m4_dquote(AS_ESCAPE(_m4_expand(m4_set_contents([$2], [
 ])))), [\\\$LINENO\(.*\)$], [";$1=$$1$LINENO;$1=$$1"\1])"])
 
 
@@ -219,7 +219,7 @@ dnl Remove any tests from suggested that are also required
 [m4_set_map([_AS_DETECT_SUGGESTED_BODY], [_AS_DETECT_SUGGESTED_PRUNE])]dnl
 [m4_pushdef([AS_EXIT], [exit m4_default([$1], 1)])]dnl
 [if test "x$CONFIG_SHELL" = x; then
-  as_bourne_compatible="AS_ESCAPE(m4_expand([_AS_BOURNE_COMPATIBLE]))"
+  as_bourne_compatible="AS_ESCAPE(_m4_expand([_AS_BOURNE_COMPATIBLE]))"
   _AS_DETECT_EXPAND([as_required], [_AS_DETECT_REQUIRED_BODY])
   _AS_DETECT_EXPAND([as_suggested], [_AS_DETECT_SUGGESTED_BODY])
   AS_IF([_AS_RUN(["$as_required"])],
@@ -1343,8 +1343,8 @@ _ASBOX])
 m4_define([AS_FUNCTION_DESCRIBE],
 address@hidden:@ $1[]m4_ifval([$2], [ $2])
 @%:@ m4_translit(m4_format([%*s],
-                  m4_qlen(m4_expand([$1[]m4_ifval([$2], [ $2])])), []),
-                [ ], [-])
+          m4_decr(m4_qlen(_m4_expand([$1[]m4_ifval([$2], [ $2])
+]))), []), [ ], [-])
 m4_text_wrap([$3], address@hidden:@ ], [], [$4])])
 
 
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 9efe0ae..39449ad 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -813,10 +813,12 @@ m4_define([m4_echo], address@hidden)
 
 
 # m4_expand(ARG)
-# --------------
-# Return the expansion of ARG as a single string.  Unlike m4_quote($1), this
-# correctly preserves whitespace following single-quoted commas that appeared
-# within ARG.
+# _m4_expand(ARG)
+# ---------------
+# Return the expansion of ARG as a single string.  Unlike
+# m4_quote($1), this preserves whitespace following single-quoted
+# commas that appear within ARG.  It also deals with shell case
+# statements.
 #
 #   m4_define([active], [ACT, IVE])
 #   m4_define([active2], [[ACT, IVE]])
@@ -825,27 +827,33 @@ m4_define([m4_echo], address@hidden)
 #   m4_expand([active, active2])
 #   => ACT, IVE, ACT, IVE
 #
-# Unfortunately, due to limitations in m4, ARG must expand to something
-# with balanced quotes (use quadrigraphs to get around this).  The input
-# is not likely to have unbalanced -=<{(/)}>=- quotes, and it is possible
-# to have unbalanced (), provided it was specified with proper [] quotes.
-# Likewise, ARG must either avoid unquoted comments, or must be sure
-# to include the trailing newline to end the comment.
+# Unfortunately, due to limitations in m4, ARG must expand to
+# something with balanced quotes (use quadrigraphs to get around
+# this), and should not contain the unlikely delimiters -=<{( or
+# )}>=-.  It is possible to have unbalanced quoted ( or ), as well as
+# unbalanced unquoted ).  m4_expand can handle unterminated comments
+# or dnl on the final line, at the expense of speed, while _m4_expand
+# is faster but must be given a terminated expansion.
 #
-# Exploit that extra () will group unquoted commas and the following
-# whitespace, then convert () to [].  m4_bpatsubst can't handle newlines
-# inside $1, and m4_substr strips quoting.  So we (ab)use m4_changequote.
+# Exploit that extra unquoted () will group unquoted commas and the
+# following whitespace.  m4_bpatsubst can't handle newlines inside $1,
+# and m4_substr strips quoting.  So we (ab)use m4_changequote, using
+# temporary quotes to remove the delimiters that conveniently included
+# unquoted () prior to the changequote.
 #
 # Thanks to shell case statements, too many people are prone to pass
 # underquoted ), so we try to detect that by passing a marker as a
-# fourth argument; if the marker is not present, then we encountered
-# an early ), and we re-expand the first argument, but this time with
-# one more ( in the second argument and in the open-quote delimiter.
-# We must also ignore the slop from the previous try.  The final macro
-# is thus half line-noise, half art.
-m4_define([m4_expand], [_$0([$1], [(], -=<{($1)}>=-, [}>=-])])
-
-m4_define([_m4_expand],
+# fourth argument; if the marker is not present, then we assume that
+# we encountered an early ), and re-expand the first argument, but
+# this time with one more ( in the second argument and in the
+# open-quote delimiter.  We must also ignore the slop from the
+# previous try.  The final macro is thus half line-noise, half art.
+m4_define([m4_expand], [m4_chomp(_$0([$1
+]))])
+
+m4_define([_m4_expand], [$0_([$1], [(], -=<{($1)}>=-, [}>=-])])
+
+m4_define([_m4_expand_],
 [m4_if([$4], [}>=-],
        [m4_changequote([-=<{$2], [)}>=-])$3m4_changequote([, ])],
        [$0([$1], [($2], -=<{($2$1)}>=-, [}>=-])m4_ignore$2])])
@@ -2435,9 +2443,9 @@ m4_define([_m4_text_wrap_word],
 # will post-process.
 m4_define([m4_text_box],
 [m4_pushdef([m4_Border],
-           m4_translit(m4_format([%*s], m4_qlen(m4_expand([$1])), []),
-                       [ ], m4_default_quoted([$2], [-])))dnl
-[##] m4_Border [##]
+           m4_translit(m4_format([%*s], m4_decr(m4_qlen(_m4_expand([$1
+]))), []), [ ], m4_default_quoted([$2], [-])))]dnl
+[[##] m4_Border [##]
 [##] $1 [##]
 [##] m4_Border [##]_m4_popdef([m4_Border])])
 
diff --git a/tests/autotest.at b/tests/autotest.at
index d674c81..631c0c8 100644
--- a/tests/autotest.at
+++ b/tests/autotest.at
@@ -464,9 +464,10 @@ AT_CHECK_AT_TITLE_CHAR([Backslash],     [\])
 AT_CHECK_AT_TITLE_CHAR([Brackets],   [[[]]], [[]])
 AT_CHECK_AT_TITLE_CHAR([Left bracket],  [@<@&t@:@], [@<:@])
 AT_CHECK_AT_TITLE_CHAR([Right bracket], [@:@&t@>@], [@:>@])
-AT_CHECK_AT_TITLE_CHAR([Pound],       [[#]], [#])
-AT_CHECK_AT_TITLE_CHAR([Quoted comma],[[,]], [,])
-AT_CHECK_AT_TITLE_CHAR([Comma],         [,], [,])
+AT_CHECK_AT_TITLE_CHAR([Quoted pound],  [[#]], [#])
+AT_CHECK_AT_TITLE_CHAR([Pound],         [#])
+AT_CHECK_AT_TITLE_CHAR([Quoted comma],  [[,]], [,])
+AT_CHECK_AT_TITLE_CHAR([Comma],         [,])
 dnl this test also hits quadrigraphs for ()
 AT_CHECK_AT_TITLE_CHAR([Parentheses],   [(@{:@)@:address@hidden, [(())])
 AT_CHECK_AT_TITLE_CHAR([Left paren],    [[(]], [(])
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index 1af6149..52e18c1 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -701,6 +701,12 @@ esac
 case d in
   *) echo active, ;;
 esac])
+dnl unterminated comment/dnl
+m4_expand([active # active])
+m4_expand([a
+dnl])
+m4_expand([a
+-dnl])
 ]],
 [[#active
 ACTIVE
@@ -717,6 +723,10 @@ esac
 case d in
   *) echo ACTIVE, ;;
 esac
+ACTIVE # active
+a
+a
+-
 ]])
 
 AT_CLEANUP
-- 
1.6.0.4


>From b9773422ebdbb5089511f86c4c3f9ffdb33a7213 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 13 Nov 2008 21:20:18 -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.
* lib/autoconf/fortran.m4 (_AC_FC_WRAPPERS): Properly quote #.
* tests/torture.at (Substitute and define special characters):
(Define to a 2000-byte string): Enhance tests to cover
AC_DEFINE_UNQUOTED.
(@%:@define header templates): Enhance test to cover #.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog               |   12 ++++++++++++
 lib/autoconf/fortran.m4 |   20 ++++++++++----------
 lib/autoconf/general.m4 |   43 +++++++++++++++++++++++++++++++++----------
 tests/torture.at        |   44 +++++++++++++++++++++++++++++++++++++-------
 4 files changed, 92 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7b00d77..8584886 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2008-11-19  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.
+       * lib/autoconf/fortran.m4 (_AC_FC_WRAPPERS): Properly quote #.
+       * tests/torture.at (Substitute and define special characters):
+       (Define to a 2000-byte string): Enhance tests to cover
+       AC_DEFINE_UNQUOTED.
+       (@%:@define header templates): Enhance test to cover #.
+
+2008-11-19  Eric Blake  <address@hidden>
+
        Improve m4_expand robustness, part 2.
        * lib/m4sugar/m4sugar.m4 (m4_expand): Support unterminated
        comments, by wrapping old implementation...
diff --git a/lib/autoconf/fortran.m4 b/lib/autoconf/fortran.m4
index 6743aa8..c1c4fc0 100644
--- a/lib/autoconf/fortran.m4
+++ b/lib/autoconf/fortran.m4
@@ -1032,25 +1032,25 @@ case $ac_cv_[]_AC_LANG_ABBREV[]_mangling in
          AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name]) ;;
   "lower case, no underscore, extra underscore")
          AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [name])
-         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name ## _]) ;;
+         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] _]) ;;
   "lower case, underscore, no extra underscore")
-         AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [name ## _])
-         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name ## _]) ;;
+         AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [name [##] _])
+         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] _]) ;;
   "lower case, underscore, extra underscore")
-         AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [name ## _])
-         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name ## __]) ;;
+         AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [name [##] _])
+         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] __]) ;;
   "upper case, no underscore, no extra underscore")
          AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [NAME])
          AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME]) ;;
   "upper case, no underscore, extra underscore")
          AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [NAME])
-         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME ## _]) ;;
+         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] _]) ;;
   "upper case, underscore, no extra underscore")
-         AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [NAME ## _])
-         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME ## _]) ;;
+         AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [NAME [##] _])
+         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] _]) ;;
   "upper case, underscore, extra underscore")
-         AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [NAME ## _])
-         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME ## __]) ;;
+         AC_DEFINE(_AC_FC[_FUNC(name,NAME)],  [NAME [##] _])
+         AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] __]) ;;
   *)
          AC_MSG_WARN([unknown Fortran name-mangling scheme])
          ;;
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 3603cb7..110eee9 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, no complex variable
+# substitution, and no quadrigraphs.
+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
@@ -2087,13 +2110,13 @@ 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])
 ])_m4_popdef([AC_name])]dnl
-[cat >>confdefs.h <<$1_ACEOF
address@hidden:@define] $2 m4_if([$#], 2, 1, [$3], [], [/**/], [$3])
-_ACEOF
+[$1(m4_chomp(m4_expand(address@hidden:@define] $2 ]m4_if([$#], 2, 1,
+   [$3], [], [/**/], [[$3
+]]))))
 ])
 
 
diff --git a/tests/torture.at b/tests/torture.at
index 586d0f8..1a9ea4f 100644
--- a/tests/torture.at
+++ b/tests/torture.at
@@ -449,6 +449,7 @@ AT_CLEANUP
 # problems when a symbol is prefix of another.
 
 AT_SETUP(address@hidden:@define header templates])
+AT_KEYWORDS([AC@&address@hidden)
 
 AT_DATA([configure.ac],
 [[AC_INIT
@@ -474,6 +475,9 @@ AC_DEFINE([multiline_args(ARG1, ARG2)], [ARG2 \
 ARG1])
 AC_CONFIG_FILES(defs)
 
+# underquoted #
+AC_DEFINE([paste(a,b)], [a##b])
+
 # Things included in confdefs.h, but which make no sense in
 # config.h, nor in $DEFS.
 cat <<\EOF >>confdefs.h
@@ -510,6 +514,7 @@ AT_DATA([config.hin],
 #define aaac(a, aa) aa a
 #undef multiline
 #  undef multiline_args
+#define paste(a,b) a##b
 /* an ugly one: */
 #define str(define) \
 #define
@@ -542,6 +547,7 @@ line3 \
 line4
 #  define multiline_args(ARG1, ARG2) ARG2 \
 ARG1
+#define paste(a,b) a##b
 /* an ugly one: */
 #define str(define) \
 #define
@@ -553,7 +559,7 @@ AT_CHECK([cat config.h], 0, expout)
 
 # Check the value of DEFS.
 AT_DATA([expout],
-[[-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -
DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -Dfoo=toto -Dbar=tata -Dbaz=titi -
Dfubar=tutu -Da=A -Daaa=AAA -Daa=AA -Dmultiline=line1line2line3\ line4 -
Dmultiline_args\(ARG1,\ ARG2\)=ARG2\ ARG1
+[[-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -
DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -Dfoo=toto -Dbar=tata -Dbaz=titi -
Dfubar=tutu -Da=A -Daaa=AAA -Daa=AA -Dmultiline=line1line2line3\ line4 -
Dmultiline_args\(ARG1,\ ARG2\)=ARG2\ ARG1 -Dpaste\(a,b\)=a\#\#b
 ]])
 
 # Because we strip trailing spaces in `testsuite' we can't leave one in
@@ -756,16 +762,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 +786,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 +810,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 +835,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 +854,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 +869,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 +929,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.4







reply via email to

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