mirror of https://github.com/dyne/zuper.git
sub/command optarg parser refurbished from Tomb
This commit is contained in:
parent
f0417a1c03
commit
a9b9d76b0d
150
zuper
150
zuper
|
|
@ -704,6 +704,7 @@ EOF
|
||||||
func "$_num key/values stored in $_path"
|
func "$_num key/values stored in $_path"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# }}} Key/Value filesave
|
# }}} Key/Value filesave
|
||||||
|
|
||||||
# {{{ Get/Set REST API
|
# {{{ Get/Set REST API
|
||||||
|
|
@ -845,6 +846,155 @@ EOF
|
||||||
|
|
||||||
# }}} Get/Set REST API
|
# }}} Get/Set REST API
|
||||||
|
|
||||||
|
# {{{ Parse commandline options
|
||||||
|
|
||||||
|
# for example usage, see Tomb http://tomb.dyne.org
|
||||||
|
vars+=(subcommand)
|
||||||
|
arrs+=(option_main option_params)
|
||||||
|
maps+=(option option_subcommands)
|
||||||
|
|
||||||
|
# Hi, dear developer! Are you trying to add a new subcommand, or
|
||||||
|
# to add some options? Well, keep in mind that option names are
|
||||||
|
# global: they cannot bear a different meaning or behaviour across
|
||||||
|
# subcommands. The only exception is "-o" which means: "options
|
||||||
|
# passed to the local subcommand", and thus can bear a different
|
||||||
|
# meaning for different subcommands.
|
||||||
|
#
|
||||||
|
# For example, "-s" means "size" and accepts one argument. If you
|
||||||
|
# are tempted to add an alternate option "-s" (e.g., to mean
|
||||||
|
# "silent", and that doesn't accept any argument) DON'T DO IT!
|
||||||
|
#
|
||||||
|
# There are two reasons for that:
|
||||||
|
# I. Usability; users expect that "-s" is "size"
|
||||||
|
# II. Option parsing WILL EXPLODE if you do this kind of bad
|
||||||
|
# things (it will complain: "option defined more than once")
|
||||||
|
#
|
||||||
|
# If you want to use the same option in multiple commands then you
|
||||||
|
# can only use the non-abbreviated long-option version like:
|
||||||
|
# -force and NOT -f
|
||||||
|
|
||||||
|
option.is_set() {
|
||||||
|
|
||||||
|
# Check whether a commandline option is set.
|
||||||
|
#
|
||||||
|
# Synopsis: option_is_set -flag [out]
|
||||||
|
#
|
||||||
|
# First argument is the commandline flag (e.g., "-s").
|
||||||
|
# If the second argument is present and set to 'out', print out the
|
||||||
|
# result: either 'set' or 'unset' (useful for if conditions).
|
||||||
|
#
|
||||||
|
# Return 0 if is set, 1 otherwise
|
||||||
|
local -i r # the return code (0 = set, 1 = unset)
|
||||||
|
|
||||||
|
[[ -n ${(k)option[$1]} ]];
|
||||||
|
r=$?
|
||||||
|
|
||||||
|
[[ $2 == "out" ]] && {
|
||||||
|
[[ $r == 0 ]] && { print 'set' } || { print 'unset' }
|
||||||
|
}
|
||||||
|
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
# Print the option value matching the given flag
|
||||||
|
# Unique argument is the commandline flag (e.g., "-s").
|
||||||
|
option.value() {
|
||||||
|
print -n - "${option[$1]}"
|
||||||
|
}
|
||||||
|
option.parse() {
|
||||||
|
|
||||||
|
### Detect subcommand
|
||||||
|
local -aU every_opts #every_opts behave like a set; that is, an array with unique elements
|
||||||
|
for optspec in ${option_subcommands}${option_main}; do
|
||||||
|
for opt in ${=optspec}; do
|
||||||
|
every_opts+=${opt}
|
||||||
|
done
|
||||||
|
done
|
||||||
|
local -a oldstar
|
||||||
|
oldstar=("${(@)argv}")
|
||||||
|
#### detect early: useful for --option-parsing
|
||||||
|
zparseopts -M -D -Adiscardme ${every_opts}
|
||||||
|
if [[ -n ${(k)discardme[--option-parsing]} ]]; then
|
||||||
|
print $1
|
||||||
|
if [[ -n "$1" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
unset discardme
|
||||||
|
if ! zparseopts -M -E -D -Adiscardme ${every_opts}; then
|
||||||
|
_failure "Error parsing."
|
||||||
|
return 127
|
||||||
|
fi
|
||||||
|
unset discardme
|
||||||
|
subcommand=${1}
|
||||||
|
if [[ -z $subcommand ]]; then
|
||||||
|
subcommand="__default"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z ${(k)option_subcommands[$subcommand]} ]]; then
|
||||||
|
_warning "There's no such command \"::1 subcommand::\"." $subcommand
|
||||||
|
exitv=127 _failure "Please try -h for help."
|
||||||
|
fi
|
||||||
|
argv=("${(@)oldstar}")
|
||||||
|
unset oldstar
|
||||||
|
|
||||||
|
### Parsing global + command-specific options
|
||||||
|
# zsh magic: ${=string} will split to multiple arguments when spaces occur
|
||||||
|
set -A cmd_opts ${option_main} ${=option_subcommands[$subcommand]}
|
||||||
|
# if there is no option, we don't need parsing
|
||||||
|
if [[ -n $cmd_opts ]]; then
|
||||||
|
zparseopts -M -E -D -Aoption ${cmd_opts}
|
||||||
|
if [[ $? != 0 ]]; then
|
||||||
|
_warning "Some error occurred during option processing."
|
||||||
|
exitv=127 _failure "See \"sdk help\" for more info."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
#build option_params (array of arguments) and check if there are unrecognized options
|
||||||
|
ok=0
|
||||||
|
option_params=()
|
||||||
|
for arg in $*; do
|
||||||
|
if [[ $arg == '--' || $arg == '-' ]]; then
|
||||||
|
ok=1
|
||||||
|
continue #it shouldn't be appended to option_params
|
||||||
|
elif [[ $arg[1] == '-' ]]; then
|
||||||
|
if [[ $ok == 0 ]]; then
|
||||||
|
exitv=127 _failure "Unrecognized option ::1 arg:: for subcommand ::2 subcommand::" $arg $subcommand
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
option_params+=$arg
|
||||||
|
done
|
||||||
|
# First parameter actually is the subcommand: delete it and shift
|
||||||
|
[[ $subcommand != '__default' ]] && { option_params[1]=(); shift }
|
||||||
|
|
||||||
|
### End parsing command-specific options
|
||||||
|
|
||||||
|
[[ "$option_params" == "" ]] && {
|
||||||
|
func "sdk command: ::1 subcommand::" $subcommand
|
||||||
|
} || {
|
||||||
|
func "sdk command: ::1 subcommand:: ::2 param::" $subcommand $option_params
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Later: process subcommand
|
||||||
|
# case "$subcommand" in
|
||||||
|
# help)
|
||||||
|
# print "TODO: help"
|
||||||
|
# ;;
|
||||||
|
# __default)
|
||||||
|
# zdump
|
||||||
|
# ;;
|
||||||
|
|
||||||
|
# # Reject unknown command and suggest help
|
||||||
|
# *)
|
||||||
|
# _warning "Command \"::1 subcommand::\" not recognized." $subcommand
|
||||||
|
# _message "Try -h for help."
|
||||||
|
# return 1
|
||||||
|
# ;;
|
||||||
|
# esac
|
||||||
|
|
||||||
|
# }}}
|
||||||
|
|
||||||
# {{{ Helpers
|
# {{{ Helpers
|
||||||
|
|
||||||
function helper.isfound isfound() {
|
function helper.isfound isfound() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue