libtool-commit
[Top][All Lists]
Advanced

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

[SCM] GNU Libtool branch, master, updated. v2.4.6-19-gaabc46a


From: Pavel Raiskup
Subject: [SCM] GNU Libtool branch, master, updated. v2.4.6-19-gaabc46a
Date: Wed, 04 Nov 2015 06:19:54 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Libtool".

The branch, master has been updated
       via  aabc46ac1bee0bf79e0185f70eb58df8568f37af (commit)
       via  dc8bd92d5faae8b587f525f54929cf9d9fae9eee (commit)
       via  a3c6e99c9cde0f786fa3df88360c84cf33ddc278 (commit)
       via  f323f10d2ba8b0ae55232a4beebb46b6f914a429 (commit)
       via  ed4f739f62f261c0dd759426fce3d7801fb0721a (commit)
       via  9187e9a231e0a06cc29c336857e95f07f855b2c9 (commit)
       via  16dbc070d32e6d4601cb5878dfdf69f2e29c84e1 (commit)
       via  32f0df9835ac15ac17e04be57c368172c3ad1d19 (commit)
      from  b7b6ec33baa4747eb147e9e249e675e477d861f4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit aabc46ac1bee0bf79e0185f70eb58df8568f37af
Author: Pavel Raiskup <address@hidden>
Date:   Mon Nov 2 14:54:11 2015 +0100

    gl/tests: new tests for options-parser
    
    * gl/build-aux/options-parser (func_parse_options): Put the info
    message 'enabling shell trace mode' on stderr.
    * gl/modules/options-parser-tests: New test module.
    * gl/tests/test-option-parser.sh: New test-case.
    * gl/tests/test-option-parser-helper: New test-case helper.
    * bootstrap: Sync with option-parser.

commit dc8bd92d5faae8b587f525f54929cf9d9fae9eee
Author: Pavel Raiskup <address@hidden>
Date:   Sun Nov 1 21:43:31 2015 +0100

    gl/funclib.sh: func_quotefast_eval & tilde fix
    
    Testsuite detected that printf built-in in Bash up to 4.2 was not
    able to properly escape tilde.
    
    * gl/build-aux/funclib.sh (func_quote_for_eval): If printf
    supports -v option, test also whether we properly escape tilde.
    With Bash <= 4.2, call func_quote_portable with ~* strings.
    * bootstrap: Sync with funclib.sh.

commit a3c6e99c9cde0f786fa3df88360c84cf33ddc278
Author: Pavel Raiskup <address@hidden>
Date:   Sat Oct 31 15:49:01 2015 +0100

    syntax-check: fix sed syntax errors
    
    Multi-line single-quoted shell arguments defined within makefile
    rules end up having the trailing backslash.  This caused problem
    in some sc_* rules as GNU sed does not interpret trailing
    backslash the same way as SHELL (== appending next line).
    Switching to double quotes means that SHELL will remove the
    trailing backslash for subsequent sed call.  This silences a lot
    of GNU sed warnings seen before like:
    
      sed: -e expression #1, char 96: unterminated address regex
    
    * cfg.mk (sc_libtool_m4_cc_basename): Use $(SED) instead of sed,
    use double quotes for sed's multi-line argument.
    (sc_prohibit_set_dummy_without_shift): Likewise.
    (sc_prohibit_test_const_follows_var): Likewise.

commit f323f10d2ba8b0ae55232a4beebb46b6f914a429
Author: Pavel Raiskup <address@hidden>
Date:   Sat Oct 31 14:33:18 2015 +0100

    gl/tests: new tests for func_quote* family
    
    * gl/modules/funclib.sh-tests: New test module.
    * gl/modules/all-shells-tests: New test (helper) module.
    * gl/tests/test-funclib-quote.sh: New test case.
    * gl/tests/test-all-shells.sh: New gl test helper.
    * cfg.mk (sc_useless_braces_in_variable_derefs): Whitelist
    new test-funclib-quote.sh as the pattern is used there
    intentionally.
    (sc_space_tab): Likewise.
    (sc_useless_braces_in_variable_derefs): Remove /cvsu pattern as
    the file is not used with git.
    (sc_prohibit_command_in_subst): New checker.

commit ed4f739f62f261c0dd759426fce3d7801fb0721a
Author: Pavel Raiskup <address@hidden>
Date:   Mon Oct 12 22:52:29 2015 +0200

    check: enable gnulib's testsuite
    
    * Makefile.am (SUBDIRS): Add gnulib-tests.
    (EXTRA_DIST): Distribute also update-copyright script.  This does
    not happen automatically because we manually remove ./lib
    directory created by gnulib-tool.  Not having the file distributed
    causes 'make check' failure, however.
    (dotversion): Fix to point to $(top_srcdir).
    * bootstrap.conf (gnulib_tool_options): Add gnulib-tool args
    needed to successfully install gnulib's tests.
    * configure.ac (CONFIG_STATUS_DEPENDENCIES): Look for .version in
    $(top_srcdir).
    * gnulib: Sync with upstream.
    * build-aux/.gitignore: Ignore ar-lib coming from automake.

commit 9187e9a231e0a06cc29c336857e95f07f855b2c9
Author: Pavel Raiskup <address@hidden>
Date:   Sun Oct 11 14:35:15 2015 +0200

    funclib: refactor quoting methods a bit
    
    From now we have two basic functions to perform string quoting for
    shell evaluation -- 'func_quote_arg' to quote one argument and
    'func_quote' which takes list of arguments to be quoted.
    
    New function name-scheme should be more descriptive (previously we
    called func_quote_for_eval with one argument and also multiple
    arguments, while we had confusing
    $func_quote_for_eval_unquoted_result which is redundant for
    multiple-arguments call).
    
    New abstraction allowed us (in an easy way) to implement
    bash-specific optimization for quoting  (using
    'printf -v VARNAME %q "$value"', suggested by Eric Blake), this
    construct may be used on those places where we don't care much
    about the result aesthetics (its thus not useful for '*.la'
    generation or for error printing).
    
    * gl/build-aux/funclib.sh (func_append_quoted): Use
    func_quote_arg internally (kept in 'pretty' mode for now).
    (func_quote): Made to be "main" high-level quoting method taking
    list of arguments to be quoted into single command.  It replaces
    func_quote_for_{expand,eval}.
    (func_quote_portable): Implements quoting in shell, falling back
    to portable sed call (rare cases).
    (func_quotefast_eval): New internal function using fast
    bash-specific construct, falling back to func_quote_portable for
    non-Bash scripts.
    (func_quote_arg): New function to quote one argument.
    (func_quote_for_eval): Removed.  All callers changed to call
    func_quote.
    (func_quote_for_expand): Likewise.
    * bootstrap: Sync with funclib.sh and options-parser.

commit 16dbc070d32e6d4601cb5878dfdf69f2e29c84e1
Author: Pavel Raiskup <address@hidden>
Date:   Mon Oct 5 13:16:08 2015 +0200

    libtool: optimizing options-parser hooks
    
    Its not necessary to (re)func_quote_for_eval in each function in
    the hook hierarchy.  Usually it is enough if the leaf function
    does func_quote_for_eval and its caller just re-uses the
    <CALLEE>_return variable.
    
    This is follow up for the previous commit.
    
    * gl/build-aux/options-parser (func_run_hooks): Propagate
    $EXIT_SUCCESS return code down to caller if *any* hook succeeded.
    Never re-quote the result -- either the arguments are left
    untouched, or the options have already been properly quoted by
    succeeding hooks.
    (func_parse_options): Quote '$@' and return $EXIT_SUCCESS only if
    we changed something.
    (func_validate_options): Likewise.
    (func_options_prep): Likewise.
    (func_options_finish): New hook-caller for 'func_options' hooks.
    (func_options): Propagate return value down to top-level caller,
    but pay attention we have always set $func_options_result.
    * build-aux/ltmain.in (libtool_options_prep): Quote '$@' and
    return $EXIT_SUCCESS only if we changed something.
    (libtool_parse_options): Likewise.
    * bootstrap: Sync gl/build-aux/with option-parser.

commit 32f0df9835ac15ac17e04be57c368172c3ad1d19
Author: Pavel Raiskup <address@hidden>
Date:   Sun Oct 4 21:55:03 2015 +0200

    libtool: mitigate the $sed_quote_subst slowdown
    
    When it is reasonably possible, use shell implementation for
    quoting.
    
    References:
    http://lists.gnu.org/archive/html/libtool/2015-03/msg00005.html
    http://lists.gnu.org/archive/html/libtool/2015-02/msg00000.html
    https://debbugs.gnu.org/cgi/bugreport.cgi?bug=20006
    
    * gl/build-aux/funclib.sh (func_quote): New function that can be
    used as substitution for '$SED $sed_quote_subst' call.
    * build-aux/ltmain.in (func_emit_wrapper): Use func_quote instead
    of '$SED $sed_quote_subst'.
    (func_mode_link): Likewise.
    * NEWS: Document.
    * bootstrap: Sync with funclib.sh.

-----------------------------------------------------------------------

Summary of changes:
 .gitignore                         |    1 +
 Makefile.am                        |    7 +-
 NEWS                               |    5 +
 bootstrap                          |  450 +++++++++++++++++++++++++-----------
 bootstrap.conf                     |    1 +
 build-aux/.gitignore               |    1 +
 build-aux/ltmain.in                |  139 +++++++-----
 cfg.mk                             |   26 ++-
 configure.ac                       |    4 +-
 gl/build-aux/bootstrap.in          |   22 +-
 gl/build-aux/funclib.sh            |  255 +++++++++++++++------
 gl/build-aux/options-parser        |  173 ++++++++++----
 gl/doc/bootstrap.texi              |    4 +-
 gl/modules/all-shells-tests        |   10 +
 gl/modules/funclib.sh-tests        |   12 +
 gl/modules/options-parser-tests    |   13 +
 gl/tests/test-all-shells.sh        |  104 +++++++++
 gl/tests/test-funclib-quote.sh     |  184 +++++++++++++++
 gl/tests/test-option-parser-helper |  204 ++++++++++++++++
 gl/tests/test-option-parser.sh     |  133 +++++++++++
 gnulib                             |    2 +-
 libtoolize.in                      |   18 +-
 22 files changed, 1418 insertions(+), 350 deletions(-)
 create mode 100644 gl/modules/all-shells-tests
 create mode 100644 gl/modules/funclib.sh-tests
 create mode 100644 gl/modules/options-parser-tests
 create mode 100644 gl/tests/test-all-shells.sh
 create mode 100755 gl/tests/test-funclib-quote.sh
 create mode 100755 gl/tests/test-option-parser-helper
 create mode 100755 gl/tests/test-option-parser.sh

