-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

[adding autoconf-patches, replies can drop autoconf]

According to Eric Blake on 4/6/2009 8:25 PM:
> According to Mike Frysinger on 4/6/2009 3:43 PM:
> I'm also leaning towards omitting the else if $1 is provably blank,
> otherwise providing the : in case non-blank $1 ultimately expands to a
> blank (unless someone finds a shell where 'if false ; then :; fi; echo $?'
> fails to output 0).  AS_CASE and AS_FOR are also candidates for this.  And
> it will be easier with m4_ifblank.  Stay tuned; I'll have a patch by the
> end of the week.

Here's what I'm about to apply.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             e...@byu.net
-----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

iEYEARECAAYFAkneyqwACgkQ84KuGfSFAYA4xACeM27WusneT1UueEUy6khYtCCq
jDMAoNIacTpzZ+4wwaDXQrESVr6Ii7Z8
=yCfL
-----END PGP SIGNATURE-----
>From 709c9c86af078eefd4c44f3df3de52dda678794e Mon Sep 17 00:00:00 2001
From: Eric Blake <e...@byu.net>
Date: Thu, 9 Apr 2009 07:05:00 -0600
Subject: [PATCH 1/2] Add m4_blank and friends.

* lib/m4sugar/m4sugar.m4 (m4_blank, m4_nblank, m4_default_nblank)
(m4_default_nblank_quoted): New macros.
* NEWS: Document them.
* doc/autoconf.texi (Conditional constructs): Likewise.
* tests/m4sugar.at (m4sugar shorthand conditionals): New test.
Suggested by Mike Frysinger.

Signed-off-by: Eric Blake <e...@byu.net>
---
 ChangeLog              |   10 ++++++
 NEWS                   |    3 ++
 doc/autoconf.texi      |   53 ++++++++++++++++++++++++++++-
 lib/m4sugar/m4sugar.m4 |   47 +++++++++++++++++++++++---
 tests/m4sugar.at       |   85 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 190 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index be9ab98..4429431 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2009-04-09  Eric Blake  <e...@byu.net>

+       Add m4_blank and friends.
+       * lib/m4sugar/m4sugar.m4 (m4_blank, m4_nblank, m4_default_nblank)
+       (m4_default_nblank_quoted): New macros.
+       * NEWS: Document them.
+       * doc/autoconf.texi (Conditional constructs): Likewise.
+       * tests/m4sugar.at (m4sugar shorthand conditionals): New test.
+       Suggested by Mike Frysinger.
+
+2009-04-09  Eric Blake  <e...@byu.net>
+
        Avoid problems caused by deleting in-use directory.
        * lib/autotest/general.m4 (AT_INIT) <at_fn_group_prepare>: Only
        remove the contents of $at_group_dir, not the directory itself.
diff --git a/NEWS b/NEWS
index e91fc39..0357cbd 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,9 @@ GNU Autoconf NEWS - User visible changes.
    proper m4 quoting.  For shell comments, this is a new feature; for
    non-shell comments, this fixes a regression introduced in 2.63b.

+** The following documented m4sugar macros are new:
+   m4_default_nblank  m4_default_nblank_quoted  m4_ifblank  m4_ifnblank
+
 * Major changes in Autoconf 2.63b (2009-03-31) [beta]
   Released by Eric Blake, based on git versions 2.63.*.

diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 5e490fe..a47d3c8 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10987,25 +10987,74 @@ Conditional constructs

 @defmac m4_default (@var{expr-1}, @var{expr-2})
 @defmacx m4_default_quoted (@var{expr-1}, @var{expr-2})
+...@defmacx m4_default_nblank (@var{expr-1}, @ovar{expr-2})
+...@defmacx m4_default_nblank_quoted (@var{expr-1}, @ovar{expr-2})
 @msindex{default}
 @msindex{default_quoted}
-If @var{expr-1} is not empty, use it.  Otherwise, select @var{expr-2}.
+...@msindex{default_nblank}
+...@msindex{default_nblank_quoted}
+If @var{expr-1} contains text, use it.  Otherwise, select @var{expr-2}.
 @code{m4_default} expands the result, while @code{m4_default_quoted}
 does not.  Useful for providing a fixed default if the expression that
-results in @var{expr-1} would otherwise be empty.
+results in @var{expr-1} would otherwise be empty.  The difference
+between @code{m4_default} and @code{m4_default_nblank} is whether an
+argument consisting of just blanks (space, tab, newline) is
+significant.  When using the expanding versions, note that an argument
+may contain text but still expand to an empty string.

 @example
 m4_define([active], [ACTIVE])dnl
+m4_define([empty], [])dnl
 m4_define([demo1], [m4_default([$1], [$2])])dnl
 m4_define([demo2], [m4_default_quoted([$1], [$2])])dnl
