From 723c9e5c0f2c3aa7ef46534ad084974fa2282435 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 9 Apr 2009 07:05:00 -0600 Subject: [PATCH] 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 --- 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 efa20564..3c2b4a11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2009-04-13 Eric Blake + 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-13 Eric Blake + Finish upgrade to GFDL 1.3. * doc/autoconf.texi (copying): Use correct license; comment change was missed on 2008-11-04. diff --git a/NEWS b/NEWS index e91fc393..0357cbdb 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 8dd22d6e..fc4d6188 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -10988,25 +10988,74 @@ m4_cond([m4_index([$1], [\])], [-1], [$2], @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 8356d082..420fd998 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 6286af2d..2dd81dca 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. ## ## --------- ## -- 2.11.4.GIT