diff --git a/.gitignore b/.gitignore
index c3016d1..ab4fdcb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,6 +41,7 @@
 /INSTALL
 /README-release
 /gnulib-local
+/gnulib-tests
 /libtoolize
 /libtoolize.in
 /maint.mk
diff --git a/Makefile.am b/Makefile.am
index fd11dd0..1a1d10d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,7 +27,7 @@ ACLOCAL_AMFLAGS               = -I m4
 AM_CPPFLAGS            =
 AM_LDFLAGS             =
 
-SUBDIRS                        = .
+SUBDIRS                        = . gnulib-tests
 DIST_SUBDIRS           = $(SUBDIRS)
 EXTRA_DIST             =
 
@@ -88,11 +88,12 @@ ltversion_in        = $(srcdir)/$(macro_dir)/ltversion.in
 ltversion_m4   = $(srcdir)/$(macro_dir)/ltversion.m4
 no_bogus_macros        = $(srcdir)/$(aux_dir)/no-bogus-m4-defines
 options_parser = $(srcdir)/$(aux_dir)/options-parser
+u2d_copyright  = $(srcdir)/$(aux_dir)/update-copyright
 
 EXTRA_DIST     += $(extract_trace) $(funclib_sh) $(inline_source) \
                  $(libtoolize_in) $(ltmain_in) $(ltmain_sh) \
                  $(ltversion_in) $(ltversion_m4) $(no_bogus_macros) \
-                 $(options_parser)
+                 $(options_parser) $(u2d_copyright)
 
 ## These are the replacements that need to be made at bootstrap time,
 ## because they must be static in distributed files, and not accidentally
@@ -538,7 +539,7 @@ git_log_fix         = $(srcdir)/$(aux_dir)/git-log-fix
 thanks_gen             = $(srcdir)/$(aux_dir)/thanks-gen
 
 dotserial              = $(distdir)/.serial
-dotversion             = $(srcdir)/.version
+dotversion             = $(top_srcdir)/.version
 tarball_version                = $(distdir)/.tarball-version
 readme                 = $(distdir)/README
 changelog              = $(distdir)/ChangeLog
diff --git a/NEWS b/NEWS
index a3c5b12..bca041c 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ NEWS - list of user-visible changes between releases of GNU 
Libtool
     variable, which obsoletes AR_FLAGS.  This is due to naming conventions
     among other *FLAGS and to be consistent with Automake's ARFLAGS.
 
+  - Gnulib testsuite is enabled and run during 'make check'.
+
 ** Important incompatible changes:
 
   - Libtool changed ARFLAGS/AR_FLAGS default from 'cru' to 'cr'.
@@ -17,6 +19,9 @@ NEWS - list of user-visible changes between releases of GNU 
Libtool
   - Fix significant slowdown of libtoolize for certain projects (regression
     introduced in 2.4.3 release) caused by infinite m4 macro recursion.
 
+  - Mitigate the slowdown of libtool script (introduced in v2.4.3) caused by
+    increased number of calls to '$SED $sed_quote_subst' (bug#20006).
+
 * Noteworthy changes in release 2.4.6 (2015-02-15) [stable]
 
 ** New features:
diff --git a/bootstrap b/bootstrap
index c179f51..aa3a8b8 100755
--- a/bootstrap
+++ b/bootstrap
@@ -230,7 +230,7 @@ vc_ignore=
 
 # Source required external libraries:
 # Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
+scriptversion=2015-11-01.21; # UTC
 
 # General shell script boiler plate, and helper functions.
 # Written by Gary V. Vaughan, 2004
@@ -746,16 +746,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1+=\\ \$func_quote_arg_result"
   }'
 else
   func_append_quoted ()
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1=\$$1\\ \$func_quote_arg_result"
   }
 fi
 
@@ -1257,85 +1257,198 @@ func_relative_path ()
 }
 
 
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
+# func_quote_portable EVAL ARG
+# ----------------------------
+# Internal function to portably implement func_quote_arg.  Note that we still
+# keep attention to performance here so we as much as possible try to avoid
+# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
+func_quote_portable ()
 {
     $debug_cmd
 
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
-        *[\\\`\"\$]*)
-         _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-       func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+    func_quote_portable_result=$2
+
+    # one-time-loop (easy break)
+    while true
+    do
+      if $1; then
+        func_quote_portable_result=`$ECHO "$2" | $SED \
+          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
+        break
       fi
 
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \  ]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
+      # Quote for eval.
+      case $func_quote_portable_result in
+        *[\\\`\"\$]*)
+          case $func_quote_portable_result in
+            *[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" 
| $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
+
+          func_quote_portable_old_IFS=$IFS
+          for _G_char in '\' '`' '"' '$'
+          do
+            # STATE($1) PREV($2) SEPARATOR($3)
+            set start "" ""
+            
func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
+            IFS=$_G_char
+            for _G_part in $func_quote_portable_result
+            do
+              case $1 in
+              quote)
+                func_append func_quote_portable_result "$3$2"
+                set quote "$_G_part" "\\$_G_char"
+                ;;
+              start)
+                set first "" ""
+                func_quote_portable_result=
+                ;;
+              first)
+                set quote "$_G_part" ""
+                ;;
+              esac
+            done
+          done
+          IFS=$func_quote_portable_old_IFS
           ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-         ;;
+        *) ;;
       esac
-
-      if test -n "$func_quote_for_eval_result"; then
-       func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
+      break
     done
+
+    func_quote_portable_unquoted_result=$func_quote_portable_result
+    case $func_quote_portable_result in
+      # double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and variable expansion
+      # for a subsequent eval.
+      # many bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+        func_quote_portable_result=\"$func_quote_portable_result\"
+        ;;
+    esac
 }
 
 
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
-    $debug_cmd
+# func_quotefast_eval ARG
+# -----------------------
+# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
+# but optimized for speed.  Result is stored in $func_quotefast_eval.
+if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
+  printf -v _GL_test_printf_tilde %q '~'
+  if test '\~' = "$_GL_test_printf_tilde"; then
+    func_quotefast_eval ()
+    {
+      printf -v func_quotefast_eval_result %q "$1"
+    }
+  else
+    # Broken older Bash implementations.  Make those faster too if possible.
+    func_quotefast_eval ()
+    {
+      case $1 in
+        '~'*)
+          func_quote_portable false "$1"
+          func_quotefast_eval_result=$func_quote_portable_result
+          ;;
+        *)
+          printf -v func_quotefast_eval_result %q "$1"
+          ;;
+      esac
+    }
+  fi
+else
+  func_quotefast_eval ()
+  {
+    func_quote_portable false "$1"
+    func_quotefast_eval_result=$func_quote_portable_result
+  }
+fi
 
-    case $1 in
-      *[\\\`\"]*)
-       _G_arg=`$ECHO "$1" | $SED \
-           -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
+
+# func_quote_arg MODEs ARG
+# ------------------------
+# Quote one ARG to be evaled later.  MODEs argument may contain zero ore more
+# specifiers listed below separated by ',' character.  This function returns 
two
+# values:
+#   i) func_quote_arg_result
+#      double-quoted (when needed), suitable for a subsequent eval
+#  ii) func_quote_arg_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.  Available only if 'unquoted' is specified.
+#
+# Available modes:
+# ----------------
+# 'eval' (default)
+#       - escape shell special characters
+# 'expand'
+#       - the same as 'eval';  but do not quote variable references
+# 'pretty'
+#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
+#         later used in func_quote to get output like: 'echo "a b"' instead of
+#         'echo a\ b'.  This is slower than default on some shells.
+# 'unquoted'
+#       - produce also $func_quote_arg_unquoted_result which does not contain
+#         wrapping double-quotes.
+#
+# Examples for 'func_quote_arg pretty,unquoted string':
+#
+#   string      | *_result              | *_unquoted_result
+#   ------------+-----------------------+-------------------
+#   "           | \"                    | \"
+#   a b         | "a b"                 | a b
+#   "a b"       | "\"a b\""             | \"a b\"
+#   *           | "*"                   | *
+#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
+#
+# Examples for 'func_quote_arg pretty,unquoted,expand string':
+#
+#   string        |   *_result          |  *_unquoted_result
+#   --------------+---------------------+--------------------
+#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
+func_quote_arg ()
+{
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
+        ;;
     esac
 
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
-        _G_arg=\"$_G_arg\"
+    case ,$1, in
+      *,pretty,*|*,expand,*|*,unquoted,*)
+        func_quote_portable $_G_quote_expand "$2"
+        func_quote_arg_result=$func_quote_portable_result
+        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
+        ;;
+      *)
+        # Faster quote-for-eval for some shells.
+        func_quotefast_eval "$2"
+        func_quote_arg_result=$func_quotefast_eval_result
         ;;
     esac
+}
+
 
-    func_quote_for_expand_result=$_G_arg
+# func_quote MODEs ARGs...
+# ------------------------
+# Quote all ARGs to be evaled later and join them into single command.  See
+# func_quote_arg's description for more info.
+func_quote ()
+{
+    $debug_cmd
+    _G_func_quote_mode=$1 ; shift
+    func_quote_result=
+    while test 0 -lt $#; do
+      func_quote_arg "$_G_func_quote_mode" "$1"
+      if test -n "$func_quote_result"; then
+        func_append func_quote_result " $func_quote_arg_result"
+      else
+        func_append func_quote_result "$func_quote_arg_result"
+      fi
+      shift
+    done
 }
 
 
@@ -1381,8 +1494,8 @@ func_show_eval ()
     _G_cmd=$1
     _G_fail_exp=${2-':'}
 
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
+    func_quote_arg pretty,expand "$_G_cmd"
+    eval "func_notquiet $func_quote_arg_result"
 
     $opt_dry_run || {
       eval "$_G_cmd"
@@ -1407,8 +1520,8 @@ func_show_eval_locale ()
     _G_fail_exp=${2-':'}
 
     $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
+      func_quote_arg expand,pretty "$_G_cmd"
+      eval "func_echo $func_quote_arg_result"
     }
 
     $opt_dry_run || {
@@ -1536,7 +1649,7 @@ func_lt_ver ()
 #! /bin/sh
 
 # Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
+scriptversion=2015-10-12.13; # UTC
 
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
@@ -1696,6 +1809,8 @@ func_run_hooks ()
 {
     $debug_cmd
 
+    _G_rc_run_hooks=false
+
     case " $hookable_fns " in
       *" $1 "*) ;;
       *) func_fatal_error "'$1' does not support hook funcions.n" ;;
