On Monday 05 of October 2015 09:47:05 Pavel Raiskup wrote: > On Monday 05 of October 2015 01:25:24 Pavel Raiskup wrote: > > On Monday 05 of October 2015 00:45:50 Pavel Raiskup wrote: > > > > should we test the size of the string first ? i've written such raw > > > > shell > > > > string parsing functions before, and once you hit a certain size (like > > > > 1k+ > > > > iirc), forking out to sed is way faster, especially when running in > > > > multibyte > > > > locales (like UTF8) which most people are doing nowadays. > > > > -mike > > > > > > Well, that optimization would require (fast) strlen()-like construct. > > > Anyway, the vast majority of calls to func_quote () function will have > > > short ARG, and its complexity is still "just" linear. We could optimize > > > later if that was a real issue. > > > > > > I would like to propose solution based on Eric's one, without using of > > > '${VAR%.}' and '${VAR#.}' constructs -- sounds like this could be even > > > more portable while it keeps almost the same speed (if we can use += its > > > even faster). > > > > > > I have yet a another patch trying to minimize option-parser overhead > > > (that is focused on the POV of Richard, but that needs to be cleaned up a > > > bit, I'll post hopefully tomorrow). > > > > > > Any comment is welcome! > > > > Re-attached (fixes for 'make syntax-check' and fixed one comment). > > Hmm, one might-be-a-problem with this (catched by testsuite), when you > have: > > $ cat build-aux/test-quoting > . `echo "$0" |${SED-sed} 's|[^/]*$||'`/funclib.sh > # source this for "GNU m4" detection methods > . `echo "$0" |${SED-sed} 's|[^/]*$||'`/extract-trace > > func_quote_for_eval "$@" > echo "$func_quote_for_eval_result" > > Then: > > $ ./build-aux/test-quoting '"a b"' # fine > "\"a b\"" > > $ ./build-aux/test-quoting '"*tool"' # broken > ./build-aux/test-quoting '"*tool"' > \"libtool\" > > We would like to have an output \"*\". I'm not aware of portable way > how to disable wildcard expansion in shell, and autoconf 'Shellology' > section haven't helped me. In particular, the problem is here: > > x='a"[a-z]*"c' > IFS='"' > for i in $x; do # Here we wan't to disable wildcard expansion > echo $i > done > > Any idea other than fallback to $sed_quote_subst in case of '*' or '[' > exists in ARG?
Attaching two (yet to be cleaned) patches doing the optimization. Is anybody able to test/comment on this particular solution? That would be really appreciated. Pavel
>From 1b89ae66f88c3822b2afec128f288d409287780f Mon Sep 17 00:00:00 2001 From: Pavel Raiskup <prais...@redhat.com> Date: Sun, 4 Oct 2015 21:55:03 +0200 Subject: [PATCH 1/2] 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. --- NEWS | 3 +++ bootstrap | 56 +++++++++++++++++++++++++++++++++++++++++++++++-- build-aux/ltmain.in | 10 +++++---- gl/build-aux/funclib.sh | 56 +++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 117 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index a3c5b12..7c23d03 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,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..2649478 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-10-04.22; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 @@ -1257,6 +1257,57 @@ func_relative_path () } +# func_quote ARG +# -------------- +# Aesthetically quote one ARG, store the result into $func_quote_result. Note +# that we keep attention to performance here (so far O(N) complexity as long as +# func_append is O(1)). +func_quote () +{ + $debug_cmd + + func_quote_result=$1 + + case $func_quote_result in + *[\\\`\"\$]*) + case $func_quote_result in + *'*'*|*'['*) + func_quote_result=`$ECHO "$func_quote_result" | $SED "$sed_quote_subst"` + return 0 + ;; + esac + + func_quote_old_IFS=$IFS + for _G_char in '\' '`' '"' '$' + do + # STATE($1) PREV($2) SEPARATOR($3) + set start "" "" + func_quote_result=dummy"$_G_char$func_quote_result$_G_char"dummy + IFS=$_G_char + for _G_part in $func_quote_result + do + case $1 in + quote) + func_append func_quote_result "$3$2" + set quote "$_G_part" "\\$_G_char" + ;; + start) + set first "" "" + func_quote_result= + ;; + first) + set quote "$_G_part" "" + ;; + esac + done + IFS=$func_quote_old_IFS + done + ;; + *) ;; + esac +} + + # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. @@ -1275,7 +1326,8 @@ func_quote_for_eval () while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + func_quote "$1" + _G_unquoted_arg=$func_quote_result ;; *) _G_unquoted_arg=$1 ;; esac diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in index 0c40da0..24acefd 100644 --- a/build-aux/ltmain.in +++ b/build-aux/ltmain.in @@ -3346,7 +3346,8 @@ else if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + func_quote "$ECHO" + qECHO=$func_quote_result $ECHO "\ # A function that is used when there is no print builtin or printf. @@ -8596,8 +8597,8 @@ EOF relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + func_quote "(cd `pwd`; $relink_command)" + relink_command=$func_quote_result fi # Only actually do things if not in dry run mode. @@ -8843,7 +8844,8 @@ EOF 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 "$relink_command" + relink_command=$func_quote_result if test yes = "$hardcode_automatic"; then relink_command= fi diff --git a/gl/build-aux/funclib.sh b/gl/build-aux/funclib.sh index 39d972e..8032e6b 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-10-04.22; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 @@ -1026,6 +1026,57 @@ func_relative_path () } +# func_quote ARG +# -------------- +# Aesthetically quote one ARG, store the result into $func_quote_result. Note +# that we keep attention to performance here (so far O(N) complexity as long as +# func_append is O(1)). +func_quote () +{ + $debug_cmd + + func_quote_result=$1 + + case $func_quote_result in + *[\\\`\"\$]*) + case $func_quote_result in + *'*'*|*'['*) + func_quote_result=`$ECHO "$func_quote_result" | $SED "$sed_quote_subst"` + return 0 + ;; + esac + + func_quote_old_IFS=$IFS + for _G_char in '\' '`' '"' '$' + do + # STATE($1) PREV($2) SEPARATOR($3) + set start "" "" + func_quote_result=dummy"$_G_char$func_quote_result$_G_char"dummy + IFS=$_G_char + for _G_part in $func_quote_result + do + case $1 in + quote) + func_append func_quote_result "$3$2" + set quote "$_G_part" "\\$_G_char" + ;; + start) + set first "" "" + func_quote_result= + ;; + first) + set quote "$_G_part" "" + ;; + esac + done + IFS=$func_quote_old_IFS + done + ;; + *) ;; + esac +} + + # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. @@ -1044,7 +1095,8 @@ func_quote_for_eval () while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + func_quote "$1" + _G_unquoted_arg=$func_quote_result ;; *) _G_unquoted_arg=$1 ;; esac -- 2.5.0
>From c283b8a8e7540b65fd7a7d32fceec6ed42b5b2a7 Mon Sep 17 00:00:00 2001 From: Pavel Raiskup <prais...@redhat.com> Date: Mon, 5 Oct 2015 13:16:08 +0200 Subject: [PATCH 2/2] libbtool: optimize parse-options calls Its not necessary to re-escape-for-eval in each function in the hook-able function tree -- usually is enough if the leaf function executes func_quote_for_eval() and its caller just re-uses the CALLEE_return value. * gl/build-aux/options-parser (func_run_hooks): Propagate 0 return code down to caller if any $_G_hook succeeded. Don't re-quote the result as that has already been done by the succeeding hook itself. (func_parse_options): Quote only if we changed something and use appropriate return code. (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 only if we changed something and use appropriate return code. (libtool_parse_options): Likewise. * bootstrap: Sync gl/build-aux/with option-parser. --- bootstrap | 128 +++++++++++++++++++++++++++++++++----------- build-aux/ltmain.in | 33 +++++++++--- gl/build-aux/options-parser | 128 +++++++++++++++++++++++++++++++++----------- 3 files changed, 220 insertions(+), 69 deletions(-) diff --git a/bootstrap b/bootstrap index 2649478..c4de711 100755 --- a/bootstrap +++ b/bootstrap @@ -1744,10 +1744,17 @@ func_remove_hook () # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. +# If at least one hook returns 0 (exit success) upon execution, +# func_run_hooks () returns zero too. Otherwise 1 is returned. +# All hooks are expected to correctly return $HOOKNAME_result variable +# upon success exection. The output variable $func_run_hooks_result +# is set to latest (successful) $HOOKNAME_result. 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" ;; @@ -1756,16 +1763,24 @@ func_run_hooks () eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do - eval $_G_hook '"$@"' + _G_hook_unchanged=${_G_hook}_unchanged + eval $_G_hook_unchanged=false - # 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=true + fi done - func_quote_for_eval ${1+"$@"} - func_run_hooks_result=$func_quote_for_eval_result + if $_G_rc_run_hooks; then + # No need to re-quote by func_quoteh + func_run_hooks_result=$_G_hook_result + fi + + $_G_rc_run_hooks } @@ -1839,6 +1854,24 @@ func_run_hooks () # multiple option parsing hooks can be added safely. +# func_options_finish [ARG]... +# ---------------------------- +# All finishing suff required after the option parse loop. This executes +# all 'func_options' hooks. +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 @@ -1848,17 +1881,26 @@ 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 + if $_G_rc_options; then + func_options_result=$_G_res_var + else + # As a top-level function, we need *always* set the *_result + func_quote_for_eval ${1+"$@"} + func_options_result=$func_quote_for_eval_result + fi + + $_G_rc_options } @@ -1869,7 +1911,9 @@ func_options () # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before -# returning. +# returning and 0 returned. If no changes were done, script might return +# 1 and caller of the hook will not read the 'func_run_hooks_result' +# value. func_hookable func_options_prep func_options_prep () { @@ -1879,10 +1923,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 } @@ -1896,18 +1944,21 @@ 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 + # Adjust func_parse_options positional parameters to match + 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 @@ -1977,13 +2028,23 @@ func_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_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_parse_options } @@ -1996,16 +2057,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/build-aux/ltmain.in b/build-aux/ltmain.in index 24acefd..e57042a 100644 --- a/build-aux/ltmain.in +++ b/build-aux/ltmain.in @@ -358,6 +358,8 @@ libtool_options_prep () nonopt= preserve_args= + _G_rc_libtool_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_libtool_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_libtool_options_prep; then + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result + fi + + $_G_rc_libtool_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 @@ -475,14 +487,21 @@ libtool_parse_options () ;; # An option not handled by this hook function: - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + *) 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_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_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 diff --git a/gl/build-aux/options-parser b/gl/build-aux/options-parser index d651f1d..73db1e3 100644 --- a/gl/build-aux/options-parser +++ b/gl/build-aux/options-parser @@ -157,10 +157,17 @@ func_remove_hook () # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. +# If at least one hook returns 0 (exit success) upon execution, +# func_run_hooks () returns zero too. Otherwise 1 is returned. +# All hooks are expected to correctly return $HOOKNAME_result variable +# upon success exection. The output variable $func_run_hooks_result +# is set to latest (successful) $HOOKNAME_result. 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 +176,24 @@ func_run_hooks () eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do - eval $_G_hook '"$@"' + _G_hook_unchanged=${_G_hook}_unchanged + eval $_G_hook_unchanged=false - # 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=true + fi done - func_quote_for_eval ${1+"$@"} - func_run_hooks_result=$func_quote_for_eval_result + if $_G_rc_run_hooks; then + # No need to re-quote by func_quoteh + func_run_hooks_result=$_G_hook_result + fi + + $_G_rc_run_hooks } @@ -252,6 +267,24 @@ func_run_hooks () # multiple option parsing hooks can be added safely. +# func_options_finish [ARG]... +# ---------------------------- +# All finishing suff required after the option parse loop. This executes +# all 'func_options' hooks. +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 +294,26 @@ 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 + if $_G_rc_options; then + func_options_result=$_G_res_var + else + # As a top-level function, we need *always* set the *_result + func_quote_for_eval ${1+"$@"} + func_options_result=$func_quote_for_eval_result + fi + + $_G_rc_options } @@ -282,7 +324,9 @@ func_options () # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before -# returning. +# returning and 0 returned. If no changes were done, script might return +# 1 and caller of the hook will not read the 'func_run_hooks_result' +# value. func_hookable func_options_prep func_options_prep () { @@ -292,10 +336,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,18 +357,21 @@ 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 + # Adjust func_parse_options positional parameters to match + 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 @@ -390,13 +441,23 @@ func_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_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_parse_options } @@ -409,16 +470,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 } -- 2.5.0
_______________________________________________ https://lists.gnu.org/mailman/listinfo/libtool