+2009-04-13 Eric Blake <ebb9@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-13 Eric Blake <ebb9@byu.net>
Finish upgrade to GFDL 1.3.
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.*.
@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
# 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.
# 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)
# -------------
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. ##
## --------- ##