@@ -1704,16 +1819,16 @@ func_run_hooks ()
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
+      if eval $_G_hook '"$@"'; then
+        # store returned options list back into positional
+        # parameters for next 'cmd' execution.
+        eval _G_hook_result=\$${_G_hook}_result
+        eval set dummy "$_G_hook_result"; shift
+        _G_rc_run_hooks=:
+      fi
     done
 
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
+    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
 }
 
 
@@ -1723,10 +1838,16 @@ func_run_hooks ()
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
+# full positional parameter list in your hook function, you may remove/edit
+# any options that you action, and then pass back the remaining unprocessed
 # options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
+# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
+# hook's caller know that it should pay attention to
+# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
+# arguments are left untouched by the hook and therefore caller will ignore the
+# result variable.
+#
+# Like this:
 #
 #    my_options_prep ()
 #    {
@@ -1736,9 +1857,11 @@ func_run_hooks ()
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
+#        # No change in '$@' (ignored completely by this hook).  There is
+#        # no need to do the equivalent (but slower) action:
+#        # func_quote eval ${1+"$@"}
+#        # my_options_prep_result=$func_quote_result
+#        false
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1747,25 +1870,37 @@ func_run_hooks ()
 #    {
 #        $debug_cmd
 #
+#        args_changed=false
+#
 #        # Note that for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=: ;;
+#            --silent|-s) opt_silent=:
+#                         args_changed=:
+#                         ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
+#                         args_changed=:
 #                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#            *)           # Make sure the first unrecognised option "$_G_opt"
+#                         # is added back to "$@", we could need that later
+#                         # if $args_changed is true.
+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
+#        if $args_changed; then
+#          func_quote eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_result
+#        fi
+#
+#        $args_changed
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1777,16 +1912,32 @@ func_run_hooks ()
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll alse need to manually amend $usage_message to reflect the extra
+# You'll also need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
+# func_options_finish [ARG]...
+# ----------------------------
+# Finishing the option parse loop (call 'func_options' hooks ATM).
+func_options_finish ()
+{
+    $debug_cmd
+
+    _G_func_options_finish_exit=false
+    if func_run_hooks func_options ${1+"$@"}; then
+      func_options_finish_result=$func_run_hooks_result
+      _G_func_options_finish_exit=:
+    fi
+
+    $_G_func_options_finish_exit
+}
+
+
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -1796,17 +1947,28 @@ func_options ()
 {
     $debug_cmd
 
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
+    _G_rc_options=false
+
+    for my_func in options_prep parse_options validate_options options_finish
+    do
+      if eval func_$my_func '${1+"$@"}'; then
+        eval _G_res_var='$'"func_${my_func}_result"
+        eval set dummy "$_G_res_var" ; shift
+        _G_rc_options=:
+      fi
+    done
 
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+    # Save modified positional parameters for caller.  As a top-level
+    # options-parser function we always need to set the 'func_options_result'
+    # variable (regardless the $_G_rc_options value).
+    if $_G_rc_options; then
+      func_options_result=$_G_res_var
+    else
+      func_quote eval ${1+"$@"}
+      func_options_result=$func_quote_result
+    fi
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    $_G_rc_options
 }
 
 
@@ -1815,9 +1977,9 @@ func_options ()
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
+# needs to propagate that back to rest of this script, then the complete
 # modified list must be put in 'func_run_hooks_result' before
-# returning.
+# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1827,10 +1989,14 @@ func_options_prep ()
     opt_verbose=false
     opt_warning_types=
 
-    func_run_hooks func_options_prep ${1+"$@"}
+    _G_rc_options_prep=false
+    if func_run_hooks func_options_prep ${1+"$@"}; then
+      _G_rc_options_prep=:
+      # save modified positional parameters for caller
+      func_options_prep_result=$func_run_hooks_result
+    fi
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    $_G_rc_options_prep
 }
 
 
@@ -1844,23 +2010,25 @@ func_parse_options ()
 
     func_parse_options_result=
 
+    _G_rc_parse_options=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
-
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+      if func_run_hooks func_parse_options ${1+"$@"}; then
+        eval set dummy "$func_run_hooks_result"; shift
+        _G_rc_parse_options=:
+      fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
         --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode"
+                      func_echo "enabling shell trace mode" >&2
                       $debug_cmd
                       ;;
 
@@ -1870,7 +2038,10 @@ func_parse_options ()
                      ;;
 
         --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
+                      if test $# = 0 && func_missing_arg $_G_opt; then
+                        _G_rc_parse_options=:
+                        break
+                      fi
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -1923,15 +2094,25 @@ func_parse_options ()
                       shift
                       ;;
 
-        --)           break ;;
+        --)           _G_rc_parse_options=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift
+                      _G_match_parse_options=false
+                      break
+                      ;;
       esac
+
+      $_G_match_parse_options && _G_rc_parse_options=:
     done
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+
+    if $_G_rc_parse_options; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      func_parse_options_result=$func_quote_result
+    fi
+
+    $_G_rc_parse_options
 }
 
 
@@ -1944,16 +2125,21 @@ func_validate_options ()
 {
     $debug_cmd
 
+    _G_rc_validate_options=false
+
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    func_run_hooks func_validate_options ${1+"$@"}
+    if func_run_hooks func_validate_options ${1+"$@"}; then
+      # save modified positional parameters for caller
+      func_validate_options_result=$func_run_hooks_result
+      _G_rc_validate_options=:
+    fi
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    $_G_rc_validate_options
 }
 
 
@@ -2633,7 +2819,7 @@ test extract-trace = "$progname" && func_main "$@"
 # End:
 
 # Set a version string for *this* script.
-scriptversion=2015-01-20.17; # UTC
+scriptversion=2015-10-12.13; # UTC
 
 
 ## ------------------- ##
@@ -2661,8 +2847,8 @@ func_bootstrap ()
 
     # Save the current positional parameters to prevent them being
     # corrupted by calls to 'set' in 'func_init'.
-    func_quote_for_eval ${1+"$@"}
-    _G_saved_positional_parameters=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    _G_saved_positional_parameters=$func_quote_result
 
     # Initialisation.
     func_init
@@ -4701,8 +4887,8 @@ func_show_eval ()
     _G_fail_exp=${2-':'}
 
     ${opt_silent-'false'} || {
-      func_quote_for_eval $_G_cmd
-      eval func_truncate_cmd $func_quote_for_eval_result
+      func_quote eval $_G_cmd
+      eval func_truncate_cmd $func_quote_result
       func_echo "running: $tc_bold$func_truncate_cmd_result$tc_reset"
     }
 
@@ -5089,8 +5275,8 @@ bootstrap_options_prep ()
     opt_skip_po=false
 
     # Pass back the list of options we consumed.
-    func_quote_for_eval ${1+"$@"}
-    bootstrap_options_prep_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    bootstrap_options_prep_result=$func_quote_result
 }
 func_add_hook func_options_prep bootstrap_options_prep
 
@@ -5140,8 +5326,8 @@ bootstrap_parse_options ()
     done
 
     # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    bootstrap_parse_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    bootstrap_parse_options_result=$func_quote_result
 }
 func_add_hook func_parse_options bootstrap_parse_options
 
@@ -5159,8 +5345,8 @@ bootstrap_validate_options ()
         && func_fatal_help "too many arguments"
 
     # Pass back the (empty) list of unconsumed options.
-    func_quote_for_eval ${1+"$@"}
-    bootstrap_validate_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    bootstrap_validate_options_result=$func_quote_result
 }
 func_add_hook func_validate_options bootstrap_validate_options
 
diff --git a/bootstrap.conf b/bootstrap.conf
index db6c74d..9bc1342 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -61,6 +61,7 @@ gnulib_tool_options=$gnulib_tool_options"
         --avoid=dummy
         --libtool
         --macro-prefix=GL
+        --with-tests --tests-base=gnulib-tests
 "
 
 # gnulib modules used by this package.
diff --git a/build-aux/.gitignore b/build-aux/.gitignore
index a4c2231..f67c054 100644
--- a/build-aux/.gitignore
+++ b/build-aux/.gitignore
@@ -1,4 +1,5 @@
 /announce-gen
+/ar-lib
 /compile
 /depcomp
 /do-release-commit-and-tag
diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in
index 0c40da0..1cbe875 100644
--- a/build-aux/ltmain.in
+++ b/build-aux/ltmain.in
@@ -358,6 +358,8 @@ libtool_options_prep ()
     nonopt=
     preserve_args=
 
+    _G_rc_lt_options_prep=:
+
     # Shorthand for --mode=foo, only valid as the first argument
     case $1 in
     clean|clea|cle|cl)
@@ -381,11 +383,18 @@ libtool_options_prep ()
     uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
       shift; set dummy --mode uninstall ${1+"$@"}; shift
       ;;
+    *)
+      _G_rc_lt_options_prep=false
+      ;;
     esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
+    if $_G_rc_lt_options_prep; then
+      # Pass back the list of options.
+      func_quote eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_result
+    fi
+
+    $_G_rc_lt_options_prep
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -397,9 +406,12 @@ libtool_parse_options ()
 {
     $debug_cmd
 
+    _G_rc_lt_parse_options=false
+
     # Perform our own loop to consume as many options as possible in
     # each iteration.
     while test $# -gt 0; do
+      _G_match_lt_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -474,15 +486,22 @@ libtool_parse_options ()
                         func_append preserve_args " $_G_opt"
                         ;;
 
-       # An option not handled by this hook function:
-        *)             set dummy "$_G_opt" ${1+"$@"};  shift; break  ;;
+        # An option not handled by this hook function:
+        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
+                        _G_match_lt_parse_options=false
+                        break
+                        ;;
       esac
+      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
     done
 
+    if $_G_rc_lt_parse_options; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_result
+    fi
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
+    $_G_rc_lt_parse_options
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -539,8 +558,8 @@ libtool_validate_options ()
     }
 
     # Pass back the unparsed argument list
-    func_quote_for_eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_result
 }
 func_add_hook func_validate_options libtool_validate_options
 
@@ -1506,8 +1525,8 @@ func_mode_compile ()
       esac
     done
 
