autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 5/5] m4sh: assume ${a:-b} support


From: Eric Blake
Subject: [PATCH 5/5] m4sh: assume ${a:-b} support
Date: Wed, 25 Aug 2010 17:18:21 -0600

* 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 <address@hidden>
---

This shaved off another 1k from coreutils' configure script (together
with 4/5, that's a 0.4% reduction).

The empty variable check, '${var:+false} :', requires the trailing :,
due to older zsh that had the bug of not resetting $? to 0 on an empty
command.

Any objections or comments before I push this?

Meanwhile, we've documented several shell bugs that appear to be
limited to Ultirx, such as redirecting the same fd more than once, and
have also documented that such bugs are no longer a portability
concern; we even have examples in autoconf code where we use the very
behavior documented as buggy, with no bug reports about it.  So, I'm
thinking that the next step is to assume that the Ultrix bug of
${a="$b"} setting the 8th-bit of all bytes in $a is no longer a
portability concern.  If so, we can simplify our recommendations on
how to portably set a variable to a default value.  The Solaris
/bin/sh bug of ${a='}'} when $a is already set is still real, however,
as is the issue of ${a+two words}; but in both cases, it is safe to
use $tmp='three } words'; ${a+$tmp}.  However, I have no idea if the
qnx bug 4.25 bug of $tmp='two words'; ${a=$tmp} setting $a to just
'words' is still present.

So, I think it IS worth a followup patch to add a shell snoop code for
those various variable defaulting issues, to see if anyone is still
using a system with working shell functions but either the Ultrix or
QNX bug.  If 2.68 doesn't uncover any such platform, then later
releases can start simplifying:

test "${a+set}" = set || a=value

into

tmp=value; : "${a=$tmp}"

for arbitrary values, and even shorter sequences when we know that
value does not contain } or whitespace.

 ChangeLog           |   10 ++++++++
 doc/autoconf.texi   |    5 +++-
 lib/m4sugar/m4sh.m4 |   16 +++++++++---
 tests/m4sh.at       |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f7a06a7..eb168e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2010-08-25  Eric Blake  <address@hidden>

+       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-25  Eric Blake  <address@hidden>
+
        m4sh: reduce size of AS_VAR_TEST_SET
        * lib/m4sugar/m4sh.m4 (AS_VAR_TEST_SET): Make more compact.

diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index c1e86c0..efe3aa5 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -15395,6 +15395,9 @@ Shell Substitutions
 Old BSD shells, including the Ultrix @code{sh}, don't accept the
 colon for any shell substitution, and complain and die.
 Similarly for address@hidden@var{var}:address@hidden@}, 
address@hidden@var{var}:address@hidden@}, 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 address@hidden@address@hidden@}
 @cindex address@hidden@address@hidden@}
@@ -18290,7 +18293,7 @@ Limitations of Usual Tools
 # 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.
-: "address@hidden/address@hidden"
+: "address@hidden:=/address@hidden"
 @{
   tmp=`
     (umask 077 && mktemp -d "$TMPDIR/fooXXXXXX") 2>/dev/null
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index facd70d..ead7b14 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -859,8 +859,10 @@ m4_defun([AS_LINENO_PUSH],
 # -----------------------
 # 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])



@@ -1617,7 +1619,11 @@ m4_define([_AS_LITERAL_HEREDOC_IF_NO], [$2])
 # which name is inspired by PREFIX (should be 2-4 chars max).
 m4_define([AS_TMPDIR],
 [# Create a (secure) tmp directory for tmp files.
+<<<<<<< Updated upstream
 m4_if([$2], [], [: "${TMPDIR=/tmp}"])
+=======
+m4_if([$2], [], [: ${TMPDIR:=/tmp}])
+>>>>>>> Stashed changes
 {
   as_tmp=`(umask 077 && mktemp -d "m4_default([$2],
     [$TMPDIR])/$1XXXXXX") 2>/dev/null` &&
@@ -1981,10 +1987,12 @@ m4_define([AS_VAR_GET],
 # 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])])


diff --git a/tests/m4sh.at b/tests/m4sh.at
index de2bdc9..e73c971 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -552,7 +552,71 @@ AT_CHECK([$CONFIG_SHELL ./script])

 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


 ## ------------------- ##
-- 
1.7.2.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]