--- /dev/null
+#! /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
+
+:
--- /dev/null
+#! /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