-    func_quote_for_eval "$libobj"
-    test "X$libobj" != "X$func_quote_for_eval_result" \
+    func_quote_arg pretty "$libobj"
+    test "X$libobj" != "X$func_quote_arg_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'   &()|`$[]' \
       && func_warning "libobj name '$libobj' may not contain shell special 
characters."
     func_dirname_and_basename "$obj" "/" ""
@@ -1580,8 +1599,8 @@ compiler."
 
     func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
     srcfile=$func_to_tool_file_result
-    func_quote_for_eval "$srcfile"
-    qsrcfile=$func_quote_for_eval_result
+    func_quote_arg pretty "$srcfile"
+    qsrcfile=$func_quote_arg_result
 
     # Only build a PIC object if we are building libtool libraries.
     if test yes = "$build_libtool_libs"; then
@@ -2184,8 +2203,8 @@ func_mode_install ()
        case $nonopt in *shtool*) :;; *) false;; esac
     then
       # Aesthetically quote it.
-      func_quote_for_eval "$nonopt"
-      install_prog="$func_quote_for_eval_result "
+      func_quote_arg pretty "$nonopt"
+      install_prog="$func_quote_arg_result "
       arg=$1
       shift
     else
@@ -2195,8 +2214,8 @@ func_mode_install ()
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
-    func_quote_for_eval "$arg"
-    func_append install_prog "$func_quote_for_eval_result"
+    func_quote_arg pretty "$arg"
+    func_append install_prog "$func_quote_arg_result"
     install_shared_prog=$install_prog
     case " $install_prog " in
       *[\\\ /]cp\ *) install_cp=: ;;
@@ -2253,12 +2272,12 @@ func_mode_install ()
       esac
 
       # Aesthetically quote the argument.
-      func_quote_for_eval "$arg"
-      func_append install_prog " $func_quote_for_eval_result"
+      func_quote_arg pretty "$arg"
+      func_append install_prog " $func_quote_arg_result"
       if test -n "$arg2"; then
-       func_quote_for_eval "$arg2"
+       func_quote_arg pretty "$arg2"
       fi
-      func_append install_shared_prog " $func_quote_for_eval_result"
+      func_append install_shared_prog " $func_quote_arg_result"
     done
 
     test -z "$install_prog" && \
@@ -2269,8 +2288,8 @@ func_mode_install ()
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
-       func_quote_for_eval "$install_override_mode"
-       func_append install_shared_prog " -m $func_quote_for_eval_result"
+       func_quote_arg pretty "$install_override_mode"
+       func_append install_shared_prog " -m $func_quote_arg_result"
       fi
     fi
 
@@ -2566,8 +2585,8 @@ func_mode_install ()
                relink_command=`$ECHO "$relink_command" | $SED 
'address@hidden@%'"$outputname"'%g'`
 
                $opt_quiet || {
-                 func_quote_for_expand "$relink_command"
-                 eval "func_echo $func_quote_for_expand_result"
+                 func_quote_arg expand,pretty "$relink_command"
+                 eval "func_echo $func_quote_arg_result"
                }
                if eval "$relink_command"; then :
                  else
@@ -3346,7 +3365,8 @@ else
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
     file=\"\$0\""
 
-    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    func_quote_arg pretty "$ECHO"
+    qECHO=$func_quote_arg_result
     $ECHO "\
 
 # A function that is used when there is no print builtin or printf.
@@ -3356,7 +3376,7 @@ func_fallback_echo ()
 \$1
 _LTECHO_EOF'
 }
-    ECHO=\"$qECHO\"
+    ECHO=$qECHO
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -4699,9 +4719,9 @@ func_mode_link ()
     while test "$#" -gt 0; do
       arg=$1
       shift
-      func_quote_for_eval "$arg"
-      qarg=$func_quote_for_eval_unquoted_result
-      func_append libtool_args " $func_quote_for_eval_result"
+      func_quote_arg pretty,unquoted "$arg"
+      qarg=$func_quote_arg_unquoted_result
+      func_append libtool_args " $func_quote_arg_result"
 
       # If the previous option needs an argument, assign it.
       if test -n "$prev"; then
@@ -5299,9 +5319,9 @@ func_mode_link ()
        save_ifs=$IFS; IFS=,
        for flag in $args; do
          IFS=$save_ifs
-          func_quote_for_eval "$flag"
-         func_append arg " $func_quote_for_eval_result"
-         func_append compiler_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+         func_append arg " $func_quote_arg_result"
+         func_append compiler_flags " $func_quote_arg_result"
        done
        IFS=$save_ifs
        func_stripname ' ' '' "$arg"
@@ -5315,10 +5335,10 @@ func_mode_link ()
        save_ifs=$IFS; IFS=,
        for flag in $args; do
          IFS=$save_ifs
-          func_quote_for_eval "$flag"
-         func_append arg " $wl$func_quote_for_eval_result"
-         func_append compiler_flags " $wl$func_quote_for_eval_result"
-         func_append linker_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+         func_append arg " $wl$func_quote_arg_result"
+         func_append compiler_flags " $wl$func_quote_arg_result"
+         func_append linker_flags " $func_quote_arg_result"
        done
        IFS=$save_ifs
        func_stripname ' ' '' "$arg"
@@ -5342,8 +5362,8 @@ func_mode_link ()
 
       # -msg_* for osf cc
       -msg_*)
-       func_quote_for_eval "$arg"
-       arg=$func_quote_for_eval_result
+       func_quote_arg pretty "$arg"
+       arg=$func_quote_arg_result
        ;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -5366,8 +5386,8 @@ func_mode_link ()
       
-t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       
-O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
       -specs=*)
-        func_quote_for_eval "$arg"
-       arg=$func_quote_for_eval_result
+        func_quote_arg pretty "$arg"
+       arg=$func_quote_arg_result
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
@@ -5388,15 +5408,15 @@ func_mode_link ()
          continue
         else
          # Otherwise treat like 'Some other compiler flag' below
-         func_quote_for_eval "$arg"
-         arg=$func_quote_for_eval_result
+         func_quote_arg pretty "$arg"
+         arg=$func_quote_arg_result
         fi
        ;;
 
       # Some other compiler flag.
       -* | +*)
-        func_quote_for_eval "$arg"
-       arg=$func_quote_for_eval_result
+        func_quote_arg pretty "$arg"
+       arg=$func_quote_arg_result
        ;;
 
       *.$objext)
@@ -5516,8 +5536,8 @@ func_mode_link ()
       *)
        # Unknown arguments in both finalize_command and compile_command need
        # to be aesthetically quoted because they are evaled later.
-       func_quote_for_eval "$arg"
-       arg=$func_quote_for_eval_result
+       func_quote_arg pretty "$arg"
+       arg=$func_quote_arg_result
        ;;
       esac # arg
 
@@ -8023,8 +8043,8 @@ EOF
            for cmd in $concat_cmds; do
              IFS=$save_ifs
              $opt_quiet || {
-                 func_quote_for_expand "$cmd"
-                 eval "func_echo $func_quote_for_expand_result"
+                 func_quote_arg expand,pretty "$cmd"
+                 eval "func_echo $func_quote_arg_result"
              }
              $opt_dry_run || eval "$cmd" || {
                lt_exit=$?
@@ -8117,8 +8137,8 @@ EOF
          eval cmd=\"$cmd\"
          IFS=$save_ifs
          $opt_quiet || {
-           func_quote_for_expand "$cmd"
-           eval "func_echo $func_quote_for_expand_result"
+           func_quote_arg expand,pretty "$cmd"
+           eval "func_echo $func_quote_arg_result"
          }
          $opt_dry_run || eval "$cmd" || {
            lt_exit=$?
@@ -8592,12 +8612,12 @@ EOF
          elif eval var_value=\$$var; test -z "$var_value"; then
            relink_command="$var=; export $var; $relink_command"
          else
-           func_quote_for_eval "$var_value"
-           relink_command="$var=$func_quote_for_eval_result; export $var; 
$relink_command"
+           func_quote_arg pretty "$var_value"
+           relink_command="$var=$func_quote_arg_result; export $var; 
$relink_command"
          fi
        done
-       relink_command="(cd `pwd`; $relink_command)"
-       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+       func_quote_arg pretty,unquoted "(cd `pwd`; $relink_command)"
+       relink_command=$func_quote_arg_unquoted_result
       fi
 
       # Only actually do things if not in dry run mode.
@@ -8837,13 +8857,14 @@ EOF
        elif eval var_value=\$$var; test -z "$var_value"; then
          relink_command="$var=; export $var; $relink_command"
        else
-         func_quote_for_eval "$var_value"
-         relink_command="$var=$func_quote_for_eval_result; export $var; 
$relink_command"
+         func_quote_arg pretty,unquoted "$var_value"
+         relink_command="$var=$func_quote_arg_unquoted_result; export $var; 
$relink_command"
        fi
       done
       # Quote the link command for shipping.
       relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args 
--mode=relink $libtool_args @inst_prefix_dir@)"
-      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      func_quote_arg pretty,unquoted "$relink_command"
+      relink_command=$func_quote_arg_unquoted_result
       if test yes = "$hardcode_automatic"; then
        relink_command=
       fi
diff --git a/cfg.mk b/cfg.mk
index 6767b2d..42eea18 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -70,9 +70,9 @@ local-checks-to-skip =                                \
 
 # Check for correct usage of $cc_basename in libtool.m4.
 sc_libtool_m4_cc_basename:
-       @sed -n '/case \$$cc_basename in/,/esac/ {                      \
+       @$(SED) -n "/case \\\$$cc_basename in/,/esac/ {                 \
          /^[    ]*[a-zA-Z][a-zA-Z0-9+]*[^*][    ]*)/p;                 \
-       }' '$(srcdir)/$(macro_dir)/libtool.m4' | grep . && {            \
+       }" '$(srcdir)/$(macro_dir)/libtool.m4' | grep . && {            \
          msg="\$$cc_basename matches should include a trailing '*'."   \
          $(_sc_say_and_exit) } || :
 
@@ -112,6 +112,13 @@ sc_prohibit_bracket_as_test:
        halt="use 'if test' instead of 'if ['"                  \
          $(_sc_search_regexp)
 
+# : ${foo=`bar`} is not perfectly portable (see Shellology in autoconf's 
manual)
+exclude_file_name_regexp--sc_prohibit_command_in_subst = ^cfg.mk$$
+sc_prohibit_command_in_subst:
+       @prohibit='\$$\{[^`}]*`[^`]*`[^}]*}'                            \
+       halt='do not use `command` in $${ } substitution`'              \
+         $(_sc_search_regexp)
+
 # Check for quotes within backquotes within quotes "`"bar"`"
 exclude_file_name_regexp--sc_prohibit_nested_quotes = ^cfg.mk$$
 sc_prohibit_nested_quotes:
@@ -135,12 +142,12 @@ sc_prohibit_set_dummy_without_shift:
        @files=$$($(VC_LIST_EXCEPT));                                   \
        if test -n "$$files"; then                                      \
          grep -nE '(set dummy|shift)' $$files |                        \
-           sed -n '/set[        ][      ]*dummy/{                      \
+           $(SED) -n "/set[     ][      ]*dummy/{                      \
              /set.*dummy.*;.*shift/d;                                  \
              N;                                                        \
              /\n.*shift/D;                                             \
              p;                                                        \
-            }' | grep -n . && {                                                
\
+           }" | grep -n . && {                                         \
            msg="use 'shift' after 'set dummy'"                         \
            $(_sc_say_and_exit) } || :;                                 \
        else :;                                                         \
@@ -209,11 +216,11 @@ sc_prohibit_test_const_follows_var:
 exclude_file_name_regexp--sc_require_function_nl_brace = 
(^HACKING|\.[ch]|\.texi)$$
 sc_require_function_nl_brace:
        @for file in $$($(VC_LIST_EXCEPT)); do                          \
-         sed -n '/^func_[^      ]*[     ]*(/{                          \
+         $(SED) -n "/^func_[^   ]*[     ]*(/{                          \
            N;                                                          \
            /^func_[^    ]* ()\n{$$/d;                                  \
            p;                                                          \
-         }' $$file | grep -E . && {                                    \
+         }" $$file | grep -E . && {                                    \
            msg="found malformed function_definition in $$file"         \
            $(_sc_say_and_exit) } || :;                                 \
        done
@@ -238,7 +245,8 @@ define _sc_search_regexp_or_exclude
   fi || :;
 endef
 
-exclude_file_name_regexp--sc_useless_braces_in_variable_derefs = /cvsu$$
+exclude_file_name_regexp--sc_useless_braces_in_variable_derefs = \
+       test-funclib-quote.sh$$
 sc_useless_braces_in_variable_derefs:
        @prohibit='\$${[0-9A-Za-z_]+}[^0-9A-Za-z_]'                     \
        halt='found spurious braces around variable dereference'        \
@@ -258,11 +266,9 @@ sc_useless_quotes_in_case:
          $(_sc_search_regexp)
 
 # List syntax-check exempted files.
-exclude_file_name_regexp--sc_error_message_uppercase = \
-  ^$(_build-aux)/cvsu$$
 exclude_file_name_regexp--sc_prohibit_strcmp = \
   ^doc/libtool.texi$$
 exclude_file_name_regexp--sc_prohibit_test_minus_ao = \
   ^m4/libtool.m4$$
-exclude_file_name_regexp--sc_space_tab = \.diff$$
+exclude_file_name_regexp--sc_space_tab = (\.diff|test-funclib-quote.sh)$$
 exclude_file_name_regexp--sc_trailing_blank-non-rfc3676 = \.diff$$
diff --git a/configure.ac b/configure.ac
index 6c66f1e..5647be4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -111,7 +111,7 @@ AB_INIT([$autobuild_mode])
 
 
 dnl Make sure config.status is regenerated when the version timestamp changes
-AC_SUBST([CONFIG_STATUS_DEPENDENCIES], ['$(srcdir)/.version'])
+AC_SUBST([CONFIG_STATUS_DEPENDENCIES], ['$(top_srcdir)/.version'])
 
 
 ## ------------------------------- ##
@@ -182,5 +182,5 @@ AM_MISSING_PROG([HELP2MAN], [help2man])
 ## -------- ##
 ## Outputs. ##
 ## -------- ##
-AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([Makefile gnulib-tests/Makefile])
 AC_OUTPUT
diff --git a/gl/build-aux/bootstrap.in b/gl/build-aux/bootstrap.in
index 6e686da..6da21d9 100755
--- a/gl/build-aux/bootstrap.in
+++ b/gl/build-aux/bootstrap.in
@@ -232,7 +232,7 @@ vc_ignore=
 . `echo "$0" |${SED-sed} 's|[^/]*$||'`"extract-trace"
 
 # Set a version string for *this* script.
-scriptversion=2015-01-20.17; # UTC
+scriptversion=2015-10-12.13; # UTC
 
 
 ## ------------------- ##
@@ -260,8 +260,8 @@ func_bootstrap ()
 
     # Save the current positional parameters to prevent them being
     # corrupted by calls to 'set' in 'func_init'.
-    func_quote_for_eval ${1+"$@"}
-    _G_saved_positional_parameters=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    _G_saved_positional_parameters=$func_quote_result
 
     # Initialisation.
     func_init
@@ -2300,8 +2300,8 @@ func_show_eval ()
     _G_fail_exp=${2-':'}
 
     ${opt_silent-'false'} || {
-      func_quote_for_eval $_G_cmd
-      eval func_truncate_cmd $func_quote_for_eval_result
+      func_quote eval $_G_cmd
+      eval func_truncate_cmd $func_quote_result
       func_echo "running: $tc_bold$func_truncate_cmd_result$tc_reset"
     }
 
@@ -2688,8 +2688,8 @@ bootstrap_options_prep ()
     opt_skip_po=false
 
     # Pass back the list of options we consumed.
-    func_quote_for_eval ${1+"$@"}
-    bootstrap_options_prep_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    bootstrap_options_prep_result=$func_quote_result
 }
 func_add_hook func_options_prep bootstrap_options_prep
 
@@ -2739,8 +2739,8 @@ bootstrap_parse_options ()
     done
 
     # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    bootstrap_parse_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    bootstrap_parse_options_result=$func_quote_result
 }
 func_add_hook func_parse_options bootstrap_parse_options
 
@@ -2758,8 +2758,8 @@ bootstrap_validate_options ()
         && func_fatal_help "too many arguments"
 
     # Pass back the (empty) list of unconsumed options.
-    func_quote_for_eval ${1+"$@"}
-    bootstrap_validate_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    bootstrap_validate_options_result=$func_quote_result
 }
 func_add_hook func_validate_options bootstrap_validate_options
 
diff --git a/gl/build-aux/funclib.sh b/gl/build-aux/funclib.sh
index 39d972e..d95ac2d 100644
--- a/gl/build-aux/funclib.sh
+++ b/gl/build-aux/funclib.sh
@@ -1,5 +1,5 @@
 # Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
+scriptversion=2015-11-01.21; # UTC
 
 # General shell script boiler plate, and helper functions.
 # Written by Gary V. Vaughan, 2004
@@ -515,16 +515,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1+=\\ \$func_quote_arg_result"
   }'
 else
   func_append_quoted ()
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1=\$$1\\ \$func_quote_arg_result"
   }
 fi
 
@@ -1026,85 +1026,198 @@ func_relative_path ()
 }
 
 
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
+# func_quote_portable EVAL ARG
+# ----------------------------
+# Internal function to portably implement func_quote_arg.  Note that we still
+# keep attention to performance here so we as much as possible try to avoid
+# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
+func_quote_portable ()
 {
     $debug_cmd
 
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
-        *[\\\`\"\$]*)
-         _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-       func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+    func_quote_portable_result=$2
+
+    # one-time-loop (easy break)
+    while true
+    do
+      if $1; then
+        func_quote_portable_result=`$ECHO "$2" | $SED \
+          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
+        break
       fi
 
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \  ]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
+      # Quote for eval.
+      case $func_quote_portable_result in
+        *[\\\`\"\$]*)
+          case $func_quote_portable_result in
+            *[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" 
| $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
+
+          func_quote_portable_old_IFS=$IFS
+          for _G_char in '\' '`' '"' '$'
+          do
+            # STATE($1) PREV($2) SEPARATOR($3)
+            set start "" ""
+            
func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
+            IFS=$_G_char
+            for _G_part in $func_quote_portable_result
+            do
+              case $1 in
+              quote)
+                func_append func_quote_portable_result "$3$2"
+                set quote "$_G_part" "\\$_G_char"
+                ;;
+              start)
+                set first "" ""
+                func_quote_portable_result=
+                ;;
+              first)
+                set quote "$_G_part" ""
+                ;;
+              esac
+            done
+          done
+          IFS=$func_quote_portable_old_IFS
           ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-         ;;
+        *) ;;
       esac
-
-      if test -n "$func_quote_for_eval_result"; then
-       func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
+      break
     done
+
+    func_quote_portable_unquoted_result=$func_quote_portable_result
+    case $func_quote_portable_result in
+      # double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and variable expansion
+      # for a subsequent eval.
+      # many bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+        func_quote_portable_result=\"$func_quote_portable_result\"
+        ;;
+    esac
 }
 
 
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
-    $debug_cmd
+# func_quotefast_eval ARG
+# -----------------------
+# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
+# but optimized for speed.  Result is stored in $func_quotefast_eval.
+if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
+  printf -v _GL_test_printf_tilde %q '~'
+  if test '\~' = "$_GL_test_printf_tilde"; then
+    func_quotefast_eval ()
+    {
+      printf -v func_quotefast_eval_result %q "$1"
+    }
+  else
+    # Broken older Bash implementations.  Make those faster too if possible.
+    func_quotefast_eval ()
+    {
+      case $1 in
+        '~'*)
+          func_quote_portable false "$1"
+          func_quotefast_eval_result=$func_quote_portable_result
+          ;;
+        *)
+          printf -v func_quotefast_eval_result %q "$1"
+          ;;
+      esac
+    }
+  fi
+else
+  func_quotefast_eval ()
+  {
+    func_quote_portable false "$1"
+    func_quotefast_eval_result=$func_quote_portable_result
+  }
+fi
 
