]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
maint: pick XSI funcs at runtime, not configure time.
authorGary V. Vaughan <gary@gnu.org>
Sat, 19 Nov 2011 13:54:43 +0000 (20:54 +0700)
committerGary V. Vaughan <gary@gnu.org>
Tue, 2 Oct 2012 14:02:50 +0000 (21:02 +0700)
Determine, on a function by function basis, what XSI features
are available in the shell that is actually running the script,
rather than the one that was picked at configure time by the
re-execution engine.
* m4/libtool.m4 (_LT_PROG_FUNCTION_REPLACE)
(_LT_PROG_REPLACE_SHELLFNS): Remove.
(_LT_CHECK_SHELL_FEATURES): Remove tests for XSI and += support.
* build-aux/general.m4sh (func_append, func_append_quoted)
(func_arith, func_len, func_basename, func_dirname)
(func_dirname_and_basename, func_stripname): List both enhanced
and fallback implementations, and choose one based on whether
the enhanced features required by the fastest version are
available.
* build-aux/getopt.m4sh (func_split_short_opt)
(func_split_long_opt): Ditto.
* build-aux/ltmain.m4sh (func_lo2o, func_xform): Ditto.
* tests/getopt-m4sh.at: Add tests for enhanced and fallback
implementations of func_arith, func_len, func_stripname and
func_dirname_and_basename.
* NEWS: Updated.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
NEWS
build-aux/general.m4sh
build-aux/getopt.m4sh
build-aux/ltmain.m4sh
m4/libtool.m4
tests/getopt-m4sh.at

diff --git a/NEWS b/NEWS
index 0479a3490af609cd41a0f1d2b7cb1bec9b7b8d0e..ecd4fa10da9e38b7f6b81b10480c551224c4e545 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -49,6 +49,10 @@ NEWS - list of user-visible changes between releases of GNU Libtool
     mode is selected; `--standalone' never worked, and is no longer
     accepted.
   - Libtool and libtoolize no longer choke on paths with a comma in them.
+  - In the case where $SHELL does not have the same enhanced features
+    (e.g. the ability to parse `var+=append') as $CONFIG_SHELL, libtool
+    will now correctly fallback to using only vanilla shell features
+    instead of failing with a parse at startup.
 
 ** Important incompatible changes:
 
index 007e6a6bce49f360fa7ed5871e88f6bb5a6cca5d..8c0b6547b3716307889c54f4b1b2abe564bf1a56 100644 (file)
@@ -74,62 +74,139 @@ dirname='s|/[^/]*$||'
 basename='s|^.*/||'
 
 
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
+# lt_HAVE_PLUSEQ_OP
+# Can be empty, in which case the shell is probed, "yes" if += is useable
+# or anything else if += does not work.
+# NOTE: You can short-circuit the fork and test on every invocation (e.g.
+# on Windows where fork emulations are unreasonably slow) by setting this
+# in the environment of this script.
+test -z "$lt_HAVE_PLUSEQ_OP" \
+    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+    && lt_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$lt_HAVE_PLUSEQ_OP"; then
+  # func_append var value
+  # Append VALUE to the end of shell variable VAR.
+  eval 'func_append ()
+  {
+    eval "$1+=\$2"
+  }'
+
+  # func_append_quoted var value
+  # Quote VALUE and append to the end of shell variable VAR, separated
+  # by a space.
+  eval 'func_append_quoted ()
+  {
+    func_quote_for_eval "$2"
+    eval "$1+=\\ \$func_quote_for_eval_result"
+  }'
+else
+  func_append ()
+  {
     eval "$1=\$$1\$2"
-} # func_append may be replaced by extended shell implementation
+  }
 