+m4_define([demo3], [m4_default_nblank([$1], [$2])])dnl
+m4_define([demo4], [m4_default_nblank_quoted([$1], [$2])])dnl
 demo1([active], [default])
 @result{}ACTIVE
 demo1([], [active])
 @result{}ACTIVE
+demo1([empty], [text])
+...@result{}
+-demo1([ ], [active])-
+...@result{}- -
 demo2([active], [default])
 @result{}active
 demo2([], [active])
 @result{}active
+demo2([empty], [text])
+...@result{}empty
+-demo2([ ], [active])-
+...@result{}- -
+demo3([active], [default])
+...@result{}active
+demo3([], [active])
+...@result{}active
+demo3([empty], [text])
+...@result{}
+-demo3([ ], [active])-
+...@result{}-active-
+demo4([active], [default])
+...@result{}active
+demo4([], [active])
+...@result{}active
+demo4([empty], [text])
+...@result{}empty
+-demo4([ ], [active])-
+...@result{}-active-
+...@end example
+...@end defmac
+
+...@defmac m4_ifblank (@var{cond}, @ovar{if-blank}, @ovar{if-text})
+...@defmacx m4_ifnblank (@var{cond}, @ovar{if-text}, @ovar{if-blank})
+...@msindex{ifblank}
+...@msindex{ifnblank}
+If @var{cond} is empty or consists only of blanks (space, tab, newline),
+then expand @var{if-blank}; otherwise, expand @var{if-text}.  Two
+variants exist, in order to make it easier to select the correct logical
+sense when using only two parameters.  Note that this is more efficient
+than the equivalent behavior of:
+...@example
+m4_ifval(m4_normalize([...@var{cond}]), @var{if-text}, @var{if-cond})
 @end example
 @end defmac

diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 8356d08..420fd99 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -335,6 +335,29 @@ m4_builtin([sinclude], [$1])])
 # it runs TRUE, etc.


+# m4_ifblank(COND, [IF-BLANK], [IF-TEXT])
+# m4_ifnblank(COND, [IF-TEXT], [IF-BLANK])
+# ----------------------------------------
+# If COND is empty, or consists only of blanks (space, tab, newline),
+# then expand IF-BLANK, otherwise expand IF-TEXT.  This differs from
+# m4_ifval only if COND has just whitespace, but it helps optimize in
+# spite of users who mistakenly leave trailing space after what they
+# thought was an empty argument:
+#   macro(
+#         []
+#        )
+#
+# Writing one macro in terms of the other causes extra overhead, so
+# we inline both definitions.
+m4_define([m4_ifblank],
+[m4_if(m4_translit([[$1]],  [ ][       ][
+]), [], [$2], [$3])])
+
+m4_define([m4_ifnblank],
+[m4_if(m4_translit([[$1]],  [ ][       ][
+]), [], [$3], [$2])])
+
+
 # m4_ifval(COND, [IF-TRUE], [IF-FALSE])
 # -------------------------------------
 # If COND is not the empty string, expand IF-TRUE, otherwise IF-FALSE.