-    case $1 in
-      *[\\\`\"]*)
-       _G_arg=`$ECHO "$1" | $SED \
-           -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
+
+# func_quote_arg MODEs ARG
+# ------------------------
+# Quote one ARG to be evaled later.  MODEs argument may contain zero ore more
+# specifiers listed below separated by ',' character.  This function returns 
two
+# values:
+#   i) func_quote_arg_result
+#      double-quoted (when needed), suitable for a subsequent eval
+#  ii) func_quote_arg_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.  Available only if 'unquoted' is specified.
+#
+# Available modes:
+# ----------------
+# 'eval' (default)
+#       - escape shell special characters
+# 'expand'
+#       - the same as 'eval';  but do not quote variable references
+# 'pretty'
+#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
+#         later used in func_quote to get output like: 'echo "a b"' instead of
+#         'echo a\ b'.  This is slower than default on some shells.
+# 'unquoted'
+#       - produce also $func_quote_arg_unquoted_result which does not contain
+#         wrapping double-quotes.
+#
+# Examples for 'func_quote_arg pretty,unquoted string':
+#
+#   string      | *_result              | *_unquoted_result
+#   ------------+-----------------------+-------------------
+#   "           | \"                    | \"
+#   a b         | "a b"                 | a b
+#   "a b"       | "\"a b\""             | \"a b\"
+#   *           | "*"                   | *
+#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
+#
+# Examples for 'func_quote_arg pretty,unquoted,expand string':
+#
+#   string        |   *_result          |  *_unquoted_result
+#   --------------+---------------------+--------------------
+#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
+func_quote_arg ()
+{
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
+        ;;
     esac
 
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
-        _G_arg=\"$_G_arg\"
+    case ,$1, in
+      *,pretty,*|*,expand,*|*,unquoted,*)
+        func_quote_portable $_G_quote_expand "$2"
+        func_quote_arg_result=$func_quote_portable_result
+        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
+        ;;
+      *)
+        # Faster quote-for-eval for some shells.
+        func_quotefast_eval "$2"
+        func_quote_arg_result=$func_quotefast_eval_result
         ;;
     esac
+}
+
 
-    func_quote_for_expand_result=$_G_arg
+# func_quote MODEs ARGs...
+# ------------------------
+# Quote all ARGs to be evaled later and join them into single command.  See
+# func_quote_arg's description for more info.
+func_quote ()
+{
+    $debug_cmd
+    _G_func_quote_mode=$1 ; shift
+    func_quote_result=
+    while test 0 -lt $#; do
+      func_quote_arg "$_G_func_quote_mode" "$1"
+      if test -n "$func_quote_result"; then
+        func_append func_quote_result " $func_quote_arg_result"
+      else
+        func_append func_quote_result "$func_quote_arg_result"
+      fi
+      shift
+    done
 }
 
 
@@ -1150,8 +1263,8 @@ func_show_eval ()
     _G_cmd=$1
     _G_fail_exp=${2-':'}
 
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
+    func_quote_arg pretty,expand "$_G_cmd"
+    eval "func_notquiet $func_quote_arg_result"
 
     $opt_dry_run || {
       eval "$_G_cmd"
@@ -1176,8 +1289,8 @@ func_show_eval_locale ()
     _G_fail_exp=${2-':'}
 
     $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
+      func_quote_arg expand,pretty "$_G_cmd"
+      eval "func_echo $func_quote_arg_result"
     }
 
     $opt_dry_run || {
diff --git a/gl/build-aux/options-parser b/gl/build-aux/options-parser
index d651f1d..02b6e06 100644
--- a/gl/build-aux/options-parser
+++ b/gl/build-aux/options-parser
@@ -1,7 +1,7 @@
 #! /bin/sh
 
 # Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
+scriptversion=2015-10-12.13; # UTC
 
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
@@ -161,6 +161,8 @@ func_run_hooks ()
 {
     $debug_cmd
 
+    _G_rc_run_hooks=false
+
     case " $hookable_fns " in
       *" $1 "*) ;;
       *) func_fatal_error "'$1' does not support hook funcions.n" ;;
@@ -169,16 +171,16 @@ func_run_hooks ()
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
+      if eval $_G_hook '"$@"'; then
+        # store returned options list back into positional
+        # parameters for next 'cmd' execution.
+        eval _G_hook_result=\$${_G_hook}_result
+        eval set dummy "$_G_hook_result"; shift
+        _G_rc_run_hooks=:
+      fi
     done
 
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
+    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
 }
 
 
@@ -188,10 +190,16 @@ func_run_hooks ()
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
+# full positional parameter list in your hook function, you may remove/edit
+# any options that you action, and then pass back the remaining unprocessed
 # options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
+# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
+# hook's caller know that it should pay attention to
+# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
+# arguments are left untouched by the hook and therefore caller will ignore the
+# result variable.
+#
+# Like this:
 #
 #    my_options_prep ()
 #    {
@@ -201,9 +209,11 @@ func_run_hooks ()
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
+#        # No change in '$@' (ignored completely by this hook).  There is
+#        # no need to do the equivalent (but slower) action:
+#        # func_quote eval ${1+"$@"}
+#        # my_options_prep_result=$func_quote_result
+#        false
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -212,25 +222,37 @@ func_run_hooks ()
 #    {
 #        $debug_cmd
 #
+#        args_changed=false
+#
 #        # Note that for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=: ;;
+#            --silent|-s) opt_silent=:
+#                         args_changed=:
+#                         ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
+#                         args_changed=:
 #                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#            *)           # Make sure the first unrecognised option "$_G_opt"
+#                         # is added back to "$@", we could need that later
+#                         # if $args_changed is true.
+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
+#        if $args_changed; then
+#          func_quote eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_result
+#        fi
+#
+#        $args_changed
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -242,16 +264,32 @@ func_run_hooks ()
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll alse need to manually amend $usage_message to reflect the extra
+# You'll also need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
+# func_options_finish [ARG]...
+# ----------------------------
+# Finishing the option parse loop (call 'func_options' hooks ATM).
+func_options_finish ()
+{
+    $debug_cmd
+
+    _G_func_options_finish_exit=false
+    if func_run_hooks func_options ${1+"$@"}; then
+      func_options_finish_result=$func_run_hooks_result
+      _G_func_options_finish_exit=:
+    fi
+
+    $_G_func_options_finish_exit
+}
+
+
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -261,17 +299,28 @@ func_options ()
 {
     $debug_cmd
 
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
+    _G_rc_options=false
 
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+    for my_func in options_prep parse_options validate_options options_finish
+    do
+      if eval func_$my_func '${1+"$@"}'; then
+        eval _G_res_var='$'"func_${my_func}_result"
+        eval set dummy "$_G_res_var" ; shift
+        _G_rc_options=:
+      fi
+    done
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    # Save modified positional parameters for caller.  As a top-level
+    # options-parser function we always need to set the 'func_options_result'
+    # variable (regardless the $_G_rc_options value).
+    if $_G_rc_options; then
+      func_options_result=$_G_res_var
+    else
+      func_quote eval ${1+"$@"}
+      func_options_result=$func_quote_result
+    fi
+
+    $_G_rc_options
 }
 
 
@@ -280,9 +329,9 @@ func_options ()
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
+# needs to propagate that back to rest of this script, then the complete
 # modified list must be put in 'func_run_hooks_result' before
-# returning.
+# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -292,10 +341,14 @@ func_options_prep ()
     opt_verbose=false
     opt_warning_types=
 
-    func_run_hooks func_options_prep ${1+"$@"}
+    _G_rc_options_prep=false
+    if func_run_hooks func_options_prep ${1+"$@"}; then
+      _G_rc_options_prep=:
+      # save modified positional parameters for caller
+      func_options_prep_result=$func_run_hooks_result
+    fi
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    $_G_rc_options_prep
 }
 
 
@@ -309,23 +362,25 @@ func_parse_options ()
 
     func_parse_options_result=
 
+    _G_rc_parse_options=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
-
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+      if func_run_hooks func_parse_options ${1+"$@"}; then
+        eval set dummy "$func_run_hooks_result"; shift
+        _G_rc_parse_options=:
+      fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
         --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode"
+                      func_echo "enabling shell trace mode" >&2
                       $debug_cmd
                       ;;
 
@@ -335,7 +390,10 @@ func_parse_options ()
                      ;;
 
         --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
+                      if test $# = 0 && func_missing_arg $_G_opt; then
+                        _G_rc_parse_options=:
+                        break
+                      fi
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -388,15 +446,25 @@ func_parse_options ()
                       shift
                       ;;
 
-        --)           break ;;
+        --)           _G_rc_parse_options=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift
+                      _G_match_parse_options=false
+                      break
+                      ;;
       esac
+
+      $_G_match_parse_options && _G_rc_parse_options=:
     done
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+
+    if $_G_rc_parse_options; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      func_parse_options_result=$func_quote_result
+    fi
+
+    $_G_rc_parse_options
 }
 
 
@@ -409,16 +477,21 @@ func_validate_options ()
 {
     $debug_cmd
 
+    _G_rc_validate_options=false
+
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    func_run_hooks func_validate_options ${1+"$@"}
+    if func_run_hooks func_validate_options ${1+"$@"}; then
+      # save modified positional parameters for caller
+      func_validate_options_result=$func_run_hooks_result
+      _G_rc_validate_options=:
+    fi
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    $_G_rc_validate_options
 }
 
 
diff --git a/gl/doc/bootstrap.texi b/gl/doc/bootstrap.texi
index 2f7b382..b28bd71 100755
--- a/gl/doc/bootstrap.texi
+++ b/gl/doc/bootstrap.texi
@@ -390,8 +390,8 @@ my_silent_option ()
     esac
 
     # return modified option list
-    func_quote_for_eval address@hidden"$@@"@}
-    func_run_hooks_result=$func_quote_for_eval_result
+    func_quote eval address@hidden"$@@"@}
+    func_run_hooks_result=$func_quote_result
 @}
 func_add_hook func_parse_options my_silent_option
 @end smallexample
