* tests/m4sh.at (Null variable substitution): New test.
* doc/autoconf.texi (Shell Substitutions) <${var:-value}>: Mention
that m4sh guarantees support.
(Limitations of Usual Tools) <mktemp>: Use it.
* lib/m4sugar/m4sh.m4 (AS_LINENO_POP, AS_VAR_IF, AS_TMPDIR):
Exploit use of colon for smaller files.
Signed-off-by: Eric Blake <eblake@redhat.com>
+2010-08-27 Eric Blake <eblake@redhat.com>
+
+ m4sh: assume ${a:-b} support
+ * tests/m4sh.at (Null variable substitution): New test.
+ * doc/autoconf.texi (Shell Substitutions) <${var:-value}>: Mention
+ that m4sh guarantees support.
+ (Limitations of Usual Tools) <mktemp>: Use it.
+ * lib/m4sugar/m4sh.m4 (AS_LINENO_POP, AS_VAR_IF, AS_TMPDIR):
+ Exploit use of colon for smaller files.
+
2010-08-26 Eric Blake <eblake@redhat.com>
docs: document m4_define_default
Old BSD shells, including the Ultrix @code{sh}, don't accept the
colon for any shell substitution, and complain and die.
Similarly for $@{@var{var}:=@var{value}@}, $@{@var{var}:?@var{value}@}, etc.
+However, all shells that support functions allow the use of colon in
+shell substitution, and since m4sh requires functions, you can portably
+use null variable substitution patterns in configure scripts.
@item $@{@var{var}+@var{value}@}
@cindex $@{@var{var}+@var{value}@}
# Create a temporary directory $tmp in $TMPDIR (default /tmp).
# Use mktemp if possible; otherwise fall back on mkdir,
# with $RANDOM to make collisions less likely.
-: "$@{TMPDIR=/tmp@}"
+: "$@{TMPDIR:=/tmp@}"
@{
tmp=`
(umask 077 && mktemp -d "$TMPDIR/fooXXXXXX") 2>/dev/null
# -----------------------
# If this is call balances the outermost call to AS_LINENO_PUSH,
# AS_MESSAGE will restart printing $LINENO as the line number.
+#
+# No need to use AS_UNSET, since as_lineno is necessarily set.
m4_defun([AS_LINENO_POP],
-[eval $as_lineno_stack; test "x$as_lineno_stack" = x && AS_UNSET([as_lineno])])
+[eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno])
# it is a documented part of the public API and must not be changed.
m4_define([AS_TMPDIR],
[# Create a (secure) tmp directory for tmp files.
-m4_if([$2], [], [: "${TMPDIR=/tmp}"])
+m4_if([$2], [], [: "${TMPDIR:=/tmp}"])
{
tmp=`(umask 077 && mktemp -d "m4_default([$2],
[$TMPDIR])/$1XXXXXX") 2>/dev/null` &&
# Polymorphic, and avoids sh expansion error upon interrupt or term signal.
m4_define([AS_VAR_IF],
[AS_LITERAL_WORD_IF([$1],
- [AS_IF([test "x$$1" = x""$2]],
+ [AS_IF(m4_ifval([$2], [[test "x$$1" = x[]$2]], [[${$1:+false} :]])],
[AS_VAR_COPY([as_val], [$1])
- AS_IF([test "x$as_val" = x""$2]],
- [AS_IF([eval test \"x\$"$1"\" = x"_AS_ESCAPE([$2], [`], [\"$])"]]),
+ AS_IF(m4_ifval([$2], [[test "x$as_val" = x[]$2]], [[${as_val:+false} :]])],
+ [AS_IF(m4_ifval([$2],
+ [[eval test \"x\$"$1"\" = x"_AS_ESCAPE([$2], [`], [\"$])"]],
+ [[eval \${$1:+false} :]])]),
[$3], [$4])])
AT_CLEANUP
+## ---------------------------- ##
+## Null variable substitution. ##
+## ---------------------------- ##
+# According to http://www.in-ulm.de/~mascheck/bourne/, all shells with
+# functions also support `${a:-b}'.
+
+AT_SETUP([Null variable substitution])
+AT_KEYWORDS([m4sh])
+
+AT_DATA_M4SH([script.as],
+[[AS_INIT
+
+AS_UNSET([a])
+b=
+c=.
+case ${a:-x}${b:-y}${c:-z} in
+ xy.) ;;
+ *) exit 1 ;;
+esac
+case ${a-x}${b-y}${c-z} in
+ x.) ;;
+ *) exit 2 ;;
+esac
+
+case ${a+x}${b+y}${c+z} in
+ yz) ;;
+ *) exit 3 ;;
+esac
+case ${a:+x}${b:+y}${c:+z} in
+ z) ;;
+ *) exit 4 ;;
+esac
+
+case ${a=x}${b=y}${c=z} in
+ x.) ;;
+ *) exit 5 ;;
+esac
+AS_UNSET([a])
+case ${a:=x}${b:=y}${c:=z} in
+ xy.) ;;
+ *) exit 6 ;;
+esac
+case $a$b$c in
+ xy.) ;;
+ *) exit 7 ;;
+esac
+AS_UNSET([a])
+b=
+
+(: ${a?oops}; echo fail) 2>err && exit 8
+grep oops err >/dev/null || exit 9
+test "${b?oops}" = '' || exit 10
+test "${c?oops}" = . || exit 11
+(: ${a:?oops}; echo fail) 2>err && exit 12
+grep oops err >/dev/null || exit 13
+(: ${b:?oops}; echo fail) 2>err && exit 14
+grep oops err >/dev/null || exit 15
+test "${c:?oops}" = . || exit 16
+]])
+
+AT_CHECK_M4SH
+AT_CHECK([$CONFIG_SHELL ./script])
+
+AT_CLEANUP
## ------------------- ##