Add usage_or_errors() to parse_options.sh.

This commit is contained in:
Daniel Nichter
2011-12-15 12:01:22 -07:00
parent 92c8635c4a
commit f3ac1b20c2
2 changed files with 57 additions and 26 deletions

View File

@@ -28,7 +28,9 @@ set -u
# sub will be scoped locally. # sub will be scoped locally.
declare -a ARGV # non-option args (probably input files) declare -a ARGV # non-option args (probably input files)
declare EXT_ARGV # everything after -- (args for an external command) declare EXT_ARGV # everything after -- (args for an external command)
OPT_ERR=${OPT_ERR:-""} declare -a OPT_ERRS # errors while parsing options, for usage_or_errors()
OPT_VERSION="no"
OPT_HELP="no"
# Sub: usage # Sub: usage
# Print usage (--help) and list the program's options. # Print usage (--help) and list the program's options.
@@ -46,15 +48,43 @@ usage() {
local file=$1 local file=$1
local usage=$(grep '^Usage: ' $file) local usage=$(grep '^Usage: ' $file)
if [ "$OPT_ERR" ]; then
echo "Error: ${OPT_ERR}" >&2
fi
echo $usage >&2 echo $usage >&2
echo >&2 echo >&2
echo "For more information, 'man $TOOL' or 'perldoc $file'." >&2 echo "For more information, 'man $TOOL' or 'perldoc $file'." >&2
} }
usage_or_errors() {
local file=$1
if [ "$OPT_VERSION" = "yes" ]; then
local version=$(grep '^pt-[^ ]\+ [0-9]' $file)
echo "$version"
return 0
fi
if [ "$OPT_HELP" = "yes" ]; then
usage "$file"
return 0
fi
local n_errs=${#OPT_ERRS[*]}
if [ $n_errs -gt 0 ]; then
local i=0
echo "Errors parsing command line options:" >&2
echo >&2
while [ $i -lt $n_errs ]; do
echo " * ${OPT_ERRS[$i]}" >&2
i=$(($i + 1))
done
echo >&2
usage $file
return 1
fi
# No --help, --version, or errors.
return 0
}
# Sub: parse_options # Sub: parse_options
# Parse Perl POD options from a program file. # Parse Perl POD options from a program file.
# #
@@ -143,17 +173,20 @@ parse_options() {
fi fi
;; ;;
*) *)
die "Invalid attribute in $TMPDIR/po/$opt_spec: $line" echo "Invalid attribute in $TMPDIR/po/$opt_spec: $line" >&2
exit 1
esac esac
done < $TMPDIR/po/$opt_spec done < $TMPDIR/po/$opt_spec
if [ -z "$opt" ]; then if [ -z "$opt" ]; then
die "No long attribute in option spec $TMPDIR/po/$opt_spec" echo "No long attribute in option spec $TMPDIR/po/$opt_spec" >&2
exit 1
fi fi
if [ $neg -eq 1 ]; then if [ $neg -eq 1 ]; then
if [ -z "$default_val" ] || [ "$default_val" != "yes" ]; then if [ -z "$default_val" ] || [ "$default_val" != "yes" ]; then
die "Option $opt_spec is negatable but not default: yes" echo "Option $opt_spec is negatable but not default: yes" >&2
exit 1
fi fi
fi fi
@@ -171,6 +204,7 @@ parse_options() {
# specified on the command line, then we re-eval $OPT_FOO=500 to update # specified on the command line, then we re-eval $OPT_FOO=500 to update
# $OPT_FOO. # $OPT_FOO.
local i=0 # ARGV index local i=0 # ARGV index
local j=0 # OPT_ERRS index
for opt; do for opt; do
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
break # no more opts break # no more opts
@@ -181,15 +215,6 @@ parse_options() {
EXT_ARGV="$@" EXT_ARGV="$@"
break break
fi fi
if [ "$opt" = "--version" ]; then
version=$(grep '^pt-[^ ]\+ [0-9]' $0)
echo "$version"
exit 0
fi
if [ "$opt" = "--help" ]; then
usage $file
exit 0
fi
shift shift
if [ $(expr "$opt" : "-") -eq 0 ]; then if [ $(expr "$opt" : "-") -eq 0 ]; then
# Option does not begin with a hyphen (-), so treat it as # Option does not begin with a hyphen (-), so treat it as
@@ -217,7 +242,9 @@ parse_options() {
else else
spec=$(grep "^shortform:-$opt\$" $TMPDIR/po/* | cut -d ':' -f 1) spec=$(grep "^shortform:-$opt\$" $TMPDIR/po/* | cut -d ':' -f 1)
if [ -z "$spec" ]; then if [ -z "$spec" ]; then
die "Unknown option: $opt" OPT_ERRS[j]="Unknown option: $real_opt"
j=$((j+1))
continue
fi fi
fi fi
@@ -228,7 +255,9 @@ parse_options() {
required_arg=$(cat $spec | grep '^type:' | cut -d':' -f2) required_arg=$(cat $spec | grep '^type:' | cut -d':' -f2)
if [ -n "$required_arg" ]; then if [ -n "$required_arg" ]; then
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
die "$real_opt requires a $required_arg argument" OPT_ERRS[j]="$real_opt requires a $required_arg argument"
j=$((j+1))
continue
else else
val="$1" val="$1"
shift shift

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
TESTS=25 TESTS=26
TMPFILE="$TEST_TMPDIR/parse-opts-output" TMPFILE="$TEST_TMPDIR/parse-opts-output"
@@ -11,6 +11,7 @@ source "$LIB_DIR/parse_options.sh"
# Parse options from POD using all default values. # Parse options from POD using all default values.
# ############################################################################ # ############################################################################
TOOL="pt-stalk"
TMPDIR="$TEST_TMPDIR" TMPDIR="$TEST_TMPDIR"
parse_options "$T_LIB_DIR/samples/bash/po001.sh" "" 2>$TMPFILE parse_options "$T_LIB_DIR/samples/bash/po001.sh" "" 2>$TMPFILE
@@ -64,12 +65,13 @@ is "$OPT_VERSION" "yes" "Short form"
# ############################################################################ # ############################################################################
# Have to call this in a subshell because the error will cause an exit. # Have to call this in a subshell because the error will cause an exit.
( parse_options "$T_LIB_DIR/samples/bash/po001.sh" --foo >$TMPFILE 2>&1
parse_options "$T_LIB_DIR/samples/bash/po001.sh" --foo >$TMPFILE 2>&1 is "`cat $TMPFILE`" "" "No warnings or errors yet"
)
usage_or_errors "$T_LIB_DIR/samples/bash/po001.sh" >$TMPFILE 2>&1
local err=$? local err=$?
is "$err" "1" "Non-zero exit on unknown option" is "$err" "1" "Non-zero exit on unknown option"
cmd_ok "grep -q 'Unknown option: foo' $TMPFILE" "Error on unknown option" cmd_ok "grep -q 'Unknown option: --foo' $TMPFILE" "Error on unknown option"
# ############################################################################ # ############################################################################
# Done # Done