-
-# func_append_quoted var value
-# Quote VALUE and append to the end of shell variable VAR, separated
-# by a space.
-func_append_quoted ()
-{
+  func_append_quoted ()
+  {
     func_quote_for_eval "$2"
     eval "$1=\$$1\\ \$func_quote_for_eval_result"
-} # func_append_quoted may be replaced by extended shell implementation
+  }
+fi
 
 
+# lt_HAVE_ARITH_OP
+# Can be empty, in which case the shell is probed, "yes" if $((...)) is
+# useable or anything else if it does not work.
+# NOTE: You can short-circuit the fork and test on every invocation (e.g.
+# on Windows where fork emulations are unreasonably slow) by setting this
+# in the environment of this script.
+test -z "$lt_HAVE_ARITH_OP" \
+    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+    && lt_HAVE_ARITH_OP=yes
+
 # func_arith arithmetic-term...
-func_arith ()
-{
+if test yes = "$lt_HAVE_ARITH_OP"; then
+  eval 'func_arith ()
+  {
+    func_arith_result=$(( $* ))
+  }'
+else
+  func_arith ()
+  {
     func_arith_result=`expr "$@"`
-} # func_arith may be replaced by extended shell implementation
+  }
+fi
+
+
+# lt_HAVE_XSI_OPS
+# Can be empty, in which case the shell is probed, "yes" if XSI length
+# and matching operators are useable or anything else if they do not work.
+# NOTE: You can short-circuit the fork and test on every invocation (e.g.
+# on Windows where fork emulations are unreasonably slow) by setting this
+# in the environment of this script.
+test -z "$lt_HAVE_XSI_OPS" \
+    && (eval 'x=a/b/c;
+      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+    && lt_HAVE_XSI_OPS=yes
 
 
 # func_len string
 # STRING may not start with a hyphen.
-func_len ()
-{
+if test yes = "$lt_HAVE_XSI_OPS"; then
+  eval 'func_len ()
+  {
+    func_len_result=${#1}
+  }'
+else
+  func_len ()
+  {
     func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
-} # func_len may be replaced by extended shell implementation
+  }
+fi
 
 
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
-    func_dirname_result=`$ECHO "$1" | $SED "$dirname"`
-    if test "X$func_dirname_result" = "X$1"; then
-      func_dirname_result=$3
-    else
-      func_append func_dirname_result $2
-    fi
-} # func_dirname may be replaced by extended shell implementation
+if test yes = "$lt_HAVE_XSI_OPS"; then
+  # If this shell supports suffix pattern removal, then use it to avoid
+  # forking. Hide the definitions single quotes in case the shell chokes
+  # on unsupported syntax...
+
+  _b='func_basename_result=${1##*/}'
+  _d='case $1 in
+        */*) func_dirname_result=${1%/*}$2 ;;
+        *  ) func_dirname_result=$3        ;;
+      esac'
+
+else
+  # ...otherwise fall back to using sed.
+
+  _b='func_basename_result=`$ECHO "$1" |$SED "$basename"`'
+  _d='func_dirname_result=`$ECHO "$1"  |$SED "$dirname"`
+      if test "X$func_dirname_result" = "X$1"; then
+        func_dirname_result=$3
+      else
+        func_append func_dirname_result "$2"
+      fi'
+fi
 
 
 # func_basename file
-func_basename ()
+eval 'func_basename ()
 {
-    func_basename_result=`$ECHO "$1" | $SED "$basename"`
-} # func_basename may be replaced by extended shell implementation
+    $debug_cmd
+    '"$_b"'
+}'
 
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+    $debug_cmd
+    '"$_d"'
+}'
 
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
+# func_dirname_and_basename file append nondir_replacement perform
+# func_basename and func_dirname in a single function
 # call:
 #   dirname:  Compute the dirname of FILE.  If nonempty,
 #             add APPEND to the result, otherwise set result
@@ -137,20 +214,14 @@ func_basename ()
 #             value returned in "$func_dirname_result"
 #   basename: Compute filename of FILE.
 #             value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
 {
-    # Extract subdirectory from the argument.
-    func_dirname_result=`$ECHO "$1" | $SED -e "$dirname"`
-    if test "X$func_dirname_result" = "X$1"; then
-      func_dirname_result=$3
-    else
-      func_append func_dirname_result $2
-    fi
-    func_basename_result=`$ECHO "$1" | $SED -e "$basename"`
-} # func_dirname_and_basename may be replaced by extended shell implementation
+    $debug_cmd
+    '"$_b"'
+    '"$_d"'
+}'
 
 
 # func_stripname prefix suffix name
@@ -159,13 +230,24 @@ func_dirname_and_basename ()
 # characters, hashes, percent signs, but SUFFIX may contain a leading
 # dot (in which case that matches only a dot).
 # func_strip_suffix prefix name
-func_stripname ()
-{
+if test yes = "$lt_HAVE_XSI_OPS"; then
+  eval 'func_stripname ()
+  {
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary variable first.
+    func_stripname_result=$3
+    func_stripname_result=${func_stripname_result#"$1"}
+    func_stripname_result=${func_stripname_result%"$2"}
+  }'
+else
+  func_stripname ()
+  {
     case $2 in
       .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;;
       *)  func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;;
     esac
-} # func_stripname may be replaced by extended shell implementation
+  }
+fi
 
 
 # These SED scripts presuppose an absolute path with a trailing slash.
index 27a8352df15e9c689d15f4aff88589b00606af76..e5e97714f0ad7370ba44a6d6cb537f247d035acf 100644 (file)
@@ -618,30 +618,49 @@ func_missing_arg ()
 }
 
 
-# func_split_short_opt shortopt
-# Set func_split_short_opt_name and func_split_short_opt_arg shell
-# variables after splitting SHORTOPT after the 2nd character.
-func_split_short_opt ()
-{
+# If this shell supports prefix and suffix pattern removal, then
+# use them to avoid forking. Hide the definition in an eval in case
+# the shell chokes on unsupported syntax...
+if test yes = "$lt_HAVE_XSI_OPS"; then
+  # func_split_short_opt shortopt
+  # Set func_split_short_opt_name and func_split_short_opt_arg shell
+  # variables after splitting SHORTOPT after the 2nd character.
+  eval 'func_split_short_opt ()
+  {
+    $debug_cmd
+
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+  }'
+
+  # func_split_long_opt longopt
+  # Set func_split_long_opt_name and func_split_long_opt_arg shell
+  # variables after splitting LONGOPT at the `=' sign.
+  eval 'func_split_long_opt ()
+  {
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}
+  }'
+else
+  # ...otherwise fall back to using sed.
+  func_split_short_opt ()
+  {
     my_sed_short_opt='1s/^\(..\).*$/\1/;q'
     my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
 
     func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
     func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
-} # func_split_short_opt may be replaced by extended shell implementation
+  }
 
-
-# func_split_long_opt longopt
-# Set func_split_long_opt_name and func_split_long_opt_arg shell
-# variables after splitting LONGOPT at the `=' sign.
-func_split_long_opt ()
-{
+  func_split_long_opt ()
+  {
     my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
     my_sed_long_arg='1s/^--[^=]*=//'
 
     func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
     func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
-} # func_split_long_opt may be replaced by extended shell implementation
+  }
+fi
 
 exit_cmd=:
 ]])
index 657007288c67e49dade345b666775aeae8555545..623c0f669f4cea770db7b9ebfeb9c26d48f079bf 100644 (file)
@@ -149,18 +149,36 @@ extracted_serial=0
 exec_cmd=
 
 
-# func_lo2o object
-func_lo2o ()
-{
-    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
-} # func_lo2o may be replaced by extended shell implementation
+# If this shell supports prefix and suffix pattern removal, then
+# use them to avoid forking. Hide the definition in an eval in case
+# the shell chokes on unsupported syntax...
+if test yes = "$lt_HAVE_XSI_OPS"; then
+  # func_lo2o object
+  eval 'func_lo2o ()
+  {
+    case $1 in
+      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+      *   ) func_lo2o_result=$1               ;;
+    esac
+  }'
 
+  # func_xform libobj-or-source
+  eval 'func_xform ()
+  {
+    func_xform_result=${1%.*}.lo
+  }'
+else
+  # ...otherwise fall back to using sed.
+  func_lo2o ()
+  {
+    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+  }
 
-# func_xform libobj-or-source
-func_xform ()
-{
-    func_xform_result=`$ECHO "$1" | $SED 's/\.[^.]*$/.lo/'`
-} # func_xform may be replaced by extended shell implementation
+  func_xform ()
+  {
+    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+  }
+fi
 
 
 # func_fatal_configuration arg...
index 8690e8dbebebc9122f9d98c9492a396c62ce99ac..417ebe463ea53558d81bbdd6903fd5b1f2964810 100644 (file)
@@ -756,8 +756,6 @@ _LT_EOF
   sed '$q' "$ltmain" >> "$cfgfile" \
      || (rm -f "$cfgfile"; exit 1)
 
-  _LT_PROG_REPLACE_SHELLFNS
-
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
@@ -7776,27 +7774,7 @@ dnl AC_DEFUN([LT_AC_PROG_SED], [])
 # Find out whether the shell is Bourne or XSI compatible,
 # or has some other useful features.
 m4_defun([_LT_CHECK_SHELL_FEATURES],
-[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
-# Try some XSI features
-xsi_shell=no
-( _lt_dummy=a/b/c
-  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
-      = c,a/b,b/c, \
-    && eval 'test 2 -eq $(( 1 + 1 )) \
-    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
-  && xsi_shell=yes
-AC_MSG_RESULT([$xsi_shell])
-_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
-
-AC_MSG_CHECKING([whether the shell understands "+="])
-lt_shell_append=no
-( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test barbaz = "$foo" ) \
-    >/dev/null 2>&1 \
-  && lt_shell_append=yes
-AC_MSG_RESULT([$lt_shell_append])
-_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
-
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   lt_unset=unset
 else
   lt_unset=false
@@ -7820,99 +7798,6 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
 ])# _LT_CHECK_SHELL_FEATURES
 
 
-# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
-# ------------------------------------------------------
-# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
-# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
-m4_defun([_LT_PROG_FUNCTION_REPLACE],
-[dnl {
-sed -e '/^$1 ()$/,/^} # $1 /c\
-$1 ()\
-{\
-m4_bpatsubsts([$2], [$], [\\], [^\([    ]\)], [\\\1])
-} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
-  && mv -f "$cfgfile.tmp" "$cfgfile" \
-    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
-test 0 -eq $? || _lt_function_replace_fail=:
-])
-
-
-# _LT_PROG_REPLACE_SHELLFNS
-# -------------------------
-# Replace existing portable implementations of several shell functions with
-# equivalent extended shell implementations where those features are available..
-m4_defun([_LT_PROG_REPLACE_SHELLFNS],
-[if test yes = "$xsi_shell"; then
-  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
-    case @S|@1 in
-      */*) func_dirname_result=${1%/*}@S|@2 ;;
-      *  ) func_dirname_result=@S|@3 ;;
-    esac])
-
-  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
-    func_basename_result=${1##*/}])
-
-  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
-    case @S|@1 in
-      */*) func_dirname_result=${1%/*}@S|@2 ;;
-      *  ) func_dirname_result=@S|@3 ;;
-    esac
-    func_basename_result=${1##*/}])
-
-  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
-    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
-    # positional parameters, so assign one to ordinary parameter first.
-    func_stripname_result=@S|@3
-    func_stripname_result=${func_stripname_result#"@S|@1"}
-    func_stripname_result=${func_stripname_result%"@S|@2"}])
-
-  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
-    func_split_long_opt_name=${1%%=*}
-    func_split_long_opt_arg=${1#*=}])
-
-  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
-    func_split_short_opt_arg=${1#??}
-    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
-
-  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
-    case @S|@1 in
-      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
-      *)    func_lo2o_result=@S|@1 ;;
-    esac])
-
-  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
-
-  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
-
-  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
-fi
-
-if test yes = "$lt_shell_append"; then
-  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "@S|@1+=\\@S|@2"])
-
-  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
-    func_quote_for_eval "@S|@2"
-dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
-    eval "@S|@1+=\\\\ \\$func_quote_for_eval_result"])
-
-  # Save a `func_append' function call where possible by direct use of '+='
-  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
-    && mv -f "$cfgfile.tmp" "$cfgfile" \
-      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
-  test 0 -eq $? || _lt_function_replace_fail=:
-else
-  # Save a `func_append' function call even when '+=' is not available
-  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
-    && mv -f "$cfgfile.tmp" "$cfgfile" \
-      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
-  test 0 -eq $? || _lt_function_replace_fail=:
-fi
-
-if test : = "$_lt_function_replace_fail"; then
-  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
-fi
-])
-
 # _LT_PATH_CONVERSION_FUNCTIONS
 # -----------------------------
 # Determine which file name conversion functions should be used by
