Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Use getopt_long from Stéphane Chazelas. Thanks Stéphane!

  • Loading branch information...
commit 999996f63ab05d8268c842d716f23674f3c65de3 1 parent e6815e5
@rocky authored
View
7 AUTHORS
@@ -1 +1,8 @@
R. Bernstein (rocky@gnu.org)
+
+Kate Ward is the author of shunit2 used in unit testing
+
+Stéphane Chazelas is the author of getopts_long.sh for GNU long options
+ processing
+
+Nikolaj Schumacher is the author of elk-test.el used in GNU Emacs testing
View
23 Makefile.am
@@ -1,3 +1,19 @@
+# Copyright (C) 2008 Rocky Bernstein rocky@gnu.org
+#
+# zshdb 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 2, or (at your option) any later
+# version.
+#
+# zshdb 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 zshdb; see the file COPYING. If not, write to the Free Software
+# Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+
SUBDIRS = command emacs lib test
pkgdata_DATA = \
@@ -5,12 +21,13 @@ pkgdata_DATA = \
dbg-io.sh \
dbg-main.sh \
dbg-opts.sh \
- dbg-trace.sh
+ dbg-trace.sh \
+ getopts_long.sh
# Set up the install target
bin_SCRIPTS = kshdb
-EXTRA_DIST = $(pkgdata_DATA) THANKS getopt-test.sh
+EXTRA_DIST = $(pkgdata_DATA) THANKS
# cvs2cl
MAINTAINERCLEANFILES = ChangeLog
@@ -36,5 +53,3 @@ ACLOCAL_AMFLAGS=-I .
endif
.PHONY: $(CL) test
-
-
View
3  THANKS
@@ -1,2 +1,5 @@
Thanks to David Korn for the adding necessary support to ksh
needed to get this off the ground and make debugging possible.
+
+Thanks to Kate Ward, Stéphane Chazelas and Nikolaj Schumacher for
+programs used in conjunction with zshdb.
View
29 configure.ac
@@ -6,26 +6,6 @@ AM_PATH_LISPDIR
AM_MAINTAINER_MODE
AM_INIT_AUTOMAKE([no-define])
-AC_SUBST(TRY_GETOPT)
-
-AC_ARG_ENABLE([gnugetopt],
- AC_HELP_STRING([--enable-getopt],
- [Allow GNU-style long options (default enabled)]))
-
-if test "${enable_getopt}" != "no" ; then
- $SH_PROG ${srcdir}/getopt-test.sh
- if test $? -eq 0 ; then
- AC_MSG_RESULT([Good! Your long options seem to be working okay.])
- TRY_GETOPT=1
- else
- AC_MSG_WARN([getopt doesn't seem to handle long options correctly.])
- AC_MSG_WARN([Disabling long-options in] DEBUGGER[.])
- TRY_GETOPT=0
- fi
-else
- TRY_GETOPT=0
-fi
-
AC_CONFIG_SRCDIR(DEBUGGER.in)
if test x$srcdir = x ; then
srcdir=$ac_pwd
@@ -48,8 +28,8 @@ then
fi
if test "$SH_PROG" = no; then
- AC_MSG_ERROR([I didn't find the DEBUGGER executable.\
- You might want to use the --with-DEBUGGER option.])
+ AC_MSG_ERROR([I didn't find the] POSIXSHELL [executable.\
+ You might want to use the] --with-POSIXSHELL [option.])
fi
AC_MSG_CHECKING([Checking whether $SH_PROG is compatible with DEBUGGER])
@@ -98,7 +78,8 @@ else
fi
fi
-AM_CONDITIONAL(INSTALL_EMACS_LISP, test "x$lispdir" != "x")
+AM_CONDITIONAL(INSTALL_EMACS_LISP,
+ [test "x$lispdir" != "x" -a "x$EMACS" != "xno"])
AC_CONFIG_FILES([ \
Makefile \
@@ -121,6 +102,8 @@ AC_CONFIG_FILES([test/example/hanoi.sh],
AC_CONFIG_FILES([test/unit/test-alias.sh], [chmod +x test/unit/test-alias.sh])
AC_CONFIG_FILES([test/unit/test-columns.sh],
[chmod +x test/unit/test-columns.sh])
+AC_CONFIG_FILES([test/unit/test-dbg-opts.sh],
+ [chmod +x test/unit/test-dbg-opts.sh])
AC_CONFIG_FILES([test/unit/test-filecache.sh],
[chmod +x test/unit/test-filecache.sh])
AC_CONFIG_FILES([test/unit/test-fns.sh], [chmod +x test/unit/test-fns.sh])
View
265 dbg-opts.sh
@@ -17,154 +17,139 @@
# with kshdb; see the file COPYING. If not, write to the Free Software
# Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
-typeset _Dbg_tmpdir=/tmp
-typeset -i _Dbg_opt_linetrace=0
-typeset -i o_no_quit=0
+_Dbg_usage() {
+ printf "Usage:
+ ${_Dbg_pname} [OPTIONS] <script_file>
-# Use gdb-style annotate?
-typeset -i _Dbg_annotate=0
-
-function _Dbg_usage_long {
- printf "usage:
- ${_Dbg_pname} [OPTIONS] <script_file>
-
-Runs bash <script_file> under a debugger.
+Runs zsh <script_file> under a debugger.
-options:
- -A | --annotate LEVEL set annotation level.
- -B | --basename basename only on source listings.
+options:
+ -h | --help Print this help.
+ -q | --quiet Do not print introductory and quiet messages.
+ -A | --annotate LEVEL Set the annotation level.
+ -B | --basename Show basename only on source file listings.
(Needed in regression tests)
- -h | --help print this help
- -n | --nx |--no-init Don't run initialization files
- -c cmd | --eval-command cmd Run this passed argument as a script
- -q | --quiet Quiet. Do not print introductory and quiet messages.
-L libdir | --library libdir
- set directory location of library helper file: $_Dbg_main
- The default directory is: $_Dbg_libdir
- -T tmpdir | --tempdir set directory location for temporary files: $_Dbg_tmpdir
- -t tty | --tty tty | --terminal tty
- set debugger terminal
- -x command | --command cmdfile
- execute debugger commands from cmdfile
- -X | --trace set line tracing
- -V | --version show version number and no-warranty and exit.
-
-Long options may be abbreviated, e.g. --lib is okay for --library.
-" 1>&2
+ Set the directory location of library helper file: $_Dbg_main
+ -n | --nx | --no-init Don't run initialization files.
+ -V | --version Print the debugger version number.
+ -x command | --command CMDFILE
+ Execute debugger commands from CMDFILE.
+" >&2
+ exit 100
}
-_Dbg_usage_short() {
- printf "_Dbg_usage:
- ${_Dbg_pname} [OPTIONS] <script_file>
-
-Runs script_file under a debugger.
-
-options:
- -A LEVEL set annotation level.
- -B basename only on source listings. (Needed in regression tests)
- -h print this help
- -n Don't run initialization files
- -c command Run this passed command as a script
- -q Quiet. Do not print introductory and quiet messages.
- -L libdir | --library libdir
- set directory location of library helper file: $_Dbg_main
- the default directory is: $_Dbg_libdir
- -T tmpdir set directory location for temporary files: $_Dbg_tmpdir
- -t tty set debugger terminal
- -x cmdfile execute debugger commands from cmdfile
- -X set line tracing
- -Y set line tracing with variable expansion
- -V show version number and no-warranty and exit.
-" 1>&2
+_Dbg_show_version() {
+ printf 'There is absolutely no warranty for kshdb. Type "show warranty" for details.
+' >&2
+ exit 101
+
}
-# Process using short or long options, depending on the availability
-# of getopt
-TEMP=`getopt -o testing t 2>/dev/null`
-if ((_Dbg_try_getopt && 0 == $? )) ; then
- # Process using long options
- # Note that we use `"$@"' to let each command-line parameter expand to a
- # separate word. The quotes around `$@' are essential!
- # We need TEMP as the `eval set --' would nuke the return value of getopt.
- TEMP=`getopt -o A:Bc:hL:nqt:T::x:XYV \
---long annotate:,basename,command:,debugger,exec-command,help,library:,no-init,quiet,tempdir:,terminal:,trace,tty,version \
- -n 'kshdb' -- "$@"`
-
- if [ $? != 0 ] ; then
- echo "Use --help for option help. Terminating..." >&2 ;
- exit 1 ;
- fi
-
- # Note the quotes around `$TEMP': they are essential!
- eval set -- "$TEMP"
-
- while true ; do
- case $1 in
- -A|--annotate) _Dbg_annotate="$2"; shift ;;
- -B|--basename) _Dbg_basename_only=1 ;;
- -c|--eval-command) _Dbg_cmd="$2"; shift ;;
- --debugger) ;; # This option is for compatibility with bash --debugger
- -h|--help) _Dbg_usage_long; exit 100 ;;
- -L|--library) shift ;; # Handled previously
- -n|--nx|--no-init) _Dbg_no_init=1 ;;
- -q|--quiet) _Dbg_quiet=1 ;;
- -T|--tempdir) _Dbg_tmpdir=$2; shift ;;
- -t|--terminal|--tty)
- if ! $(touch $2 >/dev/null 2>/dev/null); then
- echo "${_Dbg_pname}: Can't access $2 for writing."
- elif [[ ! -w $2 ]] ; then
- echo "${_Dbg_pname}: terminal $2 needs to be writable."
- else
- _Dbg_tty=$2 ;
- fi
- shift
- ;;
- -x|--command) DBG_INPUT="$DBG_INPUT $2"; shift ;;
- -X|--trace) _Dbg_opt_linetrace=1 ;;
- # -Y|--vtrace) _Dbg_opt_linetrace=1 ; _Dbg_opt_linetrace_expand=1 ;;
- -V|--version) show_version=1 ;;
- --) shift ; break ;;
- *)
- echo "Use --help for option help. Terminating..."
- exit 2 ;;
- esac
- shift
- done
-else
- # Process using short options
- while getopts :A:Bc:hL:nqt:T:x:XYV opt; do
- case $opt in
- A) _Dbg_annotate=1 ;;
- B) _Dbg_basename_only=1 ;;
- c) _Dbg_cmd="$OPTARG" ;;
- h) _Dbg_usage_short; exit 100 ;;
- n) _Dbg_no_init=1 ;;
- q) _Dbg_quiet=1 ;;
- L) ;; # Handled previously
- T) _Dbg_tmpdir=$OPTARG ;;
- t)
- if ! $(touch $OPTARG >/dev/null 2>/dev/null); then
- echo "${_Dbg_pname}: Can't access $OPTARG for writing."
- elif [[ ! -w $OPTARG ]] ; then
- echo "${_Dbg_pname}: terminal $OPTARG needs to be writable."
- else
- _Dbg_tty=$OPTARG
- fi
- ;;
- V) show_version=1 ;;
- x) DBG_INPUT="$OPTARG" ;;
- X) _Dbg_opt_linetrace=1 ;;
- # Y) _Dbg_opt_linetrace=1 ; _Dbg_opt_linetrace_expand=1 ;;
- *)
- if ((_Dbg_basename_only == 1)) ; then
- echo "${_Dbg_pname}: unrecognized option -- $OPTARG"
+# Script arguments before adulteration by _Dbg_parse_otps
+typeset -a _Dbg_orig_script_args
+_Dbg_orig_script_args=($@)
+
+
+# The following globals are set by _Dbg_parse_opts. Any values set are
+# the default values.
+typeset -a _Dbg_script_args
+
+typeset -i _Dbg_annotate=0
+typeset -i _Dbg_linetrace=0
+typeset -i _Dbg_basename_only=0
+typeset -i _Dbg_o_nx=0
+
+
+_Dbg_parse_options() {
+
+ . ${_Dbg_libdir}/getopts_long.sh
+
+ typeset -i _Dbg_o_quiet=0
+ typeset -i _Dbg_o_version=0
+
+ while getopts_long A:Bx:hL:nqV opt \
+ annotate required_argument \
+ basename 0 \
+ cmdfile required_argument \
+ help 0 \
+ '?' 0 \
+ library required_argument \
+ no-init 0 \
+ nx 0 \
+ quiet 0 \
+ version 0 \
+ '' "$@"
+ do
+ case "$opt" in
+ A | annotate )
+ _Dbg_o_annotate=$OPTLARG
+ ;;
+ B | basename )
+ _Dbg_basename_only=1
+ ;;
+ x | command )
+ DBG_INPUT=$OPTLARG
+ ;;
+ h | '?' | help )
+ _Dbg_usage
+ ;;
+ L | library )
+ ;;
+ V | version )
+ _Dbg_o_version=1
+ ;;
+ n | nx | no-init )
+ _Dbg_o_nx=1
+ ;;
+ q | quiet )
+ _Dbg_o_quiet=1
+ ;;
+ * )
+ print "Unknown option $opt. Use -h or --help to see options" >&2
+ exit 2
+ ;;
+ esac
+ done
+ shift "$(($OPTLIND - 1))"
+
+ if (( ! _Dbg_o_quiet && ! _Dbg_o_version )); then
+ print "Zsh Shell Debugger, release $_Dbg_release"
+ printf '
+Copyright 2008 Rocky Bernstein
+This is free software, covered by the GNU General Public License, and you are
+welcome to change it and/or distribute copies of it under certain conditions.
+
+'
+ fi
+ (( _Dbg_o_version )) && _Dbg_show_version
+
+ if [[ -n $_Dbg_o_annotate ]] ; then
+ if [[ ${_Dbg_o_annotate} == [0-9]* ]] ; then
+ _Dbg_annotate=$_Dbg_o_annotate
+ if (( _Dbg_annotate > 3 || _Dbg_annotate < 0)); then
+ print "Annotation level must be less between 0 and 3. Got: $_Dbg_annotate." >&2
+ print "Setting Annotation level to 0." >&2
+ _Dbg_annotate=0
+ fi
else
- echo "$0: unrecognized option -- $OPTARG"
+ print "Annotate option should be an integer, got ${_Dbg_o_annotate}." >&2
+ print "Setting annotation level to 0." >&2
fi
- echo "Use -h for option help. Terminating..."
- exit 2
- ;;
- esac
- done
- shift $(($OPTIND - 1))
+ fi
+ unset _Dbg_o_annotate _Dbg_o_version _Dbg_o_quiet
+ _Dbg_script_args=($@)
+}
+
+[[ -n $DBG_INPUT ]] && typeset -p DBG_INPUT
+
+
+# Stand-alone Testing.
+if [[ -n "$_Dbg_dbg_opts_test" ]] ; then
+ OPTLIND=1
+ _Dbg_libdir='.'
+ _Dbg_parse_options "$@"
+ typeset -p _Dbg_annotate
+ typeset -p _Dbg_linetrace
+ typeset -p _Dbg_basename_only
fi
View
13 dbg-pre.sh
@@ -38,8 +38,6 @@ typeset -r _Dbg_release='0.01git'
# Will be set to 1 if the top-level call is a debugger.
typeset -i _Dbg_script=0
-typeset -i _Dbg_basename_only=0
-
# Expand filename given as $1.
# we echo the expanded name or return $1 unchanged if a bad filename.
# Return is 0 if good or 1 if bad.
@@ -56,7 +54,7 @@ function _Dbg_expand_filename {
typeset -x dirname=${filename%/*}
# No slash given in filename? Then use . for dirname
- [[ $dirname == $basename ]] && dirname='.'
+ [[ $dirname == $basename ]] && [[ $filename != '/' ]] && dirname='.'
# Dirname is ''? Then use / for dirname
dirname=${dirname:-/}
@@ -64,11 +62,11 @@ function _Dbg_expand_filename {
# Handle tilde expansion in dirname
dirname=$(echo $dirname)
- typeset long_path;
+ typeset long_path
[[ $basename == '.' ]] && basename=''
if long_path=$( (cd "$dirname" ; pwd) ) ; then
- if [[ $long_path == '/' ]] ; then
+ if [[ "$long_path" == '/' ]] ; then
echo "/$basename"
else
echo "$long_path/$basename"
@@ -91,6 +89,8 @@ _Dbg_tempname() {
# Process command-line options
. ${_Dbg_libdir}/dbg-opts.sh
+OPTLIND=1
+_Dbg_parse_options "$@"
if [[ ! -d $_Dbg_tmpdir ]] && [[ ! -w $_Dbg_tmpdir ]] ; then
echo "${_Dbg_pname}: cannot write to temp directory $_Dbg_tmpdir." >&2
@@ -108,9 +108,6 @@ typeset _Dbg_init_cwd=$PWD
# fi
# fi
-typeset -a _Dbg_script_args
-_Dbg_script_args=($@)
-
typeset -i _Dbg_running=1 # True we are not finished running the program
typeset -i _Dbg_currentbp=0 # If nonzero, the breakpoint number that we
View
675 getopts_long.sh
@@ -0,0 +1,675 @@
+#! /bin/echo Usage:.
+#
+# getopts_long -- POSIX shell getopts with GNU-style long option support
+#
+# Copyright 2005-2008 Stephane Chazelas <stephane_chazelas@yahoo.fr>
+#
+# Permission to use, copy, modify, distribute, and sell this software and
+# its documentation for any purpose is hereby granted without fee, provided
+# that the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation. No representations are made about the suitability of this
+# software for any purpose. It is provided "as is" without express or
+# implied warranty.
+
+
+getopts_long() {
+ # args: shortopts, var, [name, type]*, "", "$@"
+ #
+ # getopts_long parses command line arguments. It works like the
+ # getopts shell built-in command except that it also recognises long
+ # options a la GNU.
+ #
+ # You must provide getopts_long with the list of supported single
+ # letter options in the same format as getopts', followed by the
+ # variable name you want getopts_long to return the current processed
+ # option in, followed by the list of long option names (without the
+ # leading "--") and types (0 or no_argument, 1 or required_argument,
+ # 2 or optional_argument). The end of the long option specification
+ # is indicated by an empty argument. Then follows the list of
+ # arguments to be parsed.
+ #
+ # The $OPTLIND variable must be set to 1 before the first call of the
+ # getopts_long function to process a given list of arguments.
+ #
+ # getopts_long returns the value of the current option in the variable
+ # whose name is provided as its second argument (be careful to avoid
+ # variables that have a special signification to getopts_long or the
+ # shell or any other tool you may call from your script). If the
+ # current option is a single letter option, then it is returned
+ # without the leading "-". If it's a long option (possibly
+ # abbreviated), then the full name of the option (without the leading
+ # "--") is returned. If the option has an argument, then it is stored
+ # in the $OPTLARG variable. If the current option is not recognised,
+ # or if it is provided with an argument while it is not expecting one
+ # (as in --opt=value) or if it is not provided with an argument while
+ # it is expecting one, or if the option is so abbreviated that it is
+ # impossible to identify the option uniquely, then:
+ # - if the short option specifications begin with ":", getopts_long
+ # returns ":" in the output variable and $OPTLARG contains the
+ # faulty option name (in full except in the case of the ambiguous
+ # or bad option) and $OPTLERR contains the error message.
+ # - if not, then getopts_long behaves the same as above except that
+ # it returns "?" instead of ":", leaves $OPTLARG unset and
+ # displays the error message on stderr.
+ #
+ # The exit status of getopts_long is 0 unless the end of options is
+ # reached or an error is encountered in the syntax of the getopts_long
+ # call.
+ #
+ # After getopts_long has finished processing the options, $OPTLIND
+ # contains the index of the first non-option argument or $# + 1 if
+ # there's no non-option argument.
+ #
+ # The "=" character is not allowed in a long option name. Any other
+ # character is. "-" and ":" are not allowed as short option names. Any
+ # other character is. If a short option appears more than once in the
+ # specification, the one with the greatest number of ":"s following it
+ # is retained. If a long option name is provided more than once, only
+ # the first one is taken into account. Note that if you have both a -a
+ # and --a option, there's no way to differentiate them. Beside the
+ # $OPTLIND, $OPTLARG, and $OPTLERR, getopts_long uses the $OPTLPENDING
+ # variable to hold the remaining options to be processed for arguments
+ # with several one-letter options. That variable shouldn't be used
+ # anywhere else in your script. Those 4 variables are the only ones
+ # getopts_long may modify.
+ #
+ # Dependency: only POSIX utilities are called by that function. They
+ # are "set", "unset", "shift", "break", "return", "eval", "command",
+ # ":", "printf" and "[". Those are generally built in the POSIX
+ # shells. Only "printf" has been known not to be in some old versions
+ # of bash, zsh or ash based shells.
+ #
+ # Differences with the POSIX getopts:
+ # - if an error is detected during the parsing of command line
+ # arguments, the error message is stored in the $OPTLERR variable
+ # - in the single-letter option specification, if a letter is
+ # followed by 2 colons ("::"), then the option can have an optional
+ # argument as in GNU getopt(3). In that case, the argument must
+ # directly follow the option as in -oarg (not -o arg).
+ # - there must be an empty argument to mark the end of the option
+ # specification.
+ # - long options starting with "--" are supported.
+ #
+ # Differences with GNU getopt_long(3):
+ # - getopts_long doesn't allow options to be interspersed with other
+ # arguments (as if POSIXLY_CORRECT was set for GNU getopt_long(3))
+ # - there's no linkage of any sort between the short and long
+ # options. The caller is responsible of that (see example below).
+ #
+ # Compatibility:
+ # getopts_long code is (hopefully) POSIX.2/SUSv3 compliant. It won't
+ # work with the Bourne/SystemV shell. Use /usr/xpg4/bin/sh or ksh or
+ # bash on Solaris.
+ # It has been tested successfully with:
+ # - bash 3.0 (patch level 16) on Cygwin
+ # - zsh 4.2.4 on Solaris 2.7
+ # - /usr/xpg4/bin/sh (same as /usr/bin/ksh) (ksh88i) on Solaris 2.7
+ # - /usr/dt/bin/dtksh (ksh93d) on Solaris 2.7
+ # - /usr/bin/ksh (pdksh 5.2.14) on Linux
+ # - zsh 3.0.6 on Solaris 2.8
+ # - bash 2.0.3 on Solaris 2.8
+ # - dash 0.5.2 on Linux
+ # - bash 2.05b (patch level 0) on Linux
+ # - ksh93p and ksh93q on Linux
+ #
+ # It is known to fail with those non-POSIX compliant shells:
+ # - /bin/sh on Solaris
+ # - /usr/bin/sh on Cygwin
+ # - bash 1.x
+ #
+ # Bugs:
+ # please report them to <stephane_chazelas@yahoo.fr>
+ #
+ # Example:
+ #
+ # verbose=false opt_bar=false bar=default_bar foo=default_foo
+ # opt_s=false opt_long=false
+ # OPTLIND=1
+ # while getopts_long :sf:b::vh opt \
+ # long 0 \
+ # foo required_argument \
+ # bar 2 \
+ # verbose no_argument \
+ # help 0 "" "$@"
+ # do
+ # case "$opt" in
+ # s) opt_s=true;;
+ # long) opt_long=true;;
+ # v|verbose) verbose=true;;
+ # h|help) usage; exit 0;;
+ # f|foo) foo=$OPTLARG;;
+ # b|bar) bar=${OPTLARG-$bar};;
+ # :) printf >&2 '%s: %s\n' "${0##*/}" "$OPTLERR"
+ # usage
+ # exit 1;;
+ # esac
+ # done
+ # shift "$(($OPTLIND - 1))"
+ # # process the remaining arguments
+
+ [ -n "${ZSH_VERSION+z}" ] && emulate -L sh
+
+ unset OPTLERR OPTLARG || :
+
+ case "$OPTLIND" in
+ "" | 0 | 1 | *[!0-9]*)
+ # First time in the loop. Initialise the parameters.
+ OPTLIND=1
+ OPTLPENDING=
+ ;;
+ esac
+
+ if [ "$#" -lt 2 ]; then
+ printf >&2 'getopts_long: not enough arguments\n'
+ return 1
+ fi
+
+ # validate variable name. Need to fix locale for character ranges.
+ LC_ALL=C command eval '
+ case "$2" in
+ *[!a-zA-Z_0-9]*|""|[0-9]*)
+ printf >&2 "getopts_long: invalid variable name: \`%s'\''\n" "$2"
+ return 1
+ ;;
+ esac'
+
+ # validate short option specification
+ case "$1" in
+ ::*|*:::*|*-*)
+ printf >&2 "getopts_long: invalid option specification: \`%s'\n" "$1"
+ return 1
+ ;;
+ esac
+
+ # validate long option specifications
+
+ # POSIX shells only have $1, $2... as local variables, hence the
+ # extensive use of "set" in that function.
+
+ set 4 "$@"
+ while :; do
+ if
+ [ "$1" -gt "$#" ] || {
+ eval 'set -- "${'"$1"'}" "$@"'
+ [ -n "$1" ] || break
+ [ "$(($2 + 2))" -gt "$#" ]
+ }
+ then
+ printf >&2 "getopts_long: long option specifications must end in an empty argument\n"
+ return 1
+ fi
+ eval 'set -- "${'"$(($2 + 2))"'}" "$@"'
+ # $1 = type, $2 = name, $3 = $@
+ case "$2" in
+ *=*)
+ printf >&2 "getopts_long: invalid long option name: \`%s'\n" "$2"
+ return 1
+ ;;
+ esac
+ case "$1" in
+ 0 | no_argument) ;;
+ 1 | required_argument) ;;
+ 2 | optional_argument) ;;
+ *)
+ printf >&2 "getopts_long: invalid long option type: \`%s'\n" "$1"
+ return 1
+ ;;
+ esac
+ eval "shift 3; set $(($3 + 2))"' "$@"'
+ done
+ shift
+
+ eval "shift; set $(($1 + $OPTLIND))"' "$@"'
+
+ # unless there are pending short options to be processed (in
+ # $OPTLPENDING), the current option is now in ${$1}
+
+ if [ -z "$OPTLPENDING" ]; then
+ [ "$1" -le "$#" ] || return 1
+ eval 'set -- "${'"$1"'}" "$@"'
+
+ case "$1" in
+ --)
+ OPTLIND=$(($OPTLIND + 1))
+ return 1
+ ;;
+ --*)
+ ;;
+ -?*)
+ OPTLPENDING="${1#-}"
+ shift
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+ OPTLIND=$(($OPTLIND + 1))
+ fi
+
+ if [ -n "$OPTLPENDING" ]; then
+ # WA for zsh and bash 2.03 bugs:
+ OPTLARG=${OPTLPENDING%"${OPTLPENDING#?}"}
+ set -- "$OPTLARG" "$@"
+ OPTLPENDING="${OPTLPENDING#?}"
+ unset OPTLARG
+
+ # $1 = current option = ${$2+1}, $3 = $@
+
+ case "$1" in
+ [-:])
+ OPTLERR="bad option: \`-$1'"
+ case "$3" in
+ :*)
+ eval "$4=:"
+ OPTLARG="$1"
+ ;;
+ *)
+ printf >&2 '%s\n' "$OPTLERR"
+ eval "$4='?'"
+ ;;
+ esac
+ ;;
+
+ *)
+ case "$3" in
+ *"$1"::*) # optional argument
+ eval "$4=\"\$1\""
+ if [ -n "$OPTLPENDING" ]; then
+ # take the argument from $OPTLPENDING if any
+ OPTLARG="$OPTLPENDING"
+ OPTLPENDING=
+ fi
+ ;;
+
+ *"$1":*) # required argument
+ if [ -n "$OPTLPENDING" ]; then
+ # take the argument from $OPTLPENDING if any
+ OPTLARG="$OPTLPENDING"
+ eval "$4=\"\$1\""
+ OPTLPENDING=
+ else
+ # take the argument from the next argument
+ if [ "$(($2 + 2))" -gt "$#" ]; then
+ OPTLERR="option \`-$1' requires an argument"
+ case "$3" in
+ :*)
+ eval "$4=:"
+ OPTLARG="$1"
+ ;;
+ *)
+ printf >&2 '%s\n' "$OPTLERR"
+ eval "$4='?'"
+ ;;
+ esac
+ else
+ OPTLIND=$(($OPTLIND + 1))
+ eval "OPTLARG=\"\${$(($2 + 2))}\""
+ eval "$4=\"\$1\""
+ fi
+ fi
+ ;;
+
+ *"$1"*) # no argument
+ eval "$4=\"\$1\""
+ ;;
+ *)
+ OPTLERR="bad option: \`-$1'"
+ case "$3" in
+ :*)
+ eval "$4=:"
+ OPTLARG="$1"
+ ;;
+ *)
+ printf >&2 '%s\n' "$OPTLERR"
+ eval "$4='?'"
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ else # long option
+
+ # remove the leading "--"
+ OPTLPENDING="$1"
+ shift
+ set 6 "${OPTLPENDING#--}" "$@"
+ OPTLPENDING=
+
+ while
+ eval 'set -- "${'"$1"'}" "$@"'
+ [ -n "$1" ]
+ do
+ # $1 = option name = ${$2+1}, $3 => given option = ${$4+3}, $5 = $@
+
+ case "${3%%=*}" in
+ "$1")
+ OPTLPENDING=EXACT
+ break;;
+ esac
+
+ # try to see if the current option can be seen as an abbreviation.
+ case "$1" in
+ "${3%%=*}"*)
+ if [ -n "$OPTLPENDING" ]; then
+ [ "$OPTLPENDING" = AMBIGUOUS ] || eval '[ "${'"$(($OPTLPENDING + 2))"'}" = "$1" ]' ||
+ OPTLPENDING=AMBIGUOUS
+ # there was another different option matching the current
+ # option. The eval thing is in case one option is provided
+ # twice in the specifications which is OK as per the
+ # documentation above
+ else
+ OPTLPENDING="$2"
+ fi
+ ;;
+ esac
+ eval "shift 2; set $(($2 + 2)) "'"$@"'
+ done
+
+ case "$OPTLPENDING" in
+ AMBIGUOUS)
+ OPTLERR="option \`--${3%%=*}' is ambiguous"
+ case "$5" in
+ :*)
+ eval "$6=:"
+ OPTLARG="${3%%=*}"
+ ;;
+ *)
+ printf >&2 '%s\n' "$OPTLERR"
+ eval "$6='?'"
+ ;;
+ esac
+ OPTLPENDING=
+ return 0
+ ;;
+ EXACT)
+ eval 'set "${'"$(($2 + 2))"'}" "$@"'
+ ;;
+ "")
+ OPTLERR="bad option: \`--${3%%=*}'"
+ case "$5" in
+ :*)
+ eval "$6=:"
+ OPTLARG="${3%%=*}"
+ ;;
+ *)
+ printf >&2 '%s\n' "$OPTLERR"
+ eval "$6='?'"
+ ;;
+ esac
+ OPTLPENDING=
+ return 0
+ ;;
+ *)
+ # we've got an abbreviated long option.
+ shift
+ eval 'set "${'"$(($OPTLPENDING + 1))"'}" "${'"$OPTLPENDING"'}" "$@"'
+ ;;
+ esac
+
+ OPTLPENDING=
+
+ # $1 = option type, $2 = option name, $3 unused,
+ # $4 = given option = ${$5+4}, $6 = $@
+
+ case "$4" in
+ *=*)
+ case "$1" in
+ 1 | required_argument | 2 | optional_argument)
+ eval "$7=\"\$2\""
+ OPTLARG="${4#*=}"
+ ;;
+ *)
+ OPTLERR="option \`--$2' doesn't allow an argument"
+ case "$6" in
+ :*)
+ eval "$7=:"
+ OPTLARG="$2"
+ ;;
+ *)
+ printf >&2 '%s\n' "$OPTLERR"
+ eval "$7='?'"
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ *)
+ case "$1" in
+ 1 | required_argument)
+ if [ "$(($5 + 5))" -gt "$#" ]; then
+ OPTLERR="option \`--$2' requires an argument"
+ case "$6" in
+ :*)
+ eval "$7=:"
+ OPTLARG="$2"
+ ;;
+ *)
+ printf >&2 '%s\n' "$OPTLERR"
+ eval "$7='?'"
+ ;;
+ esac
+ else
+ OPTLIND=$(($OPTLIND + 1))
+ eval "OPTLARG=\"\${$(($5 + 5))}\""
+ eval "$7=\"\$2\""
+ fi
+ ;;
+ *)
+ # optional argument (but obviously not provided) or no
+ # argument
+ eval "$7=\"\$2\""
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ return 0
+}
+
+# testing code
+if [ -n "$_Dbg_getopts_long_test" ]; then
+test_getopts_long() {
+ expected="$1" had=
+ shift
+ OPTLIND=1
+
+ while err="$(set +x;getopts_long "$@" 2>&1 > /dev/null)"
+ getopts_long "$@" 2> /dev/null; do
+ eval "opt=\"\$$2\""
+ had="$had|$opt@${OPTLARG-unset}@${OPTLERR-unset}@$err"
+ done
+ had="$had|$OPTLIND|$err"
+
+ if [ "$had" = "$expected" ]; then
+ echo PASS
+ else
+ echo FAIL
+ printf 'Expected: %s\n Got: %s\n' "$expected" "$had"
+ fi
+}
+while IFS= read -r c && IFS= read -r e; do
+ printf '+ %-72s ' "$c"
+ #set -x
+ eval "test_getopts_long \"\$e\" $c"
+done << \EOF
+: a
+|1|getopts_long: long option specifications must end in an empty argument
+:a opt "" -a
+|a@unset@unset@|2|
+:a opt "" -a b
+|a@unset@unset@|2|
+:a opt "" -a -a
+|a@unset@unset@|a@unset@unset@|3|
+:a opt "" -ab
+|a@unset@unset@|:@b@bad option: `-b'@|2|
+:a: opt "" -ab
+|a@b@unset@|2|
+:a: opt "" -a b
+|a@b@unset@|3|
+:a: opt "" -a -a
+|a@-a@unset@|3|
+:a: opt "" -a
+|:@a@option `-a' requires an argument@|2|
+:a:: opt "" -a
+|a@unset@unset@|2|
+:a:: opt "" -ab
+|a@b@unset@|2|
+:a:: opt "" -a b
+|a@unset@unset@|2|
+:a:: opt "" -a -a
+|a@unset@unset@|a@unset@unset@|3|
+:a:: opt "" -:a:
+|:@:@bad option: `-:'@|a@:@unset@|2|
+:= opt ""
+|1|
+:: opt ""
+|1|getopts_long: invalid option specification: `::'
+: opt ""
+|1|
+:a:a opt "" -a
+|:@a@option `-a' requires an argument@|2|
+:a::a opt "" -a
+|a@unset@unset@|2|
+:ab:c:: opt "" -abc -cba -bac
+|a@unset@unset@|b@c@unset@|c@ba@unset@|b@ac@unset@|4|
+: opt abc 0 "" --abc
+|abc@unset@unset@|2|
+: opt abc no_argument "" --abc
+|abc@unset@unset@|2|
+: opt abc no_argument "" --abc=foo
+|:@abc@option `--abc' doesn't allow an argument@|2|
+: opt abc no_argument "" --abc foo
+|abc@unset@unset@|2|
+: opt abc 1 "" --abc=foo
+|abc@foo@unset@|2|
+: opt abc required_argument "" --abc foo
+|abc@foo@unset@|3|
+: opt abc required_argument "" --abc=
+|abc@@unset@|2|
+: opt abc required_argument "" --abc
+|:@abc@option `--abc' requires an argument@|2|
+: opt abc 2 "" --abc
+|abc@unset@unset@|2|
+: opt abc optional_argument "" --abc=
+|abc@@unset@|2|
+: opt abc optional_argument "" --abc=foo
+|abc@foo@unset@|2|
+: opt abc optional_argument "" --abc --abc
+|abc@unset@unset@|abc@unset@unset@|3|
+: opt abc 0 abcd 0 "" --abc
+|abc@unset@unset@|2|
+: opt abc 0 abd 0 "" --ab
+|:@ab@option `--ab' is ambiguous@|2|
+: opt abc 0 abcd 0 "" --ab
+|:@ab@option `--ab' is ambiguous@|2|
+: opt abc 0 abc 1 "" --abc
+|abc@unset@unset@|2|
+: opt abc 0 acd 0 "" --ab
+|abc@unset@unset@|2|
+:abc:d:e::f:: opt ab 0 ac 1 bc 2 cd 1 cde 2 "" -abcdef -a -f -c --a --a= --b=foo -fg
+|a@unset@unset@|b@unset@unset@|c@def@unset@|a@unset@unset@|f@unset@unset@|c@--a@unset@|:@a@option `--a' is ambiguous@|bc@foo@unset@|f@g@unset@|9|
+a opt "" -a
+|a@unset@unset@|2|
+a opt "" -a b
+|a@unset@unset@|2|
+a opt "" -a -a
+|a@unset@unset@|a@unset@unset@|3|
+a opt "" -ab
+|a@unset@unset@|?@unset@bad option: `-b'@bad option: `-b'|2|
+a: opt "" -ab
+|a@b@unset@|2|
+a: opt "" -a b
+|a@b@unset@|3|
+a: opt "" -a -a
+|a@-a@unset@|3|
+a: opt "" -a
+|?@unset@option `-a' requires an argument@option `-a' requires an argument|2|
+a:: opt "" -a
+|a@unset@unset@|2|
+a:: opt "" -ab
+|a@b@unset@|2|
+a:: opt "" -a b
+|a@unset@unset@|2|
+a:: opt "" -a -a
+|a@unset@unset@|a@unset@unset@|3|
+a:: opt "" -:a:
+|?@unset@bad option: `-:'@bad option: `-:'|a@:@unset@|2|
+= opt ""
+|1|
+: opt ""
+|1|
+'' opt ""
+|1|
+a:a opt "" -a
+|?@unset@option `-a' requires an argument@option `-a' requires an argument|2|
+a::a opt "" -a
+|a@unset@unset@|2|
+ab:c:: opt "" -abc -cba -bac
+|a@unset@unset@|b@c@unset@|c@ba@unset@|b@ac@unset@|4|
+'' opt abc 0 "" --abc
+|abc@unset@unset@|2|
+'' opt abc no_argument "" --abc
+|abc@unset@unset@|2|
+'' opt abc no_argument "" --abc=foo
+|?@unset@option `--abc' doesn't allow an argument@option `--abc' doesn't allow an argument|2|
+'' opt abc no_argument "" --abc foo
+|abc@unset@unset@|2|
+'' opt abc 1 "" --abc=foo
+|abc@foo@unset@|2|
+'' opt abc required_argument "" --abc foo
+|abc@foo@unset@|3|
+'' opt abc required_argument "" --abc=
+|abc@@unset@|2|
+'' opt abc required_argument "" --abc
+|?@unset@option `--abc' requires an argument@option `--abc' requires an argument|2|
+'' opt abc 2 "" --abc
+|abc@unset@unset@|2|
+'' opt abc optional_argument "" --abc=
+|abc@@unset@|2|
+'' opt abc optional_argument "" --abc=foo
+|abc@foo@unset@|2|
+'' opt abc optional_argument "" --abc --abc
+|abc@unset@unset@|abc@unset@unset@|3|
+'' opt abc 0 abcd 0 "" --abc
+|abc@unset@unset@|2|
+'' opt abc 0 abd 0 "" --ab
+|?@unset@option `--ab' is ambiguous@option `--ab' is ambiguous|2|
+'' opt abc 0 abcd 0 "" --ab
+|?@unset@option `--ab' is ambiguous@option `--ab' is ambiguous|2|
+'' opt abc 0 abc 1 "" --abc
+|abc@unset@unset@|2|
+'' opt abc 0 acd 0 "" --ab
+|abc@unset@unset@|2|
+abc:d:e::f:: opt ab 0 ac 1 bc 2 cd 1 cde 2 "" -abcdef -a -f -c --a --a= --b=foo -fg
+|a@unset@unset@|b@unset@unset@|c@def@unset@|a@unset@unset@|f@unset@unset@|c@--a@unset@|?@unset@option `--a' is ambiguous@option `--a' is ambiguous|bc@foo@unset@|f@g@unset@|9|
+: '' '' a
+|1|getopts_long: invalid variable name: `'
+: 1a ''
+|1|getopts_long: invalid variable name: `1a'
+- a
+|1|getopts_long: invalid option specification: `-'
+:a::a:abcd o ab 1 abc 1 abd 1 abe 1 abc 2 '' -aa --ab 1 --abc
+|a@a@unset@|ab@1@unset@|:@abc@option `--abc' requires an argument@|5|
+:
+|1|getopts_long: not enough arguments
+'\[$' o -- 0 ' ' 1 '#' required_argument '' '-\\\[$' --\ =a --\#=\$\$
+|\@unset@unset@|\@unset@unset@|\@unset@unset@|[@unset@unset@|$@unset@unset@| @a@unset@|#@$$@unset@|4|
+: o a 1 b 2 c
+|1|getopts_long: long option specifications must end in an empty argument
+: o a 1 b 2
+|1|getopts_long: long option specifications must end in an empty argument
+: o a 1 b 2 c 3 '' --c
+|1|getopts_long: invalid long option type: `3'
+": " o " " 1 '' "- " "-- =1"
+| @unset@unset@| @unset@unset@| @1@unset@|3|
+: o a 1 '' --c
+|:@c@bad option: `--c'@|2|
+: o a 1 '' --c=foo
+|:@c@bad option: `--c'@|2|
+: o ab 1 ac 1 ad 1 a 1 '' --a=1
+|a@1@unset@|2|
+EOF
+fi
View
1  test/unit/.gitignore
@@ -3,6 +3,7 @@
/Makefile.in
/test-alias.sh
/test-columns.sh
+/test-dbg-opts.sh
/test-filecache.sh
/test-fns.sh
/test-frame.sh
View
2  test/unit/Makefile.am
@@ -3,6 +3,7 @@
TESTS = test-alias.sh \
test-columns.sh \
+ test-dbg-opts.sh \
test-filecache.sh \
test-fns.sh \
test-frame.sh \
@@ -20,6 +21,7 @@ abs_builddir=@abs_builddir@
EXTRA_DIST = $(TESTS) $(check_DATA) \
test-alias.sh.in \
test-columns.sh.in \
+ test-dbg-opts.sh.in \
test-filecache.sh.in \
test-fns.sh.in \
test-frame.sh.in \
View
270 test/unit/shunit2
@@ -1,4 +1,4 @@
-# $Id: shunit2 211 2008-07-17 14:32:33Z kate.ward@forestent.com $
+# $Id: shunit2 224 2008-09-03 22:20:42Z kate.ward@forestent.com $
# vim:et:ft=sh:sts=2:sw=2
# vim:foldmethod=marker:foldmarker=/**,*/
#
@@ -72,10 +72,18 @@ unset shunit_const_ shunit_constants_ shunit_ro_opts_
__shunit_skip=${SHUNIT_FALSE}
__shunit_suite=''
+# counts of tests
+__shunit_testSuccess=${SHUNIT_TRUE}
+__shunit_testsTotal=0
__shunit_testsPassed=0
__shunit_testsFailed=0
-__shunit_testsSkipped=0
-__shunit_testsTotal=0
+
+# counts of asserts
+__shunit_assertsTotal=0
+__shunit_assertsPassed=0
+__shunit_assertsFailed=0
+__shunit_assertsSkipped=0
+
__shunit_reportGenerated=${SHUNIT_FALSE}
# macros
@@ -116,7 +124,7 @@ assertEquals()
[ -z "${shunit_message_:-}" ] && shunit_message_=''
if [ $# -eq 3 ]; then
- shunit_message_="${shunit_message_}$1"
+ shunit_message_="$1"
shift
fi
shunit_expected_=$1
@@ -124,7 +132,7 @@ assertEquals()
shunit_return=${SHUNIT_TRUE}
if [ "${shunit_expected_}" = "${shunit_actual_}" ]; then
- _shunit_testPassed
+ _shunit_assertPass
else
failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}"
shunit_return=${SHUNIT_FALSE}
@@ -166,7 +174,7 @@ assertNotEquals()
[ -z "${shunit_message_:-}" ] && shunit_message_=''
if [ $# -eq 3 ]; then
- shunit_message_="${shunit_message_}$1"
+ shunit_message_="$1"
shift
fi
shunit_unexpected_=$1
@@ -174,7 +182,7 @@ assertNotEquals()
shunit_return=${SHUNIT_TRUE}
if [ "${shunit_unexpected_}" != "${shunit_actual_}" ]; then
- _shunit_testPassed
+ _shunit_assertPass
else
failSame "${shunit_message_}" "$@"
shunit_return=${SHUNIT_FALSE}
@@ -394,9 +402,9 @@ assertTrue()
# record the test
if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
- _shunit_testPassed
+ _shunit_assertPass
else
- _shunit_testFailed "${shunit_message_}"
+ _shunit_assertFail "${shunit_message_}"
fi
unset shunit_message_ shunit_condition_ shunit_match_
@@ -464,9 +472,9 @@ assertFalse()
# record the test
if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
- _shunit_testPassed
+ _shunit_assertPass
else
- _shunit_testFailed "${shunit_message_}"
+ _shunit_assertFail "${shunit_message_}"
fi
unset shunit_message_ shunit_condition_ shunit_match_
@@ -509,7 +517,7 @@ fail()
shift
fi
- _shunit_testFailed "${shunit_message_}"
+ _shunit_assertFail "${shunit_message_}"
unset shunit_message_
return ${SHUNIT_FALSE}
@@ -547,13 +555,13 @@ failNotEquals()
[ -z "${shunit_message_:-}" ] && shunit_message_=''
if [ $# -eq 3 ]; then
- shunit_message_="${shunit_message_}$1"
+ shunit_message_="$1"
shift
fi
shunit_unexpected_=$1
shunit_actual_=$2
- _shunit_testFailed "${shunit_message_:+${shunit_message_} }expected:<${shunit_unexpected_}> but was:<${shunit_actual_}>"
+ _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected:<${shunit_unexpected_}> but was:<${shunit_actual_}>"
unset shunit_message_ shunit_unexpected_ shunit_actual_
return ${SHUNIT_FALSE}
@@ -588,11 +596,11 @@ failSame()
[ -z "${shunit_message_:-}" ] && shunit_message_=''
if [ $# -eq 3 ]; then
- shunit_message_="${shunit_message_}$1"
+ shunit_message_="$1"
shift
fi
- _shunit_testFailed "${shunit_message_:+${shunit_message_} }expected not same"
+ _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected not same"
unset shunit_message_
return ${SHUNIT_FALSE}
@@ -755,11 +763,12 @@ isSkipping()
#*/
suite_addTest()
{
- _su_func=${1:-}
+ shunit_func_=${1:-}
- __shunit_suite="${__shunit_suite:+${__shunit_suite} }${_su_func}"
+ __shunit_suite="${__shunit_suite:+${__shunit_suite} }${shunit_func_}"
+ __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
- unset _su_func
+ unset shunit_func_
}
#/**
@@ -854,17 +863,61 @@ suite_addTest()
# internal shUnit2 functions
#
+# this function is a cross-platform temporary directory creation tool. not all
+# OSes have the mktemp function, so one is included here.
+_shunit_mktempDir()
+{
+ # try the standard mktemp function
+ ( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ) && return
+
+ # the standard mktemp didn't work. doing our own.
+ if [ -r '/dev/urandom' ]; then
+ _shunit_random_=`od -vAn -N4 -tx4 </dev/urandom |sed 's/^[^0-9a-f]*//'`
+ elif [ -n "${RANDOM:-}" ]; then
+ # $RANDOM works
+ _shunit_random_=${RANDOM}${RANDOM}${RANDOM}$$
+ else
+ # $RANDOM doesn't work
+ _shunit_date_=`date '+%Y%m%d%H%M%S'`
+ _shunit_random_=`expr ${_shunit_date_} / $$`
+ fi
+
+ _shunit_tmpDir_="${TMPDIR:-/tmp}/shunit.${_shunit_random_}"
+ ( umask 077 && mkdir "${_shunit_tmpDir_}" ) || {
+ _shunit_fatal 'could not create temporary directory! exiting'
+ exit ${SHUNIT_FALSE}
+ }
+
+ echo ${_shunit_tmpDir_}
+ unset _shunit_date_ _shunit_random_ _shunit_tmpDir_
+}
+
+# this function is here to work around issues in Cygwin
+_shunit_mktempFunc()
+{
+ for _shunit_func_ in oneTimeSetUp oneTimeTearDown setUp tearDown suite; do
+ _shunit_file_="${__shunit_tmpDir}/${_shunit_func_}"
+ cat <<EOF >"${_shunit_file_}"
+#! /bin/sh
+exit ${SHUNIT_TRUE}
+EOF
+ chmod +x "${_shunit_file_}"
+ done
+
+ unset _shunit_file_
+}
+
_shunit_cleanup()
{
- name=$1
+ _shunit_name_=$1
- case ${name} in
- EXIT) signal=0 ;;
- INT) signal=2 ;;
- TERM) signal=15 ;;
+ case ${_shunit_name_} in
+ EXIT) _shunit_signal_=0 ;;
+ INT) _shunit_signal_=2 ;;
+ TERM) _shunit_signal_=15 ;;
*)
- _shunit_warn "unrecognized trap value (${name})"
- signal=0
+ _shunit_warn "unrecognized trap value (${_shunit_name_})"
+ _shunit_signal_=0
;;
esac
@@ -872,25 +925,27 @@ _shunit_cleanup()
rm -fr "${__shunit_tmpDir}"
# exit for all non-EXIT signals
- if [ ${name} != 'EXIT' ]; then
- _shunit_warn "trapped and now handling the (${name}) signal"
- _shunit_generateReport
+ if [ ${_shunit_name_} != 'EXIT' ]; then
+ _shunit_warn "trapped and now handling the (${_shunit_name_}) signal"
# disable EXIT trap
trap 0
# add 128 to signal and exit
- exit `expr ${signal} + 128`
+ exit `expr ${_shunit_signal_} + 128`
elif [ ${__shunit_reportGenerated} -eq ${SHUNIT_FALSE} ] ; then
- _shunit_testFailed 'Unknown failure encountered running a test'
+ _shunit_assertFail 'Unknown failure encountered running a test'
_shunit_generateReport
+ exit ${SHUNIT_ERROR}
fi
+
+ unset _shunit_name_ _shunit_signal_
}
+# The actual running of the tests happens here.
_shunit_execSuite()
{
- echo '#'
- echo '# Performing tests'
- echo '#'
- for _su_func in ${__shunit_suite}; do
+ for _shunit_test_ in ${__shunit_suite}; do
+ __shunit_testSuccess=${SHUNIT_TRUE}
+
# disable skipping
endSkipping
@@ -898,121 +953,94 @@ _shunit_execSuite()
setUp
# execute the test
- echo "${_su_func}"
- eval ${_su_func}
+ echo "${_shunit_test_}"
+ eval ${_shunit_test_}
# execute the per-test tear-down function
tearDown
+
+ # update stats
+ if [ ${__shunit_testSuccess} -eq ${SHUNIT_TRUE} ]; then
+ __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1`
+ else
+ __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1`
+ fi
done
- unset _su_func
+ unset _shunit_test_
}
+# This function exits shUnit2 with the appropriate error code and OK/FAILED
+# message.
_shunit_generateReport()
{
- _su__awkPercent='{printf("%4d %3.0f%%", $1, $1*100/$2)}'
- if [ ${__shunit_testsTotal:-0} -gt 0 ]; then
- _su__passed=`echo ${__shunit_testsPassed} ${__shunit_testsTotal} |\
- awk "${_su__awkPercent}"`
- _su__failed=`echo ${__shunit_testsFailed} ${__shunit_testsTotal} |\
- awk "${_su__awkPercent}"`
- _su__skipped=`echo ${__shunit_testsSkipped} ${__shunit_testsTotal} |\
- awk "${_su__awkPercent}"`
- _su__total=`echo ${__shunit_testsTotal} 100 |\
- awk '{printf("%4d %3d%%", $1, $2)}'`
- else
- _su__passed=`echo 0 0 |awk '{printf("%4d %3d%%", $1, $2)}'`
- _su__failed=${_su__passed}
- _su__skipped=${_su__passed}
- _su__total=${_su__passed}
- fi
-
- cat <<EOF
-
-#
-# Test report
-#
-tests passed: ${_su__passed}
-tests failed: ${_su__failed}
-tests skipped: ${_su__skipped}
-tests total: ${_su__total}
-EOF
- __shunit_reportGenerated=${SHUNIT_TRUE}
-
- unset _su__awkPercent _su__passed _su__failed _su__skipped _su__total
-}
+ _shunit_ok_=${SHUNIT_TRUE}
-# this function is a cross-platform temporary directory creation tool. not all
-# OSes have the mktemp function, so one is included here.
-_shunit_mktempDir()
-{
- # try the standard mktemp function
- ( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ) && return
+ # if no exit code was provided one, determine an appropriate one
+ [ ${__shunit_testsFailed} -gt 0 \
+ -o ${__shunit_testSuccess} -eq ${SHUNIT_FALSE} ] \
+ && _shunit_ok_=${SHUNIT_FALSE}
- # the standard mktemp didn't work. doing our own.
- if [ -r '/dev/urandom' ]; then
- _su__random=`od -vAn -N4 -tx4 </dev/urandom |sed 's/^[^0-9a-f]*//'`
- elif [ -n "${RANDOM:-}" ]; then
- # $RANDOM works
- _su__random=${RANDOM}${RANDOM}${RANDOM}$$
+ echo
+ if [ ${__shunit_testsTotal} -eq 1 ]; then
+ echo "Ran ${__shunit_testsTotal} test."
else
- # $RANDOM doesn't work
- _su__date=`date '+%Y%m%d%H%M%S'`
- _su__random=`expr ${_su__date} / $$`
+ echo "Ran ${__shunit_testsTotal} tests."
fi
- _su__tmpDir="${TMPDIR:-/tmp}/shunit.${_su__random}"
- ( umask 077 && mkdir "${_su__tmpDir}" ) || {
- echo 'shUnit:FATAL could not create temporary directory! exiting' >&2
- exit 1
- }
-
- echo ${_su__tmpDir}
- unset _su__date _su__random _su__tmpDir
-}
+ _shunit_failures_=''
+ _shunit_skipped_=''
+ [ ${__shunit_assertsFailed} -gt 0 ] \
+ && _shunit_failures_="failures=${__shunit_assertsFailed}"
+ [ ${__shunit_assertsSkipped} -gt 0 ] \
+ && _shunit_skipped_="skipped=${__shunit_assertsSkipped}"
+
+ if [ ${_shunit_ok_} -eq ${SHUNIT_TRUE} ]; then
+ _shunit_msg_='OK'
+ [ -n "${_shunit_skipped_}" ] \
+ && _shunit_msg_="${_shunit_msg_} (${_shunit_skipped_})"
+ else
+ _shunit_msg_="FAILED (${_shunit_failures_}"
+ [ -n "${_shunit_skipped_}" ] \
+ && _shunit_msg_="${_shunit_msg_},${_shunit_skipped_}"
+ _shunit_msg_="${_shunit_msg_})"
+ fi
-# this function is here to work around issues in Cygwin
-_shunit_mktempFunc()
-{
- for _su__func in oneTimeSetUp oneTimeTearDown setUp tearDown suite; do
- _su__file="${__shunit_tmpDir}/${_su__func}"
- cat <<EOF >"${_su__file}"
-#! /bin/sh
-exit 0
-EOF
- chmod +x "${_su__file}"
- done
+ echo
+ echo ${_shunit_msg_}
+ __shunit_reportGenerated=${SHUNIT_TRUE}
- unset _su__file
+ unset _shunit_failures_ _shunit_msg_ _shunit_ok_ _shunit_skipped_
}
_shunit_shouldSkip()
{
[ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE}
- _shunit_testSkipped
+ _shunit_assertSkip
}
-_shunit_testPassed()
+_shunit_assertPass()
{
- __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1`
- __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
+ __shunit_assertsPassed=`expr ${__shunit_assertsPassed} + 1`
+ __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
}
-_shunit_testFailed()
+_shunit_assertFail()
{
- _su__msg=$1
+ _shunit_msg_=$1
- __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1`
- __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
- echo "${__SHUNIT_ASSERT_MSG_PREFIX}${_su__msg}" >&2
+ __shunit_testSuccess=${SHUNIT_FALSE}
+ __shunit_assertsFailed=`expr ${__shunit_assertsFailed} + 1`
+ __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
+ echo "${__SHUNIT_ASSERT_MSG_PREFIX}${_shunit_msg_}"
- unset _su__msg
+ unset _shunit_msg_
}
-_shunit_testSkipped()
+_shunit_assertSkip()
{
- __shunit_testsSkipped=`expr ${__shunit_testsSkipped} + 1`
- __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
+ __shunit_assertsSkipped=`expr ${__shunit_assertsSkipped} + 1`
+ __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
}
#------------------------------------------------------------------------------
@@ -1054,10 +1082,12 @@ _shunit_execSuite
# execute the oneTimeTearDown function (if it exists)
oneTimeTearDown
-# generate report
+# generate the report
_shunit_generateReport
-[ ${__shunit_testsFailed} -eq 0 ] || exit 1
+# that's it folks
+[ ${__shunit_testsFailed} -eq 0 ]
+exit $?
#/**
# </s:shelldoc>
View
75 test/unit/test-dbg-opts.sh.in
@@ -0,0 +1,75 @@
+#!@SH_PROG@
+# -*- shell-script -*-
+PS4='(${.sh.file}:${LINENO}): ${.sh.fun} - [${.sh.subshell}]
+'
+
+traceAssertEquals() {
+ first="$1"
+ second="$2"
+ third="$3"
+ typeset -p first
+ typeset -p second
+ typeset -p third
+}
+
+do_opts_test() {
+ if (( $# < 3 )); then
+ assertTrue "Too few parameters: $# should be at least 3" $(($# < 3))
+ return 1
+ fi
+ typeset assert_msg="$1"; shift
+ typeset expected_eval="$1"; shift
+ typeset expected_value="$1" ; shift
+ # typeset -p assert_msg
+ # typeset -p expected_eval
+ # typeset -p expected_value
+
+ . ${abs_top_srcdir}/dbg-opts.sh
+ OPTLIND=1
+ _Dbg_parse_options "$@"
+ assertEquals "$assert_msg" "$expected_value" "$(eval $expected_eval)"
+}
+
+test_opts()
+{
+ do_opts_test 'No opts (annotate, basename, linetrace)' \
+ 'print "$_Dbg_annotate $_Dbg_basename_only $_Dbg_linetrace"' \
+ '0 0 0'
+
+ # Eval expression value options
+ msg='Short annotate'
+ do_opts_test "$msg" 'print $_Dbg_annotate' 1 -q -A 1
+ msg='Long annotate'
+ do_opts_test "$msg" 'print $_Dbg_annotate' 3 --quiet --annotate 3
+ msg='Annotate default'
+ do_opts_test "$msg" 'print $_Dbg_annotate' 0 --quiet
+ msg='Short basename'
+ do_opts_test "$msg" 'print $_Dbg_basename_only' 1 -B --quiet
+ msg='basename default'
+ do_opts_test "$msg" 'print $_Dbg_basename_only' 0 --quiet
+ msg='Long basename'
+ do_opts_test "$msg" 'print $_Dbg_basename_only' 1 --quiet --basename
+ msg='Long --no-init'
+ do_opts_test "$msg" 'print $_Dbg_o_nx' 1 --no-init --quiet
+ msg='--no-init default'
+ do_opts_test "$msg" 'print $_Dbg_o_nx' 0 -q
+ msg='Short --no-init (-n)'
+ do_opts_test "$msg" 'print $_Dbg_o_nx' 1 -n --quiet
+ msg='Alternate no-init'
+ do_opts_test "$msg" 'print $_Dbg_o_nx' 1 -B -q -L . --nx
+}
+
+if [ '@abs_top_srcdir@' = '' ] ; then
+ echo "Something is wrong abs_top_srcdir is not set."
+ exit 1
+fi
+abs_top_srcdir=@abs_top_srcdir@
+# Make sure @top_srcdir@ has a trailing slash
+abs_top_srcdir=${abs_top_srcdir%%/}/
+_Dbg_libdir=$abs_top_srcdir
+
+# load shunit2
+shunit_file=${abs_top_srcdir}test/unit/shunit2
+. ${shunit_file}
+
+
Please sign in to comment.
Something went wrong with that request. Please try again.