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