index 81160db15e67fe3692d5efb8bf06a99d8af71d72..370eb0ffdf0b69a67b4fb99c0c84dd93029242ed 100644 (file)
@@ -40,9 +40,22 @@ M4SH_GETOPTS(
   [a!],        [--append],     [],     [func_append list "$optarg$nl"],
   [f], [--force],      [],     [opts="$opts force"],
   [i], [--install],    [],     [opts="$opts install"],
+  [l;],        [--length],     [],     [],
+  [p!],        [--path],       [],     [func_dirname_and_basename "$optarg"],
   [v], [--verbose],    [],     [opts="$opts verbose"],
   [!], [--ltdl],       [false],[opts="$opts ltdl=$optarg"],
-[echo "$list" $opts])
+[test -z "$opt_length" || {
+  for s in $opt_length; do
+    func_len "$s"
+    func_arith ${len-0} + $func_len_result; len=$func_arith_result
+  done
+  echo len=$len
+}
+test -z "$opt_path" || {
+  func_stripname b_ .d "$func_basename_result"
+  echo "$func_dirname_result:$func_stripname_result"
+}
+test -z "$list$opts" || echo "$list" $opts])
 ]])
 m4_pattern_forbid([m4_include])
 m4_pattern_forbid([AS_INIT])
@@ -53,22 +66,11 @@ $SED "s|@LN_S\@|$LN_S|g;s|@SED\@|$SED|g" t-options > options
 ])# _LT_AT_GETOPT_M4SH_SETUP
 
 
-# _LT_AT_EXTENDED_SHELL_FUNC_EXTRACT(FUNC-NAME)
-# ---------------------------------------------
-# Extract the 'Extended-shell'-decorated function FUNC-NAME from libtool
-m4_define([_LT_AT_XSI_FUNC_EXTRACT],
-[dnl {{
-$SED '/^# $1/q' options > options.tmp
-$SED -n '/^$1 ()/,/^} # Extended-shell $1 /p' $abs_top_builddir/libtool >> options.tmp
-$SED '1,/^} # $1 /d' options >> options.tmp
-rm -f options && mv options.tmp options])
-
-
 ## ----------------------- ##
 ## Short option splitting. ##
 ## ----------------------- ##
 
-AT_SETUP([short option splitting])
+AT_SETUP([fallback short option splitting])
 
 AT_DATA(expout,
 [[ force verbose install
@@ -76,22 +78,18 @@ AT_DATA(expout,
 
 _LT_AT_GETOPT_M4SH_SETUP
 
-AT_CHECK([$SHELL ./options -fvi], 0, [expout])
+AT_CHECK([lt_HAVE_XSI_OPS=no $SHELL ./options -fvi], 0, [expout])
 
 AT_CLEANUP
 
 
-AT_SETUP([enhanced shell short option splitting])
-
-# Don't bother with additional XSI checks unless functions were substituted
-AT_CHECK([fgrep '@%:@ Extended-shell func_split_short_opt' $abs_top_builddir/libtool >/dev/null 2>&1 || (exit 77)])
+AT_SETUP([enhanced short option splitting])
 
 AT_DATA(expout,
 [[ force verbose install
 ]])
 
 _LT_AT_GETOPT_M4SH_SETUP
-_LT_AT_XSI_FUNC_EXTRACT(func_split_short_opt)
 
 AT_CHECK([$SHELL ./options -fvi], 0, [expout])
 
@@ -102,7 +100,7 @@ AT_CLEANUP
 ## Long option splitting. ##
 ## ---------------------- ##
 
-AT_SETUP([long option splitting])
+AT_SETUP([fallback long option splitting])
 
 AT_DATA(expout,
 [[ ltdl=long
@@ -110,22 +108,18 @@ AT_DATA(expout,
 
 _LT_AT_GETOPT_M4SH_SETUP
 
-AT_CHECK([$SHELL ./options --ltdl=long], 0, [expout])
+AT_CHECK([lt_HAVE_XSI_OPS=no $SHELL ./options --ltdl=long], 0, [expout])
 
 AT_CLEANUP
 
 
-AT_SETUP([XSI long option splitting])
-
-# Don't bother with additional XSI checks unless functions were substituted
-AT_CHECK([fgrep '@%:@ Extended-shell func_split_long_opt' $abs_top_builddir/libtool >/dev/null 2>&1 || (exit 77)])
+AT_SETUP([enhanced long option splitting])
 
 AT_DATA(expout,
 [[ ltdl=long
 ]])
 
 _LT_AT_GETOPT_M4SH_SETUP
-_LT_AT_XSI_FUNC_EXTRACT(func_split_long_opt)
 
 AT_CHECK([$SHELL ./options --ltdl=long], 0, [expout])
 
@@ -136,7 +130,7 @@ AT_CLEANUP
 ## Option appending. ##
 ## ----------------- ##
 
-AT_SETUP([option appending])
+AT_SETUP([fallback option appending])
 
 AT_DATA(expout,
 [[first   --append second
@@ -146,15 +140,12 @@ third
 
 _LT_AT_GETOPT_M4SH_SETUP
 
-AT_CHECK([$SHELL ./options -a "first   --append second" -athird], 0, [expout])
+AT_CHECK([lt_HAVE_PLUSEQ_OP=no $SHELL ./options -a "first   --append second" -athird], 0, [expout])
 
 AT_CLEANUP
 
 
-AT_SETUP([enhanced shell option appending])
-
-# Don't bother with additional += check unless functions were substituted
-AT_CHECK([fgrep '@%:@ Extended-shell func_append ' $abs_top_builddir/libtool >/dev/null 2>&1 || (exit 77)])
+AT_SETUP([enhanced option appending])
 
 AT_DATA(expout,
 [[first   --append second
@@ -163,8 +154,67 @@ third
 ]])
 
 _LT_AT_GETOPT_M4SH_SETUP
-_LT_AT_XSI_FUNC_EXTRACT(func_append)
 
 AT_CHECK([$SHELL ./options -a "first   --append second" -athird], 0, [expout])
 
 AT_CLEANUP
+
+
+## ----------------- ##
+## Shell arithmetic. ##
+## ----------------- ##
+
+AT_SETUP([fallback arithmetic])
+
+AT_DATA(expout,
+[[len=9
+]])
+
+_LT_AT_GETOPT_M4SH_SETUP
+
+AT_CHECK([lt_HAVE_ARITH_OP=no $SHELL ./options -l short --length long], 0, [expout])
+
+AT_CLEANUP
+
+
+AT_SETUP([enhanced arithmetic])
+
+AT_DATA(expout,
+[[len=9
+]])
+
+_LT_AT_GETOPT_M4SH_SETUP
+
+AT_CHECK([$SHELL ./options -l short --length long], 0, [expout])
+
+AT_CLEANUP
+
+
+## ------------- ##
+## Path slicing. ##
+## ------------- ##
+
+AT_SETUP([fallback path slicing])
+
+AT_DATA(expout,
+[[a:c
+]])
+
+_LT_AT_GETOPT_M4SH_SETUP
+
+AT_CHECK([lt_HAVE_XSI_OPS=no $SHELL ./options -p a/b_c.d], 0, [expout])
+
+AT_CLEANUP
+
+
+AT_SETUP([enhanced path slicing])
+
+AT_DATA(expout,
+[[a:c
+]])
+
+_LT_AT_GETOPT_M4SH_SETUP
+
+AT_CHECK([$SHELL ./options -p a/b_c.d], 0, [expout])
+
+AT_CLEANUP