]> 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>
Thu, 8 Dec 2011 08:56:49 +0000 (15:56 +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 eeda222ad3d475b05f6d0365481f6ee03e37fb31..252b2d2c02bf11269a127800a39ce9d6ccc98797 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 b88c9840cf65e2e811d5e784efce8d856926d989..922e9576f410e6b707ac9502cb21cd39363334b0 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 4be85a5210b785a68cfefd0a86289950659caec7..0eef323c5d3d34205d26d96efffcead3678283e1 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 "$foo" = barbaz ) \
-    >/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 x"$xsi_shell" = xyes; 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 x"$lt_shell_append" = xyes; 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 x"$_lt_function_replace_fail" = x":"; 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