@@ -559,31 +582,43 @@ m4_define([m4_define_default],


 # m4_default(EXP1, EXP2)
-# ----------------------
-# Returns EXP1 if non empty, otherwise EXP2.  Expand the result.
+# m4_default_nblank(EXP1, EXP2)
+# -----------------------------
+# Returns EXP1 if not empty/blank, otherwise EXP2.  Expand the result.
 #
-# This macro is called on hot paths, so inline the contents of m4_ifval,
+# m4_default is called on hot paths, so inline the contents of m4_ifval,
 # for one less round of expansion.
 m4_define([m4_default],
 [m4_if([$1], [], [$2], [$1])])

+m4_define([m4_default_nblank],
+[m4_ifblank([$1], [$2], [$1])])
+

 # m4_default_quoted(EXP1, EXP2)
-# -----------------------------
-# Returns EXP1 if non empty, otherwise EXP2.  Leave the result quoted.
+# m4_default_nblank_quoted(EXP1, EXP2)
+# ------------------------------------
+# Returns EXP1 if non empty/blank, otherwise EXP2.  Leave the result quoted.
 #
 # For comparison:
 #   m4_define([active], [ACTIVE])
 #   m4_default([active], [default]) => ACTIVE
 #   m4_default([], [active]) => ACTIVE
+#   -m4_default([ ], [active])- => - -
+#   -m4_default_nblank([ ], [active])- => -ACTIVE-
 #   m4_default_quoted([active], [default]) => active
 #   m4_default_quoted([], [active]) => active
+#   -m4_default_quoted([ ], [active])- => - -
+#   -m4_default_nblank_quoted([ ], [active])- => -active-
 #
-# This macro is called on hot paths, so inline the contents of m4_ifval,
+# m4_default macro is called on hot paths, so inline the contents of m4_ifval,
 # for one less round of expansion.
 m4_define([m4_default_quoted],
 [m4_if([$1], [], [[$2]], [[$1]])])

+m4_define([m4_default_nblank_quoted],
+[m4_ifblank([$1], [[$2]], [[$1]])])
+

 # m4_defn(NAME)
 # -------------
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index 6286af2..2dd81dc 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -649,6 +649,91 @@ m
 AT_CLEANUP


+## ------------------------------------------------- ##
+## m4_ifval, m4_ifblank, m4_ifset, m4_default, etc.  ##
+## ------------------------------------------------- ##
+
+AT_SETUP([m4sugar shorthand conditionals])
+AT_KEYWORDS([m4@&t...@_ifval m4@&t...@_ifblank m4@&t...@_ifnblank 
m4@&t...@_ifset
+m4@&t...@_default m4@&t...@_default_quoted m4@&t...@_default_nblank
+m4@&t...@_default_nblank_quoted])
+
+AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])m4_define([empty])
+m4_ifval([active], [yes], [no])
+m4_ifval([empty], [yes], [no])
+m4_ifval([ ], [yes], [no])
+m4_ifval([], [yes], [no])
+m4_ifblank([active], [yes], [no])
+m4_ifblank([empty], [yes], [no])
+m4_ifblank([ ], [yes], [no])
+m4_ifblank([], [yes], [no])
+m4_ifnblank([active], [yes], [no])
+m4_ifnblank([empty], [yes], [no])
+m4_ifnblank([ ], [yes], [no])
+m4_ifnblank([], [yes], [no])
+m4_ifset([active], [yes], [no])
+m4_ifset([empty], [yes], [no])
+m4_ifset([ ], [yes], [no])
+m4_ifset([], [yes], [no])
+---
+m4_define([demo1], [m4_default([$1], [$2])])dnl
+m4_define([demo2], [m4_default_quoted([$1], [$2])])dnl
+m4_define([demo3], [m4_default_nblank([$1], [$2])])dnl
+m4_define([demo4], [m4_default_nblank_quoted([$1], [$2])])dnl
+demo1([active], [default])
+demo1([], [active])
+demo1([empty], [text])
+-demo1([ ], [active])-
+demo2([active], [default])
+demo2([], [active])
+demo2([empty], [text])
+-demo2([ ], [active])-
+demo3([active], [default])
+demo3([], [active])
+demo3([empty], [text])
+-demo3([ ], [active])-
+demo4([active], [default])
+demo4([], [active])
+demo4([empty], [text])
+-demo4([ ], [active])-
+]], [[
+yes
+yes
+yes
+no
+no
+no
+yes
+yes
+yes
+yes
+no
+no
+yes
+no
+no
+no
+---
+ACTIVE
+ACTIVE
+
+- -
+active
+active
+empty
+- -
+ACTIVE
+ACTIVE
+
+-ACTIVE-
+active
+active
+empty
+-active-
+]])
+
+AT_CLEANUP
+
 ## --------- ##
 ## m4_cond.  ##
 ## --------- ##
-- 
1.6.1.2


>From 73b4250ff10680265b65215b5e72e41688f2308c Mon Sep 17 00:00:00 2001
From: Eric Blake <e...@byu.net>
Date: Thu, 9 Apr 2009 21:45:18 -0600
Subject: [PATCH 2/2] Make AS_IF, AS_CASE, and AS_FOR more robust to blank 
arguments.

* lib/m4sugar/m4sh.m4 (_AS_CASE, _AS_CASE_DEFAULT, AS_FOR, _AS_IF)
(_AS_IF_ELSE, AS_IF): Avoid syntax error on blank argument.
* NEWS: Mention this.
* tests/m4sh.at (AS@&t...@_if and AS@&t...@_case, AS@&t...@_for): Update
tests.
Reported by Mike Frysinger.

Signed-off-by: Eric Blake <e...@byu.net>
---
 ChangeLog           |    8 ++++++++
 NEWS                |    3 +++
 lib/m4sugar/m4sh.m4 |   29 ++++++++++++++++-------------
 tests/m4sh.at       |   11 ++++++++++-
 4 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4429431..071b418 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2009-04-09  Eric Blake  <e...@byu.net>

+       Make AS_IF, AS_CASE, and AS_FOR more robust to blank arguments.
+       * lib/m4sugar/m4sh.m4 (_AS_CASE, _AS_CASE_DEFAULT, AS_FOR, _AS_IF)
+       (_AS_IF_ELSE, AS_IF): Avoid syntax error on blank argument.
+       * NEWS: Mention this.
+       * tests/m4sh.at (AS@&t...@_if and AS@&t...@_case, AS@&t...@_for): Update
+       tests.
+       Reported by Mike Frysinger.
+
        Add m4_blank and friends.
        * lib/m4sugar/m4sugar.m4 (m4_blank, m4_nblank, m4_default_nblank)
        (m4_default_nblank_quoted): New macros.
diff --git a/NEWS b/NEWS
index 0357cbd..8eb3a06 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ GNU Autoconf NEWS - User visible changes.
 * Major changes in Autoconf 2.64 (2009-??-??) [stable]
   Released by Eric Blake, based on git versions 2.63b.*.

+** AS_IF, AS_CASE, and AS_FOR have been taught to avoid syntax errors
+   even when given arguments that expand to just whitespace.
+
 ** Ensure AT_CHECK can support commands that include a # given with
    proper m4 quoting.  For shell comments, this is a new feature; for
    non-shell comments, this fixes a regression introduced in 2.63b.
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index 88881b1..b3dc63a 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -514,14 +514,16 @@ _AS_UNSET_PREPARE
 # | esac
 # The shell comments are intentional, to work around people who don't
 # realize the impacts of using insufficient m4 quoting.  This macro
-# always provides a default case, to work around a Solaris /bin/sh
-# bug regarding the exit status when no case matches.
+# always uses : and provides a default case, to work around Solaris
+# /bin/sh bugs regarding the exit status.
 m4_define([_AS_CASE],
 [ [...@%:@(]
-  $1[)] m4_default([$2], [:]) ;;])
+  $1[)] :
+    $2 ;;])
 m4_define([_AS_CASE_DEFAULT],
 [ [...@%:@(]
-  *[)] m4_default([$1], [:]) ;;])
+  *[)] :
+    $1 ;;])

 m4_defun([AS_CASE],
 [case $1 in[]m4_map_args_pair([_$0], [_$0_DEFAULT],
@@ -583,8 +585,8 @@ m4_defun([AS_FOR],
 [m4_pushdef([$1], m4_if([$3], [], [[$$2]], m4_translit([$3], ]dnl
 m4_dquote(_m4_defn([m4_cr_symbols2]))[[%+=:,./-]), [], [[$3]], [[$$2]]))]dnl
 [for $2[]m4_ifval([$3], [ in $3])
-do
-  m4_default([$4], [:])
+do :
+  $4
 done[]_m4_popdef([$1])])


@@ -602,17 +604,18 @@ done[]_m4_popdef([$1])])
 # with simplifications if IF-TRUE1 and/or IF-FALSE is empty.
 #
 m4_define([_AS_IF],
-[elif $1; then
-  m4_default([$2], [:])
+[elif $1; then :
+  $2
 ])
 m4_define([_AS_IF_ELSE],
-[m4_ifvaln([$1],
-[else
-  $1])])
+[m4_ifnblank([$1],
+[else :
+  $1
+])])

 m4_defun([AS_IF],
-[if $1; then
-  m4_default([$2], [:])
+[if $1; then :
+  $2
 m4_map_args_pair([_$0], [_$0_ELSE], m4_shift2($@))]dnl
 [fi[]])# AS_IF

diff --git a/tests/m4sh.at b/tests/m4sh.at
index def63aa..fecb59a 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -859,6 +859,11 @@ rm -f file
 AS_CASE([`touch file; false`]) && test -f file && echo fifteen
 dnl The next line is badly underquoted; don't intentionally copy this style.
 AS_CASE([foo], [foo], m4_do(AS_CASE([bar], [bar], [echo sixteen])))
+dnl Handle blank arguments.
+AS_IF([false], [:], [ ]) && AS_CASE([foo], [foo], []
+) && echo seventeen
+m4_define([empty])AS_IF([false], [:], [empty]
+) && AS_CASE([foo], [foo], [empty]) && echo eighteen

 # check that require works correctly
 m4_for([n], 1, 9, [],
@@ -911,6 +916,8 @@ thirteen
 fourteen
 fifteen
 sixteen
+seventeen
+eighteen
 foo1=1 bar1=1
 foo2=2 bar2=
 foo3=3 bar3=
@@ -979,13 +986,15 @@ AS_FOR([m4var], [shvar], ['$list'],
 AS_FOR([m4var], [shvar], [\'],
 [echo "m4var $shvar"])

-# Syntax checks: cope with empty arguments.
+# Syntax checks: cope with empty/blank arguments.
 set f g
 AS_FOR([], [shvar], [],
 [echo "m4_defn([]) $shvar"])
 rm -f file
 AS_FOR([], [shvar], [`touch file`])
 test -f file || exit 1
+AS_FOR([], [shvar], [], [ ])
+m4_define([empty])AS_FOR([], [shvar], [], [empty])

 # Check that break works.
 while :
-- 
1.6.1.2

Reply via email to