summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAxel Beckert <abe@deuxchevaux.org>2017-09-12 23:22:34 +0200
committerAxel Beckert <abe@deuxchevaux.org>2017-09-12 23:22:34 +0200
commit4aaf06e6678dcead65d7226bd6bde3cffeb2cb2e (patch)
tree5c8e2ac2c9a85e2e6568aed7120372e6efa074ac
parentf33de64abf57611e59df72da230f3d0d6760c4c5 (diff)
parent6ff4787e830f8edb3a7e32490a88a131e4b62f7f (diff)
downloadzsh-4aaf06e6678dcead65d7226bd6bde3cffeb2cb2e.tar.gz
zsh-4aaf06e6678dcead65d7226bd6bde3cffeb2cb2e.zip
Merge tag 'zsh-5.4.2' into debian
Release 5.4.2
-rw-r--r--ChangeLog96
-rw-r--r--Completion/BSD/Command/_rcctl2
-rw-r--r--Completion/Base/Utility/_regex_words21
-rw-r--r--Completion/Linux/Command/_modutils2
-rw-r--r--Completion/Solaris/Command/_snoop111
-rw-r--r--Completion/Unix/Command/_arp110
-rw-r--r--Completion/Unix/Command/_chsh97
-rw-r--r--Completion/Unix/Command/_dhclient86
-rw-r--r--Completion/Unix/Command/_git4
-rw-r--r--Completion/Unix/Command/_gpg12
-rw-r--r--Completion/Unix/Command/_ip15
-rw-r--r--Completion/Unix/Command/_mpc111
-rw-r--r--Completion/Unix/Command/_ngrep33
-rw-r--r--Completion/Unix/Command/_route254
-rw-r--r--Completion/Unix/Command/_tcpdump177
-rw-r--r--Completion/Unix/Command/_vmstat90
-rw-r--r--Completion/Unix/Command/_w47
-rw-r--r--Completion/Unix/Command/_who64
-rw-r--r--Completion/Unix/Type/_bpf_filters215
-rw-r--r--Config/version.mk4
-rw-r--r--Doc/Zsh/options.yo24
-rw-r--r--Etc/FAQ.yo2
-rw-r--r--Functions/VCS_Info/VCS_INFO_patch2subject11
-rw-r--r--README23
-rw-r--r--Src/Modules/pcre.c68
-rw-r--r--Src/exec.c59
-rw-r--r--Src/init.c4
-rw-r--r--Src/lex.c6
-rw-r--r--Src/loop.c9
-rw-r--r--Src/module.c15
-rw-r--r--Src/parse.c48
-rw-r--r--Src/signals.c2
-rw-r--r--Src/zsh.h23
-rw-r--r--Test/A01grammar.ztst37
-rw-r--r--Test/E01options.ztst30
-rw-r--r--Test/V07pcre.ztst33
36 files changed, 1579 insertions, 366 deletions
diff --git a/ChangeLog b/ChangeLog
index 9649617fe..906666871 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,101 @@
+2017-08-27 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * unposted: Config/version.mk: 5.4.2.
+
+2017-08-25 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * 41599: README, Etc/FAQ.yo: updates for 5.4.2.
+
+2017-08-25 William da Silva <w.vigolodasilva@gmail.com>
+
+ * 41602 (tweaked): Completion/Unix/Command/_gpg: Improve wording
+ in gpg completion.
+
+2017-08-25 Oliver Kiddle <opk@zsh.org>
+
+ * 41601: Completion/Unix/Command/_arp,
+ Completion/Unix/Command/_route: handle system differences
+ in arp completion and add function for route
+
+ * 41600: Completion/Unix/Command/_mpc: fix quoting of
+ songs for completion and avoid sending errors to stderr
+
+ * 41598: Completion/Unix/Command/_w,
+ Completion/Unix/Command/_who: new who and w completions
+
+2017-08-24 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * 41590 (modified as per 41595): README, Doc/Zsh/options.yo,
+ Src/exec.c, Src/init.c, Src/loop.c, Src/signals.c, Src/zsh.h,
+ Test/E01options.ztst: make ERR_RETURN work within each function
+ context, leaving ERR_EXIT global.
+
+2017-08-22 Daniel Shahaf <d.s@daniel.shahaf.name>
+
+ * 41565: Functions/VCS_Info/VCS_INFO_patch2subject: vcs_info
+ patch2subject: Support `svn log -r N --diff` output.
+
+2017-08-18 Oliver Kiddle <opk@zsh.org>
+
+ * 41568: Completion/Unix/Command/_vmstat: handle vmstat options
+ on NetBSD and Solaris and add some exclusion lists
+
+ * 41563: Completion/Base/Utility/_regex_words: fix completion
+ description alignment with _regex_words
+
+ * 41562: Completion/BSD/Command/_rcctl: correct completed word
+
+ * 41561: Completion/Unix/Command/_dhclient: handle Free/OpenBSD
+ and bring options up-to-date for the ISC implementation
+
+ * 41560: Completion/Unix/Command/_chsh: cleanup chsh completion
+ for different platforms
+
+2017-08-16 Oliver Kiddle <opk@zsh.org>
+
+ * Tomasz Pala: users/22834: Completion/Linux/Command/_modutils:
+ fix irritating bug in file glob for Linux kernel modules
+
+ * Tomasz Pala: users/22834: Completion/Unix/Command/_ip:
+ allow completion after -c and a few other new options
+
+ * 41556: Completion/Solaris/Command/_snoop
+ Completion/Unix/Command/_ngrep, Completion/Unix/Command/_tcpdump,
+ Completion/Unix/Type/_bpf_filters: complete BPF (libpcap) filters
+
+ * 41552: Completion/Unix/Command/_git: complete only branches
+ after git worktree add --detach because the --detach is
+ superfluous for other commits
+
+2017-08-15 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * posted twice but has not shown up: Src/exec.c, Src/zsh.h:
+ record file desriptors that remain open to save ones in the
+ range 0 to 9 in fdtable and close them on forking.
+
+2017-08-14 Peter Stephenson <p.stephenson@samsung.com>
+
+ * Phil: 4152: Src/Modules/pcre.c, Test/V07pcre.ztst: fix big
+ with uninititialised memory in logic for extracting matched
+ parentheses.
+
+2017-08-11 Peter Stephenson <p.stephenson@samsung.com>
+
+ * Phil: 41527 (tweak to use heap memory): Src/module.c,
+ Test/V07pcre.ztst: fix [[ ... ]]] conditions passed to modules.
+
+2017-08-09 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * unposted: README: 5.4,1 typo fixed.
+
+ * 41504: Src/lex.c, Src/parse.c, Test/A01grammar.ztst: make
+ empty strings work in case patterns with no opening
+ parenthesis.
+
2017-08-08 Peter Stephenson <p.w.stephenson@ntlworld.com>
+ * unposted: Config/version.mk: update to 5.4.1-dev-0.
+
* unposted: Config/verson.mk, README, Etc/FAQ.yo: update to version
5.4.1.
diff --git a/Completion/BSD/Command/_rcctl b/Completion/BSD/Command/_rcctl
index 0a030f486..62cb8f634 100644
--- a/Completion/BSD/Command/_rcctl
+++ b/Completion/BSD/Command/_rcctl
@@ -23,7 +23,7 @@ case $service in
':variable:compadd -a variables'
;;
ls)
- _arguments ':display a list of services and daemons matching:(all faulty off on started stopped)'
+ _arguments ':display a list of services and daemons matching:(all failed off on started stopped)'
;;
order)
_arguments \
diff --git a/Completion/Base/Utility/_regex_words b/Completion/Base/Utility/_regex_words
index 62c2491bb..90b4a9735 100644
--- a/Completion/Base/Utility/_regex_words
+++ b/Completion/Base/Utility/_regex_words
@@ -1,6 +1,6 @@
#autoload
-local opt OPTARG
+local opt OPTARG matches end
local term=$'\0'
while getopts "t:" opt; do
@@ -31,19 +31,22 @@ fi
integer i
local -a wds
+if [[ $term = $'\0' ]]; then
+ matches=":${tag}:${desc}:(( "
+ end="))"
+else
+ matches=":${tag}:${desc}:_values -s ${(q)term} ${(q)desc}"
+fi
+
for (( i = 1; i <= $#; i++ )); do
wds=(${(s.:.)argv[i]})
reply+=(/${wds[1]//\**/"[^$term]#"}"$term"/)
if [[ $term = $'\0' ]]; then
- reply+=(":${tag}:${desc}:(( ${wds[1]//\*}:${wds[2]//(#m)[: \(\)]/\\$MATCH} ))")
+ matches+="${wds[1]//\*}${wds[2]:+\\:${wds[2]//(#m)[: \(\)]/\\$MATCH}} "
else
- reply+=(":${tag}:${desc}:_values -s ${(q)term} ${(q)desc} \
-${(q)${${wds[1]//\*}//(#m)[:\[\]]/\\$MATCH}}\\[${(q)${wds[2]//(#m)[:\[\]]/\\$MATCH}}\\]")
+ matches+=" ${(q)${${wds[1]//\*}//(#m)[:\[\]]/\\$MATCH}}\\[${(q)${wds[2]//(#m)[:\[\]]/\\$MATCH}}\\]"
fi
eval "reply+=($wds[3])"
- if (( $i == $# )); then
- reply+=(\))
- else
- reply+=(\|)
- fi
+ reply+=(\|)
done
+reply+=( /'[]'/ "${matches}${end}" \) )
diff --git a/Completion/Linux/Command/_modutils b/Completion/Linux/Command/_modutils
index 7de97f60e..5aa4c9cc7 100644
--- a/Completion/Linux/Command/_modutils
+++ b/Completion/Linux/Command/_modutils
@@ -107,7 +107,7 @@ _modutils() {
if _cache_invalid modules-$kver || ! _retrieve_cache modules-$kver;
then
# 2011-01-02 gi1242: Do we need .o files? Or is .ko enough?
- modules=( $modules_dir/$kver/(*~(source|build))/**/*.(o|ko|ko.gz|.ko.xz)(.:t:r:r) )
+ modules=( $modules_dir/$kver/(*~(source|build))/**/*.(o|ko|ko.gz|ko.xz)(.:t:r:r) )
_store_cache modules-$kver modules
fi
diff --git a/Completion/Solaris/Command/_snoop b/Completion/Solaris/Command/_snoop
index f734c2fb1..77798a730 100644
--- a/Completion/Solaris/Command/_snoop
+++ b/Completion/Solaris/Command/_snoop
@@ -1,87 +1,32 @@
#compdef snoop
-_snoop() {
- local -a t_opt exp
+local -a args
-t_opt=(
- "r"\:"time relative to first packet"
- "a"\:"absolute time"
- "d"\:"delta time - time since receiving previous packet"
+[[ $OSTYPE = solaris2.<11-> ]] && args=(
+ '-I+[capture packets from specified interface]:interface:_net_interfaces'
)
-
-exp=(
- "ether"
- "ethertype"
- "host"
- "from"
- "to"
- "ip"
- "ip6"
- "arp"
- "rarp"
- "pppoe"
- "pppoed"
- "pppoes"
- "vlan"
- "vlan-id"
- "broadcast"
- "multicast"
- "bootp"
- "dhcp"
- "dhcp6"
- "apple"
- "decnet"
- "greater"
- "less"
- "udp"
- "tcp"
- "icmp"
- "icmp6"
- "ah"
- "esp"
- "net"
- "port"
- "rpc"
- "zone"
- "ldap"
- "gateway"
- "nofrag"
- ">"
- ">="
- "<"
- "<="
- "="
- "!="
- "and"
- "or"
- "not"
- "slp"
- "sctp"
- "ospf"
-)
-
- _arguments \
- '-a[generate audio signal on receiving packets]' \
- '-c[quit after capturing maxcount packets]:maxcount' \
- '-d[capture packets from specified device]:device:_net_interfaces' \
- '-i[display packets previously captured to file]:file:_files' \
- '-n[use file as IP address-to-name mapping table]:file:_files' \
- '-o[save captured packets to file]:file:_files' \
- '-p[display one or more packets from captured file]:first packet number [ , last packet number]' \
- '-q[do not display packet counter when capturing to file]' \
- '-r[do not resolve IP addresses to names]' \
- '-s[truncate each packet after snaplen bytes]:snaplen' \
- '-t[time-stamp presentation]:time-stamp mode:(($t_opt))' \
- '-C[list code generated from filter expression]' \
- '-D[display number of packets dropped on the summary line]' \
- '-N[create IP-address-to-name mapping table file (used with -i)]' \
- '-I[capture packets from specified interface]:interface:_net_interfaces' \
- '-P[capture packets in non-promiscuous mode]' \
- '-S[display size of the entire link layer frame in bytes]' \
- '-V[verbose summary mode]' \
- '-v[verbose mode]' \
- '-x[display offset and length of packet in HEX and ASCII]:offset [ , length]' \
- '*:expression:(($exp))' \
-}
-
-_snoop "$@"
+_arguments -s -S -A "-*" \
+ '-a[generate audio signal on receiving packets]' \
+ '-c+[quit after capturing specified number of packets]:number of packets' \
+ '-d+[capture packets from specified device]:device:_net_interfaces' \
+ '-i+[display packets previously captured to file]:file:_files' \
+ '-n+[use file as IP address-to-name mapping table]:file:_files' \
+ '-o+[save captured packets to file]:file:_files' \
+ '-p+[display one or more packets from captured file]:first packet number [ , last packet number]' \
+ "-q[don't display packet counter when capturing to file]" \
+ "-r[don't resolve IP addresses to names]" \
+ '-s[truncate each packet after specified number of bytes]:length (bytes)' \
+ '-t+[specify time-stamp presentation]:time-stamp mode:((
+ r\:relative\ to\ first\ packet
+ a\:absolute
+ d\:delta\ -\ since\ previous\ packet
+ ))' \
+ '-C[list code generated from filter expression]' \
+ '-D[display number of packets dropped on the summary line]' \
+ '-N[create IP-address-to-name mapping table file (used with -i)]' \
+ '-P[capture packets in non-promiscuous mode]' \
+ '-S[display size of the entire link layer frame in bytes]' \
+ '-V[verbose summary mode]' \
+ '-v[verbose mode]' \
+ '-x+[display offset and length of packet in HEX and ASCII]:offset [ , length]' \
+ '*::expression:= _bpf_filters'
diff --git a/Completion/Unix/Command/_arp b/Completion/Unix/Command/_arp
index f340e979e..80e829022 100644
--- a/Completion/Unix/Command/_arp
+++ b/Completion/Unix/Command/_arp
@@ -1,23 +1,103 @@
#compdef arp
local state line expl curcontext="$curcontext" ret=1
-local -a cmds
+typeset -A opt_args
+local -a cmds args
-cmds=(-a --display -d --delete -s --set -f --file)
+flags=( temp pub )
+cmds=(
+ '(2 3)-a[show entries for all hosts]'
+ '(2 -d)-d[delete entry from table]'
+ '(-n -v)-s[create an arp entry]'
+ '(2 3 -n -v)-f[read multiple entries from file]'
+)
+args=( '-n[show numeric addresses]' )
+vopt='-v[be verbose]'
-_arguments -C \
- "($cmds 1 -D --use-device)"{-a,--display}'[show entries for all or specified hosts]:host:->hostintable' \
- "($cmds 1 -n --numeric -D --use-device -H --hw-type)"{-d,--delete}'[delete entry from table]:host:->hostintable' \
- "($cmds 1 -n --numeric)"{-s,--set}'[create an ARP entry]:host:_hosts:ethernet address::*:option:(temp trail pub)' \
- "($cmds 1 -n --numeric)"{-f,--file}'[read multiple entries from file]:file:_files' \
- '(-i --device)'{-i,--device}'[select an interface]:::_net_interfaces:' \
- '(-D --use-device -a --display -d --delete)'{-D,--use-device}"[use the interface ifa's hardware address]" \
- '(-H --hw-type -d --delete)'{-H,--hw-type}'[class of entries to check for]:class:(ether arcnet pronet ax25 netrom)' \
- '(-n --numeric -d --delete -s --set -f --file)'{-n,--numeric}'[shows numerical addresses]' \
- '(-v --verbose)'{-v,--verbose}'[be verbose]' \
- '(-a)1:host:->hostintable' && ret=0
+if (( ${+words[(r)-d]} )) && [[ $OSTYPE = (*bsd|dragonfly|darwin)* ]]; then
+ args+=( '(1 *)-a[delete all entries]' )
+fi
-[[ "$state" = hostintable ]] &&
- _wanted hosts expl 'host' compadd ${${${(f)"$(${words[1]} -an)"}##[ ?(]#}%%[ )]*} && ret=0
+case $OSTYPE in
+ linux*)
+ cmds=(
+ '(2 * -D --use-device)-a[show entries in BSD style output format]'
+ '!(2 * -D --use-device)-e'
+ '(2 -n --numeric -D --use-device -H --hw-type)'{-d,--delete}'[delete entry from table]'
+ '(-n --numeric)'{-s,--set}'[create an ARP entry]'
+ '(2 * -D --use-device)'{-f,--file}'[read multiple entries from file]'
+ )
+ args=(
+ '(-i --device)'{-i+,--device=}'[select an interface]:interface:_net_interfaces'
+ '(-D --use-device -a --display -d --delete)'{-D,--use-device}"[use specified interface's hardware address]"
+ '(-H --hw-type -d --delete)'{-H+,--hw-type=}'[specify class of entries to check for]:class:(ash ether arcnet pronet ax25 netrom rose dlci fddi hippi irda x25 infiniband eui64)'
+ '(* -n --numeric -d --delete -s --set -f --file)'{-n,--numeric}'[show numeric addresses]'
+ '(-v --verbose)'{-v,--verbose}'[be verbose]'
+ )
+ flags+=( netmask )
+ ;;
+ darwin*|freebsd*|dragonfly*)
+ cmds+=( '(-n -v -i)-S[create an arp entry, replacing any existing entry]' )
+ ;|
+ darwin*|freebsd*)
+ args+=( '(-s -Q -f)-i+[select an interface]:interface:_net_interfaces' )
+ ;|
+ darwin*)
+ args+=(
+ '(-d -s -S -f)-l[show link-layer reachability information]'
+ '(-d -s -S -f)-x[show extended link-layer reachability information]'
+ )
+ flags+=( reject blackhole only ifscope )
+ ;;
+ dragonfly*)
+ flags+=( only )
+ args+=( '-c:cpu' )
+ ;;
+ netbsd*)
+ flags+=( proxy )
+ args+=( $vopt )
+ ;;
+ freebsd*)
+ args+=( $vopt )
+ flags+=( blackhole reject )
+ ;;
+ openbsd*)
+ args+=(
+ '(-a -d -W)-F[overwrite existing entries]'
+ '(-W)-V+[select the routing domain]:routing domain'
+ )
+ cmds+=(
+ '(- 1)-W[send the wake on LAN frame]'
+ )
+ flags+=( permanent )
+ ;;
+ solaris*) flags+=( trail permanent) ;;
+esac
+
+_arguments -C -s -S $args \
+ '1: :->hostintable' \
+ '2:ethernet address' \
+ "*: :->flags" \
+ + '(cmds)' $cmds && ret=0
+
+if [[ "$state" = hostintable ]]; then
+ if [[ -n $opt_args[(i)-(D|-use-device)] ]]; then
+ _wanted interfaces expl interface _net_interfaces && ret=0
+ elif [[ -n $opt_args[(i)-(f|-file)] ]]; then
+ _files && ret=0
+ elif [[ -n $opt_args[(i)-(s|S|-set)] ]]; then
+ _hosts && ret=0
+ else
+ _wanted hosts expl 'host' compadd ${${${(f)"$(${words[1]} -an)"}##[ ?(]#}%%[ )]*} && ret=0
+ fi
+elif [[ "$state" = flags ]]; then
+ if [[ $words[CURRENT-1] = netmask ]]; then
+ _message -e netmasks netmask
+ elif (( $+opt_args[-W] )) || [[ $words[CURRENT-1] = ifscope ]]; then
+ _wanted interfaces expl interface _net_interfaces && ret=0
+ else
+ _wanted flags expl flag compadd -F line $flags && ret=0
+ fi
+fi
return ret
diff --git a/Completion/Unix/Command/_chsh b/Completion/Unix/Command/_chsh
index 97552e3ac..006aa82a1 100644
--- a/Completion/Unix/Command/_chsh
+++ b/Completion/Unix/Command/_chsh
@@ -1,40 +1,67 @@
#compdef chsh chpass
+
+local variant help=h
+local -a args shells
+
case $OSTYPE in
-(darwin*|*bsd*)
- _arguments : \
- '-s[Specify user login shell]:shell:(${(Z+Cn+)"$(</etc/shells)"})' \
- "-l[Specify location of user]:node:" \
- "-u[Specify authentication name]:auth user:" \
- "1:user name:_users"
+ darwin*|*bsd*)
+ args=( '(-a)-s[specify new login shell]:shell:($shells)' )
+ ;|
+ (free|net|open)bsd*)
+ args+=( '(-s 1)-a[specify user database entry]:passwd entry' )
+ ;|
+ darwin*)
+ args+=(
+ '-l[specify location of user]:location'
+ '-u[specify authentication name]:auth user'
+ )
;;
-(linux-gnu)
- if { =chsh -v } >&/dev/null
- then
- local -a opts shells
- shells=( $(=chsh -l) )
- _arguments : \
- "(-)-s[Specify your login shell]:shell:($shells)" \
- "(-)--shell[Specify your login shell]:shell:($shells)" \
- "(-)-l[Print shells in /etc/shells]" \
- "(-)--list-shells[Print shells in /etc/shells]" \
- "(-)-u[Print a usage message and exit]" \
- "(-)--help[Print a usage message and exit]" \
- "(-)-v[Print version information and exit]" \
- "(-)--version[Print version information and exit]" \
- "1:user name:_users"
- return
- fi
- # else fall through
- ;&
-(*)
- local s=''
- # Use $s to cause all options to be treated as mutually exclusive
- [[ $words[CURRENT-1] = -* ]] && s="(-)$words[CURRENT-1]"
- # This fiddling with $s is a hack to cause "_arguments : --" to use
- # the /etc/shells listing for -s or --shell even when the description
- # of that option has been pulled from the GNU --help output.
- [[ $words[CURRENT-1] = (-s|--shell) ]] &&
- s="$s"'[ ]:shell:(${(Z+Cn+)"$(</etc/shells)"})'
- _arguments : $s "1:user name:_users" --
+ (free|net)bsd*)
+ args+=(
+ '(-y)-l[update only the local password file]'
+ '(-l)-y[force YP database entry to be changed]'
+ )
+ ;|
+ freebsd*)
+ args+=(
+ '-p[specify encrypted password field]:password hash'
+ '-e[change account expire time]:expiry time'
+ '-d[specify NIS domain]:domain'
+ '-h[specify NIS server to query]:NIS server:_hosts'
+ '-o[force use of RPC-based updates]'
+ )
+ ;;
+ (linux-gnu)
+ _pick_variant -r variant util-linux=util-linux suse=pwdutils debian -v
+ args=( -S : '(-)'{-s+,--shell=}'[specify new login shell]:shell:($shells)' )
+ case $variant in
+ suse|util-linux)
+ shells=( $(_call_program shells $words[1] -l) )
+ args+=(
+ '(-)'{-l,--list-shells}'[print shells in /etc/shells]'
+ '(-)'{-v,--version}'[display version information]'
+ )
+ help=u
+ ;|
+ util-linux|debian)
+ args+=( '(-)-'{$help,-help}'[display help information]' )
+ ;|
+ suse)
+ args+=(
+ '(-)'{-u,--usage}'[display short usage message]'
+ '(-)--help[display help information]'
+ '(-D --binddn)'{-D+,--binddn=}'[specify LDAP disingushed name to bind]:binddn'
+ '(-P --path)'{-P+,--path=}'[specify path to search for passwd and shadow files]:path:_directories'
+ '(-q --quiet)'{-q,--quiet}"[don't be verbose]"
+ '--service=[use specified name service]:service:(files nis nisplus ldap)'
+ )
+ ;;
+ debian)
+ args+=( '(-R --root)'{-R+,--root=}'[specify directory to chroot into]:directory:_directories' )
+ ;;
+ esac
;;
esac
+
+(( $#shells )) || shells=( ${(Z+Cn+)"$(</etc/shells)"} )
+_arguments $args '1:user name:_users'
diff --git a/Completion/Unix/Command/_dhclient b/Completion/Unix/Command/_dhclient
index dafe299d9..10cb551e0 100644
--- a/Completion/Unix/Command/_dhclient
+++ b/Completion/Unix/Command/_dhclient
@@ -2,27 +2,69 @@
local args
-if _pick_variant three=V3 two --help; then
- args=(
- '-q[quiet]'
- '-1[only try once to get a lease]'
- '-r[release the current lease]'
- '-lf[lease file]:lease file:_files'
- '-pf[pid file]:pid file:_files'
- '-cf[config file]:config file:_files'
- '-sf[script file]:script file:_files'
- '-e[env vars to pass to child processes]:env var key value pairs:'
- '-s[transmit to specific target instead of broadcast]:server:_hosts'
- '-g[force giaddr field]:relay:_hosts'
- '-n[do not configure any interfaces]'
- '-nw[daemonize immediately rather than wait for IP acquisition]'
- '-w[do not exit if there are no interfaces found to configure]'
- )
-else
- args=( '-e[exit if configuration failed after a certain time]' )
-fi
+case $OSTYPE in
+ (open|free)bsd*)
+ args+=(
+ '-c+[specify configuration file]:file:_files'
+ '-l+[specify leases file]:file:_files'
+ '-u[reject leases with unknown options]'
+ )
+ ;|
+ freebsd*)
+ args+=(
+ '(-d)-b[immediately move to the background]'
+ '-p+[specify PID file]:file:_files'
+ )
+ ;;
+ openbsd*)
+ args+=(
+ '-i+[ignore values provided by leases for specified options]:options'
+ '-L+[specify file to write option data too]:file:_files'
+ )
+ ;;
+ *) # ISC implementation, used on Linux and NetBSD
+ args=(
+ '!(-6 -S -T -P -D -N)-4'
+ '(-4 -s)-6[use the DHCPv6 protocol]'
+ '-1[only try once to get a lease]'
+ '(-d)-nw[daemonize immediately rather than wait for IP acquisition]'
+ "-m[don't require responding ethernet address of dhcp server to match expectation]"
+ '-v[verbose log messages]'
+ "-w[don't exit if there are no interfaces found to configure]"
+ "-n[don't configure any interfaces]"
+ '-e[specify env vars to pass to child processes]:env var key value pairs'
+ '(-x)-r[release the current lease]'
+ '(-r)-x[stop the running DHCP client without releaseing current lease]'
+ '-p[specify port to transmit to / listen on]:port:_ports'
+ '(-6)-s[transmit to specific target instead of broadcast]:server:_hosts'
+ '-g[force giaddr field]:relay:_hosts'
+ '-i[use a DUID with DHCPv4 clients]'
+ '-I[use the standard DDNS scheme]'
+ '--version[display version number]'
+ '(-4)-S[use Information-request to get only stateless configuration]'
+ '(-4)*-T[ask for IPv6 temporary addresses]'
+ '(-4)-P[enable IPv6 prefix delegation]'
+ '-D[specify DUID selection method]:DUID:((LL\:link-layer LLT\:link-layer\ plus\ timestamp))'
+ '(-4)-N[restore normal address query for IPv6]'
+ '-lf[lease file]:lease file:_files'
+ '(--no-pid)-pf[pid file]:pid file:_files'
+ '(-pf)--no-pid[disable writing pid files]'
+ '-cf[config file]:config file:_files'
+ '-sf[script file]:script file:_files'
+ '-4o6[DHCPv4 over DHCPv6 protocol]:port'
+ "-nc[don't drop capabilities]"
+ '-B[set the BOOTP broadcast flag in request packets]'
+ '-C[specify dhcp-client-identifier option]:option'
+ '(-F)-H[specify host-name option]:host name:_hosts'
+ '(-H)-F[specify fully qualified hostname option]:host name:_hosts'
+ '-V[specify vendor-class-identifier option]:option'
+ '--request-options[specify list of options the client is to request from the server]:options'
+ '--timeout[specify time after which dhclient will decide that no DHCP servers can be contacted]:timeout'
+ )
+ ;;
+esac
-_arguments $args \
- '-p[port to transmit to / listen on]:_ports' \
- '-d[force to run in foreground]' \
+_arguments -s -S -A "-*" $args \
+ '-q[quiet]' \
+ '(-b -nw)-d[remain as a foreground process]' \
':interface:_net_interfaces'
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 518e6d198..26554de05 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -2027,9 +2027,9 @@ _git-worktree() {
case $line[1] in
(add)
if (( $words[(I)--detach] )); then
- args=( ':commit:__git_commits' )
- else
args=( ':branch:__git_branch_names' )
+ else
+ args=( ':commit:__git_commits' )
fi
_arguments \
'(-f --force)'{-f,--force}'[checkout branch even if already checked out in another worktree]' \
diff --git a/Completion/Unix/Command/_gpg b/Completion/Unix/Command/_gpg
index fe6084f20..d7a8ece4c 100644
--- a/Completion/Unix/Command/_gpg
+++ b/Completion/Unix/Command/_gpg
@@ -26,7 +26,7 @@ fi
[[ $service = gpgv ]] || args+=(
'(-e --encrypt)'{-e,--encrypt}'[encrypt data. this option may be combined with --sign]'
{-d,--decrypt}'[decrypt file or stdin]'
- '(-c --symmetric)'{-c,--symmetric}'[encrypt with symmetric cypher only]'
+ '(-c --symmetric)'{-c,--symmetric}'[encrypt with symmetric cipher only]'
'(-s --sign)'{-s,--sign}'[make a signature]'
'*'{-r+,--recipient}'[specify user to encrypt for]:recipient:->public-keys'
'(-u --local-user)'{-u+,--local-user}'[use name as the user ID to sign]:user attachment:_users'
@@ -52,7 +52,7 @@ fi
'--fingerprint[list all keys with their fingerprints]:key attachment:->public-keys'
'--list-packets[list only the sequence of packets]'
'--gen-key[generate a new pair key]'
- '--edit-key[a menu for edit yours keys]:key attachment:->public-keys'
+ '--edit-key[interactively edit a key]:key attachment:->public-keys'
'--sign-key[sign a key]:key attachment:->public-keys'
'--lsign-key[sign a key but mark as non-exportable]:key attachment:->public-keys'
'--delete-keys[remove key from public keyring]:key attachment:->public-keys'
@@ -60,12 +60,12 @@ fi
'--delete-secret-and-public-keys:key attachment:->secret-keys'
'--gen-revoke[generate a revocation certificate]'
'--desig-revoke[generate a designated revocation certificate]'
- '--export[export all key from all keyrings]'
+ '--export[export all keys from all keyrings]'
'--send-keys[send keys to a keyserver]:key attachment:->public-keyids'
'--export-secret-keys:key attachment:->secret-keys'
'--export-secret-subkeys:key attachment:->secret-keys'
- '--import[import a gpg key from a file]:_files attachment:_files'
- '--fast-import[import a file without build trustdb]:_files attachment:_files'
+ '--import[import a gpg key from a file]:attachment (file):_files'
+ '--fast-import[import a file without adding to trustdb]:attachment (file):_files'
'--fetch-keys[fetch key at URIs]:uri:'
'--recv-keys[receive a list of keys from a keyserver]:key attachment:->public-keyids'
'--refresh-keys[update all keys from a keyserver]'
@@ -82,7 +82,7 @@ fi
'--gen-random:count' '--gen-prime'
'--warranty[print warranty info]'
'(-a --armor)'{-a,--armor}'[create ASCII armored output]'
- '--default-key[specify default user-id for signatures]:key:->secret-keys'
+ '--default-key[specify default user ID for signatures]:key:->secret-keys'
'--default-recipient[specify default recipient]:recipient:->public-keys'
'--default-recipient-self[use default key as default recipient]'
'--no-default-recipient[reset default recipient]'
diff --git a/Completion/Unix/Command/_ip b/Completion/Unix/Command/_ip
index 6e1cc3b78..74101c646 100644
--- a/Completion/Unix/Command/_ip
+++ b/Completion/Unix/Command/_ip
@@ -530,15 +530,30 @@ args=(
/$'[^\0]#\0'/
)
+# TODO:
+# -b*atch <FILENAME>
+# -force (for batch mode)
+# -l*oops <COUNT>
+# -n*etns <NETNS>
+# -rc, -rcvbuf<SIZE>
_regex_words options "ip options" \
'-h*uman:output statistics with human readable values' \
'-i*ec:print human readable rates in IEC units (ie. 1K = 1024)' \
'-s*tatistics:output statistics' \
+ '-d*etails:output more detailed information' \
+ '-c*olor:color output' \
+ '-a*ll:executes specified command over all objects' \
'-f*amily:select protocol family:$subcmd_family' \
'-4:IPv4' \
'-6:IPv6' \
+ '-B:family bridge' \
+ '-D:family DECnet' \
+ '-I:family IPX' \
+ '-M:family MPLS' \
'-0:link protocol, no networking' \
'-o*neline:output one record per line' \
+ '-t*imestamp:display current time when using monitor option' \
+ '-ts*hort:display current time in shorter format when using monitor option' \
'-r*esolve:use system resolver for DNS names'
args+=("$reply[@]" "#")
diff --git a/Completion/Unix/Command/_mpc b/Completion/Unix/Command/_mpc
index e0c6888b0..fee5e06f4 100644
--- a/Completion/Unix/Command/_mpc
+++ b/Completion/Unix/Command/_mpc
@@ -1,4 +1,4 @@
-#compdef mpc
+#compdef mpc -value-,MPD_HOST,-default
local OUT foo MPD_MUSIC_DIR MPC_PLAYLIST_MATCHER MPC_FORMAT_STRING
@@ -26,13 +26,17 @@ _mpc_command() {
mpc_cmds=(
add:"append a song to the end of the current playlist"
+ cdprev:"compact disk player-like previous command"
+ channels:"list the channels that other clients have subscribed to"
clear:"clear the current playlist"
+ clearerror:"clear the current error"
crop:"remove all songs except for the currently playing song"
current:"show the currently playing song"
crossfade:"set and display crossfade settings"
del:"remove a song from the current playlist"
- disable:"disable a output"
- enable:"enable a output"
+ disable:"disable an output"
+ enable:"enable an output"
+ toggleoutput:"toggle an output"
idle:"wait until an event occurs"
idleloop:"loop waiting for events"
insert:"insert a song after the currently playing song in the playlist"
@@ -40,6 +44,8 @@ _mpc_command() {
load:"load file as a playlist"
ls:"list the contents of specified directory"
lsplaylists:"list currently available playlists"
+ mixrampdb:"set and display mixrampdb settings"
+ mixramdelay:"set and display mixrampdelay settings"
move:"move song in playlist"
next:"play the next song in the current playlist"
outputs:"show the current outputs"
@@ -51,10 +57,14 @@ _mpc_command() {
repeat:"toggle repeat mode, or specify state"
single:"toggle single mode, or specify state"
consume:"toggle consume mode, or specify state"
+ replaygain:"set or display the replay gain mode"
rm:"remove a playlist"
save:"save a playlist to file"
search:"search for a song"
+ searchadd:"search songs and add them to the current playlist"
+ searchplay:"search and play songs from the current playlist"
find:"search for a song, exact match"
+ findadd:"find songs and add them to the current playlist"
list:"list all tags of given type"
seek:"seek to the position specified in percent"
shuffle:"shuffle the current playlist"
@@ -65,13 +75,18 @@ _mpc_command() {
version:"report version of MPD"
volume:"set volume"
status:"display MPD status"
+ sendmessage:"send a message to the specified channel"
+ waitmessage:"wait for at least one message on the specified channel"
+ subscribe:"subscribe to the specified channel and continuously receive messages"
+ sticker:"sticker management"
)
if (( CURRENT == 1 )); then
- _describe -t commands "mpc command" mpc_cmds
+ _describe -t commands "mpc command" mpc_cmds || \
+ _wanted commands expl "mpc command" compadd loadtab tab lstab
else
local cmd=$words[1]
- local curcontext="${curcontext%:*}:mpc-${cmd}" ret=1
+ local curcontext="${curcontext%:*:*}:mpc-${cmd}:" ret=1
if ! _call_function ret _mpc_$cmd; then
_default && ret=0
fi
@@ -100,13 +115,13 @@ _mpc_helper_songnumbers() {
NM="$compstate[nmatches]"
fi
- out=("${(@f)$(_call_program song-numbers mpc $foo playlist)}")
+ out=("${(@f)$(_call_program song-numbers $mpccmd $foo playlist)}")
out=("${(@M)out[@]:#${~MATCH}}")
sn=("${(@)${(@M)out}//(#b)(#s)(\#|[ >]#)([0-9]#)*/$match[2]}")
list=("${(@Mr:COLUMNS-1:)out}")
- _wanted -V 'song numbers' expl 'song number' \
+ _wanted -V song-numbers expl 'song number' \
compadd "$@" -ld list "$all[@]" -a sn && ret=0
if [[ -n "$all" ]]; then
@@ -131,8 +146,8 @@ _mpc_helper_songnumbers() {
(( $+functions[_mpc_helper_playlists] )) ||
_mpc_helper_playlists() {
local list expl
- list=(${(f)"$(mpc lsplaylists)"})
- _wanted list expl playlist compadd -M $MPC_PLAYLIST_MATCHER $expl -a list
+ list=(${(f)"$(_call_program playlists $mpccmd lsplaylists)"})
+ _wanted playlists expl playlist compadd -M $MPC_PLAYLIST_MATCHER $expl -a list
}
(( $+functions[_mpc_helper_files] )) ||
@@ -142,12 +157,13 @@ _mpc_helper_files() {
return
fi
- local -U list expl
+ local -U list expl prefix=$PREFIX
if [[ $words[CURRENT] != */* ]]; then
- list=( ${${(f)"$(mpc listall)"}%%/*})
+ list=( ${${(f)"$(_call_program files $mpccmd listall)"}%%/*})
_wanted files expl file compadd -qS/ -a list
else
- list=(${(f)"$(mpc tab $words[CURRENT])"})
+ [[ $compstate[quote] = [\'\"] ]] && prefix="$compstate[quote]$PREFIX$compstate[quote]"
+ list=(${(f)"$($mpccmd tab -- ${(Q)prefix} 2>/dev/null)"})
_wanted files expl file _multi_parts / list
fi
}
@@ -159,12 +175,13 @@ _mpc_helper_directories() {
return
fi
- local -U list expl
+ local -U list expl prefix=$PREFIX
if [[ $words[CURRENT] != */* ]]; then
- list=( ${${(M)${(f)"$(mpc listall)"}:#*/*}%%/*})
+ list=( ${${(M)${(f)"$(_call_program directories $mpccmd listall)"}:#*/*}%%/*})
_wanted directories expl directory compadd -qS/ -a list
else
- list=(${(f)"$(mpc lstab $words[CURRENT])"})
+ [[ $compstate[quote] = [\'\"] ]] && prefix="$compstate[quote]$PREFIX$compstate[quote]"
+ list=(${(f)"$($mpccmd lstab -- ${(Q)prefix} 2>/dev/null)"})
_wanted directories expl directory _multi_parts / list
fi
}
@@ -172,7 +189,7 @@ _mpc_helper_directories() {
(( $+functions[_mpc_helper_outputs] )) ||
_mpc_helper_outputs() {
local vals outline
- vals=(${${${${(M)${(f)"$(mpc outputs 2> /dev/null)"}:#Output * \(*\) is (en|dis)abled}##Output }%%\) is (en|dis)abled}/ \(/:})
+ vals=(${${${${(M)${(f)"$(_call_program outputs $mpccmd outputs)"}:#Output * \(*\) is (en|dis)abled}##Output }%%\) is (en|dis)abled}/ \(/:})
_describe -t outputs output vals
}
@@ -200,6 +217,10 @@ _mpc_disable() {
_mpc_helper_outputs
}
+_mpc_toggleoutput() {
+ _mpc_helper_outputs
+}
+
_mpc_move() {
if (( $#words <= 3 )); then
_mpc_helper_songnumbers
@@ -216,22 +237,41 @@ _mpc_ls() {
_mpc_helper_directories
}
+_mpc_lstab() {
+ _mpc_helper_directories
+}
+
_mpc_load() {
_mpc_helper_playlists
}
+_mpc_loadtab() {
+ _mpc_helper_playlists
+}
+
_mpc_save() {
_mpc_helper_playlists
}
+_mpc_tab() {
+ _mpc_helper_files
+}
+
_mpc_rm() {
_mpc_helper_playlists
}
_mpc_volume() {
- local expl
- compset -P '[-+]'
- _wanted list expl volume compadd $expl - {0..100}
+ local expl value="${${$(_call_program volume $mpccmd volume)#*:}%\%}" ret=1
+ if [[ -prefix \+ && $value -lt 100 ]]; then
+ _wanted -V volume expl volume compadd $expl - +{1..$((100-value))} && ret=0
+ elif [[ -prefix - && $value -gt 0 ]]; then
+ _wanted -V volume expl volume compadd $expl - -{1..$value} && ret=0
+ else
+ _wanted -V volume expl volume compadd $expl - {0..100} && ret=0
+ compstate[insert]=menu:$((value+1))
+ fi
+ return ret
}
_mpc_repeat() {
@@ -250,6 +290,10 @@ _mpc_consume() {
_mpc_helper_bool
}
+_mpc_current() {
+ _arguments --wait
+}
+
_mpc_search() {
local list expl
list=(album artist title track name genre date composer performer comment disc filename any)
@@ -273,7 +317,28 @@ _mpc_update() {
_mpc_helper_files
}
-_arguments \
- '--format[specify the format of song display]:format string' \
- '--no-status[prevent printing song status on completion]' \
- '*::mpc command:_mpc_command'
+if [[ $service = *MPD_HOST* ]]; then
+ _hosts
+ return
+fi
+
+local curcontext="$curcontext" state line expl ret=1
+local mpccmd="$words[1]"
+
+_arguments -C \
+ '(-q --quiet --no-status -v --verbose)'{-v,--verbose}'[give verbose output]' \
+ '(-q --quiet --no-status -v --verbose)'{-q,--quiet,--no-status}'[prevent printing song status on completion]' \
+ '(-h --host)'{-h,--host=}'[connect to specified host]:_hosts' \
+ '(-p --port)'{-p,--port=}'[connect to server port]:port' \
+ '(-f --format)'{-f,--format=}'[specify the format of song display]:format string:->formats' \
+ '(-w --wait)'{-w,--wait}'[wait for operation to finish (e.g. database update)]' \
+ '*::mpc command:_mpc_command' && ret=0
+
+if [[ $state = formats ]]; then
+ compset -P '([^%]|%[^%]#%)#'
+ _wanted metadata expl 'metadata delimiter' compadd -p % -S % \
+ artist album albumartist comment composer date disc genre performer title \
+ track time file position mtime mdate && ret=0
+fi
+
+return ret
diff --git a/Completion/Unix/Command/_ngrep b/Completion/Unix/Command/_ngrep
new file mode 100644
index 000000000..924597826
--- /dev/null
+++ b/Completion/Unix/Command/_ngrep
@@ -0,0 +1,33 @@
+#compdef ngrep
+
+_arguments -s -S \
+ '(- 1 *)-h[display help information]' \
+ '(- 1 *)-V[display version information]' \
+ "-q[be quiet (don't print packet reception hash marks)]" \
+ '-e[show empty packets]' \
+ '-i[ignore case]' \
+ '-v[invert match]' \
+ "-R[don't do privilege revocation logic]" \
+ '(-W)-x[print in alternate hexdump format]' \
+ '-X[interpret match expression as hexadecimal]' \
+ '-w[word-regex (expression must match as a word)]' \
+ "-p[don't go into promiscuous mode]" \
+ '-l[make stdout line buffered]' \
+ '-D[replay pcap_dumps with their recorded time intervals]' \
+ '-t[print timestamp every time a packet is matched]' \
+ '-T[print delta timestamp every time a packet is matched specify twice for delta from first match]' \
+ "-M[don't do multi-line match (do single-line match instead)]" \
+ '(-d -s)-I+[read packet stream from pcap format file]:file:_files' \
+ '-O+[dump matched packets in pcap format file]:file:_files' \
+ '-n+[look at only specified number of packets]:packets' \
+ '-A+[dump specified number of context packets after a match]:packets' \
+ '(-I)-s+[set the bpf caplen]:length (bytes) [65535]' \
+ '-S+[set the upper limit on size of packets matched]:size (bytes)' \
+ '(-x)-W+[set the dump format]:packet display format:(normal byline single none)' \
+ '-c+[force the column width to the specified size]:columns' \
+ '-P+[set the non-printable display char to what is specified]:character [.]' \
+ '-F+[read the bpf filter from the specified file]:file:_files' \
+ '-N[show sub protocol number]' \
+ '(-I)-d+[use specified device instead of the pcap default]:interface:_net_interfaces' \
+ '1: :_guard "^-*" pattern' \
+ '*::expression:_bpf_filters'
diff --git a/Completion/Unix/Command/_route b/Completion/Unix/Command/_route
new file mode 100644
index 000000000..f8426874c
--- /dev/null
+++ b/Completion/Unix/Command/_route
@@ -0,0 +1,254 @@
+#compdef route
+
+local curcontext="$curcontext" expect ret=1
+local -a state state_descr line args families modifiers ignore sub sequential tags
+local -A opt_args subcmds once params
+
+subcmds=(
+ add 'add a route'
+ flush 'remove all routes'
+ delete 'delete a specific route'
+ change 'change aspects of a route (such as its gateway)'
+ get 'lookup route for a destination'
+ monitor 'continuously report any changes to the routing information'
+)
+args=(
+ '-n[output addresses numerically]'
+ '(-q)-v[verbose output]'
+)
+modifiers=(
+ '-net:interpret destination as a network'
+ '-host:interpret destination as a host'
+)
+params=(
+ '-dst' target # does this definitely follow
+ '(-|)netmask' netmask
+ '(gw|-gateway)' gateway
+ metric metric
+ '(mss|window|-(send|recv)pipe)' size:bytes
+ '[i-]rtt' time:ms
+ -rttvar rttvar
+ -mtu mtu
+ '(dev|-ifscope|-ifp)' interface
+ -ifa address
+ -expire time:epoch
+ -hopcount hopcount
+ -tag tag
+ -prefixlen bits
+ '-(label|push|pop|swap)' label
+ -priority number # is it a number
+ -secattr secattr
+ '(-iw|-iwmax|-msl)' value
+ '-fib' table
+)
+
+case $OSTYPE in
+ ^linux*)
+ args+=( '(-v)-q[suppress all output]' )
+ families=( -inet -inet6 )
+ modifiers+=(
+ '-dst:distinguish a destination'
+ '-gateway:distinguish a gateway address'
+ -netmask
+ -rtt -rttvar
+ -sendpipe -recvpipe
+ -mtu -hopcount
+ -expire
+ '-lock' '-lockrest'
+ -i{,nter}face:'indicate destination is directly reachable'
+ '-static:manually added route'
+ '-nostatic:pretend route added by kernel or daemon'
+ '-reject:emit an ICMP unreachable when matched'
+ '-blackhole:silently discard packets (during updates)'
+ '-proto1:set protocol specific routing flag #1'
+ '-proto2:set protocol specific routing flag #2'
+ )
+ sequential=( target gateway netmask )
+ ;|
+ *bsd*|darwin*|dragonfly*)
+ modifiers+=(
+ -link '-ifp' '-ifa' # do these need an argument: interface or address
+ '-prefixlen:indicate mask bits'
+ )
+ ;|
+ (net|free)bsd*|darwin*|dragonfly*)
+ families+=( -xns )
+ modifiers+=( '-xresolve:emit mesg on use (for external lookup)' )
+ ;|
+ (net|open)bsd*|darwin*|dragonfly*)
+ modifiers+=(
+ '-cloning:generate a new route on use'
+ '-llinfo:validly translate proto addr to link addr'
+ )
+ ;|
+ (open|free)bsd*|darwin*|dragonfly*)
+ args+=(
+ "-d[debug-only mode: don't update routing table]"
+ '-t[test-only mode: /dev/null used instead of a socket]'
+ )
+ ;|
+ netbsd*|solaris*)
+ args+=( '-f[remove all routes first]' )
+ ;;
+ (netbsd|darwin|dragonfly)*)
+ modifiers+=( '-proxy:make entry a link level proxy' )
+ ;|
+ (netbsd|openbsd|dragonfly)*)
+ subcmds+=( show 'print out the routing table' )
+ families+=( -mpls )
+ ;|
+ (netbsd|darwin)*)
+ families+=( -atalk )
+ ;|
+ (freebsd|darwin)*)
+ families+=( -osi )
+ ;|
+ (openbsd|dragonfly)*)
+ modifiers+=( -push -pop -swap )
+ ;|
+ freebsd*)
+ subcmds+=(
+ del $subcmds[delete]
+ show $subcmds[get]
+ )
+ args+=(
+ '(-6)-4[specify IPv4 address family]'
+ '(-4)-6[specify IPv6 address family]'
+ )
+ families+=( -4 -6 )
+ modifiers+=( '-fib:specify a routing table' )
+ ;;
+ netbsd*)
+ subcmds+=( flushall 'remove all routes including the default gateway' )
+ args+=(
+ '-S[print a space when a flag is missing to align flags]'
+ '-s[suppress all output from get except for the gateway]'
+ )
+ modifiers+=(
+ '-tag'
+ '-noreject:clear reject flag'
+ '-noblackhole:clear blackhole flag'
+ )
+ ;;
+ openbsd*)
+ subcmds+=( exec 'execute a command with alternate routing table' )
+ args+=(
+ '-T+[select specified alternate routing table]:table id'
+ )
+ modifiers+=(
+ -sa
+ '-label'
+ '-priority'
+ '-mpath:multiple gateways for a destination exist'
+ -mplslabel -in -out
+ )
+ ;;
+ solaris*)
+ subcmds+=( show 'display list of routes applied at system startup' )
+ args+=(
+ '-p[make changes to the route tables persistent across system restarts]'
+ '-R+[specify alternate root directory where changes are applied]:directory:_directories'
+ )
+ modifiers+=(
+ "-private:don't advertise this route"
+ '-multirt:create the specified redundant route'
+ '-setsrc:assign the default source address'
+ '-secattr:security attributes'
+ )
+ ;;
+ darwin*)
+ modifiers+=( -ifscope )
+ ;|
+ dragonfly*)
+ modifiers+=( -iw -iwmax -msl )
+ ;|
+ linux*)
+ args+=(
+ '(H -n)--numeric[output addresses numerically]'
+ '(H)*'{-e,--extend}'[display other/more information]'
+ '!(H -C --cache)'{-F,--fib}
+ '(H -C --cache)'{-C,--cache}'[display routing cache instead of FIB]'
+ + '(family)'
+ '-A+[use specified address family]:address family:(inet inet6 ax25 netrom ipx ddp x25)'
+ -4 -6 --inet --inet6 --ax25 --netrom --ipx --ddp --x25
+ + '(H)'
+ '(1 *)'{-h,--help}'[display help information]'
+ '(1 *)'{-V,--version}'[display version information]'
+ )
+ subcmds[del]=$subcmds[delete]
+ unset 'subcmds[monitor]' 'subcmds[get]' 'subcmds[change]'
+ modifiers+=(
+ netmask gw metric mss window irtt reject mod dyn reinstate
+ 'dev:force route to be associated with the specified device'
+ )
+ sequential=( target interface )
+ ;;
+esac
+
+print -v sub -f '%s\\:%s' ${(kvq)subcmds}
+_arguments -C -s -S "1:command:(($sub))" '*::args:->args' $args && ret=0
+
+[[ -n $opt_args[(i)-[46]] ]] && families=()
+
+if [[ -n $state ]]; then
+ if [[ $line[1] = exec ]]; then
+ shift words
+ (( CURRENT-- ))
+ _normal
+ elif [[ $line[1] = (flush|monitor) ]]; then
+ sequential=()
+ fi
+
+ for ((i=2;i<CURRENT;i++)); do
+ if [[ -n $expect ]]; then
+ sequential=( ${sequential:#$expect} )
+ expect=''
+ continue
+ fi
+
+ expect=${params[(K)$words[i]]}
+ if [[ -n $expect ]]; then
+ ignore+=( ${(Q)words[i]} )
+ else
+ if [[ -n ${(M)${families%%:*}:#${(q)words[i]}} ]]; then
+ families=()
+ elif [[ -n ${(M)${modifiers%%:*}:#${(q)words[i]}} ]]; then
+ ignore+=( ${(q)words[i]} )
+ elif [[ $words[1] != -lock ]]; then
+ shift sequential
+ fi
+ fi
+ done
+
+ [[ -z $expect ]] && tags=( modifiers families )
+ _tags values $tags
+ while _tags; do
+ if _requested values; then
+ case ${expect:-$sequential[1]} in
+ target)
+ if [[ -z $expect ]]; then
+ _wanted -x targets expl target compadd default && ret=0
+ else
+ _message -e targets target
+ fi
+ ;;
+ interface) _net_interfaces && ret=0 ;;
+ size:bytes) _guard "[0-9]#" 'size (bytes)' ;; # _guard usage pointless
+ time:ms) _guard "[0-9]#" 'time (ms)' ;;
+ time:microseconds) _guard "[0-9]#" 'time (microseconds)' ;;
+ time:epoch) _guard "[0-9]#" 'expiration time (seconds since epoch)' ;;
+ rttvar) _guard "[0-9]#" 'time variance (microseconds)' ;;
+ mtu) _guard "[0-9]#" 'max MTU (bytes)' ;;
+ hopcount) _guard "[0-9]#" 'hop count' ;;
+ ssthresh) _message -e threshold 'ss threshold' ;;
+ bits) _guard "[0-9]#" 'bits' ;;
+ *) _guard "[^-]#" "${expect:-$sequential[1]}" ;;
+ esac
+ fi
+ _requested modifiers && _describe -t modifiers modifier modifiers -F ignore && ret=0
+ _requested families expl 'address family' compadd -a families && ret=0
+ (( ret )) || break
+ done
+fi
+
+return ret
diff --git a/Completion/Unix/Command/_tcpdump b/Completion/Unix/Command/_tcpdump
index 2c1d82226..4b9950fa5 100644
--- a/Completion/Unix/Command/_tcpdump
+++ b/Completion/Unix/Command/_tcpdump
@@ -1,17 +1,25 @@
#compdef tcpdump
-typeset -A opt_args
+local args ret=1
+local root
+(( EUID )) && root='!'
-_interfaces() {
- local disp expl sep
- _description interfaces expl 'network interface'
- _net_interfaces "$expl[@]"
- if zstyle -t ":completion:${curcontext}:interfaces" verbose; then
- zstyle -s ":completion:${curcontext}:interfaces" list-separator sep || sep=--
- disp=( "any $sep capture on all interfaces" )
- compadd "$expl[@]" -ld disp any
+_tcpdump_interfaces() {
+ local disp expl sep interfaces
+ [[ $OSTYPE != openbsd* ]] &&
+ interfaces=( ${${${${(f)"$(_call_program interfaces tcpdump -D)"}#<->.}//[()]/}/ /:} )
+ if (( $#interfaces )); then
+ _describe -t interfaces 'network interface' interfaces
else
- compadd "$expl[@]" any
+ _description interfaces expl 'network interface'
+ _net_interfaces "$expl[@]"
+ if zstyle -t ":completion:${curcontext}:interfaces" verbose; then
+ zstyle -s ":completion:${curcontext}:interfaces" list-separator sep || sep=--
+ disp=( "any $sep capture on all interfaces" )
+ compadd "$expl[@]" -ld disp any
+ else
+ compadd "$expl[@]" any
+ fi
fi
}
@@ -40,43 +48,50 @@ _esp_secrets () {
}
_packet_types () {
+ local -a types
types=(
- 'cnfp[Cisco NetFlow protocol]'
- 'rpc[Remote Procedure Call]'
- 'rtp[Real-Time Applications protocol]'
- 'rtcp[Real-Time Applications control protocol]'
- 'vat[Visual Audio Tool]'
- 'wb[distributed White Board]'
+ 'cnfp:Cisco NetFlow protocol'
+ 'rpc:Remote Procedure Call'
+ 'rtp:Real-Time Applications protocol'
+ 'rtcp:Real-Time Applications control protocol'
+ 'vat:Visual Audio Tool'
+ 'wb:distributed White Board'
)
if [[ $OSTYPE = openbsd* ]]; then
types+=(
- 'sack[RFC 2018 TCP Selective Acknowledgements Options]'
- 'vrrp[Virtual Router Redundancy Protocol]'
- 'tcp[Transmission Control Protocol]'
+ 'sack:RFC 2018 TCP Selective Acknowledgements Options'
+ 'vrrp:Virtual Router Redundancy Protocol'
+ 'tcp:Transmission Control Protocol'
)
else
types+=(
- 'aodv[Ad-hoc On-demand Distance Vector protocol]'
- 'carp[Common Address Redundancy Protocol]'
- 'radius[RADIUS]'
- 'snmp[Simple Network Management Protocol]'
- 'tftp[Trivial File Transfer Protocol]'
- 'vxlan[Virtual eXtensible Local Area Network]'
- 'zmtpl[ZeroMQ Message Transport Protocol]'
+ 'aodv:Ad-hoc On-demand Distance Vector protocol'
+ 'carp:Common Address Redundancy Protocol'
+ 'radius:RADIUS'
+ 'snmp:Simple Network Management Protocol'
+ 'tftp:Trivial File Transfer Protocol'
+ 'vxlan:Virtual eXtensible Local Area Network'
+ 'zmtpl:ZeroMQ Message Transport Protocol'
)
fi
- _values 'Packets type' $types
+ _describe -t packet-types 'packet type' types
+}
+
+_time_stamp_types () {
+ local vals
+ vals=( ${${${(ps:\n :)"$(_call_program time-stamp-types tcpdump -J ${(kv)opt_args[(i)-i|--interface]} 2>&1)"}[2,-1]:#*cannot be set*}/ /:} )
+ _describe -t time-stamp-types "time stamp type" vals
}
_data_link_types () {
- if (( $+opt_args[-i] )); then
- vals=( ${${${(s: :)"$(_call_program data-link-types tcpdump -L -i $opt_args[-i] 2>&1)"}[2,-1]}/ /:} )
- _describe -t data-link-types "data link types ($opt_args[-i])" vals && ret=0
- else
- _values "Data link types (general)" \
- "EN10MB" \
- "LINUX_SLL"
- fi
+ local vals expl
+ if (( $+opt_args[(i)-i|--interface] )); then
+ vals=( ${${${(s: :)"$(_call_program data-link-types tcpdump -L ${(kv)opt_args[(i)-i|--interface]} 2>&1)"}[2,-1]}/ /:} )
+ _describe -t data-link-types "data link type (${(v)opt_args[(i)-i|--interface]})" vals
+ else
+ _wanted data-link-types expl "data link type (general)" \
+ compadd EN10MB LINUX_SLL
+ fi
}
_bpf_filter () {
@@ -84,79 +99,95 @@ _bpf_filter () {
args=(
'-A[print each packet in ASCII]'
- '-c[exit after receiving specified number of packets]:number of packets'
+ '-c+[exit after receiving specified number of packets]:number of packets'
'(-ddd)-d[dump the compiled packet-matching code in a human readable form]'
'(-ddd)-dd[dump packet-matching code as a C program fragment]'
'(-d -dd)-ddd[dump packet-matching code as decimal numbers (preceded with a count)]'
"-E[decrypting IPsec ESP packets]:spi@ipaddr::algo\:secret:_esp_secrets"
'-e[print the link-level header on each dump line]'
- '-F[input file for the filter expression]:filter expression file:_files'
+ '-F+[specify input file for the filter expression]:filter expression file:_files'
"-f[print 'foreign' IPv4 addresses numerically]"
'-l[make stdout line buffered]'
"-N[don't print domain name qualification of host names]"
- "-n[don't convert addresses to names]"
+ "(-nn)-n[don't convert addresses to names]"
"-O[don't run the packet-matching code optimizer]"
- "-p[don't put the interface into promiscuous mode]"
+ '(-p --no-promiscuous-mode)'{-p,--no-promiscuous-mode}"[don't put the interface into promiscuous mode]"
'-q[quick (quiet?) output]'
- '-r[read packets from file]:input file:_files'
- '-S[print absolute TCP sequence numbers]'
- '-s[specify number of bytes of data to snarf from each packet]:number of bytes to snap'
- '-T[interpret captured packets as specified type]:packet type:_packet_types'
+ '-r+[read packets from file]:input file:_files'
+ '(-S --absolute-tcp-sequence-numbers)'{-S,--absolute-tcp-sequence-numbers}'[print absolute TCP sequence numbers]'
+ '-T+[interpret captured packets as specified type]:packet type:_packet_types'
"(-tt -ttt -tttt -ttttt)-t[don't print a timestamp on each dump line]"
'(-t -ttt -tttt -ttttt)-tt[print an unformatted timestamp on each dump line]'
'(-vv -vvv)-v[slightly more verbose output]'
'(-v -vvv)-vv[more verbose output]'
- '-w[write the raw packets to file]:output file:_files'
+ '-w+[write the raw packets to file]:output file:_files'
'-X[print each packet (minus its link level header) in hex and ASCII]'
'-x[print each packet (minus its link level header) in hex]'
- '-y[set the data link type to use while capturing packets]:data link type:_data_link_types'
- '*:BPF filter:_bpf_filter'
+ '(-y --linktype)'{-y+,--linktype=}'[set the data link type to use while capturing packets]: :_data_link_types'
)
if [[ $OSTYPE = openbsd* ]]; then
- args+=(
+ args=(
+ '-i+[specify interface]:interface:_tcpdump_interfaces'
+ - listd
+ '-L[list data link types for the interface]'
+ - capture
+ ${(R)args:#(|\*)(|\(*\))--*} # removes any long-options
'(-n)-a[attempt to convert network and broadcast addresses to names]'
'-D[select packet flowing in specified direction]:direction:(in out)'
'-I[print the interface on each dump line]'
'-o[print a guess of the possible operating system(s)]'
+ '-s+[specify amount of data to snarf from each packet]:length (bytes) [116]'
'(-t -tt -tttt -ttttt)-ttt[print day and month in timestamp]'
'(-t -tt -ttt -ttttt)-tttt[print timestamp difference between packets]'
'(-t -tt -ttt -tttt)-ttttt[print timestamp difference since the first packet]'
)
else
- args+=(
- '-B[specify the capture buffer size in KiB]:capture buffer size'
+ args=(
+ '(-i --interface -D --list-interfaces)'{-i+,--interface=}'[specify interface]:interface:_tcpdump_interfaces'
+ - listt
+ '(-J --list-time-stamp-types)'{-J,--list-time-stamp-types}'[list supported time stamp types]'
+ - listd
+ '(-L --list-data-link-types)'{-L,--list-data-link-types}'[list data link types for the interface]'
+ - capture
+ $args
+ '(-B --buffer-size)'{-B+,--buffer-size=}'[set the operating system capture buffer size]:size (kiB)'
'-b[print the AS number in BGP packets in ASDOT notation]'
- '-C[specify output file size in MB (10e6 bytes)]:output file size'
- '(-* *)'-D'[print the list of the network interfaces available on the system]'
- '-G[specify the interval to rotate the dump file in seconds]:dump file rotate seconds'
+ '-C+[specify output file size]:output file size (MB)'
+ '(-)'{-D,--list-interfaces}'[print the list of the network interfaces available on the system]'
+ '-G+[rotate dump file specified with -w at specified interval]:interval (seconds)'
'-H[attempt to detect 802.11s draft mesh headers]'
- '(-* *)-h[print version strings and a usage message]'
+ '(- *)'{-h,--help}'[display help information]'
+ '(- *)--version[display version information]'
+ '(-I --monitor-mode)'{-I,--monitor-mode}'[put the Wi-Fi interface in monitor mode]'
+ '--immediate-mode[deliver packets to tcpdump as soon as they arrive without buffering]'
'-I[put the interface in monitor mode]'
- '(-* *)-J[list the supported timestamp types]'
- '-j[set the timestamp type]:timestamp type'
- "-K[don't attempt to verify checksums]"
- '*-m[load SMI MIB module definitions]:SMI MIB module definitions:_files'
- '-M[shared secret for validating the digests in TCP segments with the TCP-MD5 option]:secret'
- '-R[assume ESP/AH packets to be based on old specification (RFC1825 to RFC1829)]'
- '(-t -tt -tttt)-ttt[print a delta (in micro-seconds) between current and previous line on each dump line]'
- '(-t -tt -ttt)-tttt[print a timestamp in default format proceeded by date on each dump line]'
- '(-t -tt -ttt -tttt)-ttttt[print a delta (micro-second resolution) since the first line on each dump line]'
- '-U[make output packet-buffered when saving to file (-w)]'
+ '(-j --time-stamp-type)'{-j+,--time-stamp-type=}'[set the time stamp type for the capture]: :_time_stamp_types'
+ '--time-stamp-precision=[set the time stamp precision for the capture]:precision [micro]:(micro nano)'
+ '(-K --dont-verify-checksums)'{-K,--dont-verify-checksums}"[don't verify IP, TCP, or UDP checksums]"
+ '*-m+[load SMI MIB module definitions]:SMI MIB module definition:_files'
+ "(-n)-nn[don't convert protocol and port numbers to names]"
+ '-M+[specify shared secret for validating the digests in TCP segments with the TCP-MD5 option]:secret'
+ '(-# --number)'{-\#,--number}'[print an optional packet number at the beginning of the line]'
+ '(-O --no-optimize)'{-O,--no-optimize}"[don't run the packet-matching code optimizer]"
+ '(-s --snapshot-length)'{-s+,--snapshot-length=}'[specify amount of data to snarf from each packet]:length (bytes) [65535]'
+ '(-t -tt -tttt -ttttt)-ttt[print a delta (in micro-seconds) on each line since previous line]'
+ '(-t -tt -ttt -ttttt)-tttt[print a timestamp in default format preceded by date on each dump line]'
+ '(-t -tt -ttt -tttt)-ttttt[print a delta (in micro-seconds) on each line since first line]'
+ '(-U --packet-buffered)'{-U,--packet-buffered}'[make output packet-buffered when saving to file (-w)]'
'-u[print undecoded NFS handles]'
- '-V[Read a list of filenames from file]:file:_files'
+ '-V+[read a list of filenames from specified file]:file:_files'
'(-v -vv)-vvv[most verbose output]'
- '-W[limit the number of created files (-C)]:number of files'
+ '-W+[limit the number of created files (-C)]:number of files'
'(-X)-XX[print each packet, including its link level header, in hex and ASCII]'
'(-x)-xx[print each packet, including its link level header, in hex]'
- '-Z[drops privileges (if root) and changes user ID (along with primary group)]:user:_users'
- '-z[command to run after file rotation]:command:_command_names'
+ "${root}(-Z --relinquish-privileges)"{-Z+,--relinquish-privileges=}'[drop privileges and run as specified user]:user:_users'
+ '-z+[specify command to run on files (with -C or -G)]:command:_command_names -e'
)
fi
+[[ $OSTYPE = freebsd* ]] && args+=(
+ '-R[assume ESP/AH packets to be based on old specification (RFC1825 to RFC1829)]'
+)
-_arguments : \
- '-i[interface]:interface:_interfaces' \
- - optL \
- '-L[list the known data link types for the interface]' \
- - default \
- $args
+_arguments -s $args \
+ '*::BPF filter:= _bpf_filters'
diff --git a/Completion/Unix/Command/_vmstat b/Completion/Unix/Command/_vmstat
index 7082cbbd5..7d3008592 100644
--- a/Completion/Unix/Command/_vmstat
+++ b/Completion/Unix/Command/_vmstat
@@ -4,28 +4,31 @@ local -a specs
case $OSTYPE in
*linux*)
specs=(
- '(-a --active)'{-a,--active}'[active/inactive memory]'
- '(-f --forks)'{-f,--forks}'[number of forks since boot]'
- '(-m --slabs)'{-m,--slabs}'[slabinfo]'
- '(-n --one-header)'{-n,--one-header}'[do not redisplay header]'
- '(-s --stats)'{-s,--stats}'[event counter statistics]'
- '(-d --disk)'{-d,--disk}'[disk statistics]'
- '(-D --disk-sum)'{-D,--disk-sum}'[summarize disk statistics]'
- '(-p --partition)'{-p,--partition}'[partition specific statistics]:partition:_files'
- '(-S --unit)'{-S+,--unit}'[define display unit]:unit prefix:(( k\:1000 K\:1024 m\:1000000 M\:1048576 ))'
'(-w --wide)'{-w,--wide}'[wide output]'
'(-t --timestamp)'{-t,--timestamp}'[show timestamp]'
- '1:delay' '2:count'
+ '(-n --one-header)'{-n,--one-header}'[do not redisplay header]'
+ '(-S --unit)'{-S+,--unit=}'[specify unit for displayed sizes]:unit prefix [K]:((k\:1000 K\:1024 m\:1000000 M\:1048576))'
+ '1: :_guard "[0-9]#" "interval (seconds)"' '2:count'
+ + '(action)' \
+ '(- :)'{-h,--help}'[display help information]'
+ '(- :)'{-V,--version}'[display version information]'
+ {-a,--active}'[show active/inactive memory]'
+ '(- :)'{-f,--forks}'[show number of forks since boot]'
+ '(-S --unit -t --timestamp -w --wide)'{-m,--slabs}'[show slabinfo]'
+ '(-w --wide -n --one-header -t --timestamp :)'{-s,--stats}'[show event counter statistics]'
+ {-d,--disk}'[show disk statistics]'
+ {-p+,--partition=}'[show partition specific statistics]:partition:_files -W /dev -g "*(-%)"'
+ '(- :)'{-D,--disk-sum}'[summarize disk statistics]'
)
;;
- freebsd*|openbsd*)
+ *bsd*)
specs=(
- '-c[number of times to refresh the display]:count'
+ '-c+[specify number of times to refresh the display]:count'
'-f[report on the number fork syscalls since boot and pages of virtual memory for each]'
'-i[report the number of interrupts taken by devices since boot]'
- '-M[source file to extract values associated with the name list from]:core:_files'
- '-N[source file to extract the name list from]:system:_files'
- '-w[specify delay between each display]:delay (seconds)'
+ '-M+[specify core file to extract values associated with the name list from]:core:_files'
+ '-N+[specify file to extract the name list from]:system:_files'
+ '-w+[specify delay between each display]:delay (seconds)'
'*:disk:_files'
)
;|
@@ -35,23 +38,60 @@ case $OSTYPE in
'-h[human readable memory columns output]'
'-H[scriptable memory columns output]'
'-m[report on the usage of kernel dynamic memory allocated using malloc(9) by type]'
- '-n[change the maximum number of disks to display]:number of disks to display'
+ '-n+[change the maximum number of disks to display]:number of disks to display'
'-o[list virtual memory objects]'
'-P[report per-cpu system/user/idle cpu statistics]'
- '-p[specify which types of devices to display]: :->devices'
- '-s[display the contents of the SUM structure]:sum'
+ '-p+[specify which types of devices to display]: :->devices'
+ '-s[display the contents of the SUM structure]'
'-z[report on memory used by the kernel zone allocator, uma(9), by zone]'
)
- ;;
- openbsd*)
+ ;|
+ (net|open)bsd*)
specs+=(
'-m[report usage of kernel dynamic memory listed first by size of allocation then type of usage]'
- '-s[display the contents of the UVMEXP structure]:uvmexp'
- '-t[report on the number of page in and page reclaims since boot]'
+ '-s[display the contents of the UVMEXP structure]'
'-v[print more verbose information]'
+ )
+ ;|
+ openbsd*)
+ specs+=(
+ '-t[report on the number of page in and page reclaims since boot]'
'-z[include statistics about all interrupts]'
)
;;
+ netbsd*)
+ specs+=(
+ '-C[report on kernel memory caches]'
+ '-e[report the values of system event counters]'
+ '-H[report all hash table statistics]'
+ '-h+[dump specified hash table]:hash table:->hashes'
+ '-L[list all hash tables]'
+ '-l[list UVM histories maintained by the kernel]'
+ '-t[display contents of the vmtotal structure]'
+ '-U[dump all UVM histories]'
+ '-u+[dump specified UVM history]:uvm'
+ '-W[print more information about kernel memory pools]'
+ )
+ ;;
+ freebsd*|solaris*)
+ specs+=(
+ '::disk:_files -W /dev -g "*(-%b)"'
+ ': :_guard "[0-9]#" "interval (seconds)"' ':count'
+ )
+ ;|
+ solaris2.<11->)
+ specs+=( '(-i -s)-T+[specify time format]:time format:((u\:seconds\ since\ epoch d\:standard\ date\ format))' )
+ ;&
+ solaris*)
+ specs+=(
+ '-q[suppress messages related to state changes]'
+ + '(actions)' \
+ '(-T)-i[report the number of interrupts taken by devices since boot]'
+ '-p[report paging activity]'
+ '(-T)-s[display the total number of system events since boot]'
+ '-S[report on swapping rather than paging activity]'
+ )
+ ;;
esac
if (( $#specs )); then
@@ -73,7 +113,11 @@ if (( $#specs )); then
'SCSI[Small Computer System Interface devices]'
'other[any other device interface]' 'pass[passthrough devices]'
)
- _values -C -s , 'device type' "$types[@]" && ret=0
+ _values -s , 'device type' "$types[@]" && ret=0
+ elif [[ $state == hashes ]]; then
+ local -a tables
+ tables=( ${${${(f)"$(_call_program hashes $words[1] -L)"}[2,-1]#?}/ ##/:} )
+ _describe -t hashes 'hash table' tables && ret=0
fi
return ret
fi
diff --git a/Completion/Unix/Command/_w b/Completion/Unix/Command/_w
new file mode 100644
index 000000000..8fb4154c7
--- /dev/null
+++ b/Completion/Unix/Command/_w
@@ -0,0 +1,47 @@
+#compdef w
+
+local args
+
+case $OSTYPE in
+ linux*)
+ args=(
+ '(H -f --from)'{-f,--from}'[toggle display of remote hostname]'
+ '(H -h)--no-header[suppress the heading]'
+ '(H -i --ip-addr)'{-i,--ip-addr}'[display IP address instead of hostname]'
+ '(H -o --old-style -s --short)'{-o,--old-style}'[old style output format]'
+ '(H -s --short -o --old-style)'{-s,--short}'[use short output format]'
+ '(H -u --no-current)'{-u,--no-current}'[ignore the username while figuring out the current process and cpu times]'
+ + H
+ '(-)--help[display help information]'
+ '(-)'{-V,--version}'[display version information]'
+ )
+ ;;
+ *bsd*|darwin*|dragonfly*)
+ args+=( '-i[sort output by idle time]' )
+ ;|
+ openbsd*)
+ args+=( '-a[translate network addresses into names]' )
+ ;|
+ (free|net)bsd*|dragonfly*)
+ args+=( '-n[show network addresses as numbers]' )
+ ;|
+ *bsd*|dragonfly*)
+ args+=(
+ '-M+[extract values from specified core]:core file:_files'
+ '-N+[extract name list from specified system]:system file:_files'
+ )
+ ;|
+ freebsd*|dragonfly*)
+ args+=( '-d[dump process list on a per controlling tty basis]' )
+ ;|
+ solaris*)
+ args+=( '!(-s -w -l)'{-l,-w}
+ '-s[short output form]'
+ '(-)-u[produce only the heading line]'
+ )
+ ;|
+esac
+
+_arguments -S -s \
+ '(--no-header)-h[suppress the heading]' \
+ '*:user:_users' $args
diff --git a/Completion/Unix/Command/_who b/Completion/Unix/Command/_who
new file mode 100644
index 000000000..1f901af18
--- /dev/null
+++ b/Completion/Unix/Command/_who
@@ -0,0 +1,64 @@
+#compdef who gwho
+
+local args variant
+
+_pick_variant -r variant gnu=GNU $OSTYPE --version
+
+case $variant in
+ gnu)
+ args=(
+ '(Q -a --all -b --boot -d --dead -l --login -p --process -q --count -r --runlevel -t --time -T -w --mesg --message --writable -u --users)'{-a,--all}'[same as -b -d --login -p -r -t -T -u]'
+ '(Q -b --boot)'{-b,--boot}'[print time of last system boot]'
+ '(Q -d --dead -a --all)'{-d,--dead}'[print dead processes]'
+ '(Q -H --heading)'{-H,--heading}'[print line of column headings]'
+ '(Q -l --login)'{-l,--login}'[print system login processes]'
+ '(Q)--lookup[canonicalize hostnames via DNS]'
+ '(Q)-m[print information about current terminal]'
+ '(Q -p --process)'{-p,--process}'[print active processes spawned by init]'
+ '(Q -r --runlevel)'{-r,--runlevel}'[print current runlevel]'
+ '(Q -t --time)'{-t,--time}'[print last system clock change]'
+ '(Q -T -w --mesg --message --writable)'{-T,-w,--mesg,--message,--writable}"[show user's message acceptance status as +, - or ?]"
+ '(Q -u --users)'{-u,--users}'[show idle time]'
+ '!(Q -a)-s' '!(Q -a)--short'
+ + Q
+ '(-)'{-q,--count}'[print only login names and number of users logged on]'
+ '(-)--help[display help information]'
+ '(-)--version[display version information]'
+ )
+ ;;
+ darwin*|dragonfly*|netbsd*|solaris*)
+ args=(
+ '(Q -a)-d[print dead processes]'
+ '(Q -a)-l[print system login processes]'
+ '(Q -a)-p[print active processes spawned by init]'
+ '(Q -a)-r[print current runlevel]'
+ '(Q -a)-t[print last system clock change]'
+ )
+ ;|
+ dragonfly*|netbsd*)
+ args+=( '(Q)-v[show process exit status, session id etc]' )
+ ;|
+ (net|free)bsd*|darwin*|dragonfly*|solaris*)
+ args+=(
+ '(Q -b -d -p -r -T -u)-a[print all entries]'
+ '(Q -a)-b[print time of last system boot]'
+ '!(Q -a)-s'
+ )
+ ;|
+ *)
+ args+=(
+ '(Q)-H[print line of column headings]'
+ '(Q)-m[print information about current terminal]'
+ "(Q -a)-T[show user's message acceptance status as +, - or ?]"
+ '(Q -a)-u[show idle time]'
+ + Q '(-a -b -d -H -l -m -p -r -s -t -T -v)-q[print only login names and number of users logged on]'
+ )
+ ;|
+ solaris*)
+ args+=(
+ '(-a -b -d -H -l -m -p -r -s -t -T)-n+[specify number of users to list per line]:number'
+ )
+ ;;
+esac
+
+_arguments -s -S ':file:_files' $args
diff --git a/Completion/Unix/Type/_bpf_filters b/Completion/Unix/Type/_bpf_filters
new file mode 100644
index 000000000..c62481e09
--- /dev/null
+++ b/Completion/Unix/Type/_bpf_filters
@@ -0,0 +1,215 @@
+# spaces are valid instead of word ends, perhaps better to just do compset -q
+
+local -a networks fields dirs protos relop
+local -A subtypes flags
+local values dir wlantype skip repeat=1 packet proto=0
+local suf=']'
+
+local WORD=$'[^ \0]##[ \0]##'
+
+networks=(
+ /$'[^/ \0]#'/
+ \(
+ /$'[ \0]'/ ': _message -e networks network'
+ /$'mask[ \0]'/ ':masks:mask:(mask)'
+ /$WORD/ ':netmasks:netmask:'
+ \|
+ /// /$WORD/ ': _message -e masks "netmask length (bits)"'
+ \)
+)
+subtypes=(
+ mgt 'assoc-req assoc-resp reassoc-req reassoc-resp probe-req probe-resp beacon atim disassoc auth deauth'
+ ctl 'ps-poll rts cts ack cf-end cf-end-ack'
+ data 'data data-cf-ack data-cf-poll data-cf-ack-poll null cf-ack cf-poll cf-ack-poll qos-data qos-data-cf-ack qos-data-cf-poll qos-data-cf-ack-poll qos qos-cf-poll and qos-cf-ack-poll'
+)
+flags=(
+ len len
+ tcp 'tcp-fin tcp-syn tcp-rst tcp-push tcp-ack tcp-urg'
+ icmp 'icmp-echoreply icmp-unreach icmp-sourcequench icmp-redirect icmp-echo icmp-routeradvert icmp-routersolicit icmp-timxceed icmp-paramprob icmp-tstamp icmp-tstampreply icmp-ireq icmp-ireqreply icmp-maskreq icmp-maskreply'
+)
+
+case $OSTYPE in
+ solaris*)
+ fields=( ipaddr etheraddr atalkaddr ethertype rpc nofrag inet inet6 vlan-id )
+ protos=( bootp dhcp dhcp6 apple pppoe ldap slp ospf )
+ dirs=( from to )
+ relop=( \^ % )
+ ;|
+ solaris2.<11->)
+ fields+=( zone )
+ ;|
+ (free|open)bsd*) # pf(4) specific filters
+ fields=( ifname on rnr rulenum srnr subruleset reason ruleset rset action )
+ ;|
+ ^(solaris|openbsd)*)
+ protos+=( mpls netbeui iso geneve aarp ipx llc )
+ ;|
+ ^openbsd*)
+ protos+=( ah esp sctp pppoed pppoes )
+ ;|
+ ^solaris*)
+ protos+=( fddi wlan atalk stp lat moprc mopdl )
+ relop=( '>>' '<<' )
+ ;;
+esac
+
+compquote suf
+
+# the regex is essentially:
+# ( [not]* ( expression | [protocol]? [standalone-field | direction field ]? ) and|or ) *
+# the proto variable ensures that and/or is not allowed if there is no
+# protocol or field: it is one, the other or both but not neither
+
+_regex_arguments _bpf /$'[^\0]#\0'/ \( \
+ /$'(not[ \0]#|![ \0]#|(\\\\|)\\([ \0]#)'/ ':operators:operator:(not ()' \# \
+ \(\
+ \(\
+ \(\
+ /"(0x[0-9a-f]##|[0-9]##|${(j.|.)${=flags}})"$'[ \0]#'/ -'((repeat != 2))' ":expressions:expression:compadd ${=flags[$packet]}" \
+ \|\
+ /'[a-z]##(\\|)\[[^\]]##(\\|)\]'$'[ \0]#'/ \
+ \|\
+ /'[a-z]##(\\|)\[[^:\]]##:'/ /'[]'/ ':sizes:field size (bytes):compadd -S "$suf" 1 2 4' \
+ \|\
+ /'tcp(\\|)\['/ -packet=tcp \
+ /'[]'/ ':offsets:header offset:compadd -S "$suf " tcpflags' \
+ \|\
+ /'icmp(\\|)\['/ -packet=icmp \
+ /'[]'/ ':offsets:header offset:compadd -S "$suf " icmptype icmpcode' \
+ \|\
+ /'[a-z]##(\\|)\['/ /'[]'/ ':offsets:offset:' \
+ \)\
+ \(\
+ /$'(\\\\|)([<>=!](\\\\|)[<>=]|[<>&|=+*/%^-])[ \0]#'/ -'repeat=0' ":operators:operator:(+ - = != < > <= >= & | $relop and or)" \
+ // ': _message -e expressions expression' \
+ \|\
+ // -'repeat=2' \
+ \)\
+ \) \# \
+ // -'(( repeat == 2))' \
+ // -'repeat=1' \
+ \|\
+ /$'ether[ \0]proto[ \0]'/ \
+ /$WORD/ ':protocols:protocol:(\ip \ip6 \arp \rarp \atalk \aarp \dec \net \sca \lat \mopdl \moprc \iso \stp \ipx \netbeui)' \
+ \|\
+ /$'(less|greater)[ \0]'/ ':fields:field:(less greater)' \
+ /$WORD/ ':numbers:length (bytes):' \
+ \|\
+ \(\
+ /$'(tcp|udp|icmp|ether|ip|ip6|arp|rarp|decnet|bootp|dhcp|dhcp6|apple|pppoe|pppoed|ldap|ah|esp|slp|sctp|ospf|iso|clnp|esis|isis|atalk|aarp|iso|stp|ipx|netbeui|lat|moprc|mopdl)[ \0]'/ ":protocols:protocol qualifier:(tcp udp icmp ether tr ip ip6 arp rarp decnet $protos)" \
+ \| /$'((fddi|tr|wlan)[ \0]|)'/ '-(( ++proto ))' \) \
+ \(\
+ /$'mpls[ \0]'/ \
+ /$'((0x|)[0-9a-f]##[ \0]|)'/ ': _message -e labels "label number"' \
+ \|\
+ /$'geneve[ \0]'/ \
+ /$'((0x|)[0-9a-f]##[ \0]|)'/ ': _message -e vnis "vni"' \
+ \|\
+ /$'pppoes[ \0]'/ \
+ /$'((0x|)[0-9a-f]##[ \0]|)'/ ': _message -e session-ids "session id"' \
+ \|\
+ /$'proto[ \0]'/ ':fields:field:(proto)' \
+ /$WORD/ ':protocols:protocol:(\icmp \icmp6 \igmp \igrp \pim \ah \esp \vrrp \udp \tcp)' \
+ \|\
+ /$'(broad|multi)cast[ \0]'/ ':fields:field:(broadcast multicast)' \
+ \|\
+ /$'type[ \0]'/ ':fields:field:(type)' \
+ /$WORD/ -'wlantype=${match%?}' ':wlan-types:wlan type:(mgt ctl data)' \
+ \(\
+ /$'subtype[ \0]'/ ':fields:field:(subtype)' \
+ /$WORD/ ':subtypes:subtype:compadd ${=subtypes[$wlantype]:-$subtypes}' \
+ \| \)\
+ \|\
+ /$'protochain[ \0]'/ ':fields:field:(protochain)' \
+ /$WORD/ ':protocols:protocol:' \
+ \|\
+ /$'vlan-id[ \0]'/ \
+ /$WORD/ ':vlans:vlan:' \
+ \|\
+ /$'vlan[ \0]'/ ':fields:field:(vlan)' \
+ \( /$WORD/ ': _message -e vlans vlan' \| \) \
+ \|\
+ \(\
+ /$'(ra|ta|addr[1-4]|inbound|outbound)[ \0]'/ ":directions:direction qualifier:(src dst inbound outbound ra ta addr1 addr2 addr3 addr4 $dirs)" \
+ \|\
+ /$'(src|from|dst|to)[ \0]'/ -'values=${values:-hosts};dir=$match' \
+ \(\
+ /$'(or|and)[ \0]'/ ':operators:operator:(or and)' \
+ /$'(src|dst)[ \0]'/ ':directions:direction qualifier:compadd ${${${${dir%?}:/dst/to}:/(src|from)/dst}:/to/src}' \
+ \| \)\
+ \| \)\
+ \(\
+ /$'(host|gateway)[ \0]'/ ":fields:field:(host gateway $fields)" \
+ /$WORD/ -values=hosts ':hosts:host:_hosts' \
+ \|\
+ /$'inet(6|)[ \0]'/ \
+ \( /$'host[ \0]'/ ':fields:field:(host)' \| \) \
+ /$WORD/ -values=hosts ':hosts:host:_hosts' \
+ \|\
+ /$'ethertype[ \0]'/ \
+ /$WORD/ ':numbers:number:' \
+ \|\
+ /$'(ipaddr|etheraddr|atalkaddr)[ \0]'/ \
+ /$WORD/ ':addresses:address:' \
+ \|\
+ /$'llc[ \0]'/\
+ /$'((s|u|rr|rnr|rej|ui|ua|disc|sabme|test|xid|frmr)[ \0]|)'/ ':types:type:(s u rr rnr rej ui ua disc sabme test xid frmr)' \
+ \|\
+ /$'(ifname|on)[ \0]'/ \
+ /$WORD/ ':interfaces:interface:_net_interfaces' \
+ \|\
+ /$'(rnr|rulenum|srnr|subruleset)[ \0]'/ \
+ /$WORD/ ':rules:rule number:' \
+ \|\
+ /$'reason[ \0]'/ \
+ /$WORD/ ':reasons:reason:(match bad-offset fragment short normalize memory)' \
+ \|\
+ /$'(rset|ruleset)[ \0]'/ \
+ /$WORD/ ':rule-sets:rule set:' \
+ \|\
+ /$'action[ \0]'/ \
+ /$WORD/ ':actions:action:(pass block nat rdr binat scrub)' \
+ \|\
+ /$'rpc[ \0]'/ \
+ \(\
+ /$'[^, \0]##[ \0]'/ ':programs:rpc program:compadd -qS, - ${${(f)"$(</etc/rpc)"}%%[[:blank:]#]*}' \
+ \|\
+ /$'[^, \0]##,[^, \0]##,'/ /$'[^, \0]##[ \0]'/ ':procedures:procedure:' \
+ \|\
+ /$'[^, \0]##,'/ /$'[^, \0]##[ \0]'/ ':versions:version:' \
+ \)\
+ \|\
+ /$'zone[ \0]'/ \
+ /$WORD/ ':zones:zone:_zones' \
+ \|\
+ /$'port[ \0]'/ ':fields:field:(port)' \
+ /$WORD/ -values=ports ':ports:port:_ports' \
+ \|\
+ /$'portrange[ \0]'/ -values=portranges ':fields:field:(portrange)' \
+ /$'[^ \0-]##-'/ ':ports:port:_ports -S-' \
+ /$WORD/ ':ports:port:_ports' \
+ \|\
+ /$'net[ \0]'/ -values='networks' ':fields:field:(net)' \
+ $networks \
+ \|\
+ // -'[[ $values = hosts ]]' \
+ /$WORD/ ':hosts:host:_hosts' \
+ \|\
+ // -'[[ $values = ports ]]' \
+ /$WORD/ ':ports:port:_ports' \
+ \|\
+ // -'[[ $values = networks ]]' \
+ $networks \
+ \|\
+ // -'[[ $values = portranges ]]' \
+ /$'[^ \0-]##-'/ ':ports:port:_ports -S-' \
+ /$WORD/ ':ports:port:_ports' \
+ \|\
+ // -'(( ++proto ))' \
+ \)\
+ \)\
+ \)\
+ // -'(( proto < 2 ))' \
+ /$'(and|or|&&|\\|\\||\\))[ \0]'/ -proto=0 ':operators:operator:compadd and or \)' \) \#
+
+_bpf "$@"
diff --git a/Config/version.mk b/Config/version.mk
index 363618aca..9ec6475eb 100644
--- a/Config/version.mk
+++ b/Config/version.mk
@@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
-VERSION=5.4.1
-VERSION_DATE='August 8, 2017'
+VERSION=5.4.2
+VERSION_DATE='August 27, 2017'
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index 70092d681..42571fccd 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1659,6 +1659,13 @@ as it is by default, and the option tt(ERR_EXIT) is found to have been set
on exit, then the command for which the tt(DEBUG) trap is being executed is
skipped. The option is restored after the trap exits.
+Non-zero status in a command list containing tt(&&) or tt(||) is ignored
+for commands not at the end of the list. Hence
+
+example(false && true)
+
+does not trigger exit.
+
Exiting due to tt(ERR_EXIT) has certain interactions with asynchronous
jobs noted in
ifzman(the section JOBS in zmanref(zshmisc))\
@@ -1672,10 +1679,25 @@ cindex(function return, on error)
cindex(return from function, on error)
item(tt(ERR_RETURN))(
If a command has a non-zero exit status, return immediately from the
-enclosing function. The logic is identical to that for tt(ERR_EXIT),
+enclosing function. The logic is similar to that for tt(ERR_EXIT),
except that an implicit tt(return) statement is executed instead of an
tt(exit). This will trigger an exit at the outermost level of a
non-interactive script.
+
+Normally this option inherits the behaviour of tt(ERR_EXIT) that
+code followed by `tt(&&)' `tt(||)' does not trigger a return. Hence
+in the following:
+
+example(summit || true)
+
+no return is forced as the combined effect always has a zero return
+status.
+
+Note. however, that if tt(summit) in the above example is itself a
+function, code inside it is considered separately: it may force a return
+from tt(summit) (assuming the option remains set within tt(summit)), but
+not from the enclosing context. This behaviour is different from
+tt(ERR_EXIT) which is unaffected by function scope.
)
pindex(EVAL_LINENO)
pindex(NO_EVAL_LINENO)
diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index 689b90022..adde2d56c 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -306,7 +306,7 @@ sect(On what machines will it run?)
sect(What's the latest version?)
- Zsh 5.4.1 is the latest production version. For details of all the
+ Zsh 5.4.2 is the latest production version. For details of all the
changes, see the NEWS file in the source distribution.
A beta of the next version is sometimes available. Development of zsh is
diff --git a/Functions/VCS_Info/VCS_INFO_patch2subject b/Functions/VCS_Info/VCS_INFO_patch2subject
index e222e8382..a48c16b04 100644
--- a/Functions/VCS_Info/VCS_INFO_patch2subject
+++ b/Functions/VCS_Info/VCS_INFO_patch2subject
@@ -6,14 +6,18 @@
integer -r LIMIT=10
local -a lines
local needle
+ readonly svn_log_pattern='^r[0-9]* [|] .*'
if [[ -f "$1" ]]; then
# Extract the first LIMIT lines, or up to the first empty line or the start of the unidiffs,
# whichever comes first.
while (( i++ < LIMIT )); do
IFS= read -r "lines[$i]"
- if [[ -z ${lines[$i]} ]] || [[ ${lines[$i]} == (#b)(---|Index:)* ]]; then
+ if [[ -z ${lines[$i]} ]] || [[ ${lines[$i]} == (#b)(---[^-]|Index:)* ]]; then
lines[$i]=()
- break
+ # For 'svn log -r N --diff' output, read the first paragraph too.
+ if ! [[ $lines[i-1] =~ $svn_log_pattern ]]; then
+ break
+ fi
fi
done < "$1"
@@ -51,6 +55,9 @@
fi
} < "$1"
REPLY=$needle
+ elif [[ $lines[2] =~ $svn_log_pattern ]]; then
+ REPLY=$lines[4]
+ if (( ${+lines[5]} )); then REPLY+='...'; fi
elif (( ${+lines[1]} )); then
# The first line of the file is not part of the diff.
REPLY=${lines[1]}
diff --git a/README b/README
index 7f81b1ed9..e22cfc12e 100644
--- a/README
+++ b/README
@@ -5,11 +5,11 @@ THE Z SHELL (ZSH)
Version
-------
-This is version 5.4,1 of the shell. This is a stable release. There
-are a few visible improvements since 5.3.1, the last widely released
-version, as well as many bugfixes. Note in particular the changs
-highlighted under "Incompatibilites since 5.3.1" below. See NEWS for
-more information.
+This is version 5.4.2 of the shell. This is a stable release. There
+are some significant bug fixes over 5.4.1 and a few visible improvements
+since 5.3.1, the previous widely released version, as well as many
+bug fixes. Note in particular the changs highlighted under
+"Incompatibilites since 5.3.1" below. See NEWS for more information.
Installing Zsh
--------------
@@ -81,6 +81,19 @@ against user defined widgets inadvertently reading from the tty device,
and addresses the antisocial behaviour of running a command with its
stdin closed.
+5) [New between 5.4.1 and 5.4.2] In previous versions of the shell, the
+following code:
+
+ () { setopt err_return; false; echo 'oh no' } && true
+
+printed "oh no", as the ERR_RETURN behaviour was suppressed when
+a function was executed on the left hand side of an "&&" list. This was
+undocumented and inconvenient as it is generally more useful to consider
+execution within a function in isolation from its environment. The shell
+now returns from the function on executing `false'. (This is general
+to all functions; an anonymous function is shown here for compactness.)
+
+
Incompatibilities between 5.0.8 and 5.3
----------------------------------------
diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c
index 27191d709..659fd22d5 100644
--- a/Src/Modules/pcre.c
+++ b/Src/Modules/pcre.c
@@ -148,7 +148,7 @@ bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int f
/**/
static int
-zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar,
+zpcre_get_substrings(char *arg, int *ovec, int captured_count, char *matchvar,
char *substravar, int want_offset_pair, int matchedinarr,
int want_begin_end)
{
@@ -156,15 +156,13 @@ zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar,
char offset_all[50];
int capture_start = 1;
- if (matchedinarr)
+ if (matchedinarr) {
+ /* bash-style captures[0] entire-matched string in the array */
capture_start = 0;
- if (matchvar == NULL)
- matchvar = "MATCH";
- if (substravar == NULL)
- substravar = "match";
-
+ }
+
/* captures[0] will be entire matched string, [1] first substring */
- if (!pcre_get_substring_list(arg, ovec, ret, (const char ***)&captures)) {
+ if (!pcre_get_substring_list(arg, ovec, captured_count, (const char ***)&captures)) {
int nelem = arrlen(captures)-1;
/* Set to the offsets of the complete match */
if (want_offset_pair) {
@@ -176,30 +174,43 @@ zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar,
* difference between the two values in each paired entry in ovec.
* ovec is length 2*(1+capture_list_length)
*/
- match_all = metafy(captures[0], ovec[1] - ovec[0], META_DUP);
- setsparam(matchvar, match_all);
+ if (matchvar) {
+ match_all = metafy(captures[0], ovec[1] - ovec[0], META_DUP);
+ setsparam(matchvar, match_all);
+ }
/*
* If we're setting match, mbegin, mend we only do
* so if there were parenthesised matches, for consistency
- * (c.f. regex.c).
+ * (c.f. regex.c). That's the next block after this one.
+ * Here we handle the simpler case where we don't worry about
+ * Unicode lengths, etc.
+ * Either !want_begin_end (ie, this is bash) or nelem; if bash
+ * then we're invoked always, even without nelem results, to
+ * set the array variable with one element in it, the complete match.
*/
- if (!want_begin_end || nelem) {
+ if (substravar &&
+ (!want_begin_end || nelem)) {
char **x, **y;
- int vec_off;
+ int vec_off, i;
y = &captures[capture_start];
- matches = x = (char **) zalloc(sizeof(char *) * (arrlen(y) + 1));
- vec_off = 2;
- do {
+ matches = x = (char **) zalloc(sizeof(char *) * (captured_count+1-capture_start));
+ for (i = capture_start; i < captured_count; i++, y++) {
+ vec_off = 2*i;
if (*y)
*x++ = metafy(*y, ovec[vec_off+1]-ovec[vec_off], META_DUP);
else
*x++ = NULL;
- vec_off += 2;
- } while (*y++);
+ }
+ *x = NULL;
setaparam(substravar, matches);
}
if (want_begin_end) {
+ /*
+ * cond-infix rather than builtin; also not bash; so we set a bunch
+ * of variables and arrays to values which require handling Unicode
+ * lengths
+ */
char *ptr = arg;
zlong offs = 0;
int clen, leftlen;
@@ -306,7 +317,9 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func))
zwarnnam(nam, "no pattern has been compiled");
return 1;
}
-
+
+ matched_portion = "MATCH";
+ receptacle = "match";
if(OPT_HASARG(ops,c='a')) {
receptacle = OPT_ARG(ops,c);
}
@@ -318,8 +331,8 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func))
return 1;
}
/* For the entire match, 'Return' the offset byte positions instead of the matched string */
- if(OPT_ISSET(ops,'b')) want_offset_pair = 1;
-
+ if(OPT_ISSET(ops,'b')) want_offset_pair = 1;
+
if ((ret = pcre_fullinfo(pcre_pattern, pcre_hints, PCRE_INFO_CAPTURECOUNT, &capcount)))
{
zwarnnam(nam, "error %d in fullinfo", ret);
@@ -360,7 +373,7 @@ cond_pcre_match(char **a, int id)
{
pcre *pcre_pat;
const char *pcre_err;
- char *lhstr, *rhre, *lhstr_plain, *rhre_plain, *avar=NULL;
+ char *lhstr, *rhre, *lhstr_plain, *rhre_plain, *avar, *svar;
int r = 0, pcre_opts = 0, pcre_errptr, capcnt, *ov, ovsize;
int lhstr_plain_len, rhre_plain_len;
int return_value = 0;
@@ -380,8 +393,13 @@ cond_pcre_match(char **a, int id)
ov = NULL;
ovsize = 0;
- if (isset(BASHREMATCH))
- avar="BASH_REMATCH";
+ if (isset(BASHREMATCH)) {
+ svar = NULL;
+ avar = "BASH_REMATCH";
+ } else {
+ svar = "MATCH";
+ avar = "match";
+ }
switch(id) {
case CPCRE_PLAIN:
@@ -414,7 +432,7 @@ cond_pcre_match(char **a, int id)
break;
}
else if (r>0) {
- zpcre_get_substrings(lhstr_plain, ov, r, NULL, avar, 0,
+ zpcre_get_substrings(lhstr_plain, ov, r, svar, avar, 0,
isset(BASHREMATCH),
!isset(BASHREMATCH));
return_value = 1;
diff --git a/Src/exec.c b/Src/exec.c
index f339dd6d0..cd99733f1 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -41,12 +41,15 @@ enum {
ADDVAR_RESTORE = 1 << 2
};
-/* used to suppress ERREXIT and trapping of SIGZERR, SIGEXIT. */
+/*
+ * used to suppress ERREXIT and trapping of SIGZERR, SIGEXIT.
+ * Bits from noerrexit_bits.
+ */
/**/
int noerrexit;
-/* used to suppress ERREXIT for one occurrence */
+/* used to suppress ERREXIT or ERRRETURN for one occurrence: 0 or 1 */
/**/
int this_noerrexit;
@@ -972,7 +975,7 @@ enum {
static void
entersubsh(int flags)
{
- int sig, monitor, job_control_ok;
+ int i, sig, monitor, job_control_ok;
if (!(flags & ESUB_KEEPTRAP))
for (sig = 0; sig < SIGCOUNT; sig++)
@@ -1083,6 +1086,14 @@ entersubsh(int flags)
opts[MONITOR] = 0;
opts[USEZLE] = 0;
zleactive = 0;
+ /*
+ * If we've saved fd's for later restoring, we're never going
+ * to restore them now, so just close them.
+ */
+ for (i = 10; i <= max_zsh_fd; i++) {
+ if (fdtable[i] & FDT_SAVED_MASK)
+ zclose(i);
+ }
if (flags & ESUB_PGRP)
clearjobtab(monitor);
get_usage();
@@ -1291,7 +1302,7 @@ execlist(Estate state, int dont_change_job, int exiting)
int oerrexit_opt = opts[ERREXIT];
Param pm;
opts[ERREXIT] = 0;
- noerrexit = 1;
+ noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN;
if (ltype & Z_SIMPLE) /* skip the line number */
pc2++;
pm = setsparam("ZSH_DEBUG_CMD", getpermtext(state->prog, pc2, 0));
@@ -1343,13 +1354,13 @@ execlist(Estate state, int dont_change_job, int exiting)
int isend = (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END);
next = state->pc + WC_SUBLIST_SKIP(code);
if (!oldnoerrexit)
- noerrexit = !isend;
+ noerrexit = isend ? 0 : NOERREXIT_EXIT | NOERREXIT_RETURN;
if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT) {
/* suppress errexit for "! this_command" */
if (isend)
this_noerrexit = 1;
/* suppress errexit for ! <list-of-shell-commands> */
- noerrexit = 1;
+ noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN;
}
switch (WC_SUBLIST_TYPE(code)) {
case WC_SUBLIST_END:
@@ -1436,11 +1447,11 @@ sublist_done:
/*
* See hairy code near the end of execif() for the
- * following. "noerrexit == 2" only applies until
+ * following. "noerrexit " only applies until
* we hit execcmd on the way down. We're now
* on the way back up, so don't restore it.
*/
- if (oldnoerrexit != 2)
+ if (!(oldnoerrexit & NOERREXIT_UNTIL_EXEC))
noerrexit = oldnoerrexit;
if (sigtrapped[SIGDEBUG] && !isset(DEBUGBEFORECMD) && !donedebug) {
@@ -1450,7 +1461,7 @@ sublist_done:
*/
int oerrexit_opt = opts[ERREXIT];
opts[ERREXIT] = 0;
- noerrexit = 1;
+ noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN;
exiting = donetrap;
ret = lastval;
dotrap(SIGDEBUG);
@@ -1466,16 +1477,19 @@ sublist_done:
/* Check whether we are suppressing traps/errexit *
* (typically in init scripts) and if we haven't *
* already performed them for this sublist. */
- if (!noerrexit && !this_noerrexit && !donetrap && !this_donetrap) {
- if (sigtrapped[SIGZERR] && lastval) {
+ if (!this_noerrexit && !donetrap && !this_donetrap) {
+ if (sigtrapped[SIGZERR] && lastval &&
+ !(noerrexit & NOERREXIT_EXIT)) {
dotrap(SIGZERR);
donetrap = 1;
}
if (lastval) {
int errreturn = isset(ERRRETURN) &&
- (isset(INTERACTIVE) || locallevel || sourcelevel);
- int errexit = isset(ERREXIT) ||
- (isset(ERRRETURN) && !errreturn);
+ (isset(INTERACTIVE) || locallevel || sourcelevel) &&
+ !(noerrexit & NOERREXIT_RETURN);
+ int errexit = (isset(ERREXIT) ||
+ (isset(ERRRETURN) && !errreturn)) &&
+ !(noerrexit & NOERREXIT_EXIT);
if (errexit) {
if (sigtrapped[SIGEXIT])
dotrap(SIGEXIT);
@@ -2318,6 +2332,9 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag,
return;
}
save[fd1] = fdN;
+ DPUTS(fdtable[fdN] != FDT_INTERNAL,
+ "Saved file descriptor not marked as internal");
+ fdtable[fdN] |= FDT_SAVED_MASK;
}
}
}
@@ -3008,7 +3025,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
preargs = NULL;
/* if we get this far, it is OK to pay attention to lastval again */
- if (noerrexit == 2 && !is_shfunc)
+ if ((noerrexit & NOERREXIT_UNTIL_EXEC) && !is_shfunc)
noerrexit = 0;
/* Do prefork substitutions.
@@ -3575,7 +3592,8 @@ execcmd_exec(Estate state, Execcmd_params eparams,
}
if (!bad && fn->fd1 <= max_zsh_fd) {
if (fn->fd1 >= 10 &&
- fdtable[fn->fd1] == FDT_INTERNAL)
+ (fdtable[fn->fd1] & FDT_TYPE_MASK) ==
+ FDT_INTERNAL)
bad = 3;
}
}
@@ -4270,7 +4288,7 @@ closem(int how)
for (i = 10; i <= max_zsh_fd; i++)
if (fdtable[i] != FDT_UNUSED &&
- (how == FDT_UNUSED || fdtable[i] == how)) {
+ (how == FDT_UNUSED || (fdtable[i] & FDT_TYPE_MASK) == how)) {
if (i == SHTTY)
SHTTY = -1;
zclose(i);
@@ -5450,6 +5468,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
char saveopts[OPT_SIZE], *oldscriptname = scriptname;
char *name = shfunc->node.nam;
int flags = shfunc->node.flags, ooflags;
+ int savnoerrexit;
char *fname = dupstring(name);
int obreaks, ocontflag, oloops, saveemulation, restore_sticky;
Eprog prog;
@@ -5472,6 +5491,11 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
trap_return--;
oldlastval = lastval;
oldnumpipestats = numpipestats;
+ savnoerrexit = noerrexit;
+ /*
+ * Suppression of ERR_RETURN is turned off in function scope.
+ */
+ noerrexit &= ~NOERREXIT_RETURN;
if (noreturnval) {
/*
* Easiest to use the heap here since we're bracketed
@@ -5690,6 +5714,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
if (trap_state == TRAP_STATE_PRIMED)
trap_return++;
ret = lastval;
+ noerrexit = savnoerrexit;
if (noreturnval) {
lastval = oldlastval;
numpipestats = oldnumpipestats;
diff --git a/Src/init.c b/Src/init.c
index d8c26aca2..87dd2e26d 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -1070,7 +1070,7 @@ setupvals(char *cmd, char *runscript, char *zsh_name)
sfcontext = SFC_NONE;
trap_return = 0;
trap_state = TRAP_STATE_INACTIVE;
- noerrexit = -1;
+ noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN | NOERREXIT_SIGNAL;
nohistsave = 1;
dirstack = znewlinklist();
bufstack = znewlinklist();
@@ -1199,7 +1199,7 @@ init_signals(void)
void
run_init_scripts(void)
{
- noerrexit = -1;
+ noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN | NOERREXIT_SIGNAL;
if (EMULATION(EMULATE_KSH|EMULATE_SH)) {
if (islogin)
diff --git a/Src/lex.c b/Src/lex.c
index b2d9b3f42..8493d4737 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -760,7 +760,7 @@ gettok(void)
return AMPER;
case LX1_BAR:
d = hgetc();
- if (d == '|')
+ if (d == '|' && !incasepat)
return DBAR;
else if (d == '&')
return BARAMP;
@@ -1058,7 +1058,7 @@ gettokstr(int c, int sub)
if (isset(SHGLOB)) {
if (sub || in_brace_param)
break;
- if (incasepat && !lexbuf.len)
+ if (incasepat > 0 && !lexbuf.len)
return INPAR;
if (!isset(KSHGLOB) && lexbuf.len)
goto brk;
@@ -1859,7 +1859,7 @@ exalias(void)
Reswd rw;
hwend();
- if (interact && isset(SHINSTDIN) && !strin && !incasepat &&
+ if (interact && isset(SHINSTDIN) && !strin && incasepat <= 0 &&
tok == STRING && !nocorrect && !(inbufflags & INP_ALIAS) &&
(isset(CORRECTALL) || (isset(CORRECT) && incmdpos)))
spckword(&tokstr, 1, incmdpos, 1);
diff --git a/Src/loop.c b/Src/loop.c
index f7eae307b..4859c976b 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -542,7 +542,7 @@ execif(Estate state, int do_exec)
end = state->pc + WC_IF_SKIP(code);
if (!noerrexit)
- noerrexit = 1;
+ noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN;
while (state->pc < end) {
code = *state->pc++;
if (wc_code(code) != WC_IF ||
@@ -567,7 +567,12 @@ execif(Estate state, int do_exec)
if (run) {
/* we need to ignore lastval until we reach execcmd() */
- noerrexit = olderrexit ? olderrexit : lastval ? 2 : 0;
+ if (olderrexit)
+ noerrexit = olderrexit;
+ else if (lastval)
+ noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN | NOERREXIT_UNTIL_EXEC;
+ else
+ noerrexit = 0;
cmdpush(run == 2 ? CS_ELSE : (s ? CS_ELIFTHEN : CS_IFTHEN));
execlist(state, 1, do_exec);
cmdpop();
diff --git a/Src/module.c b/Src/module.c
index 21d68b1ac..4ae78310f 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -649,11 +649,21 @@ getconddef(int inf, const char *name, int autol)
{
Conddef p;
int f = 1;
+ char *lookup, *s;
+
+ /* detokenize the Dash to the form encoded in lookup tables */
+ lookup = dupstring(name);
+ if (!lookup)
+ return NULL;
+ for (s = lookup; *s != '\0'; s++) {
+ if (*s == Dash)
+ *s = '-';
+ }
do {
for (p = condtab; p; p = p->next) {
if ((!!inf == !!(p->flags & CONDF_INFIX)) &&
- !strcmp(name, p->name))
+ !strcmp(lookup, p->name))
break;
}
if (autol && p && p->module) {
@@ -664,7 +674,7 @@ getconddef(int inf, const char *name, int autol)
if (f) {
(void)ensurefeature(p->module,
(p->flags & CONDF_INFIX) ? "C:" : "c:",
- (p->flags & CONDF_AUTOALL) ? NULL : name);
+ (p->flags & CONDF_AUTOALL) ? NULL : lookup);
f = 0;
p = NULL;
} else {
@@ -674,6 +684,7 @@ getconddef(int inf, const char *name, int autol)
} else
break;
} while (!p);
+
return p;
}
diff --git a/Src/parse.c b/Src/parse.c
index ba9cd61eb..27052527d 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -48,7 +48,11 @@ mod_export int incond;
/**/
mod_export int inredir;
-/* != 0 if we are about to read a case pattern */
+/*
+ * 1 if we are about to read a case pattern
+ * -1 if we are not quite sure
+ * 0 otherwise
+ */
/**/
int incasepat;
@@ -1194,6 +1198,7 @@ par_case(int *cmplx)
for (;;) {
char *str;
+ int skip_zshlex;
while (tok == SEPER)
zshlex();
@@ -1201,11 +1206,17 @@ par_case(int *cmplx)
break;
if (tok == INPAR)
zshlex();
- if (tok != STRING)
- YYERRORV(oecused);
- if (!strcmp(tokstr, "esac"))
- break;
- str = dupstring(tokstr);
+ if (tok == BAR) {
+ str = dupstring("");
+ skip_zshlex = 1;
+ } else {
+ if (tok != STRING)
+ YYERRORV(oecused);
+ if (!strcmp(tokstr, "esac"))
+ break;
+ str = dupstring(tokstr);
+ skip_zshlex = 0;
+ }
type = WC_CASE_OR;
pp = ecadd(0);
palts = ecadd(0);
@@ -1243,10 +1254,11 @@ par_case(int *cmplx)
* this doesn't affect our ability to match a | or ) as
* these are valid on command lines.
*/
- incasepat = 0;
+ incasepat = -1;
incmdpos = 1;
- for (;;) {
+ if (!skip_zshlex)
zshlex();
+ for (;;) {
if (tok == OUTPAR) {
ecstr(str);
ecadd(ecnpats++);
@@ -1302,10 +1314,26 @@ par_case(int *cmplx)
}
zshlex();
- if (tok != STRING)
+ switch (tok) {
+ case STRING:
+ /* Normal case */
+ str = dupstring(tokstr);
+ zshlex();
+ break;
+
+ case OUTPAR:
+ case BAR:
+ /* Empty string */
+ str = dupstring("");
+ break;
+
+ default:
+ /* Oops. */
YYERRORV(oecused);
- str = dupstring(tokstr);
+ break;
+ }
}
+ incasepat = 0;
par_save_list(cmplx);
if (tok == SEMIAMP)
type = WC_CASE_AND;
diff --git a/Src/signals.c b/Src/signals.c
index cad40f4eb..94f379e72 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -652,7 +652,7 @@ zhandler(int sig)
case SIGINT:
if (!handletrap(SIGINT)) {
if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
- isset(INTERACTIVE) && noerrexit < 0)
+ isset(INTERACTIVE) && (noerrexit & NOERREXIT_SIGNAL))
zexit(SIGINT, 1);
if (list_pipe || chline || simple_pline) {
breaks = loops;
diff --git a/Src/zsh.h b/Src/zsh.h
index ccd11db3d..abe9a9c82 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -456,6 +456,18 @@ enum {
#define FDT_PROC_SUBST 7
#endif
+/*
+ * Mask to get the basic FDT type.
+ */
+#define FDT_TYPE_MASK 15
+
+/*
+ * Bit flag that fd is saved for later restoration.
+ * Currently this is only use with FDT_INTERNAL. We use this fact so as
+ * not to have to mask checks against other types.
+ */
+#define FDT_SAVED_MASK 16
+
/* Flags for input stack */
#define INP_FREE (1<<0) /* current buffer can be free'd */
#define INP_ALIAS (1<<1) /* expanding alias or history */
@@ -2110,6 +2122,17 @@ enum source_return {
SOURCE_ERROR = 2
};
+enum noerrexit_bits {
+ /* Suppress ERR_EXIT and traps: global */
+ NOERREXIT_EXIT = 1,
+ /* Suppress ERR_RETURN: per function call */
+ NOERREXIT_RETURN = 2,
+ /* NOERREXIT only needed on way down */
+ NOERREXIT_UNTIL_EXEC = 4,
+ /* Force exit on SIGINT */
+ NOERREXIT_SIGNAL = 8
+};
+
/***********************************/
/* Definitions for history control */
/***********************************/
diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst
index 9625a15bc..0302c9624 100644
--- a/Test/A01grammar.ztst
+++ b/Test/A01grammar.ztst
@@ -820,6 +820,43 @@
0:case keeps exit status of last command executed in compound-list
>37
+ case '' in
+ burble) print No.
+ ;;
+ spurble|) print Yes!
+ ;;
+ |burble) print Not quite.
+ ;;
+ esac
+ case '' in
+ burble) print No.
+ ;;
+ |burble) print Wow!
+ ;;
+ spurble|) print Sorry.
+ ;;
+ esac
+ case '' in
+ gurgle) print No.
+ ;;
+ wurgle||jurgle) print Yikes!
+ ;;
+ durgle|) print Hmm.
+ ;;
+ |zurgle) print Hah.
+ ;;
+ esac
+ case '' in
+ # Useless doubled empty string to check special case.
+ ||jurgle) print Ok.
+ ;;
+ esac
+0: case with no opening parentheses and empty string
+>Yes!
+>Wow!
+>Yikes!
+>Ok.
+
x=1
x=2 | echo $x
echo $x
diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index f01d83567..8101ff539 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -345,6 +345,36 @@
>ZERR trapped
>off after
+ (
+ setopt ERR_EXIT
+ () { false; print is executed; } && true
+ () { false; print is not executed; }
+ print is not executed
+ )
+1:ERR_EXIT is suppressed within a function followed by "&&"
+>is executed
+
+ (
+ setopt ERR_RETURN
+ () { false; print is not executed; } || print is executed
+ print is also executed
+ )
+0:ERR_RETURN is not suppressed within a function followed by "||"
+>is executed
+>is also executed
+
+ (
+ setopt ERR_RETURN
+ () {
+ () { false; print Not executed 1; } || true
+ print Executed
+ () { false; print Not executed 2; }
+ print Not executed 3;
+ } && false
+ )
+1:ERR_RETURN with additional levels
+>Executed
+
(print before; setopt noexec; print after)
0:NO_EXEC option
>before
diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst
index 7426e7bf8..9feeb47fb 100644
--- a/Test/V07pcre.ztst
+++ b/Test/V07pcre.ztst
@@ -137,6 +137,39 @@
0:ensure ASCII NUL passes in and out of matched plaintext
>6; 3; 3
+# Ensure the long-form infix operator works
+ [[ foo -pcre-match ^f..$ ]]
+ print $?
+ [[ foo -pcre-match ^g..$ ]]
+ print $?
+ [[ ! foo -pcre-match ^g..$ ]]
+ print $?
+0:infix -pcre-match works
+>0
+>1
+>0
+
+# Bash mode; note zsh documents that variables not updated on match failure,
+# which remains different from bash
+ setopt bash_rematch
+ [[ "goo" -pcre-match ^f.+$ ]] ; print $?
+ [[ "foo" -pcre-match ^f.+$ ]] ; print -l $? _${^BASH_REMATCH[@]}
+ [[ "foot" -pcre-match ^f([aeiou]+)(.)$ ]]; print -l $? _${^BASH_REMATCH[@]}
+ [[ "foo" -pcre-match ^f.+$ ]] ; print -l $? _${^BASH_REMATCH[@]}
+ [[ ! "goo" -pcre-match ^f.+$ ]] ; print $?
+ unsetopt bash_rematch
+0:bash-compatibility works
+>1
+>0
+>_foo
+>0
+>_foot
+>_oo
+>_t
+>0
+>_foo
+>0
+
# Subshell because crash on failure
( setopt re_match_pcre
[[ test.txt =~ '^(.*_)?(test)' ]]