diff --git a/gl/modules/all-shells-tests b/gl/modules/all-shells-tests
new file mode 100644
index 0000000..e47a943
--- /dev/null
+++ b/gl/modules/all-shells-tests
@@ -0,0 +1,10 @@
+Files:
+tests/test-all-shells.sh
+
+Depends-on:
+funclib.sh
+
+Makefile.am:
+TESTS_ENVIRONMENT += \
+       abs_aux_dir='$(abs_aux_dir)' \
+       abs_srcdir='$(abs_srcdir)'
diff --git a/gl/modules/funclib.sh-tests b/gl/modules/funclib.sh-tests
new file mode 100644
index 0000000..80991c7
--- /dev/null
+++ b/gl/modules/funclib.sh-tests
@@ -0,0 +1,12 @@
+Files:
+tests/test-funclib-quote.sh
+
+Depends-on:
+test-framework-sh
+all-shells-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += \
+       test-funclib-quote.sh
diff --git a/gl/modules/options-parser-tests b/gl/modules/options-parser-tests
new file mode 100644
index 0000000..76b4edb
--- /dev/null
+++ b/gl/modules/options-parser-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-option-parser.sh
+tests/test-option-parser-helper
+
+Depends-on:
+test-framework-sh
+all-shells-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += \
+       test-option-parser.sh
diff --git a/gl/tests/test-all-shells.sh b/gl/tests/test-all-shells.sh
new file mode 100644
index 0000000..d56c305
--- /dev/null
+++ b/gl/tests/test-all-shells.sh
@@ -0,0 +1,104 @@
+#! /bin/sh
+
+# Unit test helper.
+#
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+# This shell snippet (when sourced) tries to find as many /bin/sh compatible
+# shells as possible on tested box -- and then re-executes the calling script
+# in all of them.  At the end, the default shell (/bin/sh usually) is also
+# tested.
+#
+# To write compatible test-case, you usually need only those lines:
+#
+#   #! /bin/sh
+#
+#   all_shells_script=$0
+#   . "$abs_srcdir/test-all-shells.sh"
+#
+#   your_check && all_shells_error "failed your_check"
+#
+#   $all_shells_exit_cmd
+
+
+# List of shells we try to check in.
+: ${GL_ALL_SHELLS='ash bash dash ksh zsh busybox'}
+
+# List of directories to search for the shell interpreter.
+: ${GL_ALL_SHELLS_DIRS='/bin /sbin'}
+
+# List of shell emulations to test with BusyBox.
+: ${GL_ALL_SHELLS_BBE='sh ash'}
+
+. "$abs_aux_dir"/funclib.sh || exit 1
+
+all_shells_exit_cmd=:
+
+: ${all_shells_script=false}
+
+
+all_shells_error ()
+{
+    $ECHO "error: $*" >&2
+    all_shells_exit_cmd=false
+}
+
+
+__notify_shell ()
+{
+    $ECHO "== running in '$*' ==" >&2
+}
+
+
+__reexec_in_all_shells ()
+{
+    for _G_dir in $GL_ALL_SHELLS_DIRS
+    do
+      for _G_shell in $GL_ALL_SHELLS
+      do
+        _G_abs_shell=$_G_dir/$_G_shell
+        test -f "$_G_abs_shell" || continue
+
+        case $_G_abs_shell in
+          *busybox)
+            for _G_bbe in $GL_ALL_SHELLS_BBE
+            do
+              _G_full_bb="$_G_abs_shell $_G_bbe"
+              __notify_shell "$_G_full_bb"
+              __GL_ALL_SHELLS_SHELL="$_G_full_bb" \
+              "$_G_abs_shell" "$_G_bbe" "$all_shells_script" ${1+"$@"} \
+                  || all_shells_error "can't run in $_G_bbe"
+            done
+            ;;
+          *)
+            __notify_shell "$_G_abs_shell"
+            __GL_ALL_SHELLS_SHELL="$_G_abs_shell" \
+            "$_G_abs_shell" "$all_shells_script" ${1+"$@"} \
+                || all_shells_error "can't run in $_G_abs_shell"
+            ;;
+        esac
+      done
+    done
+}
+
+
+test x = "x$__GL_ALL_SHELLS_SHELL" \
+    && __reexec_in_all_shells ${1+"$@"} \
+    && __notify_shell "default shell"
+
+:
diff --git a/gl/tests/test-funclib-quote.sh b/gl/tests/test-funclib-quote.sh
new file mode 100755
index 0000000..7669a44
--- /dev/null
+++ b/gl/tests/test-funclib-quote.sh
@@ -0,0 +1,184 @@
+#! /bin/sh
+
+# Unit tests for funclib.sh
+#
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+all_shells_script=$0
+. "$abs_srcdir/test-all-shells.sh" || exit 1
+
+
+_compare_or_error ()
+{
+    _G_msg="strings differ:
+    a: $2
+    b: $3"
+    test "$2" = "$3" || all_shells_error "$_G_msg"
+}
+
+
+dump_args ()
+{
+    dump_args_result=
+    _separator=
+    for arg
+    do
+      func_append dump_args_result "$_separator$arg"
+      _separator=' '
+    done
+}
+
+
+# test_q_eval DESC ARGs...
+# ------------------------
+# Apply 'func_quote eval' on ARGs and eval the result.  The eval-ed result must
+# 100% match the original ARGs.
+test_q_eval ()
+{
+    description="$1" ; shift
+
+    dump_args ${1+"$@"}
+    original=$dump_args_result
+
+    $ECHO "~> func_quote eval: $description: $original"
+
+    # Pretty implementation
+    func_quote eval,pretty ${1+"$@"} \
+      || all_shells_error "can't pretty func_quote args '$*'"
+    eval "set dummy $func_quote_result" ; shift
+    dump_args ${1+"$@"}
+    pretty=$dump_args_result
+
+    # Fast implementation (if available)
+    func_quote eval ${1+"$@"} || all_shells_error "can't fast func_quote args 
'$*'"
+    eval "set dummy $func_quote_result" ; shift
+    dump_args ${1+"$@"}
+    fast=$dump_args_result
+
+    _compare_or_error "$description (pretty)"     "$original" "$pretty"
+    _compare_or_error "$description (fast)"       "$original" "$fast"
+}
+
+
+# test_q_arg_eval DESC ARG
+# ------------------------
+# Apply 'func_quote_arg eval' on ARG and eval the result.  Echo-ed result 
within
+# eval must match original echo-ed ARG.
+test_q_arg_eval ()
+{
+    description=$1
+    original=$2
+    original_echo=`$ECHO "$original"`
+
+    $ECHO "~> func_quote_arg eval: $description: $original_echo"
+
+    func_quote_arg pretty,unquoted "$original" \
+        || all_shells_error "can't quote_arg: $original"
+    pretty=$func_quote_arg_result
+    pretty_unquoted=$func_quote_arg_unquoted_result
+    pretty_echo=`eval '$ECHO '"$pretty"` \
+        || all_shells_error "can't eval: $pretty"
+
+    pretty_unquoted_echo=`eval '$ECHO '"\"$pretty_unquoted\""` \
+        || all_shells_error "can't eval: $pretty"
+
+    # Fast implementation.
+    func_quote_arg eval "$original"
+    fast=$func_quote_arg_result
+    fast_echo=`eval '$ECHO '"$fast"` || all_shells_error "can't eval: $pretty"
+
+    _compare_or_error "$description (pretty)" \
+        "$original_echo" "$pretty_echo"
+    _compare_or_error "$description (pretty_unquoted)" \
+        "$original_echo" "$pretty_unquoted_echo"
+    _compare_or_error "$description (fast)" \
+        "$original_echo" "$fast_echo"
+}
+
+
+# test_q_expand DESC EXP_RESULT ARG
+# ---------------------------------
+# Test that 'func_quote expand' works fine --> all shell special characters are
+# quoted except '$' -- while all variables are expanded.
+test_q_expand ()
+{
+    description=$1 ; shift
+    exp_result=$1 ; shift
+
+    dump_args ${1+"$@"}
+    $ECHO "~> func_quote expand: $description: $dump_args_result"
+
+    func_quote expand ${1+"$@"}
+    eval "set dummy $func_quote_result" ; shift
+    dump_args ${1+"$@"}
+
+    _compare_or_error "$description (expand)" "$exp_result" "$dump_args_result"
+}
+
+
+## ============== ##
+## Start testing! ##
+## ============== ##
+
+aaa=aaa ; bbb=bbb ; ccc=ccc ; ddd=ddd
+
+# Needed for later testing of globbing.
+touch fltestA fltestB
+
+test_q_eval     basic             a b c
+# TODO: Intentionally not checking newline here yet, it never worked.
+test_q_eval     spaces            'space space' 'tab   tab'
+test_q_eval     empty_arg         '' '' ''
+test_q_eval     globs             '*' '.*' '[a-zA-Z0-9_]' '?' '~'
+test_q_eval     variables         '$aaa' '${bbb}' '"${ccc} $ddd"'
+test_q_eval     exclamation-mark  '$!' '!$' '!'
+test_q_eval     tilde             '"~"'
+test_q_eval     single-quotes     "'a'" "'"'$bbb'"'"
+test_q_eval     shell-vars        '$1' '$@' '$*' 'ending$'
+test_q_eval     complicated-cmd   grep b '>' /noperm '<' /noperm
+
+test_q_arg_eval basic             a
+test_q_arg_eval single-quotes     "'''"
+test_q_arg_eval double-quotes     '"""'
+test_q_arg_eval tilde             '~'
+test_q_arg_eval ampersand         '&'
+test_q_arg_eval pipe              '|'
+test_q_arg_eval questionmark      'fltest?'
+test_q_arg_eval glob-bracket      'fltest[A-Z]'
+test_q_arg_eval space             'space space'
+test_q_arg_eval tab               'tab tab'
+test_q_arg_eval '`command`'       '`false command`'
+test_q_arg_eval '$(command)'      '$(false command)'
+test_q_arg_eval semicolon         '; false'
+test_q_arg_eval vars              '$aaa ${bbb} "${ccc} $ddd"'
+test_q_arg_eval if-then-else      'if false; then false; else false; fi'
+test_q_arg_eval file-redirect     'echo a > /no-perm 2> /no-perm'
+test_q_arg_eval case-stmt         'case $empty in "") false;; a) broken ;; 
esac'
+test_q_arg_eval comment           'unexistent #'
+test_q_arg_eval func              'func () { } # syntax error'
+
+test_q_expand   basic             'a b c aaa d'   a b c '$aaa' d
+test_q_expand   double-quotes     '" " " "bbb"'   '"' '" "' '"$bbb"'
+test_q_expand   spaces            '     ccc'     ' ' ' ' '${ccc}'
+# Note the *no expected space* here!
+test_q_expand   non-existent      ''              '$empty' '${empty}'
+test_q_expand   non-existent-2    '"" ""'         '"$empty"' '"${empty}"'
+# TODO: Intentionally not checking '$(cmd)' yet.
+test_q_expand   '`command`'       '`aaa bbb`'     '`$aaa $empty${bbb}`'
+
+$all_shells_exit_cmd && rm -rf fltest*
diff --git a/gl/tests/test-option-parser-helper 
b/gl/tests/test-option-parser-helper
new file mode 100755
index 0000000..d92747a
--- /dev/null
+++ b/gl/tests/test-option-parser-helper
@@ -0,0 +1,204 @@
+#! /bin/sh
+
+# Unit tests for funclib.sh
+#
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+. "$abs_aux_dir"/funclib.sh || exit 1
+. "$abs_aux_dir"/options-parser || exit 1
+
+scriptversion='test-version'
+
+func_help ()
+{
+    $ECHO "HELP"
+    exit 0
+}
+
+
+# Make sure that setting <func_name>_result has no effect if we return non-zero
+# return value.
+test_prep_do_nothing ()
+{
+    test_prep_do_nothing_result=
+    false
+}
+func_add_hook func_options_prep test_prep_do_nothing
+
+
+test_prep_shortcuts ()
+{
+    debug_on=
+    test x--debug = "x$1" && debug_on=--debug && shift
+
+    case $1 in
+      short|shortc|shortcu|shortcut)
+        shift
+        func_quote eval --test SHORTCUT $debug_on ${1+"$@"}
+        test_prep_shortcuts_result=$func_quote_result
+        ;;
+      *)
+        false
+        ;;
+    esac
+}
+func_add_hook func_options_prep test_prep_shortcuts
+
+
+test_parse_split_short ()
+{
+    while test $# -gt 0
+    do
+      _G_opt=$1 ; shift
+      case $_G_opt in
+        -t?*)
+          func_split_short_opt "$_G_opt"
+          set dummy "$func_split_short_opt_name" \
+              "$func_split_short_opt_arg" ${1+"$@"}
+          shift
+          ;;
+        *)
+          set dummy "$_G_opt" ${1+"$@"} ; shift
+          ;;
+      esac
+      break
+    done
+
+    func_quote eval ${1+"$@"}
+    test_parse_split_short_result=$func_quote_result
+    :
+}
+func_add_hook func_parse_options test_parse_split_short
+
+
+test_parse_subst_equal_signs ()
+{
+    _G_opt=$1 ; shift
+    case $_G_opt in
+      --*=*)
+        func_split_equals "$_G_opt"
+        set dummy "$func_split_equals_lhs" \
+            "$func_split_equals_rhs" ${1+"$@"}
+        shift
+        func_quote eval ${1+"$@"}
+        test_parse_subst_equal_signs_result=$func_quote_result
+        ;;
+      *)
+        false
+        ;;
+    esac
+}
+func_add_hook func_parse_options test_parse_subst_equal_signs
+
+
+test_parse_do_nothing ()
+{
+    test_parse_do_nothing_result=
+    false
+}
+func_add_hook func_parse_options test_parse_do_nothing
+
+
+test_parse_eat_test ()
+{
+    _t_parse_match=false
+    _G_opt=$1 ; shift
+    case $_G_opt in
+      --test|-t)
+        test $# = 0 && func_missing_arg $_G_opt
+        _t_parse_match=:
+        opt_test=$1
+        shift
+        ;;
+    esac
+
+    $_t_parse_match && {
+      func_quote eval ${1+"$@"}
+      test_parse_eat_test_result=$func_quote_result
+    }
+}
+func_add_hook func_parse_options test_parse_eat_test
+
+
+test_validate_do_nothing ()
+{
+    test_validate_do_nothing_result=
+    false
+}
+func_add_hook func_validate_options test_validate_do_nothing
+
+
+test_validate_eat_sth ()
+{
+    if test validate_out = "$1"; then
+      shift
+      func_quote eval ${1+"$@"}
+      test_validate_eat_sth_result=$func_quote_result
+    else
+      false
+    fi
+}
+func_add_hook func_validate_options test_validate_eat_sth
+
+
+unset_test_opt ()
+{
+    case $# in
+      0)
+        $ECHO UNSET_TEST
+        ;;
+      1)
+        $ECHO "ONE_ARG $*"
+        ;;
+      2)
+        case $1 in
+          eval)
+            eval "$2"
+            exit $?
+            ;;
+        esac
+        ;;
+      3)
+        $ECHO THREE_ARGS
+        ;;
+      *)
+        $ECHO MORE_ARGS
+        ;;
+    esac
+}
+
+
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+case ${opt_test-unset} in
+  '')
+    $ECHO "EMPTY_TEST"
+    ;;
+  unset)
+    unset_test_opt ${1+"$@"}
+    ;;
+  false)
+    $ECHO "FALSE_TEST"
+    exit 1
+    ;;
+  *)
+    $ECHO $opt_test
+    ;;
+esac
+
+:
diff --git a/gl/tests/test-option-parser.sh b/gl/tests/test-option-parser.sh
new file mode 100755
index 0000000..816dd03
--- /dev/null
+++ b/gl/tests/test-option-parser.sh
@@ -0,0 +1,133 @@
+#! /bin/sh
+
+# Unit tests for funclib.sh
+#
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+all_shells_script=$0
+. "$abs_srcdir/test-all-shells.sh"
+
+. "$abs_aux_dir"/options-parser || exit 1
+
+helper=$abs_srcdir/test-option-parser-helper
+
+check_output_inner ()
+{
+    exp_output=$1 ; shift
+    exp_retval=$1 ; shift
+
+    func_quote pretty ${1+"$@"}
+    $ECHO "[[ output check ]] args: $func_quote_result"
+
+    output=`$helper ${1+"$@"} 2>/dev/null`
+    rc=$?
+    test "$rc" -eq "$exp_retval" \
+        || all_shells_error "unexpected exit status $rc $exp_retval"
+
+    if test "$exp_output" = "$output"
+    then
+      :
+    else
+      $ECHO "expected:"
+      $ECHO "$exp_output"
+      $ECHO "given:"
+      $ECHO "$output"
+      all_shells_error "unexpected output"
+    fi
+}
+
+
+check_output ()
+{
+    _co_exp_output=$1 ; shift
+    _co_exp_retval=$1 ; shift
+    # TODO: check with --debug
+    check_output_inner "$_co_exp_output" "$_co_exp_retval" ${1+"$@"}
+    check_output_inner "$_co_exp_output" "$_co_exp_retval" --debug ${1+"$@"}
+}
+
+
+check_retval ()
+{
+    exp_retval=$1 ; shift
+    func_quote pretty ${1+"$@"}
+    $ECHO "[[ retval check ]] args: $func_quote_result"
+    $helper ${1+"$@"} >/dev/null 2>/dev/null
+    rc=$?
+    test "$rc" -eq "$exp_retval" \
+        || all_shells_error "unexpected retval $rc (should be $exp_retval)"
+}
+
+
+grep_output ()
+{
+    grep_for=$1 ; shift
+    exp_retval=$1 ; shift
+
+    func_quote pretty ${1+"$@"}
+    $ECHO "[[ grep for '$grep_for' ]] args: $func_quote_result"
+
+    output=`$helper ${1+"$@"} 2>/dev/null`
+    rc=$?
+    case $output in
+      *$grep_for*) : ;;
+      *) all_shells_error "$grep_for is not in stdout $output" ;;
+    esac
+
+    test "$rc" -eq "$exp_retval" \
+        || all_shells_error "unexpected retval $rc (should be $exp_retval)"
+}
+
+
+check_output HELP         0 --help
+check_output HELP         0 --test jej --help
+check_output HELP         0 --test=jej --help
+check_output HELP         0 --test= --help
+
+check_output EMPTY_TEST   0 --test=
+check_output EMPTY_TEST   0 -t ''
+check_output EMPTY_TEST   0 --test ''
+check_output FALSE_TEST   1 --test=false
+check_output FALSE_TEST   1 -tfalse
+check_output FALSE_TEST   1 -t false
+check_output UNSET_TEST   0
+check_output 'ONE_ARG a'  0 a
+check_output THREE_ARGS   0 a b c
+check_output MORE_ARGS    0 a b c d
+
+check_output SHORTCUT     0 short
+check_output SHORTCUT     0 shortcut
+check_output HELP         0 short --help
+
+check_output eval         4 eval 'echo eval ; exit 4'
+check_output eval         4 validate_out eval 'echo eval ; exit 4'
+
+# No argument.
+check_retval              1 --test
+check_retval              1 --not-existent
+check_retval              1 short --not-existent
+
+grep_output  test-version 0 --version
+grep_output  test-version 0 --version --whatever
+grep_output  test-version 0 --debug --version
+
+# TODO: Shouldn't this code be able to parse multiple occurrences of
+# single option (IOW, hooks should be called in loop..)?
+# check_output FALSE_TEST 1 short --test false
+# check_output FALSE_TEST 1 --test a --test false
+
+$all_shells_exit_cmd
diff --git a/gnulib b/gnulib
index a5a1569..82d514b 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit a5a1569d1953536af019636c49bd3e7a5cbbbde2
+Subproject commit 82d514b0645efd10b2b68b911372ae84e1a54da4
diff --git a/libtoolize.in b/libtoolize.in
index 798bd0a..3fe61ce 100644
--- a/libtoolize.in
+++ b/libtoolize.in
@@ -151,11 +151,11 @@ libtoolize_environment_options ()
 
     # Pass back the updated list of options.
     if test -n "$envopts"; then
-      func_quote_for_eval "$envopts" ${1+"$@"}
+      func_quote eval "$envopts" ${1+"$@"}
     else
-      func_quote_for_eval ${1+"$@"}
+      func_quote eval ${1+"$@"}
     fi
-    libtoolize_environment_options_result=$func_quote_for_eval_result
+    libtoolize_environment_options_result=$func_quote_result
 }
 func_add_hook func_options_prep libtoolize_environment_options
 
@@ -181,8 +181,8 @@ libtoolize_options_prep ()
     ltdl_mode=
 
     # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtoolize_options_prep_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    libtoolize_options_prep_result=$func_quote_result
 }
 func_add_hook func_options_prep libtoolize_options_prep
 
@@ -252,8 +252,8 @@ libtoolize_parse_options ()
     done
 
     # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtoolize_parse_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    libtoolize_parse_options_result=$func_quote_result
 }
 func_add_hook func_parse_options libtoolize_parse_options
 
@@ -286,8 +286,8 @@ libtoolize_validate_options ()
       func_fatal_help "unknown additional arguments: 'address@hidden'"
 
     # Pass back the empty argument list
-    func_quote_for_eval ${1+"$@"}
-    libtoolize_validate_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    libtoolize_validate_options_result=$func_quote_result
 }
 func_add_hook func_validate_options libtoolize_validate_options
 


hooks/post-receive
-- 
GNU Libtool



reply via email to

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