mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-05-25 09:26:04 +02:00
make _arguments use more than one action when appropriate; add _argument_sets to complete different sets of arguments and options for the same command (10908)
This commit is contained in:
parent
fc56c62312
commit
d49da60670
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2000-04-25 Sven Wischnowsky <wischnow@informatik.hu-berlin.de>
|
||||
|
||||
* 10908: Completion/Base/.distfiles, Completion/Base/_argument_sets,
|
||||
Completion/Base/_arguments, Completion/Base/_describe,
|
||||
Completion/Builtins/_bindkey, Completion/Builtins/_compdef,
|
||||
Completion/Builtins/_emulate, Completion/Builtins/_zpty,
|
||||
Completion/Core/_tags, Doc/Zsh/compsys.yo,
|
||||
Etc/completion-style-guide, Src/Zle/computil.c: make _arguments
|
||||
use more than one action when appropriate; add _argument_sets to
|
||||
complete different sets of arguments and options for the same command
|
||||
|
||||
2000-04-24 Bart Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 10900: Src/Makefile.in: Replace a dependency on Makefile with a
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles
|
||||
_brace_parameter _command_names _condition _default _equal
|
||||
_long_options _match_pattern _match_pattern.orig _match_test _parameter
|
||||
_precommand _redirect _subscript _tilde _vars
|
||||
_arg_compile _argument_sets _arguments _brace_parameter _combination
|
||||
_command_names _condition _default _describe _equal _first _jobs _math
|
||||
_parameter _precommand _redirect _regex_arguments _subscript _tilde
|
||||
_value _values
|
||||
'
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#autoload
|
||||
|
||||
local all ret=1 end xor has_args had_args ostate ocontext oopt_args r
|
||||
local opre="$PREFIX" oipre="$IPREFIX" ocur="$CURRENT"
|
||||
local osuf="$SUFFIX" oisuf="$ISUFFIX" owords
|
||||
|
||||
owords="$words[@]"
|
||||
|
||||
end=$argv[(i)-]
|
||||
[[ end -gt $# ]] && return 1
|
||||
|
||||
all=( "${(@)argv[1,end]}" )
|
||||
|
||||
shift end
|
||||
|
||||
xor=()
|
||||
ostate=()
|
||||
ocontext=()
|
||||
|
||||
while true; do
|
||||
end=$argv[(i)-]
|
||||
|
||||
_arguments -M xor "$1" "$all[@]" "${(@)argv[2,end-1]}"
|
||||
r=$?
|
||||
|
||||
oopt_args=( "$oopt_args[@]" "${(kv)opt_args}" )
|
||||
if [[ r -eq 300 ]]; then
|
||||
ret=300
|
||||
ostate=( "$ostate[@]" "$state[@]" )
|
||||
ocontext=( "$ocontext[@]" "$context[@]" )
|
||||
PREFIX="$opre" SUFFIX="$osuf"
|
||||
IPREFIX="$oipre" ISUFFIX="$oisuf"
|
||||
CURRENT="$ocur" words=( "$owords[@]" )
|
||||
elif [[ "$r$ret" = 01 ]]; then
|
||||
ret=0
|
||||
fi
|
||||
|
||||
[[ end -gt $# ]] && break
|
||||
|
||||
shift end
|
||||
done
|
||||
|
||||
opt_args=( "$oopt_args[@]" )
|
||||
|
||||
if [[ ret -eq 300 ]]; then
|
||||
state=( "$ostate[@]" )
|
||||
context=( "$ocontext[@]" )
|
||||
elif [[ -z "$has_args" ]]; then
|
||||
if [[ -n "$had_args" ]]; then
|
||||
_message "no more arguments"
|
||||
else
|
||||
_message "no arguments"
|
||||
fi
|
||||
fi
|
||||
|
||||
return ret
|
|
@ -4,7 +4,7 @@
|
|||
# descriptions given as arguments to this function.
|
||||
|
||||
local long cmd="$words[1]" descr mesg subopts opt usecc autod
|
||||
local oldcontext="$curcontext" hasopts
|
||||
local oldcontext="$curcontext" hasopts multi ismulti
|
||||
|
||||
long=$argv[(I)--]
|
||||
if (( long )); then
|
||||
|
@ -148,36 +148,37 @@ if (( long )); then
|
|||
set -- "$tmpargv[@]" "${(@P)name}"
|
||||
fi
|
||||
|
||||
multi=(-i)
|
||||
subopts=()
|
||||
while [[ "$1" = -(O*|C) ]]; do
|
||||
while [[ "$1" = -(O*|C|M*) ]]; do
|
||||
case "$1" in
|
||||
-C) usecc=yes; shift ;;
|
||||
-O) subopts=( "${(@P)2}" ); shift 2 ;;
|
||||
*) subopts=( "${(@P)1[3,-1]}" ); shift ;;
|
||||
-O*) subopts=( "${(@P)1[3,-1]}" ); shift ;;
|
||||
-M) ismulti=yes multi=(-I "$2" "$3"); shift 3 ;;
|
||||
-M*) ismulti=yes multi=(-I "${1[3,-1]}" "$2"); shift 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
zstyle -s ":completion:${curcontext}:options" auto-description autod
|
||||
|
||||
if (( $# )) && comparguments -i "$autod" "$@"; then
|
||||
if (( $# )) && comparguments "$multi[@]" "$autod" "$@"; then
|
||||
local nm="$compstate[nmatches]" action noargs aret expl local
|
||||
local next direct odirect equal single match matched ws tmp1 tmp2 tmp3
|
||||
local opts subc prefix suffix
|
||||
local opts subc tc prefix suffix descrs actions subcs
|
||||
local origpre="$PREFIX" origipre="$IPREFIX"
|
||||
|
||||
if comparguments -D descr action; then
|
||||
comparguments -C subc
|
||||
curcontext="${oldcontext%:*}:$subc"
|
||||
|
||||
if comparguments -D descrs actions subcs; then
|
||||
if comparguments -O next direct odirect equal; then
|
||||
opts=yes
|
||||
_tags arguments options
|
||||
_tags "$subcs[@]" options
|
||||
else
|
||||
_tags arguments
|
||||
_tags "$subcs[@]"
|
||||
fi
|
||||
else
|
||||
if comparguments -a; then
|
||||
noargs='no more arguments'
|
||||
had_args=yes
|
||||
else
|
||||
noargs='no arguments'
|
||||
fi
|
||||
|
@ -187,83 +188,100 @@ if (( $# )) && comparguments -i "$autod" "$@"; then
|
|||
_tags options
|
||||
fi
|
||||
|
||||
context=()
|
||||
state=()
|
||||
|
||||
while true; do
|
||||
while _tags; do
|
||||
if [[ -n "$matched" ]] || _requested arguments; then
|
||||
_description arguments expl "$descr"
|
||||
while (( $#descrs )); do
|
||||
|
||||
if [[ "$action" = \=\ * ]]; then
|
||||
action="$action[3,-1]"
|
||||
words=( "$subc" "$words[@]" )
|
||||
(( CURRENT++ ))
|
||||
fi
|
||||
action="$actions[1]"
|
||||
descr="$descrs[1]"
|
||||
subc="$subcs[1]"
|
||||
|
||||
if [[ "$action" = -\>* ]]; then
|
||||
comparguments -W line opt_args
|
||||
state="${${action[3,-1]##[ ]#}%%[ ]#}"
|
||||
if [[ -n "$usecc" ]]; then
|
||||
curcontext="${oldcontext%:*}:$subc"
|
||||
else
|
||||
context="$subc"
|
||||
fi
|
||||
compstate[restore]=''
|
||||
aret=yes
|
||||
else
|
||||
if [[ -z "$local" ]]; then
|
||||
local line
|
||||
typeset -A opt_args
|
||||
local=yes
|
||||
if [[ -n "$matched" ]] || _requested "$subc"; then
|
||||
|
||||
curcontext="${oldcontext%:*}:$subc"
|
||||
|
||||
_description "$subc" expl "$descr"
|
||||
|
||||
if [[ "$action" = \=\ * ]]; then
|
||||
action="$action[3,-1]"
|
||||
words=( "$subc" "$words[@]" )
|
||||
(( CURRENT++ ))
|
||||
fi
|
||||
|
||||
comparguments -W line opt_args
|
||||
|
||||
if [[ "$action" = \ # ]]; then
|
||||
|
||||
# An empty action means that we should just display a message.
|
||||
|
||||
[[ -n "$matched" ]] && compadd -n -Q -S '' -s "$SUFFIX" - "$PREFIX"
|
||||
mesg="$descr"
|
||||
|
||||
elif [[ "$action" = \(\(*\)\) ]]; then
|
||||
|
||||
# ((...)) contains literal strings with descriptions.
|
||||
|
||||
eval ws\=\( "${action[3,-3]}" \)
|
||||
|
||||
_describe "$descr" ws -M "$match" "$subopts[@]"
|
||||
|
||||
elif [[ "$action" = \(*\) ]]; then
|
||||
|
||||
# Anything inside `(...)' is added directly.
|
||||
|
||||
_all_labels arguments expl "$descr" \
|
||||
compadd "$subopts[@]" - ${=action[2,-2]}
|
||||
elif [[ "$action" = \{*\} ]]; then
|
||||
|
||||
# A string in braces is evaluated.
|
||||
|
||||
while _next_label arguments expl "$descr"; do
|
||||
eval "$action[2,-2]"
|
||||
done
|
||||
elif [[ "$action" = \ * ]]; then
|
||||
|
||||
# If the action starts with a space, we just call it.
|
||||
|
||||
eval "action=( $action )"
|
||||
while _next_label arguments expl "$descr"; do
|
||||
"$action[@]"
|
||||
done
|
||||
if [[ "$action" = -\>* ]]; then
|
||||
comparguments -W line opt_args
|
||||
state=( "$state[@]" "${${action[3,-1]##[ ]#}%%[ ]#}" )
|
||||
if [[ -n "$usecc" ]]; then
|
||||
curcontext="${oldcontext%:*}:$subc"
|
||||
else
|
||||
context=( "$context[@]" "$subc" )
|
||||
fi
|
||||
compstate[restore]=''
|
||||
aret=yes
|
||||
else
|
||||
if [[ -z "$local" ]]; then
|
||||
local line
|
||||
typeset -A opt_args
|
||||
local=yes
|
||||
fi
|
||||
|
||||
# Otherwise we call it with the description-arguments.
|
||||
comparguments -W line opt_args
|
||||
|
||||
eval "action=( $action )"
|
||||
while _next_label arguments expl "$descr"; do
|
||||
"$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
|
||||
done
|
||||
if [[ "$action" = \ # ]]; then
|
||||
|
||||
# An empty action means that we should just display a message.
|
||||
|
||||
[[ -n "$matched" ]] &&
|
||||
compadd -n -Q -S '' -s "$SUFFIX" - "$PREFIX"
|
||||
mesg="$descr"
|
||||
|
||||
elif [[ "$action" = \(\(*\)\) ]]; then
|
||||
|
||||
# ((...)) contains literal strings with descriptions.
|
||||
|
||||
eval ws\=\( "${action[3,-3]}" \)
|
||||
|
||||
_describe -t "$subc" "$descr" ws -M "$match" "$subopts[@]"
|
||||
|
||||
elif [[ "$action" = \(*\) ]]; then
|
||||
|
||||
# Anything inside `(...)' is added directly.
|
||||
|
||||
_all_labels "$subc" expl "$descr" \
|
||||
compadd "$subopts[@]" - ${=action[2,-2]}
|
||||
elif [[ "$action" = \{*\} ]]; then
|
||||
|
||||
# A string in braces is evaluated.
|
||||
|
||||
while _next_label "$subc" expl "$descr"; do
|
||||
eval "$action[2,-2]"
|
||||
done
|
||||
elif [[ "$action" = \ * ]]; then
|
||||
|
||||
# If the action starts with a space, we just call it.
|
||||
|
||||
eval "action=( $action )"
|
||||
while _next_label "$subc" expl "$descr"; do
|
||||
"$action[@]"
|
||||
done
|
||||
else
|
||||
|
||||
# Otherwise we call it with the description-arguments.
|
||||
|
||||
eval "action=( $action )"
|
||||
while _next_label "$subc" expl "$descr"; do
|
||||
"$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
shift 1 descrs
|
||||
shift 1 actions
|
||||
shift 1 subcs
|
||||
done
|
||||
|
||||
if [[ -z "$matched$hasopts" ]] && _requested options &&
|
||||
{ ! zstyle -T ":completion:${curcontext}:options" prefix-needed ||
|
||||
|
@ -344,7 +362,11 @@ if (( $# )) && comparguments -i "$autod" "$@"; then
|
|||
[[ -n "$aret" ]] && return 300
|
||||
|
||||
[[ -n "$mesg" ]] && _message "$mesg"
|
||||
[[ -n "$noargs" ]] && _message "$noargs"
|
||||
if [[ -n "$noargs" ]]; then
|
||||
[[ -z "$ismulti" ]] && _message "$noargs"
|
||||
else
|
||||
has_args=yes
|
||||
fi
|
||||
|
||||
# Set the return value.
|
||||
|
||||
|
|
|
@ -10,6 +10,12 @@ local _type=values _descr
|
|||
if [[ "$1" = -o ]]; then
|
||||
_type=options
|
||||
shift
|
||||
elif [[ "$1" = -t ]]; then
|
||||
_type="$2"
|
||||
shift 2
|
||||
elif [[ "$1" = -t* ]]; then
|
||||
_type="${1[3,-1]}"
|
||||
shift
|
||||
fi
|
||||
|
||||
# Do the tests. `showd' is set if the descriptions should be shown.
|
||||
|
|
|
@ -24,7 +24,7 @@ _arguments -C -s \
|
|||
'(-l -L -d -D -A -N -m -s *)-r[unbind specified in-strings]:*:in-string' \
|
||||
'(-l -L -d -D -A -N -m -r *)-s[bind each in-string to each out-string]:*:key string' \
|
||||
'(-e -v -a -M -l -L -d -D -A -N -m)-R[interpret in-strings as ranges]' \
|
||||
'(-l -L -d -A -N -m -r -s)*::widgets:->widget'
|
||||
'(-l -L -d -A -N -m -r -s)*::widgets:->widget' && return 0
|
||||
|
||||
case $state in
|
||||
keymap)
|
||||
|
|
|
@ -8,11 +8,19 @@ _arguments -C -s \
|
|||
'(-a -n -p -P -k -K)-d[delete]:*:completed command:->ccom' \
|
||||
'(-n -d -P -k -K)-p[completion for command matching pattern]:completion function:->cfun:pattern' \
|
||||
'(-n -d -p -k -K)-P[as -p for commands without own completion]:completion function:->cfun:pattern' \
|
||||
'(-d -p -P -K)-k[define widget and key binding]:completion function:->cfun:widget name::style:->style:*:key' \
|
||||
'(-d -p -P -k)-K[define multiple widgets based on function]:completion function:->cfun:widget name::style:->style:*:key' \
|
||||
'1:completion function:->cfun' \
|
||||
'2:commands:_command_names'
|
||||
|
||||
'(-d -p -P -K)-k[define widget and key binding]:completion function:->cfun:style:->style:*:key' \
|
||||
'(-d -p -P -k)-K[define multiple widgets based on function]:*::: :->multi' \
|
||||
':completion function:->cfun' \
|
||||
'*:commands: _command_names' && return 0
|
||||
|
||||
if [[ $state = multi ]]; then
|
||||
case $(( CURRENT % 3 )) in
|
||||
0) _message key
|
||||
return 1;;
|
||||
1) state=cfun;;
|
||||
2) state=style;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case $state in
|
||||
ccom)
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
_arguments -C -s \
|
||||
'-L[set local_options and local_traps as well]' \
|
||||
'-R[reset all options instead of only those needed for script portability]' \
|
||||
'1::shell to emulate:(zsh sh ksh csh)'
|
||||
'::shell to emulate:(zsh sh ksh csh)'
|
||||
|
|
|
@ -9,7 +9,7 @@ _arguments -C -s \
|
|||
'(-e -b -d -r -L)-w[send string to command]:name:->name:*:strings to write' \
|
||||
'(-e -b -d -w -L *)-r[read string from command]:name:->name:param:_parameters' \
|
||||
'(-e -b -d -w -r)-L[list defined commands as calls]' \
|
||||
'(-r)*::args:_normal'
|
||||
'(-r)*::args:_normal' && return 0
|
||||
|
||||
if [[ $state = name ]]; then
|
||||
list=( ${${(f)"$(zpty)"}#*\) } )
|
||||
|
|
|
@ -53,7 +53,7 @@ if (( $# )); then
|
|||
"$_sort_tags" "$@"
|
||||
else
|
||||
zstyle -a ":completion:${curcontext}:" tag-order order ||
|
||||
order=('arguments values' options)
|
||||
order=('(|*-)argument-* (|*-)option-* values' options)
|
||||
|
||||
for tag in $order; do
|
||||
case $tag in
|
||||
|
|
|
@ -331,7 +331,7 @@ enditemize()
|
|||
|
||||
As an example, the context name
|
||||
|
||||
example(tt(:completion::complete:dvips:-o-1:files))
|
||||
example(tt(:completion::complete:dvips:option-o-1:files))
|
||||
|
||||
says that normal completion was attempted on an argument of the tt(dvips)
|
||||
command (more precisely: completion was attempted on the first argument
|
||||
|
@ -1501,7 +1501,7 @@ This style is used when completing arguments of the Debian `tt(dpkg)'
|
|||
program. It contains an override for the default package set
|
||||
for a given context. For example,
|
||||
|
||||
example(zstyle ':completion:*:complete:dpkg:--status-1:' packageset avail)
|
||||
example(zstyle ':completion:*:complete:dpkg:option--status-1:' packageset avail)
|
||||
|
||||
causes available packages, rather than only installed packages,
|
||||
to be completed for `dpkg --status'.
|
||||
|
@ -2879,11 +2879,11 @@ exclusive. Such a list is given in parentheses at the beginning, as in
|
|||
`tt((-two -three 1)-one:...)' or `tt((-foo):...)'. In the first
|
||||
example, the options `tt(-two)' and `tt(-three)' and the first
|
||||
argument will not be offered as possible completions if the option
|
||||
`tt(-one)' is on the line. Also, the list may contain a single star as
|
||||
one of its elements to specify that the description for the rest
|
||||
arguments should not be used and it may contain a colon to specify
|
||||
that the descriptions for all normal (non-option-) arguments should
|
||||
not be used.
|
||||
`tt(-one)' is on the line before the cursor. Also, the list may
|
||||
contain a single star as one of its elements to specify that the
|
||||
description for the rest arguments should not be used and it may
|
||||
contain a colon to specify that the descriptions for all normal
|
||||
(non-option-) arguments should not be used.
|
||||
|
||||
In each of the cases above, the var(action) says how the possible
|
||||
completions should be generated. In cases where only one of a fixed
|
||||
|
@ -2896,9 +2896,10 @@ matches will be listed together with their descriptions if the
|
|||
tt(description) style for the tt(values) tag is set.
|
||||
|
||||
An var(action) of the form `tt(->)var(string)' is used by functions
|
||||
that implement a state machine. In this case, the `var(string)' (with
|
||||
all leading and trailing spaces and tabs removed) will be stored in
|
||||
the global parameter tt(state) and the function returns with a return
|
||||
that implement a state machine. In this case, the `var(string)'s (with
|
||||
all leading and trailing spaces and tabs removed) of all actions that
|
||||
have to be used will be stored in
|
||||
the global array tt(state) and the function returns with a return
|
||||
value of 300 (to make it distinguishable from other return values)
|
||||
after setting the global `tt(context)', `tt(line)' and `tt(opt_args)'
|
||||
parameters as described below and without resetting any changes made
|
||||
|
@ -2965,13 +2966,15 @@ and their arguments. These are stored in the associative array
|
|||
`tt(opt_args)', using the option names as keys and their arguments as
|
||||
the values. For options that have more than one argument these are
|
||||
given as one string, separated by colons. All colons in the original
|
||||
arguments are preceded with backslashes. The parameter `tt(context)'
|
||||
will be set to the automatically created context name. This is either
|
||||
a string of the form `var(-opt)tt(-)var(n)' for the var(n)'th argument
|
||||
arguments are preceded with backslashes.
|
||||
|
||||
The parameter `tt(context)'
|
||||
will be set to the automatically created context names. This are either
|
||||
strings of the form `tt(option)var(-opt)tt(-)var(n)' for the var(n)'th argument
|
||||
of the option var(-opt), or a string of the form `tt(argument-)var(n)'
|
||||
for the var(n)'th argument (for rest arguments the var(n) is the
|
||||
string `tt(rest)'). For example, when completing the argument of the tt(-o)
|
||||
option, the name is `tt(-o-1)' and for the second normal (non-option-)
|
||||
option, the name is `tt(option-o-1)' and for the second normal (non-option-)
|
||||
argument it is `tt(argument-2)'.
|
||||
|
||||
Also, during the evaluation of the var(action), the context name in
|
||||
|
@ -3091,6 +3094,41 @@ arguments. The first one describes the first argument as a
|
|||
be completed. The last description says that all other arguments are
|
||||
`var(page numbers)' but does not give possible completions.
|
||||
)
|
||||
findex(_argument_sets)
|
||||
item(tt(_argument_sets) var(sets) ...)(
|
||||
This is like tt(_arguments) but allows to specify multiple sets of
|
||||
options and arguments. The arguments are sets of specifications for
|
||||
tt(_arguments) separated by single hyphens. The specifications before
|
||||
the first hyphen are shared by all sets given after the first
|
||||
hyphen. The first word in every other set gives the name of the
|
||||
set. This name may appear in exclusion lists in the specifications,
|
||||
either alone or before (with a `tt(-)' between the name and the rest)
|
||||
one of the possible values described for tt(_arguments) above.
|
||||
|
||||
For example:
|
||||
|
||||
example(_argument_sets \
|
||||
-a \
|
||||
- set1 \
|
||||
-c \
|
||||
- set2 \
|
||||
-d \
|
||||
':arg:(x2 y2)')
|
||||
|
||||
This defines two sets. When the command line contains the option
|
||||
`tt(-c)', the `tt(-d)' option and the argument will not be considered
|
||||
possible completions. When it contains `tt(-d)' or an argument, the
|
||||
option `tt(-c)' will not be completed any more, but if `tt(-a)' is
|
||||
given, both sets will still be considered valid, because it appears
|
||||
before the first hyphen, so both sets contain this option.
|
||||
|
||||
Don't expect too much with complicated options that get their
|
||||
arguments in the same string and `tt(->)var(state)' actions or with
|
||||
the tt(-C) option that is given to tt(_arguments), otherwise most
|
||||
things should work. Note that the contexts reported in the tt(context)
|
||||
array and the options in the tt(opt_args) association are prefixed
|
||||
with the set names and a hyphen.
|
||||
)
|
||||
findex(_values)
|
||||
item(tt(_values) var(specs) ...)(
|
||||
This is used to complete values (strings) and their arguments or
|
||||
|
|
|
@ -27,7 +27,7 @@ by giving it to functions like `_tags' via the `-C' options, as in:
|
|||
|
||||
local context ...
|
||||
...
|
||||
_arguments ... '-foo:foo:->foo'
|
||||
_arguments ... '-foo:foo:->foo' && return 0
|
||||
...
|
||||
if [[ "$state" = foo ]]; then
|
||||
_tags -C "$context" ...
|
||||
|
@ -47,7 +47,7 @@ reported back to functions you call. E.g.:
|
|||
|
||||
local curcontext="$curcontext" ...
|
||||
...
|
||||
_arguments -C ... 'foo:foo:->foo'
|
||||
_arguments -C ... 'foo:foo:->foo' && return 0
|
||||
...
|
||||
if [[ "$state" = foo ]]; then
|
||||
_tags ...
|
||||
|
@ -60,6 +60,32 @@ value changed by `_arguments' and `_values' is only used in your
|
|||
function (and make sure to initialise it to its old value as in the
|
||||
example).
|
||||
|
||||
All this only works if the specifications given to `_arguments' define
|
||||
options and arguments that are completely separate. If there is more
|
||||
than one `->state' action and more than one of them might be needed
|
||||
for the same word, you'll have to use a loop:
|
||||
|
||||
local state context line i expl ret=1
|
||||
...
|
||||
_arguments \
|
||||
'::arg1:->arg1' \
|
||||
'*:args:->rest' && return 0
|
||||
|
||||
while (( $#state )); do
|
||||
case "$state[1]" in
|
||||
arg1) _wanted -C "$context[1]" foo expl 'foo' compadd - foo1 foo2 && ret=0;;
|
||||
rest) _wanted -C "$context[1]" bar expl 'bar' compadd - bar1 bar2 && ret=0;;
|
||||
esac
|
||||
shift 1 state
|
||||
shift 1 context
|
||||
done
|
||||
|
||||
return ret
|
||||
|
||||
As you can see, `state' and `context' are really arrays. In this
|
||||
example, completion for the first argument has to complete both `foo's
|
||||
and `bar's.
|
||||
|
||||
Then, before adding the matches, see if matches of that type are
|
||||
requested by the user in the current context. If you will add only one
|
||||
type of matches, this is very simple. You can use the function
|
||||
|
|
|
@ -304,6 +304,7 @@ struct cadef {
|
|||
char *match; /* -M spec to use */
|
||||
int argsactive; /* if arguments are still allowed */
|
||||
/* used while parsing a command line */
|
||||
char *set; /* set name, shared */
|
||||
};
|
||||
|
||||
/* Description for an option. */
|
||||
|
@ -317,6 +318,7 @@ struct caopt {
|
|||
Caarg args; /* option arguments */
|
||||
int active; /* still allowed on command line */
|
||||
int num; /* it's the num'th option */
|
||||
char *set; /* set name, shared */
|
||||
};
|
||||
|
||||
#define CAO_NEXT 1
|
||||
|
@ -335,7 +337,10 @@ struct caarg {
|
|||
char *end; /* end-pattern for ::<pat>:... */
|
||||
char *opt; /* option name if for an option */
|
||||
int num; /* it's the num'th argument */
|
||||
int min; /* it's also this argument, using opt. args */
|
||||
int direct; /* number was given directly */
|
||||
int active; /* still allowed on command line */
|
||||
char *set; /* set name, shared */
|
||||
};
|
||||
|
||||
#define CAA_NORMAL 1
|
||||
|
@ -393,6 +398,7 @@ freecadef(Cadef d)
|
|||
Caopt p, n;
|
||||
|
||||
zsfree(d->match);
|
||||
zsfree(d->set);
|
||||
if (d->defs)
|
||||
freearray(d->defs);
|
||||
|
||||
|
@ -454,7 +460,8 @@ bslashcolon(char *s)
|
|||
/* Parse an argument definition. */
|
||||
|
||||
static Caarg
|
||||
parse_caarg(int mult, int type, int num, char *oname, char **def)
|
||||
parse_caarg(int mult, int type, int num, int opt, char *oname, char **def,
|
||||
char *set)
|
||||
{
|
||||
Caarg ret = (Caarg) zalloc(sizeof(*ret));
|
||||
char *p = *def, *d, sav;
|
||||
|
@ -463,8 +470,11 @@ parse_caarg(int mult, int type, int num, char *oname, char **def)
|
|||
ret->descr = ret->action = ret->end = NULL;
|
||||
ret->xor = NULL;
|
||||
ret->num = num;
|
||||
ret->min = num - opt;
|
||||
ret->type = type;
|
||||
ret->opt = ztrdup(oname);
|
||||
ret->direct = 0;
|
||||
ret->set = set;
|
||||
|
||||
/* Get the description. */
|
||||
|
||||
|
@ -498,16 +508,22 @@ parse_caarg(int mult, int type, int num, char *oname, char **def)
|
|||
/* Parse an array of definitions. */
|
||||
|
||||
static Cadef
|
||||
parse_cadef(char *nam, char **args)
|
||||
parse_cadef(char *nam, char **args, int multi)
|
||||
{
|
||||
Cadef ret;
|
||||
Caopt *optp;
|
||||
Caarg argp;
|
||||
char **oargs = args, *p, *q, *match = "r:|[_-]=* r:|=*", **xor;
|
||||
char *adpre, *adsuf;
|
||||
char *adpre, *adsuf, *set = NULL, *doset = NULL;
|
||||
int single = 0, anum = 1, xnum, nopts, ndopts, nodopts;
|
||||
|
||||
nopts = ndopts = nodopts = 0;
|
||||
|
||||
if (multi) {
|
||||
if (!args[1])
|
||||
return NULL;
|
||||
set = tricat(*args++, "-", "");
|
||||
}
|
||||
/* First string is the auto-description definition. */
|
||||
|
||||
for (p = args[0]; *p && (p[0] != '%' || p[1] != 'd'); p++);
|
||||
|
@ -551,6 +567,7 @@ parse_cadef(char *nam, char **args)
|
|||
ret->defs = zarrdup(oargs);
|
||||
ret->ndefs = arrlen(oargs);
|
||||
ret->lastt = time(0);
|
||||
ret->set = set;
|
||||
if (single) {
|
||||
ret->single = (Caopt *) zalloc(256 * sizeof(Caopt));
|
||||
memset(ret->single, 0, 256 * sizeof(Caopt));
|
||||
|
@ -561,6 +578,10 @@ parse_cadef(char *nam, char **args)
|
|||
/* Get the definitions. */
|
||||
|
||||
for (optp = &(ret->opts); *args; args++) {
|
||||
if (args[0][0] == '-' && !args[0][1]) {
|
||||
doset = set;
|
||||
continue;
|
||||
}
|
||||
p = dupstring(*args);
|
||||
xnum = 0;
|
||||
if (*p == '(') {
|
||||
|
@ -689,7 +710,7 @@ parse_cadef(char *nam, char **args)
|
|||
/* There's at least one argument. */
|
||||
|
||||
Caarg *oargp = &oargs;
|
||||
int atype, rest, oanum = 1;
|
||||
int atype, rest, oanum = 1, onum = 0;
|
||||
char *end;
|
||||
|
||||
/* Loop over the arguments. */
|
||||
|
@ -736,7 +757,10 @@ parse_cadef(char *nam, char **args)
|
|||
|
||||
/* And the definition. */
|
||||
|
||||
*oargp = parse_caarg(!rest, atype, oanum++, name, &p);
|
||||
*oargp = parse_caarg(!rest, atype, oanum++, onum,
|
||||
name, &p, doset);
|
||||
if (atype == CAA_OPT)
|
||||
onum++;
|
||||
if (end)
|
||||
(*oargp)->end = ztrdup(end);
|
||||
oargp = &((*oargp)->next);
|
||||
|
@ -751,6 +775,7 @@ parse_cadef(char *nam, char **args)
|
|||
optp = &((*optp)->next);
|
||||
|
||||
opt->next = NULL;
|
||||
opt->set = doset;
|
||||
opt->name = ztrdup(rembslashcolon(name));
|
||||
if (descr)
|
||||
opt->descr = ztrdup(descr);
|
||||
|
@ -810,15 +835,15 @@ parse_cadef(char *nam, char **args)
|
|||
} else
|
||||
type = CAA_RARGS;
|
||||
}
|
||||
ret->rest = parse_caarg(0, type, -1, NULL, &p);
|
||||
ret->rest = parse_caarg(0, type, -1, 0, NULL, &p, doset);
|
||||
ret->rest->xor = xor;
|
||||
} else {
|
||||
/* It's a normal argument definition. */
|
||||
|
||||
int type = CAA_NORMAL;
|
||||
int type = CAA_NORMAL, direct;
|
||||
Caarg arg, tmp, pre;
|
||||
|
||||
if (idigit(*p)) {
|
||||
if ((direct = idigit(*p))) {
|
||||
/* Argment number is given. */
|
||||
int num = 0;
|
||||
|
||||
|
@ -840,8 +865,9 @@ parse_cadef(char *nam, char **args)
|
|||
type = CAA_OPT;
|
||||
p++;
|
||||
}
|
||||
arg = parse_caarg(0, type, anum - 1, NULL, &p);
|
||||
arg = parse_caarg(0, type, anum - 1, 0, NULL, &p, doset);
|
||||
arg->xor = xor;
|
||||
arg->direct = direct;
|
||||
|
||||
/* Sort the new definition into the existing list. */
|
||||
|
||||
|
@ -865,7 +891,13 @@ parse_cadef(char *nam, char **args)
|
|||
ret->nopts = nopts;
|
||||
ret->ndopts = ndopts;
|
||||
ret->nodopts = nodopts;
|
||||
|
||||
|
||||
for (argp = ret->args, xnum = 0; argp; argp = argp->next) {
|
||||
if (!argp->direct)
|
||||
argp->min = argp->num - xnum;
|
||||
if (argp->type == CAA_OPT)
|
||||
xnum++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -873,7 +905,7 @@ parse_cadef(char *nam, char **args)
|
|||
* are newly built. */
|
||||
|
||||
static Cadef
|
||||
get_cadef(char *nam, char **args)
|
||||
get_cadef(char *nam, char **args, int multi)
|
||||
{
|
||||
Cadef *p, *min, new;
|
||||
int i, na = arrlen(args);
|
||||
|
@ -887,7 +919,7 @@ get_cadef(char *nam, char **args)
|
|||
min = p;
|
||||
if (i)
|
||||
min = p;
|
||||
if ((new = parse_cadef(nam, args))) {
|
||||
if ((new = parse_cadef(nam, args, multi))) {
|
||||
freecadef(*min);
|
||||
*min = new;
|
||||
}
|
||||
|
@ -974,10 +1006,10 @@ ca_get_arg(Cadef d, int n)
|
|||
if (d->argsactive) {
|
||||
Caarg a = d->args;
|
||||
|
||||
while (a && a->num < n)
|
||||
while (a && (n < a->min || n > a->num))
|
||||
a = a->next;
|
||||
|
||||
if (a && a->num == n && a->active)
|
||||
if (a && a->min <= n && a->num >= n && a->active)
|
||||
return a;
|
||||
|
||||
return (d->rest && d->rest->active ? d->rest : NULL);
|
||||
|
@ -987,20 +1019,32 @@ ca_get_arg(Cadef d, int n)
|
|||
|
||||
/* Use a xor list, marking options as inactive. */
|
||||
|
||||
static void
|
||||
ca_inactive(Cadef d, char **xor)
|
||||
{
|
||||
if (xor) {
|
||||
Caopt opt;
|
||||
static LinkList ca_xor;
|
||||
|
||||
for (; *xor; xor++) {
|
||||
if (xor[0][0] == ':' && !xor[0][1])
|
||||
static int
|
||||
ca_inactive(Cadef d, char **xor, int cur)
|
||||
{
|
||||
if (xor && cur <= compcurrent) {
|
||||
Caopt opt;
|
||||
char *x;
|
||||
int sl = (d->set ? strlen(d->set) : -1);
|
||||
|
||||
for (; (x = *xor); xor++) {
|
||||
if (ca_xor)
|
||||
addlinknode(ca_xor, x);
|
||||
if (sl > 0) {
|
||||
if (strpfx(d->set, x))
|
||||
x += sl;
|
||||
else if (!strncmp(d->set, x, sl - 1))
|
||||
return 1;
|
||||
}
|
||||
if (x[0] == ':' && !x[1])
|
||||
d->argsactive = 0;
|
||||
else if (xor[0][0] == '*' && !xor[0][1]) {
|
||||
else if (x[0] == '*' && !x[1]) {
|
||||
if (d->rest)
|
||||
d->rest->active = 0;
|
||||
} else if (xor[0][0] >= '0' && xor[0][0] <= '9') {
|
||||
int n = atoi(xor[0]);
|
||||
} else if (x[0] >= '0' && x[0] <= '9') {
|
||||
int n = atoi(x);
|
||||
Caarg a = d->args;
|
||||
|
||||
while (a && a->num < n)
|
||||
|
@ -1008,10 +1052,11 @@ ca_inactive(Cadef d, char **xor)
|
|||
|
||||
if (a && a->num == n)
|
||||
a->active = 0;
|
||||
} else if ((opt = ca_get_opt(d, *xor, 1, NULL)))
|
||||
} else if ((opt = ca_get_opt(d, x, 1, NULL)))
|
||||
opt->active = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* State when parsing a command line. */
|
||||
|
@ -1022,7 +1067,7 @@ struct castate {
|
|||
Caarg def, ddef;
|
||||
Caopt curopt;
|
||||
int opt, arg, argbeg, optbeg, nargbeg, restbeg, curpos;
|
||||
int inopt, inrest, inarg, nth, doff, singles;
|
||||
int inopt, inrest, inarg, nth, doff, singles, oopt;
|
||||
LinkList args;
|
||||
LinkList *oargs;
|
||||
};
|
||||
|
@ -1030,10 +1075,10 @@ struct castate {
|
|||
static struct castate ca_laststate;
|
||||
static int ca_parsed = 0, ca_alloced = 0;
|
||||
|
||||
/* Pars a command line. */
|
||||
/* Parse a command line. */
|
||||
|
||||
static void
|
||||
ca_parse_line(Cadef d)
|
||||
static int
|
||||
ca_parse_line(Cadef d, int multi)
|
||||
{
|
||||
Caarg adef, ddef;
|
||||
Caopt ptr, wasopt;
|
||||
|
@ -1073,7 +1118,7 @@ ca_parse_line(Cadef d)
|
|||
state.curopt = NULL;
|
||||
state.argbeg = state.optbeg = state.nargbeg = state.restbeg =
|
||||
state.nth = state.inopt = state.inarg = state.opt = state.arg = 1;
|
||||
state.inrest = state.doff = state.singles = state.doff = 0;
|
||||
state.inrest = state.doff = state.singles = state.doff = state.oopt = 0;
|
||||
state.curpos = compcurrent;
|
||||
state.args = znewlinklist();
|
||||
state.oargs = (LinkList *) zalloc(d->nopts * sizeof(LinkList));
|
||||
|
@ -1086,7 +1131,7 @@ ca_parse_line(Cadef d)
|
|||
if (!compwords[1]) {
|
||||
ca_laststate.opt = ca_laststate.arg = 0;
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
/* Loop over the words from the line. */
|
||||
|
||||
|
@ -1095,7 +1140,8 @@ ca_parse_line(Cadef d)
|
|||
ddef = adef = NULL;
|
||||
doff = state.singles = 0;
|
||||
|
||||
ca_inactive(d, argxor);
|
||||
if (ca_inactive(d, argxor, cur))
|
||||
return 1;
|
||||
|
||||
/* We've a definition for an argument, skip to the next. */
|
||||
|
||||
|
@ -1104,7 +1150,8 @@ ca_parse_line(Cadef d)
|
|||
if (state.curopt)
|
||||
zaddlinknode(state.oargs[state.curopt->num], ztrdup(line));
|
||||
|
||||
state.opt = (state.def->type == CAA_OPT);
|
||||
if ((state.opt = (state.def->type == CAA_OPT)) && state.def->opt)
|
||||
state.oopt++;
|
||||
|
||||
if (state.def->type == CAA_REST || state.def->type == CAA_RARGS ||
|
||||
state.def->type == CAA_RREST) {
|
||||
|
@ -1145,7 +1192,8 @@ ca_parse_line(Cadef d)
|
|||
|
||||
state.oargs[state.curopt->num] = znewlinklist();
|
||||
|
||||
ca_inactive(d, state.curopt->xor);
|
||||
if (ca_inactive(d, state.curopt->xor, cur))
|
||||
return 1;
|
||||
|
||||
/* Collect the argument strings. Maybe. */
|
||||
|
||||
|
@ -1184,7 +1232,8 @@ ca_parse_line(Cadef d)
|
|||
if ((tmpopt = d->single[STOUC(*p)])) {
|
||||
state.oargs[tmpopt->num] = znewlinklist();
|
||||
|
||||
ca_inactive(d, tmpopt->xor);
|
||||
if (ca_inactive(d, tmpopt->xor, cur))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (state.def &&
|
||||
|
@ -1203,12 +1252,16 @@ ca_parse_line(Cadef d)
|
|||
state.opt = 0;
|
||||
else
|
||||
state.curopt = NULL;
|
||||
} else if (state.arg) {
|
||||
} else if (multi && (*line == '-' || *line == '+') && cur != compcurrent)
|
||||
return 1;
|
||||
else if (state.arg) {
|
||||
/* Otherwise it's a normal argument. */
|
||||
if (state.inopt) {
|
||||
state.inopt = 0;
|
||||
state.nargbeg = cur - 1;
|
||||
}
|
||||
if (!d->args && !d->rest)
|
||||
return 1;
|
||||
if ((adef = state.def = ca_get_arg(d, state.nth)) &&
|
||||
(state.def->type == CAA_RREST ||
|
||||
state.def->type == CAA_RARGS)) {
|
||||
|
@ -1291,6 +1344,7 @@ ca_parse_line(Cadef d)
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Build a colon-list from a list. */
|
||||
|
@ -1327,6 +1381,88 @@ ca_colonlist(LinkList l)
|
|||
return ztrdup("");
|
||||
}
|
||||
|
||||
static void
|
||||
ca_set_data(char *opt, Caarg arg, char **args, int single)
|
||||
{
|
||||
LinkList descr, act, subc;
|
||||
char nbuf[40], *buf;
|
||||
int restr = 0, onum, miss = 0, rest, oopt = 1, lopt = 0, addopt;
|
||||
|
||||
descr = newlinklist();
|
||||
act = newlinklist();
|
||||
subc = newlinklist();
|
||||
|
||||
rec:
|
||||
|
||||
addopt = (opt ? 0 : ca_laststate.oopt);
|
||||
|
||||
for (; arg && (arg->num < 0 ||
|
||||
(arg->min <= ca_laststate.nth + addopt &&
|
||||
arg->num >= ca_laststate.nth));) {
|
||||
if ((lopt = arg->type == CAA_OPT) && !opt && oopt > 0)
|
||||
oopt = 0;
|
||||
|
||||
addlinknode(descr, arg->descr);
|
||||
addlinknode(act, arg->action);
|
||||
|
||||
if (!restr) {
|
||||
if ((restr = (arg->type == CAA_RARGS)))
|
||||
restrict_range(ca_laststate.optbeg, arrlen(compwords) - 1);
|
||||
else if ((restr = (arg->type == CAA_RREST)))
|
||||
restrict_range(ca_laststate.argbeg, arrlen(compwords) - 1);
|
||||
}
|
||||
if (arg->opt) {
|
||||
buf = (char *) zhalloc((arg->set ? strlen(arg->set) : 0) +
|
||||
strlen(arg->opt) + 40);
|
||||
if (arg->num > 0)
|
||||
sprintf(buf, "%soption%s-%d",
|
||||
(arg->set ? arg->set : ""), arg->opt, arg->num);
|
||||
else
|
||||
sprintf(buf, "%soption%s-rest",
|
||||
(arg->set ? arg->set : ""), arg->opt);
|
||||
} else if (arg->num > 0) {
|
||||
sprintf(nbuf, "argument-%d", arg->num);
|
||||
buf = (arg->set ? dyncat(arg->set, nbuf) : dupstring(nbuf));
|
||||
} else
|
||||
buf = (arg->set ? dyncat(arg->set, "argument-rest") :
|
||||
dupstring("argument-rest"));
|
||||
|
||||
addlinknode(subc, buf);
|
||||
|
||||
if (single)
|
||||
break;
|
||||
|
||||
if (!opt && arg->num >= 0 && !arg->next && miss)
|
||||
arg = ca_laststate.d->rest;
|
||||
else {
|
||||
onum = arg->num;
|
||||
rest = (onum != arg->min && onum == ca_laststate.nth);
|
||||
if ((arg = arg->next)) {
|
||||
if (arg->num != onum + 1)
|
||||
miss = 1;
|
||||
} else if (rest || (oopt > 0 && !opt)) {
|
||||
arg = ca_laststate.d->rest;
|
||||
oopt = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!single && opt && lopt) {
|
||||
opt = NULL;
|
||||
arg = ca_get_arg(ca_laststate.d, ca_laststate.nth);
|
||||
|
||||
goto rec;
|
||||
}
|
||||
if (!opt && oopt > 0) {
|
||||
oopt = -1;
|
||||
arg = ca_laststate.d->rest;
|
||||
|
||||
goto rec;
|
||||
}
|
||||
set_list_array(args[0], descr);
|
||||
set_list_array(args[1], act);
|
||||
set_list_array(args[2], subc);
|
||||
}
|
||||
|
||||
static int
|
||||
bin_comparguments(char *nam, char **args, char *ops, int func)
|
||||
{
|
||||
|
@ -1340,14 +1476,14 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
|
|||
zwarnnam(nam, "invalid argument: %s", args[0], 0);
|
||||
return 1;
|
||||
}
|
||||
if (args[0][1] != 'i' && !ca_parsed) {
|
||||
if (args[0][1] != 'i' && args[0][1] != 'I' && !ca_parsed) {
|
||||
zwarnnam(nam, "no parsed state", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
switch (args[0][1]) {
|
||||
case 'i': min = 2; max = -1; break;
|
||||
case 'D': min = 2; max = 2; break;
|
||||
case 'C': min = 1; max = 1; break;
|
||||
case 'i':
|
||||
case 'I': min = 2; max = -1; break;
|
||||
case 'D': min = 3; max = 3; break;
|
||||
case 'O': min = 4; max = 4; break;
|
||||
case 'L': min = 3; max = 4; break;
|
||||
case 's': min = 1; max = 1; break;
|
||||
|
@ -1368,17 +1504,43 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
|
|||
}
|
||||
switch (args[0][1]) {
|
||||
case 'i':
|
||||
case 'I':
|
||||
if (compcurrent > 1 && compwords[0]) {
|
||||
Cadef def = get_cadef(nam, args + 1);
|
||||
Cadef def;
|
||||
int cap = ca_parsed;
|
||||
LinkList cax = ca_xor;
|
||||
|
||||
ca_parsed = 0;
|
||||
|
||||
if (!def)
|
||||
return 1;
|
||||
if (args[0][1] == 'I') {
|
||||
char **xor;
|
||||
|
||||
ca_parsed = cap;
|
||||
ca_parse_line(def);
|
||||
if (!(def = get_cadef(nam, args + 2, 1)))
|
||||
return 1;
|
||||
|
||||
ca_parsed = cap;
|
||||
ca_xor = newlinklist();
|
||||
if ((xor = getaparam(args[1]))) {
|
||||
if (arrcontains(xor, args[2], 0) ||
|
||||
ca_inactive(def, xor, compcurrent)) {
|
||||
ca_xor = cax;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (ca_parse_line(def, 1)) {
|
||||
ca_xor = cax;
|
||||
return 1;
|
||||
}
|
||||
set_list_array(args[1], ca_xor);
|
||||
} else {
|
||||
if (!(def = get_cadef(nam, args + 1, 0)))
|
||||
return 1;
|
||||
|
||||
ca_parsed = cap;
|
||||
ca_xor = NULL;
|
||||
ca_parse_line(def, 0);
|
||||
}
|
||||
ca_xor = cax;
|
||||
ca_parsed = 1;
|
||||
|
||||
return 0;
|
||||
|
@ -1390,35 +1552,11 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
|
|||
Caarg arg = ca_laststate.def;
|
||||
|
||||
if (arg) {
|
||||
setsparam(args[1], ztrdup(arg->descr));
|
||||
setsparam(args[2], ztrdup(arg->action));
|
||||
|
||||
if (ca_laststate.doff > 0)
|
||||
ignore_prefix(ca_laststate.doff);
|
||||
if (arg->type == CAA_RARGS)
|
||||
restrict_range(ca_laststate.optbeg,
|
||||
arrlen(compwords) - 1);
|
||||
else if (arg->type == CAA_RREST)
|
||||
restrict_range(ca_laststate.argbeg,
|
||||
arrlen(compwords) - 1);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case 'C':
|
||||
{
|
||||
Caarg arg = ca_laststate.def;
|
||||
|
||||
if (arg) {
|
||||
char buf[20];
|
||||
ca_set_data(arg->opt, arg, args + 1, (ca_laststate.doff > 0));
|
||||
|
||||
if (arg->num > 0)
|
||||
sprintf(buf, "%d", arg->num);
|
||||
else
|
||||
strcpy(buf, "rest");
|
||||
|
||||
setsparam(args[1], (arg->opt ? tricat(arg->opt, "-", buf) :
|
||||
tricat("argument-", buf, "")));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -1474,11 +1612,7 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
|
|||
Caopt opt = ca_get_opt(ca_laststate.d, args[1], 1, NULL);
|
||||
|
||||
if (opt && opt->args) {
|
||||
setsparam(args[2], ztrdup(opt->args->descr));
|
||||
setsparam(args[3], ztrdup(opt->args->action));
|
||||
|
||||
if (args[4])
|
||||
setsparam(args[4], tricat(opt->name, "-1", ""));
|
||||
ca_set_data(opt->name, opt->args, args + 2, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1528,7 +1662,8 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
|
|||
for (o = ca_laststate.d->opts, a = ca_laststate.oargs; o;
|
||||
o = o->next, a++) {
|
||||
if (*a) {
|
||||
*p++ = ztrdup(o->name);
|
||||
*p++ = (o->set ? tricat(o->set, o->name, "") :
|
||||
ztrdup(o->name));
|
||||
*p++ = ca_colonlist(*a);
|
||||
}
|
||||
}
|
||||
|
@ -1740,7 +1875,7 @@ parse_cvdef(char *nam, char **args)
|
|||
vtype = CVV_OPT;
|
||||
} else
|
||||
vtype = CVV_ARG;
|
||||
arg = parse_caarg(0, 0, 0, name, &p);
|
||||
arg = parse_caarg(0, 0, 0, 0, name, &p, NULL);
|
||||
} else {
|
||||
vtype = CVV_NOARG;
|
||||
arg = NULL;
|
||||
|
@ -2243,6 +2378,7 @@ settags(int level, char **tags)
|
|||
|
||||
/* Check if an array contains a string. */
|
||||
|
||||
/**/
|
||||
static int
|
||||
arrcontains(char **a, char *s, int colon)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue