From 74647ade06864fb6005a9bd079ffce5158c9a05a Mon Sep 17 00:00:00 2001 From: dana Date: Sat, 14 May 2022 14:13:12 -0500 Subject: unposted: Post-release version bump --- ChangeLog | 2 ++ Config/version.mk | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5425b198f..6f3fd4408 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2022-05-14 dana + * unposted: Config/version.mk: Post-release version bump + * unposted: Config/version.mk: Update for 5.9 2022-05-11 Jun-ichi Takimoto diff --git a/Config/version.mk b/Config/version.mk index 524c87246..e1b02e713 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.9 -VERSION_DATE='May 14, 2022' +VERSION=5.9.0.1-dev +VERSION_DATE='May 15, 2022' -- cgit v1.2.3 From 361de369edd3bd17066b5f72e056e487545b364e Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Sun, 15 May 2022 00:41:38 +0200 Subject: 50220: Documentation: Fix typos found by Debian's Lintian tool --- ChangeLog | 5 +++++ Doc/Zsh/builtins.yo | 2 +- Doc/Zsh/options.yo | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f3fd4408..b5e85e180 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-05-15 Axel Beckert + + * 50220: Doc/Zsh/{builtins,options}.yo: Fix typos found by + Debian's Lintian tool. + 2022-05-14 dana * unposted: Config/version.mk: Post-release version bump diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 280f1d72a..641e46cf9 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1936,7 +1936,7 @@ retain their special attributes when made local. For each var(name)tt(=)var(value) assignment, the parameter var(name) is set to var(value). If the assignment is omitted and var(name) -does em(not) refer to an existing parameter, a new parameter is intialized +does em(not) refer to an existing parameter, a new parameter is initialized to empty string, zero, or empty array (as appropriate), em(unless) the shell option tt(TYPESET_TO_UNSET) is set. When that option is set, the parameter attributes are recorded but the parameter remains unset. diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 443676b78..5e673eb5c 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1952,7 +1952,7 @@ pindex(NOTYPESETTOUNSET) item(tt(TYPESET_TO_UNSET) )( When declaring a new parameter with any of the `tt(typeset)' family of related commands, the parameter remains unset unless and until a -value is explicity assigned to it, either in the `tt(typeset)' command +value is explicitly assigned to it, either in the `tt(typeset)' command itself or as a later assignment statement. ) pindex(VERBOSE) -- cgit v1.2.3 From 84dde7c7b622737a34526ac2a5ba29ddc6c072d8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 14 May 2022 20:34:28 -0700 Subject: Jan Brieg: 50212 (and discussion): Add "bright" color variants --- ChangeLog | 5 +++++ Functions/Misc/colors | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5e85e180..a63f820a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-05-14 Bart Schaefer + + * Jan Brieg: 50212 (and discussion): Functions/Misc/colors: Add + "bright" color variants + 2022-05-15 Axel Beckert * 50220: Doc/Zsh/{builtins,options}.yo: Fix typos found by diff --git a/Functions/Misc/colors b/Functions/Misc/colors index 5e9d77d10..5c9924adb 100644 --- a/Functions/Misc/colors +++ b/Functions/Misc/colors @@ -63,6 +63,16 @@ color=( # 63 double-overline-or-left # 64 stress # 65 no-ideogram-marking + +# Bright color codes (xterm extension) + 90 bright-gray 100 bg-bright-gray + 91 bright-red 101 bg-bright-red + 92 bright-green 102 bg-bright-green + 93 bright-yellow 103 bg-bright-yellow + 94 bright-blue 104 bg-bright-blue + 95 bright-magenta 105 bg-bright-magenta + 96 bright-cyan 106 bg-bright-cyan + 97 bright-white 107 bg-bright-white ) # A word about black and white: The "normal" shade of white is really a @@ -79,7 +89,7 @@ for k in ${(k)color}; do color[${color[$k]}]=$k; done # Add "fg-" keys for all the text colors, for clarity. -for k in ${color[(I)3?]}; do color[fg-${color[$k]}]=$k; done +for k in ${color[(I)[39]?]}; do color[fg-${color[$k]}]=$k; done # This is inaccurate, but the prompt theme system needs it. @@ -89,7 +99,11 @@ for k in grey gray; do color[bg-$k]=${color[bg-black]} done -# Assistance for the color-blind. +# Assistance for the colo(u)r-blind. + +for k in '' fg- bg-; do + color[${k}bright-grey]=${color[${k}bright-gray]} +done colour=(${(kv)color}) # A case where ksh namerefs would be useful ... -- cgit v1.2.3 From 545c42cdac25b73134a9577e3c0efa36d76b4091 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 14 May 2022 21:36:27 -0700 Subject: 50229: Typo --- ChangeLog | 2 ++ NEWS | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a63f820a8..191c64818 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2022-05-14 Bart Schaefer + * 50229: NEWS: Typo + * Jan Brieg: 50212 (and discussion): Functions/Misc/colors: Add "bright" color variants diff --git a/NEWS b/NEWS index d7a817c1e..cdafd1ff5 100644 --- a/NEWS +++ b/NEWS @@ -49,7 +49,7 @@ negative numbers. The (*) expansion flag enables EXTENDED_GLOB for pattern matching. For example, ${(*)sample/(#b)*(pat)*/${match[1]}} uses backreferences even if EXTENDED_GLOB is not otherwise set. However, this does not -descend into nested exapansions, and doubling as (**) does not disable +descend into nested expansions, and doubling as (**) does not disable EXTENDED_GLOB. The compinit function learnt a -w option to explain why compdump runs. -- cgit v1.2.3 From a54d70457934662318feac9fcc750d2691250f33 Mon Sep 17 00:00:00 2001 From: Arvid Norlander Date: Sat, 14 May 2022 17:40:28 +0200 Subject: github #91: _find (gnu/freebsd/darwin): Add some flags and syntaxes * -exec and -execdir can take ; or + as an ending marker. Previously only ; was supported. This is part of POSIX for -exec (support for + for -ok is optional and none of the implementations I looked at seem to support that). * Missing completion for -files0-from (GNU find 4.9.0 and later). This flag needs to go with the global flags at the beginning and load the paths from the given file instead of from the command line. * Missing completion for the -newerXY family of flags (GNU find 4.3.3, also available in FreeBSD and MacOS at least). --- ChangeLog | 5 +++++ Completion/Unix/Command/_find | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 191c64818..98e3089d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-05-20 Arvid Norlander + + * github #91: Completion/Unix/Command/_find: _find + (gnu/freebsd/darwin): Add some flags and syntaxes + 2022-05-14 Bart Schaefer * 50229: NEWS: Typo diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find index 74111f92b..560b77f7e 100644 --- a/Completion/Unix/Command/_find +++ b/Completion/Unix/Command/_find @@ -37,6 +37,11 @@ case $variant in args+=( '*-Bmin:birth time (minutes)' '*-Bnewer:file to compare (birth time):_files' + '*-newer'{a,B,c,m}{a,B,c,m}'[if [aBcm\]time is newer than [aBcm\]time of given file]:reference file:_files' + '*-newerat[if access time is newer than given timestamp]:timestamp: ' + '*-newerBt[if birth time is newer than given timestamp]:timestamp: ' + '*-newerct[if creation time is newer than given timestamp]:timestamp: ' + '*-newermt[if modification time is newer than given timestamp]:timestamp: ' '*-Btime:birth time (hours)' ) ;| @@ -46,7 +51,7 @@ case $variant in '*-anewer:file to compare (access time):_files' '*-cnewer:file to compare (inode change time):_files' '*-empty' - '*-execdir:program: _command_names -e:*\;::program arguments: _normal' + '*-execdir:program: _command_names -e:*(\;|+)::program arguments: _normal' '*-maxdepth:maximum search depth' '*-mindepth:minimum search depth' '*-path:path pattern to search:' @@ -110,6 +115,7 @@ case $variant in '*-readable' '*-writable' '*-xtype:file type:((b\:block\ special\ file c\:character\ special\ file d\:directory p\:named\ pipe f\:normal\ file l\:symbolic\ link s\:socket))' + '-files0-from[start recursing from targets in given file]:NUL-separated targets file:_files' '*-fls:output file:_files' '*-fprint:output file:_files' '*-fprint0:output file:_files' @@ -126,7 +132,7 @@ _arguments -C $args \ '*-atime:access time (days):->times' \ '*-ctime:inode change time (days):->times' \ '*-depth' \ - '*-exec:program: _command_names -e:*\;::program arguments: _normal' \ + '*-exec:program: _command_names -e:*(\;|+)::program arguments: _normal' \ '*-follow' \ '*-fstype:file system type:_file_systems' \ '*-group:group:_groups' \ @@ -147,7 +153,7 @@ _arguments -C $args \ '*-user:user:_users' \ '*-xdev' \ '*-a' '*-o' \ - '(-D -E -H -L -O -P -f -s -x --help --version)*:directory:_files -/' \ + '(-D -E -H -L -O -P -f -s -x --files0-from --help --version)*:directory:_files -/' \ && ret=0 if [[ $state = times ]]; then -- cgit v1.2.3 From 1e52cd968d7ffd9da3249ef01f6c41f8b29e4df3 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 22 May 2022 15:50:45 -0700 Subject: 50278: use `man -w` in preference to `manpath`; fix caching and precedence of -M --- ChangeLog | 5 +++++ Completion/Unix/Command/_man | 45 +++++++++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 98e3089d5..b2cecc1a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-05-22 Bart Schaefer + + * 50278: Completion/Unix/Command/_man: use `man -w` in preference + to `manpath` for portability; fix caching and precedence of -M + 2022-05-20 Arvid Norlander * github #91: Completion/Unix/Command/_find: _find diff --git a/Completion/Unix/Command/_man b/Completion/Unix/Command/_man index dba1d13dc..190811e41 100644 --- a/Completion/Unix/Command/_man +++ b/Completion/Unix/Command/_man @@ -16,7 +16,7 @@ _man() { local dirs expl mrd awk variant noinsert local -a context line state state_descr args modes - local -aU sects + local -aU sects _manpath local -A opt_args val_args sect_descs if [[ $service == man ]]; then @@ -168,29 +168,40 @@ _man() { _arguments -s -S : $args '*::: :->man' && return 0 [[ -n $state ]] || return 1 + # Override man path + [[ -n ${opt_args[-M]} ]] && + _manpath=( ${(s<:>)opt_args[-M]} ) + + # Restore cached man path to avoid $(manpath) if we can if (( ! $#_manpath )); then - local mp - mp=( ${(s.:.)$(manpath 2>/dev/null)} ) - [[ "$mp" == *:* ]] && mp=( ${(s.:.)mp} ) - if (( $#mp )); then - _manpath=( $mp ) - elif (( $#manpath )); then - _manpath=( $manpath ) + if (( ! $+_manpath_cache )); then + typeset -gHA _manpath_cache fi + if [[ -z $_manpath_cache[$MANPATH] ]]; then + local mp + mp=( ${(s.:.)$({ command man -w || manpath } 2>/dev/null)} ) + [[ "$mp" == *:* ]] && mp=( ${(s.:.)mp} ) + if (( $#mp )); then + _manpath_cache[$MANPATH]=${(j.:.)mp} + elif (( $#manpath )); then + _manpath_cache[$MANPATH]=$MANPATH + fi + fi + _manpath=( ${(s.:.)_manpath_cache[$MANPATH]} ) + fi + + # Augment man path + if [[ -n ${opt_args[-m]} ]]; then + [[ $variant == (netbsd|openbsd)* ]] && + _manpath+=( ${(s<:>)opt_args[-m]} ) + elif [[ $variant == aix* ]]; then + # _manpath declared -U so no need to test + _manpath+=( /usr/share/man ) fi (( $#_manpath )) || _manpath=( /usr/man(-/) /(opt|usr)/(pkg|dt|share|X11R6|local)/(cat|)man(-/) ) - # Override man path - [[ -n ${opt_args[-M]} ]] && - _manpath=( ${(s<:>)opt_args[-M]} ) - - # Augment man path - [[ $variant == (netbsd|openbsd)* ]] && - [[ -n ${opt_args[-m]} ]] && - _manpath+=( ${(s<:>)opt_args[-m]} ) - # `sman' is the SGML manual directory for Solaris 7. # 1M is system administrator commands on SVR4 -- cgit v1.2.3 From c1f1bbc5b9c128944b82afed25140ee62ccf522a Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Tue, 24 May 2022 22:26:29 +0200 Subject: github #93: Replace /etc/mtab with /proc/self/mounts for Linux /proc/self/mounts has been available since Linux 2.4.19, released in 2002. /etc/mtab is usually a symlink to this file but might not exist --- ChangeLog | 7 +++++++ Completion/Linux/Command/_btrfs | 2 +- Completion/Linux/Command/_fusermount | 2 +- Completion/Unix/Type/_umountable | 7 ++++++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index b2cecc1a3..f82e492f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2022-05-25 Norbert Lange + + * github #93: Completion/Linux/Command/_btrfs, + Completion/Linux/Command/_fusermount, + Completion/Unix/Type/_umountable: Replace /etc/mtab with + /proc/self/mounts for Linux. + 2022-05-22 Bart Schaefer * 50278: Completion/Unix/Command/_man: use `man -w` in preference diff --git a/Completion/Linux/Command/_btrfs b/Completion/Linux/Command/_btrfs index 65cf067aa..1d87fd83a 100644 --- a/Completion/Linux/Command/_btrfs +++ b/Completion/Linux/Command/_btrfs @@ -424,7 +424,7 @@ while (( $#state )); do ;; mounts) _wanted mount-points expl 'mount point' compadd \ - ${${${(M)${(f)"$( Date: Tue, 24 May 2022 22:34:50 +0200 Subject: github #94: Support .zst kernel modules with modutils --- ChangeLog | 3 +++ Completion/Linux/Command/_modutils | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f82e492f8..3fbd9d9b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-05-25 Norbert Lange + * github #94: Completion/Linux/Command/_modutils: Support .zst + kernel modules with modutils. + * github #93: Completion/Linux/Command/_btrfs, Completion/Linux/Command/_fusermount, Completion/Unix/Type/_umountable: Replace /etc/mtab with diff --git a/Completion/Linux/Command/_modutils b/Completion/Linux/Command/_modutils index 3e46130a2..f19784dff 100644 --- a/Completion/Linux/Command/_modutils +++ b/Completion/Linux/Command/_modutils @@ -127,7 +127,7 @@ _modutils() { fi if _cache_invalid modules-$kver || ! _retrieve_cache modules-$kver; then - 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|ko.zst)(.:t:r:r) ) modaliases=( ${${${(M)${(f)"$(<$modules_dir/$kver/modules.alias)"}:#alias*}#alias }%% *} ) _store_cache modules-$kver modules modaliases fi -- cgit v1.2.3 From 92da264eea88582d51c9932b6233863298f79016 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 26 May 2022 09:32:33 +0100 Subject: 50286: avoid zed error if nounset is in effect --- ChangeLog | 4 ++++ Functions/Misc/zed | 14 ++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3fbd9d9b5..6b65e7996 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-05-26 Peter Stephenson + + * 50286: Functions/Misc/zed: avoid error if nounset is in effect. + 2022-05-25 Norbert Lange * github #94: Completion/Linux/Command/_modutils: Support .zst diff --git a/Functions/Misc/zed b/Functions/Misc/zed index 7d0d590db..bb075512c 100644 --- a/Functions/Misc/zed +++ b/Functions/Misc/zed @@ -14,15 +14,17 @@ local var opts zed_file_name integer TMOUT=0 okargs=1 fun hist bind local -a expand -zparseopts -D -A opts f h b x: +zparseopts -D -A opts f h b x: || return 1 fun=$+opts[-f] hist=$+opts[-h] bind=$+opts[-b] -if [[ $opts[-x] == <-> ]]; then - expand=(-x $opts[-x]) -elif (( $+opts[-x] )); then - print -r "Integer expected after -x: $opts[-x]" >&2 - return 1 +if (( $+opts[-x] )); then + if [[ $opts[-x] == <-> ]]; then + expand=(-x $opts[-x]) + else + print -r "Integer expected after -x: $opts[-x]" >&2 + return 1 + fi fi [[ $0 = fned ]] && fun=1 -- cgit v1.2.3 From e4557ef852d512eddbd70f9c59e4bfb9fc4527a9 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 26 May 2022 09:33:43 +0100 Subject: 50287: Use getcwd by default. --- ChangeLog | 3 +++ configure.ac | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b65e7996..b637cdfdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-05-26 Peter Stephenson + * 50287: configure.ac: Turn on use of getcwd by default. Leave + the ability to turn it off per OS configuration. + * 50286: Functions/Misc/zed: avoid error if nounset is in effect. 2022-05-25 Norbert Lange diff --git a/configure.ac b/configure.ac index c72148d06..77e381f50 100644 --- a/configure.ac +++ b/configure.ac @@ -2021,11 +2021,15 @@ if test x$zsh_cv_sys_superroot = xyes; then fi dnl CHECK FOR SYSTEMS REQUIRING GETCWD +dnl This is now turned on by default, as we expect modern getcwd +dnl implementations to work correctly. Any exceptions should be added +dnl to the first case. Currently there are none, hence it is forced +dnl not to match. AC_CACHE_CHECK(whether we should use the native getcwd, zsh_cv_use_getcwd, [case "${host_cpu}-${host_vendor}-${host_os}" in - *QNX*) zsh_cv_use_getcwd=yes ;; - *) zsh_cv_use_getcwd=no ;; + *NOMATCH*) zsh_cv_use_getcwd=no ;; + *) zsh_cv_use_getcwd=yes ;; esac]) AH_TEMPLATE([USE_GETCWD], [Define to 1 if you need to use the native getcwd.]) -- cgit v1.2.3 From 8756cc6add3d27d05e869fc7317e3043ab2be5b2 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 30 May 2022 12:02:50 -0700 Subject: Marlon Richert: 50307 (cf. PWS 50205): suffix aliases should not collide with directory names when completing --- ChangeLog | 6 ++++++ Completion/Zsh/Type/_suffix_alias_files | 1 + 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index b637cdfdd..43a805bc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-05-30 Bart Schaefer + + * Marlon Richert: 50307 (cf. PWS 50205): + Completion/Zsh/Type/_suffix_alias_files: suffix aliases should not + collide with directory names when completing + 2022-05-26 Peter Stephenson * 50287: configure.ac: Turn on use of getcwd by default. Leave diff --git a/Completion/Zsh/Type/_suffix_alias_files b/Completion/Zsh/Type/_suffix_alias_files index 1c2c8ebb5..b6fa4e7f5 100644 --- a/Completion/Zsh/Type/_suffix_alias_files +++ b/Completion/Zsh/Type/_suffix_alias_files @@ -16,6 +16,7 @@ else tmpa=(${(kq)saliases}) pat="*.(${(kj.|.)tmpa})" fi +[[ -o autocd ]] || pat+='(#q^/)' # _wanted is called for us by _command_names _path_files "$@" -g $pat -- cgit v1.2.3 From 22b1a91c2a07e6d6a57975a1ab47d66f92aa21f2 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Fri, 3 Jun 2022 19:32:56 +0900 Subject: 50306: fix wait for child that was stopped/continued do not call addbgstatus() when child is stopped/continued --- ChangeLog | 5 +++++ Src/jobs.c | 20 ++++++++++++++++++-- Src/signals.c | 10 ++++------ Test/A05execution.ztst | 7 +++++++ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 43a805bc7..780f967f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-06-03 Jun-ichi Takimoto + + * 50306: Src/jobs.c, Src/signals.c, Test/A05execution.ztst: fix + wait builtin for child that has been stopped and continued. + 2022-05-30 Bart Schaefer * Marlon Richert: 50307 (cf. PWS 50205): diff --git a/Src/jobs.c b/Src/jobs.c index a91ef787f..aa32f4e80 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -414,7 +414,7 @@ storepipestats(Job jn, int inforeground, int fixlastval) jpipestats[i] = (WIFSIGNALED(p->status) ? 0200 | WTERMSIG(p->status) : (WIFSTOPPED(p->status) ? - 0200 | WEXITSTATUS(p->status) : + 0200 | WSTOPSIG(p->status) : WEXITSTATUS(p->status))); if (jpipestats[i]) pipefail = jpipestats[i]; @@ -471,7 +471,7 @@ update_job(Job jn) val = (WIFSIGNALED(pn->status) ? 0200 | WTERMSIG(pn->status) : (WIFSTOPPED(pn->status) ? - 0200 | WEXITSTATUS(pn->status) : + 0200 | WSTOPSIG(pn->status) : WEXITSTATUS(pn->status))); signalled = WIFSIGNALED(pn->status); } @@ -2221,6 +2221,7 @@ addbgstatus(pid_t pid, int status) { static long child_max; Bgstatus bgstatus_entry; + LinkNode node; if (!child_max) { #ifdef _SC_CHILD_MAX @@ -2244,6 +2245,21 @@ addbgstatus(pid_t pid, int status) if (!bgstatus_list) return; } +#ifdef DEBUG + /* See if an entry already exists for the pid */ + for (node = firstnode(bgstatus_list); node; incnode(node)) { + bgstatus_entry = (Bgstatus)getdata(node); + if (bgstatus_entry->pid == pid) { + /* In theory this should not happen because addbgstatus() is + * called only once when the process exits or gets killed. */ + dputs("addbgstatus called again: pid %d: status %d -> %d", + pid, bgstatus_entry->status, status); + bgstatus_entry->status = status; + return; + } + } +#endif + /* Add an entry for the pid */ if (bgstatus_count == child_max) { /* Overflow. List is in order, remove first */ rembgstatus(firstnode(bgstatus_list)); diff --git a/Src/signals.c b/Src/signals.c index 5c787e2a8..a61368554 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -576,12 +576,10 @@ wait_for_processes(void) */ if (jn && !(jn->stat & (STAT_CURSH|STAT_BUILTIN)) && jn - jobtab != thisjob) { - int val = (WIFSIGNALED(status) ? - 0200 | WTERMSIG(status) : - (WIFSTOPPED(status) ? - 0200 | WEXITSTATUS(status) : - WEXITSTATUS(status))); - addbgstatus(pid, val); + if (WIFEXITED(status)) + addbgstatus(pid, WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + addbgstatus(pid, 0200 | WTERMSIG(status)); } unqueue_signals(); diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst index d95ee363c..b257ddf2c 100644 --- a/Test/A05execution.ztst +++ b/Test/A05execution.ztst @@ -396,6 +396,13 @@ F:anonymous function, and a descriptor leak when backgrounding a pipeline # TBD: the 0 above is believed to be bogus and should also be turned # into 127 when the ccorresponding bug is fixed in the main shell. + sleep 1 & pid=$! + kill -STOP $pid + sleep 1 + kill -CONT $pid + wait $pid +0:wait for stopped and continued process + # Without the outer subshell, the test harness reports the pre-46060 behaviour # as "skipped" rather than "failed". (( exit 130 ) | { sleep 1; echo hello }) -- cgit v1.2.3 From 3e3cfabcc74dc79d4d8717c4e5859d8d01be6c54 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 3 Jun 2022 20:08:15 -0700 Subject: 50325: revert 38150 and fix in calling function cfp_matcher_range() instead --- ChangeLog | 5 +++++ Src/Zle/compmatch.c | 2 +- Src/Zle/computil.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 780f967f6..839beb4f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,11 @@ * 50306: Src/jobs.c, Src/signals.c, Test/A05execution.ztst: fix wait builtin for child that has been stopped and continued. +2022-06-02 Bart Schaefer + + * 50325: Src/Zle/compmatch.c, Src/Zle/computil.c: revert 38150 and + fix in calling function cfp_matcher_range() instead + 2022-05-30 Bart Schaefer * Marlon Richert: 50307 (cf. PWS 50205): diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c index bb8359f1d..56e5509a4 100644 --- a/Src/Zle/compmatch.c +++ b/Src/Zle/compmatch.c @@ -1319,7 +1319,7 @@ pattern_match_equivalence(Cpattern lp, convchar_t wind, int wmtp, convchar_t lchr; int lmtp; - if (!PATMATCHINDEX(lp->u.str, wind, &lchr, &lmtp)) { + if (!PATMATCHINDEX(lp->u.str, wind-1, &lchr, &lmtp)) { /* * No equivalent. No possible match; give up. */ diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 59abb4cc4..77ccdebf7 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -4383,7 +4383,7 @@ cfp_matcher_range(Cmatcher *ms, char *add) * word pattern. */ if ((ind = pattern_match_equivalence - (m->word, ind, mt, addc)) != CHR_INVALID) { + (m->word, ind+1, mt, addc)) != CHR_INVALID) { if (ret) { if (imeta(ind)) { *p++ = Meta; -- cgit v1.2.3 From a99f96797f5fc424554a94313dfc0d4a5b0923a1 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 4 Jun 2022 14:19:42 -0700 Subject: 50323: create helper for shadowing builtins or existing functions and use it when redefining compadd et al. --- ChangeLog | 7 ++++ Completion/Base/Utility/_shadow | 71 +++++++++++++++++++++++++++++++++++ Completion/Base/Widget/_complete_help | 3 +- Functions/Zle/keeper | 3 +- 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 Completion/Base/Utility/_shadow diff --git a/ChangeLog b/ChangeLog index 839beb4f9..5490385f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2022-06-04 Bart Schaefer + + * 50323: Completion/Base/Utility/_shadow (new file), + Completion/Base/Widget/_complete_help, Functions/Zle/keeper: + create helper for shadowing builtins or existing functions and + use it when redefining compadd et al. + 2022-06-03 Jun-ichi Takimoto * 50306: Src/jobs.c, Src/signals.c, Test/A05execution.ztst: fix diff --git a/Completion/Base/Utility/_shadow b/Completion/Base/Utility/_shadow new file mode 100644 index 000000000..5b0f79c36 --- /dev/null +++ b/Completion/Base/Utility/_shadow @@ -0,0 +1,71 @@ +#autoload + +## Recommended usage: +# { +# _shadow fname +# function fname { +# # Do your new thing +# } +# # Invoke callers of fname +# } always { +# _unshadow fname +# } +## Alternate usage: +# { +# _shadow -s suffix fname +# function fname { +# # Do other stuff +# fname@suffix new args for fname +# } +# # Invoke callers of fname +# } always { +# _unshadow -s suffix fname +# } +## + +# BUGS: +# * `functions -c` acts like `autoload +X` +# * name collisions are possible in alternate usage +# * functions that examine $0 probably misfire + +zmodload zsh/parameter # Or what? + +# This probably never comes up, but protect ourself from recursive call +# chains that may duplicate the top elements of $funcstack by creating +# a counter of _shadow calls and using it to make shadow names unique. +typeset -gHi _shadowdepth=0 + +# Create a copy of each fname so that a caller may redefine +_shadow() { + local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:$((_shadowdepth+1)) ) + local fname + zparseopts -K -A fsfx -D s: + for fname; do + local shadowname=${fname}@${fsfx[-s]} + (( ${+functions[$fname]} )) && + builtin functions -c $fname $shadowname + done + ((_shadowdepth++)) +} + +# Remove the redefined function and shadowing name +_unshadow() { + local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:${_shadowdepth} ) + local fname + zparseopts -K -A fsfx -D s: + for fname; do + local shadowname=${fname}@${fsfx[-s]} + if (( ${+functions[$shadowname]} )); then + builtin functions -c $shadowname $fname + builtin unfunction $shadowname + elif (( ${+functions[$fname]} )); then + builtin unfunction $fname + fi + done + ((_shadowdepth--)) +} + +# This is tricky. When we call _shadow recursively from autoload, +# there's an extra level of stack in $functrace that will confuse +# the later call to _unshadow. Fool ourself into working correctly. +(( ARGC )) && _shadow -s ${funcstack[2]}:${functrace[2]}:1 "$@" diff --git a/Completion/Base/Widget/_complete_help b/Completion/Base/Widget/_complete_help index 69855de9d..da5947e7f 100644 --- a/Completion/Base/Widget/_complete_help +++ b/Completion/Base/Widget/_complete_help @@ -10,6 +10,7 @@ _complete_help() { local -H _help_filter_funcstack="alternative|call_function|describe|dispatch|wanted|requested|all_labels|next_label" { + _shadow compadd compcall zstyle compadd() { return 1 } compcall() { _help_sort_tags use-compctl } zstyle() { @@ -43,7 +44,7 @@ _complete_help() { ${1:-_main_complete} } always { - unfunction compadd compcall zstyle + _unshadow compadd compcall zstyle } for i in "${(@ok)help_funcs}"; do diff --git a/Functions/Zle/keeper b/Functions/Zle/keeper index a40125771..1570eb94a 100644 --- a/Functions/Zle/keeper +++ b/Functions/Zle/keeper @@ -73,6 +73,7 @@ zstyle ':completion:expand-kept-result:*' completer _insert_kept _expand_word_and_keep() { { + _shadow compadd function compadd { local -A args zparseopts -E -A args J: @@ -85,7 +86,7 @@ _expand_word_and_keep() { } _expand_word } always { - unfunction compadd + _unshadow compadd } } -- cgit v1.2.3 From b26b6b3fe00b94a2d4370b1afd2644034947b6b8 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 7 Jun 2022 10:02:14 +0100 Subject: Tweaks to MULTI_FUNC_DEF Output multiple function definitions using "function" form. Note exceptions to errors with NO_MULTI_FUNC_DEF --- ChangeLog | 6 ++++++ Doc/Zsh/options.yo | 5 +++++ Src/text.c | 12 ++++++++++-- Test/C04funcdef.ztst | 20 ++++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5490385f7..71f879776 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-06-07 Peter Stephenson + + * 50339: Doc/Zsh/options.yo, Src/text.c, Test/C04funcdef.ztst: + Make multiple function output safer with NO_MULTI_FUNC_DEF and + document exceptions to errors raised by MULTI_FUNC_DEF. + 2022-06-04 Bart Schaefer * 50323: Completion/Base/Utility/_shadow (new file), diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 5e673eb5c..bf73664c9 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1884,6 +1884,11 @@ fn2)var(...)tt(LPAR()RPAR())'; if the option is not set, this causes a parse error. Definition of multiple functions with the tt(function) keyword is always allowed. Multiple function definitions are not often used and can cause obscure errors. + +Note that no error is raised if multiple functions are defined as a +result of a set of names that were originally read as a single word on +the command line, for example `tt(TRAP{INT,QUIT})'. Although there are +no plans to change this behaviour at present, it is not guaranteed. ) pindex(MULTIOS) pindex(NO_MULTIOS) diff --git a/Src/text.c b/Src/text.c index 5cd7685fd..56127c457 100644 --- a/Src/text.c +++ b/Src/text.c @@ -578,11 +578,16 @@ gettext2(Estate state) Wordcode end = p + WC_FUNCDEF_SKIP(code); int nargs = *state->pc++; + if (nargs > 1) + taddstr("function "); taddlist(state, nargs); if (nargs) taddstr(" "); if (tjob) { - taddstr("() { ... }"); + if (nargs > 1) + taddstr("{ ... }"); + else + taddstr("() { ... }"); state->pc = end; if (!nargs) { /* @@ -594,7 +599,10 @@ gettext2(Estate state) } stack = 1; } else { - taddstr("() {"); + if (nargs > 1) + taddstr("{"); + else + taddstr("() {"); tindent++; taddnl(1); n = tpush(code, 1); diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index af469c527..b8509b25c 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -53,6 +53,26 @@ >b: redirection >a: redirection + define_multiple() { + fn1 fn2 fn3() { + print This is $0 + } + } + which -x2 define_multiple + define_multiple + fn1 + fn2 + fn3 +0: Safe output of multiple function definitions +>define_multiple () { +> function fn1 fn2 fn3 { +> print This is $0 +> } +>} +>This is fn1 +>This is fn2 +>This is fn3 + functions -M m1 m1() { (( $# )) } print $(( m1() )) -- cgit v1.2.3 From 52761c94185f8405d8069c1d4bacc8b5210a1850 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 8 Jun 2022 20:41:24 -0700 Subject: 50335: simplify "wait" usage, fix signal handling - remove the preliminary "wait" for all the process - remove "nomonitor" (because it was only needed for that "wait") - explicitly adds traps to exit for tty-generated signals plus TERM - capture the signal trap context and restore it in background jobs - wrap in an "always" block to clean up local helper functions - update comments to note another buglet and drop support for zsh 4.x. --- ChangeLog | 5 +++++ Functions/Misc/zargs | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 71f879776..c13d8a163 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-06-08 Bart Schaefer + + * 50335: Functions/Misc/zargs: simplify "wait" usage, fix signal + handling for functions used as the command. + 2022-06-07 Peter Stephenson * 50339: Doc/Zsh/options.yo, Src/text.c, Test/C04funcdef.ztst: diff --git a/Functions/Misc/zargs b/Functions/Misc/zargs index 81916a3ac..782d6811e 100644 --- a/Functions/Misc/zargs +++ b/Functions/Misc/zargs @@ -39,9 +39,14 @@ # # "Killed by a signal" is determined by the usual shell rule that $? is # the signal number plus 128, so zargs can be fooled by a command that -# explicitly exits with 129+. Also, zsh prior to 4.1.x returns 1 rather -# than 127 for "command not found" so this function incorrectly returns -# 123 in that case if used with zsh 4.0.x. +# explicitly exits with 129+. If the command passed to zargs is a shell +# function which uses "exit" instead of "return", zsh interprets 129+ as +# a signal sent to the process group and may terminate zargs with that +# status. This is avoided when running zargs -P 2 or greater. +# +# ZARGS_VERSION 1.5 is the last to support zsh 4.x. Also, zsh prior to +# 4.1.x returns 1 rather than 127 for "command not found" so zargs +# incorrectly returned 123 in that case if used with zsh 4.0.x. # # Because of "wait" limitations, --max-procs spawns max-procs jobs, then # waits for all of those, then spawns another batch, etc. @@ -71,6 +76,10 @@ # * The use of SIGUSR1 and SIGUSR2 to change the number of parallel jobs # is not supported. +{ # Begin "always" block to reset locally defined functions + +local ZARGS_VERSION="1.8" + # First, capture the current setopts as "sticky emulation" if zmodload zsh/parameter then @@ -84,11 +93,20 @@ else emulate $(emulate -l) -c '_zarun() { eval "$@" }' fi +local _zaTRAPS="$(trap)" +_zatraps() { + # In children, these traps may be reset to default behavior, even + # if the calling shell has traps. Restore to surrounding context, + # but assure that if zargs itself is signaled, children will exit. + [[ -o interactive ]] && + function TRAP{HUP,INT,QUIT,TERM} { exit $((128 + $1)) } + [[ -n "$_zaTRAPS" ]] && eval "$_zaTRAPS" + unset _zaTRAPS +} + emulate -L zsh || return 1 local -a opts eof n s l P i -local ZARGS_VERSION="1.7" - if zparseopts -a opts -D -- \ -eof::=eof e::=eof \ -exit x \ @@ -193,14 +211,14 @@ then (( c = $#command - 1 )) else command=( print -r -- ) fi -local wait bg -local execute=' +local bg execute=' if (( $opts[(I)-(-interactive|p)] )) then read -q "?$call?..." || continue elif (( $opts[(I)-(-verbose|t)] )) then print -u2 -r -- "$call" fi _zarun "{ + _zatraps \"\${call[@]}\" } $bg"' local ret=0 analyze=' @@ -263,12 +281,10 @@ fi if (( P != 1 && ARGC > 1 )) then - # These setopts are necessary for "wait" on multiple jobs to work. - setopt nonotify nomonitor + setopt nonotify # Do not report each exiting job local -a _zajobs local j bg='& _zajobs+=( $! )' - wait='wait' analyze=' for j in $_zajobs; do wait $j @@ -316,4 +332,8 @@ return $ret ) +} always { + builtin unfunction _zarun _zatraps +} + # } -- cgit v1.2.3 From 734740a5ed52d236f3893cc738fb09c7203a5138 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 8 Jun 2022 20:48:42 -0700 Subject: 50341: disallow here-document markers containing newline --- ChangeLog | 2 ++ Src/parse.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index c13d8a163..b16668984 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2022-06-08 Bart Schaefer + * 50341: Src/parse.c: disallow here-doc markers containing newline + * 50335: Functions/Misc/zargs: simplify "wait" usage, fix signal handling for functions used as the command. diff --git a/Src/parse.c b/Src/parse.c index d612b7e17..5054e59d5 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -2248,6 +2248,9 @@ par_redir(int *rp, char *idstring) struct heredocs **hd; int htype = type; + if (strchr(tokstr, '\n')) + YYERROR(ecused); + /* * Add two here for the string to remember the HERE * terminator in raw and munged form. -- cgit v1.2.3 From c36068357b32b90cf034991bad7e9e1386c396c7 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 9 Jun 2022 15:08:39 +0900 Subject: 50342: fix test added by 50306 --- ChangeLog | 5 +++++ Src/jobs.c | 2 ++ Test/A05execution.ztst | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b16668984..2dce207dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-06-09 Jun-ichi Takimoto + + * 50342: Src/jobs.c, Test/A05execution.ztst: fix test added by + 50306 + 2022-06-08 Bart Schaefer * 50341: Src/parse.c: disallow here-doc markers containing newline diff --git a/Src/jobs.c b/Src/jobs.c index aa32f4e80..e0e453ed8 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -2221,7 +2221,9 @@ addbgstatus(pid_t pid, int status) { static long child_max; Bgstatus bgstatus_entry; +#ifdef DEBUG LinkNode node; +#endif if (!child_max) { #ifdef _SC_CHILD_MAX diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst index b257ddf2c..bcadc6d56 100644 --- a/Test/A05execution.ztst +++ b/Test/A05execution.ztst @@ -396,7 +396,7 @@ F:anonymous function, and a descriptor leak when backgrounding a pipeline # TBD: the 0 above is believed to be bogus and should also be turned # into 127 when the ccorresponding bug is fixed in the main shell. - sleep 1 & pid=$! + sleep 2 & pid=$! kill -STOP $pid sleep 1 kill -CONT $pid -- cgit v1.2.3 From d24ab95469fd5514e308fcb4926a218abe492082 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 9 Jun 2022 13:30:55 -0700 Subject: 50351: "functions -c" can set signal traps --- ChangeLog | 4 ++++ Src/builtin.c | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2dce207dc..742e7d716 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-06-09 Bart Schaefer + + * 50351: Src/builtin.c: "functions -c" can set signal traps + 2022-06-09 Jun-ichi Takimoto * 50342: Src/jobs.c, Test/A05execution.ztst: fix test added by diff --git a/Src/builtin.c b/Src/builtin.c index 1cef7cce8..7f00d9d29 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3274,6 +3274,7 @@ bin_functions(char *name, char **argv, Options ops, int func) if (OPT_ISSET(ops,'c')) { Shfunc newsh; + char *s = argv[1]; if (!*argv || !argv[1] || argv[2]) { zwarnnam(name, "-c: requires two arguments"); return 1; @@ -3305,7 +3306,21 @@ bin_functions(char *name, char **argv, Options ops, int func) newsh->redir->nref++; if (shf->sticky) newsh->sticky = sticky_emulation_dup(sticky, 0); - shfunctab->addnode(shfunctab, ztrdup(argv[1]), &newsh->node); + /* is newsh a signal trap? (adapted from exec.c) */ + if (!strncmp(s, "TRAP", 4)) { + int signum = getsignum(s + 4); + if (signum != -1) { + if (settrap(signum, NULL, ZSIG_FUNC)) { + freeeprog(newsh->funcdef); + dircache_set(&newsh->filename, NULL); + zfree(newsh, sizeof(*newsh)); + return 1; + } + /* Remove any old node explicitly */ + removetrapnode(signum); + } + } + shfunctab->addnode(shfunctab, ztrdup(s), &newsh->node); return 0; } -- cgit v1.2.3 From d4955bc0f9403551503012c3f36c841210ce0cd5 Mon Sep 17 00:00:00 2001 From: Matthew Martin Date: Thu, 9 Jun 2022 13:37:51 -0700 Subject: 50359: fix bad sticky-emulation in "functions -c" --- ChangeLog | 4 ++++ Src/builtin.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 742e7d716..dc2ec1e89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-06-09 Matthew Martin + + * 50359: Src/builtin.c: fix bad sticky-emulation in "functions -c" + 2022-06-09 Bart Schaefer * 50351: Src/builtin.c: "functions -c" can set signal traps diff --git a/Src/builtin.c b/Src/builtin.c index 7f00d9d29..a7b7755a7 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3305,7 +3305,7 @@ bin_functions(char *name, char **argv, Options ops, int func) if (newsh->redir) newsh->redir->nref++; if (shf->sticky) - newsh->sticky = sticky_emulation_dup(sticky, 0); + newsh->sticky = sticky_emulation_dup(shf->sticky, 0); /* is newsh a signal trap? (adapted from exec.c) */ if (!strncmp(s, "TRAP", 4)) { int signum = getsignum(s + 4); -- cgit v1.2.3 From 285b6c2538a3d5d427b13827679cb933a7e49c83 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 9 Jun 2022 15:10:43 -0700 Subject: 50363: avoid use of heap memory that depends on parameter scoping --- ChangeLog | 5 +++++ Src/Modules/param_private.c | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index dc2ec1e89..2995844ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-06-09 Bart Schaefer + + * 50363: Src/Modules/param_private.c: avoid use of heap memory + that depends on parameter scoping + 2022-06-09 Matthew Martin * 50359: Src/builtin.c: fix bad sticky-emulation in "functions -c" diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index c53839152..065fa63d2 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -92,7 +92,7 @@ makeprivate(HashNode hn, UNUSED(int flags)) makeprivate_error = 1; return; } - struct gsu_closure *gsu = zhalloc(sizeof(struct gsu_closure)); + struct gsu_closure *gsu = zalloc(sizeof(struct gsu_closure)); switch (PM_TYPE(pm->node.flags)) { case PM_SCALAR: gsu->g = (void *)(pm->gsu.s); @@ -269,6 +269,8 @@ pps_unsetfn(Param pm, int explicit) gsu->unsetfn(pm, explicit); if (explicit) pm->gsu.s = (GsuScalar)c; + else + zfree(c, sizeof(struct gsu_closure)); } /**/ @@ -306,6 +308,8 @@ ppi_unsetfn(Param pm, int explicit) gsu->unsetfn(pm, explicit); if (explicit) pm->gsu.i = (GsuInteger)c; + else + zfree(c, sizeof(struct gsu_closure)); } /**/ @@ -343,6 +347,8 @@ ppf_unsetfn(Param pm, int explicit) gsu->unsetfn(pm, explicit); if (explicit) pm->gsu.f = (GsuFloat)c; + else + zfree(c, sizeof(struct gsu_closure)); } /**/ @@ -381,6 +387,8 @@ ppa_unsetfn(Param pm, int explicit) gsu->unsetfn(pm, explicit); if (explicit) pm->gsu.a = (GsuArray)c; + else + zfree(c, sizeof(struct gsu_closure)); } static HashTable emptytable; @@ -420,6 +428,8 @@ pph_unsetfn(Param pm, int explicit) gsu->unsetfn(pm, explicit); if (explicit) pm->gsu.h = (GsuHash)c; + else + zfree(c, sizeof(struct gsu_closure)); } /* -- cgit v1.2.3 From 6a6e358baf1b40924dfe47300acaf34e5549850c Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Sat, 11 Jun 2022 14:09:02 +0900 Subject: 50356: work around a yodl bug (mishandling of \'e) the bug has been fixed at least in yodl-4.04.02 --- ChangeLog | 4 ++++ Etc/FAQ.yo | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2995844ae..33e3a4b17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-06-11 Jun-ichi Takimoto + + * 50356: Etc/FAQ.yo: work around a yodl bug (mishandling of \'e) + 2022-06-09 Bart Schaefer * 50363: Src/Modules/param_private.c: avoid use of heap memory diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 8bd7262fe..8a6895454 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -1055,8 +1055,9 @@ label(31) Other ways of causing word splitting include a judicious use of `eval': + COMMENT(CHAR(39) is a workaround for a bug in some versions of yodl)\ verb( - sentence="Longtemps, je me suis couch\\'e de bonne heure." + sentence="Longtemps, je me suis couch\\CHAR(39)e de bonne heure." eval "words=($sentence)" ) after which $words is an array with the words of $sentence (note -- cgit v1.2.3 From 61f35bb6264b04fc24e09144a2515227d5531826 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 11 Jun 2022 15:02:46 -0700 Subject: 50355: documentation and return status consistency in zsh/system module --- ChangeLog | 6 ++++++ Doc/Zsh/mod_system.yo | 16 +++++++++++++--- Src/Modules/system.c | 19 +++++++++++++++++-- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33e3a4b17..b5781f398 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-06-11 Bart Schaefer + + * 50355: Doc/Zsh/mod_system.yo, Src/Modules/system.c: make return + status values of sysopen consistent with other sys* functions, + make ERRNO values consistent for all, and update documentation + 2022-06-11 Jun-ichi Takimoto * 50356: Etc/FAQ.yo: work around a yodl bug (mishandling of \'e) diff --git a/Doc/Zsh/mod_system.yo b/Doc/Zsh/mod_system.yo index 884c3e753..e25201faa 100644 --- a/Doc/Zsh/mod_system.yo +++ b/Doc/Zsh/mod_system.yo @@ -74,6 +74,11 @@ truncate file to size 0 ) enditem() +A return status of 0 indicates the descriptor was successfully opened, +otherwise an error message is printed, and 1 is returned for an error +in the parameters to the command, or 2 is returned for a system error. +The parameter tt(ERRNO) is nonzero for system errors. + To close the file, use one of the following: example(tt(exec {)var(fd)tt(}<&-) @@ -123,11 +128,11 @@ error for which a message is printed to standard error. ) item(2)( There was an error on the read, or on polling the input file descriptor -for a timeout. The parameter tt(ERRNO) gives the error. +for a timeout. The parameter tt(ERRNO) identifies the error. ) item(3)( Data were successfully read, but there was an error writing them -to var(outfd). The parameter tt(ERRNO) gives the error. +to var(outfd). The parameter tt(ERRNO) identifies the error. ) item(4)( The attempt to read timed out. Note this does not set tt(ERRNO) as this @@ -147,6 +152,11 @@ expression. The tt(-u) option allows the file descriptor to be specified. By default the offset is specified relative to the start or the file but, with the tt(-w) option, it is possible to specify that the offset should be relative to the current position or the end of the file. + +The return status may be 0 for success, 1 for an error in the parameters +to the command, or 2 for an error on the seek; no error message is +printed in the last case, but the parameter tt(ERRNO) reflects +the error that occurred. ) item(tt(syswrite) [ tt(-c) var(countvar) ] [ tt(-o) var(outfd) ] var(data))( The data (a single string of bytes) are written to the file descriptor @@ -166,7 +176,7 @@ returning early. The return status may be 0 for success, 1 for an error in the parameters to the command, or 2 for an error on the write; no error message is -printed in the last case, but the parameter tt(ERRNO) will reflect +printed in the last case, but the parameter tt(ERRNO) reflects the error that occurred. ) xitem(tt(zsystem flock) [ tt(-t) var(timeout) ] [ tt(-i) var(interval) ] [ tt(-f) var(var) ] [tt(-er)] var(file)) diff --git a/Src/Modules/system.c b/Src/Modules/system.c index ea11ef037..929a8b002 100644 --- a/Src/Modules/system.c +++ b/Src/Modules/system.c @@ -74,6 +74,8 @@ bin_sysread(char *nam, char **args, Options ops, UNUSED(int func)) int infd = 0, outfd = -1, bufsize = SYSREAD_BUFSIZE, count; char *outvar = NULL, *countvar = NULL, *inbuf; + errno = 0; /* Distinguish non-system errors */ + /* -i: input file descriptor if not stdin */ if (OPT_ISSET(ops, 'i')) { infd = getposint(OPT_ARG(ops, 'i'), nam); @@ -238,6 +240,8 @@ bin_syswrite(char *nam, char **args, Options ops, UNUSED(int func)) int outfd = 1, len, count, totcount; char *countvar = NULL; + errno = 0; /* Distinguish non-system errors */ + /* -o: output file descriptor if not stdout */ if (OPT_ISSET(ops, 'o')) { outfd = getposint(OPT_ARG(ops, 'o'), nam); @@ -303,6 +307,13 @@ static struct { const char *name; int oflag; } openopts[] = { { "trunc", O_TRUNC } }; +/* + * Return values of bin_sysopen: + * 0 Success + * 1 Error in parameters to command + * 2 Error on open, ERRNO set by system + */ + /**/ static int bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func)) @@ -319,6 +330,8 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func)) int fdflags = 0; #endif + errno = 0; /* Distinguish non-system errors */ + if (!OPT_ISSET(ops, 'u')) { zwarnnam(nam, "file descriptor not specified"); return 1; @@ -374,12 +387,12 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func)) if (fd == -1) { zwarnnam(nam, "can't open file %s: %e", *args, errno); - return 1; + return 2; } moved_fd = (explicit > -1) ? redup(fd, explicit) : movefd(fd); if (moved_fd == -1) { zwarnnam(nam, "can't open file %s", *args); - return 1; + return 2; } #ifdef FD_CLOEXEC @@ -423,6 +436,8 @@ bin_sysseek(char *nam, char **args, Options ops, UNUSED(int func)) char *whence; off_t pos; + errno = 0; /* Distinguish non-system errors */ + /* -u: file descriptor if not stdin */ if (OPT_ISSET(ops, 'u')) { fd = getposint(OPT_ARG(ops, 'u'), nam); -- cgit v1.2.3 From fc431b59567497f124705687041bc9cd90d92824 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 14 Jun 2022 01:55:27 +0900 Subject: 50365: fix indent in FAQ (text version) Lack of indent of the 1st line of a paragraph is fixed, but now two or more consecutive blank lines will be copied to text output as is. --- ChangeLog | 4 ++++ Etc/FAQ.yo | 69 +++++++------------------------------------------------------- 2 files changed, 11 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5781f398..04a940ca1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-06-14 Jun-ichi Takimoto + + * 50365: Etc/FAQ.yo: fix indent in FAQ (text version) + 2022-06-11 Bart Schaefer * 50355: Doc/Zsh/mod_system.yo, Src/Modules/system.c: make return diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 8a6895454..ebe86c202 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -57,6 +57,11 @@ def(emdash)(0)(\ whentxt(--))\ SUBST(_LPAR_)(CHAR(40))\ SUBST(_RPAR_)(CHAR(41)) +COMMENT(-- preserve the indent of the 1st line of paragraph --)\ +IFDEF(txt)(\ + DEFINESYMBOL(XXparagraph)()\ + PUSHMACRO(PARAGRAPH)(0)(SYMBOLVALUE(XXparagraph))\ +)() myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(2010/02/15) COMMENT(-- the following are for Usenet and must appear first)\ description(\ @@ -163,7 +168,7 @@ Acknowledgments Copyright --- End of Contents --- -) +)\ chapter(Introducing zsh and how to install it) @@ -222,7 +227,6 @@ email(mail-server@rtfm.mit.edu) For any more eclectic information, you should contact the mailing list: see question link(6.2)(62). - sect(What is it?) Zsh is a UNIX command interpreter (shell) which of the standard @@ -242,7 +246,6 @@ sect(What is it?) included with the source distribution are highly recommended. A list of features is given in FEATURES, also with the source. - sect(What is it good at?) Here are some things that zsh is particularly good at. No claim of @@ -284,7 +287,6 @@ sect(What is it good at?) it() Spelling correction. ) - sect(On what machines will it run?) From version 3.0, zsh uses GNU autoconf as the installation @@ -313,7 +315,6 @@ sect(On what machines will it run?) signames.h file. This makes the signals code unusable. This often happens on Ultrix, HP-UX, IRIX (?). Install gawk if you experience such problems. - sect(What's the latest version?) Zsh 5.9 is the latest production version. For details of all the @@ -335,7 +336,6 @@ sect(What's the latest version?) users), or to enhance compatibility with other Bourne shell derivatives, or (mostly in the 3.0 series) to provide POSIX compliance. - sect(Where do I get it?) label(16) @@ -435,7 +435,6 @@ sect(I don't have root access: how do I make zsh my login shell?) /etc/shells on all appropriate machines, including NIS clients, or you may have problems with FTP to that machine. - chapter(How does zsh differ from...?) As has already been mentioned, zsh is most similar to ksh, while many @@ -639,7 +638,6 @@ link(2.3)(23). ) ) - sect(Similarities with csh) Although certain features aim to ease the withdrawal symptoms of csh @@ -673,7 +671,6 @@ sect(Similarities with csh) it() Arrays have csh-like features (see under link(2.1)(21)). ) - sect(Why do my csh aliases not work? (Plus other alias pitfalls.)) label(23) @@ -863,7 +860,6 @@ mytt(compctl) ) and can now bind tt(run-fg-editor) just like any other editor function. - sect(Similarities with bash) label(25) @@ -889,7 +885,6 @@ label(25) and `tt((#e))' to match the end. These require the option tt(EXTENDED_GLOB) to be set. - sect(Shouldn't zsh be more/less like ksh/(t)csh?) People often ask why zsh has all these `unnecessary' csh-like features, @@ -916,7 +911,6 @@ sect(Shouldn't zsh be more/less like ksh/(t)csh?) want. The introduction of loadable in modules in version 3.1 should help. - sect(What is zsh's support for Unicode/UTF-8?) `Unicode', or UCS for Universal Character Set, is the modern way @@ -935,7 +929,6 @@ sect(What is zsh's support for Unicode/UTF-8?) this becomes a production release.) This is discussed more fully below, see `Multibyte input and output'. - sect(Why does my bash script report an error when I run it under zsh?) label(28) @@ -996,7 +989,6 @@ label(28) languages and adjusting it accordingly, just like you would when translating a book from American English to British English. - chapter(How to get various things to work) sect(Why does mytt($var) where mytt(var="foo bar") not do what I expect?) @@ -1166,7 +1158,6 @@ sect(In which startup file do I put...?) put in tt(.zshrc) to save your history. - sect(What is the difference between `export' and the tt(ALL_EXPORT) option?) Normally, you would put a variable into the environment by using @@ -1192,7 +1183,6 @@ sect(What is the difference between `export' and the tt(ALL_EXPORT) option?) it immediately afterwards. Only those variables will be automatically exported. - sect(How do I turn off spelling correction/globbing for a single command?) In the first case, you presumably have mytt(setopt correctall) in an @@ -1217,7 +1207,6 @@ sect(How do I turn off spelling correction/globbing for a single command?) Note also that a shell function won't work: the no... directives must be expanded before the rest of the command line is parsed. - sect(How do I get the Meta key to work on my xterm?) label(35) @@ -1255,7 +1244,6 @@ label(35) each byte is used to indicate a part of a multibyte character. See link(chapter 5)(c5). - sect(How do I automatically display the directory in my xterm title bar?) You should use the special function mytt(chpwd), which is called when @@ -1283,7 +1271,6 @@ sect(How do I automatically display the directory in my xterm title bar?) directly: just put mytt(chpwd) in tt(.zshrc) after it is defined or \ autoloaded. - sect(How do I make the completion list use eight bit characters?) If you are sure your terminal handles this, the easiest way from versions @@ -1297,7 +1284,6 @@ sect(How do I make the completion list use eight bit characters?) possibility may be to set tt(LC_ALL=en_US). For older versions of the shell, there is no easy way out. - sect(Why do the cursor (arrow) keys not work? (And other terminal oddities.)) The cursor keys send different codes depending on the terminal; zsh @@ -1365,7 +1351,6 @@ sect(Why do the cursor (arrow) keys not work? (And other terminal oddities.)) what we used to get the cursor keys above), replace mytt(echoti smkx) with mytt(echotc ks) and replace mytt(echoti rmkx) with mytt(echotc ke). - sect(Why does my terminal act funny in some way?) If you are using an OpenWindows cmdtool as your terminal, any @@ -1408,7 +1393,6 @@ sect(Why does my terminal act funny in some way?) afterwards: just the modes it uses itself and a number of special processing characters (see the tt(stty(1)) manual page). - sect(Why does zsh not work in an Emacs shell mode any more?) (This information comes from Bart Schaefer and other zsh-workers.) @@ -1438,7 +1422,6 @@ sect(Why does zsh not work in an Emacs shell mode any more?) ) to ~/.emacs. - sect(Why do my autoloaded functions not autoload [the first time]?) The problem is that there are two possible ways of autoloading a @@ -1484,7 +1467,6 @@ sect(Why do my autoloaded functions not autoload [the first time]?) parentheses removes the directory part of the filenames, leaving just the function names.) - sect(How does base arithmetic work?) The ksh syntax is now understood, i.e. @@ -1528,7 +1510,6 @@ sect(How does base arithmetic work?) print $(( [#16] 255 )) ) - sect(How do I get a newline in my prompt?) label(313) @@ -1551,7 +1532,6 @@ label(313) is a neat way of doing what you want. Note that it is the quotes, not the prompt expansion, which turns the `tt(\n)' into a newline. - sect(Why does mytt(bindkey ^a command-name) or mytt(stty intr ^-) do something funny?) You probably have the extendedglob option set in which case tt(^) and tt(#) @@ -1561,7 +1541,6 @@ sect(Why does mytt(bindkey ^a command-name) or mytt(stty intr ^-) do something f See link(3.27)(327) if you want to know more about the pattern character mytt(^). - sect(Why can't I bind tt(\C-s) and tt(\C-q) any more?) The control-s and control-q keys now do flow control by default, @@ -1575,7 +1554,6 @@ sect(Why can't I bind tt(\C-s) and tt(\C-q) any more?) control and hence restoring the use of the keys: put mytt(setopt noflowcontrol) in your tt(.zshrc) file. - sect(How do I execute command mytt(foo) within function mytt(foo)?) The command mytt(command foo) does just that. You don't need this with @@ -1587,7 +1565,6 @@ sect(How do I execute command mytt(foo) within function mytt(foo)?) using `command'. If mytt(foo) is a builtin rather than an external command, use mytt(builtin foo) instead. - sect(Why do history substitutions with single bangs do something funny?) If you have a command like "tt(echo !-2:$ !$)", the first history @@ -1596,7 +1573,6 @@ sect(Why do history substitutions with single bangs do something funny?) tt(!-2:$). The option tt(CSH_JUNKIE_HISTORY) makes all single bangs refer to the last command. - sect(Why does zsh kill off all my background jobs when I logout?) Simple answer: you haven't asked it not to. Zsh (unlike [t]csh) gives @@ -1614,13 +1590,11 @@ sect(Why does zsh kill off all my background jobs when I logout?) Likewise, you can start a background job with mytt(&!) instead of just mytt(&) at the end, which will automatically disown the job. - sect(How do I list all my history entries?) Tell zsh to start from entry 1: mytt(history 1). Those entries at the start which are no longer in memory will be silently omitted. - sect(How does the alternative loop syntax, e.g. mytt(while {...} {...}) \ work?) @@ -1678,7 +1652,6 @@ work?) manual), which you are in any case encouraged even more strongly not to use in programs as it can be very confusing. - sect(Why is my history not being saved?) label(321) @@ -1696,7 +1669,6 @@ label(321) above. There are also various options affecting history; see the manual. - sect(How do I get a variable's value to be evaluated as another variable?) The problem is that you have a variable tt($E) containing the string @@ -1733,7 +1705,6 @@ sect(How do I get a variable's value to be evaluated as another variable?) it, this works). So in mytt(${${E}}), the internal mytt(${...}) actually does nothing. - sect(How do I prevent the prompt overwriting output when there is no newline?) The problem is normally limited to zsh versions prior to 4.3.0 due to the @@ -1776,7 +1747,6 @@ sect(How do I prevent the prompt overwriting output when there is no newline?) One final alternative is to put a newline in your prompt -- see question link(3.13)(313) for that. - sect(What's wrong with cut and paste on my xterm?) On the majority of modern UNIX systems, cutting text from one window and @@ -1815,7 +1785,6 @@ sect(What's wrong with cut and paste on my xterm?) in the tt(zshparam) manual page for details. ) - sect(How do I get coloured prompts on my colour xterm?) (Or `color xterm', if you're reading this in black and white.) @@ -1859,7 +1828,6 @@ sect(How do I get coloured prompts on my colour xterm?) `mytt([0m)' puts printing back to normal so that the rest of the line is unchanged. - sect(Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?) This is a slightly unexpected effect of the option tt(MULTIOS), which is @@ -1903,7 +1871,6 @@ sect(Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?) (to the pipe) and start anew with tt(>foo.out) instead of adding it as a redirection target to stdout. - sect(What are these `^' and `~' pattern characters, anyway?) label(327) @@ -2030,7 +1997,6 @@ label(327) in the current directory or any parent.) ) - sect(How do I edit the input buffer in $EDITOR?) label(328) @@ -2046,7 +2012,6 @@ label(328) command-line for editing. The command will not be automatically executed; quitting the editor will only return to zsh's command-line editing mode. - sect(Why does `which' output for missing commands go to stdout?) The issue is that if you run: @@ -2076,7 +2041,6 @@ sect(Why does `which' output for missing commands go to stdout?) other Bourne-style shells it is in fact self-consistent. Note that the exit status does reflect the fact the command can't be found. - sect(Why doesn't the expansion mytt(*.{tex,aux,pdf}) do what I expect?) Based on the behaviour of some other shells, you might guess that the @@ -2114,10 +2078,8 @@ sect(Why doesn't the expansion mytt(*.{tex,aux,pdf}) do what I expect?) This is harder for the user to remember but easier for the shell to parse! - chapter(The mysteries of completion) - sect(What is completion?) `Completion' is where you hit a particular command key (TAB is the @@ -2147,7 +2109,6 @@ sect(What is completion?) compinit; compinit)' in your tt(.zshrc) should be enough if the system is installed properly. - sect(What sorts of things can be completed?) label(42) @@ -2171,7 +2132,6 @@ label(42) `anything where an automated guess is possible'. Just hit TAB and see if the shell manages to guess correctly. - sect(How does zsh deal with ambiguous completions?) Often there will be more than one possible completion: two files @@ -2209,7 +2169,6 @@ sect(How does zsh deal with ambiguous completions?) from version 3.1 tt(LIST_AMBIGUOUS) is set by default; if you use autolist, you may well want to `unsetopt listambiguous'. - sect(How do I complete in the middle of words / just what's before the cursor?) Sometimes you have a word on the command-line which is incomplete in the @@ -2238,7 +2197,6 @@ sect(How do I complete in the middle of words / just what's before the cursor?) can expand to tt(/usr/local/bin) or anything else that matches. This saves you having to expand the middle part of the path separately. - sect(How do I get started with programmable completion?) label(45) @@ -2251,7 +2209,6 @@ label(45) tells you how to configure the completion system and chapter 15 how to write your own completion functions. - sect(Suppose I want to complete all files during a special completion?) If you're using the completion system the shell will decide what @@ -2283,7 +2240,6 @@ sect(Suppose I want to complete all files during a special completion?) completion. Your actual completer style may include other actions, such as expansion or approximate completion. - chapter(Multibyte input and output) label(c5) @@ -2334,7 +2290,6 @@ sect(What is multibyte input?) way, for example on Windows, but the shell can't deal directly with text in those formats.) - sect(How does zsh handle multibyte input and output?) Until version 4.3, zsh didn't handle multibyte input properly at all. @@ -2379,7 +2334,6 @@ sect(How does zsh handle multibyte input and output?) in inverse video. Highlighting of such special characters can be modified using the new array parameter tt(zle_highlight). - sect(How do I ensure multibyte input and output work on my system?) Once you have a version of zsh with multibyte support, you need to @@ -2451,7 +2405,6 @@ sect(How do I ensure multibyte input and output work on my system?) to compile with the tt(MULTIBYTE) option enabled, but the system didn't provide full support for it. - sect(How can I input characters that aren't on my keyboard?) Two functions are provided with zsh that help you input characters. @@ -2495,7 +2448,6 @@ url(http://www.unicode.org/charts/)(http://www.unicode.org/charts/). See also url(http://www.cl.cam.ac.uk/~mgk25/unicode.html#input)(http://www.cl.cam.ac.uk/~mgk25/unicode.html#input) for general information on entering Unicode characters from a keyboard. - chapter(The future of zsh) sect(What bugs are currently known and unfixed? (Plus recent \ @@ -2512,7 +2464,6 @@ label(61) most important changes, and in particular draws attention to incompatibilities you might notice. - sect(Where do I report bugs, get more info / who's working on zsh?) label(62) @@ -2577,7 +2528,6 @@ label(62) Of course, you can also post zsh queries to the Usenet group comp.unix.shell; if all else fails, you could even e-mail me. - sect(What's on the wish-list?) The code bears the marks of the ages and many things could be done much @@ -2601,7 +2551,6 @@ sect(What's on the wish-list?) it() Option for glob qualifiers to follow perl syntax (a traditional item). ) - sect(Did zsh have problems in the year 2000?) Not that I heard of; it's up to you to be careful with two-digit dates, @@ -2609,7 +2558,6 @@ sect(Did zsh have problems in the year 2000?) and also by the command `tt(print -P)'. Earlier versions of zsh may show problems here. - sect(When reporting a bug, how do I reduce my mytt(.zshrc) into a minimal reproduction recipe?) When reporting a bug, the gold standard is to include with the bug @@ -2623,9 +2571,8 @@ sect(When reporting a bug, how do I reduce my mytt(.zshrc) into a minimal reprod and then, within that instance of the shell, run a minimal short sequence of commands that reproduces the bug. A good way to devise such recipes is the following: - COMMENT(For reference, here's Vim's write-up of a similar process: -https://github.com/chrisbra/vim_faq/blob/de424bd8e08bcf0e6b1e0563ee49514dfed926ae/vim_faq.txt#L1153-L1228) +https://github.com/chrisbra/vim_faq/blob/de424bd8e08bcf0e6b1e0563ee49514dfed926ae/vim_faq.txt#L1153-L1228)\ enumeration( myeit() First, ensure the bug is reproducible. To do this, start @@ -2701,7 +2648,6 @@ https://github.com/chrisbra/vim_faq/blob/de424bd8e08bcf0e6b1e0563ee49514dfed926a Bug reports should be emailed to the mytt(zsh-workers@zsh.org) public mailing list; see link(6.2)(62) for details. - nsect(Acknowledgments:) Thanks to zsh-list, in particular Bart Schaefer, for suggestions @@ -2713,7 +2659,6 @@ thanks. The world is eternally in the debt of Paul Falstad for inventing zsh in the first place (though the wizzo extended completion is by Sven Wischnowsky). - nsect(Copyright Information:) This document is copyright (C) P.W. Stephenson, 1995, 1996, 1997, -- cgit v1.2.3 From 123497b78e850b845d2054303612c25bccb887e3 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 16 Jun 2022 17:25:01 +0100 Subject: 50372: remove Usenet references from FAQ --- ChangeLog | 5 +++++ Etc/FAQ.yo | 40 ++++------------------------------------ 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 04a940ca1..d8a057fcd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-06-16 Peter Stephenson + + * 50372: Etc/FAQ.yo: remove redundant references from days of + Usenet posting. + 2022-06-14 Jun-ichi Takimoto * 50365: Etc/FAQ.yo: fix indent in FAQ (text version) diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index ebe86c202..8c795685a 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -35,7 +35,7 @@ def(myeit)(0)(\ def(myeitd)(0)(\ whenlatex(eit())whenhtml(eit())whenman(eit())whenms(eit())whensgml(eit())\ whentxt(.))\ -COMMENT(-- don't want headers for text, USENET headers must come first --)\ +COMMENT(-- don't want headers for text --)\ def(myreport)(3)(\ whentxt(report()()())\ whenhtml(report(ARG1)(ARG2)(ARG3))\ @@ -63,14 +63,6 @@ IFDEF(txt)(\ PUSHMACRO(PARAGRAPH)(0)(SYMBOLVALUE(XXparagraph))\ )() myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(2010/02/15) -COMMENT(-- the following are for Usenet and must appear first)\ -description(\ -mydit(Archive-Name:) unix-faq/shell/zsh -mydit(Last-Modified:) 2020/08/08 -mydit(Submitted-By:) email(coordinator@zsh.org (Peter Stephenson)) -mydit(Posting-Frequency:) Monthly -mydit(Copyright:) (C) P.W. Stephenson, 1995--2020 (see end of document) -) This document contains a list of frequently-asked (or otherwise significant) questions concerning the Z-shell, a command interpreter @@ -191,23 +183,6 @@ url(https://zsh.sourceforge.io/FAQ/)(https://zsh.sourceforge.io/FAQ/) . can be found at url(https://zsh.sourceforge.io/FAQ/zshfaq.txt) (https://zsh.sourceforge.io/FAQ/zshfaq.txt) . - Another useful source of information is the collection of FAQ articles - posted frequently to the Usenet news groups comp.unix.questions, - comp.unix.shells and comp.answers with answers to general questions - about UNIX. The fifth of the seven articles deals with shells, - including zsh, with a brief description of differences. There is - also a separate FAQ on shell differences and how to change your - shell. Usenet FAQs are available via FTP from rtfm.mit.edu and - mirrors and also on the World Wide Web; see - description( - mydit(USA) url(http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html) - (http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html) - mydit(UK) url(http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html) - (http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html) - mydit(Netherlands) url(http://www.cs.uu.nl/wais/html/na-dir/unix-faq/shell/.html) - (http://www.cs.uu.nl/wais/html/na-dir/unix-faq/shell/.html) - ) - You can also get it via email by emailing \ email(mail-server@rtfm.mit.edu) with, in the body of the message, mytt(send faqs/unix-faq/shell/zsh). @@ -439,8 +414,7 @@ chapter(How does zsh differ from...?) As has already been mentioned, zsh is most similar to ksh, while many of the additions are to please csh users. Here are some more detailed -notes. See also the article `UNIX shell differences and how to change -your shell' posted frequently to the USENET group comp.unix.shell. +notes. sect(Differences from sh and ksh) label(21) @@ -898,10 +872,7 @@ sect(Shouldn't zsh be more/less like ksh/(t)csh?) tt(CSH_JUNKIE) options. This argument still holds. On the other hand, the arguments for having what is close to a plug-in replacement for ksh are, if anything, even more powerful: the deficiencies of csh as a - programming language are well known (look in any Usenet FAQ archive, e.g. - url(http://www.cis.ohio-state.edu/hypertext/faq/usenet/unix-faq/\ - shell/csh-whynot/faq.html) -(http://www.cis.ohio-state.edu/hypertext/faq/usenet/unix-faq/shell/csh-whynot/faq.html) + programming language are well known (search for tt(csh-whynot) if you are in any doubt) and zsh is able to run many standard scripts such as /etc/rc. @@ -2517,7 +2488,7 @@ label(62) Mail email(sympa@zsh.org?subject=help) for detailed information. Administrative matters are best sent to email(zsh-workers-owner@zsh.org). - + Note that this location changed in August 2020, and the instructions to go with it are slightly different. @@ -2525,9 +2496,6 @@ label(62) url(http://www.zsh.org/mla/)(http://www.zsh.org/mla/) at the main zsh archive site. - Of course, you can also post zsh queries to the Usenet group - comp.unix.shell; if all else fails, you could even e-mail me. - sect(What's on the wish-list?) The code bears the marks of the ages and many things could be done much -- cgit v1.2.3 From f7441b46456c3acee4a2bd500b8f6409c70f33a8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 21 Jun 2022 17:58:57 -0700 Subject: 50368: adjust ztie'd bitflags so local variables cannot mess with database --- ChangeLog | 5 +++++ Src/Modules/db_gdbm.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8a057fcd..0cdd632f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-06-21 Bart Schaefer + + * 50368: Src/Modules/db_gdbm.c: adjust bitflags so local copies of + variables cannot mess with database file contents + 2022-06-16 Peter Stephenson * 50372: Etc/FAQ.yo: remove redundant references from days of diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index 7e11ec939..3fefd412b 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -34,8 +34,8 @@ #include "db_gdbm.mdh" #include "db_gdbm.pro" -#ifndef PM_UPTODATE -#define PM_UPTODATE (1<<19) /* Parameter has up-to-date data (e.g. loaded from DB) */ +#ifndef PM_UPTODATE /* Parameter has up-to-date data (e.g. loaded from DB) */ +#define PM_UPTODATE PM_DONTIMPORT_SUID /* Safe PM_ bit to re-use */ #endif static Param createhash( char *name, int flags ); @@ -111,7 +111,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func)) struct gsu_scalar_ext *dbf_carrier; char *resource_name, *pmname; GDBM_FILE dbf = NULL; - int read_write = GDBM_SYNC, pmflags = PM_REMOVABLE; + int read_write = GDBM_SYNC, pmflags = PM_REMOVABLE|PM_SINGLE; Param tied_param; if(!OPT_ISSET(ops,'d')) { -- cgit v1.2.3 From cb59dfb3a6f6cce414c5b852c138d5f6bea6d563 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 21 Jun 2022 18:04:45 -0700 Subject: 50379/50380: fix off-by-one side-effect of workers/49906 that broke $(jobs -l) --- ChangeLog | 3 +++ Src/jobs.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0cdd632f9..5220d2e83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-06-21 Bart Schaefer + * 50379 (tweaked per 50380): Src/jobs.c: fix off-by-one + side-effect of workers/49906 that broke $(jobs -l) + * 50368: Src/Modules/db_gdbm.c: adjust bitflags so local copies of variables cannot mess with database file contents diff --git a/Src/jobs.c b/Src/jobs.c index e0e453ed8..707374297 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -2402,7 +2402,7 @@ bin_fg(char *name, char **argv, Options ops, int func) int curmaxjob, ignorejob; if (unset(MONITOR) && oldmaxjob) { jobptr = oldjobtab; - curmaxjob = oldmaxjob ? oldmaxjob - 1 : 0; + curmaxjob = oldmaxjob; ignorejob = 0; } else { jobptr = jobtab; -- cgit v1.2.3 From 13c6b648385b550efde5bf7be4bdb97cb67dec5f Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 16 Jul 2022 20:53:59 -0700 Subject: users/27852: local _compskip to avoid propagating any changes by _normal --- ChangeLog | 5 +++++ Completion/Unix/Command/_python | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5220d2e83..d6d3f98d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-07-16 Bart Schaefer + + * users/27852: Completion/Unix/Command/_python: Make a local copy + of $_compskip to avoid propagating outward any changes by _normal + 2022-06-21 Bart Schaefer * 50379 (tweaked per 50380): Src/jobs.c: fix off-by-one diff --git a/Completion/Unix/Command/_python b/Completion/Unix/Command/_python index e5bac18bb..2711b8fd3 100644 --- a/Completion/Unix/Command/_python +++ b/Completion/Unix/Command/_python @@ -3,7 +3,7 @@ # Python 2.7 # Python 3.9 -local curcontext="$curcontext" state state_descr line +local curcontext="$curcontext" state state_descr line _compskip="$_compskip" typeset -A opt_args local -a args -- cgit v1.2.3 From ac6257f1507af144f7c88d030bbf076790d86a42 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Sun, 24 Jul 2022 20:41:20 +0900 Subject: 50418: use setenv(3)/getenv(3) on newer macOS --- ChangeLog | 5 +++++ Src/zsh_system.h | 3 ++- configure.ac | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d6d3f98d2..ce2ec2dd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-07-24 Jun-ichi Takimoto + + * 50418: Src/zsh_system.h, configure.ac: use setenv(3)/getenv(3) + on newer macOS + 2022-07-16 Bart Schaefer * users/27852: Completion/Unix/Command/_python: Make a local copy diff --git a/Src/zsh_system.h b/Src/zsh_system.h index 6f4efce96..16f724401 100644 --- a/Src/zsh_system.h +++ b/Src/zsh_system.h @@ -783,7 +783,8 @@ extern char **environ; * We always need setenv and unsetenv in pairs, because * we don't know how to do memory management on the values set. */ -#if defined(HAVE_SETENV) && defined(HAVE_UNSETENV) && !defined(__APPLE__) +#if defined(HAVE_SETENV) && defined(HAVE_UNSETENV) \ + && !defined(SETENV_MANGLES_EQUAL) # define USE_SET_UNSET_ENV #endif diff --git a/configure.ac b/configure.ac index 77e381f50..890ef8dd2 100644 --- a/configure.ac +++ b/configure.ac @@ -1515,6 +1515,14 @@ else zsh_cv_use_xattr=no fi]) +dnl We don't want to use setenv(3) on El Capitan or older OS X because it +dnl removes a leading '=' from the value of the environment variable +AH_TEMPLATE([SETENV_MANGLES_EQUAL], +[Define to 1 if setenv removes a leading =]) +case $host_os in + darwin1[0-5]*) AC_DEFINE(SETENV_MANGLES_EQUAL) ;; +esac + dnl ------------- dnl CHECK SIGNALS dnl ------------- -- cgit v1.2.3 From 8e1c6ed6bf416e7716b4c6d5c6822ec752db7b36 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Sun, 24 Jul 2022 21:08:06 +0900 Subject: 50421: add context as the 1st arg to _dispatch --- ChangeLog | 3 +++ Completion/Zsh/Context/_redirect | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ce2ec2dd3..660fbbd6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-07-24 Jun-ichi Takimoto + * 50421: Completion/Zsh/Context/_redirect: add missing context + as the 1st argument to _dispatch + * 50418: Src/zsh_system.h, configure.ac: use setenv(3)/getenv(3) on newer macOS diff --git a/Completion/Zsh/Context/_redirect b/Completion/Zsh/Context/_redirect index e6da5d115..520a7666e 100644 --- a/Completion/Zsh/Context/_redirect +++ b/Completion/Zsh/Context/_redirect @@ -15,4 +15,5 @@ if [[ "$CURRENT" != "1" ]]; then fi fi -_dispatch -redirect-,{${compstate[redirect]},-default-},${^strs} +_dispatch -redirect-,${compstate[redirect]},$_comp_command \ + -redirect-,{${compstate[redirect]},-default-},${^strs} -- cgit v1.2.3 From 7996fa561e93d9c27919ed4d4257c13d99db3807 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Fri, 5 Aug 2022 22:53:31 +0900 Subject: Felipe Contreras: 50435+50436 (+50444): do not build anything Use 'make -nqp' to ensure nothing is actually built by completion. Also include some performance improvements, but it can be still rather slow in a large project's source tree. --- ChangeLog | 6 ++++++ Completion/Unix/Command/_make | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 660fbbd6b..5b89a7d21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-08-05 Jun-ichi Takimoto + + * Felipe Contreras: 50435+50436 (+50444): + Completion/Unix/Command/_make: do not actually build anything. + Also include some performance improvements. + 2022-07-24 Jun-ichi Takimoto * 50421: Completion/Zsh/Context/_redirect: add missing context diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make index ae91440f0..510368e8b 100644 --- a/Completion/Unix/Command/_make +++ b/Completion/Unix/Command/_make @@ -118,10 +118,34 @@ _make-parseMakefile () { done } +_make-parseDataBase () { + local input var TAB=$'\t' IFS= skip=0 + + while read input + do + if [[ $skip = 1 ]]; then + skip=0 + continue + fi + case "$input " in + (\# Not a target*|\# environment*) + skip=1 # skip next line + ;; + ([[:alnum:]][[:alnum:]_]#[" "$TAB]#(\?|:|::|)=*) + var=${input%%[ $TAB]#(\?|:|::|)=*} + VARIABLES[$var]=1 + ;; + ([[*?[:alnum:]$][^$TAB:=%]#:[^=]*) + TARGETS+=( ${input%%:*} ) + ;; + esac + done +} + _make() { local prev="$words[CURRENT-1]" file expl tmp is_gnu incl match basedir nul=$'\0' - local context state state_descr line + local curcontext=$curcontext state state_descr line local -a option_specs local -A VARIABLES VAR_ARGS opt_args local -aU TARGETS keys @@ -185,7 +209,7 @@ _make() { ) fi - _arguments -s $option_specs \ + _arguments -C -S -s $option_specs \ '*:make target:->target' && ret=0 [[ $state = cdir ]] && cdir=-2 @@ -214,6 +238,10 @@ _make() { ;; (target) + # target name starting with '-' is allowed only after '--' + if [[ $words[CURRENT] = -* ]] && (( ${words[(i)--]} > CURRENT )); then + return ret + fi file=${(v)opt_args[(I)(-f|--file|--makefile)]} if [[ -n $file ]] then @@ -239,7 +267,7 @@ _make() { if [[ $is_gnu == gnu ]] then if zstyle -t ":completion:${curcontext}:targets" call-command; then - _make-parseMakefile < <(_call_program targets "$words[1]" -nsp --no-print-directory -f "$file" --always-make 2> /dev/null) + _make-parseDataBase < <(_call_program targets "$words[1]" -nqp --no-print-directory -f "$file" .DEFAULT 2> /dev/null) else _make-parseMakefile < $file fi -- cgit v1.2.3 From eb738c793a6f9f293fc655c6aa87effc3dd9e44f Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sun, 28 Aug 2022 16:45:48 +0000 Subject: unposted: _imagemagick: Add *.svg and *.webp files. As a comment just above the hunk indicates, many more formats could be added. --- ChangeLog | 5 +++++ Completion/Unix/Command/_imagemagick | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5b89a7d21..1b97eefcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-08-28 Daniel Shahaf + + * unposted: Completion/Unix/Command/_imagemagick: Add *.svg + and *.webp files. + 2022-08-05 Jun-ichi Takimoto * Felipe Contreras: 50435+50436 (+50444): diff --git a/Completion/Unix/Command/_imagemagick b/Completion/Unix/Command/_imagemagick index b7671fe49..6553868d9 100644 --- a/Completion/Unix/Command/_imagemagick +++ b/Completion/Unix/Command/_imagemagick @@ -12,7 +12,7 @@ typeset -A opt_args # # and certainly many other things... -formats=(jpg jpeg jp2 j2k jpc jpx jpf tif tiff miff ras bmp cgm dcx ps eps fig fits fpx gif mpeg pbm pgm ppm pcd pcl pdf pcx png rad rgb rgba rle sgi html shtml tga ttf uil xcf xwd xbm xpm yuv) +formats=(jpg jpeg jp2 j2k jpc jpx jpf tif tiff miff ras bmp cgm dcx ps eps fig fits fpx gif mpeg pbm pgm ppm pcd pcl pdf pcx png rad rgb rgba rle sgi html shtml tga ttf uil xcf xwd xbm xpm yuv svg webp) if (( $# )); then _files "$@" -g "*.(#i)(${(j:|:)formats})(-.)" -- cgit v1.2.3 From 4fc5dc0292acd77f17281f451774ba2ca4203026 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 15 Sep 2022 18:56:20 +0900 Subject: 50629: do not use egrep in tests --- ChangeLog | 6 ++++++ Test/D07multibyte.ztst | 16 ++-------------- Test/E01options.ztst | 2 +- Test/V07pcre.ztst | 16 ++-------------- Test/X02zlevi.ztst | 11 +---------- Test/X03zlebindkey.ztst | 11 +---------- Test/Y01completion.ztst | 11 +---------- Test/ztst.zsh | 15 +++++++++++++++ 8 files changed, 29 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b97eefcc..1f28ffcbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-09-15 Jun-ichi Takimoto + + * 50629: Test/D07multibyte.ztst, Test/E01options.ztst, + Test/V07pcre.ztst, Test/X02zlevi.ztst, Test/X03zlebindkey.ztst, + Test/Y01completion.ztst, Test/ztst.zsh: do not use egrep in tests + 2022-08-28 Daniel Shahaf * unposted: Completion/Unix/Command/_imagemagick: Add *.svg diff --git a/Test/D07multibyte.ztst b/Test/D07multibyte.ztst index e2e9a25ef..6909346cb 100644 --- a/Test/D07multibyte.ztst +++ b/Test/D07multibyte.ztst @@ -1,19 +1,7 @@ %prep -# Find a UTF-8 locale. - setopt multibyte -# Don't let LC_* override our choice of locale. - unset -m LC_\* - mb_ok= - langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 - $(locale -a 2>/dev/null | egrep 'utf8|UTF-8')) - for LANG in $langs; do - if [[ é = ? ]]; then - mb_ok=1 - break; - fi - done - if [[ -z $mb_ok ]]; then + LANG=$(ZTST_find_UTF8) + if [[ -z $LANG ]]; then ZTST_unimplemented="no UTF-8 locale or multibyte mode is not implemented" else print -u $ZTST_fd Testing multibyte with locale $LANG diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 2acbfd357..d38fbed74 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -651,7 +651,7 @@ >noktarg1 >0 1 - showopt() { setopt | egrep 'localoptions|ksharrays'; } + showopt() { echo ${(FM)${(@f)"$(setopt)"}:#(localoptions|ksharrays)*} } f1() { setopt localoptions ksharrays; showopt } f2() { setopt ksharrays; showopt } setopt kshoptionprint diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst index c9c844d2a..ca13419e5 100644 --- a/Test/V07pcre.ztst +++ b/Test/V07pcre.ztst @@ -6,20 +6,8 @@ return 0 fi setopt rematch_pcre -# Find a UTF-8 locale. - setopt multibyte -# Don't let LC_* override our choice of locale. - unset -m LC_\* - mb_ok= - langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 - $(locale -a 2>/dev/null | egrep 'utf8|UTF-8')) - for LANG in $langs; do - if [[ é = ? ]]; then - mb_ok=1 - break; - fi - done - if [[ -z $mb_ok ]]; then + LANG=$(ZTST_find_UTF8) + if [[ -z $LANG ]]; then ZTST_unimplemented="no UTF-8 locale or multibyte mode is not implemented" else print -u $ZTST_fd Testing PCRE multibyte with locale $LANG diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst index 8146d6752..203c13c32 100644 --- a/Test/X02zlevi.ztst +++ b/Test/X02zlevi.ztst @@ -1,16 +1,7 @@ # Tests of the vi mode of ZLE %prep - unset -m LC_\* - ZSH_TEST_LANG= - langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 - $(locale -a 2>/dev/null | egrep 'utf8|UTF-8')) - for LANG in $langs; do - if [[ é = ? ]]; then - ZSH_TEST_LANG=$LANG - break; - fi - done + ZSH_TEST_LANG=$(ZTST_find_UTF8) if ( zmodload zsh/zpty 2>/dev/null ); then . $ZTST_srcdir/comptest comptestinit -v -z $ZTST_testdir/../Src/zsh diff --git a/Test/X03zlebindkey.ztst b/Test/X03zlebindkey.ztst index 43692a85b..5277332a7 100644 --- a/Test/X03zlebindkey.ztst +++ b/Test/X03zlebindkey.ztst @@ -3,16 +3,7 @@ # into bindings. The latter is particularly tricky with multibyte sequences. %prep - unset -m LC_\* - ZSH_TEST_LANG= - langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 - $(locale -a 2>/dev/null | egrep 'utf8|UTF-8')) - for LANG in $langs; do - if [[ é = ? ]]; then - ZSH_TEST_LANG=$LANG - break; - fi - done + ZSH_TEST_LANG=$(ZTST_find_UTF8) if ( zmodload zsh/zpty 2>/dev/null ); then . $ZTST_srcdir/comptest comptestinit -z $ZTST_testdir/../Src/zsh diff --git a/Test/Y01completion.ztst b/Test/Y01completion.ztst index 6af0efc6d..f976f9f91 100644 --- a/Test/Y01completion.ztst +++ b/Test/Y01completion.ztst @@ -1,16 +1,7 @@ # Tests for completion system. %prep - unset -m LC_\* - ZSH_TEST_LANG= - langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 - $(locale -a 2>/dev/null | egrep 'utf8|UTF-8')) - for LANG in $langs; do - if [[ é = ? ]]; then - ZSH_TEST_LANG=$LANG - break; - fi - done + ZSH_TEST_LANG=$(ZTST_find_UTF8) if ( zmodload zsh/zpty 2>/dev/null ); then . $ZTST_srcdir/comptest mkdir comp.tmp diff --git a/Test/ztst.zsh b/Test/ztst.zsh index aca275c1c..d95b726e7 100755 --- a/Test/ztst.zsh +++ b/Test/ztst.zsh @@ -37,6 +37,21 @@ emulate -R zsh # LANG must be passed to child zsh. export LANG +# find UTF-8 locale +ZTST_find_UTF8 () { + setopt multibyte + # Don't let LC_* override our choice of locale. + unset -m LC_\* + local langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 + ${(M)$(locale -a 2>/dev/null):#*.(utf8|UTF-8)}) + for LANG in $langs; do + if [[ é = ? ]]; then + echo $LANG + return + fi + done +} + # Don't propagate variables that are set by default in the shell. typeset +x WORDCHARS -- cgit v1.2.3 From ab4d62eb975a4c4c51dd35822665050e2ddc6918 Mon Sep 17 00:00:00 2001 From: Nicholas Vinson Date: Wed, 21 Sep 2022 09:22:11 +0900 Subject: 50641: use 'int main()' in test C-codes in configure --- ChangeLog | 5 ++++ aczsh.m4 | 64 ++++++++++++++++++++--------------------- configure.ac | 94 ++++++++++++++++++++++++++---------------------------------- 3 files changed, 77 insertions(+), 86 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f28ffcbf..375172ec9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-09-21 Jun-ichi Takimoto + + * Nicholas Vinson: 50641: aczsh.m4, configure.ac: use 'int main()' + in test C-codes in configure + 2022-09-15 Jun-ichi Takimoto * 50629: Test/D07multibyte.ztst, Test/E01options.ztst, diff --git a/aczsh.m4 b/aczsh.m4 index 1209ac614..b31236020 100644 --- a/aczsh.m4 +++ b/aczsh.m4 @@ -44,6 +44,7 @@ AC_DEFUN(zsh_64_BIT_TYPE, #include #endif +int main() { $1 foo = 0; @@ -118,7 +119,6 @@ AC_TRY_COMMAND($DLLD -o conftest1.$DL_EXT $LDFLAGS $DLLDFLAGS conftest1.o $LIBS AC_TRY_COMMAND($CC -c $CFLAGS $CPPFLAGS $DLCFLAGS conftest2.c 1>&AS_MESSAGE_LOG_FD) && AC_TRY_COMMAND($DLLD -o conftest2.$DL_EXT $LDFLAGS $DLLDFLAGS conftest2.o $LIBS 1>&AS_MESSAGE_LOG_FD); then AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include #ifdef HPUX10DYNAMIC #include #define RTLD_LAZY BIND_DEFERRED @@ -146,29 +146,30 @@ char *zsh_gl_sym_addr ; #define RTLD_GLOBAL 0 #endif +int main() { void *handle1, *handle2; void *(*zsh_getaddr1)(), *(*zsh_getaddr2)(); void *sym1, *sym2; handle1 = dlopen("./conftest1.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle1) exit(1); + if(!handle1) return(1); handle2 = dlopen("./conftest2.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle2) exit(1); + if(!handle2) return(1); zsh_getaddr1 = (void *(*)()) dlsym(handle1, "${us}zsh_getaddr1"); zsh_getaddr2 = (void *(*)()) dlsym(handle2, "${us}zsh_getaddr2"); sym1 = zsh_getaddr1(); sym2 = zsh_getaddr2(); - if(!sym1 || !sym2) exit(1); - if(sym1 != sym2) exit(1); + if(!sym1 || !sym2) return(1); + if(sym1 != sym2) return(1); dlclose(handle1); handle1 = dlopen("./conftest1.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle1) exit(1); + if(!handle1) return(1); zsh_getaddr1 = (void *(*)()) dlsym(handle1, "${us}zsh_getaddr1"); sym1 = zsh_getaddr1(); - if(!sym1) exit(1); - if(sym1 != sym2) exit(1); - exit(0); + if(!sym1) return(1); + if(sym1 != sym2) return(1); + return(0); } ]])],[zsh_cv_shared_$1=yes], [zsh_cv_shared_$1=no], @@ -200,7 +201,6 @@ AC_TRY_COMMAND($DLLD -o conftest1.$DL_EXT $LDFLAGS $DLLDFLAGS conftest1.o $LIBS AC_TRY_COMMAND($CC -c $CFLAGS $CPPFLAGS $DLCFLAGS conftest2.c 1>&AS_MESSAGE_LOG_FD) && AC_TRY_COMMAND($DLLD -o conftest2.$DL_EXT $LDFLAGS $DLLDFLAGS conftest2.o $LIBS 1>&AS_MESSAGE_LOG_FD); then AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include #ifdef HPUX10DYNAMIC #include #define RTLD_LAZY BIND_DEFERRED @@ -228,19 +228,19 @@ char *zsh_gl_sym_addr ; #define RTLD_GLOBAL 0 #endif - +int main() { void *handle1, *handle2; int (*fred1)(), (*fred2)(); handle1 = dlopen("./conftest1.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle1) exit(1); + if(!handle1) return(1); handle2 = dlopen("./conftest2.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle2) exit(1); + if(!handle2) return(1); fred1 = (int (*)()) dlsym(handle1, "${us}fred"); fred2 = (int (*)()) dlsym(handle2, "${us}fred"); - if(!fred1 || !fred2) exit(1); - exit((*fred1)() != 42 || (*fred2)() != 69); + if(!fred1 || !fred2) return(1); + return((*fred1)() != 42 || (*fred2)() != 69); } ]])],[zsh_cv_sys_dynamic_clash_ok=yes], [zsh_cv_sys_dynamic_clash_ok=no], @@ -276,7 +276,6 @@ AC_TRY_COMMAND($DLLD -o conftest1.$DL_EXT $LDFLAGS $DLLDFLAGS conftest1.o $LIBS AC_TRY_COMMAND($CC -c $CFLAGS $CPPFLAGS $DLCFLAGS conftest2.c 1>&AS_MESSAGE_LOG_FD) && AC_TRY_COMMAND($DLLD -o conftest2.$DL_EXT $LDFLAGS $DLLDFLAGS conftest2.o $LIBS 1>&AS_MESSAGE_LOG_FD); then AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include #ifdef HPUX10DYNAMIC #include #define RTLD_LAZY BIND_DEFERRED @@ -304,17 +303,18 @@ char *zsh_gl_sym_addr ; #define RTLD_GLOBAL 0 #endif +int main() { void *handle; int (*barneysym)(); handle = dlopen("./conftest1.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle) exit(1); + if(!handle) return(1); handle = dlopen("./conftest2.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle) exit(1); + if(!handle) return(1); barneysym = (int (*)()) dlsym(handle, "${us}barney"); - if(!barneysym) exit(1); - exit((*barneysym)() != 69); + if(!barneysym) return(1); + return((*barneysym)() != 69); } ]])],[zsh_cv_sys_dynamic_rtld_global=yes], [zsh_cv_sys_dynamic_rtld_global=no], @@ -346,7 +346,6 @@ AC_TRY_COMMAND($DLLD -o conftest1.$DL_EXT $LDFLAGS $DLLDFLAGS conftest1.o $LIBS save_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include #ifdef HPUX10DYNAMIC #include #define RTLD_LAZY BIND_DEFERRED @@ -374,15 +373,16 @@ char *zsh_gl_sym_addr ; #define RTLD_GLOBAL 0 #endif +int main() { void *handle; int (*barneysym)(); handle = dlopen("./conftest1.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle) exit(1); + if(!handle) return(1); barneysym = (int (*)()) dlsym(handle, "${us}barney"); - if(!barneysym) exit(1); - exit((*barneysym)() != 69); + if(!barneysym) return(1); + return((*barneysym)() != 69); } int fred () { return 42; } @@ -420,7 +420,6 @@ elif save_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS -s" AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include #ifdef HPUX10DYNAMIC #include #define RTLD_LAZY BIND_DEFERRED @@ -448,15 +447,16 @@ char *zsh_gl_sym_addr ; #define RTLD_GLOBAL 0 #endif +int main() { void *handle; int (*barneysym)(); handle = dlopen("./conftest1.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle) exit(1); + if(!handle) return(1); barneysym = (int (*)()) dlsym(handle, "${us}barney"); - if(!barneysym) exit(1); - exit((*barneysym)() != 69); + if(!barneysym) return(1); + return((*barneysym)() != 69); } int fred () { return 42; } @@ -488,7 +488,6 @@ echo 'int fred () { return 42; }' > conftest1.c if AC_TRY_COMMAND($CC -c $CFLAGS $CPPFLAGS $DLCFLAGS conftest1.c 1>&AS_MESSAGE_LOG_FD) && AC_TRY_COMMAND($DLLD -o conftest1.$DL_EXT $LDFLAGS $DLLDFLAGS -s conftest1.o $LIBS 1>&AS_MESSAGE_LOG_FD); then AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include #ifdef HPUX10DYNAMIC #include #define RTLD_LAZY BIND_DEFERRED @@ -516,15 +515,16 @@ char *zsh_gl_sym_addr ; #define RTLD_GLOBAL 0 #endif +int main() { void *handle; int (*fredsym)(); handle = dlopen("./conftest1.$DL_EXT", RTLD_LAZY | RTLD_GLOBAL); - if(!handle) exit(1); + if(!handle) return(1); fredsym = (int (*)()) dlsym(handle, "${us}fred"); - if(!fredsym) exit(1); - exit((*fredsym)() != 42); + if(!fredsym) return(1); + return((*fredsym)() != 42); } ]])],[zsh_cv_sys_dynamic_strip_lib=yes], [zsh_cv_sys_dynamic_strip_lib=no], diff --git a/configure.ac b/configure.ac index 890ef8dd2..074141d38 100644 --- a/configure.ac +++ b/configure.ac @@ -585,7 +585,7 @@ fi dnl Checking if compiler correctly cast signed to unsigned. AC_CACHE_CHECK(if signed to unsigned casting is broken, zsh_cv_c_broken_signed_to_unsigned_casting, -[AC_RUN_IFELSE([AC_LANG_SOURCE([[main(){return((int)(unsigned char)((char) -1) == 255);}]])],[zsh_cv_c_broken_signed_to_unsigned_casting=yes],[zsh_cv_c_broken_signed_to_unsigned_casting=no],[zsh_cv_c_broken_signed_to_unsigned_casting=no])]) +[AC_RUN_IFELSE([AC_LANG_SOURCE([[int main(){return((int)(unsigned char)((char) -1) == 255);}]])],[zsh_cv_c_broken_signed_to_unsigned_casting=yes],[zsh_cv_c_broken_signed_to_unsigned_casting=no],[zsh_cv_c_broken_signed_to_unsigned_casting=no])]) AH_TEMPLATE([BROKEN_SIGNED_TO_UNSIGNED_CASTING], [Define to 1 if compiler incorrectly cast signed to unsigned.]) if test x$zsh_cv_c_broken_signed_to_unsigned_casting = xyes; then @@ -1046,7 +1046,7 @@ else [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include -main() { return sizeof(off_t) < 8; } +int main() { return sizeof(off_t) < 8; } ]])],[zsh_cv_off_t_is_64_bit=yes],[zsh_cv_off_t_is_64_bit=no],[zsh_cv_off_t_is_64_bit=no])]) if test x$zsh_cv_off_t_is_64_bit = xyes; then AC_DEFINE(OFF_T_IS_64_BIT) @@ -1056,7 +1056,7 @@ main() { return sizeof(off_t) < 8; } [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include -main() { return sizeof(ino_t) < 8; } +int main() { return sizeof(ino_t) < 8; } ]])],[zsh_cv_ino_t_is_64_bit=yes],[zsh_cv_ino_t_is_64_bit=no],[zsh_cv_ino_t_is_64_bit=no])]) if test x$zsh_cv_ino_t_is_64_bit = xyes; then AC_DEFINE(INO_T_IS_64_BIT) @@ -1369,7 +1369,7 @@ zsh_cv_func_realpath_accepts_null, #include #include ],[ -exit(!realpath("/", (char*)0)); +return(!realpath("/", (char*)0)); ])], [zsh_cv_func_realpath_accepts_null=yes], [zsh_cv_func_realpath_accepts_null=no], @@ -1393,10 +1393,9 @@ AC_CACHE_CHECK(if tgetent accepts NULL, zsh_cv_func_tgetent_accepts_null, [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include -#include int tgetent(char *, char *); char *tgetstr(char *, char **); -main() +int main() { char buf[4096]; int r1 = tgetent(buf, "vt100"); @@ -1407,7 +1406,7 @@ main() tgetstr("cl", &u); creat("conftest.tgetent", 0640); } - exit((r1 != r2) || r2 == -1); + return((r1 != r2) || r2 == -1); } ]])],[if test -f conftest.tgetent; then zsh_cv_func_tgetent_accepts_null=yes @@ -1421,10 +1420,9 @@ AC_CACHE_CHECK(if tgetent returns 0 on success, zsh_cv_func_tgetent_zero_success, [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include -#include int tgetent(char *, char*); char *tgetstr(char *, char **); -main() +int main() { char buf[4096]; int r1 = tgetent(buf, "!@#$%^&*"); @@ -1435,7 +1433,7 @@ main() tgetstr("cl", &u); creat("conftest.tgetent0", 0640); } - exit(r1 == r2); + return(r1 == r2); } ]])],[if test -f conftest.tgetent0; then zsh_cv_func_tgetent_zero_success=yes @@ -1869,8 +1867,7 @@ zsh_cv_rlim_t_is_longer, #include #endif #include -#include -main(){struct rlimit r;exit(sizeof(r.rlim_cur) <= sizeof(long));}]])],[zsh_cv_rlim_t_is_longer=yes],[zsh_cv_rlim_t_is_longer=no],[zsh_cv_rlim_t_is_longer=yes])]) +int main(){struct rlimit r;return(sizeof(r.rlim_cur) <= sizeof(long));}]])],[zsh_cv_rlim_t_is_longer=yes],[zsh_cv_rlim_t_is_longer=no],[zsh_cv_rlim_t_is_longer=yes])]) if test x$zsh_cv_rlim_t_is_longer = xyes; then AC_CACHE_CHECK(if rlim_t is a quad, zsh_cv_rlim_t_is_quad_t, @@ -1880,13 +1877,12 @@ if test x$zsh_cv_rlim_t_is_longer = xyes; then #endif #include #include -#include -main() { +int main() { struct rlimit r; char buf[20]; r.rlim_cur = 0; sprintf(buf, "%qd", r.rlim_cur); - exit(strcmp(buf, "0")); + return(strcmp(buf, "0")); }]])],[zsh_cv_rlim_t_is_quad_t=yes],[zsh_cv_rlim_t_is_quad_t=no],[zsh_cv_rlim_t_is_quad_t=no])]) if test x$zsh_cv_rlim_t_is_quad_t = xyes; then AC_DEFINE(RLIM_T_IS_QUAD_T) @@ -1903,8 +1899,7 @@ else #include #endif #include -#include - main(){struct rlimit r;r.rlim_cur=-1;exit(r.rlim_cur<0);}]])],[zsh_cv_type_rlim_t_is_unsigned=yes],[zsh_cv_type_rlim_t_is_unsigned=no],[zsh_cv_type_rlim_t_is_unsigned=no])]) + int main(){struct rlimit r;r.rlim_cur=-1;return(r.rlim_cur<0);}]])],[zsh_cv_type_rlim_t_is_unsigned=yes],[zsh_cv_type_rlim_t_is_unsigned=no],[zsh_cv_type_rlim_t_is_unsigned=no])]) if test x$zsh_cv_type_rlim_t_is_unsigned = xyes; then AC_DEFINE(RLIM_T_IS_UNSIGNED) DEFAULT_RLIM_T="unsigned $DEFAULT_RLIM_T" @@ -2187,9 +2182,8 @@ zsh_cv_sys_fifo, #include #include #include -#include #include -main() +int main() { char c; int fd; @@ -2200,18 +2194,18 @@ main() #else if(mknod("/tmp/fifo$$", 0010600, 0) < 0) #endif - exit(1); + return(1); pid = fork(); if(pid < 0) - exit(1); + return(1); if(pid) { fd = open("/tmp/fifo$$", O_RDONLY); - exit(fd < 0 || read(fd, &c, 1) != 1 || c != 'x'); + return(fd < 0 || read(fd, &c, 1) != 1 || c != 'x'); } fd = open("/tmp/fifo$$", O_WRONLY); ret = (fd < 0 || write(fd, "x", 1) < 1); unlink("/tmp/fifo$$"); - exit(ret); + return(ret); } ]])],[zsh_cv_sys_fifo=yes],[zsh_cv_sys_fifo=no],[zsh_cv_sys_fifo=yes]) ]) @@ -2289,8 +2283,7 @@ zsh_cv_sys_link, [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -#include -main() +int main() { int ret; char *tmpfile, *newfile; @@ -2299,11 +2292,11 @@ main() unlink(tmpfile); unlink(newfile); if(creat(tmpfile, 0644) < 0) - exit(1); + return(1); ret = link(tmpfile, newfile); unlink(tmpfile); unlink(newfile); - exit(ret<0); + return(ret<0); } ]])],[zsh_cv_sys_link=yes],[zsh_cv_sys_link=no],[zsh_cv_sys_link=yes])]) AH_TEMPLATE([HAVE_LINK], @@ -2322,12 +2315,11 @@ zsh_cv_sys_killesrch, #include #include #include -#include -main() +int main() { int pid = (getpid() + 10000) & 0xffffff; while (pid && (kill(pid, 0) == 0 || errno != ESRCH)) pid >>= 1; - exit(errno!=ESRCH); + return(errno!=ESRCH); } ]])],[zsh_cv_sys_killesrch=yes],[zsh_cv_sys_killesrch=no],[zsh_cv_sys_killesrch=yes])]) AH_TEMPLATE([BROKEN_KILL_ESRCH], @@ -2348,12 +2340,11 @@ if test x$signals_style = xPOSIX_SIGNALS; then [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -#include int child=0; void handler(sig) int sig; {if(sig==SIGCHLD) child=1;} -main() { +int main() { struct sigaction act; sigset_t set; int pid, ret; @@ -2368,7 +2359,7 @@ main() { if(pid>0) { sigemptyset(&set); ret=sigsuspend(&set); - exit(child==0); + return(child==0); } } ]])],[zsh_cv_sys_sigsuspend=yes],[zsh_cv_sys_sigsuspend=no],[zsh_cv_sys_sigsuspend=yes])]) @@ -2400,15 +2391,14 @@ case "x$zsh_working_tcsetpgrp" in #include #include #include -#include -main() { +int main() { int fd; int ret; fd=open("/dev/tty", O_RDWR); - if (fd < 0) exit(2); + if (fd < 0) return(2); ret=tcsetpgrp(fd, tcgetpgrp(fd)); - if (ret < 0) exit(1); - exit(0); + if (ret < 0) return(1); + return(0); } ]])],[zsh_cv_sys_tcsetpgrp=yes],[ case $? in @@ -2448,7 +2438,7 @@ if test x$ac_cv_func_getpwnam = xyes; then #include #include #include -main() { +int main() { struct passwd *pw1, *pw2; char buf[1024], name[1024]; sprintf(buf, "%d:%d", getpid(), rand()); @@ -2456,7 +2446,7 @@ main() { if (pw1) strcpy(name, pw1->pw_name); sprintf(buf, "%d:%d", rand(), getpid()); pw2=getpwnam(buf); - exit(pw1!=0 && pw2!=0 && !strcmp(name, pw2->pw_name)); + return(pw1!=0 && pw2!=0 && !strcmp(name, pw2->pw_name)); } ]])],[zsh_cv_sys_getpwnam_faked=no],[zsh_cv_sys_getpwnam_faked=yes],[zsh_cv_sys_getpwnam_faked=no])]) if test x$zsh_cv_sys_getpwnam_faked = xyes; then @@ -2775,20 +2765,17 @@ elif test "x$dynamic" = xyes; then zsh_cv_sys_elf, [AC_RUN_IFELSE([AC_LANG_SOURCE([[/* Test for whether ELF binaries are produced */ #include -#include #include -main(argc, argv) -int argc; -char *argv[]; +int main(int argc, char *argv[]) { char b[4]; int i = open(argv[0],O_RDONLY); if(i == -1) - exit(1); /* fail */ + return(1); /* fail */ if(read(i,b,4)==4 && b[0]==127 && b[1]=='E' && b[2]=='L' && b[3]=='F') - exit(0); /* succeed (yes, it's ELF) */ + return(0); /* succeed (yes, it's ELF) */ else - exit(1); /* fail */ + return(1); /* fail */ }]])],[zsh_cv_sys_elf=yes],[zsh_cv_sys_elf=no],[zsh_cv_sys_elf=yes])]) # We use [0-9]* in case statements, so need to change quoting @@ -2924,13 +2911,12 @@ LDFLAGS="$old_LDFLAGS") AC_CACHE_CHECK(if your dlsym() needs a leading underscore, zsh_cv_func_dlsym_needs_underscore, [echo failed >conftestval && cat >conftest.c <&AS_MESSAGE_LOG_FD) && AC_TRY_COMMAND($DLLD $LDFLAGS $DLLDFLAGS -o conftest.$DL_EXT conftest.o 1>&AS_MESSAGE_LOG_FD) && AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include -#include #ifdef HPUX10DYNAMIC #include #define RTLD_LAZY BIND_DEFERRED @@ -2957,16 +2943,16 @@ char *zsh_gl_sym_addr ; extern int fred() ; -main() +int main() { void * handle ; void * symbol ; FILE *f=fopen("conftestval", "w"); - if (!f) exit(1); + if (!f) return(1); handle = dlopen("./conftest.$DL_EXT", RTLD_LAZY) ; if (handle == NULL) { fprintf (f, "dlopen failed") ; - exit(1); + return(1); } symbol = dlsym(handle, "fred") ; if (symbol == NULL) { @@ -2974,13 +2960,13 @@ main() symbol = dlsym(handle, "_fred") ; if (symbol == NULL) { fprintf (f, "dlsym failed") ; - exit(1); + return(1); } fprintf (f, "yes") ; } else fprintf (f, "no") ; - exit(0); + return(0); }]])],[zsh_cv_func_dlsym_needs_underscore=`cat conftestval`],[zsh_cv_func_dlsym_needs_underscore=failed dynamic=no],[zsh_cv_func_dlsym_needs_underscore=no])]) if test "x$zsh_cv_func_dlsym_needs_underscore" = xyes; then -- cgit v1.2.3 From 6e827d8f9a50653aa1905d8aff8cc91e6e2423c4 Mon Sep 17 00:00:00 2001 From: Julian Prein Date: Mon, 19 Sep 2022 02:02:18 +0000 Subject: 50648: Use $ZCALC_HISTORY where appropriate --- ChangeLog | 5 +++++ Doc/Zsh/contrib.yo | 7 +++++-- Functions/Misc/zcalc | 4 +++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 375172ec9..48c65d01b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-09-25 Peter Stephenson + + * 50648: Functions/Misc/zcalc: Julian Prein: Use ZCALC_HISTFILE + where defined for zcalc history. + 2022-09-21 Jun-ichi Takimoto * Nicholas Vinson: 50641: aczsh.m4, configure.ac: use 'int main()' diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 0ef59dbc9..96de5aa9b 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3972,8 +3972,11 @@ calculation is stored. For example, the result of the calculation on the line preceded by `tt(4> )' is available as tt($4). The last value calculated is available as tt(ans). Full command line editing, including the history of previous calculations, is available; the history is saved in -the file tt(~/.zcalc_history). To exit, enter a blank line or type `tt(:q)' -on its own (`tt(q)' is allowed for historical compatibility). +the file tt($ZCALC_HISTFILE). If tt($ZCALC_HISTFILE) is unset, +tt($ZDOTDIR/.zcalc_history) is used instead, which in turn falls backs to +tt($HOME/.zcalc_history) if tt($ZDOTDIR) is unset. To exit, enter a blank +line or type `tt(:q)' on its own (`tt(q)' is allowed for historical +compatibility). A line ending with a single backslash is treated in the same fashion as it is in command line editing: the backslash is removed, the diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc index 480373345..6cd2822c9 100644 --- a/Functions/Misc/zcalc +++ b/Functions/Misc/zcalc @@ -124,8 +124,10 @@ integer _rpn_mode _matched _show_stack _i _n integer _max_stack _push local -a _expressions stack + # We use our own history file with an automatic pop on exit. -history -ap "${ZDOTDIR:-$HOME}/.zcalc_history" +history -ap "${ZCALC_HISTFILE:-${ZDOTDIR:-$HOME}/.zcalc_history}" + _forms=( '%2$g' '%.*g' '%.*f' '%.*E' '') -- cgit v1.2.3 From 1b421e4978440234fb73117c8505dad1ccc68d46 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 26 Sep 2022 10:52:50 +0900 Subject: 50658 + test: Enable to switch between C/UTF-8 locales in PCRE --- ChangeLog | 5 +++++ Src/Modules/pcre.c | 10 ++-------- Test/V07pcre.ztst | 11 +++++++++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 48c65d01b..77345c050 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-09-26 Jun-ichi Takimoto + + * 50658 + test: Src/Modules/pcre.c, Test/V07pcre.ztst: Enable to + switch between C/UTF-8 locales in PCRE + 2022-09-25 Peter Stephenson * 50648: Functions/Misc/zcalc: Julian Prein: Use ZCALC_HISTFILE diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index 6289e003e..46875a59b 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -47,8 +47,6 @@ zpcre_utf8_enabled(void) #if defined(MULTIBYTE_SUPPORT) && defined(HAVE_NL_LANGINFO) && defined(CODESET) static int have_utf8_pcre = -1; - /* value can toggle based on MULTIBYTE, so don't - * be too eager with caching */ if (have_utf8_pcre < -1) return 0; @@ -56,15 +54,11 @@ zpcre_utf8_enabled(void) return 0; if ((have_utf8_pcre == -1) && - (!strcmp(nl_langinfo(CODESET), "UTF-8"))) { - - if (pcre_config(PCRE_CONFIG_UTF8, &have_utf8_pcre)) + (pcre_config(PCRE_CONFIG_UTF8, &have_utf8_pcre))) { have_utf8_pcre = -2; /* erk, failed to ask */ } - if (have_utf8_pcre < 0) - return 0; - return have_utf8_pcre; + return (have_utf8_pcre == 1) && (!strcmp(nl_langinfo(CODESET), "UTF-8")); #else return 0; diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst index ca13419e5..22a0b64c7 100644 --- a/Test/V07pcre.ztst +++ b/Test/V07pcre.ztst @@ -162,3 +162,14 @@ echo $match[2] ) 0:regression for segmentation fault, workers/38307 >test + + LANG_SAVE=$LANG + [[ é =~ '^.\z' ]]; echo $? + LANG=C + [[ é =~ '^..\z' ]]; echo $? + LANG=$LANG_SAVE + [[ é =~ '^.\z' ]]; echo $? +0:swich between C/UTF-8 locales +>0 +>0 +>0 -- cgit v1.2.3 From 1e4c7bcae5daec29cbf85968e013576d665c3816 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 26 Sep 2022 11:09:22 +0900 Subject: 50662: unset LC_* for all the tests --- ChangeLog | 2 ++ Test/ztst.zsh | 16 +++------------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 77345c050..597fd9093 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2022-09-26 Jun-ichi Takimoto + * 50662: Test/ztst.zsh: unset LC_* for all the tests + * 50658 + test: Src/Modules/pcre.c, Test/V07pcre.ztst: Enable to switch between C/UTF-8 locales in PCRE diff --git a/Test/ztst.zsh b/Test/ztst.zsh index d95b726e7..ea1b016d5 100755 --- a/Test/ztst.zsh +++ b/Test/ztst.zsh @@ -25,23 +25,13 @@ # still not be good enough. Maybe we should trick it somehow. emulate -R zsh -# Ensure the locale does not screw up sorting. Don't supply a locale -# unless there's one set, to minimise problems. -[[ -n $LC_ALL ]] && LC_ALL=C -[[ -n $LC_CTYPE ]] && LC_CTYPE=C -[[ -n $LC_COLLATE ]] && LC_COLLATE=C -[[ -n $LC_NUMERIC ]] && LC_NUMERIC=C -[[ -n $LC_MESSAGES ]] && LC_MESSAGES=C -[[ -n $LANG ]] && LANG=C -# Test file may (or may not) set LANG to other locales. In either case, -# LANG must be passed to child zsh. -export LANG +# By default tests are run in C locale. LANG must be passed to child zsh. +unset -m LC_\* +export LANG=C # find UTF-8 locale ZTST_find_UTF8 () { setopt multibyte - # Don't let LC_* override our choice of locale. - unset -m LC_\* local langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 ${(M)$(locale -a 2>/dev/null):#*.(utf8|UTF-8)}) for LANG in $langs; do -- cgit v1.2.3 From 33938ad489e6f3c280d431f92920db5a00458534 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 27 Sep 2022 15:20:24 +0900 Subject: 50668: treat 8bit chars correctly when multibyte is unset The problem was found in character range, but may have existed in other occasions --- ChangeLog | 5 +++++ Src/utils.c | 2 +- Test/D09brace.ztst | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 597fd9093..8679bf019 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-09-27 Jun-ichi Takimoto + + * 50668: Src/utils.c, Test/D09brace.ztst: treat 8bit characters + in charcter range correctly when multibyte is unset + 2022-09-26 Jun-ichi Takimoto * 50662: Test/ztst.zsh: unset LC_* for all the tests diff --git a/Src/utils.c b/Src/utils.c index 62bd3e602..edf5d3df7 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5519,7 +5519,7 @@ mb_metacharlenconv(const char *s, wint_t *wcp) if (!isset(MULTIBYTE) || STOUC(*s) <= 0x7f) { /* treat as single byte, possibly metafied */ if (wcp) - *wcp = (wint_t)(*s == Meta ? s[1] ^ 32 : *s); + *wcp = (wint_t)STOUC(*s == Meta ? s[1] ^ 32 : *s); return 1 + (*s == Meta); } /* diff --git a/Test/D09brace.ztst b/Test/D09brace.ztst index 580ed430f..961947b67 100644 --- a/Test/D09brace.ztst +++ b/Test/D09brace.ztst @@ -116,3 +116,10 @@ print -r {1..10}{.. 0:Unmatched braces after matched braces are left alone. >1{.. 2{.. 3{.. 4{.. 5{.. 6{.. 7{.. 8{.. 9{.. 10{.. + + () { + setopt localoptions no_multibyte + echo -E {$'\x80'..$'\x81'} + } +0:range of 8bit chars, multibyte option unset +>\M-^@ \M-^A -- cgit v1.2.3 From 0a69a2f6cb3b752daeaf7e5d7f866b0f204e68e0 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 28 Sep 2022 17:11:08 -0400 Subject: 50399: Completion/Base/Widget/_complete_debug Properly local scope PS4 change --- ChangeLog | 4 ++++ Completion/Base/Widget/_complete_debug | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8679bf019..453ee6ebe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-09-28 Eric Cook + * Bart Schaefer: 50399: Completion/Base/Widget/_complete_debug + Properly local scope PS4 change + 2022-09-27 Jun-ichi Takimoto * 50668: Src/utils.c, Test/D09brace.ztst: treat 8bit characters diff --git a/Completion/Base/Widget/_complete_debug b/Completion/Base/Widget/_complete_debug index 94fd4accd..d8b1bd837 100644 --- a/Completion/Base/Widget/_complete_debug +++ b/Completion/Base/Widget/_complete_debug @@ -19,7 +19,7 @@ integer debug_fd=-1 setopt localoptions no_ignorebraces debug_indent=( '%'{3..20}'(e. .)' ) } - local PROMPT4 PS4="${(j::)debug_indent}+%N:%i> " + local PROMPT4="$PROMPT4" PS4="${(j::)debug_indent}+%N:%i> " setopt xtrace : $ZSH_NAME $ZSH_VERSION ${1:-_main_complete} -- cgit v1.2.3 From c901c1e412647d2f4150c36feaea431026b13d9a Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Wed, 28 Sep 2022 17:59:48 -0400 Subject: 50695: Completion/Unix/Command/_mysql_utils add --protocol option --- ChangeLog | 3 +++ Completion/Unix/Command/_mysql_utils | 1 + 2 files changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index 453ee6ebe..6674c60e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ * Bart Schaefer: 50399: Completion/Base/Widget/_complete_debug Properly local scope PS4 change + * 50695: Completion/Unix/Command/_mysql_utils add --protocol + option + 2022-09-27 Jun-ichi Takimoto * 50668: Src/utils.c, Test/D09brace.ztst: treat 8bit characters diff --git a/Completion/Unix/Command/_mysql_utils b/Completion/Unix/Command/_mysql_utils index 9f70687b0..2f5fd3efe 100644 --- a/Completion/Unix/Command/_mysql_utils +++ b/Completion/Unix/Command/_mysql_utils @@ -210,6 +210,7 @@ _mysql_utils() { "--no-defaults[don't read default options from any options file]" '--defaults-file=[read defaults from the given file]:file:_files' '--defaults-extra-file=[read specified file after the global files]:defaults file:_files' + '--protocol=[connection protocol to use for connecting to the server]:protocol:(tcp socket pipe memory)' '(-S --socket)'{-S+,--socket=}'[specify socket file to use for connection]:server socket file:_files' '(-h --host)'{-h+,--host=}'[specify server hostname]:hostname:_mysql_hosts' '(-P --port)'{-P+,--port=}'[specify port number for connection]:server port:_mysql_ports' -- cgit v1.2.3 From b7f280ab597b07bbb22fb741589fe7754fc5cc0c Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 29 Sep 2022 12:26:36 +0900 Subject: 50671: enable spell check in *.ztst by vim --- ChangeLog | 4 ++++ Util/ztst-syntax.vim | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6674c60e6..732721595 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-09-29 Jun-ichi Takimoto + + * 50671: Util/ztst-syntax.vim: enable spell check in *.ztst + 2022-09-28 Eric Cook * Bart Schaefer: 50399: Completion/Base/Widget/_complete_debug Properly local scope PS4 change diff --git a/Util/ztst-syntax.vim b/Util/ztst-syntax.vim index 639b9a4ec..42378e7a1 100644 --- a/Util/ztst-syntax.vim +++ b/Util/ztst-syntax.vim @@ -36,7 +36,7 @@ syn match ztstPayload /^\s.*/ contains=@zsh syn match ztstExitCode /^\d\+\|^-/ nextgroup=ztstFlags syn match ztstFlags /[.dDqf]*:/ contained nextgroup=ztstTestName contains=ztstColon syn match ztstColon /:.\@=/ contained -syn region ztstTestName start=// end=/$/ contained +syn region ztstTestName start=// end=/$/ contained contains=@Spell syn match ztstInputMarker /^<.\@=/ nextgroup=ztstInput syn region ztstInput start=// end=/$/ contained @@ -54,7 +54,7 @@ syn match ztstErrputLiteral /^[?].\@=/ nextgroup=ztstErrp syn region ztstErrput start=// end=/$/ contained syn match ztstFrequentExplanationMarker /^F:/ nextgroup=ztstFrequentExplanation -syn region ztstFrequentExplanation start=// end=/$/ contained +syn region ztstFrequentExplanation start=// end=/$/ contained contains=@Spell syn match ztstDirective /^%.*/ -- cgit v1.2.3 From 727b493e2b782fca0f3933865faa9a0a6ab1a2c4 Mon Sep 17 00:00:00 2001 From: Wesley Schwengle Date: Mon, 17 Oct 2022 13:13:13 +0900 Subject: 50736: silence use-after-free warning (gcc-12.2) --- ChangeLog | 5 +++++ Src/Zle/compmatch.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 732721595..cb47acd1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-10-17 Jun-ichi Takimoto + + * Wesley Schwengle: 50736: Src/Zle/compmatch.c: silence + use-after-free waring (gcc-12.2) + 2022-09-29 Jun-ichi Takimoto * 50671: Util/ztst-syntax.vim: enable spell check in *.ztst diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c index 56e5509a4..ddcecd589 100644 --- a/Src/Zle/compmatch.c +++ b/Src/Zle/compmatch.c @@ -2045,12 +2045,12 @@ join_strs(int la, char *sa, int lb, char *sb) zlelineasstring(line, mp->llen, 0, &convlen, NULL, 0); if (rr <= convlen) { - char *or = rs; + ptrdiff_t diff = rp - rs; int alloclen = (convlen > 20) ? convlen : 20; rs = realloc(rs, (rl += alloclen)); rr += alloclen; - rp += rs - or; + rp = rs + diff; } memcpy(rp, convstr, convlen); rp += convlen; @@ -2073,11 +2073,11 @@ join_strs(int la, char *sa, int lb, char *sb) } else { /* Same character, just take it. */ if (rr <= 1 /* HERE charlen */) { - char *or = rs; + ptrdiff_t diff = rp - rs; rs = realloc(rs, (rl += 20)); rr += 20; - rp += rs - or; + rp = rs + diff; } /* HERE: multibyte char */ *rp++ = *sa; -- cgit v1.2.3 From b82e8e10355aba96cf3cf4e75bae71a6a3f8b235 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 17 Oct 2022 16:21:01 +0100 Subject: 50786: Make match etc. local when used in styles. Avoids side effects of add-zle-hook-widget. --- ChangeLog | 5 +++++ Functions/Misc/add-zle-hook-widget | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb47acd1b..61390fc9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-10-17 Peter Stephenson + + * 50786: Functions/Misc/add-zle-hook-widget: make match + etc. local when used in styles. + 2022-10-17 Jun-ichi Takimoto * Wesley Schwengle: 50736: Src/Zle/compmatch.c: silence diff --git a/Functions/Misc/add-zle-hook-widget b/Functions/Misc/add-zle-hook-widget index 4d8049083..4293a07dd 100644 --- a/Functions/Misc/add-zle-hook-widget +++ b/Functions/Misc/add-zle-hook-widget @@ -39,7 +39,7 @@ zstyle zle-hook types ${hooktypes#zle-} # Relying on multifuncdef option here function azhw:${^hooktypes} { - local -a hook_widgets + local -a hook_widgets match mbegin mend local hook # Values of these styles look like number:name # and we run them in number order @@ -58,7 +58,7 @@ function azhw:${^hooktypes} { # Redefine ourself with the setup left out function add-zle-hook-widget { - local -a hooktypes + local -a hooktypes match mbegin mend zstyle -a zle-hook types hooktypes # This part copied from add-zsh-hook -- cgit v1.2.3 From a7e4394d1b06cbd004c85b5fecfe864eb93b4385 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 22 Oct 2022 20:26:23 -0700 Subject: 50714: also complete in the 2nd argument of "git diff" anything that could be in the 1st argument. This probably shouldn't complete ranges but all other code is in common, so leaving it to someone more familiar with _git to clean up. --- ChangeLog | 5 +++++ Completion/Unix/Command/_git | 27 ++++++++++++--------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61390fc9d..0c11fe53b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-10-22 Bart Schaefer + + * 50714: Completion/Unix/Command/_git (_git-diff): also complete + in the 2nd argument position anything that could be in the 1st. + 2022-10-17 Peter Stephenson * 50786: Functions/Misc/add-zle-hook-widget: make match diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index cecb80ac3..6a1c4158a 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -808,18 +808,6 @@ _git-diff () { # Otherwise, more complex conditions need to be checked. case $CURRENT in - (1) - local files_alt='files::__git_changed-in-working-tree_files' - if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then - files_alt='files::__git_changed-in-index_files' - fi - - _alternative \ - 'commit-ranges::__git_commit_ranges' \ - 'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ - $files_alt \ - 'blobs::__git_blobs ' && ret=0 - ;; (2) # Check if first argument is something special. In case of committish ranges and committishs offer a full list compatible completions. if __git_is_committish_range $line[1]; then @@ -841,10 +829,19 @@ _git-diff () { elif [[ -n ${opt_args[(I)--cached|--staged]} ]]; then # Example: git diff --cached file1 __git_changed-in-index_files && ret=0 - else - # Example: git diff file1 - __git_changed-in-working-tree_files && ret=0 fi + ;& + (1) + local files_alt='files::__git_changed-in-working-tree_files' + if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then + files_alt='files::__git_changed-in-index_files' + fi + + _alternative \ + 'commit-ranges::__git_commit_ranges' \ + 'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ + $files_alt \ + 'blobs::__git_blobs ' && ret=0 ;; (*) if __git_is_committish_range $line[1]; then -- cgit v1.2.3 From 6b5ee0c17c817f12537ab7d3e5027b015f8f9475 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 23 Oct 2022 16:25:04 -0700 Subject: users/28243: update "typeset +" documentation --- ChangeLog | 6 +++++- Doc/Zsh/builtins.yo | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c11fe53b..b97244f68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -2022-10-22 Bart Schaefer +2022-10-23 Bart Schaefer + + * users/28243: Doc/Zsh/builtins.yo: update "typeset +" doc + +2022-10-22 Bart Schaefer * 50714: Completion/Unix/Command/_git (_git-diff): also complete in the 2nd argument position anything that could be in the 1st. diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 641e46cf9..dd54a0fc8 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2047,8 +2047,9 @@ startitem() item(tt(PLUS()))( If `tt(PLUS())' appears by itself in a separate word as the last option, then the names of all parameters (functions with tt(-f)) are printed, but -the values (function bodies) are not. No var(name) arguments may appear, -and it is an error for any other options to follow `tt(PLUS())'. The +the values (function bodies) are not. If var(name) arguments appear, +both those names and their values are printed in the form of assignments. +It is an error for any other options to follow `tt(PLUS())', but the effect of `tt(PLUS())' is as if all attribute flags which precede it were given with a `tt(PLUS())' prefix. For example, `tt(typeset -U PLUS())' is equivalent to `tt(typeset +U)' and displays the names of all arrays having @@ -2081,7 +2082,8 @@ Except when assignments are made with var(name)tt(=)var(value), using tt(+m) forces the matching parameters and their attributes to be printed, even inside a function. Note that tt(-m) is ignored if no patterns are given, so `tt(typeset -m)' displays attributes but `tt(typeset -a +m)' -does not. +does not. Ordinary scalar string parameters have no attributes, so for +those tt(+m) prints only the names. ) item(tt(-p) [ var(n) ])( If the tt(-p) option is given, parameters and values are printed in the -- cgit v1.2.3 From 5b1c204c54e3ba41411e583ea649532b12977845 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 23 Oct 2022 16:28:14 -0700 Subject: Unposted: Fix typo in comment --- Src/parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/parse.c b/Src/parse.c index 5054e59d5..2fac5c89c 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -120,7 +120,7 @@ struct heredocs *hdocs; * - if not (type & Z_END), followed by next WC_LIST * * WC_SUBLIST - * - data contains type (&&, ||, END) and flags (coprog, not) + * - data contains type (&&, ||, END) and flags (coproc, not) * - followed by code for sublist * - if not (type == END), followed by next WC_SUBLIST * -- cgit v1.2.3 From b76dcecfe3461aa9a9e29dffe2484f097611f9ff Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Tue, 25 Oct 2022 12:49:48 +0200 Subject: 50840: Doc/Zsh/grammar.yo: Correct NO_MATCH to NOMATCH --- ChangeLog | 4 ++++ Doc/Zsh/grammar.yo | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b97244f68..45db78834 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-10-25 Axel Beckert + + * 50840: Doc/Zsh/grammar.yo: Correct NO_MATCH to NOMATCH. + 2022-10-23 Bart Schaefer * users/28243: Doc/Zsh/builtins.yo: update "typeset +" doc diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo index f8f4ada86..9af211090 100644 --- a/Doc/Zsh/grammar.yo +++ b/Doc/Zsh/grammar.yo @@ -536,7 +536,7 @@ itemiz(Errors creating command or process substitutions) itemiz(Syntax errors in glob qualifiers) itemiz(File generation errors where not caught by the option tt(BAD_PATTERN)) itemiz(All bad patterns used for matching within case statements) -itemiz(File generation failures where not caused by tt(NO_MATCH) or +itemiz(File generation failures where not caused by tt(NOMATCH) or similar options) itemiz(All file generation errors where the pattern was used to create a multio) -- cgit v1.2.3 From 0a66d6f3ec5a26e8541878473e02a24a6042396d Mon Sep 17 00:00:00 2001 From: Peter Grayson Date: Tue, 25 Oct 2022 16:43:21 -0400 Subject: 50844: Remove _stgit completion script The StGit project ships its own zsh completion script which is more complete and up-to-date than those shipped with zsh. https://github.com/stacked-git/stgit/blob/master/completion/stgit.zsh Also, the _stgit completions that ship with zsh, which dynamically parse StGit's help output, will be broken by the upcoming StGit 2.0 release due to changes in the help output. Signed-off-by: Peter Grayson --- ChangeLog | 5 ++++ Completion/Unix/Command/_stgit | 52 ------------------------------------------ 2 files changed, 5 insertions(+), 52 deletions(-) delete mode 100644 Completion/Unix/Command/_stgit diff --git a/ChangeLog b/ChangeLog index 45db78834..bf2d73a8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-10-31 Peter Grayson + + * 50844: Completion/Unix/Command/_stgit: Remove _stgit completion + script + 2022-10-25 Axel Beckert * 50840: Doc/Zsh/grammar.yo: Correct NO_MATCH to NOMATCH. diff --git a/Completion/Unix/Command/_stgit b/Completion/Unix/Command/_stgit deleted file mode 100644 index e31af460a..000000000 --- a/Completion/Unix/Command/_stgit +++ /dev/null @@ -1,52 +0,0 @@ -#compdef stg - -typeset -a subcmds - -subcmds=( ${${${(M)${(f)"$(stg help 2> /dev/null)"}## *}# }/#(#b)([^[:space:]]##)[[:space:]]##(*)/$match[1]:$match[2]} ) - -local curcontext="$curcontext" expl -local subcmd -local ret=1 - -if (( CURRENT == 2 )); then - _describe -t commands 'stgit command' subcmds && ret=0 -else - shift words - (( CURRENT-- )) - subcmd="$words[1]" - curcontext="${curcontext%:*}-${subcmd}:" - - case $subcmd in - (push) - _wanted -V unapplied-patches expl "patch" \ - compadd ${${(M)${(f)"$(stg series 2> /dev/null)"}##- *}#- } \ - && ret=0 - ;; - (pop) - _wanted -V applied-patches expl "patch" \ - compadd ${${(M)${(f)"$(stg series 2> /dev/null)"}##[+>] *}#[+>] } \ - && ret=0 - ;; - (edit|files|goto|rename|log|float|delete|sink|mail|sync|show|pick|hide|squash) - _wanted -V patches expl "patch" \ - compadd $(stg series --noprefix 2> /dev/null) \ - && ret=0 - ;; - (ref*) - last_word="$words[$CURRENT-1]" - refresh_patch_options=( -p --patch ) - if [[ -n ${refresh_patch_options[(r)$last_word]} ]]; then - _wanted -V applied-patches expl "patch" \ - compadd ${${(M)${(f)"$(stg series 2> /dev/null)"}##[+>] *}#[+>] } \ - && ret=0 - else - _files && ret=0 - fi - ;; - (*) - _files && ret=0 - ;; - esac -fi - -return ret -- cgit v1.2.3 From 159c892b9be15d123bb1ca2517876172f1a2e77a Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 31 Oct 2022 16:50:16 -0700 Subject: 50855: Clarify how commands are hashed, and searched-for by "whence". --- ChangeLog | 5 +++++ Doc/Zsh/builtins.yo | 21 ++++++++++++++------- Doc/Zsh/params.yo | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf2d73a8f..0f918288b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-10-31 Bart Schaefer + + * 50855: Doc/Zsh/builtins.yo, Doc/Zsh/params.yo: Clarify how + commands are hashed, and searched-for by "whence". + 2022-10-31 Peter Grayson * 50844: Completion/Unix/Command/_stgit: Remove _stgit completion diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index dd54a0fc8..b6217f66d 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1052,9 +1052,11 @@ The choice of hash table to work on is determined by the tt(-d) option; without the option the command hash table is used, and with the option the named directory hash table is used. -A command var(name) starting with a tt(/) is never hashed, whether by -explicit use of the tt(hash) command or otherwise. Such a command -is always found by direct look up in the file system. +A command var(name) starting with a tt(/) or with a relative path +starting with tt(./) or tt(../) is never executed by lookup in +the command hash table, and these can only be added to the table by +explicit use of the tt(hash) command. Such a command is always +found by direct look up in the file system. Given no arguments, and neither the tt(-r) or tt(-f) options, the selected hash table will be listed in full. @@ -1063,9 +1065,11 @@ The tt(-r) option causes the selected hash table to be emptied. It will be subsequently rebuilt in the normal fashion. The tt(-f) option causes the selected hash table to be fully rebuilt immediately. For the command hash table this hashes -all the absolute directories in the tt(PATH), -and for the named directory hash table this adds all users' home directories. +all (and em(only)) the absolute directories in the tt(PATH), +and for the named directory hash table this adds all users' home +directories. These two options cannot be used with any arguments. +Both options remove any explicitly-added elements. The tt(-m) option causes the arguments to be taken as patterns (which should be quoted) and the elements of the hash table @@ -2523,11 +2527,14 @@ item(tt(-a))( Do a search for all occurrences of var(name) throughout the command path. Normally only the first occurrence is printed. +When combined with tt(-m), only names appearing in the command hash +table are searched, but all occurrences of those names are printed. ) item(tt(-m))( The arguments are taken as patterns (pattern characters should be -quoted), and the information is displayed for each command matching one -of these patterns. +quoted), and the information is displayed for each entry in the command +hash table matching one of these patterns. The hash table is first +refilled, in case of changes to tt(PATH). ) item(tt(-s))( If a pathname contains symlinks, print the symlink-free pathname as well. diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index b543d1c38..2a30085a8 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1414,6 +1414,7 @@ An array (colon-separated list) of directories to search for commands. When this parameter is set, each directory is scanned and all files found are put in a hash table. +Directories named by relative path are not scanned for hashing. ) vindex(POSTEDIT) item(tt(POSTEDIT) )( -- cgit v1.2.3 From 7a2e3b9039a866ad0b45a70b498fad1ae5ad7de7 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 31 Oct 2022 16:51:07 -0700 Subject: unposted: incorrect email address --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0f918288b..c6daa5998 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -2022-10-31 Bart Schaefer +2022-10-31 Bart Schaefer * 50855: Doc/Zsh/builtins.yo, Doc/Zsh/params.yo: Clarify how commands are hashed, and searched-for by "whence". -- cgit v1.2.3 From f8d93888a8efd6c8142e74ece83b38632661de47 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Wed, 2 Nov 2022 16:27:27 +0900 Subject: 50851: restore typtab when necessary inittyptab() must be called when returning from a function with "setopt localoptions MULTIBYTE|BANGHIST|SHSTDIN", and also in function dosetopt() when setting these options (via $options, for example). We intentionally did not take account of the options EMACS/VI because these options are obsolete and their use is not recommended. --- ChangeLog | 6 ++++++ Doc/Zsh/options.yo | 16 ++++++++++------ Src/exec.c | 12 ++++++++++++ Src/options.c | 6 +++++- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6daa5998..6146209cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-11-02 Jun-ichi Takimoto + + * 50851: Doc/Zsh/options.yo, Src/exec.c, Src/options.c: restore + state (such as typtab) when returning from a function with + localoptions (but do not take care of EMACS/VI options). + 2022-10-31 Bart Schaefer * 50855: Doc/Zsh/builtins.yo, Doc/Zsh/params.yo: Clarify how diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index bf73664c9..445052617 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -2550,10 +2550,12 @@ pindex(NO_EMACS) pindex(NOEMACS) item(tt(EMACS))( If ZLE is loaded, turning on this option has the equivalent effect -of `tt(bindkey -e)'. In addition, the VI option is unset. +of `tt(bindkey -e)'. In addition, the tt(VI) option is unset. Turning it off has no effect. The option setting is -not guaranteed to reflect the current keymap. This option is -provided for compatibility; tt(bindkey) is the recommended interface. +not guaranteed to reflect the current keymap, and the tt(LOCALOPTIONS) +option does not work correctly. This option is provided only for +compatibility, and its use is highly discouraged. tt(bindkey) is the +recommended interface. ) pindex(OVERSTRIKE) pindex(NO_OVERSTRIKE) @@ -2582,10 +2584,12 @@ pindex(NO_VI) pindex(NOVI) item(tt(VI))( If ZLE is loaded, turning on this option has the equivalent effect -of `tt(bindkey -v)'. In addition, the EMACS option is unset. +of `tt(bindkey -v)'. In addition, the tt(EMACS) option is unset. Turning it off has no effect. The option setting is -not guaranteed to reflect the current keymap. This option is -provided for compatibility; tt(bindkey) is the recommended interface. +not guaranteed to reflect the current keymap, and the tt(LOCALOPTIONS) +option does not work correctly. This option is provided only for +compatibility, and its use is highly discouraged. tt(bindkey) is the +recommended interface. ) pindex(ZLE) pindex(NO_ZLE) diff --git a/Src/exec.c b/Src/exec.c index f2911807c..c8bcf4ee5 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5961,11 +5961,23 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) emulation = funcsave->emulation; sticky = funcsave->sticky; } else if (isset(LOCALOPTIONS)) { + /* we need to call inittyptab() if these options change */ + int init_typtab = +#ifdef MULTIBYTE_SUPPORT + funcsave->opts[MULTIBYTE] != opts[MULTIBYTE] || +#endif + funcsave->opts[BANGHIST] != opts[BANGHIST] || + funcsave->opts[SHINSTDIN] != opts[SHINSTDIN]; + /* take care of SUNKEYBOARDHACK but not of EMACS/VI */ + if (funcsave->opts[SUNKEYBOARDHACK] != opts[SUNKEYBOARDHACK]) + keyboardhackchar = funcsave->opts[SUNKEYBOARDHACK] ? '`' : '\0'; /* restore all shell options except PRIVILEGED and RESTRICTED */ funcsave->opts[PRIVILEGED] = opts[PRIVILEGED]; funcsave->opts[RESTRICTED] = opts[RESTRICTED]; memcpy(opts, funcsave->opts, sizeof(opts)); emulation = funcsave->emulation; + if (init_typtab) + inittyptab(); } else { /* just restore a couple. */ opts[XTRACE] = funcsave->opts[XTRACE]; diff --git a/Src/options.c b/Src/options.c index a1fe918fc..a994b563e 100644 --- a/Src/options.c +++ b/Src/options.c @@ -904,7 +904,11 @@ dosetopt(int optno, int value, int force, char *new_opts) keyboardhackchar = (value ? '`' : '\0'); } new_opts[optno] = value; - if (optno == BANGHIST || optno == SHINSTDIN) + if ( +#ifdef MULTIBYTE_SUPPORT + optno == MULTIBYTE || +#endif + optno == BANGHIST || optno == SHINSTDIN) inittyptab(); return 0; } -- cgit v1.2.3 From 188c5cd518b512073d3fd1dbf09c91b7968efcaa Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 6 Nov 2022 11:25:47 -0800 Subject: 50874: fix handling of tty signals for jobs in the current shell when waiting for the right side of a pipeline. Reverts 15bf8ace (workers/50134). Thanks to Jun T. for debugging assistance. Issues came down to two things: 1. update_job() may be called on a process group leader even when a signal was NOT sent to any process in that process group. This caused jobs to be resumed or backgrounded incorrectly or in the wrong order. 2. When there is a current-shell complex command (in braces) on the right side of a pipeline, external processes within it have their own process groups, but a tty signal sent to such a process should be treated as if received by the whole complex command. This fixes: * Suspend/resume of a foreground pipeline within a shell function * Interrupt or suspend/resume of processes in a pipeline ending in { ... } * Interrupt of such a pipeline after exit of the last process in { ... } These affected interactive shells only (MONITOR set plus tty signals). --- ChangeLog | 5 +++++ Src/jobs.c | 24 +++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6146209cf..7016ca76e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-11-06 Bart Schaefer + + * 50874: Src/jobs.c: fix handling of tty signals for jobs in + the current shell when waiting for the right side of a pipeline. + 2022-11-02 Jun-ichi Takimoto * 50851: Doc/Zsh/options.yo, Src/exec.c, Src/options.c: restore diff --git a/Src/jobs.c b/Src/jobs.c index 707374297..76c762ee5 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -544,16 +544,14 @@ update_job(Job jn) if (isset(MONITOR)) { pid_t pgrp = gettygrp(); /* get process group of tty */ + int deadpgrp = (mypgrp != pgrp && inforeground && pgrp > 1 && + kill(-pgrp, 0) == -1 && errno == ESRCH); /* is this job in the foreground of an interactive shell? */ if (mypgrp != pgrp && inforeground && - (jn->gleader == pgrp || - (pgrp > 1 && - (kill(-pgrp, 0) == -1 && errno == ESRCH)))) { + ((jn->gleader == pgrp && signalled) || deadpgrp)) { if (list_pipe) { - if (somestopped || (pgrp > 1 && - kill(-pgrp, 0) == -1 && - errno == ESRCH)) { + if (somestopped || deadpgrp) { attachtty(mypgrp); /* check window size and adjust if necessary */ adjustwinsize(0); @@ -566,6 +564,12 @@ update_job(Job jn) * when the job is finally deleted. */ jn->stat |= STAT_ATTACH; + /* + * If we're in shell jobs on the right side of a pipeline + * we should treat it like a job in the current shell. + */ + if (inforeground == 2) + inforeground = 1; } /* If we have `foo|while true; (( x++ )); done', and hit * ^C, we have to stop the loop, too. */ @@ -1488,10 +1492,7 @@ addproc(pid_t pid, char *text, int aux, struct timeval *bgtime, * set it for that, too. */ if (gleader != -1) { - if (jobtab[thisjob].stat & STAT_CURSH) - jobtab[thisjob].gleader = gleader; - else - jobtab[thisjob].gleader = pid; + jobtab[thisjob].gleader = gleader; if (list_pipe_job_used != -1) jobtab[list_pipe_job_used].gleader = gleader; /* @@ -1500,7 +1501,7 @@ addproc(pid_t pid, char *text, int aux, struct timeval *bgtime, */ last_attached_pgrp = gleader; } else if (!jobtab[thisjob].gleader) - jobtab[thisjob].gleader = pid; + jobtab[thisjob].gleader = pid; /* attach this process to end of process list of current job */ pnlist = &jobtab[thisjob].procs; } @@ -2506,6 +2507,7 @@ bin_fg(char *name, char **argv, Options ops, int func) jobtab[job].stat &= ~STAT_CURSH; } if ((stopped = (jobtab[job].stat & STAT_STOPPED))) { + /* WIFCONTINUED will makerunning() again at killjb() */ makerunning(jobtab + job); if (func == BIN_BG) { /* Set $! to indicate this was backgrounded */ -- cgit v1.2.3 From 298919f43a565cc2e130c8cb3f67773f7a54fca1 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 8 Nov 2022 14:12:01 +0000 Subject: users/28338: command substitution with alias edge case. See added regression test. --- ChangeLog | 5 +++++ Src/lex.c | 8 ++++++++ Test/D08cmdsubst.ztst | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7016ca76e..3018706b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-11-08 Peter Stephenson + + * users/28338: Src/lex.c, Test/D08cmdsubst.ztst: edge case of an + edge case in command expansion of alias. + 2022-11-06 Bart Schaefer * 50874: Src/jobs.c: fix handling of tty signals for jobs in diff --git a/Src/lex.c b/Src/lex.c index ece02659e..e2f8bcfb1 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -1429,10 +1429,18 @@ gettokstr(int c, int sub) peek == STRING && lexbuf.ptr[-1] == '}' && lexbuf.ptr[-2] != Bnull) { /* hack to get {foo} command syntax work */ + /* + * Alias expansion when parsing command substitution means that + * the case for raw lexical analysis may not be the same. + * (Just go with it, OK?) + */ + int lar = lex_add_raw; + lex_add_raw = lexbuf_raw.len > 0 && lexbuf_raw.ptr[-1] == '}'; lexbuf.ptr--; lexbuf.len--; lexstop = 0; hungetc('}'); + lex_add_raw = lar; } *lexbuf.ptr = '\0'; DPUTS(cmdsp != ocmdsp, "BUG: gettok: cmdstack changed."); diff --git a/Test/D08cmdsubst.ztst b/Test/D08cmdsubst.ztst index 04bf698aa..e415831a0 100644 --- a/Test/D08cmdsubst.ztst +++ b/Test/D08cmdsubst.ztst @@ -177,3 +177,11 @@ 0:Alias expansion needed in parsing substitutions >hi >bye + +# This should silently print a blank line; the original problem was +# a parse error as the last character of the unexpanded alias +# was erased, symptom: "command not found: W" + alias WI='while {false}' + eval 'echo $(WI blah)' +0:Aliases with braces in command substitution can cause havoc +> -- cgit v1.2.3 From d873ed6026d7b0c48d6e65ec06df491d015a4d59 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 8 Nov 2022 20:36:49 -0800 Subject: 50897: nonzero status of complex commands should trigger ERR_EXIT --- ChangeLog | 5 +++++ Src/exec.c | 2 +- Src/loop.c | 12 ++++++------ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3018706b8..76a8091e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-11-08 Bart Schaefer + + * 50897: Src/exec.c, Src/loop.c: nonzero status of complex + commands should trigger ERR_EXIT + 2022-11-08 Peter Stephenson * users/28338: Src/lex.c, Test/D08cmdsubst.ztst: edge case of an diff --git a/Src/exec.c b/Src/exec.c index c8bcf4ee5..2422dae91 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -451,7 +451,7 @@ execcursh(Estate state, int do_exec) cmdpop(); state->pc = end; - this_noerrexit = 1; + this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); return lastval; } diff --git a/Src/loop.c b/Src/loop.c index db5b3e097..be5261369 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -208,7 +208,7 @@ execfor(Estate state, int do_exec) loops--; simple_pline = old_simple_pline; state->pc = end; - this_noerrexit = 1; + this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); return lastval; } @@ -336,7 +336,7 @@ execselect(Estate state, UNUSED(int do_exec)) loops--; simple_pline = old_simple_pline; state->pc = end; - this_noerrexit = 1; + this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); return lastval; } @@ -478,7 +478,7 @@ execwhile(Estate state, UNUSED(int do_exec)) popheap(); loops--; state->pc = end; - this_noerrexit = 1; + this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); return lastval; } @@ -532,7 +532,7 @@ execrepeat(Estate state, UNUSED(int do_exec)) loops--; simple_pline = old_simple_pline; state->pc = end; - this_noerrexit = 1; + this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); return lastval; } @@ -587,7 +587,7 @@ execif(Estate state, int do_exec) lastval = 0; } state->pc = end; - this_noerrexit = 1; + this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); return lastval; } @@ -701,7 +701,7 @@ execcase(Estate state, int do_exec) if (!anypatok) lastval = 0; - this_noerrexit = 1; + this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); return lastval; } -- cgit v1.2.3 From 61610ea4bdc3e2de11c258017f377db3d1d6d993 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 9 Nov 2022 20:24:57 -0800 Subject: 50922: fix additional cases of signals for current shell jobs on the right of a pipeline. Backs out part of 188c5cd5 (workers/50874). With this change, after a new subshell is forked upon suspend of the right side of a pipeline, the previous foreground subjob is resumed first and the new subshell remains stopped until that job finishes. --- ChangeLog | 6 ++++++ Src/exec.c | 8 ++++++-- Src/jobs.c | 6 ------ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 76a8091e3..fe10e2982 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-11-09 Bart Schaefer + + * 50922: Src/exec.c, Src/jobs.c: fix additional cases of signals + for current shell jobs on the right of a pipeline. Backs out + part of 50874. + 2022-11-08 Bart Schaefer * 50897: Src/exec.c, Src/loop.c: nonzero status of complex diff --git a/Src/exec.c b/Src/exec.c index 2422dae91..d4e681887 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1899,8 +1899,12 @@ execpline(Estate state, wordcode slcode, int how, int last1) break; } } - else if (subsh && jn->stat & STAT_STOPPED) - thisjob = newjob; + else if (subsh && jn->stat & STAT_STOPPED) { + if (thisjob == newjob) + makerunning(jn); + else + thisjob = newjob; + } else break; } diff --git a/Src/jobs.c b/Src/jobs.c index 76c762ee5..4863962b9 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -564,12 +564,6 @@ update_job(Job jn) * when the job is finally deleted. */ jn->stat |= STAT_ATTACH; - /* - * If we're in shell jobs on the right side of a pipeline - * we should treat it like a job in the current shell. - */ - if (inforeground == 2) - inforeground = 1; } /* If we have `foo|while true; (( x++ )); done', and hit * ^C, we have to stop the loop, too. */ -- cgit v1.2.3 From 1ba8714a7ac665e661c1b3a716ffe2af73d1e443 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 9 Nov 2022 21:37:56 -0800 Subject: 50928: fix tests for 50897, mention behavior change in NEWS --- ChangeLog | 3 +++ NEWS | 9 +++++++++ Src/exec.c | 2 ++ Test/C03traps.ztst | 17 ++++++----------- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe10e2982..d88fa4cbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-11-09 Bart Schaefer + * 50928: News, Src/exec.c, Test/C03traps.ztst: fix tests for 50897, + mention behavior change in NEWS + * 50922: Src/exec.c, Src/jobs.c: fix additional cases of signals for current shell jobs on the right of a pipeline. Backs out part of 50874. diff --git a/NEWS b/NEWS index cdafd1ff5..9c28169bb 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,15 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH Note also the list of incompatibilities in the README file. +Changes since 5.9 +----------------- + +Handling of ERR_EXIT is corrected when the final status of a structured +command (for, select, while, repeat, if, case, or a list in braces) is +nonzero. To be compatible with other shells, "zsh -e" now exits in +those circumstances, whereas previous versions did not. This does not +affect the handling of nonzero status within conditional statements. + Changes since 5.8.1 ------------------- diff --git a/Src/exec.c b/Src/exec.c index d4e681887..eef40232e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1442,6 +1442,8 @@ execlist(Estate state, int dont_change_job, int exiting) execsimple(state); else execpline(state, code, ltype, (ltype & Z_END) && exiting); + if (unset(ERRRETURN)) + this_noerrexit = noerrexit; state->pc = next; goto sublist_done; break; diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index f120809a7..5cc45e2de 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -713,7 +713,7 @@ F:Must be tested with a top-level script rather than source or function fi } fn() { - setopt err_return + setopt localoptions err_return fn2 || true } fn @@ -726,8 +726,7 @@ F:Must be tested with a top-level script rather than source or function done print OK ) -0:ERR_EXIT not triggered by status 1 at end of for ->OK +1:ERR_EXIT triggered by status 1 at end of for (setopt err_exit integer x=0 @@ -736,8 +735,7 @@ F:Must be tested with a top-level script rather than source or function done print OK ) -0:ERR_EXIT not triggered by status 1 at end of while ->OK +1:ERR_EXIT triggered by status 1 at end of while (setopt err_exit repeat 1; do @@ -745,8 +743,7 @@ F:Must be tested with a top-level script rather than source or function done print OK ) -0:ERR_EXIT not triggered by status 1 at end of repeat ->OK +1:ERR_EXIT triggered by status 1 at end of repeat (setopt err_exit if true; then @@ -754,8 +751,7 @@ F:Must be tested with a top-level script rather than source or function fi print OK ) -0:ERR_EXIT not triggered by status 1 at end of if ->OK +1:ERR_EXIT triggered by status 1 at end of if (setopt err_exit { @@ -763,8 +759,7 @@ F:Must be tested with a top-level script rather than source or function } print OK ) -0:ERR_EXIT not triggered by status 1 at end of { } ->OK +1:ERR_EXIT triggered by status 1 at end of { } unsetopt err_exit err_return (setopt err_exit -- cgit v1.2.3 From 8839e969bf8f3f129d0efd8ecd51505610a1f01b Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 9 Nov 2022 21:48:46 -0800 Subject: 50929: fix handling of ERR_RETURN bent by 50928. --- ChangeLog | 2 ++ Src/exec.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d88fa4cbb..6478f5480 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2022-11-09 Bart Schaefer + * 50929: Src/exec.c: fix handling of ERR_RETURN bent by 50928. + * 50928: News, Src/exec.c, Test/C03traps.ztst: fix tests for 50897, mention behavior change in NEWS diff --git a/Src/exec.c b/Src/exec.c index eef40232e..ce0c1f1ad 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1442,7 +1442,7 @@ execlist(Estate state, int dont_change_job, int exiting) execsimple(state); else execpline(state, code, ltype, (ltype & Z_END) && exiting); - if (unset(ERRRETURN)) + if (!locallevel || unset(ERRRETURN)) this_noerrexit = noerrexit; state->pc = next; goto sublist_done; -- cgit v1.2.3 From b1533066ca7d50c88b37ce72093c12cf19807818 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 12 Nov 2022 08:28:28 -0800 Subject: unposted (see 50930): note bug with suspending conditional expressions --- Etc/BUGS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Etc/BUGS b/Etc/BUGS index 72c313e88..1719946b1 100644 --- a/Etc/BUGS +++ b/Etc/BUGS @@ -50,3 +50,8 @@ related, probably obsolete, vared special case for $TERM set to "emacs". ------------------------------------------------------------------------ users/26071: Strange behavior about option completion of "git push --f" ------------------------------------------------------------------------ +50930: If a conditional expression appears in a current-shell construct +(such as { sleep 20 && print $? }) which is then suspended with ^Z, the +return value of the left side of the expression is always 148 (SIGSTOP) +and thus the expression is likely to be incorrectly interpreted. +------------------------------------------------------------------------ -- cgit v1.2.3 From c4d557bb0a9cf6a7241f760ad466e2d91359ceb2 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 17 Nov 2022 20:05:12 +0100 Subject: 50934: use OSC 52 escape sequence when copying to "* or "+ vi buffers --- ChangeLog | 6 ++++++ Doc/Zsh/zle.yo | 11 ++++++++--- Src/Zle/zle.h | 3 +++ Src/Zle/zle_utils.c | 32 +++++++++++++++++++++++++++++++- Src/Zle/zle_vi.c | 9 ++++++--- 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6478f5480..c42163434 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-11-17 Oliver Kiddle + + * 50934: Doc/Zsh/zle.yo, Src/Zle/zle.h, Src/Zle/zle_utils.c, + Src/Zle/zle_vi.c: use OSC 52 escape sequence when copying to + "* or "+ vi buffers + 2022-11-09 Bart Schaefer * 50929: Src/exec.c: fix handling of ERR_RETURN bent by 50928. diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 2d033a0a1..58700072a 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -2470,10 +2470,11 @@ command. tt(run-help) is normally aliased to tt(man). tindex(vi-set-buffer) item(tt(vi-set-buffer) (unbound) (tt(")) (unbound))( Specify a buffer to be used in the following command. -There are 37 buffers that can be specified: +There are 39 buffers that can be specified: the 26 `named' buffers tt("a) to tt("z), the `yank' buffer tt("0), -the nine `queued' buffers tt("1) to tt("9) and the `black hole' buffer -tt("_). The named buffers can also be specified as tt("A) to tt("Z). +the nine `queued' buffers tt("1) to tt("9), the `black hole' buffer +tt("_) and the system selection tt("*) and clipboard tt("+). +The named buffers can also be specified as tt("A) to tt("Z). When a buffer is specified for a cut, change or yank command, the text concerned replaces the previous contents of the specified buffer. If @@ -2482,6 +2483,10 @@ appended to the buffer instead of overwriting it. When using the tt("_) buffer, nothing happens. This can be useful for deleting text without affecting any buffers. +Updating the system clipboard relies on specific support from the terminal. +Reading it is not possible so a paste command with tt("*) or tt("+) will do +nothing. + If no buffer is specified for a cut or change command, tt("1) is used, and the contents of tt("1) to tt("8) are each shifted along one buffer; the contents of tt("9) is lost. If no buffer is specified for a yank diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 391586c4a..f59545397 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -258,6 +258,9 @@ struct modifier { #define MOD_NULL (1<<5) /* throw away text for the vi cut buffer */ #define MOD_CHAR (1<<6) /* force character-wise movement */ #define MOD_LINE (1<<7) /* force line-wise movement */ +#define MOD_PRI (1<<8) /* OS primary selection for the vi cut buffer */ +#define MOD_CLIP (1<<9) /* OS clipboard for the vi cut buffer */ +#define MOD_OSSEL (MOD_PRI | MOD_CLIP) /* either system selection */ /* current modifier status */ diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 526216fa7..3d9017dcf 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -936,6 +936,28 @@ cut(int i, int ct, int flags) cuttext(zleline + i, ct, flags); } +static char* +base64_encode(const char *src, size_t len) { + static const char* base64_table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + const unsigned char *end = (unsigned char *)src + len; + const unsigned char *in = (unsigned char *)src; + char *ret = zhalloc(1 + 4 * ((len + 2) / 3)); /* 4 bytes out for 3 in */ + char *cur = ret; + + for (; end - in > 0; in += 3, cur += 4) { + unsigned int n = *in << 16; + cur[3] = end - in > 2 ? base64_table[(n |= in[2]) & 0x3f] : '='; + cur[2] = end - in > 1 ? base64_table[((n |= in[1]<<8) >> 6) & 0x3f] : '='; + cur[1] = base64_table[(n >> 12) & 0x3f]; + cur[0] = base64_table[n >> 18]; + } + *cur = '\0'; + + return ret; +} + /* * As cut, but explicitly supply the text together with its length. */ @@ -948,7 +970,15 @@ cuttext(ZLE_STRING_T line, int ct, int flags) return; UNMETACHECK(); - if (zmod.flags & MOD_VIBUF) { + if (zmod.flags & MOD_OSSEL) { + int cutll; + char *mbcut = zlelineasstring(line, ct, 0, &cutll, NULL, 1); + unmetafy(mbcut, &cutll); + mbcut = base64_encode(mbcut, cutll); + + fprintf(shout, "\e]52;%c;%s\a", zmod.flags & MOD_CLIP ? 'c' : 'p', + mbcut); + } else if (zmod.flags & MOD_VIBUF) { struct cutbuffer *b = &vibuf[zmod.vibuf]; if (!(zmod.flags & MOD_VIAPP) || !b->buf) { diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index 0f198d0e8..24d9de6ea 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -1014,6 +1014,9 @@ int visetbuffer(char **args) { ZLE_INT_T ch; + ZLE_CHAR_T *match = ZWS("_*+"); + int registermod[] = { MOD_NULL, MOD_PRI, MOD_CLIP }; + ZLE_CHAR_T *found; if (*args) { ch = **args; @@ -1022,12 +1025,12 @@ visetbuffer(char **args) } else { ch = getfullchar(0); } - if (ch == ZWC('_')) { - zmod.flags |= MOD_NULL; + if ((found = ZS_strchr(match, ch))) { + zmod.flags |= registermod[found - match]; prefixflag = 1; return 0; } else - zmod.flags &= ~MOD_NULL; + zmod.flags &= ~(MOD_NULL | MOD_OSSEL); if ((ch < ZWC('0') || ch > ZWC('9')) && (ch < ZWC('a') || ch > ZWC('z')) && (ch < ZWC('A') || ch > ZWC('Z'))) -- cgit v1.2.3 From f0aa42e7e5ba62ea8a519a0cf7b086e31fccdc48 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 17 Nov 2022 20:10:52 +0100 Subject: unposted (c.f. Denis Bitouzé: users/28405): handle also lualatex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 3 +++ Completion/Unix/Command/_tex | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c42163434..1be882aae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-11-17 Oliver Kiddle + * unposted (c.f. Denis Bitouzé: users/28405): + Completion/Unix/Command/_tex: handle also lualatex + * 50934: Doc/Zsh/zle.yo, Src/Zle/zle.h, Src/Zle/zle_utils.c, Src/Zle/zle_vi.c: use OSC 52 escape sequence when copying to "* or "+ vi buffers diff --git a/Completion/Unix/Command/_tex b/Completion/Unix/Command/_tex index f1428c494..1a70b5058 100644 --- a/Completion/Unix/Command/_tex +++ b/Completion/Unix/Command/_tex @@ -1,4 +1,4 @@ -#compdef tex latex slitex pdftex pdflatex jadetex pdfjadetex xetex=tex xelatex=latex latexmk +#compdef tex latex slitex pdftex pdflatex jadetex pdfjadetex xetex=tex xelatex=latex latexmk lualatex _arguments : \ '-enc[enable encTeX extensions]' \ -- cgit v1.2.3 From ca87b7e43fa40b627a9b868079398c4fae6a4dc2 Mon Sep 17 00:00:00 2001 From: Wu Zhenyu Date: Sun, 14 Aug 2022 04:15:13 +0800 Subject: github #95: Add completions for neomutt --- ChangeLog | 3 +++ Completion/Unix/Command/_mutt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1be882aae..7d4b0534a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-11-17 Oliver Kiddle + * github #95: Wu Zhenyu: Completion/Unix/Command/_mutt: + Add completions for neomutt + * unposted (c.f. Denis Bitouzé: users/28405): Completion/Unix/Command/_tex: handle also lualatex diff --git a/Completion/Unix/Command/_mutt b/Completion/Unix/Command/_mutt index 67b974a8d..9686ce6f1 100644 --- a/Completion/Unix/Command/_mutt +++ b/Completion/Unix/Command/_mutt @@ -1,4 +1,4 @@ -#compdef mutt +#compdef mutt neomutt _arguments -s -S \ '::recipient:_email_addresses -n mutt' \ -- cgit v1.2.3 From dbefe08f3ef9921c2e02e481659f3caa5e8aabe9 Mon Sep 17 00:00:00 2001 From: Matt Koscica Date: Fri, 18 Feb 2022 09:02:11 +0100 Subject: github #87 (tweaked): update options tmux 3.4 Import completion updates from tmux.git, the revision used was c67abcf8182b, and the updates were generated by Util/check-tmux-state. check-tmux-state: changes to output parsing + variable declaration parsing of `tmux show-options` is slightly more idiomatic (thanks to @phy1729 for the syntax), and it now also ignores user-specified options (which are prefixed with an @ symbol). the lines defining and declaring supported_server_options were also swapped to the correct order - `typeset` was being called after supported_server_options was populated, contrary to all the other supported_*/available_* arrays used in the same area of the file. --- ChangeLog | 3 +++ Completion/Unix/Command/_tmux | 53 ++++++++++++++++++++++++++++++++++++++----- Util/check-tmux-state | 14 ++++++------ 3 files changed, 57 insertions(+), 13 deletions(-) mode change 100644 => 100755 Util/check-tmux-state diff --git a/ChangeLog b/ChangeLog index 7d4b0534a..c4a88f053 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-11-17 Oliver Kiddle + * github #87: Matt Koscica: Completion/Unix/Command/_tmux: + update options tmux 3.4 + * github #95: Wu Zhenyu: Completion/Unix/Command/_mutt: Add completions for neomutt diff --git a/Completion/Unix/Command/_tmux b/Completion/Unix/Command/_tmux index 844af58fc..c8ed24b26 100644 --- a/Completion/Unix/Command/_tmux +++ b/Completion/Unix/Command/_tmux @@ -130,6 +130,8 @@ _tmux_aliasmap=( popup display-popup # buffers + clearphist clear-prompt-history + showphist show-prompt-history clearhist clear-history deleteb delete-buffer lsb list-buffers @@ -267,6 +269,11 @@ _tmux-clear-history() { _arguments '-t+[specify target pane]:pane:__tmux-panes' } +_tmux-clear-prompt-history() { + [[ -n ${tmux_describe} ]] && print "remove history of values for command line prompts" && return + _arguments '-T+[specify prompt type]:prompt type:(command search target window-target)' +} + _tmux-clock-mode() { [[ -n ${tmux_describe} ]] && print "enter clock mode" && return _arguments '-t+[specify target pane]:pane:__tmux-panes' @@ -282,8 +289,7 @@ _tmux-command-prompt() { '-I+[specify list of initial inputs]:initial-text (comma-separated list)' \ '-p+[specify list of prompts]:prompts (comma-separated list)' \ '-t+[specify target client]:client:__tmux-clients' \ - '(-W)-T[prompt is for a target - tab complete as appropriate]' \ - '(-T)-W[prompt is for a window - tab complete as appropriate]' \ + '-T+[specify prompt type]:prompt type:(command search target window-target)' \ '*:::template:= _tmux' } @@ -388,13 +394,19 @@ _tmux-display-panes() { _tmux-display-popup() { [[ -n ${tmux_describe} ]] && print "display a popup box over a pane" && return _arguments -s \ + "-B[don't surround the popup by a border]" \ '-C[close any popup on the client]' \ '-c+[specify target client]:client:__tmux-clients' \ '-d+[specify working directory for the command]:directory:_directories' \ + '*-e[specify environment variable]:environment variable:_parameters -g "*export*" -qS=' \ '-E[close the popup when the command exits]' \ + '(-E)-EE[only close the popup when the command exits successfully]' \ '-w+[specify width]:width' \ '-h+[specify height]:height' \ + '-s+[specify the style for the popup]:style:__tmux-style' \ + '-S+[specify the style for the popup border]:style:__tmux-style' \ '-t+[specify target pane]:pane:__tmux-panes' \ + '-T+[specify popup title (supports formats)]:format:__tmux-formats' \ '-x+[specify horizontal position]:position' \ '-y+[specify vertical position]:position' \ ':shell command:_cmdstring' @@ -865,6 +877,10 @@ _tmux-send-prefix() { '-t+[specify target pane]:pane:__tmux-panes' } +# NOTE: this is actually an alias for "show-messages -JT", but until the +# aliasmap system in check-tmux-state can properly handle aliases which are +# more complex than a single word, it's best to leave this here. + _tmux-server-info() { [[ -n ${tmux_describe} ]] && print "show server information" && return __tmux-nothing-else @@ -1041,6 +1057,11 @@ _tmux-show-options() { return ret } +_tmux-show-prompt-history() { + [[ -n ${tmux_describe} ]] && print "show status prompt history" && return + _arguments '-T+[specify prompt type]:prompt type:(command search target window-target)' +} + _tmux-show-window-options() { [[ -n ${tmux_describe} ]] && print "show window options" && return local curcontext="$curcontext" state line ret=1 @@ -1530,7 +1551,6 @@ function __tmux-option-guard() { 'status-right-style:__tmux-style' 'status-style:__tmux-style' 'update-environment:MSG:string listing env. variables' - 'user-keys:MSG:key' 'visual-activity:DESC:on off' 'visual-bell:DESC:on off' 'visual-silence:DESC:on off' @@ -1549,6 +1569,7 @@ function __tmux-option-guard() { 'message-limit:'${int_guard} 'set-clipboard:DESC:on off' 'terminal-overrides:MSG:overrides string' + 'user-keys:MSG:key' ) else options=( @@ -1643,6 +1664,8 @@ function __tmux-session-options() { 'set-titles-string:format used by set-titles' 'silence-action:set action on window silence when monitor-silence is on' 'status:show or hide the status bar' + 'status-bg:set the background style used by the status bar' + 'status-fg:set the foreground style used by the status bar' 'status-format:specify the format to be used for each line of the status line' 'status-interval:interval (in seconds) for status bar updates' 'status-justify:position of the window list in status bar' @@ -1656,7 +1679,6 @@ function __tmux-session-options() { 'status-right-style:style of right part of status line' 'status-style:style status line' "update-environment:list of variables to be copied to a session's environment" - 'user-keys:set list of user-defined key escape sequences' 'visual-activity:display status line messages upon activity' 'visual-bell:use visual bell instead of audible' 'visual-silence:print a message if monitor-silence is on' @@ -1701,20 +1723,28 @@ function __tmux-panes() { fi } + function __tmux-server-options() { local -a tmux_server_options tmux_server_options=( + 'backspace:set key sent by tmux for backspace' 'buffer-limit:number of buffers kept per session' 'command-alias:custom command aliases' + 'copy-command:specify the default command when "copy-pipe" is called without arguments' 'default-terminal:default terminal definition string' 'escape-time:set timeout to detect single escape characters (in msecs)' + 'editor:specify the command used when tmux runs an editor' 'exit-unattached:make server exit if it has no attached clients' 'exit-empty:exit when there are no active sessions' + 'extended-keys:control whether tmux will send extended keys through to the terminal' 'focus-events:request focus events from terminal' 'history-file:tmux command history file name' 'message-limit:set size of message log per client' + 'prompt-history-limit:set the number of history items to save in the history file' 'set-clipboard:use esc sequences to set terminal clipboard' + 'terminal-features:set terminal features not detected by terminfo' 'terminal-overrides:override terminal descriptions' + 'user-keys:set list of user-defined key escape sequences' ) _describe -t tmux-server-options 'tmux server option' tmux_server_options } @@ -1770,10 +1800,15 @@ function __tmux-window-options() { 'aggressive-resize:aggressively resize windows' 'allow-rename:allow programs to change window titles' 'alternate-screen:allow alternate screen feature to be used' - 'automatic-rename:attempt to automatically rename windows' 'automatic-rename-format:format for automatic renames' + 'automatic-rename:attempt to automatically rename windows' 'clock-mode-colour:set clock colour' 'clock-mode-style:set clock hour format (12/24)' + 'copy-mode-current-match-style:set the style of the current search match in copy mode' + 'copy-mode-mark-style:set the style of the line containing the mark in copy mode' + 'copy-mode-match-style:set the style of search matches in copy mode' + 'cursor-colour:set the colour of the cursor' + 'cursor-style:set the style of the cursor' 'main-pane-height:set height for main-* layouts' 'main-pane-width:set width for main-* layouts' 'mode-keys:mode to use in copy and choice modes (vi/emacs)' @@ -1786,11 +1821,18 @@ function __tmux-window-options() { 'pane-active-border-style:style of border of active pane' 'pane-base-index:integer at which to start indexing panes' 'pane-border-format:set pane border format string' + 'pane-border-indicators:set the indicator style for the active pane in a two pane split' + 'pane-border-lines:set the type of characters used for drawing pane borders' 'pane-border-status:turn border status off or set its position' 'pane-border-style:style of border pane' + "pane-colours:an array used to configure tmux's colour palette" + 'popup-border-lines:set the type of line used to draw popup borders' + "popup-border-style:set the style for the popup's border" + 'popup-style:set the popup style' "remain-on-exit:don't destroy windows after the program exits" 'synchronize-panes:send input to all panes of a window' 'window-active-style:style of active window' + 'window-size:indicate how to automatically size windows' 'window-status-activity-style:style of status bar activity tag' 'window-status-bell-style:style of status bar bell tag' 'window-status-current-format:set status line format for active window' @@ -1799,7 +1841,6 @@ function __tmux-window-options() { 'window-status-last-style:style of last window in status bar' 'window-status-separator:separator drawn between windows in status line' 'window-status-style:general status bar style' - 'window-size:indicate how to automatically size windows' 'window-style:style of window' 'wrap-search:search wrap around at the end of a pane' 'xterm-keys:generate xterm-style function key sequences' diff --git a/Util/check-tmux-state b/Util/check-tmux-state old mode 100644 new mode 100755 index 2c6106203..d95e0c230 --- a/Util/check-tmux-state +++ b/Util/check-tmux-state @@ -74,18 +74,18 @@ available_aliases=( $( $tmux list-commands | # Gather information about options: typeset -a supported_session_options supported_session_options=( ${"${tmux_session_options[@]}"%%:*} ) -typeset -a available_session_options -available_session_options=( $( $tmux show-options -g | cut -f1 -d' ' ) ) +typeset -aU available_session_options +available_session_options=( ${${${(f)"$($tmux show-options -g)"}:#@*}%%(\[<->\])# *} ) -typeset -a available_server_options -supported_server_options=( ${"${tmux_server_options[@]}"%%:*} ) typeset -a supported_server_options -available_server_options=( $( $tmux show-options -s -g | cut -f1 -d' ' ) ) +supported_server_options=( ${"${tmux_server_options[@]}"%%:*} ) +typeset -aU available_server_options +available_server_options=( ${${${(f)"$($tmux show-options -s -g)"}:#@*}%%(\[<->\])# *} ) typeset -a supported_window_options supported_window_options=( ${"${tmux_window_options[@]}"%%:*} ) -typeset -a available_window_options -available_window_options=( $( $tmux show-options -w -g | cut -f1 -d' ' ) ) +typeset -aU available_window_options +available_window_options=( ${${${(f)"$($tmux show-options -w -g)"}:#@*}%%(\[<->\])# *} ) typeset -a supported available -- cgit v1.2.3 From e4aeb3b911d1909a4d150ec832159b97ebec2a40 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 17 Nov 2022 21:10:28 +0100 Subject: unposted (c.f. Norikatsu Shigemura: github #96): add missing local declaration --- ChangeLog | 3 +++ Completion/Unix/Command/_cut | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c4a88f053..c0fe24965 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-11-17 Oliver Kiddle + * unposted (c.f. Norikatsu Shigemura: github #96): + Completion/Unix/Command/_cut: add missing local declaration + * github #87: Matt Koscica: Completion/Unix/Command/_tmux: update options tmux 3.4 diff --git a/Completion/Unix/Command/_cut b/Completion/Unix/Command/_cut index d3b1e2b10..29565280d 100644 --- a/Completion/Unix/Command/_cut +++ b/Completion/Unix/Command/_cut @@ -1,6 +1,7 @@ #compdef cut gcut typeset -A _cut_args +local -a args case $LANG in (de_DE.UTF-8) @@ -45,7 +46,7 @@ if _pick_variant gnu="Free Soft" unix --version; then '*:file:_files' else case $OSTYPE in - freebsd*|dragonfly*) args+=( '(-d)-w[use whitespace as the delimiter]' ) ;; + freebsd*|dragonfly*) args=( '(-d)-w[use whitespace as the delimiter]' ) ;; esac _arguments $args \ "-b[${_cut_args[bytes]}]:list" \ -- cgit v1.2.3 From 291940bae6cc0471c35c73498e873bc58dae9a95 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Wed, 23 Nov 2022 14:21:25 +0000 Subject: unposted (cf. 51016): Add a test case for underscore-followed-by-digits in math context. --- ChangeLog | 5 +++++ Test/C01arith.ztst | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index c0fe24965..2ae9ccade 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-11-23 Daniel Shahaf + + * unposted (cf. 51016): Test/C01arith.ztst: Add a test case + for underscore-followed-by-digits in math context. + 2022-11-17 Oliver Kiddle * unposted (c.f. Norikatsu Shigemura: github #96): diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst index d0092fefa..ba9c65e5b 100644 --- a/Test/C01arith.ztst +++ b/Test/C01arith.ztst @@ -251,6 +251,14 @@ >5000 >255 + set -- {101..120} + _10=42 + echo $_10 : $1_0 + echo $(( _10 )) : $(( 1_0 )) +0:underscores in front of a numeric identifier is not a math constant +>42 : 101_0 +>42 : 10 + # Force floating point. for expr in "3/4" "0x100/0x200" "0x30/0x10"; do print $(( $expr )) -- cgit v1.2.3 From 1be52186b4aed40eb9fe295691932037ecf6c6ab Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Fri, 2 Dec 2022 19:19:27 +0900 Subject: 51079: metafy sep in array subscript flag (s:sep:) this enable sep to contain \0 etc. --- ChangeLog | 5 +++++ Src/params.c | 10 +++++++--- Test/D06subscript.ztst | 5 +++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ae9ccade..27c6fee98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-12-02 Jun-ichi Takimoto + + * 51079: Src/params.c, Test/D06subscript.ztst: metafy sep in the + array subscript flag (s:sep:) so that sep can contain \0 etc. + 2022-11-23 Daniel Shahaf * unposted (cf. 51016): Test/C01arith.ztst: Add a test case diff --git a/Src/params.c b/Src/params.c index 27ea82298..f1fe38955 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1262,7 +1262,6 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, /* first parse any subscription flags */ if (v->pm && (*s == '(' || *s == Inpar)) { int escapes = 0; - int waste; for (s++; *s != ')' && *s != Outpar && s != *str; s++) { switch (*s) { case 'r': @@ -1339,8 +1338,13 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, sav = *t; *t = '\0'; s += arglen; - sep = escapes ? getkeystring(s, &waste, GETKEYS_SEP, NULL) - : dupstring(s); + if (escapes) { + int len; + sep = getkeystring(s, &len, GETKEYS_SEP, NULL); + sep = metafy(sep, len, META_HREALLOC); + } + else + sep = dupstring(s); *t = sav; s = t + arglen - 1; break; diff --git a/Test/D06subscript.ztst b/Test/D06subscript.ztst index adbd398c4..21127e641 100644 --- a/Test/D06subscript.ztst +++ b/Test/D06subscript.ztst @@ -294,3 +294,8 @@ F:Regression test for workers/42297 [[ ${a[$i]} = ${a[i]} ]] 0f:Math evaluation of commas in array subscripts F:In math, (($i)) should be the same as ((i)), see workers/47748. + + string=$'foo\0bar' + echo ${string[(pws:\0:)1]} +0:Word splitting by NUL +>foo -- cgit v1.2.3 From 41b402d36d0aeac594cf424a9e46b5edb20c815d Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Fri, 2 Dec 2022 19:34:55 +0900 Subject: 51080: allow multibyte chars in glob qualifier (u:uname:) --- ChangeLog | 3 +++ Src/glob.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 27c6fee98..33f3f90de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-02 Jun-ichi Takimoto + * 51080: Src/glob.c: allow multibyte characters in glob qualifier + (u:uname:) + * 51079: Src/params.c, Test/D06subscript.ztst: metafy sep in the array subscript flag (s:sep:) so that sep can contain \0 etc. diff --git a/Src/glob.c b/Src/glob.c index 400be12d5..490bafc37 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1481,7 +1481,7 @@ zglob(LinkList list, LinkNode np, int nountok) sav = *tt; *tt = '\0'; - if ((pw = getpwnam(s + arglen))) + if ((pw = getpwnam(unmeta(s + arglen)))) data = pw->pw_uid; else { zerr("unknown username '%s'", s + arglen); -- cgit v1.2.3 From 23dc19f005b6a9ac0740b46155f14dbcfa697421 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sat, 3 Dec 2022 20:31:42 -0800 Subject: 51001: Reverts 8839e969b, most of 1ba8714a, and d873ed60. Also correct ChangeLog --- ChangeLog | 11 ++--------- NEWS | 9 --------- Src/exec.c | 4 +--- Src/loop.c | 12 ++++++------ Test/C03traps.ztst | 15 ++++++++++----- 5 files changed, 19 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33f3f90de..3b77f1023 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,20 +31,13 @@ 2022-11-09 Bart Schaefer - * 50929: Src/exec.c: fix handling of ERR_RETURN bent by 50928. - - * 50928: News, Src/exec.c, Test/C03traps.ztst: fix tests for 50897, - mention behavior change in NEWS + * 50928: Test/C03traps.ztst: scoping of ERR_RETURN in test + (most of this patch was not retained) * 50922: Src/exec.c, Src/jobs.c: fix additional cases of signals for current shell jobs on the right of a pipeline. Backs out part of 50874. -2022-11-08 Bart Schaefer - - * 50897: Src/exec.c, Src/loop.c: nonzero status of complex - commands should trigger ERR_EXIT - 2022-11-08 Peter Stephenson * users/28338: Src/lex.c, Test/D08cmdsubst.ztst: edge case of an diff --git a/NEWS b/NEWS index 9c28169bb..cdafd1ff5 100644 --- a/NEWS +++ b/NEWS @@ -4,15 +4,6 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH Note also the list of incompatibilities in the README file. -Changes since 5.9 ------------------ - -Handling of ERR_EXIT is corrected when the final status of a structured -command (for, select, while, repeat, if, case, or a list in braces) is -nonzero. To be compatible with other shells, "zsh -e" now exits in -those circumstances, whereas previous versions did not. This does not -affect the handling of nonzero status within conditional statements. - Changes since 5.8.1 ------------------- diff --git a/Src/exec.c b/Src/exec.c index ce0c1f1ad..b0f42ae67 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -451,7 +451,7 @@ execcursh(Estate state, int do_exec) cmdpop(); state->pc = end; - this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); + this_noerrexit = 1; return lastval; } @@ -1442,8 +1442,6 @@ execlist(Estate state, int dont_change_job, int exiting) execsimple(state); else execpline(state, code, ltype, (ltype & Z_END) && exiting); - if (!locallevel || unset(ERRRETURN)) - this_noerrexit = noerrexit; state->pc = next; goto sublist_done; break; diff --git a/Src/loop.c b/Src/loop.c index be5261369..db5b3e097 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -208,7 +208,7 @@ execfor(Estate state, int do_exec) loops--; simple_pline = old_simple_pline; state->pc = end; - this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); + this_noerrexit = 1; return lastval; } @@ -336,7 +336,7 @@ execselect(Estate state, UNUSED(int do_exec)) loops--; simple_pline = old_simple_pline; state->pc = end; - this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); + this_noerrexit = 1; return lastval; } @@ -478,7 +478,7 @@ execwhile(Estate state, UNUSED(int do_exec)) popheap(); loops--; state->pc = end; - this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); + this_noerrexit = 1; return lastval; } @@ -532,7 +532,7 @@ execrepeat(Estate state, UNUSED(int do_exec)) loops--; simple_pline = old_simple_pline; state->pc = end; - this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); + this_noerrexit = 1; return lastval; } @@ -587,7 +587,7 @@ execif(Estate state, int do_exec) lastval = 0; } state->pc = end; - this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); + this_noerrexit = 1; return lastval; } @@ -701,7 +701,7 @@ execcase(Estate state, int do_exec) if (!anypatok) lastval = 0; - this_noerrexit = (WC_SUBLIST_TYPE(*end) != WC_SUBLIST_END); + this_noerrexit = 1; return lastval; } diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index 5cc45e2de..a7a040d70 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -726,7 +726,8 @@ F:Must be tested with a top-level script rather than source or function done print OK ) -1:ERR_EXIT triggered by status 1 at end of for +0:ERR_EXIT not triggered by status 1 at end of for +>OK (setopt err_exit integer x=0 @@ -735,7 +736,8 @@ F:Must be tested with a top-level script rather than source or function done print OK ) -1:ERR_EXIT triggered by status 1 at end of while +0:ERR_EXIT not triggered by status 1 at end of while +>OK (setopt err_exit repeat 1; do @@ -743,7 +745,8 @@ F:Must be tested with a top-level script rather than source or function done print OK ) -1:ERR_EXIT triggered by status 1 at end of repeat +0:ERR_EXIT not triggered by status 1 at end of repeat +>OK (setopt err_exit if true; then @@ -751,7 +754,8 @@ F:Must be tested with a top-level script rather than source or function fi print OK ) -1:ERR_EXIT triggered by status 1 at end of if +0:ERR_EXIT not triggered by status 1 at end of if +>OK (setopt err_exit { @@ -759,7 +763,8 @@ F:Must be tested with a top-level script rather than source or function } print OK ) -1:ERR_EXIT triggered by status 1 at end of { } +0:ERR_EXIT not triggered by status 1 at end of { } +>OK unsetopt err_exit err_return (setopt err_exit -- cgit v1.2.3 From fda6fd9513ffdbd75c490e8e55ce33f370a9bd17 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sat, 3 Dec 2022 20:35:58 -0800 Subject: 51001: fix for ERR_EXIT with "always" blocks; update tests --- Src/loop.c | 1 + Test/C03traps.ztst | 36 +++++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Src/loop.c b/Src/loop.c index db5b3e097..7c3e04b8a 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -793,6 +793,7 @@ exectry(Estate state, int do_exec) cmdpop(); popheap(); state->pc = end; + this_noerrexit = 1; return endval; } diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index a7a040d70..4719dfd57 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -721,22 +721,19 @@ F:Must be tested with a top-level script rather than source or function >Good (setopt err_exit - for x in y; do - false && true - done + false && true print OK ) -0:ERR_EXIT not triggered by status 1 at end of for +0:ERR_EXIT not triggered by "false && true" >OK (setopt err_exit - integer x=0 - while (( ! x++ )); do + for x in y; do false && true done print OK ) -0:ERR_EXIT not triggered by status 1 at end of while +0:ERR_EXIT not triggered by status 1 at end of for >OK (setopt err_exit @@ -755,6 +752,31 @@ F:Must be tested with a top-level script rather than source or function print OK ) 0:ERR_EXIT not triggered by status 1 at end of if +>OK + + (setopt err_exit + loop=true + while print COND; $loop; do + loop=false + false && true + done + print OK + ) +0:ERR_EXIT not triggered by status 1 at end of while +>COND +>COND +>OK + + (setopt err_exit + { + false && true + } always { + print ALWAYS + } + print OK + ) +0:ERR_EXIT not triggered by status 1 at end of always +>ALWAYS >OK (setopt err_exit -- cgit v1.2.3 From d47b8480f0eb883d54fcbef22999bf26d13d56a4 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sat, 3 Dec 2022 20:42:13 -0800 Subject: 51001: fix for ERR_EXIT with pipeline negation ("!"); update tests --- Src/exec.c | 13 ++++++++----- Test/C03traps.ztst | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Src/exec.c b/Src/exec.c index b0f42ae67..d8501ca68 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -63,7 +63,10 @@ typedef struct funcsave *Funcsave; /**/ int noerrexit; -/* used to suppress ERREXIT or ERRRETURN for one occurrence: 0 or 1 */ +/* + * used to suppress ERREXIT and ERRRETURN for the command under evaluation. + * 0 or 1 + */ /**/ int this_noerrexit; @@ -1429,10 +1432,7 @@ execlist(Estate state, int dont_change_job, int exiting) if (!oldnoerrexit) 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 ! */ + /* suppress errexit for the commands in ! */ noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; } switch (WC_SUBLIST_TYPE(code)) { @@ -1443,6 +1443,9 @@ execlist(Estate state, int dont_change_job, int exiting) else execpline(state, code, ltype, (ltype & Z_END) && exiting); state->pc = next; + /* suppress errexit for the command "! ..." */ + if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT) + this_noerrexit = 1; goto sublist_done; break; case WC_SUBLIST_AND: diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index 4719dfd57..08e24a32e 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -720,6 +720,21 @@ F:Must be tested with a top-level script rather than source or function 0:ERR_RETURN in "else" branch in nested function >Good + (setopt err_exit + ! true + print OK + ) +0:ERR_EXIT not triggered by "! true" +>OK + + (setopt err_exit + fn() { true } + ! fn + print OK + ) +0:ERR_EXIT not triggered by "! fn" +>OK + (setopt err_exit false && true print OK -- cgit v1.2.3 From dd3ba3d5991f5c99334742147fb2213b8c400a42 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sat, 3 Dec 2022 20:44:10 -0800 Subject: 51001: fix for ERR_EXIT following shell function; update tests --- Src/exec.c | 10 +------ Test/C03traps.ztst | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 9 deletions(-) diff --git a/Src/exec.c b/Src/exec.c index d8501ca68..43df8211a 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5932,15 +5932,6 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) * This function is forced to return. */ retflag = 0; - /* - * The calling function isn't necessarily forced to return, - * but it should be made sensitive to ERR_EXIT and - * ERR_RETURN as the assumptions we made at the end of - * constructs within this function no longer apply. If - * there are cases where this is not true, they need adding - * to C03traps.ztst. - */ - this_noerrexit = 0; breaks = funcsave->breaks; } freearray(pparams); @@ -6010,6 +6001,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) trap_return++; ret = lastval; noerrexit = funcsave->noerrexit; + this_noerrexit = 0; if (noreturnval) { lastval = funcsave->lastval; numpipestats = funcsave->numpipestats; diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index 08e24a32e..a8880673f 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -742,6 +742,15 @@ F:Must be tested with a top-level script rather than source or function 0:ERR_EXIT not triggered by "false && true" >OK + (setopt err_exit + fn() { + false && true + } + fn + print OK + ) +1:ERR_EXIT not triggered by "false && true" but by return from fn + (setopt err_exit for x in y; do false && true @@ -751,6 +760,17 @@ F:Must be tested with a top-level script rather than source or function 0:ERR_EXIT not triggered by status 1 at end of for >OK + (setopt err_exit + fn() { + for x in y; do + false && true + done + } + fn + print OK + ) +1:ERR_EXIT not triggered by status 1 at end of for but by return from fn + (setopt err_exit repeat 1; do false && true @@ -760,6 +780,17 @@ F:Must be tested with a top-level script rather than source or function 0:ERR_EXIT not triggered by status 1 at end of repeat >OK + (setopt err_exit + fn() { + repeat 1; do + false && true + done + } + fn + print OK + ) +1:ERR_EXIT not triggered by status 1 at end of repeat but by return from fn + (setopt err_exit if true; then false && true @@ -769,6 +800,17 @@ F:Must be tested with a top-level script rather than source or function 0:ERR_EXIT not triggered by status 1 at end of if >OK + (setopt err_exit + fn() { + if true; then + false && true + fi + } + fn + print OK + ) +1:ERR_EXIT not triggered by status 1 at end of if but by return from fn + (setopt err_exit loop=true while print COND; $loop; do @@ -782,6 +824,21 @@ F:Must be tested with a top-level script rather than source or function >COND >OK + (setopt err_exit + fn() { + loop=true + while print COND; $loop; do + loop=false + false && true + done + } + fn + print OK + ) +1:ERR_EXIT not triggered by status 1 at end of while but by return from fn +>COND +>COND + (setopt err_exit { false && true @@ -794,6 +851,20 @@ F:Must be tested with a top-level script rather than source or function >ALWAYS >OK + (setopt err_exit + fn() { + { + false && true + } always { + print ALWAYS + } + } + fn + print OK + ) +1:ERR_EXIT not triggered by status 1 at end of always but by return from fn +>ALWAYS + (setopt err_exit { false && true @@ -803,6 +874,17 @@ F:Must be tested with a top-level script rather than source or function 0:ERR_EXIT not triggered by status 1 at end of { } >OK + (setopt err_exit + fn() { + { + false && true + } + } + fn + print OK + ) +1:ERR_EXIT not triggered by status 1 at end of { } but by return from fn + unsetopt err_exit err_return (setopt err_exit for x in y; do -- cgit v1.2.3 From 28ac3e9fe5b68b517c477ad231966aaeed426085 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 3 Dec 2022 20:46:13 -0800 Subject: 51001: ChangeLog entry for preceding four patch commits. --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3b77f1023..fdd9ac26c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-12-03 Bart Schaefer + + * Philippe Altherr: 51001: Src/exec.c, Src/loop.c, + Test/C03traps.ztst: adjust handling of ERR_EXIT to more closely + align with POSIX and with other shells; add corresponding tests + 2022-12-02 Jun-ichi Takimoto * 51080: Src/glob.c: allow multibyte characters in glob qualifier -- cgit v1.2.3 From 259f1e944b96715fda25f7ba227da05bdb7e600f Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sat, 3 Dec 2022 21:03:36 -0800 Subject: 51071: fix ERR_RETURN for functions in conditional statements --- ChangeLog | 4 ++++ Src/exec.c | 12 +++++------- Test/C03traps.ztst | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index fdd9ac26c..215da1b19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-12-03 Bart Schaefer + * Philippe Altherr: 51071: Src/exec.c, Test/C03traps.ztst: fix + ERR_RETURN when a function using && / || is called within another + statement using && / || + * Philippe Altherr: 51001: Src/exec.c, Src/loop.c, Test/C03traps.ztst: adjust handling of ERR_EXIT to more closely align with POSIX and with other shells; add corresponding tests diff --git a/Src/exec.c b/Src/exec.c index 43df8211a..711d8f374 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1427,14 +1427,12 @@ execlist(Estate state, int dont_change_job, int exiting) goto sublist_done; } while (wc_code(code) == WC_SUBLIST) { - int isend = (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END); + int isandor = WC_SUBLIST_TYPE(code) != WC_SUBLIST_END; + int isnot = WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT; next = state->pc + WC_SUBLIST_SKIP(code); - if (!oldnoerrexit) - noerrexit = isend ? 0 : NOERREXIT_EXIT | NOERREXIT_RETURN; - if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT) { - /* suppress errexit for the commands in ! */ + /* suppress errexit for commands before && and || and after ! */ + if (isandor || isnot) noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; - } switch (WC_SUBLIST_TYPE(code)) { case WC_SUBLIST_END: /* End of sublist; just execute, ignoring status. */ @@ -1444,7 +1442,7 @@ execlist(Estate state, int dont_change_job, int exiting) execpline(state, code, ltype, (ltype & Z_END) && exiting); state->pc = next; /* suppress errexit for the command "! ..." */ - if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT) + if (isnot) this_noerrexit = 1; goto sublist_done; break; diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index a8880673f..b7132da81 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -670,6 +670,22 @@ F:Must be tested with a top-level script rather than source or function >before-out >before-in + (set -o err_return + fn() { + print before-in + { false; true } && true + print after-in + } + print before-out + fn && true + print after-out + ) +0:ERR_RETURN not triggered on LHS of "&&" in function on LHS of "&&" (regression test) +>before-out +>before-in +>after-in +>after-out + mkdir -p zdotdir print >zdotdir/.zshenv ' setopt norcs errreturn -- cgit v1.2.3 From f253ea6b9d14901e24fa6a376936effad9e6547b Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sat, 3 Dec 2022 21:14:26 -0800 Subject: 51076: fix ERR_EXIT when used with "eval" or "source"; documentary comments --- ChangeLog | 3 +++ Src/exec.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- Test/C03traps.ztst | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 215da1b19..2355b4fa1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-03 Bart Schaefer + * Philippe Altherr: 51076: Src/exec.c, Test/C03traps.ztst: fix + ERR_EXIT when used with "eval" or "source"; documentary comments + * Philippe Altherr: 51071: Src/exec.c, Test/C03traps.ztst: fix ERR_RETURN when a function using && / || is called within another statement using && / || diff --git a/Src/exec.c b/Src/exec.c index 711d8f374..8ff6489ec 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -56,7 +56,17 @@ struct funcsave { typedef struct funcsave *Funcsave; /* - * used to suppress ERREXIT and trapping of SIGZERR, SIGEXIT. + * Used to suppress ERREXIT and trapping of SIGZERR, SIGEXIT in the + * evaluation of sub-commands of the command under evaluation. The + * variable must be updated before the evaluation of the sub-commands + * starts and restored to its previous state right after that + * evaluation ends. The variable is read and acted upon in execlist. + * + * A good usage example can be found in execwhile in loop.c, which + * evaluates while statements. The variable is updated to disable + * ERREXIT just before evaluating the while's condition and restored + * to its previous state right after the evaluation of the condition. + * * Bits from noerrexit_bits. */ @@ -64,7 +74,36 @@ typedef struct funcsave *Funcsave; int noerrexit; /* - * used to suppress ERREXIT and ERRRETURN for the command under evaluation. + * Used to suppress ERREXIT and ERRRETURN for the command under + * evaluation. The variable must be enabled (set to 1) at the very + * end of the evaluation of the command. It must come after the + * evaluation of any sub-commands of the command under evaluation. The + * variable is read and acted upon in execlist, which also takes care + * of initialising and resetting it to 0. + * + * Unlike the variable noerrexit, whose state applies to the + * evaluation of whole sub-commands (and their direct and indirect + * sub-commands), the scope of the variable this_noerrexit is much + * more localized. ERREXIT and ERRRETURN are triggered at the end of + * the function execlist after the evaluation of some or all of the + * list's sub-commands. The role of the variable this_noerrexit is to + * give to the functions evaluating the list's sub-commands the + * possibility to tell the calling execlist not to trigger ERREXIT and + * ERRRETURN. In other words, the variable acts as an additional + * return value between the called evaluation functions and the + * calling execlist. For that reason the variable must always be set + * as late as possible and in particular after any sub-command + * evaluation. If the variable is set before the evaluation of a + * sub-command, if may affect the wrong execlist, if the sub-command + * evaluation involves another execlist call, and/or the variable may + * get modified by the sub-command evaluation and thus wouldn't return + * the desired value to the calling execlist. + * + * Good usage examples can be found in the exec functions in loop.c, + * which evaluate compound commands. The variable is enabled right + * before returning from the functions, after all the sub-commands of + * the compound commands have already been evaluated. + * * 0 or 1 */ @@ -1427,6 +1466,7 @@ execlist(Estate state, int dont_change_job, int exiting) goto sublist_done; } while (wc_code(code) == WC_SUBLIST) { + this_noerrexit = 0; int isandor = WC_SUBLIST_TYPE(code) != WC_SUBLIST_END; int isnot = WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT; next = state->pc + WC_SUBLIST_SKIP(code); @@ -1582,6 +1622,7 @@ sublist_done: break; code = *state->pc++; } + this_noerrexit = 0; pline_level = old_pline_level; list_pipe = old_list_pipe; list_pipe_job = old_list_pipe_job; @@ -5999,7 +6040,6 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) trap_return++; ret = lastval; noerrexit = funcsave->noerrexit; - this_noerrexit = 0; if (noreturnval) { lastval = funcsave->lastval; numpipestats = funcsave->numpipestats; diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index b7132da81..e0b6afb5f 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -954,6 +954,47 @@ F:Must be tested with a top-level script rather than source or function 1:ERR_EXIT triggered by status 1 at end of anon func >Still functioning + (setopt err_exit + loop=true; while print loop $? >&2; $loop; do loop=false; false && true; done + print done $? >&2 + ) +0: ERR_EXIT neither triggered inside loop nor triggered by while statement +?loop 0 +?loop 1 +?done 1 + + (setopt err_exit + { loop=true; while print loop $? >&2; $loop; do loop=false; false && true; done } || false + print done $? >&2 + ) +1: ERR_EXIT not triggered inside loop but triggered by rhs of || +?loop 0 +?loop 1 + + (setopt err_exit + eval 'loop=true; while print loop $? >&2; $loop; do loop=false; false && true; done' + print done $? >&2 + ) +1: ERR_EXIT not triggered inside loop but triggered by eval +?loop 0 +?loop 1 + + (setopt err_exit + source <(echo 'loop=true; while print loop $? >&2; $loop; do loop=false; false && true; done') + print done $? >&2 + ) +1: ERR_EXIT not triggered inside loop but triggered by source +?loop 0 +?loop 1 + + (setopt err_exit + v=$(loop=true; while print loop $? >&2; $loop; do loop=false; false && true; done) + print done $? >&2 + ) +1: ERR_EXIT not triggered inside loop but triggered by command substitution +?loop 0 +?loop 1 + if zmodload zsh/system 2>/dev/null; then ( trap 'echo TERM; exit 2' TERM -- cgit v1.2.3 From ab9c579ef9a1ad6482267719f5d031f6a5dbf24e Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sat, 3 Dec 2022 21:35:51 -0800 Subject: 51098: remove unreachable NOERREXIT_UNTIL_EXEC code and effects --- ChangeLog | 3 +++ Src/exec.c | 13 +------------ Src/loop.c | 15 +++------------ Src/zsh.h | 2 -- 4 files changed, 7 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2355b4fa1..91c8e69d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-03 Bart Schaefer + * Philippe Altherr: 51098: Src/exec.c, Src/loop.c, Src/zsh.h: + remove unreachable NOERREXIT_UNTIL_EXEC code and effects + * Philippe Altherr: 51076: Src/exec.c, Test/C03traps.ztst: fix ERR_EXIT when used with "eval" or "source"; documentary comments diff --git a/Src/exec.c b/Src/exec.c index 8ff6489ec..1dd569019 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1559,14 +1559,7 @@ execlist(Estate state, int dont_change_job, int exiting) state->pc--; sublist_done: - /* - * See hairy code near the end of execif() for the - * 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 & NOERREXIT_UNTIL_EXEC)) - noerrexit = oldnoerrexit; + noerrexit = oldnoerrexit; if (sigtrapped[SIGDEBUG] && !isset(DEBUGBEFORECMD) && !donedebug) { /* @@ -3246,10 +3239,6 @@ execcmd_exec(Estate state, Execcmd_params eparams, } else preargs = NULL; - /* if we get this far, it is OK to pay attention to lastval again */ - if (noerrexit & NOERREXIT_UNTIL_EXEC) - noerrexit = 0; - /* Do prefork substitutions. * * Decide if we need "magic" handling of ~'s etc. in diff --git a/Src/loop.c b/Src/loop.c index 7c3e04b8a..61543ed73 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -569,23 +569,14 @@ execif(Estate state, int do_exec) s = 1; state->pc = next; } + noerrexit = olderrexit; if (run) { - /* we need to ignore lastval until we reach execcmd() */ - if (olderrexit || run == 2) - noerrexit = olderrexit; - else if (lastval) - noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN | NOERREXIT_UNTIL_EXEC; - else - noerrexit &= ~ (NOERREXIT_EXIT | NOERREXIT_RETURN); cmdpush(run == 2 ? CS_ELSE : (s ? CS_ELIFTHEN : CS_IFTHEN)); execlist(state, 1, do_exec); cmdpop(); - } else { - noerrexit = olderrexit; - if (!retflag && !errflag) - lastval = 0; - } + } else if (!retflag && !errflag) + lastval = 0; state->pc = end; this_noerrexit = 1; diff --git a/Src/zsh.h b/Src/zsh.h index 40f9ea537..703231ca2 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2220,8 +2220,6 @@ enum noerrexit_bits { 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 }; -- cgit v1.2.3 From 8086f106159c2e9fc562b5ce88b8aefdb5fe5d23 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sat, 3 Dec 2022 21:46:42 -0800 Subject: 51094: consistent use of bit-manipulation for noerrexit value changes --- ChangeLog | 3 +++ Src/exec.c | 6 +++--- Src/loop.c | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91c8e69d3..8caeecd81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-03 Bart Schaefer + * Philippe Altherr: 51094: Src/exec.c, Src/loop.c: consistent + use of bit-manipulation for noerrexit flag value changes + * Philippe Altherr: 51098: Src/exec.c, Src/loop.c, Src/zsh.h: remove unreachable NOERREXIT_UNTIL_EXEC code and effects diff --git a/Src/exec.c b/Src/exec.c index 1dd569019..1810fca5e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1415,7 +1415,7 @@ execlist(Estate state, int dont_change_job, int exiting) int oerrexit_opt = opts[ERREXIT]; Param pm; opts[ERREXIT] = 0; - noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; + noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN; if (ltype & Z_SIMPLE) /* skip the line number */ pc2++; pm = assignsparam("ZSH_DEBUG_CMD", @@ -1472,7 +1472,7 @@ execlist(Estate state, int dont_change_job, int exiting) next = state->pc + WC_SUBLIST_SKIP(code); /* suppress errexit for commands before && and || and after ! */ if (isandor || isnot) - noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; + noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN; switch (WC_SUBLIST_TYPE(code)) { case WC_SUBLIST_END: /* End of sublist; just execute, ignoring status. */ @@ -1568,7 +1568,7 @@ sublist_done: */ int oerrexit_opt = opts[ERREXIT]; opts[ERREXIT] = 0; - noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; + noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN; exiting = donetrap; ret = lastval; dotrap(SIGDEBUG); diff --git a/Src/loop.c b/Src/loop.c index 61543ed73..88c55dd1a 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -428,7 +428,7 @@ execwhile(Estate state, UNUSED(int do_exec)) } else { for (;;) { state->pc = loop; - noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN; + noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN; /* In case the test condition is a functional no-op, * make sure signal handlers recognize ^C to end the loop. */ -- cgit v1.2.3 From f9bb03cd72cdfe878e6ef51ef292c3a6b2550b7d Mon Sep 17 00:00:00 2001 From: Atte Peltomäki Date: Tue, 6 Dec 2022 20:40:21 -0800 Subject: 51088: fix standards reference in comment --- ChangeLog | 4 ++++ Functions/Misc/colors | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8caeecd81..5e710bb7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-12-06 Bart Schaefer + + * Atte Peltomäki: 51088: Functions/Misc/colors: typo in comment + 2022-12-03 Bart Schaefer * Philippe Altherr: 51094: Src/exec.c, Src/loop.c: consistent diff --git a/Functions/Misc/colors b/Functions/Misc/colors index 5c9924adb..8a0cec383 100644 --- a/Functions/Misc/colors +++ b/Functions/Misc/colors @@ -44,7 +44,7 @@ color=( 35 magenta 45 bg-magenta 36 cyan 46 bg-cyan 37 white 47 bg-white -# 38 iso-8316-6 # 48 bg-iso-8316-6 +# 38 iso-8613-6 # 48 bg-iso-8613-6 39 default 49 bg-default # Other codes: -- cgit v1.2.3 From 2473d83521f349c743da62a2b239dc281094c1c6 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 6 Dec 2022 20:47:10 -0800 Subject: 51108: single letter forms of Shift-JIS / EUC-JP options were reversed --- ChangeLog | 3 +++ Completion/Unix/Command/_nkf | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e710bb7c..f3d5fde9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-06 Bart Schaefer + * Shohei YOSHIDA: 51108: Completion/Unix/Command/_nkf: single + letter forms of Shift-JIS / EUC-JP options were reversed + * Atte Peltomäki: 51088: Functions/Misc/colors: typo in comment 2022-12-03 Bart Schaefer diff --git a/Completion/Unix/Command/_nkf b/Completion/Unix/Command/_nkf index 0c4f06fb5..ae79e745a 100644 --- a/Completion/Unix/Command/_nkf +++ b/Completion/Unix/Command/_nkf @@ -10,8 +10,8 @@ _arguments -s \ '(-u)-b[Output is buffered]' \ '(-b)-u[Output is unbuffered]' \ '($outputs)'{-j,--jis}'[Output is JIS 7 bit]' \ - '($outputs)'{-e,--sjis}'[Output is Shift JIS]' \ - '($outputs)'{-s,--euc}'[Output is EUC-JP]' \ + '($outputs)'{-s,--sjis}'[Output is Shift JIS]' \ + '($outputs)'{-e,--euc}'[Output is EUC-JP]' \ '($outputs)'{-w,--utf8}'[Output is UTF-8 (No BOM)]' \ '($outputs)-w8[Output is UTF-8 (BOM)]' \ '($outputs)'{-w16,-w16b0,--utf16}'[Output is UTF-16 (BigEndian; No BOM)]' \ @@ -23,8 +23,8 @@ _arguments -s \ '($outputs)--mac[Output is for Mac]' \ '($outputs)--windows[Output is for Windows]' \ '($inputs)-J[Input assumption is JIS 7 bit]' \ - '($inputs)-E[Input assumption is Shift JIS]' \ - '($inputs)-S[Input assumption is EUC-JP]' \ + '($inputs)-S[Input assumption is Shift JIS]' \ + '($inputs)-E[Input assumption is EUC-JP]' \ '($inputs)-W[Input assumption is UTF-8 (No BOM)]' \ '($inputs)-W8[Input assumption is UTF-8 (BOM)]' \ '($inputs)-W16[Input assumption is UTF-16 (BigEndian; No BOM)]' \ -- cgit v1.2.3 From ca7c42e1ee1706f39bbeb163ef323c819aee8357 Mon Sep 17 00:00:00 2001 From: Peter Grayson Date: Thu, 8 Dec 2022 09:52:42 -0500 Subject: 51138: Updated StGit patch detection in vcs_info The vcs_info patch detection code attempted to interrogate StGit patch stack state by inspecting .git/patches/applied and .git/patches/unapplied. As of StGit 0.15 (2009), patch stack metadata is captured in the repo's object database. And as of StGit 1.0 (2021), no stack or patch state is maintained in any files in the .git/ directory. Zsh's approach for interrogating StGit patch state is thus obsoleted. This patch updates vcs_info to determine whether StGit is initialized on a branch by looking at the appropriate git refs and uses StGit's prescribed interface for interrogating applied and unapplied patch state via the `stg series` command. This approach will work with all versions of StGit >=0.15. Signed-off-by: Peter Grayson --- ChangeLog | 5 ++++ Functions/VCS_Info/Backends/VCS_INFO_get_data_git | 36 +++++++++++++++++------ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3d5fde9d..63e9c5041 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-12-08 Peter Grayson + + * 51138: Functions/VCS_Info/Backends/VCS_INFO_get_data_git: + Updated StGit patch detection in vcs_info + 2022-12-06 Bart Schaefer * Shohei YOSHIDA: 51108: Completion/Unix/Command/_nkf: single diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git index e45eebc8e..23d4d31a1 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git +++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git @@ -184,15 +184,8 @@ fi VCS_INFO_adjust VCS_INFO_git_getaction ${gitdir} -local patchdir=${gitdir}/patches/${gitbranch} -if [[ -d $patchdir ]] && [[ -f $patchdir/applied ]] \ - && [[ -f $patchdir/unapplied ]] -then - # stgit - git_patches_applied=(${(f)"$(< "${patchdir}/applied")"}) - git_patches_unapplied=(${(f)"$(< "${patchdir}/unapplied")"}) - VCS_INFO_git_handle_patches -elif [[ -d "${gitdir}/rebase-merge" ]]; then +local patchdir +if [[ -d "${gitdir}/rebase-merge" ]]; then # 'git rebase -i' patchdir="${gitdir}/rebase-merge" local p @@ -389,6 +382,31 @@ elif [[ -f "${gitdir}/CHERRY_PICK_HEAD" ]]; then git_patches_unapplied=() fi VCS_INFO_git_handle_patches +elif command -v stg >/dev/null && + ${vcs_comm[cmd]} show-ref --quiet refs/stacks/${gitbranch} refs/heads/${gitbranch}.stgit 2>/dev/null && + git_patches_applied=(${(f)"$(stg series --noprefix --applied 2>/dev/null)"}) +then + # Testing for StGit patches is done after testing for all git-proper + # patches/states. If a StGit user's repo is in one of those states, they + # will want to see that instead of the StGit patch info. + + # Performance note: testing for the stg executable is done first because it + # is extremely cheap and there is nothing else to do if it isn't present. + # Using git to test whether a StGit stack is initialized is cheaper than + # running stg itself; especially for versions of StGit <= 2.0. Thus getting + # StGit patch info should only have a material runtime cost if StGit is + # installed and in-use for the current branch. + + # In StGit >=1.2, the existence of refs/stacks/ indicates StGit is + # initialized. In StGit >=0.15, it is refs/heads/.stgit. + + # N.B. the "--noprefix" option is available in StGit 2.x as an alias for + # --no-prefix. The former is compatible with StGit versions going back to + # 2008. + if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-unapplied; then + git_patches_unapplied=(${(f)"$(stg series --noprefix --unapplied 2>/dev/null)"}) + fi + VCS_INFO_git_handle_patches else gitmisc='' fi -- cgit v1.2.3 From 7cdada166cd9a05103a838d18e9be9811f68bc1d Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 8 Dec 2022 21:59:25 +0000 Subject: 51142: vcs_info git: Check the get-unapplied style as documented The style was treated as "always true" rather than as "settable, false by default" in the rebase-merge and cherry-pick cases. This affects the gen-unapplied-string hook, and may also affect gen-applied-string and set-patch-format hooks if they accessed VCS_INFO_get_data_git's internal parameters directly. If this affects you, just set the style in your zshrc: . zstyle ':vcs_info:git*:*:*' get-unapplied true --- ChangeLog | 5 +++++ Functions/VCS_Info/Backends/VCS_INFO_get_data_git | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 63e9c5041..dab0a9147 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-12-08 Daniel Shahaf + + * 51142: Functions/VCS_Info/Backends/VCS_INFO_get_data_git: + vcs_info git: Check the get-unapplied style as documented + 2022-12-08 Peter Grayson * 51138: Functions/VCS_Info/Backends/VCS_INFO_get_data_git: diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git index 23d4d31a1..37cd048db 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git +++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git @@ -244,7 +244,9 @@ if [[ -d "${gitdir}/rebase-merge" ]]; then (( $+REPLY )) && git_patches_applied+=( "$REPLY" ) done fi - if [[ -f "${patchdir}/git-rebase-todo" ]] ; then + if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-unapplied && + [[ -f "${patchdir}/git-rebase-todo" ]] + then for p in ${(f)"$(< "${patchdir}/git-rebase-todo")"}; do VCS_INFO_git_map_rebase_line_to_hash_and_subject "$p" (( $+REPLY )) && git_patches_unapplied+=( "$REPLY" ) @@ -374,7 +376,9 @@ elif [[ -f "${gitdir}/CHERRY_PICK_HEAD" ]]; then # TODO: maybe read up to the first blank line IFS='' read -r subject < "${gitdir}/MERGE_MSG" git_patches_applied=( "$(<${gitdir}/CHERRY_PICK_HEAD) ${subject}" ) - if [[ -f "${gitdir}/sequencer/todo" ]]; then + if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-unapplied && + [[ -f "${gitdir}/sequencer/todo" ]] + then # Get the next patches, and remove the one that's in CHERRY_PICK_HEAD. git_patches_unapplied=( ${${(M)${(f)"$(<"${gitdir}/sequencer/todo")"}:#pick *}#pick } ) git_patches_unapplied[1]=() -- cgit v1.2.3 From 510df60dd1f90f99026ac17e341df2313e064509 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 9 Dec 2022 01:39:21 +0000 Subject: 51144, 51146: vcs_info git: stg: Extract patch descriptions Joint work with Peter Grayson. --- ChangeLog | 6 ++++++ Functions/VCS_Info/Backends/VCS_INFO_get_data_git | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index dab0a9147..77dfc0377 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-12-09 Daniel Shahaf + + * 51144, 51146: + Functions/VCS_Info/Backends/VCS_INFO_get_data_git: vcs_info git: + stg: Extract patch descriptions + 2022-12-08 Daniel Shahaf * 51142: Functions/VCS_Info/Backends/VCS_INFO_get_data_git: diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git index 37cd048db..9a608adab 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git +++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git @@ -388,7 +388,7 @@ elif [[ -f "${gitdir}/CHERRY_PICK_HEAD" ]]; then VCS_INFO_git_handle_patches elif command -v stg >/dev/null && ${vcs_comm[cmd]} show-ref --quiet refs/stacks/${gitbranch} refs/heads/${gitbranch}.stgit 2>/dev/null && - git_patches_applied=(${(f)"$(stg series --noprefix --applied 2>/dev/null)"}) + git_patches_applied=(${${(f)"$(stg series --noprefix --applied --description 2>/dev/null)"}/ #[#]}) then # Testing for StGit patches is done after testing for all git-proper # patches/states. If a StGit user's repo is in one of those states, they @@ -408,7 +408,7 @@ then # --no-prefix. The former is compatible with StGit versions going back to # 2008. if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-unapplied; then - git_patches_unapplied=(${(f)"$(stg series --noprefix --unapplied 2>/dev/null)"}) + git_patches_unapplied=(${${(f)"$(stg series --noprefix --unapplied --description 2>/dev/null)"}/ #[#]}) fi VCS_INFO_git_handle_patches else -- cgit v1.2.3 From 48f36784a808857af9b6450263c1454195433aaf Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 9 Dec 2022 19:21:45 -0800 Subject: 51047: fix quoting of completion matches when _canonical_paths -N option is used --- ChangeLog | 7 ++++++- Completion/Unix/Type/_canonical_paths | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 77dfc0377..f65712ccf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-12-09 Bart Schaefer + + * 51047: Completion/Unix/Type/_canonical_paths: fix quoting + of completion matches when _canonical_paths -N option is used + 2022-12-09 Daniel Shahaf * 51144, 51146: @@ -187,7 +192,7 @@ * 50418: Src/zsh_system.h, configure.ac: use setenv(3)/getenv(3) on newer macOS -2022-07-16 Bart Schaefer +2022-07-16 Bart Schaefer * users/27852: Completion/Unix/Command/_python: Make a local copy of $_compskip to avoid propagating outward any changes by _normal diff --git a/Completion/Unix/Type/_canonical_paths b/Completion/Unix/Type/_canonical_paths index a8fbbb524..1444bc165 100644 --- a/Completion/Unix/Type/_canonical_paths +++ b/Completion/Unix/Type/_canonical_paths @@ -42,7 +42,8 @@ _canonical_paths_add_paths () { # ### Ideally, this codepath would do what the 'if' above does, # ### but telling compadd to pretend the "word on the command line" # ### is ${"the word on the command line"/$origpref/$canpref}. - matches+=(${${(M)files:#$canpref*}/$canpref/$origpref}) + # ### The following approximates that. + matches+=(${(q)${(M)files:#$canpref*}/$canpref/$origpref}) fi for subdir in $expref?*(@); do -- cgit v1.2.3 From 72540a758ac755fc89137dd9b92c8d0d6a5d95e1 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Fri, 9 Dec 2022 19:27:31 -0800 Subject: 51111: update completion for global to version 6.6.8 --- ChangeLog | 3 +++ Completion/Unix/Command/_global | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f65712ccf..7472f056c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-09 Bart Schaefer + * Shohei YOSHIDA: 51111: Completion/Unix/Command/_global: + update completion for global to version 6.6.8 + * 51047: Completion/Unix/Type/_canonical_paths: fix quoting of completion matches when _canonical_paths -N option is used diff --git a/Completion/Unix/Command/_global b/Completion/Unix/Command/_global index ffd8c0dce..4ffd7f8ce 100644 --- a/Completion/Unix/Command/_global +++ b/Completion/Unix/Command/_global @@ -9,15 +9,18 @@ _arguments \ "$cmds"{-I,--idutils}'[print all lines which match pattern using id-utils]:pattern' \ "$cmds"{-p,--print-dbpath}'[print location of GTAGS]' \ "$cmds"{-P,--path}'[print paths matching pattern]:pattern:' \ + "$cmds"'--print[print locate of root/dbpath/conf]:name:(root dbpath conf)' \ "$cmds"{-u,--update}'[locate tag files and update incrementally]' \ '(-a --absolute)'{-a,--absolute}'[print absolute path names]' \ '(--color)--color=-[color matches]::color:(always auto never)' \ + '(-C --directory)'{-C,--directory}'[change the directory before doing all the work]:dir:_files -/' \ '(-d --definition)'{-d,--definition}'[print locations of definitions]' \ '(-e --regexp :)'{-e,--regexp}'[specify pattern]:pattern:_global_tags' \ + '(-E --extended-regexp -G --basic-regexp)'{-E,--extended-regexp}'[interpret pattern as a extended regular expression]' \ '(--encode-path)--encode-path=-[encode path characters in hexadecimal representation]:format' \ '(-F --first-match)'{-f,--first-match}'[stop searching if tag is found in current tag file]' \ '(--from-here)--from-here=-[decide tag type by context]:line_path:' \ - '(-G --basic-regexp :)'{-G,--basic-regexp}'[specify basic regexp to use]:word:_global_tags' \ + '(-E --extended-regexp -G --basic-regexp)'{-G,--basic-regexp}'[interpret pattern as a basic regular expression]' \ '(--gtagsconf)--gtagsconf=-[set environment variable GTAGSCONF]:file:_files' \ '(--gtagslabel)--gtagslabel=-[set environment variable GTAGSLABEL]:file:_files' \ '(-i --ignore-case)'{-i,--ignore-case}'[ignore case in patterns]' \ @@ -27,6 +30,7 @@ _arguments \ '(-M --match-case)'{-m,--match-case}'[enable case sensitive search]' \ '(--match-part)--match-part=-[specify how path name completion should match]::part:(first last all)' \ '(-n --nofilter)'{-n,--nofilter}'[suppress sort filter and path conversion filter]' \ + '(-N --nearness)'{-N,--nearness=-}'[use nearness sort method for the output]:start:_files' \ '(-O --only-other)'{-O,--only-other}'[search only text files]' \ '(-o --other)'{-o,--other}'[search in other files, not just source files (with -g)]' \ '(--path-style)--path-style=-[specify path style]::style:(relative absolute shorter abslib through)' \ @@ -34,11 +38,12 @@ _arguments \ '(-q --quiet)'{-q,--quiet}'[quiet mode]' \ '(-r --reference --rootdir)'{-r,--reference,--rootdir}'[find object references instead of definitions]' \ '(--result)--result=-[specify result format]::format:(path ctags ctags-x grep cscope)' \ - '(- :)--single-update=-[updata tag for specified file]:file:_files' \ + '(- :)--single-update=-[update tag for specified file]:file:_files' \ '(-s --symbol)'{-s,--symbol}'[find symbols instead of function names]:pattern' \ '(-t --tags)'{-t,--tags}'[output in standard ctags format]' \ '(-T --through -s -r -l)'{-T,--through}'[search through all tag files in GTAGSLIBPATH]' \ '(-v --verbose)'{-v,--verbose}'[verbose mode]' \ + '(-V --invert-match)'{-V,--invert-match}'[invert the sense of matching, to select non-matching lines]' \ '(-x --cxref)'{-x,--cxref}'[additionally list line number and contents]' \ '(- :)--version[display version information]' \ '(- :)--help[display help information]' \ -- cgit v1.2.3 From 2028539cb168d652dfa77e5b85b382c319b3a99a Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 9 Dec 2022 19:30:35 -0800 Subject: 51161: correct errno after closing xtrace FD --- ChangeLog | 2 ++ Src/exec.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7472f056c..0a2a880f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2022-12-09 Bart Schaefer + * 51161: Src/exec.c: correct errno after closing xtrace FD + * Shohei YOSHIDA: 51111: Completion/Unix/Command/_global: update completion for global to version 6.6.8 diff --git a/Src/exec.c b/Src/exec.c index 1810fca5e..a1059af5e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4336,10 +4336,13 @@ execcmd_exec(Estate state, Execcmd_params eparams, } } if (newxtrerr) { + int eno = errno; fil = fileno(newxtrerr); fclose(newxtrerr); xtrerr = oxtrerr; + /* Call zclose() to clean up internal tables, ignore EBADF */ zclose(fil); + errno = eno; } zsfree(STTYval); -- cgit v1.2.3 From 14559421e2a054f9b09d6fa1971158a5e7e162a6 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 12 Dec 2022 10:27:29 +0000 Subject: 51134: document interactive behaviour with ERR_EXIT and ERR_RETURN --- ChangeLog | 5 +++++ Doc/Zsh/options.yo | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0a2a880f4..d8672c028 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-12-12 Peter Stephenson + + * 51134: Doc/Zsh/options.yo: document interactions between + ERR_EXIT and ERR_RETURN and interactive shells. + 2022-12-09 Bart Schaefer * 51161: Src/exec.c: correct errno after closing xtrace FD diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 445052617..e92969531 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1744,6 +1744,9 @@ Exiting due to tt(ERR_EXIT) has certain interactions with asynchronous jobs noted in ifzman(the section JOBS in zmanref(zshmisc))\ ifnzman(noderef(Jobs & Signals)). + +Note this behaviour is not disabled in interactive shells --- +a non-zero status on the command line causes the shell to exit. ) pindex(ERR_RETURN) pindex(NO_ERR_RETURN) @@ -1756,7 +1759,10 @@ If a command has a non-zero exit status, return immediately from the 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. +non-interactive script. At the top level of an interactive shell, +it will trigger a return to the command prompt; in other +words, the sequence of commands typed by the user may be +thought of as a function for this purpose. Normally this option inherits the behaviour of tt(ERR_EXIT) that code followed by `tt(&&)' `tt(||)' does not trigger a return. Hence -- cgit v1.2.3 From 67d4bf5bb936a5b95160410b4790f2bf4113c75f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 12 Dec 2022 10:30:13 +0000 Subject: 51134: ! return doesn't change the return status --- Src/exec.c | 2 +- Test/A01grammar.ztst | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Src/exec.c b/Src/exec.c index a1059af5e..7001fd615 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1961,7 +1961,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) } else unqueue_signals(); - if ((slflags & WC_SUBLIST_NOT) && !errflag) + if ((slflags & WC_SUBLIST_NOT) && !errflag && !retflag) lastval = !lastval; } if (!pline_level) diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst index 0312fe94e..b3aea1055 100644 --- a/Test/A01grammar.ztst +++ b/Test/A01grammar.ztst @@ -970,3 +970,15 @@ F:its expectations. 0:Non-interactive shell command input is line buffered >Value is first >Value is second + + fn() { + ! false + } +0:! inverts the status of implicit return + + fn () { + false + ! return + } + fn +1:! does not affect return status of explicit return -- cgit v1.2.3 From 8a45f16d83b0c4582a51e492e73595bf3321d580 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Tue, 13 Dec 2022 21:01:47 -0800 Subject: 51193: Discuss ERR_EXIT changes --- ChangeLog | 4 ++++ NEWS | 8 ++++++++ README | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8672c028..747d3eba3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-12-13 Bart Schaefer + + * Philippe Altherr: 51193: NEWS, README: Discuss ERR_EXIT changes + 2022-12-12 Peter Stephenson * 51134: Doc/Zsh/options.yo: document interactions between diff --git a/NEWS b/NEWS index cdafd1ff5..e3a16a8bc 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,14 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH Note also the list of incompatibilities in the README file. +Changes since 5.9 +----------------- + +The ERR_EXIT and ERR_RETURN options were refined to be more self- +consistent and better aligned with the POSIX-2017 specification of +`set -e`. For details on what exactly changed, see the list of +incompatibilities in the README file. + Changes since 5.8.1 ------------------- diff --git a/README b/README index 21142e17c..cb6d380aa 100644 --- a/README +++ b/README @@ -31,8 +31,56 @@ Zsh is a shell with lots of features. For a list of some of these, see the file FEATURES, and for the latest changes see NEWS. For more details, see the documentation. -Incompatibilities since 5.8.1 ------------------------------ +Incompatibilities since 5.9 +--------------------------- + +The ERR_EXIT and ERR_RETURN options were refined to be more self- +consistent and better aligned with the POSIX-2017 specification of +`set -e`: + + - Function calls or anonymous functions prefixed with `!` now never + trigger exit or return. Negated function calls or anonymous + functions used to trigger exit or return if ERR_EXIT or ERR_RETURN + was set and the function call or anonymous function returned a + zero exit status. Example: + + setopt ERR_EXIT + f() { true } + ! f + echo "This is printed only since 5.10." + + - The `always` command now ignores ERR_EXIT and ERR_RETURN, as other + complex commands do, if its exit status comes from a command + executed while the option is ignored. Example: + + setopt ERR_EXIT + { false && true } always { echo "This was and still is printed." } + echo "This is printed only since 5.10." + + - Function calls, anonymous functions, and the `eval`, `.`, and + `source` builtins now never ignore ERR_EXIT and ERR_RETURN on + their own. These commands used to ignore ERR_EXIT and ERR_RETURN + if their result came from a complex command (if, for, ...) whose + result came from a command executed while the option is + ignored. Example: + + setopt ERR_EXIT + f() { if true; then false && true; fi } + f + echo "This is printed only prior to 5.10." + + - The `&&` and `||` operators now always ignore ERR_RETURN in their + left operand. Until this version, the operators failed to ignored + ERR_RETURN in their left operand if they were executed as part of + a function call or an anonymous function that was itself executed + in a context where ERR_RETURN is ignored. Example: + + setopt ERR_RETURN + f() { { false; echo "This is printed only since 5.10." } || true } + if f; then true; fi + +Incompatibilities between 5.8.1 and 5.9 +--------------------------------------- compinit: A "y" response to the "Ignore ... and continue?" prompt removes insecure elements from the set of completion functions, where previously -- cgit v1.2.3 From 727079f7e547fe17e73fa6e240fe5c07ab01abe9 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Tue, 13 Dec 2022 21:05:13 -0800 Subject: 51198: Clarify and expand ERR_EXIT and ERR_RETURN documentation --- ChangeLog | 3 ++ Doc/Zsh/options.yo | 84 ++++++++++++++++++++++++++++++------------------------ 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index 747d3eba3..cea087a01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-13 Bart Schaefer + * Philippe Altherr: 51198: Doc/Zsh/options.yo: Clarify and expand + ERR_EXIT and ERR_RETURN documentation to include updated behavior + * Philippe Altherr: 51193: NEWS, README: Discuss ERR_EXIT changes 2022-12-12 Peter Stephenson diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index e92969531..cbd3d0f8e 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1723,22 +1723,30 @@ pindex(NOERREXIT) cindex(exit status, trapping) item(tt(ERR_EXIT) (tt(-e), ksh: tt(-e)))( If a command has a non-zero exit status, execute the tt(ZERR) -trap, if set, and exit. This is disabled while running initialization -scripts. - -The behaviour is also disabled inside tt(DEBUG) traps. In this -case the option is handled specially: it is unset on entry to -the trap. If the option tt(DEBUG_BEFORE_CMD) is set, -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. +trap, if set, and exit. + +The option is ignored when executing the commands following tt(while), +tt(until), tt(if), or tt(elif), a pipeline beginning with tt(!), or +any command other than the last in command list containing tt(&&) or +tt(||). Hence neither `tt(if foo; then true; fi)', nor `tt(foo && +true)' trigger exit when tt(foo) returns with a non-zero exit status. +Note that if tt(foo) is a function, the option is also ignored during +its whole execution. + +The option is also ignored when executing a complex command (tt(if), +tt(for), tt(while), tt(until), tt(repeat), tt(case), tt(select), +tt(always), or a list in braces) if its exit status comes from a +command executed while the option is ignored. Hence, the tt(if) +command in `tt(if true; then false && true; fi)' does not trigger +exit. + +Finally, the option is also ignored while running initialization +scripts and inside tt(DEBUG) traps. In the latter case, the option is +handled specially: it is unset on entry to the trap. If the option +tt(DEBUG_BEFORE_CMD) is set, 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. Exiting due to tt(ERR_EXIT) has certain interactions with asynchronous jobs noted in @@ -1755,29 +1763,29 @@ pindex(NOERRRETURN) 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 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. At the top level of an interactive shell, -it will trigger a return to the command prompt; in other -words, the sequence of commands typed by the user may be -thought of as a function for this purpose. - -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. +enclosing function. Except as explained below, an implicit tt(return) +statement is executed following the same logic described for +tt(ERR_EXIT). This will trigger an exit at the outermost level of a +non-interactive script. At the top level of an interactive shell, it +will trigger a return to the command prompt; in other words, the +sequence of commands typed by the user may be thought of as a function +for this purpose. + +Unlike for tt(ERR_EXIT), when a function is called while the option is +being ignored, the option is NOT ignored during the execution of the +function. Hence, if tt(foo) in `tt(foo && true)' is a function, code +inside it is considered separately: it may force a return from tt(foo) +(assuming the option remains set within tt(foo)). + +Like for tt(ERR_EXIT), the option is ignored inside tt(DEBUG) traps +but it's not unset on entry to the trap and setting or unsetting it +inside the trap has no special effect. + +If tt(ERR_RETURN) and tt(ERR_EXIT) are both set, it may happen that +both exit and return should be triggered. In that case only exit is +triggered. ) pindex(EVAL_LINENO) pindex(NO_EVAL_LINENO) -- cgit v1.2.3 From 6d49734d46a66b572cf064f60dac8d9e0ad309d0 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 13 Dec 2022 21:11:33 -0800 Subject: 51210: Clear errflag before calling EXIT trap If this is not done, special cases such as failures in special builtins or errors in math expressions skip the trap execution. --- ChangeLog | 3 +++ Src/exec.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index cea087a01..3536d0b1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-13 Bart Schaefer + * 51210: Src/exec.c: Clear errflag before calling EXIT trap, + otherwise the trap is skipped for special-case errors in builtins + * Philippe Altherr: 51198: Doc/Zsh/options.yo: Clarify and expand ERR_EXIT and ERR_RETURN documentation to include updated behavior diff --git a/Src/exec.c b/Src/exec.c index 7001fd615..2b7e0c7c5 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1598,6 +1598,7 @@ sublist_done: (isset(ERRRETURN) && !errreturn)) && !(noerrexit & NOERREXIT_EXIT); if (errexit) { + errflag = 0; if (sigtrapped[SIGEXIT]) dotrap(SIGEXIT); if (mypid != getpid()) @@ -1630,9 +1631,12 @@ sublist_done: thisjob = cj; if (exiting && sigtrapped[SIGEXIT]) { + int eflag = errflag; + errflag = 0; /* Clear the context for trap */ dotrap(SIGEXIT); /* Make sure this doesn't get executed again. */ sigtrapped[SIGEXIT] = 0; + errflag = eflag; } unqueue_signals(); -- cgit v1.2.3 From 5c9713603d571fd228efc4c25c0efc9064d95a87 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 15 Dec 2022 20:38:08 +0000 Subject: unposted: zsh.h: lextok: Add an explanatory comment with a cross-reference. --- ChangeLog | 5 +++++ Src/zsh.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3536d0b1e..bcf50f80c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-12-15 Daniel Shahaf + + * unposted: Src/zsh.h: lextok: Add an explanatory comment with + a cross-reference. + 2022-12-13 Bart Schaefer * 51210: Src/exec.c: Clear errflag before calling EXIT trap, diff --git a/Src/zsh.h b/Src/zsh.h index 703231ca2..b7eb39804 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -309,6 +309,9 @@ enum { /* * Lexical tokens: unlike the character tokens above, these never * appear in strings and don't necessarily represent a single character. + * + * See Src/lex.c:tokstrings[] for hints on what these mean. Note that + * SEPER or SEMI are both stringified as ";"./ */ enum lextok { -- cgit v1.2.3 From 56e7b147adc4404419b6295d25bc0ed179f6d889 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 15 Dec 2022 21:35:21 +0000 Subject: unposted: Follow-up to the last commit: Fix a typo in a comment. --- ChangeLog | 3 +++ Src/zsh.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bcf50f80c..b0c3f79cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-15 Daniel Shahaf + * unposted: Src/zsh.h: Follow-up to the last commit: Fix a typo + in a comment. + * unposted: Src/zsh.h: lextok: Add an explanatory comment with a cross-reference. diff --git a/Src/zsh.h b/Src/zsh.h index b7eb39804..6f68df6a4 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -311,7 +311,7 @@ enum { * appear in strings and don't necessarily represent a single character. * * See Src/lex.c:tokstrings[] for hints on what these mean. Note that - * SEPER or SEMI are both stringified as ";"./ + * SEPER or SEMI are both stringified as ";". */ enum lextok { -- cgit v1.2.3 From 1de8baded2c3f4b8facdaf8f5bc5ffb392e73199 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 16 Dec 2022 14:58:20 +0000 Subject: unpasted: add missing ChangeLog entry --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index b0c3f79cb..acde99fb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,10 @@ 2022-12-12 Peter Stephenson + * 51134: Src/exec.c, Test/A01grammar.ztst: ! return doesn't + affect return status, only the (now irrelevant) local status + within the returning function. + * 51134: Doc/Zsh/options.yo: document interactions between ERR_EXIT and ERR_RETURN and interactive shells. -- cgit v1.2.3 From 7fb6c133bfdf445b4478897adc142ed7d07b5fd6 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 16 Dec 2022 23:12:54 +0100 Subject: 51215: consume whole CSI sequences from the input This affects CSI sequences that aren't explicitly bound but arrive within the usual KEYTIMEOUT time limits. A single undefined-key widget is run instead of unintended bindings for Escape and other characters in the sequence. --- ChangeLog | 6 ++++++ Src/Zle/zle_keymap.c | 27 +++++++++++++++++++++++++-- Test/X02zlevi.ztst | 7 +++++++ Test/X03zlebindkey.ztst | 22 ++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index acde99fb4..e9e572957 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2022-12-16 Oliver Kiddle + + * 51215: Src/Zle/zle_keymap.c, Test/X03zlebindkey.ztst, + Test/X02zlevi.ztst: consume whole CSI sequences from the input + even where they aren't explicitly bound + 2022-12-15 Daniel Shahaf * unposted: Src/zsh.h: Follow-up to the last commit: Fix a typo diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index d90838f03..48691e8d0 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1586,7 +1586,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) Thingy func = t_undefinedkey; char *str = NULL; int lastlen = 0, lastc = lastchar; - int timeout = 0; + int timeout = 0, csi = 0, startcsi; keybuflen = 0; keybuf[0] = 0; @@ -1636,7 +1636,30 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) } #endif } - if (!ispfx) + + /* CSI key sequences have a well defined structure so if we currently + * have an incomplete one, loop so the rest of it will be included in + * the key sequence if that arrives within the timeout. */ + if (keybuflen >= 3 && !csi) { + startcsi = keybuflen - 3; + csi = keybuf[startcsi] == '\033' && keybuf[keybuflen - 2] == '['; + } + if (csi) { + csi = keybuf[keybuflen - 2] != Meta && keybuf[keybuflen - 1] >= 0x20 + && keybuf[keybuflen - 1] <= 0x3f; + /* If we reach the end of a valid CSI sequence and the matched key + * binding is for part of the CSI introduction, select instead the + * undefined-key widget and consume the full sequence from the + * input buffer. */ + if (!csi && keybuf[keybuflen - 1] >= 0x40 && + keybuf[keybuflen - 1] <= 0x7e && lastlen > startcsi && + lastlen <= startcsi + 2) { + func = t_undefinedkey; + lastlen = keybuflen; + } + } + + if (!ispfx && !csi) break; } if(!lastlen && keybuflen) diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst index 203c13c32..ccfb7b1c6 100644 --- a/Test/X02zlevi.ztst +++ b/Test/X02zlevi.ztst @@ -596,6 +596,13 @@ >BUFFER: 1ls `2` $(3) "4" $'5' ${6} >CURSOR: 0 + zpty_run 'bindkey -s -a "cw" "dwi"' + zletest $'one two\e0cwyksi' + zpty_run 'bindkey -r -a "cw"' +0:for a vi command, wait to allow a longer binding to be used +>BUFFER: yksitwo +>CURSOR: 4 + %clean zmodload -ui zsh/zpty diff --git a/Test/X03zlebindkey.ztst b/Test/X03zlebindkey.ztst index 5277332a7..1b63b3920 100644 --- a/Test/X03zlebindkey.ztst +++ b/Test/X03zlebindkey.ztst @@ -37,6 +37,28 @@ >"^Xy" "bar" >"^Xy" undefined-key + zpty_run 'bindkey -s "\e[" altbracket' + zletest $'$\C-A\e[17~' + zpty_run 'bindkey -r "\e["' +0:binding to CSI introduction is not used if a full sequence arrives +>BUFFER: $ +>CURSOR: 0 + + zpty_run 'bindkey -s "\e[1" altbracketone' + zletest $'$\C-A\e[17~' + zpty_run 'bindkey -r "\e[1"' +0:binding to longer prefix of a CSI sequence is used +# we assume the user knows what they're doing +>BUFFER: altbracketone7~$ +>CURSOR: 15 + + zpty_run 'bindkey -s "\e[" altbracket' + zletest $'$\C-A\e[177' + zpty_run 'bindkey -r "\e["' +0:use prefix binding where we don't have a CSI sequence +>BUFFER: altbracket177$ +>CURSOR: 13 + # As we're only looking at definitions here, we don't # bother using the pseudo-terminal; just test in the normal fashion. bindkey -e -- cgit v1.2.3 From a73c705b0c864a9ce042fca6e72e0c92d4ad8237 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 16 Dec 2022 23:22:33 +0100 Subject: 51212: remove STOUC() macro This served as a workaround for ancient compilers where casts to unsigned char were broken. --- ChangeLog | 12 +++++++ Etc/zsh-development-guide | 3 -- Src/Modules/curses.c | 4 +-- Src/Modules/stat.c | 2 +- Src/Modules/zftp.c | 12 +++---- Src/Modules/zpty.c | 2 +- Src/Modules/zutil.c | 24 +++++++------- Src/Zle/compcore.c | 6 ++-- Src/Zle/complete.c | 2 +- Src/Zle/complist.c | 12 +++---- Src/Zle/zle.h | 2 +- Src/Zle/zle_keymap.c | 22 ++++++------- Src/Zle/zle_main.c | 4 +-- Src/Zle/zle_thingy.c | 4 +-- Src/Zle/zle_utils.c | 4 +-- Src/builtin.c | 20 ++++++------ Src/exec.c | 2 +- Src/glob.c | 4 +-- Src/hist.c | 6 ++-- Src/init.c | 10 +++--- Src/input.c | 8 ++--- Src/lex.c | 10 +++--- Src/math.c | 2 +- Src/module.c | 2 +- Src/params.c | 25 ++++++++------- Src/parse.c | 6 ++-- Src/pattern.c | 81 ++++++++++++++++++++++++----------------------- Src/prompt.c | 2 +- Src/sort.c | 4 +-- Src/subst.c | 6 ++-- Src/utils.c | 68 +++++++++++++++++++-------------------- Src/zsh.h | 13 -------- Src/ztype.h | 2 +- configure.ac | 10 ------ 34 files changed, 192 insertions(+), 204 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9e572957..996704135 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2022-12-16 Oliver Kiddle + * 51212: Etc/zsh-development-guide, Src/Modules/curses.c, + Src/Modules/stat.c, Src/Modules/zftp.c, Src/Modules/zpty.c, + Src/Modules/zutil.c, Src/Zle/compcore.c, Src/Zle/complete.c, + Src/Zle/complist.c, Src/Zle/zle.h, Src/Zle/zle_keymap.c, + Src/Zle/zle_main.c, Src/Zle/zle_thingy.c, Src/Zle/zle_utils.c, + Src/builtin.c, Src/exec.c, Src/glob.c, Src/hist.c, Src/init.c, + Src/input.c, Src/lex.c, Src/math.c, Src/module.c, Src/params.c, + Src/parse.c, Src/pattern.c, Src/prompt.c, Src/sort.c, Src/subst.c, + Src/utils.c, Src/zsh.h, Src/ztype.h, configure.ac: remove STOUC() + macro which served as a workaround for ancient compilers where + casts to unsigned char were broken + * 51215: Src/Zle/zle_keymap.c, Test/X03zlebindkey.ztst, Test/X02zlevi.ztst: consume whole CSI sequences from the input even where they aren't explicitly bound diff --git a/Etc/zsh-development-guide b/Etc/zsh-development-guide index e8c292cfd..565b0b1d9 100644 --- a/Etc/zsh-development-guide +++ b/Etc/zsh-development-guide @@ -223,9 +223,6 @@ C coding style * Do not use space between the function name and the opening parenthesis. Use space after if/for/while. Use space after type casts. -* Do not use (unsigned char) casts since some compilers do not handle - them properly. Use the provided STOUC(X) macro instead. - * If you use emacs 19.30 or newer you can put the following line to your ~/.emacs file to make these formatting rules the default: diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c index e46903916..ad17ed65f 100644 --- a/Src/Modules/curses.c +++ b/Src/Modules/curses.c @@ -1426,10 +1426,10 @@ zccmd_querychar(const char *nam, char **args) inc &= A_CHARTEXT; if (imeta(inc)) { instr[0] = Meta; - instr[1] = STOUC(inc ^ 32); + instr[1] = (unsigned char) (inc ^ 32); instr[2] = '\0'; } else { - instr[0] = STOUC(inc); + instr[0] = (unsigned char) inc; instr[1] = '\0'; } attrs = inc; diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c index 0df9b35b7..c9f851974 100644 --- a/Src/Modules/stat.c +++ b/Src/Modules/stat.c @@ -406,7 +406,7 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func)) } else { for (; *arg; arg++) { if (strchr("glLnNorstT", *arg)) - ops->ind[STOUC(*arg)] = 1; + ops->ind[(unsigned char) *arg] = 1; else if (*arg == 'A') { if (arg[1]) { arrnam = arg+1; diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index e8e239e76..49b3ffa89 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -944,9 +944,9 @@ zfopendata(char *name, union tcp_sockaddr *zdsockp, int *is_passivep) return 1; } for (i = 0; i < 4; i++) - iaddr[i] = STOUC(nums[i]); - iport[0] = STOUC(nums[4]); - iport[1] = STOUC(nums[5]); + iaddr[i] = (unsigned char) nums[i]; + iport[0] = (unsigned char) nums[4]; + iport[1] = (unsigned char) nums[5]; memcpy(&zdsockp->in.sin_addr, iaddr, sizeof(iaddr)); memcpy(&zdsockp->in.sin_port, iport, sizeof(iport)); @@ -2438,7 +2438,7 @@ zftp_type(char *name, char **args, int flags) fflush(stdout); return 0; } else { - nt = toupper(STOUC(*str)); + nt = toupper((unsigned char) *str); /* * RFC959 specifies other types, but these are the only * ones we know what to do with. @@ -2472,7 +2472,7 @@ zftp_mode(char *name, char **args, UNUSED(int flags)) fflush(stdout); return 0; } - nt = str[0] = toupper(STOUC(*str)); + nt = str[0] = toupper((unsigned char) *str); if (str[1] || (nt != 'S' && nt != 'B')) { zwarnnam(name, "transfer mode %s not recognised", str); return 1; @@ -3075,7 +3075,7 @@ bin_zftp(char *name, char **args, UNUSED(Options ops), UNUSED(int func)) if ((prefs = getsparam_u("ZFTP_PREFS"))) { zfprefs = 0; for (ptr = prefs; *ptr; ptr++) { - switch (toupper(STOUC(*ptr))) { + switch (toupper((unsigned char) *ptr)) { case 'S': /* sendport */ zfprefs |= ZFPF_SNDP; diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c index dfd2a2a7a..c2656698c 100644 --- a/Src/Modules/zpty.c +++ b/Src/Modules/zpty.c @@ -638,7 +638,7 @@ ptyread(char *nam, Ptycmd cmd, char **args, int noblock, int mustmatch) readchar = cmd->read; cmd->read = -1; } else - readchar = STOUC(buf[used]); + readchar = (unsigned char) buf[used]; if (imeta(readchar)) { buf[used++] = Meta; buf[used++] = (char) (readchar ^ 32); diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 2f17c03f1..8a7d0a4c5 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -795,11 +795,11 @@ static char *zformat_substring(char* instr, char **specs, char **outp, if (idigit(*s)) { for (min = 0; idigit(*s); s++) - min = (min * 10) + (int) STOUC(*s) - '0'; + min = (min * 10) + (int) (unsigned char) *s - '0'; } /* Ternary expressions */ - testit = (STOUC(*s) == '('); + testit = ((unsigned char) *s == '('); if (testit && s[1] == '-') { /* Allow %(-1... etc. */ @@ -808,25 +808,25 @@ static char *zformat_substring(char* instr, char **specs, char **outp, } if ((*s == '.' || testit) && idigit(s[1])) { for (max = 0, s++; idigit(*s); s++) - max = (max * 10) + (int) STOUC(*s) - '0'; + max = (max * 10) + (int) (unsigned char) *s - '0'; } else if (*s == '.' || testit) s++; - if (testit && STOUC(*s)) { + if (testit && (unsigned char) *s) { int actval, testval, endcharl; /* Only one number is useful for ternary expressions. */ testval = (min >= 0) ? min : (max >= 0) ? max : 0; - if (specs[STOUC(*s)] && *specs[STOUC(*s)]) { + if (specs[(unsigned char) *s] && *specs[(unsigned char) *s]) { if (presence) { if (testval) #ifdef MULTIBYTE_SUPPORT if (isset(MULTIBYTE)) - actval = MB_METASTRWIDTH(specs[STOUC(*s)]); + actval = MB_METASTRWIDTH(specs[(unsigned char) *s]); else #endif - actval = strlen(specs[STOUC(*s)]); + actval = strlen(specs[(unsigned char) *s]); else actval = 1; actval = right ? (testval < actval) : (testval >= actval); @@ -834,7 +834,7 @@ static char *zformat_substring(char* instr, char **specs, char **outp, if (right) /* put the sign back */ testval *= -1; /* zero means values are equal, i.e. true */ - actval = (int)mathevali(specs[STOUC(*s)]) - testval; + actval = (int) mathevali(specs[(unsigned char) *s]) - testval; } } else actval = presence ? !right : testval; @@ -855,7 +855,7 @@ static char *zformat_substring(char* instr, char **specs, char **outp, return NULL; } else if (skip) { continue; - } else if ((spec = specs[STOUC(*s)])) { + } else if ((spec = specs[(unsigned char) *s])) { int len; if ((len = strlen(spec)) > max && max >= 0) @@ -950,7 +950,7 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) zwarnnam(nam, "invalid argument: %s", *ap); return 1; } - specs[STOUC(ap[0][0])] = ap[0] + 2; + specs[(unsigned char) ap[0][0]] = ap[0] + 2; } out = (char *) zhalloc(olen = 128); @@ -1864,7 +1864,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) d->vals = d->last = NULL; opt_descs = d; if (!o[1]) - sopts[STOUC(*o)] = d; + sopts[(unsigned char) *o] = d; if ((flags & ZOF_MAP) && !map_opt_desc(d)) { zwarnnam(nam, "cyclic option mapping: %s", args[-1]); return 1; @@ -1888,7 +1888,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) } if (!(d = lookup_opt(o + 1))) { while (*++o) { - if (!(d = sopts[STOUC(*o)])) { + if (!(d = sopts[(unsigned char) *o])) { if (fail) { if (*o != '-') zwarnnam(nam, "bad option: -%c", *o); diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 4ac5d089f..64a860fa3 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -2898,9 +2898,9 @@ add_match_data(int alt, char *str, char *orig, Cline line, *t++ = '$'; *t++ = '\''; *t++ = '\\'; - *t++ = '0' + ((STOUC(curchar) >> 6) & 7); - *t++ = '0' + ((STOUC(curchar) >> 3) & 7); - *t++ = '0' + (STOUC(curchar) & 7); + *t++ = '0' + (((unsigned char) curchar >> 6) & 7); + *t++ = '0' + (((unsigned char) curchar >> 3) & 7); + *t++ = '0' + ((unsigned char) curchar & 7); *t++ = '\''; } while (cnt == MB_INCOMPLETE && fs < fe); /* Scanning restarts from the spot after the char we skipped. */ diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index 67a60963e..96ad7b3f1 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -518,7 +518,7 @@ parse_class(Cpattern p, char *iptr) ch = range_type((char *)iptr, nptr-iptr); iptr = nptr + 2; if (ch != PP_UNKWN) - *optr++ = STOUC(Meta) + ch; + *optr++ = (unsigned char) Meta + ch; } else { /* characters stay metafied */ char *ptr1 = iptr; diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 0dc64db6a..6e0eac31f 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -291,12 +291,12 @@ getcolval(char *s, int multi) case '?': *p = '\177'; break; default: if (*s >= '0' && *s <= '7') { - int i = STOUC(*s); + int i = (unsigned char) *s; if (*++s >= '0' && *s <= '7') { - i = (i * 8) + STOUC(*s); + i = (i * 8) + (unsigned char) *s; if (*++s >= '0' && *s <= '7') - i = (i * 8) + STOUC(*s); + i = (i * 8) + (unsigned char) *s; } *p = (char) i; } else @@ -305,7 +305,7 @@ getcolval(char *s, int multi) } else if (*s == '^') { if ((s[1] >= '@' && s[1] <= '_') || (s[1] >= 'a' && s[1] <= 'z')) - *p = (char) (STOUC(*s) & ~0x60); + *p = (char) ((unsigned char) *s & ~0x60); else if (s[1] == '?') *p = '\177'; else { @@ -794,7 +794,7 @@ clnicezputs(int do_colors, char *s, int ml) */ for (t = sptr; *t; t++) { /* Input is metafied... */ - int nc = (*t == Meta) ? STOUC(*++t ^ 32) : STOUC(*t); + int nc = (*t == Meta) ? (unsigned char) (*++t ^ 32) : (unsigned char) *t; /* Is the screen full? */ if (ml == mlend - 1 && col == zterm_columns - 1) { mlprinted = ml - oml; @@ -852,7 +852,7 @@ clnicezputs(int do_colors, char *s, int ml) cc = *s++ ^ 32; for (t = nicechar(cc); *t; t++) { - int nc = (*t == Meta) ? STOUC(*++t ^ 32) : STOUC(*t); + int nc = (*t == Meta) ? (unsigned char) (*++t ^ 32) : (unsigned char) *t; if (ml == mlend - 1 && col == zterm_columns - 1) { mlprinted = ml - oml; return 0; diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index f59545397..97cc7d797 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -526,7 +526,7 @@ typedef REFRESH_ELEMENT *REFRESH_STRING; ((int)((unsigned)(x) - ZSH_INVALID_WCHAR_BASE)) /* Turn a single byte character into a private wide character */ #define ZSH_CHAR_TO_INVALID_WCHAR(x) \ - ((wchar_t)(STOUC(x) + ZSH_INVALID_WCHAR_BASE)) + ((wchar_t)((unsigned char) x + ZSH_INVALID_WCHAR_BASE)) #endif diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 48691e8d0..ec8dd031e 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -404,7 +404,7 @@ static void scankeys(HashNode hn, UNUSED(int flags)) { Key k = (Key) hn; - int f = k->nam[0] == Meta ? STOUC(k->nam[1])^32 : STOUC(k->nam[0]); + int f = k->nam[0] == Meta ? (unsigned char) k->nam[1]^32 : (unsigned char) k->nam[0]; char m[3]; while(skm_last < f) { @@ -566,7 +566,7 @@ mod_export int bindkey(Keymap km, const char *seq, Thingy bind, char *str) { Key k; - int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]); + int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0]; char *buf, *ptr; if(km->flags & KM_IMMUTABLE) @@ -661,7 +661,7 @@ keybind(Keymap km, char *seq, char **strp) Key k; if(ztrlen(seq) == 1) { - int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]); + int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0]; Thingy bind = km->first[f]; if(bind) @@ -687,7 +687,7 @@ keyisprefix(Keymap km, char *seq) if(!*seq) return 1; if(ztrlen(seq) == 1) { - int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]); + int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0]; if(km->first[f]) return 0; @@ -764,10 +764,10 @@ bin_bindkey(char *name, char **argv, Options ops, UNUSED(int func)) int n; /* select operation and ensure no clashing arguments */ - for(op = opns; op->o && !OPT_ISSET(ops,STOUC(op->o)); op++) ; + for(op = opns; op->o && !OPT_ISSET(ops,(unsigned char) op->o); op++) ; if(op->o) for(opp = op; (++opp)->o; ) - if(OPT_ISSET(ops,STOUC(opp->o))) { + if(OPT_ISSET(ops,(unsigned char) opp->o)) { zwarnnam(name, "incompatible operation selection options"); return 1; } @@ -1049,7 +1049,7 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, Options ops, char m[3]; if(len < 2 || len > 2 + (bseq[1] == '-') || - (first = STOUC(bseq[0])) > (last = STOUC(bseq[len - 1]))) { + (first = (unsigned char) bseq[0]) > (last = (unsigned char) bseq[len - 1])) { zwarnnam(name, "malformed key range `%s'", useq); ret = 1; } else { @@ -1149,8 +1149,8 @@ scanbindlist(char *seq, Thingy bind, char *str, void *magic) if(bind == bs->bind && (bind || !strcmp(str, bs->str)) && ztrlen(seq) == 1 && ztrlen(bs->lastseq) == 1) { int l = bs->lastseq[1] ? - STOUC(bs->lastseq[1]) ^ 32 : STOUC(bs->lastseq[0]); - int t = seq[1] ? STOUC(seq[1]) ^ 32 : STOUC(seq[0]); + (unsigned char) bs->lastseq[1] ^ 32 : (unsigned char) bs->lastseq[0]; + int t = seq[1] ? (unsigned char) seq[1] ^ 32 : (unsigned char) seq[0]; if(t == l + 1) { zsfree(bs->lastseq); @@ -1526,10 +1526,10 @@ getrestchar_keybuf(void) */ while (1) { if (bufind < buflen) { - c = STOUC(keybuf[bufind++]); + c = (unsigned char) keybuf[bufind++]; if (c == Meta) { DPUTS(bufind == buflen, "Meta at end of keybuf"); - c = STOUC(keybuf[bufind++]) ^ 32; + c = (unsigned char) keybuf[bufind++] ^ 32; } } else { /* diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 9edf30e01..40b902901 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -876,7 +876,7 @@ getbyte(long do_keytmout, int *timeout, int full) #endif if (kungetct) - ret = STOUC(kungetbuf[--kungetct]); + ret = (unsigned char) kungetbuf[--kungetct]; else { for (;;) { int q = queue_signal_level(); @@ -940,7 +940,7 @@ getbyte(long do_keytmout, int *timeout, int full) else if (cc == '\n') cc = '\r'; - ret = STOUC(cc); + ret = (unsigned char) cc; } /* * curvichg.buf is raw bytes, not wide characters, so is dealt diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index cd3f2c356..1b036a8a0 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -366,10 +366,10 @@ bin_zle(char *name, char **args, Options ops, UNUSED(int func)) int n; /* select operation and ensure no clashing arguments */ - for(op = opns; op->o && !OPT_ISSET(ops,STOUC(op->o)); op++) ; + for(op = opns; op->o && !OPT_ISSET(ops, (unsigned char) op->o); op++) ; if(op->o) for(opp = op; (++opp)->o; ) - if(OPT_ISSET(ops,STOUC(opp->o))) { + if(OPT_ISSET(ops, (unsigned char) opp->o)) { zwarnnam(name, "incompatible operation selection options"); return 1; } diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 3d9017dcf..2536e9faa 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -1265,7 +1265,7 @@ bindztrdup(char *str) char *buf, *ptr, *ret; for(ptr = str; *ptr; ptr++) { - c = *ptr == Meta ? STOUC(*++ptr) ^ 32 : STOUC(*ptr); + c = *ptr == Meta ? (unsigned char) *++ptr ^ 32 : (unsigned char) *ptr; if(c & 0x80) { len += 3; c &= 0x7f; @@ -1279,7 +1279,7 @@ bindztrdup(char *str) } ptr = buf = zalloc(len); for(; *str; str++) { - c = *str == Meta ? STOUC(*++str) ^ 32 : STOUC(*str); + c = *str == Meta ? (unsigned char) *++str ^ 32 : (unsigned char) *str; if(c & 0x80) { *ptr++ = '\\'; *ptr++ = 'M'; diff --git a/Src/builtin.c b/Src/builtin.c index a7b7755a7..db83313d6 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2634,7 +2634,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) * these flags are defined in zsh.h */ for (; *optstr; optstr++, bit <<= 1) { - int optval = STOUC(*optstr); + int optval = (unsigned char) *optstr; if (OPT_MINUS(ops,optval)) on |= bit; else if (OPT_PLUS(ops,optval)) @@ -4752,7 +4752,7 @@ bin_print(char *name, char **args, Options ops, int func) */ if (*aptr == '\033' || *aptr == '\233') { for (aptr++, l--; - l && !isalpha(STOUC(*aptr)); + l && !isalpha((unsigned char) (*aptr)); aptr++, l--) ; aptr++; @@ -5313,9 +5313,9 @@ bin_print(char *name, char **args, Options ops, int func) else cc = WEOF; if (cc == WEOF) - cc = (curlen > 1) ? STOUC(curarg[1]) : 0; + cc = (curlen > 1) ? (unsigned char) (curarg[1]) : 0; #else - cc = (curlen > 1) ? STOUC(curarg[1]) : 0; + cc = (curlen > 1) ? (unsigned char) (curarg[1]) : 0; #endif if (type == 2) { doubleval = cc; @@ -6685,7 +6685,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) continue; first = 0; } - if (imeta(STOUC(*bptr))) { + if (imeta((unsigned char) *bptr)) { bptr[1] = bptr[0] ^ 32; bptr[0] = Meta; bptr += 2; @@ -6878,7 +6878,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) if (bslash) continue; } - if (imeta(STOUC(*bptr))) { + if (imeta((unsigned char) *bptr)) { bptr[1] = bptr[0] ^ 32; bptr[0] = Meta; bptr += 2; @@ -7000,14 +7000,14 @@ zread(int izle, int *readchar, long izle_timeout) buffer. This may be a null byte to indicate EOF. If reading from the buffer, move on the buffer pointer. */ if (*zbuf == Meta) - return zbuf++, STOUC(*zbuf++ ^ 32); + return zbuf++, (unsigned char) (*zbuf++ ^ 32); else - return (*zbuf) ? STOUC(*zbuf++) : EOF; + return (*zbuf) ? (unsigned char) *zbuf++ : EOF; } if (*readchar >= 0) { cc = *readchar; *readchar = -1; - return STOUC(cc); + return (unsigned char) cc; } for (;;) { /* read a character from readfd */ @@ -7015,7 +7015,7 @@ zread(int izle, int *readchar, long izle_timeout) switch (ret) { case 1: /* return the character read */ - return STOUC(cc); + return (unsigned char) cc; case -1: #if defined(EAGAIN) || defined(EWOULDBLOCK) if (!retry && readfd == 0 && ( diff --git a/Src/exec.c b/Src/exec.c index 2b7e0c7c5..c8eb71b34 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -603,7 +603,7 @@ zexecve(char *pth, char **argv, char **newenvp) isbinary = 1; hasletter = 0; for (ptr = execvebuf; ptr < ptr2; ptr++) { - if (islower(STOUC(*ptr)) || *ptr == '$' || *ptr == '`') + if (islower((unsigned char) *ptr) || *ptr == '$' || *ptr == '`') hasletter = 1; if (hasletter && *ptr == '\n') { isbinary = 0; diff --git a/Src/glob.c b/Src/glob.c index 490bafc37..63f8a5fa7 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -2418,11 +2418,11 @@ xpandbraces(LinkList list, LinkNode *np) memset(ccl, 0, sizeof(ccl) / sizeof(ccl[0])); for (p = str + 1; p < str2;) { if (itok(c1 = *p++)) - c1 = ztokens[c1 - STOUC(Pound)]; + c1 = ztokens[c1 - (unsigned char) Pound]; if ((char) c1 == Meta) c1 = 32 ^ *p++; if (itok(c2 = *p)) - c2 = ztokens[c2 - STOUC(Pound)]; + c2 = ztokens[c2 - (unsigned char) Pound]; if ((char) c2 == Meta) c2 = 32 ^ p[1]; if (IS_DASH((char)c1) && lastch >= 0 && diff --git a/Src/hist.c b/Src/hist.c index bff0abe61..82d03a840 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2235,7 +2235,7 @@ casemodify(char *str, int how) char *mbptr; for (mbptr = mbstr; mbptr < mbstr + len2; mbptr++) { - if (imeta(STOUC(*mbptr))) { + if (imeta((unsigned char) *mbptr)) { *ptr2++ = Meta; *ptr2++ = *mbptr ^ 32; } else @@ -2254,10 +2254,10 @@ casemodify(char *str, int how) int c; int mod = 0; if (*str == Meta) { - c = STOUC(str[1] ^ 32); + c = (unsigned char) (str[1] ^ 32); str += 2; } else - c = STOUC(*str++); + c = (unsigned char) *str++; switch (how) { case CASMOD_LOWER: if (isupper(c)) { diff --git a/Src/init.c b/Src/init.c index 871d46b12..9981d059a 100644 --- a/Src/init.c +++ b/Src/init.c @@ -500,10 +500,10 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, } } break; - } else if (isspace(STOUC(**argv))) { + } else if (isspace((unsigned char) **argv)) { /* zsh's typtab not yet set, have to use ctype */ while (*++*argv) - if (!isspace(STOUC(**argv))) { + if (!isspace((unsigned char) **argv)) { badoptionstring: WARN_OPTION("bad option string: '%s'", args); return 1; @@ -1724,9 +1724,9 @@ zsh_main(UNUSED(int argc), char **argv) * interactive */ typtab['\0'] |= IMETA; - typtab[STOUC(Meta) ] |= IMETA; - typtab[STOUC(Marker)] |= IMETA; - for (t0 = (int)STOUC(Pound); t0 <= (int)STOUC(Nularg); t0++) + typtab[(unsigned char) Meta ] |= IMETA; + typtab[(unsigned char) Marker] |= IMETA; + for (t0 = (int) (unsigned char) Pound; t0 <= (int) (unsigned char) Nularg; t0++) typtab[t0] |= ITOK | IMETA; for (t = argv; *t; *t = metafy(*t, -1, META_ALLOC), t++); diff --git a/Src/input.c b/Src/input.c index 9898a7177..d55b05696 100644 --- a/Src/input.c +++ b/Src/input.c @@ -220,7 +220,7 @@ shingetchar(void) int nread, rsize = isset(SHINSTDIN) ? 1 : SHINBUFSIZE; if (shinbufptr < shinbufendptr) - return STOUC(*shinbufptr++); + return (unsigned char) *shinbufptr++; shinbufreset(); #ifdef USE_LSEEK @@ -242,7 +242,7 @@ shingetchar(void) zerr("lseek(%d, %d): %e", SHIN, -(nread - rsize), errno); } else shinbufendptr = shinbuffer + nread; - return STOUC(*shinbufptr++); + return (unsigned char) *shinbufptr++; } #endif for (;;) { @@ -259,7 +259,7 @@ shingetchar(void) } if (shinbufendptr == shinbuffer) return -1; - return STOUC(*shinbufptr++); + return (unsigned char) *shinbufptr++; } /* Read a line from SHIN. Convert tokens and * @@ -328,7 +328,7 @@ ingetc(void) if (inbufleft) { inbufleft--; inbufct--; - if (itok(lastc = STOUC(*inbufptr++))) + if (itok(lastc = (unsigned char) *inbufptr++)) continue; if (((inbufflags & INP_LINENO) || !strin) && lastc == '\n') lineno++; diff --git a/Src/lex.c b/Src/lex.c index e2f8bcfb1..15da85a93 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -423,7 +423,7 @@ initlextabs(void) for (t0 = 0; lx2[t0]; t0++) lexact2[(int)lx2[t0]] = t0; lexact2['&'] = LX2_BREAK; - lexact2[STOUC(Meta)] = LX2_META; + lexact2[(unsigned char) Meta] = LX2_META; lextok2['*'] = Star; lextok2['?'] = Quest; lextok2['{'] = Inbrace; @@ -722,7 +722,7 @@ gettok(void) } return peek; } - switch (lexact1[STOUC(c)]) { + switch (lexact1[(unsigned char) c]) { case LX1_BKSLASH: d = hgetc(); if (d == '\n') @@ -960,8 +960,8 @@ gettokstr(int c, int sub) if (inbl && !in_brace_param && !pct) act = LX2_BREAK; else { - act = lexact2[STOUC(c)]; - c = lextok2[STOUC(c)]; + act = lexact2[(unsigned char) c]; + c = lextok2[(unsigned char) c]; } switch (act) { case LX2_BREAK: @@ -1263,7 +1263,7 @@ gettokstr(int c, int sub) continue; } else { add(Bnull); - if (c == STOUC(Meta)) { + if (c == (unsigned char) Meta) { c = hgetc(); #ifdef DEBUG if (lexstop) { diff --git a/Src/math.c b/Src/math.c index 777ad9c31..12c8d6f6b 100644 --- a/Src/math.c +++ b/Src/math.c @@ -955,7 +955,7 @@ getcvar(char *s) } } #endif - mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t); + mn.u.l = (unsigned char) (*t == Meta ? t[1] ^ 32 : *t); } unqueue_signals(); return mn; diff --git a/Src/module.c b/Src/module.c index bab4d8d73..6cf442270 100644 --- a/Src/module.c +++ b/Src/module.c @@ -2474,7 +2474,7 @@ bin_zmodload(char *nam, char **args, Options ops, UNUSED(int func)) return 1; } for (fp = fonly; *fp; fp++) { - if (OPT_ISSET(ops,STOUC(*fp)) && !OPT_ISSET(ops,'F')) { + if (OPT_ISSET(ops,(unsigned char) *fp) && !OPT_ISSET(ops,'F')) { zwarnnam(nam, "-%c is only allowed with -F", *fp); return 1; } diff --git a/Src/params.c b/Src/params.c index f1fe38955..2e4a6eae2 100644 --- a/Src/params.c +++ b/Src/params.c @@ -732,7 +732,7 @@ split_env_string(char *env, char **name, char **value) tenv = strcpy(zhalloc(strlen(env) + 1), env); for (str = tenv; *str && *str != '='; str++) { - if (STOUC(*str) >= 128) { + if ((unsigned char) *str >= 128) { /* * We'll ignore environment variables with names not * from the portable character set since we don't @@ -4123,7 +4123,8 @@ char * tiedarrgetfn(Param pm) { struct tieddata *dptr = (struct tieddata *)pm->u.data; - return *dptr->arrptr ? zjoin(*dptr->arrptr, STOUC(dptr->joinchar), 1) : ""; + return *dptr->arrptr ? + zjoin(*dptr->arrptr, (unsigned char) dptr->joinchar, 1) : ""; } /**/ @@ -4819,12 +4820,12 @@ keyboardhacksetfn(UNUSED(Param pm), char *x) zwarn("Only one KEYBOARD_HACK character can be defined"); /* could be changed if needed */ } for (i = 0; i < len; i++) { - if (!isascii(STOUC(x[i]))) { + if (!isascii((unsigned char) x[i])) { zwarn("KEYBOARD_HACK can only contain ASCII characters"); return; } } - keyboardhackchar = len ? STOUC(x[0]) : '\0'; + keyboardhackchar = len ? (unsigned char) x[0] : '\0'; free(x); } else keyboardhackchar = '\0'; @@ -4858,14 +4859,14 @@ histcharssetfn(UNUSED(Param pm), char *x) if (len > 3) len = 3; for (i = 0; i < len; i++) { - if (!isascii(STOUC(x[i]))) { + if (!isascii((unsigned char) x[i])) { zwarn("HISTCHARS can only contain ASCII characters"); return; } } - bangchar = len ? STOUC(x[0]) : '\0'; - hatchar = len > 1 ? STOUC(x[1]) : '\0'; - hashchar = len > 2 ? STOUC(x[2]) : '\0'; + bangchar = len ? (unsigned char) x[0] : '\0'; + hatchar = len > 1 ? (unsigned char) x[1] : '\0'; + hashchar = len > 2 ? (unsigned char) x[2] : '\0'; free(x); } else { bangchar = '!'; @@ -5087,7 +5088,7 @@ arrfixenv(char *s, char **t) if (pm->node.flags & PM_SPECIAL) joinchar = ':'; else - joinchar = STOUC(((struct tieddata *)pm->u.data)->joinchar); + joinchar = (unsigned char) ((struct tieddata *)pm->u.data)->joinchar; addenv(pm, t ? zjoin(t, joinchar, 1) : ""); } @@ -5109,9 +5110,9 @@ zputenv(char *str) char *ptr; int ret; - for (ptr = str; *ptr && STOUC(*ptr) < 128 && *ptr != '='; ptr++) + for (ptr = str; *ptr && (unsigned char) *ptr < 128 && *ptr != '='; ptr++) ; - if (STOUC(*ptr) >= 128) { + if ((unsigned char) *ptr >= 128) { /* * Environment variables not in the portable character * set are non-standard and we don't really know of @@ -6022,7 +6023,7 @@ printparamnode(HashNode hn, int printflags) * append the join char for tied parameters if different from colon * for typeset -p output. */ - unsigned char joinchar = STOUC(((struct tieddata *)peer->u.data)->joinchar); + unsigned char joinchar = (unsigned char) ((struct tieddata *)peer->u.data)->joinchar; if (joinchar != ':') { char buf[2]; buf[0] = joinchar; diff --git a/Src/parse.c b/Src/parse.c index 2fac5c89c..283225b74 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -433,9 +433,9 @@ ecstrcode(char *s) t = has_token(s); wordcode c = (t ? 3 : 2); switch (l) { - case 4: c |= ((wordcode) STOUC(s[2])) << 19; - case 3: c |= ((wordcode) STOUC(s[1])) << 11; - case 2: c |= ((wordcode) STOUC(s[0])) << 3; break; + case 4: c |= ((wordcode) (unsigned char) s[2]) << 19; + case 3: c |= ((wordcode) (unsigned char) s[1]) << 11; + case 2: c |= ((wordcode) (unsigned char) s[0]) << 3; break; case 1: c = (t ? 7 : 6); break; } return c; diff --git a/Src/pattern.c b/Src/pattern.c index e947d1216..3edda1772 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -239,7 +239,7 @@ typedef unsigned long zrange_t; * a bit tricky... */ #define WCHAR_INVALID(ch) \ - ((wchar_t) (0xDC00 + STOUC(ch))) + ((wchar_t) (0xDC00 + (unsigned char) ch)) #endif /* MULTIBYTE_SUPPORT */ /* @@ -346,7 +346,7 @@ metacharinc(char **x) * set doesn't have the property that all bytes with the 8th * bit clear are single characters then we are stuffed. */ - if (!(patglobflags & GF_MULTIBYTE) || !(STOUC(*inptr) & 0x80)) + if (!(patglobflags & GF_MULTIBYTE) || !((unsigned char) *inptr & 0x80)) { if (itok(*inptr)) inchar = ztokens[*inptr++ - Pound]; @@ -357,7 +357,7 @@ metacharinc(char **x) inchar = *inptr++; } *x = inptr; - return (wchar_t)STOUC(inchar); + return (wchar_t)(unsigned char) inchar; } while (*inptr) { @@ -1181,8 +1181,8 @@ pattern_range_to_string(char *rangestr, char *outstr) int len = 0; while (*rangestr) { - if (imeta(STOUC(*rangestr))) { - int swtype = STOUC(*rangestr) - STOUC(Meta); + if (imeta((unsigned char) *rangestr)) { + int swtype = (unsigned char) *rangestr - (unsigned char) Meta; if (swtype == 0) { /* Ordindary metafied character */ @@ -1278,17 +1278,17 @@ patcomppiece(int *flagp, int paren) kshchar = '\0'; if (*patparse && patparse[1] == Inpar) { if (*patparse == zpc_special[ZPC_KSH_PLUS]) - kshchar = STOUC('+'); + kshchar = (unsigned char) '+'; else if (*patparse == zpc_special[ZPC_KSH_BANG]) - kshchar = STOUC('!'); + kshchar = (unsigned char) '!'; else if (*patparse == zpc_special[ZPC_KSH_BANG2]) - kshchar = STOUC('!'); + kshchar = (unsigned char) '!'; else if (*patparse == zpc_special[ZPC_KSH_AT]) - kshchar = STOUC('@'); + kshchar = (unsigned char) '@'; else if (*patparse == zpc_special[ZPC_KSH_STAR]) - kshchar = STOUC('*'); + kshchar = (unsigned char) '*'; else if (*patparse == zpc_special[ZPC_KSH_QUEST]) - kshchar = STOUC('?'); + kshchar = (unsigned char) '?'; } /* @@ -1468,7 +1468,8 @@ patcomppiece(int *flagp, int paren) ch = range_type(patparse, len); patparse = nptr + 2; if (ch != PP_UNKWN) - patadd(NULL, STOUC(Meta) + ch, 1, PA_NOALIGN); + patadd(NULL, (unsigned char) Meta + ch, 1, + PA_NOALIGN); continue; } charstart = patparse; @@ -1476,10 +1477,10 @@ patcomppiece(int *flagp, int paren) if (*patparse == Dash && patparse[1] && patparse[1] != Outbrack) { - patadd(NULL, STOUC(Meta)+PP_RANGE, 1, PA_NOALIGN); + patadd(NULL, (unsigned char) Meta+PP_RANGE, 1, PA_NOALIGN); if (itok(*charstart)) { - patadd(0, STOUC(ztokens[*charstart - Pound]), 1, - PA_NOALIGN); + patadd(0, (unsigned char) ztokens[*charstart - Pound], + 1, PA_NOALIGN); } else { patadd(charstart, 0, patparse-charstart, PA_NOALIGN); } @@ -1487,7 +1488,7 @@ patcomppiece(int *flagp, int paren) METACHARINC(patparse); } if (itok(*charstart)) { - patadd(0, STOUC(ztokens[*charstart - Pound]), 1, + patadd(0, (unsigned char) ztokens[*charstart - Pound], 1, PA_NOALIGN); } else { patadd(charstart, 0, patparse-charstart, PA_NOALIGN); @@ -1910,8 +1911,8 @@ charref(char *x, char *y, int *zmb_ind) wchar_t wc; size_t ret; - if (!(patglobflags & GF_MULTIBYTE) || !(STOUC(*x) & 0x80)) - return (wchar_t) STOUC(*x); + if (!(patglobflags & GF_MULTIBYTE) || !((unsigned char) *x & 0x80)) + return (wchar_t) (unsigned char) *x; ret = mbrtowc(&wc, x, y-x, &shiftstate); @@ -1937,7 +1938,7 @@ charnext(char *x, char *y) wchar_t wc; size_t ret; - if (!(patglobflags & GF_MULTIBYTE) || !(STOUC(*x) & 0x80)) + if (!(patglobflags & GF_MULTIBYTE) || !((unsigned char) *x & 0x80)) return x + 1; ret = mbrtowc(&wc, x, y-x, &shiftstate); @@ -1965,8 +1966,8 @@ charrefinc(char **x, char *y, int *z) wchar_t wc; size_t ret; - if (!(patglobflags & GF_MULTIBYTE) || !(STOUC(**x) & 0x80)) - return (wchar_t) STOUC(*(*x)++); + if (!(patglobflags & GF_MULTIBYTE) || !((unsigned char) **x & 0x80)) + return (wchar_t) (unsigned char) *(*x)++; ret = mbrtowc(&wc, *x, y-*x, &shiftstate); @@ -2025,13 +2026,13 @@ charsub(char *x, char *y) #else /* no MULTIBYTE_SUPPORT */ /* Get a character from the start point in a string */ -#define CHARREF(x, y) (STOUC(*(x))) +#define CHARREF(x, y) ((unsigned char) (*(x))) /* Get a pointer to the next character */ #define CHARNEXT(x, y) ((x)+1) /* Increment a pointer past the current character. */ #define CHARINC(x, y) ((x)++) /* Get a character and increment */ -#define CHARREFINC(x, y, z) (STOUC(*(x)++)) +#define CHARREFINC(x, y, z) ((unsigned char) (*(x)++)) /* Counter the number of characters between two pointers, smaller first */ #define CHARSUB(x,y) ((y) - (x)) @@ -2890,7 +2891,7 @@ patmatch(Upat prog) } if (!no && P_OP(next) == P_EXACTLY && (!P_LS_LEN(next) || - !idigit(STOUC(*P_LS_STR(next)))) && + !idigit((unsigned char) (*P_LS_STR(next)))) && !(patglobflags & 0xff)) return 0; patinput = --save; @@ -3600,8 +3601,8 @@ mb_patmatchrange(char *range, wchar_t ch, int zmb_ind, wint_t *indptr, int *mtp) * ranges specially. */ while (*range) { - if (imeta(STOUC(*range))) { - int swtype = STOUC(*range++) - STOUC(Meta); + if (imeta((unsigned char) *range)) { + int swtype = (unsigned char) *range++ - (unsigned char) Meta; if (mtp) *mtp = swtype; switch (swtype) { @@ -3753,8 +3754,8 @@ mb_patmatchindex(char *range, wint_t ind, wint_t *chr, int *mtp) *mtp = 0; while (*range) { - if (imeta(STOUC(*range))) { - int swtype = STOUC(*range++) - STOUC(Meta); + if (imeta((unsigned char) *range)) { + int swtype = (unsigned char) *range++ - (unsigned char) Meta; switch (swtype) { case 0: range--; @@ -3845,13 +3846,13 @@ patmatchrange(char *range, int ch, int *indptr, int *mtp) * ranges specially. */ for (; *range; range++) { - if (imeta(STOUC(*range))) { - int swtype = STOUC(*range) - STOUC(Meta); + if (imeta((unsigned char) *range)) { + int swtype = (unsigned char) *range - (unsigned char) Meta; if (mtp) *mtp = swtype; switch (swtype) { case 0: - if (STOUC(*++range ^ 32) == ch) + if ((unsigned char) (*++range ^ 32) == ch) return 1; break; case PP_ALPHA: @@ -3931,9 +3932,9 @@ patmatchrange(char *range, int ch, int *indptr, int *mtp) break; case PP_RANGE: range++; - r1 = STOUC(UNMETA(range)); + r1 = (unsigned char) UNMETA(range); METACHARINC(range); - r2 = STOUC(UNMETA(range)); + r2 = (unsigned char) UNMETA(range); if (*range == Meta) range++; if (r1 <= ch && ch <= r2) { @@ -3955,7 +3956,7 @@ patmatchrange(char *range, int ch, int *indptr, int *mtp) DPUTS(1, "BUG: unknown metacharacter in range."); break; } - } else if (STOUC(*range) == ch) { + } else if ((unsigned char) *range == ch) { if (mtp) *mtp = 0; return 1; @@ -3989,12 +3990,12 @@ patmatchindex(char *range, int ind, int *chr, int *mtp) *mtp = 0; for (; *range; range++) { - if (imeta(STOUC(*range))) { - int swtype = STOUC(*range) - STOUC(Meta); + if (imeta((unsigned char) *range)) { + int swtype = (unsigned char) *range - (unsigned char) Meta; switch (swtype) { case 0: /* ordinary metafied character */ - rchr = STOUC(*++range) ^ 32; + rchr = (unsigned char) *++range ^ 32; if (!ind) { *chr = rchr; return 1; @@ -4028,9 +4029,9 @@ patmatchindex(char *range, int ind, int *chr, int *mtp) case PP_RANGE: range++; - r1 = STOUC(UNMETA(range)); + r1 = (unsigned char) UNMETA(range); METACHARINC(range); - r2 = STOUC(UNMETA(range)); + r2 = (unsigned char) UNMETA(range); if (*range == Meta) range++; rdiff = r2 - r1; @@ -4050,7 +4051,7 @@ patmatchindex(char *range, int ind, int *chr, int *mtp) } } else { if (!ind) { - *chr = STOUC(*range); + *chr = (unsigned char) *range; return 1; } } diff --git a/Src/prompt.c b/Src/prompt.c index 092de63a4..3cb95039c 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1666,7 +1666,7 @@ match_colour(const char **teststrp, int is_fg, int colour) tc = TCBGCOLOUR; } if (teststrp) { - if (**teststrp == '#' && isxdigit(STOUC((*teststrp)[1]))) { + if (**teststrp == '#' && isxdigit((unsigned char) (*teststrp)[1])) { struct color_rgb color; char *end; zlong col = zstrtol(*teststrp+1, &end, 16); diff --git a/Src/sort.c b/Src/sort.c index 26949ad9c..ce2b4bbc3 100644 --- a/Src/sort.c +++ b/Src/sort.c @@ -138,7 +138,7 @@ eltpcmp(const void *a, const void *b) int mul = 0; for (; *as == *bs && *as; as++, bs++); #ifndef HAVE_STRCOLL - cmp = (int)STOUC(*as) - (int)STOUC(*bs); + cmp = (int) (unsigned char) *as - (int) (unsigned char) *bs; #endif if (sortnumeric < 0) { if (*as == '-' && idigit(as[1]) && idigit(*bs)) { @@ -159,7 +159,7 @@ eltpcmp(const void *a, const void *b) bs++; for (; idigit(*as) && *as == *bs; as++, bs++); if (idigit(*as) || idigit(*bs)) { - cmp = mul * ((int)STOUC(*as) - (int)STOUC(*bs)); + cmp = mul * ((int) (unsigned char) *as - (int) (unsigned char) *bs); while (idigit(*as) && idigit(*bs)) as++, bs++; if (idigit(*as) && !idigit(*bs)) diff --git a/Src/subst.c b/Src/subst.c index 0f98e6ea3..b8e4023e1 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -556,7 +556,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep, for ( ; *x; x += l) { char c = (l = *x == Meta) ? x[1] ^ 32 : *x; l++; - if (!iwsep(STOUC(c))) + if (!iwsep((unsigned char) c)) break; *ms_flags |= MULTSUB_WS_AT_START; } @@ -573,7 +573,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep, convchar_t c; if (*x == Dash) *x = '-'; - if (itok(STOUC(*x))) { + if (itok((unsigned char) *x)) { /* token, can't be separator, must be single byte */ rawc = *x; l = 1; @@ -582,7 +582,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep, if (!inq && !inp && WC_ZISTYPE(c, ISEP)) { *x = '\0'; for (x += l; *x; x += l) { - if (itok(STOUC(*x))) { + if (itok((unsigned char) *x)) { /* as above */ rawc = *x; l = 1; diff --git a/Src/utils.c b/Src/utils.c index edf5d3df7..32492a93b 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -86,7 +86,7 @@ set_widearray(char *mb_array, Widechar_array wca) while (*mb_array) { int mblen; - if (STOUC(*mb_array) <= 0x7f) { + if ((unsigned char) *mb_array <= 0x7f) { mb_array++; *wcptr++ = (wchar_t)*mb_array; continue; @@ -2920,7 +2920,7 @@ read1char(int echo) restore_queue_signals(q); if (echo) write_loop(SHTTY, &c, 1); - return STOUC(c); + return (unsigned char) c; } /**/ @@ -4123,20 +4123,20 @@ inittyptab(void) #endif /* typtab['.'] |= IIDENT; */ /* Allow '.' in variable names - broken */ typtab['_'] = IIDENT | IUSER; - typtab['-'] = typtab['.'] = typtab[STOUC(Dash)] = IUSER; + typtab['-'] = typtab['.'] = typtab[(unsigned char) Dash] = IUSER; typtab[' '] |= IBLANK | INBLANK; typtab['\t'] |= IBLANK | INBLANK; typtab['\n'] |= INBLANK; typtab['\0'] |= IMETA; - typtab[STOUC(Meta) ] |= IMETA; - typtab[STOUC(Marker)] |= IMETA; - for (t0 = (int)STOUC(Pound); t0 <= (int)STOUC(LAST_NORMAL_TOK); t0++) + typtab[(unsigned char) Meta ] |= IMETA; + typtab[(unsigned char) Marker] |= IMETA; + for (t0 = (int) (unsigned char) Pound; t0 <= (int) (unsigned char) LAST_NORMAL_TOK; t0++) typtab[t0] |= ITOK | IMETA; - for (t0 = (int)STOUC(Snull); t0 <= (int)STOUC(Nularg); t0++) + for (t0 = (int) (unsigned char) Snull; t0 <= (int) (unsigned char) Nularg; t0++) typtab[t0] |= ITOK | IMETA | INULL; for (s = ifs ? ifs : EMULATION(EMULATE_KSH|EMULATE_SH) ? DEFAULT_IFS_SH : DEFAULT_IFS; *s; s++) { - int c = STOUC(*s == Meta ? *++s ^ 32 : *s); + int c = (unsigned char) (*s == Meta ? *++s ^ 32 : *s); #ifdef MULTIBYTE_SUPPORT if (!isascii(c)) { /* see comment for wordchars below */ @@ -4152,7 +4152,7 @@ inittyptab(void) typtab[c] |= ISEP; } for (s = wordchars ? wordchars : DEFAULT_WORDCHARS; *s; s++) { - int c = STOUC(*s == Meta ? *++s ^ 32 : *s); + int c = (unsigned char) (*s == Meta ? *++s ^ 32 : *s); #ifdef MULTIBYTE_SUPPORT if (!isascii(c)) { /* @@ -4173,16 +4173,16 @@ inittyptab(void) DEFAULT_IFS_SH : DEFAULT_IFS, &ifs_wide); #endif for (s = SPECCHARS; *s; s++) - typtab[STOUC(*s)] |= ISPECIAL; + typtab[(unsigned char) *s] |= ISPECIAL; if (typtab_flags & ZTF_SP_COMMA) - typtab[STOUC(',')] |= ISPECIAL; + typtab[(unsigned char) ','] |= ISPECIAL; if (isset(BANGHIST) && bangchar && (typtab_flags & ZTF_INTERACT)) { typtab_flags |= ZTF_BANGCHAR; typtab[bangchar] |= ISPECIAL; } else typtab_flags &= ~ZTF_BANGCHAR; for (s = PATCHARS; *s; s++) - typtab[STOUC(*s)] |= IPATTERN; + typtab[(unsigned char) *s] |= IPATTERN; unqueue_signals(); } @@ -4193,10 +4193,10 @@ makecommaspecial(int yesno) { if (yesno != 0) { typtab_flags |= ZTF_SP_COMMA; - typtab[STOUC(',')] |= ISPECIAL; + typtab[(unsigned char) ','] |= ISPECIAL; } else { typtab_flags &= ~ZTF_SP_COMMA; - typtab[STOUC(',')] &= ~ISPECIAL; + typtab[(unsigned char) ','] &= ~ISPECIAL; } } @@ -4336,7 +4336,7 @@ itype_end(const char *ptr, int itype, int once) if (wc == WEOF) { /* invalid, treat as single character */ - int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr); + int chr = (unsigned char) (*ptr == Meta ? ptr[1] ^ 32 : *ptr); /* in this case non-ASCII characters can't match */ if (chr > 127 || !zistype(chr,itype)) break; @@ -4375,7 +4375,7 @@ itype_end(const char *ptr, int itype, int once) } else #endif for (;;) { - int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr); + int chr = (unsigned char) (*ptr == Meta ? ptr[1] ^ 32 : *ptr); if (!zistype(chr,itype)) break; ptr += (*ptr == Meta) ? 2 : 1; @@ -4983,11 +4983,11 @@ unmeta_one(const char *in, int *sz) *sz = mb_metacharlenconv_r(in, &wc, &wstate); #else if (in[0] == Meta) { - *sz = 2; - wc = STOUC(in[1] ^ 32); + *sz = 2; + wc = (unsigned char) (in[1] ^ 32); } else { - *sz = 1; - wc = STOUC(in[0]); + *sz = 1; + wc = (unsigned char) in[0]; } #endif return wc; @@ -5022,11 +5022,11 @@ ztrcmp(char const *s1, char const *s2) if(!(c1 = *s1)) c1 = -1; - else if(c1 == STOUC(Meta)) + else if(c1 == (unsigned char) Meta) c1 = *++s1 ^ 32; if(!(c2 = *s2)) c2 = -1; - else if(c2 == STOUC(Meta)) + else if(c2 == (unsigned char) Meta) c2 = *++s2 ^ 32; if(c1 == c2) @@ -5458,7 +5458,7 @@ mb_metacharlenconv_r(const char *s, wint_t *wcp, mbstate_t *mbsp) const char *ptr; wchar_t wc; - if (STOUC(*s) <= 0x7f) { + if ((unsigned char) *s <= 0x7f) { if (wcp) *wcp = (wint_t)*s; return 1; @@ -5516,10 +5516,10 @@ mb_metacharlenconv_r(const char *s, wint_t *wcp, mbstate_t *mbsp) mod_export int mb_metacharlenconv(const char *s, wint_t *wcp) { - if (!isset(MULTIBYTE) || STOUC(*s) <= 0x7f) { + if (!isset(MULTIBYTE) || (unsigned char) *s <= 0x7f) { /* treat as single byte, possibly metafied */ if (wcp) - *wcp = (wint_t)STOUC(*s == Meta ? s[1] ^ 32 : *s); + *wcp = (wint_t)(unsigned char) (*s == Meta ? s[1] ^ 32 : *s); return 1 + (*s == Meta); } /* @@ -5581,7 +5581,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr) inchar = *ptr; ptr++; - if (complete && STOUC(inchar) <= STOUC(0x7f)) { + if (complete && (unsigned char) inchar <= (unsigned char) 0x7f) { /* * We rely on 7-bit US-ASCII as a subset, so skip * multibyte handling if we have such a character. @@ -5657,7 +5657,7 @@ mb_charlenconv_r(const char *s, int slen, wint_t *wcp, mbstate_t *mbsp) const char *ptr; wchar_t wc; - if (slen && STOUC(*s) <= 0x7f) { + if (slen && (unsigned char) *s <= 0x7f) { if (wcp) *wcp = (wint_t)*s; return 1; @@ -5698,7 +5698,7 @@ mb_charlenconv_r(const char *s, int slen, wint_t *wcp, mbstate_t *mbsp) mod_export int mb_charlenconv(const char *s, int slen, wint_t *wcp) { - if (!isset(MULTIBYTE) || STOUC(*s) <= 0x7f) { + if (!isset(MULTIBYTE) || (unsigned char) *s <= 0x7f) { if (wcp) *wcp = (wint_t)*s; return 1; @@ -5717,7 +5717,7 @@ mod_export int metacharlenconv(const char *x, int *c) { /* - * Here we don't use STOUC() on the chars since they + * Here we don't use an (unsigned char) cast on the chars since they * may be compared against other chars and this will fail * if chars are signed and the high bit is set. */ @@ -5779,7 +5779,7 @@ sb_niceformat(const char *s, FILE *stream, char **outstrp, int flags) eptr = ptr + umlen; while (ptr < eptr) { - int c = STOUC(*ptr); + int c = (unsigned char) *ptr; if (c == '\'' && (flags & NICEFLAG_QUOTE)) { fmt = "\\'"; newl = 2; @@ -5996,9 +5996,9 @@ addunprintable(char *v, const char *u, const char *uend) */ int c; if (*u == Meta) - c = STOUC(*++u ^ 32); + c = (unsigned char) (*++u ^ 32); else - c = STOUC(*u); + c = (unsigned char) *u; switch (c) { case '\0': *v++ = '\\'; @@ -7104,7 +7104,7 @@ getkeystring(char *s, int *len, int how, int *misc) continue; #ifdef MULTIBYTE_SUPPORT } else if ((how & GETKEY_SINGLE_CHAR) && - isset(MULTIBYTE) && STOUC(*s) > 127) { + isset(MULTIBYTE) && (unsigned char) *s > 127) { wint_t wc; int len; len = mb_metacharlenconv(s, &wc); @@ -7207,7 +7207,7 @@ getkeystring(char *s, int *len, int how, int *misc) t = tbuf; } if ((how & GETKEY_SINGLE_CHAR) && t != tmp) { - *misc = STOUC(tmp[0]); + *misc = (unsigned char) tmp[0]; return s + 1; } } diff --git a/Src/zsh.h b/Src/zsh.h index 6f68df6a4..b035a1184 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -135,19 +135,6 @@ struct mathfunc { #define STRMATHFUNC(name, func, id) \ { NULL, name, MFF_STR, NULL, func, NULL, 0, 0, id } -/* Character tokens are sometimes casted to (unsigned char)'s. * - * Unfortunately, some compilers don't correctly cast signed to * - * unsigned promotions; i.e. (int)(unsigned char)((char) -1) evaluates * - * to -1, instead of 255 like it should. We circumvent the troubles * - * of such shameful delinquency by casting to a larger unsigned type * - * then back down to unsigned char. */ - -#ifdef BROKEN_SIGNED_TO_UNSIGNED_CASTING -# define STOUC(X) ((unsigned char)(unsigned short)(X)) -#else -# define STOUC(X) ((unsigned char)(X)) -#endif - /* Meta together with the character following Meta denotes the character * * which is the exclusive or of 32 and the character following Meta. * * This is used to represent characters which otherwise has special * diff --git a/Src/ztype.h b/Src/ztype.h index 5c85b0cd7..8757fc733 100644 --- a/Src/ztype.h +++ b/Src/ztype.h @@ -43,7 +43,7 @@ #define IWSEP (1 << 13) #define INULL (1 << 14) #define IPATTERN (1 << 15) -#define zistype(X,Y) (typtab[STOUC(X)] & Y) +#define zistype(X,Y) (typtab[(unsigned char) (X)] & Y) #define idigit(X) zistype(X,IDIGIT) #define ialnum(X) zistype(X,IALNUM) #define iblank(X) zistype(X,IBLANK) /* blank, not including \n */ diff --git a/configure.ac b/configure.ac index 074141d38..f340d2993 100644 --- a/configure.ac +++ b/configure.ac @@ -582,16 +582,6 @@ if test x$zsh_cv_c_have_union_init = xyes; then AC_DEFINE(HAVE_UNION_INIT) fi -dnl Checking if compiler correctly cast signed to unsigned. -AC_CACHE_CHECK(if signed to unsigned casting is broken, -zsh_cv_c_broken_signed_to_unsigned_casting, -[AC_RUN_IFELSE([AC_LANG_SOURCE([[int main(){return((int)(unsigned char)((char) -1) == 255);}]])],[zsh_cv_c_broken_signed_to_unsigned_casting=yes],[zsh_cv_c_broken_signed_to_unsigned_casting=no],[zsh_cv_c_broken_signed_to_unsigned_casting=no])]) -AH_TEMPLATE([BROKEN_SIGNED_TO_UNSIGNED_CASTING], -[Define to 1 if compiler incorrectly cast signed to unsigned.]) -if test x$zsh_cv_c_broken_signed_to_unsigned_casting = xyes; then - AC_DEFINE(BROKEN_SIGNED_TO_UNSIGNED_CASTING) -fi - dnl Checking if the compiler supports variable-length arrays AC_CACHE_CHECK(if the compiler supports variable-length arrays, zsh_cv_c_variable_length_arrays, -- cgit v1.2.3 From 2701ab161df1f259b8292a650a4ea5cebd668d81 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 13 Dec 2022 20:12:06 +0900 Subject: 51207: fix for read -d when the delimiter is a byte >= 0x80 --- ChangeLog | 3 +++ Src/builtin.c | 7 ++++--- Test/B04read.ztst | 6 ++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 996704135..5b0af2135 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-16 Oliver Kiddle + * Jun T.: 51207: Src/builtin.c, Test/B04read.ztst: + fix for read -d when the delimiter is a byte >= 0x80 + * 51212: Etc/zsh-development-guide, Src/Modules/curses.c, Src/Modules/stat.c, Src/Modules/zftp.c, Src/Modules/zpty.c, Src/Modules/zutil.c, Src/Zle/compcore.c, Src/Zle/complete.c, diff --git a/Src/builtin.c b/Src/builtin.c index db83313d6..951970138 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6286,7 +6286,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) char *laststart; size_t ret; #else - char delim = '\n'; + int delim = '\n'; #endif if (OPT_HASARG(ops,c='k')) { @@ -6413,10 +6413,11 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) if (wi != WEOF) delim = (wchar_t)wi; else - delim = (wchar_t)((delimstr[0] == Meta) ? + delim = (wchar_t) (unsigned char) ((delimstr[0] == Meta) ? delimstr[1] ^ 32 : delimstr[0]); #else - delim = (delimstr[0] == Meta) ? delimstr[1] ^ 32 : delimstr[0]; + delim = (unsigned char) ((delimstr[0] == Meta) ? + delimstr[1] ^ 32 : delimstr[0]); #endif if (SHTTY != -1) { struct ttyinfo ti; diff --git a/Test/B04read.ztst b/Test/B04read.ztst index 25c3d4173..96adf51c7 100644 --- a/Test/B04read.ztst +++ b/Test/B04read.ztst @@ -82,6 +82,12 @@ >Testing the >null hypothesis + print -n $'first line\x80second line\x80' | + while read -d $'\x80' line; do print $line; done +0:read with a delimiter >= 0x80 +>first line +>second line + # Note that trailing NULLs are not stripped even if they are in # $IFS; only whitespace characters contained in $IFS are stripped. print -n $'Aaargh, I hate nulls.\0\0\0' | read line -- cgit v1.2.3 From 35a2f155c3b92e67957325e1f49e409546378e3e Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 17 Dec 2022 00:09:37 +0100 Subject: 51214: handle read -d and a delimiter that can't be decoded into a character Terminate input at the raw byte value of the delimiter. Also document and test the use of an empty string as a way to specify NUL as the delimiter. --- ChangeLog | 4 ++++ Doc/Zsh/builtins.yo | 3 ++- Src/builtin.c | 7 +++++-- Test/B04read.ztst | 4 ++++ Test/D07multibyte.ztst | 14 ++++++++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b0af2135..130bec319 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-12-16 Oliver Kiddle + * 51214: Doc/Zsh/builtins.yo, Src/builtin.c, Test/B04read.ztst, + Test/D07multibyte.ztst: with read -d and a delimiter that can't be + decoded into a character terminate input at the raw byte value + * Jun T.: 51207: Src/builtin.c, Test/B04read.ztst: fix for read -d when the delimiter is a byte >= 0x80 diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index b6217f66d..56428a714 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1589,7 +1589,8 @@ Input is read from the coprocess. ) item(tt(-d) var(delim))( Input is terminated by the first character of var(delim) instead of -by newline. +by newline. For compatibility with other shells, if var(delim) is an +empty string, input is terminated at the first NUL. ) item(tt(-t) [ var(num) ])( Test if input is available before attempting to read. If var(num) diff --git a/Src/builtin.c b/Src/builtin.c index 951970138..70a950666 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6282,6 +6282,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) long izle_timeout = 0; #ifdef MULTIBYTE_SUPPORT wchar_t delim = L'\n', wc; + int rawbyte = 0; mbstate_t mbs; char *laststart; size_t ret; @@ -6412,9 +6413,11 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) wi = WEOF; if (wi != WEOF) delim = (wchar_t)wi; - else + else { delim = (wchar_t) (unsigned char) ((delimstr[0] == Meta) ? delimstr[1] ^ 32 : delimstr[0]); + rawbyte = 1; + } #else delim = (unsigned char) ((delimstr[0] == Meta) ? delimstr[1] ^ 32 : delimstr[0]); @@ -6842,7 +6845,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) break; } *bptr = (char)c; - if (isset(MULTIBYTE)) { + if (isset(MULTIBYTE) && !rawbyte) { ret = mbrtowc(&wc, bptr, 1, &mbs); if (!ret) /* NULL */ ret = 1; diff --git a/Test/B04read.ztst b/Test/B04read.ztst index 96adf51c7..14bdaeef5 100644 --- a/Test/B04read.ztst +++ b/Test/B04read.ztst @@ -82,6 +82,10 @@ >Testing the >null hypothesis + read -ed '' <<<$'one\0two' +0:empty delimiter terminates at nulls +>one + print -n $'first line\x80second line\x80' | while read -d $'\x80' line; do print $line; done 0:read with a delimiter >= 0x80 diff --git a/Test/D07multibyte.ztst b/Test/D07multibyte.ztst index 6909346cb..413c4fe73 100644 --- a/Test/D07multibyte.ztst +++ b/Test/D07multibyte.ztst @@ -212,6 +212,20 @@ >first >second + read -ed £ +0:read with multibyte delimiter where bytes of delimiter also occur in input +one¤twoãthree + + read -ed $'\xa0' <<<$'first\xa0second' +0:read delimited by a byte that isn't a valid multibyte character +>first + + read -ed $'\xc2' +0:read delimited by a single byte terminates if the byte is part of a multibyte character +one + (IFS=« read -d » -A array print -l $array) -- cgit v1.2.3 From bc7511bdd887cfda7eb45e8009de079d35c4d7f1 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sat, 24 Dec 2022 11:17:16 +0000 Subject: 51249: use of --force-local with tar completion --- ChangeLog | 5 +++++ Completion/Unix/Command/_tar | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 130bec319..0771c2719 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-12-30 Peter Stephenson + + * Daniel: 51249: Completion/Unix/Command/_tar: copy + --force-local option as needed for file names. + 2022-12-16 Oliver Kiddle * 51214: Doc/Zsh/builtins.yo, Src/builtin.c, Test/B04read.ztst, diff --git a/Completion/Unix/Command/_tar b/Completion/Unix/Command/_tar index f9901c0c9..1cabd9713 100644 --- a/Completion/Unix/Command/_tar +++ b/Completion/Unix/Command/_tar @@ -158,7 +158,7 @@ elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then fi if [[ $tf != $_tar_cache_name && -f $tf ]]; then - _tar_cache_list=("${(@f)$($words[1] $largs $tf)}") + _tar_cache_list=("${(@f)$($words[1] ${words[(r)--force-local]} $largs $tf)}") _tar_cache_name=$tf fi -- cgit v1.2.3 From 4f1544a6287d2b1c14730826ac9a5822ea928b7c Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Sat, 17 Dec 2022 23:45:09 +0900 Subject: 51233: Update sanitizer list to GCC 12 Add following sanitizers - bounds-strict - hwaddress - kernel-address - kernel-hwaddress - leak - pointer-compare - pointer-subtract - shadow-call-stack - shift-base - shift-exponent - thread - undefined And sort the list in alphabetical order --- ChangeLog | 5 +++++ Completion/Unix/Command/_gcc | 12 +++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0771c2719..7d6ca6619 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-12-31 Oliver Kiddle + + * Shohei YOSHIDA: 51233: Completion/Unix/Command/_gcc: + Update sanitizer list to GCC 12 + 2022-12-30 Peter Stephenson * Daniel: 51249: Completion/Unix/Command/_tar: copy diff --git a/Completion/Unix/Command/_gcc b/Completion/Unix/Command/_gcc index ac0e8fda3..f10000391 100644 --- a/Completion/Unix/Command/_gcc +++ b/Completion/Unix/Command/_gcc @@ -1318,11 +1318,13 @@ fi local -a sanitizers sanitizers=( - address alignment bool bounds enum float-cast-overflow float-divide-by-zero - integer-divide-by-zero memory nonnull-attribute null nullability-arg - nullability-assign nullability-return object-size pointer-overflow return - unsigned-integer-overflow returns-nonnull-attribute shift signed-integer-overflow - unreachable vla-bound vptr + address alignment bool bounds bounds-strict enum builtin float-cast-overflow + float-divide-by-zero hwaddress integer-divide-by-zero kernel-address + kernel-hwaddress leak memory nonnull-attribute null nullability-arg nullability-assign + nullability-return object-size pointer-compare pointer-overflow pointer-subtract return + returns-nonnull-attribute shadow-call-stack shift shift-base shift-exponent + signed-integer-overflow thread undefined unsigned-integer-overflow unreachable + vla-bound vptr ) local -a languages -- cgit v1.2.3 From 1ff0f12a9a66776af4c0412bfd9369ba646eb53d Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 27 Dec 2022 11:31:49 +0900 Subject: 51253: Update ruby completion for version 3.2.0 --- ChangeLog | 3 +++ Completion/Unix/Command/_ruby | 27 +++++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d6ca6619..6f3063bf6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-31 Oliver Kiddle + * Shohei YOSHIDA: 51253: Completion/Unix/Command/_ruby: + Update ruby completion for version 3.2.0 + * Shohei YOSHIDA: 51233: Completion/Unix/Command/_gcc: Update sanitizer list to GCC 12 diff --git a/Completion/Unix/Command/_ruby b/Completion/Unix/Command/_ruby index 0e1f5dbc0..9b182693f 100644 --- a/Completion/Unix/Command/_ruby +++ b/Completion/Unix/Command/_ruby @@ -40,20 +40,27 @@ opts=( '(-v)--verbose[turn on verbose mode and disable script from stdin]' '-x-[strip off text before #!ruby line and perhaps cd to directory]:directory:_files -/' '(1 * -)--copyright[print the copyright]' - --{en,dis}'able=[enable or disable features]:feature:(gems did_you_mean rubyopt frozen_string_literal jit all)' + --{en,dis}'able=[enable or disable features]:feature:(gems error_highlight did_you_mean syntax_suggest rubyopt frozen_string_literal mjit yjit all)' \!--{en,dis}able-{gems,rubyopt,all} - '--dump=[dump debug information]:information:_sequence compadd - insns yydebug parsetree parsetree_with_comment' + '--dump=[dump debug information]:information:_sequence compadd - insns insns_without_opt yydebug parsetree parsetree_with_comment' --{external,internal}'-encoding=:charset:->charsets' '!'{-y,--yydebug} '!--dump=:target:(version copyright usage yydebug syntax parsetree parsetree_with_comment insns)' - '--jit[enable jit with default options]' - '--jit-warnings[enable printing JIT warnings]' - '--jit-debug[enable JIT debugging (very slow)]' - '--jit-wait[wait until JIT compilation finishes every time (for testing)]' - '--jit-save-temps[save JIT temporary files]' - '--jit-verbose=-[print JIT logs of level num or less to stderr]:maximum log level [0]' - '--jit-max-cache=-[specify max number of methods to be JIT-ed in a cache]:number [100]' - '--jit-min-calls=-[specify number of calls to trigger JIT]:calls [10000]' + '(--mjit --yjit)--jit[enable jit for the platform]' + '(--jit --yjit)--mjit[enable C compiler-based JIT compiler]' + '(--jit --mjit)--yjit[enable in-process JIT compiler]' + '--mjit-warnings[enable printing JIT warnings]' + '--mjit-debug[enable JIT debugging (very slow)]' + '--mjit-wait[wait until JIT compilation finishes every time (for testing)]' + '--mjit-save-temps[save JIT temporary files]' + '--mjit-verbose=-[print JIT logs of level num or less to stderr]:maximum log level [0]' + '--mjit-max-cache=-[specify max number of methods to be JIT-ed in a cache]:number [100]' + '--mjit-min-calls=-[specify number of calls to trigger JIT]:calls [10000]' + '--yjit-stat[enable collecting YJIT statistics]' + '--yjit-exec-mem-size=-[size of executable memory block in MiB]:mem size' + '--yjit-call-threshold=-[number of calls to trigger JIT]:number' + '--yjit-max-versions=-[maximum number of versions per basic block]:versions' + '--yjit-greedy-versioning[greedy versioning mode]' ) irb=( -- cgit v1.2.3 From 7b50d620804ad457e77ea05e2e8d41d708b618f3 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 27 Dec 2022 11:31:50 +0900 Subject: 51254: Add irb completion for version 1.6.2 --- ChangeLog | 3 +++ Completion/Unix/Command/_ruby | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f3063bf6..12bc70958 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-31 Oliver Kiddle + * Shohei YOSHIDA: 51254: Completion/Unix/Command/_ruby: + Add irb completion for version 1.6.2 + * Shohei YOSHIDA: 51253: Completion/Unix/Command/_ruby: Update ruby completion for version 3.2.0 diff --git a/Completion/Unix/Command/_ruby b/Completion/Unix/Command/_ruby index 9b182693f..8b1c0bf41 100644 --- a/Completion/Unix/Command/_ruby +++ b/Completion/Unix/Command/_ruby @@ -69,16 +69,28 @@ irb=( $opts[(r)*-d\[*] '(--noinspect)--inspect[use inspect for output]' "(--inspect)--noinspect[don't use inspect for output]" - '(--noreadline)--readline[use readline extension]' - "(--readline)--noreadline[don't use readline extension]" '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--prompt,--prompt-mode}'[switch prompt mode]:prompt mode:(default simple xmp inf-ruby)' '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--inf-ruby-mode,--simple-prompt,--noprompt} '--tracer[display trace for each command execution]' '--back-trace-limit[set limit for backtraces]:limit [16]:' '!--irb_debug:level' '--context-mode:n' + '--extra-doc-dir[add an extra doc dir for the doc dialog]' '(--noecho)--echo[show result]' "(--echo)--noecho[don't show result]" + '(--noecho-on-assignment)--echo-on-assignment[show result on assignment]' + "(--echo-on-assignment)--noecho-on-assignment[don't show result on assignment]" + '--truncate-echo-on-assignment[show truncated result on assignment]' + '(--nomultiline)--multiline[use multiline editor module]' + "(--multiline)--nomultiline[don't use multiline editor module]" + '(--nosingleline)--singleline[use single line editor module]' + "(--singleline)--nosingleline[don't use single line editor module]" + '(--nocolorize)--colorize[use color-highlighting]' + "(--colorize)--nocolorize[don't use color-highlighting]" + '(--noautocomplete)--autocomplete[use auto-completion]' + "(--autocomplete)--noautocomplete[don't use auto-completion]" + '(--noscript)--script[script mode]' + '(--script)--noscript[no script mode]' '--single-irb[share self with sub-irb]' '(--noverbose)--verbose[show details]' "(--verbose)--noverbose[don't show details]" -- cgit v1.2.3 From 92316b70ff467c60551e75fcb9da5131d024d019 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 27 Dec 2022 11:31:51 +0900 Subject: 51255: Update erb completion for version 4.0.2 --- ChangeLog | 3 +++ Completion/Unix/Command/_ruby | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12bc70958..ea064eab8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-12-31 Oliver Kiddle + * Shohei YOSHIDA: 51255: Completion/Unix/Command/_ruby: + Update erb completion for version 4.0.2 + * Shohei YOSHIDA: 51254: Completion/Unix/Command/_ruby: Add irb completion for version 1.6.2 diff --git a/Completion/Unix/Command/_ruby b/Completion/Unix/Command/_ruby index 8b1c0bf41..314307ebb 100644 --- a/Completion/Unix/Command/_ruby +++ b/Completion/Unix/Command/_ruby @@ -100,8 +100,9 @@ erb=( "-P[don't evaluate lines which start with %]" '-T[specify trim mode]:mode [0]:((0\:EOL\ remains 1\:EOL\ removed\ if\ line\ ends\ with\ %\> 2\:EOL\ removed\ if\ line\ starts\ with\ \<%\ and\ ends\ with\ %\> -\:EOL\ is\ removed\ if\ line\ ends\ with\ -%\>,\ leading\ whitespace\ removed\ after\ \<%-))' '(-d --debug)'{-d,--debug}'[set debugging flags (set $DEBUG to true)]' - '-n[used with -x, prepends line number to output]' - '-x[convert eRuby to Ruby]' + '-n[print ruby script with line number]' + '-x[print ruby script]' + '-v[enable verbose mode]' ) case "$service" in -- cgit v1.2.3 From d23bcf11714063498a9aec17a360af485026fef2 Mon Sep 17 00:00:00 2001 From: Max Coplan Date: Fri, 30 Dec 2022 15:41:27 -0800 Subject: 51263: fix typo - `an path` -> `a path` --- ChangeLog | 2 ++ Doc/Zsh/files.yo | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ea064eab8..9efe679f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2022-12-31 Oliver Kiddle + * Max Coplan: 51263: Doc/Zsh/files.yo: fix typo, an -> a + * Shohei YOSHIDA: 51255: Completion/Unix/Command/_ruby: Update erb completion for version 4.0.2 diff --git a/Doc/Zsh/files.yo b/Doc/Zsh/files.yo index 65debe044..c6c7da307 100644 --- a/Doc/Zsh/files.yo +++ b/Doc/Zsh/files.yo @@ -14,7 +14,7 @@ cindex(zshenv) Commands are first read from tt(zshenv()); this cannot be overridden. Subsequent behaviour is modified by the tt(RCS) and tt(GLOBAL_RCS) options; the former affects all startup files, while the -second only affects global startup files (those shown here with an +second only affects global startup files (those shown here with a path starting with a tt(/)). If one of the options is unset at any point, any subsequent startup file+LPAR()s+RPAR() of the corresponding -- cgit v1.2.3 From 4ad99ab788caf5d64b21c7fb6ca3cbbf1c769b27 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 6 Jan 2023 12:58:31 +0000 Subject: unposted (cf. users/28616): _svnadmin: Add comment noting a case that's not completed correctly. --- ChangeLog | 6 ++++++ Completion/Unix/Command/_subversion | 3 +++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9efe679f4..09398077a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-01-06 Daniel Shahaf + + * unposted (cf. users/28616): + Completion/Unix/Command/_subversion: _svnadmin: Add comment + noting a case that's not completed correctly. + 2022-12-31 Oliver Kiddle * Max Coplan: 51263: Doc/Zsh/files.yo: fix typo, an -> a diff --git a/Completion/Unix/Command/_subversion b/Completion/Unix/Command/_subversion index 8fc46a292..9a0328dca 100644 --- a/Completion/Unix/Command/_subversion +++ b/Completion/Unix/Command/_subversion @@ -318,6 +318,9 @@ _svnadmin () { # Test cases: # svnadmin freeze . rsync -- offers --file # svnadmin freeze -- . rsync - offers rsync's options + # svnadmin freeze . -- rsync - should do the same (but currently doesn't) + # + # TODO: Fix the third case. # # Note: the NORMARG calculations here include one positional argument # (the '.') before the command. -- cgit v1.2.3 From 81684e334d34ca315938569f3154945d0bfb05e0 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sun, 8 Jan 2023 13:09:34 +0000 Subject: unposted: In a comment, replace a C variables glob pattern with its matches, for greppability. --- ChangeLog | 5 +++++ Src/Zle/zle_refresh.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 09398077a..c6a15b9e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-01-08 Daniel Shahaf + + * unposted: Src/Zle/zle_refresh.c: In a comment, replace a C + variables glob pattern with its matches, for greppability. + 2023-01-06 Daniel Shahaf * unposted (cf. users/28616): diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 30b5d4447..2db5f0642 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -36,8 +36,8 @@ * non-zero width followed by an arbitrary (but typically small) * number of characters that have zero width (combining characters). * - * The allocated size for each array is given by ?mw_size; nmw_ind - * is the next free element, i.e. nmwbuf[nmw_ind] will be the next + * The allocated size for each array is given by omw_size and nmw_size; + * nmw_ind is the next free element, i.e. nmwbuf[nmw_ind] will be the next * element to be written (we never insert into omwbuf). We initialise * nmw_ind to 1 to avoid the index stored in the character looking like a * NULL. This wastees a word but it's safer than messing with pointers. -- cgit v1.2.3 From 996b51515600859ce7f952f22c6262ecd24578e1 Mon Sep 17 00:00:00 2001 From: Nathan Houghton Date: Wed, 4 Jan 2023 14:44:18 -0800 Subject: 51276: Fix diff completion for non GNU / FreeBSD platforms On OpenBSD, "diff -urpN dir1/ di" would refuse to complete a second filename/directory name. This was caused by the -u and -U options getting dropped from args (overwriting args vs appending). --- ChangeLog | 5 +++++ Completion/Unix/Type/_diff_options | 41 ++++++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6a15b9e6..773971c5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-01-10 Oliver Kiddle + + * Nathan Houghton: 51276: Completion/Unix/Type/_diff_options: + Fix diff completion for non GNU / FreeBSD platforms + 2023-01-08 Daniel Shahaf * unposted: Src/Zle/zle_refresh.c: In a comment, replace a C diff --git a/Completion/Unix/Type/_diff_options b/Completion/Unix/Type/_diff_options index dfa9889f2..2646527df 100644 --- a/Completion/Unix/Type/_diff_options +++ b/Completion/Unix/Type/_diff_options @@ -133,33 +133,44 @@ else case $OSTYPE in openbsd*|solaris2.<9->) of+=' -u -U' + ;| + openbsd*|solaris*) + of+=' -n -C -D' + ;| + solaris*) + of+=' -h' + ;| + openbsd*) + of+=' -q' + ;| + # modifications to "$of" should be done above this line so that it is + # uniformly defined while constructing $args + openbsd*|solaris2.<9->) args+=( - "($of)-u[output a unified diff]" - "($of)-U+[output a unified diff]:lines of context" + "($of)-u[output a unified diff]" + "($of)-U+[output a unified diff]:lines of context" ) ;| openbsd*|solaris*) args+=( - "($of)-C+[output a context diff]:lines of context" - "($of)-D+[output merged file with preprocessor directives]:preprocessor symbol" - '-i[case insensitive]' - '-l[long output format (paginate with pr(1))]' - '-s[report on identical files]' - '-t[expand tabs in output lines]' + "($of)-C+[output a context diff]:lines of context" + "($of)-D+[output merged file with preprocessor directives]:preprocessor symbol" + '-i[case insensitive]' + '-s[report on identical files]' + '-t[expand tabs in output lines]' ) ;| solaris*) - of+=' -h -n' args+=( - '-w[ignore all white space]' - "($of)-h[do a fast, half-hearted job]" - "($of)-n[output a reversed ed script]" + '-w[ignore all white space]' + "($of)-h[do a fast, half-hearted job]" + "($of)-n[output a reversed ed script]" '-S+[set first file in comparison]:start with file:_files' + '-l[long output format (paginate with pr(1))]' ) ;; openbsd*) - of+=' -n -q -u -C -D -U' - args=( + args+=( "($of)-n[output an rcsdiff(1)-compatible diff]" "($of)-q[only print a line when the files differ; does not produce a list of changes]" '-a[treat all files as ASCII text]' @@ -173,7 +184,7 @@ else '-P[treat absent files in the second directory as if they were empty]' '-S[start a directory diff from a file name]:file name:_files' '*-X[exclude files and subdirectories whose basenames match lines in a file]:file name:_files' - '-x[exclude files and subdirectories whose basenames match a pattern]:pattern' + '*-x[exclude files and subdirectories whose basenames match a pattern]:pattern' ) ;; esac -- cgit v1.2.3 From 667ead3a64e590ac758e9f0a053849c7aaccec66 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Jan 2023 20:53:17 +0100 Subject: 51258, 51272: refactor handling of terminal attributes, removing OFF flags in zattr --- ChangeLog | 8 ++ Src/Modules/watch.c | 64 +++++----- Src/Zle/complist.c | 60 ++++----- Src/Zle/zle.h | 6 +- Src/Zle/zle_main.c | 19 +-- Src/Zle/zle_refresh.c | 316 ++++++++++++---------------------------------- Src/Zle/zle_tricky.c | 48 +++---- Src/Zle/zle_utils.c | 2 +- Src/builtin.c | 4 +- Src/init.c | 3 +- Src/input.c | 2 +- Src/loop.c | 2 +- Src/prompt.c | 254 +++++++++++++++++++++++++------------ Src/subst.c | 11 +- Src/utils.c | 7 +- Src/zsh.h | 45 ++----- Test/D01prompt.ztst | 13 ++ Test/X04zlehighlight.ztst | 14 +- 18 files changed, 400 insertions(+), 478 deletions(-) diff --git a/ChangeLog b/ChangeLog index 773971c5a..b3518f1bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2023-01-10 Oliver Kiddle + * 51258, 51272: Src/Modules/watch.c, Src/Zle/complist.c, + Src/Zle/zle.h, Src/Zle/zle_main.c, Src/Zle/zle_refresh.c, + Src/Zle/zle_tricky.c, Src/Zle/zle_utils.c, Src/builtin.c, + Src/init.c, Src/input.c, Src/loop.c, Src/prompt.c, + Src/subst.c, Src/utils.c, Src/zsh.h, Test/D01prompt.ztst, + Test/X04zlehighlight.ztst: refactor handling of terminal + attributes, removing OFF flags in zattr + * Nathan Houghton: 51276: Completion/Unix/Type/_diff_options: Fix diff completion for non GNU / FreeBSD platforms diff --git a/Src/Modules/watch.c b/Src/Modules/watch.c index d45c3cf3d..0de8cbf9a 100644 --- a/Src/Modules/watch.c +++ b/Src/Modules/watch.c @@ -255,8 +255,10 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) while (*fmt) if (*fmt == '\\') { if (*++fmt) { - if (prnt) + if (prnt) { + applytextattributes(TSC_RAW); putchar(*fmt); + } ++fmt; } else if (fini) return fmt; @@ -266,8 +268,10 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) else if (*fmt == fini) return ++fmt; else if (*fmt != '%') { - if (prnt) + if (prnt) { + applytextattributes(TSC_RAW); putchar(*fmt); + } ++fmt; } else { if (*++fmt == BEGIN3) @@ -277,12 +281,15 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) else switch (*(fm2 = fmt++)) { case 'n': + applytextattributes(TSC_RAW); printf("%.*s", (int)sizeof(u->ut_name), u->ut_name); break; case 'a': + applytextattributes(TSC_RAW); printf("%s", (!inout) ? "logged off" : "logged on"); break; case 'l': + applytextattributes(TSC_RAW); if (!strncmp(u->ut_line, "tty", 3)) printf("%.*s", (int)sizeof(u->ut_line) - 3, u->ut_line + 3); else @@ -290,6 +297,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) break; # ifdef WATCH_UTMP_UT_HOST case 'm': + applytextattributes(TSC_RAW); for (p = u->ut_host, i = sizeof(u->ut_host); i && *p; i--, p++) { if (*p == '.' && !idigit(p[1])) break; @@ -297,6 +305,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) } break; case 'M': + applytextattributes(TSC_RAW); printf("%.*s", (int)sizeof(u->ut_host), u->ut_host); break; # endif /* WATCH_UTMP_UT_HOST */ @@ -343,9 +352,11 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) len = ztrftime(buf, 40, fm2, tm, 0L); if (len > 0) metafy(buf, len, META_NOALLOC); + applytextattributes(TSC_RAW); printf("%s", (*buf == ' ') ? buf + 1 : buf); break; case '%': + applytextattributes(TSC_RAW); putchar('%'); break; case 'F': @@ -354,16 +365,13 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) atr = match_colour((const char**)&fmt, 1, 0); if (*fmt == '}') fmt++; - if (!(atr & (TXT_ERROR | TXTNOFGCOLOUR))) { - txtunset(TXT_ATTR_FG_COL_MASK); - txtset(atr & TXT_ATTR_FG_ON_MASK); - set_colour_attribute(atr, COL_SEQ_FG, TSC_RAW); + if (atr && atr != TXT_ERROR) { + tsetattrs(atr); + break; } - } - break; + } /* fall-through */ case 'f': - txtunset(TXT_ATTR_FG_ON_MASK); - set_colour_attribute(TXTNOFGCOLOUR, COL_SEQ_FG, TSC_RAW); + tunsetattrs(TXTFGCOLOUR); break; case 'K': if (*fmt == '{') { @@ -371,49 +379,43 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) atr = match_colour((const char**)&fmt, 0, 0); if (*fmt == '}') fmt++; - if (!(atr & (TXT_ERROR | TXTNOBGCOLOUR))) { - txtunset(TXT_ATTR_BG_COL_MASK); - txtset(atr & TXT_ATTR_BG_ON_MASK); - set_colour_attribute(atr, COL_SEQ_BG, TSC_RAW); + if (atr && atr != TXT_ERROR) { + tsetattrs(atr); + break; } - } - break; + } /* fall-through */ case 'k': - txtunset(TXT_ATTR_BG_ON_MASK); - set_colour_attribute(TXTNOBGCOLOUR, COL_SEQ_BG, TSC_RAW); + tunsetattrs(TXTBGCOLOUR); break; case 'S': - txtset(TXTSTANDOUT); - tsetcap(TCSTANDOUTBEG, TSC_RAW); + tsetattrs(TXTSTANDOUT); break; case 's': - txtunset(TXTSTANDOUT); - tsetcap(TCSTANDOUTEND, TSC_RAW|TSC_DIRTY); + tunsetattrs(TXTSTANDOUT); break; case 'B': - txtset(TXTBOLDFACE); - tsetcap(TCBOLDFACEBEG, TSC_RAW|TSC_DIRTY); + tsetattrs(TXTBOLDFACE); break; case 'b': - txtunset(TXTBOLDFACE); - tsetcap(TCALLATTRSOFF, TSC_RAW|TSC_DIRTY); + tunsetattrs(TXTBOLDFACE); break; case 'U': - txtset(TXTUNDERLINE); - tsetcap(TCUNDERLINEBEG, TSC_RAW); + tsetattrs(TXTUNDERLINE); break; case 'u': - txtunset(TXTUNDERLINE); - tsetcap(TCUNDERLINEEND, TSC_RAW|TSC_DIRTY); + tunsetattrs(TXTUNDERLINE); break; default: + applytextattributes(TSC_RAW); putchar('%'); putchar(*fm2); break; } } - if (prnt) + if (prnt) { + applytextattributes(TSC_RAW); putchar('\n'); + } return fmt; } diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 6e0eac31f..8bdf1bb29 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -1072,7 +1072,7 @@ static int compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) { char *p, nc[2*DIGBUFSIZE + 12], nbuf[2*DIGBUFSIZE + 12]; - int l = 0, cc = 0, b = 0, s = 0, u = 0, m, ask, beg, stat; + int l = 0, cc = 0, m, ask, beg, stat; if ((stat = !fmt)) { if (mlbeg >= 0) { @@ -1118,48 +1118,46 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) m = 0; switch (cchar) { case ZWC('%'): - if (dopr == 1) + if (dopr == 1) { + applytextattributes(0); putc('%', shout); + } cc++; break; case ZWC('n'): if (!stat) { sprintf(nc, "%d", n); - if (dopr == 1) + if (dopr == 1) { + applytextattributes(0); fputs(nc, shout); + } /* everything here is ASCII... */ cc += strlen(nc); } break; case ZWC('B'): - b = 1; if (dopr) - tcout(TCBOLDFACEBEG); + tsetattrs(TXTBOLDFACE); break; case ZWC('b'): - b = 0; m = 1; if (dopr) - tcout(TCALLATTRSOFF); + tunsetattrs(TXTBOLDFACE); break; case ZWC('S'): - s = 1; if (dopr) - tcout(TCSTANDOUTBEG); + tsetattrs(TXTSTANDOUT); break; case ZWC('s'): - s = 0; m = 1; if (dopr) - tcout(TCSTANDOUTEND); + tunsetattrs(TXTSTANDOUT); break; case ZWC('U'): - u = 1; if (dopr) - tcout(TCUNDERLINEBEG); + tsetattrs(TXTUNDERLINE); break; case ZWC('u'): - u = 0; m = 1; if (dopr) - tcout(TCUNDERLINEEND); + tunsetattrs(TXTUNDERLINE); break; case ZWC('F'): case ZWC('K'): @@ -1173,20 +1171,21 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) } else atr = match_colour(NULL, is_fg, arg); if (atr != TXT_ERROR && dopr) - set_colour_attribute(atr, is_fg ? COL_SEQ_FG : - COL_SEQ_BG, 0); + tsetattrs(atr); break; case ZWC('f'): if (dopr) - set_colour_attribute(TXTNOFGCOLOUR, COL_SEQ_FG, 0); + tunsetattrs(TXTFGCOLOUR); break; case ZWC('k'): if (dopr) - set_colour_attribute(TXTNOBGCOLOUR, COL_SEQ_BG, 0); + tunsetattrs(TXTBGCOLOUR); break; case ZWC('{'): if (arg) cc += arg; + if (dopr) + applytextattributes(0); for (; *p && (*p != '%' || p[1] != '}'); p++) if (dopr) putc(*p == Meta ? *++p ^ 32 : *p, shout); @@ -1197,7 +1196,7 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) if (stat) { sprintf(nc, "%d/%d", (n ? mlastm : mselect), listdat.nlist); - m = 2; + m = 1; } break; case ZWC('M'): @@ -1205,20 +1204,20 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) sprintf(nbuf, "%d/%d", (n ? mlastm : mselect), listdat.nlist); sprintf(nc, "%-9s", nbuf); - m = 2; + m = 1; } break; case ZWC('l'): if (stat) { sprintf(nc, "%d/%d", ml + 1, listdat.nlines); - m = 2; + m = 1; } break; case ZWC('L'): if (stat) { sprintf(nbuf, "%d/%d", ml + 1, listdat.nlines); sprintf(nc, "%-9s", nbuf); - m = 2; + m = 1; } break; case ZWC('p'): @@ -1230,7 +1229,7 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) ((ml + 1) * 100) / listdat.nlines); else strcpy(nc, "Top"); - m = 2; + m = 1; } break; case ZWC('P'): @@ -1242,25 +1241,19 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) ((ml + 1) * 100) / listdat.nlines); else strcpy(nc, "Top "); - m = 2; + m = 1; } break; } - if (m == 2 && dopr == 1) { + if (m && dopr) { /* nc only contains ASCII text */ int l = strlen(nc); if (l + cc > zterm_columns - 2) nc[l -= l + cc - (zterm_columns - 2)] = '\0'; + applytextattributes(0); fputs(nc, shout); cc += l; - } else if (dopr && m == 1) { - if (b) - tcout(TCBOLDFACEBEG); - if (s) - tcout(TCSTANDOUTBEG); - if (u) - tcout(TCUNDERLINEBEG); } } else break; @@ -1276,6 +1269,7 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) cc = 0; } if (dopr == 1) { + applytextattributes(0); if (ml == mlend - 1 && (cc % zterm_columns) == zterm_columns - 1) { dopr = 0; diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 97cc7d797..1a3e4c241 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -490,11 +490,7 @@ typedef struct { */ REFRESH_CHAR chr; /* - * Its attributes. 'On' attributes (TXT_ATTR_ON_MASK) are - * applied before the character, 'off' attributes (TXT_ATTR_OFF_MASK) - * after it. 'On' attributes are present for all characters that - * need the effect; 'off' attributes are only present for the - * last character in the sequence. + * Its attributes. */ zattr atr; } REFRESH_ELEMENT; diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 40b902901..39be33939 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1230,9 +1230,9 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) char *pptbuf; int pptlen; - pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL, - &pmpt_attr), + pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL), &pptlen); + pmpt_attr = txtcurrentattrs; write_loop(2, pptbuf, pptlen); free(pptbuf); return shingetline(); @@ -1267,10 +1267,11 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) fetchttyinfo = 0; trashedzle = 0; raw_lp = lp; - lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL, &pmpt_attr); + lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL); + pmpt_attr = txtcurrentattrs; raw_rp = rp; - rpmpt_attr = pmpt_attr; - rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL, &rpmpt_attr); + rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL); + rpmpt_attr = txtcurrentattrs; free_prepostdisplay(); zlereadflags = flags; @@ -2009,8 +2010,8 @@ reexpandprompt(void) char *new_lprompt, *new_rprompt; looping = reexpanding; - new_lprompt = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL, - &pmpt_attr); + new_lprompt = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL); + pmpt_attr = txtcurrentattrs; free(lpromptbuf); lpromptbuf = new_lprompt; @@ -2018,8 +2019,8 @@ reexpandprompt(void) continue; rpmpt_attr = pmpt_attr; - new_rprompt = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL, - &rpmpt_attr); + new_rprompt = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL); + rpmpt_attr = txtcurrentattrs; free(rpromptbuf); rpromptbuf = new_rprompt; } while (looping != reexpanding); diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 2db5f0642..ae8e5c109 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -208,7 +208,7 @@ int predisplaylen, postdisplaylen; * displayed on screen. */ -static zattr default_atr_on, special_atr_on; +static zattr default_attr, special_attr; /* * Array of region highlights, no special termination. @@ -245,12 +245,12 @@ char *tcout_func_name; int cost; # define SELECT_ADD_COST(X) (cost += X) -# define zputc(a) (zwcputc(a, NULL), cost++) +# define zputc(a) (zwcputc(a), cost++) # define zwrite(a, b) (zwcwrite((a), (b)), \ cost += ((b) * ZLE_CHAR_SIZE)) #else # define SELECT_ADD_COST(X) -# define zputc(a) zwcputc(a, NULL) +# define zputc(a) zwcputc(a) # define zwrite(a, b) zwcwrite((a), (b)) #endif @@ -316,14 +316,14 @@ static void zle_set_highlight(void) { char **atrs = getaparam("zle_highlight"); - int special_atr_on_set = 0; - int region_atr_on_set = 0; - int isearch_atr_on_set = 0; - int suffix_atr_on_set = 0; - int paste_atr_on_set = 0; + int special_attr_set = 0; + int region_attr_set = 0; + int isearch_attr_set = 0; + int suffix_attr_set = 0; + int paste_attr_set = 0; struct region_highlight *rhp; - special_atr_on = default_atr_on = 0; + special_attr = default_attr = 0; if (!region_highlights) { region_highlights = (struct region_highlight *) zshcalloc(N_SPECIAL_HIGHLIGHTS*sizeof(struct region_highlight)); @@ -340,41 +340,41 @@ zle_set_highlight(void) for (; *atrs; atrs++) { if (!strcmp(*atrs, "none")) { /* reset attributes for consistency... usually unnecessary */ - special_atr_on = default_atr_on = 0; - special_atr_on_set = 1; - paste_atr_on_set = region_atr_on_set = - isearch_atr_on_set = suffix_atr_on_set = 1; + special_attr = default_attr = 0; + special_attr_set = 1; + paste_attr_set = region_attr_set = + isearch_attr_set = suffix_attr_set = 1; } else if (strpfx("default:", *atrs)) { - match_highlight(*atrs + 8, &default_atr_on); + match_highlight(*atrs + 8, &default_attr); } else if (strpfx("special:", *atrs)) { - match_highlight(*atrs + 8, &special_atr_on); - special_atr_on_set = 1; + match_highlight(*atrs + 8, &special_attr); + special_attr_set = 1; } else if (strpfx("region:", *atrs)) { match_highlight(*atrs + 7, ®ion_highlights[0].atr); - region_atr_on_set = 1; + region_attr_set = 1; } else if (strpfx("isearch:", *atrs)) { match_highlight(*atrs + 8, &(region_highlights[1].atr)); - isearch_atr_on_set = 1; + isearch_attr_set = 1; } else if (strpfx("suffix:", *atrs)) { match_highlight(*atrs + 7, &(region_highlights[2].atr)); - suffix_atr_on_set = 1; + suffix_attr_set = 1; } else if (strpfx("paste:", *atrs)) { match_highlight(*atrs + 6, &(region_highlights[3].atr)); - paste_atr_on_set = 1; + paste_attr_set = 1; } } } /* Defaults */ - if (!special_atr_on_set) - special_atr_on = TXTSTANDOUT; - if (!region_atr_on_set) + if (!special_attr_set) + special_attr = TXTSTANDOUT; + if (!region_attr_set) region_highlights[0].atr = TXTSTANDOUT; - if (!isearch_atr_on_set) + if (!isearch_attr_set) region_highlights[1].atr = TXTUNDERLINE; - if (!suffix_atr_on_set) + if (!suffix_attr_set) region_highlights[2].atr = TXTBOLDFACE; - if (!paste_atr_on_set) + if (!paste_attr_set) region_highlights[3].atr = TXTSTANDOUT; allocate_colour_buffer(); @@ -571,22 +571,6 @@ unset_region_highlight(Param pm, int exp) } -/* The last attributes that were on. */ -static zattr lastatr; - -/* - * Clear the last attributes that we set: used when we're going - * to be outputting stuff that shouldn't show up as text. - */ -static void -clearattributes(void) -{ - if (lastatr) { - settextattributes(TXT_ATTR_OFF_FROM_ON(lastatr)); - lastatr = 0; - } -} - /* * Output a termcap capability, clearing any text attributes so * as not to mess up the display. @@ -595,7 +579,7 @@ clearattributes(void) static void tcoutclear(int cap) { - clearattributes(); + cleartextattributes(0); tcout(cap); } @@ -603,47 +587,20 @@ tcoutclear(int cap) * Output the character. This must come from the new video * buffer, nbuf, since we access the multiword buffer nmwbuf * directly. - * - * curatrp may be NULL, otherwise points to an integer specifying - * what attributes were turned on for a character output immediately - * before, in order to optimise output of attribute changes. */ /**/ void -zwcputc(const REFRESH_ELEMENT *c, zattr *curatrp) +zwcputc(const REFRESH_ELEMENT *c) { - /* - * Safety: turn attributes off if last heard of turned on. - * This differs from *curatrp, which is an optimisation for - * writing lots of stuff at once. - */ #ifdef MULTIBYTE_SUPPORT mbstate_t mbstate; int i; VARARR(char, mbtmp, MB_CUR_MAX + 1); #endif - if (lastatr & ~c->atr) { - /* Stuff on we don't want, turn it off */ - settextattributes(TXT_ATTR_OFF_FROM_ON(lastatr & ~c->atr)); - lastatr = 0; - } - - /* - * Don't output "on" attributes in a string of characters with - * the same attributes. Be careful in case a different colour - * needs setting. - */ - if ((c->atr & TXT_ATTR_ON_MASK) && - (!curatrp || - ((*curatrp & TXT_ATTR_ON_VALUES_MASK) != - (c->atr & TXT_ATTR_ON_VALUES_MASK)))) { - /* Record just the control flags we might need to turn off... */ - lastatr = c->atr & TXT_ATTR_ON_MASK; - /* ...but set including the values for colour attributes */ - settextattributes(c->atr & TXT_ATTR_ON_VALUES_MASK); - } + treplaceattrs(c->atr); + applytextattributes(0); #ifdef MULTIBYTE_SUPPORT if (c->atr & TXT_MULTIWORD_MASK) { @@ -664,35 +621,15 @@ zwcputc(const REFRESH_ELEMENT *c, zattr *curatrp) #else fputc(c->chr, shout); #endif - - /* - * Always output "off" attributes since we only turn off at - * the end of a chunk of highlighted text. - */ - if (c->atr & TXT_ATTR_OFF_MASK) { - settextattributes(c->atr & TXT_ATTR_OFF_MASK); - lastatr &= ~((c->atr & TXT_ATTR_OFF_MASK) >> TXT_ATTR_OFF_ON_SHIFT); - } - if (curatrp) { - /* - * Remember the current attributes: those that are turned - * on, less those that are turned off again. Include - * colour attributes here in case the colour changes to - * another non-default one. - */ - *curatrp = (c->atr & TXT_ATTR_ON_VALUES_MASK) & - ~((c->atr & TXT_ATTR_OFF_MASK) >> TXT_ATTR_OFF_ON_SHIFT); - } } static int zwcwrite(const REFRESH_STRING s, size_t i) { size_t j; - zattr curatr = 0; for (j = 0; j < i; j++) - zwcputc(s + j, &curatr); + zwcputc(s + j); return i; /* TODO something better for error indication */ } @@ -939,29 +876,6 @@ snextline(Rparams rpms) rpms->sen = rpms->s + winw; } - -/**/ -static void -settextattributes(zattr atr) -{ - if (txtchangeisset(atr, TXTNOBOLDFACE)) - tsetcap(TCALLATTRSOFF, 0); - if (txtchangeisset(atr, TXTNOSTANDOUT)) - tsetcap(TCSTANDOUTEND, 0); - if (txtchangeisset(atr, TXTNOUNDERLINE)) - tsetcap(TCUNDERLINEEND, 0); - if (txtchangeisset(atr, TXTBOLDFACE)) - tsetcap(TCBOLDFACEBEG, 0); - if (txtchangeisset(atr, TXTSTANDOUT)) - tsetcap(TCSTANDOUTBEG, 0); - if (txtchangeisset(atr, TXTUNDERLINE)) - tsetcap(TCUNDERLINEBEG, 0); - if (txtchangeisset(atr, TXTFGCOLOUR|TXTNOFGCOLOUR)) - set_colour_attribute(atr, COL_SEQ_FG, 0); - if (txtchangeisset(atr, TXTBGCOLOUR|TXTNOBGCOLOUR)) - set_colour_attribute(atr, COL_SEQ_BG, 0); -} - #ifdef MULTIBYTE_SUPPORT /* * Add a multiword glyph at the screen location base. @@ -1043,7 +957,6 @@ zrefresh(void) int tmppos; /* t - tmpline */ int tmpalloced; /* flag to free tmpline when finished */ int remetafy; /* flag that zle line is metafied */ - zattr txtchange; /* attributes set after prompts */ int rprompt_off = 1; /* Offset of rprompt from right of screen */ struct rparams rpms; #ifdef MULTIBYTE_SUPPORT @@ -1194,7 +1107,7 @@ zrefresh(void) tsetcap(TCALLATTRSOFF, 0); tsetcap(TCSTANDOUTEND, 0); tsetcap(TCUNDERLINEEND, 0); - txtattrmask = 0; + txtcurrentattrs = txtpendingattrs = txtunknownattrs = 0; if (trashedzle && !clearflag) reexpandprompt(); @@ -1219,8 +1132,8 @@ zrefresh(void) if (lpromptwof == winw) zputs("\n", shout); /* works with both hasam and !hasam */ } else { - txtchange = pmpt_attr; - settextattributes(txtchange); + treplaceattrs(pmpt_attr); + applytextattributes(0); } if (clearflag) { zputc(&zr_cr); @@ -1264,8 +1177,8 @@ zrefresh(void) rpms.sen = *nbuf + winw; for (t = tmpline, tmppos = 0; tmppos < tmpll; t++, tmppos++) { unsigned ireg; - zattr base_atr_on = default_atr_on, base_atr_off = 0; - zattr all_atr_on, all_atr_off; + zattr base_attr = default_attr; + zattr all_attr; struct region_highlight *rhp; /* * Calculate attribute based on region. @@ -1282,26 +1195,21 @@ zrefresh(void) tmppos < rhp->end + offset) { if (rhp->atr & (TXTFGCOLOUR|TXTBGCOLOUR)) { /* override colour with later entry */ - base_atr_on = (base_atr_on & ~TXT_ATTR_ON_VALUES_MASK) | - rhp->atr; + base_attr = rhp->atr; } else { /* no colour set yet */ - base_atr_on |= rhp->atr; + base_attr |= rhp->atr; } - if (tmppos == rhp->end + offset - 1 || - tmppos == tmpll - 1) - base_atr_off |= TXT_ATTR_OFF_FROM_ON(rhp->atr); } } - if (special_atr_on & (TXTFGCOLOUR|TXTBGCOLOUR)) { + if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) { /* keep colours from special attributes */ - all_atr_on = special_atr_on | - (base_atr_on & ~TXT_ATTR_COLOUR_ON_MASK); + all_attr = special_attr | + (base_attr & ~TXT_ATTR_COLOUR_MASK); } else { /* keep colours from standard attributes */ - all_atr_on = special_atr_on | base_atr_on; + all_attr = special_attr | base_attr; } - all_atr_off = TXT_ATTR_OFF_FROM_ON(all_atr_on); if (t == scs) /* if cursor is here, remember it */ rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln]; @@ -1319,10 +1227,9 @@ zrefresh(void) } else { do { rpms.s->chr = ZWC(' '); - rpms.s->atr = base_atr_on; + rpms.s->atr = base_attr; rpms.s++; } while ((++t0) & 7); - rpms.s[-1].atr |= base_atr_off; } } #ifdef MULTIBYTE_SUPPORT @@ -1341,11 +1248,9 @@ zrefresh(void) rpms.s->chr = ZWC(' '); if (!started) started = 1; - rpms.s->atr = all_atr_on; + rpms.s->atr = all_attr; rpms.s++; } while (rpms.s < rpms.sen); - if (started) - rpms.s[-1].atr |= all_atr_off; if (nextline(&rpms, 1)) break; if (t == scs) { @@ -1369,7 +1274,7 @@ zrefresh(void) * occurrence. */ rpms.s->chr = ZWC('?'); - rpms.s->atr = all_atr_on | all_atr_off; + rpms.s->atr = all_attr; rpms.s++; } else { /* We can fit it without reaching the end of the line. */ @@ -1377,7 +1282,7 @@ zrefresh(void) * As we don't actually output the WEOF, we attach * any off attributes to the character itself. */ - rpms.s->atr = base_atr_on | base_atr_off; + rpms.s->atr = base_attr; if (ichars > 1) { /* * Glyph includes combining characters. @@ -1393,7 +1298,7 @@ zrefresh(void) while (--width > 0) { rpms.s->chr = WEOF; /* Not used, but be consistent... */ - rpms.s->atr = base_atr_on | base_atr_off; + rpms.s->atr = base_attr; rpms.s++; } } @@ -1410,17 +1315,16 @@ zrefresh(void) #endif ) { /* other control character */ rpms.s->chr = ZWC('^'); - rpms.s->atr = all_atr_on; + rpms.s->atr = all_attr; rpms.s++; if (rpms.s == rpms.sen) { /* text wrapped */ - rpms.s[-1].atr |= all_atr_off; if (nextline(&rpms, 1)) break; } rpms.s->chr = (((unsigned int)*t & ~0x80u) > 31) ? ZWC('?') : (*t | ZWC('@')); - rpms.s->atr = all_atr_on | all_atr_off; + rpms.s->atr = all_attr; rpms.s++; } #ifdef MULTIBYTE_SUPPORT @@ -1432,7 +1336,6 @@ zrefresh(void) char dispchars[11]; char *dispptr = dispchars; wchar_t wc; - int started = 0; #ifdef __STDC_ISO_10646__ if (ZSH_INVALID_WCHAR_TEST(*t)) { @@ -1449,31 +1352,23 @@ zrefresh(void) if (mbtowc(&wc, dispptr, 1) == 1 /* paranoia */) { rpms.s->chr = wc; - if (!started) - started = 1; - rpms.s->atr = all_atr_on; + rpms.s->atr = all_attr; rpms.s++; if (rpms.s == rpms.sen) { /* text wrapped */ - if (started) { - rpms.s[-1].atr |= all_atr_off; - started = 0; - } if (nextline(&rpms, 1)) break; } } dispptr++; } - if (started) - rpms.s[-1].atr |= all_atr_off; if (*dispptr) /* nextline said stop processing */ break; } #else else { /* normal character */ rpms.s->chr = *t; - rpms.s->atr = base_atr_on | base_atr_off; + rpms.s->atr = base_attr; rpms.s++; } #endif @@ -1499,13 +1394,12 @@ zrefresh(void) if (statusline) { int outll, outsz; - zattr all_atr_on, all_atr_off; + zattr all_attr; char *statusdup = ztrdup(statusline); ZLE_STRING_T outputline = stringaszleline(statusdup, 0, &outll, &outsz, NULL); - all_atr_on = special_atr_on; - all_atr_off = TXT_ATTR_OFF_FROM_ON(all_atr_on); + all_attr = special_attr; rpms.tosln = rpms.ln + 1; nbuf[rpms.ln][winw + 1] = zr_zr; /* text not wrapped */ @@ -1525,7 +1419,7 @@ zrefresh(void) } if (width > rpms.sen - rpms.s) { rpms.s->chr = ZWC('?'); - rpms.s->atr = all_atr_on | all_atr_off; + rpms.s->atr = all_attr; rpms.s++; } else { rpms.s->chr = *u; @@ -1542,7 +1436,7 @@ zrefresh(void) #endif if (ZC_icntrl(*u)) { /* simplified processing in the status line */ rpms.s->chr = ZWC('^'); - rpms.s->atr = all_atr_on; + rpms.s->atr = all_attr; rpms.s++; if (rpms.s == rpms.sen) { nbuf[rpms.ln][winw + 1] = zr_nl;/* text wrapped */ @@ -1550,7 +1444,7 @@ zrefresh(void) } rpms.s->chr = (((unsigned int)*u & ~0x80u) > 31) ? ZWC('?') : (*u | ZWC('@')); - rpms.s->atr = all_atr_on | all_atr_off; + rpms.s->atr = all_attr; rpms.s++; } else { rpms.s->chr = *u; @@ -1725,7 +1619,6 @@ zrefresh(void) /* output the right-prompt if appropriate */ if (put_rpmpt && !iln && !oput_rpmpt) { - zattr attrchange; moveto(0, winw - rprompt_off - rpromptw); zputs(rpromptbuf, shout); @@ -1735,39 +1628,9 @@ zrefresh(void) zputc(&zr_cr); vcs = 0; } - /* reset character attributes to that set by the main prompt */ - txtchange = pmpt_attr; - /* - * Keep attributes that have actually changed, - * which are ones off in rpmpt_attr and on in - * pmpt_attr, and vice versa. - */ - attrchange = txtchange & - (TXT_ATTR_OFF_FROM_ON(rpmpt_attr) | - TXT_ATTR_ON_FROM_OFF(rpmpt_attr)); - /* - * Careful in case the colour changed. - */ - if (txtchangeisset(txtchange, TXTFGCOLOUR) && - (!txtchangeisset(rpmpt_attr, TXTFGCOLOUR) || - ((txtchange ^ rpmpt_attr) & TXT_ATTR_FG_COL_MASK))) - { - attrchange |= - txtchange & (TXTFGCOLOUR | TXT_ATTR_FG_COL_MASK); - } - if (txtchangeisset(txtchange, TXTBGCOLOUR) && - (!txtchangeisset(rpmpt_attr, TXTBGCOLOUR) || - ((txtchange ^ rpmpt_attr) & TXT_ATTR_BG_COL_MASK))) - { - attrchange |= - txtchange & (TXTBGCOLOUR | TXT_ATTR_BG_COL_MASK); - } - /* - * Now feed these changes into the usual function, - * if necessary. - */ - if (attrchange) - settextattributes(attrchange); + /* reset character attributes to that set by the main prompt */ + treplaceattrs(pmpt_attr); + applytextattributes(0); } } @@ -1782,8 +1645,8 @@ individually */ /* reset character attributes */ if (clearf && postedit) { - if ((txtchange = pmpt_attr ? pmpt_attr : rpmpt_attr)) - settextattributes(txtchange); + treplaceattrs(pmpt_attr ? pmpt_attr : rpmpt_attr); + applytextattributes(0); } clearf = 0; oput_rpmpt = put_rpmpt; @@ -1984,8 +1847,6 @@ refreshline(int ln) /* 3: main display loop - write out the buffer using whatever tricks we can */ for (;;) { - zattr now_off; - #ifdef MULTIBYTE_SUPPORT if ((!nl->chr || nl->chr != WEOF) && (!ol->chr || ol->chr != WEOF)) { #endif @@ -2087,7 +1948,7 @@ refreshline(int ln) * deletions, so turn off text attributes. */ if (first) { - clearattributes(); + cleartextattributes(0); first = 0; } tc_delchars(i); @@ -2176,13 +2037,8 @@ refreshline(int ln) break; do { #endif - /* - * If an attribute was on here but isn't any more, - * output the sequence to turn it off. - */ - now_off = ol->atr & ~nl->atr & TXT_ATTR_ON_MASK; - if (now_off) - settextattributes(TXT_ATTR_OFF_FROM_ON(now_off)); + treplaceattrs(nl->atr); + applytextattributes(0); /* * This is deliberately called if nl->chr is WEOF @@ -2560,8 +2416,8 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) for (t0 = 0; t0 < tmpll; t0++) { unsigned ireg; - zattr base_atr_on = 0, base_atr_off = 0; - zattr all_atr_on, all_atr_off; + zattr base_attr = 0; + zattr all_attr; struct region_highlight *rhp; /* * Calculate attribute based on region. @@ -2576,38 +2432,33 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) offset = predisplaylen; /* increment over it */ if (rhp->start + offset <= t0 && t0 < rhp->end + offset) { - if (base_atr_on & (TXTFGCOLOUR|TXTBGCOLOUR)) { + if (base_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) { /* keep colour already set */ - base_atr_on |= rhp->atr & ~TXT_ATTR_COLOUR_ON_MASK; + base_attr |= rhp->atr & ~TXT_ATTR_COLOUR_MASK; } else { /* no colour set yet */ - base_atr_on |= rhp->atr; + base_attr |= rhp->atr; } - if (t0 == rhp->end + offset - 1 || - t0 == tmpll - 1) - base_atr_off |= TXT_ATTR_OFF_FROM_ON(rhp->atr); } } - if (special_atr_on & (TXTFGCOLOUR|TXTBGCOLOUR)) { + if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) { /* keep colours from special attributes */ - all_atr_on = special_atr_on | - (base_atr_on & ~TXT_ATTR_COLOUR_ON_MASK); + all_attr = special_attr | + (base_attr & ~TXT_ATTR_COLOUR_MASK); } else { /* keep colours from standard attributes */ - all_atr_on = special_atr_on | base_atr_on; + all_attr = special_attr | base_attr; } - all_atr_off = TXT_ATTR_OFF_FROM_ON(all_atr_on); if (tmpline[t0] == ZWC('\t')) { for (*vp++ = zr_sp; (vp - vbuf) & 7; ) *vp++ = zr_sp; - vp[-1].atr |= base_atr_off; } else if (tmpline[t0] == ZWC('\n')) { vp->chr = ZWC('\\'); - vp->atr = all_atr_on; + vp->atr = all_attr; vp++; vp->chr = ZWC('n'); - vp->atr = all_atr_on | all_atr_off; + vp->atr = all_attr; vp++; #ifdef MULTIBYTE_SUPPORT } else if (WC_ISPRINT(tmpline[t0]) && @@ -2623,7 +2474,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) } } else ichars = 1; - vp->atr = base_atr_on | base_atr_off; + vp->atr = base_attr; if (ichars > 1) addmultiword(vp, tmpline+t0, ichars); else @@ -2631,7 +2482,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) vp++; while (--width > 0) { vp->chr = WEOF; - vp->atr = base_atr_on | base_atr_off; + vp->atr = base_attr; vp++; } t0 += ichars - 1; @@ -2644,11 +2495,11 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) ZLE_INT_T t = tmpline[++t0]; vp->chr = ZWC('^'); - vp->atr = all_atr_on; + vp->atr = all_attr; vp++; vp->chr = (((unsigned int)t & ~0x80u) > 31) ? ZWC('?') : (t | ZWC('@')); - vp->atr = all_atr_on | all_atr_off; + vp->atr = all_attr; vp++; } #ifdef MULTIBYTE_SUPPORT @@ -2656,7 +2507,6 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) char dispchars[11]; char *dispptr = dispchars; wchar_t wc; - int started = 0; if ((unsigned)tmpline[t0] > 0xffffU) { sprintf(dispchars, "<%.08x>", (unsigned)tmpline[t0]); @@ -2666,20 +2516,16 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) while (*dispptr) { if (mbtowc(&wc, dispptr, 1) == 1 /* paranoia */) { vp->chr = wc; - if (!started) - started = 1; - vp->atr = all_atr_on; + vp->atr = all_attr; vp++; } dispptr++; } - if (started) - vp[-1].atr |= all_atr_off; } #else else { vp->chr = tmpline[t0]; - vp->atr = base_atr_on | base_atr_off; + vp->atr = base_attr; vp++; } #endif diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index fdd168763..f94bfce3c 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -2426,7 +2426,7 @@ mod_export int printfmt(char *fmt, int n, int dopr, int doesc) { char *p = fmt, nc[DIGBUFSIZE]; - int l = 0, cc = 0, b = 0, s = 0, u = 0, m; + int l = 0, cc = 0; MB_METACHARINIT(); for (; *p; ) { @@ -2437,48 +2437,45 @@ printfmt(char *fmt, int n, int dopr, int doesc) if (idigit(*++p)) arg = zstrtol(p, &p, 10); if (*p) { - m = 0; switch (*p) { case '%': - if (dopr) + if (dopr) { + applytextattributes(0); putc('%', shout); + } cc++; break; case 'n': sprintf(nc, "%d", n); - if (dopr) + if (dopr) { + applytextattributes(0); fputs(nc, shout); + } cc += MB_METASTRWIDTH(nc); break; case 'B': - b = 1; if (dopr) - tcout(TCBOLDFACEBEG); + tsetattrs(TXTBOLDFACE); break; case 'b': - b = 0; m = 1; if (dopr) - tcout(TCALLATTRSOFF); + tunsetattrs(TXTBOLDFACE); break; case 'S': - s = 1; if (dopr) - tcout(TCSTANDOUTBEG); + tsetattrs(TXTSTANDOUT); break; case 's': - s = 0; m = 1; if (dopr) - tcout(TCSTANDOUTEND); + tunsetattrs(TXTSTANDOUT); break; case 'U': - u = 1; if (dopr) - tcout(TCUNDERLINEBEG); + tsetattrs(TXTUNDERLINE); break; case 'u': - u = 0; m = 1; if (dopr) - tcout(TCUNDERLINEEND); + tunsetattrs(TXTUNDERLINE); break; case 'F': case 'K': @@ -2491,18 +2488,19 @@ printfmt(char *fmt, int n, int dopr, int doesc) } else atr = match_colour(NULL, is_fg, arg); if (atr != TXT_ERROR) - set_colour_attribute(atr, is_fg ? COL_SEQ_FG : - COL_SEQ_BG, 0); + tsetattrs(atr); break; case 'f': - set_colour_attribute(TXTNOFGCOLOUR, COL_SEQ_FG, 0); + tunsetattrs(TXTFGCOLOUR); break; case 'k': - set_colour_attribute(TXTNOBGCOLOUR, COL_SEQ_BG, 0); + tunsetattrs(TXTBGCOLOUR); break; case '{': if (arg) cc += arg; + if (dopr) + applytextattributes(0); for (p++; *p && (*p != '%' || p[1] != '}'); p++) { if (*p == Meta) { p++; @@ -2518,14 +2516,6 @@ printfmt(char *fmt, int n, int dopr, int doesc) p--; break; } - if (dopr && m) { - if (b) - tcout(TCBOLDFACEBEG); - if (s) - tcout(TCSTANDOUTBEG); - if (u) - tcout(TCUNDERLINEBEG); - } } else break; p++; @@ -2533,6 +2523,7 @@ printfmt(char *fmt, int n, int dopr, int doesc) if (*p == '\n') { cc++; if (dopr) { + applytextattributes(0); if (tccan(TCCLEAREOL)) tcout(TCCLEAREOL); else { @@ -2551,6 +2542,7 @@ printfmt(char *fmt, int n, int dopr, int doesc) convchar_t cchar; int clen = MB_METACHARLENCONV(p, &cchar); if (dopr) { + applytextattributes(0); while (clen--) { if (*p == Meta) { p++; diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 2536e9faa..1a580a9e6 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -1250,7 +1250,7 @@ getzlequery(void) REFRESH_ELEMENT re; re.chr = c; re.atr = 0; - zwcputc(&re, NULL); + zwcputc(&re); } return c == ZWC('y'); } diff --git a/Src/builtin.c b/Src/builtin.c index 70a950666..4c295d11f 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4603,6 +4603,8 @@ bin_print(char *name, char **args, Options ops, int func) /* compute lengths, and interpret according to -P, -D, -e, etc. */ argc = arrlen(args); len = (int *) hcalloc(argc * sizeof(int)); + if (OPT_ISSET(ops, 'P')) + txtunknownattrs = TXT_ATTR_ALL; for (n = 0; n < argc; n++) { /* first \ sequences */ if (fmt || @@ -4633,7 +4635,7 @@ bin_print(char *name, char **args, Options ops, int func) */ char *str = unmetafy( promptexpand(metafy(args[n], len[n], META_NOALLOC), - 0, NULL, NULL, NULL), + 0, NULL, NULL), &len[n]); args[n] = dupstrpfx(str, len[n]); free(str); diff --git a/Src/init.c b/Src/init.c index 9981d059a..75ef2e094 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1654,8 +1654,7 @@ VA_DCL lp = va_arg(ap, char **); - pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL, - NULL), + pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL), &pptlen); write_loop(2, pptbuf, pptlen); free(pptbuf); diff --git a/Src/input.c b/Src/input.c index d55b05696..5a612669b 100644 --- a/Src/input.c +++ b/Src/input.c @@ -402,7 +402,7 @@ inputline(void) char *pptbuf; int pptlen; pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL, - 0, NULL, NULL, NULL), &pptlen); + 0, NULL, NULL), &pptlen); write_loop(2, pptbuf, pptlen); free(pptbuf); } diff --git a/Src/loop.c b/Src/loop.c index 88c55dd1a..7df379ecf 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -282,7 +282,7 @@ execselect(Estate state, UNUSED(int do_exec)) /* Keep any user interrupt error status */ errflag = oef | (errflag & ERRFLAG_INT); } else { - str = promptexpand(prompt3, 0, NULL, NULL, NULL); + str = promptexpand(prompt3, 0, NULL, NULL); zputs(str, stderr); free(str); fflush(stderr); diff --git a/Src/prompt.c b/Src/prompt.c index 3cb95039c..880194f87 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -30,10 +30,20 @@ #include "zsh.mdh" #include "prompt.pro" -/* text attribute mask */ +/* current text attributes */ /**/ -mod_export zattr txtattrmask; +mod_export zattr txtcurrentattrs; + +/* pending changes for attributes */ + +/**/ +mod_export zattr txtpendingattrs; + +/* mask of attributes with an unknown state */ + +/**/ +mod_export zattr txtunknownattrs; /* the command stack for use with %_ in prompts */ @@ -160,15 +170,11 @@ promptpath(char *p, int npath, int tilde) * between spacing and non-spacing parts of the prompt, and * Nularg, which (in a non-spacing sequence) indicates a * `glitch' space. - * - * txtchangep gives an integer controlling the attributes of - * the prompt. This is for use in zle to maintain the attributes - * consistently. Other parts of the shell should not need to use it. */ /**/ mod_export char * -promptexpand(char *s, int ns, char *rs, char *Rs, zattr *txtchangep) +promptexpand(char *s, int ns, char *rs, char *Rs) { struct buf_vars new_vars; @@ -212,7 +218,7 @@ promptexpand(char *s, int ns, char *rs, char *Rs, zattr *txtchangep) new_vars.bp1 = NULL; new_vars.truncwidth = 0; - putpromptchar(1, '\0', txtchangep); + putpromptchar(1, '\0'); addbufspc(2); if (new_vars.dontcount) *new_vars.bp++ = Outpar; @@ -253,7 +259,7 @@ parsecolorchar(zattr arg, int is_fg) *ep = '\0'; /* expand the contents of the argument so you can use * %v for example */ - coll = col = promptexpand(bv->fm, 0, NULL, NULL, NULL); + coll = col = promptexpand(bv->fm, 0, NULL, NULL); *ep = oc; arg = match_colour((const char **)&coll, is_fg, 0); free(col); @@ -278,7 +284,7 @@ parsecolorchar(zattr arg, int is_fg) /**/ static int -putpromptchar(int doprint, int endchar, zattr *txtchangep) +putpromptchar(int doprint, int endchar) { char *ss, *hostnam; int t0, arg, test, sep, j, numjobs, len; @@ -430,10 +436,9 @@ putpromptchar(int doprint, int endchar, zattr *txtchangep) /* Don't do the current truncation until we get back */ otruncwidth = bv->truncwidth; bv->truncwidth = 0; - if (!putpromptchar(test == 1 && doprint, sep, - txtchangep) || !*++bv->fm || - !putpromptchar(test == 0 && doprint, ')', - txtchangep)) { + if (!putpromptchar(test == 1 && doprint, sep) || + !*++bv->fm || + !putpromptchar(test == 0 && doprint, ')')) { bv->truncwidth = otruncwidth; return 0; } @@ -519,71 +524,57 @@ putpromptchar(int doprint, int endchar, zattr *txtchangep) unqueue_signals(); break; case 'S': - txtchangeset(txtchangep, TXTSTANDOUT, TXTNOSTANDOUT); - txtset(TXTSTANDOUT); - tsetcap(TCSTANDOUTBEG, TSC_PROMPT); + tsetattrs(TXTSTANDOUT); + applytextattributes(TSC_PROMPT); break; case 's': - txtchangeset(txtchangep, TXTNOSTANDOUT, TXTSTANDOUT); - txtunset(TXTSTANDOUT); - tsetcap(TCSTANDOUTEND, TSC_PROMPT|TSC_DIRTY); + tunsetattrs(TXTSTANDOUT); + applytextattributes(TSC_PROMPT); break; case 'B': - txtchangeset(txtchangep, TXTBOLDFACE, TXTNOBOLDFACE); - txtset(TXTBOLDFACE); - tsetcap(TCBOLDFACEBEG, TSC_PROMPT|TSC_DIRTY); + tsetattrs(TXTBOLDFACE); + applytextattributes(TSC_PROMPT); break; case 'b': - txtchangeset(txtchangep, TXTNOBOLDFACE, TXTBOLDFACE); - txtunset(TXTBOLDFACE); - tsetcap(TCALLATTRSOFF, TSC_PROMPT|TSC_DIRTY); + tunsetattrs(TXTBOLDFACE); + applytextattributes(TSC_PROMPT); break; case 'U': - txtchangeset(txtchangep, TXTUNDERLINE, TXTNOUNDERLINE); - txtset(TXTUNDERLINE); - tsetcap(TCUNDERLINEBEG, TSC_PROMPT); + tsetattrs(TXTUNDERLINE); + applytextattributes(TSC_PROMPT); break; case 'u': - txtchangeset(txtchangep, TXTNOUNDERLINE, TXTUNDERLINE); - txtunset(TXTUNDERLINE); - tsetcap(TCUNDERLINEEND, TSC_PROMPT|TSC_DIRTY); + tunsetattrs(TXTUNDERLINE); + applytextattributes(TSC_PROMPT); break; case 'F': atr = parsecolorchar(arg, 1); - if (!(atr & (TXT_ERROR | TXTNOFGCOLOUR))) { - txtchangeset(txtchangep, atr & TXT_ATTR_FG_ON_MASK, - TXTNOFGCOLOUR | TXT_ATTR_FG_COL_MASK); - txtunset(TXT_ATTR_FG_COL_MASK); - txtset(atr & TXT_ATTR_FG_ON_MASK); - set_colour_attribute(atr, COL_SEQ_FG, TSC_PROMPT); + if (atr && atr != TXT_ERROR) { + tsetattrs(atr); + applytextattributes(TSC_PROMPT); break; } /* else FALLTHROUGH */ case 'f': - txtchangeset(txtchangep, TXTNOFGCOLOUR, TXT_ATTR_FG_ON_MASK); - txtunset(TXT_ATTR_FG_ON_MASK); - set_colour_attribute(TXTNOFGCOLOUR, COL_SEQ_FG, TSC_PROMPT); + tunsetattrs(TXTFGCOLOUR); + applytextattributes(TSC_PROMPT); break; case 'K': atr = parsecolorchar(arg, 0); - if (!(atr & (TXT_ERROR | TXTNOBGCOLOUR))) { - txtchangeset(txtchangep, atr & TXT_ATTR_BG_ON_MASK, - TXTNOBGCOLOUR | TXT_ATTR_BG_COL_MASK); - txtunset(TXT_ATTR_BG_COL_MASK); - txtset(atr & TXT_ATTR_BG_ON_MASK); - set_colour_attribute(atr, COL_SEQ_BG, TSC_PROMPT); + if (atr && atr != TXT_ERROR) { + tsetattrs(atr); + applytextattributes(TSC_PROMPT); break; } /* else FALLTHROUGH */ case 'k': - txtchangeset(txtchangep, TXTNOBGCOLOUR, TXT_ATTR_BG_ON_MASK); - txtunset(TXT_ATTR_BG_ON_MASK); - set_colour_attribute(TXTNOBGCOLOUR, COL_SEQ_BG, TSC_PROMPT); + tunsetattrs(TXTBGCOLOUR); + applytextattributes(TSC_PROMPT); break; case '[': if (idigit(*++bv->fm)) arg = zstrtol(bv->fm, &bv->fm, 10); - if (!prompttrunc(arg, ']', doprint, endchar, txtchangep)) + if (!prompttrunc(arg, ']', doprint, endchar)) return *bv->fm; break; case '<': @@ -596,7 +587,7 @@ putpromptchar(int doprint, int endchar, zattr *txtchangep) if (arg <= 0) arg = 1; } - if (!prompttrunc(arg, *bv->fm, doprint, endchar, txtchangep)) + if (!prompttrunc(arg, *bv->fm, doprint, endchar)) return *bv->fm; break; case '{': /*}*/ @@ -1015,7 +1006,7 @@ tsetcap(int cap, int flags) { if (tccan(cap) && !isset(SINGLELINEZLE) && !(termflags & (TERM_NOUP|TERM_BAD|TERM_UNKNOWN))) { - switch (flags & TSC_OUTPUT_MASK) { + switch (flags) { case TSC_RAW: tputs(tcstr[cap], 1, putraw); break; @@ -1045,20 +1036,6 @@ tsetcap(int cap, int flags) } break; } - - if (flags & TSC_DIRTY) { - flags &= ~TSC_DIRTY; - if (txtisset(TXTBOLDFACE) && cap != TCBOLDFACEBEG) - tsetcap(TCBOLDFACEBEG, flags); - if (txtisset(TXTSTANDOUT)) - tsetcap(TCSTANDOUTBEG, flags); - if (txtisset(TXTUNDERLINE)) - tsetcap(TCUNDERLINEBEG, flags); - if (txtisset(TXTFGCOLOUR)) - set_colour_attribute(txtattrmask, COL_SEQ_FG, flags); - if (txtisset(TXTBGCOLOUR)) - set_colour_attribute(txtattrmask, COL_SEQ_BG, flags); - } } } @@ -1219,8 +1196,7 @@ countprompt(char *str, int *wp, int *hp, int overf) /**/ static int -prompttrunc(int arg, int truncchar, int doprint, int endchar, - zattr *txtchangep) +prompttrunc(int arg, int truncchar, int doprint, int endchar) { if (arg > 0) { char ch = *bv->fm, *ptr, *truncstr; @@ -1267,7 +1243,7 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar, w = bv->bp - bv->buf; bv->fm++; bv->trunccount = bv->dontcount; - putpromptchar(doprint, endchar, txtchangep); + putpromptchar(doprint, endchar); bv->trunccount = 0; ptr = bv->buf + w; /* putpromptchar() may have realloc()'d */ *bv->bp = '\0'; @@ -1547,7 +1523,7 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar, * With bv->truncwidth set to zero, we always reach endchar * * (or the terminating NULL) this time round. * */ - if (!putpromptchar(doprint, endchar, txtchangep)) + if (!putpromptchar(doprint, endchar)) return 0; } /* Now we have to trick it into matching endchar again */ @@ -1585,6 +1561,122 @@ cmdpop(void) cmdsp--; } +/* functions for handling attributes */ + +/**/ +mod_export void +applytextattributes(int flags) +{ + zattr change = txtcurrentattrs ^ txtpendingattrs; + zattr keepon = ~change & txtpendingattrs & TXT_ATTR_ALL; + zattr turnoff = change & ~txtpendingattrs & TXT_ATTR_ALL; + int keepcount, turncount = 0; + + /* bail out early if we wouldn't do anything */ + if (!change) + return; + + if (txtunknownattrs) { + txtunknownattrs &= ~change; /* changes cease to be unknown */ + /* can't turn unknown attrs back on so avoid wiping them */ + keepcount = 1; + } else { + /* If we want to turn off more attributes than we want to keep on + * then it takes fewer termcap sequences to just turn off all the + * attributes. */ + for (keepcount = 0; keepon; keepcount++) /* count bits */ + keepon &= keepon - 1; + for (; turnoff; turncount++) + turnoff &= turnoff - 1; + } + + if (keepcount < turncount || (change & ~txtpendingattrs & TXTBOLDFACE)) { + tsetcap(TCALLATTRSOFF, flags); + /* this cleared all attributes, may need to restore some */ + change = txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs; + txtunknownattrs = 0; + } else { + if (change & ~txtpendingattrs & TXTSTANDOUT) { + tsetcap(TCSTANDOUTEND, flags); + /* in some cases, that clears all attributes */ + change = (txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs) | + (TXTUNDERLINE & change); + } + if (change & ~txtpendingattrs & TXTUNDERLINE) { + tsetcap(TCUNDERLINEEND, flags); + /* in some cases, that clears all attributes */ + change = txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs; + } + } + if (change & txtpendingattrs & TXTBOLDFACE) + tsetcap(TCBOLDFACEBEG, flags); + if (change & txtpendingattrs & TXTSTANDOUT) + tsetcap(TCSTANDOUTBEG, flags); + if (change & txtpendingattrs & TXTUNDERLINE) + tsetcap(TCUNDERLINEBEG, flags); + + if (change & TXT_ATTR_FG_MASK) + set_colour_attribute(txtpendingattrs, COL_SEQ_FG, flags); + if (change & TXT_ATTR_BG_MASK) + set_colour_attribute(txtpendingattrs, COL_SEQ_BG, flags); + + txtcurrentattrs = txtpendingattrs; +} + +/**/ +mod_export void +cleartextattributes(int flags) +{ + treplaceattrs(0); + applytextattributes(flags); +} + +/**/ +mod_export void +treplaceattrs(zattr newattrs) +{ + if (txtunknownattrs) { + /* Set current attributes to the opposite of the new ones + * for any that are unknown so that applytextattributes() + * detects them as changed. */ + txtcurrentattrs &= ~txtunknownattrs; + txtcurrentattrs |= txtunknownattrs & ~newattrs; + } + + txtpendingattrs = newattrs; +} + +/**/ +mod_export void +tsetattrs(zattr newattrs) +{ + /* assume any unknown attributes that we're now setting were unset */ + txtcurrentattrs &= ~(newattrs & txtunknownattrs); + + txtpendingattrs |= newattrs & TXT_ATTR_ALL; + if (newattrs & TXTFGCOLOUR) { + txtpendingattrs &= ~TXT_ATTR_FG_MASK; + txtpendingattrs |= newattrs & TXT_ATTR_FG_MASK; + } + if (newattrs & TXTBGCOLOUR) { + txtpendingattrs &= ~TXT_ATTR_BG_MASK; + txtpendingattrs |= newattrs & TXT_ATTR_BG_MASK; + } +} + +/**/ +mod_export void +tunsetattrs(zattr newattrs) +{ + /* assume any unknown attributes that we're now unsetting were set */ + txtcurrentattrs |= newattrs & txtunknownattrs; + + txtpendingattrs &= ~(newattrs & TXT_ATTR_ALL); + if (newattrs & TXTFGCOLOUR) + txtpendingattrs &= ~TXT_ATTR_FG_MASK; + if (newattrs & TXTBGCOLOUR) + txtpendingattrs &= ~TXT_ATTR_BG_MASK; +} /***************************************************************************** * Utilities dealing with colour and other forms of highlighting. @@ -1607,7 +1699,7 @@ struct highlight { }; static const struct highlight highlights[] = { - { "none", 0, TXT_ATTR_ON_MASK }, + { "none", 0, TXT_ATTR_ALL }, { "bold", TXTBOLDFACE, 0 }, { "standout", TXTSTANDOUT, 0 }, { "underline", TXTUNDERLINE, 0 }, @@ -1645,8 +1737,8 @@ match_named_colour(const char **teststrp) * Match just the colour part of a highlight specification. * If teststrp is NULL, use the already parsed numeric colour. * Return the attributes to set in the attribute variable. - * Return -1 for out of range. Does not check the character - * following the colour specification. + * Return TXT_ERROR for out of range. Does not check the + * character following the colour specification. */ /**/ @@ -1693,10 +1785,8 @@ match_colour(const char **teststrp, int is_fg, int colour) } } else if ((named = ialpha(**teststrp))) { colour = match_named_colour(teststrp); - if (colour == 8) { - /* default */ - return is_fg ? TXTNOFGCOLOUR : TXTNOBGCOLOUR; - } + if (colour == 8) /* default */ + return 0; if (colour < 0) return TXT_ERROR; } @@ -2024,13 +2114,13 @@ set_colour_attribute(zattr atr, int fg_bg, int flags) if (fg_bg == COL_SEQ_FG) { colour = txtchangeget(atr, TXT_ATTR_FG_COL); tc = TCFGCOLOUR; - def = txtchangeisset(atr, TXTNOFGCOLOUR); - use_truecolor = txtchangeisset(atr, TXT_ATTR_FG_24BIT); + def = !(atr & TXTFGCOLOUR); + use_truecolor = atr & TXT_ATTR_FG_24BIT; } else { colour = txtchangeget(atr, TXT_ATTR_BG_COL); tc = TCBGCOLOUR; - def = txtchangeisset(atr, TXTNOBGCOLOUR); - use_truecolor = txtchangeisset(atr, TXT_ATTR_BG_24BIT); + def = !(atr & TXTBGCOLOUR); + use_truecolor = atr & TXT_ATTR_BG_24BIT; } /* Test if current zle_highlight settings are customized, or diff --git a/Src/subst.c b/Src/subst.c index b8e4023e1..897188862 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3716,6 +3716,8 @@ colonsubscript: if (presc) { int ops = opts[PROMPTSUBST], opb = opts[PROMPTBANG]; int opp = opts[PROMPTPERCENT]; + zattr savecurrent = txtcurrentattrs; + zattr saveunknown = txtunknownattrs; if (presc < 2) { opts[PROMPTPERCENT] = 1; @@ -3738,7 +3740,8 @@ colonsubscript: for (; *ap; ap++) { char *tmps; untokenize(*ap); - tmps = promptexpand(*ap, 0, NULL, NULL, NULL); + txtunknownattrs = TXT_ATTR_ALL; + tmps = promptexpand(*ap, 0, NULL, NULL); *ap = dupstring(tmps); free(tmps); } @@ -3747,10 +3750,14 @@ colonsubscript: if (!copied) val = dupstring(val), copied = 1; untokenize(val); - tmps = promptexpand(val, 0, NULL, NULL, NULL); + txtunknownattrs = TXT_ATTR_ALL; + tmps = promptexpand(val, 0, NULL, NULL); val = dupstring(tmps); free(tmps); } + + txtpendingattrs = txtcurrentattrs = savecurrent; + txtunknownattrs = saveunknown; opts[PROMPTSUBST] = ops; opts[PROMPTBANG] = opb; opts[PROMPTPERCENT] = opp; diff --git a/Src/utils.c b/Src/utils.c index 32492a93b..55f2d1ab0 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1543,7 +1543,8 @@ preprompt(void) if (!eolmark) eolmark = "%B%S%#%s%b"; opts[PROMPTPERCENT] = 1; - str = promptexpand(eolmark, 1, NULL, NULL, NULL); + txtunknownattrs = TXT_ATTR_ALL; + str = promptexpand(eolmark, 1, NULL, NULL); countprompt(str, &w, 0, -1); opts[PROMPTPERCENT] = percents; zputs(str, shout); @@ -1713,7 +1714,7 @@ printprompt4(void) opts[XTRACE] = 0; unmetafy(s, &l); s = unmetafy(promptexpand(metafy(s, l, META_NOALLOC), - 0, NULL, NULL, NULL), &l); + 0, NULL, NULL), &l); opts[XTRACE] = t; fprintf(xtrerr, "%s", s); @@ -3211,7 +3212,7 @@ spckword(char **s, int hist, int cmd, int ask) x = 'n'; } else if (shout) { char *pptbuf; - pptbuf = promptexpand(sprompt, 0, best, guess, NULL); + pptbuf = promptexpand(sprompt, 0, best, guess); zputs(pptbuf, shout); free(pptbuf); fflush(shout); diff --git a/Src/zsh.h b/Src/zsh.h index b035a1184..35ae033e3 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2681,25 +2681,8 @@ struct ttyinfo { #define TXTFGCOLOUR 0x0008 #define TXTBGCOLOUR 0x0010 -#define TXT_ATTR_ON_MASK 0x001F - -#define txtisset(X) (txtattrmask & (X)) -#define txtset(X) (txtattrmask |= (X)) -#define txtunset(X) (txtattrmask &= ~(X)) - -#define TXTNOBOLDFACE 0x0020 -#define TXTNOSTANDOUT 0x0040 -#define TXTNOUNDERLINE 0x0080 -#define TXTNOFGCOLOUR 0x0100 -#define TXTNOBGCOLOUR 0x0200 - -#define TXT_ATTR_OFF_MASK 0x03E0 -/* Bits to shift off right to get on */ -#define TXT_ATTR_OFF_ON_SHIFT 5 -#define TXT_ATTR_OFF_FROM_ON(attr) \ - (((attr) & TXT_ATTR_ON_MASK) << TXT_ATTR_OFF_ON_SHIFT) -#define TXT_ATTR_ON_FROM_OFF(attr) \ - (((attr) & TXT_ATTR_OFF_MASK) >> TXT_ATTR_OFF_ON_SHIFT) +#define TXT_ATTR_ALL 0x001F + /* * Indicates to zle_refresh.c that the character entry is an * index into the list of multiword symbols. @@ -2707,7 +2690,7 @@ struct ttyinfo { #define TXT_MULTIWORD_MASK 0x0400 /* used when, e.g an invalid colour is specified */ -#define TXT_ERROR 0x0800 +#define TXT_ERROR 0xF00000F000000800 /* Mask for colour to use in foreground */ #define TXT_ATTR_FG_COL_MASK 0x000000FFFFFF0000 @@ -2723,26 +2706,19 @@ struct ttyinfo { /* Flag to indicate that background is a 24-bit colour */ #define TXT_ATTR_BG_24BIT 0x8000 -/* Things to turn on, including values for the colour elements */ -#define TXT_ATTR_ON_VALUES_MASK \ - (TXT_ATTR_ON_MASK|TXT_ATTR_FG_COL_MASK|TXT_ATTR_BG_COL_MASK|\ - TXT_ATTR_FG_24BIT|TXT_ATTR_BG_24BIT) - /* Mask out everything to do with setting a foreground colour */ -#define TXT_ATTR_FG_ON_MASK \ +#define TXT_ATTR_FG_MASK \ (TXTFGCOLOUR|TXT_ATTR_FG_COL_MASK|TXT_ATTR_FG_24BIT) /* Mask out everything to do with setting a background colour */ -#define TXT_ATTR_BG_ON_MASK \ +#define TXT_ATTR_BG_MASK \ (TXTBGCOLOUR|TXT_ATTR_BG_COL_MASK|TXT_ATTR_BG_24BIT) /* Mask out everything to do with activating colours */ -#define TXT_ATTR_COLOUR_ON_MASK \ - (TXT_ATTR_FG_ON_MASK|TXT_ATTR_BG_ON_MASK) +#define TXT_ATTR_COLOUR_MASK \ + (TXT_ATTR_FG_MASK|TXT_ATTR_BG_MASK) -#define txtchangeisset(T,X) ((T) & (X)) #define txtchangeget(T,A) (((T) & A ## _MASK) >> A ## _SHIFT) -#define txtchangeset(T, X, Y) ((void)(T && (*T &= ~(Y), *T |= (X)))) /* * For outputting sequences to change colour: specify foreground @@ -2750,7 +2726,6 @@ struct ttyinfo { */ #define COL_SEQ_FG (0) #define COL_SEQ_BG (1) -#define COL_SEQ_COUNT (2) struct color_rgb { unsigned int red, green, blue; @@ -2766,11 +2741,7 @@ enum { /* Raw output: use stdout rather than shout */ TSC_RAW = 0x0001, /* Output to current prompt buffer: only used when assembling prompt */ - TSC_PROMPT = 0x0002, - /* Mask to get the output mode */ - TSC_OUTPUT_MASK = 0x0003, - /* Change needs reset of other attributes */ - TSC_DIRTY = 0x0004 + TSC_PROMPT = 0x0002 }; /****************************************/ diff --git a/Test/D01prompt.ztst b/Test/D01prompt.ztst index 6879e6fd1..a0abb7e1d 100644 --- a/Test/D01prompt.ztst +++ b/Test/D01prompt.ztst @@ -258,6 +258,19 @@ fi 0:Equivalence of terminal colour settings (background colour) + A1=${(%):-%s} + A2=${(%):-%u} + A3=${(%):-%s%u%s} + [[ $A3 = $A1$A2 && -n $A1 && -n $A2 ]] +0:Attribute optimisation - preserve initial disabling of attribute but drop useless later one + + : ${(%):-%K{blue}} + A1="${(%):-%b}x" + : ${(%):-%k} + A2="${(%):-%b}x" + [[ $A1 = $A2 && -n $A1 && -n $A2 ]] +0:Don't restore attributes from earlier substitution after disabling bold + (RPS1=foo; echo $RPS1 $RPROMPT) (RPS2=bar; echo $RPS2 $RPROMPT2) -fD:RPS1 and RPROMPT are aliases (regression from 5.0.6) (workers/49600) diff --git a/Test/X04zlehighlight.ztst b/Test/X04zlehighlight.ztst index f84c02505..6d9ca4a48 100644 --- a/Test/X04zlehighlight.ztst +++ b/Test/X04zlehighlight.ztst @@ -79,7 +79,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:region highlight - standout overlapping on other region_highlight entry ->0m27m24mtr7mu27me word2 word3 +>0m27m24mtr7mu0me word2 word3 zpty_start zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=green" ); }' @@ -90,7 +90,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:basic region_highlight with 8 colors ->0m27m24mCDE|32|trueCDE|39| +>0m27m24mCDE|32|true0m zpty_start zpty_input 'rh_widget() { region_highlight+=( "0 4 fg=green memo=someplugin" ); typeset -p region_highlight }' @@ -145,7 +145,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:basic region_highlight with true-color (hex-triplets) ->0m27m24m38;2;4;8;16mtrueCDE|39| +>0m27m24m38;2;4;8;16mtrue0m zpty_start zpty_input 'zmodload zsh/nearcolor' @@ -157,7 +157,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:basic region_highlight with near-color (hex-triplets at input) ->0m27m24mCDE|3232|trueCDE|39| +>0m27m24mCDE|3232|true0m zpty_start zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=green" ); rh2; }' @@ -169,7 +169,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:overlapping region_highlight with 8 colors ->0m27m24mCDE|32|tCDE|31|rCDE|39|CDE|32|ueCDE|39| +>0m27m24mCDE|32|tCDE|31|rCDE|32|ue0m zpty_start zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=#00cc00" ); rh2; }' @@ -181,7 +181,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:overlapping region_highlight with true-color ->0m27m24m38;2;0;204;0mt38;2;204;0;0mrCDE|39|38;2;0;204;0mueCDE|39| +>0m27m24m38;2;0;204;0mt38;2;204;0;0mr38;2;0;204;0mue0m zpty_start zpty_input 'zmodload zsh/nearcolor' @@ -194,7 +194,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:overlapping region_highlight with near-color (hex-triplets at input) ->0m27m24mCDE|340|tCDE|3160|rCDE|39|CDE|340|ueCDE|39| +>0m27m24mCDE|340|tCDE|3160|rCDE|340|ue0m zpty_start zpty_input 'f () { zle clear-screen; zle g -f nolast; BUFFER=": ${(q)LASTWIDGET}" }; zle -N f' -- cgit v1.2.3 From c01479a2ede78b9b53057322e4b9f5bd0a103a00 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Jan 2023 20:57:03 +0100 Subject: 51280: add support for italic and faint fonts in the line editor --- ChangeLog | 4 ++++ Doc/Zsh/zle.yo | 10 +++++++++- Src/Zle/zle_refresh.c | 26 +++----------------------- Src/init.c | 19 ++++++++++++++++++- Src/prompt.c | 39 ++++++++++++++++++++++++++++++++++++-- Src/zsh.h | 52 +++++++++++++++++++++++++++++---------------------- 6 files changed, 101 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3518f1bf..9e2938bf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-01-10 Oliver Kiddle + * 51280: Doc/Zsh/zle.yo, Src/Zle/zle_refresh.c, Src/init.c, + Src/prompt.c, Src/zsh.h: add support for italic and faint + fonts in the line editor + * 51258, 51272: Src/Modules/watch.c, Src/Zle/complist.c, Src/Zle/zle.h, Src/Zle/zle_main.c, Src/Zle/zle_refresh.c, Src/Zle/zle_tricky.c, Src/Zle/zle_utils.c, Src/builtin.c, diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 58700072a..60254e828 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -2780,9 +2780,13 @@ This works similarly to the foreground colour, except the background is not usually affected by the bold attribute. ) item(tt(bold))( -The characters in the given context are shown in a bold font. +The characters in the given context are shown with a bold font weight. Not all terminals distinguish bold fonts. ) +item(tt(faint))( +The characters in the given context are shown with a faint font weight. +Not all terminals distinguish faint fonts. +) item(tt(standout))( The characters in the given context are shown in the terminal's standout mode. The actual effect is specific to the terminal; on many terminals it @@ -2796,6 +2800,10 @@ The characters in the given context are shown underlined. Some terminals show the foreground in a different colour instead; in this case whitespace will not be highlighted. ) +item(tt(italic))( +The characters in the given context are shown in a italic font. +Not all terminals support italic fonts. +) enditem() The characters described above as `special' are as follows. The diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index ae8e5c109..d40400886 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -1193,23 +1193,10 @@ zrefresh(void) offset = predisplaylen; /* increment over it */ if (rhp->start + offset <= tmppos && tmppos < rhp->end + offset) { - if (rhp->atr & (TXTFGCOLOUR|TXTBGCOLOUR)) { - /* override colour with later entry */ - base_attr = rhp->atr; - } else { - /* no colour set yet */ - base_attr |= rhp->atr; - } + base_attr = mixattrs(rhp->atr, base_attr); } } - if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) { - /* keep colours from special attributes */ - all_attr = special_attr | - (base_attr & ~TXT_ATTR_COLOUR_MASK); - } else { - /* keep colours from standard attributes */ - all_attr = special_attr | base_attr; - } + all_attr = mixattrs(special_attr, base_attr); if (t == scs) /* if cursor is here, remember it */ rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln]; @@ -2441,14 +2428,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) } } } - if (special_attr & (TXTFGCOLOUR|TXTBGCOLOUR)) { - /* keep colours from special attributes */ - all_attr = special_attr | - (base_attr & ~TXT_ATTR_COLOUR_MASK); - } else { - /* keep colours from standard attributes */ - all_attr = special_attr | base_attr; - } + all_attr = mixattrs(special_attr, base_attr); if (tmpline[t0] == ZWC('\t')) { for (*vp++ = zr_sp; (vp - vbuf) & 7; ) diff --git a/Src/init.c b/Src/init.c index 75ef2e094..68621a0ad 100644 --- a/Src/init.c +++ b/Src/init.c @@ -747,7 +747,7 @@ init_shout(void) static char *tccapnams[TC_COUNT] = { "cl", "le", "LE", "nd", "RI", "up", "UP", "do", "DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta", - "md", "so", "us", "me", "se", "ue", "ch", + "md", "mh", "so", "us", "ZH", "me", "se", "ue", "ZR", "ch", "ku", "kd", "kl", "kr", "sc", "rc", "bc", "AF", "AB" }; @@ -872,6 +872,23 @@ init_term(void) /* The following is an attempt at a heuristic, * but it fails in some cases */ /* rprompt_indent = ((hasam && !hasbw) || hasye || !tccan(TCLEFT)); */ + + /* if there's no termcap entry for italics, use CSI 3 m */ + if (!tccan(TCITALICSBEG)) { + zsfree(tcstr[TCITALICSBEG]); + tcstr[TCITALICSBEG] = ztrdup("\033[3m"); + tclen[TCITALICSBEG] = 4; + } + if (!tccan(TCITALICSEND)) { + zsfree(tcstr[TCITALICSEND]); + tcstr[TCITALICSEND] = ztrdup("\033[23m"); + tclen[TCITALICSEND] = 5; + } + if (!tccan(TCFAINTBEG)) { + zsfree(tcstr[TCFAINTBEG]); + tcstr[TCFAINTBEG] = ztrdup("\033[2m"); + tclen[TCFAINTBEG] = 4; + } } return 1; } diff --git a/Src/prompt.c b/Src/prompt.c index 880194f87..488a90d09 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1590,7 +1590,15 @@ applytextattributes(int flags) turnoff &= turnoff - 1; } - if (keepcount < turncount || (change & ~txtpendingattrs & TXTBOLDFACE)) { + /* enabling bold can be relied upon to disable faint + * (the converse not so as that commonly does nothing at all) */ + if (txtcurrentattrs & TXTFAINT && txtpendingattrs & TXTBOLDFACE) { + --turncount; + change &= ~TXTFAINT; + } + + if (keepcount < turncount || + (change & ~txtpendingattrs & TXT_ATTR_FONT_WEIGHT)) { tsetcap(TCALLATTRSOFF, flags); /* this cleared all attributes, may need to restore some */ change = txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs; @@ -1607,13 +1615,19 @@ applytextattributes(int flags) /* in some cases, that clears all attributes */ change = txtpendingattrs & TXT_ATTR_ALL & ~txtunknownattrs; } + if (change & ~txtpendingattrs & TXTITALIC) + tsetcap(TCITALICSEND, flags); } if (change & txtpendingattrs & TXTBOLDFACE) tsetcap(TCBOLDFACEBEG, flags); + if (change & txtpendingattrs & TXTFAINT) + tsetcap(TCFAINTBEG, flags); if (change & txtpendingattrs & TXTSTANDOUT) tsetcap(TCSTANDOUTBEG, flags); if (change & txtpendingattrs & TXTUNDERLINE) tsetcap(TCUNDERLINEBEG, flags); + if (change & txtpendingattrs & TXTITALIC) + tsetcap(TCITALICSBEG, flags); if (change & TXT_ATTR_FG_MASK) set_colour_attribute(txtpendingattrs, COL_SEQ_FG, flags); @@ -1678,6 +1692,25 @@ tunsetattrs(zattr newattrs) txtpendingattrs &= ~TXT_ATTR_BG_MASK; } +/* Merge two attribute sets. In an case where attributes might conflict + * choose those from the first parameter. Foreground and background + * colours are taken together - less likely to end up with unreadable + * combinations. */ + +/**/ +mod_export zattr +mixattrs(zattr primary, zattr secondary) +{ + zattr result = secondary; + /* take colours from primary */ + if (primary & (TXTFGCOLOUR|TXTBGCOLOUR)) + result &= ~TXT_ATTR_COLOUR_MASK; + /* take font weight from primary */ + if (primary & TXT_ATTR_FONT_WEIGHT) + result &= ~TXT_ATTR_FONT_WEIGHT; + return result | primary; +} + /***************************************************************************** * Utilities dealing with colour and other forms of highlighting. * @@ -1700,9 +1733,11 @@ struct highlight { static const struct highlight highlights[] = { { "none", 0, TXT_ATTR_ALL }, - { "bold", TXTBOLDFACE, 0 }, + { "bold", TXTBOLDFACE, TXTFAINT }, + { "faint", TXTFAINT, TXTBOLDFACE }, { "standout", TXTSTANDOUT, 0 }, { "underline", TXTUNDERLINE, 0 }, + { "italic", TXTITALIC, 0 }, { NULL, 0, 0 } }; diff --git a/Src/zsh.h b/Src/zsh.h index 35ae033e3..e834c7e06 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2646,22 +2646,25 @@ struct ttyinfo { #define TCDELLINE 16 #define TCNEXTTAB 17 #define TCBOLDFACEBEG 18 -#define TCSTANDOUTBEG 19 -#define TCUNDERLINEBEG 20 -#define TCALLATTRSOFF 21 -#define TCSTANDOUTEND 22 -#define TCUNDERLINEEND 23 -#define TCHORIZPOS 24 -#define TCUPCURSOR 25 -#define TCDOWNCURSOR 26 -#define TCLEFTCURSOR 27 -#define TCRIGHTCURSOR 28 -#define TCSAVECURSOR 29 -#define TCRESTRCURSOR 30 -#define TCBACKSPACE 31 -#define TCFGCOLOUR 32 -#define TCBGCOLOUR 33 -#define TC_COUNT 34 +#define TCFAINTBEG 19 +#define TCSTANDOUTBEG 20 +#define TCUNDERLINEBEG 21 +#define TCITALICSBEG 22 +#define TCALLATTRSOFF 23 +#define TCSTANDOUTEND 24 +#define TCUNDERLINEEND 25 +#define TCITALICSEND 27 +#define TCHORIZPOS 27 +#define TCUPCURSOR 28 +#define TCDOWNCURSOR 29 +#define TCLEFTCURSOR 30 +#define TCRIGHTCURSOR 31 +#define TCSAVECURSOR 32 +#define TCRESTRCURSOR 33 +#define TCBACKSPACE 34 +#define TCFGCOLOUR 35 +#define TCBGCOLOUR 36 +#define TC_COUNT 37 #define tccan(X) (tclen[X]) @@ -2676,12 +2679,14 @@ struct ttyinfo { #endif #define TXTBOLDFACE 0x0001 -#define TXTSTANDOUT 0x0002 -#define TXTUNDERLINE 0x0004 -#define TXTFGCOLOUR 0x0008 -#define TXTBGCOLOUR 0x0010 +#define TXTFAINT 0x0002 +#define TXTSTANDOUT 0x0004 +#define TXTUNDERLINE 0x0008 +#define TXTITALIC 0x0010 +#define TXTFGCOLOUR 0x0020 +#define TXTBGCOLOUR 0x0040 -#define TXT_ATTR_ALL 0x001F +#define TXT_ATTR_ALL 0x007F /* * Indicates to zle_refresh.c that the character entry is an @@ -2690,7 +2695,10 @@ struct ttyinfo { #define TXT_MULTIWORD_MASK 0x0400 /* used when, e.g an invalid colour is specified */ -#define TXT_ERROR 0xF00000F000000800 +#define TXT_ERROR 0xF00000F000000003 + +/* Mask for font weight */ +#define TXT_ATTR_FONT_WEIGHT (TXTBOLDFACE|TXTFAINT) /* Mask for colour to use in foreground */ #define TXT_ATTR_FG_COL_MASK 0x000000FFFFFF0000 -- cgit v1.2.3 From 9d99a01367e85dc3d9cd8e711d78dc1cec6f018b Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Jan 2023 21:02:16 +0100 Subject: 51281: keep track of attributes left on at the end of left and right prompts and reapply them explicitly as appropriate --- ChangeLog | 4 ++++ Src/Zle/zle_main.c | 7 ++++++- Src/Zle/zle_refresh.c | 41 ++++++++++++++++------------------------- Src/zsh.h | 3 ++- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e2938bf8..9aac1d59b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-01-10 Oliver Kiddle + * 51281: Src/Zle/zle_main.c, Src/Zle/zle_refresh.c, Src/zsh.h: + keep track of attributes left on at the end of left and right + prompts and reapply them explicitly as appropriate + * 51280: Doc/Zsh/zle.yo, Src/Zle/zle_refresh.c, Src/init.c, Src/prompt.c, Src/zsh.h: add support for italic and faint fonts in the line editor diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 39be33939..686c6f5b4 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1267,11 +1267,13 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) fetchttyinfo = 0; trashedzle = 0; raw_lp = lp; + txtcurrentattrs = txtpendingattrs = txtunknownattrs = 0; lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL); pmpt_attr = txtcurrentattrs; raw_rp = rp; rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL); rpmpt_attr = txtcurrentattrs; + prompt_attr = mixattrs(pmpt_attr, rpmpt_attr); free_prepostdisplay(); zlereadflags = flags; @@ -2010,6 +2012,7 @@ reexpandprompt(void) char *new_lprompt, *new_rprompt; looping = reexpanding; + txtcurrentattrs = txtpendingattrs = txtunknownattrs = 0; new_lprompt = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL); pmpt_attr = txtcurrentattrs; free(lpromptbuf); @@ -2018,9 +2021,9 @@ reexpandprompt(void) if (looping != reexpanding) continue; - rpmpt_attr = pmpt_attr; new_rprompt = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL); rpmpt_attr = txtcurrentattrs; + prompt_attr = mixattrs(pmpt_attr, rpmpt_attr); free(rpromptbuf); rpromptbuf = new_rprompt; } while (looping != reexpanding); @@ -2067,6 +2070,8 @@ trashzle(void) zrefresh(); showinglist = sl; moveto(nlnct, 0); + treplaceattrs(prompt_attr); + applytextattributes(0); if (clearflag && tccan(TCCLEAREOD)) { tcout(TCCLEAREOD); clearflag = listshown = 0; diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index d40400886..ab84a1376 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -149,7 +149,7 @@ char *lpromptbuf, *rpromptbuf; /* Text attributes after displaying prompts */ /**/ -zattr pmpt_attr, rpmpt_attr; +zattr pmpt_attr, rpmpt_attr, prompt_attr; /* number of lines displayed */ @@ -254,13 +254,13 @@ int cost; # define zwrite(a, b) zwcwrite((a), (b)) #endif -static const REFRESH_ELEMENT zr_cr = { ZWC('\r'), 0 }; +static const REFRESH_ELEMENT zr_cr = { ZWC('\r'), TXT_ERROR }; #ifdef MULTIBYTE_SUPPORT -static const REFRESH_ELEMENT zr_dt = { ZWC('.'), 0 }; +static const REFRESH_ELEMENT zr_dt = { ZWC('.'), TXT_ERROR }; #endif -static const REFRESH_ELEMENT zr_nl = { ZWC('\n'), 0 }; -static const REFRESH_ELEMENT zr_sp = { ZWC(' '), 0 }; -static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), 0 }; +static const REFRESH_ELEMENT zr_nl = { ZWC('\n'), TXT_ERROR }; +static const REFRESH_ELEMENT zr_sp = { ZWC(' '), TXT_ERROR }; +static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), TXT_ERROR }; /* * Constant arrays to be copied into place: these are memcpy'd, @@ -599,8 +599,10 @@ zwcputc(const REFRESH_ELEMENT *c) VARARR(char, mbtmp, MB_CUR_MAX + 1); #endif - treplaceattrs(c->atr); - applytextattributes(0); + if (c->atr != TXT_ERROR) { + treplaceattrs(c->atr); + applytextattributes(0); + } #ifdef MULTIBYTE_SUPPORT if (c->atr & TXT_MULTIWORD_MASK) { @@ -1131,9 +1133,8 @@ zrefresh(void) zputs(lpromptbuf, shout); if (lpromptwof == winw) zputs("\n", shout); /* works with both hasam and !hasam */ - } else { - treplaceattrs(pmpt_attr); - applytextattributes(0); + /* lpromptbuf includes literal escapes so we need to update for it */ + txtcurrentattrs = txtpendingattrs = pmpt_attr; } if (clearflag) { zputc(&zr_cr); @@ -1177,7 +1178,7 @@ zrefresh(void) rpms.sen = *nbuf + winw; for (t = tmpline, tmppos = 0; tmppos < tmpll; t++, tmppos++) { unsigned ireg; - zattr base_attr = default_attr; + zattr base_attr = mixattrs(default_attr, prompt_attr); zattr all_attr; struct region_highlight *rhp; /* @@ -1265,10 +1266,6 @@ zrefresh(void) rpms.s++; } else { /* We can fit it without reaching the end of the line. */ - /* - * As we don't actually output the WEOF, we attach - * any off attributes to the character itself. - */ rpms.s->atr = base_attr; if (ichars > 1) { /* @@ -1606,8 +1603,9 @@ zrefresh(void) /* output the right-prompt if appropriate */ if (put_rpmpt && !iln && !oput_rpmpt) { - moveto(0, winw - rprompt_off - rpromptw); + treplaceattrs(pmpt_attr); + applytextattributes(0); zputs(rpromptbuf, shout); if (rprompt_off) { vcs = winw - rprompt_off; @@ -1615,9 +1613,7 @@ zrefresh(void) zputc(&zr_cr); vcs = 0; } - /* reset character attributes to that set by the main prompt */ - treplaceattrs(pmpt_attr); - applytextattributes(0); + txtcurrentattrs = txtpendingattrs = rpmpt_attr; } } @@ -1630,11 +1626,6 @@ individually */ refreshline(iln); } -/* reset character attributes */ - if (clearf && postedit) { - treplaceattrs(pmpt_attr ? pmpt_attr : rpmpt_attr); - applytextattributes(0); - } clearf = 0; oput_rpmpt = put_rpmpt; diff --git a/Src/zsh.h b/Src/zsh.h index e834c7e06..073f8b71b 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2694,7 +2694,8 @@ struct ttyinfo { */ #define TXT_MULTIWORD_MASK 0x0400 -/* used when, e.g an invalid colour is specified */ +/* Used when, e.g an invalid colour is specified. Also used in REFRESH_ELEMENT + * to indicate that attributes should remain unchanged. */ #define TXT_ERROR 0xF00000F000000003 /* Mask for font weight */ -- cgit v1.2.3 From cc672f1c3bfa9cdf4bbf100d85439340a479cb6b Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Jan 2023 21:06:55 +0100 Subject: 51289: don't disable non-colour attributes in prompts for SINGLE_LINE_ZLE and remove superfluous extra escapes to disable attributes --- ChangeLog | 4 ++++ Src/Zle/zle_refresh.c | 2 -- Src/prompt.c | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9aac1d59b..c3bc7b6e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-01-10 Oliver Kiddle + * 51289: Src/Zle/zle_refresh.c, Src/prompt.c: don't disable + non-colour attributes in prompts for SINGLE_LINE_ZLE and remove + superfluous extra escapes to disable attributes + * 51281: Src/Zle/zle_main.c, Src/Zle/zle_refresh.c, Src/zsh.h: keep track of attributes left on at the end of left and right prompts and reapply them explicitly as appropriate diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index ab84a1376..8949a851c 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -1107,8 +1107,6 @@ zrefresh(void) #endif /* we probably should only have explicitly set attributes */ tsetcap(TCALLATTRSOFF, 0); - tsetcap(TCSTANDOUTEND, 0); - tsetcap(TCUNDERLINEEND, 0); txtcurrentattrs = txtpendingattrs = txtunknownattrs = 0; if (trashedzle && !clearflag) diff --git a/Src/prompt.c b/Src/prompt.c index 488a90d09..4f29a6728 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1004,8 +1004,7 @@ stradd(char *d) mod_export void tsetcap(int cap, int flags) { - if (tccan(cap) && !isset(SINGLELINEZLE) && - !(termflags & (TERM_NOUP|TERM_BAD|TERM_UNKNOWN))) { + if (tccan(cap) && !(termflags & (TERM_NOUP|TERM_BAD|TERM_UNKNOWN))) { switch (flags) { case TSC_RAW: tputs(tcstr[cap], 1, putraw); -- cgit v1.2.3 From 498b771a821c9ca7f77b9f64789dfdfb79fd0631 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Jan 2023 21:09:54 +0100 Subject: 51290: fix display of control characters with SINGLE_LINE_ZLE set --- ChangeLog | 3 +++ Src/Zle/zle_refresh.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c3bc7b6e6..1ed133a71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-01-10 Oliver Kiddle + * 51290: Src/Zle/zle_refresh.c: fix display of control + characters with SINGLE_LINE_ZLE set + * 51289: Src/Zle/zle_refresh.c, Src/prompt.c: don't disable non-colour attributes in prompts for SINGLE_LINE_ZLE and remove superfluous extra escapes to disable attributes diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 8949a851c..b196370dc 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -2419,6 +2419,8 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) } all_attr = mixattrs(special_attr, base_attr); + if (t0 == tmpcs) + nvcs = vp - vbuf; if (tmpline[t0] == ZWC('\t')) { for (*vp++ = zr_sp; (vp - vbuf) & 7; ) *vp++ = zr_sp; @@ -2461,7 +2463,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) && (unsigned)tmpline[t0] <= 0xffU #endif ) { - ZLE_INT_T t = tmpline[++t0]; + ZLE_INT_T t = tmpline[t0]; vp->chr = ZWC('^'); vp->atr = all_attr; @@ -2498,8 +2500,6 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) vp++; } #endif - if (t0 == tmpcs) - nvcs = vp - vbuf - 1; } if (t0 == tmpcs) nvcs = vp - vbuf; -- cgit v1.2.3 From be2c91bbc3361398a18ea4b77d493dded0a60e79 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Jan 2023 21:13:52 +0100 Subject: 51291: support for highlighting ellipses in the line editor --- ChangeLog | 3 +++ Doc/Zsh/zle.yo | 3 +++ Src/Zle/zle_refresh.c | 60 ++++++++++++++++++++++++++++++--------------------- Src/prompt.c | 3 +++ 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ed133a71..e1d81845b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-01-10 Oliver Kiddle + * 51291: Doc/Zsh/zle.yo, Src/Zle/zle_refresh.c, Src/prompt.c: + support for highlighting ellipses in the line editor + * 51290: Src/Zle/zle_refresh.c: fix display of control characters with SINGLE_LINE_ZLE set diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 60254e828..c622483d7 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -2691,6 +2691,9 @@ for different completions. item(tt(paste))( Following a command to paste text, the characters that were inserted. ) +item(tt(ellipsis))( +Markers used to indicate where the text doesn't fit within the terminal. +) enditem() When tt(region_highlight) is set, the contexts that describe a region DASH()- diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index b196370dc..a587f696a 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -203,12 +203,12 @@ int predisplaylen, postdisplaylen; /* - * Attributes used by default on the command line, and - * attributes for highlighting special (unprintable) characters - * displayed on screen. + * Attributes used by default on the command line, + * for highlighting special (unprintable) characters displayed on screen, + * and for ellipsis continuation markers. */ -static zattr default_attr, special_attr; +static zattr default_attr, special_attr, ellipsis_attr; /* * Array of region highlights, no special termination. @@ -259,8 +259,8 @@ static const REFRESH_ELEMENT zr_cr = { ZWC('\r'), TXT_ERROR }; static const REFRESH_ELEMENT zr_dt = { ZWC('.'), TXT_ERROR }; #endif static const REFRESH_ELEMENT zr_nl = { ZWC('\n'), TXT_ERROR }; -static const REFRESH_ELEMENT zr_sp = { ZWC(' '), TXT_ERROR }; -static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), TXT_ERROR }; +static const REFRESH_ELEMENT zr_sp = { ZWC(' '), 0 }; +static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), 0 }; /* * Constant arrays to be copied into place: these are memcpy'd, @@ -269,10 +269,10 @@ static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), TXT_ERROR }; static const REFRESH_ELEMENT zr_end_ellipsis[] = { { ZWC(' '), 0 }, { ZWC('<'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, { ZWC(' '), 0 }, }; #define ZR_END_ELLIPSIS_SIZE \ @@ -281,16 +281,16 @@ static const REFRESH_ELEMENT zr_end_ellipsis[] = { static const REFRESH_ELEMENT zr_mid_ellipsis1[] = { { ZWC(' '), 0 }, { ZWC('<'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, }; #define ZR_MID_ELLIPSIS1_SIZE \ ((int)(sizeof(zr_mid_ellipsis1)/sizeof(zr_mid_ellipsis1[0]))) static const REFRESH_ELEMENT zr_mid_ellipsis2[] = { - { ZWC('>'), 0 }, + { ZWC('>'), TXT_ERROR }, { ZWC(' '), 0 }, }; #define ZR_MID_ELLIPSIS2_SIZE \ @@ -298,10 +298,10 @@ static const REFRESH_ELEMENT zr_mid_ellipsis2[] = { static const REFRESH_ELEMENT zr_start_ellipsis[] = { { ZWC('>'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, }; #define ZR_START_ELLIPSIS_SIZE \ ((int)(sizeof(zr_start_ellipsis)/sizeof(zr_start_ellipsis[0]))) @@ -321,6 +321,7 @@ zle_set_highlight(void) int isearch_attr_set = 0; int suffix_attr_set = 0; int paste_attr_set = 0; + int ellipsis_attr_set = 0; struct region_highlight *rhp; special_attr = default_attr = 0; @@ -361,6 +362,9 @@ zle_set_highlight(void) } else if (strpfx("paste:", *atrs)) { match_highlight(*atrs + 6, &(region_highlights[3].atr)); paste_attr_set = 1; + } else if (strpfx("ellipsis:", *atrs)) { + match_highlight(*atrs + 9, &ellipsis_attr); + ellipsis_attr_set = 1; } } } @@ -376,6 +380,9 @@ zle_set_highlight(void) region_highlights[2].atr = TXTBOLDFACE; if (!paste_attr_set) region_highlights[3].atr = TXTSTANDOUT; + if (!ellipsis_attr_set) + ellipsis_attr = TXTBGCOLOUR | ((zattr) 3 << TXT_ATTR_BG_COL_SHIFT) | + TXTFGCOLOUR | ((zattr) 4 << TXT_ATTR_FG_COL_SHIFT); allocate_colour_buffer(); } @@ -599,10 +606,8 @@ zwcputc(const REFRESH_ELEMENT *c) VARARR(char, mbtmp, MB_CUR_MAX + 1); #endif - if (c->atr != TXT_ERROR) { - treplaceattrs(c->atr); - applytextattributes(0); - } + treplaceattrs(c->atr); + applytextattributes(0); #ifdef MULTIBYTE_SUPPORT if (c->atr & TXT_MULTIWORD_MASK) { @@ -1479,6 +1484,7 @@ zrefresh(void) } #endif ZR_memcpy(rpms.sen, zr_end_ellipsis, ZR_END_ELLIPSIS_SIZE); + rpms.sen[1].atr = ellipsis_attr; #ifdef MULTIBYTE_SUPPORT /* Extend to the end if we backed off for a wide character */ if (extra_ellipsis) { @@ -1514,6 +1520,7 @@ zrefresh(void) } #endif ZR_memcpy(rpms.sen, zr_mid_ellipsis1, ZR_MID_ELLIPSIS1_SIZE); + rpms.sen[1].atr = ellipsis_attr; rpms.sen += ZR_MID_ELLIPSIS1_SIZE; #ifdef MULTIBYTE_SUPPORT /* Extend if we backed off for a wide character */ @@ -1523,6 +1530,7 @@ zrefresh(void) } #endif ZR_memcpy(rpms.sen, zr_mid_ellipsis2, ZR_MID_ELLIPSIS2_SIZE); + rpms.sen[1].atr = prompt_attr; nbuf[rpms.tosln][winw] = nbuf[rpms.tosln][winw + 1] = zr_zr; } @@ -1555,7 +1563,9 @@ zrefresh(void) t0 = winw - lpromptw; t0 = t0 > ZR_START_ELLIPSIS_SIZE ? ZR_START_ELLIPSIS_SIZE : t0; ZR_memcpy(nbuf[0] + lpromptw, zr_start_ellipsis, t0); + (*nbuf + lpromptw)->atr = ellipsis_attr; ZR_memset(nbuf[0] + lpromptw + t0, zr_sp, winw - t0 - lpromptw); + (*nbuf + lpromptw + t0)->atr = prompt_attr; nbuf[0][winw] = nbuf[0][winw + 1] = zr_zr; } @@ -2514,11 +2524,11 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) } if (winpos) { vbuf[winpos].chr = ZWC('<'); /* line continues to the left */ - vbuf[winpos].atr = 0; + vbuf[winpos].atr = ellipsis_attr; } if ((int)ZR_strlen(vbuf + winpos) > (winw - hasam)) { vbuf[winpos + winw - hasam - 1].chr = ZWC('>'); /* line continues to right */ - vbuf[winpos + winw - hasam - 1].atr = 0; + vbuf[winpos + winw - hasam - 1].atr = ellipsis_attr; vbuf[winpos + winw - hasam] = zr_zr; } ZR_strcpy(nbuf[0], vbuf + winpos); diff --git a/Src/prompt.c b/Src/prompt.c index 4f29a6728..39fcf5eb7 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1648,6 +1648,9 @@ cleartextattributes(int flags) mod_export void treplaceattrs(zattr newattrs) { + if (newattrs == TXT_ERROR) + return; + if (txtunknownattrs) { /* Set current attributes to the opposite of the new ones * for any that are unknown so that applytextattributes() -- cgit v1.2.3 From b513ca21c8aff35c76bb9b1cb30a9644e936833a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Jan 2023 21:17:24 +0100 Subject: 51292: fix dynamic updates of region_highlight to account for PREDISPLAY --- ChangeLog | 3 +++ Src/Zle/zle_utils.c | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1d81845b..ddee8700e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-01-10 Oliver Kiddle + * 51292: Src/Zle/zle_utils.c: fix dynamic updates of + region_highlight to account for PREDISPLAY + * 51291: Doc/Zsh/zle.yo, Src/Zle/zle_refresh.c, Src/prompt.c: support for highlighting ellipses in the line editor diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 1a580a9e6..45a82dd5e 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -866,13 +866,13 @@ shiftchars(int to, int cnt) if (rhp->start_meta - sub > to + cnt) rhp->start_meta -= cnt; else - rhp->start_meta = to; + rhp->start_meta = to + sub; } if (rhp->end_meta - sub > to) { if (rhp->end_meta - sub > to + cnt) rhp->end_meta -= cnt; else - rhp->end_meta = to; + rhp->end_meta = to + sub; } } } @@ -896,13 +896,13 @@ shiftchars(int to, int cnt) if (rhp->start - sub > to + cnt) rhp->start -= cnt; else - rhp->start = to; + rhp->start = to + sub; } if (rhp->end - sub > to) { if (rhp->end - sub > to + cnt) rhp->end -= cnt; else - rhp->end = to; + rhp->end = to + sub; } } } -- cgit v1.2.3 From 246b7c75055654dcc6186db1c4d52724dc522aa2 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 11 Jan 2023 15:58:45 +0100 Subject: 51295: where the end of a region coincides with the end of PREDISPLAY, don't extend it to include new text Also fix issue where an int was used for a copy of attributes which breaks if int is smaller than zattr. --- ChangeLog | 5 +++++ Src/Zle/zle_utils.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ddee8700e..628fdcc63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-01-11 Oliver Kiddle + + * 51295: Src/Zle/zle_utils.c: where the end of a region coincides + with the end of PREDISPLAY, don't extend it to include new text + 2023-01-10 Oliver Kiddle * 51292: Src/Zle/zle_utils.c: fix dynamic updates of diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 45a82dd5e..9ce91049c 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -580,7 +580,7 @@ struct zle_region; struct zle_region { struct zle_region *next; /* Entries of region_highlight, as needed */ - int atr; + zattr atr; int start; int end; int flags; @@ -799,7 +799,7 @@ spaceinline(int ct) if (rhp->start_meta - sub >= zlemetacs) { rhp->start_meta += ct; } - if (rhp->end_meta - sub >= zlemetacs) { + if (rhp->end_meta - sub >= zlemetacs && (!predisplaylen || zlecs)) { rhp->end_meta += ct; } } @@ -827,7 +827,7 @@ spaceinline(int ct) if (rhp->start - sub >= zlecs) { rhp->start += ct; } - if (rhp->end - sub >= zlecs) { + if (rhp->end - sub >= zlecs && (!predisplaylen || zlecs)) { rhp->end += ct; } } -- cgit v1.2.3 From e2a39513dcff152fdfe1d966c0eb3156cce260b6 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 11 Jan 2023 16:05:06 +0100 Subject: unposted: mention attributes changes, fix renumbering mistake and allow completion to offer prompt escapes for PROMPT_EOL_MARK --- ChangeLog | 4 ++++ Completion/Zsh/Type/_ps1234 | 2 +- NEWS | 6 ++++++ Src/zsh.h | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 628fdcc63..7213bf5f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-01-11 Oliver Kiddle + * unposted: NEWS, Src/zsh.h, Completion/Zsh/Type/_ps1234: mention + attributes changes, fix renumbering mistake and allow completion + to offer prompt escapes for PROMPT_EOL_MARK + * 51295: Src/Zle/zle_utils.c: where the end of a region coincides with the end of PREDISPLAY, don't extend it to include new text diff --git a/Completion/Zsh/Type/_ps1234 b/Completion/Zsh/Type/_ps1234 index 0ea2cdda9..07dea5905 100644 --- a/Completion/Zsh/Type/_ps1234 +++ b/Completion/Zsh/Type/_ps1234 @@ -1,4 +1,4 @@ -#compdef -value-,PROMPT,-default- -value-,PROMPT2,-default- -value-,PROMPT3,-default- -value-,PROMPT4,-default- -value-,RPROMPT,-default- -value-,RPROMPT2,-default- -value-,PS1,-default- -value-,PS2,-default- -value-,PS3,-default- -value-,PS4,-default- -value-,RPS1,-default- -value-,RPS2,-default- -value-,SPROMPT,-default- +#compdef -value-,PROMPT,-default- -value-,PROMPT2,-default- -value-,PROMPT3,-default- -value-,PROMPT4,-default- -value-,RPROMPT,-default- -value-,RPROMPT2,-default- -value-,PS1,-default- -value-,PS2,-default- -value-,PS3,-default- -value-,PS4,-default- -value-,RPS1,-default- -value-,RPS2,-default- -value-,SPROMPT,-default- -value-,PROMPT_EOL_MARK,-default- local -a specs ccol local expl grp cols bs suf pre changed=1 ret=1 diff --git a/NEWS b/NEWS index e3a16a8bc..0e726699f 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,12 @@ Note also the list of incompatibilities in the README file. Changes since 5.9 ----------------- +In region_highlight and zle_highlight, italic and faint can be +specified as font attributes for terminals that support them. + +Ellipsis markers shown by the line editor to indicate where the line +doesn't fit in the terminal can be highlighted. + The ERR_EXIT and ERR_RETURN options were refined to be more self- consistent and better aligned with the POSIX-2017 specification of `set -e`. For details on what exactly changed, see the list of diff --git a/Src/zsh.h b/Src/zsh.h index 073f8b71b..f82e76e4b 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2653,7 +2653,7 @@ struct ttyinfo { #define TCALLATTRSOFF 23 #define TCSTANDOUTEND 24 #define TCUNDERLINEEND 25 -#define TCITALICSEND 27 +#define TCITALICSEND 26 #define TCHORIZPOS 27 #define TCUPCURSOR 28 #define TCDOWNCURSOR 29 -- cgit v1.2.3 From 3a08f682885b1d83b6b573e2f1c0122ec5b6f5db Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Tue, 27 Dec 2022 17:49:50 +0100 Subject: 51256: Add --refetch to completions of git-fetch --- ChangeLog | 3 +++ Completion/Unix/Command/_git | 1 + 2 files changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7213bf5f0..d6475c3a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-01-11 Oliver Kiddle + * Jörg Sommer: 51256: Completion/Unix/Command/_git: + Add --refetch to completions of git-fetch + * unposted: NEWS, Src/zsh.h, Completion/Zsh/Type/_ps1234: mention attributes changes, fix renumbering mistake and allow completion to offer prompt escapes for PROMPT_EOL_MARK diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 6a1c4158a..14fa01436 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -890,6 +890,7 @@ _git-fetch () { '(--all -m --multiple)'{-m,--multiple}'[fetch from multiple remotes]' \ '(-n --no-tags -t --tags)'{-n,--no-tags}'[disable automatic tag following]' \ '--prefetch[modify the refspec to place all refs within refs/prefetch/]' \ + '--refetch[fetch all objects as a fresh clone would]' \ '(-P --prune-tags)'{-P,--prune-tags}'[prune local tags no longer on remote and clobber changed tags]' \ '--write-fetch-head[write fetched references to the FETCH_HEAD file]' \ "--negotiate-only[don't fetch a packfile; instead, print ancestors of negotiation tips]" \ -- cgit v1.2.3 From 857bc4343b9215bcf6ac2761cbdd0a11fcd4d010 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 11 Jan 2023 18:41:10 +0100 Subject: 51297: update expected test results to match more optimised escape sequences with recent changes --- ChangeLog | 3 +++ Test/X04zlehighlight.ztst | 16 ++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index d6475c3a2..23baf278b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-01-11 Oliver Kiddle + * 51297: Test/X04zlehighlight.ztst: update expected test results + to match more optimised escape sequences with recent changes + * Jörg Sommer: 51256: Completion/Unix/Command/_git: Add --refetch to completions of git-fetch diff --git a/Test/X04zlehighlight.ztst b/Test/X04zlehighlight.ztst index 6d9ca4a48..296635bf5 100644 --- a/Test/X04zlehighlight.ztst +++ b/Test/X04zlehighlight.ztst @@ -79,7 +79,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:region highlight - standout overlapping on other region_highlight entry ->0m27m24mtr7mu0me word2 word3 +>0mtr7mu0me word2 word3 zpty_start zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=green" ); }' @@ -90,7 +90,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:basic region_highlight with 8 colors ->0m27m24mCDE|32|true0m +>0mCDE|32|true zpty_start zpty_input 'rh_widget() { region_highlight+=( "0 4 fg=green memo=someplugin" ); typeset -p region_highlight }' @@ -145,7 +145,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:basic region_highlight with true-color (hex-triplets) ->0m27m24m38;2;4;8;16mtrue0m +>0m38;2;4;8;16mtrue zpty_start zpty_input 'zmodload zsh/nearcolor' @@ -157,7 +157,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:basic region_highlight with near-color (hex-triplets at input) ->0m27m24mCDE|3232|true0m +>0mCDE|3232|true zpty_start zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=green" ); rh2; }' @@ -169,7 +169,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:overlapping region_highlight with 8 colors ->0m27m24mCDE|32|tCDE|31|rCDE|32|ue0m +>0mCDE|32|tCDE|31|rCDE|32|ue zpty_start zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=#00cc00" ); rh2; }' @@ -181,7 +181,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:overlapping region_highlight with true-color ->0m27m24m38;2;0;204;0mt38;2;204;0;0mr38;2;0;204;0mue0m +>0m38;2;0;204;0mt38;2;204;0;0mr38;2;0;204;0mue zpty_start zpty_input 'zmodload zsh/nearcolor' @@ -194,7 +194,7 @@ zpty_line 1 p # the line of interest, preserving escapes ("p") zpty_stop 0:overlapping region_highlight with near-color (hex-triplets at input) ->0m27m24mCDE|340|tCDE|3160|rCDE|340|ue0m +>0mCDE|340|tCDE|3160|rCDE|340|ue zpty_start zpty_input 'f () { zle clear-screen; zle g -f nolast; BUFFER=": ${(q)LASTWIDGET}" }; zle -N f' @@ -205,7 +205,7 @@ zpty_line 1 p zpty_stop 0:zle $widgetname -f nolast ->0m27m24m0m27m24m: clear-screen +>0m0m: clear-screen %clean -- cgit v1.2.3 From 03292bceecba1ca39745f82fe37f321d08b138e4 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 16 Jan 2023 11:10:02 +0000 Subject: 51278: make (i) subscript flag for zero-length string consistent --- ChangeLog | 6 ++++++ Src/params.c | 2 +- Test/D06subscript.ztst | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 23baf278b..69ea1ab53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-01-16 Peter Stephenson + + * 51278: Src/params.c, Test/D06subscript.ztst: result of (i) + subscript flag with zero-length string was inconsistent with + other cases. + 2023-01-11 Oliver Kiddle * 51297: Test/X04zlehighlight.ztst: update expected test results diff --git a/Src/params.c b/Src/params.c index 2e4a6eae2..6362b382c 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1669,7 +1669,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, /* Searching characters */ int slen; d = getstrvalue(v); - if (!d || !*d) + if (!d) return 0; /* * beg and len are character counts, not raw offsets. diff --git a/Test/D06subscript.ztst b/Test/D06subscript.ztst index 21127e641..57cdc027c 100644 --- a/Test/D06subscript.ztst +++ b/Test/D06subscript.ztst @@ -299,3 +299,12 @@ F:In math, (($i)) should be the same as ((i)), see workers/47748. echo ${string[(pws:\0:)1]} 0:Word splitting by NUL >foo + + string="a" + print ${string[(i)x]} + string="" + print ${string[(i)x]} +0:Can check off end of zero length string +F:Regression test for inconsistency of failed (i) on zero-length string +>2 +>1 -- cgit v1.2.3 From f93ad02b94bd18c96a0861506127e3a246fb8eec Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 21 Jan 2023 19:18:15 -0800 Subject: 51310: zle -F handlers preserve LASTWIDGET Also fix email address in an old ChangeLog entry --- ChangeLog | 6 +++++- Src/Zle/zle_main.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 69ea1ab53..2143d9fcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-01-21 Bart Schaefer + + * 51310: Src/Zle/zle_main.c: zle -F handlers preserve LASTWIDGET + 2023-01-16 Peter Stephenson * 51278: Src/params.c, Test/D06subscript.ztst: result of (i) @@ -627,7 +631,7 @@ * 49960: Doc/Zsh/compsys.yo: Sort lists in zshcompsys. -2022-04-05 Bart Schaefer +2022-04-05 Bart Schaefer * 49994: Src/glob.c: Single-byte equivalence of users/22601 and workers/40891 for matching against zero-length strings diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 686c6f5b4..cfa0a739d 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -737,6 +737,7 @@ raw_getbyte(long do_keytmout, char *cptr, int full) ) { /* Handle the fd. */ char *fdbuf; + Thingy save_lbindk = lbindk; { char buf[BDIGBUFSIZE]; convbase(buf, lwatch_fd->fd, 10); @@ -779,6 +780,7 @@ raw_getbyte(long do_keytmout, char *cptr, int full) */ errtry = 1; } + lbindk = save_lbindk; } } /* Function may have invalidated the display. */ -- cgit v1.2.3 From 37569049f092a841047413709cd39b2480211ecc Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 21 Jan 2023 19:21:30 -0800 Subject: 51313: fix "git rerere forget" completion --- ChangeLog | 2 ++ Completion/Unix/Command/_git | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2143d9fcb..3ceb2aa73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-01-21 Bart Schaefer + * 51313: Completion/Unix/Command/_git: fix "git rerere forget" + * 51310: Src/Zle/zle_main.c: zle -F handlers preserve LASTWIDGET 2023-01-16 Peter Stephenson diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 14fa01436..b3ed7b5c8 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -4259,14 +4259,14 @@ _git-rerere () { _arguments -C -S -s $endopt \ '--rerere-autoupdate[register clean resolutions in index]' \ - ': :->command' && ret=0 + ': :->command' \ + '*: :{ [[ $words[CURRENT-1] = forget ]] && __git_cached_files }' && ret=0 case $state in (command) - # TODO: This isn't optimal, as forget get confused. _values command \ 'clear[reset metadata used by rerere]' \ - 'forget[resets metadata used by rerere for specific conflict]: :__git_cached_files' \ + 'forget[resets metadata used by rerere for specific conflict]' \ 'diff[output diffs for the current state of the resolution]' \ 'status[print paths with conflicts whose merge resolution rerere will record]' \ 'remaining[print paths with conflicts that have not been autoresolved by rerere]' \ -- cgit v1.2.3 From f54ed0b76a07f21c96ddf5b51dc46d9e8b74e41c Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Thu, 19 Jan 2023 10:48:24 +0900 Subject: 51322 (+ minor tweak): Update gnu make completion for version 4.4 Add `--jobserver-style`, `--shuffle` and `--trace` options And delete '--warn-undefined-functions' option. This option was implemented only in redhat's older make and the official gnu make has never supported it. --- ChangeLog | 5 +++++ Completion/Unix/Command/_make | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ceb2aa73..8e71f1ced 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-01-22 Shohei YOSHIDA + + * 51322 (+ minor tweak): Completion/Unix/Command/_make: Update gnu + make completion for version 4.4 + 2023-01-21 Bart Schaefer * 51313: Completion/Unix/Command/_git: fix "git rerere forget" diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make index 510368e8b..d5ec6423d 100644 --- a/Completion/Unix/Command/_make +++ b/Completion/Unix/Command/_make @@ -176,26 +176,28 @@ _make() { '(-i --ignore-errors)'{-i,--ignore-errors}'[ignore errors from recipes]' '*'{-I,--include-dir=}'[search specified directory for included makefiles]:search path for included makefile:->dir' '(-j --jobs)'{-j+,--jobs=}'[allow specified number of parallel jobs; unlimited jobs with no arg]:: : _guard "[0-9]#" "number of jobs"' + '--jobserver-style=[select the style of jobserver to use]:style:(fifo pipe sem)' '(-k --keep-going)'{-k,--keep-going}"[keep going when some targets can't be made]" '(-l --load-average --max-load)'{-l,--load-average=,--max-load}"[don't start multiple jobs unless load is below specified value]:load" '(-L --check-symlink-times)'{-L,--check-symlink-times}'[use the latest mtime between symlinks and target]' '(-n --just-print --dry-run --recon)'{-n,--just-print,--dry-run,--recon}"[don't actually run any recipe; just print them]" '*'{-o,--old-file=,--assume-old=}"[consider specified file to be old and don't remake it]:file not to remake:->file" '(-O --output-sync)'{-O-,--output-sync=-}'[synchronize output of parallel jobs]::granularity for grouping output:compadd -E 0 none line target recurse' - '(-p --print-data-base)'{-p,--print-data-base}'[print makes internal database]' + '(-p --print-data-base)'{-p,--print-data-base}"[print make's internal database]" '(-q --question)'{-q,--question}'[run no recipe; exit status says if up to date]' '(-r --no-builtin-rules)'{-r,--no-builtin-rules}'[disable the built-in implicit rules]' + '--shuffle=-[perform shuffle of prerequisites and goals]::seed (integer) or mode:(random reverse none)' '(-R --no-builtin-variables)'{-R,--no-builtin-variables}'[disable the built-in variable settings]' '(-s --silent --quiet)'{-s,--silent,--quiet}"[don't echo recipes]" '--no-silent[echo recipes (disable --silent mode)]' '(-S --no-keep-going --stop)'{-S,--no-keep-going,--stop}'[turns off -k]' '(-t --touch)'{-t,--touch}'[touch targets instead of remaking them]' + '--trace[print tracing information]' '(- *)'{-v,--version}'[print the version number of make and exit]' '(-w --print-directory)'{-w,--print-directory}'[print the current directory]' '--no-print-directory[turn off -w, even if it was turned on implicitly]' '*'{-W,--what-if=,--new-file=,--assume-new=}'[consider specified file to be infinitely new]:file to treat as modified:->file' '--warn-undefined-variables[warn when an undefined variable is referenced]' - '--warn-undefined-functions[warn when an undefined user function is called]' ) else # Basic make options only. -- cgit v1.2.3 From ba834fa53c4f6919eebd4b5feee69f720ffe3e7e Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 24 Jan 2023 11:08:32 +0900 Subject: 51326: Improve -fsanitize option completion - Support comma separated completion - Accept multiple `-fsanitize` options --- ChangeLog | 5 +++++ Completion/Unix/Command/_gcc | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8e71f1ced..2bbddeccc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-01-24 Shohei YOSHIDA + + * 51326: Completion/Unix/Command/_gcc: Improve -fsanitize + option completion + 2023-01-22 Shohei YOSHIDA * 51322 (+ minor tweak): Completion/Unix/Command/_make: Update gnu diff --git a/Completion/Unix/Command/_gcc b/Completion/Unix/Command/_gcc index f10000391..8690c5599 100644 --- a/Completion/Unix/Command/_gcc +++ b/Completion/Unix/Command/_gcc @@ -1894,7 +1894,7 @@ args+=( '-freschedule-modulo-scheduled-loops[enable/disable the traditional scheduling in loops that already passed modulo scheduling]' '-frounding-math[disable optimizations that assume default FP rounding behavior]' '-frtti[generate run time type descriptor information]' - "-fsanitize=-[enable AddressSanitizer, a memory error detector]:style:($sanitizers)" + "*-fsanitize=-[enable AddressSanitizer, a memory error detector]:style:->sanitize" '-fsched2-use-superblocks[if scheduling post reload, do superblock scheduling]' '-fsched-critical-path-heuristic[enable the critical path heuristic in the scheduler]' '-fsched-dep-count-heuristic[enable the dependent count heuristic in the scheduler]' @@ -2284,6 +2284,9 @@ archgeneric) arch+=(generic) _wanted cputypes expl "CPU type" compadd -a arch && ret=0 ;; +sanitize) + _values -s , 'sanitizer' $sanitizers + ;; esac return ret -- cgit v1.2.3 From 9a75555b0fd41f54767ee683b667e9df377500b2 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 27 Jan 2023 15:08:52 +0000 Subject: unposted: Fix typo in an X-Seq number in an old ChangeLog entry --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2bbddeccc..4d18c597b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8770,7 +8770,7 @@ g 2016-12-10 Barton E. Schaefer - * 40134: Src/builtin.c, Src/Zle/compmatch.c: silence spurious + * 40143: Src/builtin.c, Src/Zle/compmatch.c: silence spurious compiler warnings. 2016-12-10 Daniel Shahaf -- cgit v1.2.3 From f264fcde80a7ba2b687a1b94d567c48bbdf3423d Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Wed, 25 Jan 2023 14:48:38 +0900 Subject: 51330: Update python3 completion for version 3.11 --- ChangeLog | 5 +++++ Completion/Unix/Command/_python | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4d18c597b..6a7af6eed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-01-27 Shohei YOSHIDA + + * 51330: Completion/Unix/Command/_python: Update python3 + completion for version 3.11 + 2023-01-24 Shohei YOSHIDA * 51326: Completion/Unix/Command/_gcc: Improve -fsanitize diff --git a/Completion/Unix/Command/_python b/Completion/Unix/Command/_python index 2711b8fd3..6e209a199 100644 --- a/Completion/Unix/Command/_python +++ b/Completion/Unix/Command/_python @@ -1,7 +1,7 @@ #compdef -P python[0-9.]# # Python 2.7 -# Python 3.9 +# Python 3.11 local curcontext="$curcontext" state state_descr line _compskip="$_compskip" typeset -A opt_args @@ -12,7 +12,11 @@ if _pick_variant python3=Python\ 3 python2 --version; then '(-bb)-b[issue warnings about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str]' '(-b)-bb[issue errors about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str]' '--check-hash-based-pycs[configure how Python evaluates up-to-dateness of hash-based .pyc files]:mode:(always default never)' + '--help-env[print help about Python environment variables and exit]' + '--help-xoptions[print help about implementation-specific -X options and exit]' + '--help-all[print complete help information and exit]' "-I[isolate Python from the user's environment]" + '-P[do not prepend a potentially unsafe path to sys.path]' '-q[do not print version and copyright messages]' '-X[set implementation-specific option]:option' ) -- cgit v1.2.3 From 096e72ce78ac9fb6fa944261d6cc386f6d067326 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 27 Jan 2023 18:42:20 +0000 Subject: unposted (cribbed from users/28784 by Roman): Add XFail tests for substituting a single-quoting backslash. --- ChangeLog | 6 ++++++ Test/D04parameter.ztst | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6a7af6eed..44b24c534 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-01-27 Daniel Shahaf + + * unposted (cribbed from users/28784 by Roman): + Test/D04parameter.ztst: Add XFail tests for substituting a + single-quoting backslash. + 2023-01-27 Shohei YOSHIDA * 51330: Completion/Unix/Command/_python: Update python3 diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 6bf55b4db..29275f13f 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2727,3 +2727,18 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888 1:parameter expansion flags parsing error gives a clue ?(eval):1: error in flags near position 7 in '${(zZ+x+):-}' + slash='/' + print -r -- x${slash/'/'}y +-Df:(users/28784) substituting a single-quoted backslash, part #1: slash +>xy + + single_quote="'" + print -r -- x${single_quote/'/'}y +-Df:(users/28784) substituting a single-quoted backslash, part #2: single quote +>x/y + + control="foobar" + print -r -- x${control/'bar'}y +0:(users/28784 inspired this) substituting a single-quoted backslash, part #3: control +>xfooy + -- cgit v1.2.3 From 88ccf2be1e3ba70608e69639c8929254ff01fcc8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 31 Jan 2023 17:08:57 -0800 Subject: 51337: parameter attributes cross-reference typeset equivalents (or lack thereof) --- ChangeLog | 5 +++++ Doc/Zsh/expn.yo | 31 ++++++++++++++++--------------- Doc/Zsh/mod_parameter.yo | 3 ++- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 44b24c534..f2456de50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-01-31 Bart Schaefer + + * 51337: Doc/Zsh/expn.yo, Doc/Zsh/mod_parameter.yo: parameter + attributes cross-reference typeset equivalents (or lack thereof) + 2023-01-27 Daniel Shahaf * unposted (cribbed from users/28784 by Roman): diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index eb8cdbae5..ad55c24ba 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1093,7 +1093,7 @@ tt(KSH_ARRAYS) option a subscript `tt([*])' or `tt([@])' is needed to operate on the whole array, as usual. ) item(tt(L))( -Convert all letters in the result to lower case. +Convert all letters in the result to lower case, like `tt(typeset -l)'. ) item(tt(n))( Sort decimal integers numerically; if the first differing @@ -1177,34 +1177,35 @@ of the parameter would usually appear. This string consists of keywords separated by hyphens (`tt(-)'). The first keyword in the string describes the main type, it can be one of `tt(scalar)', `tt(array)', `tt(integer)', `tt(float)' or `tt(association)'. The other keywords describe the type in -more detail: +more detail, in most cases corresponding to options of the `tt(typeset)' +command: startitem() item(tt(local))( for local parameters ) item(tt(left))( -for left justified parameters +for left justified parameters (tt(-L)) ) item(tt(right_blanks))( -for right justified parameters with leading blanks +for right justified parameters with leading blanks (tt(-R)) ) item(tt(right_zeros))( -for right justified parameters with leading zeros +for right justified parameters with leading zeros (tt(-Z)) ) item(tt(lower))( for parameters whose value is converted to all lower case when it is -expanded +expanded (tt(-l)) ) item(tt(upper))( for parameters whose value is converted to all upper case when it is -expanded +expanded (tt(-u)) ) item(tt(readonly))( -for readonly parameters +for readonly parameters (tt(-r)) ) item(tt(tag))( -for tagged parameters +for tagged parameters (tt(-t)) ) item(tt(tied))( for parameters tied to another parameter in the manner of tt(PATH) @@ -1212,16 +1213,16 @@ for parameters tied to another parameter in the manner of tt(PATH) special parameters or user-defined with `tt(typeset -T)' ) item(tt(export))( -for exported parameters +for exported parameters (tt(-x) or `tt(export)') ) item(tt(unique))( -for arrays which keep only the first occurrence of duplicated values +for arrays which keep only the first occurrence of duplicated values (tt(-U)) ) item(tt(hide))( -for parameters with the `hide' flag +for parameters with the `hide' flag (tt(-h)) ) item(tt(hideval))( -for parameters with the `hideval' flag +for parameters with the `hideval' flag (tt(-H)) ) item(tt(special))( for special parameters defined by the shell @@ -1229,10 +1230,10 @@ for special parameters defined by the shell enditem() ) item(tt(u))( -Expand only the first occurrence of each unique word. +Expand only the first occurrence of each unique word, like `tt(typeset -U)'. ) item(tt(U))( -Convert all letters in the result to upper case. +Convert all letters in the result to upper case, like `tt(typeset -u)'. ) item(tt(v))( Used with tt(k), substitute (as two consecutive words) both the key diff --git a/Doc/Zsh/mod_parameter.yo b/Doc/Zsh/mod_parameter.yo index f3bcd7957..18fd3606e 100644 --- a/Doc/Zsh/mod_parameter.yo +++ b/Doc/Zsh/mod_parameter.yo @@ -125,7 +125,8 @@ zmanref(zshexpn) ifnzman(\ noderef(Parameter Expansion) )\ -. +. The value may also be `tt(undefined)' indicating a parameter that +may be autoloaded from a module but has not yet been referenced. Setting or unsetting keys in this array is not possible. ) vindex(modules) -- cgit v1.2.3 From c8c894f83fbb07b4f65b2ac8db639680062b25d9 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 31 Jan 2023 17:45:42 -0800 Subject: 51342: update PARAMDEF description --- ChangeLog | 2 ++ Etc/zsh-development-guide | 11 +++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index f2456de50..05c7d86c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-01-31 Bart Schaefer + * 51342: Etc/zsh-development-guide: update PARAMDEF description + * 51337: Doc/Zsh/expn.yo, Doc/Zsh/mod_parameter.yo: parameter attributes cross-reference typeset equivalents (or lack thereof) diff --git a/Etc/zsh-development-guide b/Etc/zsh-development-guide index 565b0b1d9..da6932003 100644 --- a/Etc/zsh-development-guide +++ b/Etc/zsh-development-guide @@ -612,7 +612,7 @@ For defining parameters, a module can call `createparam()' directly or use a table to describe them, e.g.: static struct paramdef patab[] = { - PARAMDEF("foo", PM_INTEGER, NULL, get_foo, set_foo, unset_foo), + PARAMDEF("foo", PM_INTEGER, NULL, foo_gsu), INTPARAMDEF("exint", &intparam), STRPARAMDEF("exstr", &strparam), ARRPARAMDEF("exarr", &arrparam), @@ -626,9 +626,9 @@ There are four macros used: in zsh.h) - optionally a pointer to a variable holding the value of the parameter - - three functions that will be used to get the value of the - parameter, store a value in the parameter, and unset the - parameter + - a GSU pointer to the three functions that will be used to get + the value of the parameter, store a value in the parameter, + and unset the parameter - the other macros provide simple ways to define the most common types of parameters; they get the name of the parameter and a pointer to a variable holding the value as arguments; they are @@ -636,6 +636,9 @@ There are four macros used: variables whose addresses are given should be of type `long', `char *', and `char **', respectively +GSU (get, set, unset) structures are defined in Src/zsh.h for each of +the parameter types scalar, integer, float, array, and hash. + For a description of how to write functions for getting or setting the value of parameters, or how to write a function to unset a parameter, see the description of the following functions in the `params.c' file: -- cgit v1.2.3 From 21baad1037c1aa85384a81dd77a4661676336133 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 2 Feb 2023 10:09:21 +0000 Subject: 51307: Improve error on attempt to define function from aliased name --- ChangeLog | 6 ++++++ Src/input.c | 5 +++-- Src/parse.c | 3 +++ Test/A02alias.ztst | 7 ++++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05c7d86c7..ee9a623d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-02-02 Peter Stephenson + + * 51307: Src/input.c, Src/parse.c, Test/A02alias.ztst: error + on attempt to expand alias in function definition name didn't + find the original alias and printed an extra error. + 2023-01-31 Bart Schaefer * 51342: Etc/zsh-development-guide: update PARAMDEF description diff --git a/Src/input.c b/Src/input.c index 5a612669b..0da065e51 100644 --- a/Src/input.c +++ b/Src/input.c @@ -816,6 +816,7 @@ char *input_hasalias(void) { int flags = inbufflags; struct instacks *instackptr = instacktop; + char *alias_nam = NULL; for (;;) { @@ -824,9 +825,9 @@ char *input_hasalias(void) DPUTS(instackptr == instack, "BUG: continuation at bottom of instack"); instackptr--; if (instackptr->alias) - return instackptr->alias->node.nam; + alias_nam = instackptr->alias->node.nam; flags = instackptr->flags; } - return NULL; + return alias_nam; } diff --git a/Src/parse.c b/Src/parse.c index 283225b74..a07a6cc71 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -2055,6 +2055,9 @@ par_simple(int *cmplx, int nr) if (isset(EXECOPT) && hasalias && !isset(ALIASFUNCDEF) && argc && hasalias != input_hasalias()) { zwarn("defining function based on alias `%s'", hasalias); + herrflush(); + if (noerrs != 2) + errflag |= ERRFLAG_ERROR; YYERROR(oecused); } diff --git a/Test/A02alias.ztst b/Test/A02alias.ztst index ca415fa39..1c6969e74 100644 --- a/Test/A02alias.ztst +++ b/Test/A02alias.ztst @@ -123,7 +123,12 @@ eval 'badalias() { print does not work; }') 1:ALIAS_FUNC_DEF off by default. ?(eval):1: defining function based on alias `badalias' -?(eval):1: parse error near `()' + + (alias firstalias=notacommand + alias secondalias=firstalias + eval 'secondalias() { print does not work either; }') +1:ALIAS_FUNC_DEF reports original alias if multiple +?(eval):1: defining function based on alias `secondalias' (alias goodalias=isafunc setopt ALIAS_FUNC_DEF -- cgit v1.2.3 From 76d095df9de31d46b0ca042039855ffc286f5fdb Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 2 Feb 2023 10:12:17 +0000 Subject: 51306: error message in ${unset?error} should be expanded --- ChangeLog | 3 +++ Doc/Zsh/expn.yo | 4 +++- Src/subst.c | 6 +++++- Test/D04parameter.ztst | 5 +++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee9a623d4..6bdaeedbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-02-02 Peter Stephenson + * 51306: Doc/Zsh/expn.yo, Src/subst.c, Test/D04parameter.ztst: + error message in ${unset?...} should be expanded. + * 51307: Src/input.c, Src/parse.c, Test/A02alias.ztst: error on attempt to expand alias in function definition name didn't find the original alias and printed an extra error. diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index ad55c24ba..fd5443b20 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -665,7 +665,9 @@ item(tt(${)var(name)tt(:?)var(word)tt(}))( In the first form, if var(name) is set, or in the second form if var(name) is both set and non-null, then substitute its value; otherwise, print var(word) and exit from the shell. Interactive shells instead return to -the prompt. If var(word) is omitted, then a standard message is printed. +the prompt. If var(word) is omitted, then a standard message is +printed. Note that var(word) is expanded even though its value +is not substituted onto the command line. ) enditem() diff --git a/Src/subst.c b/Src/subst.c index 897188862..4ad9fee1a 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3076,7 +3076,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, if (vunset) { if (isset(EXECOPT)) { *idend = '\0'; - zerr("%s: %s", idbeg, *s ? s : "parameter not set"); + if (*s){ + singsub(&s); + zerr("%s: %s", idbeg, s); + } else + zerr("%s: %s", idbeg, "parameter not set"); /* * In interactive shell we need to return to * top-level prompt --- don't clear this error diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 29275f13f..a11652d1e 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -110,6 +110,11 @@ *>*foo:1: 1: no arguments given >reached + message="expand me and remove quotes" + (: ${UNSET_PARAM?$message}) +1:${...?....} performs expansion on the message +?(eval):2: UNSET_PARAM: expand me and remove quotes + print ${set1:+word1} ${set1+word2} ${null1:+word3} ${null1+word4} print ${unset1:+word5} ${unset1+word6} 0:${...:+...}, ${...+...} -- cgit v1.2.3 From bffdbccda69683ce857dfad457e3209c0f00aa0c Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 2 Feb 2023 17:54:17 +0000 Subject: 51354: Fix markup in man page version --- ChangeLog | 4 ++++ Doc/Zsh/params.yo | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6bdaeedbf..1a66e94e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-02-02 Daniel Shahaf + + * 51354: Doc/Zsh/params.yo: Fix markup in man page version + 2023-02-02 Peter Stephenson * 51306: Doc/Zsh/expn.yo, Src/subst.c, Test/D04parameter.ztst: diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 2a30085a8..55009c6de 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1668,7 +1668,7 @@ well as any directory names. The default is `tt(/tmp/zsh)'. vindex(TMPSUFFIX) item(tt(TMPSUFFIX))( A filename suffix which the shell will use for temporary files created -by process substitutions (e.g., `tt(=LPAR()var(list)RPAR())'). +by process substitutions (e.g., `tt(=LPAR())var(list)tt(RPAR())'). Note that the value should include a leading dot `tt(.)' if intended to be interpreted as a file extension. The default is not to append any suffix, thus this parameter should be assigned only when needed -- cgit v1.2.3 From d6b027c3c1203da5f3c6451bd6e2e0b81bd766b6 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 6 Feb 2023 14:16:17 +0000 Subject: 51350: ${(S)...//#%...} didn't match the whole string --- ChangeLog | 5 +++++ Src/subst.c | 3 +++ Test/D04parameter.ztst | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1a66e94e9..2e63157de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-02-06 Peter Stephenson + + * 51350: Src/subst.c, Test/D04parameter.ztst: the combination + ${(S)...//#%...} needs to match as far as possible. + 2023-02-02 Daniel Shahaf * 51354: Doc/Zsh/params.yo: Fix markup in man page version diff --git a/Src/subst.c b/Src/subst.c index 4ad9fee1a..3dd920e87 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2926,6 +2926,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, */ if (!(flags & (SUB_MATCH|SUB_REST|SUB_BIND|SUB_EIND|SUB_LEN))) flags |= SUB_REST; + /* If matching at start and end, don't stop early */ + if ((flags & (SUB_START|SUB_END)) == (SUB_START|SUB_END)) + flags |= SUB_LONG; /* * With ":" treat a value as unset if the variable is set but diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index a11652d1e..7990c2958 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2307,6 +2307,13 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888 >x >y + a="string" + print ${(S)a//#%((#b)(*))/different} + print $match[1] +0:Fully anchored string must be fully searched +>different +>string + my_width=6 my_index=1 my_options=Option1 -- cgit v1.2.3 From 6502d05897a7d9441fcabfd24f203cffe4da59aa Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 9 Feb 2023 00:10:19 +0100 Subject: 51320, 51383: fixes to prevent later reappearance of old attributes Also associated test updates and a test fix for TERM=dumb. --- ChangeLog | 7 +++++++ Src/Zle/complist.c | 2 ++ Src/Zle/zle_main.c | 2 +- Src/Zle/zle_tricky.c | 2 ++ Test/D01prompt.ztst | 2 +- Test/X04zlehighlight.ztst | 2 +- 6 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e63157de..bbe45a3f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-02-09 Oliver Kiddle + + * 51320, 51383: Src/Zle/zle_main.c, Src/Zle/complist.c, + Src/Zle/zle_tricky.c, Test/D01prompt.ztst, + Test/X04zlehighlight.ztst: fixes to prevent later reappearance + of old attributes + 2023-02-06 Peter Stephenson * 51350: Src/subst.c, Test/D04parameter.ztst: the combination diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 8bdf1bb29..9cb89a60d 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -1305,6 +1305,8 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) } } if (dopr) { + treplaceattrs(0); + applytextattributes(0); if (!(cc % zterm_columns)) fputs(" \010", shout); cleareol(); diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index cfa0a739d..4a6c02133 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -2071,9 +2071,9 @@ trashzle(void) trashedzle = 1; zrefresh(); showinglist = sl; - moveto(nlnct, 0); treplaceattrs(prompt_attr); applytextattributes(0); + moveto(nlnct, 0); if (clearflag && tccan(TCCLEAREOD)) { tcout(TCCLEAREOD); clearflag = listshown = 0; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index f94bfce3c..07fac7144 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -2560,6 +2560,8 @@ printfmt(char *fmt, int n, int dopr, int doesc) } } if (dopr) { + treplaceattrs(0); + applytextattributes(0); if (!(cc % zterm_columns)) fputs(" \010", shout); if (tccan(TCCLEAREOL)) diff --git a/Test/D01prompt.ztst b/Test/D01prompt.ztst index a0abb7e1d..55861cca1 100644 --- a/Test/D01prompt.ztst +++ b/Test/D01prompt.ztst @@ -261,7 +261,7 @@ A1=${(%):-%s} A2=${(%):-%u} A3=${(%):-%s%u%s} - [[ $A3 = $A1$A2 && -n $A1 && -n $A2 ]] + [[ $A3 = $A1$A2 ]] 0:Attribute optimisation - preserve initial disabling of attribute but drop useless later one : ${(%):-%K{blue}} diff --git a/Test/X04zlehighlight.ztst b/Test/X04zlehighlight.ztst index 296635bf5..87a59fde5 100644 --- a/Test/X04zlehighlight.ztst +++ b/Test/X04zlehighlight.ztst @@ -40,7 +40,7 @@ # Fix e^Mexit - match ((?)\r(?)), if \2 == \3, then replace with \2 # otherwise replace with \1 stripped out of leading/trailing [[:space:]] REPLY=${REPLY//(#b)((?(#c0,1))$cm(?(#c0,1)))/${${${(M)match[2]:#${match[3]}}:+${match[2]}}:-${${match[1]##[[:space:]]##}%%[[:space:]]##}}} - [[ -n "$REPLY" ]] && print -r -- ${${REPLY%%[[:space:]]##}##[[:space:]]##} + [[ -n "$REPLY" ]] && print -r -- ${${REPLY%%${~cm}*}##[[:space:]]##} done } zpty_stop() { -- cgit v1.2.3 From d3edf318306e37d2d96c4e4ea442d10207722e94 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 09:52:39 -0800 Subject: 51404: Nullify filelist after deleting (fix segfault) --- ChangeLog | 4 ++++ Src/jobs.c | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bbe45a3f4..7f467a8ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-02-12 Bart Schaefer + + * 51404: Src/jobs.c: Nullify filelist after deleting (fix segfault) + 2023-02-09 Oliver Kiddle * 51320, 51383: Src/Zle/zle_main.c, Src/Zle/complist.c, diff --git a/Src/jobs.c b/Src/jobs.c index 4863962b9..59ddd952e 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1372,8 +1372,10 @@ cleanfilelists(void) DPUTS(shell_exiting >= 0, "BUG: cleanfilelists() before exit"); - for (i = 1; i <= maxjob; i++) + for (i = 1; i <= maxjob; i++) { deletefilelist(jobtab[i].filelist, 0); + jobtab[i].filelist = 0; + } } /**/ @@ -1531,8 +1533,10 @@ havefiles(void) int i; for (i = 1; i <= maxjob; i++) - if (jobtab[i].stat && jobtab[i].filelist) + if (jobtab[i].stat && jobtab[i].filelist && + peekfirst(jobtab[i].filelist)) { return 1; + } return 0; } -- cgit v1.2.3 From 511e020c68955f737036b7febd360615517a3637 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 11:21:23 -0800 Subject: 51360: Initial implementation of named references. --- ChangeLog | 4 + Src/Modules/param_private.c | 17 +++- Src/Modules/parameter.c | 4 +- Src/builtin.c | 56 ++++++++++++- Src/params.c | 190 ++++++++++++++++++++++++++++++++++++++++++-- Src/subst.c | 3 +- Src/zsh.h | 8 +- 7 files changed, 266 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f467a8ac..aecb1efcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-02-12 Bart Schaefer + * 51360: Src/Modules/param_private.c, Src/Modules/parameter.c, + Src/builtin.c, Src/params.c, Src/subst.c, Src/zsh.h: Initial + implementation of named references. + * 51404: Src/jobs.c: Nullify filelist after deleting (fix segfault) 2023-02-09 Oliver Kiddle diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index 065fa63d2..70f36ceb1 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -512,9 +512,16 @@ static GetNodeFunc getparamnode; static HashNode getprivatenode(HashTable ht, const char *nam) { - HashNode hn = getparamnode(ht, nam); + /* getparamnode() would follow namerefs, we must not do that here */ + HashNode hn = gethashnode2(ht, nam); Param pm = (Param) hn; + /* autoload has precedence over nameref, so getparamnode() */ + if (pm && (pm->node.flags & PM_AUTOLOAD)) { + hn = getparamnode(ht, nam); + pm = (Param) hn; + /* how would an autoloaded private behave? return here? */ + } while (!fakelevel && pm && locallevel > pm->level && is_private(pm)) { if (!(pm->node.flags & PM_UNSET)) { /* @@ -533,6 +540,12 @@ getprivatenode(HashTable ht, const char *nam) } pm = pm->old; } + + /* resolve nameref after skipping private parameters */ + if (pm && (pm->node.flags & PM_NAMEREF) && + (pm->u.str || (pm->node.flags & PM_UNSET))) + pm = (Param) resolve_nameref(pm, NULL); + return (HashNode)pm; } @@ -571,7 +584,7 @@ printprivatenode(HashNode hn, int printflags) static struct builtin bintab[] = { /* Copied from BUILTIN("local"), "P" added */ - BUILTIN("private", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_private, 0, -1, 0, "AE:%F:%HL:%PR:%TUZ:%ahi:%lmprtux", "P") + BUILTIN("private", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_private, 0, -1, 0, "AE:%F:%HL:%PR:%TUZ:%ahi:%lnmprtux", "P") }; static struct features module_features = { diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index dbb61e474..5bf675e2a 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -49,13 +49,15 @@ paramtypestr(Param pm) if (pm->node.flags & PM_AUTOLOAD) return dupstring("undefined"); - switch (PM_TYPE(f)) { + /* For simplicity we treat PM_NAMEREF as PM_TYPE(PM_SCALAR) */ + switch (PM_TYPE(f)|(f & PM_NAMEREF)) { case PM_SCALAR: val = "scalar"; break; case PM_ARRAY: val = "array"; break; case PM_INTEGER: val = "integer"; break; case PM_EFLOAT: case PM_FFLOAT: val = "float"; break; case PM_HASHED: val = "association"; break; + case PM_NAMEREF: val = "nameref"; break; } DPUTS(!val, "BUG: type not handled in parameter"); val = dupstring(val); diff --git a/Src/builtin.c b/Src/builtin.c index 4c295d11f..8039b644e 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -55,7 +55,7 @@ static struct builtin builtins[] = BUILTIN("cd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL), BUILTIN("chdir", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL), BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL), - BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmp:%rtuxz", NULL), + BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmnp:%rtuxz", NULL), BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL), BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL), BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL), @@ -88,7 +88,7 @@ static struct builtin builtins[] = BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL), BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -1, 0, NULL, NULL), BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL), - BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lp:%rtux", NULL), + BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lnp:%rtux", NULL), BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL), #if defined(ZSH_MEM) & defined(ZSH_MEM_DEBUG) @@ -121,7 +121,7 @@ static struct builtin builtins[] = BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_trap, 0, -1, 0, NULL, NULL), BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL), BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"), - BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klp:%rtuxmz", NULL), + BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klp:%rtuxmnz", NULL), BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL), BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL), BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"), @@ -2030,6 +2030,19 @@ typeset_single(char *cname, char *pname, Param pm, int func, int usepm, tc, keeplocal = 0, newspecial = NS_NONE, readonly, dont_set = 0; char *subscript; + if (pm && (pm->node.flags & PM_NAMEREF) && !((off|on) & PM_NAMEREF)) { + if (!(off & PM_NAMEREF)) + pm = (Param)resolve_nameref(pm, NULL); + if (pm && (pm->node.flags & PM_NAMEREF) && + (on & ~(PM_NAMEREF|PM_LOCAL))) { + /* Changing type of PM_SPECIAL|PM_AUTOLOAD is a fatal error. * + * Should this be a fatal error as well, rather than warning? */ + zwarnnam(cname, "%s: can't change type of a named reference", + pname); + return NULL; + } + } + /* * Do we use the existing pm? Note that this isn't the end of the * story, because if we try and create a new pm at the same @@ -2406,6 +2419,11 @@ typeset_single(char *cname, char *pname, Param pm, int func, return NULL; } } else if ((subscript = strchr(pname, '['))) { + if (on & PM_NAMEREF) { + zerrnam(cname, + "%s: reference variable cannot be an array", pname); + return NULL; + } if (on & PM_READONLY) { zerrnam(cname, "%s: can't create readonly array elements", pname); @@ -2640,6 +2658,14 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) else if (OPT_PLUS(ops,optval)) off |= bit; } + if (OPT_MINUS(ops,'n')) { + if (on|off) { + zwarnnam(name, "no other attributes allowed with -n"); + return 1; + } + on |= PM_NAMEREF; + } else if (OPT_PLUS(ops,'n')) + off |= PM_NAMEREF; roff = off; /* Sanity checks on the options. Remove conflicting options. */ @@ -3022,6 +3048,27 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) } continue; } + + if (on & PM_NAMEREF) { + if (asg->value.scalar && + (strcmp(asg->name, asg->value.scalar) == 0 || + ((pm = (Param)resolve_nameref((Param)hn, asg)) && + (pm->node.flags & PM_NAMEREF)))) { + if (pm->node.flags & PM_SPECIAL) + zwarnnam(name, "%s: invalid reference", pm->node.nam); + else + zwarnnam(name, "%s: invalid self reference", asg->name); + returnval = 1; + continue; + } + if (hn) { + /* namerefs always start over fresh */ + if (((Param)hn)->level >= locallevel) + unsetparam_pm((Param)hn, 0, 1); + hn = NULL; + } + } + if (!typeset_single(name, asg->name, (Param)hn, func, on, off, roff, asg, NULL, ops, 0)) @@ -3805,7 +3852,8 @@ bin_unset(char *name, char **argv, Options ops, int func) returnval = 1; } } else { - if (unsetparam_pm(pm, 0, 1)) + if ((pm = (Param)resolve_nameref(pm, NULL)) && + unsetparam_pm(pm, 0, 1)) returnval = 1; } if (ss) diff --git a/Src/params.c b/Src/params.c index 6362b382c..69b7f484f 100644 --- a/Src/params.c +++ b/Src/params.c @@ -536,6 +536,9 @@ getparamnode(HashTable ht, const char *nam) nam); } } + + if (hn && ht == realparamtab) + hn = resolve_nameref(pm, NULL); return hn; } @@ -993,6 +996,34 @@ createparam(char *name, int flags) gethashnode2(paramtab, name) : paramtab->getnode(paramtab, name)); + if (oldpm && (oldpm->node.flags & PM_NAMEREF) && + !(flags & PM_NAMEREF)) { + Param lastpm; + struct asgment stop; + stop.flags = PM_NAMEREF | (flags & PM_LOCAL); + stop.name = oldpm->node.nam; + stop.value.scalar = oldpm->u.str; + lastpm = (Param)resolve_nameref(oldpm, &stop); + if (lastpm) { + if (lastpm->node.flags & PM_NAMEREF) { + if (lastpm->u.str && *(lastpm->u.str)) { + name = lastpm->u.str; + oldpm = NULL; + } else { + if (!(lastpm->node.flags & PM_READONLY)) + lastpm->node.flags |= PM_UNSET; + return lastpm; + } + } else { + /* nameref pointing to an unset local */ + DPUTS(!(lastpm->node.flags & PM_UNSET), + "BUG: local parameter is not unset"); + oldpm = lastpm; + } + } else + flags |= PM_NAMEREF; + } + DPUTS(oldpm && oldpm->level > locallevel, "BUG: old local parameter not deleted"); if (oldpm && (oldpm->level == locallevel || !(flags & PM_LOCAL))) { @@ -2109,6 +2140,23 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) memset(v, 0, sizeof(*v)); else v = (Value) hcalloc(sizeof *v); + if ((pm->node.flags & PM_NAMEREF) && pm->u.str && *(pm->u.str)) { + /* only happens for namerefs pointing to array elements */ + char *ref = dupstring(pm->u.str); + char *ss = pm->width ? ref + pm->width : NULL; + if (ss) { + sav = *ss; + *ss = 0; + } + Param p1 = (Param)gethashnode2(paramtab, ref); + if (!(p1 && (pm = upscope(p1, pm->base))) || + ((pm->node.flags & PM_UNSET) && + !(pm->node.flags & PM_DECLARED))) + return NULL; + if (ss) + *ss = sav; + s = ss; + } if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) { /* Overload v->isarr as the flag bits for hashed arrays. */ v->isarr = flags | (isvarat ? SCANPM_ISVAR_AT : 0); @@ -2677,6 +2725,7 @@ assignstrvalue(Value v, char *val, int flags) } break; } + setscope(v->pm); if ((!v->pm->env && !(v->pm->node.flags & PM_EXPORTED) && !(isset(ALLEXPORT) && !(v->pm->node.flags & PM_HASHELEM))) || (v->pm->node.flags & PM_ARRAY) || v->pm->ename) @@ -3084,11 +3133,20 @@ assignsparam(char *s, char *val, int flags) } } if (!v && !(v = getvalue(&vbuf, &t, 1))) { - unqueue_signals(); zsfree(val); + unqueue_signals(); /* errflag |= ERRFLAG_ERROR; */ return NULL; } + if (*val && (v->pm->node.flags & PM_NAMEREF)) { + if (!valid_refname(val)) { + zerr("invalid variable name: %s", val); + zsfree(val); + unqueue_signals(); + errflag |= ERRFLAG_ERROR; + return NULL; + } + } if (flags & ASSPM_WARN) check_warn_pm(v->pm, "scalar", created, 1); v->pm->node.flags &= ~PM_DEFAULTED; @@ -3115,8 +3173,8 @@ assignsparam(char *s, char *val, int flags) lhs.u.l = lhs.u.l + (zlong)rhs.u.d; } setnumvalue(v, lhs); - unqueue_signals(); zsfree(val); + unqueue_signals(); return v->pm; /* avoid later setstrvalue() call */ case PM_ARRAY: if (unset(KSHARRAYS)) { @@ -3141,9 +3199,9 @@ assignsparam(char *s, char *val, int flags) case PM_INTEGER: case PM_EFLOAT: case PM_FFLOAT: + zsfree(val); unqueue_signals(); zerr("attempt to add to slice of a numeric variable"); - zsfree(val); return NULL; case PM_ARRAY: kshappend: @@ -3602,7 +3660,8 @@ unsetparam(char *s) if ((pm = (Param) (paramtab == realparamtab ? /* getnode2() to avoid autoloading */ paramtab->getnode2(paramtab, s) : - paramtab->getnode(paramtab, s)))) + paramtab->getnode(paramtab, s))) && + !(pm->node.flags & PM_NAMEREF)) unsetparam_pm(pm, 0, 1); unqueue_signals(); } @@ -5783,7 +5842,8 @@ static const struct paramtypes pmtypes[] = { { PM_TAGGED, "tagged", 't', 0}, { PM_EXPORTED, "exported", 'x', 0}, { PM_UNIQUE, "unique", 'U', 0}, - { PM_TIED, "tied", 'T', 0} + { PM_TIED, "tied", 'T', 0}, + { PM_NAMEREF, "namref", 'n', 0} }; #define PMTYPES_SIZE ((int)(sizeof(pmtypes)/sizeof(struct paramtypes))) @@ -6037,3 +6097,123 @@ printparamnode(HashNode hn, int printflags) else if (!(printflags & PRINT_KV_PAIR)) putchar('\n'); } + +/**/ +mod_export HashNode +resolve_nameref(Param pm, const Asgment stop) +{ + HashNode hn = (HashNode)pm; + const char *seek = stop ? stop->value.scalar : NULL; + + if (pm && (pm->node.flags & PM_NAMEREF)) { + if (pm && (pm->node.flags & (PM_UNSET|PM_TAGGED))) { + /* Semaphore with createparam() */ + pm->node.flags &= ~PM_UNSET; + /* See V10private.ztst end is in scope but private: + if (pm->node.flags & PM_SPECIAL) + return NULL; + */ + return (HashNode) pm; + } else if (pm->u.str) { + if ((pm->node.flags & PM_TAGGED) || + (stop && strcmp(pm->u.str, stop->name) == 0)) { + /* zwarnnam(pm->u.str, "invalid self reference"); */ + return stop ? (HashNode)pm : NULL; + } + if (*(pm->u.str)) + seek = pm->u.str; + } + } + else if (pm && !(stop && (stop->flags & PM_NAMEREF))) + return (HashNode)pm; + if (seek) { + queue_signals(); + /* pm->width is the offset of any subscript */ + if (pm && (pm->node.flags & PM_NAMEREF) && pm->width) { + if (stop) { + if (stop->flags & PM_NAMEREF) + hn = (HashNode)pm; + else + hn = NULL; + } else { + /* this has to be the end of any chain */ + hn = (HashNode)pm; /* see fetchvalue() */ + } + } else if ((hn = gethashnode2(realparamtab, seek))) { + if (pm) { + if (!(stop && (stop->flags & (PM_LOCAL)))) + hn = (HashNode)upscope((Param)hn, + ((pm->node.flags & PM_NAMEREF) ? + pm->base : ((Param)hn)->level)); + /* user can't tag a nameref, safe for loop detection */ + pm->node.flags |= PM_TAGGED; + } + if (hn) { + if (hn->flags & PM_AUTOLOAD) + hn = getparamnode(realparamtab, seek); + if (!(hn->flags & PM_UNSET)) + hn = resolve_nameref((Param)hn, stop); + } + if (pm) + pm->node.flags &= ~PM_TAGGED; + } else if (stop && (stop->flags & PM_NAMEREF)) + hn = (HashNode)pm; + unqueue_signals(); + } + + return hn; +} + +/**/ +static void +setscope(Param pm) +{ + if (pm->node.flags & PM_NAMEREF) { + Param basepm; + char *t = pm->u.str ? itype_end(pm->u.str, IIDENT, 0) : NULL; + + /* Temporarily change nameref to array parameter itself */ + if (t && *t == '[') + *t = 0; + else + t = 0; + basepm = (Param)resolve_nameref(pm, NULL); + if (t) { + pm->width = t - pm->u.str; + *t = '['; + } + if (basepm) + pm->base = ((basepm->node.flags & PM_NAMEREF) ? + basepm->base : basepm->level); + } +} + +/**/ +mod_export Param +upscope(Param pm, int reflevel) +{ + Param up = pm->old; + while (pm && up && up->level >= reflevel) { + pm = up; + if (up) + up = up->old; + } + return pm; +} + +/**/ +mod_export int +valid_refname(char *val) +{ + char *t = itype_end(val, IIDENT, 0); + + if (*t != 0) { + if (*t == '[') { + tokenize(t = dupstring(t+1)); + t = parse_subscript(t, 0, ']'); + } else { + t = NULL; + } + } + return !!t; +} diff --git a/Src/subst.c b/Src/subst.c index 3dd920e87..05bfcc03b 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2573,13 +2573,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, !(v->pm->node.flags & PM_UNSET))) { int f = v->pm->node.flags; - switch (PM_TYPE(f)) { + switch (PM_TYPE(f)|(f & PM_NAMEREF)) { case PM_SCALAR: val = "scalar"; break; case PM_ARRAY: val = "array"; break; case PM_INTEGER: val = "integer"; break; case PM_EFLOAT: case PM_FFLOAT: val = "float"; break; case PM_HASHED: val = "association"; break; + case PM_NAMEREF: val = "nameref"; break; } val = dupstring(val); if (v->pm->level) diff --git a/Src/zsh.h b/Src/zsh.h index f82e76e4b..1e35bd33e 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1852,8 +1852,9 @@ struct param { GsuHash h; } gsu; - int base; /* output base or floating point prec */ - int width; /* field width */ + int base; /* output base or floating point prec or */ + /* for namerefs, locallevel of reference */ + int width; /* field width or nameref subscript idx */ char *env; /* location in environment, if exported */ char *ename; /* name of corresponding environment var */ Param old; /* old struct for use with local */ @@ -1932,9 +1933,10 @@ struct tieddata { */ #define PM_HASHELEM (1<<28) /* is a hash-element */ #define PM_NAMEDDIR (1<<29) /* has a corresponding nameddirtab entry */ +#define PM_NAMEREF (1<<30) /* pointer to a different parameter */ /* The option string corresponds to the first of the variables above */ -#define TYPESET_OPTSTR "aiEFALRZlurtxUhHTkz" +#define TYPESET_OPTSTR "aiEFALRZlurtxUhHT" /* These typeset options take an optional numeric argument */ #define TYPESET_OPTNUM "LRZiEF" -- cgit v1.2.3 From 143e153259efbb6b6b0d804b753bc2a69e422660 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 11:23:06 -0800 Subject: 51361: Tests for 51360. --- ChangeLog | 3 + Test/K01nameref.ztst | 439 +++++++++++++++++++++++++++++++++++++++++++++++++++ Test/V10private.ztst | 78 +++++++++ 3 files changed, 520 insertions(+) create mode 100644 Test/K01nameref.ztst diff --git a/ChangeLog b/ChangeLog index aecb1efcf..db768ccbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-02-12 Bart Schaefer + * 51361: Test/K01nameref.ztst, Test/V10private.ztst: Tests + for 51360. + * 51360: Src/Modules/param_private.c, Src/Modules/parameter.c, Src/builtin.c, Src/params.c, Src/subst.c, Src/zsh.h: Initial implementation of named references. diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst new file mode 100644 index 000000000..b38831100 --- /dev/null +++ b/Test/K01nameref.ztst @@ -0,0 +1,439 @@ +# Tests for the zsh/param/private module + +%prep + + # Required in order to declare an unset hash for substitution test + setopt TYPESET_TO_UNSET + + : ${ZTST_continue:=1} + +%test + + typeset -n ptr + typeset -n +0:minimal declaration +>ptr + + typeset -n ptr= + typeset -n +0:nameref placeholder +>ptr='' + + typeset -n ptr + ptr=var + typeset -n +0:assign nameref placeholder +>ptr=var + + typeset -n ptr=var + typeset +n ptr + typeset -p ptr +0:remove nameref attribute +>typeset ptr=var + + typeset -n ptr + typeset -t ptr + typeset -p ptr +0:change type of a placeholder +F:Other type changes are fatal errors, should this also be? +>typeset -n ptr='' +*?*ptr: can't change type of a named reference + + typeset -n ptr=var + typeset -t ptr + typeset -p ptr var +0:change type of referenced var +>typeset -n ptr=var +>typeset -t var + + typeset -n ptr[1]=var +1:illegal nameref name +*?*reference variable cannot be an array + + typeset var=value + typeset -n ptr=var + print $ptr +0:basic nameref expansion +>value + + typeset var=(val1 val2) + typeset -n ptr=var + print $ptr +0:nameref array expansion +>val1 val2 + + typeset -A var=(val1 val2) + typeset -n ptr=var + print ${(kv)ptr} +0:nameref hash expansion +>val1 val2 + + typeset -n ptr=var + typeset var=value + typeset -p ptr var + ptr=newvalue + typeset -p ptr var +0:assign existing scalar via nameref +>typeset -n ptr=var +>typeset var=value +>typeset -n ptr=var +>typeset var=newvalue + + typeset -n ptr=var + typeset var=value + unset ptr + typeset -p var +0:unset via nameref + + typeset -n ptr=var + typeset var=value + typeset -p ptr var + typeset ptr=newvalue + typeset -p ptr var +0:typeset existing scalar via nameref +>typeset -n ptr=var +>typeset var=value +>typeset -n ptr=var +>typeset var=newvalue + + typeset -n ptr=var + ptr=value + typeset -p var ptr + unset var # for next test +0:assign new scalar via nameref +>typeset -g var=value +>typeset -n ptr=var + + typeset -n ptr=var + typeset var=(val1 val2) + typeset -p ptr var + ptr=(new1 new2) + typeset -p ptr var +0:assign existing array via nameref +>typeset -n ptr=var +>typeset -a var=( val1 val2 ) +>typeset -n ptr=var +>typeset -a var=( new1 new2 ) + + typeset -p ptr1 ptr2 var +1:check state of paramtab ONE +F:unexpected side-effects of previous tests +*?*no such variable: ptr1 +*?*no such variable: ptr2 +*?*no such variable: var + + typeset -n ptr=var + ptr=(val1 val2) + typeset -p var ptr + unset var # for next test +0:assign new array via nameref +>typeset -g -a var=( val1 val2 ) +>typeset -n ptr=var + + typeset -n ptr2=var + typeset -n ptr1=ptr2 + typeset var=value + typeset -p ptr1 ptr2 var + print $ptr1 +0:indirect nameref expansion +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var +>typeset var=value +>value + + typeset -p ptr1 ptr2 var +1:check state of paramtab TWO +F:unexpected side-effects of previous tests +*?*no such variable: ptr1 +*?*no such variable: ptr2 +*?*no such variable: var + + typeset var + typeset -n ptr2=var + typeset -n ptr1=ptr2 + typeset ptr1=newvalue + typeset -p ptr1 ptr2 var +0:typeset existing parameter indirectly +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var +>typeset var=newvalue + + typeset var=value + typeset -n ptr2=var + typeset -n ptr1=ptr2 + unset ptr1 + typeset -p ptr1 ptr2 var +0:unset parameter indirectly +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var + + typeset -n ptr2=var + typeset -n ptr1=ptr2 + typeset ptr1=newvalue + typeset -p ptr1 ptr2 var + unset var # for next test +0:typeset new parameter indirectly +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var +>typeset var=newvalue + + typeset -n ptr2=var + typeset -n ptr1=ptr2 + typeset var=value + typeset -p ptr1 ptr2 var + ptr1=newvalue + typeset -p ptr1 ptr2 var +0:assign new parameter indirectly +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var +>typeset var=value +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var +>typeset var=newvalue + + typeset -p ptr1 ptr2 var +1:check state of paramtab THREE +F:unexpected side-effects of previous tests +*?*no such variable: ptr1 +*?*no such variable: ptr2 +*?*no such variable: var + + typeset -a var + typeset -n ptr2=var + typeset -n ptr1=ptr2 + typeset ptr1=(val1 val2) + typeset -p ptr1 ptr2 var +0:typeset existing array indirectly +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var +>typeset -a var=( val1 val2 ) + + typeset -n ptr2=var + typeset -n ptr1=ptr2 + typeset ptr1=(val1 val2) + typeset -p ptr1 ptr2 var + unset var # for next test +0:typeset new array indirectly +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var +>typeset -a var=( val1 val2 ) + + typeset -p ptr1 ptr2 var +1:check state of paramtab FOUR +F:unexpected side-effects of previous tests +*?*no such variable: ptr1 +*?*no such variable: ptr2 +*?*no such variable: var + + typeset -n ptr2=var + typeset -n ptr1=ptr2 + ptr1=(val1 val2) + typeset -p ptr1 ptr2 var +0:assign new array indirectly +>typeset -n ptr1=ptr2 +>typeset -n ptr2=var +>typeset -g -a var=( val1 val2 ) + + typeset -n ptr1=ptr2 + typeset -n ptr2=ptr1 +1:direct nameref loop not allowed +*?*invalid self reference + + typeset -n ptr1=ptr2 + typeset -n ptr2=ptr3 + typeset -n ptr3=ptr1 +1:indirect nameref loop not allowed +*?*invalid self reference + + typeset -n ptr2='path[2]' + print -r -- $ptr2 +0d:nameref to array element +>${path[2]} + + typeset -A hash=(x MISS y HIT) + typeset -n ptr1='hash[y]' + print -r -- $ptr1 +0:nameref to hash element +>HIT + + typeset -a ary=(1 2) + typeset -n ptr2='ary[2]' + ptr2=TWO + typeset -p ary +0:assign array element by nameref +>typeset -a ary=( 1 TWO ) + + typeset -n ptr2='ary[2]' + ptr2=TWO + typeset -p ary +0f:create array element by nameref +F:ksh93 does not implement this either +>typeset -a ary=( '' TWO ) + + typeset -A hash=(x MISS y MISS) + typeset -n ptr1='hash[y]' + ptr1=HIT + typeset -p hash +0:assign to hash element by nameref +>typeset -A hash=( [x]=MISS [y]=HIT ) + + typeset -A hash + typeset -n ptr1='hash[y]' + ptr1=HIT + typeset -p hash +0f:create hash by element nameref +F:ksh93 does not implement this either +>typeset -A hash=( [y]=HIT ) + + typeset -n ptr1='not good' +1:invalid nameref +*?*invalid variable name: not good + + typeset -A hash + typeset -n ptr1='hash[y]' + print ${ptr1::=HIT} + typeset -p ptr1 hash +0f:create hash by element substitution +>HIT +>typeset -n ptr1='hash[y]' +>typeset -A hash=( [y]=HIT ) + + typeset -n ptr=gval + gval=global + () { local gval=local; print $ptr; typeset -p ptr gval } + unset gval # for next test +0:up-reference part 1 +>global +>typeset -g -n ptr=gval +>typeset gval=local + + typeset -p ptr ptr1 ptr2 val gval +1:check state of paramtab FIVE +F:unexpected side-effects of previous tests +*?*no such variable: ptr +*?*no such variable: ptr1 +*?*no such variable: ptr2 +*?*no such variable: val +*?*no such variable: gval + + typeset -n ptr1=gval + typeset gval + () { typeset gval=local; ptr1=global } + typeset -p ptr1 gval +0:up-reference assignment part 1 +F:All tests run inside a function, so "typeset gval" creates a local; +F:if that were omitted, ptr1= assignment would create a true global +F:and the output below would change to "typeset -g gval=global" +>typeset -n ptr1=gval +>typeset gval=global + + typeset -p ptr ptr1 ptr2 val gval +1:check state of paramtab SIX +F:unexpected side-effects of previous tests +*?*no such variable: ptr +*?*no such variable: ptr1 +*?*no such variable: ptr2 +*?*no such variable: val +*?*no such variable: gval + + typeset gval=global + () { + typeset -n ptr=gval + local gval=local + print $ptr + } + typeset -p ptr gval +1:up-reference part 2 +>global +*?*no such variable: ptr +>typeset gval=global + + typeset -n ptr=gval + () { + local lval=local + typeset -n ptr=lval + ptr=LOCAL + typeset -p lval gval ptr + } + typeset -p ptr +0:localized namerefs hide global namerefs +*?*no such variable: gval +>typeset lval=LOCAL +>typeset -n ptr=lval +>typeset -n ptr=gval + + () { + zmodload -u zsh/parameter + typeset -n myself=parameters[myself] + local -h parameters + print -r -- $myself + typeset -p parameters + } +0:up-reference part 3, autoloading with hidden special +>nameref-local +>typeset parameters + + () { + typeset notdef + unset notdef + () { + typeset -n ptr=notdef + ptr=(DEFINED) + } + typeset -p notdef + } +0:up-reference part 4, unset local and type change +>typeset -a notdef=( DEFINED ) + + () { + typeset -n ptr1=ptr2 + typeset -n ptr2 + typeset -p ptr1 ptr2 + typeset val=LOCAL + () { + ptr1=val + typeset -n + printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" + } + typeset -p ptr1 ptr2 + } + typeset -p ptr2 +1:up-reference part 5, stacked namerefs, end not in scope +F:What is the correct behavior for the scope of ptr1? +>typeset -n ptr1=ptr2 +>typeset -n ptr2='' +>ptr1=ptr2 +>ptr2=val +>ptr1=LOCAL +>ptr2=LOCAL +>typeset -n ptr1=ptr2 +>typeset -n ptr2=val +*?*no such variable: ptr2 + + typeset ptr2 + () { + typeset -n ptr1=ptr2 + typeset -n ptr2 + typeset -p ptr1 ptr2 + typeset val=LOCAL + () { + ptr1=val + typeset -n + printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" + } + typeset -p ptr1 ptr2 + } + typeset -p ptr2 +0:up-reference part 6, stacked namerefs, end is in scope +F:Same test, should part 5 output look like this? +>typeset -n ptr1=ptr2 +>typeset -n ptr2='' +>ptr1=ptr2 +>ptr2='' +>ptr1=val +>ptr2= +>typeset -n ptr1=ptr2 +>typeset -n ptr2='' +>typeset ptr2=val + +%clean diff --git a/Test/V10private.ztst b/Test/V10private.ztst index 56ffbc5b4..b191afcb7 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -299,6 +299,84 @@ F:future revision will create a global with this assignment *>* *>* + typeset top=TOP + () { + local -P -n test=top + print $top + () { print UP: $test } + } +0:nameref can be declared private +>TOP +>UP: + + () { + typeset -n ptr1=ptr2 + private -n ptr2 + typeset -p ptr1 ptr2 + typeset val=LOCAL + () { + ptr1=val + typeset -n + printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" + } + typeset -p ptr1 ptr2 + } + typeset -p ptr2 +1:up-reference for private namerefs, end not in scope +F:See K01typeset.ztst up-reference part 5 +F:Here ptr1 finds private ptr2 by scope mismatch, assignment silently fails +>typeset -n ptr1=ptr2 +>ptr1=ptr2 +>ptr1= +>ptr2= +>typeset -n ptr1=ptr2 +*?*no such variable: ptr2 + + typeset ptr2 + () { + typeset -n ptr1=ptr2 + private -n ptr2 + typeset -p ptr1 ptr2 + typeset val=LOCAL + () { + ptr1=val; + typeset -n + printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" + } + typeset -p ptr1 ptr2 + } + typeset -p ptr2 +0:up-reference for private namerefs, end is in scope +F:See K01typeset.ztst up-reference part 5 +F:Here ptr1 points to global ptr2 so assignment succeeds +>typeset -n ptr1=ptr2 +>ptr1=ptr2 +>ptr2=val +>ptr1=val +>ptr2=val +>typeset -n ptr1=ptr2 +>typeset ptr2=val + + () { + setopt localoptions errreturn + private -n ptr2 + typeset -n ptr1=ptr2 + typeset -p ptr1 ptr2 + typeset val=LOCAL + () { + ptr1=val + typeset -n + printf "v %s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" + } + typeset -p ptr1 ptr2 + } + typeset -p ptr1 ptr2 +1:up-reference for private namerefs, end is in scope but private +F:Should we allow "public" namerefs to private parameters? +*?*ptr2: invalid reference +*?*no such variable: ptr1 +*?*no such variable: ptr2 + %clean rm -r private.TMP -- cgit v1.2.3 From 102145b0487ddd7d2a048a0787b79146434d2cd6 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 11:25:42 -0800 Subject: 51362: Begin documentation for named references. --- ChangeLog | 3 ++ Doc/Zsh/builtins.yo | 20 ++++++++++-- Doc/Zsh/expn.yo | 82 ++++++++++++++++++++++++++++++++++++++++++++++-- Doc/Zsh/mod_parameter.yo | 2 +- Doc/Zsh/params.yo | 46 ++++++++++++++++++++++++++- 5 files changed, 146 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index db768ccbc..221b9838d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-02-12 Bart Schaefer + * 51362: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/params.yo, + Doc/Zsh/mod_parameter.yo: Begin documentation for named references. + * 51361: Test/K01nameref.ztst, Test/V10private.ztst: Tests for 51360. diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 56428a714..64c47346f 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2037,6 +2037,20 @@ To initialize a parameter var(param) to a command output and mark it readonly, use tt(typeset -r )var(param) or tt(readonly )var(param) after the parameter assignment statement. +cindex(named reference) +cindex(reference, named) +The flag tt(-n) creates a em(named reference) to another parameter. +The second parameter need not exist at the time the reference is +created. No other attribute flags may be used in conjunction with +tt(-n). The var(name) assigned-to may not be an array element nor use +a subscript, but the var(value) assigned may be any valid parameter +name syntax, even a subscripted array element (incuding an associative +array element) or an array slice, which is evaluated when the named +reference is expanded. +See ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)) and +ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)) for details of the +behavior of named references. + If no attribute flags are given, and either no var(name) arguments are present or the flag tt(+m) is used, then each parameter name printed is preceded by a list of the attributes of that parameter (tt(array), @@ -2242,9 +2256,9 @@ automatically given the tt(-h) attribute to avoid name clashes. item(tt(-H))( Hide value: specifies that tt(typeset) will not display the value of the parameter when listing parameters; the display for such parameters is -always as if the `tt(PLUS())' flag had been given. Use of the parameter is -in other respects normal, and the option does not apply if the parameter is -specified by name, or by pattern with the tt(-m) option. This is on by +always as if the `tt(PLUS())' flag were given, but use of the parameter is +in other respects normal. This effect does not apply when the parameter is +specified by name or by pattern with the tt(-m) option. This is on by default for the parameters in the tt(zsh/parameter) and tt(zsh/mapfile) modules. Note, however, that unlike the tt(-h) flag this is also useful for non-special parameters. diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index fd5443b20..ff6087cac 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1226,6 +1226,9 @@ for parameters with the `hide' flag (tt(-h)) item(tt(hideval))( for parameters with the `hideval' flag (tt(-H)) ) +item(tt(nameref))( +for named references having an empty value (tt(-n)) +) item(tt(special))( for special parameters defined by the shell ) @@ -1523,6 +1526,77 @@ Include the unmatched portion in the result (the em(R)est). ) enditem() +subsect(Named References) +cindex(named references) +cindex(namerefs) +cindex(reference variables) +cindex(parameters, nameref) +The command +ifzman() +indent(tt(typeset -n )var(pname)tt(=)var(rname)) + +initializes a parameter var(pname) as a reference to a second +parameter var(rname). With the few exceptions described here, when +var(pname) is used in any of the expansion forms described above, the +parameter var(rname) is expanded instead. This is similar to the +action of the `tt((P))' expansion flag, but when var(rname) has itself +been declared a named reference, that third parameter referenced by +var(pname) is also expanded, and so on. With `tt((P))' this must be +done explicitly, so for example +tt(${LPAR()P)tt(RPAR()${LPAR()P)tt(RPAR())var(name)tt(}}). + +Unlike `tt((P))', named references in substitutions that perform +assignment, such as tt(${)var(pname)tt(::=)var(word)tt(}), do not +create new arrays when var(rname) is in the form of an array element +or slice and no such array (or associative array) is presently set. +This includes arrays declared, but not initialized, when the option +tt(TYPESET_TO_UNSET) is in effect. The var(word) is substituted but +no assignment occurs. + +Also unlike `tt((P))' named references always expand parameters at +the scope in which var(rname) existed when `tt(typeset -n)' was +called. This can be used to expand or assign parameters from an +earlier scope even if a local of the same name has been declared at +a later scope. Example: +ifzman() +example(tt(caller=OUTER) +tt(func LPAR()RPAR() {) +tt( print before local: $caller) +tt( typeset -n outer=$1) +tt( local caller=INNER) +tt( print by reference: $outer) +tt( outer=RESULT) +tt(}) +tt(func caller) +tt(print after func: $caller)) + +displays the output +ifzman() +example(tt(before local: OUTER) +tt(by reference: OUTER) +tt(after func: RESULT)) + +When var(rname) includes an array subscript, the subscript expression +is interpreted at the time tt(${)var(pname)tt(}) is expanded. Any +form of subscript is allowed, including those that select individual +elements, substrings of scalar strings, or multiple elements as with +array slices or the `tt((i))', `tt((I))', `tt((r))', `tt((R))' and +`tt((w))' subscript flags. + +When var(rname) is an array (but not an array element or slice), the +named reference may also be used in substitutions requiring an +var(arrayname), so these are equivalent: +ifzman() +example(tt(${)var(name)tt(:|)var(rname)tt(}) +tt(${)var(name)tt(:|)var(pname)tt(})) + +Expansions of the form `tt(${LPAR()t)tt(RPAR())var(pname)tt(})' expand +the type information of var(rname), unless var(rname) is empty, in which +case `tt(nameref)' is expanded, or when no variable var(rname) exists, +in which case the expansion is empty. + +See also ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)). + subsect(Rules) cindex(parameter expansion rules) cindex(rules, parameter expansion) @@ -1545,12 +1619,16 @@ substitutions; the nested substitution will return either a scalar or an array as determined by the flags, possibly adjusted for quoting. All the following steps take place where applicable at all levels of substitution. -Note that, unless the `tt((P))' flag is present, the flags and any +Note that, unless the `tt((P))' flag or a named reference is present, +the flags and any subscripts apply directly to the value of the nested substitution; for example, the expansion tt(${${foo}}) behaves exactly the same as -tt(${foo}). When the `tt((P))' flag is present in a nested substitution, +tt(${foo}). When a named reference or the `tt((P))' flag is used in a +nested substitution, the other substitution rules are applied to the value em(before) it is interpreted as a name, so tt(${${(P)foo}}) may differ from tt(${(P)foo}). +When both a named reference and the `tt((P))' flag appear, the named +reference is resolved before `tt((P))' is applied. At each nested level of substitution, the substituted words undergo all forms of single-word substitution (i.e. not filename generation), including diff --git a/Doc/Zsh/mod_parameter.yo b/Doc/Zsh/mod_parameter.yo index 18fd3606e..0e89d65c8 100644 --- a/Doc/Zsh/mod_parameter.yo +++ b/Doc/Zsh/mod_parameter.yo @@ -125,7 +125,7 @@ zmanref(zshexpn) ifnzman(\ noderef(Parameter Expansion) )\ -. The value may also be `tt(undefined)' indicating a parameter that +. The value may also be `tt(undefined)' indicating a parameter that may be autoloaded from a module but has not yet been referenced. Setting or unsetting keys in this array is not possible. ) diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 55009c6de..2dfd5bd14 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -80,6 +80,7 @@ startmenu() menu(Array Parameters) menu(Positional Parameters) menu(Local Parameters) +menu(Named References) menu(Parameters Set By The Shell) menu(Parameters Used By The Shell) endmenu() @@ -592,7 +593,7 @@ array assignment of the form `var(n)tt(=LPAR())var(value) ...tt(RPAR())' is allowed, and has the effect of shifting all the values at positions greater than var(n) by as many positions as necessary to accommodate the new values. -texinode(Local Parameters)(Parameters Set By The Shell)(Positional Parameters)(Parameters) +texinode(Local Parameters)(Named References)(Positional Parameters)(Parameters) sect(Local Parameters) Shell function executions delimit scopes for shell parameters. (Parameters are dynamically scoped.) The tt(typeset) builtin, and its @@ -626,6 +627,49 @@ find the programs in tt(/new/directory) inside a function. Note that the restriction in older versions of zsh that local parameters were never exported has been removed. +cindex(named references) +cindex(references, named) +texinode(Named References)(Parameters Set By The Shell)(Local Parameters)(Parameters) +sect(Named References) +Zsh supports two different mechanisms for indirect parameter referencing: +ifzman() +example(tt(typeset )var(name)tt(=)var(rname) +tt(print -r -- ${LPAR()P)tt(RPAR())var(name)tt(})) +ifzman() +example(tt(typeset -n )var(pname)tt(=)var(rname) +tt(print -r -- ${)var(pname)tt(})) + +The `tt((P))' flag method is older and should be used when a script +needs to be backwards-compatible. This is described fully in +ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)). + +When a em(named reference) is created with `tt(typeset -n)', all uses +of var(pname) in assignments and expansions instead assign to or +expand var(rname). This also applies to `tt(unset )var(pname)' and to +most subsequent uses of `tt(typeset)' with the exception of +`tt(typeset +n)', so to remove a named reference it is necessary to +use: +ifzman() +example(tt(typeset +n )var(pname) +tt(unset )var(pname)) + +When `tt(typeset -n )var(pname)tt(=)var(rname)' appears in a given +(global or function) scope, `tt(${)var(pname)tt(})' refers to +var(rname) in the scope of the tt(typeset) command. This differs +from ksh93 where the scope used is that of var(rname) even if the +current var(rname) would be found in a surrounding scope. +em(This is a misfeature.) + +An empty reference such as one of +ifzman() +example(tt(typeset -n )var(pname) +tt(typeset -n )var(pname)tt(=) +tt(typeset -n )var(pname)tt(="")) + +acts as a placeholder. The first non-empty assignment to var(pname) +initializes the reference, and subsequently any expansions of, or +assignments to, var(pname) act on the referenced parameter. + texinode(Parameters Set By The Shell)(Parameters Used By The Shell)(Local Parameters)(Parameters) sect(Parameters Set By The Shell) In the parameter lists that follow, the mark `' indicates that the -- cgit v1.2.3 From 3e55a135c10d3582af22a3e6dc616f57ea212df8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 11:29:10 -0800 Subject: 51374: Expose named references in $parameters, fix substitution error. --- ChangeLog | 4 ++ Src/Modules/parameter.c | 11 +++-- Src/params.c | 10 ++++- Test/K01nameref.ztst | 105 ++++++++++++++++++++++++++++++++++++++++-------- Test/README | 1 + 5 files changed, 110 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 221b9838d..af448c5e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-02-12 Bart Schaefer + * 51374: Src/Modules/parameter.c, Src/params.c, Test/README, + Test/K01nameref.ztst: Expose named references in $parameters, + fix substitution error. + * 51362: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/params.yo, Doc/Zsh/mod_parameter.yo: Begin documentation for named references. diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index 5bf675e2a..a659300fd 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -105,10 +105,15 @@ getpmparameter(UNUSED(HashTable ht), const char *name) pm->node.nam = dupstring(name); pm->node.flags = PM_SCALAR | PM_READONLY; pm->gsu.s = &nullsetscalar_gsu; - if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) && - !(rpm->node.flags & PM_UNSET)) + if ((rpm = (Param) realparamtab->getnode2(realparamtab, name)) && + !(rpm->node.flags & PM_UNSET)) { pm->u.str = paramtypestr(rpm); - else { + if ((rpm->node.flags & PM_NAMEREF) && + (rpm = (Param) realparamtab->getnode(realparamtab, name)) && + !(rpm->node.flags & PM_UNSET)) { + pm->u.str = zhtricat(pm->u.str, "-", paramtypestr(rpm)); + } + } else { pm->u.str = dupstring(""); pm->node.flags |= (PM_UNSET|PM_SPECIAL); } diff --git a/Src/params.c b/Src/params.c index 69b7f484f..98950d88f 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2155,7 +2155,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) return NULL; if (ss) *ss = sav; - s = ss; + s = dyncat(ss,*pptr); } if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) { /* Overload v->isarr as the flag bits for hashed arrays. */ @@ -6170,6 +6170,7 @@ setscope(Param pm) { if (pm->node.flags & PM_NAMEREF) { Param basepm; + struct asgment stop; char *t = pm->u.str ? itype_end(pm->u.str, IIDENT, 0) : NULL; /* Temporarily change nameref to array parameter itself */ @@ -6177,7 +6178,12 @@ setscope(Param pm) *t = 0; else t = 0; - basepm = (Param)resolve_nameref(pm, NULL); + stop.name = ""; + stop.value.scalar = NULL; + stop.flags = PM_NAMEREF; + if (locallevel) + stop.flags |= PM_LOCAL; + basepm = (Param)resolve_nameref(pm, &stop); if (t) { pm->width = t - pm->u.str; *t = '['; diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index b38831100..a663194a7 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -1,11 +1,11 @@ -# Tests for the zsh/param/private module +# Tests for named references %prep # Required in order to declare an unset hash for substitution test setopt TYPESET_TO_UNSET - : ${ZTST_continue:=1} + : ${ZTST_continue::=1} %test @@ -53,7 +53,13 @@ F:Other type changes are fatal errors, should this also be? typeset var=value typeset -n ptr=var print $ptr -0:basic nameref expansion +0:basic nameref expansion, no braces +>value + + typeset var=value + typeset -n ptr=var + print ${ptr} +0:basic nameref expansion, braces >value typeset var=(val1 val2) @@ -115,9 +121,10 @@ F:Other type changes are fatal errors, should this also be? >typeset -n ptr=var >typeset -a var=( new1 new2 ) - typeset -p ptr1 ptr2 var + typeset -p ptr ptr1 ptr2 var 1:check state of paramtab ONE F:unexpected side-effects of previous tests +*?*no such variable: ptr *?*no such variable: ptr1 *?*no such variable: ptr2 *?*no such variable: var @@ -247,13 +254,24 @@ F:unexpected side-effects of previous tests typeset -n ptr2='path[2]' print -r -- $ptr2 -0d:nameref to array element +0q:nameref to array element, no braces +>${path[2]} + + typeset -n ptr2='path[2]' + print -r -- ${ptr2} +0q:nameref to array element, with braces >${path[2]} typeset -A hash=(x MISS y HIT) typeset -n ptr1='hash[y]' print -r -- $ptr1 -0:nameref to hash element +0:nameref to hash element, no braces +>HIT + + typeset -A hash=(x MISS y HIT) + typeset -n ptr1='hash[y]' + print -r -- ${ptr1} +0:nameref to hash element, with braces >HIT typeset -a ary=(1 2) @@ -362,16 +380,16 @@ F:unexpected side-effects of previous tests >typeset -n ptr=lval >typeset -n ptr=gval + typeset -A var=(myself outside) () { - zmodload -u zsh/parameter - typeset -n myself=parameters[myself] - local -h parameters + typeset -n myself=var[myself] + local -h var print -r -- $myself - typeset -p parameters + typeset -p var } -0:up-reference part 3, autoloading with hidden special ->nameref-local ->typeset parameters +0:up-reference part 3, hidden global +>outside +>typeset var () { typeset notdef @@ -401,7 +419,7 @@ F:unexpected side-effects of previous tests 1:up-reference part 5, stacked namerefs, end not in scope F:What is the correct behavior for the scope of ptr1? >typeset -n ptr1=ptr2 ->typeset -n ptr2='' +>typeset -n ptr2 >ptr1=ptr2 >ptr2=val >ptr1=LOCAL @@ -427,13 +445,68 @@ F:What is the correct behavior for the scope of ptr1? 0:up-reference part 6, stacked namerefs, end is in scope F:Same test, should part 5 output look like this? >typeset -n ptr1=ptr2 ->typeset -n ptr2='' +>typeset -n ptr2 >ptr1=ptr2 ->ptr2='' +>ptr2 >ptr1=val >ptr2= >typeset -n ptr1=ptr2 >typeset -n ptr2='' >typeset ptr2=val + if zmodload zsh/parameter; then + () { + zmodload -u zsh/parameter + typeset -n myself=parameters[myself] + local -h parameters + print -r -- $myself + typeset -p parameters + } + else ZTST_skip='Cannot zmodload zsh/parameter, skipping autoload test' + fi +0:up-reference part 3, autoloading with hidden special +>nameref-local-nameref-local +>typeset parameters + + typeset ptr2=var2 + typeset var2=GLOBAL + () { + typeset -n ptr1=ptr2 + typeset ptr2=var1 + typeset var1=VAR1 + typeset var2=VAR2 + print -r -- ${(P)ptr1} + } +0: +>VAR2 + + ary=(one two three four) + typeset -n ptr=ary + print -r ${(j.:.)ptr//o/0} +0:expansion flags and string replacement +>0ne:tw0:three:f0ur + + var=value + typeset -n ptr=var + myscalar=ptr + echo ${(P)myscalar} +0:named references with (P), as ${(P)name_of_nameref} +>value + + var=value + myscalar=var + typeset -n ptr=myscalar + echo ${(P)ptr} +0:named references with (P), as ${(P)nameref} +>value + + ary=( 'bry[1]' 'bry[2]' ) + bry=( lorem ipsum ) + typeset -n ptr='ary[2]' + print -r -- ${ptr} + print -r -- ${(P)ptr} +0:named references with (P), array element to array element +>bry[2] +>ipsum + %clean diff --git a/Test/README b/Test/README index 670434ac3..b9d393d7c 100644 --- a/Test/README +++ b/Test/README @@ -6,6 +6,7 @@ scripts names: C: shell commands with special syntax D: substititution E: options + K: features adopted from ksh P: privileged (needs super-user privileges) V: modules W: builtin interactive commands and constructs -- cgit v1.2.3 From e807ac1157015581c1466407cbe722179244be37 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 11:32:11 -0800 Subject: 51375: Clarify documentation, fix typos, add indexing. --- ChangeLog | 3 +++ Doc/Zsh/builtins.yo | 12 +++++++++--- Doc/Zsh/expn.yo | 4 ++-- Doc/Zsh/mod_parameter.yo | 8 ++++++++ Doc/Zsh/params.yo | 36 ++++++++++++++++++++++-------------- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index af448c5e3..1353de45d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-02-12 Bart Schaefer + * 51375: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/params.yo, + Doc/Zsh/mod_parameter.yo: Clarify, fix typos, add indexing. + * 51374: Src/Modules/parameter.c, Src/params.c, Test/README, Test/K01nameref.ztst: Expose named references in $parameters, fix substitution error. diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 64c47346f..97a82226b 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2041,16 +2041,22 @@ cindex(named reference) cindex(reference, named) The flag tt(-n) creates a em(named reference) to another parameter. The second parameter need not exist at the time the reference is -created. No other attribute flags may be used in conjunction with -tt(-n). The var(name) assigned-to may not be an array element nor use +created. No attributes except tt(-g) may be used in conjunction with +tt(-n). The var(name) so created may not be an array element nor use a subscript, but the var(value) assigned may be any valid parameter -name syntax, even a subscripted array element (incuding an associative +name syntax, even a subscripted array element (including an associative array element) or an array slice, which is evaluated when the named reference is expanded. See ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)) and ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)) for details of the behavior of named references. +Local function scoping rules for `tt(typeset)' do apply with `tt(-n)', +so a declaration within a function persists only until the end of the +function unless `tt(-g -n)' is specified, and any local parameter (of +any type) with the same var(name) supplants a named reference from a +surrounding scope. + If no attribute flags are given, and either no var(name) arguments are present or the flag tt(+m) is used, then each parameter name printed is preceded by a list of the attributes of that parameter (tt(array), diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index ff6087cac..8b1c69c55 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1592,8 +1592,8 @@ tt(${)var(name)tt(:|)var(pname)tt(})) Expansions of the form `tt(${LPAR()t)tt(RPAR())var(pname)tt(})' expand the type information of var(rname), unless var(rname) is empty, in which -case `tt(nameref)' is expanded, or when no variable var(rname) exists, -in which case the expansion is empty. +case the expansion is `tt(nameref)', or when no variable var(rname) +exists, in which case the expansion is empty. See also ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)). diff --git a/Doc/Zsh/mod_parameter.yo b/Doc/Zsh/mod_parameter.yo index 0e89d65c8..3defef2b7 100644 --- a/Doc/Zsh/mod_parameter.yo +++ b/Doc/Zsh/mod_parameter.yo @@ -127,6 +127,14 @@ noderef(Parameter Expansion) )\ . The value may also be `tt(undefined)' indicating a parameter that may be autoloaded from a module but has not yet been referenced. +When the key is the name of a named reference, the value is +`tt(nameref-)' prepended to the type of the referenced parameter, +for example +ifzman() +example(tt(% typeset -n parms=parameters) +tt(% print -r ${parameters[parms]}) +tt(nameref-association-readonly-hide-hideval-special)) + Setting or unsetting keys in this array is not possible. ) vindex(modules) diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 2dfd5bd14..c7ecf0f64 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -85,6 +85,8 @@ menu(Parameters Set By The Shell) menu(Parameters Used By The Shell) endmenu() texinode(Array Parameters)(Positional Parameters)()(Parameters) +cindex(array parameters) +cindex(parameters, array) sect(Array Parameters) To assign an array value, write one of: findex(set, use of) @@ -567,6 +569,8 @@ entire second parameter concatenated with the filename generation pattern `tt([3,5])'. texinode(Positional Parameters)(Local Parameters)(Array Parameters)(Parameters) +cindex(positional parameters) +cindex(parameters, positional) sect(Positional Parameters) The positional parameters provide access to the command-line arguments of a shell function, shell script, or the shell itself; see @@ -594,6 +598,8 @@ allowed, and has the effect of shifting all the values at positions greater than var(n) by as many positions as necessary to accommodate the new values. texinode(Local Parameters)(Named References)(Positional Parameters)(Parameters) +cindex(local parameters) +cindex(parameters, local) sect(Local Parameters) Shell function executions delimit scopes for shell parameters. (Parameters are dynamically scoped.) The tt(typeset) builtin, and its @@ -627,9 +633,9 @@ find the programs in tt(/new/directory) inside a function. Note that the restriction in older versions of zsh that local parameters were never exported has been removed. +texinode(Named References)(Parameters Set By The Shell)(Local Parameters)(Parameters) cindex(named references) cindex(references, named) -texinode(Named References)(Parameters Set By The Shell)(Local Parameters)(Parameters) sect(Named References) Zsh supports two different mechanisms for indirect parameter referencing: ifzman() @@ -641,24 +647,24 @@ tt(print -r -- ${)var(pname)tt(})) The `tt((P))' flag method is older and should be used when a script needs to be backwards-compatible. This is described fully in -ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)). +the Parameter Expansion Flags section of +ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)). Zsh +versions em(greater than) tt(5.9.0) are required for `tt(typeset -n)'. +This manual was generated with Zsh tt(version()). When a em(named reference) is created with `tt(typeset -n)', all uses of var(pname) in assignments and expansions instead assign to or expand var(rname). This also applies to `tt(unset )var(pname)' and to most subsequent uses of `tt(typeset)' with the exception of -`tt(typeset +n)', so to remove a named reference it is necessary to -use: +`tt(typeset -n)' and `tt(typeset +n)', so to remove a named reference +it is necessary to use one of: ifzman() -example(tt(typeset +n )var(pname) -tt(unset )var(pname)) +example(tt(typeset -n )var(pname) +tt(typeset +n )var(pname)) -When `tt(typeset -n )var(pname)tt(=)var(rname)' appears in a given -(global or function) scope, `tt(${)var(pname)tt(})' refers to -var(rname) in the scope of the tt(typeset) command. This differs -from ksh93 where the scope used is that of var(rname) even if the -current var(rname) would be found in a surrounding scope. -em(This is a misfeature.) +followed by +ifzman() +indent(tt(unset )var(pname)) An empty reference such as one of ifzman() @@ -668,9 +674,11 @@ tt(typeset -n )var(pname)tt(="")) acts as a placeholder. The first non-empty assignment to var(pname) initializes the reference, and subsequently any expansions of, or -assignments to, var(pname) act on the referenced parameter. +assignments to, var(pname) act on the referenced parameter. This +is explained in the Named References section of +ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)). -texinode(Parameters Set By The Shell)(Parameters Used By The Shell)(Local Parameters)(Parameters) +texinode(Parameters Set By The Shell)(Parameters Used By The Shell)(Named References)(Parameters) sect(Parameters Set By The Shell) In the parameter lists that follow, the mark `' indicates that the parameter is special. `' indicates that the parameter does not exist -- cgit v1.2.3 From 3eed6f70cdfea63cfdc380a4df8382fff38af55d Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 11:51:41 -0800 Subject: 51402: Some ksh/bash features, additional sanity checking * Add "unset -n" * Allow and enforce "typeset -n -r" for read-only references * "can't change type via subscript reference" error * Better checking for self-referential declarations/assignments * Ksh-style "foo=bar; typeset -n foo" creates foo=bar reference * Support "typeset -n ref; for ref in ..." * Subscripted references use NO_EXEC for safety * References assigned in called scopes reset scope at end * Allow named references to $! $? $$ $- $0 $_ --- ChangeLog | 5 ++++ Src/builtin.c | 49 +++++++++++++++++++++++-------- Src/loop.c | 6 ++-- Src/params.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- Src/zsh.h | 4 +++ 5 files changed, 129 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1353de45d..2b2f2a08b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2023-02-12 Bart Schaefer + * 51402: Src/builtin.c, Src/loop.c, Src/params.c, Src/zsh.h: + Add ksh/bash features (unset -n, for ref), readonly refs, + better error checking and messages, code injection safety, + allow references to $! $? $$ $- $0 $_ + * 51375: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/params.yo, Doc/Zsh/mod_parameter.yo: Clarify, fix typos, add indexing. diff --git a/Src/builtin.c b/Src/builtin.c index 8039b644e..cf7e9d9fe 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -126,7 +126,7 @@ static struct builtin builtins[] = BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL), BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"), BUILTIN("unhash", 0, bin_unhash, 1, -1, BIN_UNHASH, "adfms", NULL), - BUILTIN("unset", BINF_PSPECIAL, bin_unset, 1, -1, BIN_UNSET, "fmv", NULL), + BUILTIN("unset", BINF_PSPECIAL, bin_unset, 1, -1, BIN_UNSET, "fmvn", NULL), BUILTIN("unsetopt", 0, bin_setopt, 0, -1, BIN_UNSETOPT, NULL, NULL), BUILTIN("wait", 0, bin_fg, 0, -1, BIN_WAIT, NULL, NULL), BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsSwx:", NULL), @@ -2034,11 +2034,16 @@ typeset_single(char *cname, char *pname, Param pm, int func, if (!(off & PM_NAMEREF)) pm = (Param)resolve_nameref(pm, NULL); if (pm && (pm->node.flags & PM_NAMEREF) && - (on & ~(PM_NAMEREF|PM_LOCAL))) { + (on & ~(PM_NAMEREF|PM_LOCAL|PM_READONLY))) { /* Changing type of PM_SPECIAL|PM_AUTOLOAD is a fatal error. * * Should this be a fatal error as well, rather than warning? */ - zwarnnam(cname, "%s: can't change type of a named reference", - pname); + if (pm->width) + zwarnnam(cname, + "%s: can't change type via subscript reference", + pm->u.str); + else + zwarnnam(cname, "%s: can't change type of a named reference", + pname); return NULL; } } @@ -2223,6 +2228,11 @@ typeset_single(char *cname, char *pname, Param pm, int func, zerrnam(cname, "%s: restricted", pname); return pm; } + if ((pm->node.flags & PM_READONLY) && + (pm->node.flags & PM_NAMEREF & off)) { + zerrnam(cname, "%s: read-only reference", pname); + return pm; + } if ((on & PM_UNIQUE) && !(pm->node.flags & PM_READONLY & ~off)) { Param apm; char **x; @@ -2659,7 +2669,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) off |= bit; } if (OPT_MINUS(ops,'n')) { - if (on|off) { + if ((on & ~PM_READONLY)|off) { zwarnnam(name, "no other attributes allowed with -n"); return 1; } @@ -3051,9 +3061,8 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) if (on & PM_NAMEREF) { if (asg->value.scalar && - (strcmp(asg->name, asg->value.scalar) == 0 || - ((pm = (Param)resolve_nameref((Param)hn, asg)) && - (pm->node.flags & PM_NAMEREF)))) { + ((pm = (Param)resolve_nameref((Param)hn, asg)) && + (pm->node.flags & PM_NAMEREF))) { if (pm->node.flags & PM_SPECIAL) zwarnnam(name, "%s: invalid reference", pm->node.nam); else @@ -3063,8 +3072,12 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) } if (hn) { /* namerefs always start over fresh */ - if (((Param)hn)->level >= locallevel) + if (((Param)hn)->level >= locallevel) { + Param oldpm = (Param)hn; + if (!asg->value.scalar && oldpm->u.str) + asg->value.scalar = dupstring(oldpm->u.str); unsetparam_pm((Param)hn, 0, 1); + } hn = NULL; } } @@ -3762,7 +3775,11 @@ bin_unset(char *name, char **argv, Options ops, int func) if ((!(pm->node.flags & PM_RESTRICTED) || unset(RESTRICTED)) && pattry(pprog, pm->node.nam)) { - unsetparam_pm(pm, 0, 1); + if (!OPT_ISSET(ops,'n') && + (pm->node.flags & PM_NAMEREF) && pm->u.str) + unsetparam(pm->u.str); + else + unsetparam_pm(pm, 0, 1); match++; } } @@ -3814,6 +3831,11 @@ bin_unset(char *name, char **argv, Options ops, int func) zerrnam(name, "%s: restricted", pm->node.nam); returnval = 1; } else if (ss) { + if ((pm->node.flags & PM_NAMEREF) && + (!(pm = (Param)resolve_nameref(pm, NULL)) || pm->width)) { + /* warning? */ + continue; + } if (PM_TYPE(pm->node.flags) == PM_HASHED) { HashTable tht = paramtab; if ((paramtab = pm->gsu.h->getfn(pm))) @@ -3852,8 +3874,11 @@ bin_unset(char *name, char **argv, Options ops, int func) returnval = 1; } } else { - if ((pm = (Param)resolve_nameref(pm, NULL)) && - unsetparam_pm(pm, 0, 1)) + if (!OPT_ISSET(ops,'n')) { + if (!(pm = (Param)resolve_nameref(pm, NULL))) + continue; + } + if (unsetparam_pm(pm, 0, 1)) returnval = 1; } if (ss) diff --git a/Src/loop.c b/Src/loop.c index 7df379ecf..0f3847541 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -53,7 +53,7 @@ execfor(Estate state, int do_exec) wordcode code = state->pc[-1]; int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND), ctok = 0, atok = 0; int last = 0; - char *name, *str, *cond = NULL, *advance = NULL; + char *str, *cond = NULL, *advance = NULL; zlong val = 0; LinkList vars = NULL, args = NULL; int old_simple_pline = simple_pline; @@ -151,7 +151,7 @@ execfor(Estate state, int do_exec) int count = 0; for (node = firstnode(vars); node; incnode(node)) { - name = (char *)getdata(node); + char *name = (char *)getdata(node); if (!args || !(str = (char *) ugetnode(args))) { if (count) { @@ -165,7 +165,7 @@ execfor(Estate state, int do_exec) fprintf(xtrerr, "%s=%s\n", name, str); fflush(xtrerr); } - setsparam(name, ztrdup(str)); + setloopvar(name, ztrdup(str)); count++; } if (!count) diff --git a/Src/params.c b/Src/params.c index 98950d88f..4910d65fe 100644 --- a/Src/params.c +++ b/Src/params.c @@ -997,7 +997,7 @@ createparam(char *name, int flags) paramtab->getnode(paramtab, name)); if (oldpm && (oldpm->node.flags & PM_NAMEREF) && - !(flags & PM_NAMEREF)) { + !(flags & PM_NAMEREF) && (oldpm = upscope(oldpm, oldpm->base))) { Param lastpm; struct asgment stop; stop.flags = PM_NAMEREF | (flags & PM_LOCAL); @@ -1467,10 +1467,14 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, if (ishash && (keymatch || !rev)) remnulargs(s); if (needtok) { + char exe = opts[EXECOPT]; s = dupstring(s); if (parsestr(&s)) return 0; + if (flags & SCANPM_NOEXEC) + opts[EXECOPT] = 0; singsub(&s); + opts[EXECOPT] = exe; } else if (rev) remnulargs(s); /* This is probably always a no-op, but ... */ if (!rev) { @@ -2153,9 +2157,12 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) ((pm->node.flags & PM_UNSET) && !(pm->node.flags & PM_DECLARED))) return NULL; - if (ss) + if (ss) { + flags |= SCANPM_NOEXEC; *ss = sav; - s = dyncat(ss,*pptr); + s = dyncat(ss,*pptr); + } else + s = *pptr; } if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) { /* Overload v->isarr as the flag bits for hashed arrays. */ @@ -5782,7 +5789,8 @@ scanendscope(HashNode hn, UNUSED(int flags)) export_param(pm); } else unsetparam_pm(pm, 0, 0); - } + } else if ((pm->node.flags & PM_NAMEREF) && pm->base > pm->level) + pm->base = locallevel; } @@ -6109,10 +6117,10 @@ resolve_nameref(Param pm, const Asgment stop) if (pm && (pm->node.flags & (PM_UNSET|PM_TAGGED))) { /* Semaphore with createparam() */ pm->node.flags &= ~PM_UNSET; - /* See V10private.ztst end is in scope but private: - if (pm->node.flags & PM_SPECIAL) + if (pm->node.flags & PM_NEWREF) /* See setloopvar() */ return NULL; - */ + if (pm->u.str && *(pm->u.str) && (pm->node.flags & PM_TAGGED)) + pm->node.flags |= PM_SELFREF; /* See setscope() */ return (HashNode) pm; } else if (pm->u.str) { if ((pm->node.flags & PM_TAGGED) || @@ -6157,13 +6165,29 @@ resolve_nameref(Param pm, const Asgment stop) if (pm) pm->node.flags &= ~PM_TAGGED; } else if (stop && (stop->flags & PM_NAMEREF)) - hn = (HashNode)pm; + hn = (pm && (pm->node.flags & PM_NEWREF)) ? NULL : (HashNode)pm; unqueue_signals(); } return hn; } +/**/ +mod_export void +setloopvar(char *name, char *value) +{ + Param pm = (Param) gethashnode2(realparamtab, name); + + if (pm && (pm->node.flags & PM_NAMEREF)) { + pm->base = pm->width = 0; + pm->u.str = ztrdup(value); + pm->node.flags |= PM_NEWREF; + setscope(pm); + pm->node.flags &= ~PM_NEWREF; + } else + setsparam(name, value); +} + /**/ static void setscope(Param pm) @@ -6188,9 +6212,50 @@ setscope(Param pm) pm->width = t - pm->u.str; *t = '['; } - if (basepm) - pm->base = ((basepm->node.flags & PM_NAMEREF) ? - basepm->base : basepm->level); + if (basepm) { + if (basepm->node.flags & PM_NAMEREF) { + if (pm == basepm) { + if (pm->node.flags & PM_SELFREF) { + /* Loop signalled by resolve_nameref() */ + if (upscope(pm, pm->base) == pm) { + zerr("%s: invalid self reference", pm->u.str); + unsetparam_pm(pm, 0, 1); + return; + } + pm->node.flags &= ~PM_SELFREF; + } else if (pm->base == pm->level) { + if (pm->u.str && *(pm->u.str) && + strcmp(pm->node.nam, pm->u.str) == 0) { + zerr("%s: invalid self reference", pm->u.str); + unsetparam_pm(pm, 0, 1); + return; + } + } + } else if (basepm->u.str) { + if (basepm->base <= basepm->level && + strcmp(pm->node.nam, basepm->u.str) == 0) { + zerr("%s: invalid self reference", pm->u.str); + unsetparam_pm(pm, 0, 1); + return; + } + } + } else + pm->base = basepm->level; + } + if (pm->base > pm->level) { + if (EMULATION(EMULATE_KSH)) { + zerr("%s: global reference cannot refer to local variable", + pm->node.nam); + unsetparam_pm(pm, 0, 1); + } else if (isset(WARNNESTEDVAR)) + zwarn("%s: global reference to local variable: %s", + pm->node.nam, pm->u.str); + } + if (pm->u.str && upscope(pm, pm->base) == pm && + strcmp(pm->node.nam, pm->u.str) == 0) { + zerr("%s: invalid self reference", pm->u.str); + unsetparam_pm(pm, 0, 1); + } } } @@ -6217,7 +6282,10 @@ valid_refname(char *val) if (*t == '[') { tokenize(t = dupstring(t+1)); t = parse_subscript(t, 0, ']'); - } else { + } else if (t[1] || !(*t == '!' || *t == '?' || + *t == '$' || *t == '-' || + *t == '0' || *t == '_')) { + /* Skipping * @ # because of doshfunc() implementation */ t = NULL; } } diff --git a/Src/zsh.h b/Src/zsh.h index 1e35bd33e..96b4b06bd 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1935,6 +1935,9 @@ struct tieddata { #define PM_NAMEDDIR (1<<29) /* has a corresponding nameddirtab entry */ #define PM_NAMEREF (1<<30) /* pointer to a different parameter */ +#define PM_SELFREF PM_UNIQUE /* Overload when namerefs resolved */ +#define PM_NEWREF PM_SINGLE /* Overload in for-loop namerefs */ + /* The option string corresponds to the first of the variables above */ #define TYPESET_OPTSTR "aiEFALRZlurtxUhHT" @@ -1959,6 +1962,7 @@ struct tieddata { * elements */ #define SCANPM_CHECKING (1<<10) /* Check if set, no need to create */ +#define SCANPM_NOEXEC (1<<11) /* No command substitutions, etc. */ /* "$foo[@]"-style substitution * Only sign bit is significant */ -- cgit v1.2.3 From acb15e3cc9af6c5b51e570765e6734e958d32aef Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 11:57:31 -0800 Subject: 51403: Tests and documentation for 51402, clean up some other tests. --- ChangeLog | 4 ++ Doc/Zsh/builtins.yo | 16 +++-- Doc/Zsh/expn.yo | 5 +- Doc/Zsh/func.yo | 34 +++++++++++ Doc/Zsh/grammar.yo | 3 + Doc/Zsh/params.yo | 4 +- Test/K01nameref.ztst | 170 ++++++++++++++++++++++++++++++++++++++++++++++++--- 7 files changed, 218 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b2f2a08b..0cc33c7f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-02-12 Bart Schaefer + * 51403: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/func.yo, + Doc/Zsh/grammar.yo, Doc/Zsh/params.yo, Test/K01nameref.ztst: + Tests and documentation for 51402, clean up some other tests. + * 51402: Src/builtin.c, Src/loop.c, Src/params.c, Src/zsh.h: Add ksh/bash features (unset -n, for ref), readonly refs, better error checking and messages, code injection safety, diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 97a82226b..92917c06c 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2041,12 +2041,13 @@ cindex(named reference) cindex(reference, named) The flag tt(-n) creates a em(named reference) to another parameter. The second parameter need not exist at the time the reference is -created. No attributes except tt(-g) may be used in conjunction with +created. Only tt(-g) and tt(-r) may be used in conjunction with tt(-n). The var(name) so created may not be an array element nor use a subscript, but the var(value) assigned may be any valid parameter name syntax, even a subscripted array element (including an associative array element) or an array slice, which is evaluated when the named -reference is expanded. +reference is expanded. It is an error for a named reference to refer +to itself, even indirectly through a chain of references. See ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)) and ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)) for details of the behavior of named references. @@ -2443,7 +2444,7 @@ with the command `tt(zmodload -F zsh/rlimits b:unlimit)'. ) findex(unset) cindex(parameters, unsetting) -item(tt(unset) [ tt(-fmv) ] var(name) ...)( +item(tt(unset) [ tt(-fmv) ] [ tt(-n) ] var(name) ...)( Each named parameter is unset. Local parameters remain local even if unset; they appear unset within scope, but the previous value will still reappear when the scope ends. @@ -2457,10 +2458,13 @@ be quoted) and all parameters with matching names are unset. Note that this cannot be used when unsetting associative array elements, as the subscript will be treated as part of the pattern. -The tt(-v) flag specifies that var(name) refers to parameters. This is the -default behaviour. +The tt(-v) flag specifies that var(name) refers to parameters. This is +the default behaviour. If the tt(-n) option is supplied, and +var(name) is a a named reference, var(name) will be unset rather than +the variable it references. -tt(unset -f) is equivalent to tt(unfunction). +tt(unset -f) is equivalent to tt(unfunction). The tt(-n) option has +no effect with tt(-f). ) findex(unsetopt) cindex(options, unsetting) diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 8b1c69c55..ef01794e6 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1581,7 +1581,10 @@ is interpreted at the time tt(${)var(pname)tt(}) is expanded. Any form of subscript is allowed, including those that select individual elements, substrings of scalar strings, or multiple elements as with array slices or the `tt((i))', `tt((I))', `tt((r))', `tt((R))' and -`tt((w))' subscript flags. +`tt((w))' subscript flags. However, the subscript is evaluated with +the tt(NO_EXEC) option in effect, so command substitution and other +similar constructs produce no output, although are not syntactically +excluded. When var(rname) is an array (but not an array element or slice), the named reference may also be used in substitutions requiring an diff --git a/Doc/Zsh/func.yo b/Doc/Zsh/func.yo index 12db3f56a..d4914df7a 100644 --- a/Doc/Zsh/func.yo +++ b/Doc/Zsh/func.yo @@ -13,6 +13,40 @@ Functions are executed like commands with the arguments passed as positional parameters. (See noderef(Command Execution).) +Parameters declared by any of the `tt(typeset)' family of commands +during the execution of a function become em(local) to the function +unless the `tt(-g)' option is used. This is the em(scope) of the +parameter, which extends dynamically to any other functions called by +the declaring function. In most cases, local parameters take the +place of any other parameter having the same name that was assigned or +declared in an earlier function scope. +(See noderef(Local Parameters).) + +A named parameter declared with the `tt(-n)' option to any of the +`tt(typeset)' commands becomes a reference to a parameter in scope at +the time of assignment to the named reference, which may be at a +different call level than the declaring function. For this reason, +it is good practice to declare a named reference as soon as the +referent parameter is in scope, and as early as possible in the +function if the reference is to a parameter in a calling scope. + +A typical use of named references is to pass the name +of the referent as a positional parameter. For example, +ifzman() +example(pop+LPAR()RPAR() { + local -n ref=$1 + local last=$ref[$#ref] + ref[$#ref]=LPAR()RPAR() + print -r -- $last +} +array=LPAR() a list of five values RPAR() +pop array) + +prints the word `tt(values)' and shortens `tt($array)' to +`tt(LPAR() a list of five RPAR())'. There are no local parameters in +tt(pop) at the time `tt(ref=$1)' is assigned, so `tt(ref)' becomes a +reference to `tt(array)' in the caller. + Functions execute in the same process as the caller and share all files and present working directory with the diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo index 9af211090..1b834f41a 100644 --- a/Doc/Zsh/grammar.yo +++ b/Doc/Zsh/grammar.yo @@ -187,6 +187,9 @@ Expand the list of var(word)s, and set the parameter var(name) to each of them in turn, executing var(list) each time. If the `tt(in) var(word)' is omitted, use the positional parameters instead of the var(word)s. +If any var(name) has been declared as a named reference, +the corresponding var(word) is treated as the name of a +parameter and var(name) is made a reference to that. The var(term) consists of one or more newline or tt(;) which terminate the var(word)s, and are optional when the diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index c7ecf0f64..946c00793 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -656,8 +656,8 @@ When a em(named reference) is created with `tt(typeset -n)', all uses of var(pname) in assignments and expansions instead assign to or expand var(rname). This also applies to `tt(unset )var(pname)' and to most subsequent uses of `tt(typeset)' with the exception of -`tt(typeset -n)' and `tt(typeset +n)', so to remove a named reference -it is necessary to use one of: +`tt(typeset -n)' and `tt(typeset +n)', so to remove a named reference, +use either `tt(unset -n )var(pname)' or one of: ifzman() example(tt(typeset -n )var(pname) tt(typeset +n )var(pname)) diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index a663194a7..61c2b006a 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -23,6 +23,12 @@ ptr=var typeset -n 0:assign nameref placeholder +>ptr=var + + typeset ptr=var + typeset -n ptr + typeset -n +0:convert scalar to nameref >ptr=var typeset -n ptr=var @@ -46,6 +52,11 @@ F:Other type changes are fatal errors, should this also be? >typeset -n ptr=var >typeset -t var + typeset -n ptr=var[2] + typeset -t ptr +1:change type of referenced array element +*?*var\[2\]: can't change type via subscript reference + typeset -n ptr[1]=var 1:illegal nameref name *?*reference variable cannot be an array @@ -91,6 +102,14 @@ F:Other type changes are fatal errors, should this also be? typeset -p var 0:unset via nameref + typeset -n ptr=var + typeset var=value + unset -n ptr + typeset -p var ptr +0:unset of the nameref itself +F:If earlier tests change, might get "no such variable" here +>typeset var=value + typeset -n ptr=var typeset var=value typeset -p ptr var @@ -105,11 +124,11 @@ F:Other type changes are fatal errors, should this also be? typeset -n ptr=var ptr=value typeset -p var ptr - unset var # for next test 0:assign new scalar via nameref >typeset -g var=value >typeset -n ptr=var + unset var typeset -n ptr=var typeset var=(val1 val2) typeset -p ptr var @@ -132,11 +151,11 @@ F:unexpected side-effects of previous tests typeset -n ptr=var ptr=(val1 val2) typeset -p var ptr - unset var # for next test 0:assign new array via nameref >typeset -g -a var=( val1 val2 ) >typeset -n ptr=var + unset var typeset -n ptr2=var typeset -n ptr1=ptr2 typeset var=value @@ -178,12 +197,12 @@ F:unexpected side-effects of previous tests typeset -n ptr1=ptr2 typeset ptr1=newvalue typeset -p ptr1 ptr2 var - unset var # for next test 0:typeset new parameter indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset var=newvalue + unset var typeset -n ptr2=var typeset -n ptr1=ptr2 typeset var=value @@ -219,19 +238,18 @@ F:unexpected side-effects of previous tests typeset -n ptr1=ptr2 typeset ptr1=(val1 val2) typeset -p ptr1 ptr2 var - unset var # for next test 0:typeset new array indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset -a var=( val1 val2 ) - typeset -p ptr1 ptr2 var + typeset -p ptr1 ptr2 1:check state of paramtab FOUR F:unexpected side-effects of previous tests *?*no such variable: ptr1 *?*no such variable: ptr2 -*?*no such variable: var + unset var typeset -n ptr2=var typeset -n ptr1=ptr2 ptr1=(val1 val2) @@ -244,6 +262,20 @@ F:unexpected side-effects of previous tests typeset -n ptr1=ptr2 typeset -n ptr2=ptr1 1:direct nameref loop not allowed +*?*invalid self reference + + unset var + typeset -gn ptr1=var + typeset -p ptr1 +0:global reference to unset var +>typeset -g -n ptr1=var + + unset -n ptr1 + typeset -gn ptr1 + typeset -p ptr1 + ptr1=ptr1 +1:global direct reference +>typeset -g -n ptr1 *?*invalid self reference typeset -n ptr1=ptr2 @@ -252,28 +284,39 @@ F:unexpected side-effects of previous tests 1:indirect nameref loop not allowed *?*invalid self reference + typeset -n ptr1 ptr2 + ptr1=ptr2 + ptr2=ptr1 +1:looping assignment not allowed +*?*invalid self reference + + unset -n ptr2 typeset -n ptr2='path[2]' print -r -- $ptr2 0q:nameref to array element, no braces >${path[2]} + unset -n ptr2 typeset -n ptr2='path[2]' print -r -- ${ptr2} 0q:nameref to array element, with braces >${path[2]} + unset -n ptr1 typeset -A hash=(x MISS y HIT) typeset -n ptr1='hash[y]' print -r -- $ptr1 0:nameref to hash element, no braces >HIT + unset -n ptr1 typeset -A hash=(x MISS y HIT) typeset -n ptr1='hash[y]' print -r -- ${ptr1} 0:nameref to hash element, with braces >HIT + unset -n ptr2 typeset -a ary=(1 2) typeset -n ptr2='ary[2]' ptr2=TWO @@ -281,6 +324,7 @@ F:unexpected side-effects of previous tests 0:assign array element by nameref >typeset -a ary=( 1 TWO ) + unset -n ptr2 typeset -n ptr2='ary[2]' ptr2=TWO typeset -p ary @@ -288,6 +332,7 @@ F:unexpected side-effects of previous tests F:ksh93 does not implement this either >typeset -a ary=( '' TWO ) + unset -n ptr1 typeset -A hash=(x MISS y MISS) typeset -n ptr1='hash[y]' ptr1=HIT @@ -295,6 +340,7 @@ F:ksh93 does not implement this either 0:assign to hash element by nameref >typeset -A hash=( [x]=MISS [y]=HIT ) + unset -n ptr1 typeset -A hash typeset -n ptr1='hash[y]' ptr1=HIT @@ -303,10 +349,13 @@ F:ksh93 does not implement this either F:ksh93 does not implement this either >typeset -A hash=( [y]=HIT ) + unset -n ptr1 typeset -n ptr1='not good' 1:invalid nameref *?*invalid variable name: not good + unset -n ptr1 + unset hash typeset -A hash typeset -n ptr1='hash[y]' print ${ptr1::=HIT} @@ -316,24 +365,25 @@ F:ksh93 does not implement this either >typeset -n ptr1='hash[y]' >typeset -A hash=( [y]=HIT ) + unset -n ptr + unset gval typeset -n ptr=gval gval=global () { local gval=local; print $ptr; typeset -p ptr gval } - unset gval # for next test 0:up-reference part 1 >global >typeset -g -n ptr=gval >typeset gval=local - typeset -p ptr ptr1 ptr2 val gval + typeset -p ptr ptr1 ptr2 val 1:check state of paramtab FIVE F:unexpected side-effects of previous tests *?*no such variable: ptr *?*no such variable: ptr1 *?*no such variable: ptr2 *?*no such variable: val -*?*no such variable: gval + unset gval typeset -n ptr1=gval typeset gval () { typeset gval=local; ptr1=global } @@ -509,4 +559,106 @@ F:Same test, should part 5 output look like this? >bry[2] >ipsum + unset -n ref + unset var + typeset -n ref=var + typeset var=GLOBAL + () { + typeset -n ref=$1 + print -r $ref + ref=RESET + typeset -p ref var + } ref + typeset -p ref var +0:local reference points to same-name global reference, part 1 +>GLOBAL +>typeset -n ref=ref +>typeset -g var=RESET +>typeset -n ref=var +>typeset var=RESET + + unset -n ref + unset var + typeset -n ref=var + () { + typeset -n ref=$1 + print -r $ref + ref=RESET + typeset -p ref var + } ref + typeset -p ref var +0:local reference points to same-name global reference, part 2 +> +>typeset -n ref=ref +>typeset -g var=RESET +>typeset -n ref=var +>typeset -g var=RESET + + unset -n ref + unset one + typeset -n ref + typeset one=ONE + for ref in one ref two; do print -r $ref; done +1:for-loop variable is a reference, part 1 +>ONE +*?*ref: invalid self reference + + unset -n ref + unset one + typeset -n ref + () { + typeset one=ONE + for ref in one ref two; do print -r ${(t)ref}; done + } +1:for-loop variable is a reference, part 2 +>scalar-local +*?*ref: invalid self reference + + unset -n ref + unset one var + typeset -n ref=var + () { + typeset one=ONE + typeset -n ref=ref + for ref in one ref two; do + typeset -p ref + print -r $ref + done + typeset -p ref + } + typeset -p ref +0:for-loop variable is a reference, part 3 +>typeset -n ref=one +>ONE +>typeset -n ref=ref +> +>typeset -n ref=two +> +>typeset -n ref=two +>typeset -n ref=var + + unset -n ref + unset one + typeset -n ref + () { + setopt localoptions warn_nested_var + typeset one=ONE + for ref in one two; do print -r ${(t)ref}; done + typeset -n ref + for ref in one two; do print -r ${(t)ref}; done + } +0:for-loop variable is a reference, part 4, warnings +>scalar-local +> +>scalar-local +> +*?*ref: global reference to local variable: one + + typeset -n ptr='ary[$(echo 2)]' + typeset -a ary=(one two three) + print $ptr +1:attempt deferred command substitution in subscript +F:runs in `setopt noexec` so $(...) returns nothing +*?*bad math expression: empty string + %clean -- cgit v1.2.3 From f4c706f0c84bddb7777d38635c4ba1d43703e2e5 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Feb 2023 12:20:33 -0800 Subject: 51417: Check subscripts in named reference values more rigorously. --- ChangeLog | 3 +++ Src/params.c | 11 ++++++++++- Test/K01nameref.ztst | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0cc33c7f1..6dc453f7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-02-12 Bart Schaefer + * 51417: Src/params.c, Test/K01nameref.ztst: Check subscripts + in named reference values more rigorously. + * 51403: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/func.yo, Doc/Zsh/grammar.yo, Doc/Zsh/params.yo, Test/K01nameref.ztst: Tests and documentation for 51402, clean up some other tests. diff --git a/Src/params.c b/Src/params.c index 4910d65fe..f61374b87 100644 --- a/Src/params.c +++ b/Src/params.c @@ -6281,7 +6281,16 @@ valid_refname(char *val) if (*t != 0) { if (*t == '[') { tokenize(t = dupstring(t+1)); - t = parse_subscript(t, 0, ']'); + while ((t = parse_subscript(t, 0, ']')) && *t++ == Outbrack) { + if (*t == Inbrack) + ++t; + else + break; + } + if (t && *t) { + /* zwarn("%s: stuff after subscript: %s", val, t); */ + t = NULL; + } } else if (t[1] || !(*t == '!' || *t == '?' || *t == '$' || *t == '-' || *t == '0' || *t == '_')) { diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index 61c2b006a..d2abdd391 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -350,9 +350,9 @@ F:ksh93 does not implement this either >typeset -A hash=( [y]=HIT ) unset -n ptr1 - typeset -n ptr1='not good' + typeset -n ptr1='not[2]good' 1:invalid nameref -*?*invalid variable name: not good +*?*invalid variable name: not\[2\]good unset -n ptr1 unset hash -- cgit v1.2.3 From 03887bb03fbca246fa94b5b5f2266572c0b6d038 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 13 Feb 2023 18:20:11 -0800 Subject: 51430: Misc. problems with typeset and $parameters * Fix and test for regression of assignment when using typeset command * Fix output of typeset +m and $parameters[ref] * Prevent segfault in typeset --- ChangeLog | 7 +++++++ Src/Modules/parameter.c | 2 +- Src/builtin.c | 16 ++++++++++------ Src/params.c | 2 +- Test/K01nameref.ztst | 14 ++++++++++++++ 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6dc453f7f..be0d8d5e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-02-13 Bart Schaefer + + * 51430: Src/Modules/parameter.c, Src/builtin.c, Src/params.c, + Test/K01nameref.ztst: Fix and test for regression of assignment + when using typeset command, fix output of typeset +m and + $parameters[ref], prevent segfault in typeset. + 2023-02-12 Bart Schaefer * 51417: Src/params.c, Test/K01nameref.ztst: Check subscripts diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index a659300fd..96a211c69 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -108,7 +108,7 @@ getpmparameter(UNUSED(HashTable ht), const char *name) if ((rpm = (Param) realparamtab->getnode2(realparamtab, name)) && !(rpm->node.flags & PM_UNSET)) { pm->u.str = paramtypestr(rpm); - if ((rpm->node.flags & PM_NAMEREF) && + if ((rpm->node.flags & PM_NAMEREF) && rpm->u.str && *(rpm->u.str) && (rpm = (Param) realparamtab->getnode(realparamtab, name)) && !(rpm->node.flags & PM_UNSET)) { pm->u.str = zhtricat(pm->u.str, "-", paramtypestr(rpm)); diff --git a/Src/builtin.c b/Src/builtin.c index cf7e9d9fe..47b337edc 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2262,8 +2262,9 @@ typeset_single(char *cname, char *pname, Param pm, int func, */ if (!(on & PM_READONLY) || !isset(POSIXBUILTINS)) off |= PM_UNSET; - pm->node.flags = (pm->node.flags | - (on & ~PM_READONLY)) & ~off; + if (!OPT_ISSET(ops, 'p')) + pm->node.flags = (pm->node.flags | + (on & ~PM_READONLY)) & ~off; } if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) { if (typeset_setwidth(cname, pm, ops, on, 0)) @@ -3063,12 +3064,15 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) if (asg->value.scalar && ((pm = (Param)resolve_nameref((Param)hn, asg)) && (pm->node.flags & PM_NAMEREF))) { - if (pm->node.flags & PM_SPECIAL) + if (pm->node.flags & PM_SPECIAL) { zwarnnam(name, "%s: invalid reference", pm->node.nam); - else + returnval = 1; + continue; + } else if (pm->u.str && strcmp(pm->u.str, asg->name) == 0) { zwarnnam(name, "%s: invalid self reference", asg->name); - returnval = 1; - continue; + returnval = 1; + continue; + } } if (hn) { /* namerefs always start over fresh */ diff --git a/Src/params.c b/Src/params.c index f61374b87..92cbecf63 100644 --- a/Src/params.c +++ b/Src/params.c @@ -5851,7 +5851,7 @@ static const struct paramtypes pmtypes[] = { { PM_EXPORTED, "exported", 'x', 0}, { PM_UNIQUE, "unique", 'U', 0}, { PM_TIED, "tied", 'T', 0}, - { PM_NAMEREF, "namref", 'n', 0} + { PM_NAMEREF, "nameref", 'n', 0} }; #define PMTYPES_SIZE ((int)(sizeof(pmtypes)/sizeof(struct paramtypes))) diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index d2abdd391..d240e4917 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -25,6 +25,20 @@ 0:assign nameref placeholder >ptr=var + unset ptr + typeset -n ptr + typeset -n ptr=var + typeset -n +0:assign placeholder with new typeset +>ptr=var + + typeset -n ptr1 + typeset -n ptr2=ptr1 + typeset -n +0:chain ending in placeholder +>ptr1 +>ptr2=ptr1 + typeset ptr=var typeset -n ptr typeset -n -- cgit v1.2.3 From 7e0c4406ceba1e021bf37680d6a6b8dcd3dd657f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 14 Feb 2023 09:21:19 +0000 Subject: 51424: $(<...) shouldn't try to open a file with NO_EXEC --- ChangeLog | 5 +++++ Src/exec.c | 3 +++ Test/E01options.ztst | 3 +++ 3 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index be0d8d5e1..b490b0ee8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-02-14 Peter Stephenson + + * 51425: Src/exec.c, Test/E01OPTIONS: $(<...) shouldn't try to + open a file with NO_EXEC. + 2023-02-13 Bart Schaefer * 51430: Src/Modules/parameter.c, Src/builtin.c, Src/params.c, diff --git a/Src/exec.c b/Src/exec.c index c8eb71b34..3330bbce8 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4678,6 +4678,9 @@ getoutput(char *cmd, int qt) if (!prog) return NULL; + if (!isset(EXECOPT)) + return newlinklist(); + if ((s = simple_redir_name(prog, REDIR_READ))) { /* $(< word) */ int stream; diff --git a/Test/E01options.ztst b/Test/E01options.ztst index d38fbed74..533e08773 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -416,6 +416,9 @@ 1:NO_EXEC does recognize bad substitution syntax *?* bad substitution + (setopt noexec; : $( Date: Tue, 14 Feb 2023 17:54:42 -0800 Subject: 51437: Fix incorrectly-passed test case, masked by unrelated bug. A bug with zmodload when unloading/reloading a static module caused the state of the shell options to change during K01 test. Worked around it. Also changed warnnestedvar messages to look more like other such. --- ChangeLog | 5 +++++ Src/params.c | 5 +++-- Test/K01nameref.ztst | 23 +++++++++++++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b490b0ee8..9e7608293 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-02-14 Bart Schaefer + + * 51437: Src/params.c, Test/K01nameref.ztst: Fix incorrectly-passed + test case, masked by unrelated bug. Improve warnnestedvar message. + 2023-02-14 Peter Stephenson * 51425: Src/exec.c, Test/E01OPTIONS: $(<...) shouldn't try to diff --git a/Src/params.c b/Src/params.c index 92cbecf63..e940d7995 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3068,7 +3068,7 @@ check_warn_pm(Param pm, const char *pmtype, int created, } else return; - if (pm->node.flags & PM_SPECIAL) + if (pm->node.flags & (PM_SPECIAL|PM_NAMEREF)) return; for (i = funcstack; i; i = i->prev) { @@ -6181,6 +6181,7 @@ setloopvar(char *name, char *value) if (pm && (pm->node.flags & PM_NAMEREF)) { pm->base = pm->width = 0; pm->u.str = ztrdup(value); + pm->node.flags &= ~PM_UNSET; pm->node.flags |= PM_NEWREF; setscope(pm); pm->node.flags &= ~PM_NEWREF; @@ -6248,7 +6249,7 @@ setscope(Param pm) pm->node.nam); unsetparam_pm(pm, 0, 1); } else if (isset(WARNNESTEDVAR)) - zwarn("%s: global reference to local variable: %s", + zwarn("reference %s in enclosing scope set to local variable %s", pm->node.nam, pm->u.str); } if (pm->u.str && upscope(pm, pm->base) == pm && diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index d240e4917..6a5e767df 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -532,6 +532,13 @@ F:Same test, should part 5 output look like this? >nameref-local-nameref-local >typeset parameters + if [[ $options[typesettounset] != on ]]; then + ZTST_skip='Ignoring zmodload bug that resets TYPESET_TO_UNSET' + setopt typesettounset + fi +0:options reloaded +F:Checking for a bug in zmodload that affects later tests + typeset ptr2=var2 typeset var2=GLOBAL () { @@ -541,7 +548,7 @@ F:Same test, should part 5 output look like this? typeset var2=VAR2 print -r -- ${(P)ptr1} } -0: +0:Order of evaluation with ${(P)...} >VAR2 ary=(one two three four) @@ -666,7 +673,19 @@ F:Same test, should part 5 output look like this? > >scalar-local > -*?*ref: global reference to local variable: one +*?*reference ref*to local variable one + + unset -n ref + typeset -n ref + () { + setopt localoptions warn_nested_var + typeset inner + ref=inner + } + typeset -p ref +0:Global variable is a reference, warning +>typeset -n ref=inner +*?*reference ref*to local variable inner typeset -n ptr='ary[$(echo 2)]' typeset -a ary=(one two three) -- cgit v1.2.3 From 619cf4fbd5843b3b6cb94be3ce5a2953bfc29dc5 Mon Sep 17 00:00:00 2001 From: Øystein Walle Date: Fri, 10 Feb 2023 08:23:01 +0100 Subject: 51391: complete remote branch names respecting --delete for git push --- ChangeLog | 5 +++++ Completion/Unix/Command/_git | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9e7608293..d4701b99b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-02-17 Oliver Kiddle + + * Øystein Walle: 51391: Completion/Unix/Command/_git: + complete remote branch names respecting --delete for git push + 2023-02-14 Bart Schaefer * 51437: Src/params.c, Test/K01nameref.ztst: Fix incorrectly-passed diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index b3ed7b5c8..a2555cbf0 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -1459,6 +1459,14 @@ _git-push () { # only complete files on the local end, not the remote end. Still, it may be # helpful to get some sort of completion going, perhaps modifying the path # later on to match the remote end. + + local ref_arg + if (( words[(I)-d|--delete] )); then + ref_arg='*: :__git_remote_branch_names_noprefix' + else + ref_arg='*: :__git_ref_specs_pushy' + fi + _arguments -S -s $endopt \ '--all[push all refs under refs/heads/]' \ '--prune[remove remote branches that do not have a local counterpart]' \ @@ -1494,7 +1502,7 @@ _git-push () { '(-4 --ipv4 -6 --ipv6)'{-4,--ipv4}'[use IPv4 addresses only]' \ '(-4 --ipv4 -6 --ipv6)'{-6,--ipv6}'[use IPv6 addresses only]' \ ': :__git_any_repositories' \ - '*: :__git_ref_specs_pushy' && ret=0 + $ref_arg && ret=0 case $state in (lease) -- cgit v1.2.3 From 6f4aa1d9496ed37e6ebbf70d86a35a9d5e1fb605 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 17 Feb 2023 23:38:14 +0100 Subject: 51447: silence compiler maybe-uninitialized warning by combining a couple of variables --- ChangeLog | 3 +++ Src/Zle/zle_keymap.c | 25 +++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index d4701b99b..7472298d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-02-17 Oliver Kiddle + * 51447: Src/Zle/zle_keymap.c: silence compiler maybe-uninitialized + warning by combining a couple of variables + * Øystein Walle: 51391: Completion/Unix/Command/_git: complete remote branch names respecting --delete for git push diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index ec8dd031e..a31ab22d7 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1586,7 +1586,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) Thingy func = t_undefinedkey; char *str = NULL; int lastlen = 0, lastc = lastchar; - int timeout = 0, csi = 0, startcsi; + int timeout = 0, csi = 0; keybuflen = 0; keybuf[0] = 0; @@ -1640,22 +1640,23 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) /* CSI key sequences have a well defined structure so if we currently * have an incomplete one, loop so the rest of it will be included in * the key sequence if that arrives within the timeout. */ - if (keybuflen >= 3 && !csi) { - startcsi = keybuflen - 3; - csi = keybuf[startcsi] == '\033' && keybuf[keybuflen - 2] == '['; - } + if (!csi && keybuflen >= 3 && keybuf[keybuflen - 3] == '\033' && + keybuf[keybuflen - 2] == '[') + csi = keybuflen - 1; if (csi) { - csi = keybuf[keybuflen - 2] != Meta && keybuf[keybuflen - 1] >= 0x20 - && keybuf[keybuflen - 1] <= 0x3f; + if (keybuf[keybuflen - 2] == Meta || keybuf[keybuflen - 1] < 0x20 + || keybuf[keybuflen - 1] > 0x3f) { /* If we reach the end of a valid CSI sequence and the matched key * binding is for part of the CSI introduction, select instead the * undefined-key widget and consume the full sequence from the * input buffer. */ - if (!csi && keybuf[keybuflen - 1] >= 0x40 && - keybuf[keybuflen - 1] <= 0x7e && lastlen > startcsi && - lastlen <= startcsi + 2) { - func = t_undefinedkey; - lastlen = keybuflen; + if (keybuf[keybuflen - 1] >= 0x40 && + keybuf[keybuflen - 1] <= 0x7e && lastlen > csi - 2 && + lastlen <= csi) { + func = t_undefinedkey; + lastlen = keybuflen; + } + csi = 0; } } -- cgit v1.2.3 From c83ce203f5c78d3b4da8d59807fcfbcc23be2a21 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 18 Feb 2023 01:10:10 +0100 Subject: 51455, 51461: new completion for the OpenLDAP client tools including a helper function for LDAP search filters --- ChangeLog | 7 ++ Completion/BSD/Command/_ldap | 4 +- Completion/Unix/Command/_openldap | 222 ++++++++++++++++++++++++++++++++++ Completion/Unix/Type/_ldap_attributes | 27 +++++ Completion/Unix/Type/_ldap_filters | 91 ++++++++++++++ 5 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 Completion/Unix/Command/_openldap create mode 100644 Completion/Unix/Type/_ldap_attributes create mode 100644 Completion/Unix/Type/_ldap_filters diff --git a/ChangeLog b/ChangeLog index 7472298d6..b5bb1da99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-02-19 Oliver Kiddle + + * 51455, 51461: Completion/Unix/Type/_ldap_attributes + Completion/BSD/Command/_ldap, Completion/Unix/Command/_openldap, + Completion/Unix/Type/_ldap_filters: new completion for the OpenLDAP + client tools including a helper function for LDAP search filters + 2023-02-17 Oliver Kiddle * 51447: Src/Zle/zle_keymap.c: silence compiler maybe-uninitialized diff --git a/Completion/BSD/Command/_ldap b/Completion/BSD/Command/_ldap index 8fa17e2f8..181e6b0d0 100644 --- a/Completion/BSD/Command/_ldap +++ b/Completion/BSD/Command/_ldap @@ -80,8 +80,8 @@ else '-x[use simple authentication]' \ '-Z[use StartTLS]' \ '-z+[specify maximum number of results or 0 for no limit]:size limit [0]:' \ - '::filter:' \ - '*:attribute:' + '1: :_ldap_filters' \ + '*: :_ldap_attributes' ;; esac fi diff --git a/Completion/Unix/Command/_openldap b/Completion/Unix/Command/_openldap new file mode 100644 index 000000000..233d0950e --- /dev/null +++ b/Completion/Unix/Command/_openldap @@ -0,0 +1,222 @@ +#compdef ldapadd ldapcompare ldapdelete ldapexop ldapmodify ldapmodrdn ldappasswd ldapsearch ldapurl ldapwhoami + +local curcontext="$curcontext" nm="$compstate[nmatches]" +local -a args auth state line expl + +args=( '*-e[general extensions]:extension:->general-extensions' ) + +case $service in + ldapadd|ldapcompare|ldapdelete|ldapexop|ldapmodify|ldapmodrdn|ldappasswd|ldapsearch|ldapwhoami) + if (( $words[(I)-[^Z]#Z[^Z]#] )); then + args+=( '*-Z[require success for start TLS request]' ) + elif (( ! $words[(I)-[^Z]#Z] )); then + args+=( '-Z[start TLS request]' ) + fi + args+=( + '!(-)-VV' '-V[display version information]' + '*-d+[set LDAP debugging level]:level:((1\:trace 2\:packets 4\:args 8\:conns 10\:ber 2048\:parse -1\:all))' + "-n[show what would be done but don't actually do it]" + '-v[verbose output]' + "-N[don't use reverse DNS to canonicalize SASL host name]" + '*-o+[specify any ldap.conf options]: : _values option + "ldif_wrap[specify width]\:width" + "nettimeout[specify timeout]\:timeout (seconds)"' + ) + auth=( + '-D[specify bind DN]:binddn' + '-H[specify LDAP URIs]:uri' + '-P[specify protocol version]:version [3]:(2 3)' + + simple + '(sasl)-x[use simple authentication]' + '(sasl -W -y)-w+[specify bind password]:bind password' + '(sasl -w -y)-W[prompt for bind password]' + '(sasl -w -W)-y+[read password from file]:file:_files' + + sasl + '(simple)-O+[specify SASL security properties]: : _values -s , property + none noplain noactive nodict noanonymous forwardsec passcred + minssf\:factor maxssf\:factor maxbufsize\:factor' + '(simple)-X+[specify SASL authorization identity]:authzid:->authzids' + '(simple)-Y+[specify SASL mechanism]:mechanism:compadd -M "m:{a-zA-Z}={A-Za-z}" EXTERNAL GSSAPI' # iana has a full list but cyrus support seems limited + '(simple)-R+[specify SASL realm]:realm' + '(simple)-U+[specify SASL authentication identity]:authcid' + '(simple)-I[use SASL Interactive mode]' + '(simple)-Q[use SASL Quiet mode]' + ) + ;| + ldapadd|ldapcompare|ldapdelete|ldapmodify|ldapmodrdn|ldapsearch) + if (( $words[(I)-[^M]#M[^M]#] )); then + args+=( '*-M[enable Manage DSA IT control critical]' ) + elif (( ! $words[(I)-[^M]#M] )); then + args+=( '-M[enable Manage DSA IT control]' ) + fi + ;| + ldapadd|ldapdelete|ldapmodify|ldapmodrdn|ldapsearch) + # ldapexop documents but doesn't implement this + args+=( '(1 2 *)-f+[read operations from file]:file:_files' ) + ;| + ldapadd|ldapdelete|ldapmodify|ldapmodrdn|ldapsearch) + args+=( "-c[continuous operation mode (don't stop on errors)]" ) + ;| + ldapdelete|ldapsearch) + args+=( '-z+[specify size limit]:size limit (entries)' ) + ;| + ldapadd|ldapmodify) + args+=( + '-S+[write records that are skipped due to an error to file]:file:_files' + '*-E+[modify extensions]:extension:->modify-extensions' + ) + ;| + ldapurl|ldapsearch) + args+=( + '(decompose)-s+[specify search scope]:search scope [sub]:(base one sub children)' + ) + ;| + ldapdelete|ldapmodrdn|ldapurl|ldapwhoami) args+=( '!*-E+:extension' ) ;| + + ldapadd) args+=( '!-a' ) ;; + ldapmodify) args+=( '-a[add new entries]' ) ;; + ldapcompare) + args+=( + '-z[quiet mode - no output aside return status]' + '*-E+[compare extensions]:extension:->compare-extensions' + ) + ;; + ldapdelete) + args+=( + '-r[do a recursive delete]' + '*: :_guard "^-*" "distinguished name"' + ) + ;; + ldapexop) args+=( '*:: :->extended-operations' ) ;; + ldapmodrdn) + args+=( + '-r[remove old RDN values from the entry]' + '-s[specify new superior entry to move target to]:entry' + '1:distinguished name' + '2:relative distinguished name' + ) + ;; + ldappasswd) + args+=( + '(-a -t)-A[prompt for old password]' + '(-A -t)-a+[specify old password]:password' + '(-A -a)-t+[read old password from file]:file:_files' + '(-s -T)-S[prompt for new password]' + '(-S -T)-s+[specify new password]:password' + '(-S -s)-T+[read new password from file]:file:_files' + ) + ;; + ldapsearch) + if (( $words[(I)-[^L]#L[^L]#L[^L]#] )); then + args+=( '*-L[LDIF format without comments and version]' ) + elif (( $words[(I)-[^L]#L[^L]#] )); then + args+=( '*-L[LDIF format without comments]' ) + elif ! (( $words[(I)-[^L]#L[^L]#L[^L]#L] )); then + args+=( '-L[LDIFv1 format]' ) + else + args+=( '!*-L' ) + fi + if (( $words[(I)-[^t]#t[^t]#] )); then + args+=( '*-t[write all retrieved values to files in temporary directory]' ) + elif (( ! $words[(I)-[^t]#t] )); then + args+=( '-t[write binary values to files in temporary directory]' ) + fi + + args+=( + '-a+[specify how aliases dereferencing is done]:deref [never]:(never always search find)' + '-A[retrieve attributes only (no values)]' + '-b+[specify base dn for search]:basedn' + '*-E+[search extensions]:extension:->search-extensions' + '-F+[specify URL prefix for temporary files]:prefix [file:///tmp//]' + '-l+[specify time limit for search]:time limit (seconds)' + '-S+[sort results by specified attribute]:attribute:_ldap_attributes' + '-T[write files to specified directory]:path [/tmp]:_directories' + '-u[include User Friendly entry names in the output]' + '1: :_ldap_filters' + '2: : _alternative + "attributes:attribute:_ldap_attributes" + "attributes:attribute:((1.1\:no\ attributes \*\:all\ user\ attributes \+\:all\ operational\ attributes))"' + '*:attribute:_ldap_attributes -F line' + ) + ;; + ldapurl) + args+=( + - compose + '-a+[set a list of attribute selectors]:attribute selectors (comma separated)' + '-b+[set the searchbase]:search base' + '-f+[set the URL filter]:filter:_ldap_filters' + '-h+[set the host]:host:_hosts' + '-p+[set the tcp port]:port:(389 636)' + '-S+[set the URL scheme]:scheme:(ldap ldaps)' + - decompose + '(-s)-H+[specify URI to be exploded]:uri' + ) + ;; +esac + +_arguments -C -S -s $args $auth + +case $state in + extended-operations) + case $CURRENT:$words[1] in + 1:*) + if compset -P '*::'; then + _message -e data 'base64 data' + elif compset -P '*:'; then + _message -e data data + else + _alternative \ + 'oids::_guard "(<->(|.))#" oid' \ + 'operations:operation:(whoami cancel refresh)' + fi + ;; + 2:cancel) _message -e ids 'cancel id' ;; + 2:refresh) _message -e names 'distinguished name' ;; + 3:refresh) _message -e times 'ttl' ;; + *) _message 'no more arguments' ;; + esac + ;; + *-extensions) + if ! compset -P \!; then + _description criticality expl critical + compadd -S "" "$expl[@]" \! + fi + ;| + modify-extensions) _values extension 'txn:txn:(abort commit)' ;; + compare-extensions) _values extension dontUseCopy ;; + search-extensions) + _values extension \ + 'mv[matched values filter]:filter:_ldap_filters' \ + 'pr[paged results/prompt]:size[/prompt|noprompt]' \ + 'sss[server side sorting]: :_sequence -s / _ldap_attributes' \ + 'subentries: :(true false)' \ + 'sync:sync[/cookie][/slimit]:((ro\:refreshOnly rp\:refreshAndPersist))' \ + 'vlv[virtual list view]:before/after(/offset/count|\:value' \ + 'deref:derefAttr:_sequence _ldap_attributes' \ + dontUseCopy domainScope + ;; + general-extensions) + _values extension \ + 'assert:filter:_ldap_filters' \ + 'authzid:authzid:->authzids' \ + {post,pre}'read: :_sequence _ldap_attributes' \ + 'sessiontracking:username:_users' \ + 'chaining:behavior:(chainingPreferred chainingRequired referralsPreferred referralsRequired)' \ + bauthzid manageDSAit noop ppolicy relax abandon cancel ignore + ;& + authzids) + if [[ $state != authzids ]]; then + : # fall-through from above without the authzids state + elif compset -P 'u:'; then + _description users expl authzid + _users "$expl[@]" + elif compset -P 'dn:'; then + _message -e ids 'distinguished name' + else + _description prefixes expl prefix + compadd -S: "$expl[@]" u dn + fi + ;; +esac + +[[ nm -ne "$compstate[nmatches]" ]] diff --git a/Completion/Unix/Type/_ldap_attributes b/Completion/Unix/Type/_ldap_attributes new file mode 100644 index 000000000..0711cfbf1 --- /dev/null +++ b/Completion/Unix/Type/_ldap_attributes @@ -0,0 +1,27 @@ +#autoload + +local -a expl attrs + +# These come from dumping attributes from basic installations of both openldap +# and FreeIPA and combining results. It is possible to have custom additions so +# a definitive list is not possible Hence the use of -x with compadd. +# +attrs=( + associatedDomain authenticationMethod automountInformation automountKey + automountMapName bindTimeLimit cACertificate;binary cn dc defaultSearchBase + defaultServerList description displayName dn followReferrals gecos gidNumber + givenName homeDirectory info initials ipaCertIssuerSerial ipaCertSubject + ipaConfigString ipaKeyExtUsage ipaKeyTrust ipaNTSecurityIdentifier + ipaPublicKey ipaUniqueID ipHostNumber loginShell mail member memberUid + mepManagedBy nisDomain nisNetgroupTriple o objectClass objectClassMap ou + pwdAllowUserChange pwdAttribute pwdCheckQuality pwdExpireWarning + pwdFailureCountInterval pwdGraceAuthNLimit pwdInHistory pwdLockout + pwdLockoutDuration pwdMaxAge pwdMaxFailure pwdMinAge pwdMinLength + pwdMustChange pwdSafeModify searchTimeLimit serviceSearchDescriptor sn + telephoneNumber uid uidNumber userCertificate;binary userPKCS12 + userSMIMECertificate +) + +_description ldap-attributes expl "ldap attribute" +compadd "${@:/-X/-x}" "${expl[@]:/-X/-x}" \ + -M 'm:{a-zA-Z}={A-Za-z} r:[^A-Z]||[A-Z]=* r:|=*' -a attrs diff --git a/Completion/Unix/Type/_ldap_filters b/Completion/Unix/Type/_ldap_filters new file mode 100644 index 000000000..5e0e30f01 --- /dev/null +++ b/Completion/Unix/Type/_ldap_filters @@ -0,0 +1,91 @@ +#autoload + +# LDAP search filters conforming to RFC4515 + +local -a expl excl optype disp end pre +local -i nest=0 +local open='(' close=')' andop='&' orop='|' + +[[ -prefix - ]] && return 1 + +local -a matchingrules=( # From RFC4517 + bitStringMatch booleanMatch caseExactIA5Match + caseExactMatch caseExactOrderingMatch caseExactSubstringsMatch + caseIgnoreIA5Match caseIgnoreIA5SubstringsMatch caseIgnoreListMatch + caseIgnoreListSubstringsMatch caseIgnoreMatch caseIgnoreOrderingMatch + caseIgnoreSubstringsMatch directoryStringFirstComponentMatch + distinguishedNameMatch generalizedTimeMatch generalizedTimeOrderingMatch + integerFirstComponentMatch integerMatch integerOrderingMatch keywordMatch + numericStringMatch numericStringOrderingMatch numericStringSubstringsMatch + objectIdentifierFirstComponentMatch objectIdentifierMatch octetStringMatch + octetStringOrderingMatch telephoneNumberMatch telephoneNumberSubstringsMatch + uniqueMemberMatch wordMatch +) +local -a classes=( # Sampled from real servers, arbitrary other values allowed + automount automountMap cosTemplate dcObject device dnaSharedConfig domain + domainRelatedObject DUAConfigProfile extensibleObject groupOfNames + groupOfPrincipals ieee802device inetOrgPerson inetuser ipaassociation ipaca + ipacaacl ipaCertificate ipaCertMapConfigObject ipacertprofile ipaConfigObject + ipaDomainIDRange ipaDomainLevelConfig ipaGuiConfig ipahbacrule ipahbacservice + ipahbacservicegroup ipahost ipahostgroup ipaIDrange ipaKeyPolicy + ipakrbprincipal ipaNameResolutionData ipaNTDomainAttrs ipaNTGroupAttrs + ipaNTUserAttrs ipaobject ipaPublicKeyObject ipaReplTopoManagedServer + ipaservice ipaSshGroupOfPubKeys ipasshhost ipasshuser ipasudorule + ipaSupportedDomainLevelConfig ipaTrustedADDomainRange ipaUserAuthTypeClass + ipausergroup ipHost krbContainer krbprincipal krbprincipalaux + krbrealmcontainer krbTicketPolicyAux mepManagedEntry mepOriginEntry + nestedGroup nisDomainObject nisNetgroup nsContainer nsDS5Replica nshost + organization organizationalPerson organizationalRole organizationalUnit + person pilotObject pkiCA pkiuser posixAccount posixGroup pwdPolicy + shadowAccount simpleSecurityObject top +) + +compquote open close andop orop +open=${(q)open} close=${(q)close} +# default to double rather than backslash quoting +[[ -z $compstate[quote] && -z $PREFIX ]] && pre='"(' + +zstyle -s ":completion:${curcontext}:operators" list-separator sep || sep=-- +print -v disp -f "%s $sep %s" \| or \& and \! not +end=( ") $sep end" ) +excl=( ! \\\| \& ) # compadd -F uses globs: only | needs quoting + +local -a query=( + \( /$'*\0[ \t\n]#'/ \) # strip off any preceding arguments + \( + \( "/${open}!/" -'optype[++nest]=1;pre=""' + \| "/${open}${(q)orop}/" -'optype[++nest]=2;pre=""' + \| "/${open}${andop}/" -'optype[++nest]=3;pre=""' + \| '/[]/' ':operators:operator:compadd -F "( ${(q)excl[optype[nest]]} )" -d disp -P ${pre:-${(Q)open}} -S ${(Q)open} \| \& \!' \) + \| + \( "/${open}[^\\)]##/" "%$close%" # pass over whole var=value, needed due to lack of backtracking after the following + \| "/${open}(#i)homeDirectory=/" '/[]/' ':directories:directory:_directories -P / -W / -r ") \t\n\-"' + \| "/${open}(#i)loginShell=/" '/[]/' ':shells:shell:compadd -S ${(Q)close} ${(f)^"$(~]##/' '%[=:<>~]%' -'pre=""' + ':object-types:object type:_ldap_attributes -P ${pre:-${(Q)open}} -S = -r ":=~<> \t\n\-"' + \( + '/:/' + '/[^:]##:=/' ':matching-rules:matching rule:compadd -S ":=" -a matchingrules' + \| + '/([~<>]|)=/' ':operators:operator:compadd -S "" "<=" \>= \~=' + \) + '/[^\\)]##/' "%$close%" ': _message -e object-values "object value (* for presence check)"' + \) + "/$close/" -'(( nest ))' ':brackets:bracket:compadd ${=query[nest]:+-S ""} \)' + \( + # This use of -P/-d and an empty match works around a limitation/bug where + # mixed use of -P removes any quoting + "/$close/" ':operators:operator:compadd ${=query[nest-1]:+-S ""} -d end -P ${(Q)close} ""' + \( // -'(( --nest ))' \| '//' -'((!nest))' '/[]/' ': compadd ""' \) + \) \# + // -'(( nest && optype[nest] > 1 ))' + \) \# +) + +_regex_arguments _ldap_search_filters "$query[@]" +_ldap_search_filters -- cgit v1.2.3 From 76be800073255eb3cdc1bcdec3159a973f163ad7 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sun, 19 Feb 2023 15:06:45 +0100 Subject: 51456: complete only modified files with git add -u Also fix a typo, add a missing =, add a prompt for function name after git blame -L and git worktree --force has gained a short -f form. --- ChangeLog | 3 +++ Completion/Unix/Command/_git | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5bb1da99..8cca5d1e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-02-19 Oliver Kiddle + * 51456: Completion/Unix/Command/_git: complete only modified + files with git add -u + * 51455, 51461: Completion/Unix/Type/_ldap_attributes Completion/BSD/Command/_ldap, Completion/Unix/Command/_openldap, Completion/Unix/Type/_ldap_filters: new completion for the OpenLDAP diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index a2555cbf0..49f9fa504 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -76,17 +76,21 @@ _git-add () { case $state in (file) - declare -a ignored_files_alternatives + declare -a file_alternatives + if [[ -z ${opt_args[(I)-u|--update]} ]]; then + file_alternatives=( + 'other-files::__git_ignore_line_inside_arguments __git_other_files' + ) + fi if [[ -n ${opt_args[(I)-f|--force]} ]]; then - ignored_files_alternatives=( + file_alternatives+=( 'ignored-modified-files:ignored modified file:__git_ignore_line_inside_arguments __git_modified_files --ignored' 'ignored-other-files:ignored other file:__git_ignore_line_inside_arguments __git_other_files --ignored') fi _alternative \ 'modified-files::__git_ignore_line_inside_arguments __git_modified_files' \ - 'other-files::__git_ignore_line_inside_arguments __git_other_files' \ - $ignored_files_alternatives && ret=0 + $file_alternatives && ret=0 ;; esac @@ -2365,7 +2369,7 @@ _git-worktree() { _arguments -S $endopt \ '(-n --dry-run)'{-n,--dry-run}"[don't remove, show only]" \ '(-v --verbose)'{-v,--verbose}'[report pruned objects]' \ - '--expire[expire objects older than specified time]:time' && ret=0 + '--expire=[expire objects older than specified time]:time' && ret=0 ;; (list) _arguments -S $endopt '--porcelain[machine-readable output]' && ret=0 @@ -2379,7 +2383,8 @@ _git-worktree() { ':location:_directories' && ret=0 ;; (remove) - _arguments -C -S $endopt '--force[remove working trees that are not clean or that have submodules]' \ + _arguments -C -S $endopt \ + '(-f --force)'{-f,--force}'[remove working trees that are not clean or that have submodules]' \ ': :->worktrees' && ret=0 ;; (unlock) @@ -3901,7 +3906,7 @@ _git-reflog () { ;; (delete) _arguments -C -S \ - '(-n --dry-run)'{-n,--dry-run}"[dpn't update entries; show what would be done]" \ + '(-n --dry-run)'{-n,--dry-run}"[don't update entries; show what would be done]" \ '--updateref[update ref with SHA-1 of top reflog entry after expiring or deleting]' \ '--rewrite[adjust reflog entries to ensure old SHA-1 points to new SHA-1 of previous entry after expiring or deleting]' \ '--verbose[output additional information]' \ @@ -4134,7 +4139,8 @@ _git-blame () { else _alternative \ 'line-numbers: :__git_guard_number "line number"' \ - 'regexes::_guard "(/[^/]#(\\?[^/]#)#(/|)|)" regex' && ret=0 + 'regexes::_guard "(/[^/]#(\\?[^/]#)#(/|)|)" regex' \ + 'functions::_guard "(|:*)" "function name"' && ret=0 fi ;; esac -- cgit v1.2.3 From d2768f2f886c34dafa535b46796948b6a860d974 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 20 Feb 2023 10:32:40 -0800 Subject: 51431: "typeset -p" shouldn't change parameter flags --- ChangeLog | 4 ++++ Src/builtin.c | 46 +++++++++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8cca5d1e4..52491f4b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-02-20 Bart Schaefer + + * 51431: Src/builtin.c: "typeset -p" shouldn't change parameter flags + 2023-02-19 Oliver Kiddle * 51456: Completion/Unix/Command/_git: complete only modified diff --git a/Src/builtin.c b/Src/builtin.c index 47b337edc..11c1ab3a4 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2106,15 +2106,27 @@ typeset_single(char *cname, char *pname, Param pm, int func, return NULL; } tc = 1; - usepm = 0; + if (OPT_MINUS(ops,'p')) + usepm = (on & pm->node.flags); + else if (OPT_PLUS(ops,'p')) + usepm = (off & pm->node.flags); + else + usepm = 0; } else if (usepm || newspecial != NS_NONE) { int chflags = ((off & pm->node.flags) | (on & ~pm->node.flags)) & (PM_INTEGER|PM_EFLOAT|PM_FFLOAT|PM_HASHED| PM_ARRAY|PM_TIED|PM_AUTOLOAD); /* keep the parameter if just switching between floating types */ - if ((tc = chflags && chflags != (PM_EFLOAT|PM_FFLOAT))) - usepm = 0; + if ((tc = chflags && chflags != (PM_EFLOAT|PM_FFLOAT))) { + if (OPT_MINUS(ops,'p')) + usepm = (on & pm->node.flags); + else if (OPT_PLUS(ops,'p')) + usepm = (off & pm->node.flags); + else + usepm = 0; + } + } /* @@ -2166,13 +2178,16 @@ typeset_single(char *cname, char *pname, Param pm, int func, } if (err) { - zerrnam(cname, "%s: can't change type of a special parameter", - pname); + if (!OPT_ISSET(ops,'p')) + zerrnam(cname, + "%s: can't change type of a special parameter", + pname); return NULL; } } else if (pm->node.flags & PM_AUTOLOAD) { - zerrnam(cname, "%s: can't change type of autoloaded parameter", - pname); + if (!OPT_ISSET(ops,'p')) + zerrnam(cname, "%s: can't change type of autoloaded parameter", + pname); return NULL; } } @@ -2208,6 +2223,10 @@ typeset_single(char *cname, char *pname, Param pm, int func, * ii. we are creating a new local parameter */ if (usepm) { + if (OPT_MINUS(ops,'p') && on && !(on & pm->node.flags)) + return NULL; + else if (OPT_PLUS(ops,'p') && off && !(off & pm->node.flags)) + return NULL; if ((asg->flags & ASG_ARRAY) ? !(PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) : (asg->value.scalar && (PM_TYPE(pm->node.flags & @@ -2254,6 +2273,10 @@ typeset_single(char *cname, char *pname, Param pm, int func, arrfixenv(pm->node.nam, x); } } + if (OPT_ISSET(ops,'p')) { + paramtab->printnode(&pm->node, PRINT_TYPESET); + return pm; + } if (usepm == 2) /* do not change the PM_UNSET flag */ pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~off; else { @@ -2262,9 +2285,8 @@ typeset_single(char *cname, char *pname, Param pm, int func, */ if (!(on & PM_READONLY) || !isset(POSIXBUILTINS)) off |= PM_UNSET; - if (!OPT_ISSET(ops, 'p')) - pm->node.flags = (pm->node.flags | - (on & ~PM_READONLY)) & ~off; + pm->node.flags = (pm->node.flags | + (on & ~PM_READONLY)) & ~off; } if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) { if (typeset_setwidth(cname, pm, ops, on, 0)) @@ -2310,8 +2332,6 @@ typeset_single(char *cname, char *pname, Param pm, int func, if (errflag) return NULL; pm->node.flags |= (on & PM_READONLY); - if (OPT_ISSET(ops,'p')) - paramtab->printnode(&pm->node, PRINT_TYPESET); return pm; } @@ -2328,7 +2348,7 @@ typeset_single(char *cname, char *pname, Param pm, int func, * or we're converting the type of a parameter. In the * last case only, we need to delete the old parameter. */ - if (tc) { + if (tc && !OPT_ISSET(ops,'p')) { /* Maintain existing readonly/exported status... */ on |= ~off & (PM_READONLY|PM_EXPORTED) & pm->node.flags; /* ...but turn off existing readonly so we can delete it */ -- cgit v1.2.3 From 82f307bddfaff0f6e45bf315ff43ea4192529cad Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 21 Feb 2023 12:16:40 +0000 Subject: Fix access to autoloaded parameter. Namerefef resolution needs to happen on the parameter after autoload. --- ChangeLog | 4 ++++ Src/params.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 52491f4b5..0b7d4dad1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-02-21 Peter Stephenson + + * 51466: Src/params.c: fix access to autoloaded parameter. + 2023-02-20 Bart Schaefer * 51431: Src/builtin.c: "typeset -p" shouldn't change parameter flags diff --git a/Src/params.c b/Src/params.c index e940d7995..90302b1b0 100644 --- a/Src/params.c +++ b/Src/params.c @@ -538,7 +538,7 @@ getparamnode(HashTable ht, const char *nam) } if (hn && ht == realparamtab) - hn = resolve_nameref(pm, NULL); + hn = resolve_nameref((Param)hn, NULL); return hn; } -- cgit v1.2.3 From f604645d06d03a43de8c0c7192be0fda59c26758 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 24 Feb 2023 12:34:14 +0100 Subject: 51474: make -e and --vault-id options repeatable and update for new options to ansible 2.13.2 --- ChangeLog | 5 +++ Completion/Unix/Command/_ansible | 89 +++++++++++++++++++++++++++++----------- 2 files changed, 69 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b7d4dad1..204e64365 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-02-24 Oliver Kiddle + + * 51474: Completion/Unix/Command/_ansible: make -e and --vault-id + options repeatable and update for new options to ansible 2.13.2 + 2023-02-21 Peter Stephenson * 51466: Src/params.c: fix access to autoloaded parameter. diff --git a/Completion/Unix/Command/_ansible b/Completion/Unix/Command/_ansible index 2d976b0a0..7b85a58e4 100644 --- a/Completion/Unix/Command/_ansible +++ b/Completion/Unix/Command/_ansible @@ -20,8 +20,10 @@ case $service in ;| ansible|ansible-console|ansible-playbook|ansible-pull) args+=( - '(-K --ask-become-pass)'{-K,--ask-become-pass}'[ask for privilege escalation password]' - '(-k --ask-pass)'{-k,--ask-pass}'[ask for connection password]' + '(-K --ask-become-pass --become-password-file)'{-K,--ask-become-pass}'[ask for privilege escalation password]' + '(-K --ask-become-pass)--become-password-file=[specify file containing become password]:file:_files' + '(-k --ask-pass --connection-password-file)'{-k,--ask-pass}'[ask for connection password]' + '(-k --ask-pass)--connection-password-file=[specify file containing connection password]:file:_files' '--list-hosts[output list of matching hosts]' '(-l --limit)'{-l+,--limit=}'[further limit hosts to an additional pattern]:host subset:->hosts' '(-T --timeout)'{-T+,--timeout=}'[override the connection timeout]:timeout (seconds) [10]' @@ -49,8 +51,8 @@ case $service in ansible|ansible-console|ansible-inventory|ansible-playbook|ansible-pull) args+=( --ask-vault-pass{,word}'[ask for vault password]' - '(-e --extra-vars)'{-e+,--extra-vars=}'[set additional variables]:key=value or YAML/JSON' - '--vault-id=[specify vault identity to use]:vault identity' + \*{-e+,--extra-vars=}'[set additional variables]:key=value, YAML/JSON or @file:->extra-vars' + '*--vault-id=[specify vault identity to use]:vault identity' --vault-pass{,word}-file='[specify vault password file]:vault password file:_files' \*{-i+,--inventory=}'[specify inventory host file or host list]: : _alternative "files\:inventory file\:_files" "hosts\:host\: _sequence _hosts"' @@ -86,15 +88,15 @@ case $service in ) ;; ansible-config) - args+=( - '(-c --config)'{-c+,--config=}'[specify configuration file]:config file:_files' + args=( -A "-*" $args '1:action:(( list\:list\ all\ configuration dump\:show\ the\ current\ settings,\ merge\ specified\ configuration view\:display\ the\ current\ config\ file + init\:create\ initial\ configuration ))' + '*::args:->config' ) - [[ -n $words[(r)dump] ]] && args+=( '--only-changed[only show configuration that is changed from the default]' ) ;; ansible-console) args+=( @@ -103,11 +105,11 @@ case $service in ;; ansible-doc) args+=( - '!--metadata-dump' # "internal testing only" + '!--metadata-dump' '!--no-fail-on-errors' # "internal use only" '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-j,--json}'[change output to json format]' '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-l,--list}'[list available plugins]' '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-F,--list_files}'[show plugin names and their source files without summaries]' - '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-s,--snippet}'[show playbook snippet for specified plugins]' + '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-s,--snippet}'[show playbook snippet for inventory, lookup and module plugins]' '(-l --list -F --list_files -s --snippet -e --entry-point)--metadata-dump[dump json metadata for all plugins]' '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-e+,--entry-point=}'[select the entry point for roles]:entry point' '(-t --type)'{-t+,--type=}'[choose plugin type]:plugin type [module]:(become cache callback cliconf connection httpapi inventory lookup netconf shell vars module strategy role keyword)' @@ -218,18 +220,13 @@ case $state in ;; connect-types) plug=connection - ;& - plugins) - plugvar=_ansible_${plug}_plugins - typeset -ga ${plug} - if zstyle -T ":completion:${curcontext}:plugins" verbose; then - (( ${(P)#plugvar} )) || set -A ${plugvar} \ - ${${(f)"$(_call_program plugins ansible-doc -t $plug -l)"}/ ##/:} - _describe -t plugins "${plug} plugin" $plugvar -M 'r:|.=* r:|=*' && ret=0 + state=plugins + ;; + extra-vars) + if compset -P '@'; then + _files -g "*.(json|yml|yaml|ini)(-.)" && ret=0 else - (( ${(P)#plugvar} )) || set -A ${plugvar} \ - ${${(f)"$(_call_program plugins ansible-doc -t $plug -F)"}%% *} - _wanted plugins expl "${plug} plugin" compadd -M 'r:|.=* r:|=*' -a $plugvar && ret=0 + _message 'key=value, YAML/JSON or @file' fi ;; tags) @@ -237,9 +234,39 @@ case $state in _sequence _wanted tags expl tag compadd - \ ${(s.,.)${(j.,.)${(M)${(f)"$(cat **/*.yml)"}:# #tags:*}#*: }} && ret=0 ;; + config) + ign='' + curcontext="${curcontext%:*}-${words[1]}:" + (( $#words > 3 )) && ign='!' + args=( + "${ign}(-)"{-h,--help}'[display usage information]' + \*{-v,--verbose}'[verbose mode]' + '(-c --config)'{-c+,--config=}'[specify configuration file]:config file:_files' + '(-t --type)'{-t+,--type=}'[filter down to a specific plugin type]:plugin type [base]:(all base become cache callback cliconf connection httpapi inventory lookup netconf shell vars)' + '*:plugin:->plugins' + ) + case $words[1] in + dump) + args+=( + '(--only-changed --changed-only)'{--only-changed,--changed-only}'[only show configuration that is changed from the default]' + ) + ;; + init) + args+=( + '--format=[specify output format for init]:format:(init env vars)' + '--disabled[prefix all entries with a comment character]' + ) + ;; + esac + _arguments -s -S : $args && ret=0 + plug=${(v)opt_args[(i)-(t|-type)]} + [[ $plug = base ]] && state= + ;; galaxy) ign='' gactions=( delete import info init install list remove search setup ) + args=( "${ign}(-)"{-h,--help}'[display usage information]' ) + (( $#words > 3 )) && ign='!' case ${(j.:.)line[1,3]} in (role|collection):*:*) subcmd="${line[1]}-${line[2]}" @@ -253,14 +280,11 @@ case $state in [^:]#) words=( role "$words[@]" ) (( CURRENT++ )) + args=() ;; esac curcontext="${curcontext%:*}-${subcmd}:" - (( $#words > 3 )) && ign='!' - args=( - "${ign}(-)"{-h,--help}'[display usage information]' - '1: :{ _wanted actions expl action compadd -a gactions }' - ) + args+=( '1: :{ _wanted actions expl action compadd -a gactions }' ) case $subcmd in *-*) args+=( @@ -403,4 +427,19 @@ case $state in ;; esac +if [[ $state = plugins ]]; then + [[ -z $plug ]] && return ret + plugvar=_ansible_${plug}_plugins + typeset -ga ${plug} + if zstyle -T ":completion:${curcontext}:plugins" verbose; then + (( ${(P)#plugvar} )) || set -A ${plugvar} \ + ${${(f)"$(_call_program plugins ansible-doc -t $plug -l)"}/ ##/:} + _describe -t plugins "${plug} plugin" $plugvar -M 'r:|.=* r:|=*' && ret=0 + else + (( ${(P)#plugvar} )) || set -A ${plugvar} \ + ${${(f)"$(_call_program plugins ansible-doc -t $plug -F)"}%% *} + _wanted plugins expl "${plug} plugin" compadd -M 'r:|.=* r:|=*' -a $plugvar && ret=0 + fi +fi + return ret -- cgit v1.2.3 From bb36b80178e38adf67188a7367b88dd9de6b39db Mon Sep 17 00:00:00 2001 From: Sebastian Stark Date: Tue, 21 Feb 2023 23:12:47 +0100 Subject: 51470 (tweaked, c.f. 51476): Separate cdpath elements in path-directories completion --- ChangeLog | 4 ++++ Completion/Zsh/Command/_cd | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 204e64365..1897e2fa6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-02-24 Oliver Kiddle + * Sebastian Stark: 51470 (tweaked, c.f. 51476): + Completion/Zsh/Command/_cd: Separate cdpath elements in + path-directories completion + * 51474: Completion/Unix/Command/_ansible: make -e and --vault-id options repeatable and update for new options to ansible 2.13.2 diff --git a/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd index 46237e73d..961d121e0 100644 --- a/Completion/Zsh/Command/_cd +++ b/Completion/Zsh/Command/_cd @@ -70,8 +70,15 @@ else tmpcdpath=(${${(@)cdpath:#.}:#$PWD}) - (( $#tmpcdpath )) && - alt=( 'path-directories:directory in cdpath:_path_files -W tmpcdpath -/' ) + if zstyle -t ":completion:${curcontext}:path-directories" separate-sections; then + local elem + for ((elem=1; elem <= $#tmpcdpath; elem++)); do + alt+=( "path-directories-$elem:directory in $tmpcdpath[$elem]:_path_files -W 'tmpcdpath[$elem]' -/" ) + done + else + (( $#tmpcdpath )) && + alt=( 'path-directories:directory in cdpath:_path_files -W tmpcdpath -/' ) + fi # With cdablevars, we can complete foo as if ~foo/ if [[ -o cdablevars && -n "$PREFIX" && "$PREFIX" != <-> ]]; then -- cgit v1.2.3 From d76004588b26c179893431122ebfe064d58cf907 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Thu, 23 Feb 2023 16:39:35 +0900 Subject: 51473: Update cal/ncal completion - Support util-linux and bsdmainutils cal on Linux - Support each BSD's implementations --- ChangeLog | 3 + Completion/Unix/Command/_cal | 129 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 119 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1897e2fa6..1891b8b5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-02-24 Oliver Kiddle + * Shohei YOSHIDA: 51473: Completion/Unix/Command/_cal: + Update cal/ncal completion + * Sebastian Stark: 51470 (tweaked, c.f. 51476): Completion/Zsh/Command/_cd: Separate cdpath elements in path-directories completion diff --git a/Completion/Unix/Command/_cal b/Completion/Unix/Command/_cal index 82bb98b5f..b92e8153f 100644 --- a/Completion/Unix/Command/_cal +++ b/Completion/Unix/Command/_cal @@ -1,28 +1,131 @@ #compdef cal ncal -local args +local -a args +args=() case $service in cal) - args=( - '-3[three in a row]' - '-m[Monday as first day of the week]' - ) + # check util-linux's cal or bsdmainutils's cal + if $service --version 1>/dev/null 2>/dev/null ; then + args+=( + '(-1 --one)'{-1,--one}'[show only a single month]' + '(-3 --three)'{-3,--three}'[show three months spanning the date]' + '(-n --months)'{-n,--months=}"[show num months starting with date's month]:month" + '(-S --span)'{-S,--span}'[span the date when displaying multiple month]' + '(-s --sunday)'{-s,--sunday}'[Sunday as first day of week]' + '(-m --monday)'{-m,--monday}'[Monday as first day of week]' + '(-j --julian)'{-j,--julian}'[use day-of-year for all calendars]' + '--reform=[Gregorian reform date]:val:(1752 gregorian iso julian)' + '--iso[alias for --reform=iso]' + '(-y --year)'{-y,--year}'[show the whole year]' + '(-Y --twelve)'{-Y,--twelve}'[show the next twelve months]' + '(-w --week)'{-w,--week=-}'[show US or ISO-8601 week numbers]::num' + '(-v --vertical)'{-v,--vertical}'[show day vertically instead of line]' + '(-c --columns)'{-c,--columns=}'[amount of columns to use]:width' + '--color=-[colorize messages]:when:(auto always never)' + '(- *)'{-h,--help}'[display help]' + '(- *)'{-V,--version}'[display version]' + ) + else + case $OSTYPE in + (linux*|openbsd*|freebsd*|netbsd*|darwin*|dragonfly*) + args+=( + '-j[display Julian days]' + ) + ;| + (linux*|freebsd*|netbsd*|darwin*|dragonfly*) + args+=( + '-3[display the previous, current and next month surrounding today]' + '-A[months to add after]:months' + '-B[months to add before]:months' + ) + ;| + (freebsd*|netbsd*|darwin*|dragonfly*) + args+=( + '-h[turns off highlighting of today]' + ) + ;| + (netbsd*|openbsd*) + args+=( + '-y[display a calendar for the current year]' + ) + ;| + (linux*|freebsd*|darwin*|dragonfly*) + args+=( + '-m[display the specified month]:month' + '-y[display a calendar for the specified year]:year' + '-C[switch to cal mode]' + '-d[use yyyy-mm as the current date]:yyyy-mm' + ) + ;| + (freebsd*|darwin*|dragonfly*) + args+=( + '-N[switch to ncal mode]' + ) + ;| + (linux*) + args+=( + '-1[display only the current month]' + ) + ;| + (openbsd*) + args+=( + '-m[display weeks starting on Monday instead of Sunday]' + '-w[display week numbers in the month display]' + ) + ;| + (netbsd*) + args+=( + '-C[display context months before and after the specified month]:months' + '-d[specifies the day of the week on which the calendar should start]:day_of_week' + '-h[highlight the current day]' + '-R[selects an alternate Gregorian reform point from the default of September 3rd, 1752]:reform-sp' + '-r[display the month in which the Gregorian Reform adjustment was applied]' + ) + ;; + esac + fi ;; ncal) args=( - '-J[display Julian calendar]' - '-e[display date of western Easter]' - '-o[display date of orthodox Easter]' - '-p[assume as by ncal]' - '-s[country code]' - '-w[print number of the week below each column]' + '-h[turns off highlighting of today]' + '-J[display Julian Calendar]' + '-e[display date of Easter]' + '-j[display Julian days]' + '-o[display date of Orthodox Easter]' + '-m[display the specified month]:month' + '-p[print the country codes and switching days from Julian to Gregorian Calendar]' + '-s[assume the switch from Julian to Gregorian Calendar at the date associated with the country_code]:country_code' + '-w[print the number of the week below each week column]' + '-y[display a calendar for the specified year]:year' + '-3[display the previous, current and next month surrounding today]' + '-A[months to add after]:months' + '-B[months to add before]:months' + '-C[switch to cal mode]' + '-d[use yyyy-mm as the current date]:yyyy-mm' + '-H[use yyyy-mm-dd as the current date]:yyyy-mm-dd' + '-M[weeks start on Monday]' + '-S[weeks start on Sunday]' + '-W[first week of the year has at least number days]:number' + '-b[use oldstyle format for ncal output]' ) + + case $OSTYPE in + (linux*) + args+=( + '-b[use oldstyle format for ncal output]' + '-1[display only the current month]' + ) + ;; + (*) + args+=( + '-N[switch to ncal mode]' + ) + ;; + esac ;; esac _arguments "${args[@]}" \ - '-j[display Julian days]' \ - '-y[display a calendar for the current year]' \ '::month' \ ':year' -- cgit v1.2.3 From ec4bd3169d0734ca8ec74ccc52235e71d7e59166 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 26 Feb 2023 18:54:10 -0800 Subject: 51460: avoid crash on bad parameter autofeature --- ChangeLog | 4 ++++ Src/module.c | 17 +++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1891b8b5a..2c07606c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-02-26 Bart Schaefer + + * 51460: Src/module.c: avoid crash on bad parameter autofeature + 2023-02-24 Oliver Kiddle * Shohei YOSHIDA: 51473: Completion/Unix/Command/_cal: diff --git a/Src/module.c b/Src/module.c index 6cf442270..a6005f30b 100644 --- a/Src/module.c +++ b/Src/module.c @@ -1198,6 +1198,7 @@ add_autoparam(const char *module, const char *pnam, int flags) { Param pm; int ret; + int ne = noerrs; queue_signals(); if ((ret = checkaddparam(pnam, (flags & FEAT_IGNORE)))) { @@ -1212,14 +1213,18 @@ add_autoparam(const char *module, const char *pnam, int flags) return ret == 2 ? 0 : -1; } - pm = setsparam(dupstring(pnam), ztrdup(module)); - - pm->node.flags |= PM_AUTOLOAD; - if (flags & FEAT_AUTOALL) - pm->node.flags |= PM_AUTOALL; + noerrs = 2; + if ((pm = setsparam(dupstring(pnam), ztrdup(module)))) { + pm->node.flags |= PM_AUTOLOAD; + if (flags & FEAT_AUTOALL) + pm->node.flags |= PM_AUTOALL; + ret = 0; + } else + ret = -1; + noerrs = ne; unqueue_signals(); - return 0; + return ret; } /* Remove a parameter added with add_autoparam() */ -- cgit v1.2.3 From 3d8c567d581831ed2a60b34d8a855531b0cf197d Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 26 Feb 2023 19:18:19 -0800 Subject: Fix typo --- ChangeLog | 2 ++ Doc/Zsh/restricted.yo | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2c07606c5..6ce0d9fbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-02-26 Bart Schaefer + * unposted: Doc/Zsh/restricted.yo: fix typo + * 51460: Src/module.c: avoid crash on bad parameter autofeature 2023-02-24 Oliver Kiddle diff --git a/Doc/Zsh/restricted.yo b/Doc/Zsh/restricted.yo index 33dfc96c6..7948cfe8a 100644 --- a/Doc/Zsh/restricted.yo +++ b/Doc/Zsh/restricted.yo @@ -65,7 +65,7 @@ variables. Except for the few listed above, zsh does not restrict the setting of environment variables. If a `tt(perl)', `tt(python)', `tt(bash)', or other general purpose -interpreted script it treated as a restricted +interpreted script is treated as a restricted command, the user can work around the restriction by setting specially crafted `tt(PERL5LIB)', `tt(PYTHONPATH)', `tt(BASHENV)' (etc.) environment variables. On GNU systems, any -- cgit v1.2.3 From b3980ecc583bfe34db46d47538448af1a953095e Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 26 Feb 2023 19:26:46 -0800 Subject: 51464: utility to interpret zsh.h constants --- ChangeLog | 2 + Util/printdefines | 601 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 603 insertions(+) create mode 100644 Util/printdefines diff --git a/ChangeLog b/ChangeLog index 6ce0d9fbf..6ba598e4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-02-26 Bart Schaefer + * 51464: Util/printdefines: utility to interpret zsh.h constants + * unposted: Doc/Zsh/restricted.yo: fix typo * 51460: Src/module.c: avoid crash on bad parameter autofeature diff --git a/Util/printdefines b/Util/printdefines new file mode 100644 index 000000000..30c06533b --- /dev/null +++ b/Util/printdefines @@ -0,0 +1,601 @@ +#!/bin/zsh -f +emulate -L zsh -o extendedglob + +zmodload zsh/param/private + +local -AHPrt jobstats=( + mapbase 16 + $((0x0001)) STAT_CHANGED # status changed and not reported + $((0x0002)) STAT_STOPPED # all procs stopped or exited + $((0x0004)) STAT_TIMED # job is being timed + $((0x0008)) STAT_DONE # job is done + $((0x0010)) STAT_LOCKED # shell is finished creating this job, + # may be deleted from job table + $((0x0020)) STAT_NOPRINT # job was killed internally, + # we don't want to show that + $((0x0040)) STAT_INUSE # this job entry is in use + $((0x0080)) STAT_SUPERJOB # job has a subjob + $((0x0100)) STAT_SUBJOB # job is a subjob + $((0x0200)) STAT_WASSUPER # was a super-job, sub-job needs to be + # deleted + $((0x0400)) STAT_CURSH # last command is in current shell + $((0x0800)) STAT_NOSTTY # the tty settings are not inherited + # from this job when it exits. + $((0x1000)) STAT_ATTACH # delay reattaching shell to tty + $((0x2000)) STAT_SUBLEADER # is super-job, but leader is sub-shell + + $((0x4000)) STAT_BUILTIN # job at tail of pipeline is a builtin + $((0x8000)) STAT_SUBJOB_ORPHANED + # STAT_SUBJOB with STAT_SUPERJOB exited + $((0x10000)) STAT_DISOWN # STAT_SUPERJOB with disown pending + +#-1 SP_RUNNING # fake status for jobs currently running +) +local -AHPrt paramflags=( + mapbase 2 + 0 PM_SCALAR # scalar + $((1<<0)) PM_ARRAY # array + $((1<<1)) PM_INTEGER # integer + $((1<<2)) PM_EFLOAT # double with %e output + $((1<<3)) PM_FFLOAT # double with %f output + $((1<<4)) PM_HASHED # association + + $((1<<5)) PM_LEFT # left justify, remove leading blanks + $((1<<6)) PM_RIGHT_B # right justify, fill with leading blanks + $((1<<7)) PM_RIGHT_Z # right justify, fill with leading zeros + $((1<<8)) PM_LOWER # all lower case + + $((1<<9)) PM_UPPER # all upper case +# $((1<<9)) PM_UNDEFINED # undefined (autoloaded) shell function + + $((1<<10)) PM_READONLY # readonly + $((1<<11)) PM_TAGGED # tagged + $((1<<12)) PM_EXPORTED # exported +# $((1<<12)) PM_ABSPATH_USED # (function): loaded using absolute path + + $((1<<13)) PM_UNIQUE # remove duplicates +# $((1<<13)) PM_UNALIASED # (function) do not expand aliases + + $((1<<14)) PM_HIDE # Special behaviour hidden by local +# $((1<<14)) PM_CUR_FPATH # (function): can use $fpath with filename + $((1<<15)) PM_HIDEVAL # Value not shown in `typeset' commands +# $((1<<15)) PM_WARNNESTED # (function): non-recursive WARNNESTEDVAR + $((1<<16)) PM_TIED # array tied to colon-path or v.v. +# $((1<<16)) PM_TAGGED_LOCAL # (function): non-recursive PM_TAGGED + +# Remaining flags do not correspond directly to command line switches + $((1<<17)) PM_DONTIMPORT_SUID # do not import if running setuid +# $((1<<17)) PM_LOADDIR # (function) filename gives load directory + $((1<<18)) PM_SINGLE # special can only have a single instance + $((1<<18)) PM_ANONYMOUS # (function) anonymous function + $((1<<19)) PM_LOCAL # this parameter will be made local +# $((1<<19)) PM_KSHSTORED # (function) stored in ksh form + $((1<<20)) PM_SPECIAL # special builtin parameter +# $((1<<20)) PM_ZSHSTORED # (function) stored in zsh form + $((1<<21)) PM_RO_BY_DESIGN # specials that can be made read-only by user +##$(((1<<20)|(1<<10)|(1<<21))) PM_READONLY_SPECIAL +# $((1<<22)) PM_DONTIMPORT # do not import this variable + $((1<<22)) PM_DECLARED # explicitly named with typeset + $((1<<23)) PM_RESTRICTED # cannot be changed in restricted mode + $((1<<24)) PM_UNSET # has null value +##$(((1<<22)|(1<<24))) PM_DEFAULTED + $((1<<25)) PM_REMOVABLE # special can be removed from paramtab + $((1<<26)) PM_AUTOLOAD # autoloaded from module + $((1<<27)) PM_NORESTORE # do not restore value of local special + $((1<<27)) PM_AUTOALL # autoload all features in module + $((1<<28)) PM_HASHELEM # is a hash-element + $((1<<29)) PM_NAMEDDIR # has a corresponding nameddirtab entry + $((1<<30)) PM_NAMEREF # pointer to a different parameter +) +local -AHPrt chartokens=( + mapbase integer + $((83)) Meta + $((84)) Pound + $((85)) String + $((86)) Hat + $((87)) Star + $((88)) Inpar + $((89)) Inparmath + $((90)) Outbrace + $((91)) Inbrack + $((92)) Outbrack + $((93)) Tick + $((94)) Inang + $((95)) Outang + $((96)) OutangProc + $((97)) Quest + $((98)) Tilde + $((99)) Qtick + $((a0)) Bnullkeep + $((a1)) Nularg + $((a2)) Marker +) +local -AHPrt fdtabletype=( + mapbase integer + $((0)) FDT_UNUSED + $((1)) FDT_INTERNAL + $((2)) FDT_EXTERNAL + $((3)) FDT_MODULE + $((4)) FDT_XTRACE + $((5)) FDT_FLOCK + $((6)) FDT_FLOCK_EXEC + $((7)) FDT_PROC_SUBST +) +local -AHPrt inputstates=( + mapbase 2 + $((1<<0)) INP_FREE + $((1<<1)) INP_ALIAS + $((1<<2)) INP_HIST + $((1<<3)) INP_CONT + $((1<<4)) INP_ALCONT + $((1<<5)) INP_HISTCONT +) +local -AHPrt metafytypes=( + mapbase integer + $((0)) META_REALLOC + $((1)) META_USEHEAP + $((2)) META_STATIC + $((3)) META_DUP + $((4)) META_ALLOC + $((5)) META_NOALLOC + $((6)) META_HEAPDUP + $((7)) META_HREALLOC +) +local -AHPrt jobtypes=( + mapbase 2 + $((1<<0)) Z_TIMED # pipeline is being timed + $((1<<1)) Z_SYNC # run this sublist synchronously (;) + $((1<<2)) Z_ASYNC # run this sublist asynchronously (&) + $((1<<3)) Z_DISOWN # run this sublist without job control (&|) + $((1<<4)) Z_END + $((1<<5)) Z_SIMPLE +) +local -AHPrt condtypes=( + mapbase integer + $((0)) COND_NOT + $((1)) COND_AND + $((2)) COND_OR + $((3)) COND_STREQ + $((4)) COND_STRDEQ + $((5)) COND_STRNEQ + $((6)) COND_STRLT + $((7)) COND_STRGTR + $((8)) COND_NT + $((9)) COND_OT + $((10)) COND_EF + $((11)) COND_EQ + $((12)) COND_NE + $((13)) COND_LT + $((14)) COND_GT + $((15)) COND_LE + $((16)) COND_GE + $((17)) COND_REGEX + $((18)) COND_MOD + $((19)) COND_MODI +) +local -AHPrt wordcodes=( + mapbase integer + $((1)) WC_LIST + $((2)) WC_SUBLIST + $((3)) WC_PIPE + $((4)) WC_REDIR + $((5)) WC_ASSIGN + $((6)) WC_SIMPLE + $((7)) WC_TYPESET + $((8)) WC_SUBSH + $((9)) WC_CURSH + $((10)) WC_TIMED + $((11)) WC_FUNCDEF + $((12)) WC_FOR + $((13)) WC_SELECT + $((14)) WC_WHILE + $((15)) WC_REPEAT + $((16)) WC_CASE + $((17)) WC_IF + $((18)) WC_COND + $((19)) WC_ARITH + $((20)) WC_AUTOFN + $((21)) WC_TRY + $((22)) WC_COUNT +) +local -AHPrt wcsublists=( + mapbase 10 + $((0)) WC_SUBLIST_END + $((1)) WC_SUBLIST_AND + $((2)) WC_SUBLIST_OR + $((4)) WC_SUBLIST_COPROC + $((8)) WC_SUBLIST_NOT + $((16)) WC_SUBLIST_SIMPLE +) +local -AHPrt eprogstates=( + mapbase 10 + $((1)) EF_REAL + $((2)) EF_HEAP + $((4)) EF_MAP + $((8)) EF_RUN +) +local -AHPrt builtintypes=( + mapbase 2 + $((1<<1)) BINF_PLUSOPTS # +xyz legal + $((1<<2)) BINF_PRINTOPTS + $((1<<3)) BINF_ADDED # is in the builtins hash table + $((1<<5)) BINF_PREFIX + $((1<<6)) BINF_DASH + $((1<<7)) BINF_BUILTIN + $((1<<8)) BINF_COMMAND + $((1<<9)) BINF_EXEC + $((1<<10)) BINF_NOGLOB + $((1<<11)) BINF_PSPECIAL + $((1<<12)) BINF_SKIPINVALID # Treat invalid option as argument + $((1<<13)) BINF_KEEPNUM # `[-+]NUM' can be an option + $((1<<14)) BINF_SKIPDASH # Treat `-' as argument (maybe `+') + $((1<<15)) BINF_DASHDASHVALID # Handle `--' even if SKIPINVALD + $((1<<16)) BINF_CLEARENV # new process started with cleared env + $((1<<17)) BINF_AUTOALL # autoload all features at once + $((1<<18)) BINF_HANDLES_OPTS + $((1<<19)) BINF_ASSIGN +) +local -AHPrt patflags=( + mapbase 16 + $((0x0000)) PAT_HEAPDUP # Dummy flag for default behavior + $((0x0001)) PAT_FILE # Pattern is a file name + $((0x0002)) PAT_FILET # Pattern is top level file, affects ~ + $((0x0004)) PAT_ANY # Match anything (cheap "*") + $((0x0008)) PAT_NOANCH # Not anchored at end + $((0x0010)) PAT_NOGLD # Don't glob dots + $((0x0020)) PAT_PURES # Pattern is a pure string: set internally + $((0x0040)) PAT_STATIC # Don't copy pattern to heap as per default + $((0x0080)) PAT_SCAN # Scanning, so don't try must-match test + $((0x0200)) PAT_NOTSTART # Start of string is not real start + $((0x0400)) PAT_NOTEND # End of string is not real end + $((0x0800)) PAT_HAS_EXCLUDP # (internal): top-level path1~path2. +) +local -AHPrt patclasses=( + mapbase integer + $((1)) PP_FIRST + $((1)) PP_ALPHA + $((2)) PP_ALNUM + $((3)) PP_ASCII + $((4)) PP_BLANK + $((5)) PP_CNTRL + $((6)) PP_DIGIT + $((7)) PP_GRAPH + $((8)) PP_LOWER + $((9)) PP_PRINT + $((10)) PP_PUNCT + $((11)) PP_SPACE + $((12)) PP_UPPER + $((13)) PP_XDIGIT + $((14)) PP_IDENT + $((15)) PP_IFS + $((16)) PP_IFSSPACE + $((17)) PP_WORD + $((18)) PP_INCOMPLETE + $((19)) PP_INVALID + $((19)) PP_LAST + $((20)) PP_UNKWN + $((21)) PP_RANGE +) +local -AHPrt globmodifiers=( + mapbase 16 + $((0x0100)) GF_LCMATCHUC + $((0x0200)) GF_IGNCASE + $((0x0400)) GF_BACKREF + $((0x0800)) GF_MATCHREF + $((0x1000)) GF_MULTIBYTE # Use multibyte if supported by build +) +local -AHPrt scanparamflags=( + mapbase 2 + $((1<<0)) SCANPM_WANTVALS # Return value includes hash values + $((1<<1)) SCANPM_WANTKEYS # Return value includes hash keys + $((1<<2)) SCANPM_WANTINDEX # Return value includes array index + $((1<<3)) SCANPM_MATCHKEY # Subscript matched against key + $((1<<4)) SCANPM_MATCHVAL # Subscript matched against value + $((1<<5)) SCANPM_MATCHMANY # Subscript matched repeatedly, return all + $((1<<6)) SCANPM_ASSIGNING # Assigning whole array/hash + $((1<<7)) SCANPM_KEYMATCH # keys of hash treated as patterns + $((1<<8)) SCANPM_DQUOTED # substitution was double-quoted + $((1<<9)) SCANPM_ARRONLY # value is array but we don't + $((1<<10)) SCANPM_CHECKING # Check if set, no need to create + $((1<<11)) SCANPM_NOEXEC # No command substitutions, etc. +) +local -AHPrt substmodifiers=( + mapbase 16 + $((0x0001)) SUB_END # match end instead of beginning, % or %% + $((0x0002)) SUB_LONG # % or # doubled, get longest match + $((0x0004)) SUB_SUBSTR # match a substring + $((0x0008)) SUB_MATCH # include the matched portion + $((0x0010)) SUB_REST # include the unmatched portion + $((0x0020)) SUB_BIND # index of beginning of string + $((0x0040)) SUB_EIND # index of end of string + $((0x0080)) SUB_LEN # length of match + $((0x0100)) SUB_ALL # match complete string + $((0x0200)) SUB_GLOBAL # global substitution ${..//all/these} + $((0x0400)) SUB_DOSUBST # replacement string needs substituting + $((0x4000)) SUB_EGLOB # use extended globbing in patterns +) +local -AHPrt printnodeflags=( + mapbase 2 + $((1<<0)) PRINT_NAMEONLY + $((1<<1)) PRINT_TYPE + $((1<<2)) PRINT_LIST + $((1<<3)) PRINT_KV_PAIR + $((1<<4)) PRINT_INCLUDEVALUE + $((1<<5)) PRINT_TYPESET + $((1<<6)) PRINT_LINE + $((1<<7)) PRINT_POSIX_EXPORT + $((1<<8)) PRINT_POSIX_READONLY + $((1<<7)) PRINT_WHENCE_CSH + $((1<<8)) PRINT_WHENCE_VERBOSE + $((1<<9)) PRINT_WHENCE_SIMPLE + $((1<<10)) PRINT_WHENCE_FUNCDEF + $((1<<11)) PRINT_WHENCE_WORD +) +local -AHPrt savehistflags=( + mapbase 16 + $((0x00000001)) HIST_MAKEUNIQUE # Kill this new entry if not unique + $((0x00000002)) HIST_OLD # Command is already written to disk + $((0x00000004)) HIST_READ # Command was read back from disk + $((0x00000008)) HIST_DUP # Command duplicates a later line + $((0x00000010)) HIST_FOREIGN # Command came from another shell + $((0x00000020)) HIST_TMPSTORE # Kill when user enters another cmd + $((0x00000040)) HIST_NOWRITE # Keep internally but don't write +) +local -AHPrt histflags=( + mapbase 10 + $((1)) HISTFLAG_DONE + $((2)) HISTFLAG_NOEXEC + $((4)) HISTFLAG_RECALL + $((8)) HISTFLAG_SETTY +) +local -AHPrt histfileflags=( + mapbase 16 + $((0x0001)) HFILE_APPEND + $((0x0002)) HFILE_SKIPOLD + $((0x0004)) HFILE_SKIPDUPS + $((0x0008)) HFILE_SKIPFOREIGN + $((0x0010)) HFILE_FAST + $((0x0020)) HFILE_NO_REWRITE + $((0x8000)) HFILE_USE_OPTIONS +) +local -AHPrt modloadflags=( + mapbase 2 + $((1<<0)) MOD_BUSY + $((1<<1)) MOD_UNLOAD + $((1<<2)) MOD_SETUP + $((1<<3)) MOD_LINKED + $((1<<4)) MOD_INIT_S + $((1<<5)) MOD_INIT_B + $((1<<6)) MOD_ALIAS +) +local -AHPrt modcondflags=( + mapbase 10 + $((1)) CONDF_INFIX + $((2)) CONDF_ADDED + $((4)) CONDF_AUTOALL +) +local -AHPrt mathfunctypes=( + mapbase 10 + $((1)) MFF_STR + $((2)) MFF_ADDED + $((4)) MFF_USERFUNC + $((8)) MFF_AUTOALL +) +local -AHPrt lexflags=( + mapbase 16 + $((0x0001)) LEXFLAGS_ACTIVE + $((0x0002)) LEXFLAGS_ZLE + $((0x0004)) LEXFLAGS_COMMENTS_KEEP + $((0x0008)) LEXFLAGS_COMMENTS_STRIP + $((0x0010)) LEXFLAGS_NEWLINE +) +local -AHPrt lexstates=( + mapbase integer + $((0)) IN_NOTHING + $((1)) IN_CMD + $((2)) IN_MATH + $((3)) IN_COND + $((4)) IN_ENV + $((5)) IN_PAR +) +local -AHPrt emulations=( + mapbase 2 + $((1<<1)) EMULATE_CSH # C shell + $((1<<2)) EMULATE_KSH # Korn shell + $((1<<3)) EMULATE_SH # Bourne shell + $((1<<4)) EMULATE_ZSH # `native' mode +) +local -AHPrt terminaltypes=( + mapbase 16 + $((0x01)) TERM_BAD # terminal has extremely basic capabilities + $((0x02)) TERM_UNKNOWN # unknown terminal type + $((0x04)) TERM_NOUP # terminal has no up capability + $((0x08)) TERM_SHORT # terminal is < 3 lines high + $((0x10)) TERM_NARROW # terminal is < 3 columns wide +) +local -AHPrt termcapacts=( + mapbase integer + $((0)) TCCLEARSCREEN + $((1)) TCLEFT + $((2)) TCMULTLEFT + $((3)) TCRIGHT + $((4)) TCMULTRIGHT + $((5)) TCUP + $((6)) TCMULTUP + $((7)) TCDOWN + $((8)) TCMULTDOWN + $((9)) TCDEL + $((10)) TCMULTDEL + $((11)) TCINS + $((12)) TCMULTINS + $((13)) TCCLEAREOD + $((14)) TCCLEAREOL + $((15)) TCINSLINE + $((16)) TCDELLINE + $((17)) TCNEXTTAB + $((18)) TCBOLDFACEBEG + $((19)) TCFAINTBEG + $((20)) TCSTANDOUTBEG + $((21)) TCUNDERLINEBEG + $((22)) TCITALICSBEG + $((23)) TCALLATTRSOFF + $((24)) TCSTANDOUTEND + $((25)) TCUNDERLINEEND + $((26)) TCITALICSEND + $((27)) TCHORIZPOS + $((28)) TCUPCURSOR + $((29)) TCDOWNCURSOR + $((30)) TCLEFTCURSOR + $((31)) TCRIGHTCURSOR + $((32)) TCSAVECURSOR + $((33)) TCRESTRCURSOR + $((34)) TCBACKSPACE + $((35)) TCFGCOLOUR + $((36)) TCBGCOLOUR +) +local -AHPrt cmdstackstates=( + mapbase integer + $((0)) CS_FOR + $((1)) CS_WHILE + $((2)) CS_REPEAT + $((3)) CS_SELECT + $((4)) CS_UNTIL + $((5)) CS_IF + $((6)) CS_IFTHEN + $((7)) CS_ELSE + $((8)) CS_ELIF + $((9)) CS_MATH + $((10)) CS_COND + $((11)) CS_CMDOR + $((12)) CS_CMDAND + $((13)) CS_PIPE + $((14)) CS_ERRPIPE + $((15)) CS_FOREACH + $((16)) CS_CASE + $((17)) CS_FUNCDEF + $((18)) CS_SUBSH + $((19)) CS_CURSH + $((20)) CS_ARRAY + $((21)) CS_QUOTE + $((22)) CS_DQUOTE + $((23)) CS_BQUOTE + $((24)) CS_CMDSUBST + $((25)) CS_MATHSUBST + $((26)) CS_ELIFTHEN + $((27)) CS_HEREDOC + $((28)) CS_HEREDOCD + $((29)) CS_BRACE + $((30)) CS_BRACEPAR + $((31)) CS_ALWAYS + $((32)) CS_COUNT +) + +zmodload zsh/parameter +local seek=${parameters[paramflags]} + +if [[ $1 = (|-)-h(|elp) ]] +then + print -u2 Usage: + print -u2 " printdefines [ category ] [ name | value ]" + shift +fi + +if [[ -z $1 ]] +then + print -u2 "Choose category:" + print -u2 -aC3 -- ${(ok)parameters[(R)$seek]} + return 1 +fi + +local -a outflag + +if [[ -z $parameters[$1] || $parameters[$1] != $seek ]] +then + local -n scan + for scan in ${(k)parameters[(R)$seek]} + do + if [[ -n ${scan[(R)$1]} ]] + then + local -a hits + set -A hits ${${(nk)scan[(R)$~1]}:#mapbase} + integer -i ${scan[mapbase]/integer/10} w=${hits[-1]} + integer x=${#${scan[mapbase]/integer/}}+2 + while (($#hits)) + do + if [[ $scan[mapbase] = 2 ]] + then + w=${hits[1]} + local +i flag + if (( w )) + then + printf -v flag '1<<%d\t%s' $((${#w} - x)) $hits[1] + else + printf -v flag '0<<0\t%s' $hits[1] + fi + else + integer -i ${scan[mapbase]/integer/10} -Z ${#w} flag=${hits[1]} + fi + outflag+=($scan[$hits[1]] $flag ) + shift hits + done + local +n scan # ${!scan} + print -aC2 -- "--- $scan" --- $outflag + local -n scan + outflag=() + fi + done + return 0 +fi + +local -n ref=$1 + +if [[ $2 = <-> ]] +then + integer i=$2 + integer flag + if [[ $ref[mapbase] = integer ]] + then + if (( (i -= ${${ref[$2]:+$2}:-0}) == 0 )) + then + outflag=($ref[$2]) + fi + else + for flag in ${${(nk)ref}:#mapbase} + do + if (( i == flag || flag > 0 && (i & flag) == flag )) + then + # print $i $flag + outflag+=(${ref[$flag]}) + (( i -= flag )) + fi + done + fi + print $2 ${(j:|:)outflag} + if (( i )) + then + print Unknown $1: $i + fi +else + set -- ${${(nk)ref[(R)${~2:-*}]}:#mapbase} + integer -i ${ref[mapbase]/integer/10} w=${argv[-1]} + integer x=${#${ref[mapbase]/integer/}}+2 + while ((ARGC)) + do + if [[ $ref[mapbase] = 2 ]] + then + integer -i 2 w=$1 + local +i flag + if (( w )) + then + printf -v flag '1<<%d\t%s' $((${#w} - x)) $1 + else + printf -v flag '0<<0\t%s' $1 + fi + else + integer -i ${ref[mapbase]/integer/10} -Z ${#w} flag=$1 + fi + outflag+=($ref[$1] $flag ) + shift + done + print -aC2 -- $outflag +fi -- cgit v1.2.3 From 86a5278f9f5ab516ff2b099d64af2d5567983b5a Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Tue, 28 Feb 2023 14:35:52 +0100 Subject: 51491: Check should use zlemetacs instead of zlecs Coverity noticed that this first branch of the if statement has "meta" added to all the variable names except this zlecs at the end, so change it to match. --- ChangeLog | 5 +++++ Src/Zle/zle_utils.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6ba598e4c..3fc73e413 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-02-28 Mikael Magnusson + + * 51491: Src/Zle/zle_utils.c: Check should use zlemetacs instead + of zlecs + 2023-02-26 Bart Schaefer * 51464: Util/printdefines: utility to interpret zsh.h constants diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 9ce91049c..454a877a9 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -799,7 +799,7 @@ spaceinline(int ct) if (rhp->start_meta - sub >= zlemetacs) { rhp->start_meta += ct; } - if (rhp->end_meta - sub >= zlemetacs && (!predisplaylen || zlecs)) { + if (rhp->end_meta - sub >= zlemetacs && (!predisplaylen || zlemetacs)) { rhp->end_meta += ct; } } -- cgit v1.2.3 From 806d096b0e7a64bf9712be1cb8159a1ef5b4bf81 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 5 Mar 2023 13:26:57 -0800 Subject: unposted: fix memory leak flagged by coverity --- ChangeLog | 4 ++++ Src/Modules/param_private.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3fc73e413..e344e8878 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-03-05 Bart Schaefer + + * unposted: Src/Modules/param_private.c: coverity memory leak + 2023-02-28 Mikael Magnusson * 51491: Src/Zle/zle_utils.c: Check should use zlemetacs instead diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index 70f36ceb1..e43f0edb4 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -122,6 +122,7 @@ makeprivate(HashNode hn, UNUSED(int flags)) break; default: makeprivate_error = 1; + zfree(gsu, sizeof(struct gsu_closure)); break; } /* PM_HIDE so new parameters in deeper scopes do not shadow */ -- cgit v1.2.3 From a9ba1662165823a0303a03fdeddb2ce4ca3814e5 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 5 Mar 2023 14:03:42 -0800 Subject: 51483: Enable assignment and expansion of parameters with ksh-like namespace prefixes. --- ChangeLog | 5 +++++ Src/Zle/compcore.c | 4 ++-- Src/Zle/zle_tricky.c | 6 +++--- Src/lex.c | 2 +- Src/params.c | 11 ++++++----- Src/subst.c | 15 +++++++++------ Src/utils.c | 18 ++++++++++++++++-- Src/zsh.h | 2 ++ Src/ztype.h | 1 + 9 files changed, 45 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index e344e8878..38a0395d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2023-03-05 Bart Schaefer + * 51483: Src/Zle/compcore.c, Src/Zle/zle_tricky.c, Src/lex.c, + Src/params.c, Src/subst.c, Src/utils.c, Src/zsh.h, Src/ztype.h: + Enable assignment and expansion of parameters with ksh-like + namespace prefixes. + * unposted: Src/Modules/param_private.c: coverity memory leak 2023-02-28 Mikael Magnusson diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 64a860fa3..77fce66e8 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1230,14 +1230,14 @@ check_param(char *s, int set, int test) else if (idigit(*e)) while (idigit(*e)) e++; - else if ((ie = itype_end(e, IIDENT, 0)) != e) { + else if ((ie = itype_end(e, INAMESPC, 0)) != e) { do { e = ie; if (comppatmatch && *comppatmatch && (*e == Star || *e == Quest)) ie = e + 1; else - ie = itype_end(e, IIDENT, 0); + ie = itype_end(e, INAMESPC, 0); } while (ie != e); } diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 07fac7144..690cf6efb 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -576,7 +576,7 @@ parambeg(char *s) while (idigit(*e)) e++; else - e = itype_end(e, IIDENT, 0); + e = itype_end(e, INAMESPC, 0); /* Now make sure that the cursor is inside the name. */ if (offs <= e - s && offs >= b - s && n <= 0) { @@ -765,7 +765,7 @@ docomplete(int lst) else if (idigit(*q)) do q++; while (idigit(*q)); else - q = itype_end(q, IIDENT, 0); + q = itype_end(q, INAMESPC, 0); sav = *q; *q = '\0'; if (zlemetacs - wb == q - s && @@ -1497,7 +1497,7 @@ get_comp_string(void) if (varq) tt = clwords[clwpos]; - s = itype_end(tt, IIDENT, 0); + s = itype_end(tt, INAMESPC, 0); sav = *s; *s = '\0'; zsfree(varname); diff --git a/Src/lex.c b/Src/lex.c index 15da85a93..2f7937410 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -1230,7 +1230,7 @@ gettokstr(int c, int sub) else { int sav = *lexbuf.ptr; *lexbuf.ptr = '\0'; - t = itype_end(t, IIDENT, 0); + t = itype_end(t, INAMESPC, 0); if (t < lexbuf.ptr) { skipparens(Inbrack, Outbrack, &t); } else { diff --git a/Src/params.c b/Src/params.c index 90302b1b0..d3b6a7d43 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1223,7 +1223,7 @@ isident(char *s) break; } else { /* Find the first character in `s' not in the iident type table */ - ss = itype_end(s, IIDENT, 0); + ss = itype_end(s, INAMESPC, 0); } /* If the next character is not [, then it is * @@ -2086,6 +2086,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) char *s, *t, *ie; char sav, c; int ppar = 0; + int itype = (flags & SCANPM_NONAMESPC) ? IIDENT : INAMESPC; s = t = *pptr; @@ -2095,7 +2096,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) else ppar = *s++ - '0'; } - else if ((ie = itype_end(s, IIDENT, 0)) != s) + else if ((ie = itype_end(s, itype, 0)) != s) s = ie; else if (c == Quest) *s++ = '?'; @@ -2183,7 +2184,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) return v; } } else if (!(flags & SCANPM_ASSIGNING) && v->isarr && - itype_end(t, IIDENT, 1) != t && isset(KSHARRAYS)) + itype_end(t, INAMESPC, 1) != t && isset(KSHARRAYS)) v->end = 1, v->isarr = 0; } if (!bracks && *s) @@ -6196,7 +6197,7 @@ setscope(Param pm) if (pm->node.flags & PM_NAMEREF) { Param basepm; struct asgment stop; - char *t = pm->u.str ? itype_end(pm->u.str, IIDENT, 0) : NULL; + char *t = pm->u.str ? itype_end(pm->u.str, INAMESPC, 0) : NULL; /* Temporarily change nameref to array parameter itself */ if (t && *t == '[') @@ -6277,7 +6278,7 @@ upscope(Param pm, int reflevel) mod_export int valid_refname(char *val) { - char *t = itype_end(val, IIDENT, 0); + char *t = itype_end(val, INAMESPC, 0); if (*t != 0) { if (*t == '[') { diff --git a/Src/subst.c b/Src/subst.c index 05bfcc03b..7a4b433bc 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1870,7 +1870,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * these later on, too. */ c = *s; - if (itype_end(s, IIDENT, 1) == s && *s != '#' && c != Pound && + if (itype_end(s, INAMESPC, 1) == s && *s != '#' && c != Pound && !IS_DASH(c) && c != '!' && c != '$' && c != String && c != Qstring && c != '?' && c != Quest && @@ -2332,7 +2332,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } } else if ((c == '#' || c == Pound) && (inbrace || !isset(POSIXIDENTIFIERS)) && - (itype_end(s+1, IIDENT, 0) != s + 1 + (itype_end(s+1, INAMESPC, 0) != s + 1 || (cc = s[1]) == '*' || cc == Star || cc == '@' || cc == '?' || cc == Quest || cc == '$' || cc == String || cc == Qstring @@ -2369,8 +2369,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * Try to handle this when parameter is named * by (P) (second part of test). */ - if (itype_end(s+1, IIDENT, 0) != s+1 || (aspar && isstring(s[1]) && - (s[2] == Inbrace || s[2] == Inpar))) + if (itype_end(s+1, INAMESPC, 0) != s+1 || + (aspar && isstring(s[1]) && + (s[2] == Inbrace || s[2] == Inpar))) chkset = 1, s++; else if (!inbrace) { /* Special case for `$+' on its own --- leave unmodified */ @@ -2531,6 +2532,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, scanflags |= SCANPM_DQUOTED; if (chkset) scanflags |= SCANPM_CHECKING; + if (!inbrace) + scanflags |= SCANPM_NONAMESPC; /* * Second argument: decide whether to use the subexpression or * the string next on the line as the parameter name. @@ -3211,7 +3214,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, shortest = 0; ++s; } - if (*itype_end(s, IIDENT, 0)) { + if (*itype_end(s, INAMESPC, 0)) { untokenize(s); zerr("not an identifier: %s", s); return NULL; @@ -3271,7 +3274,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, int intersect = (*s == '*' || *s == Star); char **compare, **ap, **apsrc; ++s; - if (*itype_end(s, IIDENT, 0)) { + if (*itype_end(s, INAMESPC, 0)) { untokenize(s); zerr("not an identifier: %s", s); return NULL; diff --git a/Src/utils.c b/Src/utils.c index 55f2d1ab0..1393ecb13 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3123,7 +3123,7 @@ spckword(char **s, int hist, int cmd, int ask) if (**s == String && !*t) { guess = *s + 1; - if (itype_end(guess, IIDENT, 1) == guess) + if (itype_end(guess, INAMESPC, 1) == guess) return; ic = String; d = 100; @@ -4310,13 +4310,27 @@ wcsitype(wchar_t c, int itype) * If "once" is set, just test the first character, i.e. (outptr != * inptr) tests whether the first character is valid in an identifier. * - * Currently this is only called with itype IIDENT, IUSER or ISEP. + * Currently called only with itype INAMESPC, IIDENT, IUSER or ISEP. */ /**/ mod_export char * itype_end(const char *ptr, int itype, int once) { + if (itype == INAMESPC) { + itype = IIDENT; + if (once == 0 && !isset(POSIXIDENTIFIERS)) { + /* Special case for names containing ".", ksh93 namespaces */ + char *t = itype_end(ptr + (*ptr == '.'), itype, 0); + if (t > ptr+1) { + if (*t == '.') + return itype_end(t+1, itype, 0); + else + return t; + } + } + } + #ifdef MULTIBYTE_SUPPORT if (isset(MULTIBYTE) && (itype != IIDENT || !isset(POSIXIDENTIFIERS))) { diff --git a/Src/zsh.h b/Src/zsh.h index 96b4b06bd..0de1f7afb 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1963,6 +1963,8 @@ struct tieddata { */ #define SCANPM_CHECKING (1<<10) /* Check if set, no need to create */ #define SCANPM_NOEXEC (1<<11) /* No command substitutions, etc. */ +#define SCANPM_NONAMESPC (1<<12) /* namespace syntax not allowed */ + /* "$foo[@]"-style substitution * Only sign bit is significant */ diff --git a/Src/ztype.h b/Src/ztype.h index 8757fc733..4675f73a9 100644 --- a/Src/ztype.h +++ b/Src/ztype.h @@ -43,6 +43,7 @@ #define IWSEP (1 << 13) #define INULL (1 << 14) #define IPATTERN (1 << 15) +#define INAMESPC (1 << 16) #define zistype(X,Y) (typtab[(unsigned char) (X)] & Y) #define idigit(X) zistype(X,IDIGIT) #define ialnum(X) zistype(X,IALNUM) -- cgit v1.2.3 From 4bc1f6e0d2b60976b9c0412d72097ee1c812139b Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 5 Mar 2023 14:06:25 -0800 Subject: 51484: Extend named reference handling for special parameters, improve doc. --- ChangeLog | 3 ++ Doc/Zsh/builtins.yo | 2 + Src/params.c | 108 +++++++++++++++++++++++++++++++--------------------- 3 files changed, 69 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38a0395d6..30e9850e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-03-05 Bart Schaefer + * 51484: Src/builtins.yo Src/params.c: Extend named reference + handling for special parameters, improve doc. + * 51483: Src/Zle/compcore.c, Src/Zle/zle_tricky.c, Src/lex.c, Src/params.c, Src/subst.c, Src/utils.c, Src/zsh.h, Src/ztype.h: Enable assignment and expansion of parameters with ksh-like diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 92917c06c..5393cb149 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1924,6 +1924,8 @@ redef(SPACES)(0)(tt(ifztexi(NOTRANS(@ @ @ @ @ @ @ @ ))ifnztexi( ))) xitem(tt(typeset )[ {tt(PLUS())|tt(-)}tt(AHUaghlmrtux) ] \ [ {tt(PLUS())|tt(-)}tt(EFLRZip) [ var(n) ] ]) xitem(SPACES()[ tt(+) ] [ var(name)[tt(=)var(value)] ... ]) +xitem(tt(typeset )[ {tt(PLUS())|tt(-)}tt(n) ] \ +[ tt(-gr) ] [ var(name)[tt(=)var(value)] ... ]) xitem(tt(typeset )tt(-T) [ {tt(PLUS())|tt(-)}tt(Uglrux) ] [ {tt(PLUS())|tt(-)}tt(LRZp) [ var(n) ] ]) xitem(SPACES()[ tt(+) | var(SCALAR)[tt(=)var(value)] var(array)[tt(=LPAR())var(value) ...tt(RPAR())] [ var(sep) ] ]) item(tt(typeset) tt(-f) [ {tt(PLUS())|tt(-)}tt(TUkmtuz) ] [ tt(+) ] [ var(name) ... ])( diff --git a/Src/params.c b/Src/params.c index d3b6a7d43..c9f4b3017 100644 --- a/Src/params.c +++ b/Src/params.c @@ -475,6 +475,15 @@ static initparam argvparam_pm = IPDEF9("", &pparams, NULL, \ ((V) && (!(V)->pm || ((V)->pm->node.flags & PM_UNSET) || \ !(V)->pm->node.nam || !*(V)->pm->node.nam)) +/* + * For named references. Simple named references are just like scalars + * for efficiency, but special named references need get/set functions. + */ +#define GETREFNAME(PM) (((PM)->node.flags & PM_SPECIAL) ? \ + (PM)->gsu.s->getfn(PM) : (PM)->u.str) +#define SETREFNAME(PM,S) (((PM)->node.flags & PM_SPECIAL) ? \ + (PM)->gsu.s->setfn(PM,(S)) : ((PM)->u.str = (S))) + static Param argvparam; /* "parameter table" - hash table containing the parameters @@ -520,7 +529,7 @@ getparamnode(HashTable ht, const char *nam) HashNode hn = gethashnode2(ht, nam); Param pm = (Param) hn; - if (pm && pm->u.str && (pm->node.flags & PM_AUTOLOAD)) { + if (pm && (pm->node.flags & PM_AUTOLOAD) && pm->u.str) { char *mn = dupstring(pm->u.str); (void)ensurefeature(mn, "p:", (pm->node.flags & PM_AUTOALL) ? NULL : @@ -1002,12 +1011,13 @@ createparam(char *name, int flags) struct asgment stop; stop.flags = PM_NAMEREF | (flags & PM_LOCAL); stop.name = oldpm->node.nam; - stop.value.scalar = oldpm->u.str; + stop.value.scalar = GETREFNAME(oldpm); lastpm = (Param)resolve_nameref(oldpm, &stop); if (lastpm) { if (lastpm->node.flags & PM_NAMEREF) { - if (lastpm->u.str && *(lastpm->u.str)) { - name = lastpm->u.str; + char *refname = GETREFNAME(lastpm); + if (refname && *refname) { + name = refname; oldpm = NULL; } else { if (!(lastpm->node.flags & PM_READONLY)) @@ -2145,25 +2155,28 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) memset(v, 0, sizeof(*v)); else v = (Value) hcalloc(sizeof *v); - if ((pm->node.flags & PM_NAMEREF) && pm->u.str && *(pm->u.str)) { - /* only happens for namerefs pointing to array elements */ - char *ref = dupstring(pm->u.str); - char *ss = pm->width ? ref + pm->width : NULL; - if (ss) { - sav = *ss; - *ss = 0; + if (pm->node.flags & PM_NAMEREF) { + char *refname = GETREFNAME(pm); + if (refname && *refname) { + /* only happens for namerefs pointing to array elements */ + char *ref = dupstring(refname); + char *ss = pm->width ? ref + pm->width : NULL; + if (ss) { + sav = *ss; + *ss = 0; + } + Param p1 = (Param)gethashnode2(paramtab, ref); + if (!(p1 && (pm = upscope(p1, pm->base))) || + ((pm->node.flags & PM_UNSET) && + !(pm->node.flags & PM_DECLARED))) + return NULL; + if (ss) { + flags |= SCANPM_NOEXEC; + *ss = sav; + s = dyncat(ss,*pptr); + } else + s = *pptr; } - Param p1 = (Param)gethashnode2(paramtab, ref); - if (!(p1 && (pm = upscope(p1, pm->base))) || - ((pm->node.flags & PM_UNSET) && - !(pm->node.flags & PM_DECLARED))) - return NULL; - if (ss) { - flags |= SCANPM_NOEXEC; - *ss = sav; - s = dyncat(ss,*pptr); - } else - s = *pptr; } if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) { /* Overload v->isarr as the flag bits for hashed arrays. */ @@ -3648,7 +3661,7 @@ mod_export Param setiparam_no_convert(char *s, zlong val) { /* - * If the target is already an integer, thisgets converted + * If the target is already an integer, this gets converted * back. Low technology rules. */ char buf[BDIGBUFSIZE]; @@ -6115,22 +6128,23 @@ resolve_nameref(Param pm, const Asgment stop) const char *seek = stop ? stop->value.scalar : NULL; if (pm && (pm->node.flags & PM_NAMEREF)) { - if (pm && (pm->node.flags & (PM_UNSET|PM_TAGGED))) { + char *refname = GETREFNAME(pm); + if (pm->node.flags & (PM_UNSET|PM_TAGGED)) { /* Semaphore with createparam() */ pm->node.flags &= ~PM_UNSET; if (pm->node.flags & PM_NEWREF) /* See setloopvar() */ return NULL; - if (pm->u.str && *(pm->u.str) && (pm->node.flags & PM_TAGGED)) + if (refname && *refname && (pm->node.flags & PM_TAGGED)) pm->node.flags |= PM_SELFREF; /* See setscope() */ return (HashNode) pm; - } else if (pm->u.str) { + } else if (refname) { if ((pm->node.flags & PM_TAGGED) || - (stop && strcmp(pm->u.str, stop->name) == 0)) { - /* zwarnnam(pm->u.str, "invalid self reference"); */ + (stop && strcmp(refname, stop->name) == 0)) { + /* zwarnnam(refname, "invalid self reference"); */ return stop ? (HashNode)pm : NULL; } - if (*(pm->u.str)) - seek = pm->u.str; + if (*refname) + seek = refname; } } else if (pm && !(stop && (stop->flags & PM_NAMEREF))) @@ -6180,8 +6194,13 @@ setloopvar(char *name, char *value) Param pm = (Param) gethashnode2(realparamtab, name); if (pm && (pm->node.flags & PM_NAMEREF)) { + if (pm->node.flags & PM_READONLY) { + /* Bash error is: "%s: readonly variable" */ + zerr("read-only reference: %s", pm->node.nam); + return; + } pm->base = pm->width = 0; - pm->u.str = ztrdup(value); + SETREFNAME(pm, ztrdup(value)); pm->node.flags &= ~PM_UNSET; pm->node.flags |= PM_NEWREF; setscope(pm); @@ -6197,7 +6216,8 @@ setscope(Param pm) if (pm->node.flags & PM_NAMEREF) { Param basepm; struct asgment stop; - char *t = pm->u.str ? itype_end(pm->u.str, INAMESPC, 0) : NULL; + char *refname = GETREFNAME(pm); + char *t = refname ? itype_end(refname, INAMESPC, 0) : NULL; /* Temporarily change nameref to array parameter itself */ if (t && *t == '[') @@ -6211,7 +6231,7 @@ setscope(Param pm) stop.flags |= PM_LOCAL; basepm = (Param)resolve_nameref(pm, &stop); if (t) { - pm->width = t - pm->u.str; + pm->width = t - refname; *t = '['; } if (basepm) { @@ -6220,23 +6240,23 @@ setscope(Param pm) if (pm->node.flags & PM_SELFREF) { /* Loop signalled by resolve_nameref() */ if (upscope(pm, pm->base) == pm) { - zerr("%s: invalid self reference", pm->u.str); + zerr("%s: invalid self reference", refname); unsetparam_pm(pm, 0, 1); return; } pm->node.flags &= ~PM_SELFREF; } else if (pm->base == pm->level) { - if (pm->u.str && *(pm->u.str) && - strcmp(pm->node.nam, pm->u.str) == 0) { - zerr("%s: invalid self reference", pm->u.str); + if (refname && *refname && + strcmp(pm->node.nam, refname) == 0) { + zerr("%s: invalid self reference", refname); unsetparam_pm(pm, 0, 1); return; } } - } else if (basepm->u.str) { + } else if ((t = GETREFNAME(basepm))) { if (basepm->base <= basepm->level && - strcmp(pm->node.nam, basepm->u.str) == 0) { - zerr("%s: invalid self reference", pm->u.str); + strcmp(pm->node.nam, t) == 0) { + zerr("%s: invalid self reference", refname); unsetparam_pm(pm, 0, 1); return; } @@ -6251,11 +6271,11 @@ setscope(Param pm) unsetparam_pm(pm, 0, 1); } else if (isset(WARNNESTEDVAR)) zwarn("reference %s in enclosing scope set to local variable %s", - pm->node.nam, pm->u.str); + pm->node.nam, refname); } - if (pm->u.str && upscope(pm, pm->base) == pm && - strcmp(pm->node.nam, pm->u.str) == 0) { - zerr("%s: invalid self reference", pm->u.str); + if (refname && upscope(pm, pm->base) == pm && + strcmp(pm->node.nam, refname) == 0) { + zerr("%s: invalid self reference", refname); unsetparam_pm(pm, 0, 1); } } -- cgit v1.2.3 From ea0bd72dd84a783355969e0a9a1584ce7b1ea08b Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 5 Mar 2023 14:16:31 -0800 Subject: 51485: module for several ksh93 features, mostly enabled only in ksh emulation. --- ChangeLog | 4 + Doc/Makefile.in | 2 +- Doc/Zsh/mod_ksh93.yo | 211 ++++++++++++++++++++++++++++++++++++++++ Src/Modules/ksh93.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++ Src/Modules/ksh93.mdd | 8 ++ Src/utils.c | 2 +- 6 files changed, 490 insertions(+), 2 deletions(-) create mode 100644 Doc/Zsh/mod_ksh93.yo create mode 100644 Src/Modules/ksh93.c create mode 100644 Src/Modules/ksh93.mdd diff --git a/ChangeLog b/ChangeLog index 30e9850e5..a6a1b2d8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-03-05 Bart Schaefer + * 51485: Doc/Makefile.in, Doc/Zsh/mod_ksh93.yo, Src/utils.c, + Src/Modules/ksh93.c, Src/Modules/ksh93.mdd: module for several + ksh93 features, mostly enabled only in ksh emulation. + * 51484: Src/builtins.yo Src/params.c: Extend named reference handling for special parameters, improve doc. diff --git a/Doc/Makefile.in b/Doc/Makefile.in index 23e5fc7e2..136b080d6 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -63,7 +63,7 @@ Zsh/mod_compctl.yo Zsh/mod_complete.yo Zsh/mod_complist.yo \ Zsh/mod_computil.yo Zsh/mod_curses.yo \ Zsh/mod_datetime.yo Zsh/mod_db_gdbm.yo Zsh/mod_deltochar.yo \ Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_langinfo.yo \ -Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo \ +Zsh/mod_ksh93.yo Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo \ Zsh/mod_nearcolor.yo Zsh/mod_newuser.yo \ Zsh/mod_parameter.yo Zsh/mod_pcre.yo Zsh/mod_private.yo \ Zsh/mod_regex.yo Zsh/mod_sched.yo Zsh/mod_socket.yo \ diff --git a/Doc/Zsh/mod_ksh93.yo b/Doc/Zsh/mod_ksh93.yo new file mode 100644 index 000000000..3ae644bd1 --- /dev/null +++ b/Doc/Zsh/mod_ksh93.yo @@ -0,0 +1,211 @@ +COMMENT(!MOD!zsh/ksh93 +Extended ksh93 compatibility for "emulate ksh" +!MOD!) +cindex(ksh93) +The tt(zsh/ksh93) module provides one builtin and several parameters to +improve compatibility with ksh93. As of this writing, several ksh93 +features are still missing. + +subsect(Ksh Builtins) +The single builtin provided by this module is: + +startitem() +findex(nameref) +cindex(named references, creating) +item(tt(nameref) [ tt(-r) ] var(pname)[tt(=)var(rname)])( +Equivalent to tt(typeset -n )var(pname)tt(=)var(rname) + +However, tt(nameref) is a builtin command rather than a reserved word, +so when var(rname) uses subscript syntax it must be quoted against +globbing. Subscripts in referenced parameters are not supported in +ksh93, so this is not a significant compatibility issue. +) +enditem() + +subsect(Ksh Parameters) +cindex(parameters, ksh) +Parameters supplied by this module that are marked with `' below are +available only in ksh emulation. + +startitem() +vindex(.sh.command) +item(tt(.sh.command))( +A named reference to `tt(ZSH_DEBUG_CMD)' +) +vindex(.sh.edchar) +item(tt(.sh.edchar) )( +In a ZLE widget, equivalent to the `tt(KEYS)' special parameter. In a +future release, assignments to this parameter will affect the input +stream seen by ZLE. +) +vindex(.sh.edcol) +item(tt(.sh.edcol))( +A named reference to the ZLE special parameter `tt(CURSOR)'. +) +vindex(.sh.edmode) +item(tt(.sh.edmode) )( +In a ZLE widget, this parameter has the value tt(ESC) (tt($'\e')) if the +`tt(main)' keymap is selected, and the empty string otherwise. This is +intended for use with vi-mode key bindings (`tt(bindkey -v)'). In a +future revision, assigning `tt(.sh.edchar=${.sh.edmode})' is expected +to initiate `tt(vicmd)' mode when `tt(viins)' is active, and do +nothing when `tt(vicmd)' is already active. +) +vindex(.sh.edtext) +item(tt(.sh.edtext))( +A named reference to the `tt(BUFFER)' special ZLE parameter. +) +vindex(.sh.file) +item(tt(.sh.file))( +A named reference to the `tt(ZSH_SCRIPT)' parameter. +) +vindex(.sh.fun) +item(tt(.sh.fun) )( +In a shell function, the function's name. Usually the same as `tt($0)', +but not affected by tt(POSIX_ARGZERO) or tt(FUNCTION_ARGZERO) options. +) +vindex(.sh.level) +item(tt(.sh.level) )( +In a shell function, initially set to the depth of the call stack. This +may be assigned to change the apparent depth. However, such assignment +does not affect the scope of local parameters. +) +vindex(.sh.lineno) +item(tt(.sh.lineno))( +A named reference to the `tt(LINENO)' special parameter. +) +vindex(.sh.match) +item(tt(.sh.match))( +An array equivalent to the `tt(match)' parameter as assigned by the +`tt(LPAR()#b)tt(RPAR())' extended globbing flag. When the +tt(KSH_ARRAYS) option is set, `tt(${.sh.match[0]})' gives the value of +the `tt(MATCH)' parameter as set by the `tt(LPAR()#m)tt(RPAR())' extended +globbing flag. Currently, the tt(EXTENDED_GLOB) option must be enabled +and those flags must be explicitly used in a pattern in order for these +values of `tt(.sh.match)' to be set. +) +vindex(.sh.name) +item(tt(.sh.name) )( +When the `tt(vared)' command is used, this parameter may be used in +user-defined ZLE widgets to get the name of the variable being edited. +A future release is expected to use this parameter in the implementation +of "discipline functions". +) +vindex(.sh.subscript) +item(tt(.sh.subscript) )( +When `tt(vared)' has been used on an array element, this parameter holds +the array index (either a number, or an associative array key). +) +vindex(.sh.subshell) +item(tt(.sh.subshell))( +A named reference to the `tt(ZSH_SUBSHELL)' parameter. +) +vindex(.sh.value) +item(tt(.sh.value) )( +In `tt(vared)' this is a named reference to the ZLE special `tt(BUFFER)'. +A future release is expected to use this parameter in the implementation +of "discipline functions". +) +vindex(.sh.version) +item(tt(.sh.version))( +A named reference to `tt(ZSH_PATCHLEVEL)'. +) +enditem() + +subsect(Future Compatibility) + +The following features of ksh93 are not currently supported but may be +available in a future release. + +startitem() +item(var(pathdir)tt(/.paths))( +Each directory var(pathdir) in the tt(PATH) parameter may contain a +text file `tt(.paths)' which may define additional directories to +be searched for function definitions (tt(FPATH)), external executables +(tt(PATH)), and plugin files (similar to tt(MODULE_PATH)). + +em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.) +) +item(tt(builtin -f )var(file))( +Installs a new shell builtin command dynamically linked from var(file), +where var(file) is found by a path search and the base name of the file +is the name of the builtin to be added. + +Similar to `tt(zmodload -F zsh/)var(file)tt( +b:)var(file)'. + +em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.) +) +item(tt(namespace )var(ident)tt( { )var(list)tt( }))( +This reserved word executes the current shell compound command +tt({ )var(list)tt( }), with the special behavior that all functions +and parameters `var(name)' declared within var(list) are implicitly +prefixed to become `tt(.)var(ident)tt(.)var(name)', and similarly any +reference to a function or parameter `var(name)' is searched for as +`tt(.)var(ident)tt(.)var(name)' before falling back to `var(name)'. + +em(THIS FEATURE IS NOT YET IMPLEMENTED.) +) +item(tt(.sh.math) )( +This parameter is more accurately considered a namespace. A function +defintion of the form +ifzman() +indent(tt(function .sh.math.)var(name)tt( )var(ident)tt( ... { )var(list)tt( })) + +is equivalent to the native zsh definition +ifzman() +example(tt(function )var(name)tt( {) +tt( local )var(ident)tt(=$1 ...) +tt( )var(list) +tt(}) +tt(functions -M )var(name)tt( 1 3)) +ifzman() +Up to 3 var(ident) arguments, interpreted as floating point numbers, +may be provided for a function defined with tt(.sh.math) in this way. +The names (but not definitions) of all such functions are available +via tt(${.sh.math[@]}). + +em(THIS FEATURE IS NOT YET IMPLEMENTED.) +) +item(tt(var(name)tt(.get)))( +A shell function having this name, if defined, is invoked whenever the +parameter tt(${)var(name)tt(}) is referenced, including by commands +such as `tt(typeset -p)'. If the special variable `tt(.sh.value)' is +assigned by the function, that value is substituted instead of the +true value of var(name). This does not change the value of var(name), +but there is no way to access the actual value without first removing +the function. + +Additionally, an explicit reference to tt(${)var(name)tt(.get}) +calls the function var(name)tt(.get) even if there is no parameter +`var(name)' and substitutes the standard output of the function. + +em(THIS FEATURE IS NOT YET IMPLEMENTED.) +) +xitem(tt(var(name)tt(.set))) +item(tt(var(name)tt(.append)))( +Shell functions having these names are invoked when the parameter +var(name) is assigned or (for array types) has a new field appended. +The function may change the result of the operation by assigning to +the `tt(.sh.value)' special parameter, or block the change by +unsetting `tt(.sh.value)'. + +Explicit reference to tt(${)var(name)tt(.set}) or tt(${)var(name)tt(.append}) +substitutes the standard output of the function. + +em(THIS FEATURE IS NOT YET IMPLEMENTED.) +) +item(tt(var(name)tt(.unset)))( +When a function of this name is defined, it is called whenever the +parameter var(name) would be unset. The function must explicitly +`tt(unset )var(name)', otherwise the variable remains set. + +em(THIS FEATURE IS NOT YET IMPLEMENTED.) +) +item(tt(${ )var(list)tt(;}))( +Note the space after the opening brace (tt({)). This executes var(list) +in the current shell and substitutes its standard output in the manner +of `tt($LPAR())var(list)tt(RPAR())' but without forking. + +em(THIS FEATURE IS NOT YET IMPLEMENTED.) +) +enditem() diff --git a/Src/Modules/ksh93.c b/Src/Modules/ksh93.c new file mode 100644 index 000000000..9dc75c93c --- /dev/null +++ b/Src/Modules/ksh93.c @@ -0,0 +1,265 @@ +/* + * ksh93.c - support for more ksh93 features + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 2022 Barton E. Schaefer + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Barton E. Schaefer or the Zsh Development + * Group be liable to any party for direct, indirect, special, incidental, or + * consequential damages arising out of the use of this software and its + * documentation, even if Barton E. Schaefer and the Zsh + * Development Group have been advised of the possibility of such damage. + * + * Barton E. Schaefer and the Zsh Development Group + * specifically disclaim any warranties, including, but not limited to, the + * implied warranties of merchantability and fitness for a particular purpose. + * The software provided hereunder is on an "as is" basis, and + * Barton E. Schaefer and the Zsh Development Group have no + * obligation to provide maintenance, support, updates, enhancements, or + * modifications. + * + */ + +#include "ksh93.mdh" +#include "ksh93.pro" + +/* Implementing "namespace" requires creating a new keword. Hrm. */ + +/* + * Standard module configuration/linkage + */ + +static struct builtin bintab[] = { + BUILTIN("nameref", BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "gr", "n") +}; + +#include "zsh.mdh" + +static void +edcharsetfn(Param pm, char *x) +{ + /* + * To make this work like ksh, we must intercept $KEYS before the widget + * is looked up, so that changing the key sequence causes a different + * widget to be substituted. Somewhat similar to "bindkey -s". + * + * Ksh93 adds SIGKEYBD to the trap list for this purpose. + */ + ; +} + +static char ** +matchgetfn(Param pm) +{ + char **zsh_match = getaparam("match"); + + /* For this to work accurately, ksh emulation should always imply + * that the (#m) and (#b) extendedglob operators are enabled. + * + * When we have a 0th element (ksharrays), it is $MATCH. Elements + * 1st and larger mirror the $match array. + */ + + if (pm->u.arr) + freearray(pm->u.arr); + if (zsh_match && *zsh_match) { + if (isset(KSHARRAYS)) { + char **ap = + (char **) zalloc(sizeof(char *) * (arrlen(zsh_match)+1)); + pm->u.arr = ap; + *ap++ = ztrdup(getsparam("MATCH")); + while (*zsh_match) + *ap = ztrdup(*zsh_match++); + } else + pm->u.arr = zarrdup(zsh_match); + } else if (isset(KSHARRAYS)) { + pm->u.arr = mkarray(ztrdup(getsparam("MATCH"))); + } else + pm->u.arr = NULL; + + return arrgetfn(pm); +} + +static const struct gsu_scalar constant_gsu = + { strgetfn, NULL, nullunsetfn }; + +static const struct gsu_scalar sh_edchar_gsu = + { strvargetfn, edcharsetfn, nullunsetfn }; +static const struct gsu_scalar sh_edmode_gsu = + { strgetfn, nullstrsetfn, nullunsetfn }; +static const struct gsu_array sh_match_gsu = + { matchgetfn, arrsetfn, stdunsetfn }; +static const struct gsu_scalar sh_name_gsu = + { strvargetfn, nullstrsetfn, nullunsetfn }; +static const struct gsu_scalar sh_subscript_gsu = + { strvargetfn, nullstrsetfn, nullunsetfn }; + +static char *sh_name; +static char *sh_subscript; +static char *sh_edchar; +static char sh_edmode[2]; + +/* + * Some parameters listed here do not appear in ksh93.mdd autofeatures + * because they are only instantiated by ksh93_wrapper() below. This + * obviously includes those commented out here. + */ +static struct paramdef partab[] = { + PARAMDEF(".sh.command", PM_NAMEREF|PM_READONLY, "ZSH_DEBUG_CMD", &constant_gsu), + PARAMDEF(".sh.edchar", PM_SCALAR|PM_SPECIAL, &sh_edchar, &sh_edchar_gsu), + PARAMDEF(".sh.edcol", PM_NAMEREF|PM_READONLY, "CURSOR", &constant_gsu), + PARAMDEF(".sh.edmode", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_edmode, &sh_edmode_gsu), + PARAMDEF(".sh.edtext", PM_NAMEREF|PM_READONLY, "BUFFER", &constant_gsu), + PARAMDEF(".sh.file", PM_NAMEREF|PM_READONLY, "ZSH_SCRIPT", &constant_gsu), + /* PARAMDEF(".sh.fun", PM_SCALAR|PM_UNSET, NULL, &constant_gsu), */ + /* PARAMDEF(".sh.level", PM_INTEGER|PM_UNSET, NULL, &constant_gsu), */ + PARAMDEF(".sh.lineno", PM_NAMEREF|PM_READONLY, "LINENO", &constant_gsu), + PARAMDEF(".sh.match", PM_ARRAY|PM_READONLY, NULL, &sh_match_gsu), + PARAMDEF(".sh.name", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_name, &sh_name_gsu), + PARAMDEF(".sh.subscript", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_subscript, &sh_subscript_gsu), + PARAMDEF(".sh.subshell", PM_NAMEREF|PM_READONLY, "ZSH_SUBSHELL", &constant_gsu), + /* SPECIALPMDEF(".sh.value", 0, NULL, NULL, NULL), */ + PARAMDEF(".sh.version", PM_NAMEREF|PM_READONLY, "ZSH_PATCHLEVEL", &constant_gsu) +}; + +static struct features module_features = { + bintab, sizeof(bintab)/sizeof(*bintab), + NULL, 0, + NULL, 0, + partab, sizeof(partab)/sizeof(*partab), + 0 +}; + +/**/ +static int +ksh93_wrapper(Eprog prog, FuncWrap w, char *name) +{ + Funcstack f; + Param pm; + zlong num = funcstack->prev ? getiparam(".sh.level") : 0; + + if (!EMULATION(EMULATE_KSH)) + return 1; + + if (num == 0) + for (f = funcstack; f; f = f->prev, num++); + else + num++; + + queue_signals(); + ++locallevel; /* Make these local */ + if ((pm = createparam(".sh.level", PM_LOCAL|PM_UNSET))) { + pm->level = locallevel; /* Why is this necessary? */ + setiparam(".sh.level", num); + } + if ((pm = createparam(".sh.fun", PM_LOCAL|PM_UNSET))) { + pm->level = locallevel; + setsparam(".sh.fun", ztrdup(name)); + pm->node.flags |= PM_READONLY; + } + if (zleactive) { + extern mod_import_variable char *curkeymapname; /* XXX */ + extern mod_import_variable char *varedarg; /* XXX */ + /* How to distinguish emacs bindings? */ + if (curkeymapname && strcmp(curkeymapname, "main") == 0) + strcpy(sh_edmode, "\e"); + else + strcpy(sh_edmode, ""); + if (!sh_edchar) + sh_edchar = dupstring(getsparam("KEYS")); + if (varedarg) { + char *ie = itype_end((sh_name = dupstring(varedarg)), INAMESPC, 0); + if (ie && *ie) { + *ie++ = '\0'; + /* Assume bin_vared has validated subscript */ + sh_subscript = dupstring(ie); + ie = sh_subscript + strlen(sh_subscript); + *--ie = '\0'; + } else + sh_subscript = NULL; + if ((pm = createparam(".sh.value", PM_LOCAL|PM_NAMEREF|PM_UNSET))) { + pm->level = locallevel; + setloopvar(".sh.value", "BUFFER"); /* Hack */ + } + } else + sh_name = sh_subscript = NULL; + } else { + sh_edchar = sh_name = sh_subscript = NULL; + strcpy(sh_edmode, ""); + /* TODO: + * - disciplines + * - special handling of .sh.value in math + */ + } + --locallevel; + unqueue_signals(); + + return 1; +} + +static struct funcwrap wrapper[] = { + WRAPDEF(ksh93_wrapper), +}; + +/**/ +int +setup_(UNUSED(Module m)) +{ + return 0; +} + +/**/ +int +features_(Module m, char ***features) +{ + *features = featuresarray(m, &module_features); + return 0; +} + +/**/ +int +enables_(Module m, int **enables) +{ + return handlefeatures(m, &module_features, enables); +} + +/**/ +int +boot_(Module m) +{ + return addwrapper(m, wrapper); +} + +/**/ +int +cleanup_(Module m) +{ + struct paramdef *p; + + deletewrapper(m, wrapper); + + /* Clean up namerefs, otherwise deleteparamdef() is confused */ + for (p = partab; p < partab + sizeof(partab)/sizeof(*partab); ++p) { + if (p->flags & PM_NAMEREF) { + HashNode hn = gethashnode2(paramtab, p->name); + if (hn) + ((Param)hn)->node.flags &= ~PM_NAMEREF; + } + } + return setfeatureenables(m, &module_features, NULL); +} + +/**/ +int +finish_(UNUSED(Module m)) +{ + return 0; +} diff --git a/Src/Modules/ksh93.mdd b/Src/Modules/ksh93.mdd new file mode 100644 index 000000000..2759884a0 --- /dev/null +++ b/Src/Modules/ksh93.mdd @@ -0,0 +1,8 @@ +name=zsh/ksh93 +link=either +load=yes + +autofeatures="b:nameref" +autofeatures_emu="b:nameref p:.sh.command p:.sh.edcol p:.sh.edtext p:.sh.file p:.sh.lineno p:.sh.match p:.sh.subshell p:.sh.version" + +objects="ksh93.o" diff --git a/Src/utils.c b/Src/utils.c index 1393ecb13..8ce9a175d 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -4319,7 +4319,7 @@ itype_end(const char *ptr, int itype, int once) { if (itype == INAMESPC) { itype = IIDENT; - if (once == 0 && !isset(POSIXIDENTIFIERS)) { + if (once == 0 && (!isset(POSIXIDENTIFIERS) || EMULATION(EMULATE_KSH))) { /* Special case for names containing ".", ksh93 namespaces */ char *t = itype_end(ptr + (*ptr == '.'), itype, 0); if (t > ptr+1) { -- cgit v1.2.3 From 9bd9693fdb2f752b19bfdf9c958c05db7d2393ba Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 5 Mar 2023 14:21:18 -0800 Subject: 51486: clarify module development section --- ChangeLog | 2 ++ Etc/zsh-development-guide | 17 ++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index a6a1b2d8c..301f048cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-03-05 Bart Schaefer + * 51486: Etc/zsh-development-guide: clarify module section + * 51485: Doc/Makefile.in, Doc/Zsh/mod_ksh93.yo, Src/utils.c, Src/Modules/ksh93.c, Src/Modules/ksh93.mdd: module for several ksh93 features, mostly enabled only in ksh emulation. diff --git a/Etc/zsh-development-guide b/Etc/zsh-development-guide index da6932003..5cb542709 100644 --- a/Etc/zsh-development-guide +++ b/Etc/zsh-development-guide @@ -371,8 +371,8 @@ particular they can be called before or after `boot_'. The function named `boot_' should register function wrappers, hooks and anything that will be visible to the user that is not handled by features_ and enables_ (so features should not be turned on here). It will be called -after the `setup_'-function, and also after the initial set of features -have been set by calls to `features_' and `enables_'. +after the initial set of features have been set by calls to `features_' +and `enables_'. The function named `cleanup_', is called when the user tries to unload a module and should de-register all features and hooks. A call @@ -624,17 +624,20 @@ There are four macros used: - the name of the parameter - the parameter flags to set for it (from the PM_* flags defined in zsh.h) - - optionally a pointer to a variable holding the value of the - parameter + - optionally a pointer to the value of the parameter - a GSU pointer to the three functions that will be used to get the value of the parameter, store a value in the parameter, and unset the parameter - the other macros provide simple ways to define the most common types of parameters; they get the name of the parameter and a pointer to a variable holding the value as arguments; they are - used to define integer-, scalar-, and array-parameters, so the - variables whose addresses are given should be of type `long', - `char *', and `char **', respectively + used to define integer-, scalar-, and array-parameters, so for + those macros the pointer to the parameter value should be the + address of a variable of type `long', `char *',or `char **', + respectively, pointing in turn to the desired value. + - Parameters used in a module that don't have special behaviour + shouldn't be declared in this way, instead they should just be + created in `boot_' with the standard parameter functions. GSU (get, set, unset) structures are defined in Src/zsh.h for each of the parameter types scalar, integer, float, array, and hash. -- cgit v1.2.3 From ac1bf482ba43d4bf68708625e56a42860541d851 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 6 Mar 2023 14:54:28 -0800 Subject: 51524: dependency on zsh/zle for linkage --- ChangeLog | 4 ++++ Src/Modules/ksh93.mdd | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 301f048cf..618475dd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-03-06 Bart Schaefer + + * 51524: Src/Modules/ksh93.mdd: dependency on zsh/zle for linkage + 2023-03-05 Bart Schaefer * 51486: Etc/zsh-development-guide: clarify module section diff --git a/Src/Modules/ksh93.mdd b/Src/Modules/ksh93.mdd index 2759884a0..85e35e9cb 100644 --- a/Src/Modules/ksh93.mdd +++ b/Src/Modules/ksh93.mdd @@ -5,4 +5,6 @@ load=yes autofeatures="b:nameref" autofeatures_emu="b:nameref p:.sh.command p:.sh.edcol p:.sh.edtext p:.sh.file p:.sh.lineno p:.sh.match p:.sh.subshell p:.sh.version" +moddeps="zsh/zle" + objects="ksh93.o" -- cgit v1.2.3 From 0562be0af8127bb728774de47e4e8851461bd8e2 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 6 Mar 2023 19:54:48 -0800 Subject: 51509 (+ fix typo): Add ${(!)name} for the referred-to name of a named reference Extend ${!name} in ksh emulation for same --- ChangeLog | 4 ++++ Src/params.c | 7 +++++-- Src/subst.c | 38 +++++++++++++++++++++++++++++++------- Src/zsh.h | 1 + 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 618475dd4..809466c0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-03-06 Bart Schaefer + * 51509 (+ fix typo): Src/params.c, Src/subst.c, Src/zsh.h: Add + ${(!)name} for the referred-to parameter of a named reference, + and extend ${!name} in ksh emulation for same + * 51524: Src/Modules/ksh93.mdd: dependency on zsh/zle for linkage 2023-03-05 Bart Schaefer diff --git a/Src/params.c b/Src/params.c index c9f4b3017..85eaee609 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2144,7 +2144,10 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) int isvarat; isvarat = (t[0] == '@' && !t[1]); - pm = (Param) paramtab->getnode(paramtab, *t == '0' ? "0" : t); + if (flags & SCANPM_NONAMEREF) + pm = (Param) paramtab->getnode2(paramtab, *t == '0' ? "0" : t); + else + pm = (Param) paramtab->getnode(paramtab, *t == '0' ? "0" : t); if (sav) *s = sav; *pptr = s; @@ -2155,7 +2158,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) memset(v, 0, sizeof(*v)); else v = (Value) hcalloc(sizeof *v); - if (pm->node.flags & PM_NAMEREF) { + if ((pm->node.flags & PM_NAMEREF) && !(flags & SCANPM_NONAMEREF)) { char *refname = GETREFNAME(pm); if (refname && *refname) { /* only happens for namerefs pointing to array elements */ diff --git a/Src/subst.c b/Src/subst.c index 7a4b433bc..974d6171e 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1818,14 +1818,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * Use for the (k) flag. Goes down into the parameter code, * sometimes. */ - char hkeys = 0; + int hkeys = 0; /* * Used for the (v) flag, ditto. Not quite sure why they're * separate, but the tradition seems to be that things only * get combined when that makes the result more obscure rather * than less. */ - char hvals = 0; + int hvals = 0; /* * Whether we had to evaluate a subexpression, i.e. an * internal ${...} or $(...) or plain $pm. We almost don't @@ -1870,8 +1870,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * these later on, too. */ c = *s; - if (itype_end(s, INAMESPC, 1) == s && *s != '#' && c != Pound && - !IS_DASH(c) && + if (itype_end(s, (c == Inbrace ? INAMESPC : IIDENT), 1) == s && + *s != '#' && c != Pound && !IS_DASH(c) && c != '!' && c != '$' && c != String && c != Qstring && c != '?' && c != Quest && c != '*' && c != Star && c != '@' && c != '{' && @@ -1891,15 +1891,30 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, s++; /* * In ksh emulation a leading `!' is a special flag working - * sort of like our (k). + * sort of like our (k). This is true only for arrays or + * associative arrays and only with subscripts [*] or [@], + * so zsh's implementation is approximate. For namerefs + * in ksh, ${!ref} substitues the parameter name at the + * end of any chain of references, rather than the value. + * * TODO: this is one of very few cases tied directly to * the emulation mode rather than an option. Since ksh * doesn't have parameter flags it might be neater to * handle this with the ^, =, ~ stuff, below. */ if ((c = *s) == '!' && s[1] != Outbrace && EMULATION(EMULATE_KSH)) { - hkeys = SCANPM_WANTKEYS; + hkeys = SCANPM_WANTKEYS|SCANPM_NONAMEREF; s++; + /* There's a slew of other special bash meanings of parameter + * references that start with "!": + * ${!name} == ${(P)name} (when name is not a nameref) + * ${!name*} == ${(k)parameters[(I)name*]} + * ${!name@} == ${(@k)parameters[(I)name*]} + * ${!name[*]} == ${(k)name} (but indexes of ordinary arrays, too) + * ${!name[@]} == ${(@k)name} (ditto, as noted above for ksh) + * + * See also workers/34390, workers/34397, workers/34408. + */ } else if (c == '(' || c == Inpar) { char *t, sav; int tt = 0; @@ -2154,10 +2169,19 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, escapes = 1; break; + case '!': + if ((hkeys|hvals) & ~SCANPM_NONAMEREF) + goto flagerr; + hkeys = SCANPM_NONAMEREF; + break; case 'k': + if (hkeys & ~SCANPM_WANTKEYS) + goto flagerr; hkeys = SCANPM_WANTKEYS; break; case 'v': + if (hvals & ~SCANPM_WANTVALS) + goto flagerr; hvals = SCANPM_WANTVALS; break; @@ -2308,7 +2332,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, /* * Look for special unparenthesised flags. * TODO: could make these able to appear inside parentheses, too, - * i.e. ${(^)...} etc. + * i.e. ${(^)...} etc., but ${(~)...} already has another meaning. */ for (;;) { if ((c = *s) == '^' || c == Hat) { diff --git a/Src/zsh.h b/Src/zsh.h index 0de1f7afb..f3a777045 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1964,6 +1964,7 @@ struct tieddata { #define SCANPM_CHECKING (1<<10) /* Check if set, no need to create */ #define SCANPM_NOEXEC (1<<11) /* No command substitutions, etc. */ #define SCANPM_NONAMESPC (1<<12) /* namespace syntax not allowed */ +#define SCANPM_NONAMEREF (1<<13) /* named references are not followed */ /* "$foo[@]"-style substitution * Only sign bit is significant -- cgit v1.2.3 From 8d009d35a9eeacb1bbe9399316d2649a47102014 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 6 Mar 2023 20:01:04 -0800 Subject: 51510: Skip namespaces in "set"/"typeset" output, add tests, fix bug --- ChangeLog | 5 +++ Src/builtin.c | 14 +++++-- Src/params.c | 4 ++ Src/utils.c | 8 ++-- Src/zsh.h | 1 + Test/K02parameter.ztst | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 Test/K02parameter.ztst diff --git a/ChangeLog b/ChangeLog index 809466c0e..96adb9c57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2023-03-06 Bart Schaefer + * 51510: Src/builtin.c, Src/params.c, Src/utils.c, Src/zsh.h, + Test/K02parameter.ztst: parameters with a leading namespace are + skipped in output of "set" and "typeset", add tests for ksh-like + parameter handling and fix a bug thus revealed + * 51509 (+ fix typo): Src/params.c, Src/subst.c, Src/zsh.h: Add ${(!)name} for the referred-to parameter of a named reference, and extend ${!name} in ksh emulation for same diff --git a/Src/builtin.c b/Src/builtin.c index 11c1ab3a4..d99802f5f 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2240,7 +2240,8 @@ typeset_single(char *cname, char *pname, Param pm, int func, paramtab->printnode(&pm->node, PRINT_TYPESET); else if (!OPT_ISSET(ops,'g') && (unset(TYPESETSILENT) || OPT_ISSET(ops,'m'))) - paramtab->printnode(&pm->node, PRINT_INCLUDEVALUE); + paramtab->printnode(&pm->node, + PRINT_INCLUDEVALUE|PRINT_WITH_NAMESPACE); return pm; } if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) { @@ -2274,7 +2275,7 @@ typeset_single(char *cname, char *pname, Param pm, int func, } } if (OPT_ISSET(ops,'p')) { - paramtab->printnode(&pm->node, PRINT_TYPESET); + paramtab->printnode(&pm->node, PRINT_TYPESET|PRINT_WITH_NAMESPACE); return pm; } if (usepm == 2) /* do not change the PM_UNSET flag */ @@ -2662,7 +2663,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) char *optstr = TYPESET_OPTSTR; int on = 0, off = 0, roff, bit = PM_ARRAY; int i; - int returnval = 0, printflags = 0; + int returnval = 0, printflags = PRINT_WITH_NAMESPACE; int hasargs = *argv != NULL || (assigns && firstnode(assigns)); /* POSIXBUILTINS is set for bash/ksh and both ignore -p with args */ @@ -2730,7 +2731,6 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) queue_signals(); - /* Given no arguments, list whatever the options specify. */ if (OPT_ISSET(ops,'p')) { if (isset(POSIXBUILTINS) && SHELL_EMULATION() != EMULATE_KSH) { @@ -2756,8 +2756,14 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) /* -p0 treated as -p for consistency */ } } + + /* Given no arguments, list whatever the options specify. */ if (!hasargs) { int exclude = 0; + + if (!OPT_ISSET(ops,'m')) + printflags &= ~PRINT_WITH_NAMESPACE; + if (!OPT_ISSET(ops,'p')) { if (!(on|roff)) printflags |= PRINT_TYPE; diff --git a/Src/params.c b/Src/params.c index 85eaee609..021d341e8 100644 --- a/Src/params.c +++ b/Src/params.c @@ -5966,6 +5966,10 @@ printparamnode(HashNode hn, int printflags) Param p = (Param) hn; Param peer = NULL; + if (!(p->node.flags & PM_HASHELEM) && + !(printflags & PRINT_WITH_NAMESPACE) && *(p->node.nam) == '.') + return; + if (p->node.flags & PM_UNSET) { if ((printflags & (PRINT_POSIX_READONLY|PRINT_POSIX_EXPORT) && p->node.flags & (PM_READONLY|PM_EXPORTED)) || diff --git a/Src/utils.c b/Src/utils.c index 8ce9a175d..14ff0ed47 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -4319,13 +4319,13 @@ itype_end(const char *ptr, int itype, int once) { if (itype == INAMESPC) { itype = IIDENT; - if (once == 0 && (!isset(POSIXIDENTIFIERS) || EMULATION(EMULATE_KSH))) { + if (!isset(POSIXIDENTIFIERS) || EMULATION(EMULATE_KSH)) { /* Special case for names containing ".", ksh93 namespaces */ char *t = itype_end(ptr + (*ptr == '.'), itype, 0); - if (t > ptr+1) { + if (t > ptr + (*ptr == '.')) { if (*t == '.') - return itype_end(t+1, itype, 0); - else + ptr = t + 1; /* Fall through */ + else if (!once) return t; } } diff --git a/Src/zsh.h b/Src/zsh.h index f3a777045..a0243e98e 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2184,6 +2184,7 @@ typedef groupset *Groupset; #define PRINT_LINE (1<<6) #define PRINT_POSIX_EXPORT (1<<7) #define PRINT_POSIX_READONLY (1<<8) +#define PRINT_WITH_NAMESPACE (1<<9) /* flags for printing for the whence builtin */ #define PRINT_WHENCE_CSH (1<<7) diff --git a/Test/K02parameter.ztst b/Test/K02parameter.ztst new file mode 100644 index 000000000..8a1be1e36 --- /dev/null +++ b/Test/K02parameter.ztst @@ -0,0 +1,106 @@ +# Test parameter expansion with namespace syntax +# (heavily borrowed from D04parameter.ztst) + +%prep + +%test + + .k02.foo='the first parameter' + .k02.bar='the second parameter' + print -l $.k02.foo ${.k02.bar} +0:Basic scalars with namespace +F:Braces are required +>$.k02.foo +>the second parameter + + typeset .k02.bar='the second parameter' + print -l ${.k02.bar} +0:Scalar but with typeset +>the second parameter + + .k02.array1=(the first array) + .k02.array2=(the second array) + print -l $.k02.array1 ${.k02.array2} +0:Basic arrays with namespace +>$.k02.array1 +>the +>second +>array + + typeset -a .k02.array2=(the second array) + print -l ${.k02.array2} +0:Array but with typeset +>the +>second +>array + + setopt ksharrays + print -l ${.k02.array2} + unsetopt ksharrays +0:Basic ksharray with namespace +>the + + setopt shwordsplit + print -l ${.k02.foo} ${==.k02.bar} + unsetopt shwordsplit +0:Basic shwordsplit with namespace +>the +>first +>parameter +>the second parameter + + print ${+.k02.foo} ${+.k02.notappearinginthistest} +0:$+... and namespace +>1 0 + + .k02.x=() + print ${+.k02.x} ${+.k02.x[1]} ${+.k02.x[(r)foo]} ${+.k02.x[(r)bar]} + .k02.x=(foo) + print ${+.k02.x} ${+.k02.x[1]} ${+.k02.x[(r)foo]} ${+.k02.x[(r)bar]} +0:$+... with arrays and namespace +>1 0 0 0 +>1 1 1 0 + + # See D04 for complete explanation. + # For K02 we're just testing that flag syntax works. + .k02.foo=' {six} (seven) >eight< }nine{ |forty-two| $many$ )ten( more' + .k02.array=(${(z).k02.foo}) + print -l ${(Q).k02.array} +0:${(z)...} and ${(Q)...} for some hard to parse cases +>< +>five +>> +>{six} +>( +>seven +>) +>> +>eight +>< +>}nine{ +>| +>forty-two +>| +>$many$ +>) +>ten( more + + .k02.array=(characters in an array) + print ${(c)#.k02.array} +0:${(c)#...} +>22 + + () { + typeset -n .k02.ref=.k02.array + emulate -L ksh + print -l ${!.k02.ref} ${(!).k02.ref} ${.k02.ref} + } +0:namerefs with namespaces +>.k02.array +>.k02.array +>characters + + k.2=test + print ${k.2} +0:Parse without leading dot (future proofing) +>test -- cgit v1.2.3 From b17431e6dd4977a166b8d577fee03ccd68822957 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 6 Mar 2023 20:04:31 -0800 Subject: 51511: Documentation for namespaces --- ChangeLog | 2 ++ Doc/Zsh/expn.yo | 12 ++++++++++++ Doc/Zsh/params.yo | 17 ++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 96adb9c57..4fe025adf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-03-06 Bart Schaefer + * 51511: Doc/Zsh/expn.yo, Doc/Zsh/params.yo: Document namespaces + * 51510: Src/builtin.c, Src/params.c, Src/utils.c, Src/zsh.h, Test/K02parameter.ztst: parameters with a leading namespace are skipped in output of "set" and "typeset", add tests for ksh-like diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index ef01794e6..19f5909ea 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -604,6 +604,16 @@ and other operators, such as `tt(${PREFIX:-"/usr/local"})'. Parameter expansions can also be nested. These topics will be introduced below. The full rules are complicated and are noted at the end. +cindex(namespace) +Parameter expansions may optionally include a em(namespace) prefix in +the format `tt(.)var(identifier)tt(.)' This currently has no special +meaning to the shell, but provides a convenient means of grouping +related parameters. Expansions using a namespace em(must) include +braces (tt({) and tt(})) as shown in the descriptions below, and +only one namespace prefix is allowed. Note that, for support of +possible future features, the first `tt(.)' is optional, but omitting +it is discouraged. + In the expansions discussed below that require a pattern, the form of the pattern is the same as that used for filename generation; see noderef(Filename Generation). Note that these patterns, along with @@ -616,6 +626,8 @@ substitution on the expansion of parameter tt($i). In the following descriptions, `var(word)' refers to a single word substituted on the command line, not necessarily a space delimited word. +The reference to `var(name)' in each description presumes any optional +namespace prefix. startitem() item(tt(${)var(name)tt(}))( diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 946c00793..528c27f93 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -52,6 +52,20 @@ cindex(assignment) ifzman() indent(var(name)tt(=)var(value)) +cindex(namespace) +The var(name) in an assignment may optionally include a em(namespace) +prefix: +ifzman() +indent(tt(.)var(namespace)tt(.)var(parameter)tt(=)var(value)) + +Namespaces have no special meaning to the shell except that parameters +with a `tt(.)' prefix are not listed by the `tt(set)' builtin, nor +shown by the `tt(typeset)' builtin unless explicitly named or the +`tt(-m)' option is used. They provide a convenient way to group +related variables. Note that, for support of possible future features, +the first `tt(.)' is optional, but omitting it is discouraged. Unlike +ksh, a namespace need not be declared before it is referenced. + In scalar assignment, var(value) is expanded as a single string, in which the elements of arrays are joined together; filename expansion is not performed unless the option tt(GLOB_ASSIGN) is set. @@ -70,7 +84,8 @@ change its type to integer or float, and with tt(GLOB_ASSIGN) assigning a pattern to a variable may change its type to an array. To reference the value of a parameter, write `tt($)var(name)' or -`tt(${)var(name)tt(})'. See +`tt(${)var(name)tt(})'. The latter form is required when var(name) +includes a namespace prefix. See ifzman(em(Parameter Expansion) in zmanref(zshexpn))\ ifnzman(noderef(Parameter Expansion)) for complete details. That section also explains the effect -- cgit v1.2.3 From 42640b26136cbc1e35df08210028a3c3f41161f9 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 6 Mar 2023 20:08:12 -0800 Subject: 51511: More discussion of unsupported ksh features --- ChangeLog | 2 ++ Doc/Zsh/mod_ksh93.yo | 71 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4fe025adf..91c0584b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-03-06 Bart Schaefer + * 51512: Doc/Zsh/mod_ksh93.yo: More about unsupported features + * 51511: Doc/Zsh/expn.yo, Doc/Zsh/params.yo: Document namespaces * 51510: Src/builtin.c, Src/params.c, Src/utils.c, Src/zsh.h, diff --git a/Doc/Zsh/mod_ksh93.yo b/Doc/Zsh/mod_ksh93.yo index 3ae644bd1..d58b979b9 100644 --- a/Doc/Zsh/mod_ksh93.yo +++ b/Doc/Zsh/mod_ksh93.yo @@ -118,23 +118,6 @@ The following features of ksh93 are not currently supported but may be available in a future release. startitem() -item(var(pathdir)tt(/.paths))( -Each directory var(pathdir) in the tt(PATH) parameter may contain a -text file `tt(.paths)' which may define additional directories to -be searched for function definitions (tt(FPATH)), external executables -(tt(PATH)), and plugin files (similar to tt(MODULE_PATH)). - -em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.) -) -item(tt(builtin -f )var(file))( -Installs a new shell builtin command dynamically linked from var(file), -where var(file) is found by a path search and the base name of the file -is the name of the builtin to be added. - -Similar to `tt(zmodload -F zsh/)var(file)tt( +b:)var(file)'. - -em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.) -) item(tt(namespace )var(ident)tt( { )var(list)tt( }))( This reserved word executes the current shell compound command tt({ )var(list)tt( }), with the special behavior that all functions @@ -208,4 +191,58 @@ of `tt($LPAR())var(list)tt(RPAR())' but without forking. em(THIS FEATURE IS NOT YET IMPLEMENTED.) ) +item(tt(typeset -C )var(name)[tt(=)var(values)tt( ...)])( +Creates a em(compound variable). + +em(THIS FEATURE IS NOT YET IMPLEMENTED, and the syntax of var(values) +is unlikely to be fully ksh compatible.) +) +enditem() + +subsect(Other Differences) + +The following features of ksh93 are not currently supported and there are +no plans to implement them. + +startitem() +item(var(pathdir)tt(/.paths))( +Each directory var(pathdir) in the tt(PATH) parameter may contain a +text file `tt(.paths)' which may define additional directories to +be searched for function definitions (tt(FPATH)), external executables +(tt(PATH)), and plugin files (similar to tt(MODULE_PATH)). + +em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.) +) +item(tt(builtin -f )var(file))( +Installs a new shell builtin command dynamically linked from var(file), +where var(file) is found by a path search and the base name of the file +is the name of the builtin to be added. + +Similar to `tt(zmodload -F zsh/)var(file)tt( +b:)var(file)'. + +em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.) +) +item(tt(typeset -H )var(name)[tt(=)var(value)])( +Used for em(host-name file mapping) on some operating systems. + +em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.) +) +item(tt(typeset ){tt(PLUS()|-)}tt(M )var(mapname)tt( )var(name)[tt(=)var(value)])( +Declares a character translation var(mapname) for values assigned to var(name). +) +xitem(tt(typeset -S)) +xitem(tt(typeset -T ) [tt(-f)] [ var(tname)tt(=LPAR())var(values)tt(RPAR()) ]) +item(tt(typeset -h )var(str))( +Used to define em(typed variables) and properties of their em(sub-variables). +The tt(-T) and tt(-h) options conflict with existing zsh usage. +) +item(tt(typeset -X )var(name)[tt(=)var(value)])( +Declares a floating-point variable displayed in hexadecimal format. +) +item(tt(typeset -b )var(name)[tt(=)var(value)])( +Declares a parameter stored in em(base64) format. +) +item(tt(typeset -m )var(newname)tt(=)var(oldname))( +em(Moves) var(oldname) to var(newname). Conflicts with native zsh usage. +) enditem() -- cgit v1.2.3 From 8424fe5e23dbae3983bdb03a91c49f467865fc33 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 7 Mar 2023 17:57:06 -0800 Subject: 51534: update for recent changes in zsh.h --- ChangeLog | 4 ++++ Util/printdefines | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91c0584b3..f15072191 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-03-07 Bart Schaefer + + * 51534: Util/printdefines: update for recent changes + 2023-03-06 Bart Schaefer * 51512: Doc/Zsh/mod_ksh93.yo: More about unsupported features diff --git a/Util/printdefines b/Util/printdefines index 30c06533b..c1306a19e 100644 --- a/Util/printdefines +++ b/Util/printdefines @@ -288,16 +288,18 @@ local -AHPrt scanparamflags=( mapbase 2 $((1<<0)) SCANPM_WANTVALS # Return value includes hash values $((1<<1)) SCANPM_WANTKEYS # Return value includes hash keys - $((1<<2)) SCANPM_WANTINDEX # Return value includes array index + $((1<<2)) SCANPM_WANTINDEX # Return value includes array index $((1<<3)) SCANPM_MATCHKEY # Subscript matched against key $((1<<4)) SCANPM_MATCHVAL # Subscript matched against value - $((1<<5)) SCANPM_MATCHMANY # Subscript matched repeatedly, return all - $((1<<6)) SCANPM_ASSIGNING # Assigning whole array/hash + $((1<<5)) SCANPM_MATCHMANY # Subscript matched repeatedly, return all + $((1<<6)) SCANPM_ASSIGNING # Assigning whole array/hash $((1<<7)) SCANPM_KEYMATCH # keys of hash treated as patterns $((1<<8)) SCANPM_DQUOTED # substitution was double-quoted $((1<<9)) SCANPM_ARRONLY # value is array but we don't $((1<<10)) SCANPM_CHECKING # Check if set, no need to create $((1<<11)) SCANPM_NOEXEC # No command substitutions, etc. + $((1<<12)) SCANPM_NONAMESPC # namespace syntax not allowed + $((1<<13)) SCANPM_NONAMEREF # named references are not followed ) local -AHPrt substmodifiers=( mapbase 16 @@ -314,7 +316,7 @@ local -AHPrt substmodifiers=( $((0x0400)) SUB_DOSUBST # replacement string needs substituting $((0x4000)) SUB_EGLOB # use extended globbing in patterns ) -local -AHPrt printnodeflags=( +local -AHPrt printparamflags=( mapbase 2 $((1<<0)) PRINT_NAMEONLY $((1<<1)) PRINT_TYPE @@ -325,6 +327,9 @@ local -AHPrt printnodeflags=( $((1<<6)) PRINT_LINE $((1<<7)) PRINT_POSIX_EXPORT $((1<<8)) PRINT_POSIX_READONLY + $((1<<9)) PRINT_WITH_NAMESPACE +) +local -AHPrt printwhenceflags=( $((1<<7)) PRINT_WHENCE_CSH $((1<<8)) PRINT_WHENCE_VERBOSE $((1<<9)) PRINT_WHENCE_SIMPLE -- cgit v1.2.3 From 211682b78faf253b6d02cea7371f2fe03ada36f1 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 11 Mar 2023 13:52:05 +0100 Subject: 51539: don't complete diff options to git blame --- ChangeLog | 5 +++++ Completion/Unix/Command/_git | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index f15072191..c32e38e7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-03-11 Oliver Kiddle + + * 51539: Completion/Unix/Command/_git: don't complete diff + options to git blame + 2023-03-07 Bart Schaefer * 51534: Util/printdefines: update for recent changes diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 49f9fa504..1a9c79034 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -393,7 +393,7 @@ _git-bundle () { ':bundle:_files' && ret=0 else local revision_options - __git_setup_revision_options + __git_setup_revision_options -d _arguments -S -s \ $revision_options \ @@ -783,6 +783,7 @@ _git-diff () { _arguments -C -s $endopt \ $* \ $diff_options \ + '--exit-code[report exit code 1 if differences, 0 otherwise]' \ '(--exit-code)--quiet[disable all output]' \ $diff_stage_options \ '(--cached --staged)--no-index[show diff between two paths on the filesystem]' \ @@ -974,6 +975,7 @@ _git-format-patch () { '--interdiff=[insert interdiff against previous patch series in cover letter or single patch]:reference to tip of previous series:__git_revisions' \ '--range-diff=[insert range-diff against previous patch series in cover letter or single patch]:reference to tip ot previous series:__git_revisions' \ '--creation-factor=[for range-diff, specify weighting for creation]:weighting (percent)' \ + '--force-in-body-from[show in-body From: even if identical to the e-mail header]' \ ': :->commit-or-commit-range' && ret=0 case $state in @@ -4096,7 +4098,7 @@ _git-blame () { declare -A opt_args declare -a revision_options - __git_setup_revision_options + __git_setup_revision_options -d # TODO: Not sure about __git_cached_files. _arguments -C -S -s $endopt \ @@ -5344,8 +5346,11 @@ _git-diff-index () { # to given tree-ish? This should be done for git-diff as well, in that case. _arguments -S \ $revision_options \ + '--exit-code[report exit code 1 if differences, 0 otherwise]' \ + '(--exit-code)--quiet[disable all output]' \ "--cached[don't consider the work tree at all]" \ '-m[flag non-checked-out files as up-to-date]' \ + '--merge-base[use merge base instead of comparing directly]' \ ': :__git_tree_ishs' \ '*: :__git_cached_files' } @@ -5362,16 +5367,18 @@ _git-diff-tree () { # __git_setup_revision_options, but only used by this command, so only have # them here. _arguments -C -S -s \ - $revision_options \ + ${revision_options:#*--cc\[*} \ + '--exit-code[report exit code 1 if differences, 0 otherwise]' \ + '(--exit-code)--quiet[disable all output]' \ '-r[recurse into subdirectories]' \ '(-r )-t[display tree objects in diff output]' \ '--root[display root diff]' \ + '--merge-base[use merge base instead of comparing directly]' \ '-m[do not ignore merges]' \ '-s[do not show differences]' \ '(--pretty --header)-v[display commit message before differences]' \ '--no-commit-id[do not display commit IDs]' \ - '(-c --cc)-c[show differences from each of parents to merge result]' \ - '(-c --cc)--cc[how differences from each of parents and omit differences from only one parent]' \ + '(-c)--cc[combined diff format for merge commits, further omitting uninteresting hunks]' \ '--combined-all-paths[show name of file in all parents for combined diffs]' \ '--always[always show commit itself and commit log message]' \ ': :__git_tree_ishs' \ @@ -5560,7 +5567,7 @@ _git-rev-list () { declare -A opt_args declare -a revision_options - __git_setup_revision_options + __git_setup_revision_options -d _arguments -C -S $endopt \ $revision_options \ @@ -7691,8 +7698,9 @@ __git_setup_diff_options () { local exclusive_diff_options='(--name-only --name-status --check -s --no-patch)' diff_options=( - {-p,-u,--patch}'[generate diff in patch format]' - {-U,--unified=}'[generate diff with given lines of context]: :__git_guard_number lines' + '(-p -u --patch)'{-p,-u,--patch}'[generate diff in patch format]' + '(-U --unified -W --function-context)'{-U-,--unified=-}'[generate diff with given lines of context]:: :__git_guard_number lines' + '(-U --unified -W --function-context)'{-W,--function-context}'[show whole function where a match was found]' \ '--raw[generate default raw diff output]' '--patch-with-raw[generate patch but also keep the default raw diff output]' $exclusive_diff_options{-s,--no-patch}'[suppress diff output]' @@ -7773,7 +7781,6 @@ __git_setup_diff_options () { '--output-indicator-new=[specify the character to indicate a new line]:character [+]' '--output-indicator-old=[specify the character to indicate a old line]:character [-]' '--output-indicator-context=[specify the character to indicate a context line]:character [ ]' - '--exit-code[report exit code 1 if differences, 0 otherwise]' '( --no-ext-diff)--ext-diff[allow external diff helper to be executed]' '(--ext-diff )--no-ext-diff[disallow external diff helper to be executed]' '(--textconv --no-textconv)--textconv[allow external text conversion filters to be run when comparing binary files]' @@ -7784,7 +7791,10 @@ __git_setup_diff_options () { '--line-prefix=[prepend additional prefix to every line of output]:prefix' '(--src-prefix --dst-prefix)--no-prefix[do not show any source or destination prefix]' '(-c --cc)'{-c,--cc}'[combined diff format for merge commits]' - '--output=[output to a specific file]: :_files') + '--output=[output to a specific file]: :_files' + '--expand-tabs=-[replace each tab with spaces]::tab width [8]' + '!(--expand-tabs)--no-expand-tabs' + ) } (( $+functions[__git_setup_diff_stage_options] )) || @@ -7894,11 +7904,15 @@ __git_format_placeholders() { (( $+functions[__git_setup_revision_options] )) || __git_setup_revision_options () { - local -a diff_options - __git_setup_diff_options + if [[ $1 = "-d" ]]; then # don't include diff options if passed -d + revision_options=() + else + local -a diff_options + __git_setup_diff_options + revision_options=( $diff_options ) + fi - revision_options=( - $diff_options + revision_options+=( '(-v --header)'{--pretty=-,--format=-}'[pretty print commit messages]::format:__git_format_placeholders' '(--abbrev-commit --no-abbrev-commit)--abbrev-commit[show only partial prefixes of commit object names]' '(--abbrev-commit --no-abbrev-commit)--no-abbrev-commit[show the full 40-byte hexadecimal commit object name]' -- cgit v1.2.3 From 25dceb1dea4ee1c23dcc02f3f7f5c0bf345c492c Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 11 Mar 2023 13:20:21 -0800 Subject: 51557: Clarify availability of ksh-mode parameters, improve vi-mode detection. --- ChangeLog | 5 +++++ Doc/Zsh/mod_ksh93.yo | 8 +++++--- Src/Modules/ksh93.c | 5 +++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index f15072191..cc2890b2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-03-11 Bart Schaefer + + * 51557: Doc/zsh/mod_ksh93.yo, Src/Modules/ksh93.c: Clarify + availability of ksh-mode parameters, improve vi-mode detection. + 2023-03-07 Bart Schaefer * 51534: Util/printdefines: update for recent changes diff --git a/Doc/Zsh/mod_ksh93.yo b/Doc/Zsh/mod_ksh93.yo index d58b979b9..99dab385f 100644 --- a/Doc/Zsh/mod_ksh93.yo +++ b/Doc/Zsh/mod_ksh93.yo @@ -24,8 +24,10 @@ enditem() subsect(Ksh Parameters) cindex(parameters, ksh) -Parameters supplied by this module that are marked with `' below are -available only in ksh emulation. +Parameters supplied by this module that are marked with `' below +are available only when ksh emulation is active before entry to the +shell function, that is, `tt(emulate ksh)' locally to a function does +not populate these parameters for that function. startitem() vindex(.sh.command) @@ -45,7 +47,7 @@ A named reference to the ZLE special parameter `tt(CURSOR)'. vindex(.sh.edmode) item(tt(.sh.edmode) )( In a ZLE widget, this parameter has the value tt(ESC) (tt($'\e')) if the -`tt(main)' keymap is selected, and the empty string otherwise. This is +tt(VI) option is set and the `tt(main)' keymap is selected. This is intended for use with vi-mode key bindings (`tt(bindkey -v)'). In a future revision, assigning `tt(.sh.edchar=${.sh.edmode})' is expected to initiate `tt(vicmd)' mode when `tt(viins)' is active, and do diff --git a/Src/Modules/ksh93.c b/Src/Modules/ksh93.c index 9dc75c93c..51999dd71 100644 --- a/Src/Modules/ksh93.c +++ b/Src/Modules/ksh93.c @@ -168,8 +168,9 @@ ksh93_wrapper(Eprog prog, FuncWrap w, char *name) if (zleactive) { extern mod_import_variable char *curkeymapname; /* XXX */ extern mod_import_variable char *varedarg; /* XXX */ - /* How to distinguish emacs bindings? */ - if (curkeymapname && strcmp(curkeymapname, "main") == 0) + /* bindkey -v forces VIMODE so this test is as good as any */ + if (curkeymapname && isset(VIMODE) && + strcmp(curkeymapname, "main") == 0) strcpy(sh_edmode, "\e"); else strcpy(sh_edmode, ""); -- cgit v1.2.3 From 29503debc778535011f085589d94448db25f8efa Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 11 Mar 2023 13:22:10 -0800 Subject: 51558: Clarify "for" with positional parameters and named reference. --- ChangeLog | 4 +++- Doc/Zsh/grammar.yo | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cc2890b2f..210c4f9c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ 2023-03-11 Bart Schaefer - * 51557: Doc/zsh/mod_ksh93.yo, Src/Modules/ksh93.c: Clarify + * 51558: Doc/Zsh/grammar.yo: Clarify "for" loops + named refs. + + * 51557: Doc/Zsh/mod_ksh93.yo, Src/Modules/ksh93.c: Clarify availability of ksh-mode parameters, improve vi-mode detection. 2023-03-07 Bart Schaefer diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo index 1b834f41a..915b93bc0 100644 --- a/Doc/Zsh/grammar.yo +++ b/Doc/Zsh/grammar.yo @@ -190,6 +190,9 @@ use the positional parameters instead of the var(word)s. If any var(name) has been declared as a named reference, the corresponding var(word) is treated as the name of a parameter and var(name) is made a reference to that. +Note that for the positional parameters, this treats the +value of each positional as parameter name rather than +creating a reference to the position. The var(term) consists of one or more newline or tt(;) which terminate the var(word)s, and are optional when the -- cgit v1.2.3 From 6725cbc05fc7943290896ae80d706f335eec96ba Mon Sep 17 00:00:00 2001 From: Sven Joachim Date: Mon, 13 Mar 2023 19:44:25 -0700 Subject: Sven Joachim: 51563: Fix unmatched double quote --- ChangeLog | 4 ++++ Completion/Debian/Command/_sbuild | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b4952c8d6..e80b09833 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-03-13 Bart Schaefer + + * Sven Joachim: 51563: Completion/Debian/Command/_sbuild: unmatched " + 2023-03-11 Bart Schaefer * 51558: Doc/Zsh/grammar.yo: Clarify "for" loops + named refs. diff --git a/Completion/Debian/Command/_sbuild b/Completion/Debian/Command/_sbuild index a32b5e8c5..459738d5d 100644 --- a/Completion/Debian/Command/_sbuild +++ b/Completion/Debian/Command/_sbuild @@ -124,7 +124,7 @@ _sbuild() { '--aspcud-criteria=[Optimization for aspcud]:criteria' \ '(--resolve-alternatives --no-resolve-alternatives)--resolve-alternatives[allow alternatives in Build-Depends*]' \ '(--resolve-alternatives --no-resolve-alternatives)--no-resolve-alternatives[disallow alternatives in Build-Depends*]' \ - '--extra-package=[make a package or directory available to the resolver]:package:_files -g "*deb(-.)' \ + '--extra-package=[make a package or directory available to the resolver]:package:_files -g "*deb(-.)"' \ '--extra-repository=[add a repository to the resolver]:url' \ '--extra-repository-key=[add key to the resolver]:key:_files -g "*.asc(-.)"' \ '--build-path=[place to build the package inside chroot]:path:_files -/' \ -- cgit v1.2.3 From dd13048b3b8cf710f44424ce9fedc2b56c31fde3 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 13 Mar 2023 19:46:39 -0700 Subject: 51572: fix "shift" error when running standalone --- ChangeLog | 2 ++ Functions/Misc/run-help | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e80b09833..7ecc36a67 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-03-13 Bart Schaefer + * 51572: Functions/Misc/run-help: fix error when running standalone + * Sven Joachim: 51563: Completion/Debian/Command/_sbuild: unmatched " 2023-03-11 Bart Schaefer diff --git a/Functions/Misc/run-help b/Functions/Misc/run-help index d52c1b032..14d09bd65 100644 --- a/Functions/Misc/run-help +++ b/Functions/Misc/run-help @@ -98,13 +98,13 @@ do if whence "run-help-$1:t" >/dev/null then local cmd_args - builtin getln cmd_args + builtin getln cmd_args && builtin print -z "$cmd_args" - cmd_args=( ${(z)cmd_args} ) + cmd_args=( ${(z)${cmd_args:-"$*"}} ) # Discard the command itself & everything before it. shift $cmd_args[(i)${run_help_orig_cmd:-$1}] cmd_args || - return + continue # Discard options, parameter assignments & paths. cmd_args=( ${cmd_args[@]:#([-+]*|*=*|*/*|\~*)} ) -- cgit v1.2.3 From 4b7a9fd0ecb750646cac76c41383f8391cd0fdd9 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 14 Mar 2023 20:51:15 -0700 Subject: 51573: additional "typset -p -m" fix for namespaces The "-m pattern" option is supposed to enable printing namespaces, but that didn't work when combined with -p. The -p option could also cause an unset parameter to become set if a named reference pointed at it. --- ChangeLog | 4 ++++ Src/builtin.c | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7ecc36a67..f16bd7811 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-03-14 Bart Schaefer + + * 51573: Src/builtin.c: additional "typset -p -m" fix for namespaces + 2023-03-13 Bart Schaefer * 51572: Functions/Misc/run-help: fix error when running standalone diff --git a/Src/builtin.c b/Src/builtin.c index d99802f5f..f38a54936 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2236,12 +2236,12 @@ typeset_single(char *cname, char *pname, Param pm, int func, } on &= ~PM_LOCAL; if (!on && !roff && !ASG_VALUEP(asg)) { + int with_ns = OPT_ISSET(ops,'m') ? PRINT_WITH_NAMESPACE : 0; if (OPT_ISSET(ops,'p')) - paramtab->printnode(&pm->node, PRINT_TYPESET); + paramtab->printnode(&pm->node, PRINT_TYPESET|with_ns); else if (!OPT_ISSET(ops,'g') && (unset(TYPESETSILENT) || OPT_ISSET(ops,'m'))) - paramtab->printnode(&pm->node, - PRINT_INCLUDEVALUE|PRINT_WITH_NAMESPACE); + paramtab->printnode(&pm->node, PRINT_INCLUDEVALUE|with_ns); return pm; } if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) { @@ -2502,6 +2502,8 @@ typeset_single(char *cname, char *pname, Param pm, int func, "%s: inconsistent array element or slice assignment", pname); return NULL; } + } else if (!pm && OPT_ISSET(ops,'p')) { + return NULL; } /* * As we can hide existing parameters, we allow a name if -- cgit v1.2.3 From ea229be4cfb6a734938648df4322fc4473e1712e Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 16 Mar 2023 22:12:48 +0100 Subject: 51581: update completions to cover changes in OpenBSD 7.2 --- ChangeLog | 7 +++++++ Completion/BSD/Command/_fw_update | 6 ++++-- Completion/BSD/Command/_rcctl | 2 +- Completion/Unix/Command/_grep | 3 ++- Completion/Unix/Command/_netstat | 1 - Completion/Unix/Command/_ps | 2 +- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index f16bd7811..1c87f827b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-03-16 Oliver Kiddle + + * 51581: Completion/BSD/Command/_fw_update, + Completion/BSD/Command/_rcctl, Completion/Unix/Command/_grep, + Completion/Unix/Command/_netstat, Completion/Unix/Command/_ps: + update completions to cover changes in OpenBSD 7.2 + 2023-03-14 Bart Schaefer * 51573: Src/builtin.c: additional "typset -p -m" fix for namespaces diff --git a/Completion/BSD/Command/_fw_update b/Completion/BSD/Command/_fw_update index b01749f3f..84b5f808d 100644 --- a/Completion/BSD/Command/_fw_update +++ b/Completion/BSD/Command/_fw_update @@ -3,8 +3,10 @@ _arguments -s -S -A "-*" \ '(*)-a[install or update firmware for all drivers]' \ '-d[delete drivers instead of adding them]' \ - '-i[display information]' \ + '-F[download firmware only]' \ '-n[dry run]' \ - '-p[use the firmware at specified path]:path:' \ + '-p+[use the firmware at specified path]: : _alternative + "urls\:url\:_urls" + "directories\:path\:_directories"' \ '*-v[verbose output]' \ '(-a)*:driver:' diff --git a/Completion/BSD/Command/_rcctl b/Completion/BSD/Command/_rcctl index 6cfebf420..98e4f9846 100644 --- a/Completion/BSD/Command/_rcctl +++ b/Completion/BSD/Command/_rcctl @@ -3,7 +3,7 @@ local context state line local -a actions lsarg subcmds variables -actions=(check reload restart start stop) +actions=(configtest check reload restart start stop) subcmds=(disable enable get getdef ls order set) variables=(class flags status timeout user) lsarg=( diff --git a/Completion/Unix/Command/_grep b/Completion/Unix/Command/_grep index 2dcbff4a3..0f1e712fd 100644 --- a/Completion/Unix/Command/_grep +++ b/Completion/Unix/Command/_grep @@ -89,7 +89,7 @@ case $variant:$OSTYPE in ;| gpl2:(freebsd|darwin)*) arguments+=( - '(--null --no-filename -h)--null[print 0 byte after each filename]' + '(--no-filename -h)--null[print 0 byte after each filename]' '(-Z --decompress -J --bz2decompress)'{-J,--bz2decompress}"[decompress bzip2'ed input before searching]" '(-Z --decompress -J --bz2decompress)'{-Z,--decompress}"[decompress gzip'ed input before searching]" ) @@ -129,6 +129,7 @@ case $variant:$OSTYPE in arguments=( ${(M)arguments:#((#s)|*\))--(context|binary-files|line-buffered|label|max-count)*} ${${arguments:#((#s)|*\))(\*|)-[d-]*}/\)-r/\)-R} + '(-h)--null[print 0 byte after each filename]' "-U[search binary files but don't print them]" '-Z[behave as zgrep]' ) diff --git a/Completion/Unix/Command/_netstat b/Completion/Unix/Command/_netstat index 67133dc6c..8016b2475 100644 --- a/Completion/Unix/Command/_netstat +++ b/Completion/Unix/Command/_netstat @@ -280,7 +280,6 @@ case $OSTYPE in '-c+[show specified number of updates, then exit]:count' '-e[show only the number of errors on the interface]' '-q[only show interfaces that have seen packets]' - '-t[show current value of the watchdog timer function]' ) statistics+=( $popt '-r[display routing statistics]' ) groups+=( -n$nopt ) diff --git a/Completion/Unix/Command/_ps b/Completion/Unix/Command/_ps index 9b54cbcc6..905309a12 100644 --- a/Completion/Unix/Command/_ps +++ b/Completion/Unix/Command/_ps @@ -105,6 +105,7 @@ case $OSTYPE in bsdarg+=( 'M[extract values from specified core]' ) ;| linux-gnu|netbsd*) bsdarg+=( 'k[specify sort order]' ) ;| + linux-gnu|openbsd*) bsd+=( 'f[show process hierarchy]' ) ;| darwin*|freebsd*) bsd+=( 'X[skip processes with no controlling terminal]' ) bsdarg+=( '*G[select processes by real group]' ) @@ -188,7 +189,6 @@ case $OSTYPE in done bsd+=( 'c[show true command name]' - 'f[show process hierarchy]' 'h[suppress header]' 'm[show threads after processes]' 'n[numeric output for WCHAN and USER]' -- cgit v1.2.3 From 6386dd94fd0fe771e9c79864ad2a24e4f2ff123e Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 16 Mar 2023 22:15:28 +0100 Subject: 51582: openssh 9.3 completion update --- ChangeLog | 2 + Completion/Unix/Command/_ssh | 184 +++++++++++++++++++++++++++---------------- 2 files changed, 120 insertions(+), 66 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1c87f827b..4143984e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-03-16 Oliver Kiddle + * 51582: Completion/Unix/Command/_ssh: openssh 9.3 completion update + * 51581: Completion/BSD/Command/_fw_update, Completion/BSD/Command/_rcctl, Completion/Unix/Command/_grep, Completion/Unix/Command/_netstat, Completion/Unix/Command/_ps: diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index 2385272f1..e9ca454b4 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -18,14 +18,18 @@ _ssh () { '*-o+[specify extra options]:option string:->option' ) common_transfer=( + '(-O)-D+[connect directly to a local sftp server]:sftp server path:_command_names -e' '-J+[connect via a jump host]: :->userhost' '-l+[limit used bandwidth]:bandwidth (Kbit/s)' '-P+[specify port on remote host]:port number on remote host' '-p[preserve modification times, access times and modes]' '-q[disable progress meter and warnings]' '-r[recursively copy directories (follows symbolic links)]' - '-S+[specify ssh program]:path to ssh:_command_names -e' \ + '-S+[specify ssh program]:path to ssh:_command_names -e' '-v[verbose mode]' + '*(-O)-X+[specify sftp protocol option]: : _values "sftp option" + "nrequests[set max concurrent SFTP read or write requests]\:requests [64]" + "buffer[set max buffer size for a single SFTP read/write operation]\: \:_numbers -l 0 -m 256K -d 32K -u bytes -f size \:B\:bytes \:K\:kilobytes"' ) algopt='-E+[specify hash algorithm for fingerprints]:algorithm:(md5 sha256)' @@ -58,7 +62,7 @@ _ssh () { '(-v)*-q[quiet operation]' \ '*-R+[specify remote port forwarding]:remote port forwarding:->forward' \ '-S+[specify location of control socket for connection sharing]:path to control socket:_files' \ - '-Q+[query parameters]:query option:((cipher\:"supported symmetric ciphers" cipher-auth\:"supported symmetric ciphers that support authenticated encryption" mac\:"supported message integrity codes" kex\:"key exchange algorithms" key\:"key types" key-cert\:"certificate key types" key-plain\:"non-certificate key types" protocol-version\:"supported SSH protocol versions" sig\:"supported signature algorithms" help\:"show supported queries"))' \ + '-Q+[query parameters]:query option:((cipher\:"supported symmetric ciphers" cipher-auth\:"supported symmetric ciphers that support authenticated encryption" compression mac\:"supported message integrity codes" kex\:"key exchange algorithms" kex-gss\:"GSSAPI key exchange algorithms" key\:"key types" key-cert\:"certificate key types" key-plain\:"non-certificate key types" key-sig\:"all key types and signature algorithms" protocol-version\:"supported SSH protocol versions" sig\:"supported signature algorithms" help\:"show supported queries" HostbasedAcceptedAlgorithms HostKeyAlgorithms KexAlgorithms MACs PubkeyAcceptedAlgorithms))' \ '-s[invoke subsystem]' \ '(-t)-T[disable pseudo-tty allocation]' \ "(-T)*-t[force pseudo-tty allocation${tdesc}]" \ @@ -76,7 +80,8 @@ _ssh () { scp) _arguments -C -s \ '-3[copy through local host, not directly between the remote hosts]' \ - '-B[batch mode (don'\''t ask for passphrases)]' \ + "-B[batch mode (don't ask for passwords or passphrases)]" \ + '(-D -X)-O[use the original SCP protocol instead of the SFTP protocol]' \ '-T[disable strict filename checking]' \ '*:file:->file' "$common[@]" "$common_transfer[@]" && ret=0 ;; @@ -95,12 +100,14 @@ _ssh () { '--apple-load-keychain[add identities from keychain]' '--apple-use-keychain[update keychain when adding/removing identities]' ) - _arguments -s : $args \ + _arguments -C -s : $args \ '-c[identity is subject to confirmation via SSH_ASKPASS]' \ '-D[delete all identities]' \ '-d[remove identity]' \ $algopt \ '-e+[remove keys provided by the PKCS#11 shared library]:library:_files -g "*.(so|dylib)(|.<->)(-.)"' \ + '*-H[specify a known hosts file to look up hostkeys]:known hosts file:_files' \ + '*-h[constrain keys to specific hosts or destinations]:destination:->destinations' \ '-k[load plain private keys only and skip certificates]' \ '-K[load resident keys from a FIDO authenticator]' \ '-L[list public key parameters of all identities in the agent]'\ @@ -109,14 +116,13 @@ _ssh () { '-M+[specify maximum number of signatures]:number' \ '-S+[use specified library when adding FIDO authenticator-hosted keys]:library:_files' \ '-s+[add keys provided by the PKCS#11 shared library]:library:_files -g "*.(so|dylib)(|.<->)(-.)"' \ - '-t+[set maximum lifetime for identity]:maximum lifetime (in seconds or time format):' \ + '-t+[set maximum lifetime for identity]: :_numbers -u seconds "maximum lifetime" \:s\:seconds m\:minutes h\:hours d\:days w\:weeks' \ "-T[test usability of identity files' private keys]:*:public key file:_files -g '*.pub(-.)'" \ '*-v[verbose mode]' \ '-q[be quiet after a successful operation]' \ '-X[unlock the agent]' \ '-x[lock the agent with a password]' \ - '*:SSH identity file:_files' - return + '*:SSH identity file:_files' && ret=0 ;; ssh-agent) _arguments -s \ @@ -128,7 +134,7 @@ _ssh () { '-k[kill current agent]' \ '(-k)-P[specify PKCS#11 shared library whitelist]:PKCS#11 library whitelist pattern' \ '(-k -c)-s[force sh-style shell]' \ - '-t[set default maximum lifetime for identities]:maximum lifetime (in seconds or time format):' \ + '-t+[set default maximum lifetime for identities]: :_numbers -u seconds "maximum lifetime" \:s\:seconds m\:minutes h\:hours d\:days w\:weeks' \ '-v[verbose mode]' \ '*::command: _normal' return @@ -183,15 +189,13 @@ _ssh () { case ${words[arg]#-Y} in ^find-*) sigargs+=( "$p1-n+[specify namespace]:namespace" ) ;| check*|find*|verify) - sigargs+=( "$p1-s+[specify signature file]:signature file:-files" ) + sigargs+=( "$p1-s+[specify signature file]:signature file:_files" ) ;| + match*|verify) sigargs+=( '-I+[specify signer identity]:identity' ) ;| sign) sigargs+=( '*:file:_files' ) ;; verify) args=() - sigargs+=( - '-I+[specify signer identity]:identity' - '-r+[specify revocation file]:revocation file:_files' - ) + sigargs+=( '-r+[specify revocation file]:revocation file:_files' ) ;; esac fi @@ -235,12 +239,6 @@ _ssh () { "($cmn)-L[print the contents of a certificate]" \ "(${${(@)cmn:#-a}})-A[generate host keys for all key types]" \ "($cmn)-Q[test whether keys have been revoked in a KRL]" \ - "($cmn)-Y+[signature action]:action:(( - find-principals\:find\ the\ principal\ associated\ with\ the\ public\ key\ of\ a\ signature - sign\:sign\ a\ file\ using\ SSH\ key - verify\:verify\ a\ signature\ generated\ using\ the\ sign\ option - check-novalidate\:check\ signature\ structure - ))" \ - finger \ "$p1($cmn)$algopt" \ - create \ @@ -260,6 +258,13 @@ _ssh () { "($cmn -I -h -n -D -O -U -V)-k[generate a KRL file]" \ "$p1($cmn -I -h -n -D -O -U -V)-u[update a KRL]" \ - signature \ + "(${${(@)cmn:#-O}})-Y+[signature action]:action:(( + find-principals\:find\ the\ principal\ associated\ with\ the\ public\ key\ of\ a\ signature + sign\:sign\ a\ file\ using\ SSH\ key + verify\:verify\ a\ signature\ generated\ using\ the\ sign\ option + check-novalidate\:check\ signature\ structure + match-principals\:find\ matching\ principal + ))" \ $sigargs return ;; @@ -271,8 +276,10 @@ _ssh () { '-D[print keys found as SSHFP DNS records]' \ '*-f+[read hosts from file, one per line]:file:_files' \ '-H[hash all hostnames and addresses in the output]' \ + '-O+[specify a key/value option]: : _values option + "hashalg[select a hash algorithm to use with -D]\:algorithm [both]\:(sha1 sha256)"' \ '-p+[specify port on remote host]:port number on remote host' \ - '-T+[specify timeout]:timeout (seconds) [5]' \ + '-T+[specify timeout]: :_numbers -u seconds -d 5 timeout \:s\:seconds m\:minutes h\:hours d\:days w\:weeks' \ '-t+[specify key types to fetch from scanned hosts]:key type:_sequence compadd - rsa dsa ecdsa ed25519' \ '-v[verbose mode]' return @@ -282,7 +289,6 @@ _ssh () { '-a[attempt to continue interrupted transfers]' \ '-B+[specify buffer size]:buffer size (bytes) [32768]' \ '-b+[specify batch file to read]:batch file:_files' \ - '-D+[connect directly to a local sftp server]:sftp server path' \ '-f[request that files be flushed immediately after transfer]' \ '-N[disable implicit quiet mode set by -b]' \ '-R+[specify number of outstanding requests]:number of requests [64]' \ @@ -309,22 +315,37 @@ _ssh () { option) if compset -P 1 '*='; then case "${IPREFIX#-o}" in - (#i)(ciphers|macs|kexalgorithms|hostkeyalgorithms|pubkeyacceptedkeytypes|hostbasedkeytypes)=) - if ! compset -P '[+-]'; then - _wanted prefix expl 'relative to default' compadd - + - && ret=0 + (#i)(ciphers|macs|kexalgorithms|hostkeyalgorithms|pubkeyacceptedalgorithms)=) + local sep + zstyle -s ":completion:${curcontext}:" list-separator sep || sep=-- + if ! compset -P '[+-^]'; then + _wanted prefix expl 'relative to default' compadd -S '' -d \ + "( + +\ $sep\ append\ to\ default\ list + -\ $sep\ remove\ from\ default\ list + ^\ $sep\ insert\ at\ head\ of\ default\ list + )" - + - \^ && ret=0 fi ;; esac case "${IPREFIX#-o}" in - (#i)(afstokenpassing|batchmode|canonicalizefallbacklocal|challengeresponseauthentication|checkhostip|clearallforwardings|compression|enablesshkeysign|exitonforwardfailure|fallbacktorsh|forward(agent|x11)|forwardx11trusted|gatewayports|gssapiauthentication|gssapidelegatecredentials|gssapikeyexchange|gssapirenewalforcesrekey|gssapitrustdns|hashknownhosts|hostbasedauthentication|identitiesonly|kbdinteractiveauthentication|(tcp|)keepalive|nohostauthenticationforlocalhost|passwordauthentication|permitlocalcommand|proxyusefdpass|pubkeyauthentication|rhosts(|rsa)authentication|rsaauthentication|streamlocalbindunlink|usersh|kerberos(authentication|tgtpassing)|useprivilegedport|visualhostkey)=*) + (#i)(batchmode|canonicalizefallbacklocal|checkhostip|clearallforwardings|compression|enableescapecommandline|enablesshkeysign|exitonforwardfailure|fallbacktorsh|forkafterauthentication|forward(agent|x11)|forwardx11trusted|gatewayports|gssapiauthentication|gssapidelegatecredentials|gssapikeyexchange|gssapirenewalforcesrekey|gssapitrustdns|hashknownhosts|hostbasedauthentication|identitiesonly|kbdinteractiveauthentication|tcpkeepalive|nohostauthenticationforlocalhost|passwordauthentication|permitlocalcommand|permitremoteopen|proxyusefdpass|stdinnull|streamlocalbindunlink|visualhostkey)=*) _wanted values expl 'truth value' compadd yes no && ret=0 ;; + (#i)addkeystoagent=*) + _alternative \ + 'timeouts: :_numbers -u seconds "time interval" :s:seconds m:minutes h:hours d:days w:weeks' \ + 'values:value:(yes no ask confirm)' && ret=0 + ;; (#i)addressfamily=*) _wanted values expl 'address family' compadd any inet inet6 && ret=0 ;; (#i)bindaddress=*) _wanted bind-addresses expl 'bind address' _bind_addresses && ret=0 ;; + (#i)bindinterface=*) + _wanted bind-interfaces expl 'bind interface' _network_interfaces && ret=0 + ;; (#i)canonicaldomains=*) _message -e 'canonical domains (space separated)' && ret=0 ;; @@ -340,23 +361,27 @@ _ssh () { (#i)ciphers=*) state=ciphers ;; + (#i)certificatefile=*) + _description files expl 'file' + _files "$expl[@]" && ret=0 + ;; (#i)connectionattempts=*) _message -e 'connection attempts' && ret=0 ;; (#i)connecttimeout=*) - _message -e 'connection timeout' && ret=0 + _numbers -u seconds timeout :s:seconds m:minutes h:hours d:days w:weeks && ret=0 ;; (#i)controlmaster=*) - _wanted values expl 'truthish value' compadd yes no auto autoask && ret=0 + _wanted values expl 'truthish value' compadd yes no auto ask autoask && ret=0 ;; (#i)controlpath=*) _description files expl 'path to control socket' _files "$expl[@]" && ret=0 ;; (#i)controlpersist=*) - _message -e 'timeout' - ret=0 - _wanted values expl 'truth value' compadd yes no && ret=0 + _alternative \ + 'timeouts: :_numbers -u seconds timeout :s:seconds m:minutes h:hours d:days w:weeks' \ + 'values:truth value:(yes no)' && ret=0 ;; (#i)escapechar=*) _message -e 'escape character (or `none'\'')' @@ -377,9 +402,10 @@ _ssh () { (#i)hostname=*) _wanted hosts expl 'real host name to log into' _ssh_hosts && ret=0 ;; - (#i)(hostbasedkeytypes|hostkeyalgorithms|pubkeyacceptedkeytypes)=*) - _wanted key-types expl 'key type' _sequence compadd - $(_call_program key-types ssh -Q key) && ret=0 - ;; + (#i)identityagent=*) + _description files expl 'socket file' + _files -g "*(-=)" "$expl[@]" && ret=0 + ;; (#i)identityfile=*) _description files expl 'SSH identity file' _files "$expl[@]" && ret=0 @@ -410,13 +436,16 @@ _ssh () { _values -s , 'keyboard-interactive authentication method' \ 'bsdauth' 'pam' 'skey' && ret=0 ;; - (#i)(kexalgorithms|gssapikexalgorithms)=*) + (#i)kexalgorithms=*) _wanted algorithms expl 'key exchange algorithm' _sequence compadd - \ $(_call_program algorithms ssh -Q kex) && ret=0 ;; - (#i)localcommand=*) - _description commands expl 'run command locally after connecting' - _command_names && ret=0 + (#i)gssapikexalgorithms=*) + _wanted algorithms expl 'key exchange algorithm' _sequence compadd - \ + $(_call_program algorithms ssh -Q kex-gss) && ret=0 + ;; + (#i)(local|knownhosts)command=*) + _command_names -e && ret=0 ;; (#i)loglevel=*) _values 'log level' QUIET FATAL ERROR INFO VERBOSE\ @@ -429,8 +458,8 @@ _ssh () { _message -e 'number of password prompts' ret=0 ;; - (#i)pkcs11provider=*) - _description files expl 'PKCS#11 shared library' + (#i)(pkcs11|securitykey)provider=*) + _description files expl 'shared library' _files -g '*.(so|dylib)(|.<->)(-.)' "$expl[@]" && ret=0 ;; (#i)port=*) @@ -441,6 +470,17 @@ _ssh () { _values -s , 'authentication method' gssapi-with-mic \ hostbased publickey keyboard-interactive password && ret=0 ;; + (#i)proxyjump=*) + compset -P "* " + state=userhost + ;; + (#i)(hostkey|(hostbased|pubkey)accepted)algorithms=*) + _wanted key-types expl 'key type' _sequence compadd - \ + $(_call_program key-types ssh -Q key-sig) && ret=0 + ;; + (#i)pubkeyauthentication=*) + _wanted values expl 'enable' compadd yes no unbound host-bound && ret=0 + ;; (#i)protocol=*) _values -s , 'protocol version' \ '1' \ @@ -450,7 +490,13 @@ _ssh () { _cmdstring && ret=0 ;; (#i)rekeylimit=*) - _message -e 'maximum number of bytes transmitted before renegotiating session key' + if compset -P "* "; then + _numbers -u seconds "maximum time before renegotiating session key" \ + :s:seconds h:hours d:days w:weeks + else + _numbers -u bytes "maximum amount of data transmitted before renegotiating session key" \ + K:kilobytes M:megabytes G:gigabytes + fi ret=0 ;; (#i)requesttty=*) @@ -460,6 +506,9 @@ _ssh () { 'force[always request a TTY]' \ 'auto[request a TTY when opening a login session]' && ret=0 ;; + (#i)requiredrsasize=) + _wanted sizes expl 'minimum size [1024]' compadd 1024 2048 4096 && ret=0 + ;; (#i)revokedhostkeys=*) _description files expl 'revoked host keys file' _files "$expl[@]" && ret=0 @@ -478,6 +527,9 @@ _ssh () { (#i)streamlocalbindmask=*) _message -e 'octal mask' && ret=0 ;; + (#i)sessiontype=*) + _wanted session-types expl "session type" compadd none subsystem default && ret=0 + ;; (#i)stricthostkeychecking=*) _wanted values expl 'value' compadd yes no ask accept-new off && ret=0 ;; @@ -512,15 +564,18 @@ _ssh () { _description files expl 'xauth program' _files "$expl[@]" -g '*(-*)' && ret=0 ;; + *) _message -e values value ;; esac else - # old options are after the empty "\"-line + # Include, Host and Match not supported from the command-line + # final GSSAPI options are not in upstream but are widely patched in _wanted values expl 'configure file option' \ compadd -M 'm:{a-z}={A-Z} r:[^A-Z]||[A-Z]=* r:|=*' -q -S '=' - \ AddKeysToAgent \ AddressFamily \ BatchMode \ BindAddress \ + BindInterface \ CanonicalDomains \ CanonicalizeFallbackLocal \ CanonicalizeHostname \ @@ -528,7 +583,6 @@ _ssh () { CanonicalizePermittedCNAMEs \ CASignatureAlgorithms \ CertificateFile \ - ChallengeResponseAuthentication \ CheckHostIP \ Ciphers \ ClearAllForwardings \ @@ -539,10 +593,12 @@ _ssh () { ControlPath \ ControlPersist \ DynamicForward \ + EnableEscapeCommandline \ EnableSSHKeysign \ EscapeChar \ ExitOnForwardFailure \ FingerprintHash \ + ForkAfterAuthentication \ ForwardAgent \ ForwardX11 \ ForwardX11Timeout \ @@ -550,19 +606,13 @@ _ssh () { GatewayPorts \ GlobalKnownHostsFile \ GSSAPIAuthentication \ - GSSAPIClientIdentity \ GSSAPIDelegateCredentials \ - GSSAPIKeyExchange \ - GSSAPIRenewalForcesRekey \ - GSSAPIServerIdentity \ - GSSAPITrustDns \ - GSSAPIKexAlgorithms \ HashKnownHosts \ + HostbasedAcceptedAlgorithms \ HostbasedAuthentication \ - HostbasedKeyTypes \ HostKeyAlgorithms \ HostKeyAlias \ - HostName \ + Hostname \ IdentitiesOnly \ IdentityAgent \ IdentityFile \ @@ -571,33 +621,38 @@ _ssh () { KbdInteractiveAuthentication \ KbdInteractiveDevices \ KexAlgorithms \ + KnownHostsCommand \ LocalCommand \ LocalForward \ LogLevel \ + LogVerbose \ MACs \ NoHostAuthenticationForLocalhost \ NumberOfPasswordPrompts \ PasswordAuthentication \ PermitLocalCommand \ + PermitRemoteOpen \ PKCS11Provider \ Port \ PreferredAuthentications \ ProxyCommand \ ProxyJump \ ProxyUseFdpass \ - PubkeyAcceptedKeyTypes \ PubkeyAuthentication \ + PubkeyAcceptedAlgorithms \ RekeyLimit \ RemoteCommand \ RemoteForward \ RequestTTY \ + RequiredRSASize \ RevokedHostKeys \ - RhostsRSAAuthentication \ - RSAAuthentication \ + SecurityKeyProvider \ SendEnv \ ServerAliveCountMax \ ServerAliveInterval \ SetEnv \ + SessionType \ + StdinNull \ StreamLocalBindMask \ StreamLocalBindUnlink \ StrictHostKeyChecking \ @@ -606,24 +661,17 @@ _ssh () { Tunnel \ TunnelDevice \ UpdateHostKeys \ - UsePrivilegedPort \ User \ UserKnownHostsFile \ VerifyHostKeyDNS \ VisualHostKey \ XAuthLocation \ - \ - AFSTokenPassing \ - FallBackToRsh \ - KeepAlive \ - KerberosAuthentication \ - KerberosTgtPassing \ - PreferredAuthentications \ - ProtocolKeepAlives \ - RhostsAuthentication \ - SetupTimeOut \ - SmartcardDevice \ - UseRsh \ + GSSAPIClientIdentity \ + GSSAPIKeyExchange \ + GSSAPIRenewalForcesRekey \ + GSSAPIServerIdentity \ + GSSAPITrustDns \ + GSSAPIKexAlgorithms \ && ret=0 fi ;; @@ -693,6 +741,10 @@ _ssh () { _normal return ;; + destinations) + compset -P 1 '*>' + compset -S '>*' + ;& # fall-through userhost) if compset -P '*@'; then _wanted hosts expl 'remote host name' _ssh_hosts && ret=0 -- cgit v1.2.3 From 9bd477dce9a5887d42a5365aaf8906ac1f118510 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 16 Mar 2023 22:16:52 +0100 Subject: 51583: update completion of git attributes --- ChangeLog | 3 ++ Completion/Unix/Command/_git | 81 ++++++++++++++++++++------------------------ 2 files changed, 39 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4143984e3..ec32f1029 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-03-16 Oliver Kiddle + * 51583: Completion/Unix/Command/_git: update completion of + git attributes + * 51582: Completion/Unix/Command/_ssh: openssh 9.3 completion update * 51581: Completion/BSD/Command/_fw_update, diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 1a9c79034..1c3a95031 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -5866,46 +5866,51 @@ _git-upload-pack () { (( $+functions[_git-check-attr] )) || _git-check-attr () { - local z_opt= - - local curcontext=$curcontext state line ret=1 + local curcontext="$curcontext" z_opt ret=1 + local -a state line declare -A opt_args if (( words[(I)--stdin] )); then - z_opt='-z[paths are separated with NUL character when reading from stdin]' + z_opt='-z[terminate input file list and output records by a NUL character]' + else + z_opt='-z[separate output records with NUL character]' fi - _arguments -C \ - {-a,--all}'[list all attributes that are associated with the specified paths]' \ + _arguments -C $z_opt \ '--stdin[read file names from stdin instead of from command line]' \ - '--cached[consider .gitattributes in the index only, ignoring the working tree.]' \ - '-z[terminate input and output records by a NUL character]' \ - $z_opt \ + '(--source)--cached[consider .gitattributes in the index only, ignoring the working tree]' \ + '(--cached)--source=[specify tree to scan for .gitattributes (useful in bare repo)]:tree object:__git_tree_ishs' \ + - files \ + '(-a --all --)'{-a,--all}'[list all attributes that are associated with the specified paths]' \ '(-)--[interpret preceding arguments as attributes and following arguments as path names]' \ - '*:: :->attribute-or-file' && ret=0 + '*: :__git_cached_files' \ + - attrs \ + '*:::attribute:->attributes' && ret=0 case $state in - (attribute-or-file) - local -a attributes - - attributes=(crlf ident filter diff merge) - - local only_attributes=1 - for (( i = 2; i < $#words; i++ )); do - if (( attributes[(I)$words[i]] == 0 )); then - only_attributes=0 - break - fi - done - - if (( !only_attributes )) || [[ -n ${opt_args[(I)--]} ]]; then - __git_cached_files && ret=0 - else - _alternative \ - 'attributes::__git_attributes' \ - 'files::__git_cached_files' && ret=0 - fi - ;; + attributes) + local -a attributes plain dedup + attributes=( + crlf:"line-ending convention (deprecated)" + text:"line-ending normalization" + eol:"line-ending style" + working-tree-encoding:"text encoding in working directory" + ident:'$Id$ substitution' + filter:"filters" + diff:"textual diff" + merge:"merging strategy" + conflict-marker-size:"length of markers left in the work tree" + whitespace:"control over what diff and apply should consider whitespace errors" + export-ignore:"exclude from archive files" + export-subst:"expand placeholders when adding to an archive" + delta:"don't attempt compression of blobs" + encoding:"character encoding that should be used by GUI tools" + ) + plain=( ${attributes%%:*} ) + dedup=( "${(@)words[1,CURRENT-1]}" ) + (( ! ${#dedup:|plain} )) && _describe -t git-attributes \ + attribute attributes -F dedup && ret=0 + ;; esac return ret @@ -6584,20 +6589,6 @@ __git_compression_levels () { '9:maximum compression' } -(( $+functions[__git_attributes] )) || -__git_attributes () { - local -a attributes - - attributes=( - 'crlf:line-ending convention' - 'ident:ident substitution' - 'filter:filters' - 'diff:textual diff' - 'merge:merging strategy') - - _describe -t attributes attribute attributes $* -} - (( $+functions[__git_daemon_service] )) || __git_daemon_service () { local -a services -- cgit v1.2.3 From 6763f45e77b130fdcecd244440552095b5ee23b5 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 22 Mar 2023 10:24:11 +0000 Subject: 58586: print "%s" with invalid multibyte character Treat each byte that is invalid or part of an incopmlete set as a single byte. --- ChangeLog | 6 ++++++ Src/builtin.c | 27 ++++++++++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec32f1029..c575a0b3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-03-22 Peter Stephenson + + * 51586: Src/builtin.c: When printf "%s" encounters a byte + that's not part of a vaild multibyte character it should handle + it a single byte at a time. + 2023-03-16 Oliver Kiddle * 51583: Completion/Unix/Command/_git: update completion of diff --git a/Src/builtin.c b/Src/builtin.c index f38a54936..e4f356803 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5329,20 +5329,21 @@ bin_print(char *name, char **args, Options ops, int func) #ifdef MULTIBYTE_SUPPORT if (isset(MULTIBYTE)) { chars = mbrlen(ptr, lleft, &mbs); - if (chars < 0) { - /* - * Invalid/incomplete character at this - * point. Assume all the rest are a - * single byte. That's about the best we - * can do. - */ - lchars += lleft; - lbytes = (ptr - b) + lleft; - break; - } else if (chars == 0) { - /* NUL, handle as real character */ + /* + * chars <= 0 means one of + * + * 0: NUL, handle as real character + * + * -1: MB_INVALID: Assume this is + * a single character as we do + * elsewhere in the code. + * + * -2: MB_INCOMPLETE: We're not waiting + * for input on this occasion, so + * just treat this as invalid. + */ + if (chars <= 0) chars = 1; - } } else /* use the non-multibyte code below */ #endif -- cgit v1.2.3 From 324d0e7cc710fd0dd8e3a50ccc0a4ba57ec6cb7a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 27 Mar 2023 21:11:34 +0200 Subject: 51603: complete dates and times in the form that git accepts --- ChangeLog | 7 ++- Completion/Unix/Command/_git | 101 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 88 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index c575a0b3c..a2fba2ff9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,12 @@ +2023-03-27 Oliver Kiddle + + * 51603: Completion/Unix/Command/_git: complete dates and times + in the form that git accepts + 2023-03-22 Peter Stephenson * 51586: Src/builtin.c: When printf "%s" encounters a byte - that's not part of a vaild multibyte character it should handle + that's not part of a valid multibyte character it should handle it a single byte at a time. 2023-03-16 Oliver Kiddle diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 1c3a95031..1d4fe20c9 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -996,7 +996,7 @@ _git-gc () { _arguments -S -s $endopt \ '--aggressive[more aggressively optimize]' \ '--auto[check whether housekeeping is required]' \ - '( --no-prune)--prune=-[prune loose objects older than given date]::date [2 weeks ago]:__git_datetimes' \ + '( --no-prune)--prune=-[prune loose objects older than given date]::date [2 weeks ago]:_git_approxidates' \ '(--prune )--no-prune[do not prune any loose objects]' \ '(-q --quiet)'{-q,--quiet}'[suppress progress reporting]' \ '--keep-largest-pack[repack all other packs except the largest pack]' \ @@ -2371,10 +2371,14 @@ _git-worktree() { _arguments -S $endopt \ '(-n --dry-run)'{-n,--dry-run}"[don't remove, show only]" \ '(-v --verbose)'{-v,--verbose}'[report pruned objects]' \ - '--expire=[expire objects older than specified time]:time' && ret=0 + '--expire=[expire objects older than specified time]: :_git_approxidates' && ret=0 ;; (list) - _arguments -S $endopt '--porcelain[machine-readable output]' && ret=0 + _arguments -S $endopt \ + '(-v --verbose --porcelain -z)'{-v,--verbose}'[output additional information about worktrees]' \ + "--expire=[add 'prunable' annotation to worktrees older than specified time]: :_git_approxidates" \ + '(-v)--porcelain[machine-readable output]' \ + '(-v)-z[terminate each line with a NUL rather than a newline]' && ret=0 ;; (lock) _arguments -C -S $endopt '--reason=[specify reason for locking]:reason' ': :->worktrees' && ret=0 @@ -3851,7 +3855,7 @@ _git-prune () { '(-n --dry-run)'{-n,--dry-run}'[do not remove anything; just report what would be removed]' \ '(-v --verbose)'{-v,--verbose}'[report all removed objects]' \ '--progress[show progress]' \ - '--expire=[only expire loose objects older than specified date]: :__git_datetimes' \ + '--expire=[only expire loose objects older than specified date]: :_git_approxidates' \ '--exclude-promisor-objects[limit traversal to objects outside promisor packfiles]' \ '*:: :__git_heads' } @@ -3899,8 +3903,8 @@ _git-reflog () { _arguments -S \ '(-n --dry-run)'{-n,--dry-run}"[don't actually prune any entries; show what would be pruned]" \ '--stale-fix[prune any reflog entries that point to "broken commits"]' \ - '--expire=-[prune entries older than given time]: :__git_datetimes' \ - '--expire-unreachable=-[prune entries older than given time and unreachable]: :__git_datetimes' \ + '--expire=-[prune entries older than given time]:age [90 days]:_git_approxidates' \ + '--expire-unreachable=-[prune entries older than given time and unreachable]:age [30 days]:_git_approxidates' \ '--all[prune all refs]' \ '--updateref[update ref with SHA-1 of top reflog entry after expiring or deleting]' \ '--rewrite[adjust reflog entries to ensure old SHA-1 points to new SHA-1 of previous entry after expiring or deleting]' \ @@ -4046,8 +4050,10 @@ _git-repack () { _arguments -s \ '(-A --unpack-unreachable)-a[pack all objects into a single pack]' \ '(-a -k --keep-unreachable)-A[pack all objects into a single pack, but unreachable objects become loose]' \ + '--cruft[pack unreachable cruft objects separately]' \ + '--cruft-expiration=[expire cruft objects older than specified time]: :_git_approxidates' \ '-d[remove redundant packs after packing]' \ - "--unpack-unreachable=[with -A, don't loosen objects older than specified date]:date" \ + "--unpack-unreachable=[with -A, don't loosen objects older than specified date]: :_git_approxidates" \ '-f[pass --no-reuse-delta option to git pack-objects]' \ '-F[pass --no-reuse-object option to git pack-objects]' \ "-n[don't update server information]" \ @@ -4055,7 +4061,7 @@ _git-repack () { '(-l --local)'{-l,--local}'[pass --local option to git pack-objects]' \ '(-b --write-bitmap-index)'{-b,--write-bitmap-index}'[write a bitmap index]' \ '(-i --delta-islands)'{-i,--delta-islands}'[pass --delta-islands to git-pack-objects]' \ - "--unpack-unreachable=[with -A, don't loosen objects older than specified time]:time" \ + "--unpack-unreachable=[with -A, don't loosen objects older than specified time]: :_git_approxidates" \ '(-k --keep-unreachable)'{-k,--keep-unreachable}'[with -a, repack unreachable objects]' \ '--window=[number of objects to consider when doing delta compression]:number of objects' \ '--window-memory=[scale window size dynamically to not use more than specified amount of memory]: : __git_guard_bytes' \ @@ -4358,8 +4364,8 @@ _git-rev-parse () { '--is-inside-work-tree[show whether or not current working directory is inside work tree]' \ '--is-bare-repository[show whether or not repository is bare]' \ '(--revs-only --no-revs --flags --no-flags --verify)--short=-[show only shorter unique name]:: :__git_guard_number length' \ - '(--since --after)'{--since=-,--after=-}'[show --max-age= parameter corresponding given date string]:datestring' \ - '(--until --before)'{--until=-,--before=-}'[show --min-age= parameter corresponding given date string]:datestring' \ + '(--since --after)'{--since=-,--after=-}'[show --max-age= parameter corresponding given date string]: :_git_approxidates' \ + '(--until --before)'{--until=-,--before=-}'[show --min-age= parameter corresponding given date string]: :_git_approxidates' \ '--resolve-git-dir[check if is a valid repository or gitfile and print location]:git dir:_files -/' \ '*: :__git_objects' && ret=0 fi @@ -4399,7 +4405,7 @@ _git-show-branch () { if compset -P '[[:digit:]]##,'; then _alternative \ 'counts: :__git_guard_number count' \ - 'dates::__git_datetimes' && ret=0 + 'dates::_git_approxidates' && ret=0 else __git_guard_number limit fi @@ -4961,7 +4967,7 @@ _git-commit-graph() { '(--reachable --stdin-packs)--stdin-commits[walk commits starting at commits read from input]' '(--append)--size-multiple=:commits [2]' '(--append)--max-commits=:commits' - '(--append)--expire-time=:date/time:__git_datetimes' + '(--append)--expire-time=: :_git_approxidates' '--max-new-filters=[specify maximum number of changed-path bloom filters to compute]:' ) elif [[ $words[2] = verify ]]; then @@ -5130,7 +5136,9 @@ _git-pack-objects () { '--include-tag[include unasked-for annotated tags if object they reference is included]' \ '(--revs --stdin-packs --unpack-unreachable)--keep-unreachable[add objects unreachable from refs in packs named with --unpacked to resulting pack]' \ '(--revs --stdin-packs)--pack-loose-unreachable[pack unreachable loose objects]' \ - '(--revs --stdin-packs --keep-unreachable)--unpack-unreachable=-[keep unreachable objects in loose form]::time' \ + '(--revs --stdin-packs --keep-unreachable)--unpack-unreachable=-[keep unreachable objects in loose form]:: :_git_approxidates' \ + '--cruft[create a cruft pack]' \ + '--cruft-expiration=[expire cruft objects older than specified time]: :_git_approxidates' \ '--sparse[use sparse reachability algorithm]' \ '--include-tag[include tag objects that refer to objects to be packed]' \ $thin_opt \ @@ -7626,10 +7634,65 @@ __git_guard_bytes () { _numbers -u bytes ${*:-size} k m g } -(( $+functions[__git_datetimes] )) || -__git_datetimes () { - # TODO: Use this in more places. - _guard '*' 'time specification' +(( $+functions[_git_approxidates] )) || +_git_approxidates() { + local MATCH MBEGIN MEND + local match mbegin mend + local -i date time num + local -a months=( January February March April May June July August September + October November December ) + local -a weekdays=( Sunday Monday Tuesday Wednesday Thursday Friday Saturday ) + local -a numbers=( zero one two three four five six seven eight nine ten ) + local -a periods=( second minute hour day week month year ) + local -a suf=( -S. -r "._,+\\ \t\n\-" ) + + local -a pexpl + zparseopts -D -E X+:=pexpl + + local -a query=( + \( /$'*\0[ \t\n]#'/ \) + \( '/[]/' ':dates:date:compadd "${pexpl[@]:/-X/-x}"' + \| '/(@|[0-9](#c9))/' ':specials:special:compadd -S "" @' '/[]/' ': _message -e epochtimes "seconds since Unix epoch"' + \| '/(#i)(now|never)/' '%?%' ':specials:special:(now never)' '/[]/' + \| \) + \( + \( '/(#i)(one|last)/' '%[ ._,+]%' -'num=1' + \| '/[0-9](#c2,4)(-|/|.|)[0-9](#c1,2)(-|/|.|)[0-9](#c1,4)(|T)/' -'date=3' + \| '/[0-9](#c2)(:|)[0-9](#c2)(:|)[0-9](#c2)(.<->|)/' -'time=1' + \| '/20/' -'((!date))' '/[]/' ':dates:date:_dates -f "%y-%m-%d"' + \| '/1/' -'num=1' + \| '/<->/' -'num=2' + \| "/(#i)(${(j.|.)numbers})/" '%[ ._,+]%' -'num=2' + \| "/(#i)(${(j.|.)${(@)months//(#b)(???)(*)/$match[1]${match[2]//(#m)?/(|$MATCH}${match[2]//?/)}}})/" + '%[ ._,+]%' -'(( num = 0, date |= 2 ))' + \| "/(#i)(${(j.|.)${(@)weekdays//(#b)(???)(*)/$match[1]${match[2]//(#m)?/(|$MATCH}${match[2]//?/)}}})(|s)/" + '%[ ._,+]%' -'(( num = 0, date |= 1 ))' + \| '/(#i)yesterday/' '%[ ._,+]%' -'date=3' + \| "/(#i)(${(j.|.)${(@)periods%s}})(|s)/" '%[ ._,+]%' -'num=0' + \| '/(#i)(noon|midnight|tea|[ap]m)/' '%[ ._,+]%' -'time=1' + \| + \( // -'(( !(date&2) ))' // ':months:month:compadd -o nosort $suf -a months' \| \) + \( // -'(( num <= 1 && !(date&1) ))' // ':weekdays:weekday:compadd $suf -o nosort -a weekdays' \| \) + \( // -'(( num > 1 ))' + \( // -'(( date < 3 ))' // ':periods:period:compadd $suf -o nosort ${^periods[4,-1]}s' \| \) + \( // -'(( !(date&1) ))' // ':weekdays:weekday:compadd $suf -o nosort ${^weekdays}s' \| \) + \( // -'(( !time ))' // ':periods:period:compadd $suf -o nosort ${^periods[1,3]}s' \| \) + \| // -'(( num == 1 ))' + \( // -'(( date < 3 ))' // ':periods:period:compadd $suf -o nosort -a "periods[4,-1]"' \| \) + \( // -'(( !time ))' // ':periods:period:compadd $suf -o nosort -a "periods[1,3]"' \| \) + \| // -'(( num == 0 ))' + \( // -'(( !time ))' // ':specials:special:compadd $suf noon midnight tea AM PM' \| \) + \( // -'(( !date ))' // ':specials:special:compadd $suf yesterday' \| \) + // ':specials:special:compadd $suf last' # "last" is equivalent to "one" + // ':numbers:number:compadd $suf -n -o nosort -a numbers' + \) + '/[]/' + \) '/([ ._,+]|)/' + \) \# + ) + + _regex_arguments _git_dates "$query[@]" + _git_dates } (( $+functions[__git_stages] )) || @@ -7923,8 +7986,8 @@ __git_setup_revision_options () { '--count[display how many commits would have been listed]' '(-n --max-count)'{-n+,--max-count=}'[maximum number of commits to display]: :__git_guard_number' '--skip=[skip given number of commits before output]: :__git_guard_number' - '(--max-age --since --after)'{--since=,--after=}'[show commits more recent than given date]:date' - '(--min-age --until --before)'{--until=,--before=}'[show commits older than given date]: :__git_guard_number timestamp' + '(--max-age --since --after)'{--since=,--after=}'[show commits more recent than given date]: :_git_approxidates' + '(--min-age --until --before)'{--until=,--before=}'[show commits older than given date]: :_git_approxidates' '( --since --after)--max-age=-[maximum age of commits to output]: :__git_guard_number timestamp' '( --until --before)--min-age[minimum age of commits to output]: :__git_guard_number timestamp' '*--author=[limit commits to those by given author]:author' -- cgit v1.2.3 From 121810dba601a047f0a8b97fa1515b0704b21e06 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Mon, 20 Mar 2023 11:16:36 +0900 Subject: 51589: Update nm options - Update Binutils nm 2.40.0 - Update elftoolchain nm 0.7.1 --- ChangeLog | 3 +++ Completion/Unix/Command/_nm | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2fba2ff9..60642526b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-03-27 Oliver Kiddle + * Shohei YOSHIDA: 51589: Completion/Unix/Command/_nm: + Update nm options + * 51603: Completion/Unix/Command/_git: complete dates and times in the form that git accepts diff --git a/Completion/Unix/Command/_nm b/Completion/Unix/Command/_nm index 888f1ef87..b142c1d54 100644 --- a/Completion/Unix/Command/_nm +++ b/Completion/Unix/Command/_nm @@ -17,7 +17,6 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu '(- *)'{-V,--version}'[display version information]' '(-f --format -P --portability)-B[same as --format=bsd]' '(-u --undefined-only)--defined-only[display only defined symbols]' - '(-f --format -P)--format=[specify output format]:format:(bsd sysv posix)' '(-n --numeric-sort -p --no-sort --size-sort -v)'{-n,--numeric-sort}'[sort symbols numerically by address]' '(-p --no-sort -n -v --numeric-sort -r --reverse-sort --size-sort)'{-p,--no-sort}'[do not sort symbols]' '(-P --portability -B -f --format)'{-P,--portability}'[same as --format=posix]' @@ -41,7 +40,7 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu args=( ${args:#*(-C|-o|--portability)\[*} '(-C --demangle)'{-C,--demangle=-}'[decode symbol names]::style:(auto gnu-v2 gnu-v3 arm)' '(-g --extern-only)-e[only display global and static symbols]' - '(--format -P)-F+[specify output format]:format:(bsd sysv posix)' + '(-B --format -P)'{-F,--format}'[specify output format]:format:(bsd sysv posix)' '-o[with -P, same as -t o; otherwise same as -A]' '(-t --radix)-x[print values in hexadecimal]' ) @@ -51,7 +50,7 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu '--mark-special[mark special symbols]' '--color=[use color in output]:color:(always auto never)' '(-C)--demangle[decode symbol names]' - '(--format -P)-f+[specify output format]:format:(bsd sysv posix)' + '(-B -f --format -P --portability)'{-f,--format}'[specify output format]:format:(bsd sysv posix)' '(- *)--usage[give a short usage message]' '(- *)-?[display help information]' ) @@ -61,14 +60,19 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu args+=( '!(--no-recurse-limit)--recurse-limit' '--no-recurse-limit[disable demangling recursion limit]' - '(-f --format -P)-f+[specify output format]:format:(bsd sysv posix)' + '(-f --format -P -j)'{-f,--format}'[specify output format]:format:(bsd sysv posix just-symbols)' '(-C --no-demangle)--demangle=-[decode symbol names]::style [auto]:(auto gnu lucid arm hp edg gnu-v3 java gnat rust dlang)' '--ifunc-chars=[specify characters to use for indirect function symbols]:characters for global/local indirect function symbols [ii]' + '(-B -f --format -P --portability -j --just-symbols)'{-j,--just-symbols}'[Same as --format=just-symbols]' '--plugin[load specified plugin]:plugin' + '--quiet[suppress no "no symbols" diagnostic]' '--special-syms[include special symbols in the output]' '--synthetic[display synthetic symbols as well]' "--target=[target object format]:target:(${${(@M)${(f)$(_call_program targets nm --help)}:#*supported targets:*}##*: })" + '--unicode=[specify how to treat UTF-8 encoded unicode characters]:how_to_treat:(default show invalid hex escape highlight)' + '(-W --no-weak)'{-W,--no-weak}'[ignore weak symbols]' '--with-symbol-versions[display version strings after symbol names]' + '--without-symbol-versions[not display of symbol version information]' ) ;; esac -- cgit v1.2.3 From 6d40d9b63b41188cc846918e19bbf2982b9305b9 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 26 Mar 2023 10:26:25 +0200 Subject: 51602: Handle SIGIOT as an alias to SIGABRT if they are the same signal number --- ChangeLog | 5 +++++ Src/jobs.c | 5 +++++ Src/signames2.awk | 9 +++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 60642526b..9e8d45978 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-03-28 Mikael Magnusson + + * 51602: Src/jobs.c, Src/signames2.awk: Handle SIGIOT as an + alias to SIGABRT if they are the same signal number + 2023-03-27 Oliver Kiddle * Shohei YOSHIDA: 51589: Completion/Unix/Command/_nm: diff --git a/Src/jobs.c b/Src/jobs.c index 59ddd952e..15e2105eb 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -2646,6 +2646,11 @@ static const struct { { "IO", SIGIO }, #endif #endif +#if defined(SIGABRT) && defined(SIGIOT) +#if SIGABRT == SIGIOT + { "IOT", SIGIOT }, +#endif +#endif #if !defined(SIGERR) /* * If SIGERR is not defined by the operating system, use it diff --git a/Src/signames2.awk b/Src/signames2.awk index 4d15681d5..4d1557cd8 100644 --- a/Src/signames2.awk +++ b/Src/signames2.awk @@ -13,7 +13,8 @@ signam = substr(tmp[1], 4, 20) signum = tmp[2] if (signam == "CHLD" && sig[signum] == "CLD") sig[signum] = "" - if (signam == "POLL" && sig[signum] == "IO") sig[signum] = "" + if (signam == "POLL" && sig[signum] == "IO") sig[signum] = "" + if (signam == "ABRT" && sig[signum] == "IOT") sig[signum] = "" if (sig[signum] == "") { sig[signum] = signam if (0 + max < 0 + signum && signum < 60) @@ -33,9 +34,9 @@ if (signam == "IO") { msg[signum] = "i/o ready" } if (signam == "IOT") { msg[signum] = "IOT instruction" } if (signam == "KILL") { msg[signum] = "killed" } - if (signam == "LOST") { msg[signum] = "resource lost" } + if (signam == "LOST") { msg[signum] = "resource lost" } if (signam == "PIPE") { msg[signum] = "broken pipe" } - if (signam == "POLL") { msg[signum] = "pollable event occurred" } + if (signam == "POLL") { msg[signum] = "pollable event occurred" } if (signam == "PROF") { msg[signum] = "profile signal" } if (signam == "PWR") { msg[signum] = "power fail" } if (signam == "QUIT") { msg[signum] = "quit" } @@ -43,7 +44,7 @@ if (signam == "SYS") { msg[signum] = "invalid system call" } if (signam == "TERM") { msg[signum] = "terminated" } if (signam == "TRAP") { msg[signum] = "trace trap" } - if (signam == "URG") { msg[signum] = "urgent condition" } + if (signam == "URG") { msg[signum] = "urgent condition" } if (signam == "USR1") { msg[signum] = "user-defined signal 1" } if (signam == "USR2") { msg[signum] = "user-defined signal 2" } if (signam == "VTALRM") { msg[signum] = "virtual time alarm" } -- cgit v1.2.3 From 12e5db145b098a62ff11b88eea26f473ea2ecdcf Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 29 Mar 2023 10:52:05 +0100 Subject: 51608: Don't execute commands after "continue &&" Also ! continue || --- Src/exec.c | 4 ++-- Test/A01grammar.ztst | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Src/exec.c b/Src/exec.c index 3330bbce8..4328975b9 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1491,7 +1491,7 @@ execlist(Estate state, int dont_change_job, int exiting) * we find a sublist followed by ORNEXT. */ if ((ret = ((WC_SUBLIST_FLAGS(code) & WC_SUBLIST_SIMPLE) ? execsimple(state) : - execpline(state, code, Z_SYNC, 0)))) { + execpline(state, code, Z_SYNC, 0))) || breaks) { state->pc = next; code = *state->pc++; next = state->pc + WC_SUBLIST_SKIP(code); @@ -1524,7 +1524,7 @@ execlist(Estate state, int dont_change_job, int exiting) * we find a sublist followed by ANDNEXT. */ if (!(ret = ((WC_SUBLIST_FLAGS(code) & WC_SUBLIST_SIMPLE) ? execsimple(state) : - execpline(state, code, Z_SYNC, 0)))) { + execpline(state, code, Z_SYNC, 0))) || breaks) { state->pc = next; code = *state->pc++; next = state->pc + WC_SUBLIST_SKIP(code); diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst index b3aea1055..d57085798 100644 --- a/Test/A01grammar.ztst +++ b/Test/A01grammar.ztst @@ -982,3 +982,39 @@ F:its expectations. } fn 1:! does not affect return status of explicit return + + msg=unset + for x in 1 2 3 4 5; do + continue && msg=set && print Not executed + print Not executed, neither. + done + print $msg +0:continue causes immediate continuation +>unset + + msg=unset + () { + return && msg=set && print Not executed + print Not executed, not nor neither. + } + print $msg +0:return causes immediate return +>unset + + msg=unset + for x in 1 2 3 4 5; do + ! continue || msg=set && print Not executed + print Not executed, neither. + done + print $msg +0:! continue causes immediate continuation +>unset + + msg=unset + () { + ! return || msg=set && print Not executed + print Not executed, not nor neither. + } + print $msg +0:! return causes immediate return +>unset -- cgit v1.2.3 From c006d7609703afcfb2162c36d4f745125df45879 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 30 Mar 2023 14:58:07 +0900 Subject: 51604: %M in TIMEFMT should report in kilobytes --- ChangeLog | 5 +++++ Src/jobs.c | 14 +++++++------- configure.ac | 9 +++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e8d45978..526ae5265 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-03-30 Jun-ichi Takimoto + + * 51604: Src/jobs.c, configure.ac: %M in TIMEFMT should report + in kilobytes + 2023-03-28 Mikael Magnusson * 51602: Src/jobs.c, Src/signames2.awk: Handle SIGIOT as an diff --git a/Src/jobs.c b/Src/jobs.c index 15e2105eb..4d7172550 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -888,8 +888,13 @@ printtime(struct timeval *real, child_times_t *ti, char *desc) break; #endif #ifdef HAVE_STRUCT_RUSAGE_RU_MAXRSS +#ifdef RU_MAXRSS_IS_IN_BYTES +# define MAXRSS_IN_KB(x) ((x)/1024) +#else +# define MAXRSS_IN_KB(x) (x) +#endif case 'M': - fprintf(stderr, "%ld", ti->ru_maxrss / 1024); + fprintf(stderr, "%ld", MAXRSS_IN_KB(ti->ru_maxrss)); break; #endif #ifdef HAVE_STRUCT_RUSAGE_RU_MAJFLT @@ -1036,7 +1041,7 @@ should_report_time(Job j) #ifdef HAVE_GETRUSAGE if (reportmemory >= 0 && - j->procs->ti.ru_maxrss / 1024 > reportmemory) + MAXRSS_IN_KB(j->procs->ti.ru_maxrss) > reportmemory) return 1; #endif @@ -2646,11 +2651,6 @@ static const struct { { "IO", SIGIO }, #endif #endif -#if defined(SIGABRT) && defined(SIGIOT) -#if SIGABRT == SIGIOT - { "IOT", SIGIOT }, -#endif -#endif #if !defined(SIGERR) /* * If SIGERR is not defined by the operating system, use it diff --git a/configure.ac b/configure.ac index f340d2993..e6ced85d9 100644 --- a/configure.ac +++ b/configure.ac @@ -1965,6 +1965,15 @@ if test x$ac_cv_func_getrusage = xyes; then #endif #include ]) fi +dnl On some OSes (only macOS?) ru_maxrss is in bytes (not in kilobytes). +dnl Solaris uses pages as the unit, but ru_maxrss is set to zero anyway. +AH_TEMPLATE(RU_MAXRSS_IS_IN_BYTES, +[Define to 1 if ru_maxrss in struct rusage is in bytes.]) +case "$host_os" in + darwin*) + AC_DEFINE(RU_MAXRSS_IS_IN_BYTES) + ;; +esac dnl -------------------------------------------- -- cgit v1.2.3 From b411dc570217f337540c018f82797f248ec81754 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 3 Apr 2023 16:04:31 +0900 Subject: 51597: fix 'vared -c var' when var is unset --- ChangeLog | 4 ++++ Src/Zle/zle_utils.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 526ae5265..851c7e3ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-04-03 Jun-ichi Takimoto + + * 51597: Src/Zle/zle_utils.c: fix 'vared -c var' when var is unset + 2023-03-30 Jun-ichi Takimoto * 51604: Src/jobs.c, configure.ac: %M in TIMEFMT should report diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 454a877a9..51bb43339 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -512,12 +512,13 @@ stringaszleline(char *instr, int incs, int *outll, int *outsz, int *outcs) *outcs = outptr - outstr; *outll = outptr - outstr; } else { + *outstr = ZWC('\0'); *outll = 0; if (outcs) *outcs = 0; } #else - memcpy(outstr, instr, ll); + strcpy(outstr, instr); *outll = ll; if (outcs) *outcs = incs; -- cgit v1.2.3 From 98b4d4bdca15393d3cce9e072867ee6526de5d2e Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Sun, 9 Apr 2023 20:33:32 +0900 Subject: 51632: nmetafy $_ when exporting it to child --- ChangeLog | 4 ++++ Src/exec.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 851c7e3ce..1eebe2660 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-04-09 Jun-ichi Takimoto + + * 51632: Src/exec.c: unmetafy $_ when exporting it to child + 2023-04-03 Jun-ichi Takimoto * 51597: Src/Zle/zle_utils.c: fix 'vared -c var' when var is unset diff --git a/Src/exec.c b/Src/exec.c index 4328975b9..3b3d1235e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -519,7 +519,7 @@ zexecve(char *pth, char **argv, char **newenvp) if (*pth == '/') strcpy(buf + 2, pth); else - sprintf(buf + 2, "%s/%s", pwd, pth); + sprintf(buf + 2, "%s/%s", unmeta(pwd), pth); zputenv(buf); #ifndef FD_CLOEXEC closedumps(); -- cgit v1.2.3 From 8a9aea907ac4844e2ee7348c4fa6417ae9873991 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Sun, 9 Apr 2023 20:44:58 +0900 Subject: 51631: initialize $_ by copying it from environment --- ChangeLog | 3 +++ Doc/Zsh/params.yo | 5 ++++- Src/init.c | 9 ++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1eebe2660..32fd0780d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-04-09 Jun-ichi Takimoto + * 51631: Doc/Zsh/params.yo, Src/init.c: initialize $_ by copying + it from environment + * 51632: Src/exec.c: unmetafy $_ when exporting it to child 2023-04-03 Jun-ichi Takimoto diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 528c27f93..2db4210eb 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -779,7 +779,10 @@ last pipeline. ) vindex(_) item(tt(_) )( -The last argument of the previous command. +Initially, if tt(_) exists in the environment, then this parameter is set to +its value. This value may be the full pathname of the current zsh +executable or the script command file. +Later, this parameter is set to the last argument of the previous command. Also, this parameter is set in the environment of every command executed to the full pathname of the command. ) diff --git a/Src/init.c b/Src/init.c index 68621a0ad..7e98af44c 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1084,9 +1084,12 @@ setupvals(char *cmd, char *runscript, char *zsh_name) ztrdup(DEFAULT_IFS_SH) : ztrdup(DEFAULT_IFS); wordchars = ztrdup(DEFAULT_WORDCHARS); postedit = ztrdup(""); - zunderscore = (char *) zalloc(underscorelen = 32); - underscoreused = 1; - *zunderscore = '\0'; + /* If _ is set in environment then initialize our $_ by copying it */ + zunderscore = getenv("_"); + zunderscore = zunderscore ? metafy(zunderscore, -1, META_DUP) : ztrdup(""); + underscoreused = strlen(zunderscore) + 1; + underscorelen = (underscoreused + 31) & ~31; + zunderscore = (char *)zrealloc(zunderscore, underscorelen); zoptarg = ztrdup(""); zoptind = 1; -- cgit v1.2.3 From e5f8cc99f524db8db7c7fbe5957609db63869d0e Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 11 Apr 2023 21:43:15 +0900 Subject: 51639: new parameter ZSH_EXEPATH (full path of zsh executable) The full pathname is obatined by a reliable method on macOS and systems that support procfs. But on other systems (FreeBSD, OpenBSD, ...) it is guessed from argv[0], PWD and PATH. --- ChangeLog | 6 +++ Doc/Zsh/params.yo | 4 ++ Src/init.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 19 +++++++++ 4 files changed, 145 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 32fd0780d..b2c847da5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-04-11 Jun-ichi Takimoto + + * 51639: Doc/Zsh/params.yo, Src/init.c, configure.ac: add new + parameter ZSH_EXEPATH that is set to the full pathname of the + executable file of the current zsh + 2023-04-09 Jun-ichi Takimoto * 51631: Doc/Zsh/params.yo, Src/init.c: initialize $_ by copying diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 2db4210eb..57d10b8bd 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1112,6 +1112,10 @@ item(tt(ZSH_EXECUTION_STRING))( If the shell was started with the option tt(-c), this contains the argument passed to the option. Otherwise it is not set. ) +vindex(ZSH_EXEPATH) +item(tt(ZSH_EXEPATH))( +Full pathname of the executable file of the current zsh process. +) vindex(ZSH_NAME) item(tt(ZSH_NAME))( Expands to the basename of the command used to invoke this instance diff --git a/Src/init.c b/Src/init.c index 7e98af44c..ffb017e22 100644 --- a/Src/init.c +++ b/Src/init.c @@ -246,6 +246,9 @@ loop(int toplevel, int justonce) static int restricted; +/* original argv[0]. This is already metafied */ +static char *argv0; + /**/ static void parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr, @@ -257,7 +260,7 @@ parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr, if (**argv == '-') flags |= PARSEARGS_LOGIN; - argzero = posixzero = *argv++; + argv0 = argzero = posixzero = *argv++; SHIN = 0; /* @@ -893,6 +896,106 @@ init_term(void) return 1; } +/* + * Get (or guess) the absolute pathname of the current zsh exeutable. + * Try OS-specific method, and if it fails, guess the absolute pathname + * from argv0, pwd, and PATH. 'name' and 'cwd' are unmetefied versions of + * argv0 and pwd. + * Returns a zalloc()ed string (not metafied), or NULL if failed. + */ +#ifdef __APPLE__ +#include +#endif + +/**/ +static char * +getmypath(const char *name, const char *cwd) +{ + char *buf; + int namelen; + + if (!name) + return NULL; + if (*name == '-') + ++name; + if ((namelen = strlen(name)) == 0) + return NULL; +#if defined(__APPLE__) + { + uint32_t n = PATH_MAX; + int ret; + buf = (char *)zalloc(PATH_MAX); + if ((ret = _NSGetExecutablePath(buf, &n)) < 0) { + /* try again with increased buffer size */ + buf = (char *)zrealloc(buf, n); + ret = _NSGetExecutablePath(buf, &n); + } + if (ret == 0 && strlen(buf) > 0) + return buf; + else + free(buf); + } +#elif defined(PROC_SELF_EXE) + { + ssize_t n; + buf = (char *)zalloc(PATH_MAX); + n = readlink(PROC_SELF_EXE, buf, PATH_MAX); + if (n > 0 && n < PATH_MAX) { + buf[n] = '\0'; + return buf; + } + else + free(buf); + } +#endif + /* guess the absolute pathname of 'name' */ + if (name[namelen-1] == '/') /* name should not end with '/' */ + return NULL; + else if (name[0] == '/') { + /* name is already an absolute pathname */ + return ztrdup(name); + } + else if (strchr(name, '/')) { + /* relative path */ + if (!cwd) + return NULL; + buf = (char *)zalloc(strlen(cwd) + namelen + 2); + sprintf(buf, "%s/%s", cwd, name); + return buf; + } +#ifdef HAVE_REALPATH + else { + /* search each dir in PARH */ + const char *path, *sep; + char *real, *try; + int pathlen, dirlen; + + path = getenv("PATH"); + if (!path || (pathlen = strlen(path)) == 0) + return NULL; + /* for simplicity, allocate buf even if REALPATH_ACCEPTS_NULL is on */ + buf = (char *)zalloc(PATH_MAX); + try = (char *)zalloc(pathlen + namelen + 2); + do { + sep = strchr(path, ':'); + dirlen = sep ? sep - path : strlen(path); + strncpy(try, path, dirlen); + try[dirlen] = '/'; + try[dirlen+1] = '\0'; + strcat(try, name); + real = realpath(try, buf); + if (sep) + path = sep + 1; + } while (!real && sep); + free(try); + if (!real) + free(buf); + return real; /* this may be NULL */ + } +#endif + return NULL; +} + /* Initialize lots of global variables and hash tables */ /**/ @@ -1195,6 +1298,18 @@ setupvals(char *cmd, char *runscript, char *zsh_name) /* Colour sequences for outputting colours in prompts and zle */ set_default_colour_sequences(); + /* ZSH_EXEPATH */ + { + char *mypath, *exename, *cwd; + exename = unmetafy(ztrdup(argv0), NULL); + cwd = pwd ? unmetafy(ztrdup(pwd), NULL) : NULL; + mypath = getmypath(exename, cwd); + free(exename); + free(cwd); + if (mypath) { + setsparam("ZSH_EXEPATH", metafy(mypath, -1, META_REALLOC)); + } + } if (cmd) setsparam("ZSH_EXECUTION_STRING", ztrdup(cmd)); if (runscript) diff --git a/configure.ac b/configure.ac index e6ced85d9..d8a17791a 100644 --- a/configure.ac +++ b/configure.ac @@ -2011,6 +2011,25 @@ if test x$zsh_cv_sys_path_dev_fd != xno; then AC_DEFINE_UNQUOTED(PATH_DEV_FD, "$zsh_cv_sys_path_dev_fd") fi +dnl ---------------------------------------------------- +dnl CHECK FOR SYMLINK TO THE CURRENT EXECUTABLE IN /proc +dnl ---------------------------------------------------- +dnl Linux: /proc/self/exe +dnl NetBSD: /proc/curproc/exe (or /proc/self/exe, but not /proc/curproc/file) +dnl DragonFly: /proc/curproc/file +dnl Solaris: /proc/self/path/a.out +AH_TEMPLATE([PROC_SELF_EXE], +[Define to the path of the symlink to the current executable file.]) +AC_CACHE_CHECK(for symlink to the current executable in /proc, +zsh_cv_proc_self_exe, +[for zsh_cv_proc_self_exe in /proc/self/exe /proc/curproc/exe \ + /proc/curproc/file /proc/self/path/a.out no; do + test -L $zsh_cv_proc_self_exe && break +done]) +if test x$zsh_cv_proc_self_exe != xno; then + AC_DEFINE_UNQUOTED(PROC_SELF_EXE, "$zsh_cv_proc_self_exe") +fi + dnl --------------------------------- dnl CHECK FOR RFS SUPERROOT DIRECTORY dnl --------------------------------- -- cgit v1.2.3 From d6e69b72990f42549fbe8fc54dd7edd14bc66701 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 13 Apr 2023 11:18:43 +0100 Subject: Add missed ChangeLog entry for 12e5db14 --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index b2c847da5..904d207de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,11 @@ * 51604: Src/jobs.c, configure.ac: %M in TIMEFMT should report in kilobytes +2023-03-29 Peter Stephenson + + * 51608: Src/exec.c, Test/A01grammar.ztst: shouldn't be + executing commands after "continue &&" or "! continue ||". + 2023-03-28 Mikael Magnusson * 51602: Src/jobs.c, Src/signames2.awk: Handle SIGIOT as an -- cgit v1.2.3 From 8f5fe841a63fecdab4416578653549689f2c592f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 17 Apr 2023 09:30:34 +0100 Subject: 51652: fix running of TRAPEXIT explicitly. This is a special case where TRAPEXIT is unset within a TRAPEXIT as it should never run in a nested context, so just save the function structure temporarily on the heap. --- ChangeLog | 5 +++++ Src/exec.c | 34 +++++++++++++++++++++++++++++++++- Test/C03traps.ztst | 11 +++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 904d207de..981fdacd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-04-17 Peter Stephenson + + * 51652 (plus typo correction): Src/exec.c, Test/C03traps.ztst: + fix running of TRAPEXIT explicitly. + 2023-04-11 Jun-ichi Takimoto * 51639: Doc/Zsh/params.yo, Src/init.c, configure.ac: add new diff --git a/Src/exec.c b/Src/exec.c index 3b3d1235e..8f9d5a885 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5779,12 +5779,25 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) char *name = shfunc->node.nam; int flags = shfunc->node.flags; char *fname = dupstring(name); - Eprog prog; + Eprog prog, marked_prog; static int oflags; static int funcdepth; Heap funcheap; queue_signals(); /* Lots of memory and global state changes coming */ + /* + * In case this is a special function such as a trap, mark it + * as in use right now, so it doesn't get freed early. The + * worst that can happen is this hangs around in memory a little + * longer than strictly needed. + * + * Classic example of this happening is running TRAPEXIT directly. + * + * Because the shell function's contents may change, we'll ensure + * we use a consistent structure for use / free. + */ + marked_prog = shfunc->funcdef; + useeprog(marked_prog); NEWHEAPS(funcheap) { /* @@ -5818,6 +5831,22 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) memcpy(funcsave->pipestats, pipestats, bytes); } + if (!strcmp(fname, "TRAPEXIT")) { + /* + * If we are executing TRAPEXIT directly, starttrapscope() + * will pull the rug out from under us to ensure the + * exit trap isn't run inside the function. We just need + * the information locally here, so copy it on the heap. + * + * The funcdef is separately handled by reference counting. + */ + Shfunc shcopy = (Shfunc)zhalloc(sizeof(struct shfunc)); + memcpy(shcopy, shfunc, sizeof(struct shfunc)); + shcopy->node.nam = dupstring(shfunc->node.nam); + shfunc = shcopy; + name = shfunc->node.nam; + } + starttrapscope(); startpatternscope(); @@ -5942,6 +5971,8 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) funcsave->fstack.filename = getshfuncfile(shfunc); prog = shfunc->funcdef; + DPUTS1(!prog->nref, "function definition %s has zero reference count", + (fname && *fname) ? fname : ""); if (prog->flags & EF_RUN) { Shfunc shf; @@ -6046,6 +6077,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) } } OLDHEAPS; + freeeprog(marked_prog); unqueue_signals(); /* diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index e0b6afb5f..de57765a0 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -1083,6 +1083,17 @@ F:Must be tested with a top-level script rather than source or function >trap1 # As of 5.7.1-test-2, the output was "out1 fn1 trap1 fn2" (on separate lines). + TRAPEXIT() { echo This is TRAPEXIT; } + TRAPEXIT + TRAPEXIT + TRAPEXIT +0:No memory problems with explicit call to TRAPEXIT. +>This is TRAPEXIT +>This is TRAPEXIT +>This is TRAPEXIT +>This is TRAPEXIT +# Three explicit calls, one implicit call at function exit. + %clean rm -f TRAPEXIT -- cgit v1.2.3 From ba3631b4148dcd7c645354e28a8b4c7fdde9a2b7 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 18 Apr 2023 13:03:39 +0900 Subject: 51663: fix a typo in 51582 (_ssh) --- ChangeLog | 4 ++++ Completion/Unix/Command/_ssh | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 981fdacd3..01167b0c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-04-18 Jun-ichi Takimoto + + * 51663: Completion/Unix/Command/_ssh: fix a typo in 51582 + 2023-04-17 Peter Stephenson * 51652 (plus typo correction): Src/exec.c, Test/C03traps.ztst: diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index e9ca454b4..fd2a90b59 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -27,7 +27,7 @@ _ssh () { '-r[recursively copy directories (follows symbolic links)]' '-S+[specify ssh program]:path to ssh:_command_names -e' '-v[verbose mode]' - '*(-O)-X+[specify sftp protocol option]: : _values "sftp option" + '(-O)*-X+[specify sftp protocol option]: : _values "sftp option" "nrequests[set max concurrent SFTP read or write requests]\:requests [64]" "buffer[set max buffer size for a single SFTP read/write operation]\: \:_numbers -l 0 -m 256K -d 32K -u bytes -f size \:B\:bytes \:K\:kilobytes"' ) -- cgit v1.2.3 From 858b8de3d70fe76a3637c281bc2c8e3a6d961a2c Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 22 Apr 2023 14:40:23 -0700 Subject: 51670: prevent possible underflow in gettext() --- ChangeLog | 4 ++++ Src/text.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 01167b0c3..92a95ffaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-04-22 Bart Schaefer + + * 51670: Src/text.c: prevent possible underflow in gettext() + 2023-04-18 Jun-ichi Takimoto * 51663: Completion/Unix/Command/_ssh: fix a typo in 51582 diff --git a/Src/text.c b/Src/text.c index 56127c457..8b1bd96b6 100644 --- a/Src/text.c +++ b/Src/text.c @@ -335,7 +335,7 @@ getjobtext(Eprog prog, Wordcode c) tlim = tptr + JOBTEXTSIZE - 1; tjob = 1; gettext2(&s); - if (tptr[-1] == Meta) + if (tptr > jbuf && tptr[-1] == Meta) --tptr; *tptr = '\0'; freeeprog(prog); /* mark as unused */ -- cgit v1.2.3 From 7f2bdf55a3fc09f7615f84119c135458c3e75a74 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 8 May 2023 12:53:37 +0900 Subject: 51692: not skip tests for [[ -r/-N file ]] on Cygwin --- ChangeLog | 5 +++++ Test/C02cond.ztst | 8 +------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92a95ffaa..e7e84a04b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-05-08 Jun-ichi Takimoto + + * 51692: Test/C02cond.ztst: do not skip tests for [[ -r file ]] + and [[ -N file ]] on Cygwin + 2023-04-22 Bart Schaefer * 51670: Src/text.c: prevent possible underflow in gettext() diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 4366b4142..daea5b4f8 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -111,10 +111,6 @@ if (( EUID == 0 )); then print -u$ZTST_fd 'Warning: Not testing [[ ! -r file ]] (root reads anything)' [[ -r zerolength && -r unmodish ]] - elif [[ $OSTYPE = cygwin ]]; then - print -u$ZTST_fd 'Warning: Not testing [[ ! -r file ]] - (all files created by user may be readable)' - [[ -r zerolength ]] else [[ -r zerolength && ! -r unmodish ]] fi @@ -148,9 +144,7 @@ print -ru $ZTST_fd 'This test may take two seconds...' touch $newnewnew - if [[ $OSTYPE == "cygwin" ]]; then - ZTST_skip="[[ -N file ]] not supported on Cygwin" - elif (( isnfs )); then + if (( isnfs )); then ZTST_skip="[[ -N file ]] not supported with NFS" elif ! zmodload -F zsh/stat b:zstat 2> /dev/null; then ZTST_skip='[[ -N file ]] not tested; zsh/stat not available' -- cgit v1.2.3 From b2421219836d571b4f0ffa9568740922fa7005b8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 10 May 2023 21:17:51 -0700 Subject: 51593: improve search for command name after skipping prefix assignments This is aimed mostly at use of run-help as a standalone function rather than as a widget. When run-help is invoked outside widget context, there's no source line to search for the original command name, so this attempts searching the arguments. --- ChangeLog | 5 +++++ Functions/Misc/run-help | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7e84a04b..956cb7eeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-05-10 Bart Schaefer + + * 51593: Functions/Misc/run-help: improve search for original + command name after skipping prefix assignments + 2023-05-08 Jun-ichi Takimoto * 51692: Test/C02cond.ztst: do not skip tests for [[ -r file ]] diff --git a/Functions/Misc/run-help b/Functions/Misc/run-help index 14d09bd65..462044b72 100644 --- a/Functions/Misc/run-help +++ b/Functions/Misc/run-help @@ -58,11 +58,11 @@ do case $what in (*( is an alias for (noglob|nocorrect))*) [[ ${what[(w)7]:t} != ${what[(w)1]} ]] && - run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)7]:t} + run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)7]:t} ${(z)${what[(w)8,-1]}} ;; (*( is an alias)*) [[ ${what[(w)6]:t} != ${what[(w)1]} ]] && - run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)6]:t} + run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)6]:t} ${(z)${what[(w)7,-1]}} ;; (*( is a * function)) case ${what[(w)1]} in @@ -103,7 +103,7 @@ do cmd_args=( ${(z)${cmd_args:-"$*"}} ) # Discard the command itself & everything before it. - shift $cmd_args[(i)${run_help_orig_cmd:-$1}] cmd_args || + shift $cmd_args[(i)(${run_help_orig_cmd}|$1)] cmd_args 2>/dev/null || continue # Discard options, parameter assignments & paths. -- cgit v1.2.3 From ace2822019b44cc1b67015215bba3b336fe27228 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Thu, 11 May 2023 11:44:38 -0700 Subject: 51331: update _pydoc for version 3.11 --- ChangeLog | 5 +++++ Completion/Unix/Command/_pydoc | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 956cb7eeb..28e4010f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-05-11 Bart Schaefer + + * Shohei YOSHIDA: 51331: Completion/Unix/Command/_pydoc: update + for version 3.11 + 2023-05-10 Bart Schaefer * 51593: Functions/Misc/run-help: improve search for original diff --git a/Completion/Unix/Command/_pydoc b/Completion/Unix/Command/_pydoc index 677c96ad6..626c528cd 100644 --- a/Completion/Unix/Command/_pydoc +++ b/Completion/Unix/Command/_pydoc @@ -6,13 +6,14 @@ local -a args args=( '(- *)-k[search keyword]:keyword' - '(-k -g -w *)-p[start web server on specified port]:port number' + '(-k -g -w)-p[start web server on specified port]:port number' '(-)-w[write out HTML in current directory]' '(-)*: :->lookup' ) if _pick_variant pydoc3='pydoc3 -b' pydoc2 -h; then - args+=( '(-k -w *)-b[start server and open browser]' ) + args+=( '(-k -w)-b[start server and open browser]' ) + args+=( '(-k -w)-n[start web server with the given hostname]:hostname' ) else args+=( '(- *)-g[start gui]' ) fi -- cgit v1.2.3 From 8bee6e6f92bf649bb1c1b9b4c3c981bb5e469466 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Thu, 11 May 2023 11:48:32 -0700 Subject: 51340: update _rake for version 13 --- ChangeLog | 3 +++ Completion/Unix/Command/_rake | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 28e4010f2..36a934683 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-11 Bart Schaefer + * Shohei YOSHIDA: 51340: Completion/Unix/Command/_rake: update + for version 13 + * Shohei YOSHIDA: 51331: Completion/Unix/Command/_pydoc: update for version 3.11 diff --git a/Completion/Unix/Command/_rake b/Completion/Unix/Command/_rake index 10d621991..49b49c014 100644 --- a/Completion/Unix/Command/_rake +++ b/Completion/Unix/Command/_rake @@ -1,12 +1,11 @@ #compdef rake -# rake, version 0.8.3 +# rake, version 13.0.6 local curcontext="$curcontext" state line expl ret=1 typeset -A opt_args _arguments -C -s -S \ - '(--classic-namespace -C)'{--classic-namespace,-C}'[put Task and FileTask in the top level namespace]' \ '(--dry-run -n)'{--dry-run,-n}'[do a dry run without executing actions]' \ '(- *)'{--describe,-D}'[describe the tasks (matching the specified pattern), then exit]:pattern::' \ '(--execute -e)'{--execute,-e}'[execute some Ruby code and exit]:Ruby code:' \ @@ -15,7 +14,7 @@ _arguments -C -s -S \ '(- *)'{--help,-h,-H}'[display help information]' \ \*{--libdir,-I}'[include specified directory in the search path for required modules]:library directory:_files -/' \ '(--rakelibdir --rakelib -R)'{--rakelibdir,--rakelib,-R}'[auto-import any .rake files in the specified directory. (default is 'rakelib')]:rake library directory:_files -/' \ - '(--nosearch -N)'{--nosearch,-N}'[do not search parent directories for the Rakefile]' \ + '(--nosearch --no-search -N)'{--nosearch,--no-search,-N}'[do not search parent directories for the Rakefile]' \ '(- *)'{--prereqs,-P}'[display the tasks and prerequisites, then exit]' \ '(--quiet -q --silent -s --verbose -v)'{--quiet,-q}'[do not log messages to standard output]' \ '(--rakefile -f)'{--rakefile,-f}'[use specified file as the rakefile]:rake file:_files' \ @@ -27,6 +26,18 @@ _arguments -C -s -S \ '(--trace -t)'{--trace,-t}'[turn on invoke/execute tracing, enable full backtrace]' \ '(--quiet -q --silent -s --verbose -v)'{--verbose,-v}'[log message to standard output (default)]' \ '(- *)'{--version,-V}'[display version information]' \ + '--backtrace=-[enable full backtrace]::out:(stderr stdout)' \ + '--comments[show commented tasks only]' \ + '--job-stats[display job statistics]:level' \ + '--suppress-backtrace[suppress backtrace lines matching regexp PATTERN]:pattern' \ + '(-A -a)'{-A,--all}'[show all tasks]' \ + '(-B --build-all)'{-B,--build-all}'[build all prerequisites, including those which are up-to-date]' \ + '(-C --directory)'{-C,--directory}'[change to DIRECTORY before doing anything]:dir:_files -/' \ + '(-G --no-system --nosystem)'{-G,--no-system,--nosystem}'[use standard project Rakefile search paths, ignore system wide rakefiles]' \ + '(-j --jobs)'{-j,--jobs}'[specifies the maximum number of tasks to execute in parallel]::tasks' \ + '(-m --multitask)'{-m,--multitask}'[treat all tasks as multitasks]' \ + '(- *)'{-W,--where}'[describe the tasks(matching optional PATTERN) then exit]::pattern' \ + '(-X --no-deprecation-warnings)'{-X,--no-deprecation-warnings}'[disable the deprecation warnings]' \ '*:target:->target' && ret=0 case "$state" in -- cgit v1.2.3 From f376f95c47202fb1c00f41577347e25ed5d37439 Mon Sep 17 00:00:00 2001 From: Jim Date: Thu, 11 May 2023 12:32:49 -0700 Subject: 51609: fix reference to select(2) --- ChangeLog | 3 +++ Doc/Zsh/mod_zselect.yo | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 36a934683..d91ca40b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-11 Bart Schaefer + * Jim : 51609: Doc/Zsh/mod_zselect.yo: + fix reference to select(2) + * Shohei YOSHIDA: 51340: Completion/Unix/Command/_rake: update for version 13 diff --git a/Doc/Zsh/mod_zselect.yo b/Doc/Zsh/mod_zselect.yo index faf59c165..42287f116 100644 --- a/Doc/Zsh/mod_zselect.yo +++ b/Doc/Zsh/mod_zselect.yo @@ -13,7 +13,7 @@ blocks until a file descriptor is ready for reading or writing, or has an error condition, with an optional timeout. If this is not available on your system, the command prints an error message and returns status 2 (normal errors return status 1). For more information, see your system's -documentation for manref(select)(3). Note there is no connection with the +documentation for manref(select)(2). Note there is no connection with the shell builtin of the same name. Arguments and options may be intermingled in any order. Non-option -- cgit v1.2.3 From 8943b5e4505faec8d02e8535417491a87fc74d4e Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 11 May 2023 12:37:52 -0700 Subject: users/29070: clean up tokens in cmdstr before compctl completion --- ChangeLog | 3 +++ Src/Zle/zle_tricky.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index d91ca40b6..130a37b8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-11 Bart Schaefer + * users/29070: Src/Zle/zle_tricky.c: clean up tokens in cmdstr + before attempting completion (compctl only) + * Jim : 51609: Doc/Zsh/mod_zselect.yo: fix reference to select(2) diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 690cf6efb..6ceb5d87f 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -1315,6 +1315,8 @@ get_comp_string(void) ins = (tok == REPEAT ? 2 : (tok != STRING && tok != TYPESET)); zsfree(cmdstr); cmdstr = ztrdup(tokstr); + untokenize(cmdstr); + remnulargs(cmdstr); cmdtok = tok; /* * If everything before is a redirection, or anything -- cgit v1.2.3 From 51d5ddb02bef3162251df151bf114215614028fe Mon Sep 17 00:00:00 2001 From: Vidhan Bhatt Date: Fri, 10 Mar 2023 01:00:56 -0500 Subject: github #98: feat: add `shortcuts` completions --- ChangeLog | 5 ++ Completion/Darwin/Command/_shortcuts | 88 ++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 Completion/Darwin/Command/_shortcuts diff --git a/ChangeLog b/ChangeLog index 130a37b8e..0d50432a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-05-13 Oliver Kiddle + + * github #98: Vidhan Bhatt: Completion/Darwin/Command/_shortcuts: + feat: add `shortcuts` completions + 2023-05-11 Bart Schaefer * users/29070: Src/Zle/zle_tricky.c: clean up tokens in cmdstr diff --git a/Completion/Darwin/Command/_shortcuts b/Completion/Darwin/Command/_shortcuts new file mode 100644 index 000000000..5e15f0a07 --- /dev/null +++ b/Completion/Darwin/Command/_shortcuts @@ -0,0 +1,88 @@ +#compdef shortcuts + +_shortcuts() { + local curcontext="$curcontext" + local -a line state + + _arguments -C \ + "1: :->subcommand" \ + "*:: :->args" + + case $state in + subcommand) + _values "subcommand" \ + "run[run a shortcut]" \ + "list[list your shortcuts]" \ + "view[view a shortcut in shortcuts]" \ + "sign[sign a shortcut file]" \ + "help[show subcommand help information]" + ;; + args) + case ${line[1]} in + run) + _shortcuts-run + ;; + list) + _shortcuts-list + ;; + view) + _shortcuts-view + ;; + sign) + _shortcuts-sign + ;; + help) + _shortcuts-help + ;; + esac + ;; + esac +} + +_shortcuts-run() { + _arguments \ + ":shortcut name or identifier:$(_shortcut_options)" \ + {-i,--input-path}'[specify input to provide to the shortcut]:input path:_files' \ + {-o,--output-path}'[specify where to write the shortcut output, if applicable]:output path:_files' \ + '--output-type[specify type to output data in]:output type (Universal Type Identifier format)' \ + {-h,--help}'[show help information]' +} + +_shortcuts-list() { + _arguments \ + {-f,--folder-name}"[specify folder name or identifier to list shortcuts in, or \"none\" to list shortcuts not in a folder]:folder name:$(_shortcut_folder_options)" \ + '--folders[list folders instead of shortcuts]' \ + '--show-identifiers[show identifiers with each result]' \ + {-h,--help}'[show help information]' +} + +_shortcuts-view() { + _arguments \ + ":shortcut name:$(_shortcut_options)" \ + {-h,--help}'[show help information]' +} + +_shortcuts-sign() { + _arguments \ + {-m,--mode}'[specify signing mode]:mode [people-who-know-me]:(anyone people-who-know-me)' \ + {-i,--input}'[specify shortcut file to sign]:input:_files -g "*.shortcut(-.)"' \ + {-o,--output}'[specify output path for the signed shortcut file]:output:_files -g "*.shortcut(-.)"' \ + {-h,--help}'[show help information]' +} + +_shortcuts-help() { + _arguments \ + ":subcommand:(run list view sign help)" +} + +# utilities + +_shortcut_options() { + echo "($(shortcuts list | sed 's/ /\\ /g'))" +} + +_shortcut_folder_options() { + echo "($(shortcuts list --folders | sed 's/ /\\ /g') none)" +} + +_shortcuts "$@" -- cgit v1.2.3 From 9b9f3adde89e18945cf4e9029c500615d5092d87 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Wed, 7 Sep 2022 15:46:12 -0500 Subject: 50612: vcs_info: fix typo --- ChangeLog | 2 ++ Misc/vcs_info-examples | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0d50432a2..f5c77f801 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-05-13 Oliver Kiddle + * Felipe Contreras: 50612: Misc/vcs_info-examples: fix typo + * github #98: Vidhan Bhatt: Completion/Darwin/Command/_shortcuts: feat: add `shortcuts` completions diff --git a/Misc/vcs_info-examples b/Misc/vcs_info-examples index 94c47278d..ddd8dd9a8 100644 --- a/Misc/vcs_info-examples +++ b/Misc/vcs_info-examples @@ -343,7 +343,7 @@ function +vi-gen-applied-string() { # Allow substitutions and expansions in the prompt, necessary for -# using a single-quoted $vcs_info_msg_0_ in PS1, RPOMPT (as used here) and +# using a single-quoted $vcs_info_msg_0_ in PS1, RPROMPT (as used here) and # similar. Other ways of using the information are described above. setopt promptsubst # Load vcs_info to display information about version control repositories. -- cgit v1.2.3 From b62e911341c8ec7446378b477c47da4256053dc0 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 13 May 2023 00:53:32 +0200 Subject: 51723: migrate pcre module to pcre2 --- ChangeLog | 3 + Src/Modules/pcre.c | 223 +++++++++++++++++++++-------------------------------- Test/V07pcre.ztst | 13 +++- configure.ac | 20 +++-- 4 files changed, 110 insertions(+), 149 deletions(-) diff --git a/ChangeLog b/ChangeLog index f5c77f801..285b73b2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-13 Oliver Kiddle + * 51723: Src/Modules/pcre.c, Test/V07pcre.ztst, configure.ac: + migrate pcre module to pcre2 + * Felipe Contreras: 50612: Misc/vcs_info-examples: fix typo * github #98: Vidhan Bhatt: Completion/Darwin/Command/_shortcuts: diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index 46875a59b..079ecc2c5 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -34,11 +34,11 @@ #define CPCRE_PLAIN 0 /**/ -#if defined(HAVE_PCRE_COMPILE) && defined(HAVE_PCRE_EXEC) -#include +#if defined(HAVE_PCRE2_COMPILE_8) && defined(HAVE_PCRE2_H) +#define PCRE2_CODE_UNIT_WIDTH 8 +#include -static pcre *pcre_pattern; -static pcre_extra *pcre_hints; +static pcre2_code *pcre_pattern; /**/ static int @@ -54,8 +54,8 @@ zpcre_utf8_enabled(void) return 0; if ((have_utf8_pcre == -1) && - (pcre_config(PCRE_CONFIG_UTF8, &have_utf8_pcre))) { - have_utf8_pcre = -2; /* erk, failed to ask */ + (pcre2_config(PCRE2_CONFIG_UNICODE, &have_utf8_pcre))) { + have_utf8_pcre = -2; /* erk, failed to ask */ } return (have_utf8_pcre == 1) && (!strcmp(nl_langinfo(CODESET), "UTF-8")); @@ -69,115 +69,87 @@ zpcre_utf8_enabled(void) static int bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func)) { - int pcre_opts = 0, pcre_errptr, target_len; - const char *pcre_error; + uint32_t pcre_opts = 0; + int target_len; + int pcre_error; + PCRE2_SIZE pcre_offset; char *target; - if(OPT_ISSET(ops,'a')) pcre_opts |= PCRE_ANCHORED; - if(OPT_ISSET(ops,'i')) pcre_opts |= PCRE_CASELESS; - if(OPT_ISSET(ops,'m')) pcre_opts |= PCRE_MULTILINE; - if(OPT_ISSET(ops,'x')) pcre_opts |= PCRE_EXTENDED; - if(OPT_ISSET(ops,'s')) pcre_opts |= PCRE_DOTALL; + if (OPT_ISSET(ops, 'a')) pcre_opts |= PCRE2_ANCHORED; + if (OPT_ISSET(ops, 'i')) pcre_opts |= PCRE2_CASELESS; + if (OPT_ISSET(ops, 'm')) pcre_opts |= PCRE2_MULTILINE; + if (OPT_ISSET(ops, 'x')) pcre_opts |= PCRE2_EXTENDED; + if (OPT_ISSET(ops, 's')) pcre_opts |= PCRE2_DOTALL; if (zpcre_utf8_enabled()) - pcre_opts |= PCRE_UTF8; - -#ifdef HAVE_PCRE_STUDY - if (pcre_hints) -#ifdef PCRE_CONFIG_JIT - pcre_free_study(pcre_hints); -#else - pcre_free(pcre_hints); -#endif - pcre_hints = NULL; -#endif + pcre_opts |= PCRE2_UTF; if (pcre_pattern) - pcre_free(pcre_pattern); + pcre2_code_free(pcre_pattern); pcre_pattern = NULL; target = ztrdup(*args); unmetafy(target, &target_len); - if ((int)strlen(target) != target_len) { - zwarnnam(nam, "embedded NULs in PCRE pattern terminate pattern"); - } - - pcre_pattern = pcre_compile(target, pcre_opts, &pcre_error, &pcre_errptr, NULL); + pcre_pattern = pcre2_compile((PCRE2_SPTR) target, (PCRE2_SIZE) target_len, + pcre_opts, &pcre_error, &pcre_offset, NULL); free(target); if (pcre_pattern == NULL) { - zwarnnam(nam, "error in regex: %s", pcre_error); + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message(pcre_error, buffer, sizeof(buffer)); + zwarnnam(nam, "error in regex: %s", buffer); return 1; } return 0; } -/**/ -#ifdef HAVE_PCRE_STUDY - /**/ static int bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int func)) { - const char *pcre_error; - if (pcre_pattern == NULL) { zwarnnam(nam, "no pattern has been compiled for study"); return 1; } - - if (pcre_hints) -#ifdef PCRE_CONFIG_JIT - pcre_free_study(pcre_hints); -#else - pcre_free(pcre_hints); -#endif - pcre_hints = NULL; - pcre_hints = pcre_study(pcre_pattern, 0, &pcre_error); - if (pcre_error != NULL) - { - zwarnnam(nam, "error while studying regex: %s", pcre_error); - return 1; + int jit = 0; + if (!pcre2_config(PCRE2_CONFIG_JIT, &jit) && jit) { + if (pcre2_jit_compile(pcre_pattern, PCRE2_JIT_COMPLETE) < 0) { + zwarnnam(nam, "error while studying regex"); + return 1; + } } return 0; } -/**/ -#else /* !HAVE_PCRE_STUDY */ - -# define bin_pcre_study bin_notavail - -/**/ -#endif /* !HAVE_PCRE_STUDY */ - -/**/ static int -zpcre_get_substrings(char *arg, int *ovec, int captured_count, char *matchvar, - char *substravar, int want_offset_pair, int matchedinarr, - int want_begin_end) +zpcre_get_substrings(char *arg, pcre2_match_data *mdata, int captured_count, + char *matchvar, char *substravar, int want_offset_pair, + int matchedinarr, int want_begin_end) { - char **captures, *match_all, **matches; + PCRE2_SIZE *ovec; + char *match_all, **matches; char offset_all[50]; int capture_start = 1; if (matchedinarr) { - /* bash-style captures[0] entire-matched string in the array */ + /* bash-style ovec[0] entire-matched string in the array */ capture_start = 0; } - /* captures[0] will be entire matched string, [1] first substring */ - if (!pcre_get_substring_list(arg, ovec, captured_count, (const char ***)&captures)) { - int nelem = arrlen(captures)-1; + /* ovec[0] will be entire matched string, [1] first substring */ + ovec = pcre2_get_ovector_pointer(mdata); + if (ovec) { + int nelem = captured_count - 1; /* Set to the offsets of the complete match */ if (want_offset_pair) { - sprintf(offset_all, "%d %d", ovec[0], ovec[1]); + sprintf(offset_all, "%ld %ld", ovec[0], ovec[1]); setsparam("ZPCRE_OP", ztrdup(offset_all)); } /* @@ -186,7 +158,7 @@ zpcre_get_substrings(char *arg, int *ovec, int captured_count, char *matchvar, * ovec is length 2*(1+capture_list_length) */ if (matchvar) { - match_all = metafy(captures[0], ovec[1] - ovec[0], META_DUP); + match_all = metafy(arg + ovec[0], ovec[1] - ovec[0], META_DUP); setsparam(matchvar, match_all); } /* @@ -201,16 +173,12 @@ zpcre_get_substrings(char *arg, int *ovec, int captured_count, char *matchvar, */ if (substravar && (!want_begin_end || nelem)) { - char **x, **y; + char **x; int vec_off, i; - y = &captures[capture_start]; matches = x = (char **) zalloc(sizeof(char *) * (captured_count+1-capture_start)); - for (i = capture_start; i < captured_count; i++, y++) { + for (i = capture_start; i < captured_count; i++) { vec_off = 2*i; - if (*y) - *x++ = metafy(*y, ovec[vec_off+1]-ovec[vec_off], META_DUP); - else - *x++ = NULL; + *x++ = metafy(arg + ovec[vec_off], ovec[vec_off+1]-ovec[vec_off], META_DUP); } *x = NULL; setaparam(substravar, matches); @@ -247,7 +215,8 @@ zpcre_get_substrings(char *arg, int *ovec, int captured_count, char *matchvar, setiparam("MEND", offs + !isset(KSHARRAYS) - 1); if (nelem) { char **mbegin, **mend, **bptr, **eptr; - int i, *ipair; + int i; + size_t *ipair; bptr = mbegin = zalloc(sizeof(char*)*(nelem+1)); eptr = mend = zalloc(sizeof(char*)*(nelem+1)); @@ -287,8 +256,6 @@ zpcre_get_substrings(char *arg, int *ovec, int captured_count, char *matchvar, setaparam("mend", mend); } } - - pcre_free_substring_list((const char **)captures); } return 0; @@ -314,7 +281,8 @@ getposint(char *instr, char *nam) static int bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) { - int ret, capcount, *ovec, ovecsize, c; + int ret, c; + pcre2_match_data *pcre_mdata = NULL; char *matched_portion = NULL; char *plaintext = NULL; char *receptacle = NULL; @@ -344,36 +312,30 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) /* For the entire match, 'Return' the offset byte positions instead of the matched string */ 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); - return 1; - } - - ovecsize = (capcount+1)*3; - ovec = zalloc(ovecsize*sizeof(int)); - plaintext = ztrdup(*args); unmetafy(plaintext, &subject_len); if (offset_start > 0 && offset_start >= subject_len) - ret = PCRE_ERROR_NOMATCH; - else - ret = pcre_exec(pcre_pattern, pcre_hints, plaintext, subject_len, offset_start, 0, ovec, ovecsize); + ret = PCRE2_ERROR_NOMATCH; + else { + pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pattern, NULL); + ret = pcre2_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len, + offset_start, 0, pcre_mdata, NULL); + } if (ret==0) return_value = 0; - else if (ret==PCRE_ERROR_NOMATCH) /* no match */; + else if (ret == PCRE2_ERROR_NOMATCH) /* no match */; else if (ret>0) { - zpcre_get_substrings(plaintext, ovec, ret, matched_portion, receptacle, + zpcre_get_substrings(plaintext, pcre_mdata, ret, matched_portion, receptacle, want_offset_pair, 0, 0); return_value = 0; } else { - zwarnnam(nam, "error in pcre_exec [%d]", ret); + zwarnnam(nam, "error in pcre2_match [%d]", ret); } - if (ovec) - zfree(ovec, ovecsize*sizeof(int)); + if (pcre_mdata) + pcre2_match_data_free(pcre_mdata); zsfree(plaintext); return return_value; @@ -383,17 +345,19 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) static int cond_pcre_match(char **a, int id) { - pcre *pcre_pat; - const char *pcre_err; + pcre2_code *pcre_pat = NULL; + int pcre_err; + PCRE2_SIZE pcre_erroff; char *lhstr, *rhre, *lhstr_plain, *rhre_plain, *avar, *svar; - int r = 0, pcre_opts = 0, pcre_errptr, capcnt, *ov, ovsize; + int r = 0, pcre_opts = 0; + pcre2_match_data *pcre_mdata = NULL; int lhstr_plain_len, rhre_plain_len; int return_value = 0; if (zpcre_utf8_enabled()) - pcre_opts |= PCRE_UTF8; + pcre_opts |= PCRE2_UTF; if (isset(REMATCHPCRE) && !isset(CASEMATCH)) - pcre_opts |= PCRE_CASELESS; + pcre_opts |= PCRE2_CASELESS; lhstr = cond_str(a,0,0); rhre = cond_str(a,1,0); @@ -401,9 +365,6 @@ cond_pcre_match(char **a, int id) rhre_plain = ztrdup(rhre); unmetafy(lhstr_plain, &lhstr_plain_len); unmetafy(rhre_plain, &rhre_plain_len); - pcre_pat = NULL; - ov = NULL; - ovsize = 0; if (isset(BASHREMATCH)) { svar = NULL; @@ -415,27 +376,27 @@ cond_pcre_match(char **a, int id) switch(id) { case CPCRE_PLAIN: - if ((int)strlen(rhre_plain) != rhre_plain_len) { - zwarn("embedded NULs in PCRE pattern terminate pattern"); - } - pcre_pat = pcre_compile(rhre_plain, pcre_opts, &pcre_err, &pcre_errptr, NULL); - if (pcre_pat == NULL) { - zwarn("failed to compile regexp /%s/: %s", rhre, pcre_err); + if (!(pcre_pat = pcre2_compile((PCRE2_SPTR) rhre_plain, + (PCRE2_SIZE) rhre_plain_len, pcre_opts, + &pcre_err, &pcre_erroff, NULL))) + { + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message(pcre_err, buffer, sizeof(buffer)); + zwarn("failed to compile regexp /%s/: %s", rhre, buffer); break; } - pcre_fullinfo(pcre_pat, NULL, PCRE_INFO_CAPTURECOUNT, &capcnt); - ovsize = (capcnt+1)*3; - ov = zalloc(ovsize*sizeof(int)); - r = pcre_exec(pcre_pat, NULL, lhstr_plain, lhstr_plain_len, 0, 0, ov, ovsize); - /* r < 0 => error; r==0 match but not enough size in ov + pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pat, NULL); + r = pcre2_match(pcre_pat, (PCRE2_SPTR8) lhstr_plain, lhstr_plain_len, + 0, 0, pcre_mdata, NULL); + /* r < 0 => error; r==0 match but not enough size in match data * r > 0 => (r-1) substrings found; r==1 => no substrings */ if (r==0) { - zwarn("reportable zsh problem: pcre_exec() returned 0"); + zwarn("reportable zsh problem: pcre2_match() returned 0"); return_value = 1; break; } - else if (r==PCRE_ERROR_NOMATCH) { + else if (r == PCRE2_ERROR_NOMATCH) { return_value = 0; /* no match */ break; } @@ -444,7 +405,7 @@ cond_pcre_match(char **a, int id) break; } else if (r>0) { - zpcre_get_substrings(lhstr_plain, ov, r, svar, avar, 0, + zpcre_get_substrings(lhstr_plain, pcre_mdata, r, svar, avar, 0, isset(BASHREMATCH), !isset(BASHREMATCH)); return_value = 1; @@ -457,10 +418,10 @@ cond_pcre_match(char **a, int id) free(lhstr_plain); if(rhre_plain) free(rhre_plain); + if (pcre_mdata) + pcre2_match_data_free(pcre_mdata); if (pcre_pat) - pcre_free(pcre_pat); - if (ov) - zfree(ov, ovsize*sizeof(int)); + pcre2_code_free(pcre_pat); return return_value; } @@ -489,11 +450,11 @@ static struct builtin bintab[] = { static struct features module_features = { bintab, sizeof(bintab)/sizeof(*bintab), -#if defined(HAVE_PCRE_COMPILE) && defined(HAVE_PCRE_EXEC) +#if defined(HAVE_PCRE2_COMPILE_8) && defined(HAVE_PCRE2_H) cotab, sizeof(cotab)/sizeof(*cotab), -#else /* !(HAVE_PCRE_COMPILE && HAVE_PCRE_EXEC) */ +#else /* !(HAVE_PCRE2_COMPILE_8 && HAVE_PCRE2_H) */ NULL, 0, -#endif /* !(HAVE_PCRE_COMPILE && HAVE_PCRE_EXEC) */ +#endif /* !(HAVE_PCRE2_COMPILE_8 && HAVE_PCRE2_H) */ NULL, 0, NULL, 0, 0 @@ -540,19 +501,9 @@ cleanup_(Module m) int finish_(UNUSED(Module m)) { -#if defined(HAVE_PCRE_COMPILE) && defined(HAVE_PCRE_EXEC) -#ifdef HAVE_PCRE_STUDY - if (pcre_hints) -#ifdef PCRE_CONFIG_JIT - pcre_free_study(pcre_hints); -#else - pcre_free(pcre_hints); -#endif - pcre_hints = NULL; -#endif - +#if defined(HAVE_PCRE2_COMPILE_8) && defined(HAVE_PCRE2_H) if (pcre_pattern) - pcre_free(pcre_pattern); + pcre2_code_free(pcre_pattern); pcre_pattern = NULL; #endif diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst index 22a0b64c7..6eb366964 100644 --- a/Test/V07pcre.ztst +++ b/Test/V07pcre.ztst @@ -117,12 +117,17 @@ >78884; ZPCRE_OP: 25 30 >90210; ZPCRE_OP: 31 36 -# Embedded NULs allowed in plaintext, but not in RE (although \0 as two-chars allowed) +# Embedded NULs allowed in plaintext, in RE, pcre supports \0 as two-chars [[ $'a\0bc\0d' =~ '^(a\0.)(.+)$' ]] print "${#MATCH}; ${#match[1]}; ${#match[2]}" 0:ensure ASCII NUL passes in and out of matched plaintext >6; 3; 3 +# PCRE2 supports NULs also in the RE + [[ $'a\0b\0c' =~ $'^(.\0)+' ]] && print "${#MATCH}; ${#match[1]}" +0:ensure ASCII NUL works also in the regex +>4; 2 + # Ensure the long-form infix operator works [[ foo -pcre-match ^f..$ ]] print $? @@ -169,7 +174,11 @@ [[ é =~ '^..\z' ]]; echo $? LANG=$LANG_SAVE [[ é =~ '^.\z' ]]; echo $? -0:swich between C/UTF-8 locales +0:switch between C/UTF-8 locales >0 >0 >0 + + [[ abc =~ 'a(d*)bc' ]] && print "$#MATCH; $#match; ${#match[1]}" +0:empty capture +>3; 1; 0 diff --git a/configure.ac b/configure.ac index d8a17791a..4710d1659 100644 --- a/configure.ac +++ b/configure.ac @@ -438,7 +438,7 @@ fi], dnl Do you want to look for pcre support? AC_ARG_ENABLE(pcre, -AS_HELP_STRING([--enable-pcre],[enable the search for the pcre library (may create run-time library dependencies)])) +AS_HELP_STRING([--enable-pcre],[enable the search for the pcre2 library (may create run-time library dependencies)])) dnl Do you want to look for capability support? AC_ARG_ENABLE(cap, @@ -652,13 +652,12 @@ AC_HEADER_SYS_WAIT oldcflags="$CFLAGS" if test x$enable_pcre = xyes; then -AC_CHECK_PROG([PCRECONF], pcre-config, pcre-config) -dnl Typically (meaning on this single RedHat 9 box in front of me) -dnl pcre-config --cflags produces a -I output which needs to go into +AC_CHECK_PROG([PCRECONF], pcre2-config, pcre2-config) +dnl pcre2-config --cflags may produce a -I output which needs to go into dnl CPPFLAGS else configure's preprocessor tests don't pick it up, dnl producing a warning. -if test "x$ac_cv_prog_PCRECONF" = xpcre-config; then - CPPFLAGS="$CPPFLAGS `pcre-config --cflags`" +if test "x$ac_cv_prog_PCRECONF" = xpcre2-config; then + CPPFLAGS="$CPPFLAGS `pcre2-config --cflags`" fi fi @@ -668,9 +667,10 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \ locale.h errno.h stdio.h stdarg.h varargs.h stdlib.h \ unistd.h sys/capability.h \ utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \ - netinet/in_systm.h pcre.h langinfo.h wchar.h stddef.h \ + netinet/in_systm.h langinfo.h wchar.h stddef.h \ sys/stropts.h iconv.h ncurses.h ncursesw/ncurses.h \ ncurses/ncurses.h) +AC_CHECK_HEADERS([pcre2.h],,,[#define PCRE2_CODE_UNIT_WIDTH 8]) if test x$dynamic = xyes; then AC_CHECK_HEADERS(dlfcn.h) AC_CHECK_HEADERS(dl.h) @@ -948,9 +948,7 @@ if test "x$ac_found_iconv" = "xyes"; then fi if test x$enable_pcre = xyes; then -dnl pcre-config should probably be employed here -dnl AC_SEARCH_LIBS(pcre_compile, pcre) - LIBS="`$ac_cv_prog_PCRECONF --libs` $LIBS" + LIBS="`$ac_cv_prog_PCRECONF --libs8` $LIBS" fi dnl --------------------- @@ -1313,7 +1311,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ pathconf sysconf \ tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \ getcchar setcchar waddwstr wget_wch win_wch use_default_colors \ - pcre_compile pcre_study pcre_exec \ + pcre2_compile_8 \ nl_langinfo \ erand48 open_memstream \ posix_openpt \ -- cgit v1.2.3 From f3f371deb376478176866fd770fbcf9bc0d0609f Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 13 May 2023 00:56:48 +0200 Subject: 51728: assign pcre named capture groups to a hash --- ChangeLog | 3 +++ Doc/Zsh/mod_pcre.yo | 10 ++++++---- Src/Modules/pcre.c | 43 +++++++++++++++++++++++++++++++++---------- Test/V07pcre.ztst | 14 ++++++++++++++ 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 285b73b2c..2835a9405 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-13 Oliver Kiddle + * 51728: Doc/Zsh/mod_pcre.yo, Src/Modules/pcre.c, + Test/V07pcre.ztst: assign pcre named capture groups to a hash + * 51723: Src/Modules/pcre.c, Test/V07pcre.ztst, configure.ac: migrate pcre module to pcre2 diff --git a/Doc/Zsh/mod_pcre.yo b/Doc/Zsh/mod_pcre.yo index c2817f519..6d073985d 100644 --- a/Doc/Zsh/mod_pcre.yo +++ b/Doc/Zsh/mod_pcre.yo @@ -20,12 +20,12 @@ including those that indicate newline. ) findex(pcre_study) item(tt(pcre_study))( -Studies the previously-compiled PCRE which may result in faster -matching. +Requests JIT compilation for the previously-compiled PCRE which +may result in faster matching. ) findex(pcre_match) item(tt(pcre_match) [ tt(-v) var(var) ] [ tt(-a) var(arr) ] \ -[ tt(-n) var(offset) ] [ tt(-b) ] var(string))( +[ tt(-A) var(assoc) ] [ tt(-n) var(offset) ] [ tt(-b) ] var(string))( Returns successfully if tt(string) matches the previously-compiled PCRE. @@ -36,7 +36,9 @@ substrings, unless the tt(-a) option is given, in which case it will set the array var(arr). Similarly, the variable tt(MATCH) will be set to the entire matched portion of the string, unless the tt(-v) option is given, in which case the variable -var(var) will be set. +var(var) will be set. Furthermore, any named captures will +be stored in the associative array tt(.pcre.match) unless an +alternative is given with tt(-A). No variables are altered if there is no successful match. A tt(-n) option starts searching for a match from the byte var(offset) position in var(string). If the tt(-b) option is given, diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index 079ecc2c5..6be1f76e2 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -129,14 +129,17 @@ bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int f } static int -zpcre_get_substrings(char *arg, pcre2_match_data *mdata, int captured_count, - char *matchvar, char *substravar, int want_offset_pair, - int matchedinarr, int want_begin_end) +zpcre_get_substrings(pcre2_code *pat, char *arg, pcre2_match_data *mdata, + int captured_count, char *matchvar, char *substravar, char *namedassoc, + int want_offset_pair, int matchedinarr, int want_begin_end) { PCRE2_SIZE *ovec; char *match_all, **matches; char offset_all[50]; int capture_start = 1; + int vec_off; + PCRE2_SPTR ntable; /* table of named captures */ + uint32_t ncount, nsize; if (matchedinarr) { /* bash-style ovec[0] entire-matched string in the array */ @@ -174,7 +177,7 @@ zpcre_get_substrings(char *arg, pcre2_match_data *mdata, int captured_count, if (substravar && (!want_begin_end || nelem)) { char **x; - int vec_off, i; + int i; matches = x = (char **) zalloc(sizeof(char *) * (captured_count+1-capture_start)); for (i = capture_start; i < captured_count; i++) { vec_off = 2*i; @@ -184,6 +187,23 @@ zpcre_get_substrings(char *arg, pcre2_match_data *mdata, int captured_count, setaparam(substravar, matches); } + if (!pcre2_pattern_info(pat, PCRE2_INFO_NAMECOUNT, &ncount) && ncount + && !pcre2_pattern_info(pat, PCRE2_INFO_NAMEENTRYSIZE, &nsize) + && !pcre2_pattern_info(pat, PCRE2_INFO_NAMETABLE, &ntable)) + { + char **hash, **hashptr; + uint32_t nidx; + hashptr = hash = (char **)zshcalloc((ncount+1)*2*sizeof(char *)); + for (nidx = 0; nidx < ncount; nidx++) { + vec_off = (ntable[nsize * nidx] << 9) + 2 * ntable[nsize * nidx + 1]; + /* would metafy the key but pcre limits characters in the name */ + *hashptr++ = ztrdup((char *) ntable + nsize * nidx + 2); + *hashptr++ = metafy(arg + ovec[vec_off], + ovec[vec_off+1]-ovec[vec_off], META_DUP); + } + sethparam(namedassoc, hash); + } + if (want_begin_end) { /* * cond-infix rather than builtin; also not bash; so we set a bunch @@ -286,6 +306,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) char *matched_portion = NULL; char *plaintext = NULL; char *receptacle = NULL; + char *named = ".pcre.match"; int return_value = 1; /* The subject length and offset start are both int values in pcre_exec */ int subject_len; @@ -305,6 +326,9 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) if(OPT_HASARG(ops,c='v')) { matched_portion = OPT_ARG(ops,c); } + if (OPT_HASARG(ops, c='A')) { + named = OPT_ARG(ops, c); + } if(OPT_HASARG(ops,c='n')) { /* The offset position to start the search, in bytes. */ if ((offset_start = getposint(OPT_ARG(ops,c), nam)) < 0) return 1; @@ -326,8 +350,8 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) if (ret==0) return_value = 0; else if (ret == PCRE2_ERROR_NOMATCH) /* no match */; else if (ret>0) { - zpcre_get_substrings(plaintext, pcre_mdata, ret, matched_portion, receptacle, - want_offset_pair, 0, 0); + zpcre_get_substrings(pcre_pattern, plaintext, pcre_mdata, ret, matched_portion, + receptacle, named, want_offset_pair, 0, 0); return_value = 0; } else { @@ -405,9 +429,8 @@ cond_pcre_match(char **a, int id) break; } else if (r>0) { - zpcre_get_substrings(lhstr_plain, pcre_mdata, r, svar, avar, 0, - isset(BASHREMATCH), - !isset(BASHREMATCH)); + zpcre_get_substrings(pcre_pat, lhstr_plain, pcre_mdata, r, svar, avar, + ".pcre.match", 0, isset(BASHREMATCH), !isset(BASHREMATCH)); return_value = 1; break; } @@ -443,7 +466,7 @@ static struct conddef cotab[] = { static struct builtin bintab[] = { BUILTIN("pcre_compile", 0, bin_pcre_compile, 1, 1, 0, "aimxs", NULL), - BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "a:v:n:b", NULL), + BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "A:a:v:n:b", NULL), BUILTIN("pcre_study", 0, bin_pcre_study, 0, 0, 0, NULL, NULL) }; diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst index 6eb366964..027fea3aa 100644 --- a/Test/V07pcre.ztst +++ b/Test/V07pcre.ztst @@ -182,3 +182,17 @@ [[ abc =~ 'a(d*)bc' ]] && print "$#MATCH; $#match; ${#match[1]}" 0:empty capture >3; 1; 0 + + [[ category/name-12345 =~ '(?x)^ + (? [^/]* ) / + (? + (? \w+ ) - + (? \d+ ))$' ]] + typeset -p1 .pcre.match +0:named captures +>typeset -g -A .pcre.match=( +> [category]=category +> [name]=name +> [package]=name-12345 +> [version]=12345 +>) -- cgit v1.2.3 From b4d1c756f50909b4a13e5c8fe5f26f71e9d54f63 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 13 May 2023 00:59:00 +0200 Subject: 51738: support pcre's alternative DFA matching algorithm --- ChangeLog | 3 +++ Doc/Zsh/mod_pcre.yo | 6 +++++- Src/Modules/pcre.c | 53 ++++++++++++++++++++++++++++++++++++----------------- Test/V07pcre.ztst | 5 +++++ 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2835a9405..18bc4a698 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-13 Oliver Kiddle + * 51738: Doc/Zsh/mod_pcre.yo, Src/Modules/pcre.c, + Test/V07pcre.ztst: support pcre's DFA matching algorithm + * 51728: Doc/Zsh/mod_pcre.yo, Src/Modules/pcre.c, Test/V07pcre.ztst: assign pcre named capture groups to a hash diff --git a/Doc/Zsh/mod_pcre.yo b/Doc/Zsh/mod_pcre.yo index 6d073985d..da73ac85a 100644 --- a/Doc/Zsh/mod_pcre.yo +++ b/Doc/Zsh/mod_pcre.yo @@ -25,7 +25,7 @@ may result in faster matching. ) findex(pcre_match) item(tt(pcre_match) [ tt(-v) var(var) ] [ tt(-a) var(arr) ] \ -[ tt(-A) var(assoc) ] [ tt(-n) var(offset) ] [ tt(-b) ] var(string))( +[ tt(-A) var(assoc) ] [ tt(-n) var(offset) ] [ tt(-bd) ] var(string))( Returns successfully if tt(string) matches the previously-compiled PCRE. @@ -69,6 +69,10 @@ print -l $accum) ) enditem() +The option tt(-d) uses the alternative breadth-first DFA search algorithm of +pcre. This sets tt(match), or the array given with tt(-a), to all the matches +found from the same start point in the subject. + The tt(zsh/pcre) module makes available the following test condition: startitem() diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index 6be1f76e2..96f3c6e65 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -305,30 +305,29 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) pcre2_match_data *pcre_mdata = NULL; char *matched_portion = NULL; char *plaintext = NULL; - char *receptacle = NULL; - char *named = ".pcre.match"; + char *receptacle; + char *named = NULL; int return_value = 1; /* The subject length and offset start are both int values in pcre_exec */ int subject_len; int offset_start = 0; int want_offset_pair = 0; + int use_dfa = 0; if (pcre_pattern == NULL) { 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); - } - if(OPT_HASARG(ops,c='v')) { - matched_portion = OPT_ARG(ops,c); - } - if (OPT_HASARG(ops, c='A')) { - named = OPT_ARG(ops, c); + if (!(use_dfa = OPT_ISSET(ops, 'd'))) { + matched_portion = OPT_HASARG(ops, c='v') ? OPT_ARG(ops, c) : "MATCH"; + named = OPT_HASARG(ops, c='A') ? OPT_ARG(ops, c) : ".pcre.match"; + } else if (OPT_HASARG(ops, c='v') || OPT_HASARG(ops, c='A')) { + zwarnnam(nam, "-d cannot be combined with -%c", c); + return 1; } + receptacle = OPT_HASARG(ops, 'a') ? OPT_ARG(ops, 'a') : "match"; + if(OPT_HASARG(ops,c='n')) { /* The offset position to start the search, in bytes. */ if ((offset_start = getposint(OPT_ARG(ops,c), nam)) < 0) return 1; @@ -341,7 +340,25 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) if (offset_start > 0 && offset_start >= subject_len) ret = PCRE2_ERROR_NOMATCH; - else { + else if (use_dfa) { + PCRE2_SIZE old, wscount = 128, capcount = 128; + void *workspace = zhalloc(sizeof(int) * wscount); + pcre_mdata = pcre2_match_data_create(capcount, NULL); + do { + ret = pcre2_dfa_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len, + offset_start, 0, pcre_mdata, NULL, (int *) workspace, wscount); + if (ret == PCRE2_ERROR_DFA_WSSIZE) { + old = wscount; + wscount += wscount / 2; + workspace = hrealloc(workspace, sizeof(int) * old, sizeof(int) * wscount); + } else if (ret == 0) { + capcount += capcount / 2; + pcre2_match_data_free(pcre_mdata); + pcre_mdata = pcre2_match_data_create(capcount, NULL); + } else + break; + } while(1); + } else { pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pattern, NULL); ret = pcre2_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len, offset_start, 0, pcre_mdata, NULL); @@ -350,12 +367,14 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) if (ret==0) return_value = 0; else if (ret == PCRE2_ERROR_NOMATCH) /* no match */; else if (ret>0) { - zpcre_get_substrings(pcre_pattern, plaintext, pcre_mdata, ret, matched_portion, - receptacle, named, want_offset_pair, 0, 0); + zpcre_get_substrings(pcre_pattern, plaintext, pcre_mdata, ret, + matched_portion, receptacle, named, want_offset_pair, use_dfa, 0); return_value = 0; } else { - zwarnnam(nam, "error in pcre2_match [%d]", ret); + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message(ret, buffer, sizeof(buffer)); + zwarnnam(nam, "error in pcre matching for /%s/: %s", plaintext, buffer); } if (pcre_mdata) @@ -466,7 +485,7 @@ static struct conddef cotab[] = { static struct builtin bintab[] = { BUILTIN("pcre_compile", 0, bin_pcre_compile, 1, 1, 0, "aimxs", NULL), - BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "A:a:v:n:b", NULL), + BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "A:a:v:n:bd", NULL), BUILTIN("pcre_study", 0, bin_pcre_study, 0, 0, 0, NULL, NULL) }; diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst index 027fea3aa..585698d05 100644 --- a/Test/V07pcre.ztst +++ b/Test/V07pcre.ztst @@ -196,3 +196,8 @@ > [package]=name-12345 > [version]=12345 >) + + pcre_compile 'cat(er(pillar)?)?' + pcre_match -d 'the caterpillar catchment' && print $match +0:pcre_match -d +>caterpillar cater cat -- cgit v1.2.3 From a95198e268ec1d432c37afc8dc4f8839acc0c8d0 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sat, 13 May 2023 21:49:07 +0100 Subject: 51722: Safety for extracting elements of $historywords --- ChangeLog | 5 +++++ Src/Modules/parameter.c | 11 +++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 18bc4a698..85fc1de96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-05-13 Peter Stephenson + + * 51722: Src/Modules/parameter.c: Add safety to extracting + elements of $historywords. + 2023-05-13 Oliver Kiddle * 51738: Doc/Zsh/mod_pcre.yo, Src/Modules/pcre.c, diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index 96a211c69..a05ea2fe4 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -1233,9 +1233,16 @@ histwgetfn(UNUSED(Param pm)) pushnode(l, getdata(n)); while (he) { + char *hstr = he->node.nam; + int len = strlen(hstr); for (iw = he->nwords - 1; iw >= 0; iw--) { - h = he->node.nam + he->words[iw * 2]; - e = he->node.nam + he->words[iw * 2 + 1]; + int wbegin = he->words[iw * 2]; + int wend = he->words[iw * 2 + 1]; + + if (wbegin < 0 || wbegin >= len || wend < 0 || wend > len) + break; + h = hstr + wbegin; + e = hstr + wend; sav = *e; *e = '\0'; addlinknode(l, dupstring(h)); -- cgit v1.2.3 From bb441f77a70bf7b5f13ab8f9113ba9b7a1593479 Mon Sep 17 00:00:00 2001 From: Marlon Richert Date: Thu, 18 May 2023 23:44:54 +0300 Subject: 51758: Make dynamic dir completion easier to implement --- ChangeLog | 6 ++++ Completion/Zsh/Context/_dynamic_directory_name | 30 +++++++++++++----- Doc/Zsh/expn.yo | 44 ++++++++++---------------- Test/Y01completion.ztst | 11 +++++++ 4 files changed, 56 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 85fc1de96..e1b1c7da4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-05-21 Oliver Kiddle + + * Marlon Richert: 51758: Test/Y01completion.ztst, Doc/Zsh/expn.yo, + Completion/Zsh/Context/_dynamic_directory_name: Make dynamic dir + completion easier to implement + 2023-05-13 Peter Stephenson * 51722: Src/Modules/parameter.c: Add safety to extracting diff --git a/Completion/Zsh/Context/_dynamic_directory_name b/Completion/Zsh/Context/_dynamic_directory_name index f449c3b12..5e0d73a8d 100644 --- a/Completion/Zsh/Context/_dynamic_directory_name +++ b/Completion/Zsh/Context/_dynamic_directory_name @@ -1,15 +1,29 @@ #autoload +local -a dirfuncs=( + ${(k)functions[zsh_directory_name]} + $zsh_directory_name_functions +) +local descr='dynamically named directory' -local func -integer ret=1 +if (( $#dirfuncs )); then + local -a expl + local -i ret + local func suf tag=dynamically-named-directories -if [[ -n $functions[zsh_directory_name] || \ - ${+zsh_directory_name_functions} -ne 0 ]] ; then - [[ -n $functions[zsh_directory_name] ]] && zsh_directory_name c && ret=0 - for func in $zsh_directory_name_functions; do - $func c && ret=0 + [[ $ISUFFIX != \]* ]] && + suf=-S] + + _tags "$tag" + while _tags; do + while _next_label "$tag" expl "$descr" $suf; do + for func in $dirfuncs; do + $func c && ret=0 + done + done + (( ret )) || break done return ret + else - _message 'dynamic directory name: implemented as zsh_directory_name c' + _message "${descr}: implement as zsh_directory_name c" fi diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 19f5909ea..6f86d0c54 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -2066,34 +2066,24 @@ tt(/home/pws/perforce). In this simple case a static name for the directory would be just as effective. example(zsh_directory_name+LPAR()RPAR() { - emulate -L zsh - setopt extendedglob + emulate -L zsh -o extendedglob local -a match mbegin mend - if [[ $1 = d ]]; then - # turn the directory into a name - if [[ $2 = (#b)(/home/pws/perforce/)([^/]##)* ]]; then - typeset -ga reply - reply=(p:$match[2] $(( ${#match[1]} + ${#match[2]} )) ) - else - return 1 - fi - elif [[ $1 = n ]]; then - # turn the name into a directory - [[ $2 != (#b)p:(?*) ]] && return 1 - typeset -ga reply - reply=(/home/pws/perforce/$match[1]) - elif [[ $1 = c ]]; then - # complete names - local expl - local -a dirs - dirs=(/home/pws/perforce/*(/:t)) - dirs=(p:${^dirs}) - _wanted dynamic-dirs expl 'dynamic directory' compadd -S\] -a dirs - return - else - return 1 - fi - return 0 + local base=/home/pws/perforce + case $1 in + ( d ) # Turn the directory into a name. + [[ $2 == (#b)($base/)([^/]##)* ]] && + reply=( p:$match[2] $(( $#match[1] + $#match[2] )) ) + ;; + ( n ) # Turn the name into a directory. + [[ $2 == (#b)p:(?*) ]] && + reply=( $base/$match[1] ) + ;; + ( c ) # Complete names. + local -a dirs=( $base/*(/:t) ) + # Completion system populates $expl with flags for compadd. + compadd "$expl[@]" p:$^dirs + ;; + esac }) texinode(Static named directories)(`=' expansion)(Dynamic named directories)(Filename Expansion) diff --git a/Test/Y01completion.ztst b/Test/Y01completion.ztst index f976f9f91..b3ec12e52 100644 --- a/Test/Y01completion.ztst +++ b/Test/Y01completion.ztst @@ -75,6 +75,17 @@ >line: {: ~user2}{} >line: {: ~user1}{} + comptesteval 'zsh_directory_name() { compadd "$expl[@]" -- name1 name2 }' + comptest $': ~[\t\t\t\t' +0:dynamic directory names after ~[ +>line: {: ~[name}{} +>line: {: ~[name}{} +>DESCRIPTION:{dynamically named directory} +>NO:{name1} +>NO:{name2} +>line: {: ~[name1]}{} +>line: {: ~[name2]}{} + comptest $'echo ;:\C-b\C-b\t' 0:directories and files before separator >line: {echo }{;:} -- cgit v1.2.3 From 1f64d0912720ba35f92020c3c1e128039cac5df8 Mon Sep 17 00:00:00 2001 From: Marlon Richert Date: Thu, 18 May 2023 23:53:27 +0300 Subject: 51760: r and R were listed in the wrong order. --- ChangeLog | 3 +++ Doc/Zsh/compwid.yo | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1b1c7da4..2d4c68038 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-21 Oliver Kiddle + * Marlon Richert: 51760: Doc/Zsh/compwid.yo: r and R were listed + in the wrong order. + * Marlon Richert: 51758: Test/Y01completion.ztst, Doc/Zsh/expn.yo, Completion/Zsh/Context/_dynamic_directory_name: Make dynamic dir completion easier to implement diff --git a/Doc/Zsh/compwid.yo b/Doc/Zsh/compwid.yo index d32a0702f..9461ace17 100644 --- a/Doc/Zsh/compwid.yo +++ b/Doc/Zsh/compwid.yo @@ -112,7 +112,7 @@ vindex(QIPREFIX) item(tt(QIPREFIX))( This parameter is read-only and contains the quoted string up to the word being completed. E.g. when completing `tt("foo)', this parameter -contains the double quote. If the tt(-q) option of tt(compset) is used +contains the double quote. If the tt(-q) option of tt(compset) is used (see below), and the original string was `tt("foo bar)' with the cursor on the `tt(bar)', this parameter contains `tt("foo )'. ) @@ -1082,8 +1082,8 @@ enditem() ) xitem(tt(l:)tt(|)var(word-pat)tt(=)var(match-pat)) xitem(tt(L:)tt(|)var(word-pat)tt(=)var(match-pat)) -xitem(tt(R:)var(word-pat)tt(|)tt(=)var(match-pat)) -item(tt(r:)var(word-pat)tt(|)tt(=)var(match-pat))( +xitem(tt(r:)var(word-pat)tt(|)tt(=)var(match-pat)) +item(tt(R:)var(word-pat)tt(|)tt(=)var(match-pat))( If there is a substring at the tt(l:)eft or tt(r:)ight edge of the current word that matches var(word-pat), then broaden the corresponding part of the match -- cgit v1.2.3 From 9a5f213573fbda6a6d23e985113eaeb849d4ee6d Mon Sep 17 00:00:00 2001 From: Marlon Richert Date: Thu, 18 May 2023 23:53:29 +0300 Subject: 51759: Show alias values in command completions Show the value of each alias when descriptions are shown. Enabled by default. --- ChangeLog | 3 +++ Completion/Zsh/Type/_command_names | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d4c68038..a85706e15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-21 Oliver Kiddle + * Marlon Richert: 51759: Completion/Zsh/Type/_command_names: + Show alias values in command completions + * Marlon Richert: 51760: Doc/Zsh/compwid.yo: r and R were listed in the wrong order. diff --git a/Completion/Zsh/Type/_command_names b/Completion/Zsh/Type/_command_names index 12cbd69c1..d445be06e 100644 --- a/Completion/Zsh/Type/_command_names +++ b/Completion/Zsh/Type/_command_names @@ -4,7 +4,7 @@ # complete only external commands and executable files. This and a # `-' as the first argument is then removed from the arguments. -local args defs expl ffilt +local args defs expl ffilt verbose zstyle -t ":completion:${curcontext}:commands" rehash && rehash @@ -33,13 +33,19 @@ else defs=( "$defs[@]" 'builtins:builtin command:compadd -Qk builtins' "functions:shell function:compadd -k 'functions$ffilt'" - 'aliases:alias:compadd -Qk aliases' 'suffix-aliases:suffix alias:_suffix_alias_files' 'reserved-words:reserved word:compadd -Qk reswords' 'jobs:: _jobs -t' 'parameters:: _parameters -g "^*(readonly|association)*" -qS= -r "\n\t\- =[+"' 'parameters:: _parameters -g "*association*~*readonly*" -qS\[ -r "\n\t\- =[+"' ) + + if zstyle -T ":completion:${curcontext}:aliases" verbose; then + printf -v verbose %s:%s\ ${(@q+)${(kv)aliases}[@]//\:/\\:} + defs+=( "aliases:alias:(( $verbose ))" ) + else + defs+=( 'aliases:alias:compadd -Qk aliases' ) + fi fi args=( "$@" ) -- cgit v1.2.3 From caa1c38c6f0000b6ed6a6a50e8dca037ad82308a Mon Sep 17 00:00:00 2001 From: Marlon Richert Date: Fri, 5 May 2023 14:41:59 +0300 Subject: 51348: Fix subscript completion bugs inside ~[...] When completing inside ~[...] (_with_ the trailing `]` present), the following bugs occured: - Subscript completion was skipped entirely when there were one or more slashes ('/') in the subscript, which is incorrect, since slashes are allowed there. - Instead of going through _complete, $_comps[-subscript-] was called immediately, causing _setup to be skipped. - If succesful, _main_complete was exited right after, causing menu-style, comppostfuncs and other essential completion features to be skipped. --- ChangeLog | 4 ++++ Completion/Base/Core/_main_complete | 22 +++++++++------------- Test/Y01completion.ztst | 16 +++++++++++++--- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index a85706e15..39db54841 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-05-21 Oliver Kiddle + * Marlon Richert: 51682: Completion/Base/Core/_main_complete, + Test/Y01completion.ztst: Fix subscript completion bugs + inside ~[...] + * Marlon Richert: 51759: Completion/Zsh/Type/_command_names: Show alias values in command completions diff --git a/Completion/Base/Core/_main_complete b/Completion/Base/Core/_main_complete index 169ca1f40..408a66ee3 100644 --- a/Completion/Base/Core/_main_complete +++ b/Completion/Base/Core/_main_complete @@ -93,19 +93,15 @@ fi if [[ -z "$compstate[quote]" ]]; then if [[ -o equals ]] && compset -P 1 '='; then compstate[context]=equal - elif [[ "$PREFIX" != */* && "$PREFIX[1]" = '~' ]]; then - if [[ "$PREFIX" = '~['[^\]]# ]]; then - # Inside ~[...] should be treated as a subscript. - compset -p 2 - # To be consistent, we ignore all but the contents of the square - # brackets. - compset -S '\]*' - compstate[context]=subscript - [[ -n $_comps[-subscript-] ]] && $_comps[-subscript-] && return - else - compset -p 1 - compstate[context]=tilde - fi + elif [[ "$PREFIX" = \~\[[^]]# ]]; then + # Inside ~[...] should be treated as a subscript. + compset -p 2 + # To be consistent, we ignore all but the contents of the square brackets. + compset -S '\]*' + compstate[context]=subscript + elif [[ "$PREFIX" = \~[^/]# ]]; then + compset -p 1 + compstate[context]=tilde fi fi diff --git a/Test/Y01completion.ztst b/Test/Y01completion.ztst index b3ec12e52..a4060e9a4 100644 --- a/Test/Y01completion.ztst +++ b/Test/Y01completion.ztst @@ -75,17 +75,27 @@ >line: {: ~user2}{} >line: {: ~user1}{} - comptesteval 'zsh_directory_name() { compadd "$expl[@]" -- name1 name2 }' + comptesteval 'zsh_directory_name() { compadd "$expl[@]" -- name/1 name2 }' comptest $': ~[\t\t\t\t' 0:dynamic directory names after ~[ >line: {: ~[name}{} >line: {: ~[name}{} >DESCRIPTION:{dynamically named directory} ->NO:{name1} +>NO:{name/1} >NO:{name2} ->line: {: ~[name1]}{} +>line: {: ~[name/1]}{} >line: {: ~[name2]}{} + comptest $': ~[]\C-b\t\t\t\t' +0:dynamic directory names inside ~[...] +>line: {: ~[name}{]} +>line: {: ~[name}{]} +>DESCRIPTION:{dynamically named directory} +>NO:{name/1} +>NO:{name2} +>line: {: ~[name/1}{]} +>line: {: ~[name2}{]} + comptest $'echo ;:\C-b\C-b\t' 0:directories and files before separator >line: {echo }{;:} -- cgit v1.2.3 From b41dd30c90a90dd28c551af7e7f76ae29b6220d0 Mon Sep 17 00:00:00 2001 From: Marlon Richert Date: Thu, 18 May 2023 23:53:28 +0300 Subject: 51761: Use zstyle verbose for _parameters descriptions According to the manual, extra-verbose means "more verbose at the cost of a probable decrease in completion speed". That's not the case here. --- ChangeLog | 3 +++ Completion/Zsh/Type/_parameters | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 39db54841..e43613070 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-21 Oliver Kiddle + * Marlon Richert: 51761: Completion/Zsh/Type/_parameters: + Use zstyle verbose for _parameters descriptions + * Marlon Richert: 51682: Completion/Base/Core/_main_complete, Test/Y01completion.ztst: Fix subscript completion bugs inside ~[...] diff --git a/Completion/Zsh/Type/_parameters b/Completion/Zsh/Type/_parameters index b5da45c58..7f6f33e0e 100644 --- a/Completion/Zsh/Type/_parameters +++ b/Completion/Zsh/Type/_parameters @@ -21,7 +21,7 @@ zstyle -t ":completion:${curcontext}:parameters" prefix-needed && _description parameters expl parameter zparseopts -D -K -E g:=pattern -if zstyle -t ":completion:${curcontext}:parameters" extra-verbose; then +if zstyle -t ":completion:${curcontext}:parameters" verbose; then described=( "${(@M)${(@k)parameters[(R)$~pattern[2]~*(hideval|local|special)*]}:#$~pfilt*}" ) -- cgit v1.2.3 From f80ad32c3f4e6239d9d6853d14ff36e28154f075 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sun, 21 May 2023 03:36:21 +0200 Subject: 51769: fix compilation when HAVE_GETRUSAGE is not defined Also silence compiler warning when HAVE_SETUPTERM is not defined. --- ChangeLog | 3 +++ Src/jobs.c | 2 +- Src/utils.c | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e43613070..0b2993f7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-05-21 Oliver Kiddle + * 51769: Src/jobs.c, Src/utils.c: fix compilation when + HAVE_GETRUSAGE is not defined + * Marlon Richert: 51761: Completion/Zsh/Type/_parameters: Use zstyle verbose for _parameters descriptions diff --git a/Src/jobs.c b/Src/jobs.c index 4d7172550..dd7bba405 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1032,7 +1032,7 @@ should_report_time(Job j) return 1; #else { - clktck = get_clktck(); + long clktck = get_clktck(); if ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime) return 1; } diff --git a/Src/utils.c b/Src/utils.c index 14ff0ed47..f13e3a79d 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -380,11 +380,13 @@ zerrmsg(FILE *file, const char *fmt, va_list ap) fflush(file); } +#ifdef HAVE_SETUPTERM /* * Wrapper for setupterm() and del_curterm(). * These are called from terminfo.c and termcap.c. */ static int term_count; /* reference count of cur_term */ +#endif /**/ mod_export void -- cgit v1.2.3 From 88eeade0bcdba8beb4a94534312b8febbc608697 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 25 May 2023 15:47:23 +0100 Subject: 51739: detect invalid history word beginning --- ChangeLog | 4 ++++ Src/hist.c | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0b2993f7d..1a703ec04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-05-25 Peter Stephenson + + * 51739: Src/hist.c: detect invalid history word beginning. + 2023-05-21 Oliver Kiddle * 51769: Src/jobs.c, Src/utils.c: fix compilation when diff --git a/Src/hist.c b/Src/hist.c index 82d03a840..7e6394406 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -1643,12 +1643,17 @@ hend(Eprog prog) void ihwbegin(int offset) { + int pos = hptr - chline + offset; if (stophist == 2 || (histactive & HA_INWORD) || (inbufflags & (INP_ALIAS|INP_HIST)) == INP_ALIAS) return; if (chwordpos%2) chwordpos--; /* make sure we're on a word start, not end */ - chwords[chwordpos++] = hptr - chline + offset; + DPUTS1(pos < 0, "History word position < 0 in %s", + dupstrpfx(chline, hptr-chline)); + if (pos < 0) + pos = 0; + chwords[chwordpos++] = pos; } /* Abort current history word, not needed */ -- cgit v1.2.3 From 63400fdbc5b8ce639a885629e4b1087b4277691d Mon Sep 17 00:00:00 2001 From: Marlon Richert Date: Tue, 6 Jun 2023 11:03:09 +0900 Subject: 51779: update completion test for 51761 --- ChangeLog | 5 +++++ Test/Y01completion.ztst | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1a703ec04..2c0f6287a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-06-06 Jun-ichi Takimoto + + * Marlon Richert: 51779: Test/Y01completion.ztst: update + completion test for 51761 + 2023-05-25 Peter Stephenson * 51739: Src/hist.c: detect invalid history word beginning. diff --git a/Test/Y01completion.ztst b/Test/Y01completion.ztst index a4060e9a4..fb369ea69 100644 --- a/Test/Y01completion.ztst +++ b/Test/Y01completion.ztst @@ -281,10 +281,10 @@ F:regression test workers/31611 comptesteval "typeset -a bar=({$'\\0'..$'\\C-?'})" comptesteval 'typeset -A bat=( "$bar[@]" )' comptesteval 'typeset bay="$bar"' - comptesteval 'zstyle ":completion:*:parameters" extra-verbose yes' + comptesteval 'zstyle ":completion:*:parameters" verbose yes' comptesteval 'zstyle ":completion:*" fake-parameters bar bat bay' comptest $': $ba\t' -0:extra-verbose shows parameter values +0:verbose shows parameter values >line: {: $ba}{} >DESCRIPTION:{parameter} >NO:{bar -- ( '^@' '^A' '^B' '^C' '^D' '^E' '^F' '^G' '^H' '\t' '\n' '^K' '^L' '} @@ -294,15 +294,15 @@ F:regression test workers/31611 comptesteval "path=( $ZTST_srcdir:A )" comptesteval 'typeset -H paths=HIDDEN' comptest $': $path\t' -0:extra-verbose doesn't show special or hidden parameter values +0:verbose doesn't show special or hidden parameter values >line: {: $path}{} >DESCRIPTION:{parameter} >NO:{path} >NO:{paths} - comptesteval 'zstyle -d ":completion:*:parameters" extra-verbose' + comptesteval 'zstyle -d ":completion:*:parameters" verbose' comptest $': $ba\t' -0:parameter values not shown without extra-verbose +0:parameter values not shown without verbose >line: {: $ba}{} >DESCRIPTION:{parameter} >NO:{bar} -- cgit v1.2.3 From 78102120b9c9e7485e7f537864fc2c24fbe0071a Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 6 Jun 2023 09:16:46 +0100 Subject: 51816: add :S history modifier with pattern match --- ChangeLog | 6 ++++++ Doc/Zsh/expn.yo | 18 ++++++++++++------ Src/hist.c | 17 ++++++++++++----- Src/subst.c | 12 +++++++++--- Test/D04parameter.ztst | 10 ++++++++++ 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2c0f6287a..c760fccab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-06-06 Peter Stephenson + + * 51816: Doc/Zsh/expn.yo, Src/hist.c, Src/subst.c, + Test/D04parameter.ztst: add :S history modifier with pattern + match. + 2023-06-06 Jun-ichi Takimoto * Marlon Richert: 51779: Test/Y01completion.ztst: update diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 6f86d0c54..7bc736470 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -312,7 +312,8 @@ zero) that are neither `tt(.)' nor `tt(/)' and that continue to the end of the string. For example, the extension of `tt(foo.orig.c)' is `tt(.c)', and `tt(dir.c/foo)' has no extension. ) -item(tt(s/)var(l)tt(/)var(r)[tt(/)])( +xitem(tt(s/)var(l)tt(/)var(r)[tt(/)]) +item(tt(S/)var(l)tt(/)var(r)[tt(/)])( Substitute var(r) for var(l) as described below. The substitution is done only for the first string that matches var(l). For arrays and for filename @@ -324,13 +325,17 @@ perform global substitution, i.e. substitute every occurrence of var(r) for var(l). Note that the tt(g) or tt(:G) must appear in exactly the position shown. +The use of tt(S) instead of tt(s) is identical except that +the source is treated as a pattern, just as if the option +tt(HIST_SUBST_PATTERN) were set. + See further notes on this form of substitution below. ) item(tt(&))( -Repeat the previous tt(s) substitution. Like tt(s), may be preceded -immediately by a tt(g). In parameter expansion the tt(&) must appear -inside braces, and in filename generation it must be quoted with a -backslash. +Repeat the previous tt(s) or tt(S) substitution, whichever was most +recent. Like tt(s) and tt(S), may be preceded immediately by a tt(g). +In parameter expansion the tt(&) must appear inside braces, and in +filename generation it must be quoted with a backslash. ) item(tt(t) [ var(digits) ])( Remove all leading pathname components, leaving the final component (tail). @@ -377,7 +382,8 @@ substitutions or expansions are performed once at the time the qualifier is parsed, even before the `tt(:s)' expression itself is divided into var(l) and var(r) sides. -If the option tt(HIST_SUBST_PATTERN) is set, var(l) is treated as +If the option tt(HIST_SUBST_PATTERN) is set or the original substitution +was started with a capital tt(S), var(l) is treated as a pattern of the usual form described in ifzman(the section FILENAME GENERATION below)\ ifnzman(noderef(Filename Generation)). This can be used in diff --git a/Src/hist.c b/Src/hist.c index 7e6394406..b4dc53d90 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -163,6 +163,11 @@ char *hsubl; /**/ char *hsubr; +/* state of histsubstpattern at last substitution */ + +/**/ +int hsubpatopt; + /* pointer into the history line */ /**/ @@ -624,7 +629,7 @@ histsubchar(int c) return substfailed(); if (!hsubl) return -1; - if (subst(&sline, hsubl, hsubr, gbal)) + if (subst(&sline, hsubl, hsubr, gbal, 0)) return substfailed(); } else { /* Line doesn't begin ^foo^bar */ @@ -831,7 +836,7 @@ histsubchar(int c) if ((c = ingetc()) == 'g') { gbal = 1; c = ingetc(); - if (c != 's' && c != '&') { + if (c != 's' && c != 'S' && c != '&') { zerr("'s' or '&' modifier expected after 'g'"); return -1; } @@ -891,11 +896,13 @@ histsubchar(int c) } break; case 's': + case 'S': + hsubpatopt = (c == 'S'); if (getsubsargs(sline, &gbal, &cflag)) return -1; /* fall through */ case '&': if (hsubl && hsubr) { - if (subst(&sline, hsubl, hsubr, gbal)) + if (subst(&sline, hsubl, hsubr, gbal, hsubpatopt)) return substfailed(); } else { herrflush(); @@ -2315,7 +2322,7 @@ casemodify(char *str, int how) /**/ int -subst(char **strptr, char *in, char *out, int gbal) +subst(char **strptr, char *in, char *out, int gbal, int forcepat) { char *str = *strptr, *substcut, *sptr; int off, inlen, outlen; @@ -2323,7 +2330,7 @@ subst(char **strptr, char *in, char *out, int gbal) if (!*in) in = str, gbal = 0; - if (isset(HISTSUBSTPATTERN)) { + if (isset(HISTSUBSTPATTERN) || forcepat) { int fl = SUB_LONG|SUB_REST|SUB_RETFAIL; char *oldin = in; if (gbal) diff --git a/Src/subst.c b/Src/subst.c index 974d6171e..14947ae36 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -4351,6 +4351,8 @@ modify(char **str, char **ptr, int inbrace) break; case 's': + case 'S': + hsubpatopt = (**ptr == 'S'); c = **ptr; (*ptr)++; ptr1 = *ptr; @@ -4445,7 +4447,7 @@ modify(char **str, char **ptr, int inbrace) break; case '&': - c = 's'; + c = hsubpatopt ? 'S' : 's'; break; case 'g': @@ -4534,8 +4536,10 @@ modify(char **str, char **ptr, int inbrace) copy = casemodify(tt, CASMOD_UPPER); break; case 's': + case 'S': + hsubpatopt = (c == 'S'); if (hsubl && hsubr) - subst(©, hsubl, hsubr, gbal); + subst(©, hsubl, hsubr, gbal, hsubpatopt); break; case 'q': copy = quotestring(copy, QT_BACKSLASH_SHOWNULL); @@ -4620,8 +4624,10 @@ modify(char **str, char **ptr, int inbrace) *str = casemodify(*str, CASMOD_UPPER); break; case 's': + case 'S': + hsubpatopt = (c == 'S'); if (hsubl && hsubr) - subst(str, hsubl, hsubr, gbal); + subst(str, hsubl, hsubr, gbal, hsubpatopt); break; case 'q': *str = quotestring(*str, QT_BACKSLASH); diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 7990c2958..2fd2f975f 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2754,3 +2754,13 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888 0:(users/28784 inspired this) substituting a single-quoted backslash, part #3: control >xfooy + spacestring="string with spaces" + print ${spacestring:gs/[[:space:]]/ /} + print ${spacestring:g&} + print ${spacestring:gS/[[:space:]]//} + print ${spacestring:g&} +0:Different behaviour of :s and :S modifiers +>string with spaces +>string with spaces +>stringwithspaces +>stringwithspaces -- cgit v1.2.3 From 0577dafcaa9d5f7cdbf5637b2dea5ed71dd5af81 Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Fri, 2 Jun 2023 16:09:53 +0100 Subject: Protect some :s from history modifier expansion --- ChangeLog | 3 +++ Completion/Unix/Command/_ant | 4 ++-- Completion/Unix/Command/_ant.rej | 13 +++++++++++++ Completion/Unix/Command/_ffmpeg | 2 +- Completion/Unix/Command/_java | 4 ++-- Completion/Unix/Command/_subversion | 4 ++-- Completion/Zsh/Command/_cd | 2 +- 7 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 Completion/Unix/Command/_ant.rej diff --git a/ChangeLog b/ChangeLog index c760fccab..b94a009e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-06-06 Peter Stephenson + * Stephane: 51817: Protect some use of ':' from history modifier + interpreation. + * 51816: Doc/Zsh/expn.yo, Src/hist.c, Src/subst.c, Test/D04parameter.ztst: add :S history modifier with pattern match. diff --git a/Completion/Unix/Command/_ant b/Completion/Unix/Command/_ant index 7401c7449..36c7c0e89 100644 --- a/Completion/Unix/Command/_ant +++ b/Completion/Unix/Command/_ant @@ -79,8 +79,8 @@ case $state in compset -P '*:' compset -S ':*' _alternative \ - "classpath:$state:_path_files -qS: -g '*.(jar|zip)(-.)'" \ - "classpath:$state:_path_files -r': ' -/" && ret=0 + "classpath:${state}:_path_files -qS: -g '*.(jar|zip)(-.)'" \ + "classpath:${state}:_path_files -r': ' -/" && ret=0 ;; property) if compset -P 1 '*='; then diff --git a/Completion/Unix/Command/_ant.rej b/Completion/Unix/Command/_ant.rej new file mode 100644 index 000000000..15e26c9da --- /dev/null +++ b/Completion/Unix/Command/_ant.rej @@ -0,0 +1,13 @@ +--- Completion/Unix/Command/_ant ++++ Completion/Unix/Command/_ant +@@ -79,8 +79,8 @@ case $state in + compset -P '*:' + compset -S ':*' + _alternative \ +- "classpath:$state:_path_files -qS: -g '*.(jar|zip)(-.)'" \ +- "classpath:$state:_path_files -r': ' -/" && ret=0 ++ "classpath:${state}:_path_files -qS: -g '*.(jar|zip)(-.)'" \ ++ "classpath:${state}:_path_files -r': ' -/" && ret=0 + ;; + property) + if compset -P 1 '*='; then diff --git a/Completion/Unix/Command/_ffmpeg b/Completion/Unix/Command/_ffmpeg index 1329939cd..e5afdac4f 100644 --- a/Completion/Unix/Command/_ffmpeg +++ b/Completion/Unix/Command/_ffmpeg @@ -125,7 +125,7 @@ local -a _ffmpeg_argspecs lastopt_description=${lastopt_description//:/\\:} if [[ $example == filename ]]; then lastopt_takesargs=0 - lastopt+=":$lastopt_description:_files" + lastopt+=":${lastopt_description}:_files" elif [[ $lastopt == -[asv]pre ]]; then lastopt_takesargs=0 lastopt="*$lastopt" diff --git a/Completion/Unix/Command/_java b/Completion/Unix/Command/_java index ff6e82645..b2352df7b 100644 --- a/Completion/Unix/Command/_java +++ b/Completion/Unix/Command/_java @@ -438,8 +438,8 @@ classpath|sourcepath|bootstrapclasspath|docletpath) compset -P '*:' compset -S ':*' _alternative \ - "classpath:$state:_path_files -qS: -g '*.(jar|zip)(-.)'" \ - "classpath:$state:_path_files -r': ' -/" && return + "classpath:${state}:_path_files -qS: -g '*.(jar|zip)(-.)'" \ + "classpath:${state}:_path_files -r': ' -/" && return ;; extdirs) diff --git a/Completion/Unix/Command/_subversion b/Completion/Unix/Command/_subversion index 9a0328dca..ccaf310fa 100644 --- a/Completion/Unix/Command/_subversion +++ b/Completion/Unix/Command/_subversion @@ -139,7 +139,7 @@ _svn () { ;; (commit) args=( - ${args/(#b)(*--file*):arg:/$match[1]:file:_files} + ${args/(#b)(*--file*):arg:/${match[1]}:file:_files} '*:file: _svn_modified "committable"' ) ;; @@ -189,7 +189,7 @@ _svn () { args=( ':propname:(svn:ignore svn:keywords svn:executable svn:eol-style svn:mime-type svn:externals svn:needs-lock svn:global-ignores svn:auto-props)' ':propval:->propset_propval' - ${args/(#b)(*--file*):arg:/$match[1]:file:_files} + ${args/(#b)(*--file*):arg:/${match[1]}:file:_files} '*:path or url: _alternative "files:file:_files" "urls:URL:_svn_urls"' ) ;; diff --git a/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd index 961d121e0..9ca846c8f 100644 --- a/Completion/Zsh/Command/_cd +++ b/Completion/Zsh/Command/_cd @@ -73,7 +73,7 @@ else if zstyle -t ":completion:${curcontext}:path-directories" separate-sections; then local elem for ((elem=1; elem <= $#tmpcdpath; elem++)); do - alt+=( "path-directories-$elem:directory in $tmpcdpath[$elem]:_path_files -W 'tmpcdpath[$elem]' -/" ) + alt+=( "path-directories-${elem}:directory in ${tmpcdpath[$elem]}:_path_files -W 'tmpcdpath[$elem]' -/" ) done else (( $#tmpcdpath )) && -- cgit v1.2.3 From 58852b3246e41be1512d5d167bb47b69c099c324 Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Fri, 2 Jun 2023 16:29:32 +0100 Subject: Protect another : from history modifier expansion --- ChangeLog | 2 ++ Completion/Solaris/Command/_ipadm | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b94a009e7..e1cd64c91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-06-06 Peter Stephenson + * Stephan: 51818: Protect another ':'. + * Stephane: 51817: Protect some use of ':' from history modifier interpreation. diff --git a/Completion/Solaris/Command/_ipadm b/Completion/Solaris/Command/_ipadm index 34d1eacba..c59fc8108 100644 --- a/Completion/Solaris/Command/_ipadm +++ b/Completion/Solaris/Command/_ipadm @@ -136,7 +136,7 @@ _ipadm() { proto_icmp_properties=( "max_buf" "recv_buf" "send_buf" ) proto_all_properties=( $proto_ipv4_properties $proto_ipv6_properties $proto_tcp_properties $proto_udp_properties $proto_sctp_properties $proto_icmp_properties ) - proto_all_properties=( $^proto_all_properties:value:_ipadm_get_possible_values ) + proto_all_properties=( ${^proto_all_properties}:value:_ipadm_get_possible_values ) proto_propproperties=( "proto" "property" "perm" "current" "persistent" "default" "possible" ) -- cgit v1.2.3 From 2778fc5d7a1bf974147ee7e9b116adac97e20eea Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Thu, 8 Jun 2023 15:25:13 +0900 Subject: 51817: protect ':' in _rcctl This was in 51817 but missed in commit 0577daf. Also remove _ant.rej that was added by the commit. --- ChangeLog | 5 +++++ Completion/BSD/Command/_rcctl | 2 +- Completion/Unix/Command/_ant.rej | 13 ------------- 3 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 Completion/Unix/Command/_ant.rej diff --git a/ChangeLog b/ChangeLog index e1cd64c91..16ce32b54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-06-08 Jun-ichi Takimoto + + * Stephane: 51817: Completion/BSD/Command/_rcctl: protect ':' + in _rcctl (was in 51817 but missed in commit 0577daf) + 2023-06-06 Peter Stephenson * Stephan: 51818: Protect another ':'. diff --git a/Completion/BSD/Command/_rcctl b/Completion/BSD/Command/_rcctl index 98e4f9846..457c3eb85 100644 --- a/Completion/BSD/Command/_rcctl +++ b/Completion/BSD/Command/_rcctl @@ -46,6 +46,6 @@ case $service in '*:argument:' ;; ${(~j:|:)actions}|disable|enable) - _arguments "*:service to $words[2]:_services" + _arguments "*:service to ${words[2]}:_services" ;; esac diff --git a/Completion/Unix/Command/_ant.rej b/Completion/Unix/Command/_ant.rej deleted file mode 100644 index 15e26c9da..000000000 --- a/Completion/Unix/Command/_ant.rej +++ /dev/null @@ -1,13 +0,0 @@ ---- Completion/Unix/Command/_ant -+++ Completion/Unix/Command/_ant -@@ -79,8 +79,8 @@ case $state in - compset -P '*:' - compset -S ':*' - _alternative \ -- "classpath:$state:_path_files -qS: -g '*.(jar|zip)(-.)'" \ -- "classpath:$state:_path_files -r': ' -/" && ret=0 -+ "classpath:${state}:_path_files -qS: -g '*.(jar|zip)(-.)'" \ -+ "classpath:${state}:_path_files -r': ' -/" && ret=0 - ;; - property) - if compset -P 1 '*='; then -- cgit v1.2.3 From cd1a0a70972e717aa93c5fd6b36f476b5593c206 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 8 Jun 2023 15:36:31 +0900 Subject: 51826: correctly read metafied null character from history file --- ChangeLog | 3 +++ Src/hist.c | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16ce32b54..ca290ea2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-06-08 Jun-ichi Takimoto + * 51826: Src/hist.c: correctly handle metafied null character + when reading history file + * Stephane: 51817: Completion/BSD/Command/_rcctl: protect ':' in _rcctl (was in 51817 but missed in commit 0577daf) diff --git a/Src/hist.c b/Src/hist.c index b4dc53d90..bfbcd6ede 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -3803,8 +3803,14 @@ histsplitwords(char *lineptr, short **wordsp, int *nwordsp, int *nwordposp, zrealloc(words, nwords*sizeof(*words)); } words[nwordpos++] = lineptr - start; - while (*lineptr && !inblank(*lineptr)) - lineptr++; + while (*lineptr) { + if (*lineptr == Meta && lineptr[1]) + lineptr += 2; + else if (!inblank(*lineptr)) + lineptr++; + else + break; + } words[nwordpos++] = lineptr - start; } } while (*lineptr); -- cgit v1.2.3 From ecd3f9c9506c7720dc6c0833dc5d5eb00e4459c4 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 19 Jun 2023 11:19:25 +0900 Subject: 51862: support texinfo-7.0 --- ChangeLog | 4 ++++ Doc/Makefile.in | 3 ++- configure.ac | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ca290ea2a..14349dcf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-06-19 Jun-ichi Takimoto + + * 51862: Doc/Makefile.in, configure.ac: support texinfo-7.0 + 2023-06-08 Jun-ichi Takimoto * 51826: Src/hist.c: correctly handle metafied null character diff --git a/Doc/Makefile.in b/Doc/Makefile.in index 136b080d6..dabe11fe3 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -43,6 +43,7 @@ TEXI2DVI = @TEXI2DVI@ DVIPS = dvips TEXI2PDF = @TEXI2PDF@ TEXI2HTML = @TEXI2HTML@ +SET_TEXI2ANY_VAR = @SET_TEXI2ANY_VAR@ PAPERSIZE = @PAPERSIZE@ .SUFFIXES: .yo .1 @@ -266,7 +267,7 @@ texi2html.conf: $(sdir_top)/Config/version.mk d=`echo $(VERSION_DATE)`; \ v="Zsh version $(VERSION), released on $$d."; \ case '$(TEXI2HTML)' in \ - *texi2any*) echo "set_from_init_file('PRE_BODY_CLOSE','$$v');" ;; \ + *texi2any*) echo "$(SET_TEXI2ANY_VAR)('PRE_BODY_CLOSE','$$v');" ;; \ *) echo "\$$PRE_BODY_CLOSE = '$$v';" ;; \ esac > $@ diff --git a/configure.ac b/configure.ac index 4710d1659..ba76f9a60 100644 --- a/configure.ac +++ b/configure.ac @@ -623,7 +623,12 @@ fi if test x"$TEXI2HTML" = xtexi2any; then TEXI2HTML='texi2any -c TEXI2HTML=1' + case `texi2any --version 2>/dev/null | sed -e 's/^.*) *//' -e 1q` in + [[1-6]].*) SET_TEXI2ANY_VAR=set_from_init_file ;; + *) SET_TEXI2ANY_VAR=texinfo_set_from_init_file ;; + esac fi +AC_SUBST(SET_TEXI2ANY_VAR) case "$LC_PAPER" in ??_US*) PAPERSIZE=us ;; -- cgit v1.2.3 From 10bdbd8b5b0b43445aff23dcd412f25cf6aa328a Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 20 Jun 2023 18:14:27 +0900 Subject: 51877: do not build pcre module if pcre2-config is not found --- ChangeLog | 5 +++++ Src/Modules/pcre.mdd | 2 +- configure.ac | 31 +++++++++++++++++++------------ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 14349dcf2..e89ffee1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-06-20 Jun-ichi Takimoto + + * 51877: Src/Modules/pcre.mdd, configure.ac: do not build pcre + module if pcre2-config is not available. + 2023-06-19 Jun-ichi Takimoto * 51862: Doc/Makefile.in, configure.ac: support texinfo-7.0 diff --git a/Src/Modules/pcre.mdd b/Src/Modules/pcre.mdd index 6eb3c691b..3e1579117 100644 --- a/Src/Modules/pcre.mdd +++ b/Src/Modules/pcre.mdd @@ -1,5 +1,5 @@ name=zsh/pcre -link=`if test x$enable_pcre = xyes && (pcre-config --version >/dev/null 2>/dev/null); then echo dynamic; else echo no; fi` +link=`if test x$enable_pcre = xyes; then echo dynamic; else echo no; fi` load=no autofeatures="b:pcre_compile b:pcre_study b:pcre_match" diff --git a/configure.ac b/configure.ac index ba76f9a60..c5263035e 100644 --- a/configure.ac +++ b/configure.ac @@ -440,6 +440,17 @@ dnl Do you want to look for pcre support? AC_ARG_ENABLE(pcre, AS_HELP_STRING([--enable-pcre],[enable the search for the pcre2 library (may create run-time library dependencies)])) +AC_ARG_VAR(PCRE_CONFIG, [pathname of pcre2-config if it is not in PATH]) +if test "x$enable_pcre" = xyes; then + AC_CHECK_PROG([PCRE_CONFIG], pcre2-config, pcre2-config) + if test "x$PCRE_CONFIG" = x; then + enable_pcre=no + AC_MSG_WARN([pcre2-config not found: pcre module is disabled.]) + AC_MSG_NOTICE( + [Set PCRE_CONFIG to pathname of pcre2-config if it is not in PATH.]) + fi +fi + dnl Do you want to look for capability support? AC_ARG_ENABLE(cap, AS_HELP_STRING([--enable-cap],[enable the search for POSIX capabilities (may require additional headers to be added by hand)])) @@ -655,15 +666,12 @@ AC_HEADER_DIRENT AC_HEADER_STAT AC_HEADER_SYS_WAIT -oldcflags="$CFLAGS" -if test x$enable_pcre = xyes; then -AC_CHECK_PROG([PCRECONF], pcre2-config, pcre2-config) dnl pcre2-config --cflags may produce a -I output which needs to go into dnl CPPFLAGS else configure's preprocessor tests don't pick it up, dnl producing a warning. -if test "x$ac_cv_prog_PCRECONF" = xpcre2-config; then - CPPFLAGS="$CPPFLAGS `pcre2-config --cflags`" -fi +if test "x$enable_pcre" = xyes; then + CPPFLAGS="`$PCRE_CONFIG --cflags` $CPPFLAGS" + AC_CHECK_HEADERS([pcre2.h],,,[#define PCRE2_CODE_UNIT_WIDTH 8]) fi AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \ @@ -675,7 +683,6 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \ netinet/in_systm.h langinfo.h wchar.h stddef.h \ sys/stropts.h iconv.h ncurses.h ncursesw/ncurses.h \ ncurses/ncurses.h) -AC_CHECK_HEADERS([pcre2.h],,,[#define PCRE2_CODE_UNIT_WIDTH 8]) if test x$dynamic = xyes; then AC_CHECK_HEADERS(dlfcn.h) AC_CHECK_HEADERS(dl.h) @@ -952,10 +959,6 @@ if test "x$ac_found_iconv" = "xyes"; then [Define as const if the declaration of iconv() needs const.]) fi -if test x$enable_pcre = xyes; then - LIBS="`$ac_cv_prog_PCRECONF --libs8` $LIBS" -fi - dnl --------------------- dnl CHECK TERMCAP LIBRARY dnl --------------------- @@ -1316,7 +1319,6 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ pathconf sysconf \ tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \ getcchar setcchar waddwstr wget_wch win_wch use_default_colors \ - pcre2_compile_8 \ nl_langinfo \ erand48 open_memstream \ posix_openpt \ @@ -1371,6 +1373,11 @@ if test x$zsh_cv_func_realpath_accepts_null = xyes; then AC_DEFINE(REALPATH_ACCEPTS_NULL) fi +if test x$enable_pcre = xyes; then + LIBS="`$PCRE_CONFIG --libs8` $LIBS" + AC_CHECK_FUNCS(pcre2_compile_8) +fi + if test x$enable_cap = xyes; then AC_CHECK_FUNCS(cap_get_proc) fi -- cgit v1.2.3 From 4f6a1b3717bb84b8243b13c4ec9171945893c934 Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Thu, 22 Jun 2023 12:52:12 -0700 Subject: 51813: differentiate empty $2 from omitted $2 in version comparisons --- ChangeLog | 7 ++++++- Functions/Misc/is-at-least | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e89ffee1b..fc3818213 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-06-22 Bart Schaefer + + * Stephane: 51813: Functions/Misc/is-at-least: differentiate empty + $2 from omitted $2 to avoid wrong comparisons against ZSH_VERSION. + 2023-06-20 Jun-ichi Takimoto * 51877: Src/Modules/pcre.mdd, configure.ac: do not build pcre @@ -17,7 +22,7 @@ 2023-06-06 Peter Stephenson - * Stephan: 51818: Protect another ':'. + * Stephane: 51818: Protect another ':'. * Stephane: 51817: Protect some use of ':' from history modifier interpreation. diff --git a/Functions/Misc/is-at-least b/Functions/Misc/is-at-least index d4ff3552a..5985684be 100644 --- a/Functions/Misc/is-at-least +++ b/Functions/Misc/is-at-least @@ -24,8 +24,14 @@ emulate -L zsh local IFS=".-" min_cnt=0 ver_cnt=0 part min_ver version order +: ${2=$ZSH_VERSION} + +# sort out the easy corner cases first +[[ $1 = $2 ]] && return 0 # same version +[[ -n $2 ]] || return 1 # no version + min_ver=(${=1}) -version=(${=2:-$ZSH_VERSION} 0) +version=(${=2} 0) while (( $min_cnt <= ${#min_ver} )); do while [[ "$part" != <-> ]]; do -- cgit v1.2.3 From 6c993144bde84e145800ff007b1c698a867c7196 Mon Sep 17 00:00:00 2001 From: Marlon Richert Date: Thu, 22 Jun 2023 13:13:09 -0700 Subject: 51860: simplify suffix handling in _prefix to remove less accurate hack This solves the following problems in the _prefix completer: - The old code had logic for dealing with compstate[unambiguous] that was unnecessary. It works fine without it. - Because of this logic, if a widget set compstate[insert]=1 after calling _main_complete, an `x` was left after the completion on the command line. - If the same widget also set `compstate[to_end]=`, then instead, the last character of the inserted completion would be treated as an autoremovable suffix, with the actual suffix being inserted to the line as a normal character. - After inserting a completion, the cursor would move to the end of the entire current word on the command, not the end of word that was inserted. This is not what you want with _prefix, since you are trying to complete a word _before_ the one on the command line, after which you usually want to insert a separator, such as a space or slash, before the next word. --- Completion/Base/Completer/_prefix | 9 ++------ Test/Y01completion.ztst | 48 +++++++++++++++++++++++++++++++++++++++ Test/comptest | 8 ++++++- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/Completion/Base/Completer/_prefix b/Completion/Base/Completer/_prefix index 74be5f47d..aea2f7863 100644 --- a/Completion/Base/Completer/_prefix +++ b/Completion/Base/Completer/_prefix @@ -49,13 +49,8 @@ for tmp in "$comp[@]"; do fi if [[ "$tmp" != _prefix ]] && "$tmp"; then - [[ compstate[nmatches] -gt 1 ]] && return 0 - compadd -U -i "$IPREFIX" -I "$ISUFFIX" - "${compstate[unambiguous]%$suf}x" - compstate[list]= - if [[ -n $compstate[unambiguous] ]]; then - compstate[insert]=unambiguous - else - compstate[insert]=0 + if [[ -n $compstate[old_list] || ${compstate[unambiguous]%$suf} == $PREFIX ]]; then + compstate[to_end]=match fi return 0 fi diff --git a/Test/Y01completion.ztst b/Test/Y01completion.ztst index fb369ea69..fc18b19a4 100644 --- a/Test/Y01completion.ztst +++ b/Test/Y01completion.ztst @@ -35,6 +35,54 @@ >line: {: dir1/}{} >line: {: dir2/}{} + comptest $': d\t\t\t\t\t \t' +0:unambiguous prefix and autoremovable suffix +>line: {: dir}{} +>line: {: dir}{} +>DESCRIPTION:{file} +>DI:{dir1} +>DI:{dir2} +>line: {: dir1/}{} +>line: {: dir2/}{} +>line: {: dir1/}{} +>line: {: dir1 }{} +>DESCRIPTION:{file} +>DI:{dir1} +>DI:{dir2} +>FI:{file1} +>FI:{file2} + + comptest $': suf\ebd\t\t\t\t\t \t' +0:unambiguous prefix and autoremovable suffix with _prefix completer +>line: {: dir}{suf} +>line: {: dir}{suf} +>DESCRIPTION:{file} +>DI:{dir1} +>DI:{dir2} +>line: {: dir1/}{suf} +>line: {: dir2/}{suf} +>line: {: dir1/}{suf} +>line: {: dir1 }{suf} +>DESCRIPTION:{file} +>DI:{dir1} +>DI:{dir2} +>FI:{file1} +>FI:{file2} +F:regression test workers/51641 + + comptesteval 'comptest-postfunc() { compstate[insert]=1 compstate[list]= }' + comptest $': \t \t' +0:compstate[insert]=1 compstate[list]= +>line: {: dir1/}{} +>line: {: dir1 dir1/}{} + + comptest $': suf\eb\t \t' +0:compstate[insert]=1 compstate[list]= with _prefix completer +>line: {: dir1/}{suf} +>line: {: dir1 dir1/}{suf} +F:regression test workers/51641 + + comptesteval 'comptest-postfunc() {}' comptest $': *\t\t\t\t\t\t' 0:_expand shows file types >line: {: dir1/}{} diff --git a/Test/comptest b/Test/comptest index 79c69979a..39ad14768 100644 --- a/Test/comptest +++ b/Test/comptest @@ -40,7 +40,7 @@ KEYTIMEOUT=1 setopt zle autoload -U compinit compinit -u -zstyle ":completion:*" completer _expand _complete _ignored +zstyle ":completion:*" completer _expand _complete _prefix _ignored zstyle ":completion:*:default" list-colors "no=" "fi=" "di=" "ln=" "pi=" "so=" "bd=" "cd=" "ex=" "mi=" "tc=" "sp=" "lc=" "ec=\n" "rc=" zstyle ":completion:*" group-name "" zstyle ":completion:*:messages" format "%d @@ -51,6 +51,12 @@ zstyle ":completion:*:options" verbose yes zstyle ":completion:*:values" verbose yes setopt noalwayslastprompt listrowsfirst completeinword zmodload zsh/complist +zle -C complete-word complete-word complete-word-with-postfunc +complete-word-with-postfunc() { + local +h -a comppostfuncs=( comptest-postfunc ) + _main_complete "$@" +} +comptest-postfunc() {} complete-word-with-report () { print -lr "" zle complete-word -- cgit v1.2.3 From e7a8dbb16c6c779211c56ecd20cd82ecc138ed2a Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 22 Jun 2023 13:15:40 -0700 Subject: Missed ChangeLog entry from previous commit. --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index fc3818213..e48073e80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-06-22 Bart Schaefer + * Marlon Richert: 51860: Completion/Base/Completer/_prefix, + Test/Y01completion.ztst, Test/comptest: simplify suffix handling + in _prefix to remove longstanding and less accurate hack; tests. + * Stephane: 51813: Functions/Misc/is-at-least: differentiate empty $2 from omitted $2 to avoid wrong comparisons against ZSH_VERSION. -- cgit v1.2.3 From 4345eed1fe5dd6c881b948331cfa8f4a48beda42 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 22 Jun 2023 13:36:40 -0700 Subject: 51887: namespaces recognized in math, incorrect usages rejected. --- ChangeLog | 3 +++ Src/math.c | 10 +++++++--- Src/params.c | 27 +++++++++++++++++++++++++- Test/K02parameter.ztst | 52 ++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 86 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index e48073e80..0011cc947 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-06-22 Bart Schaefer + * 51887: Src/math.c, Src/params.c, Test/K02parameter.ztst: + namespaces recognized in math, incorrect usages rejected. + * Marlon Richert: 51860: Completion/Base/Completer/_prefix, Test/Y01completion.ztst, Test/comptest: simplify suffix handling in _prefix to remove longstanding and less accurate hack; tests. diff --git a/Src/math.c b/Src/math.c index 12c8d6f6b..a060181ed 100644 --- a/Src/math.c +++ b/Src/math.c @@ -641,7 +641,9 @@ zzlex(void) return MINUSEQ; } if (unary) { - if (idigit(*ptr) || *ptr == '.') { + if (idigit(*ptr) || + (*ptr == '.' && + (idigit(ptr[1]) || !itype_end(ptr, INAMESPC, 0)))) { int ctype = lexconstant(); if (ctype == NUM) { @@ -835,7 +837,9 @@ zzlex(void) case Dnull: break; default: - if (idigit(*--ptr) || *ptr == '.') + if (idigit(*--ptr) || + (*ptr == '.' && + (idigit(ptr[1]) || !itype_end(ptr, INAMESPC, 0)))) return lexconstant(); if (*ptr == '#') { if (*++ptr == '\\' || *ptr == '#') { @@ -857,7 +861,7 @@ zzlex(void) } cct = 1; } - if ((ie = itype_end(ptr, IIDENT, 0)) != ptr) { + if ((ie = itype_end(ptr, INAMESPC, 0)) != ptr) { int func = 0; char *p; diff --git a/Src/params.c b/Src/params.c index 021d341e8..2b0837e03 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1226,6 +1226,26 @@ isident(char *s) if (!*s) /* empty string is definitely not valid */ return 0; + /* This partly duplicates code in itype_end(), but we need to + * distinguish the leading namespace at this point to check the + * correctness of the identifier that follows + */ + if (*s == '.') { + if (idigit(s[1])) + return 0; /* Namespace must not start with a digit */ + /* Reject identifiers beginning with a digit in namespaces. + * Move this out below this block to also reject v.1x form. + */ + if ((ss = itype_end(s + (*s == '.'), IIDENT, 0))) { + if (*ss == '.') { + if (!ss[1]) + return 0; + if (idigit(ss[1])) + s = ss + 1; + } + } + } + if (idigit(*s)) { /* If the first character is `s' is a digit, then all must be */ for (ss = ++s; *ss; ss++) @@ -2148,7 +2168,12 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) pm = (Param) paramtab->getnode2(paramtab, *t == '0' ? "0" : t); else pm = (Param) paramtab->getnode(paramtab, *t == '0' ? "0" : t); - if (sav) + if (!pm && *t == '.' && !isident(t)) { + /* badly formed namespace reference */ + if (sav) + *s = sav; + return NULL; + } else if (sav) *s = sav; *pptr = s; if (!pm || ((pm->node.flags & PM_UNSET) && diff --git a/Test/K02parameter.ztst b/Test/K02parameter.ztst index 8a1be1e36..0b1a8dd4a 100644 --- a/Test/K02parameter.ztst +++ b/Test/K02parameter.ztst @@ -100,7 +100,55 @@ F:Braces are required >.k02.array >characters + k.=empty k.2=test - print ${k.2} + print ${k.} ${k.2} 0:Parse without leading dot (future proofing) ->test +>empty test + + .k=OK + print ${.k} +0:Bare namespace is usable (ksh compatibility) +>OK + + .k.=empty +1:Namespace must precede an identifier, assignment +?(eval):1: not an identifier: .k. + + typeset .k.=empty +1:Namespace must precede an identifier, typeset +?(eval):typeset:1: not valid in this context: .k. + + print ${.k.} +1:Namespace must precede an identifier, reference +?(eval):1: bad substitution + + .2.b=not +1:Namespace identifier must not begin with a digit, assignment +?(eval):1: not an identifier: .2.b + + typeset .2.b=not +1:Namespace identifier must not begin with a digit, typeset +?(eval):typeset:1: not valid in this context: .2.b + + print ${.2.b} +1:Namespace identifier must not begin with a digit, reference +?(eval):1: bad substitution + + .not.2b=question +1:Identifier starting with a digit must be all digits, assignment +?(eval):1: not an identifier: .not.2b + + typeset .not.2b=question +1:Identifier starting with a digit must be all digits, typeset +?(eval):typeset:1: not valid in this context: .not.2b + + print ${.not.2b} +1:Identifier starting with a digit must be all digits, reference +?(eval):1: bad substitution + + integer .var.d=0 + float .var.f=.2 + print $((.var.x = ++.var.d - -.var.f)) +0:Namespaces in math context +>1.2 -- cgit v1.2.3 From 1b9bc3441ca0e6d155243084d6e7b98925dc02cb Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 26 Jun 2023 16:52:40 +0900 Subject: 51884: reset IFS if it contains invalid characters This happens only if MULTIBYTE option is on. --- ChangeLog | 6 ++++++ Doc/Zsh/params.yo | 7 +++++-- Src/params.c | 3 +++ Src/utils.c | 42 ++++++++++++++++++++++++++---------------- Test/D04parameter.ztst | 21 +++++++++++++++++++++ 5 files changed, 61 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0011cc947..51a091aff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-06-26 Jun-ichi Takimoto + + * 51884: Doc/Zsh/params.yo, Src/params.c, Src/utils.c, + Test/D04parameter.ztst: if MULTIBYTE option is on and IFS contains + invalid bytes in curret locale then reset it to default + 2023-06-22 Bart Schaefer * 51887: Src/math.c, Src/params.c, Test/K02parameter.ztst: diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 57d10b8bd..e0410d673 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1325,15 +1325,18 @@ Internal field separators (by default space, tab, newline and NUL), that are used to separate words which result from command or parameter expansion and words read by the tt(read) builtin. Any characters from the set space, tab and -newline that appear in the IFS are called em(IFS white space). +newline that appear in the tt(IFS) are called em(IFS white space). One or more IFS white space characters or one non-IFS white space character together with any adjacent IFS white space character delimit a field. If an IFS white space character appears twice consecutively -in the IFS, this character is treated as if it were not an IFS white +in the tt(IFS), this character is treated as if it were not an IFS white space character. If the parameter is unset, the default is used. Note this has a different effect from setting the parameter to an empty string. + +If tt(MULTIBYTE) option is on and tt(IFS) contains invalid characters in +the current locale, it is reset to the default. ) vindex(KEYBOARD_HACK) item(tt(KEYBOARD_HACK))( diff --git a/Src/params.c b/Src/params.c index 2b0837e03..f5750a4b4 100644 --- a/Src/params.c +++ b/Src/params.c @@ -4748,6 +4748,7 @@ setlang(char *x) if ((x = getsparam_u(ln->name)) && *x) setlocale(ln->category, x); unqueue_signals(); + inittyptab(); } /**/ @@ -4771,6 +4772,7 @@ lc_allsetfn(Param pm, char *x) else { setlocale(LC_ALL, unmeta(x)); clear_mbstate(); + inittyptab(); } } @@ -4809,6 +4811,7 @@ lcsetfn(Param pm, char *x) } unqueue_signals(); clear_mbstate(); /* LC_CTYPE may have changed */ + inittyptab(); } #endif /* USE_LOCALE */ diff --git a/Src/utils.c b/Src/utils.c index f13e3a79d..94a33453f 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -74,9 +74,6 @@ set_widearray(char *mb_array, Widechar_array wca) } wca->len = 0; - if (!isset(MULTIBYTE)) - return; - if (mb_array) { VARARR(wchar_t, tmpwcs, strlen(mb_array)); wchar_t *wcptr = tmpwcs; @@ -87,8 +84,7 @@ set_widearray(char *mb_array, Widechar_array wca) int mblen; if ((unsigned char) *mb_array <= 0x7f) { - mb_array++; - *wcptr++ = (wchar_t)*mb_array; + *wcptr++ = (wchar_t)*mb_array++; continue; } @@ -4121,8 +4117,9 @@ inittyptab(void) * having IIDENT here is a good idea at all, but this code * should disappear into history... */ - for (t0 = 0240; t0 != 0400; t0++) - typtab[t0] = IALPHA | IALNUM | IIDENT | IUSER | IWORD; + if isset(MULTIBYTE) + for (t0 = 0240; t0 != 0400; t0++) + typtab[t0] = IALPHA | IALNUM | IIDENT | IUSER | IWORD; #endif /* typtab['.'] |= IIDENT; */ /* Allow '.' in variable names - broken */ typtab['_'] = IIDENT | IUSER; @@ -4137,11 +4134,24 @@ inittyptab(void) typtab[t0] |= ITOK | IMETA; for (t0 = (int) (unsigned char) Snull; t0 <= (int) (unsigned char) Nularg; t0++) typtab[t0] |= ITOK | IMETA | INULL; - for (s = ifs ? ifs : EMULATION(EMULATE_KSH|EMULATE_SH) ? - DEFAULT_IFS_SH : DEFAULT_IFS; *s; s++) { + /* ifs */ +#define CURRENT_DEFAULT_IFS (EMULATION(EMULATE_KSH|EMULATE_SH) ? \ + DEFAULT_IFS_SH : DEFAULT_IFS) +#ifdef MULTIBYTE_SUPPORT + if (isset(MULTIBYTE)) { + set_widearray(ifs ? ifs : CURRENT_DEFAULT_IFS, &ifs_wide); + if (ifs && !ifs_wide.chars) { + zwarn("IFS has an invalid character; resetting IFS to default"); + zsfree(ifs); + ifs = ztrdup(CURRENT_DEFAULT_IFS); + set_widearray(ifs, &ifs_wide); + } + } +#endif + for (s = ifs ? ifs : CURRENT_DEFAULT_IFS; *s; s++) { int c = (unsigned char) (*s == Meta ? *++s ^ 32 : *s); #ifdef MULTIBYTE_SUPPORT - if (!isascii(c)) { + if (isset(MULTIBYTE) && !isascii(c)) { /* see comment for wordchars below */ continue; } @@ -4154,10 +4164,15 @@ inittyptab(void) } typtab[c] |= ISEP; } + /* wordchars */ +#ifdef MULTIBYTE_SUPPORT + if (isset(MULTIBYTE)) + set_widearray(wordchars, &wordchars_wide); +#endif for (s = wordchars ? wordchars : DEFAULT_WORDCHARS; *s; s++) { int c = (unsigned char) (*s == Meta ? *++s ^ 32 : *s); #ifdef MULTIBYTE_SUPPORT - if (!isascii(c)) { + if (isset(MULTIBYTE) && !isascii(c)) { /* * If we have support for multibyte characters, we don't * handle non-ASCII characters here; instead, we turn @@ -4170,11 +4185,6 @@ inittyptab(void) #endif typtab[c] |= IWORD; } -#ifdef MULTIBYTE_SUPPORT - set_widearray(wordchars, &wordchars_wide); - set_widearray(ifs ? ifs : EMULATION(EMULATE_KSH|EMULATE_SH) ? - DEFAULT_IFS_SH : DEFAULT_IFS, &ifs_wide); -#endif for (s = SPECCHARS; *s; s++) typtab[(unsigned char) *s] |= ISPECIAL; if (typtab_flags & ZTF_SP_COMMA) diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 2fd2f975f..0d44558a7 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2280,6 +2280,27 @@ F:We do not care what $OLDPWD is, as long as it does not cause an error F:As of this writing, var=$@ and var="$@" with null IFS have unspecified F:behavior, see http://austingroupbugs.net/view.php?id=888 + ( + IFS=$'\x80' + if [[ $IFS = $' \t\n\0' ]]; then + echo OK # if $'\x80' is illegal (e.g. Linux) + else # otherwise (e.g. macOS), it should work as a separator + s=$'foo\x80\bar' + [[ ${${=s}[1]} = foo ]] && echo OK + fi + ) +0D:reset IFS to default if it contains illegal character +>OK + + ( + unsetopt multibyte + IFS=$'\xc3\xa9' + s=$'foo\xc3bar\xa9boo' + echo ${${=s}[2]} + ) +0:eight bit chars in IFS should work if multibute option is off +>bar + () { setopt localoptions extendedglob [[ $- = [[:alnum:]]## ]] || print Failed 1 -- cgit v1.2.3 From a84fdd7c8f77935ecce99ff2b0bdba738821ed79 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 26 Jun 2023 17:13:04 +0900 Subject: 51889: fix module loading problem with full RELRO If full RELRO (relocation read-only, one of the security enhancement methods for ELF-based systems) is used when building zsh (as in binary packages of most Linuxes), loading a module (e.g. zsh/zftp) fails unless all the modules it depends on are already loaded. With this patch the necessary modules are automatically loaded. --- ChangeLog | 4 ++++ Src/Modules/zftp.c | 2 +- Src/mkbltnmlst.sh | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 51a091aff..6a2801e9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-06-26 Jun-ichi Takimoto + * 51889: Src/Modules/zftp.c, Src/mkbltnmlst.sh: enable loading a + module (e.g. zftp) that depends on other modules even if zsh is + built with the full RELRO + * 51884: Doc/Zsh/params.yo, Src/params.c, Src/utils.c, Test/D04parameter.ztst: if MULTIBYTE option is on and IFS contains invalid bytes in curret locale then reset it to default diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 49b3ffa89..47a5e9de9 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -3172,7 +3172,7 @@ static struct features module_features = { int setup_(UNUSED(Module m)) { - return (require_module("zsh/net/tcp", NULL, 0) == 1); + return 0; } /**/ diff --git a/Src/mkbltnmlst.sh b/Src/mkbltnmlst.sh index c4611d8b3..067ecdaf9 100644 --- a/Src/mkbltnmlst.sh +++ b/Src/mkbltnmlst.sh @@ -76,6 +76,30 @@ for x_mod in $x_mods; do test "x$linked" = xno && echo "#endif" done +# if dynamic module 'mod' with load=no has moddeps in its .mdd, +# then output add_dep(mod, dep) for each 'dep' in moddeps. +dyn_mods="`grep ' link=dynamic .* load=no ' $CFMOD | \ + sed -e '/^#/d' -e 's/ .*/ /' -e 's/^name=/ /'`" + +for mod in $dyn_mods; do + modfile="`grep '^name='$mod' ' $CFMOD | \ + sed -e 's/^.* modfile=//' -e 's/ .*//'`" + if test "x$modfile" = x; then + echo >&2 "WARNING: no name for \`$mod' in $CFMOD (ignored)" + continue + fi + unset moddeps + . $srcdir/../$modfile + if test -n "$moddeps"; then + echo '#ifdef DYNAMIC' + echo "/* non-linked-in known module \`$mod' */" + for dep in $moddeps; do + echo " add_dep(\"$mod\", \"$dep\");" + done + echo '#endif' + fi +done + echo done_mods=" " for bin_mod in $bin_mods; do -- cgit v1.2.3 From 5ead24c8819efb3cd0d24a6ff4f178e1a5defee9 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 9 Jul 2023 19:28:28 -0700 Subject: 51890: fix "whence -wa" for multiple arguments --- ChangeLog | 4 ++++ Src/builtin.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6a2801e9b..531503312 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-07-09 Bart Schaefer + + * 51890: Src/builtin.c: fix "whence -wa" for multiple arguments + 2023-06-26 Jun-ichi Takimoto * 51889: Src/Modules/zftp.c, Src/mkbltnmlst.sh: enable loading a diff --git a/Src/builtin.c b/Src/builtin.c index e4f356803..669a47092 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4046,6 +4046,7 @@ bin_whence(char *nam, char **argv, Options ops, int func) /* Take arguments literally -- do not glob */ queue_signals(); for (; *argv; argv++) { + informed = 0; if (!OPT_ISSET(ops,'p') && !allmatched) { char *suf; -- cgit v1.2.3 From c4ec7442f1138f2c525f98febb0db6def0fbe142 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 10 Jul 2023 22:13:52 +0900 Subject: 51897: update _softwareupdate based on 51895 (Shohei YOSHIDA) --- ChangeLog | 5 + Completion/Darwin/Command/_softwareupdate | 151 ++++++++++++++++++------------ 2 files changed, 98 insertions(+), 58 deletions(-) diff --git a/ChangeLog b/ChangeLog index 531503312..8065c037d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-07-10 Jun-ichi Takimoto + + * 51897 (+ minor tweaks): Completion/Darwin/Command/_softwareupdate: + update _softwareupdate (based on 51895 by Shohei YOSHIDA) + 2023-07-09 Bart Schaefer * 51890: Src/builtin.c: fix "whence -wa" for multiple arguments diff --git a/Completion/Darwin/Command/_softwareupdate b/Completion/Darwin/Command/_softwareupdate index 6054fd768..9ac9b9cd2 100644 --- a/Completion/Darwin/Command/_softwareupdate +++ b/Completion/Darwin/Command/_softwareupdate @@ -1,75 +1,110 @@ #compdef softwareupdate -_softwareupdate_ignored_update_name() { - if [[ -z "$_softwareupdate_ignored_updates" ]]; then - local res="$(_call_program pkgs softwareupdate --ignored)" - _softwareupdate_ignored_updates=("${(Qs/, /)${${res#Current ignored updates: \(}%\)}}") - fi - if (( ${#_softwareupdate_ignored_updates} > 0 )); then - _wanted pkgs expl "ignored package" compadd -a _softwareupdate_ignored_updates && return 0 - fi - return 1 +# rebuild cache for available updates everyday (ad hoc) +_softwareupdate_caching_policy() { + local -a newer=( "$1"(Nmd-1) ) + return $#newer } -_softwareupdate_update_name() { - local name line - if [[ -z "$_softwareupdate_updates" ]]; then +# completes available updates (with description) + +_softwareupdate_update_names () { + local name line update_policy ret=1 + local cache_id=softwareupdate-updates + zstyle -s ":completion:${curcontext}:" cache-policy update_policy + if [[ -z "$update_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy \ + _softwareupdate_caching_policy + fi + if { [[ ! -v _softwareupdate_updates ]] || _cache_invalid $cache_id } && + ! _retrieve_cache $cache_id; then + # Output format of 'softwareupdate --list' seems to be not stable, + # but at least on macOS 12 and 13 it contains the following two lines + # for each update: + #* Label: update name (may contain spaces) + # Title: description of the update (single TAB before Title:) + # softwareupdate(1) manpage says the '*' before the Label: is replaced + # by '-' for non-recommended updates (but I've never seen it). _softwareupdate_updates=() - for line in ${(f)"$(_call_program pkgs softwareupdate --list)"}; do - if [[ $line == ' '* ]]; then - name="${line# ? }" - elif [[ -n "$name" ]]; then - _softwareupdate_updates+=("$name:${line# }") - name="" + for line in ${(f)"$(_call_program updates softwareupdate --list)"}; do + if [[ $line = [-\*]\ Label:\ (#b)(*) ]]; then + # add '*' or '-' in front of the name; this will be removed later + name=$line[1]$match[1] + elif [[ -n $name && $line = $'\t'Title:\ (#b)(*) ]]; then + _softwareupdate_updates+=( $name:$match[1] ) + name= fi done + _store_cache $cache_id _softwareupdate_updates fi - if (( ${#_softwareupdate_updates} > 0 )); then - _describe -t pkgs "update name" _softwareupdate_updates && return 0 - fi - return 1 + # recommended and non-recommended updates + local rec=( ${${_softwareupdate_updates:#-*}#\*} ) + local non=( ${${(M)_softwareupdate_updates:#-*}#-} ) + _describe -t updates "update" rec && ret=0 + _describe -t non-recommended-updates "non-recommended update" non && ret=0 + return ret +} + +# completes versions of available macOS full installer (with description) + +_softwareupdate_installer_versions () { + local versions=() + for line in ${(f)"$(_call_program installer-versions + softwareupdate --list-full-installers 2>/dev/null)"}; do + if [[ $line = \*\ Title:\ *\ Version:\ (#b)([0-9.]##)* ]]; then + versions+=( ${match[1]}:${line#*Title: } ) + fi + done + _describe -t insteller-versions "version" versions } +# main completion script + _softwareupdate() { - local context state line expl - typeset -A opt_args + local -a specs - _arguments -R \ - '(-h --help -l --list)-q[quiet mode]' \ - {-l,--list}'[list all available updates]:*:' \ - {-d,--download}'[download to directory set in InternetConfig]:*:' \ - {-i,--install}'[install (requires root)]:*: :->install' \ - '--ignored[show or manage ignored updates list (per-user)]:*:: :->ignored' \ - '--schedule[scheduler preferences (per-user)]:automatic checking:(on off)' \ - {-h,--help}'[print command usage]:*:' && return 0 + if (( ${words[(I)(-i|--install)]} == 0 )); then + specs=( + '--no-scan[do not scan when listing or installing updates]' + '--product-types[limit a scan to a particular product type only]:list of product types' + '--products[a comma separated list of product keys to operate on]:list of product keys' + '--force[force an operation to complete]' + '--agree-to-license[agree to the software license agreement without user interaction]' + '--verbose[enable verbose output]' + '(* -)'{-h,--help}'[print command usage]:*:' - case "$state" in - install) - _arguments \ - '(* -a --all)'{-a,--all}'[all available active updates]' \ - '(* -r --req)'{-r,--req}'[all required active updates]' \ - '*:update name:_softwareupdate_update_name' && return 0 - ;; - ignored) - local -a ignored_subcmd - ignored_subcmd=(add remove) + + '(operation)' - if (( CURRENT == 1 )); then - _describe -t commands "subcommand" ignored_subcmd && return 0 - fi - case $words[1] in - add) - _softwareupdate_update_name && return 0 - ;; - remove) - _arguments \ - '(* -a --all)'{-a,--all}'[all available active updates]' \ - '*:update name:_softwareupdate_ignored_update_name' && return 0 - ;; - esac - ;; - esac - return 1 + {-l,--list}'[list all available updates]' + {-d,--download}'[download but not install specified updates]:*: : _softwareupdate_update_names' + {-i,--install}'[download and install specified updates]' + '(* -)--list-full-installers[list the available macOS installers]' + '(* -)--fetch-full-installer[install the latest recommended macOS installer]: :(--full-installer-version): : _softwareupdate_installer_versions' + '--install-rosetta[install Rosetta 2 (Apple Silicon only)]' + '(* -)--schedule[returns the per-machine automatic check preference]' + '--background[trigger a background scan and update operation]' + '(* -)--dump-state[log the internal state of the SU daemon to /var/log/install.log]' + '--evaluate-products[evaluate a list of product keys specified by the --products option]' + '--history[show the install history]' + ) + else # if -i/--install is already on the command line + specs=( + !{-i,--install} + '(-R --restart)'{-R,--restart}'[automatically restart if required to complete installation]' + '--stdinpass[password to authenticate as an owner (Apple Silicon only)]' + '--user[local username to authenticate as an owner (Apple Silicon only)]' + '*: : _softwareupdate_update_names' + + + '(select-updates)' + + '(*)'{-a,--all}'[all updates that are applicable to your system]' + '(*)'{-r,--recommended}'[all updates recommended for your system]' + '(*)--os-only[only macOS updates]' + '(*)--safari-only[only Safari updates]' + ) + fi + + _arguments -s : $specs } _softwareupdate "$@" -- cgit v1.2.3 From 5ec4695033b9a3a57492b60439d9e3a922d9bcd1 Mon Sep 17 00:00:00 2001 From: mirsella Date: Mon, 10 Jul 2023 12:50:48 +0200 Subject: github #99: _trash: add completion for trash-d https://github.com/rushsteve1/trash-d --- ChangeLog | 5 ++++ Completion/Darwin/Command/_trash | 22 ---------------- Completion/Unix/Command/_trash | 57 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 22 deletions(-) delete mode 100644 Completion/Darwin/Command/_trash create mode 100644 Completion/Unix/Command/_trash diff --git a/ChangeLog b/ChangeLog index 8065c037d..7d24a22dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-07-19 dana + + * github #99: mirsella: Completion/Darwin/Command/_trash, + Completion/Unix/Command/_trash: add completion for trash-d + 2023-07-10 Jun-ichi Takimoto * 51897 (+ minor tweaks): Completion/Darwin/Command/_softwareupdate: diff --git a/Completion/Darwin/Command/_trash b/Completion/Darwin/Command/_trash deleted file mode 100644 index 658716432..000000000 --- a/Completion/Darwin/Command/_trash +++ /dev/null @@ -1,22 +0,0 @@ -#compdef trash - -# We only provide completion for Ali Rantakari's trash utility. There are/were a -# few others floating around with that name, but this is the one available as -# `trash` in Homebrew and MacPorts -_pick_variant ali='(Rantakari|hasseg)' other --version && { - # The hidden options here are options to rm that trash silently (and - # undocumentedly) ignores. Some options are not made mutually exclusive where - # they technically could be, for compatibility with aliases, etc. - _arguments -s -S -A '-*' : \ - '!-'{d,f,i,r,P,R,W} \ - '(: * -F -l -v)-e[empty trash]' \ - '-F[use Finder instead of system API]' \ - '(: * -e -F -s -y)-l[list items in trash]' \ - '(: * -F -l -v)-s[securely empty trash]' \ - '-v[increase output verbosity]' \ - '-y[skip confirmation prompts (with -e or -s)]' \ - '*: :_files' - return -} - -_default diff --git a/Completion/Unix/Command/_trash b/Completion/Unix/Command/_trash new file mode 100644 index 000000000..bef6e5838 --- /dev/null +++ b/Completion/Unix/Command/_trash @@ -0,0 +1,57 @@ +#compdef trash + +local variant + +_pick_variant -r variant ali='(Rantakari|hasseg)' steven='(Steven|vanZyl)' other --version + +case $variant in + ali) + # The hidden options here are options to rm that trash silently (and + # undocumentedly) ignores. Some options are not made mutually exclusive where + # they technically could be, for compatibility with aliases, etc. + _arguments -s -S -A '-*' : \ + '!-'{d,f,i,r,P,R,W} \ + '(: * -F -l -v)-e[empty trash]' \ + '-F[use Finder instead of system API]' \ + '(: * -e -F -s -y)-l[list items in trash]' \ + '(: * -F -l -v)-s[securely empty trash]' \ + '-v[increase output verbosity]' \ + '-y[skip confirmation prompts (with -e or -s)]' \ + '*: :_files' + return + ;; + steven) + local trash_dir="${TRASH_D_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/Trash}/files" + + local -a args=( + '(-v --verbose)'{-v,--verbose}'[print more information]' + + + options + '(-d --dir)'{-d,--dir}'[remove empty directories]' + '(-r -R --recursive)'{-r,-R,--recursive}'[delete directories and their contents]' + '--rm[permanently delete files]' + + + '(interactive)' + {-i,--interactive}'[ask before each deletion]' + {-I,--interactive-once}'[ask before deleting 3 or more files, or deleting recursively]' + {-f,--force}'[don'\''t prompt and ignore errors]' + + + '(actions)' + '(options input info interactive)--list[list out the files in the trash]' + '(options input info interactive)--orphans[list orphaned files in the trash]' + '(options input info)--restore[restore specified file from the trash]:trashed file:_files -W "$trash_dir"' + '(options input info)--delete[delete specified file from the trash]:trashed file:_files -W "$trash_dir"' + '(options input info)--empty[empty the trash bin]' + + + info + '(- *)'{-h,--help}'[display help information]' + '(- *)--version[output the version and exit]' + + + input + '(actions)*: :_files' + ) + _arguments -s -S : $args + return + ;; + *) _default ;; +esac -- cgit v1.2.3 From 03695f4b5819d5f20ad0ad241d9255ba8cbd8e91 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 20 Jul 2023 10:46:14 +0100 Subject: 51977: PIPEFAIL interaction with ERREXIT / ERRRETURN Ensure the list-level error handling code is executed if we detect pipe failure for a foreground job. Add tests. --- ChangeLog | 6 ++++++ Src/jobs.c | 16 ++++++++++----- Test/E01options.ztst | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d24a22dd..8ecc30f20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-07-20 Peter Stephenson + + * 51977: Src/jobs.c, Test/E01options.ztst: Combination of + PIPEFAIL and ERRRETURN / ERREXIT options failed with complex + commands at end of pipeline. + 2023-07-19 dana * github #99: mirsella: Completion/Darwin/Command/_trash, diff --git a/Src/jobs.c b/Src/jobs.c index dd7bba405..a3b9f667a 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -427,11 +427,17 @@ storepipestats(Job jn, int inforeground, int fixlastval) } if (fixlastval) { - if (jn->stat & STAT_CURSH) { - if (!lastval && isset(PIPEFAIL)) - lastval = pipefail; - } else if (isset(PIPEFAIL)) - lastval = pipefail; + if (jn->stat & STAT_CURSH) { + if (!lastval && isset(PIPEFAIL)) { + if (inforeground) + this_noerrexit = 0; + lastval = pipefail; + } + } else if (isset(PIPEFAIL)) { + if (inforeground) + this_noerrexit = 0; + lastval = pipefail; + } } } diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 533e08773..83f0371a1 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -1379,6 +1379,64 @@ F:Regression test for workers/41811 >1 >2 + pipefailfn1() { + emulate -L zsh + setopt errreturn pipefail + false | { true; } + print "Shouldn't get here, status $?" + } + pipefailfn1 +1:PIPE_FAIL causes ERR_RETURN with complex end of pipeline: braces + + pipefailfn2() { + emulate -L zsh + setopt errreturn pipefail + false | if true; then true; fi + print "Shouldn't get here, status $?" + } + pipefailfn2 || print Function failed, as expected +0:PIPE_FAIL causes ERR_RETURN with complex end of pipeline: if +>Function failed, as expected + + pipefailfn3() { + emulate -L zsh + setopt errreturn pipefail + false | while true; do break; done + print "Shouldn't get here, status $?" + } + pipefailfn3 || print Function failed, as expected +0:PIPE_FAIL causes ERR_RETURN with complex end of pipeline: while +>Function failed, as expected + + pipefailfn4() { + emulate -L zsh + setopt errreturn pipefail + false | true + print "Shouldn't get here, status $?" + } + pipefailfn4 +1:PIPE_FAIL causes ERR_RETURN in simple case + + pipefailfn5() { + emulate -L zsh + setopt errreturn pipefail + false | { true | true; } + print "Shouldn't get here, status $?" + } + pipefailfn5 || print Function failed as expected +0:PIPE_FAIL causes ERR_RETURN with nested successful pipe +>Function failed as expected + + pipefailfn6() { + emulate -L zsh + setopt errreturn pipefail + false | { false | true; } + print "Shouldn't get here, status $?" + } + pipefailfn6 || print Function failed as expected +0:PIPE_FAIL causes ERR_RETURN with nested failed pipe +>Function failed as expected + for (( i = 0; i < 10; i++ )); do () { print $i -- cgit v1.2.3 From d70e3780fc74eb6c7d8d7ea7701266725e180f23 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 26 Jul 2023 19:39:15 -0700 Subject: unposted (cf. 51899): document _shadow --- ChangeLog | 4 ++++ Doc/Zsh/compsys.yo | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8ecc30f20..836d200dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-07-26 Bart Schaefer + + * unposted (cf. 51899): Doc/Zsh/compsys.yo: document _shadow + 2023-07-20 Peter Stephenson * 51977: Src/jobs.c, Test/E01options.ztst: Combination of diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 584ede441..33baeab49 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -5227,6 +5227,50 @@ the group name. This function is called automatically from tt(_description) and hence is not normally called explicitly. ) +findex(_shadow) +findex(_unshadow) +xitem(tt(_shadow) [ tt(-s) var(suffix) ] var(command_name) ...) +item(tt(_unshadow) [ tt(-s) var(suffix) ] var(command_name) ...)( +The tt(_shadow) function creates a copy of each of the shell functions +in the var(command_name) arguments. The original functions can then +be replaced by new implementations. A later call to tt(_unshadow), +with the same var(command_name) list, removes the new implementations, +if any, and restores the originals. + +Recommended usage is to pair tt(_shadow) and tt(_unshadow) calls by +use of an `tt(always)' block: +example({ + _shadow fname + function fname { + # Do your new thing + } + # Invoke callers of fname +} always { + _unshadow fname +}) + +Any var(command_name) may instead be a builtin, but in that case no +copy is created. The expectation is that an initial tt(_shadow) is +followed by creating a wrapper function, and therafter any nested or +recursive calls thus copy and replace the wrapper function. +example({ + _shadow compadd + compadd LPAR()RPAR() { builtin compadd -O tmparr "$@" } +} always { + _unshadow compadd +}) + +The var(suffix), if supplied, is prepended by an `tt(@)' character and +then appended to each var(command_name) to create the copy. Thus +example(_shadow -s XX foo) +creates a function named `tt(foo@XX)' (unless `tt(foo)' is a builtin). +Note that a nested call to tt(_shadow) with the same var(suffix) may +result in name collisions and unexpected results, but this provides a +well-known name for the original function if the new implementation +needs to call it as a wrapper. The same var(suffix) must be used in +the call to tt(_unshadow). When no var(suffix) is present, +tt(_shadow) creates a unique suffix to avoid name collisions. +) findex(_store_cache) item(tt(_store_cache) var(cache_identifier) var(param) ...)( This function, together with tt(_retrieve_cache) and -- cgit v1.2.3 From 1ac393169ab0d77e86905acc652943be8d26679d Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Wed, 26 Jul 2023 19:44:51 -0700 Subject: 51927: Update procps watch completion for version 4.0.3 --- ChangeLog | 3 +++ Completion/Unix/Command/_watch | 3 +++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 836d200dd..ab329c767 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-07-26 Bart Schaefer + * Shohei YOSHIDA: 51927: Completion/Unix/Command/_watch: Update + procps watch completion for version 4.0.3 + * unposted (cf. 51899): Doc/Zsh/compsys.yo: document _shadow 2023-07-20 Peter Stephenson diff --git a/Completion/Unix/Command/_watch b/Completion/Unix/Command/_watch index fff3d56f6..91244abe7 100644 --- a/Completion/Unix/Command/_watch +++ b/Completion/Unix/Command/_watch @@ -18,7 +18,10 @@ case $variant in '(-g --chgexit)'{-g,--chgexit}'[exit on command output change]' \ '(-n --interval)'{-n+,--interval=}'[specify update interval]:update interval (seconds) [2]' \ '(-p --precise)'{-p,--precise}'[run command at precise intervals]' \ + '(-q --equexit)'{-q,--equexit}'[exit when output of command does not change for the given cycles]:cycles' \ + '(-r --no-rerun)'{-r,--no-rerun}'[do not run the program on terminal resize]' \ '(-t --no-title)'{-t,--no-title}'[disable header]' \ + '(-w --no-wrap)'{-w,--no-wrap}'[disable line wrapping]' \ '(-x --exec)'{-x,--exec}'[pass command to exec(2) instead of `sh -c`]' \ '(-)*::: :->cmd' \ && ret=0 -- cgit v1.2.3 From fb5a6a871c718bbe6b841d1a2b6c5fd2d7859ce8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 26 Jul 2023 19:49:50 -0700 Subject: 51950 (tweak per 51949): correct Thingy refcount in raw_getbyte() --- ChangeLog | 3 +++ Src/Zle/zle_main.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ab329c767..a6b7905fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-07-26 Bart Schaefer + * 51950 (tweak per 51949): Src/Zle/zle_main.c: correct Thingy + refcount in raw_getbyte() + * Shohei YOSHIDA: 51927: Completion/Unix/Command/_watch: Update procps watch completion for version 4.0.3 diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 4a6c02133..1afb1bf58 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -737,7 +737,7 @@ raw_getbyte(long do_keytmout, char *cptr, int full) ) { /* Handle the fd. */ char *fdbuf; - Thingy save_lbindk = lbindk; + Thingy save_lbindk = refthingy(lbindk); { char buf[BDIGBUFSIZE]; convbase(buf, lwatch_fd->fd, 10); @@ -780,6 +780,7 @@ raw_getbyte(long do_keytmout, char *cptr, int full) */ errtry = 1; } + unrefthingy(lbindk); lbindk = save_lbindk; } } -- cgit v1.2.3 From 301412c0e8f413cacf601f3a8de3f43098fd6179 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 26 Jul 2023 19:50:52 -0700 Subject: Fix reversed article numbers in most recent entry --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a6b7905fe..74496543f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ 2023-07-26 Bart Schaefer - * 51950 (tweak per 51949): Src/Zle/zle_main.c: correct Thingy + * 51949 (tweak per 51950): Src/Zle/zle_main.c: correct Thingy refcount in raw_getbyte() * Shohei YOSHIDA: 51927: Completion/Unix/Command/_watch: Update -- cgit v1.2.3 From aa85564319f4d511fae04a3cdf7a0b1fba1f67fe Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 26 Jul 2023 19:54:30 -0700 Subject: 51969: read -d and -s should not reset terminal state when stdin is redirected --- ChangeLog | 3 +++ Src/builtin.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74496543f..a02e25218 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-07-26 Bart Schaefer + * 51969: Src/builtin.c: read -d and -s should not reset terminal + state when stdin is redirected + * 51949 (tweak per 51950): Src/Zle/zle_main.c: correct Thingy refcount in raw_getbyte() diff --git a/Src/builtin.c b/Src/builtin.c index 669a47092..1568cf44c 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6483,7 +6483,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) } else readfd = izle = 0; - if (OPT_ISSET(ops,'s') && SHTTY != -1) { + if (OPT_ISSET(ops,'s') && SHTTY == readfd) { struct ttyinfo ti; gettyinfo(&ti); saveti = ti; @@ -6531,7 +6531,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) delim = (unsigned char) ((delimstr[0] == Meta) ? delimstr[1] ^ 32 : delimstr[0]); #endif - if (SHTTY != -1) { + if (SHTTY == readfd) { struct ttyinfo ti; gettyinfo(&ti); if (! resettty) { @@ -6691,7 +6691,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) /* dispose of result appropriately, etc. */ if (isem) while (val > 0 && read(SHTTY, &d, 1) == 1 && d != '\n'); - else { + else if (resettty) { settyinfo(&shttyinfo); resettty = 0; } -- cgit v1.2.3 From ec61c9a5c012ad5f72516a7a0e976a87214d2007 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Wed, 26 Jul 2023 19:58:00 -0700 Subject: 51964: support pidof variants other than procps --- ChangeLog | 3 +++ Completion/Linux/Command/_pidof | 58 ++++++++++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index a02e25218..f6604ac0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-07-26 Bart Schaefer + * Shohei YOSHIDA: 51964: Completion/Linux/Command/_pidof: support + pidof variants other than procps + * 51969: Src/builtin.c: read -d and -s should not reset terminal state when stdin is redirected diff --git a/Completion/Linux/Command/_pidof b/Completion/Linux/Command/_pidof index dd0649ce9..151a0e0f6 100644 --- a/Completion/Linux/Command/_pidof +++ b/Completion/Linux/Command/_pidof @@ -3,19 +3,51 @@ local curcontext="$curcontext" state line expl ret=1 typeset -A opt_args -local exargs="-h --help -V --version" -_arguments -C -s -w \ - '(- *)'{-h,--help}'[display help information]' \ - '(- *)'{-V,--version}'[print program version]' \ - "(-s --single-shot $exargs)"{-s,--single-shot}'[return one PID only]' \ - "(-c --check-root $exargs)"{-c,--check-root}'[omit processes with different root]' \ - '-q[quiet mode, only set the exit code]' \ - '(-w --with-workers)'{-w,--with-workers}'[show kernel workers too]' \ - "(-x $exargs)"-x'[include shells running named scripts]' \ - "($exargs)"\*{-o+,--omit-pid=}'[omit processes with PIDs]:pids:_sequence -s , _pids' \ - '(-S --separator)'{-S+,--separator=}'[specify separator put between PIDs]:separator' \ - '*:process:->procnames' \ - && return 0 +_pick_variant -r variant procps='--separator' $OSTYPE -h + +case $variant in + (procps) + local exargs="-h --help -V --version" + _arguments -C -s -w \ + '(- *)'{-h,--help}'[display help information]' \ + '(- *)'{-V,--version}'[print program version]' \ + "(-s --single-shot $exargs)"{-s,--single-shot}'[return one PID only]' \ + "(-c --check-root $exargs)"{-c,--check-root}'[omit processes with different root]' \ + '-q[quiet mode, only set the exit code]' \ + '(-w --with-workers)'{-w,--with-workers}'[show kernel workers too]' \ + "(-x $exargs)"-x'[include shells running named scripts]' \ + "($exargs)"\*{-o+,--omit-pid=}'[omit processes with PIDs]:pids:_sequence -s , _pids' \ + '(-S --separator)'{-S+,--separator=}'[specify separator put between PIDs]:separator' \ + '*:process:->procnames' \ + && return 0 + ;; + (darwin*) + # Night Production pidof + _arguments -s -w \ + '(- *)'{-h,-\?}'[display help information]' \ + '(- *)-v[print out version info on pidof]' \ + '-l[print output in long format]' \ + '-k[kill processes by name]' \ + '*:process:_process_names -a' \ + && return 0 + ;; + (*) + # sysvinit-utils + _arguments -C -s -w \ + '(- *)-h[display help information]' \ + '-c[return PIDs with the same root directory]' \ + '-d[use the provided character as output separator]:separator' \ + '-n[avoid using stat system function on network shares]' \ + '-o[omit results with a given PID]:pid:_sequence -s , _pids' \ + '-s[return one PID only]' \ + '-q[quiet mode. Do not display output]' \ + '-s[only return one PID]' \ + '-x[return PIDs of shells running scripts with a matching name]' \ + '-z[list zombie and I/O waiting processes. May cause pidof to hang]' \ + '*:process:->procnames' \ + && return 0 + ;; +esac case $state in procnames) -- cgit v1.2.3 From 5ff23c2c6db430398b0421c61fea11e8202c281a Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Wed, 26 Jul 2023 20:01:06 -0700 Subject: 51979: Update free completion for procps-ng version 4.0.3 --- ChangeLog | 3 +++ Completion/Linux/Command/_free | 1 + 2 files changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index f6604ac0a..d725239f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-07-26 Bart Schaefer + * Shohei YOSHIDA: 51979: Completion/Linux/Command/_free: Update + free completion for procps-ng version 4.0.3 + * Shohei YOSHIDA: 51964: Completion/Linux/Command/_pidof: support pidof variants other than procps diff --git a/Completion/Linux/Command/_free b/Completion/Linux/Command/_free index 6d74e4a0d..a0da97446 100644 --- a/Completion/Linux/Command/_free +++ b/Completion/Linux/Command/_free @@ -3,6 +3,7 @@ _arguments -s \ '(-l --lohi)'{-l,--lohi}'[show detailed low and high memory statistics]' \ '(-t --total)'{-t,--total}'[show total for RAM + swap]' \ + '(-v --committed)'{-v,--committed}'[show committed memory and commit limit]' \ '(-w --wide)'{-w,--wide}'[wide mode]' \ '(-s --seconds)'{-s,--seconds}'[specify the delay between display]:seconds: ' \ '(-c --count)'{-c+,--count=}'[specify the display count]:count: ' \ -- cgit v1.2.3 From baa19d2a85758d6b6bcbcd8b78f065a3be262fb3 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 26 Jul 2023 20:15:21 -0700 Subject: 51945: assorted documentation improvements, bug fixes, and new test 1) Document the behavior of "typeset -n existing_var" (via Jun T. comment) 2) Prohibit "typeset -nm pattern" because, well, it's insane. Add test. 3) Improve doc for ${(!)ref} including ${{t!)ref} (Jun T.) 4) Fix doc for how-to unset of a named ref (Jun T.) 5) Allow "typeset +r -n ref" and "typeset +r +n ref" (Jun T.) 6) Fix "typeset -r -n ref=param" to create readonly references 7) Avoid accidental removal of PM_UNSET flag (Jun T.) and update test 8) Fix "typeset -gn ref=value" and add a test for it 9) Add tests for read-only reference behavior 10) Fix infinite recursion when resolving scope of an unset local named reference, add test. --- ChangeLog | 5 ++++ Doc/Zsh/builtins.yo | 8 +++++- Doc/Zsh/expn.yo | 8 +++++- Doc/Zsh/params.yo | 4 +-- Src/builtin.c | 41 +++++++++++++++++++++++------- Src/params.c | 14 ++++++++--- Test/K01nameref.ztst | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 132 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index d725239f3..f0b6e8c4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2023-07-26 Bart Schaefer + * 51945: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/params.yo, + Src/builtin.c, Src/params.c, Test/K01nameref.ztst: improve named + references documentation, fixes for typeset -r and -g behavior, + fix unset reference behavior including scoping crash, more tests + * Shohei YOSHIDA: 51979: Completion/Linux/Command/_free: Update free completion for procps-ng version 4.0.3 diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 5393cb149..33b13ac16 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2060,6 +2060,11 @@ function unless `tt(-g -n)' is specified, and any local parameter (of any type) with the same var(name) supplants a named reference from a surrounding scope. +A scalar parameter, including an existing named reference, may be +converted to a new named reference by `tt(typeset -n )var(name)', so +the `tt(-p)' option must be included to display the value of a +specific named reference var(name). + If no attribute flags are given, and either no var(name) arguments are present or the flag tt(+m) is used, then each parameter name printed is preceded by a list of the attributes of that parameter (tt(array), @@ -2104,7 +2109,8 @@ is not used in this case). If the tt(+g) flag is combined with tt(-m), a new local parameter is created for every matching parameter that is not already local. Otherwise -tt(-m) applies all other flags or assignments to the existing parameters. +tt(-m) applies all other flags or assignments to the existing parameters, +except that the tt(-n) option cannot create named references in this way. Except when assignments are made with var(name)tt(=)var(value), using tt(+m) forces the matching parameters and their attributes to be printed, diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 7bc736470..f87832e75 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -987,6 +987,11 @@ means the same thing as the more readable `(tt(%%qqq))'. The following flags are supported: startitem() +item(tt(!))( +When the parameter being expanded is a named reference, the reference +itself is examined and thus is em(not) resolved to its referent. In +ksh emulation, the parens around this flag are optional. +) item(tt(#))( Evaluate the resulting words as numeric expressions and interpret these as character codes. Output the corresponding characters. Note @@ -1245,7 +1250,8 @@ item(tt(hideval))( for parameters with the `hideval' flag (tt(-H)) ) item(tt(nameref))( -for named references having an empty value (tt(-n)) +for named references (tt(typeset -n)) either having an empty value or +when combined with `tt(!)' as in `tt(${LPAR()!t)tt(RPAR()var(rname)})' ) item(tt(special))( for special parameters defined by the shell diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index e0410d673..5653b3bc9 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -672,9 +672,9 @@ of var(pname) in assignments and expansions instead assign to or expand var(rname). This also applies to `tt(unset )var(pname)' and to most subsequent uses of `tt(typeset)' with the exception of `tt(typeset -n)' and `tt(typeset +n)', so to remove a named reference, -use either `tt(unset -n )var(pname)' or one of: +use either `tt(unset -n )var(pname)' (preferred) or one of: ifzman() -example(tt(typeset -n )var(pname) +example(tt(typeset -n )var(pname=) tt(typeset +n )var(pname)) followed by diff --git a/Src/builtin.c b/Src/builtin.c index 1568cf44c..31af66c7c 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2248,10 +2248,14 @@ typeset_single(char *cname, char *pname, Param pm, int func, zerrnam(cname, "%s: restricted", pname); return pm; } - if ((pm->node.flags & PM_READONLY) && - (pm->node.flags & PM_NAMEREF & off)) { - zerrnam(cname, "%s: read-only reference", pname); - return pm; + if ((pm->node.flags & PM_READONLY) && !(off & PM_READONLY) && + /* It seems as though these checks should not be specific to + * PM_NAMEREF, but changing that changes historic behavior */ + ((on & PM_NAMEREF) != (pm->node.flags & PM_NAMEREF) || + (asg && (pm->node.flags & PM_NAMEREF)))) { + zerrnam(cname, "%s: read-only %s", pname, + (pm->node.flags & PM_NAMEREF) ? "reference" : "variable"); + return NULL; } if ((on & PM_UNIQUE) && !(pm->node.flags & PM_READONLY & ~off)) { Param apm; @@ -2693,7 +2697,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) off |= bit; } if (OPT_MINUS(ops,'n')) { - if ((on & ~PM_READONLY)|off) { + if ((on|off) & ~PM_READONLY) { zwarnnam(name, "no other attributes allowed with -n"); return 1; } @@ -3021,6 +3025,13 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) /* With the -m option, treat arguments as glob patterns */ if (OPT_ISSET(ops,'m')) { if (!OPT_ISSET(ops,'p')) { + if (on & PM_NAMEREF) { + /* It's generally unwise to mass-change the types of + * parameters, but for namerefs it would be fatal */ + unqueue_signals(); + zerrnam(name, "invalid reference"); + return 1; + } if (!(on|roff)) printflags |= PRINT_TYPE; if (!on) @@ -3104,13 +3115,25 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) } if (hn) { /* namerefs always start over fresh */ - if (((Param)hn)->level >= locallevel) { + if (((Param)hn)->level >= locallevel || + (!(on & PM_LOCAL) && ((Param)hn)->level < locallevel)) { Param oldpm = (Param)hn; - if (!asg->value.scalar && oldpm->u.str) + if (!asg->value.scalar && + PM_TYPE(oldpm->node.flags) == PM_SCALAR && + oldpm->u.str) asg->value.scalar = dupstring(oldpm->u.str); - unsetparam_pm((Param)hn, 0, 1); + /* Defer read-only error to typeset_single() */ + if (!(hn->flags & PM_READONLY)) + unsetparam_pm(oldpm, 0, 1); } - hn = NULL; + /* Passing a NULL pm to typeset_single() makes the + * nameref read-only before assignment, which breaks + * typeset -rn ref=var + * so this is special-cased to permit that action + * like assign-at-create for other parameter types. + */ + if (!(hn->flags & PM_READONLY)) + hn = NULL; } } diff --git a/Src/params.c b/Src/params.c index f5750a4b4..5841308d7 100644 --- a/Src/params.c +++ b/Src/params.c @@ -546,7 +546,7 @@ getparamnode(HashTable ht, const char *nam) } } - if (hn && ht == realparamtab) + if (hn && ht == realparamtab && !(hn->flags & PM_UNSET)) hn = resolve_nameref((Param)hn, NULL); return hn; } @@ -3729,7 +3729,9 @@ unsetparam_pm(Param pm, int altflag, int exp) char *altremove; if ((pm->node.flags & PM_READONLY) && pm->level <= locallevel) { - zerr("read-only variable: %s", pm->node.nam); + zerr("read-only %s: %s", + (pm->node.flags & PM_NAMEREF) ? "reference" : "variable", + pm->node.nam); return 1; } if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) { @@ -6182,8 +6184,12 @@ resolve_nameref(Param pm, const Asgment stop) seek = refname; } } - else if (pm && !(stop && (stop->flags & PM_NAMEREF))) - return (HashNode)pm; + else if (pm) { + if (!(stop && (stop->flags & PM_NAMEREF))) + return (HashNode)pm; + if (!(pm->node.flags & PM_NAMEREF)) + return (pm->level < locallevel ? NULL : (HashNode)pm); + } if (seek) { queue_signals(); /* pm->width is the offset of any subscript */ diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index 6a5e767df..d8c098a98 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -515,7 +515,7 @@ F:Same test, should part 5 output look like this? >ptr1=val >ptr2= >typeset -n ptr1=ptr2 ->typeset -n ptr2='' +>typeset -n ptr2 >typeset ptr2=val if zmodload zsh/parameter; then @@ -694,4 +694,72 @@ F:Checking for a bug in zmodload that affects later tests F:runs in `setopt noexec` so $(...) returns nothing *?*bad math expression: empty string + unset -n ref + typeset -n ref=GLOBAL + () { + typeset -gn ref=RESET + } + typeset -p ref +0:reset global reference within function +>typeset -n ref=RESET + + unset -n ref + typeset -rn ref=RO + typeset -p ref + (typeset -n ref=RW) + print status: $? expected: 1 + typeset +r -n ref + typeset -p ref + typeset -r +n ref + typeset -p ref + (typeset -rn ref) + print status: $? expected: 1 + typeset +r -n ref=RW # Assignment occurs after type change, + typeset -p ref RO # so RO=RW here. Potentially confusing. + typeset -r -n ref=RX # No type change, so referent changes ... + typeset -p ref RO # ... and previous refererent does not. + typeset +rn ref=RW # Here ref=RW, again type changed first. + typeset -p ref +0:add and remove readonly attribute with references +>typeset -rn ref=RO +*?*: ref: read-only reference +>status: 1 expected: 1 +>typeset -n ref=RO +>typeset -r ref=RO +*?*: ref: read-only variable +>status: 1 expected: 1 +>typeset -n ref=RO +>typeset -g RO=RW +>typeset -rn ref=RX +>typeset -g RO=RW +>typeset ref=RW + + () { + typeset -n r1 r2= + typeset -p r1 r2 + print -- ${(!)r1-unset} + print -- ${+r1} + typeset -p r1 + } +0:unset nameref remains unset when resolved +F:relies on global TYPESET_TO_UNSET in %prep +>typeset -n r1 +>typeset -n r2='' +>unset +>0 +>typeset -n r1 + + bar=xx + typeset -n foo=bar + () { typeset -n foo; foo=zz; foo=zz; print $bar $zz } + () { typeset -n foo; foo=zz; local zz; foo=zz; print $bar $zz } +0:regression: local nameref may not in-scope a global parameter +F:previously this could create an infinite recursion and crash +>xx +>xx zz + + typeset -nm foo=bar +1:create nameref by pattern match not allowed +*?*typeset:1: invalid reference + %clean -- cgit v1.2.3 From c4cfb674653996e68830022c7066f19ce78421b5 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 26 Jul 2023 20:27:51 -0700 Subject: unposted (cf. 51968): improve documentation of typeset -gn and -r --- ChangeLog | 3 +++ Doc/Zsh/builtins.yo | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f0b6e8c4b..c62a3da34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-07-26 Bart Schaefer + * unposted (cf. 51968): Doc/Zsh/builtins.yo: improve description + of typeset -gn and -r + * 51945: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/params.yo, Src/builtin.c, Src/params.c, Test/K01nameref.ztst: improve named references documentation, fixes for typeset -r and -g behavior, diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 33b13ac16..5eb93272a 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1924,8 +1924,8 @@ redef(SPACES)(0)(tt(ifztexi(NOTRANS(@ @ @ @ @ @ @ @ ))ifnztexi( ))) xitem(tt(typeset )[ {tt(PLUS())|tt(-)}tt(AHUaghlmrtux) ] \ [ {tt(PLUS())|tt(-)}tt(EFLRZip) [ var(n) ] ]) xitem(SPACES()[ tt(+) ] [ var(name)[tt(=)var(value)] ... ]) -xitem(tt(typeset )[ {tt(PLUS())|tt(-)}tt(n) ] \ -[ tt(-gr) ] [ var(name)[tt(=)var(value)] ... ]) +xitem(tt(typeset ){tt(PLUS())|tt(-)}tt(n) [ tt(-g) ] \ +[ {tt(PLUS())|tt(-)}tt(r) ] [ var(name)[tt(=)var(value)] ... ]) xitem(tt(typeset )tt(-T) [ {tt(PLUS())|tt(-)}tt(Uglrux) ] [ {tt(PLUS())|tt(-)}tt(LRZp) [ var(n) ] ]) xitem(SPACES()[ tt(+) | var(SCALAR)[tt(=)var(value)] var(array)[tt(=LPAR())var(value) ...tt(RPAR())] [ var(sep) ] ]) item(tt(typeset) tt(-f) [ {tt(PLUS())|tt(-)}tt(TUkmtuz) ] [ tt(+) ] [ var(name) ... ])( -- cgit v1.2.3 From 95269147fcbd85961d652ab419bb168a8aafcd14 Mon Sep 17 00:00:00 2001 From: HexorCatZ Date: Mon, 31 Jul 2023 05:33:42 +0800 Subject: github #100: _qemu: add -enable-kvm and -bios suggestion --- ChangeLog | 5 +++++ Completion/Unix/Command/_qemu | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index c62a3da34..372092a32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-07-31 dana + + * github #100: HexorCatZ: Completion/Unix/Command/_qemu: + add -enable-kvm and -bios suggestion + 2023-07-26 Bart Schaefer * unposted (cf. 51968): Doc/Zsh/builtins.yo: improve description diff --git a/Completion/Unix/Command/_qemu b/Completion/Unix/Command/_qemu index 7bc02c30c..6ca11b4fb 100644 --- a/Completion/Unix/Command/_qemu +++ b/Completion/Unix/Command/_qemu @@ -51,5 +51,7 @@ _arguments \ '-no-acpi[disable ACPI]' \ '-loadvm[start right away with a saved state]:file:_files' \ '-g[set initial graphic mode]:graphic mode:' \ + '-enable-kvm[enable KVM full virtualization support]' \ + '-bios[use specified BIOS image]:bios image:_files' \ ':disk image:_files' -- cgit v1.2.3 From aa8e4a02904b3a1c4b3064eb7502d887f7de958b Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 1 Aug 2023 14:32:55 +0100 Subject: 52008: Pattern bug with branches + exclusion Add tests. --- ChangeLog | 5 +++++ Src/pattern.c | 22 ++++++++++++++++++++-- Test/D02glob.ztst | 26 ++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 372092a32..8e6e3fb18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-08-01 Peter Stephenson + + * 52008: Src/pattern.c, Test/D02glob.ztst: Fix bug with branches + in patterns followed by an exculsion, and add tests. + 2023-07-31 dana * github #100: HexorCatZ: Completion/Unix/Command/_qemu: diff --git a/Src/pattern.c b/Src/pattern.c index 3edda1772..2a1a514fb 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -2987,14 +2987,15 @@ patmatch(Upat prog) case P_EXCSYNC: /* See the P_EXCLUDE code below for where syncptr comes from */ { - unsigned char *syncptr; + unsigned char *syncstart, *syncptr, *ptr; Upat after; after = P_OPERAND(scan); DPUTS(!P_ISEXCLUDE(after), "BUG: EXCSYNC not followed by EXCLUDE."); DPUTS(!P_OPERAND(after)->p, "BUG: EXCSYNC not handled by EXCLUDE"); - syncptr = P_OPERAND(after)->p + (patinput - patinstart); + syncstart = P_OPERAND(after)->p; + syncptr = syncstart + (patinput - patinstart); /* * If we already matched from here, this time we fail. * See WBRANCH code for story about error count. @@ -3009,6 +3010,23 @@ patmatch(Upat prog) * failed anyway. */ *syncptr = errsfound + 1; + /* + * Because of backtracking, any match before this point + * can't apply to the current branch we're on so is now + * a failure --- this can happen if, on a previous + * branch, we initially marked a success before failing + * on a later part of the pattern after marking up the + * P_EXCSYNC (even an end anchor will have this effect). + * To make sure we record the current match point + * correctly, mark those down now. + * + * This might have side effects on the efficiency of + * pathological cases involving nested branches. To + * fix that we'd probably need to record matches on + * different branches separately. + */ + for (ptr = syncstart; ptr < syncptr; ++ptr) + *ptr = 0; } break; case P_EXCEND: diff --git a/Test/D02glob.ztst b/Test/D02glob.ztst index 850a535e5..4d88e5c27 100644 --- a/Test/D02glob.ztst +++ b/Test/D02glob.ztst @@ -817,6 +817,32 @@ *>*/glob.tmp/(flip|flop) *>*/glob.tmp/(flip|flop)/trailing/components +# The following set test an obscure problem with branches followed by +# exclusions that shows up when the exclusion matches against +# something other than the complete test string, hence the complicated +# double negative. + [[ ab = (|a*)~^(*b) ]] +0:Regression test for exclusion after branches: empty first alternative + + [[ ab = (b|a*)~^(*b) ]] +0:Regression test for exclusion after branches: non-empty first alternative + + [[ ab = (b*|a*)~^(*b) ]] +0:Regression test for exclusion after branches: full length first alternative + +# Corresponding tests where the exclusion should succeed, so the +# match fails. It's hard to know how to provoke bugs here... + [[ abc = (|a*)~^(*b) ]] +1:Regression test for exclusion after branches: failure case 1 + + [[ abc = (b|a*)~^(*b) ]] +1:Regression test for exclusion after branches: failure case 2 + + [[ abc = (b*|a*)~^(*b) ]] +1:Regression test for exclusion after branches: failure case 3 + +# Careful: extendedglob off from this point. + unsetopt extendedglob print -r -- ${(*)=${(@s.+.):-A+B}/(#b)(?)/-${(L)match[1]} ${match[1]}} 0:the '*' qualfier enables extended_glob for pattern matching -- cgit v1.2.3 From 40a6265aa3f611178ccb99b05522f458ac466f61 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Sun, 6 Aug 2023 13:35:20 -0700 Subject: 52013,52014,52015,52016,52017,52018: updates for coreutils option changes --- ChangeLog | 20 ++++++++++++++++++++ Completion/Unix/Command/_date | 1 + Completion/Unix/Command/_env | 1 + Completion/Unix/Command/_head | 1 + Completion/Unix/Command/_tail | 1 + Completion/Unix/Command/_tr | 1 + Completion/Unix/Command/_wc | 1 + 7 files changed, 26 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8e6e3fb18..97efdcec4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2023-08-06 Bart Schaefer + + * Shohei YOSHIDA: 52018: Completion/Unix/Command/_wc: latest + coreutils options + + * Shohei YOSHIDA: 52017: Completion/Unix/Command/_tr: latest + coreutils options + + * Shohei YOSHIDA: 52016: Completion/Unix/Command/_tail: latest + coreutils options + + * Shohei YOSHIDA: 52015: Completion/Unix/Command/_env: latest + coreutils options + + * Shohei YOSHIDA: 52014: Completion/Unix/Command/_date: latest + coreutils options + + * Shohei YOSHIDA: 52013: Completion/Unix/Command/_head: latest + coreutils options + 2023-08-01 Peter Stephenson * 52008: Src/pattern.c, Test/D02glob.ztst: Fix bug with branches diff --git a/Completion/Unix/Command/_date b/Completion/Unix/Command/_date index 97c272830..6be34ffcd 100644 --- a/Completion/Unix/Command/_date +++ b/Completion/Unix/Command/_date @@ -19,6 +19,7 @@ if _pick_variant gnu="Free Software Foundation" unix --version; then $f{-R,--rfc-email}'[display in RFC5322 format]' $f'--rfc-3339=-[display in RFC 3339 format]:precision:(date seconds ns)' '(-u --utc --universal)'{-u,--utc,--universal}'[display or set time in UTC]' + '--resolution[output the available resolution of timestamps]' '(- :)--help[output help and exit]' '(- :)--version[output version info and exit]' ) diff --git a/Completion/Unix/Command/_env b/Completion/Unix/Command/_env index a5dd49d37..f7283e132 100644 --- a/Completion/Unix/Command/_env +++ b/Completion/Unix/Command/_env @@ -9,6 +9,7 @@ case $variant in (( $#words > 2 )) && ign='!' args=( '(-)'{-i,--ignore-environment}'[start with empty environment]' + '(-0 --null)'{-0,--null}'[end each output line with NUL, not newline]' '(--ignore-environment -i --help --version)*'{-u+,--unset=}'[remove variable from the environment]:env var to remove:_parameters -g "*export*"' '(-C --chdir)'{-C+,--chdir=}'[change working directory]:directory:_directories' '(-S --split-string)'{-S+,--split-string=}'[perform word splitting]:string to split' diff --git a/Completion/Unix/Command/_head b/Completion/Unix/Command/_head index 0771b1e4d..8877600f6 100644 --- a/Completion/Unix/Command/_head +++ b/Completion/Unix/Command/_head @@ -9,6 +9,7 @@ if _pick_variant gnu=GNU unix --version; then '(-n --lines -c --bytes)'{-n+,--lines=}'[print the first (or with -, all but the last) specified lines]:number of lines:->number' '(-q --quiet --silent -v --verbose)'{-q,--quiet,--silent}'[never print headers giving file names]' '(-q --quiet --silent -v --verbose)'{-v,--verbose}'[always print headers giving file names]' + '(-z --zero-terminated)'{-z,--zero-terminated}'[line delimiter is NUL, not newline]' '(- *)--help[display help and exit]' '(- *)--version[output version information and exit]' ) diff --git a/Completion/Unix/Command/_tail b/Completion/Unix/Command/_tail index e54a0b06e..f8006abbc 100644 --- a/Completion/Unix/Command/_tail +++ b/Completion/Unix/Command/_tail @@ -16,6 +16,7 @@ if _pick_variant gnu=GNU unix --version; then '(-q --quiet --silent -v --verbose)'{-q,--quiet,--silent}'[never output headers giving file names]' '(-q --quiet --silent -v --verbose)'{-v,--verbose}'[always output headers giving file names]' '--retry[keep trying to open a file even when it becomes inaccessible]' + '(-z --zero-terminated)'{-z,--zero-terminated}'[line delimiter is NUL, not newline]' '(- *)--help[display help and exit]' '(- *)--version[output version information and exit]' ) diff --git a/Completion/Unix/Command/_tr b/Completion/Unix/Command/_tr index 1cfe1200a..6d899431c 100644 --- a/Completion/Unix/Command/_tr +++ b/Completion/Unix/Command/_tr @@ -16,6 +16,7 @@ case $variant in '(-c -C --complement)'{-c,-C,--complement}"${descr[-c]}" '(-d --delete 2)'{-d,--delete}"${descr[-d]}" '(-s --squeeze-repeats)'{-s,--squeeze-repeats}"${descr[-s]}" + '(-t --truncate-set1)'{-t,--truncate-set1}'[first truncate ARRAY1 to length of ARRAY2]' '(- 1 2)--help[display help information]' '(- 1 2)--version[display version information]' ) diff --git a/Completion/Unix/Command/_wc b/Completion/Unix/Command/_wc index 49a03ba2c..a1897e289 100644 --- a/Completion/Unix/Command/_wc +++ b/Completion/Unix/Command/_wc @@ -13,6 +13,7 @@ if _pick_variant gnu=GNU unix --version; then args+=( '(*)--files0-from=[read NUL-terminated file list from specified file]:file:_files' '(-L --max-line-length)'{-L,--max-line-length}'[print longest line lengths]' + '--total=[when to print a line with total counts]:when:(auto always only never)' ) else args=( -A "-*" "${(@)args:#(|\(*\))(|\*)--*}" ) -- cgit v1.2.3 From 9b9870a6dc526e9d1f4406a730cbaa17a462e46f Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 14 Aug 2023 15:51:12 +0900 Subject: 52037: complete only external commands for env/watch also includes a few minor fixes for _date, _env and _watch --- ChangeLog | 7 +++++++ Completion/Unix/Command/_date | 2 +- Completion/Unix/Command/_env | 4 ++-- Completion/Unix/Command/_watch | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97efdcec4..13230c3b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-08-14 Jun-ichi Takimoto + + * 52037: Completion/Unix/Command/_date, + Completion/Unix/Command/_env, Completion/Unix/Command/_watch: + complete only external commands for env and watch, with a few + more minor fixes + 2023-08-06 Bart Schaefer * Shohei YOSHIDA: 52018: Completion/Unix/Command/_wc: latest diff --git a/Completion/Unix/Command/_date b/Completion/Unix/Command/_date index 6be34ffcd..9add1a9bc 100644 --- a/Completion/Unix/Command/_date +++ b/Completion/Unix/Command/_date @@ -19,7 +19,7 @@ if _pick_variant gnu="Free Software Foundation" unix --version; then $f{-R,--rfc-email}'[display in RFC5322 format]' $f'--rfc-3339=-[display in RFC 3339 format]:precision:(date seconds ns)' '(-u --utc --universal)'{-u,--utc,--universal}'[display or set time in UTC]' - '--resolution[output the available resolution of timestamps]' + $d'--resolution[output the available resolution of timestamps]' '(- :)--help[output help and exit]' '(- :)--version[output version info and exit]' ) diff --git a/Completion/Unix/Command/_env b/Completion/Unix/Command/_env index f7283e132..bdab71bbe 100644 --- a/Completion/Unix/Command/_env +++ b/Completion/Unix/Command/_env @@ -9,7 +9,7 @@ case $variant in (( $#words > 2 )) && ign='!' args=( '(-)'{-i,--ignore-environment}'[start with empty environment]' - '(-0 --null)'{-0,--null}'[end each output line with NUL, not newline]' + '(* -0 --null)'{-0,--null}'[end each output line with NUL, not newline]' '(--ignore-environment -i --help --version)*'{-u+,--unset=}'[remove variable from the environment]:env var to remove:_parameters -g "*export*"' '(-C --chdir)'{-C+,--chdir=}'[change working directory]:directory:_directories' '(-S --split-string)'{-S+,--split-string=}'[perform word splitting]:string to split' @@ -59,7 +59,7 @@ if [[ -n $state ]]; then shift words (( CURRENT-- )) done - _normal && ret=0 + _normal -p env && ret=0 ;; user-class) if compset -P 1 '*/'; then diff --git a/Completion/Unix/Command/_watch b/Completion/Unix/Command/_watch index 91244abe7..e12add520 100644 --- a/Completion/Unix/Command/_watch +++ b/Completion/Unix/Command/_watch @@ -18,7 +18,7 @@ case $variant in '(-g --chgexit)'{-g,--chgexit}'[exit on command output change]' \ '(-n --interval)'{-n+,--interval=}'[specify update interval]:update interval (seconds) [2]' \ '(-p --precise)'{-p,--precise}'[run command at precise intervals]' \ - '(-q --equexit)'{-q,--equexit}'[exit when output of command does not change for the given cycles]:cycles' \ + '(-q --equexit)'{-q+,--equexit=}'[exit when output of command does not change for the given cycles]:cycles' \ '(-r --no-rerun)'{-r,--no-rerun}'[do not run the program on terminal resize]' \ '(-t --no-title)'{-t,--no-title}'[disable header]' \ '(-w --no-wrap)'{-w,--no-wrap}'[disable line wrapping]' \ @@ -34,7 +34,7 @@ case $variant in then _cmdstring && ret=0 else - _normal && ret=0 + _normal -p watch && ret=0 fi ;; # watch(1) has completely different semantics on freebsd compared to linux, hence: -- cgit v1.2.3 From 7233c7a750eb0a321a67281404b74b4ea0917384 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 16 Aug 2023 13:17:14 +0100 Subject: 29130, 21931 (Ray): document what typeset -t is for. This replaces documenting what it isn't for. --- ChangeLog | 5 +++++ Doc/Zsh/builtins.yo | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 13230c3b6..efcbfc644 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-08-16 Peter Stephenson + + * 29130, 29131 (Ray): Doc/Zsh/builtins.yo: document what typeset + -t is for, not what it isn't for. + 2023-08-14 Jun-ichi Takimoto * 52037: Completion/Unix/Command/_date, diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 5eb93272a..8f310f6cf 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2320,8 +2320,10 @@ readonly). Special variables that have been made readonly retain their value and readonly attribute when made local. ) item(tt(-t))( -Tags the named parameters. Tags have no special meaning to the shell. -This flag has a different meaning when used with tt(-f); see above. +Tags the named parameters. Tags only exist to flag the parameter for +the user's own purposes --- the list of tagged parameters can be queried +using `tt(typeset -t)'. Tags have no other use. Note that the tt(-t) +flag has a different meaning when used with tt(-f); see above. ) item(tt(-u))( Convert the result to upper case whenever the parameter is expanded. -- cgit v1.2.3 From d36b9ae0dc4fdf3324f8d2ff66a174785a485932 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Mon, 21 Aug 2023 17:35:25 +0900 Subject: 52059 (+52070): _scons: fix for options --jobs and --question --- ChangeLog | 5 +++++ Completion/Unix/Command/_scons | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index efcbfc644..fd3c4e85d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-08-21 Jun-ichi Takimoto + + * Shohei YOSHIDA: 52059 (+52070): Completion/Unix/Command/_scons: + fix for options -j/--jobs and -q/--question + 2023-08-16 Peter Stephenson * 29130, 29131 (Ray): Doc/Zsh/builtins.yo: document what typeset diff --git a/Completion/Unix/Command/_scons b/Completion/Unix/Command/_scons index 77fe6dfb0..2e465216c 100644 --- a/Completion/Unix/Command/_scons +++ b/Completion/Unix/Command/_scons @@ -24,14 +24,14 @@ _arguments -s -S \ '(--implicit-cache --implicit-deps-changed)--implicit-deps-changed[rescan dependencies]' \ '(--implicit-cache --implicit-deps-unchanged)--implicit-deps-unchanged[ignore changes to scanned dependencies]' \ '--interactive[start interactive mode]' \ - '(-j --jobs)-'{j,jobs=}'[specify no of jobs to run in parallel]' \ + '(-j --jobs)-'{j,-jobs=}'[specify no of jobs to run in parallel]:number of jobs' \ '(-k --keep-going)-'{k,-keep-going}'[continue after an error]' \ '--max-drift=[set the maximum clock drift]:drift (seconds)' \ '--md5-chunksize=[set chunksize for MD5 signature computation]:size (kB)' \ '(-n --just-print --dry-run --recon)-'{n,-just-print,-dry-run,-recon}"[print commands but don't run them]" \ "--no-site-dir[don't use the usual site_scons directory]" \ '--profile=[profile scons]:output file:_files' \ - '(-q --question)-'{q,question}'[query whether up-to-date]' \ + '(-q --question)-'{q,-question}'[query whether up-to-date]' \ '-Q[suppress progress messages]' \ '--random[build dependencies in random order]' \ '(-s --silent --quiet)-'{s,-silent,-quiet}"[don't print commands]" \ -- cgit v1.2.3 From 094f230e36a4de266921ed21c0d8f3f37e634073 Mon Sep 17 00:00:00 2001 From: Nojus Gudinavičius Date: Mon, 21 Aug 2023 15:48:06 +0300 Subject: users/29175: Don't need to forget zle edits if none --- ChangeLog | 6 ++++++ Src/Zle/zle_hist.c | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog b/ChangeLog index fd3c4e85d..3849db569 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-08-22 Peter Stephenson + + * Nojus Gudinavičius: users/29175: Src/Zle/zle_hist.c: don't + need to forget edits if none were made, avoiding loop over + entire history. + 2023-08-21 Jun-ichi Takimoto * Shohei YOSHIDA: 52059 (+52070): Completion/Unix/Command/_scons: diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c index cfaa70dae..0fdad70d9 100644 --- a/Src/Zle/zle_hist.c +++ b/Src/Zle/zle_hist.c @@ -68,6 +68,13 @@ Keymap isearch_keymap; */ #define GETZLETEXT(ent) ((ent)->zle_text ? (ent)->zle_text : (ent)->node.nam) +/* + * Flag that edits have been made to a zle line. + * If not set, nothing to forget. + */ +/**/ +int have_edits = 0; + /**/ void remember_edits(void) @@ -81,6 +88,7 @@ remember_edits(void) if (ent->zle_text) free(ent->zle_text); ent->zle_text = zlemetaline ? ztrdup(line) : line; + have_edits = 1; } else if (!zlemetaline) free(line); } @@ -90,6 +98,10 @@ remember_edits(void) void forget_edits(void) { + if (!have_edits) { + return; + } + have_edits = 0; Histent he; for (he = hist_ring; he; he = up_histent(he)) { -- cgit v1.2.3 From 660a629864ba2493b473f749b8bc010bcbbb0cf0 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Sun, 27 Aug 2023 14:59:03 -0700 Subject: 52034: update sqlite3 completion for version 3.42.0 --- ChangeLog | 5 +++++ Completion/Unix/Command/_sqlite | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3849db569..a70adefdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-08-27 Bart Schaefer + + * Shohei YOSHIDA: 52034: Completion/Unix/Command/_sqlite: + update for version 3.42.0 + 2023-08-22 Peter Stephenson * Nojus Gudinavičius: users/29175: Src/Zle/zle_hist.c: don't diff --git a/Completion/Unix/Command/_sqlite b/Completion/Unix/Command/_sqlite index 7ef3c6daa..6425732f1 100644 --- a/Completion/Unix/Command/_sqlite +++ b/Completion/Unix/Command/_sqlite @@ -55,9 +55,13 @@ options+=( $^dashes'-mmap[set default mmap size]:size' $^dashes'-newline[set output row separator]:separator [\n]' $^dashes'-nofollow[refuse to open symbolic links to database files]' + $^dashes'-nonce[set the safe-mode escape nonce]:string' $^dashes'-pagecache[specify size and number of slots for page cache memory]:size (bytes): :slots' + $^dashes'-pcachetrace[trace all page cache operations]' $^dashes'-readonly[open the database read-only]' + $^dashes'-safe[enable safe-mode]' $^dashes'-stats[print memory stats before each finalize]' + $^dashes'-unsafe-testing[allow unsafe commands and modes for testing]' $^dashes'-vfs[use specified default VFS]:vfs:(unix-dotfile unix-excl unix-none unix-namedsem)' $^dashes'-zip[open the file as a ZIP Archive]' ) -- cgit v1.2.3 From 97b4a30c4e5f4837bac7c5c67bd583d3aeaf7886 Mon Sep 17 00:00:00 2001 From: Robert Woods Date: Sun, 27 Aug 2023 15:05:08 -0700 Subject: 52053: whitelist capability CAP_WAKE_ALARM Since the systemd update v254 from July 28, 2023, the capability 'CAP_WAKE_ALARM' is passed by default to some user process (especially desktop managers). Since 'CAP_WAKE_ALARM' is very narrow in focus, it is preferable that zsh does not consider it as a 'privileged' capability. --- ChangeLog | 3 +++ Src/utils.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a70adefdd..bb6afe127 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-08-27 Bart Schaefer + * Robert Woods: 52053: Src/utils.c: whitelist capability + CAP_WAKE_ALARM in 'privasserted' function + * Shohei YOSHIDA: 52034: Completion/Unix/Command/_sqlite: update for version 3.42.0 diff --git a/Src/utils.c b/Src/utils.c index 94a33453f..7040d0954 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -7551,9 +7551,9 @@ privasserted(void) /* POSIX doesn't define a way to test whether a capability set * * is empty or not. Typical. I hope this is conforming... */ cap_flag_value_t val; - cap_value_t n; - for(n = 0; !cap_get_flag(caps, n, CAP_EFFECTIVE, &val); n++) - if(val) { + cap_value_t cap; + for(cap = 0; !cap_get_flag(caps, cap, CAP_EFFECTIVE, &val); cap++) + if(val && cap != CAP_WAKE_ALARM) { cap_free(caps); return 1; } -- cgit v1.2.3 From 2a854aae481e7eb064729db28a71ed0efb2f33e6 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 27 Aug 2023 15:22:14 -0700 Subject: 52028: improvements to _shadow / _unshadow, plus helper and doc --- ChangeLog | 4 +++ Completion/Base/Utility/_shadow | 66 ++++++++++++++++++++++++++++------------- Doc/Zsh/compsys.yo | 53 +++++++++++++++++++-------------- Doc/Zsh/contrib.yo | 21 +++++++++++++ Functions/Misc/mkshadow | 11 +++++++ 5 files changed, 112 insertions(+), 43 deletions(-) create mode 100644 Functions/Misc/mkshadow diff --git a/ChangeLog b/ChangeLog index bb6afe127..412dbda61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-08-27 Bart Schaefer + * 52028: Completion/Base/Utility/_shadow, Doc/Zsh/compsys.yo, + Doc/Zsh/contrib.yo, Functions/Misc/mkshadow: improve _shadow + and _unshadow, add helper function and update documentation + * Robert Woods: 52053: Src/utils.c: whitelist capability CAP_WAKE_ALARM in 'privasserted' function diff --git a/Completion/Base/Utility/_shadow b/Completion/Base/Utility/_shadow index 5b0f79c36..b5a8acb24 100644 --- a/Completion/Base/Utility/_shadow +++ b/Completion/Base/Utility/_shadow @@ -8,7 +8,7 @@ # } # # Invoke callers of fname # } always { -# _unshadow fname +# _unshadow # } ## Alternate usage: # { @@ -19,7 +19,7 @@ # } # # Invoke callers of fname # } always { -# _unshadow -s suffix fname +# _unshadow # } ## @@ -33,36 +33,62 @@ zmodload zsh/parameter # Or what? # This probably never comes up, but protect ourself from recursive call # chains that may duplicate the top elements of $funcstack by creating # a counter of _shadow calls and using it to make shadow names unique. -typeset -gHi _shadowdepth=0 +builtin typeset -gHi .shadow.depth=0 +builtin typeset -gHa .shadow.stack # Create a copy of each fname so that a caller may redefine _shadow() { - local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:$((_shadowdepth+1)) ) - local fname + emulate -L zsh + local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:$((.shadow.depth+1)) ) + local fname shadowname + local -a fnames zparseopts -K -A fsfx -D s: for fname; do - local shadowname=${fname}@${fsfx[-s]} - (( ${+functions[$fname]} )) && - builtin functions -c $fname $shadowname + shadowname=${fname}@${fsfx[-s]} + if (( ${+functions[$shadowname]} )) + then + # Called again with the same -s, just ignore it + continue + elif (( ${+functions[$fname]} )) + then + builtin functions -c -- $fname $shadowname + fnames+=(f@$fname) + elif (( ${+builtins[$fname]} )) + then + eval "function -- $shadowname { builtin $fname \"\$@\" }" + fnames+=(b@$fname) + else + eval "function -- $shadowname { command $fname \"\$@\" }" + fnames+=(c@$fname) + fi done - ((_shadowdepth++)) + [[ -z $REPLY ]] && REPLY=${fsfx[-s]} + builtin set -A .shadow.stack ${fsfx[-s]} $fnames -- ${.shadow.stack} + ((.shadow.depth++)) } # Remove the redefined function and shadowing name _unshadow() { - local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:${_shadowdepth} ) - local fname - zparseopts -K -A fsfx -D s: - for fname; do - local shadowname=${fname}@${fsfx[-s]} - if (( ${+functions[$shadowname]} )); then - builtin functions -c $shadowname $fname - builtin unfunction $shadowname - elif (( ${+functions[$fname]} )); then - builtin unfunction $fname + emulate -L zsh + local fname shadowname fsfx=${.shadow.stack[1]} + local -a fnames + [[ -n $fsfx ]] || return 1 + shift .shadow.stack + while [[ ${.shadow.stack[1]?no shadows} != -- ]]; do + fname=${.shadow.stack[1]#?@} + shadowname=${fname}@${fsfx} + if (( ${+functions[$fname]} )); then + builtin unfunction -- $fname fi + case ${.shadow.stack[1]} in + (f@*) builtin functions -c -- $shadowname $fname ;& + ([bc]@*) builtin unfunction -- $shadowname ;; + esac + shift .shadow.stack done - ((_shadowdepth--)) + [[ -z $REPLY ]] && REPLY=$fsfx + shift .shadow.stack + ((.shadow.depth--)) } # This is tricky. When we call _shadow recursively from autoload, diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 33baeab49..3f708eb5a 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -5229,13 +5229,12 @@ and hence is not normally called explicitly. ) findex(_shadow) findex(_unshadow) -xitem(tt(_shadow) [ tt(-s) var(suffix) ] var(command_name) ...) -item(tt(_unshadow) [ tt(-s) var(suffix) ] var(command_name) ...)( +xitem(tt(_shadow) [ tt(-s) var(suffix) ] [ -- ] var(command_name) ...) +item(tt(_unshadow))( The tt(_shadow) function creates a copy of each of the shell functions in the var(command_name) arguments. The original functions can then -be replaced by new implementations. A later call to tt(_unshadow), -with the same var(command_name) list, removes the new implementations, -if any, and restores the originals. +be replaced by new implementations. A later call to tt(_unshadow) +removes the new implementations, if any, and restores the originals. Recommended usage is to pair tt(_shadow) and tt(_unshadow) calls by use of an `tt(always)' block: @@ -5246,30 +5245,38 @@ example({ } # Invoke callers of fname } always { - _unshadow fname + _unshadow }) -Any var(command_name) may instead be a builtin, but in that case no -copy is created. The expectation is that an initial tt(_shadow) is -followed by creating a wrapper function, and therafter any nested or -recursive calls thus copy and replace the wrapper function. +The var(suffix), if supplied, is prepended by an `tt(@)' character and +then appended to each var(command_name) to create the copy. Thus +example(_shadow -s XX foo) +creates a function named `tt(foo@XX)'. This provides a well-known +name for the original implementation if the new implementation needs +to call it as a wrapper. If a nested call to tt(_shadow) uses the +same var(suffix), em(no new copy is made). The presumption thus is +that suffixes and new implementations correspond one to one. + +If var(command_name) is a builtin or external command, and there has been +no preceding tt(_shadow) replacement made, the function so created calls +the shadowed name prefixed by the tt(builtin) or tt(command) keywords as +appropriate. example({ - _shadow compadd - compadd LPAR()RPAR() { builtin compadd -O tmparr "$@" } + _shadow -s wrap compadd + compadd LPAR()RPAR() { + # compadd@wrap runs builtin compadd + compadd@wrap -O tmparr "$@" } } always { - _unshadow compadd + _unshadow }) -The var(suffix), if supplied, is prepended by an `tt(@)' character and -then appended to each var(command_name) to create the copy. Thus -example(_shadow -s XX foo) -creates a function named `tt(foo@XX)' (unless `tt(foo)' is a builtin). -Note that a nested call to tt(_shadow) with the same var(suffix) may -result in name collisions and unexpected results, but this provides a -well-known name for the original function if the new implementation -needs to call it as a wrapper. The same var(suffix) must be used in -the call to tt(_unshadow). When no var(suffix) is present, -tt(_shadow) creates a unique suffix to avoid name collisions. +When no var(suffix) argument is present, tt(_shadow) creates a unique +suffix to avoid name collisions. + +Arguments of tt(_unshadow) are ignored. Every listed var(command_name) +for the most recent call to tt(_shadow) is removed. This differs from +an early implementation that required tt(_unshadow) to receive the +same var(suffix) and var(command_name) list as tt(_shadow). ) findex(_store_cache) item(tt(_store_cache) var(cache_identifier) var(param) ...)( diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 96de5aa9b..ef11d77ad 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -4336,6 +4336,27 @@ example(is-at-least 3.1.6-15 && setopt NO_GLOBAL_RCS is-at-least 3.1.0 && setopt HIST_REDUCE_BLANKS is-at-least 2.6-17 || print "You can't use is-at-least here.") ) +findex(mkshadow) +findex(rmshadow) +xitem(tt(mkshadow) [ tt(-s) var(suffix) ] [ -- ] var(command_name) ...) +item(tt(rmshadow))( +These functions are an interface to the tt(_shadow) and tt(_unshadow) +completion utilities to make them more easily accessible in other +contexts. Usage is exactly as for the completion utility: +example({ + mkshadow fname + function fname { + # Do your new thing + } + # Invoke callers of fname +} always { + rmshadow +}) + +Upon return, the value of tt($REPLY) is the suffix used to create a +copy of the original var(command_name), so var(command_name)tt(@$REPLY) +invokes that original. +) findex(nslookup) item(tt(nslookup) [ var(arg) ... ])( This wrapper function for the tt(nslookup) command requires the diff --git a/Functions/Misc/mkshadow b/Functions/Misc/mkshadow new file mode 100644 index 000000000..2ae3a0f2c --- /dev/null +++ b/Functions/Misc/mkshadow @@ -0,0 +1,11 @@ +#autoload +# Front-end to the completion helper _shadow for use outside completion. +# This just forces proper autoload of _shadow/_unshadow and calls them. + +autoload _shadow +mkshadow() { unset REPLY; _shadow "$@" } +rmshadow() { unset REPLY; _unshadow } + +# Bootstrap because of autoload special case +unset REPLY +_shadow "$@" -- cgit v1.2.3 From 5f984319b5154e9370dbf9c2012b12a133708f48 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 27 Aug 2023 15:27:45 -0700 Subject: Marlon Richert: 51861: fix _approximate when compadd has been overridden Before this patch, if compadd had been overridden by a function of the same name, _approximate would not do corrections. --- ChangeLog | 4 +++ Completion/Base/Completer/_approximate | 48 ++++++++++++++++------------------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 412dbda61..6b7b1173b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-08-27 Bart Schaefer + * Marlon Richert: 51861 (tweaked for 52028): + Completion/Base/Completer/_approximate: allow _approximate + to provide corrections even when compadd is overridden + * 52028: Completion/Base/Utility/_shadow, Doc/Zsh/compsys.yo, Doc/Zsh/contrib.yo, Functions/Misc/mkshadow: improve _shadow and _unshadow, add helper function and update documentation diff --git a/Completion/Base/Completer/_approximate b/Completion/Base/Completer/_approximate index dcd8b2776..96860b5a7 100644 --- a/Completion/Base/Completer/_approximate +++ b/Completion/Base/Completer/_approximate @@ -12,7 +12,6 @@ local _comp_correct _correct_expl _correct_group comax cfgacc match local oldcontext="${curcontext}" opm="$compstate[pattern_match]" -local dounfunction integer ret=1 if [[ "$1" = -a* ]]; then @@ -44,34 +43,31 @@ fi _tags corrections original -# Otherwise temporarily define a function to use instead of -# the builtin that adds matches. This is used to be able -# to stick the `(#a...)' in the right place (after an -# ignored prefix). +# Otherwise temporarily define a function to use instead of the builtin that +# adds matches. This is used to be able to stick the `(#a...)' in the right +# place (after an ignored prefix). # -# Current shell structure for use with "always", to make sure -# we unfunction the compadd. +# Current shell structure for use with "always", to make sure we unfunction our +# compadd and restore any compadd function defined previously. { -if (( ! $+functions[compadd] )); then - dounfunction=1 - compadd() { - local ppre="$argv[(I)-p]" - - [[ ${argv[(I)-[a-zA-Z]#U[a-zA-Z]#]} -eq 0 && - "${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return - - if [[ "$PREFIX" = \~* && ( ppre -eq 0 || "$argv[ppre+1]" != \~* ) ]]; then - PREFIX="~(#a${_comp_correct})${PREFIX[2,-1]}" - else - PREFIX="(#a${_comp_correct})$PREFIX" - fi +_shadow -s _approximate compadd +compadd() { + local ppre="$argv[(I)-p]" - (( $_correct_group && ${${argv[1,(r)-(|-)]}[(I)-*[JV]]} )) && - _correct_expl[_correct_group]=${argv[1,(r)-(-|)][(R)-*[JV]]} + [[ ${argv[(I)-[a-zA-Z]#U[a-zA-Z]#]} -eq 0 && + "${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return - builtin compadd "$_correct_expl[@]" "$@" - } -fi + if [[ "$PREFIX" = \~* && ( ppre -eq 0 || "$argv[ppre+1]" != \~* ) ]]; then + PREFIX="~(#a${_comp_correct})${PREFIX[2,-1]}" + else + PREFIX="(#a${_comp_correct})$PREFIX" + fi + + (( $_correct_group && ${${argv[1,(r)-(|-)]}[(I)-*[JV]]} )) && + _correct_expl[_correct_group]=${argv[1,(r)-(-|)][(R)-*[JV]]} + + compadd@_approximate "$_correct_expl[@]" "$@" +} _comp_correct=1 @@ -115,7 +111,7 @@ while [[ _comp_correct -le comax ]]; do done } always { - [[ -n $dounfunction ]] && (( $+functions[compadd] )) && unfunction compadd + _unshadow } (( ret == 0 )) && return 0 -- cgit v1.2.3 From 53fe16e9b52f44e2c9327901ef60b5a5a4384a96 Mon Sep 17 00:00:00 2001 From: sergio Date: Mon, 28 Aug 2023 12:02:15 +0900 Subject: 51858 (+52073): virsh's edit command accepts all domains --- ChangeLog | 5 +++++ Completion/Unix/Command/_libvirt | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6b7b1173b..9b583a6ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-08-28 Jun-ichi Takimoto + + * sergio: 51858 (+52073): Completion/Unix/Command/_libvirt: + virsh's edit subcommand accepts all domains + 2023-08-27 Bart Schaefer * Marlon Richert: 51861 (tweaked for 52028): diff --git a/Completion/Unix/Command/_libvirt b/Completion/Unix/Command/_libvirt index a3ab5a68a..bd605b9c9 100644 --- a/Completion/Unix/Command/_libvirt +++ b/Completion/Unix/Command/_libvirt @@ -20,7 +20,6 @@ typeset -A dom_opts dom_opts=( console " " destroy " " - edit " " managedsave " " reboot " " reset " " -- cgit v1.2.3 From a8853323dd631ba26869ea6e0bf1b8098247731d Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Mon, 28 Aug 2023 13:12:50 +0900 Subject: 52098, 52099, 52100, 52105(+minor tweak): update for latest macOS --- ChangeLog | 6 ++++++ Completion/Darwin/Command/_open | 8 +++++++- Completion/Darwin/Command/_otool | 7 ++++++- Completion/Darwin/Command/_sw_vers | 7 ++++++- Completion/Darwin/Command/_system_profiler | 12 ++++-------- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b583a6ed..356d7a48c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2023-08-28 Jun-ichi Takimoto + * Shohei YOSHIDA: 52098(+comment), 52099, 52100, 52105(+52106): + Completion/Darwin/Command/_open, Completion/Darwin/Command/_otool, + Completion/Darwin/Command/_sw-vers, + Completion/Darwin/Command/_system_profiler: + update for latest macOS (with a few fixes) + * sergio: 51858 (+52073): Completion/Unix/Command/_libvirt: virsh's edit subcommand accepts all domains diff --git a/Completion/Darwin/Command/_open b/Completion/Darwin/Command/_open index 2563e5eb5..1c693dfb8 100644 --- a/Completion/Darwin/Command/_open +++ b/Completion/Darwin/Command/_open @@ -25,14 +25,20 @@ _open() { '(: * -)--args[pass remaining arguments to application]:*:::argument' \ '(-a -b -e -f -R -t)-b+[specify application bundle identifier]: :->bundle-ids' \ '(-a -b -e -f -R -t)-e[open with TextEdit]' \ + '*--env[add the environment variable of the launched application]:env_var=value:_parameters -g "*export*" -qS=' \ '(-h)-f[open standard input with TextEdit or specified application]' \ '(-R)-F[open application with fresh state]' \ - '-g[do not bring application to foreground]' \ + '(-j)-g[do not bring application to foreground]' \ '(-f)-h[open library header file]' \ + '(-g)-j[launch the app hidden]' \ '(-R)-n[always open new instance of application]' \ '(-a -b -e -f -F -n -s -t -W --args)-R[reveal in Finder]' \ '(-R)-s+[specify SDK name/version]: :->sdks' \ + '--stdin[launch the application with stdin connected to the given file]:file:_files' \ + '--stdout[launch the application with stdout connected to the given file]:file:_files' \ + '--stderr[launch the application with stderr connected to the given file]:file:_files' \ '(-a -b -e -f -R -t)-t[open with default text editor]' \ + '-u[open URL with whatever application claims the url scheme]:url:_urls' \ '(-R)-W[wait for application to exit]' \ '(-f)*: :->files' \ && ret=0 diff --git a/Completion/Darwin/Command/_otool b/Completion/Darwin/Command/_otool index c3fc70b91..b6a30a730 100644 --- a/Completion/Darwin/Command/_otool +++ b/Completion/Darwin/Command/_otool @@ -13,6 +13,7 @@ _arguments \ '-D[display just the internal name of shared lib]' \ '-s[display the contents of the specified section]:segment name: :section name: ' \ '-t[display the contents of (__TEXT,__text) section]' \ + '-x[display the content of every __text section found in the file]' \ '-d[display the contents of (__DATA,__data) section]' \ '-o[display the contents of __OBJC segment]' \ '-r[display the relocation entries]' \ @@ -25,6 +26,9 @@ _arguments \ '-G[display the data in code table]' \ '-C[display the linker optimization hints]' \ '-P[print the info_plist section as strings]' \ + '-dyld_info[print bind and rebase information used by dyld]' \ + '-dyld_opcodes[print raw dyld bind and rebase opcodes present in a final linked binary]' \ + '-chained_fixups[print raw chained fixup data present in a final linked binary]' \ '-p[with -t and -v/V: start disassembly from the specified symbol]:symbol name: ' \ '-v[display verbosely (symbolically) when possible]' \ '-V[display disassembled operands symbolically]' \ @@ -34,7 +38,8 @@ _arguments \ '-function_offsets[with disassembly, print decimal offset from the last label]' \ '-j[with disassembly, print opcode bytes]' \ "-Q[use otool's disassembler]" \ - '-arch[select the specified architecture from a universal file]:arch:(i386 x86_64)' \ + '-addr_slide=[add an arbitrary slide to each pointer value when it is displayed]:slide size' \ + '-arch[select the specified architecture from a universal file]:arch:(i386 x86_64 x86_64h arm64 arm64e all)' \ '-m[object file names are not assumed to be in archive(member) syntax]' \ '(- *)--version[print version of otool]' \ '*:file:_object_files' && return 0 diff --git a/Completion/Darwin/Command/_sw_vers b/Completion/Darwin/Command/_sw_vers index 11814e0b0..415d3a05c 100644 --- a/Completion/Darwin/Command/_sw_vers +++ b/Completion/Darwin/Command/_sw_vers @@ -1,6 +1,11 @@ #compdef sw_vers +# Only options with a single dash '-' are accepted on Monterey or older, +# but both a single and double dashes are accepted on Ventura (or newer). +# We may replace '-' by '--' when Monterey fades out. + _arguments : \ '(-)-buildVersion[display build version only]' \ '(-)-productName[display product name only]' \ - '(-)-productVersion[display product version only]' + '(-)-productVersion[display product version only]' \ + '(-)-productVersionExtra[display rapid security response version only]' diff --git a/Completion/Darwin/Command/_system_profiler b/Completion/Darwin/Command/_system_profiler index fe197579d..0fd8b473b 100644 --- a/Completion/Darwin/Command/_system_profiler +++ b/Completion/Darwin/Command/_system_profiler @@ -4,17 +4,13 @@ typeset -A opt_args local context state state_descr line local -a _data_types -# TODO: Should this be static? Calling `system_profiler -listDataTypes` takes -# about 0.07-0.08 secs on my machine. Does this list ever change (between -# different versions of OS X)? -_data_types=( SP{AirPort,Applications,Audio,Bluetooth,Camera,CardReader,Component,ConfigurationProfile,DeveloperTools,Diagnostics,DisabledSoftware,DiscBurning,Displays,Ethernet,Extensions,FibreChannel,FireWire,Firewall,Fonts,Frameworks,Hardware,HardwareRAID,InstallHistory,Logs,ManagedClient,Memory,Network,NetworkLocation,NetworkVolume,PCI,ParallelATA,ParallelSCSI,Power,PrefPane,Printers,PrintersSoftware,SAS,SPI,SerialATA,Software,StartupItem,Storage,SyncServices,Thunderbolt,USB,UniversalAccess,WWAN}DataType ) -# the dynamic alternative is: -#_data_types=( ${${(f)"$(_call_program path system_profiler -listDataTypes 2>/dev/null)"}[2,-1]} ) +_data_types=( ${${(f)"$(_call_program data-types system_profiler -listDataTypes 2>/dev/null)"}[2,-1]} ) _arguments \ '(- *)-usage' \ '(- *)-listDataTypes[lists the available datatypes]' \ - '(-listDataTypes -usage)-xml[generate xml output]' \ + '(-listDataTypes -usage -json)-xml[generate xml output]' \ + '(-listDataTypes -usage -xml)-json[generate json output]' \ '(-listDataTypes -usage)-detailLevel[level of detail for the report]:detail level:(mini basic full)' \ - '(-listDataTypes -usage)-timeout+[maximum time to wait in seconds]' \ + '(-listDataTypes -usage)-timeout+[maximum time to wait in seconds(0 means no timeout)]:timeout seconds' \ '(-listDataTypes -usage)*:data type:'"($_data_types)" -- cgit v1.2.3 From 9ff1b2810e70658b2364b737478e9a996de0a644 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 3 Sep 2023 11:42:00 -0700 Subject: users/29220: fix bug with assignment to private following explicit unset --- ChangeLog | 5 +++++ Src/Modules/param_private.c | 29 ++++++++++++++++++----------- Test/V10private.ztst | 7 +++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 356d7a48c..1fc00562c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-09-03 Bart Schaefer + + * users/29220: Src/Modules/param_private.c, Test/V10private.ztst: + fix bug with assignment to private following explicit unset + 2023-08-28 Jun-ichi Takimoto * Shohei YOSHIDA: 52098(+comment), 52099, 52100, 52105(+52106): diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index e43f0edb4..8e04b2b95 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -230,7 +230,9 @@ setfn_error(Param pm) * calling the original unsetfn. This assures that if the old unsetfn * wants to use its getfn or setfn, they're unconditionally present. * The "explicit" flag indicates that "unset" was called, if zero the - * parameter is going out of scope (see params.c). + * parameter is going out of scope (see params.c). PM_DECLARED is + * asserted as if TYPESET_TO_UNSET were in use so that the private + * parameter is re-used rather than re-created when assigned again. * */ @@ -268,9 +270,10 @@ pps_unsetfn(Param pm, int explicit) pm->gsu.s = gsu; if (locallevel <= pm->level) gsu->unsetfn(pm, explicit); - if (explicit) + if (explicit) { + pm->node.flags |= PM_DECLARED; pm->gsu.s = (GsuScalar)c; - else + } else zfree(c, sizeof(struct gsu_closure)); } @@ -307,9 +310,10 @@ ppi_unsetfn(Param pm, int explicit) pm->gsu.i = gsu; if (locallevel <= pm->level) gsu->unsetfn(pm, explicit); - if (explicit) + if (explicit) { + pm->node.flags |= PM_DECLARED; pm->gsu.i = (GsuInteger)c; - else + } else zfree(c, sizeof(struct gsu_closure)); } @@ -346,9 +350,10 @@ ppf_unsetfn(Param pm, int explicit) pm->gsu.f = gsu; if (locallevel <= pm->level) gsu->unsetfn(pm, explicit); - if (explicit) + if (explicit) { + pm->node.flags |= PM_DECLARED; pm->gsu.f = (GsuFloat)c; - else + } else zfree(c, sizeof(struct gsu_closure)); } @@ -386,9 +391,10 @@ ppa_unsetfn(Param pm, int explicit) pm->gsu.a = gsu; if (locallevel <= pm->level) gsu->unsetfn(pm, explicit); - if (explicit) + if (explicit) { + pm->node.flags |= PM_DECLARED; pm->gsu.a = (GsuArray)c; - else + } else zfree(c, sizeof(struct gsu_closure)); } @@ -427,9 +433,10 @@ pph_unsetfn(Param pm, int explicit) pm->gsu.h = gsu; if (locallevel <= pm->level) gsu->unsetfn(pm, explicit); - if (explicit) + if (explicit) { + pm->node.flags |= PM_DECLARED; pm->gsu.h = (GsuHash)c; - else + } else zfree(c, sizeof(struct gsu_closure)); } diff --git a/Test/V10private.ztst b/Test/V10private.ztst index b191afcb7..b876f548d 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -377,6 +377,13 @@ F:Should we allow "public" namerefs to private parameters? *?*no such variable: ptr1 *?*no such variable: ptr2 + () { + private x=1 + unset x + x=2 + } +0:regression test for unset private + %clean rm -r private.TMP -- cgit v1.2.3 From c0caef561323b91ea0c4aa101b564f92ab51b68d Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 4 Sep 2023 15:07:52 +0900 Subject: 52112: use '_normal -p subcmd' to complete only external command --- ChangeLog | 12 ++++++++++++ Completion/BSD/Command/_jexec | 2 +- Completion/Linux/Command/_chrt | 2 +- Completion/Linux/Command/_cpupower | 2 +- Completion/Linux/Command/_ionice | 2 +- Completion/Linux/Command/_setpriv | 2 +- Completion/Linux/Command/_sysstat | 2 +- Completion/Unix/Command/_chroot | 2 +- Completion/Unix/Command/_mosh | 4 ++-- Completion/Unix/Command/_route | 2 +- Completion/Unix/Command/_screen | 2 +- Completion/Unix/Command/_script | 2 +- Completion/Unix/Command/_ssh | 4 ++-- Completion/Unix/Command/_stdbuf | 2 +- Completion/Unix/Command/_timeout | 2 +- 15 files changed, 28 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1fc00562c..0c782f617 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2023-09-04 Jun-ichi Takimoto + + * 52112: Completion/BSD/Command/_jexec, + Completion/Linux/Command/_chrt, Completion/Linux/Command/_cpupower, + Completion/Linux/Command/_ionice,Completion/Linux/Command/_setpriv, + Completion/Linux/Command/_sysstat, Completion/Unix/Command/_chroot, + Completion/Unix/Command/_mosh, Completion/Unix/Command/_route, + Completion/Unix/Command/_screen, Completion/Unix/Command/_script, + Completion/Unix/Command/_ssh, Completion/Unix/Command/_stdbuf, + Completion/Unix/Command/_timeout: use '_normal -p $service' to + complete only external commands + 2023-09-03 Bart Schaefer * users/29220: Src/Modules/param_private.c, Test/V10private.ztst: diff --git a/Completion/BSD/Command/_jexec b/Completion/BSD/Command/_jexec index 6a2d05a81..cd99ebe91 100644 --- a/Completion/BSD/Command/_jexec +++ b/Completion/BSD/Command/_jexec @@ -6,7 +6,7 @@ _jexec_normal() { # relative paths are relative to the jail's root path=( "$(_call_program paths jls -j $words[1] path)"/$^path ) shift 1 words; (( CURRENT-- )) - _normal + _normal -p $service } _jexec() { diff --git a/Completion/Linux/Command/_chrt b/Completion/Linux/Command/_chrt index 6789b66cf..5431b0799 100644 --- a/Completion/Linux/Command/_chrt +++ b/Completion/Linux/Command/_chrt @@ -62,7 +62,7 @@ elif (( CURRENT == 1 )); then else shift words (( CURRENT-- )) - _normal && ret=0 + _normal -p $service && ret=0 fi return ret diff --git a/Completion/Linux/Command/_cpupower b/Completion/Linux/Command/_cpupower index 6763bdd12..d342b69d9 100644 --- a/Completion/Linux/Command/_cpupower +++ b/Completion/Linux/Command/_cpupower @@ -95,7 +95,7 @@ case $state in '-i+[measurement interval]:interval (seconds)' '-c[schedule on every core]' '-v[increase verbosity]' - '*:::command: _normal' + '*:::command: _normal -p $service' ) ;; esac diff --git a/Completion/Linux/Command/_ionice b/Completion/Linux/Command/_ionice index ba403ca56..9989cd6a9 100644 --- a/Completion/Linux/Command/_ionice +++ b/Completion/Linux/Command/_ionice @@ -28,7 +28,7 @@ if [[ -n $state ]]; then elif (( $+opt_args[args--u] || $+opt_args[args---uid] )); then _message -e uids 'user id' else - _normal && ret=0 + _normal -p $service && ret=0 fi fi diff --git a/Completion/Linux/Command/_setpriv b/Completion/Linux/Command/_setpriv index 196f2f627..9e38152b9 100644 --- a/Completion/Linux/Command/_setpriv +++ b/Completion/Linux/Command/_setpriv @@ -96,7 +96,7 @@ _arguments -C -S -s \ '--selinux-label[request a selinux label]:SELinux labels: ' \ '--apparmor-profile[request an apparmor profile]:AppArmor profiles: ' \ '--reset-env[set environment as for a classic login shell]' \ - '*:::command:_normal' \ + '*:::command: _normal -p $service' \ && return 0 case $state in diff --git a/Completion/Linux/Command/_sysstat b/Completion/Linux/Command/_sysstat index 5620da73d..0baae0764 100644 --- a/Completion/Linux/Command/_sysstat +++ b/Completion/Linux/Command/_sysstat @@ -130,7 +130,7 @@ _pidstat() { _arguments -s : \ '-C[filter tasks by string]:task filter' \ '-d[report I/O statistics]' \ - '-e[execute specified program and monitor it with pidstat]:*::command: _normal' \ + '-e[execute specified program and monitor it with pidstat]:*::command: _normal -p $service' \ '-H[display timestamp in seconds since the epoch]' \ '-h[display horizontally]' \ '-I[divide CPU usage by number of processors]' \ diff --git a/Completion/Unix/Command/_chroot b/Completion/Unix/Command/_chroot index 516992694..a9c577bd7 100644 --- a/Completion/Unix/Command/_chroot +++ b/Completion/Unix/Command/_chroot @@ -33,7 +33,7 @@ case $variant in ;; esac -args+=( '1:new root directory:_directories' '*:::command:_normal' ) +args+=( '1:new root directory:_directories' '*::: : _normal -p $service' ) _arguments -s -S : $args && ret=0 diff --git a/Completion/Unix/Command/_mosh b/Completion/Unix/Command/_mosh index 7d1250320..6d0f746f8 100644 --- a/Completion/Unix/Command/_mosh +++ b/Completion/Unix/Command/_mosh @@ -7,7 +7,7 @@ _arguments -C \ '(-)--help[display help information]' \ '(-)--version[display version information]' \ "--no-init[don't set terminal init string]" \ - '--ssh=[specify ssh command to setup session]:ssh command:_normal' \ + '--ssh=[specify ssh command to setup session]:ssh command: _cmdstring' \ '--port=[specify server-side port range]:port:_sequence -n 2 -s \: _ports' \ '(-a -n)--predict=[control speculative local echo]:mode:(adaptive always never)' \ '(--predict -n)-a[synonym for --predict=always]' \ @@ -22,7 +22,7 @@ _arguments -C \ '--local[run mosh-server locally without using ssh]' \ '--experimental-remote-ip=[select method for discovering remote IP address to use for mosh]:method:(local remote proxy)' \ '1:remote host name:->userhost' \ - '*:::args:_normal' && ret=0 + '*::: : _normal -p $service' && ret=0 case $state in userhost) diff --git a/Completion/Unix/Command/_route b/Completion/Unix/Command/_route index 95df6d936..f0775a5d2 100644 --- a/Completion/Unix/Command/_route +++ b/Completion/Unix/Command/_route @@ -196,7 +196,7 @@ if [[ -n $state ]]; then if [[ $line[1] = exec ]]; then shift words (( CURRENT-- )) - _normal + _normal -p $service && return elif [[ $line[1] = (flush|monitor) ]]; then sequential=() fi diff --git a/Completion/Unix/Command/_screen b/Completion/Unix/Command/_screen index 6d47d2638..9336ae82d 100644 --- a/Completion/Unix/Command/_screen +++ b/Completion/Unix/Command/_screen @@ -107,7 +107,7 @@ if [[ -n $state ]]; then elif (( CURRENT > 2 )) && [[ ${words[1]} == /dev/* ]]; then _message "no more parameters" else - _normal + _normal -p $service fi ;; attached-sessions) diff --git a/Completion/Unix/Command/_script b/Completion/Unix/Command/_script index 7a3960be0..f39cfe535 100644 --- a/Completion/Unix/Command/_script +++ b/Completion/Unix/Command/_script @@ -68,7 +68,7 @@ case $OSTYPE in '-F[send output to specified named pipe]:fifo:_files -g "*(p)"' '-t+[specify interval of data flushing]:interval (seconds)' '-k[log keys sent to the program as well as output]' - '*:::arguments: _normal' + '*:::arguments: _normal $service' ) ;| darwin*|freebsd*) diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index fd2a90b59..0ba1f3775 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -136,7 +136,7 @@ _ssh () { '(-k -c)-s[force sh-style shell]' \ '-t+[set default maximum lifetime for identities]: :_numbers -u seconds "maximum lifetime" \:s\:seconds m\:minutes h\:hours d\:days w\:weeks' \ '-v[verbose mode]' \ - '*::command: _normal' + '*::command: _normal -p $service' return ;; ssh-keygen) @@ -738,7 +738,7 @@ _ssh () { local -a _comp_priv_prefix shift 1 words (( CURRENT-- )) - _normal + _normal -p $service return ;; destinations) diff --git a/Completion/Unix/Command/_stdbuf b/Completion/Unix/Command/_stdbuf index 4b7d98ba0..32b3cae2f 100644 --- a/Completion/Unix/Command/_stdbuf +++ b/Completion/Unix/Command/_stdbuf @@ -27,6 +27,6 @@ for ((i=1;i<=3;i++)); do "(${short[i]})${long[i]}=${(e)opt}" ) done -(( CURRENT > 2 )) && args+=( '*::command:_normal' ) +(( CURRENT > 2 )) && args+=( '*::command: _normal -p $service' ) _arguments -s -S $args diff --git a/Completion/Unix/Command/_timeout b/Completion/Unix/Command/_timeout index c041283ac..9c7f1a004 100644 --- a/Completion/Unix/Command/_timeout +++ b/Completion/Unix/Command/_timeout @@ -17,4 +17,4 @@ _arguments -S -A "-" $args \ '(-s --signal)'{-s,--signal}'[specify the signal to send on timeout]:signal:_signals' \ '(-k --kill-after)'{-k,--kill-after}'[followup first signal with SIGKILL if command persists after specified time]:time' \ '1: :_numbers -f -u seconds duration :s:seconds m:minutes h:hours d:days' \ - '*:::command:_normal' + '*:::command: _normal -p $service' -- cgit v1.2.3 From e3c2af216b1f77202ef5240179dabcf4aab66f91 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 5 Sep 2023 18:04:09 -0700 Subject: 52115: permit repeated "private" declarations as long as types aren't changed --- ChangeLog | 5 +++++ Src/Modules/param_private.c | 49 ++++++++++++++++++++++++++++++++++++++++++--- Test/V10private.ztst | 17 ++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c782f617..a4d2dfe2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-09-05 Bart Schaefer + + * 52115: Src/Modules/param_private.c, Test/V10private.ztst: permit + repeated "private" declarations as long as types aren't changed + 2023-09-04 Jun-ichi Takimoto * 52112: Completion/BSD/Command/_jexec, diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index 8e04b2b95..7ef6633da 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -87,9 +87,52 @@ makeprivate(HashNode hn, UNUSED(int flags)) ((pm->node.flags & (PM_SPECIAL|PM_REMOVABLE)) == PM_SPECIAL && /* typeset_single() line 2300 discards PM_REMOVABLE -- why? */ !is_private(pm->old))))) { - zwarnnam("private", "can't change scope of existing param: %s", - pm->node.nam); - makeprivate_error = 1; + if (is_private(pm->old)) { + if (pm->old->node.flags & PM_READONLY) { + zerr("read-only variable: %s", pm->node.nam); + makeprivate_error = 1; + } else if ((pm->node.flags | pm->old->node.flags) == + pm->old->node.flags) { + /* private called twice on same parameter */ + Param tpm = pm; + pm = pm->old; + --locallevel; + /* why have a union if we need this switch anyway? */ + switch (PM_TYPE(pm->node.flags)) { + case PM_SCALAR: + pm->gsu.s->setfn(pm, tpm->u.str); + tpm->u.str = NULL; + break; + case PM_INTEGER: + pm->gsu.i->setfn(pm, tpm->u.val); + break; + case PM_EFLOAT: + case PM_FFLOAT: + pm->gsu.f->setfn(pm, tpm->u.dval); + break; + case PM_ARRAY: + pm->gsu.a->setfn(pm, tpm->u.arr); + tpm->u.arr = NULL; + break; + case PM_HASHED: + pm->gsu.h->setfn(pm, tpm->u.hash); + tpm->u.hash = NULL; + break; + } + ++locallevel; + if (!(tpm->node.flags & PM_UNSET)) + pm->node.flags &= ~PM_UNSET; + } else { + zerrnam("private", + "can't change type of private param: %s", + pm->node.nam); + makeprivate_error = 1; + } + } else { + zerrnam("private", "can't change scope of existing param: %s", + pm->node.nam); + makeprivate_error = 1; + } return; } struct gsu_closure *gsu = zalloc(sizeof(struct gsu_closure)); diff --git a/Test/V10private.ztst b/Test/V10private.ztst index b876f548d..d902cac56 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -384,6 +384,23 @@ F:Should we allow "public" namerefs to private parameters? } 0:regression test for unset private + () { + private x=1 + unset x + private x=2 + print $x + } +0:private may be called twice +>2 + + () { + private x=1 + private -a x + print $x + } +1:private may not change parameter type +?(anon):private:2: can't change type of private param: x + %clean rm -r private.TMP -- cgit v1.2.3 From d82ea848bf1350c5f0d668801ff9355ac4e0ad7f Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 7 Sep 2023 22:37:16 +0900 Subject: 52114: improve _nice support -n option, complete only external commands --- ChangeLog | 5 +++++ Completion/Unix/Command/_nice | 27 ++++++++++++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index a4d2dfe2f..0b9ecfce3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-09-07 Jun-ichi Takimoto + + * 52114: Completion/Unix/Command/_nice: improve _nice (support + -n option, complete only external commands) + 2023-09-05 Bart Schaefer * 52115: Src/Modules/param_private.c, Test/V10private.ztst: permit diff --git a/Completion/Unix/Command/_nice b/Completion/Unix/Command/_nice index 29070697f..b52e5216a 100644 --- a/Completion/Unix/Command/_nice +++ b/Completion/Unix/Command/_nice @@ -1,14 +1,23 @@ #compdef nice -shift words -(( CURRENT-- )) +local -a specs=( '*:: : _normal -p $service' ) -if [[ $CURRENT -gt 1 && $words[1] = ([-+](-|)|-n)<-> ]]; then - shift words - (( CURRENT -- )) -elif [[ $CURRENT -gt 2 && $words[1] = -n ]]; then - shift 2 words - (( CURRENT -= 2 )) +# See if the 1st arg is such as -10 --10 or -+10 +if [[ $words[2] = -(-|+|)[0-9]## ]]; then + if (( $CURRENT == 2 )); then + _message 'niceness increment' && return + fi + compset -n 2 # Ignore the 1st arg +else + if _pick_variant gnu=GNU unix --version; then + specs+=( + '(-)'{-n+,--adjustment=}'[adjust niceness]:niceness increment' + '(* -)--help[display help and exit]' + '(* -)--version[output version information and exit]' + ) + else + specs+=( '-n+[specify increment of niceness]:niceness increment' ) + fi fi -_normal +_arguments : $specs -- cgit v1.2.3 From d95197a2ec43c79958aaf198189d4f138422a331 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 9 Sep 2023 22:11:50 -0700 Subject: unposted: extra quoting of words in "eval" for safety --- ChangeLog | 4 ++++ Completion/Base/Utility/_shadow | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b9ecfce3..72922feb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-09-09 Bart Schaefer + + * unposted: Completion/Base/Utility/_shadow: quoting for safety + 2023-09-07 Jun-ichi Takimoto * 52114: Completion/Unix/Command/_nice: improve _nice (support diff --git a/Completion/Base/Utility/_shadow b/Completion/Base/Utility/_shadow index b5a8acb24..9e78af38f 100644 --- a/Completion/Base/Utility/_shadow +++ b/Completion/Base/Utility/_shadow @@ -55,10 +55,10 @@ _shadow() { fnames+=(f@$fname) elif (( ${+builtins[$fname]} )) then - eval "function -- $shadowname { builtin $fname \"\$@\" }" + eval "function -- ${(q-)shadowname} { builtin ${(q-)fname} \"\$@\" }" fnames+=(b@$fname) else - eval "function -- $shadowname { command $fname \"\$@\" }" + eval "function -- ${(q-)shadowname} { command ${(q-)fname} \"\$@\" }" fnames+=(c@$fname) fi done -- cgit v1.2.3 From 96ce0abf6b7607ca2df64759c495d153132d07bd Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 10 Sep 2023 21:00:23 -0700 Subject: 52125: getoutput() must not free() after gettempname(..., 1) for heap --- ChangeLog | 4 ++++ Src/exec.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 72922feb4..c8bc5e30f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-09-10 Bart Schaefer + + * 52125: Src/exec.c: getoutput() must not free() gettempname() + 2023-09-09 Bart Schaefer * unposted: Completion/Base/Utility/_shadow: quoting for safety diff --git a/Src/exec.c b/Src/exec.c index 8f9d5a885..3a8b3e951 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4897,7 +4897,6 @@ getoutputfile(char *cmd, char **eptr) if ((fd = open(nam, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600)) < 0) { zerr("process substitution failed: %e", errno); - free(nam); if (!s) child_unblock(); return NULL; -- cgit v1.2.3 From 0eab788437d42afb290637441f88542fc496c307 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Wed, 13 Sep 2023 09:59:42 +0900 Subject: 52122 + 52129: fix (#) parameter expansion flag Without the X flag, null string "" is substituted for bad math expression. --- ChangeLog | 6 ++++++ Src/subst.c | 13 ++++++++++--- Test/D04parameter.ztst | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c8bc5e30f..45cb416dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-09-13 Jun-ichi Takimoto + + * 52122 + 52129: Src/subst.c, Test/D04parameter.ztst: fix (#) + parameter expansion flag for bad math expressions and out-of- + range characters + 2023-09-10 Bart Schaefer * 52125: Src/exec.c: getoutput() must not free() gettempname() diff --git a/Src/subst.c b/Src/subst.c index 14947ae36..d68159227 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1489,11 +1489,18 @@ subst_parse_str(char **sp, int single, int err) static char * substevalchar(char *ptr) { - zlong ires = mathevali(ptr); + zlong ires; int len = 0; + int saved_errflag = errflag; - if (errflag) - return NULL; + errflag = 0; + ires = mathevali(ptr); + + if (errflag) { /* not a valid numerical expression */ + errflag |= saved_errflag; + return noerrs ? dupstring(""): NULL; + } + errflag |= saved_errflag; #ifdef MULTIBYTE_SUPPORT if (isset(MULTIBYTE) && ires > 127) { /* '\\' + 'U' + 8 bytes of character + '\0' */ diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 0d44558a7..12ae1a446 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2785,3 +2785,43 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888 >string with spaces >stringwithspaces >stringwithspaces + + : ${(#X):-@} +1:${(#X)...}: bad math expression +?(eval):1: bad math expression: illegal character: @ + + echo a${(#):-@}z +0:${(#)...}: bad math expression +>az + + printf "a%sz\n" ${(#):-@} +0:${(#)...}: bad math expression, printf +>az + + a=( '1 +' '@' ) + : ${(#X)a} +1:${(#X)...}: array of bad math expressions +?(eval):2: bad math expression: operand expected at end of string + + printf "a%sz\n" ${(#)a} +0:${(#)...}: array of bad math expressions, printf +>az + + : ${(#X):-0x80} +1:${(#X)...}: out-of-range character +?(eval):1: character not in range + + [[ ${(#):-0x80} = $'\x80' ]] && echo OK +0:${(#)...}: out-of-range character +>OK + + a=( 0x80 0x81 ) + : ${(#X)a} +1:${(#X)...}: array of out-of-range characters +?(eval):2: character not in range + + printf "%s\n" ${(#)a} | + while read x; do echo $(( #x )); done +0:${(#)...}: array of out-of-range characters +>128 +>129 -- cgit v1.2.3 From aecef41f2e47e738214cf6c55a383b4eae87902f Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Thu, 14 Sep 2023 13:57:07 +0200 Subject: 52142: Move _history_modifiers call to _parameter _parameters is used in many contexts, like assignments in command position, assignment after typeset, etc, where history modifiers are not valid. _brace_parameter already calls _history_modifiers explicitly so this seems more in line with that. --- ChangeLog | 6 ++++++ Completion/Zsh/Context/_parameter | 5 +++++ Completion/Zsh/Type/_parameters | 5 ----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45cb416dc..978464688 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-09-15 Mikael Magnusson + + * 52142: Completion/Zsh/Context/_parameter, + Completion/Zsh/Type/_parameters: Move _history_modifiers call + to _parameter + 2023-09-13 Jun-ichi Takimoto * 52122 + 52129: Src/subst.c, Test/D04parameter.ztst: fix (#) diff --git a/Completion/Zsh/Context/_parameter b/Completion/Zsh/Context/_parameter index 7e7788535..b08d665f5 100644 --- a/Completion/Zsh/Context/_parameter +++ b/Completion/Zsh/Context/_parameter @@ -1,3 +1,8 @@ #compdef -parameter- +if compset -P '*:'; then + _history_modifiers p + return +fi + _parameters -e diff --git a/Completion/Zsh/Type/_parameters b/Completion/Zsh/Type/_parameters index 7f6f33e0e..7b7692a3c 100644 --- a/Completion/Zsh/Type/_parameters +++ b/Completion/Zsh/Type/_parameters @@ -6,11 +6,6 @@ # If you specify a -g option with a pattern, the pattern will be used to # restrict the type of parameters matched. -if compset -P '*:'; then - _history_modifiers p - return -fi - local i pfilt local -i nm=$compstate[nmatches] local -a expl pattern=( -g \* ) normal described verbose faked fakes tmp -- cgit v1.2.3 From 355cfc1b95ca65e7ab9ada5b59a82ed4f651556f Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 16 Sep 2023 13:08:59 -0700 Subject: 52153: mapfile without HAVE_MMAP should not trim newlines --- ChangeLog | 5 +++++ Src/Modules/mapfile.c | 10 ++++------ Src/input.c | 44 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 978464688..27dcf0e58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-09-16 Bart Schaefer + + * 52153: Src/input.c, Src/Modules/mapfile.c: $mapfile[fname] + should not trim newlines (only applies when not HAVE_MMAP) + 2023-09-15 Mikael Magnusson * 52142: Completion/Zsh/Context/_parameter, diff --git a/Src/Modules/mapfile.c b/Src/Modules/mapfile.c index dd86fb596..84cdfea18 100644 --- a/Src/Modules/mapfile.c +++ b/Src/Modules/mapfile.c @@ -170,6 +170,8 @@ get_contents(char *fname) #ifdef USE_MMAP caddr_t mmptr; struct stat sbuf; +#else + off_t size; #endif char *val; unmetafy(fname = ztrdup(fname), &fd); @@ -196,12 +198,8 @@ get_contents(char *fname) close(fd); #else /* don't USE_MMAP */ val = NULL; - if ((fd = open(fname, O_RDONLY | O_NOCTTY)) >= 0) { - LinkList ll; - - if ((ll = readoutput(fd, 1, 0))) - val = peekfirst(ll); - } + if ((size = zstuff(&val, fname)) > 0) + val = metafy(val, size, META_HEAPDUP); #endif /* USE_MMAP */ free(fname); return val; diff --git a/Src/input.c b/Src/input.c index 0da065e51..8d7f44d7c 100644 --- a/Src/input.c +++ b/Src/input.c @@ -610,11 +610,11 @@ inungetc(int c) } } -/* stuff a whole file into the input queue and print it */ +/* stuff a whole file into memory and return it */ /**/ -int -stuff(char *fn) +off_t +zstuff(char **out, const char *fn) { FILE *in; char *buf; @@ -622,20 +622,50 @@ stuff(char *fn) if (!(in = fopen(unmeta(fn), "r"))) { zerr("can't open %s", fn); - return 1; + return -1; } + queue_signals(); fseek(in, 0, SEEK_END); len = ftell(in); fseek(in, 0, SEEK_SET); buf = (char *)zalloc(len + 1); - if (!(fread(buf, len, 1, in))) { + if (len && !(fread(buf, len, 1, in))) { zerr("read error on %s", fn); fclose(in); - zfree(buf, len + 1); - return 1; + unqueue_signals(); + return -1; } fclose(in); buf[len] = '\0'; + *out = buf; + unqueue_signals(); + return len; +} + +/**/ +char * +ztuff(const char *fn) +{ + char *buf; + off_t len = zstuff(&buf, fn); + if (len > 0) + return buf; + else + return NULL; +} + +/* stuff a whole file into the input queue and print it */ + +/**/ +int +stuff(char *fn) +{ + char *buf; + off_t len = zstuff(&buf, fn); + + if (len < 0) + return 1; + fwrite(buf, len, 1, stderr); fflush(stderr); inputsetline(metafy(buf, len, META_REALLOC), INP_FREE); -- cgit v1.2.3 From 3aaef16569a6b9bd5ca0a2a323cc0643772f9c56 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 16 Sep 2023 17:34:39 -0700 Subject: 52154, 52155: Implement, document, and test non-forking command substitution. Comprises workers/51957, 51985, 51987, 51988, 51993, 52131, 52139, plus fixes for return values, parse errors, and trailing newlines (which were incorrectly removed) in ${ ... } --- ChangeLog | 6 +++ Doc/Zsh/expn.yo | 44 +++++++++++++--- Src/lex.c | 72 +++++++++++++++++++++----- Src/subst.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 254 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 27dcf0e58..0390ea2b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2023-09-16 Bart Schaefer + * 52155: Test/D10nofork.ztst: Tests for non-forking substitution. + + * 52154: Doc/Zsh/expn.yo, Src/lex.c, Src/subst.c: implement + and document non-forking command substitutions ${|...} and + ${ ... }. Based on Sebastian Gniazdowski: 51702. + * 52153: Src/input.c, Src/Modules/mapfile.c: $mapfile[fname] should not trim newlines (only applies when not HAVE_MMAP) diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index f87832e75..5be40bf25 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1881,23 +1881,55 @@ sect(Command Substitution) cindex(command substitution) cindex(substitution, command) A command enclosed in parentheses preceded by a dollar sign, like -`tt($LPAR())...tt(RPAR())', or quoted with grave -accents, like `tt(`)...tt(`)', is replaced with its standard output, with -any trailing newlines deleted. -If the substitution is not enclosed in double quotes, the -output is broken into words using the tt(IFS) parameter. +`tt($LPAR())...tt(RPAR())', or quoted with grave accents, like +`tt(`)...tt(`)', is executed in a subshell and replaced by its +standard output, with any trailing newlines deleted. If the +substitution is not enclosed in double quotes, the output is broken +into words using the tt(IFS) parameter. vindex(IFS, use of) The substitution `tt($LPAR()cat) var(foo)tt(RPAR())' may be replaced by the faster `tt($LPAR()<)var(foo)tt(RPAR())'. In this case var(foo) undergoes single word shell expansions (em(parameter expansion), em(command substitution) and em(arithmetic expansion)), but not -filename generation. +filename generation. No subshell is created. If the option tt(GLOB_SUBST) is set, the result of any unquoted command substitution, including the special form just mentioned, is eligible for filename generation. +A command with a leading pipe character, enclosed in braces prefixed by +a dollar sign, as in `tt(${|)...tt(})', is executed in the current shell +context, rather than in a subshell, and is replaced by the value of the +parameter tt(REPLY) at the end of the command. There em(must not) be +any whitespace between the opening brace and the pipe character. Any +prior value of tt($REPLY) is saved and restored around this substitution, +in the manner of a function local parameter. Other parameters declared +within the substitution also behave as locals, as if in a function, +unless `tt(typeset -g)' is used. Trailing newlines are em(not) deleted +from the final replacement in this case, and it is subject to filename +generation in the same way as `tt($LPAR())...tt(RPAR())' but is em(not) +split on tt(IFS) unless the tt(SH_WORD_SPLIT) option is set. + +Substitutions of the form `tt(${|)var(param)tt(|)...tt(})' are similar, +except that the substitution is replaced by the value of the parameter +named by var(param). No implicit save or restore applies to var(param) +except as noted for tt(REPLY), and var(param) should em(not) be declared +within the command. If var(param) names an array, array expansion rules +apply. + +A command enclosed in braces preceded by a dollar sign, and set off from +the braces by whitespace, like `tt(${ )...tt( })', is replaced by its +standard output. Like `tt(${|)...tt(})' and unlike +`tt($LPAR())...tt(RPAR())', the command executes in the current shell +context with function local behaviors and does not create a subshell. + +Note that because the `tt(${|)...tt(})' and `tt(${ )...tt( })' forms +must be parsed at once as both string tokens and commands, all other +braces (`tt({)' or `tt(})') within the command either must be quoted, +or must appear in syntactically valid pairs, such as around complex +commands, function bodies, or parameter references. + texinode(Arithmetic Expansion)(Brace Expansion)(Command Substitution)(Expansion) sect(Arithmetic Expansion) cindex(arithmetic expansion) diff --git a/Src/lex.c b/Src/lex.c index 2f7937410..33b17cc95 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -937,7 +937,7 @@ static enum lextok gettokstr(int c, int sub) { int bct = 0, pct = 0, brct = 0, seen_brct = 0, fdpar = 0; - int intpos = 1, in_brace_param = 0; + int intpos = 1, in_brace_param = 0, cmdsubst = 0; int inquote, unmatched = 0; enum lextok peek; #ifdef DEBUG @@ -1135,7 +1135,7 @@ gettokstr(int c, int sub) c = Inpar; break; case LX2_INBRACE: - if (isset(IGNOREBRACES) || sub) + if ((isset(IGNOREBRACES) && !cmdsubst) || sub) c = '{'; else { if (!lexbuf.len && incmdpos) { @@ -1157,8 +1157,11 @@ gettokstr(int c, int sub) if (in_brace_param) { cmdpop(); } - if (bct-- == in_brace_param) - in_brace_param = 0; + if (bct-- == in_brace_param) { + if (cmdsubst) + cmdpop(); + in_brace_param = cmdsubst = 0; + } c = Outbrace; break; case LX2_COMMA: @@ -1405,16 +1408,24 @@ gettokstr(int c, int sub) } add(c); c = hgetc(); - if (intpos) + if (intpos) intpos--; - if (lexstop) + if (lexstop) break; + if (!cmdsubst && in_brace_param && act == LX2_STRING && + (c == '|' || c == Bar || inblank(c))) { + cmdsubst = in_brace_param; + cmdpush(CS_CURSH); + } } brk: if (errflag) { if (in_brace_param) { - while(bct-- >= in_brace_param) + while(bct >= in_brace_param) { + if (bct-- == cmdsubst) + cmdpop(); cmdpop(); + } } return LEXERR; } @@ -1422,8 +1433,11 @@ gettokstr(int c, int sub) if (unmatched && !(lexflags & LEXFLAGS_ACTIVE)) zerr("unmatched %c", unmatched); if (in_brace_param) { - while(bct-- >= in_brace_param) + while(bct >= in_brace_param) { + if (bct-- == cmdsubst) + cmdpop(); cmdpop(); + } zerr("closing brace expected"); } else if (unset(IGNOREBRACES) && !sub && lexbuf.len > 1 && peek == STRING && lexbuf.ptr[-1] == '}' && @@ -1459,8 +1473,8 @@ gettokstr(int c, int sub) static int dquote_parse(char endchar, int sub) { - int pct = 0, brct = 0, bct = 0, intick = 0, err = 0; - int c; + int pct = 0, brct = 0, bct = 0, intick = 0, err = 0, cmdsubst = 0; + int c, bskip = 0; int math = endchar == ')' || endchar == ']' || infor; int zlemath = math && zlemetacs > zlemetall + addedx - inbufct; @@ -1529,11 +1543,25 @@ dquote_parse(char endchar, int sub) c = Qstring; } break; + case '{': + if (cmdsubst && !intick) { + /* In nofork substitution, tokenize as if unquoted */ + c = Inbrace; + bskip++; + } + break; case '}': if (intick || !bct) break; c = Outbrace; - bct--; + if (bskip) { + bskip--; + break; + } + if (bct-- == cmdsubst) { + cmdsubst = 0; + cmdpop(); + } cmdpop(); break; case '`': @@ -1588,14 +1616,34 @@ dquote_parse(char endchar, int sub) if (err || lexstop) break; add(c); + if (!cmdsubst && c == Inbrace) { + /* Check for ${|...} nofork command substitution */ + if ((c = hgetc()) && !lexstop) { + if (c == '|' || inblank(c)) { + cmdsubst = bct; + cmdpush(CS_CURSH); + } + hungetc(c); + } + } } if (intick == 2) ALLOWHIST if (intick) { cmdpop(); } - while (bct--) + while (bct) { + if (bct-- == cmdsubst) { + /* + * You would think this is an error, but if we call it one, + * parsestrnoerr() returns nonzero to subst_parse_str() and + * subsequently "bad substitution" is not reported + */ + /* err = 1 */ + cmdpop(); + } cmdpop(); + } if (lexstop) err = intick || endchar || err; else if (err == 1) { diff --git a/Src/subst.c b/Src/subst.c index d68159227..52afd6484 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1867,6 +1867,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * joining the array into a string (for compatibility with ksh/bash). */ int quoted_array_with_offset = 0; + /* Indicates ${|...;} */ + char *rplyvar = NULL; + /* Indicates ${ ... ;} */ + char *rplytmp = NULL; *s++ = '\0'; /* @@ -1894,8 +1898,147 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * flags in parentheses, but also one ksh hack. */ if (c == Inbrace) { + /* The command string to be run by ${|...;} */ + char *cmdarg = NULL; + size_t slen = 0; inbrace = 1; s++; + + /* Short-path for the nofork command substitution ${|cmd;} + * See other comments about kludges for why this is here. + * + * The command string is extracted and executed, and the + * substitution assigned. There's no (...)-flags processing, + * i.e. no ${|(U)cmd;}, because it looks quite awful and + * should not be part of command substitution in any case. + * Use ${(U)${|cmd;}} as you would for ${(U)$(cmd;)}. + */ + if (*s == '|' || *s == Bar || inblank(*s)) { + char *outbracep = s; + char sav = *s; + *s = Inbrace; + if (skipparens(Inbrace, Outbrace, &outbracep) == 0) { + slen = outbracep - s - 1; + if ((*s = sav) != Bar) { + sav = *outbracep; + *outbracep = '\0'; + tokenize(s); + *outbracep = sav; + } + } + } + if (slen > 1) { + char *outbracep = s + slen; + if (*outbracep == Outbrace) { + if ((rplyvar = itype_end(s+1, INAMESPC, 0))) { + if (*rplyvar == Inbrack && + (rplyvar = parse_subscript(++rplyvar, 1, ']'))) + ++rplyvar; + } + if (rplyvar == s+1 && *rplyvar == Bar) { + /* Is ${||...} a subtitution error or a syntax error? + zerr("bad substitution"); + return NULL; + */ + rplyvar = NULL; + } + if (rplyvar && *rplyvar == Bar) { + cmdarg = dupstrpfx(rplyvar+1, outbracep-rplyvar-1); + rplyvar = dupstrpfx(s+1,rplyvar-s-1); + } else { + cmdarg = dupstrpfx(s+1, outbracep-s-1); + rplyvar = "REPLY"; + } + if (inblank(*s)) { + /* + * Admittedly a hack. Take advantage of the enforced + * locality of REPLY and the semantics of $(level = locallevel; + /* if (rplyval) setsparam("REPLY", ztrdup(rplyval)); */ + } + + if (rplyvar && cmdarg && *cmdarg) { + int obreaks = breaks; + Eprog cmdprog; + /* Execute the shell command */ + untokenize(cmdarg); + cmdprog = parse_string(cmdarg, 0); + if (cmdprog) { + execode(cmdprog, 1, 0, "cmdsubst"); + cmdoutval = lastval; + /* "return" behaves as if in a function */ + if (retflag) { + retflag = 0; + breaks = obreaks; /* Is this ever not zero? */ + } + } else /* parse error */ + errflag |= ERRFLAG_ERROR; + if (rplytmp && !errflag) { + int onoerrs = noerrs; + noerrs = 2; + if ((cmdarg = ztuff(rplytmp))) + setsparam("REPLY", cmdarg); + noerrs = onoerrs; + } + } + + if (rplytmp) + unlink(rplytmp); + if (rplyvar) { + if (strcmp(rplyvar, "REPLY") == 0) { + if ((val = dupstring(getsparam("REPLY")))) + vunset = 0; + else { + vunset = 1; + val = dupstring(""); + } + } else { + s = dyncat(rplyvar, s); + rplyvar = NULL; + } + endparamscope(); + if (exit_pending) { + if (mypid == getpid()) { + /* + * paranoia: don't check for jobs, but there + * shouldn't be any if not interactive. + */ + stopmsg = 1; + zexit(exit_val, ZEXIT_NORMAL); + } else + _exit(exit_val); + } + } + /* * In ksh emulation a leading `!' is a special flag working * sort of like our (k). This is true only for arrays or @@ -2590,14 +2733,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * we let fetchvalue set the main string pointer s to * the end of the bit it's fetched. */ - if (!(v = fetchvalue(&vbuf, (subexp ? &ov : &s), - (wantt ? -1 : - ((unset(KSHARRAYS) || inbrace) ? 1 : -1)), - scanflags)) || - (v->pm && (v->pm->node.flags & PM_UNSET)) || - (v->flags & VALFLAG_EMPTY)) + if (!rplyvar && + (!(v = fetchvalue(&vbuf, (subexp ? &ov : &s), + (wantt ? -1 : + ((unset(KSHARRAYS) || inbrace) ? 1 : -1)), + scanflags)) || + (v->pm && (v->pm->node.flags & PM_UNSET)) || + (v->flags & VALFLAG_EMPTY))) vunset = 1; - if (wantt) { /* * Handle the (t) flag: value now becomes the type -- cgit v1.2.3 From 293d36ae1e34049e3f831b4b010d8ad028ff3196 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 16 Sep 2023 20:03:32 -0700 Subject: 52155: Test file missed out from previous commit --- Test/D10nofork.ztst | 448 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 448 insertions(+) create mode 100644 Test/D10nofork.ztst diff --git a/Test/D10nofork.ztst b/Test/D10nofork.ztst new file mode 100644 index 000000000..024b8ffcc --- /dev/null +++ b/Test/D10nofork.ztst @@ -0,0 +1,448 @@ +# Tests for "nofork" command substitution. + +%prep + mkdir nofork.tmp + touch nofork.tmp/file{1,2}.txt + + purr() { print -r -- "$@" } + purl() { print -rl -- "$@" } + +%test + + REPLY=OUTER + purr ${| REPLY=INNER } $REPLY +0:Basic substitution and REPLY scoping +>INNER OUTER + + purr ${| REPLY=first}:${| REPLY=second}:$REPLY +0:re-scoping of REPLY in one statement +>first:second:OUTER + + purr BEGIN${| printf -v REPLY '%s\n' one two three ; }END +0:Adjacent words +>BEGINone +>two +>three +>END + + purr "BEGIN${| printf -v REPLY '%s\n' one two three }END" +0:Adjacent words and quoting, part 1 +>BEGINone +>two +>three +>END + + purr BEGIN"${| printf -v REPLY '%s\n' one two three }"END +0:Adjacent words and quoting, part 2 +>BEGINone +>two +>three +>END + + purr BEGIN"${| + printf -v REPLY '%s\n'\ + one two three + }"END +0:Embedded newlines +>BEGINone +>two +>three +>END + + purr BEGIN"${| + printf -v REPLY $'%s\n' one two three + }"END +0:Embedded newlines and $'...' +>BEGINone +>two +>three +>END + + purl ${| print -v REPLY one word here; setopt shwordsplit } + purl ${| print -v REPLY three words here } + purl "and ${| print -v REPLY one word here }" + unsetopt shwordsplit +0:test word splitting on result +F:setting option inside is too late for that substitution +>one word here +>three +>words +>here +>and one word here + + ( + cd nofork.tmp + setopt globsubst + purr ${| REPLY=f* } + purr ${| REPLY=f? }* + unsetopt globsubst + purr ${| REPLY=f* } + purr ${| REPLY=f? }* + ) +1:globsubst on result +>file1.txt file2.txt +>file1.txt file2.txt +>f* +?(eval):8: no matches found: f?* + + purr ${| REPLY=$'trailing newlines remain\n\n' } +0:newline removal should not occur +>trailing newlines remain +> +> + + () { + purr ${| REPLY=$* ; shift 2 } + purr $* + } these are arguments +0:access to context $argv +>these are arguments +>arguments + + purr ${:-${| REPLY=${REPLY:-buried}}} + purr ${:-"${| REPLY=${REPLY:-more buried}}"} +0:nofork inside parameter scope +>buried +>more buried + + : ${(e):-'${| REPLY=oops'} +1:unclosed braces are sometimes a bad substitution +F:This seems silly, but see A01grammar ${(e):-'${'} test +?(eval):1: bad substitution + + purr ${| REPLY=oops +1:other times lack of closing brace is merely unexpected +F:Why not use this error in the previous case as well? +?(eval):1: closing brace expected + +# Next tests check that the PS2 stack is properly managed on error + + purr ${| REPLY=${REPLY:-buried}}} +1:unbalanced braces, part 0 +?(eval):1: parse error near `}' + + purr ${:-${| REPLY=${REPLY:-buried}} +1:unbalanced braces, part 1 +?(eval):1: closing brace expected + + purr ${:-"${| REPLY=${REPLY:-more buried}"} +1:unbalanced braces, part 2 +?(eval):1: unmatched " + + purr ${:-"${| REPLY=${REPLY:-more buried"}}} +1:unbalanced braces, part 3 +?(eval):1: unmatched " + + purr ${:-"${| REPLY=${REPLY:-more buried}}}" +1:unbalanced braces, part 4 +?(eval):1: closing brace expected + +# Same tests with leading space (future-proofing) + + purr ${ purr ${REPLY:-buried}}} +1:unbalanced braces, part 0+ +?(eval):1: parse error near `}' + + purr ${:-${ purr ${REPLY:-buried}} +1:unbalanced braces, part 1+ +?(eval):1: closing brace expected + + purr ${:-"${ purr ${REPLY:-more buried}"} +1:unbalanced braces, part 2+ +?(eval):1: unmatched " + + purr ${:-"${ purr ${REPLY:-more buried"}}} +1:unbalanced braces, part 3+ +?(eval):1: unmatched " + + purr ${:-"${ purr ${REPLY:-more buried}}}" +1:unbalanced braces, part 4+ +?(eval):1: closing brace expected + + purr ${ purr STDOUT } +0:capture stdout +>STDOUT +> + +# end PS2 stack tests + + purr $(purr outside ${| REPLY=inside }) + purr BEGIN$(purr outside ${| REPLY=inside })END + purr "BEGIN$(purr outside ${| REPLY=inside })END" + purr outside ${| REPLY=$(purr inside)} + purr "outside ${| REPLY=$(purr inside)}" +0:mixing with forking cmdsubst +>outside inside +>BEGINoutside insideEND +>BEGINoutside insideEND +>outside inside +>outside inside + + purr `purr outside ${| REPLY=inside }` + purr "outside `purr ${| REPLY=inside }`" + purr outside ${| REPLY=`purr inside`} + purr "outside ${| REPLY=`purr inside`}" + purr outside "`purr ${| REPLY="${:-inside}"}`" + purr "outside ${| REPLY=`purr ${:-inside}`}" +0:mixing with backticks +>outside inside +>outside inside +>outside inside +>outside inside +>outside inside +>outside inside + + purr ${| REPLY=$(( 9 + 17 )) } + purr $(( 9 + ${| REPLY=17 } )) +0:mixing with arithemetic +>26 +>26 + + unset reply + purl ${|reply| reply=(1 2 ${| REPLY=3 } 4) } + typeset -p reply +0:array behavior with global assignment +>1 +>2 +>3 +>4 +>typeset -g -a reply=( 1 2 3 4 ) + + unset outer + purr "${| + outer=OUTER + REPLY=INNER + return 7 + OUTER=NOTREACHED + } $outer $?" +0:return statement inside, part 1 +F:status of "print" should hide return +>INNER OUTER 7 + + unset outer + outer=${| REPLY=${| return 7}} +7:return status propages in assignment like $(...) + + unset outer + purr "${| + outer=OUTER + REPLY=INNER + return 7 + OUTER=NOTREACHED + } $outer $?" + print REACHED $OUTER +0:return statement inside, part 2 +>INNER OUTER 7 +>REACHED + + unset outer + purr "${| + # Localoptions needed to avoid breaking test harness? + # The setopt command affects surrounding context + setopt localoptions errreturn + outer=OUTER + REPLY=INNER + false + OUTER=NOTREACHED + } $outer $?" + print REACHED $OUTER ${options[errreturn]} +0:errreturn works inside and remains outside +>INNER OUTER 1 +>REACHED on + + ( + unset outer + purr "${| + outer=OUTER + REPLY=INNER + exit 7 + OUTER=NOTREACHED + } $outer $OUTER $?" + print NOT REACHED + ) +7:exit statement inside + + ( + unset outer + purr "${| + setopt errexit + outer=OUTER + REPLY=INNER + false + OUTER=NOTREACHED + } $outer $?" + print NOT REACHED + ) +1:errexit inside + + outer=GLOBAL + purr "${| + local outer=LOCAL + REPLY=INNER + } $outer $?" +0:local declaration inside +>INNER GLOBAL 0 + + unset zz + outer=GLOBAL + purr "${|zz| + local outer=LOCAL + zz=NONLOCAL + } $outer $?" + print $zz +0:local declaration, global assignment, part 1 +>NONLOCAL GLOBAL 0 +>NONLOCAL + + unset zz + outer=GLOBAL + purr "${${| + local outer=LOCAL + zz=NONLOCAL + }:-$zz} $outer $?" +0:local declaration, global assignment, part 2 (evaluation order) +>NONLOCAL GLOBAL 0 + + : ${| fn1() { () { print -v REPLY $'Defined Function' ;} ;} } + print "IN${| fn2() { () { print "${:-Second }${|fn1}" ;} ;} }OUT" + fn2 +0:function definition, brace nesting, quote nesting +>INOUT +>Second Defined Function + + <<-EOF + ${| REPLY=$'in a here document\n' } + EOF +0:here-document behavior +F:Fiddly here to get EOF past the test syntax +>in a here document +> + + <<<${| REPLY="in a here string" } +0:here-string behavior +>in a here string + + <<<${ purr $'stdout as a here string' } +0:another capture stdout +>stdout as a here string +> + + wrap=${| REPLY="REPLY in environment assignment" } typeset -p wrap + wrap=${ purr "capture in environment assignment" } typeset -p wrap +0:assignment context +>typeset -g wrap='REPLY in environment assignment' +>typeset -g wrap=$'capture in environment assignment\n' + +# Repeat return and exit tests with stdout capture + + purr "${ + print INNER + return 7 + } $?" +0:return statement inside, part 1+ +F:status of "print" should hide return +>INNER +> 7 + + unset outer + outer=${ return 7 } +7:return status propages in stdout capture + + unset outer + purr "${ + outer=OUTER + print INNER + return 7 + OUTER=NOTREACHED + } $outer $?" + print REACHED $OUTER +0:return statement inside, part 2+ +>INNER +> OUTER 7 +>REACHED + + unset outer + purr "${ + # Localoptions needed to avoid breaking test harness? + # The setopt command affects surrounding context + setopt localoptions errreturn + outer=OUTER + print INNER + false + OUTER=NOTREACHED + } $outer $?" + print REACHED $OUTER ${options[errreturn]} +0:errreturn works inside stdout capture +>INNER +> OUTER 1 +>REACHED on + + ( + unset outer + purr "${ + outer=OUTER + print INNER + exit 7 + OUTER=NOTREACHED + } $outer $OUTER $?" + print NOT REACHED + ) +7:exit statement inside stdout capture + + ( + unset outer + purr "${ + setopt errexit + outer=OUTER + print INNER + false + OUTER=NOTREACHED + } $outer $?" + print NOT REACHED + ) +1:errexit inside stdout capture + + setopt ignorebraces +0:dummy test to set option soon enough +F:must do this before evaluating the next test block + + purr ${| REPLY=${REPLY:-buried}}} +0:ignored braces, part 1 +>buried} + + purr ${ purr ${REPLY:-buried}}} +0:ignored braces, part 2 +>buried +>} + + purr ${ { echo nested ;} } +0:ignored braces, part 3 +>nested +> + + purr ${ { echo nested } } DONE +1:ignored braces, part 4 +?(eval):1: parse error near `}' + + # "break" blocks function calls in outer loop + # Could use print, but that might get fixed + repeat 3 do purr ${ + for x in 1 2 3 4 + do (( x == 3 )) && break 2 + # use error output to confirm loop count + print -u 2 $x + done + } XX + done +0:break N propagates +?1 +?2 + + print -u $ZTST_fd ${ZTST_testname}: TEST COMPLETE +0:make sure we got to the end +F:some tests might silently break the test harness + +%clean + + unfunction purr purl + unsetopt ignorebraces -- cgit v1.2.3 From f72757ccf30610fe8fdd1ed76d080971f767edaf Mon Sep 17 00:00:00 2001 From: Christoffer Lundell Date: Sat, 16 Sep 2023 20:06:12 -0700 Subject: 52082: Enable linewise edit-command when in visual-line mode. --- ChangeLog | 3 +++ Functions/Zle/edit-command-line | 23 +++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0390ea2b5..23e7ef6d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-09-16 Bart Schaefer + * Christoffer Lundell: 52082: Functions/Zle/edit-command-line: + Enable linewise edit-command when in visual-line mode. + * 52155: Test/D10nofork.ztst: Tests for non-forking substitution. * 52154: Doc/Zsh/expn.yo, Src/lex.c, Src/subst.c: implement diff --git a/Functions/Zle/edit-command-line b/Functions/Zle/edit-command-line index 5f7ea321f..d4b405eaf 100644 --- a/Functions/Zle/edit-command-line +++ b/Functions/Zle/edit-command-line @@ -11,15 +11,30 @@ local left right prebuffer buffer=$BUFFER lbuffer=$LBUFFER local TMPSUFFIX=.zsh # set up parameters depending on which context we are called from, # see below comment for more details -if (( REGION_ACTIVE )); then +if (( REGION_ACTIVE == 1 )); then if (( CURSOR < MARK )); then left=$CURSOR right=$MARK - lbuffer= else left=$MARK right=$CURSOR - lbuffer[right-left,-1]= fi - (( left++ )) + lbuffer=$lbuffer[++left,-1] + buffer=$BUFFER[left,++right] +elif (( REGION_ACTIVE == 2 )); then + local nl=$'\n' + if (( CURSOR < MARK )); then + left=${${BUFFER[1,CURSOR]}[(I)$nl]} + right=${${BUFFER[MARK+1,-1]}[(i)$nl]} + (( right += MARK )) + else + left=${${BUFFER[1,MARK]}[(I)$nl]} + right=${${BUFFER[CURSOR+1,-1]}[(i)$nl]} + (( right += CURSOR )) + fi + lbuffer=$lbuffer[++left,-1] + if [[ $BUFFER[right] = $nl ]]; then + # Keep the newline because "$(<$1)" below trims it + (( --right )) + fi buffer=$BUFFER[left,right] elif (( ! ZLE_RECURSIVE )); then prebuffer=$PREBUFFER -- cgit v1.2.3 From 1becbba0b614c9ef17ba28aa51c4e8e7d21f1e0f Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 16 Sep 2023 20:51:27 -0700 Subject: users/29160, workers/52156: Fix repetition of substitution modifier. --- ChangeLog | 4 ++++ Src/subst.c | 6 ++++-- Test/E01options.ztst | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 23e7ef6d3..4356a564e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-09-16 Bart Schaefer + * 52156: Test/E01options.ztst: Test case for user/29160. + + * users/29160: Src/subst.c: Fix repetition of substituion modifier. + * Christoffer Lundell: 52082: Functions/Zle/edit-command-line: Enable linewise edit-command when in visual-line mode. diff --git a/Src/subst.c b/Src/subst.c index 52afd6484..dc2052ee0 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -4689,7 +4689,8 @@ modify(char **str, char **ptr, int inbrace) case 'S': hsubpatopt = (c == 'S'); if (hsubl && hsubr) - subst(©, hsubl, hsubr, gbal, hsubpatopt); + subst(©, dupstring(hsubl), dupstring(hsubr), + gbal, hsubpatopt); break; case 'q': copy = quotestring(copy, QT_BACKSLASH_SHOWNULL); @@ -4777,7 +4778,8 @@ modify(char **str, char **ptr, int inbrace) case 'S': hsubpatopt = (c == 'S'); if (hsubl && hsubr) - subst(str, hsubl, hsubr, gbal, hsubpatopt); + subst(str, dupstring(hsubl), dupstring(hsubr), + gbal, hsubpatopt); break; case 'q': *str = quotestring(*str, QT_BACKSLASH); diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 83f0371a1..363846f5c 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -561,12 +561,14 @@ foo=(one.c two.c three.c) print ${foo:s/#%(#b)t(*).c/T${match[1]}.X/} print *(#q:s/#(#b)tmp(*e)/'scrunchy${match[1]}'/) + print ${${:-"left[({})]over"}:fs/(\\{\\}|\\(\\)|\\[\\])//} unsetopt histsubstpattern 0:HIST_SUBST_PATTERN option >TINGcd TINGfile1 TINGfile2 homedir >THUMPcd THUMPfile1 THUMPfile2 >one.c Two.X Three.X >homedir scrunchyfile1 scrunchyfile2 tmpcd +>leftover setopt ignorebraces echo X{a,b}Y -- cgit v1.2.3 From d3394f35939815bb5436b7ce4ca07069444bf78c Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 20 Sep 2023 19:49:49 +0200 Subject: 52163: completion update for OpenZFS 2.2 --- ChangeLog | 5 ++ Completion/Unix/Command/_zfs | 109 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 98 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4356a564e..55dd9ab8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-09-20 Oliver Kiddle + + * 52163: Completion/Unix/Command/_zfs: completion update for + OpenZFS 2.2 + 2023-09-16 Bart Schaefer * 52156: Test/E01options.ztst: Test case for user/29160. diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index be4a64b33..b1135bfa7 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -1,7 +1,8 @@ -#compdef zfs zdb zpool +#compdef zfs zdb zpool zstream local curcontext="$curcontext" implementation nm="$compstate[nmatches]" local -a state curstate line state_descr expl alts args +local -a devices features typeset -A opt_args val_args local MATCH MBEGIN MEND local -a subcmds @@ -13,6 +14,7 @@ local -a ds_types sum_algorithms comp_algorithms dedup_algorithms local -a ds_propnames ro_ds_props rw_ds_props ci_ds_props # dataset properties local -a po_propnames ro_po_props rw_po_props ci_po_props # pool properties +local -a ro_vdev_props rw_vdev_props _pick_variant -r implementation -c 'zpool upgrade -v' openzfs='This system supports ZFS pool feature flags' solaris @@ -98,14 +100,32 @@ rw_ds_props=( 'volsize:size:_numbers -M "m:{a-zA-Z}={A-Za-z}" -u bytes size :B {k,M,G,T,P,E,Z}{,B}' ) +ro_vdev_props=( + capacity state guid asize psize ashift size free allocated expandsize + fragmentation parity devid physpath encpath fru parent children numchildren + read_errors write_errors checksum_errors initialize_errors + null_ops read_ops write_ops free_ops claim_ops trim_ops + null_bytes read_bytes write_bytes free_bytes claim_bytes trim_bytes + removing +) +rw_vdev_props=( + {checksum,io}'_n:number of errors' {checksum,io}'_t:threshold (seconds)' + {comment,bootsize}:value + {allocating,failfast}':value:(on off)' + 'path:device path:_files -g "*(-%)" -P / -W /' +) + case $service:$implementation in *:openzfs) ds_types+=( bookmark ) - sum_algorithms+=( noparity sha512 skein edonr ) + sum_algorithms+=( noparity sha512 skein edonr blake3 ) comp_algorithms+=( zstd zstd-{1..19} zstd-fast zstd-fast-{{1..9}{,0},100,500,1000} ) - dedup_algorithms+=( {sha512,skein}{,\,verify} edonr,verify ) + dedup_algorithms+=( {sha512,skein,blake3}{,\,verify} edonr,verify ) share_rw_properties=( sharesmb:option sharenfs:option ) ro_po_props+=( + 'bcloneratio[block cloning ratio for saved space]' + 'bclonesaved[amount of storage spared by use of block cloning]' + 'bcloneused[amount of storage used by cloned blocks]' 'expandsize[uninitialized space within the pool]' 'fragmentation[amount of fragmentation in the pool]' 'freeing[amount of space remaining to be reclaimed]' @@ -119,6 +139,7 @@ case $service:$implementation in 'autotrim[periodically trim recently freed space]:value:(on off)' 'comment[text string that is available even if the pool becomes faulted]:value' 'multihost[perform pool activity check during import]:value:(on off)' + 'feature@' ) rw_ds_props+=( 'aclmode:value:(discard groupmask passthrough restricted)' @@ -139,7 +160,8 @@ case $service:$implementation in ) ro_ds_props+=( createtxg clones filesystem_count guid logicalreferenced logicalused - receive_resume_token refcompressratio snapshot_count volblocksize written + receive_resume_token refcompressratio snapshot_count snapshots_changed + volblocksize written ) delegatable_perms=( bookmark load-key change-key userobjquota userobjused groupobjquota @@ -257,6 +279,9 @@ case $service:$implementation in list offline online reguid remove replace scrub set split status upgrade ) ;; + zstream:*) + subcmds+=( dump decompress redup token recompress ) + ;; esac case $OSTYPE in @@ -294,9 +319,8 @@ ci_ds_props+=( $rw_ds_props ) ds_propnames=( ${rw_ds_props%%:*} ) po_propnames=( ${ro_po_props%%:*} ${ci_po_props%%:*} ${rw_po_props%%:*} ) - case $service in - zfs|zpool) + zfs|zpool|zstream) _arguments -C -A "-*" \ '-?[display usage information]' \ '*::command:->subcmd' && return 0 @@ -633,7 +657,9 @@ case $service:$words[1] in '(-e --embed)'{-e,--embed}'[more compact stream for blocks stored with the embedded_data feature]' '(-c --compressed)'{-c,--compressed}'[more compact stream for compressed blocks]' '(-h --holds)'{-h,--holds}'[send snapshot holds]' - '-V[set the process title to a per-second report of how much data has been send]' + '(-V --proctitle)'{-V,--proctitle}'[set the process title to a per-second report of how much data has been sent]' + \*{-X,--exclude}'[exclude datasets (with -R)]:dataset:_sequence _zfs_dataset -t fs' + '(-s --skip-missing)'{-s,--skip-missing}'[continue even when snapshots missing in the hierarchy]' '-t[create a send stream that resumes an interrupted receive]:resume token' '(-w --raw)'{-w,--raw}'[keep encrypted data exactly as it exists on disk]' - redact @@ -763,10 +789,10 @@ case $service:$words[1] in zfs:holds) [[ $implementation = openzfs ]] && args=( '-H[suppress printing of headers, tab-delimit columns]' + '-p[use (parsable) numeric output for timestamps]' ) [[ $OSTYPE = freebsd<-12>.* ]] && args+=( # features were lost with the openzfs rebase - '-p[use exact (parsable) numeric output]' '(-r)-d+[depth]:value' ) _arguments -A "-*" -S $args \ @@ -789,6 +815,9 @@ case $service:$words[1] in '-N[enumerate new child datasets (with -r)]' '(1 -e)-E[show difference from empty]' ) + [[ $implementation = openzfs ]] && args=( + "-h[don't"' \\0ooo-escape non-ASCII paths]' + ) _arguments -A "-*" -S $args \ '-F[add column for filetype character, similar to ls(1)]' \ '-H[suppress printing of headers and arrows, tab-delimit columns]' \ @@ -981,8 +1010,10 @@ case $service:$words[1] in '-H[suppress headers and tab-delimit fields]' \ '-p[display numbers in parseable (exact) values]' \ '-o+[specify fields to display]: : _values -s , field name property value source' \ - ':property:_values -s , "property" $po_propnames' \ - '*:pool:_zfs_pool' + ':property:_values -s , "property" $po_propnames ${ro_vdev_props%:*}' \ + ':pool:_zfs_pool' \ + '::vdev:->pool-vdevs-all' \ + '*:pool:_zfs_pool -F line' ;; zpool:history) @@ -1030,9 +1061,10 @@ case $service:$words[1] in _arguments -A "-*" -S \ '(-s --suspend -c --cancel)'{-c,--cancel}'[cancel initializing on specified devices]' \ '(-s --suspend -c --cancel)'{-s,--suspend}'[suspend initializing on specified devices]' \ + '(-u --uninit)'{-u,--uninit}'[clear initialization state on specified devices]' \ '(-w --wait)'{-w,--wait}'[wait until devices have finished initializing before returning]' \ ':pool:_zfs_pool' \ - '*:device:pool-devices' + '*:device:->pool-devices' ;; zpool:iostat) @@ -1165,6 +1197,7 @@ case $service:$words[1] in [[ $implementation = openzfs ]] && args=( '(-s)-p[pause scrubbing]' '-w[wait until scrub has completed before returning]' + '-e[only scrub files with known data errors]' ) _arguments -A "-*" -S $args \ '(-p)-s[stop scrubbing]' \ @@ -1174,7 +1207,8 @@ case $service:$words[1] in zpool:set) _arguments -C -A "-*" -S \ ':property:->set-pool-properties' \ - '*:pool:_zfs_pool' + ':pool:_zfs_pool' \ + ':vdev:->pool-vdevs' ;; zpool:split) @@ -1251,6 +1285,36 @@ case $service:$words[1] in ':interval' ;; + zstream:dump) + _arguments -A "-*" -S \ + '-C[suppress the validation of checksums]' \ + '(-d)-v[print metadata for each record]' \ + '(-v)-d[dump data contained in each record]' \ + ':file:_files' + ;; + + zstream:token) + _message -e tokens 'resume token' + ;; + + zstream:decompress) + _arguments -A "-*" -S \ + '-v[print summary of decompressed records]' \ + '*:offset' + ;; + + zstream:redup) + _arguments -A "-*" -S \ + '-v[print summary of converted records]' \ + ':file:stream file' + ;; + + zstream:recompress) + _arguments -A "-*" -S \ + '-l+[specify compression level]:level' \ + '*:algorithm:compadd -a comp_algorithms' + ;; + *) _default ;; @@ -1259,6 +1323,7 @@ esac while (( $#state )); do curstate=$state state=() + devices=() case $curstate in virtual-devices) local -a vdevtypes @@ -1278,8 +1343,15 @@ while (( $#state )); do _alternative $alts 'file-vdevs:file vdev:_files -W / -P /' ;; + pool-vdevs-all) devices=( all-vdevs ) ;& + pool-vdevs) # same as pool-devices but on OpenZFS 2.2+ only features + # path field is also valid + devices+=( $(_call_program devices zpool get -H -o name state $line[CURRENT-2] all-vdevs) ) + _description devices expl "$state_descr" + compadd "$expl[@]" -a devices + ;; + pool-devices) - local -a devices devices=( ${${${(M)${(f)"$(_call_program devices zpool status $line[1])"}:#$'\t' *}##[[:blank:]]#}%%[[:blank:]]*} ) if (( $#devices )); then _description devices expl "$state_descr" @@ -1321,12 +1393,13 @@ while (( $#state )); do create-properties) args=( $ci_ds_props ) ;| set-properties) args=( $rw_ds_props ) ;| newpool-properties) args=( $rw_po_props $ci_po_props ) ;| - set-pool-properties) args=( $rw_po_props ) ;| + set-pool-properties) args=( $rw_po_props $rw_vdev_props ) ;| *-properties) if compset -P 1 '(#m)*@'; then if compset -P 1 '*='; then case $MATCH in + *feature@) _wanted states expl state compadd active enabled disabled ;; *quota@) _alternative \ 'sizes: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size \:B {k,M,G,T,P,E,Z}{,B}' \ 'properties:property:(none)' @@ -1334,8 +1407,12 @@ while (( $#state )); do esac else case $MATCH in - user*@) _users -S = ;; - group*@) _groups -S = ;; + feature@) + features=( ${${${${${(f)"$(_call_program features zpool upgrade -v)"}[(r)---*,(R)VER *]}[2,-3]}:# *}%% *} ) + _wanted features expl feature compadd -qS= -a features + ;; + user*@) _users -qS= ;; + group*@) _groups -qS= ;; project*@) _message -e projects project ;; esac fi -- cgit v1.2.3 From fa17566b658f8bc42f958a68ff9df634667b4def Mon Sep 17 00:00:00 2001 From: Wesley Schwengle Date: Wed, 13 Sep 2023 22:53:04 -0400 Subject: 52141: Add trailer token completion for git commit --trailer Via 842587016d in the git project there has been support for git commit trailer tokens for the bash completion system. This commit adds similar support to zsh. It includes additional hardening of the regexp and allows for tokens which include a '.'. This can be found in git via 9a0ec17606. --- ChangeLog | 3 +++ Completion/Unix/Command/_git | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 55dd9ab8a..6b1752c7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-09-20 Oliver Kiddle + * Wesley Schwengle: 52141: Completion/Unix/Command/_git: add trailer + token completion for git commit --trailer + * 52163: Completion/Unix/Command/_zfs: completion update for OpenZFS 2.2 diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 1d4fe20c9..cefc88c5a 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -717,7 +717,7 @@ _git-commit () { {-p,--patch}'[use the interactive patch selection interface to chose which changes to commit]' \ '(--reset-author)--author[override the author name used in the commit]:author name' \ '--date=[override the author date used in the commit]:date' \ - '*--trailer=[add custom trailer(s)]:trailer' \ + '*--trailer=[add custom trailer(s)]:trailer:__git_trailers_tokens' \ '(-s --signoff)'{-s,--signoff}'[add Signed-off-by trailer at the end of the commit message]' \ '(-n --no-verify)'{-n,--no-verify}'[bypass pre-commit and commit-msg hooks]' \ '--allow-empty[allow recording an empty commit]' \ @@ -7413,6 +7413,19 @@ __git_deleted_files () { __git_files --deleted deleted-files 'deleted file' $* } +(( $+functions[__git_trailers_tokens] )) || +__git_trailers_tokens() { + declare -a trailers + local i + + local -a gtrailers=( $(_call_program trailers git config --name-only --get-regexp '^trailer\..*\.key$') ) + for i in $gtrailers; do + i=( ${${(@s:.:)i}[2,-2]} ) + trailers+=( ${(j|.|)i} ) + done + _wanted trailers expl "trailer" compadd -a trailers +} + (( $+functions[__git_modified_files] )) || __git_modified_files () { __git_files --modified modified-files 'modified file' $* -- cgit v1.2.3 From bfc419e0c6dcc796b5171ae6c316fd60ffab8030 Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Sun, 27 Aug 2023 17:57:27 +0200 Subject: 52102: Add subcommand autopurge to apt completion Autopurge (like autoremove) take the same options like purge and remove the given packages along with their dependencies they become unused. --- ChangeLog | 3 +++ Completion/Debian/Command/_apt | 14 +++++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b1752c7c..44171d558 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-09-20 Oliver Kiddle + * Jörg Sommer: 52102: Completion/Debian/Command/_apt: + Add subcommand autopurge to apt completion + * Wesley Schwengle: 52141: Completion/Unix/Command/_git: add trailer token completion for git commit --trailer diff --git a/Completion/Debian/Command/_apt b/Completion/Debian/Command/_apt index 494d3bf82..19f818c27 100644 --- a/Completion/Debian/Command/_apt +++ b/Completion/Debian/Command/_apt @@ -422,15 +422,14 @@ _apt-cmd () { /$'[^\0/=]#='/ /'[]'/ ':apt-package-versions:package version:_apt_versions_of_binary_package' \| \ \) \ \) \| \ - /$'(remove|reinstall|purge)\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'((|auto)(remove|purge)|reinstall)\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ /$'upgrade\0'/ \| \ /$'autoclean\0'/ \| \ /$'changelog\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \| \ - /$'autoremove\0'/ \| \ /$'full-upgrade\0'/ \| \ /$'dist-upgrade\0'/ \| \ /$'edit-sources\0'/ \| \ - /"[]"/ ':argument-1::compadd "$expl_action[@]" list search showsrc show depends rdepends policy update install reinstall download source build-dep remove upgrade full-upgrade dist-upgrade edit-sources autoclean changelog autoremove purge' + /"[]"/ ':argument-1::compadd "$expl_action[@]" list search showsrc show depends rdepends policy update install reinstall download source build-dep remove upgrade full-upgrade dist-upgrade edit-sources autoclean changelog autopurge autoremove purge' _apt-cmd () { local expl_action expl_packages subcmd @@ -487,19 +486,16 @@ _apt-get () { /$'[^\0/=]#='/ /'[]'/ ':apt-package-versions:package version:_apt_versions_of_binary_package' \ \) \ \) \| \ - /$'remove\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ - /$'purge\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'(|auto)(purge|remove)\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ /$'dist-upgrade\0'/ \| \ /$'dselect-upgrade\0'/ \| \ /$'clean\0'/ \| \ /$'autoclean\0'/ \| \ /$'changelog\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \| \ /$'check\0'/ \| \ - /$'autoremove\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ /$'help\0/' \| \ - /$'markauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ - /$'unmarkauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ - /"[]"/ ':argument-1::compadd "$expl_action[@]" update upgrade install remove purge dist-upgrade dselect-upgrade clean autoclean changelog check source build-dep autoremove help markauto unmarkauto download' + /$'(|un)markauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /"[]"/ ':argument-1::compadd "$expl_action[@]" update upgrade install remove purge dist-upgrade dselect-upgrade clean autoclean changelog check source build-dep autopurge autoremove help markauto unmarkauto download' _apt-get () { local expl_action expl_packages -- cgit v1.2.3 From d92b1a3547e4d7e602316e12f0a896356579c1ab Mon Sep 17 00:00:00 2001 From: Atte Peltomäki Date: Thu, 20 Jul 2023 13:52:08 +0300 Subject: 51980: Add glob qualifier grouping operator to completion Also improve wording in documentation to make glob qualifier grouping easier to find by explicit use of terms 'logical OR' and 'logical AND'. --- ChangeLog | 7 +++++-- Completion/Zsh/Type/_globquals | 1 + Doc/Zsh/expn.yo | 7 ++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 44171d558..71e1b2f76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,13 @@ 2023-09-20 Oliver Kiddle + * Atte Peltomäki: 51980: Completion/Zsh/Type/_globquals, + Doc/Zsh/expn.yo: Add glob qualifier grouping operator to completion + * Jörg Sommer: 52102: Completion/Debian/Command/_apt: Add subcommand autopurge to apt completion - * Wesley Schwengle: 52141: Completion/Unix/Command/_git: add trailer - token completion for git commit --trailer + * Wesley Schwengle: 52141: Completion/Unix/Command/_git: + add trailer token completion for git commit --trailer * 52163: Completion/Unix/Command/_zfs: completion update for OpenZFS 2.2 diff --git a/Completion/Zsh/Type/_globquals b/Completion/Zsh/Type/_globquals index bc3165eba..beb47ed30 100644 --- a/Completion/Zsh/Type/_globquals +++ b/Completion/Zsh/Type/_globquals @@ -268,6 +268,7 @@ case $state in "P:prepend word" "Y:+ at most ARG matches" "[:+ range of files" + ",:logical OR" "):end of qualifiers" "\::modifier" ) diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 5be40bf25..86a5f70c8 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -3117,9 +3117,10 @@ so both can be used on the same glob expression; for example by writing ) enditem() -More than one of these lists can be combined, separated by commas. The -whole list matches if at least one of the sublists matches (they are -`or'ed, the qualifiers in the sublists are `and'ed). Some qualifiers, +Multiple consecutive qualifiers are joined into a list by implicit logical AND. +More than one of these lists can be combined using comma `tt(,)' as logical OR. +The whole list matches if at least one of the sublists matches. +Some qualifiers, however, affect all matches generated, independent of the sublist in which they are given. These are the qualifiers `tt(M)', `tt(T)', `tt(N)', `tt(D)', `tt(n)', `tt(o)', `tt(O)' and the subscripts given -- cgit v1.2.3 From 12b61965b5f78f95109ad9f67199c43e3c90693a Mon Sep 17 00:00:00 2001 From: Wim de With Date: Thu, 8 Jun 2023 16:58:38 +0200 Subject: 51857: Include fusermount3 in fusermount completions fusermount3 is part of libfuse version 3, while fusermount is part of libfuse version 2. Since they share the exact same command line interface, we can reuse the completions. --- ChangeLog | 3 +++ Completion/Linux/Command/_fusermount | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 71e1b2f76..f03fd0d5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-09-20 Oliver Kiddle + * Wim de With: 51857: Completion/Linux/Command/_fusermount: + Include fusermount3 in fusermount completions + * Atte Peltomäki: 51980: Completion/Zsh/Type/_globquals, Doc/Zsh/expn.yo: Add glob qualifier grouping operator to completion diff --git a/Completion/Linux/Command/_fusermount b/Completion/Linux/Command/_fusermount index d55eca29c..24f9a8018 100644 --- a/Completion/Linux/Command/_fusermount +++ b/Completion/Linux/Command/_fusermount @@ -1,4 +1,4 @@ -#compdef fusermount +#compdef fusermount fusermount3 local expl context state line typeset -A opt_args -- cgit v1.2.3 From f093b41f09ab18459a75c86c0a896aa36432803b Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Tue, 23 May 2023 18:25:41 +0200 Subject: 51776: run-help-openssl: Reduce code and use new manpages Openssl switches the naming of manpages to the common style openssl-$SUBCOMMAND, e.g. openssl-enc. For backward compatibility try to show the manpage with the old name if the new one doesn't exist. --- ChangeLog | 3 +++ Functions/Misc/run-help-openssl | 8 +------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index f03fd0d5c..eeb4cd618 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-09-20 Oliver Kiddle + * Jörg Sommer: 51776: Functions/Misc/run-help-openssl: + Reduce code and use new manpages + * Wim de With: 51857: Completion/Linux/Command/_fusermount: Include fusermount3 in fusermount completions diff --git a/Functions/Misc/run-help-openssl b/Functions/Misc/run-help-openssl index c528418c8..e4e45070e 100644 --- a/Functions/Misc/run-help-openssl +++ b/Functions/Misc/run-help-openssl @@ -1,7 +1 @@ - -if [ $# -eq 0 ]; then - man openssl -else - man $1 -fi - +man openssl${1:+-$1} || man ${1:-openssl} -- cgit v1.2.3 From 9eb2b047035273891c66f6d0fc23edb22d6bfad5 Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Thu, 18 May 2023 00:12:45 +0200 Subject: 51747: ip accepts the reduction of link to l. --- ChangeLog | 3 +++ Functions/Misc/run-help-ip | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index eeb4cd618..e12ed92e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-09-20 Oliver Kiddle + * Jörg Sommer: 51747: Functions/Misc/run-help-ip: + ip accepts the reduction of link to l + * Jörg Sommer: 51776: Functions/Misc/run-help-openssl: Reduce code and use new manpages diff --git a/Functions/Misc/run-help-ip b/Functions/Misc/run-help-ip index b811ce352..f635cce71 100644 --- a/Functions/Misc/run-help-ip +++ b/Functions/Misc/run-help-ip @@ -18,7 +18,7 @@ case $1 in (addrl*) man ip-addrlabel ;; (a*) man ip-address ;; (l2*) man ip-l2tp ;; - (li*) man ip-link ;; + (l*) man ip-link ;; (ma*) man ip-maddress ;; (mo*) man ip-monitor ;; (mr*) man ip-mroute ;; -- cgit v1.2.3 From b35799269750de2801f8bf292f4374c2fa0f7a09 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 22 Sep 2023 20:29:40 -0500 Subject: 52176: metafy return from ${ ... } substitution --- ChangeLog | 5 +++++ Src/subst.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e12ed92e0..e4965b804 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-09-22 Bart Schaefer + + * 52176: Src/subst.c: metafy return from ${ ... } substitution + (adapted from Jun T.: 52172) + 2023-09-20 Oliver Kiddle * Jörg Sommer: 51747: Functions/Misc/run-help-ip: diff --git a/Src/subst.c b/Src/subst.c index dc2052ee0..f37ae935e 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2003,11 +2003,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } else /* parse error */ errflag |= ERRFLAG_ERROR; if (rplytmp && !errflag) { - int onoerrs = noerrs; + int onoerrs = noerrs, rplylen; noerrs = 2; - if ((cmdarg = ztuff(rplytmp))) - setsparam("REPLY", cmdarg); + rplylen = zstuff(&cmdarg, rplytmp); noerrs = onoerrs; + if (rplylen >= 0) + setsparam("REPLY", metafy(cmdarg, rplylen, META_REALLOC)); } } -- cgit v1.2.3 From e4e9afe373479076ee448b16944a421836ba5a40 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 23 Sep 2023 09:30:55 -0500 Subject: 52180: clarify array behavior of ${|var|...} and REPLY --- ChangeLog | 5 +++++ Doc/Zsh/expn.yo | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4965b804..0f3c9402d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-09-23 Bart Schaefer + + * 52180: Doc/Zsh/expn.yo: clarify array behavior of ${|var|...} + and the REPLY parameter + 2023-09-22 Bart Schaefer * 52176: Src/subst.c: metafy return from ${ ... } substitution diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 86a5f70c8..837a85db6 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1915,8 +1915,9 @@ Substitutions of the form `tt(${|)var(param)tt(|)...tt(})' are similar, except that the substitution is replaced by the value of the parameter named by var(param). No implicit save or restore applies to var(param) except as noted for tt(REPLY), and var(param) should em(not) be declared -within the command. If var(param) names an array, array expansion rules -apply. +within the command. If, after evaluating the expression, var(param) +names an array, array expansion rules apply. However, tt(REPLY) is +always expanded in scalar context, even if assigned an array. A command enclosed in braces preceded by a dollar sign, and set off from the braces by whitespace, like `tt(${ )...tt( })', is replaced by its -- cgit v1.2.3 From 02e33c54d85208c7d9b96d91a26d04069ff19ed2 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Wed, 27 Sep 2023 01:56:47 +0900 Subject: 52169: a few more improvements of (#) flag fix (#X) in C locale in FreeBSD, DragonFly, NetBSD. Negative values such as ${(#X):--1} are now error. UCS4 is limited to < 0x8000_0000 (in OSes without __STDC_ISO_10646__). --- ChangeLog | 4 ++ Src/subst.c | 15 ++-- Src/utils.c | 230 ++++++++++++++++++++++++++++++------------------------------ 3 files changed, 125 insertions(+), 124 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0f3c9402d..506635756 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-09-27 Jun-ichi Takimoto + + * 52169: Src/subst.c, Src/utils.c: a few more improvemets of (#) + 2023-09-23 Bart Schaefer * 52180: Doc/Zsh/expn.yo: clarify array behavior of ${|var|...} diff --git a/Src/subst.c b/Src/subst.c index f37ae935e..cdbfc138a 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1501,16 +1501,15 @@ substevalchar(char *ptr) return noerrs ? dupstring(""): NULL; } errflag |= saved_errflag; + if (ires < 0) { + zerr("character not in range"); + } #ifdef MULTIBYTE_SUPPORT - if (isset(MULTIBYTE) && ires > 127) { - /* '\\' + 'U' + 8 bytes of character + '\0' */ - char buf[11]; - - /* inefficient: should separate out \U handling from getkeystring */ - sprintf(buf, "\\U%.8x", (unsigned int)ires & 0xFFFFFFFFu); - ptr = getkeystring(buf, &len, GETKEYS_BINDKEY, NULL); + else if (isset(MULTIBYTE) && ires > 127) { + ptr = zhalloc(MB_CUR_MAX); + len = ucs4tomb((unsigned int)ires & 0xffffffff, ptr); } - if (len == 0) + if (len <= 0) #endif { ptr = zhalloc(2); diff --git a/Src/utils.c b/Src/utils.c index 7040d0954..7028c155f 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -6672,11 +6672,14 @@ dquotedzputs(char const *s, FILE *stream) # if defined(HAVE_NL_LANGINFO) && defined(CODESET) && !defined(__STDC_ISO_10646__) /* Convert a character from UCS4 encoding to UTF-8 */ -static size_t +static int ucs4toutf8(char *dest, unsigned int wval) { - size_t len; + int len; + /* UCS4 is now equvalent to UTF-32 and limited to 0 - 0x10_FFFF. + * This function accepts 0 - 0x7FFF_FFFF (old range of UCS4) to be + * compatible with wctomb(3) (in UTF-8 locale) on Linux. */ if (wval < 0x80) len = 1; else if (wval < 0x800) @@ -6687,8 +6690,12 @@ ucs4toutf8(char *dest, unsigned int wval) len = 4; else if (wval < 0x4000000) len = 5; - else + else if (wval < 0x80000000) len = 6; + else { + zerr("character not in range"); + return -1; + } switch (len) { /* falls through except to the last case */ case 6: dest[5] = (wval & 0x3f) | 0x80; wval >>= 6; @@ -6705,30 +6712,89 @@ ucs4toutf8(char *dest, unsigned int wval) } #endif +/* Convert UCS4 to a multibyte character in current locale. + * Result is saved in buf (must be at least MB_CUR_MAX bytes long). + * Returns the number of bytes saved in buf, or -1 if conversion fails. */ -/* - * The following only occurs once or twice in the code, but in different - * places depending how character set conversion is implemented. - */ -#define CHARSET_FAILED() \ - if (how & GETKEY_DOLLAR_QUOTE) { \ - while ((*tdest++ = *++s)) { \ - if (how & GETKEY_UPDATE_OFFSET) { \ - if (s - sstart > *misc) \ - (*misc)++; \ - } \ - if (*s == Snull) { \ - *len = (s - sstart) + 1; \ - *tdest = '\0'; \ - return buf; \ - } \ - } \ - *len = tdest - buf; \ - return buf; \ - } \ - *t = '\0'; \ - *len = t - buf; \ - return buf +/**/ +int +ucs4tomb(unsigned int wval, char *buf) +{ +#if defined(HAVE_WCHAR_H) && defined(HAVE_WCTOMB) && defined(__STDC_ISO_10646__) + int count = wctomb(buf, (wchar_t)wval); + if (count == -1) + zerr("character not in range"); + return count; +#else /* !(HAVE_WCHAR_H && HAVE_WCTOMB && __STDC_ISO_10646__) */ +# if defined(HAVE_NL_LANGINFO) && defined(CODESET) + if (!strcmp(nl_langinfo(CODESET), "UTF-8")) { + return ucs4toutf8(buf, wval); + } else { +# ifdef HAVE_ICONV + iconv_t cd; + char inbuf[4], *bsave = buf; + ICONV_CONST char *inptr = inbuf; + size_t inbytes = 4, outbytes = 6; + const char *codesetstr = nl_langinfo(CODESET); + size_t count; + int i; + + /* + * If the code set isn't handled, we'd better assume it's US-ASCII + * rather than just failing hopelessly. Solaris has a weird habit + * of returning 646. This is handled by the native iconv(), but + * not by GNU iconv; what's more, some versions of the native iconv + * don't handle standard names like ASCII. + * + * This should only be a problem if there's a mismatch between the + * NLS and the iconv in use, which probably only means if libiconv + * is in use. We checked at configure time if our libraries pulled + * in _libiconv_version, which should be a good test. + * + * It shouldn't ever be NULL, but while we're being paranoid... + */ +# ifdef ICONV_FROM_LIBICONV + if (!codesetstr || !*codesetstr) + codesetstr = "US-ASCII"; +# endif + cd = iconv_open(codesetstr, "UCS-4BE"); +# ifdef ICONV_FROM_LIBICONV + if (cd == (iconv_t)-1 && !strcmp(codesetstr, "646")) { + codesetstr = "US-ASCII"; + cd = iconv_open(codesetstr, "UCS-4BE"); + } +# endif + if (cd == (iconv_t)-1) { + zerr("cannot do charset conversion (iconv failed)"); + return -1; + } + + /* store value in big endian form */ + for (i=3; i>=0; i--) { + inbuf[i] = wval & 0xff; + wval >>= 8; + } + count = iconv(cd, &inptr, &inbytes, &buf, &outbytes); + iconv_close(cd); + if (count) { + /* -1 indicates error. Positive value means number of "invalid" + * (or "non-reversible") conversions, which we consider as + * "out-of-range" characters. */ + zerr("character not in range"); + return -1; + } + return buf - bsave; +# else /* !HAVE_ICONV */ + zerr("cannot do charset conversion (iconv not available)"); + return -1; +# endif /* HAVE_ICONV */ + } +# else /* !(HAVE_NL_LANGINFO && CODESET) */ + zerr("cannot do charset conversion (NLS not supported)"); + return -1; +# endif /* HAVE_NL_LANGINFO && CODESET */ +#endif /* HAVE_WCHAR_H && HAVE_WCTOMB && __STDC_ISO_10646__ */ +} /* * Decode a key string, turning it into the literal characters. @@ -6785,21 +6851,6 @@ getkeystring(char *s, int *len, int how, int *misc) char *t, *tdest = NULL, *u = NULL, *sstart = s, *tbuf = NULL; char svchar = '\0'; int meta = 0, control = 0, ignoring = 0; - int i; -#if defined(HAVE_WCHAR_H) && defined(HAVE_WCTOMB) && defined(__STDC_ISO_10646__) - wint_t wval; - int count; -#else - unsigned int wval; -# if defined(HAVE_NL_LANGINFO) && defined(CODESET) -# if defined(HAVE_ICONV) - iconv_t cd; - char inbuf[4]; - size_t inbytes, outbytes; -# endif - size_t count; -# endif -#endif DPUTS((how & GETKEY_UPDATE_OFFSET) && (how & ~(GETKEYS_DOLLARS_QUOTE|GETKEY_UPDATE_OFFSET)), @@ -6864,7 +6915,8 @@ getkeystring(char *s, int *len, int how, int *misc) } for (; *s; s++) { if (*s == '\\' && s[1]) { - int miscadded; + int miscadded, count, i; + unsigned int wval; if ((how & GETKEY_UPDATE_OFFSET) && s - sstart < *misc) { (*misc)--; miscadded = 1; @@ -6979,86 +7031,32 @@ getkeystring(char *s, int *len, int how, int *misc) *misc = wval; return s+1; } -#if defined(HAVE_WCHAR_H) && defined(HAVE_WCTOMB) && defined(__STDC_ISO_10646__) - count = wctomb(t, (wchar_t)wval); + count = ucs4tomb(wval, t); if (count == -1) { - zerr("character not in range"); - CHARSET_FAILED(); + if (how & GETKEY_DOLLAR_QUOTE) { + while ((*tdest++ = *++s)) { + if (how & GETKEY_UPDATE_OFFSET) { + if (s - sstart > *misc) + (*misc)++; + } + if (*s == Snull) { + *len = (s - sstart) + 1; + *tdest = '\0'; + return buf; + } + } + *len = tdest - buf; + } + else { + *t = '\0'; + *len = t - buf; + } + return buf; } if ((how & GETKEY_UPDATE_OFFSET) && s - sstart < *misc) (*misc) += count; t += count; -# else -# if defined(HAVE_NL_LANGINFO) && defined(CODESET) - if (!strcmp(nl_langinfo(CODESET), "UTF-8")) { - count = ucs4toutf8(t, wval); - t += count; - if ((how & GETKEY_UPDATE_OFFSET) && s - sstart < *misc) - (*misc) += count; - } else { -# ifdef HAVE_ICONV - ICONV_CONST char *inptr = inbuf; - const char *codesetstr = nl_langinfo(CODESET); - inbytes = 4; - outbytes = 6; - /* store value in big endian form */ - for (i=3;i>=0;i--) { - inbuf[i] = wval & 0xff; - wval >>= 8; - } - /* - * If the code set isn't handled, we'd better - * assume it's US-ASCII rather than just failing - * hopelessly. Solaris has a weird habit of - * returning 646. This is handled by the - * native iconv(), but not by GNU iconv; what's - * more, some versions of the native iconv don't - * handle standard names like ASCII. - * - * This should only be a problem if there's a - * mismatch between the NLS and the iconv in use, - * which probably only means if libiconv is in use. - * We checked at configure time if our libraries - * pulled in _libiconv_version, which should be - * a good test. - * - * It shouldn't ever be NULL, but while we're - * being paranoid... - */ -#ifdef ICONV_FROM_LIBICONV - if (!codesetstr || !*codesetstr) - codesetstr = "US-ASCII"; -#endif - cd = iconv_open(codesetstr, "UCS-4BE"); -#ifdef ICONV_FROM_LIBICONV - if (cd == (iconv_t)-1 && !strcmp(codesetstr, "646")) { - codesetstr = "US-ASCII"; - cd = iconv_open(codesetstr, "UCS-4BE"); - } -#endif - if (cd == (iconv_t)-1) { - zerr("cannot do charset conversion (iconv failed)"); - CHARSET_FAILED(); - } - count = iconv(cd, &inptr, &inbytes, &t, &outbytes); - iconv_close(cd); - if (count == (size_t)-1) { - zerr("character not in range"); - CHARSET_FAILED(); - } - if ((how & GETKEY_UPDATE_OFFSET) && s - sstart < *misc) - (*misc) += count; -# else - zerr("cannot do charset conversion (iconv not available)"); - CHARSET_FAILED(); -# endif - } -# else - zerr("cannot do charset conversion (NLS not supported)"); - CHARSET_FAILED(); -# endif -# endif if (how & GETKEY_DOLLAR_QUOTE) { char *t2; for (t2 = tbuf; t2 < t; t2++) { -- cgit v1.2.3 From 1b8446e1cd6dcd0644c1c96b952e11cbc472a24d Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Wed, 27 Sep 2023 23:45:00 +0900 Subject: 52188: skip tests that fail if multibyte is not available --- ChangeLog | 3 +++ Test/D04parameter.ztst | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 506635756..4c0a27878 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-09-27 Jun-ichi Takimoto + * 52188: Test/D04parameter.ztst: skip tests that fail if + multibyte is not available + * 52169: Src/subst.c, Src/utils.c: a few more improvemets of (#) 2023-09-23 Bart Schaefer diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 12ae1a446..c2008582c 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2807,21 +2807,29 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888 0:${(#)...}: array of bad math expressions, printf >az - : ${(#X):-0x80} + if [[ ! -o multibyte ]]; then + ZTST_skip='(#X) accepts any byte if multibyte is off' + else + : ${(#X):-0x80} + fi 1:${(#X)...}: out-of-range character -?(eval):1: character not in range +?(eval):4: character not in range [[ ${(#):-0x80} = $'\x80' ]] && echo OK 0:${(#)...}: out-of-range character >OK a=( 0x80 0x81 ) - : ${(#X)a} -1:${(#X)...}: array of out-of-range characters -?(eval):2: character not in range - printf "%s\n" ${(#)a} | while read x; do echo $(( #x )); done 0:${(#)...}: array of out-of-range characters >128 >129 + + if [[ ! -o multibyte ]]; then + ZTST_skip='(#X) accepts any byte if multibyte is off' + else + : ${(#X)a} + fi +1:${(#X)...}: array of out-of-range characters +?(eval):4: character not in range -- cgit v1.2.3 From 29644f12e742883ec9502205cffb318e446d7ca3 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 1 Oct 2023 11:34:33 -0700 Subject: 52193: handle UTF8-encoded USERNAME and therefore home directory in zcompile Includes one unposted thinko fix ztrdup -> dupstring --- ChangeLog | 7 +++++++ Src/init.c | 4 ++-- Src/params.c | 2 +- Src/parse.c | 12 +++++++++--- Src/utils.c | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c0a27878..840f6c5a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-10-01 Bart Schaefer + + * 52193: Src/init.c, Src/params.c, Src/utils.c: metafy USERNAME + (mostly for Cygwin compatibilty with UTF8 encodings) + + * 52193: Src/parse.c: unmetafy file paths in zcompile + 2023-09-27 Jun-ichi Takimoto * 52188: Test/D04parameter.ztst: skip tests that fail if diff --git a/Src/init.c b/Src/init.c index ffb017e22..799ad19f6 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1212,8 +1212,8 @@ setupvals(char *cmd, char *runscript, char *zsh_name) #ifdef USE_GETPWUID if ((pswd = getpwuid(cached_uid))) { if (EMULATION(EMULATE_ZSH)) - home = metafy(pswd->pw_dir, -1, META_DUP); - cached_username = ztrdup(pswd->pw_name); + home = ztrdup_metafy(pswd->pw_dir); + cached_username = ztrdup_metafy(pswd->pw_name); } else #endif /* USE_GETPWUID */ diff --git a/Src/params.c b/Src/params.c index 5841308d7..50e8627d1 100644 --- a/Src/params.c +++ b/Src/params.c @@ -4561,7 +4561,7 @@ usernamesetfn(UNUSED(Param pm), char *x) zwarn("failed to change user ID: %e", errno); else { zsfree(cached_username); - cached_username = ztrdup(pswd->pw_name); + cached_username = ztrdup_metafy(pswd->pw_name); cached_uid = pswd->pw_uid; } } diff --git a/Src/parse.c b/Src/parse.c index a07a6cc71..f7285c2ed 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -3217,12 +3217,14 @@ bin_zcompile(char *nam, char **args, Options ops, UNUSED(int func)) if (!args[1] && !(OPT_ISSET(ops,'c') || OPT_ISSET(ops,'a'))) { queue_signals(); - ret = build_dump(nam, dyncat(*args, FD_EXT), args, OPT_ISSET(ops,'U'), + dump = unmetafy(dyncat(*args, FD_EXT), NULL); + ret = build_dump(nam, dump, args, OPT_ISSET(ops,'U'), map, flags); unqueue_signals(); return ret; } - dump = (strsfx(FD_EXT, *args) ? *args : dyncat(*args, FD_EXT)); + dump = (strsfx(FD_EXT, *args) ? dupstring(*args) : dyncat(*args, FD_EXT)); + unmetafy(dump, NULL); queue_signals(); ret = ((OPT_ISSET(ops,'c') || OPT_ISSET(ops,'a')) ? @@ -3400,6 +3402,7 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags) for (hlen = FD_PRELEN, tlen = 0; *files; files++) { struct stat st; + char *fnam; if (check_cond(*files, "k")) { flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_KSHLOAD; @@ -3408,7 +3411,8 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags) flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_ZSHLOAD; continue; } - if ((fd = open(*files, O_RDONLY)) < 0 || + fnam = unmeta(*files); + if ((fd = open(fnam, O_RDONLY)) < 0 || fstat(fd, &st) != 0 || !S_ISREG(st.st_mode) || (flen = lseek(fd, 0, 2)) == -1) { if (fd >= 0) @@ -3417,8 +3421,10 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags) zwarnnam(nam, "can't open file: %s", *files); noaliases = ona; unlink(dump); + zsfree(fnam); return 1; } + zsfree(fnam); file = (char *) zalloc(flen + 1); file[flen] = '\0'; lseek(fd, 0, 0); diff --git a/Src/utils.c b/Src/utils.c index 7028c155f..790625379 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1069,7 +1069,7 @@ get_username(void) cached_uid = current_uid; zsfree(cached_username); if ((pswd = getpwuid(current_uid))) - cached_username = ztrdup(pswd->pw_name); + cached_username = ztrdup_metafy(pswd->pw_name); else cached_username = ztrdup(""); } -- cgit v1.2.3 From 0f0ba0539e9fdc063c73e3ac6751f77395c193ec Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 1 Oct 2023 13:38:25 -0700 Subject: 52195: cached_username is already metafied when initializing LOGNAME --- ChangeLog | 3 +++ Src/params.c | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 840f6c5a1..d08adc031 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-10-01 Bart Schaefer + * 52195: Src/params.c: cached_username is already metafied when + initializing LOGNAME + * 52193: Src/init.c, Src/params.c, Src/utils.c: metafy USERNAME (mostly for Cygwin compatibilty with UTF8 encodings) diff --git a/Src/params.c b/Src/params.c index 50e8627d1..957656e3f 100644 --- a/Src/params.c +++ b/Src/params.c @@ -850,12 +850,11 @@ createparamtable(void) setsparam("HOST", ztrdup_metafy(hostnam)); zfree(hostnam, 256); - setsparam("LOGNAME", ztrdup_metafy( + setsparam("LOGNAME", #ifndef DISABLE_DYNAMIC_NSS - (str = getlogin()) && *str ? str : + (str = getlogin()) && *str ? ztrdup_metafy(str) : #endif - cached_username - )); + ztrdup(cached_username)); #if !defined(HAVE_PUTENV) && !defined(USE_SET_UNSET_ENV) /* Copy the environment variables we are inheriting to dynamic * -- cgit v1.2.3 From 86196843bd8a1d7afc81631881b2e98385e5c4a7 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 3 Oct 2023 21:21:54 -0700 Subject: 52198: put back incorrectly removed zfree() --- ChangeLog | 4 ++++ Src/input.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index d08adc031..dc8d96e24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-10-03 Bart Schaefer + + * 52198: Src/input.c: put back incorrectly removed zfree() + 2023-10-01 Bart Schaefer * 52195: Src/params.c: cached_username is already metafied when diff --git a/Src/input.c b/Src/input.c index 8d7f44d7c..dd8f2edc7 100644 --- a/Src/input.c +++ b/Src/input.c @@ -632,6 +632,7 @@ zstuff(char **out, const char *fn) if (len && !(fread(buf, len, 1, in))) { zerr("read error on %s", fn); fclose(in); + zfree(buf, len + 1); unqueue_signals(); return -1; } -- cgit v1.2.3 From 1ffc6d0ef58bd0e6e4e0cb170af8c3325d77b376 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 5 Oct 2023 07:58:27 -0700 Subject: 52204: fix thinko, unmeta() buffer should not be freed --- ChangeLog | 4 ++++ Src/parse.c | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index dc8d96e24..b7d49ace2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-10-05 Bart Schaefer + + * 52204: Src/parse.c: fix unmeta() thinko from 52193 + 2023-10-03 Bart Schaefer * 52198: Src/input.c: put back incorrectly removed zfree() diff --git a/Src/parse.c b/Src/parse.c index f7285c2ed..c0a1e9f95 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -3421,10 +3421,8 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags) zwarnnam(nam, "can't open file: %s", *files); noaliases = ona; unlink(dump); - zsfree(fnam); return 1; } - zsfree(fnam); file = (char *) zalloc(flen + 1); file[flen] = '\0'; lseek(fd, 0, 0); -- cgit v1.2.3 From 60479a7a180a837df4d973b5b9b50f4cd566bef9 Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Wed, 31 May 2023 19:45:59 +0200 Subject: 51812: run-help for docker, perf, podman, ssh, svnadmin --- ChangeLog | 7 +++++++ Functions/Misc/run-help-docker | 9 +++++++++ Functions/Misc/run-help-perf | 1 + Functions/Misc/run-help-podman | 9 +++++++++ Functions/Misc/run-help-ssh | 6 ++++++ Functions/Misc/run-help-svnadmin | 1 + 6 files changed, 33 insertions(+) create mode 100644 Functions/Misc/run-help-docker create mode 100644 Functions/Misc/run-help-perf create mode 100644 Functions/Misc/run-help-podman create mode 100644 Functions/Misc/run-help-ssh create mode 100644 Functions/Misc/run-help-svnadmin diff --git a/ChangeLog b/ChangeLog index b7d49ace2..a54ffdfe2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-10-10 Oliver Kiddle + + * Jörg Sommer: 51812: Functions/Misc/run-help-docker, + Functions/Misc/run-help-perf, Functions/Misc/run-help-podman, + Functions/Misc/run-help-ssh, Functions/Misc/run-help-svnadmin: + run-help for docker, perf, podman, ssh, svnadmin + 2023-10-05 Bart Schaefer * 52204: Src/parse.c: fix unmeta() thinko from 52193 diff --git a/Functions/Misc/run-help-docker b/Functions/Misc/run-help-docker new file mode 100644 index 000000000..09a8a221a --- /dev/null +++ b/Functions/Misc/run-help-docker @@ -0,0 +1,9 @@ +if [[ $# == 0 ]] +then + man docker +elif [[ $# > 1 && $1 == (builder|checkpoint|config|container|context|image|manifest|network|node|plugin|secret|service|stack|swarm|system|trust|volume) ]] +then + man docker-$1-$2 +else + man docker-$1 +fi diff --git a/Functions/Misc/run-help-perf b/Functions/Misc/run-help-perf new file mode 100644 index 000000000..2e0695af2 --- /dev/null +++ b/Functions/Misc/run-help-perf @@ -0,0 +1 @@ +man perf${1:+-$1} diff --git a/Functions/Misc/run-help-podman b/Functions/Misc/run-help-podman new file mode 100644 index 000000000..64d9cd83f --- /dev/null +++ b/Functions/Misc/run-help-podman @@ -0,0 +1,9 @@ +if [[ $# == 0 ]] +then + man podman +elif [[ $# > 1 && $1 == (container|generate|healthcheck|image|kube|machine|manifest|network|pod|secret|system|volume) ]] +then + man podman-$1-$2 +else + man podman-$1 +fi diff --git a/Functions/Misc/run-help-ssh b/Functions/Misc/run-help-ssh new file mode 100644 index 000000000..9c48596ff --- /dev/null +++ b/Functions/Misc/run-help-ssh @@ -0,0 +1,6 @@ +if [[ $# < 2 ]] +then + man ssh +else + run-help $2 +fi diff --git a/Functions/Misc/run-help-svnadmin b/Functions/Misc/run-help-svnadmin new file mode 100644 index 000000000..dbddd6396 --- /dev/null +++ b/Functions/Misc/run-help-svnadmin @@ -0,0 +1 @@ +svnadmin help $1 | ${=PAGER:-more} -- cgit v1.2.3 From a920e368b87f24e95b015eb091e1112c378c2939 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 11 Oct 2023 00:37:35 +0200 Subject: unposted (cf. 52166): remove obsolete helper for svk --- ChangeLog | 3 +++ Functions/Misc/run-help-svk | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 Functions/Misc/run-help-svk diff --git a/ChangeLog b/ChangeLog index a54ffdfe2..3e9b6ffa0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-10-10 Oliver Kiddle + * unposted (cf. 52166): Functions/Misc/run-help-svk: + remove obsolete helper for svk + * Jörg Sommer: 51812: Functions/Misc/run-help-docker, Functions/Misc/run-help-perf, Functions/Misc/run-help-podman, Functions/Misc/run-help-ssh, Functions/Misc/run-help-svnadmin: diff --git a/Functions/Misc/run-help-svk b/Functions/Misc/run-help-svk deleted file mode 100644 index 782538246..000000000 --- a/Functions/Misc/run-help-svk +++ /dev/null @@ -1 +0,0 @@ -svk help $1 | ${=PAGER:-more} -- cgit v1.2.3 From 83f8a71a7cc2137a1d4638228b3d83717c15af54 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sun, 8 Oct 2023 23:47:25 +0200 Subject: 52214: allow extra byte for nul terminator in allocation --- ChangeLog | 2 ++ Src/subst.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3e9b6ffa0..9e0a94b10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-10-10 Oliver Kiddle + * 52214: Src/subst.c: allow extra byte for nul in allocation + * unposted (cf. 52166): Functions/Misc/run-help-svk: remove obsolete helper for svk diff --git a/Src/subst.c b/Src/subst.c index cdbfc138a..60d850feb 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1506,7 +1506,7 @@ substevalchar(char *ptr) } #ifdef MULTIBYTE_SUPPORT else if (isset(MULTIBYTE) && ires > 127) { - ptr = zhalloc(MB_CUR_MAX); + ptr = zhalloc(MB_CUR_MAX+1); len = ucs4tomb((unsigned int)ires & 0xffffffff, ptr); } if (len <= 0) -- cgit v1.2.3 From 4878c2b1307d54cbdc218ee674403c03bc1e02c1 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 10 Oct 2023 23:46:15 +0200 Subject: 52216: metafy usernames to allow for them to be UTF-8 encoded --- ChangeLog | 3 +++ Src/Modules/watch.c | 26 ++++++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e0a94b10..9a5204ce7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-10-10 Oliver Kiddle + * 52216: Src/Modules/watch.c: metafy usernames to allow for + them to be UTF-8 encoded + * 52214: Src/subst.c: allow extra byte for nul in allocation * unposted (cf. 52166): Functions/Misc/run-help-svk: diff --git a/Src/Modules/watch.c b/Src/Modules/watch.c index 0de8cbf9a..97d4fa608 100644 --- a/Src/Modules/watch.c +++ b/Src/Modules/watch.c @@ -423,20 +423,23 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) /* See if the watch entry matches */ static int -watchlog_match(char *teststr, char *actual, int len) +watchlog_match(char *teststr, char *actual, size_t buflen) { int ret = 0; Patprog pprog; char *str = dupstring(teststr); + int len = strnlen(actual, buflen); + char *user = metafy(actual, len, + len == buflen ? META_HEAPDUP : META_USEHEAP); tokenize(str); if ((pprog = patcompile(str, PAT_STATIC, 0))) { queue_signals(); - if (pattry(pprog, actual)) + if (pattry(pprog, user)) ret = 1; unqueue_signals(); - } else if (!strncmp(actual, teststr, len)) + } else if (!strcmp(user, teststr)) ret = 1; return ret; } @@ -456,10 +459,17 @@ watchlog(int inout, WATCH_STRUCT_UTMP *u, char **w, char *fmt) (void)watchlog2(inout, u, fmt, 1, 0); return; } - if (*w && !strcmp(*w, "notme") && - strncmp(u->ut_name, get_username(), sizeof(u->ut_name))) { - (void)watchlog2(inout, u, fmt, 1, 0); - return; + if (*w && !strcmp(*w, "notme")) { + int len = strnlen(u->ut_name, sizeof(u->ut_name)); + char *username = metafy(u->ut_name, len, + (len == sizeof(u->ut_name) ? + META_HEAPDUP /* allow for nul terminator */ : + META_USEHEAP)); + if (strcmp(username, get_username())) { + (void)watchlog2(inout, u, fmt, 1, 0); + return; + } + w++; } for (; *w; w++) { bad = 0; @@ -488,7 +498,7 @@ watchlog(int inout, WATCH_STRUCT_UTMP *u, char **w, char *fmt) for (vv = ++v; *vv && *vv != '%'; vv++); sav = *vv; *vv = '\0'; - if (!watchlog_match(v, u->ut_host, strlen(v))) + if (!watchlog_match(v, u->ut_host, sizeof(u->ut_host))) bad = 1; *vv = sav; v = vv; -- cgit v1.2.3 From 985952e2f616c816e24c4cf5aee70416e4f23e07 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 11 Oct 2023 00:57:16 +0200 Subject: 52217: update completions for FreeBSD 14 --- ChangeLog | 13 ++++ Completion/BSD/Command/_freebsd-update | 1 + Completion/BSD/Command/_ipfw | 137 +++++++++++++++++++-------------- Completion/BSD/Command/_pfctl | 5 +- Completion/BSD/Command/_sockstat | 8 ++ Completion/Unix/Command/_cmp | 14 +++- Completion/Unix/Command/_date | 4 +- Completion/Unix/Command/_elfdump | 11 ++- Completion/Unix/Command/_gcore | 1 + Completion/Unix/Command/_ifconfig | 17 +++- Completion/Unix/Command/_iostat | 2 +- Completion/Unix/Command/_ldd | 3 +- Completion/Unix/Command/_ls | 13 ++-- Completion/Unix/Command/_mktemp | 54 ++++++------- Completion/Unix/Command/_netstat | 3 + Completion/Unix/Command/_script | 6 +- Completion/Unix/Command/_service | 5 +- Completion/Unix/Command/_split | 13 +++- Completion/Unix/Command/_ssh | 2 +- Completion/Unix/Command/_sysctl | 8 +- Completion/Unix/Type/_diff_options | 17 ++-- 21 files changed, 213 insertions(+), 124 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9a5204ce7..cfc1a2841 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2023-10-10 Oliver Kiddle + * 52217: Completion/BSD/Command/_freebsd-update, + Completion/BSD/Command/_ipfw, Completion/BSD/Command/_pfctl, + Completion/BSD/Command/_sockstat, Completion/Unix/Command/_cmp, + Completion/Unix/Command/_date, Completion/Unix/Command/_elfdump, + Completion/Unix/Command/_gcore, Completion/Unix/Command/_mktemp, + Completion/Unix/Command/_iostat, Completion/Unix/Command/_ldd, + Completion/Unix/Command/_ls, Completion/Unix/Command/_ifconfig, + Completion/Unix/Command/_netstat, Completion/Unix/Command/_script, + Completion/Unix/Command/_service, Completion/Unix/Command/_split, + Completion/Unix/Command/_ssh, Completion/Unix/Command/_sysctl, + Completion/Unix/Type/_diff_options: + update completions for FreeBSD 14 + * 52216: Src/Modules/watch.c: metafy usernames to allow for them to be UTF-8 encoded diff --git a/Completion/BSD/Command/_freebsd-update b/Completion/BSD/Command/_freebsd-update index 7dd907298..af37641e4 100644 --- a/Completion/BSD/Command/_freebsd-update +++ b/Completion/BSD/Command/_freebsd-update @@ -17,6 +17,7 @@ _arguments \ '-d[store working files in workdir]:workdir:_files -/' \ '-f[read configuration options from conffile]:conf file:_files' \ '-F[force freebsd-update fetch to proceed where it normally would not]' \ + '-j[operate on specified jail]: :_jails' \ '-k[trust an RSA key with SHA256 of KEY]:RSA key' \ '-r[specify the new release]:new release' \ '-s[fetch files from the specified server or server pool]:server:_hosts' \ diff --git a/Completion/BSD/Command/_ipfw b/Completion/BSD/Command/_ipfw index 49d0ef1e8..b910aa34d 100644 --- a/Completion/BSD/Command/_ipfw +++ b/Completion/BSD/Command/_ipfw @@ -1,7 +1,7 @@ -#compdef ipfw +#compdef ipfw dnctl local word=$'/[^ \t\0]#[ \t\0]/' comma next pqs nat -local -a actions address pathname ropts ca +local -a actions address dummynet args ropts ca local -A opt_args nat_options _ipfw_tables() { @@ -80,6 +80,46 @@ address=( \| \) ) +dummynet=( + $'/(pipe|queue|sched)[ \t\0]/' -'pqs=${match%?}' ':dummynet-commands:dummynet configuration:$ca pipe queue sched' + $word ': _message -e numbers number' + $word ':options:config:$ca config' + \( $'/bw[ \t\0]/' + \( $word ':bandwidths: :_numbers -M "m:{a-z}={A-Z}" bandwidth {K,M,G}{bit,Byte}/s' + \| $word ':devices:device:_net_interfaces -qS " "' \) + \| $'/delay[ \t\0]/' $word ': _message -e numbers "propagation delay (ms)"' + \| $'/burst[ \t\0]/' $word ': _message -e numbers "size (bytes)"' + \| $'/profile[ \t\0]/' $word ':files:file:_files -qS " "' + \| $'/pipe[ \t\0]/' $word ': _message -e pipes pipe' + \| $'/weight[ \t\0]/' $word ': _message -e weights "weight (1-100) [1]"' + \| $'/type[ \t\0]/-' + \( $'/fq_(pie|codel)[ \t\0]/' + \( $'/limit[ \t\0]/' $word ': _message -e numbers "limit (packets) [10240]"' + \| $'/flows[ \t\0]/' $word ': _message -e numbers "flow queues [1024]"' + \| $'/quantum[ \t\0]/' ':parameters:parameter:$ca -F line quantum limit flows' \) \# + '/[]/' + \| $word ':types:scheduling algorithm:$ca fifo wf2q+ rr qfq fq_codel fq_pie fq_codel' \) + \| $'/buckets[ \t\0]/' $word ': _message -e sizes "hash table size (16-65536)"' + \| $'/mask[ \t\0]/' $word ':mask-specifiers:mask specifier:$ca dst-ip dst-ip6 src-ip src-ip6 dst-port src-port flow-id proto all' + \| $'/plr[ \t\0]/' $word ': _message -e numbers "packet loss rate (0.0-1.0)"' + \| $'/queue[ \t\0]/' $word ': _message -e sizes "queue size"' + \| $'/(red|gred)[ \t\0]/' $word ': _message -e thresholds thresholds' + \| $'/codel[ \t\0]/' + \( $'/(target|interval)[ \t\0]/' $word ': _message -e times "time (ms)"' + \| $'/(ecn|noecn)[ \t\0]/' ':options:option:$ca -F line target interval ecn noecn' \) \# + '/[]/' + \| $'/pie[ \t\0]/' + \( $'/(target|tupdate|max_burst)[ \t\0]/' $word ': _message -e times "time"' + \| $'/(alpha|beta)[ \t\0]/' $word ': _message -e weights weight' + \| $'/max_ecnth[ \t\0]/' $word ': _message -e probabilities probability' + \| $word ':options:option:$ca -F line alpha beta max_burst max_ecnth {,no}{ecn,capdrop,drand} onoff dre ts' \) \# + '/[]/' + \| // '-[[ $pqs = pipe ]]' $'/noerror[ \t\0]/' ':options:option:$ca -F line bw delay burst profile buckets mask noerror plr queue red gred codel pie' + \| // '-[[ $pqs = queue ]]' $'/noerror[ \t\0]/' ':options:option:$ca -F line pipe weight buckets mask noerror plr queue red gred codel pie' + \| // '-[[ $pqs = sched ]]' $'/[]/' ':options:option:$ca -F line type bw delay burst profile' + \) \# +) + actions=( $'/[^\0]##\0(-[a-zA-Z0-9]##[ \t]#)#/' # skip over options, completed by _arguments but can \( # be quoted in one argument which that doesn't handle @@ -241,48 +281,14 @@ actions=( \| $'/redirect_proto[ \t\0]/' $word ':protocols:protocol:$ca sctp tcp udp' $word ': _message -e ip-addresses "IP address"' $word ': _message -e ip-addresses "IP address"' - \| $word ':parameters:config parameter:$ca ip if log deny_in same_ports unreg_only unreg_cgn reset reverse proxy_only skip_global redirect_port redirect_addr redirect_proto' + \| $'/port_range[ \t\0]/' + '/[0-9]#-/' ': _message -e ports lower' + $word ': _message -e ports upper' + \| $word ':parameters:config parameter:$ca ip if log deny_in same_ports unreg_only unreg_cgn reset reverse proxy_only skip_global redirect_port redirect_addr redirect_proto port_range' \) \# \| $'/show[ \t\0]/' $word ':actions:action:(config log)' \| '/[]/' ':commands:command:$ca config show' \) - \| # dummynet configuration - $'/(pipe|queue|sched)[ \t\0]/' -'pqs=${match%?}' ':dummynet-commands:dummynet configuration:$ca pipe queue sched' - $word ': _message -e numbers number' - $word ':options:config:$ca config' - \( $'/bw[ \t\0]/' - \( $word ':bandwidths: :_numbers -M "m:{a-z}={A-Z}" bandwidth {K,M,G}{bit,Byte}/s' - \| $word ':devices:device:_net_interfaces -qS " "' \) - \| $'/delay[ \t\0]/' $word ': _message -e numbers "propagation delay (ms)"' - \| $'/burst[ \t\0]/' $word ': _message -e numbers "size (bytes)"' - \| $'/profile[ \t\0]/' $word ':files:file:_files -qS " "' - \| $'/pipe[ \t\0]/' $word ': _message -e pipes pipe' - \| $'/weight[ \t\0]/' $word ': _message -e weights "weight (1-100) [1]"' - \| $'/type[ \t\0]/-' - \( $'/fq_(pie|codel)[ \t\0]/' - \( $'/limit[ \t\0]/' $word ': _message -e numbers "limit (packets) [10240]"' - \| $'/flows[ \t\0]/' $word ': _message -e numbers "flow queues [1024]"' - \| $'/quantum[ \t\0]/' ':parameters:parameter:$ca -F line quantum limit flows' \) \# - '/[]/' - \| $word ':types:scheduling algorithm:$ca fifo wf2q+ rr qfq fq_codel fq_pie fq_codel' \) - \| $'/buckets[ \t\0]/' $word ': _message -e sizes "hash table size (16-65536)"' - \| $'/mask[ \t\0]/' $word ':mask-specifiers:mask specifier:$ca dst-ip dst-ip6 src-ip src-ip6 dst-port src-port flow-id proto all' - \| $'/plr[ \t\0]/' $word ': _message -e numbers "packet loss rate (0.0-1.0)"' - \| $'/queue[ \t\0]/' $word ': _message -e sizes "queue size"' - \| $'/(red|gred)[ \t\0]/' $word ': _message -e thresholds thresholds' - \| $'/codel[ \t\0]/' - \( $'/(target|interval)[ \t\0]/' $word ': _message -e times "time (ms)"' - \| $'/(ecn|noecn)[ \t\0]/' ':options:option:$ca -F line target interval ecn noecn' \) \# - '/[]/' - \| $'/pie[ \t\0]/' - \( $'/(target|tupdate|max_burst)[ \t\0]/' $word ': _message -e times "time"' - \| $'/(alpha|beta)[ \t\0]/' $word ': _message -e weights weight' - \| $'/max_ecnth[ \t\0]/' $word ': _message -e probabilities probability' - \| $word ':options:option:$ca -F line alpha beta max_burst max_ecnth {,no}{ecn,capdrop,drand} onoff dre ts' \) \# - '/[]/' - \| // '-[[ $pqs = pipe ]]' $'/noerror[ \t\0]/' ':options:option:$ca -F line bw delay burst profile buckets mask noerror plr queue red gred codel pie' - \| // '-[[ $pqs = queue ]]' $'/noerror[ \t\0]/' ':options:option:$ca -F line pipe weight buckets mask noerror plr queue red gred codel pie' - \| // '-[[ $pqs = sched ]]' $'/[]/' ':options:option:$ca -F line type bw delay burst profile' - \) \# + \| $dummynet \| # sysctl shortcuts $'/(en|dis)able[ \t\0]/' ':sysctl-shortcuts:sysctl shortcut:$ca enable disable' $word ':values:value:(firewall altq one_pass debug verbose dyn_keepalive)' @@ -292,11 +298,36 @@ actions=( \) ) -if (( $words[(I)-p*] )); then - pathname=( ':path:_files -P / -W /' ) -fi +case $service in + ipfw) + _regex_arguments _ipfw_actions "$actions[@]" + args=( + '!-e' # nop for compatibility + '(-p)-a[show counter values when listing rules (implied by show)]' + '(-p)-b[show only the action and the comment]' + '-c[show rules in compact form]' + '(-p)-d[show dynamic rules in addition to static ones]' + '(-p)-D[act on dynamic states only]' + '-f[run without confirmation]' + '(-p)-i[format values as IP addresses in table listings]' + '-N[resolve addresses and service names in output]' + '-q[quiet output]' + '-S[show the set each rule belongs to]' + '(-p -T)-t[show timestamp of last match, ctime() format]' + '(-p -t)-T[show timestamp of last match as seconds since epoch]' + '(-a -b -d -D -i -s -t -T *)-p+[specify preprocessor]:preprocessor:_command_names -e' + ) + if (( $words[(I)-p*] )); then + args+=( ':path:_files -P / -W /' ) + fi + ;; + dnctl) + _regex_arguments _ipfw_actions \ + $'/[^\0]##\0(-[a-zA-Z0-9]##[ \t]#)#/' \ + "$dummynet[@]" + ;; +esac -_regex_arguments _ipfw_actions "$actions[@]" if [[ -prefix *[$' \t']* ]]; then # This allows from things like ipfw "-n add..." @@ -304,22 +335,10 @@ if [[ -prefix *[$' \t']* ]]; then return fi -_arguments -s $pathname \ - '(-p)-a[show counter values when listing rules (implied by show)]' \ - '(-p)-b[show only the action and the comment]' \ - '-c[show rules in compact form]' \ - '(-p)-d[show dynamic rules in addition to static ones]' \ - '(-p)-D[act on dynamic states only]' \ - '-f[run without confirmation]' \ +_arguments -s $args \ '(- *)-h[display syntax summary]' \ - '(-p)-i[format values as IP addresses in table listings]' \ '-n[only check syntax, make no changes]' \ - '-N[resolve addresses and service names in output]' \ - '-q[quiet output]' \ - '-S[show the set each rule belongs to]' \ '(-p)-s+[sort pipes by field]:field (negative reverses):((0\:unsorted 1\:packets 2\:bytes 3\:total\ packets 4\:total\ bytes))' \ - '(-p -T)-t[show timestamp of last match, ctime() format]' \ - '(-p -t)-T[show timestamp of last match as seconds since epoch]' \ - '(-a -b -d -D -i -s -t -T *)-p+[specify preprocessor]:preprocessor:_command_names -e' \ + '-v[verbose]' \ '*:::actions:= _ipfw_actions' diff --git a/Completion/BSD/Command/_pfctl b/Completion/BSD/Command/_pfctl index 812e52bdb..8063eb504 100644 --- a/Completion/BSD/Command/_pfctl +++ b/Completion/BSD/Command/_pfctl @@ -91,7 +91,10 @@ case $OSTYPE in ) ;| freebsd*) - args+=( '-P[display ports numerically]' ) + args+=( + '-M[kill matching states in the opposite direction]' + '-P[display ports numerically]' + ) ;; esac diff --git a/Completion/BSD/Command/_sockstat b/Completion/BSD/Command/_sockstat index 1d7973db7..f372fe1b3 100644 --- a/Completion/BSD/Command/_sockstat +++ b/Completion/BSD/Command/_sockstat @@ -21,6 +21,14 @@ case $OSTYPE in '-w[use wider field size for displaying addresses]' ) ;| + freebsd<13->.*) + args+=( + '-C[display the congestion control module]' + '-i[display the inp_gencnt]' + "-n[don't resolve numeric UIDs to user names]" + '-q[quiet mode, do not print the header line]' + ) + ;| freebsd*) for proto in ${${(M)${(f)"$(.*|openbsd*) + args+=( '-z+[specify timezone for output]:time zone:_time_zone') ;| netbsd*) args+=( '-d[output date specified by string]:time string:' ) diff --git a/Completion/Unix/Command/_elfdump b/Completion/Unix/Command/_elfdump index 065f4b97f..b3cc77695 100644 --- a/Completion/Unix/Command/_elfdump +++ b/Completion/Unix/Command/_elfdump @@ -34,10 +34,15 @@ case $OSTYPE in '-l[show long section names without truncation]' '-O[specify osabi to apply]:osabi' '-P[use alternative section header]' - "*:elf file:_object_files" ) ;; - freebsd*) args+=( '-a[dump all information]' ) ;; + freebsd*) + args+=( + '-a[dump all information]' + '(-)-E[return success if file is an ELF file and failure if not]' + ) + ;; esac -_arguments -s $args +_arguments -s $args \ + "*:elf file:_object_files" diff --git a/Completion/Unix/Command/_gcore b/Completion/Unix/Command/_gcore index a31a81267..ef3afd919 100644 --- a/Completion/Unix/Command/_gcore +++ b/Completion/Unix/Command/_gcore @@ -46,6 +46,7 @@ case $OSTYPE in _arguments -s \ '-c+[write core file to specified file]:file:_files' \ '-f[dump all available segments]' \ + '-k[use the ptrace(2) PT_COREDUMP kernel facility to write the core dump]' \ '::executable:' \ ':pid:_pids' ;; diff --git a/Completion/Unix/Command/_ifconfig b/Completion/Unix/Command/_ifconfig index 25ddd55bd..4e1f25e2e 100644 --- a/Completion/Unix/Command/_ifconfig +++ b/Completion/Unix/Command/_ifconfig @@ -20,10 +20,20 @@ case $OSTYPE in ) ;; freebsd*|dragonfly*) - args=( -s $updown - '(-a -l -u -d -m -L 1 *)-C[list interface cloners]' + args=( -s $updownlist + '(-a -j -f -l -G -g -u -d -m -L 1 *)-C[list interface cloners]' + '(-C)-f+[control the output format]: :_values -s, -S\: format + "addr[adjust inet address display]\:format [numeric]\:(default fqdn host numeric)" + "ether[adjust ethernet address display]\:format [colon]\:(colon dash dotted default)" + "inet[adjust inet subnet mask display]\:format [hex]\:(default cidr dotted hex)" + "inet6[adjust inet6 prefix display]\:format [numeric]\:(default cidr numeric)"' + '(-C)-G+[exclude members of the specified group]:group' + '(-C)-g+[limit output to members of the specified group]:group' + '(-C)-k[print keying information for the interface]' '(-l -C)-m[list supported media]' + '(-C)-n[disable automatic loading of network interface drivers]' '(-l -C)-L[show address lifetime as time offset]' + '(-C)-v[get more verbose status for an interface]' ) listopts=( active caps chan countries mac mesh regdomain roam txparam txpower @@ -37,6 +47,9 @@ case $OSTYPE in roam roam:rssi roam:rate roaming ) ;| + freebsd<14->.*) + args+=( '(-C)-j+[perform actions inside jail]:jail:_jails' ) + ;; dragonfly*) args+=( '-n[disable auto-loading of kernel network interface driver]' ) ;; diff --git a/Completion/Unix/Command/_iostat b/Completion/Unix/Command/_iostat index 1152b0d8b..d3943fcb4 100644 --- a/Completion/Unix/Command/_iostat +++ b/Completion/Unix/Command/_iostat @@ -34,7 +34,6 @@ case $OSTYPE:l in args+=( '-x[show extended disk statistics]' '-z[omit lines for devices with no activity]' - '(* -)-?[display a usage statement and exit]' ) ;; dragonfly*) @@ -126,6 +125,7 @@ case $OSTYPE:l in parser=( -s ) args=( '-c[display CPU utilization report]' + "--compact[don't break into sub-reports keeping metrics to a single line]" '-d[display device utilization report]' '--dec=-[specify the number of decimal places to use]:decimal places [2]:(0 1 2)' '-f[specify alternative directory to read device statistics from]:directory:_directories' diff --git a/Completion/Unix/Command/_ldd b/Completion/Unix/Command/_ldd index 3c7b088df..98ac41e14 100644 --- a/Completion/Unix/Command/_ldd +++ b/Completion/Unix/Command/_ldd @@ -30,8 +30,7 @@ else freebsd*) args=( '-a[show all objects that are needed by each loaded object]' - '-v[verbose listing of the dynamic linking headers]' - '-f+[specify format]:format:((%a\:program\ name %A\:environment\ name %o\:library\ name %p\:path\ to\ library %x\:load\ address))' + '*-f+[specify format]:format:((%a\:program\ name %A\:environment\ name %o\:library\ name %p\:path\ to\ library %x\:load\ address))' ) ;; esac diff --git a/Completion/Unix/Command/_ls b/Completion/Unix/Command/_ls index df14e7e2c..975a28196 100644 --- a/Completion/Unix/Command/_ls +++ b/Completion/Unix/Command/_ls @@ -96,6 +96,7 @@ if ! _pick_variant gnu=gnu unix --help; then if [[ $OSTYPE = freebsd* ]]; then arguments+=( '-,[print file sizes grouped and separated by thousands]' + '(-S -f -t -U)-v[sort by version (filename treated numerically)]' '-y[with -t, sort filenames in the same order as the time]' '-Z[display MAC label]' '--color=-[control use of color]:color:(never always auto)' @@ -163,12 +164,12 @@ else '(-a --all -U -l --format -s --size -t --sort --full-time)-f[unsorted, all, short list]' '(--reverse -r -U -f)'{--reverse,-r}'[reverse sort order]' - '(--sort -t -U -v -X)-S[sort by size]' - '(--sort -S -U -v -X)-t[sort by modification time]' - '(--sort -S -t -v -X)-U[unsorted]' - '(--sort -S -t -U -X)-v[sort by version (filename treated numerically)]' - '(--sort -S -t -U -v)-X[sort by extension]' - '(-S -t -U -v -X)--sort=[specify sort key]:sort key:(size time none version extension)' + '(--sort -f -t -U -v -X)-S[sort by size]' + '(--sort -f -S -U -v -X)-t[sort by modification time]' + '(--sort -f -S -t -v -X)-U[unsorted]' + '(--sort -f -S -t -U -X)-v[sort by version (filename treated numerically)]' + '(--sort -f -S -t -U -v)-X[sort by extension]' + '(-S -f -t -U -v -X)--sort=[specify sort key]:sort key:(size time none version extension)' '--color=-[control use of color]:color:(never always auto)' "*--hide=[like -I, but overridden by -a or -A]:pattern: " diff --git a/Completion/Unix/Command/_mktemp b/Completion/Unix/Command/_mktemp index 03fc89e36..0f66d744e 100644 --- a/Completion/Unix/Command/_mktemp +++ b/Completion/Unix/Command/_mktemp @@ -1,43 +1,45 @@ #compdef mktemp gmktemp local variant -local args +local -a args -_pick_variant -r variant busybox=BusyBox gnu='Free Soft' unix --version +_pick_variant -r variant busybox=BusyBox gnu='Free Soft' $OSTYPE --version args=( '(-d --directory)'{-d,--directory}'[make directory instead of file]' - '(: -)--help[display help information]' - '(-p --tmpdir)'{-p+,--tmpdir=}'[make relative to specified directory]: :_directories' '(-q --quiet)'{-q,--quiet}'[suppress error messages]' - '--suffix=[append specified suffix to template]:template suffix' - '-t[interpret template as single path component relative to temp dir]' '(-u --dry-run)'{-u,--dry-run}'[print file name only]' - '(: -)'{-V,--version}'[display version information]' - '1: :_guard "^-*" "template name"' ) -# Non-GNU variants don't support long options (except BusyBox's --help) -if [[ $variant == *busybox* ]]; then # See also: _busybox - args=( ${args:#((#s)|*\))(\*|)--^help*} ) -elif [[ $variant != gnu ]]; then - args=( ${args:#((#s)|*\))(\*|)--*} ) -fi - -[[ $variant == gnu ]] || { - # BusyBox, OpenBSD, and Solaris have -p, but -t doesn't take an argument - if [[ $variant == *busybox* ]] || [[ $OSTYPE == (openbsd|solaris)* ]]; then - args=( ${args:#((#s)|*\))(\*|)-t*} ) - args+=( '-t[generate template relative to temp dir]' ) - # Dragonfly, FreeBSD, and Darwin take an argument to -t and support any number - # of template files. These OSes do not have -p and -V. - else - args=( ${args:#((#s)|*\))(1:*|(\*|)-[ptV]*)} ) +case $variant in + ^(dragonfly|darwin)*) + args+=( '(-p --tmpdir)'{-p+,--tmpdir=}'[make relative to specified directory]: :_directories' ) + ;| + gnu) + args+=( + '--suffix=[append specified suffix to template]:template suffix' + '(: -)'{-V,--version}'[display version information]' + ) + ;| + # Most variants don't support long options (except BusyBox's --help) + ^(gnu|freebsd*)) + args=( ${args:#((#s)|*\))(\*|)--*} ) + ;| + gnu|*busybox*) + args+=( '(: -)--help[display help information]' ) + ;| + (gnu|*busybox|openbsd|solaris)*) + args+=( + '-t[generate template relative to temp dir]' + '1: :_guard "^-*" "template name"' + ) + ;; + (dragonfly|netbsd|freebsd|darwin)*) args+=( '-t[generate template relative to temp dir using specified prefix]:template prefix' '*: :_guard "^-*" "template name"' ) - fi -} + ;; +esac _arguments -s -S : $args diff --git a/Completion/Unix/Command/_netstat b/Completion/Unix/Command/_netstat index 8016b2475..35d639f99 100644 --- a/Completion/Unix/Command/_netstat +++ b/Completion/Unix/Command/_netstat @@ -302,6 +302,9 @@ case $OSTYPE in memory+=( $Xopt) statistics+=( $Xopt ) pcb+=( $Mopts $popt ) ;; + freebsd<14->.*) + args+=( '-j+[run inside a jail]:jail:_jails' ) + ;& freebsd<13->.*) sockets+=( '-c[show TCP stack used for each session]' diff --git a/Completion/Unix/Command/_script b/Completion/Unix/Command/_script index f39cfe535..d38d56f2e 100644 --- a/Completion/Unix/Command/_script +++ b/Completion/Unix/Command/_script @@ -47,7 +47,7 @@ case $OSTYPE in '-q[be quiet: suppress display of starting and ending lines]' '(-a -r -k)-d[suppress sleeps when playing back a session]' '(-a -r -k -t)-p[play back a recorded session]' - '(-d -p)-r[record a session with input, output and timing data]' + '(-d -p -T)-r[record a session with input, output and timing data]' ) ;| netbsd*|openbsd*) @@ -60,7 +60,9 @@ case $OSTYPE in ;| freebsd*) args+=( + '-e[return exit status of the child process]' '-f[use filemon(4)]' + '(-a -r -k -t)-T[play back a recorded session, reporting only timestamps]: :_date_formats' ) ;| darwin*|dragonfly*|freebsd*) @@ -71,8 +73,6 @@ case $OSTYPE in '*:::arguments: _normal $service' ) ;| - darwin*|freebsd*) - ;| *) args+=( '(-p -d)-a[append output]' diff --git a/Completion/Unix/Command/_service b/Completion/Unix/Command/_service index 1216f57a8..28563429b 100644 --- a/Completion/Unix/Command/_service +++ b/Completion/Unix/Command/_service @@ -10,8 +10,11 @@ zstyle -T ":completion:${ctx}" tag-order && \ zstyle ":completion:${ctx}" tag-order init case $OSTYPE in + freebsd<14->.*) + args=( '-E+[set environment variable before executing the rc.d script]:variable:_parameters -g "*export*~*readonly*" -S=' ) + ;& freebsd<11->.*) - args=( '-j+[perform actions in specified jail]:jail:_jails' ) + args+=( '-j+[perform actions in specified jail]:jail:_jails' ) ;& freebsd*|dragonfly*) actions=( diff --git a/Completion/Unix/Command/_split b/Completion/Unix/Command/_split index c5ab0dc9b..5ecc1bb67 100644 --- a/Completion/Unix/Command/_split +++ b/Completion/Unix/Command/_split @@ -8,7 +8,7 @@ _pick_variant -r variant gnu=GNU $OSTYPE --version args=( '-a+[generate suffixes of specified length]:length [2]' \ - '(-l -p -n)-b+[put specified size in bytes in each output file]:size (bytes)' \ + '(-l -p -n)-b+[put specified size in bytes in each output file]: :_numbers -u bytes size k m g' \ '(-b -p -n)-l+[put specified number of lines/records in each output file]:lines' \ '1:file:_files' \ '2: :_guard "^-*" "prefix [x]"' @@ -19,8 +19,8 @@ case $variant in args=( -C '(H -a --suffix-length)'{-a+,--suffix-length=}'[generate suffixes of specified length]:length [2]' '(H)--additional-suffix=[append an additional suffix to file names]:suffix' - '(H -b --bytes -C --line-bytes -l --lines -n --number)'{-b+,--bytes=}'[put specified size in bytes in each output file]:size (bytes)' - '(H -b --bytes -C --line-bytes -l --lines -n --number)'{-C+,--line-bytes=}'[put whole lines/records up to size limit in each output file]:size (bytes)' + '(H -b --bytes -C --line-bytes -l --lines -n --number)'{-b+,--bytes=}'[put specified size in each output file]: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size {K,M,G,T,P,E,Z}{,B}' \ + '(H -b --bytes -C --line-bytes -l --lines -n --number)'{-C+,--line-bytes=}'[put whole lines/records up to size limit in each output file]: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size {K,M,G,T,P,E,Z}{,B}' '(H --numeric-suffixes -x --hex-suffixes)-d[use numeric suffixes starting at 0]' '(H -d -x --hex-suffixes)--numeric-suffixes=-[use numeric suffixes]::start value [0]' '(H -d --numeric-suffixes --hex-suffixes)-x[use hex suffixes starting at 0]' @@ -47,7 +47,12 @@ case $variant in '(-b -l -n)-p+[split the file whenever a line matches specified pattern]:pattern' ) ;| - freebsd*) args+=( '-d[use numeric suffixes]' ) ;; + freebsd*) + args+=( + '-d[use numeric suffixes]' + "-c[continue creating files and don't overwrite existing output files]" + ) + ;; esac _arguments -s -S $args && ret=0 diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index 0ba1f3775..dc3979a58 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -57,7 +57,7 @@ _ssh () { "-N[don't execute a remote command]" \ '-n[redirect stdin from /dev/null]' \ '-O+[control an active connection multiplexing master process]:multiplex control command:((check\:"check master process is running" exit\:"request the master to exit" forward\:"request forward without command execution" stop\:"request the master to stop accepting further multiplexing requests" cancel\:"cancel existing forwardings with -L and/or -R" proxy))' \ - '-P[use non privileged port]' \ + '-P+[specify a tag name that may be used to select configuration]:tag' \ '-p+[specify port on remote host]:port number on remote host' \ '(-v)*-q[quiet operation]' \ '*-R+[specify remote port forwarding]:remote port forwarding:->forward' \ diff --git a/Completion/Unix/Command/_sysctl b/Completion/Unix/Command/_sysctl index 0416ca05e..442953c4d 100644 --- a/Completion/Unix/Command/_sysctl +++ b/Completion/Unix/Command/_sysctl @@ -28,6 +28,12 @@ case $OSTYPE in '(- :)'{-V,--version}'[display version info and exit]' \ '*:sysctl variable:_files -W /proc/sys' ;; + freebsd<14->.*) + args+=( + '-F[print the format of the variable]' + '(-N)-l[show the length of variables along with their values]' + ) + ;| freebsd<11->.*) args+=( '-B[specify buffer size for reading]:buffer size' @@ -53,7 +59,7 @@ case $OSTYPE in '-d[print the description of the variable instead of its value]' \ '(-N -n)-e[separate name and value with =]' \ "-i[silently exit if variable doesn't exist]" \ - '(-n)-N[show only variable names]' \ + '(-n -l)-N[show only variable names]' \ '(-N)-n[show only variable values]' \ '(-x)-o[show opaques as well (values suppressed)]' \ '-q[suppress some warnings]' \ diff --git a/Completion/Unix/Type/_diff_options b/Completion/Unix/Type/_diff_options index 2646527df..45b777dfe 100644 --- a/Completion/Unix/Type/_diff_options +++ b/Completion/Unix/Type/_diff_options @@ -1,6 +1,6 @@ #autoload -local of ofwuc ouc oss ofwy ofwg ofwl cmd variant +local of ofwuc ouc oss ofwy ofwg ofwl cmd variant ign local -a args cmd="$1" @@ -26,6 +26,8 @@ _diff_palette() { } if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->.* ]]; then + (( $#words > 2 )) && ign='!' + # output formats of="-y --side-by-side -n --rcs -e -f --ed -q --brief -c -C --context -u -U \ --unified --old-group-format --new-group-format --changed-group-format \ @@ -61,23 +63,19 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12-> --unchanged-group-format" if [[ $variant = gnu ]]; then - (( $#words > 2 )) || args+=( - '(-v --version)'{-v,--version}'[display version information]' - '--help[display usage information]' - ) args+=( '(-H --speed-large-files)'{-H,--speed-large-files}'[assume large files and many small changes]' '(-E --ignore-tab-expansion)'{-E,--ignore-tab-expansion}'[ignore changes due to tab expansion]' '(-Z --ignore-trailing-space)'{-Z,--ignore-trailing-space}'[ignore white space at line end]' - "($ofwuc $oss -F --show-function-line)"{-F+,--show-function-line=}'[show the most recent line matching regex]:regex' "($ofwy $ouc)--left-column[output only left column of common lines]" "($ofwg $ouc $oss)--old-group-format=[set old group format]:old group format" "($ofwg $ouc $oss)--new-group-format=[set new group format]:new group format" "($ofwl $ouc $oss)--unchanged-line-format=[set unchanged line format]:unchanged line format" - '(--to-file)--from-file=[compare specified file to all operands]:from file:_files' \ - '(--from-file)--to-file=[compare all operands to specified file]:to file:_files' \ + '(--to-file)--from-file=[compare specified file to all operands]:from file:_files' + '(--from-file)--to-file=[compare all operands to specified file]:to file:_files' '--color=-[use colors in output]::when [auto]:(never always auto)' '--palette=[specify colors to use]:color:_diff_palette' + "${ign}(1 2)-v[display version information]" ) else args+=( '!--speed-large-files' ) @@ -99,6 +97,7 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12-> "($of $oss)-u[output a unified diff]" \ "($ofwuc $oss)*"{-L+,--label=}'[set label to use instead of file name and timestamp]:label' \ "($ofwuc $oss -p --show-c-function)"{-p,--show-c-function}'[show C function of each change]' \ + "($ofwuc $oss -F --show-function-line)"{-F+,--show-function-line=}'[show the most recent line matching regex]:regex' \ "($of $ouc $oss)"{-q,--brief}'[output only whether files differ]' \ "($of $ouc $oss -e --ed)"{--ed,-e}'[output an ed script]' \ "!($of $ouc $oss)--normal" \ @@ -127,6 +126,8 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12-> "($of $ouc)"{-y,--side-by-side}'[output in two columns]' \ "($ofwy $ouc)--suppress-common-lines[don't output common lines]" \ "($ofwy $ouc --width -W)"{--width=,-W+}'[set size of line]:number of characters per line' \ + "${ign}(1 2)--version[display version information]" \ + "${ign}(1 2)--help[display usage information]" \ "$@" else of='-c -e -f' -- cgit v1.2.3 From 70320635b4b50b1e84f70e17bf40f107d140bdcf Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 26 Sep 2023 23:08:54 +0200 Subject: 52189: ignore compadd -M if -U also specified as they don't make sense together This fixes df completion. --- ChangeLog | 4 ++++ Completion/Unix/Type/_umountable | 3 ++- Src/Zle/complete.c | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfc1a2841..a933a5186 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-10-10 Oliver Kiddle + * 52189: Completion/Unix/Type/_umountable, Src/Zle/complete.c: + ignore compadd -M if -U also specified as they don't make + sense together, this fixes df completion + * 52217: Completion/BSD/Command/_freebsd-update, Completion/BSD/Command/_ipfw, Completion/BSD/Command/_pfctl, Completion/BSD/Command/_sockstat, Completion/Unix/Command/_cmp, diff --git a/Completion/Unix/Type/_umountable b/Completion/Unix/Type/_umountable index 6e4988e2d..0111555b6 100644 --- a/Completion/Unix/Type/_umountable +++ b/Completion/Unix/Type/_umountable @@ -1,6 +1,6 @@ #autoload local tmp -local dev_tmp dpath_tmp mp_tmp mline +local -a dev_tmp dpath_tmp mp_tmp mline case "$OSTYPE" in linux*) @@ -15,6 +15,7 @@ irix*) ;; freebsd*|dragonfly*) /sbin/mount | while read mline; do + [[ $mline[(w)1] = map ]] && continue dev_tmp+=( $mline[(w)1] ) mp_tmp+=( $mline[(w)3] ) done diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index 96ad7b3f1..342611f1f 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -829,7 +829,9 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) ca_args: - if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) { + if (mstr && (dat.aflags & CAF_MATCH) && + (match = parse_cmatcher(name, mstr)) == pcm_err) + { zsfree(mstr); zfree(dat.dpar, dparsize); return 1; -- cgit v1.2.3 From 487fba3fb3b33fd9c5248744adc89153c7a00f26 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 15 Oct 2023 15:03:58 -0700 Subject: 52218: update notes since 5.9 release --- ChangeLog | 4 ++++ Etc/BUGS | 4 ++-- NEWS | 9 +++++++++ README | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a933a5186..ed0253bb5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-10-15 Bart Schaefer + + * 52218: Etc/BUGS, NEWS, README: notes since 5.9 release + 2023-10-10 Oliver Kiddle * 52189: Completion/Unix/Type/_umountable, Src/Zle/complete.c: diff --git a/Etc/BUGS b/Etc/BUGS index 1719946b1..e238c161c 100644 --- a/Etc/BUGS +++ b/Etc/BUGS @@ -46,12 +46,12 @@ related, probably obsolete, vared special case for $TERM set to "emacs". ------------------------------------------------------------------------ 47561: [PATCH v4] vcs_info: choose backend by basedir ------------------------------------------------------------------------ -48091: Bug in compdescribe with matcher 'b:-=+' +48091, 49276: Bug in compdescribe with matcher 'b:-=+' ------------------------------------------------------------------------ users/26071: Strange behavior about option completion of "git push --f" ------------------------------------------------------------------------ 50930: If a conditional expression appears in a current-shell construct (such as { sleep 20 && print $? }) which is then suspended with ^Z, the -return value of the left side of the expression is always 148 (SIGSTOP) +return value of the left side of the expression is always 148 (SIGTSTP) and thus the expression is likely to be incorrectly interpreted. ------------------------------------------------------------------------ diff --git a/NEWS b/NEWS index 0e726699f..80b668a6d 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,15 @@ consistent and better aligned with the POSIX-2017 specification of `set -e`. For details on what exactly changed, see the list of incompatibilities in the README file. +Support for named references and namespaces has been added, similar to +those features in ksh but with some notable differences. The `nameref` +builtin and some ksh-equivlent namespace names are available by loading +the zsh/ksh93 module. See the documentation of that module for more. + +Non-forking command substitutions with ${ ... } and ${| ... } are now +available, and the latter extended with ${|param| ... } to return the +result via assignment to the named param rather than always via $REPLY. + Changes since 5.8.1 ------------------- diff --git a/README b/README index cb6d380aa..250b1d26e 100644 --- a/README +++ b/README @@ -79,6 +79,42 @@ consistent and better aligned with the POSIX-2017 specification of f() { { false; echo "This is printed only since 5.10." } || true } if f; then true; fi +PCRE support is now PCRE2 by default. + +Parameter names may begin with a "." and follow a relaxed implementation +of ksh namespace syntax. Expansion of such parameters must use braces, +that is, in ${.param.name} form. Parameters so named are excluded from +`typeset` and `set` output unless explicitly listed in `typeset` arguments +or matched by a pattern with `typeset -m`. + +Interpretation of exclusion-patterns following alternation-patterns has +been rationalised. This means for example that `[[ ab = (|a*)~^(*b) ]]` +is true where prevously it was false. + +Improvements to handling of terminal colors and attributes in prompts +may change the behavior of some prompt sequences, most notably in +cases where `esq=${(%)...}` is used to capture an escape sequence. + +The `which` and `functions` commands output function definitions in a +format independent of the MULTI_FUNC_DEF option. + +Math context no longer interprets a leading underscore as part of a +numeric constant. + +Nul and characters greater than \x77 are correctly handled by `read -d`. + +Return values of `sysopen` from the zsh/system module have been updated +to be more similar to other commands in that module. + +The `watch' parameter and `log' command have moved to an autoloaded module. + +Tied parameters created with the zsh/db/gdbm module may not be re-tied +as locals in nested function scope. This prevents database corruption +when a function scope ends. + +Many Completion/ functions have been updated to recent versions of their +corresponding commands, so the results offered may have changed. + Incompatibilities between 5.8.1 and 5.9 --------------------------------------- -- cgit v1.2.3 From a709643b769178697173f4db9796b06bca460e26 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 15 Oct 2023 16:40:34 -0700 Subject: unposted (cf. 52219): fix typo --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 80b668a6d..4d4699f7e 100644 --- a/NEWS +++ b/NEWS @@ -20,7 +20,7 @@ incompatibilities in the README file. Support for named references and namespaces has been added, similar to those features in ksh but with some notable differences. The `nameref` -builtin and some ksh-equivlent namespace names are available by loading +builtin and some ksh-equivalent namespace names are available by loading the zsh/ksh93 module. See the documentation of that module for more. Non-forking command substitutions with ${ ... } and ${| ... } are now -- cgit v1.2.3 From c9da370470754fe4760a5c62671174fce4441931 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Tue, 15 Aug 2023 15:13:48 +0200 Subject: 52056: _sccs: don't handle subcommands in main namespace If someone using sccs wants to save typing, they can just do alias get="sccs get" anyway. --- ChangeLog | 5 +++++ Completion/Unix/Command/_sccs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ed0253bb5..5eb4876b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-10-16 Mikael Magnusson + + * 52056: Completion/Unix/Command/_sccs: _sccs: don't handle + subcommands in main namespace + 2023-10-15 Bart Schaefer * 52218: Etc/BUGS, NEWS, README: notes since 5.9 release diff --git a/Completion/Unix/Command/_sccs b/Completion/Unix/Command/_sccs index 4083fe54e..20222a5c1 100644 --- a/Completion/Unix/Command/_sccs +++ b/Completion/Unix/Command/_sccs @@ -1,4 +1,4 @@ -#compdef sccs admin cdc comb delta get help prs prt rmdel sact sccsdiff unget val what +#compdef sccs sccsdiff (( $+functions[_sccs_files] )) || _sccs_files() { -- cgit v1.2.3 From 6b34f3dc14d5caf7f4e3ef0a6416224edf905c48 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Tue, 28 Feb 2023 14:25:57 +0100 Subject: 51490: Use time_t for lastt which stores result of time(0) Coverity complained about this, and possibly some more people would in 15 years --- ChangeLog | 3 +++ Src/Zle/computil.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5eb4876b8..2774ca119 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ * 52056: Completion/Unix/Command/_sccs: _sccs: don't handle subcommands in main namespace + * 51490: Src/Zle/computil.c: Use time_t for lastt which stores + result of time(0) + 2023-10-15 Bart Schaefer * 52218: Etc/BUGS, NEWS, README: notes since 5.9 release diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 77ccdebf7..360667884 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -911,7 +911,7 @@ struct cadef { Caarg rest; /* the rest-argument */ char **defs; /* the original strings */ int ndefs; /* number of ... */ - int lastt; /* last time this was used */ + time_t lastt; /* last time this was used */ Caopt *single; /* array of single-letter options */ char *match; /* -M spec to use */ int argsactive; /* if normal arguments are still allowed */ @@ -2935,7 +2935,7 @@ struct cvdef { Cvval vals; /* value definitions */ char **defs; /* original strings */ int ndefs; /* number of ... */ - int lastt; /* last time used */ + time_t lastt; /* last time used */ int words; /* if to look at other words */ }; -- cgit v1.2.3 From 457ab9f9fe12a093dd41a6c96bff6db209471ecc Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Mon, 6 Jun 2022 12:43:57 +0200 Subject: 52222: Document bracketed-paste-url-magic --- ChangeLog | 2 ++ Doc/Zsh/contrib.yo | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2774ca119..323ae074d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ * 51490: Src/Zle/computil.c: Use time_t for lastt which stores result of time(0) + * 52222: Doc/Zsh/contrib.yo: Document bracketed-paste-url-magic + 2023-10-15 Bart Schaefer * 52218: Etc/BUGS, NEWS, README: notes since 5.9 release diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index ef11d77ad..f43ac2257 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -2448,6 +2448,33 @@ history is restricted, so cursor motions, etc., may not pass outside of the pasted content. Text assigned to tt(BUFFER) by the active widgets is copied back into tt(PASTED) before tt(paste-finish). ) +tindex(bracketed-paste-url-magic) +item(tt(bracketed-paste-url-magic))( +This widget is a simpler version of using tt(bracketed-paste-magic) +to enable tt(quote-url-magic). Rather than re-interpreting everything as +keystrokes, it simply handles quoting of pasted urls itself, and all other +text is handled like the default bracketed-paste widget. + +It limits the quoting to pastes that consist of a single url, but you +can also enable or disable quoting explicitly for a paste by setting +NUMERIC to 1 or 2 respectively (ie, by pressing alt-1 or alt-2 before +pasting). + +It is also possible to customize the list of schemas used to +decide if something is a url by setting the tt(schema) style in the +tt(:bracketed-paste-url-magic) context, for example: +ifzman() +example(zstyle :bracketed-paste-url-magic schema http:// myspecialschema:) + +The default list of schemas is tt(http:// https:// ftp:// ftps:// file:// \ + ssh:// sftp:// magnet:). + +The widget itself is installed in a similar way as +tt(bracketed-paste-magic) above, by +ifzman() +example(autoload -Uz bracketed-paste-url-magic +zle -N bracketed-paste bracketed-paste-url-magic) +) tindex(copy-earlier-word) item(tt(copy-earlier-word))( This widget works like a combination of tt(insert-last-word) and -- cgit v1.2.3 From 20739b5458d19b81afafb8b7ed96476562f69f0f Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 17 Oct 2023 09:35:27 -0700 Subject: Unposted (cf. 52221, 52227, 52228): typos and unnecessary inclusions --- README | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README b/README index 250b1d26e..692c3fefb 100644 --- a/README +++ b/README @@ -79,7 +79,7 @@ consistent and better aligned with the POSIX-2017 specification of f() { { false; echo "This is printed only since 5.10." } || true } if f; then true; fi -PCRE support is now PCRE2 by default. +PCRE support is now PCRE2. Parameter names may begin with a "." and follow a relaxed implementation of ksh namespace syntax. Expansion of such parameters must use braces, @@ -89,7 +89,7 @@ or matched by a pattern with `typeset -m`. Interpretation of exclusion-patterns following alternation-patterns has been rationalised. This means for example that `[[ ab = (|a*)~^(*b) ]]` -is true where prevously it was false. +is true where previously it was false. Improvements to handling of terminal colors and attributes in prompts may change the behavior of some prompt sequences, most notably in @@ -106,15 +106,10 @@ Nul and characters greater than \x77 are correctly handled by `read -d`. Return values of `sysopen` from the zsh/system module have been updated to be more similar to other commands in that module. -The `watch' parameter and `log' command have moved to an autoloaded module. - Tied parameters created with the zsh/db/gdbm module may not be re-tied as locals in nested function scope. This prevents database corruption when a function scope ends. -Many Completion/ functions have been updated to recent versions of their -corresponding commands, so the results offered may have changed. - Incompatibilities between 5.8.1 and 5.9 --------------------------------------- -- cgit v1.2.3 From 5fd8cccf54e8bda291b8f45ca9dacfa4205a1ced Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Fri, 13 Oct 2023 21:31:54 +0200 Subject: github #103: fix completion for zpool upgrade This is done by simply adding a missing backslash to the code. Fixes: 85bf9740a0 ("49668: update zfs completion") Signed-off-by: Christian Heusel --- ChangeLog | 5 +++++ Completion/Unix/Command/_zfs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 323ae074d..e37c0057c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-10-24 Matthew Martin + + * github #103: Christian Heusel: Completion/Unix/Command/_zfs: fix + completion for zpool upgrade + 2023-10-16 Mikael Magnusson * 52056: Completion/Unix/Command/_sccs: _sccs: don't handle diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index b1135bfa7..3265e1eb8 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -1269,7 +1269,7 @@ case $service:$words[1] in zpool:upgrade) _arguments -A "-*" -S \ - '(- *)-v[display ZFS versions and descriptions]' + '(- *)-v[display ZFS versions and descriptions]' \ "(-v)-V+[upgrade to given version]:version" \ '(-v *)-a[upgrade all pools]' \ '(-a -v)*:pool:_zfs_pool' -- cgit v1.2.3 From 0c15cc8712b5b3c83d52b1c27f416db80d3426aa Mon Sep 17 00:00:00 2001 From: ErrrorMaxx Date: Sat, 21 Oct 2023 09:05:52 +0300 Subject: github #104: fix small typo --- ChangeLog | 2 ++ Src/exec.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e37c0057c..c3d68a6a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ * github #103: Christian Heusel: Completion/Unix/Command/_zfs: fix completion for zpool upgrade + * github #104: ErrrorMaxx: Src/exec.c: fix small typo + 2023-10-16 Mikael Magnusson * 52056: Completion/Unix/Command/_sccs: _sccs: don't handle diff --git a/Src/exec.c b/Src/exec.c index 3a8b3e951..285d2c5ad 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2388,7 +2388,7 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag, /* fd will be over 10, don't touch mfds */ fd1 = movefd(fd2); if (fd1 == -1) { - zerr("cannot moved fd %d: %e", fd2, errno); + zerr("cannot move fd %d: %e", fd2, errno); return; } else { fdtable[fd1] = FDT_EXTERNAL; -- cgit v1.2.3 From 98a6892cb138a53dc4a265e29e60dbbd813f3d73 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 26 Oct 2023 08:27:18 -0700 Subject: 52244: Fix a batch of minor defects reported by Coverity. Coverity defects 1547831, 1547826 (remove unused function), 1521551, 1500752, 1500747, 1401549, 1372423, 1270645, 1255799, 1255792, 1255789, 1255787, 1255782, 1255750 --- ChangeLog | 9 +++++++++ Src/Modules/zutil.c | 6 +++--- Src/Zle/compcore.c | 5 +++-- Src/Zle/compresult.c | 12 ++++-------- Src/builtin.c | 4 +++- Src/glob.c | 3 ++- Src/hist.c | 15 ++++++++++----- Src/input.c | 12 ------------ Src/params.c | 5 ++--- Src/utils.c | 4 ++-- 10 files changed, 38 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index c3d68a6a2..ebfd2731f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2023-10-25 Bart Schaefer + + * 52244: Src/Modules/zutil.c, Src/Zle/compcore.c, + Src/Zle/compresult.c, Src/builtin.c, Src/glob.c, Src/hist.c, + Src/input.c, Src/params.c, Src/utils.c: Coverity defects 1547831, + 1547826 (remove unused function), 1521551, 1500752, 1500747, + 1401549, 1372423, 1270645, 1255799, 1255792, 1255789, 1255787, + 1255782, 1255750 + 2023-10-24 Matthew Martin * github #103: Christian Heusel: Completion/Unix/Command/_zfs: fix diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 8a7d0a4c5..8b863d5c8 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -1378,11 +1378,11 @@ rmatch(RParseResult *sm, char *subj, char *var1, char *var2, int comp) "zregexparse-guard"), !lastval))) { LinkNode aln; char **mend; - int len; + int len = 0; queue_signals(); - mend = getaparam("mend"); - len = atoi(mend[0]); + if ((mend = getaparam("mend"))) + len = atoi(mend[0]); unqueue_signals(); for (i = len; i; i--) diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 77fce66e8..9b87cad93 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -2249,8 +2249,9 @@ addmatches(Cadata dat, char **argv) llpl = strlen(lpre); llsl = strlen(lsuf); - if (llpl + (int)strlen(compqiprefix) + (int)strlen(lipre) != origlpre - || llsl + (int)strlen(compqisuffix) + (int)strlen(lisuf) != origlsuf) + /* This used to reference compqiprefix and compqisuffix, why? */ + if (llpl + (int)strlen(qipre) + (int)strlen(lipre) != origlpre + || llsl + (int)strlen(qisuf) + (int)strlen(lisuf) != origlsuf) lenchanged = 1; /* Test if there is an existing -P prefix. */ diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c index 57789c0f3..cd8c7dd64 100644 --- a/Src/Zle/compresult.c +++ b/Src/Zle/compresult.c @@ -897,7 +897,7 @@ void do_allmatches(UNUSED(int end)) { int first = 1, nm = nmatches - 1, omc = menucmp, oma = menuacc, e; - Cmatch *mc; + Cmatch *mc = 0; struct menuinfo mi; char *p = (brbeg ? ztrdup(lastbrbeg->str) : NULL); @@ -915,10 +915,10 @@ do_allmatches(UNUSED(int end)) #endif } + if (minfo.group) + mc = (minfo.group)->matches; - mc = (minfo.group)->matches; - - while (1) { + while (mc) { if (!((*mc)->flags & CMF_ALL)) { if (!first) accept_last(); @@ -1731,8 +1731,6 @@ calclist(int showall) width < zterm_columns && nth < g->dcount; nth++, tcol++) { - m = *p; - if (tcol == tcols) { tcol = 0; tlines++; @@ -1994,7 +1992,6 @@ printlist(int over, CLPrintFunc printm, int showall) (listdat.onlyexpl & ((*e)->always > 0 ? 2 : 1)))) { if (pnl) { putc('\n', shout); - pnl = 0; ml++; if (cl >= 0 && --cl <= 1) { cl = -1; @@ -2087,7 +2084,6 @@ printlist(int over, CLPrintFunc printm, int showall) (showall || !(m->flags & (CMF_HIDE|CMF_NOLIST)))) { if (pnl) { putc('\n', shout); - pnl = 0; ml++; if (cl >= 0 && --cl <= 1) { cl = -1; diff --git a/Src/builtin.c b/Src/builtin.c index 31af66c7c..9e08a1dbc 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6508,6 +6508,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) if (OPT_ISSET(ops,'s') && SHTTY == readfd) { struct ttyinfo ti; + memset(&ti, 0, sizeof(struct ttyinfo)); gettyinfo(&ti); saveti = ti; resettty = 1; @@ -6606,7 +6607,8 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) else if (resettty && SHTTY != -1) settyinfo(&saveti); if (haso) { - fclose(shout); + if (shout) + fclose(shout); shout = oshout; SHTTY = -1; } diff --git a/Src/glob.c b/Src/glob.c index 63f8a5fa7..bd199ace3 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1317,7 +1317,8 @@ zglob(LinkList list, LinkNode np, int nountok) sense = 0; if (qualct) { qn = (struct qual *)hcalloc(sizeof *qn); - qo->or = qn; + if (qo) + qo->or = qn; qo = qn; qualorct++; qualct = 0; diff --git a/Src/hist.c b/Src/hist.c index bfbcd6ede..448dfddbc 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -1359,7 +1359,8 @@ putoldhistentryontop(short keep_going) do { if (max_unique_ct-- <= 0 || he == hist_ring) { max_unique_ct = 0; - he = hist_ring->down; + if (hist_ring) + he = hist_ring->down; next = hist_ring; break; } @@ -1367,12 +1368,16 @@ putoldhistentryontop(short keep_going) next = he->down; } while (!(he->node.flags & HIST_DUP)); } - if (he != hist_ring->down) { + /* Is it really possible for hist_ring to be NULL here? */ + if (he && (!hist_ring || he != hist_ring->down)) { he->up->down = he->down; he->down->up = he->up; he->up = hist_ring; - he->down = hist_ring->down; - hist_ring->down = he->down->up = he; + if (hist_ring) { + he->down = hist_ring->down; + hist_ring->down = he; + } + he->down->up = he; } hist_ring = he; } @@ -1468,7 +1473,7 @@ should_ignore_line(Eprog prog) mod_export int hend(Eprog prog) { - int flag, hookret, stack_pos = histsave_stack_pos; + int flag, hookret = 0, stack_pos = histsave_stack_pos; /* * save: * 0: don't save diff --git a/Src/input.c b/Src/input.c index dd8f2edc7..d8ac2c0e7 100644 --- a/Src/input.c +++ b/Src/input.c @@ -643,18 +643,6 @@ zstuff(char **out, const char *fn) return len; } -/**/ -char * -ztuff(const char *fn) -{ - char *buf; - off_t len = zstuff(&buf, fn); - if (len > 0) - return buf; - else - return NULL; -} - /* stuff a whole file into the input queue and print it */ /**/ diff --git a/Src/params.c b/Src/params.c index 957656e3f..9f0cbcd67 100644 --- a/Src/params.c +++ b/Src/params.c @@ -6326,10 +6326,9 @@ mod_export Param upscope(Param pm, int reflevel) { Param up = pm->old; - while (pm && up && up->level >= reflevel) { + while (up && up->level >= reflevel) { pm = up; - if (up) - up = up->old; + up = up->old; } return pm; } diff --git a/Src/utils.c b/Src/utils.c index 790625379..0f66984cd 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -7523,8 +7523,8 @@ restoredir(struct dirsav *d) else if (d->level < 0) err = -1; if (d->dev || d->ino) { - stat(".", &sbuf); - if (sbuf.st_ino != d->ino || sbuf.st_dev != d->dev) + if (stat(".", &sbuf) < 0 || + sbuf.st_ino != d->ino || sbuf.st_dev != d->dev) err = -2; } return err; -- cgit v1.2.3 From d86cc841f78086b03fc22d2971ff82cdb3904d4d Mon Sep 17 00:00:00 2001 From: Sebastian Gniazdowski Date: Thu, 26 Oct 2023 13:41:03 -0700 Subject: 52240: use work-var $s not $suffix when setting flags --- ChangeLog | 3 +++ Functions/MIME/zsh-mime-handler | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ebfd2731f..e67a33ea9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-10-25 Bart Schaefer + * Sebastian Gniazdowski: 52240: Functions/MIME/zsh-mime-handler: + use work-var $s not $suffix when setting flags + * 52244: Src/Modules/zutil.c, Src/Zle/compcore.c, Src/Zle/compresult.c, Src/builtin.c, Src/glob.c, Src/hist.c, Src/input.c, Src/params.c, Src/utils.c: Coverity defects 1547831, diff --git a/Functions/MIME/zsh-mime-handler b/Functions/MIME/zsh-mime-handler index 288a0796d..2feacf063 100644 --- a/Functions/MIME/zsh-mime-handler +++ b/Functions/MIME/zsh-mime-handler @@ -193,7 +193,7 @@ if ! zsh-mime-contexts -s $suffix flags flags; then # Same again for flags. s=$suffix while true; do - flags="${zsh_mime_flags[$suffix]}" + flags="${zsh_mime_flags[$s]}" if [[ -n $flags ]]; then break fi -- cgit v1.2.3 From f36fccbb84e5d36ebdecede0c29e8e0c588336c9 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 26 Oct 2023 20:55:45 -0700 Subject: 50569 (Daniel Shahaf): main keymap defaults to emacs Tweaked to make the sample .zshrc code better match the former C code, and to remove the declaration of no-longer-used variable "ed". --- ChangeLog | 2 ++ Src/Zle/zle_keymap.c | 12 +++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index e67a33ea9..c7fa8a1ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-10-25 Bart Schaefer + * Daniel Shahaf: 50569 (tweaked): main keymap defaults to emacs + * Sebastian Gniazdowski: 52240: Functions/MIME/zsh-mime-handler: use work-var $s not $suffix when setting flags diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index a31ab22d7..041682ee9 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1315,7 +1315,7 @@ default_bindings(void) Keymap vismap = newkeymap(NULL, "visual"); Keymap smap = newkeymap(NULL, ".safe"); Keymap vimaps[2], vilmaps[2], kptr; - char buf[3], *ed; + char buf[3]; int i; /* vi insert mode and emacs mode: * @@ -1445,20 +1445,14 @@ default_bindings(void) } /* Put the keymaps in the right namespace. The "main" keymap * - * will be linked to the "emacs" keymap, except that if VISUAL * - * or EDITOR contain the string "vi" then it will be linked to * - * the "viins" keymap. */ + * will be linked to the "emacs" keymap. */ linkkeymap(vmap, "viins", 0); linkkeymap(emap, "emacs", 0); linkkeymap(amap, "vicmd", 0); linkkeymap(oppmap, "viopp", 0); linkkeymap(vismap, "visual", 0); linkkeymap(smap, ".safe", 1); - if (((ed = zgetenv("VISUAL")) && strstr(ed, "vi")) || - ((ed = zgetenv("EDITOR")) && strstr(ed, "vi"))) - linkkeymap(vmap, "main", 0); - else - linkkeymap(emap, "main", 0); + linkkeymap(emap, "main", 0); /* the .safe map cannot be modified or deleted */ smap->flags |= KM_IMMUTABLE; -- cgit v1.2.3 From 97e43105637d92c20cdf0eb60577329af681d870 Mon Sep 17 00:00:00 2001 From: Ulysse Buonomo Date: Tue, 26 Sep 2023 11:59:55 -0500 Subject: github #102: Ensure todo.sh completion uses builtin commands the `todo.sh` script allows redefining commands locally, which can mess up this completion script. We are using the `command` subcommand to avoid that. --- ChangeLog | 5 +++++ Completion/Unix/Command/_todo.sh | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c7fa8a1ea..07d6e6a22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-10-29 Matthew Martin + + * github #102: Ulysse Buonomo: Completion/Unix/Command/_todo.sh: + Ensure todo.sh completion uses builtin commands + 2023-10-25 Bart Schaefer * Daniel Shahaf: 50569 (tweaked): main keymap defaults to emacs diff --git a/Completion/Unix/Command/_todo.sh b/Completion/Unix/Command/_todo.sh index 99b6bb695..e26bfc94f 100644 --- a/Completion/Unix/Command/_todo.sh +++ b/Completion/Unix/Command/_todo.sh @@ -97,7 +97,7 @@ case $state in ;; (replace) item=${words[CURRENT-1]##0##} - compadd -Q -- "${(qq)$(todo.sh -p list "^[ 0]*$item " | sed '/^--/,$d')##<-> (\([A-Z]\) |)}" + compadd -Q -- "${(qq)$(todo.sh -p command list "^[ 0]*$item " | sed '/^--/,$d')##<-> (\([A-Z]\) |)}" ;; esac fi @@ -144,7 +144,7 @@ case $nextstate in ;; (item) - itemlist=(${${(M)${(f)"$(todo.sh -p list | sed '/^--/,$d')"}##<-> *}/(#b)(<->) (*)/${match[1]}:${match[2]}}) + itemlist=(${${(M)${(f)"$(todo.sh -p command list | sed '/^--/,$d')"}##<-> *}/(#b)(<->) (*)/${match[1]}:${match[2]}}) _describe -t todo-items 'todo item' itemlist ;; @@ -173,6 +173,6 @@ case $nextstate in # the + or @ (which may not even be there yet). compset -P '*[[:space:]]' _wanted search expl $projmsg \ - compadd $(todo.sh lsprj) $(todo.sh lsc) + compadd $(todo.sh command listproj) $(todo.sh command listcon) ;; esac -- cgit v1.2.3 From 8ebbf25a71ec3e194616d2d10bef629efa266bee Mon Sep 17 00:00:00 2001 From: Shohei Yoshida Date: Sat, 23 Sep 2023 12:13:36 +0900 Subject: 52179: Fix gradlew completion when it isn't in PATH --- ChangeLog | 5 +++++ Completion/Unix/Command/_gradle | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 07d6e6a22..96d8cab8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-11-01 Oliver Kiddle + + * Shohei YOSHIDA: 52179: Completion/Unix/Command/_gradle: + Fix gradlew completion when it isn't in PATH + 2023-10-29 Matthew Martin * github #102: Ulysse Buonomo: Completion/Unix/Command/_todo.sh: diff --git a/Completion/Unix/Command/_gradle b/Completion/Unix/Command/_gradle index c1f7c05ee..280aa243f 100644 --- a/Completion/Unix/Command/_gradle +++ b/Completion/Unix/Command/_gradle @@ -92,7 +92,7 @@ if [[ $state == task && ! -prefix - ]]; then zle -R "Generating cache from $gradle_buildfile" # Run gradle/gradlew and retrieve possible tasks. - for outputline in ${(f)"$($service --build-file $gradle_buildfile -q tasks --all)"}; do + for outputline in ${(f)"$($words[1] --build-file $gradle_buildfile -q tasks --all)"}; do # Tasks and subprojects each start with a lowercase letter, but whereas tasks are in camelCase, each # subproject consists of one or more sections of kebab-case, with each section ending in a ':'. -- cgit v1.2.3 From 9f57ca4ac8ae071727b1d77cbb8c4c0d893b9099 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 1 Nov 2023 00:34:29 +0100 Subject: 52252: Coverity defect 1547827 --- ChangeLog | 2 ++ Src/Modules/pcre.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 96d8cab8a..10b7ab867 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-11-01 Oliver Kiddle + * 52252: Src/Modules/pcre.c: Coverity defect 1547827 + * Shohei YOSHIDA: 52179: Completion/Unix/Command/_gradle: Fix gradlew completion when it isn't in PATH diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index 96f3c6e65..f5cda6d38 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -187,7 +187,8 @@ zpcre_get_substrings(pcre2_code *pat, char *arg, pcre2_match_data *mdata, setaparam(substravar, matches); } - if (!pcre2_pattern_info(pat, PCRE2_INFO_NAMECOUNT, &ncount) && ncount + if (namedassoc + && !pcre2_pattern_info(pat, PCRE2_INFO_NAMECOUNT, &ncount) && ncount && !pcre2_pattern_info(pat, PCRE2_INFO_NAMEENTRYSIZE, &nsize) && !pcre2_pattern_info(pat, PCRE2_INFO_NAMETABLE, &ntable)) { -- cgit v1.2.3 From a9b0ccd661db7292a4ab52b3ffe6fbc8dc8ade4f Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 31 Oct 2023 19:48:20 +0100 Subject: 52260: handle variable assignments before the command in sudo completion --- ChangeLog | 5 ++++ Completion/Unix/Command/_sudo | 56 +++++++++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 10b7ab867..719222048 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-11-02 Oliver Kiddle + + * 52260: Completion/Unix/Command/_sudo: handle variable assignments + before the command in sudo completion + 2023-11-01 Oliver Kiddle * 52252: Src/Modules/pcre.c: Coverity defect 1547827 diff --git a/Completion/Unix/Command/_sudo b/Completion/Unix/Command/_sudo index 29e5e6d75..c334c6765 100644 --- a/Completion/Unix/Command/_sudo +++ b/Completion/Unix/Command/_sudo @@ -1,9 +1,7 @@ #compdef sudo sudoedit -setopt localoptions extended_glob - -local environ e cmd cpp -local -a args _comp_priv_prefix +local curcontext="$curcontext" environ e cmd cpp ret=1 +local -a context state line args _comp_priv_prefix local -A opt_args zstyle -a ":completion:${curcontext}:" environ environ @@ -20,20 +18,21 @@ args=( '(-g --group)'{-g+,--group=}'[run command as the specified group name or ID]:group:_groups' '(-)'{-h,--help}'[display help message and exit]' '(-h --host)'{-h+,--host=}'[run command on host]:host:_hosts' - '(-K --remove-timestamp)'{-K,--remove-timestamp}'[remove timestamp file completely]' - '(-k --reset-timestamp)'{-k,--reset-timestamp}'[invalidate timestamp file]' + '(-k --reset-timestamp -K --remove-timestamp -N --no-update)'{-K,--remove-timestamp}'[remove timestamp file completely]' + '(-k --reset-timestamp -K --remove-timestamp -N --no-update)'{-k,--reset-timestamp}'[invalidate timestamp file]' \*{-l,--list}"[list user's privileges or check a specific command]" '(-n --non-interactive)'{-n,--non-interactive}'[non-interactive mode, no prompts are used]' + '(-k --reset-timestamp -K --remove-timestamp -N --no-update)'{-N,--no-update}"[don't update user's cached credentials]" '(-p --prompt)'{-p+,--prompt=}'[use the specified password prompt]:prompt' '(-R --chroot)'{-R+,--chroot=}'[change the root directory before running command]:directory:_directories' '(-r --role)'{-r+,--role=}'[create SELinux security context with specified role]: :_selinux_roles' '(-S --stdin)'{-S,--stdin}'[read password from standard input]' '(-t --type)'{-t+,--type=}'[create SELinux security context with specified type]: :_selinux_types' '(-T --command-timeout)'{-T+,--command-timeout=}'[terminate command after specified time limit]:timeout' - '(-U --other-user)'{-U+,--other-user=}'[in list mode, display privileges for user]:user:_users' + '(-U --other-user -v --validate)'{-U+,--other-user=}'[in list mode, display privileges for user]:user:_users' '(-u --user)'{-u+,--user=}'[run command (or edit file) as specified user]:user:_users' '(-)'{-V,--version}'[display version information and exit]' - '(-v --validate)'{-v,--validate}"[update user's timestamp without running a command]" + '(-v --validate -U --other-user *)'{-v,--validate}"[update user's timestamp without running a command]" ) # Does -e appears before the first word that doesn't begin with a hyphen? @@ -45,10 +44,6 @@ if [[ $service = sudoedit ]] || (( $words[(i)-e] < $words[(i)^(*sudo|-[^-]*)] )) args=( -A "-*" $args '!(-V --version -h --help)-e' '*:file:_files' ) else cmd="$words[1]" - cpp='_comp_priv_prefix=( - $cmd -n - ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]} - )' args+=( '(-e --edit 1 *)'{-e,--edit}'[edit files instead of running a command]' \ '(-s --shell)'{-s,--shell}'[run shell as the target user; a command may also be specified]' \ @@ -58,9 +53,40 @@ else '(-E -i --login -s --shell -e --edit)--preserve-env=-[preserve user environment when running command]::environment variable:_sequence _parameters -g "*export*"' \ '(-H --set-home -i --login -s --shell -e --edit)'{-H,--set-home}"[set HOME variable to target user's home dir]" \ '(-P --preserve-groups -i -login -s --shell -e --edit)'{-P,--preserve-groups}"[preserve group vector instead of setting to target's]" \ - "(-)1: :{ $cpp; _command_names -e }" - "*:: :{ $cpp; _normal }" + '*:: :->normal' + ) +fi + +_arguments -s -S $args && ret=0 + +if [[ $state = normal ]]; then + _comp_priv_prefix=( + $cmd -n + ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]} ) + if (( $+opt_args[-l] || $+opt_args[--list] )); then + _normal -p $service + return + fi + while [[ $words[1] = *=* ]]; do + if (( CURRENT == 1 )); then + compstate[parameter]="${PREFIX%%\=*}" + compset -P 1 '*=' + _value && ret=0 + return ret + fi + shift words + (( CURRENT-- )) + done + if (( CURRENT == 1 )); then + curcontext="${curcontext%:*:*}:-command-:" + _alternative \ + 'commands:: _command_names -e' \ + 'options:option:(-s --shell -l --login)' \ + 'parameters: :_parameters -g "*export*~*readonly*" -qS=' && ret=0 + else + _normal + fi fi -_arguments -s -S $args +return ret -- cgit v1.2.3 From de635b4ee56c188ccbaf0009027f9d1c0d42af0f Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 31 Oct 2023 01:04:19 +0100 Subject: 52253: support pcre callouts with shell evaluation of the callout string --- ChangeLog | 3 +++ Doc/Zsh/mod_pcre.yo | 5 +++++ Src/Modules/pcre.c | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 719222048..3f1014db3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-11-02 Oliver Kiddle + * 52253: Src/Modules/pcre.c: support pcre callouts with shell + evaluation of the callout string + * 52260: Completion/Unix/Command/_sudo: handle variable assignments before the command in sudo completion diff --git a/Doc/Zsh/mod_pcre.yo b/Doc/Zsh/mod_pcre.yo index da73ac85a..41fab4475 100644 --- a/Doc/Zsh/mod_pcre.yo +++ b/Doc/Zsh/mod_pcre.yo @@ -69,6 +69,11 @@ print -l $accum) ) enditem() +If the regular expression contains callouts, these are executed as shell code. +During the execution of the callout, the string the regular expression is +matching against is available in the parameter tt(.pcre.subject). If there is a +non-zero return status from the shell code, the callout does not match. + The option tt(-d) uses the alternative breadth-first DFA search algorithm of pcre. This sets tt(match), or the array given with tt(-a), to all the matches found from the same start point in the subject. diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index f5cda6d38..e6b59831f 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -128,6 +128,31 @@ bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int f return 0; } +static int +pcre_callout(pcre2_callout_block_8 *block, void *) +{ + Eprog prog; + int ret=0; + + if (!block->callout_number && + ((prog = parse_string((char *) block->callout_string, 0)))) + { + int ef = errflag, lv = lastval; + + setsparam(".pcre.subject", + metafy((char *) block->subject, block->subject_length, META_DUP)); + setiparam(".pcre.pos", block->current_position + 1); + execode(prog, 1, 0, "pcre"); + ret = lastval | errflag; + + /* Restore any user interrupt error status */ + errflag = ef | (errflag & ERRFLAG_INT); + lastval = lv; + } + + return ret; +} + static int zpcre_get_substrings(pcre2_code *pat, char *arg, pcre2_match_data *mdata, int captured_count, char *matchvar, char *substravar, char *namedassoc, @@ -339,6 +364,9 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) plaintext = ztrdup(*args); unmetafy(plaintext, &subject_len); + pcre2_match_context_8 *mcontext = pcre2_match_context_create(NULL); + pcre2_set_callout(mcontext, &pcre_callout, 0); + if (offset_start > 0 && offset_start >= subject_len) ret = PCRE2_ERROR_NOMATCH; else if (use_dfa) { @@ -347,7 +375,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) pcre_mdata = pcre2_match_data_create(capcount, NULL); do { ret = pcre2_dfa_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len, - offset_start, 0, pcre_mdata, NULL, (int *) workspace, wscount); + offset_start, 0, pcre_mdata, mcontext, (int *) workspace, wscount); if (ret == PCRE2_ERROR_DFA_WSSIZE) { old = wscount; wscount += wscount / 2; @@ -362,7 +390,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) } else { pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pattern, NULL); ret = pcre2_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len, - offset_start, 0, pcre_mdata, NULL); + offset_start, 0, pcre_mdata, mcontext); } if (ret==0) return_value = 0; @@ -380,6 +408,8 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) if (pcre_mdata) pcre2_match_data_free(pcre_mdata); + if (mcontext) + pcre2_match_context_free(mcontext); zsfree(plaintext); return return_value; -- cgit v1.2.3 From 491e268e8b221918531d4b4b8ef254090b019c04 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 1 Nov 2023 22:59:48 +0100 Subject: 52265: update completions for some util-linux tools to version 2.39.2 --- ChangeLog | 4 ++++ Completion/Linux/Command/_findmnt | 3 +++ Completion/Linux/Command/_lsblk | 7 ++++++- Completion/Unix/Command/_column | 16 ++++++++++++++-- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f1014db3..ed7d8568c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-11-02 Oliver Kiddle + * 52265: Completion/Linux/Command/_findmnt, + Completion/Linux/Command/_lsblk, Completion/Unix/Command/_column: + update completions for some util-linux tools to version 2.39.2 + * 52253: Src/Modules/pcre.c: support pcre callouts with shell evaluation of the callout string diff --git a/Completion/Linux/Command/_findmnt b/Completion/Linux/Command/_findmnt index 0c832364d..b29372c39 100644 --- a/Completion/Linux/Command/_findmnt +++ b/Completion/Linux/Command/_findmnt @@ -26,6 +26,7 @@ _arguments -s -C \ '(H -o --output)--output-all[output all available columns]' \ '(H -p --poll)'{-p+,--poll=}'[monitor changes in /proc/self/mountinfo]::action:(mount umount remount move)' \ '(H --real)--pseudo[print only pseudo-filesystems]' \ + '(H)--shadowed[print only filesystems over-mounted by another filesystem]' \ '(H -R --submounts)'{-R,--submounts}'[print recursively all submounts]' \ '(H --pseudo)--real[print only real filesystems]' \ '(H -S --source :)'{-S+,--source=}'[specify the mount source]: :->sources' \ @@ -35,9 +36,11 @@ _arguments -s -C \ '(H -U --uniq)'{-U,--uniq}'[ignore filesystems with duplicated mount targets]' \ '(H -u --notruncate)'{-u,--notruncate}'[do not truncate text in columns]' \ '(H -v --nofsroot)'{-v,--nofsroot}'[do not print \[/dir\] in the SOURCE column]' \ + '(H -y --shell -n --noheadings)'{-y,--shell}'[use column names usable as shell variable identifiers]' \ '(H -w --timeout)'{-w+,--timeout}'[specify timeout for --poll]:milliseconds: ' \ '(H -x --verify)'{-x,--verify}'[check mount table content]' \ '(H)--verbose[print more information]' \ + '(H)--vfs-all[print all VFS options]' \ '(H)1: :->sources_targets' \ '(H)2:: :->targets' \ + '(format)' \ diff --git a/Completion/Linux/Command/_lsblk b/Completion/Linux/Command/_lsblk index 8a9bc18bf..63aac743c 100644 --- a/Completion/Linux/Command/_lsblk +++ b/Completion/Linux/Command/_lsblk @@ -6,16 +6,19 @@ local curcontext="$curcontext" state line expl typeset -A opt_args _arguments -C -s -S \ + '(H -A --noempty)'{-A,--noempty}"[don't print empty devices]" \ '(H -E --dedup)'{-E+,--dedup=}'[de-duplicate output by specified column]:column:->columns' \ '(H -a --all)'{-a,--all}'[print all devices]' \ '(H -b --bytes)'{-b,--bytes}'[print size in bytes rather than in human readable format]' \ '(H -d --nodeps)'{-d,--nodeps}"[don't print slaves or holders]" \ '(H -I --include)*'{-e,--exclude}'[exclude devices by major number]:major device number:->majorlist' \ '(H -e --exclude)*'{-I+,--include=}'[show only devices with specified major numbers]:major device number:->majorlist' \ - '(H -n --noheadings)'{-n,--noheadings}"[don't print headings]" \ + '(H -n --noheadings -y --shell)'{-n,--noheadings}"[don't print headings]" \ '(H -p --paths)'{-p,--paths}'[print complete device path]' \ '(H -s --inverse)'{-s,--inverse}'[reverse dependency order]' \ + '(H -w --width)'{-w+,--width=}'[specify output width]:width' \ '(H -x --sort)'{-x+,--sort=}'[sort output by specified column]:column:->columns' \ + '(H -y --shell -n --noheadings)'{-y,--shell}'[use column names usable as shell variable identifiers]' \ '(H)--sysroot=[use specified directory as system root]:directory:_directories' \ '*:device:_files -g "*(-%b)" -P / -W /' \ + fields \ @@ -24,6 +27,8 @@ _arguments -C -s -S \ '(H -f --fs -o --output -O --output-all)'{-f,--fs}'[output info about filesystems]' \ '(H -m --perms -o --output -O --output-all)'{-m,--perms}'[output info about permissions]' \ '(H -S --scsi -o --output -O --output-all)'{-S,--scsi}'[output info about SCSI devices]' \ + '(H -N --nvme -o --output -O --output-all)'{-N,--nvme}'[output info about NVMe devices]' \ + '(H -v --virtio -o --output -O --output-all)'{-v,--virtio}'[output info about virtio devices]' \ '(H -t --topology -o --output -O --output-all)'{-t,--topology}'[output info about topology]' \ '(H fields)'{-o+,--output=}'[specify output columns]:output column:->columnlist' \ '(H fields)'{-O,--output-all}'[output all columns]' \ diff --git a/Completion/Unix/Command/_column b/Completion/Unix/Command/_column index 94bdccf0a..687d7620f 100644 --- a/Completion/Unix/Command/_column +++ b/Completion/Unix/Command/_column @@ -22,7 +22,7 @@ case $variant in aopts=() args=( '(info json -c --output-width)'{-c+,--output-width=}'[format output to fit display of specified width]:width' - '(info)'{-L,--table-empty-lines}"[don't ignore empty lines]" + '(info)'{-L,--keep-empty-lines}"[don't ignore empty lines]" + fill '(info table text json -x --fillrows)'{-x,--fillrows}'[print across before down]' + table @@ -30,8 +30,20 @@ case $variant in '(info fill -o --output-separator)'{-o+,--output-separator=}'[specify column separator for table output]:separator [two spaces]' '(info fill -s --separator)'{-s+,--separator=}'[specify column delimiters in input data]:delimiters' '(info fill -O --table-order)'{-O+,--table-order=}'[specify order of output columns]: :->columns' - '(info fill -N --table-columns)'{-N+,--table-columns=}'[specify column names]:names' + '(info fill -N --table-columns)*'{-C+,--table-column=}'[specify column properties]: :_values -s, -S= property + "name[column name]\:name" + "trunc[truncate text in the columns when necessary]" + "right[right align text]" + "width[specify column width]\:width" + "strictwidth[strictly follow column width setting]" + "noextreme[allow length to be ignored]" + "wrap[wrap text when necessary]" + "hide[don'\''t print column]" + "json[define type for JSON output]\:type\:(string number boolean)"' + '(info fill -N --table-columns -C --table-column)'{-N+,--table-columns=}'[specify column names]:names' + '(info fill -l --table-columns-limit)'{-l+,--table-columns-limit=}'[specify maximum number of input columns]:columns' '(info fill -H --table-hide)'{-H+,--table-hide=}"[don't print specified columns]: :->columns" + '(info fill -m --table-maxout)'{-m,--table-maxout}'[fill all available space]' + text '(info fill json -d --table-noheadings)'{-d,--table-noheadings}"[don't print header]" '(info fill json -E --table-noextreme)'{-E+,--table-noextreme}"[specify columns where length can be ignored]: :->columns" -- cgit v1.2.3 From 8e65233747ac8cd125f54931d951036a9af13995 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 1 Nov 2023 23:44:45 +0100 Subject: 52266: update completion for strace to 2.6.5 --- Completion/Linux/Command/_strace | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Completion/Linux/Command/_strace b/Completion/Linux/Command/_strace index b3b6f5096..b1c7e1c8f 100644 --- a/Completion/Linux/Command/_strace +++ b/Completion/Linux/Command/_strace @@ -11,6 +11,7 @@ _arguments -C -s \ \*{-E+,--env=}'[set or remove exported environment variable]:variable:->envars' \ '(:)*'{-p+,--attach=}'[attach to the process with specified process ID and begin tracing]:process ID:_pids' \ "${root}(-u --user)"{-u+,--user=}'[run as specified user]:user:_users' \ + '--argv0=[set argv0 for program]:name' \ '(-b --detach-on)'{-b+,--detach-on=}'[detach from process on specified syscall]:syscall:(execve)' \ '(--daemonize)-D[run tracer as detached grandchild, keeping traced process as direct child of calling process]' \ '(-D)--daemonize=-[specify how to run tracer process]::method:(grandchild pgroup session)' \ @@ -45,11 +46,14 @@ _arguments -C -s \ '(-v --no-abbrev)'{-v,--no-abbrev}'[print unabbreviated versions of environment, stat, termios, etc. calls]' \ '(-xx --strings-in-hex)-x[print all non-ASCII strings in hexadecimal string format]' \ '(-x --strings-in-hex)-xx[print all strings in hexadecimal string format]' \ - '(-x -xx)--strings-in-hex=[specify strings to print in hexadecimal format]:string type:(all non-ascii)' \ + '(-x -xx)--strings-in-hex=[specify strings to print in hexadecimal format]:string type:(all non-ascii non-ascii-chars)' \ '(-X --const-print-style)'{-X+,--const-print-style=}'[set the format for printing of named constants and flags]:format:(raw abbrev verbose)' \ '(-c --summary-only -yy --decode-fds)-y[print paths associated with file descriptor arguments]' \ '(-c --summary-only -y --decode-fds)-yy[print protocol specific information associated with socket file descriptors]' \ - '(-c --summary-only -y -yy)--decode-fds=-[print information associated with file descriptors]::information [none]:_sequence compadd - none all path socket dev pidfd' \ + '(-c --summary-only -y -yy)--decode-fds=-[print information associated with file descriptors]::information [none]:_sequence compadd - none all path socket dev pidfd signalfd' \ + '(-c --summary-only -Y)--decode-pids=[print information associated with process IDs]:information [none]:_sequence compadd - none comm pidns' \ + '!(-c --summary-only -Y --decode-pids)--pidns-translation' \ + '(-c --summary-only --decode-pids)-Y[print command names for PIDs]' \ '(-c --summary-only -C --summary -i --instruction-pointer -k --stack-traces -r --relative-timestamps -ff -t -tt -ttt --absolute-timestamps -T --syscall-times -y -yy --decode-fds)'{-c,--summary-only}'[count time, calls, and errors for each system call and report a summary]' \ '(-c --summary-only -C --summary)'{-C,--summary}'[count time, calls, and errors for each system call and report a summary in addition to regular output]' \ '(-O --summary-syscall-overhead)'{-O+,--summary-syscall-overhead=}'[specify overhead for tracing system calls]:overhead (microseconds)' \ @@ -57,9 +61,11 @@ _arguments -C -s \ '(-U --summary-columns)'{-U+,--summary-columns=}'[show specific columns in the summary report]:column:_sequence compadd - time-percent total-time min-time max-time avg-time calls errors name' \ '(-w --summary-wall-clock)'{-w,--summary-wall-clock}'[summarise syscall latency]' \ '(-c --summary-only -C)-ff[write each process trace to . (when using -o ]' \ + '--syscall-limit=[detach all tracees after tracing given number of syscalls]:limit' \ '(-d --debug)'{-d,--debug}'[show debug output of strace itself on standard error]' \ '(- 1 *)'{-h,--help}'[display help information]' \ '--seccomp-bpf[enable seccomp-bpf filtering]' \ + '--tips=-[show strace tips, tricks, and tweaks before exit]:tip [id\:random,format\:compact]' \ '(- 1 *)'{-V,--version}'[display version information]' \ '(-):command name: _command_names -e' \ '*::arguments:_normal' && ret=0 @@ -72,6 +78,7 @@ case $state in 'verbose[dereference structures for the specified set of system calls]:system call:_sequence _sys_calls -a -n' \ 'raw[print raw, undecoded arguments for the specified set of system calls]:system call:_sequence _sys_calls -a -n' \ 'signal[trace only the specified subset of signals]:signal:_sequence _signals -s -M "B\:!="' \ + 'trace-fds[trace operations on listed file descriptors]:file descriptor:_sequence _file_descriptors' \ 'read[perform a full hex and ASCII dump of all the data read from listed file descriptors]:file descriptor:_sequence _file_descriptors' \ 'write[perform a full hex and ASCII dump of all the data written to listed file descriptors]:file descriptor:_sequence _file_descriptors' \ 'fault[perform syscall fault injection]:system call:_sys_calls -a -n' \ @@ -79,7 +86,8 @@ case $state in 'status[trace system calls with given return status]:status:->status' \ 'quiet[suppress various information messages]:message [none]:_sequence compadd - none attach exit path-resolution personality thread-execve superseded' \ 'kvm[print the exit reason of kvm vcpu]: :(vcpu)' \ - 'decode-fds[print information associated with file descriptors]:information [none]:_sequence compadd - none all path socket dev pidfd' && ret=0 + 'decode-fds[print information associated with file descriptors]:information [none]:_sequence compadd - none all path socket dev pidfd signalfd' \ + 'decode-pids[print information associated with process IDs]:information [none]:_sequence compadd - none comm pidns' && ret=0 if [[ $state = status ]]; then _values -s , 'return status [all]' \ all successful failed \ -- cgit v1.2.3 From 364ecf7099c3441be1e138a432617b64c207f519 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 2 Nov 2023 16:26:16 +0100 Subject: 52268: update nmcli completion to networkmanager 1.42.2 --- ChangeLog | 4 ++++ Completion/Linux/Command/_networkmanager | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ed7d8568c..23987d64c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-11-02 Oliver Kiddle + * 52268: Completion/Linux/Command/_networkmanager: update to 1.42.2 + + * 52266: Completion/Linux/Command/_strace: update to 2.6.5 + * 52265: Completion/Linux/Command/_findmnt, Completion/Linux/Command/_lsblk, Completion/Unix/Command/_column: update completions for some util-linux tools to version 2.39.2 diff --git a/Completion/Linux/Command/_networkmanager b/Completion/Linux/Command/_networkmanager index 1e05252b2..d44c313db 100644 --- a/Completion/Linux/Command/_networkmanager +++ b/Completion/Linux/Command/_networkmanager @@ -42,8 +42,24 @@ _nm_fields() { } _nm_general() { - _arguments "1:command:(status hostname permissions logging help)" - # TODO: provide completions for logging + local curcontext="$curcontext" state line + _arguments "1:command:(status hostname permissions logging reload help)" \ + "*::arguments:->args" + + case $line[1] in + l*) + _values -w -S ' ' values \ + 'level:level' \ + 'domains:domain' + ;; + r*) + _describe -t flags 'flag' '( + "conf:NetworkManager.conf configuration" + "dns-rc:update DNS configuration" + "dns-full:restart the DNS plugin" + )' + ;; + esac } _nm_networking() { -- cgit v1.2.3 From 03f52f1da6a41529982482442360c9378211b4ce Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 2 Nov 2023 23:27:53 -0700 Subject: 50569: missed file from commit f36fccbb --- README | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README b/README index 692c3fefb..8c11e6833 100644 --- a/README +++ b/README @@ -34,6 +34,24 @@ details, see the documentation. Incompatibilities since 5.9 --------------------------- +The line editor's default keymap is now the "emacs" keymap regardless of the +value of the environment variables $VISUAL and $EDITOR. This only affects you +if your $VISUAL or $EDITOR environment variable is set to a value that +contains the string "vi". To get the previous behaviour, add + + bindkey -v + +or, if your $VISUAL and $EDITOR environment variables vary, + + if [[ ${VISUAL} == *vi* || ${EDITOR} == *vi* ]]; then + bindkey -v + else + bindkey -e + fi + +to your .zshrc file. These snippets are compatible with previous +versions of the shell. + The ERR_EXIT and ERR_RETURN options were refined to be more self- consistent and better aligned with the POSIX-2017 specification of `set -e`: -- cgit v1.2.3 From 985cc5aae87b9c231a210d689c7c8511ed060869 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 3 Nov 2023 10:15:00 -0700 Subject: Unposted: List of files was omitted from 50569 log entry --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 23987d64c..6c36d838e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,7 +28,8 @@ 2023-10-25 Bart Schaefer - * Daniel Shahaf: 50569 (tweaked): main keymap defaults to emacs + * Daniel Shahaf: 50569 (tweaked): README, Src/Zle/zle_keymap.c: + main keymap defaults to emacs * Sebastian Gniazdowski: 52240: Functions/MIME/zsh-mime-handler: use work-var $s not $suffix when setting flags -- cgit v1.2.3 From bad8af1808e3809285fbb33a5a168f09247c4793 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 8 Nov 2023 02:32:23 +0100 Subject: 52271: use correct form for unused parameter --- ChangeLog | 4 ++++ Src/Modules/pcre.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6c36d838e..0997ef5c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-11-08 Oliver Kiddle + + * 52271: Src/Modules/pcre.c: use correct form for unused parameter + 2023-11-02 Oliver Kiddle * 52268: Completion/Linux/Command/_networkmanager: update to 1.42.2 diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index e6b59831f..e48ae3ae5 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -129,7 +129,7 @@ bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int f } static int -pcre_callout(pcre2_callout_block_8 *block, void *) +pcre_callout(pcre2_callout_block_8 *block, UNUSED(void *callout_data)) { Eprog prog; int ret=0; -- cgit v1.2.3 From 7cd5b7f1fc42e73ceadfeabc1f1e9dfa3151bf42 Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Wed, 20 Sep 2023 20:50:49 -0400 Subject: 52168: add completion for xfce's xfconf-query(1) --- ChangeLog | 3 +++ Completion/Unix/Command/_xfconf-query | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Completion/Unix/Command/_xfconf-query diff --git a/ChangeLog b/ChangeLog index 0997ef5c7..1802e4a41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-11-08 Oliver Kiddle + * Eric Cook: 52168: Completion/Unix/Command/_xfconf-query: + add completion for xfce's xfconf-query(1) + * 52271: Src/Modules/pcre.c: use correct form for unused parameter 2023-11-02 Oliver Kiddle diff --git a/Completion/Unix/Command/_xfconf-query b/Completion/Unix/Command/_xfconf-query new file mode 100644 index 000000000..fa535401f --- /dev/null +++ b/Completion/Unix/Command/_xfconf-query @@ -0,0 +1,33 @@ +#compdef xfconf-query +local curcontext="$curcontext" state state_descr line ret=1 +typeset -A opt_args + +_arguments -C -s -w : \ + '(-c --channel)'{-c,--channel}'[select channel to query/modify]:channel:( ${$(xfconf-query -l)\:#Channels\:} )' \ + '(-p --property)'{-p,--property}'[select property to query/modify]:property:->property' \ + '(-v --verbose)'{-v,--verbose}'[print property and value (with -l/-m)]' \ + '(-t --type)'{-t,--type}'[specify the property value type]:type:(empty string bool {,u}int{,16,64} double array {,u}char float)' \ + '(-R --recursive)'{-R,--recursive}'[recursively reset properties (with -r)]' \ + + '(operations)' \ + {-h,--help}'[show help options]' \ + {-V,--version}'[show version information]' \ + {-s,--set}'[define the value of a property]:value' \ + {-l,--list}'[list properties or channels]' \ + {-n,--create}'[create a new property]:new property name' \ + {-r,--reset}'[reset property]' \ + {-T,--toggle}'[invert boolean property]' \ + {-m,--monitor}'[monitor a channel for property changes]' && return + +case $state in + property) + # if -c/--channel is currently on the line, use it to complete an property. + if [[ -v opt_args[(i)-(c|-channel)] ]]; then + local expl + _wanted properties expl property compadd "$@" -- ${(f)"$(xfconf-query -c ${(v)opt_args[(i)-(c|-channel)]} -l)"} && ret=0 + else # just display a message + _message -e properties property && ret=0 + fi + ;; +esac + +return ret -- cgit v1.2.3 From 2573786fd3e81e080189fd5e39be14034cc55bd1 Mon Sep 17 00:00:00 2001 From: Shotaro Aoyama Date: Thu, 2 Nov 2023 01:38:40 +0900 Subject: github #105: add "-I" for "zle" completion --- ChangeLog | 3 +++ Completion/Zsh/Command/_zle | 1 + 2 files changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1802e4a41..0c51a3464 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-11-08 Oliver Kiddle + * github #105: Shotaro Aoyama: Completion/Zsh/Command/_zle: + add "-I" for "zle" completion + * Eric Cook: 52168: Completion/Unix/Command/_xfconf-query: add completion for xfce's xfconf-query(1) diff --git a/Completion/Zsh/Command/_zle b/Completion/Zsh/Command/_zle index 0b8ef7a15..97ec8c875 100644 --- a/Completion/Zsh/Command/_zle +++ b/Completion/Zsh/Command/_zle @@ -23,6 +23,7 @@ _arguments -s -S \ \(${(j. .)opts:#-[La]}')-l+[list user-defined widgets]:*:-:->listing' \ \(${(j. .)opts:#-l}')-a[with -l, list all widgets]' \ "(: * ${(j. .)opts:#-[Lw]})-F[install file descriptor handler]:file descriptor:_file_descriptors::handler:_functions" \ + "($opts)-I[invalidate the current zle display]" \ "!($opts)-K:keymap:compadd -a keymaps" \ "($opts)-M[display message]:message: " \ "($opts)-N[define new widget]:widget name:->widget-or-function ::widget shell function:->function" \ -- cgit v1.2.3 From d8a3bff4f5b4d3df42de8f03adc70f8d0721398f Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 9 Nov 2023 16:48:12 +0100 Subject: 52280: update git completion for new options in git through to version 2.42.0 --- ChangeLog | 5 + Completion/Unix/Command/_git | 331 +++++++++++++++++++++++++++++++------------ 2 files changed, 243 insertions(+), 93 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c51a3464..a3ce2e8d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-11-09 Oliver Kiddle + + * 52280: Completion/Unix/Command/_git: update git completion for new + options in git through to version 2.42.0 + 2023-11-08 Oliver Kiddle * github #105: Shotaro Aoyama: Completion/Zsh/Command/_zle: diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index cefc88c5a..7370aaead 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -123,7 +123,10 @@ _git-am () { $apply_options \ '--quit[abort the patching operation but keep HEAD where it is]' \ '--show-current-patch=-[show the message being applied]::show [raw]:(diff raw)' \ + '(--empty)--allow-empty[record the empty patch as an empty commit]' \ + '(--allow-empty)--empty=[select hanndling of empty patches]:handling:(stop drop keep)' \ '(-i --interactive)'{-i,--interactive}'[apply patches interactively]' \ + '(-n --no-verify)'{-n,--no-verify}'[bypass pre-applypatch and applypatch-msg hooks]' \ '--committer-date-is-author-date[use author date as committer date]' \ '--ignore-date[use committer date as author date]' \ '--skip[skip the current patch]' \ @@ -164,8 +167,10 @@ _git-archive () { '--format=-[format of the resulting archive]:archive format:__git_archive_formats' \ '(- :)'{-l,--list}'[list available archive formats]' \ '(-v --verbose)'{-v,--verbose}'[report progress to stderr]' \ + '--mtime=[set modification time of archive entries]:mtime' \ '--prefix=-[prepend the given path prefix to each filename]:path prefix:_directories -r ""' \ '--add-file=[add untracked file to archive]:file:_files' \ + '--add-virtual-file=[add untracked file to archive]:path:_files' \ '(-o --output)'{-o+,--output=}'[write archive to specified file]:archive:_files' \ '--worktree-attributes[look for attributes in .gitattributes in working directory too]' \ $backend_args \ @@ -333,7 +338,8 @@ _git-branch () { "(- :)--show-current[show current branch name]" \ "($l $m $d)--create-reflog[create the branch's reflog]" \ "($l $m $d -f --force)"{-f,--force}'[force the creation of a new branch]' \ - "($l $m $d -t --track)"{-t,--track}'[setup configuration so that pull merges from the start point]' \ + "($l $m $d --track)-t[setup configuration so that pull merges from the start point]" \ + "($l $m $d -t)--track=-[setup configuration so that pull merges from the start point]::upstream tracking:(direct inherit)" \ "($l $m $d)--no-track[override the branch.autosetupmerge configuration variable]" \ "($l $m $d -u --set-upstream --set-upstream-to --unset-upstream)"{-u+,--set-upstream-to=}'[set up configuration so that pull merges]:remote branch:__git_remote_branch_names' \ "($l $m $d -u --set-upstream --set-upstream-to --unset-upstream)--unset-upstream[remove upstream configuration]" \ @@ -345,6 +351,7 @@ _git-branch () { $dependent_creation_args \ "($l $c $d $m)"{-m,--move}"[rename a branch and the corresponding reflog]" \ "($l $c $d $m)-M[rename a branch even if the new branch-name already exists]" \ + "--omit-empty[don't output a newline after empty formatted refs]" \ "($l $c $d $m)"{-c,--copy}"[copy a branch and the corresponding reflog]" \ "($l $c $d $m)-C[copy a branch even if the new branch-name already exists]" \ $dependent_modification_args \ @@ -354,6 +361,7 @@ _git-branch () { '*--sort=[specify field to sort on]: :__git_ref_sort_keys' \ '--points-at=[only list tags of the given object]: :__git_commits' \ "($c $m $d -i --ignore-case)"{-i,--ignore-case}'[sorting and filtering are case-insensitive]' \ + "($l $m $d)--recurse-submodules[recurse through submodules]" \ $dependent_deletion_args } @@ -387,8 +395,7 @@ _git-bundle () { _arguments \ '(-q --quiet)'{-q,--quiet}"[don't show progress]" \ '--progress[show progress meter]' \ - '--all-progress[show progress meter during object writing phase]' \ - '--all-progress-implied[similar to --all-progress when progress meter is shown]' \ + \!--all-progress{,-implied} \ '--version=[specify bundle format version]:version:(2 3)' \ ':bundle:_files' && ret=0 else @@ -468,13 +475,14 @@ _git-checkout () { '(-q --quiet -2 --ours -3 --theirs --patch)'{-3,--theirs}'[check out stage #3 for unmerged paths]' \ '( -B --orphan -2 --ours -3 --theirs --conflict --patch -d --detach)-b+[create a new branch based at given commit]: :__git_branch_names' \ '(-b --orphan -2 --ours -3 --theirs --conflict --patch -d --detach)-B+[create or update branch based at given commit]: :__git_branch_names' \ - '(-t --track --orphan --patch -d --detach)'{-t,--track}'[set up configuration so pull merges from the base commit]' \ + '(--track --no-track --orphan --patch -d --detach)-t[set upstream info for new branch]' \ + '(-t --no-track --orphan --patch -d --detach)--track=-[set upstream info for new branch]::configuration:(direct inherit)' \ '(--patch)--no-track[override the branch.autosetupmerge configuration variable]' \ $new_branch_reflog_opt \ '(-b -B -t --track --patch --orphan -d --detach)'{-d,--detach}'[detach the HEAD at named commit]' \ '(-b -B -t --track --patch -d --detach)--orphan=[create a new orphan branch based at given commit]: :__git_branch_names' \ '(-q --quiet -f --force -m --merge --conflict --patch)'{-m,--merge}'[3way merge current branch, working tree and new branch]' \ - '(-q --quiet -f --force -m --merge --patch)--conflict=[same as --merge, using given merge style]:style:(merge diff3)' \ + '(-q --quiet -f --force -m --merge --patch)--conflict=[same as --merge, using given merge style]:style:(merge diff3 zdiff3)' \ '(-)'{-p,--patch}'[interactively select hunks in diff between given tree-ish and working tree]' \ "--ignore-skip-worktree-bits[don't limit pathspecs to sparse entries only]" \ "--no-guess[don't second guess 'git checkout ']" '!(--no-guess)--guess' \ @@ -533,10 +541,7 @@ _git-cherry-pick () { local -a git_commit_opts git_commit_opts=(--all --not HEAD --not) _arguments \ - '(- :)--quit[end revert or cherry-pick sequence]' \ - '(- :)--continue[resume revert or cherry-pick sequence]' \ - '(- :)--skip[skip current commit and continue]' \ - '(- :)--abort[cancel revert or cherry-pick sequence]' \ + - init \ '--cleanup=[specify how to strip spaces and #comments from message]:mode:_git_cleanup_modes' \ '--allow-empty[preserve initially empty commits]' \ '--allow-empty-message[allow replaying a commit with an empty message]' \ @@ -544,15 +549,21 @@ _git-cherry-pick () { '(-e --edit --ff)'{-e,--edit}'[edit commit before committing the cherry-pick]' \ '(--ff)-x[append information about what commit was cherry-picked]' \ '(-m --mainline)'{-m+,--mainline=}'[specify mainline when cherry-picking a merge commit]:parent number' \ - '--rerere-autoupdate[update index with reused conflict resolution if possible]' \ + '(--no-rerere-autoupdate)--rerere-autoupdate[update index with reused conflict resolution if possible]' \ + '(--rerere-autoupdate)--no-rerere-autoupdate' \ '(-n --no-commit --ff)'{-n,--no-commit}'[do not make the actual commit]' \ '(-s --signoff --ff)'{-s,--signoff}'[add Signed-off-by trailer at the end of the commit message]' \ '(-S --gpg-sign --no-gpg-sign)'{-S-,--gpg-sign=-}'[GPG-sign the commit]::key id' \ "(-S --gpg-sign --no-gpg-sign)--no-gpg-sign[don't GPG-sign the commit]" \ - '*'{-s+,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies' \ + '*--strategy=[use given merge strategy]:merge strategy:__git_merge_strategies' \ '*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]: :_git_strategy_options' \ '(-e --edit -x -n --no-commit -s --signoff)--ff[fast forward, if possible]' \ - '*: : __git_commit_ranges -O expl:git_commit_opts' + '*: : __git_commit_ranges -O expl:git_commit_opts' \ + - '(sequencer)' \ + '--quit[end revert or cherry-pick sequence]' \ + '--continue[resume revert or cherry-pick sequence]' \ + '--skip[skip current commit and continue]' \ + '--abort[cancel revert or cherry-pick sequence]' \ } (( $+functions[_git-citool] )) || @@ -646,9 +657,9 @@ _git-clone () { '(-u --upload-pack)'{-u+,--upload-pack=}'[specify path to git-upload-pack on remote side]:remote path' \ '--template=[directory to use as a template for the object database]: :_directories' \ '*'{-c,--config}'[= set a configuration variable in the newly created repository]' \ - '--depth[create a shallow clone, given number of revisions deep]: :__git_guard_number depth' \ - '--shallow-since=[shallow clone since a specific time]:time' \ - '*--shallow-exclude=[shallow clone excluding commits reachable from specified remote revision]:revision' \ + '(--bundle-uri)--depth[create a shallow clone, given number of revisions deep]: :__git_guard_number depth' \ + '(--bundle-uri)--shallow-since=[shallow clone since a specific time]:time' \ + '(--bundle-uri)*--shallow-exclude=[shallow clone excluding commits reachable from specified remote revision]:revision' \ '(--no-single-branch)--single-branch[clone only history leading up to the main branch or the one specified by -b]' \ '(--single-branch)--no-single-branch[clone history leading up to each branch]' \ "--no-tags[don't clone any tags and make later fetches not follow them]" \ @@ -660,8 +671,10 @@ _git-clone () { '(-4 --ipv4 -6 --ipv6)'{-4,--ipv4}'[use IPv4 addresses only]' \ '(-4 --ipv4 -6 --ipv6)'{-6,--ipv6}'[use IPv6 addresses only]' \ '--filter=[object filtering]:filter:_git_rev-list_filters' \ + '--also-filter-submodules[apply partial clone filters to submodules]' \ '--remote-submodules[any cloned submodules will use their remote-tracking branch]' \ '--sparse[initialize the sparse-checkout file to start with only the top-level files]' \ + '(--depth --shallow-since --shallow-exclude)--bundle-uri=[before fetching, get a bundle from specified location]:uri:_urls' \ ': :->repository' \ ': :_directories' && ret=0 @@ -714,7 +727,7 @@ _git-commit () { "--no-ahead-behind[don't display detailed ahead/behind counts relative to upstream branch]" \ '(--short --dry-run)--porcelain[dry run with machine-readable output format]' \ '(--short --porcelain --dry-run -z --null)'{-z,--null}'[dry run with NULL-separated output format]' \ - {-p,--patch}'[use the interactive patch selection interface to chose which changes to commit]' \ + {-p,--patch}'[use the interactive patch selection interface to choose which changes to commit]' \ '(--reset-author)--author[override the author name used in the commit]:author name' \ '--date=[override the author date used in the commit]:date' \ '*--trailer=[add custom trailer(s)]:trailer:__git_trailers_tokens' \ @@ -726,8 +739,8 @@ _git-commit () { '(-e --edit --no-edit)'{-e,--edit}'[edit the commit message before committing]' \ '(-e --edit --no-edit)--no-edit[do not edit the commit message before committing]' \ '--no-post-rewrite[bypass the post-rewrite hook]' \ - '(-a --all --interactive -o --only -i --include)'{-i,--include}'[update the given files and commit the whole index]' \ - '(-a --all --interactive -o --only -i --include)'{-o,--only}'[commit only the given files]' \ + '(-a --all --interactive -o --only)*'{-i,--include}'[update the given files and commit the whole index]' \ + '(-a --all --interactive -i --include)*'{-o,--only}'[commit only the given files]' \ '(-u --untracked-files)'{-u-,--untracked-files=-}'[show files in untracked directories]::mode:((no\:"show no untracked files" normal\:"show untracked files and directories" all\:"show individual files in untracked directories"))' \ @@ -998,6 +1011,7 @@ _git-gc () { '--auto[check whether housekeeping is required]' \ '( --no-prune)--prune=-[prune loose objects older than given date]::date [2 weeks ago]:_git_approxidates' \ '(--prune )--no-prune[do not prune any loose objects]' \ + '--cruft[pack unreferenced objects separately]' \ '(-q --quiet)'{-q,--quiet}'[suppress progress reporting]' \ '--keep-largest-pack[repack all other packs except the largest pack]' \ } @@ -1060,6 +1074,7 @@ _git-grep () { '--threads=[use specified number of threads]:number of threads' \ '(-c --count -p --show-function)'{-p,--show-function}'[show preceding line containing function name of match]' \ '(-c --count -W --function-context)'{-W,--function-context}'[show whole function where a match was found]' \ + '(-m --max-count)'{-m+,--max-count=}'[specify maximum number of results per file]:results' \ '(1)*-f+[read patterns from given file]:pattern file:_files' \ '(1)*-e+[use the given pattern for matching]:pattern' \ $pattern_operators \ @@ -1297,6 +1312,7 @@ _git-merge () { $merge_options \ \*{-m+,--message=}'[set the commit message to be used for the merge commit]:merge message' \ \*{-F+,--file=}'[read commit message from a file]:file' \ + '--into-name=[use specified name instead of the real target]:branch name:__git_branch_names' \ '(--edit --no-edit)-e[open an editor to change the commit message]' \ '( --no-rerere-autoupdate)--rerere-autoupdate[allow the rerere mechanism to update the index]' \ '(--rerere-autoupdate )--no-rerere-autoupdate[do not allow the rerere mechanism to update the index]' \ @@ -1336,6 +1352,7 @@ _git-mv () { (( $+functions[_git-notes] )) || _git-notes () { local curcontext=$curcontext state line ret=1 + local -a args declare -A opt_args _arguments -C $endopt \ @@ -1373,12 +1390,18 @@ _git-notes () { (add) # TODO: Only complete commits that don't have notes already, unless # -f or --force has been given. - _arguments -S -s $endopt \ + args=( '(-f --force)'{-f,--force}'[overwrite existing note]' ) + ;& + (append) + _arguments -S -s $endopt $args \ '*'{-m+,--message=}'[use given note message]:message' \ '*'{-F+,--file=}'[take note message from given file]:note message file:_files' \ '(-C --reuse-message)'{-C+,--reuse-message=}'[take note message from given blob object]: :__git_blobs' \ '(-c --reedit-message)'{-c+,--reedit-message=}'[take note message from given blob object and edit it]: :__git_blobs' \ - '(-f --force)'{-f,--force}'[overwrite existing note]' \ + '--allow-empty[allow storing empty note]' \ + '(--no-separator)--separator=-[insert text between paragraphs]::paragraph break' \ + '(--separator)--no-separator' \ + '--stripspace[remove unnecessary whitespace]' \ ': :__git_commits' && ret=0 ;; (copy) @@ -1409,14 +1432,6 @@ _git-notes () { (remove) _arguments -S $endopt --ignore-missing --stdin ':object:__git_commits' && ret=0 ;; - (append) - _arguments -S -s $endopt \ - '*'{-m+,--message=}'[use given note message]:message' \ - '*'{-F+,--file=}'[take note message from given file]:note message file:_files' \ - '(-C --reuse-message)'{-C+,--reuse-message=}'[take note message from given blob object]: :__git_blobs' \ - '(-c --reedit-message)'{-c+,--reedit-message=}'[take note message from given blob object and edit it]: :__git_blobs' \ - ': :__git_commits' && ret=0 - ;; (get-ref) _nothing ;; @@ -1474,13 +1489,13 @@ _git-push () { fi _arguments -S -s $endopt \ - '--all[push all refs under refs/heads/]' \ + '(* --all --branches --mirror --tags)'{--all,--branches}'[push all branches]' \ '--prune[remove remote branches that do not have a local counterpart]' \ - '--mirror[push all refs under refs/heads/ and refs/tags/ and delete non-existing refs]' \ + '(* --all --branches --tags)--mirror[push all refs under refs/heads/ and refs/tags/ and delete non-existing refs]' \ '(-n --dry-run)'{-n,--dry-run}'[do everything except actually send the updates]' \ '--porcelain[produce machine-readable output]' \ '(-d --delete)'{-d,--delete}'[delete all listed refs from the remote repository]' \ - '--tags[all tags under refs/tags are pushed]' \ + '(* --all --branches --mirror)--tags[all tags under refs/tags are pushed]' \ '--follow-tags[also push missing annotated tags reachable from the pushed refs]' \ '(--receive-pack --exec)'{--receive-pack=-,--exec=-}'[path to git-receive-pack on remote]:remote git-receive-pack:_files' \ '(--force-with-lease --no-force-with-lease)*--force-with-lease=-[allow refs that are not ancestors to be updated if current ref matches expected value]::ref and expectation:->lease' \ @@ -1592,6 +1607,8 @@ _git-rebase () { '(--keep-base)--onto=[start new branch with HEAD equal to given revision]:newbase:__git_revisions' \ "(--apply --whitespace -C)--reschedule-failed-exec[automatically re-schedule any 'exec' that fails]" \ '(--apply --whitespace -C)--reapply-cherry-picks[apply all changes, even those already present upstream]' \ + '--update-refs[update branches that point to commits that are being rebased]' \ + '!(--update-refs)--no-update-refs' \ ':upstream branch:__git_revisions' \ '::working branch:__git_revisions' } @@ -1611,6 +1628,7 @@ _git-reset () { '--recurse-submodules=-[control recursive updating of submodules]::reset:__git_commits' \ '(-p --patch)'{-p,--patch}'[select diff hunks to remove from the index]' \ '(-q --quiet)'{-q,--quiet}'[suppress all output]' \ + '--no-refresh[skip refreshing the index after reset]' \ '(*)--pathspec-from-file=[read pathspec from file]:file:_files' \ '(*)--pathspec-file-nul[pathspec elements are separated with NUL character]' \ '(--soft --mixed --hard --merge --keep):: :__git_commits' \ @@ -1650,7 +1668,7 @@ _git-restore() { '(-q --quiet --progress)--no-progress[suppress progress reporting]' \ '(--no-progress)--progress[force progress reporting]' \ '(-m --merge)'{-m,--merge}'[perform a 3-way merge with the new branch]' \ - '--conflict=[change how conflicting hunks are presented]:conflict style [merge]:(merge diff3)' \ + '--conflict=[change how conflicting hunks are presented]:conflict style [merge]:(merge diff3 zdiff3)' \ '(-2 --ours -3 --theirs -m --merge)'{-2,--ours}'[checkout our version for unmerged files]' \ '(-2 --ours -3 --theirs -m --merge)'{-3,--theirs}'[checkout their version for unmerged files]' \ '(-p --patch)'{-p,--patch}'[select hunks interactively]' \ @@ -1702,6 +1720,7 @@ _git-revert () { '*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]: :_git_strategy_options' \ '(-S --gpg-sign --no-gpg-sign)'{-S-,--gpg-sign=-}'[GPG-sign the commit]::key id' \ "(-S --gpg-sign --no-gpg-sign)--no-gpg-sign[don't GPG-sign the commit]" \ + "--reference[use the 'reference' format to refer to commits in log message]" \ ': :__git_recent_commits' } @@ -1844,6 +1863,7 @@ _git-sparse-checkout() { add:'update the sparse-checkout file to include additional patterns' reapply:'reapply the sparsity pattern rules to paths in the working tree' disable:'disable the config setting, and restore all files in the working directory' + check-rules:'check whether sparsity rules match one or more paths' ) _describe -t commands command commands && ret=0 @@ -1854,13 +1874,22 @@ _git-sparse-checkout() { init) _arguments \ '--cone[allow for better performance with a limited set of patterns]' \ - '--no-sparse-index[rewrite index to not be sparse]' + '--no-sparse-index[rewrite index to not be sparse]' && ret=0 ;; set|add) _arguments -S \ - '--stdin[read patterns from input]' \ + '--cone[initialize the sparse-checkout in cone mode]' \ + '--sparse-index[toggle the use of a sparse index]' \ + '--skip-checks[skip some sanity checks on the given paths that might give false positives]' \ + '(*)--stdin[read patterns from input]' \ '*:pattern:_files' && ret=0 ;; + check-rules) + _arguments \ + '-z[terminate input and output files by a NUL character]' \ + '--cone[interpret rules file patterns as cone mode patterns]' \ + '--rules-file=[use patterns in specified file]:file:_files' && ret=0 + ;; esac ;; esac @@ -1879,10 +1908,11 @@ _git-stash () { '(-k --keep-index --no-keep-index)'{-k,--keep-index}'[all changes already added to the index are left intact]' '(-k --keep-index)--no-keep-index[all changes already added to the index are undone]' '(-q --quiet)'{-q,--quiet}'[suppress all output]' - '(-p --patch -a --all -u --include-untracked)'{-u,--include-untracked}'[include untracked files]' - '(-p --patch -a --all -u --include-untracked)'{-a,--all}'[include ignored files]' + '(-p --patch -a --all -u --include-untracked -S --staged)'{-u,--include-untracked}'[include untracked files]' + '(-p --patch -a --all -u --include-untracked -S --staged)'{-a,--all}'[include ignored files]' '(* -p --patch)--pathspec-from-file=[read pathspec from file]:file:_files' '(* -p --patch)--pathspec-file-nul[pathspec elements are separated with NUL character]' + '(-S --staged -a --all -u --include-untracked)'{-S,--staged}'[only stash changes that are currently staged]' ) _arguments -C \ @@ -1904,6 +1934,7 @@ _git-stash () { clear:'remove all the stashed states' drop:'remove a single stashed state from the stash list' create:'create a stash without storing it in the ref namespace' + store:'store a stash created with git stash create in the stash ref' ) _describe -t commands command commands && ret=0 @@ -1940,7 +1971,9 @@ _git-stash () { __git_setup_diff_options _arguments -S -s $endopt \ - $diff_options \ + ${diff_options:#*\)-u*} \ + '(-u --include-untracked --only-untracked)'{-u,--include-untracked}'[show the untracked files in the stash entry as part of the diff]' \ + '(-u --include-untracked)--only-untracked[show only the untracked files in the stash entry as part of the diff]' \ ':: :__git_stashes' && ret=0 ;; (pop|apply) @@ -1962,9 +1995,14 @@ _git-stash () { '(-q --quiet)'{-q,--quiet}'[suppress all output]' \ ':: :__git_stashes' && ret=0 ;; + (store) + _arguments -S -s $endopt \ + '(-m --message)'{-m+,--message=}'[specify stash description]:description' \ + '(-q --quiet)'{-q,--quiet}'[suppress all output]' && ret=0 + ;; (create) - _nothing - ;; + _message -e messages message + ;; (*) _nothing ;; @@ -2068,7 +2106,6 @@ _git-submodule () { '*: :__git_ignore_line_inside_arguments __git_submodules' && ret=0 ;; (update) - # TODO: --init not properly documented. _arguments -S \ '(-q --quiet)'{-q,--quiet}'[suppress all output]' \ '(-N --no-fetch)'{-N,--no-fetch}'[do not fetch new objects from repository]' \ @@ -2082,6 +2119,7 @@ _git-submodule () { '--force[discard local changes by checking out the current up-to-date version]' \ '--init[initialize uninitialized submodules]' \ '--single-branch[clone only one branch]' \ + '--filter=[apply partial clone filter to the submodule]:filter' \ '*: :__git_ignore_line_inside_arguments __git_submodules' && ret=0 ;; (set-branch) @@ -2153,7 +2191,7 @@ _git-subtree () { _arguments -C \ '(-q --quiet)'{-q,--quiet}'[suppress progress output]' \ '(-P --prefix)'{-P+,--prefix=}'[the path to the subtree in the repository to manipulate]: :_directories' \ - '-d[show debug messages]' \ + '(-d --debug)'{-d,--debug}'[show debug messages]' \ ': :->command' \ '*::: := ->option-or-argument' && ret=0 @@ -2250,9 +2288,10 @@ _git-switch() { '(-q --quiet --progress)--no-progress[suppress progress reporting]' \ '--progress[force progress reporting]' \ '(-m --merge --discard-changes --orphan)'{-m,--merge}'[perform a 3-way merge with the new branch]' \ - '(--discard-changes --orphan)--conflict=[change how conflicting hunks are presented]:conflict style [merge]:(merge diff3)' \ + '(--discard-changes --orphan)--conflict=[change how conflicting hunks are presented]:conflict style [merge]:(merge diff3 zdiff3)' \ '(-d --detach -c --create -C --force-create --ignore-other-worktrees --orphan --guess --no-guess 1)'{-d,--detach}'[detach HEAD at named commit]' \ - '(-t --track --no-track --guess --orphan 1)'{-t,--track}'[set upstream info for new branch]' \ + '(--track --no-track --guess --orphan 1)-t[set upstream info for new branch]' \ + '(-t --no-track --guess --orphan 1)--track=-[set upstream info for new branch]::configuration:(direct inherit)' \ "(-t --track --guess --orphan 1)--no-track[don't set upstream info for a new branch]" \ '(-c --create -C --force-create -d --detach --ignore-other-worktrees -m --merge --conflict -t --track --guess --no-track -t --track)--orphan[create new unparented branch]: :__git_branch_names' \ '!--overwrite-ignore' \ @@ -2313,6 +2352,7 @@ _git-tag () { "*--no-contains=[only list tags that don't contain the specified commit]: :__git_commits" \ '--merged=-[print only tags that are merged]:: :__git_commits' \ '--no-merged=-[print only tags that are not merged]:: :__git_commits' \ + "--omit-empty[don't output a newline after empty formatted refs]" \ '--sort=[specify how the tags should be sorted]:field:__git_ref_sort_keys' \ '--points-at=[only list tags of the given object]: :__git_commits' \ '--format=[specify format to use for the output]:format:__git_format_ref' \ @@ -2344,6 +2384,7 @@ _git-worktree() { lock:'prevent a working tree from being pruned' move:'move a working tree to a new location' remove:'remove a working tree' + repair:'repair worktree administrative files' unlock:'allow working tree to be pruned, moved or deleted' ) @@ -2358,17 +2399,24 @@ _git-worktree() { else args=( ':commit:__git_commits' ) fi - _arguments -S $endopt \ + _arguments -s -S $endopt \ '(-f --force)'{-f,--force}'[checkout branch even if already checked out in another worktree]' \ - '(-B --detach)-b+[create a new branch]: :__git_branch_names' \ - '(-b --detach)-B+[create or reset a branch]: :__git_branch_names' \ - '(-b -B)--detach[detach HEAD at named commit]' \ + '(-B -d --detach --guess-remote)-b+[create a new branch]: :__git_branch_names' \ + '(-b -d --detach --guess-remote)-B+[create or reset a branch]: :__git_branch_names' \ + '(-b -d --detach)--orphan[create unborn/orphaned branch]' \ + '(-d --detach -b -B --orphan --guess-remote --track --no-track)'{-d,--detach}'[detach HEAD at named commit]' \ '--no-checkout[suppress file checkout in new worktree]' \ '--lock[keep working tree locked after creation]' \ + '--reason=[specify reason for locking]:reason' \ + '(2 --no-guess-remote -b -B -d --detach)--guess-remote[guess remote tracking branch from path basename]' \ + "(--guess-remote)--no-guess-remote[don't guess remote tracking branch from path basename]" \ + '(--no-track -d --detach)--track[set upstream info for new branch]' \ + "(--track -d --detach)--no-track[don't set upstream info for new branch]" \ + '(-q --quiet)'{-q,--quiet}'[suppress feedback messages]' \ ':path:_directories' $args && ret=0 ;; (prune) - _arguments -S $endopt \ + _arguments -s -S $endopt \ '(-n --dry-run)'{-n,--dry-run}"[don't remove, show only]" \ '(-v --verbose)'{-v,--verbose}'[report pruned objects]' \ '--expire=[expire objects older than specified time]: :_git_approxidates' && ret=0 @@ -2393,6 +2441,9 @@ _git-worktree() { '(-f --force)'{-f,--force}'[remove working trees that are not clean or that have submodules]' \ ': :->worktrees' && ret=0 ;; + (repair) + _directories && ret=0 + ;; (unlock) state=worktrees ;; @@ -3846,7 +3897,11 @@ _git-pack-refs () { '( --no-all)--all[pack all refs]' \ '(--all )--no-all[do not pack all refs]' \ '( --no-prune)--prune[remove loose refs after packing them]' \ - '(--prune )--no-prune[do not remove loose refs after packing them]' + '(--prune )--no-prune[do not remove loose refs after packing them]' \ + '*--include=[references to include]:reference pattern:_git_full_references' \ + '*--exclude=[references to exclude]:reference pattern:_git_full_references' \ + '--no-include[clear and reset the list of include patterns]' \ + '--no-exclude[clear and reset the list of exclude patterns]' } (( $+functions[_git-prune] )) || @@ -3992,7 +4047,9 @@ _git-remote () { ': :__git_remotes' && ret=0 ;; (rename) - _arguments \ + _arguments -S $endopt \ + '(--no-progress)--progress' \ + '(--progress)--no-progress' \ ':old name:__git_remotes' \ ':new name:__git_remotes' && ret=0 ;; @@ -4071,7 +4128,8 @@ _git-repack () { '--pack-kept-objects[repack objects in packs marked with .keep]' \ '--keep-pack=[ignore named pack]:pack' \ '(-g --geometric)'{-g+,--geometric=}'[find a geometric progression with specified factor]:factor' \ - '(-m --write-midx)'{-m,--write-midx}'[write a multi-pack index of the resulting packs]' + '(-m --write-midx)'{-m,--write-midx}'[write a multi-pack index of the resulting packs]' \ + '--expire-to=[pack prefix to store a pack containing pruned objects]:directory:_directories' } (( $+functions[_git-replace] )) || @@ -4159,8 +4217,9 @@ _git-blame () { (( $+functions[_git-bugreport] )) || _git-bugreport() { _arguments \ - '(-o --output-directory)'{-o+,--output-directory=}'[specify a destination for the bugreport file]:directory:_directories' \ - '(-s --suffix)'{-s+,--suffix=}'[specify a strftime format suffix for the filename]:format:_date_formats' + '--diagnose=-[create an additional zip archive of detailed diagnostics]::mode [stats]:(stats all)' \ + '(-o --output-directory)'{-o+,--output-directory=}'[specify a destination for the bugreport]:directory:_directories' \ + '(-s --suffix)'{-s+,--suffix=}'[specify a strftime format filename suffix]:format:_date_formats' } (( $+functions[_git-cherry] )) || @@ -4180,6 +4239,14 @@ _git-count-objects () { {-H,--human-readable}'[print sizes in human readable format]' } +(( $+functions[_git-diagnose] )) || +_git-diagnose() { + _arguments -S $endopt \ + '(-o --output-directory)'{-o+,--output-directory=}'[specify a destination for the diagnostics archive]:destination:_directories' \ + '(-s --suffix)'{-s+,--suffix=}'[specify a strftime format suffix for the filename]:format:_date_formats' \ + '--mode=[specify the content of the diagnostic archive]:content [stats]:(stats all)' +} + (( $+functions[_git-difftool] )) || _git-difftool () { # TODO: Is this fine, or do we need to modify the context or similar? @@ -4209,9 +4276,10 @@ _git-fsck () { '--full[check all object directories]' \ '--connectivity-only[check only connectivity]' \ '--strict[do strict checking]' \ - '(-v --verbose)'{-v,--verbose}'[output additional information]' \ + '(-v --verbose --no-progress)'{-v,--verbose}'[output additional information]' \ '--lost-found[write dangling objects into .git/lost-found]' \ - '--progress[show progress]' \ + "(-v --verbose)--no-progress[don't show progress]" \ + '!(-v --verbose --no-progress)--progress' \ '--name-objects[show verbose names for reachable objects]' \ '*: :__git_objects' } @@ -4224,14 +4292,19 @@ _git-get-tar-commit-id () { (( $+functions[_git-help] )) || _git-help () { _arguments -S -s \ - '(-c --config -i --info -m --man -w --web)'{-a,--all}'[show all available commands]' \ + '(-a --all -g --guides --user-interfaces --developer-interfaces -c --config -i --info -m --man -w --web)'{-a,--all}'[show all available commands]' \ + '(-g --guides --user-interfaces --developer-interfaces -c --config -i --info -m --man -w --web)--no-external-commands[exclude external commands, with --all]' \ + '(-g --guides --user-interfaces --developer-interfaces -c --config -i --info -m --man -w --web)--no-aliases[exclude aliases, with --all]' \ + '(-a --all -g --guides --user-interfaces --developer-interfaces -c --config -i --info -w --web)'{-m,--man}'[display manual for the command in man format]' \ + '(-a --all -g --guides --user-interfaces --developer-interfaces -c --config -i --info -m --man)'{-w,--web}'[display manual for the command in HTML format]' \ + '(-a --all -g --guides --user-interfaces --developer-interfaces -c --config -m --man -w --web)'{-i,--info}'[display manual for the command in info format]' \ + '!(--no-verbose)'{-v,--verbose} \ + "--no-verbose[don't print command descriptions]" \ + '(-)'{-g,--guides}'[print list of useful guides]' \ + '(-)--user-interfaces[print list of user-facing repository, command and file interfaces]' \ + '(-)--developer-interfaces[print list of file formats, protocols and other developer interfaces]' \ '(-)'{-c,--config}'[print all configuration variable names]' \ - '(-a --all -g --guides -c --config -m --man -w --web)'{-i,--info}'[display manual for the command in info format]' \ - '(-a --all -g --guides -c --config -i --info -w --web)'{-m,--man}'[display manual for the command in man format]' \ - '(-a --all -g --guides -c --config -i --info -m --man)'{-w,--web}'[display manual for the command in HTML format]' \ - '(-g --guides -c --config -i --info -m --man -w --web)'{-g,--guides}'[prints a list of useful guides on the standard output]' \ - '(-v --verbose)'{-v,--verbose}'[print command descriptions]' \ - ': : _alternative commands:command:_git_commands "guides:git guide:(attributes cli core-tutorial cvs-migration diffcore everyday glossary hooks ignore modules namespaces repository-layout revisions tutorial tutorial-2 workflows)"' + ': : _alternative commands:command:_git_commands "guides:git guide:_git_help_guides"' } (( $+functions[_git-instaweb] )) || @@ -4268,7 +4341,16 @@ _git-instaweb () { (( $+functions[_git-merge-tree] )) || _git-merge-tree () { - _arguments \ + _arguments -S $endopt \ + '(1)--write-tree[do a real merge instead of a trivial merge]' \ + '(-)--trivial-merge[do a trivial merge only]' \ + '(--no-messages)--messages[also show informational/conflict messages]' \ + "(--messages)--no-messages[don't show informational/conflict messages]" \ + '-z[separate paths with the NUL character]' \ + '--name-only[list filenames without modes/oids/stages]' \ + '--allow-unrelated-histories[allow merging unrelated histories]' \ + '--stdin[perform multiple merges, one per line of input]' \ + '--merge-base=[specify a merge-base for the merge]:commit:__git_commits' \ ':base-tree:__git_tree_ishs' \ ':branch 1:__git_tree_ishs' \ ':branch 2:__git_tree_ishs' @@ -4584,6 +4666,8 @@ _git-send-email () { '--relogin-delay=[specify delay between successive logins]:delay (seconds)' \ '--cc-cmd=[specify command to generate Cc\: header with]:Cc\: command:_cmdstring' \ '--to-cmd=[specify command to generate To\: header with]:To\: command:_cmdstring' \ + '--header-cmd=[specify command to generate headers with]:header command:_cmdstring' \ + '--no-header-cmd[disable any header command in use]' \ '( --no-chain-reply-to)--chain-reply-to[send each email as a reply to previous one]' \ '(--chain-reply-to )--no-chain-reply-to[send all emails after first as replies to first one]' \ '--identity=[specify configuration identity]: :__git_sendemail_identities' \ @@ -4911,7 +4995,7 @@ _git-apply () { _arguments -S -s $endopt \ $apply_options \ - '(--index --cached --reject)'{-3,--3way}'[fall back on 3-way merge if patch fails]' \ + '(--index --cached --reject)'{-3,--3way}'[attempt three-way merge, fall back on normal patch if that fails]' \ '--stat[output diffstat for input (turns off "apply")]' \ '--numstat[same as --stat but in decimal notation and complete pathnames (turns off "apply")]' \ '--summary[output summary of git-diff extended headers (turns off "apply")]' \ @@ -4926,8 +5010,10 @@ _git-apply () { '--no-add[ignore additions made by the patch]' \ '--allow-overlap[allow overlapping hunks]' \ '--inaccurate-eof[work around missing-new-line-at-EOF bugs]' \ - '(-v --verbose)'{-v,--verbose}'[display progress on stderr]' \ + '(-v --verbose -q --quiet)'{-v,--verbose}'[display progress on stderr]' \ + '(-q --quiet -v --verbose)'{-q,--quiet}'[be more quiet]' \ '--recount[do not trust line counts in hunk headers]' \ + "--allow-empty[don't return error for empty patches]" \ '*:patch:_files' } @@ -4944,8 +5030,9 @@ _git-checkout-index () { '(-q --quiet)'{-q,--quiet}'[no warning for existing files and files not in index]' \ '(-f --force)'{-f,--force}'[force overwrite of existing files]' \ '(-a --all --stdin *)'{-a,--all}'[check out all files in index]' \ - '(-n --no-create)'{-n,--no-create}'[do not checkout new files]' \ + '(-n --no-create)'{-n,--no-create}"[don't checkout new files]" \ '--temp[write content to temporary files]' \ + "--ignore-skip-worktree-bits[don't skip files with skip-worktree set]" \ '(-a --all *)--stdin[read list of paths from the standard input]' \ '--prefix=[prefix to use when creating files]:directory:_directories' \ '--stage=[check out files from named stage]:stage:(1 2 3 all)' \ @@ -5054,7 +5141,8 @@ _git-merge-file () { '(--ours --union)--theirs[resolve conflicts favoring their side of the lines]' \ '(--ours --theirs )--union[resolve conflicts favoring both sides of the lines]' \ '--marker-size[specify length of conflict markers]: :__git_guard_number "marker length"' \ - '--diff3[use a diff3 based merge]' \ + '(--zdiff3)--diff3[show conflicts in "diff3" style]' \ + '(--diff3)--zdiff3[show conflicts in "zdiff3" style]' \ ':current file:_files' \ ':base file:_files' \ ':other file:_files' @@ -5216,6 +5304,7 @@ _git-symbolic-ref () { '(-q --quiet)'{-q,--quiet}'[do not issue error if specified name is not a symbolic ref]' \ '--short[shorten the ref name (eg. refs/heads/master -> master)]' \ '-m[update reflog for specified name with specified reason]:reason for update' \ + '--no-recurse[stop after dereferencing a single level of symbolic ref]' \ ':symbolic reference:__git_heads' \ ':: :__git_references' } @@ -5311,8 +5400,8 @@ _git-cat-file () { _arguments -S -s \ '(-t -s -e -p --allow-unknown-type 1)--textconv[show content as transformed by a textconv filter]' \ '(-t -s -e -p --allow-unknown-type 1)--filters[show content as transformed by filters]' \ - '(-t -s -e -p --allow-unknown-type 1)--path=[use a specific path for --textconv/--filters]:path:_directories' \ - query \ + '(-t -s -e -p --allow-unknown-type 1)--path=[use a specific path for --textconv/--filters]:path:_directories' \ '(-s -e -p --textconv --filters 1)-t[show type of given object]' \ '(-t -e -p --textconv --filters 1)-s[show size of given object]' \ '(-e -p --textconv --filters 1)--allow-unknown-type[allow query of broken/corrupt objects of unknown type]' \ @@ -5321,12 +5410,14 @@ _git-cat-file () { '(-):object type:(blob commit tag tree)' \ ': :__git_objects' \ - batch \ - '(--batch-check)--batch=-[print SHA1, type, size and contents (or in specified format)]::format' \ - '(--batch)--batch-check=-[print SHA1, type and size (or in specified format)]::format' \ + '(--batch-check --batch-command)--batch=-[print SHA1, type, size and contents (or in specified format)]::format' \ + '(--batch --batch-command)--batch-check=-[print SHA1, type and size (or in specified format)]::format' \ + '(--batch-check --batch)--batch-command=-[enter a command mode that reads commands and arguments from stdin]::format' \ '--follow-symlinks[follow in-tree symlinks (used with --batch or --batch-check)]' \ '--batch-all-objects[show all objects with --batch or --batch-check]' \ "--unordered[don't order --batch-all-objects output]" \ - '--buffer[disable flushing of output after each object]' + '--buffer[disable flushing of output after each object]' \ + '-Z[input and output is NUL-delimited instead of newline-delimited]' } (( $+functions[_git-diff-files] )) || @@ -5423,21 +5514,24 @@ _git-for-each-ref () { # is, %(refname), %(objecttype), %(objectsize), %(objectname) with optional '*' # in front. _arguments -S -s \ + "--omit-empty[don't output a newline after empty formatted refs]" \ '--count=[maximum number of refs to iterate over]: :__git_guard_number "maximum number of refs"' \ '*--sort=[key to sort refs by]: :__git_ref_sort_keys' \ '--format=-[output format of ref information]:format:__git_format_ref' \ '--color=-[respect any colors specified in the format]::when:(always never auto)' \ + '--exclude=[exclude refs which match pattern]:pattern:_git_full_references' \ '*--points-at=[print only refs which point at the given object]:object:__git_commits' \ '*--merged=[print only refs that are merged]:object:__git_commits' \ '*--no-merged=[print only refs that are not merged]:object:__git_commits' \ '*--contains=[print only refs that contain specified commit]:object:__git_commits' \ "*--no-contains=[print only refs that don't contain specified commit]:object:__git_commits" \ '--ignore-case[sorting and filtering are case-insensitive]' \ + '(1)--stdin[read reference patterns from stdin]' \ '(-s --shell -p --perl --python --tcl)'{-s,--shell}'[use string literals suitable for sh]' \ '(-s --shell -p --perl --python --tcl)'{-p,--perl}'[use string literals suitable for Perl]' \ '(-s --shell -p --perl --tcl)'--python'[use string literals suitable for Python]' \ '(-s --shell -p --perl --python )'--tcl'[use string literals suitable for Tcl]' \ - ':: :_guard "([^-]?#|)" pattern' + ':: :_git_full_references' } (( $+functions[_git-for-each-repo] )) || @@ -5462,15 +5556,15 @@ _git-ls-files () { '(-c --cached)'{-c,--cached}'[show cached files in output]' \ '(-d --deleted)'{-d,--deleted}'[show deleted files in output]' \ '(-m --modified)'{-m,--modified}'[show modified files in output]' \ - '(-o --others)'{-o,--others}'[show other files in output]' \ + '(-o --others --format)'{-o,--others}'[show other files in output]' \ '(-i --ignored)'{-i,--ignored}'[show ignored files in output]' \ - '(-s --stage --with-tree)'{-s,--stage}'[show stage files in output]' \ + '(-s --stage --with-tree --format)'{-s,--stage}'[show stage files in output]' \ '--directory[if a whole directory is classified as "other", show just its name]' \ - '--eol[show line endings of files]' \ + '(--format)--eol[show line endings of files]' \ $no_empty_directory_opt \ '(-s --stage -u --unmerged --with-tree)'{-u,--unmerged}'[show unmerged files in output]' \ - '--resolve-undo[show resolve-undo information]' \ - '(-k --killed)'{-k,--killed}'[show killed files in output]' \ + '(--format)--resolve-undo[show resolve-undo information]' \ + '(-k --killed --format)'{-k,--killed}'[show killed files in output]' \ '-z[separate paths with the NUL character]' \ '*'{-x,--exclude=-}'[skip files matching given pattern]:file pattern' \ '*'{-X,--exclude-from=-}'[skip files matching patterns in given file]: :_files' \ @@ -5485,6 +5579,8 @@ _git-ls-files () { '--abbrev=[use specified digits to display object names]:digits' \ '--debug[show debugging data]' \ '--deduplicate[suppress duplicate entries]' \ + '--sparse[show sparse directories in the presence of a sparse index]' \ + '(-s --stage -o --others -k --killed --resolve-undo --eol)--format=[specify format to use for the output]:format' \ '*:: :_files' } @@ -5515,9 +5611,11 @@ _git-ls-tree () { '(-t)-d[do not show children of given tree (implies -t)]' \ '-r[recurse into subdirectories]' \ '-t[show tree entries even when going to recurse them]' \ - '(-l --long --name-only --name-status)'{-l,--long}'[show object size of blob entries]' \ + '(-l --long --name-only --name-status --format)'{-l,--long}'[show object size of blob entries]' \ '-z[use NUL termination on output]' \ - '(--name-only --name-status --abbrev)'{--name-only,--name-status}'[list only filenames, one per line]' \ + '(--name-only --name-status -l --long --object-only --format --abbrev)'{--name-only,--name-status}'[list only filenames, one per line]' \ + '(--name-only --name-status --format)--object-only[list only objects]' \ + '(--name-only --name-status -l --long --object-only)--format=[specify format to use for the output]:format' \ '(--name-only --name-status)--abbrev=[use specified digits to display object names]:digits' \ '--full-name[output full path-names]' \ '(--full-name)--full-tree[do not limit listing to current working-directory]' \ @@ -5552,12 +5650,13 @@ _git-name-rev () { '*--refs=[only use refs matching given pattern]: :_guard "?#" "shell pattern"' \ '--no-refs[clear any previous ref patterns given]' \ '*--exclude=[ignore refs matching specified pattern]:pattern' \ - '(--stdin :)--all[list all commits reachable from all refs]' \ - '(--all :)--stdin[read from stdin and append revision-name]' \ + '(--annotate-stdin :)--all[list all commits reachable from all refs]' \ + '(--all :)--annotate-stdin[annotate text from stdin]' \ + '!(--all : --annotate-stdin)--stdin' \ '--name-only[display only name of commits]' \ '--no-undefined[die with non-zero return when a reference is undefined]' \ '--always[show uniquely abbreviated commit object as fallback]' \ - '(--stdin --all)*: :__git_commits' + '(--annotate-stdin --all)*: :__git_commits' } (( $+functions[_git-pack-redundant] )) || @@ -5590,6 +5689,8 @@ _git-rev-list () { "--no-object-names[don't print the names of the object IDs that are found]" \ '!(--no-object-names)--object-names)' \ '--timestamp[print raw commit timestamp]' \ + "*--exclude-hidden=[don't include refs that would be hidden by git-receive-pack or git-upload-pack]:value:(fetch receive uploadpack)" \ + '--disk-usage=-[print space used for storage by the selected commits or objects]::value:(human)' \ '( --bisect-vars --bisect-all)--bisect[show only middlemost commit object]' \ '(--bisect)--bisect-vars[same as --bisect, displaying shell-evalable code]' \ '(--bisect)--bisect-all[display all commit objects between included and excluded commits]' \ @@ -5942,9 +6043,28 @@ _git-fmt-merge-msg () { '( --no-log)--log=-[display one-line descriptions from actual commits being merged]::number of commits [20]' \ '(--log )--no-log[do not display one-line descriptions from actual commits being merged]' \ '(-m --message)'{-m+,--message=}'[use given message instead of branch names for first line in log message]:message' \ - '(-F --file)'{-F,--file}'[specify list of merged objects from file]: :_files' + '--into-name=[specify substitute name for the real target branch to use]:name' \ + '(-F --file)'{-F+,--file=}'[specify list of merged objects from file]: :_files' } +(( $+functions[_git-hook] )) || +_git-hook() { + local -a args + local gitdir=$(_call_program gitdir git rev-parse --git-dir) + [[ -f $gitdir/gitdir ]] && gitdir=$(<$gitdir/gitdir) # needed in worktrees + + (( ${(M)#words[1,CURRENT-1]:#[^-]*} >= 3 )) && args=( + {--,--end-of-options}'[end options to git hook, allowing options to the hook itself]' + ) + [[ -n ${(M)words[1,CURRENT-1]:#--(|end-of-options)} ]] && args=( '*:: :_default' ) + _arguments $args \ + '--ignore-missing[ignore any missing hook by quietly returning zero]' \ + "--to-stdin=[specify file which will be redirected to hook's stdin]:file:_files" \ + '1:subcommand:(run)' \ + '2:hook name:compadd $gitdir/hooks/*(x\:t)' +} + + (( $+functions[_git-mailinfo] )) || _git-mailinfo () { # TODO: --no-inbody-headers is undocumented. @@ -5984,7 +6104,8 @@ _git-merge-one-file () { _git-patch-id () { _arguments \ '--stable[use a sum of hashes unaffected by diff ordering]' \ - '--unstable[use patch-id compatible with git 1.9 and older]' + '--unstable[use patch-id compatible with git 1.9 and older]' \ + "--verbatim[don't strip whitespace from the patch]" } # NOTE: git-sh-setup isn't a user command. @@ -6199,6 +6320,7 @@ _git_commands () { blame:'show what revision and author last modified each line of a file' bugreport:'collect information for user to file a bug report' count-objects:'count unpacked objects and display their disk consumption' + diagnose:'generate an archive of diagnostic information' difftool:'show changes using common diff tools' fsck:'verify connectivity and validity of objects in database' help:'display help information about git' @@ -6228,7 +6350,7 @@ _git_commands () { checkout-index:'copy files from index to working directory' commit-graph:'write and verify Git commit-graph files' commit-tree:'create new commit object' - hash-object:'compute object ID and optionally create a blob from a file' + hash-object:'compute object ID and optionally create an object from a file' index-pack:'build pack index file for an existing packed archive' merge-file:'run a three-way file merge' merge-index:'run merge for files needing merging' @@ -6290,6 +6412,7 @@ _git_commands () { check-ref-format:'ensure that a reference name is well formed' column:'display data in columns' fmt-merge-msg:'produce merge commit message' + hook:'run git hooks' mailinfo:'extract patch and authorship from a single email message' mailsplit:'split mbox file into a list of files' merge-one-file:'standard helper-program to use with git merge-index' @@ -6333,6 +6456,18 @@ _git_commands () { _alternative $alts } +(( $+functions[_git_help_guides] )) || +_git_help_guides() { + local -a guides userint devint + guides=( ${${${(M)${(f)"$(_call_program git-guides git help -g)"}:# *}## #}/ ##/:} ) + userint=( ${${${(M)${(f)"$(_call_program git-guides git help --user-interfaces)"}:# *}## #}/ ##/:} ) + devint=( ${${${(M)${(f)"$(_call_program git-guides git help --developer-interfaces)"}:# *}## #}/ ##/:} ) + _alternative \ + 'git-guides: : _describe -t git-guides guide guides' \ + 'user-interfaces: : _describe -t user-interfaces "user interface" userint' \ + 'developer-interfaces: : _describe -t developer-interfaces "developer interfaces" devint' +} + (( $+functions[__git_aliases] )) || __git_aliases () { local -a aliases @@ -6370,7 +6505,7 @@ __git_date_formats () { declare -a date_formats if compset -P 'format(-local|):'; then - _strftime + _date_formats return fi @@ -7012,7 +7147,6 @@ __git_heads_remote () { (( $+functions[__git_commit_objects] )) || __git_commit_objects () { - local gitdir expl start declare -a commits if [[ -n $PREFIX[(r)@] ]] || [[ -n $SUFFIX[(r)@] ]]; then @@ -7034,7 +7168,7 @@ __git_commit_objects () { (( $+functions[__git_recent_commits] )) || __git_recent_commits () { - local gitdir expl start + local expl declare -a descr tags heads commits argument_array_names commit_opts local h i j k ret integer distance_from_head @@ -7318,6 +7452,16 @@ __git_remote_references () { __git_references } +(( $+functions[_git_full_references] )) || +_git_full_references() { + + if [[ $_git_full_refs_cache_pwd != $PWD ]]; then + _git_full_refs_cache=( ${(f)"$(_call_program references 'git for-each-ref --format=%\(refname\)')"} ) + _git_full_refs_cache_pwd=$PWD + fi + _multi_parts "$@" / _git_full_refs_cache +} + (( $+functions[__git_notes_refs] )) || __git_notes_refs () { local expl @@ -7725,6 +7869,7 @@ __git_setup_log_options () { # TODO: Need to implement - for limiting the number of commits to show. log_options=( '(- *)-h[display help]' + '--clear-decorations[clear all previously-defined decoration filters]' '--decorate-refs=[only decorate refs that match pattern]:pattern' "--decorate-refs-exclude=[don't decorate refs that match pattern]:pattern" '( --no-decorate)--decorate=-[print out ref names of any commits that are shown]: :__git_log_decorate_formats' @@ -7856,7 +8001,8 @@ __git_setup_diff_options () { '(--no-prefix)--src-prefix=[use given prefix for source]:prefix' '(--no-prefix)--dst-prefix=[use given prefix for destination]:prefix' '--line-prefix=[prepend additional prefix to every line of output]:prefix' - '(--src-prefix --dst-prefix)--no-prefix[do not show any source or destination prefix]' + "(--src-prefix --dst-prefix)--no-prefix[don't show any source or destination prefix]" + '!(--src-prefix --dst-prefix --no-prefix)--default-prefix' '(-c --cc)'{-c,--cc}'[combined diff format for merge commits]' '--output=[output to a specific file]: :_files' '--expand-tabs=-[replace each tab with spaces]::tab width [8]' @@ -8027,8 +8173,7 @@ __git_setup_revision_options () { '--tags=-[show all commits from refs/tags]::pattern' '--remotes=-[show all commits from refs/remotes]::pattern' '--glob=[show all commits from refs matching glob]:pattern' - '--exclude=[do not include refs matching glob]:pattern' - '--exclude=[do not include refs matching glob]:pattern' + "--exclude=[don't include refs matching glob]:pattern" '--ignore-missing[ignore invalid object an ref names on command line]' '--bisect[pretend as if refs/bisect/bad --not refs/bisect/good-* was given on command line]' '(-g --walk-reflogs --reverse)'{-g,--walk-reflogs}'[walk reflog entries from most recent to oldest]' @@ -8114,6 +8259,7 @@ __git_setup_fetch_options () { '--refmap=[specify refspec to map refs to remote tracking branches]:refspec' '(-4 --ipv4 -6 --ipv6)'{-4,--ipv4}'[use IPv4 addresses only]' '(-4 --ipv4 -6 --ipv6)'{-6,--ipv6}'[use IPv6 addresses only]' + '--porcelain[machine-readable output]' '--dry-run[show what would be done, without making any changes]' '(-f --force)'{-f,--force}'[force overwrite of local reference]' '(-k --keep)'{-k,--keep}'[keep downloaded pack]' @@ -8508,7 +8654,7 @@ _git() { # TODO: This needs an update # TODO: How do we fix -c argument? _arguments -C \ - '(- :)--version[display version information]' \ + '(- :)'{-v,--version}'[display version information]' \ '(- :)--help[display help message]' \ '-C[run as if git was started in given path]: :_directories' \ \*{-c,--config-env=}'[pass configuration parameter to command]: :->configuration' \ @@ -8521,7 +8667,6 @@ _git() { '--git-dir=[path to repository]: :_directories' \ '--work-tree=[path to working tree]: :_directories' \ '--namespace=[set the Git namespace]:namespace' \ - '--super-prefix=[set a prefix which gives a path from above a repository down to its root]:path:_directories' \ '--bare[use $PWD as repository]' \ '--no-replace-objects[do not use replacement refs to replace git objects]' \ '--literal-pathspecs[treat pathspecs literally, rather than as glob patterns]' \ -- cgit v1.2.3 From c3cb5a3e0cd9b6e21d5e404649098c7c659c8f9a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 14 Nov 2023 20:36:31 +0100 Subject: 52300: update completion options for ansible 2.15.2 --- ChangeLog | 4 ++++ Completion/Unix/Command/_ansible | 13 ++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a3ce2e8d6..41eb95097 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-11-14 Oliver Kiddle + + * 52300: Completion/Unix/Command/_ansible: ansible 2.15.2 updates + 2023-11-09 Oliver Kiddle * 52280: Completion/Unix/Command/_git: update git completion for new diff --git a/Completion/Unix/Command/_ansible b/Completion/Unix/Command/_ansible index 7b85a58e4..bf31819ad 100644 --- a/Completion/Unix/Command/_ansible +++ b/Completion/Unix/Command/_ansible @@ -25,7 +25,6 @@ case $service in '(-k --ask-pass --connection-password-file)'{-k,--ask-pass}'[ask for connection password]' '(-k --ask-pass)--connection-password-file=[specify file containing connection password]:file:_files' '--list-hosts[output list of matching hosts]' - '(-l --limit)'{-l+,--limit=}'[further limit hosts to an additional pattern]:host subset:->hosts' '(-T --timeout)'{-T+,--timeout=}'[override the connection timeout]:timeout (seconds) [10]' '(-c --connection)'{-c+,--connection=}'[specify connection type]:connection type [smart]:->connect-types' '(-u --user)'{-u+,--user=}'[specify remote user for connection]:remote user:_users' @@ -44,7 +43,6 @@ case $service in '(-f --forks)'{-f+,--forks=}'[specify number of parallel processes to use]:processes [5]' '--become-method=[specify privilege escalation method to use]:method [sudo]:(sesu sudo su pbrun pfexec doas dzdo ksu runas pmrun enable machinectl)' '--become-user=[specify remote user for running operations]:user:_users' - "--syntax-check[perform a syntax check on the playbook, but don't execute it]" '!(-R --su-user -U --sudo-user)'{-R,-U,--su-user,--sudo-user}':user [root]:_users' ) ;| @@ -57,6 +55,7 @@ case $service in \*{-i+,--inventory=}'[specify inventory host file or host list]: : _alternative "files\:inventory file\:_files" "hosts\:host\: _sequence _hosts"' '!(-i --inventory)--inventory-file=:inventory file:_files' + '(-l --limit)'{-l+,--limit=}'[further limit hosts to an additional pattern]:host subset:->hosts' ) ;| ansible|ansible-console|ansible-inventory) @@ -112,7 +111,7 @@ case $service in '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-s,--snippet}'[show playbook snippet for inventory, lookup and module plugins]' '(-l --list -F --list_files -s --snippet -e --entry-point)--metadata-dump[dump json metadata for all plugins]' '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-e+,--entry-point=}'[select the entry point for roles]:entry point' - '(-t --type)'{-t+,--type=}'[choose plugin type]:plugin type [module]:(become cache callback cliconf connection httpapi inventory lookup netconf shell vars module strategy role keyword)' + '(-t --type)'{-t+,--type=}'[choose plugin type]:plugin type [module]:(become cache callback cliconf connection httpapi inventory lookup netconf shell vars module strategy test filter role keyword)' '(-r --roles-path)'{-r+,--roles-path=}'[specify directory containing roles]:directory:_directories' '*:plugin:->plugins' ) @@ -147,6 +146,7 @@ case $service in '--list-tags[list all available tags]' '--list-tasks[list all tasks that would be executed]' '--start-at-task=[start the playbook at specified task]:task' + "--syntax-check[perform a syntax check on the playbook, but don't execute it]" '--key-file=[specify file to use to authenticate the connection]:private key file:_files' '*:playbook:_files -g "(#i)*.y(|a)ml"' ) @@ -249,6 +249,7 @@ case $state in dump) args+=( '(--only-changed --changed-only)'{--only-changed,--changed-only}'[only show configuration that is changed from the default]' + '(-f --format)'{-f+,--format=}'[specify output format]:format:(json yaml display)' ) ;; init) @@ -257,6 +258,11 @@ case $state in '--disabled[prefix all entries with a comment character]' ) ;; + list) + args+=( + '(-f --format)'{-f+,--format=}'[specify output format]:format:(json yaml)' + ) + ;; esac _arguments -s -S : $args && ret=0 plug=${(v)opt_args[(i)-(t|-type)]} @@ -289,6 +295,7 @@ case $state in *-*) args+=( '(-c --ignore-certs)'{-c,--ignore-certs}'[ignore SSL certificate validation errors]' + '--timeout=[specify time to wait for operations against the galaxy]:timeout (seconds) [60]' '(-s --server)'{-s+,--server=}'[specify API server destination]:server:_hosts' --{token,api-key}='[specify ansible galaxy API key]:api key' \*{-v,--verbose}'[verbose mode]' -- cgit v1.2.3 From 424746982b47c4a202fe7e4ff9e401a6cd4c222d Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 14 Nov 2023 20:39:23 +0100 Subject: 52301: update options in completions for ruby 3.2, gem 3.4.10 and ri 6.5 --- ChangeLog | 4 ++++ Completion/Unix/Command/_gem | 34 ++++++++++++++++++++++---------- Completion/Unix/Command/_ri | 46 +++++++++++++++++++++---------------------- Completion/Unix/Command/_ruby | 4 ++-- 4 files changed, 52 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 41eb95097..cb3dbe6bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-11-14 Oliver Kiddle + * 52301: Completion/Unix/Command/_gem, Completion/Unix/Command/_ri, + Completion/Unix/Command/_ruby: update options in completions for + ruby 3.2, gem 3.4.10 and ri 6.5 + * 52300: Completion/Unix/Command/_ansible: ansible 2.15.2 updates 2023-11-09 Oliver Kiddle diff --git a/Completion/Unix/Command/_gem b/Completion/Unix/Command/_gem index 7d81619bb..c5a64cdf1 100644 --- a/Completion/Unix/Command/_gem +++ b/Completion/Unix/Command/_gem @@ -20,6 +20,7 @@ lropts=( $proxy _arguments -C -s \ '(* -)'{-h,--help}'[display usage information]' \ '(* -)'{-v,--version}'[display version information]' \ + '-C[change directory first]:directory:_directories' \ '*::command:->command' && ret=0 if [[ $state = command ]]; then @@ -27,7 +28,7 @@ if [[ $state = command ]]; then cmd=subcommands else cmds=( - build cert check cleanup contents dependency environment fetch + build cert check cleanup contents dependency environment exec fetch generate_index help install info list lock mirror open outdated owner pristine push query rdoc search server signin signout sources specification stale uninstall unpack update which yank @@ -87,13 +88,13 @@ if [[ $state = command ]]; then '!(-d --details)--no-details' ) ;| - check|contents|dependency|fetch|install|list|open|pristine|query|rdoc|search|specification|uninstall|unpack|yank) + check|contents|dependency|exec|fetch|install|list|open|pristine|query|rdoc|search|specification|uninstall|unpack|yank) args+=( '(-v --version)'{-v,--version=}'[specify version of gem]:version' ) ;| - dependency|fetch|install|outdated|specification|uninstall|update|yank) + build|dependency|fetch|install|outdated|specification|uninstall|update|yank) args+=( '--platform=[specify the platform of gem]:platform' ) ;| - dependency|fetch|install|list|query|search|specification|update) + dependency|exec|fetch|install|list|query|search|specification|update) args+=( '--prerelease[include prerelease versions of a gem]' '!(--prerelease)--no-prerelease' ) ;| install|unpack|update) @@ -125,13 +126,13 @@ if [[ $state = command ]]; then ;| (un|)install|pristine|update) args+=( + '(-i --install-dir)'{-i,--install-dir=}'[specify gem repository directory to get installed gems]:directory:_directories' '(-n --bindir)'{-n,--bindir=}'[specify directory where binary files are located]:directory:_directories' ) ;| (un|)install|update) args+=( '--ignore-dependencies[ignore dependency requirements]' - '(-i --install-dir)'{-i,--install-dir=}'[specify gem repository directory to get installed gems]:directory:_directories' ) ;| owner|push) @@ -166,6 +167,7 @@ if [[ $state = command ]]; then '(-b --build)'{-b,--build=}'[build private key and self-signed certificate for specified email address]:email address:_email_addresses -c' '(-C --certificate)'{-C,--certificate=}'[specify signing certificate for --sign]:certificate' '(-K --private-key)'{-K,--private-key=}'[specify key for --sign or --build]:key' + '(-A --key-algorithm)'{-A,--key-algorithm=}'[select which key algorithm to use for --build]:algorithm' '(-s --sign)'{-s,--sign=}'[sign specified certificate with the key from -K and the certificate from -C]:certificate' '(-d --days)'{-d,--days=}'[specify days before certificate expires]:days' '(-R --re-sign)'{-R,--re-sign}'[re-sign the certificate]' @@ -181,7 +183,7 @@ if [[ $state = command ]]; then ;; cleanup) args+=( - '(-n -d --dryrun)'{-n,-d,--dryrun}"[don't uninstall gems]" + '(-n -d --dry-run)'{-n,-d,--dry-run}"[don't uninstall gems]" "--user-install[cleanup in user's home directory instead of GEM_HOME]" ) ;; @@ -201,11 +203,20 @@ if [[ $state = command ]]; then ) ;; environment) - args+=( '1:information:(gemdir gempath version remotesources platform)' ) + args+=( '1:information:(gemdir gempath home path user_gemhome version remotesources platform)' ) + ;; + exec) + args+=( + '--conservative[prefer most recent installed version to the overall latest]' + '1:gem:->gems-remote' + '*: :_default' + ) ;; fetch) def=( both \! local \! remote \! ) - args+=( ${(e)lropts} ) + args+=( ${(e)lropts} + "--no-suggestions[don't suggest alternates when gems are not found]" + ) ;; generate_index) args+=( @@ -232,13 +243,15 @@ if [[ $state = command ]]; then args+=( '(*)*--skip=[with --all, skip specified gem]:installed gem:->gems-local' "--no-extensions[don't restore gems with extensions in addition to regular gems]" + '--only-missing-extensions[only restore gems with missing extensions]' '--only-executables[only restore executables]' + '--only-plugins[only restore plugins]' ) ;; push) args+=( '1:gem file:_files -g "*.gem(-.)"' ) ;; - query) + query) # deprecated args+=( '(-n --name-matches)'{-n,--name-matches=}'[specify regex to match against gem names]:gem name (regex):->gems-local' ) @@ -266,6 +279,7 @@ if [[ $state = command ]]; then '(-r --remove)'{-r,--remove=}'[remove source]:source URI:_urls' '(-c --clear-all)'{-c,--clear-all}'[remove all sources (clear the cache)]' '(-u --update)'{-u,--update}'[update source cache]' + '(-f --force)'{-f,--force}"[don't show any confirmation prompts]" ) ;; specification) @@ -319,7 +333,7 @@ if [[ $state = command ]]; then '--norc[avoid loading any .gemrc file]' && ret=0 if [[ $state == gems* ]]; then - filter=( ${${opt_args[(I)-([lbr]|-local|-remote|-both)]}:-${${(M)state:#*-*}/gems-/--}} ) + filter=( ${${opt_args[(I)-([lbr]|-conservative|-local|-remote|-both)]/conservative/local}:-${${(M)state:#*-*}/gems-/--}} ) _description gems expl gem compadd "$expl[@]" ${${(f)"$(_call_program gems gem list $filter -q --no-versions)"}%% *} && ret=0 fi diff --git a/Completion/Unix/Command/_ri b/Completion/Unix/Command/_ri index 4d5a72985..28de7a9a9 100644 --- a/Completion/Unix/Command/_ri +++ b/Completion/Unix/Command/_ri @@ -26,33 +26,22 @@ _arguments -C \ '*:ri name:->ri-name' && return if [[ "$state" = ri-name ]]; then - local -a ri_dirs ri_ext ri_names ri_wants ri_names + local -a ri_dirs ri_names ri_wants ri_names local class_dir esc_name dir curtag tag descr expl - if "ruby${words[1]#ri}" -rrdoc/ri/ri_options -e 1 >/dev/null 2>&1; then - # Old-style Ruby 1.8.x RI - ri_dirs=( ${(f)"$(_call_program ri-names "ruby${words[1]#ri}" -rrdoc/ri/ri_options -e '"o = RI::Options.instance; o.parse(ARGV); o.path.each { |p| puts p }"' -- ${(kv)opt_args[(I)-d|--doc-dir|--(system|site|gems|home)]})"} ) - ri_ext=yaml - elif "ruby${words[1]#ri}" -rrdoc/ri -rrdoc/ri/store -e 1 >/dev/null 2>&1; then - # Newer-style Ruby 1.9.2 RI - ri_dirs=( ${(f)"$(_call_program ri-names "$words[1]" ${(kv)opt_args[(I)-d|--doc-dir|--((no-|)(system|site|gems|home)|standard-docs)]} --list-doc-dirs -f bs -T)"} ) - ri_ext=ri - else - # New-style Ruby 1.9+ RI - ri_dirs=( ${(f)"$(_call_program ri-names "$words[1]" ${(kv)opt_args[(I)-d|--doc-dir|--((no-|)(system|site|gems|home)|standard-docs)]} --list-doc-dirs -f plain -T)"} ) - ri_ext=yaml - fi + ri_dirs=( ${(f)"$(_call_program ri-names "$words[1]" ${(kv)opt_args[(I)-d|--doc-dir|--((no-|)(system|site|gems|home)|standard-docs)]} --list-doc-dirs -f bs -T)"} ) - if compset -P '?*(::|\#|.)'; then + if compset -P '?*(::|:|\#|.)'; then class_dir=${IPREFIX//(::|\#|.)/\/} fi esc_name=${${(Q)PREFIX}//(#b)([^A-Za-z0-9_])/$(printf %%%x ${(qq)match[1]})} case "$IPREFIX" in - (*::) ri_wants=( 'classes:class names' 'class-methods:class methods' );; - (*\#) ri_wants=( 'instance-methods:instance methods' );; - (*.) ri_wants=( 'class-methods:class methods' 'instance-methods:instance methods' );; - (*) ri_wants=( 'classes:class names' ) + (*::) ri_wants=( 'classes:class name' 'class-methods:class method' );; + (*:) ri_wants=( 'docs:documentation file' );; + (*\#) ri_wants=( 'instance-methods:instance method' );; + (*.) ri_wants=( 'class-methods:class method' 'instance-methods:instance method' );; + (*) ri_wants=( 'classes:class name' 'gems:gem' ) esac for curtag in $ri_wants; do @@ -63,27 +52,36 @@ if [[ "$state" = ri-name ]]; then while _tags; do while _next_label "$tag" expl "$descr"; do ri_wants=() + suf=() case "$tag" in + (gems) + ri_wants=( ruby ${${(f)"$(_call_program gems gem${words[1]#ri} list -q --no-versions)"}%% *} ) + suf=( -S : ) + ;; (classes) for dir in $ri_dirs[@]; do ri_wants+=( $dir/$class_dir*(-/:t) ) done + suf=( -S '::' ) ;; (class-methods) for dir in $ri_dirs[@]; do - fnames=( $dir/$class_dir*-c.$ri_ext(-.:t) ) - ri_wants+=( ${${fnames%-c.$ri_ext}//(#b)%(??)/$(print "\\x$match[1]")} ) + fnames=( $dir/$class_dir*-c.ri(-.:t) ) + ri_wants+=( ${${fnames%-c.ri//(#b)%(??)/$(print "\\x$match[1]")} ) done ;; (instance-methods) for dir in $ri_dirs[@]; do - fnames=( $dir/$class_dir*-i.$ri_ext(-.:t) ) - ri_wants+=( ${${fnames%-i.$ri_ext}//(#b)%(??)/$(print "\\x$match[1]")} ) + fnames=( $dir/$class_dir*-i.ri(-.:t) ) + ri_wants+=( ${${fnames%-i.ri}//(#b)%(??)/$(print "\\x$match[1]")} ) done ;; + (docs) + ri_wants=( ${${(f)"$(_call_program docs $words[1] ${(kv)opt_args[(I)-d|--doc-dir|--((no-|)(system|site|gems|home)|standard-docs)]} $IPREFIX)"}:#=*} ) + ;; esac ri_names=( ${(Q)ri_wants} ) - compadd -S '' -d ri_names -a "$expl[@]" ri_wants && ret=0 + compadd $suf -d ri_names -a "$expl[@]" ri_wants && ret=0 done (( ret )) || break done diff --git a/Completion/Unix/Command/_ruby b/Completion/Unix/Command/_ruby index 314307ebb..b6b42637d 100644 --- a/Completion/Unix/Command/_ruby +++ b/Completion/Unix/Command/_ruby @@ -44,6 +44,7 @@ opts=( \!--{en,dis}able-{gems,rubyopt,all} '--dump=[dump debug information]:information:_sequence compadd - insns insns_without_opt yydebug parsetree parsetree_with_comment' --{external,internal}'-encoding=:charset:->charsets' + '--backtrace-limit=[limit the maximum length of backtrace]:number' '!'{-y,--yydebug} '!--dump=:target:(version copyright usage yydebug syntax parsetree parsetree_with_comment insns)' '(--mjit --yjit)--jit[enable jit for the platform]' @@ -65,11 +66,10 @@ opts=( irb=( '-f[suppress read of ~/.irbrc]' - '(--noinspect)-m[bc mode (load mathn, fraction, matrix)]' $opts[(r)*-d\[*] '(--noinspect)--inspect[use inspect for output]' "(--inspect)--noinspect[don't use inspect for output]" - '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--prompt,--prompt-mode}'[switch prompt mode]:prompt mode:(default simple xmp inf-ruby)' + '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--prompt=,--prompt-mode=}'[switch prompt mode]:prompt mode:(default classic simple inf-ruby xmp null)' '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--inf-ruby-mode,--simple-prompt,--noprompt} '--tracer[display trace for each command execution]' '--back-trace-limit[set limit for backtraces]:limit [16]:' -- cgit v1.2.3 From 5c7a97ff7d8f80a2ac823c47aaca26738e16f960 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 14 Nov 2023 21:19:30 +0100 Subject: unposted (cf. 52167): mutt's -a takes a list of files terminated by -- --- ChangeLog | 3 +++ Completion/Unix/Command/_mutt | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb3dbe6bd..2e5863fea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-11-14 Oliver Kiddle + * unposted (cf. 52167): Completion/Unix/Command/_mutt: + mutt's -a takes a list of files terminated by -- + * 52301: Completion/Unix/Command/_gem, Completion/Unix/Command/_ri, Completion/Unix/Command/_ruby: update options in completions for ruby 3.2, gem 3.4.10 and ri 6.5 diff --git a/Completion/Unix/Command/_mutt b/Completion/Unix/Command/_mutt index 9686ce6f1..82a6e5fa9 100644 --- a/Completion/Unix/Command/_mutt +++ b/Completion/Unix/Command/_mutt @@ -1,14 +1,15 @@ #compdef mutt neomutt -_arguments -s -S \ +# should pass -S but that doesn't work with -- ending -a +_arguments -s \ '::recipient:_email_addresses -n mutt' \ '(- :)-A[expand given alias]:alias:_email_addresses -n mutt' \ - '*-a[attach file using MIME]::file attachment:_files' \ + '*-a[attach file using MIME]:*--:file attachment:_files' \ '*-b[specify a BCC recipient]:BCC recipient:_email_addresses -n mutt' \ '*-c[specify a CC recipient]:CC recipient:_email_addresses -n mutt' \ '(- :)-D[print the value of all variables]' \ '(-x)-E[edit the draft (-H) or include (-i) file]' \ - '-d+[log debugging output to ~/.muttdebug0]:level:(1 2 3 4 5)' \ + '-d+[log debugging output to ~/.muttdebug0]:level:(-5 -4 -3 -2 -1 0 1 2 3 4 5)' \ '-e+[specify a post-init configuration command]:post-init configuration' \ '-f+[specify mailbox to load]:mailbox: _mailboxes' \ '-F+[specify an init file]:init file:_files' \ -- cgit v1.2.3 From be223aedee772fc31e12ec8c5277f50aae25b0fe Mon Sep 17 00:00:00 2001 From: Matt Koscica Date: Mon, 9 Oct 2023 22:26:27 +0200 Subject: github #106: update tmux completion (20230919); tweak Util/check-tmux-state - update tmux completion functions - tweak check-tmux-state to take current file format into account --- ChangeLog | 3 +++ Completion/Unix/Command/_tmux | 12 ++++++++++-- Util/check-tmux-state | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e5863fea..4f5c6b024 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-11-14 Oliver Kiddle + * github #106: Matt Koscica: Completion/Unix/Command/_tmux, + Util/check-tmux-state: update tmux completion (20230919) + * unposted (cf. 52167): Completion/Unix/Command/_mutt: mutt's -a takes a list of files terminated by -- diff --git a/Completion/Unix/Command/_tmux b/Completion/Unix/Command/_tmux index c8ed24b26..b9c220f17 100644 --- a/Completion/Unix/Command/_tmux +++ b/Completion/Unix/Command/_tmux @@ -145,7 +145,6 @@ _tmux_aliasmap=( if if-shell lock lock-server run run-shell - info server-info wait wait-for ) @@ -881,7 +880,7 @@ _tmux-send-prefix() { # aliasmap system in check-tmux-state can properly handle aliases which are # more complex than a single word, it's best to leave this here. -_tmux-server-info() { +_tmux-server-access() { [[ -n ${tmux_describe} ]] && print "show server information" && return __tmux-nothing-else } @@ -1654,6 +1653,7 @@ function __tmux-session-options() { 'lock-after-time:lock sessions after N seconds' 'lock-command:command to run for locking a client' 'message-command-style:status line message command style' + 'message-line:status message and command prompt position' 'message-style:status line message style' 'mouse:enable mouse support' 'prefix:primary prefix key' @@ -1798,6 +1798,7 @@ function __tmux-window-options() { local -a tmux_window_options tmux_window_options=( 'aggressive-resize:aggressively resize windows' + 'allow-passthrough:allow programs in the pane to bypass tmux' 'allow-rename:allow programs to change window titles' 'alternate-screen:allow alternate screen feature to be used' 'automatic-rename-format:format for automatic renames' @@ -1809,8 +1810,13 @@ function __tmux-window-options() { 'copy-mode-match-style:set the style of search matches in copy mode' 'cursor-colour:set the colour of the cursor' 'cursor-style:set the style of the cursor' + 'fill-character:set the character used to fill unused window areas' 'main-pane-height:set height for main-* layouts' 'main-pane-width:set width for main-* layouts' + 'menu-style:set the menu style' + 'menu-selected-style:set the selected menu item style' + 'menu-border-style:set the menu border style' + 'menu-border-lines:set the type of characters used for drawing menu borders' 'mode-keys:mode to use in copy and choice modes (vi/emacs)' 'mode-style:set window modes style' 'monitor-activity:monitor window activity' @@ -1830,6 +1836,8 @@ function __tmux-window-options() { "popup-border-style:set the style for the popup's border" 'popup-style:set the popup style' "remain-on-exit:don't destroy windows after the program exits" + "remain-on-exit-format:set the text shown at bottom of exited panes" + 'scroll-on-clear:scroll previous contents into history before clear' 'synchronize-panes:send input to all panes of a window' 'window-active-style:style of active window' 'window-size:indicate how to automatically size windows' diff --git a/Util/check-tmux-state b/Util/check-tmux-state index d95e0c230..9772eefc1 100755 --- a/Util/check-tmux-state +++ b/Util/check-tmux-state @@ -59,7 +59,7 @@ __tmux-window-options # in the _tmux function definition file. typeset -a supported_commands supported_commands=( $( grep '^_tmux-[^(]*() *{$' $func | - sed -e 's,^.*\<_tmux-,,' -e 's,(.*$,,' ) ) + sed -e 's,^_tmux[-]\([a-z-]*\)[(].*,\1,' ) ) # Ask tmux for available commands: typeset -a available_commands -- cgit v1.2.3 From e6ad117ccb548c8411610571c92fa4094f275460 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 15 Nov 2023 20:16:04 -0800 Subject: 52202: improve handling of quoting in ${var/pattern/replacement} --- ChangeLog | 6 ++++++ Src/lex.c | 53 ++++++++++++++++++++++++++++++-------------------- Src/subst.c | 7 +++++++ Test/D04parameter.ztst | 8 ++++---- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f5c6b024..6baa171dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-11-15 Bart Schaefer + + * 52202: Src/lex.c, Src/subst.c, Test/D04parameter.ztst: improve + handling of quoting in ${var/pattern/replacement}. Still not + perfect, e.g., deeply nested expansions in the pattern may fail. + 2023-11-14 Oliver Kiddle * github #106: Matt Koscica: Completion/Unix/Command/_tmux, diff --git a/Src/lex.c b/Src/lex.c index 33b17cc95..31b130b07 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -938,7 +938,7 @@ gettokstr(int c, int sub) { int bct = 0, pct = 0, brct = 0, seen_brct = 0, fdpar = 0; int intpos = 1, in_brace_param = 0, cmdsubst = 0; - int inquote, unmatched = 0; + int inquote, unmatched = 0, in_pattern = 0; enum lextok peek; #ifdef DEBUG int ocmdsp = cmdsp; @@ -1160,7 +1160,7 @@ gettokstr(int c, int sub) if (bct-- == in_brace_param) { if (cmdsubst) cmdpop(); - in_brace_param = cmdsubst = 0; + in_brace_param = cmdsubst = in_pattern = 0; } c = Outbrace; break; @@ -1309,7 +1309,8 @@ gettokstr(int c, int sub) lexbuf.ptr--, lexbuf.len--; else break; - } + } else if (in_pattern && c == '/') + add(Bnull); add(c); } ALLOWHIST @@ -1397,26 +1398,36 @@ gettokstr(int c, int sub) */ c = Dash; break; - case LX2_BANG: - /* - * Same logic as Dash, for ! to perform negation in range. - */ - if (seen_brct) - c = Bang; - else - c = '!'; - } - add(c); - c = hgetc(); - if (intpos) + case LX2_BANG: + /* + * Same logic as Dash, for ! to perform negation in range. + */ + if (seen_brct) + c = Bang; + else + c = '!'; + case LX2_OTHER: + if (in_brace_param) { + if (c == '/') { + if (in_pattern == 0) + in_pattern = 2; + else + --in_pattern; + } + } + } + add(c); + c = hgetc(); + if (intpos) intpos--; - if (lexstop) + if (lexstop) break; - if (!cmdsubst && in_brace_param && act == LX2_STRING && - (c == '|' || c == Bar || inblank(c))) { - cmdsubst = in_brace_param; - cmdpush(CS_CURSH); - } + if (!cmdsubst && in_brace_param && act == LX2_STRING && + (c == '|' || c == Bar || inblank(c))) { + cmdsubst = in_brace_param; + cmdpush(CS_CURSH); + } else if (in_pattern == 2 && c != '/') + in_pattern = 1; } brk: if (errflag) { diff --git a/Src/subst.c b/Src/subst.c index 60d850feb..4ef1d1269 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3088,6 +3088,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, chuck(ptr); else ptr++; + } else if (c == Dnull) { + chuck(ptr); + while (*ptr && *ptr != c) + ptr++; + if (*ptr == Dnull) + chuck(ptr); + ptr--; /* Outer loop is about to increment */ } } replstr = (*ptr && ptr[1]) ? ptr+1 : ""; diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index c2008582c..69a4fd3ec 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2762,13 +2762,13 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888 slash='/' print -r -- x${slash/'/'}y --Df:(users/28784) substituting a single-quoted backslash, part #1: slash +0:(users/28784) substituting a single-quoted backslash, part #1: slash >xy single_quote="'" - print -r -- x${single_quote/'/'}y --Df:(users/28784) substituting a single-quoted backslash, part #2: single quote ->x/y + print -r -- x${single_quote/$'/'}y +0:(users/28784) substituting a single-quoted backslash, part #2: single quote +>x'y control="foobar" print -r -- x${control/'bar'}y -- cgit v1.2.3 From 420d2c713f95cade62a8db77229c2649252e348d Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 15 Nov 2023 20:21:51 -0800 Subject: 52275: rationality in zgetdir() and zgetcwd() --- ChangeLog | 4 +++ Src/compat.c | 100 +++++++++++++++++++++++++++++++---------------------------- 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6baa171dc..4c94edd3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-11-15 Bart Schaefer + * 52275: Src/compat.c: rationality in zgetdir() and zgetcwd() to + avoid silently wandering out of the current directory when path + parents are inaccessible. + * 52202: Src/lex.c, Src/subst.c, Test/D04parameter.ztst: improve handling of quoting in ${var/pattern/replacement}. Still not perfect, e.g., deeply nested expansions in the pattern may fail. diff --git a/Src/compat.c b/Src/compat.c index 817bb4aaf..8b31ad9f4 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -342,36 +342,69 @@ zopenmax(void) mod_export char * zgetdir(struct dirsav *d) { - char nbuf[PATH_MAX+3]; char *buf; +#if defined(HAVE_GETCWD) || defined(__CYGWIN__) + char *cwdbuf; +#endif +#if defined(USE_GETCWD) || defined(__CYGWIN__) +#ifdef GETCWD_CALLS_MALLOC + if ((cwdbuf = getcwd(NULL, 0))) { + buf = dupstring(cwdbuf); + free(cwdbuf); + } else + buf = NULL; +#else + cwdbuf = zalloc(PATH_MAX+1); + if ((buf = getcwd(cwdbuf, PATH_MAX))) + buf = dupstring(buf); + zfree(cwdbuf, PATH_MAX+1); +#endif /* GETCWD_CALLS_MALLOC */ + if (d && buf) + return d->dirname = ztrdup(buf); + else + return buf; +#else /* !USE_GETCWD && !__CYGWIN__ */ int bufsiz, pos; - struct stat sbuf; - ino_t pino; - dev_t pdev; -#if !defined(__CYGWIN__) && !defined(USE_GETCWD) + char nbuf[PATH_MAX+3]; struct dirent *de; DIR *dir; - dev_t dev; - ino_t ino; + struct stat sbuf; + ino_t pino, ino; + dev_t pdev, dev; int len; -#endif + strcpy(nbuf, "../"); + if (stat(".", &sbuf) == 0) { + /* Record the initial inode and device */ + pino = sbuf.st_ino; + pdev = sbuf.st_dev; + if (d) + d->ino = pino, d->dev = pdev; + } +#ifdef HAVE_GETCWD + else { +#ifdef GETCWD_CALLS_MALLOC + if ((cwdbuf = getcwd(NULL, 0))) { + buf = dupstring(cwdbuf); + free(cwdbuf); + } else + buf = NULL; +#else + cwdbuf = zalloc(PATH_MAX+1); + if ((buf = getcwd(cwdbuf, PATH_MAX))) + buf = dupstring(buf); + zfree(cwdbuf, PATH_MAX+1); +#endif /* GETCWD_CALLS_MALLOC */ + return buf; /* NULL when stat() and getcwd() both failed */ + } +#endif + /* stat() succeeded */ buf = zhalloc(bufsiz = PATH_MAX+1); pos = bufsiz - 1; buf[pos] = '\0'; - strcpy(nbuf, "../"); - if (stat(".", &sbuf) < 0) { - return NULL; - } - /* Record the initial inode and device */ - pino = sbuf.st_ino; - pdev = sbuf.st_dev; - if (d) - d->ino = pino, d->dev = pdev; -#if !defined(__CYGWIN__) && !defined(USE_GETCWD) #ifdef HAVE_FCHDIR - else + if (!d) #endif holdintr(); @@ -487,18 +520,6 @@ zgetdir(struct dirsav *d) zchdir(buf + pos + 1); noholdintr(); -#else /* __CYGWIN__, USE_GETCWD cases */ - - if (!getcwd(buf, bufsiz)) { - if (d) { - return NULL; - } - } else { - if (d) { - return d->dirname = ztrdup(buf); - } - return buf; - } #endif /* @@ -526,23 +547,6 @@ mod_export char * zgetcwd(void) { char *ret = zgetdir(NULL); -#ifdef HAVE_GETCWD - if (!ret) { -#ifdef GETCWD_CALLS_MALLOC - char *cwd = getcwd(NULL, 0); - if (cwd) { - ret = dupstring(cwd); - free(cwd); - } -#else - char *cwdbuf = zalloc(PATH_MAX+1); - ret = getcwd(cwdbuf, PATH_MAX); - if (ret) - ret = dupstring(ret); - zfree(cwdbuf, PATH_MAX+1); -#endif /* GETCWD_CALLS_MALLOC */ - } -#endif /* HAVE_GETCWD */ if (!ret) ret = unmeta(pwd); if (!ret || *ret == '\0') -- cgit v1.2.3 From 0840f34e1fb38df43b69bc5f189babfc938e3c63 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 15 Nov 2023 20:23:54 -0800 Subject: 52308: FAQ for new features, fix some old answers --- ChangeLog | 2 + Etc/FAQ.yo | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 123 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c94edd3c..10631b9e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-11-15 Bart Schaefer + * 52308: Etc/FAQ.yo: mention new features, fix some old answers + * 52275: Src/compat.c: rationality in zgetdir() and zgetcwd() to avoid silently wandering out of the current directory when path parents are inaccessible. diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 8c795685a..270a04608 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -445,7 +445,14 @@ label(21) invoked with the appropriate name. Including the command `emulate sh; setopt localoptions' in a shell function will turn on sh emulation for that function only. In version 4 (and in - 3.0.6 through 8), this can be abbreviated as `emulate -L sh'. + 3.0.6 through 8), this can be abbreviated as `emulate -L sh'; + myeit() in versions after 5.9, the myem(namespace) syntax and + myem(named references) (ksh mytt(nameref)) are available, but + differ in some details from the ksh93+ semantics; + myeit() also after 5.9, myem(non-forking command substitutions) are + available. These are described by ksh as myem(a brace group preceded + by a dollar sign) (mytt(${ list;})), but zsh has both some added + features adopted from mksh, and some limitations, see link(2.11)(211) ) The classic difference is word splitting, discussed in question \ @@ -496,9 +503,9 @@ tt(RM_STAR_SILENT), those are a completely different type of object.) it() Coprocesses are established by mytt(coproc); mytt(|&) behaves like csh. Handling of coprocess file descriptors is also different. - it() In mytt(cmd1 && cmd2 &), only mytt(cmd2) instead of the whole - expression is run in the background in zsh. The manual implies - this is a bug. Use mytt({ cmd1 && cmd2 } &) as a workaround. + it() In mytt(cmd1 && cmd2 &), instead of backgrounding the whole + expression, only mytt(cmd2) is run in the background in zsh. + Use mytt(( cmd1 && cmd2 ) &) as a workaround. ) it() Command line substitutions, globbing etc.: itemization( @@ -960,6 +967,106 @@ label(28) languages and adjusting it accordingly, just like you would when translating a book from American English to British English. +sect(What is a mytt(namespace) anyway?) +label(29) + + As of this writing, namespaces in zsh are little more than syntactic + sugar for grouping related parameters. For example, as of the update + to PCRE2, the parameters ${.pcre.match} and ${.pcre.subject} are used + for regular expression substring capture. The mytt(.pcre.) part is + the namespace, and when you refer to a parameter that has one, you + mybf(must) use the mytt(${...}) braces around the name. Assignments + are not special, they have the form mytt(.nspace.var=value) as usual. + + Parameters using a namespace have the additional property that, like + file names beginning with a dot for globbing, they're hidden from + mytt(typeset) output unless explicitly asked for. + + Namespaces appear in releases after but not including zsh 5.9. + +sect(What about named references?) +label(210) + + Named references are a bit like aliases, but for parameters. A named + reference would typically be usable in the same cases as ${(P)name} + (see link(3.22)(322)). The value of a named reference is the name + of another parameter, and when you expand or assign to the named + reference, that other parameter is expanded or assigned instead. + Thus a trivial example is + verb( + % target=RING + % typeset -n ref=target + % print $ref + RING + % ref=BULLSEYE + % print $target + BULLSEYE + ) + + One exception to this behavior is when a named reference is used as + the loop variable in a mytt(for) loop. In that case the reference is + unset and reset on each iteration of the loop. + verb( + % target=RING bullseye=SPOT other=MISS + % typeset -n ref=other + % for ref in target bullseye; do + > print $ref + > ref=HIT:$ref + > done + RING + SPOT + % print $other + MISS + % print $ref + HIT:SPOT + ) + + Named references may be used in zsh versions later than 5.9. + +sect(What is zsh's support for non-forking command substitution?) +label(211) + + This is for cases where you'd write mytt($(command)) but you don't want + the overhead or other issues associated with forking a subshell. + There are 3 variations: + enumeration( + myeit() Borrowed from mksh + verb( + ${| code } + ) + Runs code in the current shell context and then substitutes mytt(${REPLY}). + + myeit() An extension to #1 + verb( + ${|var| code } + ) + Runs code in the current shell and then substitutes mytt(${var}). + + myeit() The traditional ksh form, except that the closing mytt(;) + may usually be omitted: + verb( + ${ code } + ) + Runs code in the current shell and substitutes its standard output. + (this is done with a temporary file ala mytt($(<=( code ))) but + without the fork implied by mytt(=(...))). + ) + + In all three forms mytt(code) behaves myem(similarly) to an anonymous + function invoked like: + verb( + () { local REPLY; code } "$@" + ) + Thus, mytt($REPLY) is implicitly local and returns to its previous + value after the substitution ends, all other parameters declared from + inside the substitution are also local by default, and positional + parameters mytt($1), mytt($2), etc. are those of the calling context. + + The most significant limitation is that braces (mytt({) and mytt(})) + within the substitutions must either be in balanced pairs, or must be + quoted, that is, included in a quoted string or prefixed by backslash. + These substitutions first become usable after zsh 5.9. + chapter(How to get various things to work) sect(Why does mytt($var) where mytt(var="foo bar") not do what I expect?) @@ -1641,6 +1748,7 @@ label(321) manual. sect(How do I get a variable's value to be evaluated as another variable?) +label(322) The problem is that you have a variable tt($E) containing the string mytt(EDITOR), and a variable tt($EDITOR) containing the string mytt(emacs), @@ -2509,14 +2617,11 @@ sect(What's on the wish-list?) characters. Initial support for this appeared in version 4.3; it is reasonably complete in the line editor but patchy elsewhere (note this may require the configuration option --enable-multibyte). - it() The parameter code could do with tidying up, maybe with more of the - features made available in ksh93. + it() The parameter code could do with tidying up. it() Configuration files to enable zsh startup files to be created with the Dotfile Generator. it() Further improvements in integrating the line editor with shell functions. - it() POSIX compatibility could be improved. - it() Option for glob qualifiers to follow perl syntax (a traditional item). ) sect(Did zsh have problems in the year 2000?) @@ -2618,11 +2723,12 @@ https://github.com/chrisbra/vim_faq/blob/de424bd8e08bcf0e6b1e0563ee49514dfed926a nsect(Acknowledgments:) -Thanks to zsh-list, in particular Bart Schaefer, for suggestions +Thanks to zsh-workers, in particular Bart Schaefer, for suggestions regarding this document. Zsh has been in the hands of archivists Jim Mattson, Bas de Bakker, Richard Coleman, Zoltan Hidvegi and Andrew -Main, and the mailing list has been run by Peter Gray, Rick Ohnemus, -Richard Coleman, Karsten Thygesen and Geoff Wing, all of whom deserve +Main, and the mailing lists have been managed or hosted by Peter Gray, +Rick Ohnemus, Richard Coleman, Karsten Thygesen, Geoff Wing, Phil +Pennock, Daniel Shahaf, and Oliver Kiddle, all of whom deserve thanks. The world is eternally in the debt of Paul Falstad for inventing zsh in the first place (though the wizzo extended completion is by Sven Wischnowsky). @@ -2630,15 +2736,15 @@ Wischnowsky). nsect(Copyright Information:) This document is copyright (C) P.W. Stephenson, 1995, 1996, 1997, -1998, 1999, 2000, 2012, 2020. This text originates in the U.K. and the author -asserts his moral rights under the Copyrights, Designs and Patents Act, -1988. +1998, 1999, 2000, 2012, 2020, 2023. This text originates in the U.K. +and the author asserts his moral rights under the Copyrights, Designs +and Patents Act, 1988. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this documentation for any purpose, provided that the above copyright notice appears in all copies of this documentation. Remember, -however, that this document changes monthly and it may be more useful +however, this document changes occasionally and it may be more useful to provide a pointer to it rather than the entire text. A suitable pointer is "information on the Z-shell can be obtained on the World Wide Web at URL https://zsh.sourceforge.io/". -- cgit v1.2.3 From ddfc81a2b81e19c13f60bfff30f28ed520df8f57 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 15 Nov 2023 20:29:50 -0800 Subject: 52309: fix cases that hang with all signals blocked. * no job control inside <<(substition) * allow interrupt of multios reading from a terminal --- ChangeLog | 4 ++++ Src/exec.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 10631b9e3..0de5c2fcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-11-15 Bart Schaefer + * 52309: Src/exec.c: suppress job control inside <<(substition) + to fix cases that hang with all signals blocked. Similarly, + allow interrupt of multios reading from a terminal. + * 52308: Etc/FAQ.yo: mention new features, fix some old answers * 52275: Src/compat.c: rationality in zgetdir() and zgetcwd() to diff --git a/Src/exec.c b/Src/exec.c index 285d2c5ad..97823760f 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2309,7 +2309,7 @@ closemn(struct multio **mfds, int fd, int type) for (i = 0; i < mn->ct; i++) while ((len = read(mn->fds[i], buf, TCBUFSIZE)) != 0) { if (len < 0) { - if (errno == EINTR) + if (errno == EINTR && !isatty(mn->fds[i])) continue; else break; @@ -5096,7 +5096,7 @@ getpipe(char *cmd, int nullexec) procsubstpid = pid; return pipes[!out]; } - entersubsh(ESUB_ASYNC|ESUB_PGRP, NULL); + entersubsh(ESUB_ASYNC|ESUB_PGRP|ESUB_NOMONITOR, NULL); redup(pipes[out], out); closem(FDT_UNUSED, 0); /* this closes pipes[!out] as well */ cmdpush(CS_CMDSUBST); -- cgit v1.2.3 From 6306dcfaa52237fbaa76eafe7bc396e68eda66ca Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 17 Nov 2023 18:13:41 +0100 Subject: 52303: updates to completions for macOS 13 --- ChangeLog | 14 ++++++++++++++ Completion/Unix/Command/_chown | 7 ++++++- Completion/Unix/Command/_cp | 8 +++++--- Completion/Unix/Command/_cut | 2 +- Completion/Unix/Command/_date | 20 +++++++++----------- Completion/Unix/Command/_du | 8 ++++---- Completion/Unix/Command/_env | 4 +++- Completion/Unix/Command/_id | 4 ++-- Completion/Unix/Command/_ifconfig | 18 ++++++++++++------ Completion/Unix/Command/_ln | 12 ++++-------- Completion/Unix/Command/_ls | 33 +++++++++++++++++++-------------- Completion/Unix/Command/_make | 2 +- Completion/Unix/Command/_mount | 8 ++++++-- Completion/Unix/Command/_mv | 12 ++++++------ Completion/Unix/Command/_rm | 6 +----- Completion/Unix/Command/_sed | 5 ++--- Completion/Unix/Command/_split | 4 ++-- Completion/Unix/Command/_touch | 2 +- Completion/Unix/Command/_uniq | 2 +- Completion/Unix/Command/_xargs | 2 +- 20 files changed, 100 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0de5c2fcb..5b50aa342 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2023-11-17 Oliver Kiddle + + * 52303: Completion/Unix/Command/_ifconfig, + Completion/Unix/Command/_chown, Completion/Unix/Command/_cp, + Completion/Unix/Command/_cut, Completion/Unix/Command/_date, + Completion/Unix/Command/_du, Completion/Unix/Command/_env, + Completion/Unix/Command/_id, Completion/Unix/Command/_ln, + Completion/Unix/Command/_ls, Completion/Unix/Command/_make, + Completion/Unix/Command/_mount, Completion/Unix/Command/_mv, + Completion/Unix/Command/_rm, Completion/Unix/Command/_sed, + Completion/Unix/Command/_split, Completion/Unix/Command/_touch, + Completion/Unix/Command/_uniq, Completion/Unix/Command/_xargs: + updates to completions for macOS 13 + 2023-11-15 Bart Schaefer * 52309: Src/exec.c: suppress job control inside <<(substition) diff --git a/Completion/Unix/Command/_chown b/Completion/Unix/Command/_chown index 9ebbf7bab..4362d6e75 100644 --- a/Completion/Unix/Command/_chown +++ b/Completion/Unix/Command/_chown @@ -43,7 +43,7 @@ case "$variant" in '(-H -L -P)-P[do not follow symlinks (default)]' ) ;| - dragonfly*|freebsd*) + dragonfly*|freebsd*|darwin*) args+=( "-x[don't traverse file systems]" ) @@ -63,6 +63,11 @@ case "$variant" in '-s[owner and/or group are Windows SID strings]' ) ;; + darwin*) + args+=( + '-n[interpret user and group as numeric, avoiding name lookups]' + ) + ;; esac (( $+words[(r)--reference*] )) || args+=( '(--reference)1: :->owner' ) diff --git a/Completion/Unix/Command/_cp b/Completion/Unix/Command/_cp index f7411055b..da9428ce3 100644 --- a/Completion/Unix/Command/_cp +++ b/Completion/Unix/Command/_cp @@ -51,14 +51,16 @@ else '(aix|hpux|irix|solaris)*' '-r[copy directories recursively]' \ 'solaris2.<9->*' '-@[preserve extended attributes]' \ 'solaris2.<11->*' '-/[preserve extended attributes and extended system attributes]' \ + 'solaris2.<11->*' '-z[fast relink(3C) based copy]' \ '(darwin|dragonfly|freebsd)*' "(-f -i)-n[don't overwrite existing file]" \ 'netbsd*' "-N[don't copy file flags]" \ '(darwin|dragonfly|freebsd|netbsd|openbsd)*' '-a[archive mode, same as -RpP]' \ - '(dragonfly|freebsd)*' '-l[link files instead of copying]' \ + '(dragonfly|freebsd|darwin)*' '-l[link files instead of copying]' \ '(darwin|dragonfly|*bsd)*' '-v[show file names as they are copied]' \ 'darwin*' "-X[don't copy extended attributes or resource forks]" \ - '(dragonfly|freebsd)*' "-x[don't traverse file systems]" \ - 'freebsd<10->.*' '-s[make symbolic links instead of copies of non-directories]' + '(dragonfly|freebsd|darwin)*' "-x[don't traverse file systems]" \ + '(freebsd<10->.|darwin)*' '-s[make symbolic links instead of copies of non-directories]' \ + 'darwin*' '-c[copy files using clonefile(2)]' do [[ $OSTYPE = $~pattern ]] && args+=( $arg ) done diff --git a/Completion/Unix/Command/_cut b/Completion/Unix/Command/_cut index 29565280d..778439cf1 100644 --- a/Completion/Unix/Command/_cut +++ b/Completion/Unix/Command/_cut @@ -46,7 +46,7 @@ if _pick_variant gnu="Free Soft" unix --version; then '*:file:_files' else case $OSTYPE in - freebsd*|dragonfly*) args=( '(-d)-w[use whitespace as the delimiter]' ) ;; + freebsd*|dragonfly*|darwin*) args=( '(-d)-w[use whitespace as the delimiter]' ) ;; esac _arguments $args \ "-b[${_cut_args[bytes]}]:list" \ diff --git a/Completion/Unix/Command/_date b/Completion/Unix/Command/_date index a15d30b21..f0053ec02 100644 --- a/Completion/Unix/Command/_date +++ b/Completion/Unix/Command/_date @@ -7,8 +7,8 @@ local -a opts args opts=( -s -w -C ) if _pick_variant gnu="Free Software Foundation" unix --version; then - local d='(-d --date -f --file -r --reference -s --set)' - local f='(-I --iso-8601 -R --rfc-email --rfc-3339)' + local d='(-d --date -f --file -r --reference -s --set --resolution)' + local f='(-I --iso-8601 -R --rfc-email --rfc-3339 --resolution)' args=( $d{-d+,--date=}'[output date specified by string]:time string' '--debug[annotate parsed date and warn about questionable usage]' @@ -16,10 +16,10 @@ if _pick_variant gnu="Free Software Foundation" unix --version; then $d{-r+,--reference=}'[output last modification time of specified file]:file:_files' $d{-s+,--set=}'[set time]:time string' $f{-I-,--iso-8601=-}'[display in ISO 8601 format]::precision:(date hours minutes seconds ns)' + '(-)--resolution[output the available resolution of timestamps]' $f{-R,--rfc-email}'[display in RFC5322 format]' $f'--rfc-3339=-[display in RFC 3339 format]:precision:(date seconds ns)' - '(-u --utc --universal)'{-u,--utc,--universal}'[display or set time in UTC]' - $d'--resolution[output the available resolution of timestamps]' + '(-u --utc --universal --resolution)'{-u,--utc,--universal}'[display or set time in UTC]' '(- :)--help[output help and exit]' '(- :)--version[output version info and exit]' ) @@ -44,12 +44,12 @@ else '-f+[use specified format for input]:parsing format:_date_formats:new date' ) ;| - dragonfly*|darwin*|netbsd*|openbsd*) + dragonfly*|netbsd*|openbsd*) args+=( '-r+[output date specified by reference time]:seconds since epoch' ) ;| - freebsd*) + freebsd*|darwin*) local -a alts alts=( 'seconds:sec:_guard "(0x[0-9a-fA-F]#|[0-9]#)" "seconds since epoch"' @@ -57,23 +57,21 @@ else ) args+=( '-r+[reference time: file modification or literal time]:reference: _alternative $alts' - '(-R)-I-[display in ISO 8601 format]::precision:(date hours minutes seconds)' ) ;| freebsd*|dragonfly*|darwin*) args+=( + '-R[display in RFC2822 format]' + '(-R)-I-[display in ISO 8601 format]::precision [date]:(date hours minutes seconds)' "*-v+[adjust and print (but don't set) date]:[+-]value[ymwdHMS]" ) ;| - freebsd<-12>.*|darwin*) + freebsd<-12>.*) args+=( '-d+:daylight saving time value' '-t+:minutes west of GMT' ) ;| - freebsd*|dragonfly*) - args+=( '-R[display in RFC2822 format]' ) - ;| openbsd*|netbsd*) args+=( '-a[gradually skew]' ) ;| freebsd<14->.*|openbsd*) diff --git a/Completion/Unix/Command/_du b/Completion/Unix/Command/_du index 711f43471..ccb5bdd94 100644 --- a/Completion/Unix/Command/_du +++ b/Completion/Unix/Command/_du @@ -55,7 +55,7 @@ else ) local xdev='[skip directories on different filesystems]' for pattern arg in \ - 'freebsd*' '-A[apparent size instead of usage]' \ + '(freebsd|darwin)*' '-A[apparent size instead of usage]' \ '(darwin*|*bsd*|dragonfly*|solaris2.<10->)' '(-H -L -P)-H[follow symlinks on the command line]' \ '(darwin|*bsd|dragonfly)*' '(-H -L -P)-P[do not follow symlinks (default)]' \ '(darwin|dragonfly|freebsd)*' '*-I+[ignore files/directories matching specified mask]:mask' \ @@ -64,12 +64,12 @@ else 'netbsd*' '-i[output inode usage instead of blocks]' \ '(darwin*|freebsd*|netbsd*|solaris2.<11->)' '(-h -k -g -B)-m[use block size of 1M-byte]' \ '(darwin|freebsd<8->.|netbsd)*' '(-h -k -m -B)-g[use block size of 1G-byte]' \ - 'freebsd*' '(-h -k -m -g)-B+[block size]:block size (bytes)' \ + '(freebsd|darwin)*' '(-h -k -m -g)-B+[block size]:block size (bytes)' \ '(darwin|*bsd|dragonfly)*' '-c[display grand total]' \ - 'freebsd*' '-l[count sizes many times if hard linked]' \ + '(freebsd|darwin)*' '-l[count sizes many times if hard linked]' \ '(freebsd|netbsd)*' '-n[ignore files and directories with nodump flag set]' \ 'solaris*' "(-a)-o[don't add child directories' usage to parent's total]" \ - 'freebsd<8->.*' '-t+[report only entries for which size exceeds threshold]:threshold' \ + '(freebsd|darwin)*' '-t+[report only entries for which size exceeds threshold]:threshold' \ 'solaris*' "-d$xdev" \ '(darwin|*bsd|dragonfly|solaris)*' "-x$xdev" do diff --git a/Completion/Unix/Command/_env b/Completion/Unix/Command/_env index bdab71bbe..8cf0ad467 100644 --- a/Completion/Unix/Command/_env +++ b/Completion/Unix/Command/_env @@ -24,11 +24,13 @@ case $variant in ;; freebsd*) args=( - '-0[use NUL, not newline after each variable in output]' '-L[add variables from system login.conf(5)]: :->user-class' '-U[add variables from user and system login.conf(5)]: :->user-class' ) ;| + freebsd*|darwin*) + args=( '-0[use NUL, not newline after each variable in output]' ) + ;| freebsd*|darwin*|dragonfly*) args+=( '(-i)*-u+[remove variable from the environment]:env var to remove:_parameters -g "*export*"' diff --git a/Completion/Unix/Command/_id b/Completion/Unix/Command/_id index a0a03faad..c123afcd7 100644 --- a/Completion/Unix/Command/_id +++ b/Completion/Unix/Command/_id @@ -41,13 +41,13 @@ else darwin*|dragonfly*|freebsd*) args+=( '(-)-P[print id in the form of a password file entry]' ) ;| - darwin*|freebsd*) + freebsd*) args+=( '(-)-A[print process audit user ID]' '(-)-M[print MAC label of the current process]' + '(-)-c[print current login class]' ) ;| - freebsd*) args+=( '(-)-c[print current login class]' ) ;| darwin*|dragonfly*|freebsd*|netbsd*|openbsd*) args+=( '(-)-p[human readable output]' ) ;; diff --git a/Completion/Unix/Command/_ifconfig b/Completion/Unix/Command/_ifconfig index 4e1f25e2e..86ec46038 100644 --- a/Completion/Unix/Command/_ifconfig +++ b/Completion/Unix/Command/_ifconfig @@ -13,15 +13,16 @@ updownlist=( case $OSTYPE in darwin*) - args=( -s $updownlist ) + args=( -s $updownlist + '-X+[list interfaces whose names match regular expression]:regex:_net_interfaces' + ) opts=( $alias $debug delete dest_address ipdst nsellength {,-}trailers {,-}link{0,1,2} ) - ;; + ;| freebsd*|dragonfly*) args=( -s $updownlist - '(-a -j -f -l -G -g -u -d -m -L 1 *)-C[list interface cloners]' '(-C)-f+[control the output format]: :_values -s, -S\: format "addr[adjust inet address display]\:format [numeric]\:(default fqdn host numeric)" "ether[adjust ethernet address display]\:format [colon]\:(colon dash dotted default)" @@ -30,10 +31,7 @@ case $OSTYPE in '(-C)-G+[exclude members of the specified group]:group' '(-C)-g+[limit output to members of the specified group]:group' '(-C)-k[print keying information for the interface]' - '(-l -C)-m[list supported media]' '(-C)-n[disable automatic loading of network interface drivers]' - '(-l -C)-L[show address lifetime as time offset]' - '(-C)-v[get more verbose status for an interface]' ) listopts=( active caps chan countries mac mesh regdomain roam txparam txpower @@ -47,6 +45,14 @@ case $OSTYPE in roam roam:rssi roam:rate roaming ) ;| + freebsd*|darwin*|dragonfly*) + args+=( + '(-a -j -f -l -G -g -u -d -m -L 1 *)-C[list interface cloners]' + '(-l -C)-m[list supported media]' + '(-l -C)-L[show address lifetime as time offset]' + '(-C)-v[get more verbose status for an interface]' + ) + ;| freebsd<14->.*) args+=( '(-C)-j+[perform actions inside jail]:jail:_jails' ) ;; diff --git a/Completion/Unix/Command/_ln b/Completion/Unix/Command/_ln index 9d5efcabb..7bd2f7f27 100644 --- a/Completion/Unix/Command/_ln +++ b/Completion/Unix/Command/_ln @@ -45,9 +45,11 @@ case $variant; in {-h,-n}'[do not dereference destination]' '(-f)-i[prompt before removing destination files]') ;; - darwin*|dragonfly*|freebsd*|netbsd*|openbsd*) + darwin*|dragonfly*|*bsd*) args+=( - {-h,-n}'[do not dereference destination]' + {-h,-n}"[don't dereference destination]" + '(-L)-P[create hard links directly to symbolic links]' + '(-P)-L[create hard links to symbolic link references]' ) ;| darwin*|dragonfly*|freebsd*|netbsd*) @@ -57,12 +59,6 @@ case $variant; in '-v[print name of each linked file]' ) ;| - dragonfly*|freebsd*|netbsd*|openbsd*) - args+=( - '(-L)-P[create hard links directly to symbolic links]' - '(-P)-L[create hard links to symbolic link references]' - ) - ;| dragonfly*|freebsd*|netbsd*) args+=( "-w[warn if source of a symbolic link doesn't currently exist]" diff --git a/Completion/Unix/Command/_ls b/Completion/Unix/Command/_ls index 975a28196..392b8490b 100644 --- a/Completion/Unix/Command/_ls +++ b/Completion/Unix/Command/_ls @@ -75,12 +75,12 @@ if ! _pick_variant gnu=gnu unix --help; then if [[ $OSTYPE = (dragonfly*|freebsd*|darwin*) ]]; then arguments+=( '-G[enable colorized output]' + '(-A)-I[prevent -A from being automatically set for the super-user]' '-P[do not follow symlinks]' ) fi if [[ $OSTYPE = (dragonfly*|freebsd*) ]]; then arguments+=( - '(-A)-I[prevent -A from being automatically set for the super-user]' '(-1 -C -m -x)-D+[specify format for date]:format: _date_formats' ) fi @@ -91,15 +91,17 @@ if ! _pick_variant gnu=gnu unix --help; then ) fi if [[ $OSTYPE = (freebsd*|darwin*) ]]; then - arguments+=( '(-c -u)-U[file creation time]' ) + arguments+=( + '-,[print file sizes grouped and separated by thousands]' + '(-c -u)-U[file creation time]' + '-y[with -t, sort filenames in the same order as the time]' + '--color=-[control use of color]:color:(never always auto)' + ) fi if [[ $OSTYPE = freebsd* ]]; then arguments+=( - '-,[print file sizes grouped and separated by thousands]' '(-S -f -t -U)-v[sort by version (filename treated numerically)]' - '-y[with -t, sort filenames in the same order as the time]' '-Z[display MAC label]' - '--color=-[control use of color]:color:(never always auto)' ) fi if [[ $OSTYPE = darwin* ]]; then @@ -109,6 +111,7 @@ if ! _pick_variant gnu=gnu unix --help; then '(-l -1 -C -m -x)-o[long listing but without group information]' '-O[display file flags]' '-v[print raw characters]' + '-%[distinguish dataless files and directories with a %]' ) fi if [[ $OSTYPE = solaris* ]]; then @@ -140,8 +143,8 @@ else '(--recursive -R)'{--recursive,-R}'[list subdirectories recursively]' '(--no-group -G)'{--no-group,-G}'[inhibit display of group information]' - '(--block-size --human-readable -h --si --kilobytes -k)'{--human-readable,-h}'[print sizes in human readable form]' - '(--block-size --human-readable -h --si --kilobytes -k)--si[sizes in human readable form; powers of 1000]' + '(--block-size --human-readable -h --si --kibibytes -k)'{--human-readable,-h}'[print sizes in human readable form]' + '(--block-size --human-readable -h --si --kibibytes -k)--si[sizes in human readable form; powers of 1000]' '(--inode -i)'{--inode,-i}'[print file inode numbers]' '(--format -l -g -o -1 -C -m -x)-l[long listing]' @@ -149,16 +152,16 @@ else --group-directories-first '(--format -l --no-group -G -1 -C -m -x)-o[no group, long]' '(--format -l -g -o -C -m -x)-1[single column output]' - '(--format -l -g -o -1 -m -x)-C[list entries in columns sorted vertically]' - '(--format -l -g -o -1 -C -x)-m[comma separated]' - '(--format -l -g -o -1 -C -m)-x[sort horizontally]' + '(--format -l -g -o -1 -m -x --block-size --human-readable -h --si --kibibytes -k)-C[list entries in columns sorted vertically]' + '(--format -l -g -o -1 -C -x --block-size --human-readable -h --si --kibibytes -k)-m[comma separated]' + '(--format -l -g -o -1 -C -m --block-size --human-readable -h --si --kibibytes -k)-x[sort horizontally]' '(-l -g -o -1 -C -m -x)--format=[specify output format]:format:(verbose long commas horizontal across vertical single-column)' '(--size -s -f)'{--size,-s}'[display size of each file in blocks]' '(--time -u)-c[status change time]' '(--time -c)-u[access time]' - '(-c -u)--time=[specify time to show]:time:(ctime status use atime access)' + '(-c -u)--time=[specify time to show]:time:(ctime status use atime access birth creation)' '--time-style=[show times using specified style]:style: _alternative "time-styles\:time style\:(full-iso long-iso iso locale)" $datef' '(-a --all -U -l --format -s --size -t --sort --full-time)-f[unsorted, all, short list]' @@ -174,15 +177,16 @@ else '--color=-[control use of color]:color:(never always auto)' "*--hide=[like -I, but overridden by -a or -A]:pattern: " '--hyperlink=[output terminal codes to link files using file::// URI]::when:(none auto always)' - '(--classify -F --indicator-style -p --file-type)'{--classify,-F}'[append file type indicators]' + '(--classify -F --indicator-style -p --file-type)-F[append file type indicators]' + '(--classify -F --indicator-style -p --file-type)--classify=-[append file type indicators]::when [always]:(none auto always)' '(--file-type -p --indicator-style -F --classify)--file-type[append file type indicators except *]' '(--file-type -p --indicator-style -F --classify)-p[append / to directories]' '(-F --classify -p --file-type)--indicator-style=[specify indicator style]:indicator style:(none file-type classify slash)' '(-f)--full-time[list both full date and full time]' - '(--block-size --human-readable -h --si --kilobytes -k)'{--kilobytes,-k}'[use block size of 1k]' - '(--human-readable -h --si --kilobytes -k)--block-size=[specify block size]:block size (bytes):(K M G T P E Z Y KB MB TB PB EB ZB YB)' + '(--block-size --human-readable -h --si --kibibytes -k)'{--kibibytes,-k}'[use block size of 1k]' + '(--human-readable -h --si --kibibytes -k -C -x)--block-size=[specify block size]:block size (bytes):(K M G T P E Z Y KB MB TB PB EB ZB YB)' '(--numeric-uid-gid -n)'{--numeric-uid-gid,-n}'[numeric uid, gid]' '(--tabsize -T)'{--tabsize=,-T+}'[specify tab size]:tab size' @@ -195,6 +199,7 @@ else '(--hide-control-chars -q --show-control-chars)'{--hide-control-chars,-q}'[hide control chars]' '(-q --hide-control-chars)--show-control-chars' + '--zero[end each output line with NUL, not newline]' '(- :)--help[display help information]' '(- :)--version[display version information]' '*:file:_files' diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make index d5ec6423d..99c786dc7 100644 --- a/Completion/Unix/Command/_make +++ b/Completion/Unix/Command/_make @@ -1,4 +1,4 @@ -#compdef make gmake pmake dmake freebsd-make bmake +#compdef make gmake gnumake pmake dmake freebsd-make bmake # TODO: Based on targets given on the command line, show only variables that # are used in those targets and their dependencies. diff --git a/Completion/Unix/Command/_mount b/Completion/Unix/Command/_mount index 301b9e58e..5a379b424 100644 --- a/Completion/Unix/Command/_mount +++ b/Completion/Unix/Command/_mount @@ -40,12 +40,13 @@ fi # are below these table. local curcontext="$curcontext" state line expl suf ret=1 -local args deffs=iso9660 tmp typeops=-t _nfs_access _fs_nfs _nfs_ufs \ +local deffs=iso9660 tmp typeops=-t _nfs_access _fs_nfs _nfs_ufs \ _fs_ufs _fs_efs _fs_cd9660 _fs_iso9660 _fs_cachefs _fs_s5fs _fs_tmpfs _fs_pcfs \ _fs_hsfs _fs_advfs _fs_cdfs _fs_affs _fs_ext2 _fs_fat _fs_ext3 _fs_msdos \ _fs_msdosfs _fs_umsdos _fs_vfat _fs_hpfs _fs_ntfs _fs_reiserfs _fs_smbfs \ _fs_xfs _fs_std _fs_devfs _fs_fdesc _fs_kernfs _fs_linprocfs _fs_linsysfs \ _fs_procfs _fs_btrfs _fs_ext4 +local -a args typeset -A opt_args @@ -735,8 +736,11 @@ if [[ "$service" = mount ]]; then deffs=hsfs typeops=-F ;; + darwin*) + args=( '-k[follow no symlinks in the provided mount-on directory]' ) + ;& freebsd*|dragonfly*|darwin*) - args=( -s + args=( -s $args '(:)-a[mount all filesystems in fstab]' '-d[cause everything to be done except for the actual system call]' '-f[forced mount]' diff --git a/Completion/Unix/Command/_mv b/Completion/Unix/Command/_mv index 84e43d47e..c52e7a5e4 100644 --- a/Completion/Unix/Command/_mv +++ b/Completion/Unix/Command/_mv @@ -13,13 +13,17 @@ case $variant; in {existing,nil}"[numbered backups, if they already exist]" {simple,never}"[always make simple backups]"' '(-b --backup -n --no-clobber)-b[make a backup of each existing destination file]' + '(-v)--debug[explain how a file is copied]' '(-f --force -i --interactive -n --no-clobber)'{-f,--force}"[don't prompt before overwriting]" '(-f --force -i --interactive -n --no-clobber)'{-i,--interactive}'[prompt before overwriting existing file]' + '(-f --force -i --interactive -n --no-clobber)'{-n,--no-clobber}"[don't overwrite existing file]" + "--no-copy[don't copy if renaming fails]" '--strip-trailing-slashes[remove any trailing slashes from each source argument]' '(-S --suffix)'{-S+,--suffix=}'[specify the backup suffix]:backup suffix [~]' '(-t --target-directory)'{-t+,--target-directory=}'[move all source arguments into specified directory]:directory:_directories' '(-T --no-target-directory)'{-T,--no-target-directory}'[treat final argument as a normal file]' - '(-u --update)'{-u,--update}'[move only when destination file is older or missing]' + '(-u)--update=-[move only when destination file is older or missing]::update files [older]:(all none older)' + '(--update)-u[move only when destination file is older or missing]' '(-v --verbose)'{-v,--verbose}'[show file names after they are moved]' '(- *)--help[display usage information]' '(- *)--version[display version information]' @@ -37,6 +41,7 @@ case $variant; in darwin*|dragonfly*|freebsd*) args+=( "(-f -i)-n[don't overwrite existing file]" + "-h[if target is a symlink to a directory, don't follow it]" ) ;| darwin*|dragonfly*|*bsd*) @@ -44,11 +49,6 @@ case $variant; in '-v[show file names after they are moved]' ) ;| - dragonfly*|freebsd*) - args+=( - "-h[if target is a symlink to a directory, don't follow it]" - ) - ;; esac _arguments -s -S $aopts $args \ diff --git a/Completion/Unix/Command/_rm b/Completion/Unix/Command/_rm index e66b77fa4..6dddb5ece 100644 --- a/Completion/Unix/Command/_rm +++ b/Completion/Unix/Command/_rm @@ -47,14 +47,10 @@ case $variant; in darwin*|dragonfly*|freebsd*|netbsd*) args+=( '-W[attempt to undelete named files]' - ) - ;| - dragonfly*|freebsd*|netbsd*) - args+=( "-x[don't cross file systems when removing a hierarchy]" ) ;| - dragonfly*|freebsd*) + darwin*|dragonfly*|freebsd*) args+=( '(-i)-I[prompt when removing many files]' ) diff --git a/Completion/Unix/Command/_sed b/Completion/Unix/Command/_sed index 79a010c92..ef3aaf2fd 100644 --- a/Completion/Unix/Command/_sed +++ b/Completion/Unix/Command/_sed @@ -104,14 +104,13 @@ else case $OSTYPE in openbsd*|freebsd*|netbsd*|darwin*|dragonfly*) args+=( - '(-r -E)'-E$extended + '(-r -E)'{-E,-r}$extended '-a[delay opening files listed with w function]' ) ;| - openbsd*|freebsd*|netbsd*|dragonfly*) args+=( '(-r -E)'-r$extended ) ;| darwin*|freebsd*|netbsd*|openbsd*|dragonfly*) args+=( '-i+'$inplace ) ;| darwin*|freebsd*|netbsd*|dragonfly*) args+=( '-l[make output line buffered]' ) ;| - freebsd*|dragonfly*) args+=( '-u[disable data buffering]' ) ;| + darwin*|freebsd*|dragonfly*) args+=( '-u[disable data buffering]' ) ;| freebsd*|netbsd*|dragonfly*) args+=( '-I+[edit files in-place, treating all files as a single input stream]:: :_guard "^(*[@/; \\\]*|?(#c6,)|-*)" "suffix for backup"' diff --git a/Completion/Unix/Command/_split b/Completion/Unix/Command/_split index 5ecc1bb67..5d5afa436 100644 --- a/Completion/Unix/Command/_split +++ b/Completion/Unix/Command/_split @@ -39,17 +39,17 @@ case $variant in '(- 1 2)--version[display version information]' ) ;; - (free|net)bsd*) + (free|net)bsd*|darwin*) args+=( '(-b -l -p)-n+[generate specified number of output files]:output files' ) ;| darwin*|freebsd*) args+=( + '-d[use numeric suffixes]' '(-b -l -n)-p+[split the file whenever a line matches specified pattern]:pattern' ) ;| freebsd*) args+=( - '-d[use numeric suffixes]' "-c[continue creating files and don't overwrite existing output files]" ) ;; diff --git a/Completion/Unix/Command/_touch b/Completion/Unix/Command/_touch index 9b9144756..47190c579 100644 --- a/Completion/Unix/Command/_touch +++ b/Completion/Unix/Command/_touch @@ -28,7 +28,7 @@ case $variant in darwin*|dragonfly*|freebsd*|netbsd*) args+=( '-h[act on symbolic links themselves]' ) ;| - dragonfly*|freebsd*|openbsd*|solaris*) + darwin*|dragonfly*|freebsd*|openbsd*|solaris*) args+=( '(-r -t 1)-d+[use specified date/time]:date/time' ) ;| darwin*|dragonfly*|freebsd*|netbsd*|solaris*) diff --git a/Completion/Unix/Command/_uniq b/Completion/Unix/Command/_uniq index e123a94cd..479b3848d 100644 --- a/Completion/Unix/Command/_uniq +++ b/Completion/Unix/Command/_uniq @@ -25,7 +25,7 @@ if ! _pick_variant gnu=Free\ Soft unix --version; then if [[ "$OSTYPE" == (darwin|dragonfly|freebsd|openbsd)* ]]; then optchars+=i fi - [[ $OSTYPE = freebsd* ]] && optchars+=D + [[ $OSTYPE = (darwin|freebsd)* ]] && optchars+=D args=( ${(M)args:#(|\*)(|\(*\))-[$optchars]*} ) fi diff --git a/Completion/Unix/Command/_xargs b/Completion/Unix/Command/_xargs index 8e23a04bb..30e5f8daa 100644 --- a/Completion/Unix/Command/_xargs +++ b/Completion/Unix/Command/_xargs @@ -25,7 +25,7 @@ case $variant in '-R[specify maximum arguments that -I will replace in]:replacements' ) ;| - freebsd*|netbsd*|dragonfly*) + darwin*|freebsd*|netbsd*|dragonfly*) args+=( '-S[space that -I can use for replacements]:size (bytes) [255]' ) -- cgit v1.2.3 From 8f0a8131fad30c627d72f24a6a88ac0053cd3790 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 17 Nov 2023 18:25:21 +0100 Subject: 52307: new completion for many SELinux tools --- ChangeLog | 7 + Completion/Linux/Command/_chcon | 24 - Completion/Linux/Command/_selinux | 781 ++++++++++++++++++++++++++++++++ Completion/Linux/Command/_setpriv | 2 +- Completion/Linux/Type/_selinux_contexts | 13 +- Completion/Linux/Type/_selinux_types | 16 +- Completion/Unix/Command/_cp | 2 +- Completion/Unix/Command/_find | 4 +- Completion/Unix/Command/_install | 2 +- Completion/Unix/Command/_mount | 6 +- Completion/Unix/Command/_zfs | 2 +- 11 files changed, 821 insertions(+), 38 deletions(-) delete mode 100644 Completion/Linux/Command/_chcon create mode 100644 Completion/Linux/Command/_selinux diff --git a/ChangeLog b/ChangeLog index 5b50aa342..09b854e54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2023-11-17 Oliver Kiddle + * 52307: Completion/Linux/Command/_selinux, + Completion/Linux/Command/_chcon, Completion/Linux/Command/_setpriv, + Completion/Linux/Type/_selinux_contexts, Completion/Unix/Command/_cp, + Completion/Linux/Type/_selinux_types, Completion/Unix/Command/_find, + Completion/Unix/Command/_install, Completion/Unix/Command/_mount, + Completion/Unix/Command/_zfs: new completion for many SELinux tools + * 52303: Completion/Unix/Command/_ifconfig, Completion/Unix/Command/_chown, Completion/Unix/Command/_cp, Completion/Unix/Command/_cut, Completion/Unix/Command/_date, diff --git a/Completion/Linux/Command/_chcon b/Completion/Linux/Command/_chcon deleted file mode 100644 index 2d523f287..000000000 --- a/Completion/Linux/Command/_chcon +++ /dev/null @@ -1,24 +0,0 @@ -#compdef chcon - -local ign - -(( $#words > 2 )) && ign='!' -_arguments -C -s -S \ - '(-h --no-dereference)--dereference[dereference symlinks]' \ - '(-h --no-dereference --dereference)'{-h,--no-dereference}'[operate on symlinks themselves]' \ - '(1 -u --user -r --role -l --range -t --type)--reference=[copy security context of specified file]:file:_files' \ - '(1 --reference -u --user)'{-u+,--user=}'[set user in the target security context]: :_selinux_users' \ - '(1 --reference -r --role)'{-r+,--role=}'[set role in the target security context]: :_selinux_roles' \ - '(1 --reference -t --type)'{-t+,--type=}'[set type in the target security context]: :_selinux_types' \ - '(1 --reference -l --range)'{-l+,--range=}'[set range in the target security context]:selinux range' \ - '(--recursive -R)'{--recursive,-R}'[recurse subdirectories]' \ - '(-v --verbose)'{-v,--verbose}'[output a diagnostic for every file processed]' \ - '(-H -L -P)-H[follow symlinks on the command line]' \ - '(-H -L -P)-L[follow all symlinks]' \ - "(-H -L -P)-P[don't follow symlinks (default)]" \ - '!(--preserve-root)--no-preserve-root' \ - "--preserve-root[fail to operate recursively on '/']" \ - '(--reference -u --user -r --role -l --range -t --type)1:security context:_selinux_contexts' \ - "${ign}--help[display help information]" \ - "${ign}--version[display version information]" \ - '*:file:_files' diff --git a/Completion/Linux/Command/_selinux b/Completion/Linux/Command/_selinux new file mode 100644 index 000000000..e7d4d3b2e --- /dev/null +++ b/Completion/Linux/Command/_selinux @@ -0,0 +1,781 @@ +#compdef audit2allow audit2why avcstat chcon checkmodule checkpolicy fixfiles getpidprevcon getsebool matchpathcon restorecon runcon sealert secon sedta seinfo selinuxconlist selinuxdefcon selinuxexeccon semanage semodule semodule_unpackage sepolgen sepolicy sesearch sestatus setenforce setsebool validatetrans + +# encompasses checkpolicy libselinux-utils policycoreutils +# policycoreutils-devel policycoreutils-python-utils setools-console +# setools-console-analyses setroubleshoot-server and a few utilities from +# coreutils + +_selinux_attributes() { + local -a seattrs expl + + seattrs=( ${(f)"$(_call_program selinux-attributes seinfo --flat -a)"} ) + _description selinux-attrs expl "selinux attribute" + compadd "$@" "$expl[@]" -a seattrs +} + +_selinux_bools() { + local -a sebools expl + + sebools=( ${(f)"$(_call_program selinux-bools seinfo --flat -b)"} ) + _description selinux-bools expl "selinux boolean" + compadd "$@" "$expl[@]" -a sebools +} + +_selinux_categories() { + local -a secats expl + + secats=( ${(f)"$(_call_program selinux-categories seinfo --flat --category)"} ) + _description selinux-categories expl "selinux category" + compadd "$@" "$expl[@]" -a secats +} + +_selinux_classes() { + local -a seclasses expl + + seclasses=( ${(f)"$(_call_program selinux-classes seinfo --flat -c)"} ) + _description selinux-classes expl "selinux object class" + compadd "$@" "$expl[@]" -a seclasses +} + +_selinux_commons() { + local -a secommons expl + + secommons=( ${(f)"$(_call_program selinux-commons seinfo --flat --common)"} ) + _description selinux-commons expl "selinux common permission set" + compadd "$@" "$expl[@]" -a secommons +} + +_selinux_interfaces() { + local -a seints expl + + seints=( ${(f)"$(_call_program selinux-interfaces sepolicy interface -l)"} ) + _description selinux-interfaces expl "selinux interface" + compadd "$@" "$expl[@]" -a seints +} + +_selinux_permissions() { + local -a seperms expl + + seperms=( ${${${${(f)"$(_call_program selinux-permissions seinfo -c --flat -x)"}:#[^[:blank:]]*}#[[:blank:]]}:1} ) + _description selinux-permissions expl "selinux permission" + compadd "$@" "$expl[@]" -a seperms +} + +_selinux_sids() { + local -a sesids expl + + sesids=( ${(f)"$(_call_program selinux-sids seinfo --flat --initialsid)"} ) + _description selinux-sids expl "selinux SID" + compadd "$@" "$expl[@]" -a sesids +} + +_selinux_sens() { + local -a sens expl + + sesids=( ${(f)"$(_call_program selinux-sens seinfo --flat --initialsid)"} ) + _description selinux-sensitivities expl "selinux sensitivity" + compadd "$@" "$expl[@]" -a sesids +} + +_selinux_modules() { + local -a modules expl + + modules=( ${(f)"$(_call_program selinux-modules semodule -l)"} ) + _description selinux-modules expl "selinux module" + compadd "$@" "$expl[@]" -a modules +} + +local curcontext="$curcontext" ret=1 +local -A opt_args +local -a args sepolgen state state_descr line +local ign +(( $#words > 2 )) && ign='!' + +sepolgen=( + "${ign}(-h --help)"{-h,--help}'[display help information]' + '(--application --cgi --dbus --inetd --init --admin_user --confined_admin --desktop_user --newtype --sandbox --x_user)'*{-d+,--domain=}'[specify domain to expand]:domain:_selinux_types -a domain' + \*{-r+,--role=}'[specify role(s) to which the administrator domain will transition]: :_selinux_roles' + \*{-u+,--user=}'[specify SELinux user(s) which will transition to this domain]: :_selinux_users' + \*{-a+,--admin=}'[specify domain(s) which this confined admin will administrate]:admin domain:_selinux_types' + '(-n --name)'{-n+,--name=}'[specify name of policy to generate]:name' + '(--admin_user --confined_admin --desktop_user --newtype --sandbox --x_user)*'{-t+,--type=}'[specify type(s) for which you will generate new definition and rule(s)]:type:_selinux_types' + '(-p --path)'{-p+,--path=}'[specify path in which the generated policy files will be stored]:path:_directories' + '(--newtype)*'{-w+,--writepath=}'[specify path to which the confined processes will need to write]:path:_directories' + '1:command:_files' + + '(application)' + "(-d)--application[generate 'User Application' policy]" + "(-d)--cgi[generate 'Web Application/Script (CGI)' policy]" + "(-d)--dbus[generate 'DBUS System Daemon' policy]" + "(-d)--inetd[generate 'Internet Services Daemon' policy]" + "(-d)--init[generate 'Standard Init Daemon' policy]" + "(-d -t 1)--admin_user[generate 'Administrator Login User Role' policy]" + "(-d -t 1)--confined_admin[generate 'Confined Root Administrator Role' policy]" + "(1)--customize[generate 'Existing Domain Type' policy]" + "(-d -t 1)--desktop_user[generate 'Desktop Login User Role' policy]" + "(-d -w 1)--newtype[generate 'Module information for a new type' policy]" + "(-d -t 1)--sandbox[generate 'Sandbox' policy]" + "(-d -t 1)--term_user[generate 'Minimal Terminal Login User Role' policy]" + "(-d -t 1)--x_user[generate 'Minimal X Windows Login User Role' policy]" +) + +case $service in + check(module|policy)) + args=( + '(-b --binary)'{-b,--binary}'[read an existing binary policy file rather than a source policy.conf file]' + '(-C --cil)'{-C,--cil}'[write CIL policy file rather than binary policy file]' + '(-E --werror)'{-E,--werror}'[treat warnings as errors]' + "${ign}(-h --help)"{-h,--help}'[display help information]' + '(-U --handle-unknown)'{-U+,--handle-unknown=}'[specify how the kernel should handle unknown classes or permissions]:action:(deny allow reject)' + '(-M --mls)'{-M,--mls}'[enable the MLS policy when checking and compiling the policy]' + '(-o --output)'{-o+,--output=}'[write a policy file]:file:_files' + '-c+[specify the policy version]:policy version [latest]' + ':input file:_files' + ) + ;| + + audit2(allow|why)) + args=( + '(-b --boot -i --input)'{-b,--boot}'[audit messages since last boot]' + '(-a --all -i --input -d --dmesg)'{-a,--all}'[read input from audit log]' + '(-p --policy)'{-p+,--policy=}'[specify policy file to use for analysis]:file:_files' + '(-d --dmesg -a --all -i --input)'{-d,--dmesg}'[read input from dmesg]' + '(-i --input -a --all -b --boot)'{-i+,--input=}'[read input from file]:file:_files' + '(-l --lastreload)'{-l,--lastreload}'[read input only after the last reload]' + '(-r --requires)'{-r,--requires}'[generate require statements for rules]' + '(-m --module -M --module-package -r --requires)'{-m+,--module=}'[set the module name]:module name:_selinux_modules' + '(-M --module-package -o --output -m --module)'{-M+,--module-package=}'[generate a module package]:module package:_files' + '(-o --output -M --module-package)'{-o+,--output=}'[append output to file]:file:_files' + '(-D --dontaudit)'{-D,--dontaudit}'[generate policy with dontaudit rules]' + '(-R --reference)'{-R,--reference}'[use installed macros in generated policy]' + '!(-R --reference -N --noreference)'{-N,--noreference} + '(-v --verbose)'{-v,--verbose}'[explain generated output]' + '(-e --explain)'{-e,--explain}'[fully explain generated output]' + '(-t --type)'{-t+,--type=}'[only process messages with type matching regex]:type' + '--perm-map=[specify file name of perm map]:file:_files' + '--interface-info=[specify file name of interface information]:file:_files' + '(-x --xperms)'{-x,--xperms}'[generate extended permission rules]' + '--debug[leave generated modules for -M]' + '(-w --why)'{-w,--why}'[translate SELinux audit messages into a description of why the access was denied]' + "${ign}(-h --help)"{-h,--help}'[display help information]' + "${ign}--version[display version information]" + ) + ;; + + avcstat) + args=( + '-c[cumulative]' + '-f+[specify AVC statistics file]:file [/sys/fs/selinux/avc/cache_stats]:_files' + ': :_guard "^-*" "interval (seconds)"' + ) + ;; + + chcon) + args=( -S + '(-h --no-dereference)--dereference[dereference symlinks]' \ + '(-h --no-dereference --dereference)'{-h,--no-dereference}'[operate on symlinks themselves]' \ + '(1 -u --user -r --role -l --range -t --type)--reference=[copy security context of specified file]:file:_files' \ + '(1 --reference -u --user)'{-u+,--user=}'[set user in the target security context]: :_selinux_users' \ + '(1 --reference -r --role)'{-r+,--role=}'[set role in the target security context]: :_selinux_roles' \ + '(1 --reference -t --type)'{-t+,--type=}'[set type in the target security context]: :_selinux_types' \ + '(1 --reference -l --range)'{-l+,--range=}'[set range in the target security context]:selinux range' \ + '(--recursive -R)'{--recursive,-R}'[recurse subdirectories]' \ + '(-v --verbose)'{-v,--verbose}'[output a diagnostic for every file processed]' \ + '(-H -L -P)-H[follow symlinks on the command line]' \ + '(-H -L -P)-L[follow all symlinks]' \ + "(-H -L -P)-P[don't follow symlinks (default)]" \ + '!(--preserve-root)--no-preserve-root' \ + "--preserve-root[fail to operate recursively on '/']" \ + '(--reference -u --user -r --role -l --range -t --type)1:security context:_selinux_contexts' \ + "${ign}--help[display help information]" \ + "${ign}--version[display version information]" \ + '*:file:_files' + ) + ;; + + checkmodule) + args=( + "${ign}(-)"{-V,--version}'[show policy versions created by this program]' + '-m[build a policy module instead of a base module]' + '-c+[build a policy module targeting a modular policy version]:version (4-21)' + ) + ;; + + checkpolicy) + args=( + '(-F --conf)'{-F,--conf}'[write policy.conf file rather than binary policy file]' + '(-d --debug)'{-d,--debug}'[enter debug mode after loading the policy]' + '(-S --sort)'{-S,--sort}'[sort ocontexts before writing out the binary policy]' + '(-t --target)'{-t+,--target=}'[specify the target platform]:platform:(selinux xen)' + '(-O --optimize)'{-O,--optimize}'[optimize the final kernel policy (remove redundant rules)]' + "${ign}(-)"{-V,--version}'[display version information]' + ) + ;; + + fixfiles) + args=( + '-B[record current date in /.autorelabel to speed later labeling]' + '-F[force reset of context to match file_context for customizable files]' + '-f[clear /tmp directory without prompt for removal]' + '-R+[discover files from specified rpm packages]:package' + '-C+[run a diff on the specified file]:file:_files' + '-N+[only act on files created after the specified date]:date (YYYY-MM-DD HH\:MM):_dates' + '-v[show changes in file labels]' + '-T+[specify number of threads to use]:threads' + '1::action:(check verify restore relabel onboot)' + '*:file:_files' + ) + ;; + + getpidprevcon) + _pids + return + ;; + + getsebool) + args=( + '(:)-a[show all booleans]' + '(-a):boolean:_selinux_bools' + ) + ;; + + matchpathcon) + args=( + '-m+[force file type for the lookup]:type:(file dir pipe chr_file blk_file lnk_file sock_file)' + "-n[don't display path]" + "-N[don't use translations]" + '-f+[use alternate file_context file]:file:_files' + '-p+[use prefix to speed translations]:prefix' + '-P+[use alternate policy root path]:path:_directories' + '-V[verify file context on disk matches defaults]' + '*:file path:_files' + ) + ;; + + restorecon) + args=( + '*-e+[exclude a directory]:directory:_directories' + '-f+[provide list of files to be processed]:file:_files' + '-F[force reset of context to match file_context for customizable files]' + "-i[ignore files that don't exist]" + '-I[ignore digest to force checking of labels even if SHA256 digest matches]' + '-D[set or update any directory SHA256 digests]' + '-m[include non-seclabel mounts in relabeling checks]' + "-n[don't change any file labels (passive check)]" + '(-v)-p[show progress]' + '(-R -r)'{-R,-r}'[change file labels recursively]' + '(-p)-v[show changes in file labels]' + '-W[display warnings about entries that had no matching files]' + '-0[expect NUL characters as input filename separators]' + "-x[don't cross file system boundaries]" + '-T+[specify number of threads to use]:threads' + "${ign}(-)"{-h,-\?}'[display help information]' + '*:file path:_files' + ) + ;; + + runcon) + args=( + '(1 -c --compute)'{-c,--compute}'[compute process transition context before modifying]' + '(1 -t --type=TYPE)'{-t+,--type=}'[specify type]: :_selinux_types' + '(1 -u --user=USER)'{-u+,--user=}'[specify user identity]: :_selinux_users' + '(1 -r --role=ROLE)'{-r+,--role=}'[specify role]: :_selinux_roles' + '(1 -l --range=RANGE)'{-l+,--range=}'[specify level range]:range' + '(-)1:security context:_selinux_contexts' + '*:::args:_normal' + ) + ;; + + sealert) + args=( + '(-b --browser)'{-b,--browser}'[launch the browser]' + '(-s --service -S --noservice)'{-s,--service}'[start sealert as a dbus service]' + '(-S --noservice -s --service)'{-S,--noservice}'[start sealert without dbus service as standalone app]' + '(-l --lookupid)'{-l+,--lookupid=}'[lookup alert by id, id may be wildcard * to lookup all alerts]:id' + '(-a --analyze)'{-a+,--analyze=}'[scan a log file, analyze its AVCs]:log file:_files' + '(-u --user)'{-u+,--user=}'[logon user name]:username' + '(-p --password)'{-p+,--password=}'[logon user password]:password' + '(-P --plugin)'{-P+,--plugin=}'[specify plugin name, required for -f]:plugin name' + '(-f --fix)'{-f+,--fix=}'[fix avc with the given uuid, requires plugin]:uuid' + "${ign}(-)"{-h,--help}'[display help information]' + ) + ;; + + secon) + args=( + "${ign}(-)"{-h,--help}'[display help information]' + "${ign}(-)--version[display version information]" + '(-P --prompt)'{-P,--prompt}'[output in a format good for a prompt]' + '(-u --user)'{-u,--user}'[show user of the context]' + '(-r --role)'{-r,--role}'[show role of the context]' + '(-t --type)'{-t,--type}'[show type of the context]' + '(-s --sensitivity)'{-s,--sensitivity}'[show sensitivity level of the context]' + '(-c --clearance)'{-c,--clearance}'[show clearance level of the context]' + '(-m --mls-range)'{-m,--mls-range}'[show sensitivity to clearance range of]' + '(-R --raw)'{-R,--raw}'[output context in "raw" format]' + '(-C --color)'{-C,--color}'[output using ANSI color codes (requires -P)]' + + '(context)' + {--self,--current}'[get context for the current process]' + {--self-exec,--current-exec}'[get exec context for the current process]' + {--self-fs,--current-fs}'[get fs context for the current process]' + {--self-key,--current-key}'[get key context for the current process]' + '--parent[get context for the parent process]' + '--parent-exec[get exec context for the parent process]' + '--parent-fs[get fs context for the parent process]' + '--parent-key[get key context for the parent process]' + {-p+,--pid=}'[context from the specified pid]:pid:_pids' + '--pid-exec[use exec context from the specified pid]:pid:_pids' + '--pid-fs[use fs context from the specified pid]:pid:_pids' + '--pid-key[use key context from the specified pid]:pid:_pids' + {-f+,--file=}'[use context from the specified file]:file:_files' + {-L+,--link=}"[use context from the specified file, doesn't follow symlinks]:file:_files" + ':context:_selinux_contexts' + ) + ;; + + sedta) + args=( + '(-p --policy)'{-p+,--policy=}'[specify path to SELinux policy to analyze]:policy:_files' + '(-s --source)'{-s+,--source=}'[specify source type of the analysis]:source:_selinux_types -a domain' + '(-t --target)'{-t+,--target=}'[specify target type of the analysis]:target:_selinux_types -a domain' + '--full[print rule lists for transitions]' + '--stats[display statistics at the end of the analysis]' + '(-v --verbose)'{-v,--verbose}'[extra informational messages]' + '--debug[enable debugging]' + '(-S --shortest_path)'{-S,--shortest_path}'[calculate all shortest paths]' + '(-A --all_paths)'{-A+,--all_paths=}'[calculate all paths]:max steps' + '(-r --reverse)'{-r,--reverse}'[perform a reverse DTA]' + '(-l --limit_trans)'{-l+,--limit_trans=}'[limit to the specified number of transitions]:limit' + '*:excluded domain:_selinux_types -a domain' + "${ign}(- *)"{-h,--help}'[display help information]' + "${ign}(-)--version[display version information]" + ) + ;; + + seinfo) + args=( + '(-a --attribute)'{-a,--attribute}'[list attributes or print named attribute]:: :_selinux_attributes' + '(-b --bool)'{-b,--bool}'[list booleans or print named boolean]:: :_selinux_bools' + '(-c --class)'{-c,--class}'[list object classes or print named object class]:: :_selinux_classes' + '(-r --role)'{-r,--role}'[list roles or print named role]:: :_selinux_roles' + '(-t --type)'{-t,--type}'[list types or print named type]:: :_selinux_types' + '(-u --user)'{-u,--user}'[list users or print named user]:: :_selinux_users' + '--category[list categories or print named category]:: :_selinux_categories' + '--common[list common permission sets or print named common]:: :_selinux_commons' + '--constrain[list constraints or print constraints for named object class]:: :_selinux_classes' + '--default[list default_* statements or print statements for named object class]:: :_selinux_classes' + '--fs_use[list fs_use_* statements or print statements for named filesystem type]:: :_file_systems' + '--genfscon[list genfscon statements or print statements for named filesystem type]:: :_file_systems' + '--initialsid[list initial SIDs or print named SID]:: : _selinux_sids' + '--netifcon[list netif contexts or print for named interface]:: : _net_interfaces' + '--nodecon[list node contexts or print statement for node with specified address]::address' + '--permissive[list permissive types or print named statement]::type' + '--polcap[list policy capabilities or print named statement]::type' + '--portcon[list port contexts or print statements for port range]::port range' + '--sensitivity[list sensitivities or print named sensitivity]:: :_selinux_sens' + '--typebounds[list type bounds or print named bound type]:: :_selinux_typebounds' + '--validatetrans[list validatetrans rules or print constraints for named object class]:: :_selinux_classes' + '--all[list all components]' + '(-x --expand)'{-x,--expand}'[print additional details]' + '--flat[exclude headers and indentation in output]' + '(-v --verbose)'{-v,--verbose}'[print additional informational messages]' + '--debug[enable debugging output]' + "${ign}--help[display help information]" + "${ign}--version[display version information]" + ':policy:_files' + ) + ;; + + selinuxconlist) + args=( + '-l+[specify mcs/mls level]:level' + ':user:_selinux_users' + ':context:_selinux_contexts' + ) + ;; + + selinuxdefcon) + args=( + '-l+[specify mcs/mls level]:level' + ':user:_users' + ':context:_selinux_contexts' + ) + ;; + + selinuxexeccon) + args=( + '1:command:_files -g "*(-*)"' + '2:from context:_selinux_contexts' + ) + ;; + + semanage) + _arguments -C \ + {-h,--help}'[display help information]' \ + ': :->command' \ + '*::: := ->option-or-argument' && ret=0 + + case $state in + command) + local -a subcmds + + subcmds=( + import:'import local customizations' + export:'output local customizations' + login:'manage login mappings between linux users and SELinux confined users' + user:'manage SELinux confined users (Roles and levels for an SELinux user)' + port:'manage network port type definitions' + interface:'manage network interface type definitions' + module:'manage SELinux policy modules' + node:'manage network node type definitions' + fcontext:'manage file context mapping definitions' + boolean:'manage booleans to selectively enable functionality' + permissive:'manage process type enforcement mode' + dontaudit:'disable/enable dontaudit rules in policy' + ibpkey:'manage infiniband pkey type definitions' + ibendport:'manage infiniband end port type definitions' + ) + + _describe -t commands command subcmds + return + ;; + option-or-argument) + (( $#words > 2 )) && ign='!' || ign='' + curcontext=${curcontext%:*}-$line[1]: + args=( + "${ign}(-)"{-h,--help}'[display help information]' + '(-S --store)'{-S+,--store=}'[select an alternate SELinux Policy Store to manage]:store:_files' + ) + + case $line[1] in + ^export) + args+=( '(-N --noreload)'{-N,--noreload}"[don't reload policy after commit]" ) + ;| + boolean|fcontext|ibendport|ibpkey|interface|login|module|node|port|user) + args+=( '(-C --locallist)'{-C,--locallist}'[list local customizations]' ) + ;| + boolean|fcontext|ibendport|ibpkey|interface|login|module|node|permissive|port|user) + args+=( + '(-n --noheading)'{-n,--noheading}"[don't print list heading]" + '(-l --list)'{-l,--list}'[list records]' + '(-E --extract)'{-E,--extract}'[extract customizable commands, for use within a transaction]' + ) + ;| + boolean|dontaudit|export|import) + args+=( '(-a --add)'{-a,--add}'[add a record]' ) + ;| + boolean|fcontext|ibendport|ibpkey|interface|login|node|permissive|port|user) + args+=( + '(-d --delete)'{-d,--delete}'[delete a record]' + '(-D --deleteall)'{-D,--deleteall}'[remove all local customizations]' + ) + ;| + boolean|fcontext|ibendport|ibpkey|interface|login|node|port|user) + args+=( '(-m --modify)'{-m,--modify}'[modify a record]' ) + ;| + fcontext|login) + args+=( '(-s --seuser)'{-s+,--seuser=}'[SELinux user name]:seuser:_selinux_users' ) + ;| + fcontext|ibendport|ibpkey|interface|node|port) + args+=( '(-t --type)'{-t+,--type=}'[SELinux Type for the object]:type:_selinux_contexts -a file_type' ) + ;| + fcontext|ibendport|ibpkey|interface|login|node|port|user) + args+=( '(-r --range)'{-r+,--range=}'[specify MLS/MCS Security Range]:range' ) + ;| + + import) + args+=( '(-f --input_file)'{-f+,--input_file=}'[specify input file]:input file:_files' ) + ;; + export) + args+=( '(-f --output_file)'{-f+,--output_file=}'[specify output file]:output_file' ) + ;; + login) + args+=( '(-l --list)1: :{ compset -P % && _groups || _users }' ) + ;; + user) + args+=( + '(-L --level)'{-L,--level}'[default SELinux Level for SELinux user, s0 Default. (MLS/MCS Systems only)]:level' + \*{-R,--roles}'[specify SELinux Roles]:roles:_selinux_roles' + ': :_selinux_users' + ) + ;; + port) + args+=( + '(-p --proto)'{-p+,--proto=}'[specify protocol for the specified port]:protocol:(tcp udp dccp sctp)' + ': :_ports' + ) + ;| + interface) + args+=( ': :_selinux_interfaces' ) + ;; + module) + args+=( + '(-P --priority)'{-P+,--priority=}'[select a priority for module operations]:priority [400]' + '(-E --extract)'{-E,--extract}'[extract customizable commands, for use within a transaction]' + '(-a --add)'{-a,--add}'[add a module]:module name:_selinux_modules' + '(-r --remove)'{-r,--remove}'[remove a module]:module name:_selinux_modules' + '(-d --disable)'{-d,--disable}'[disable a module]:module name:_selinux_modules' + '(-e --enable)'{-e,--enable}'[enable a module]:module name:_selinux_modules' + ) + ;; + node) + args+=( + '(-p --proto)'{-p+,--proto=}'[specify protocol for the specified node]:protocol:(ipv4 ipv6)' + '(-M --netmask)'{-M+,--netmask=}'[specify network mask]:netmask' + ':node:' + ) + ;; + fcontext) + args+=( + '(-e --equal)'{-e+,--equal=}'[substitute target path with sourcepath when generating default label]:equal' + '(-f --ftype)'{-f+,--ftype=}'[specify file type]:file type:(( + f\:regular\ file + d\:directory + c\:character\ device + b\:block device + s\:socket + l\:symbolic\ link + p\:named\ pipe))' + ':file spec (regex):_files' + ) + ;; + boolean) + args+=( + '(-)'{-1,--on}'[enable]' + '(-)'{-0,--off}'[disable]' + ':boolean:_selinux_bools' + ) + ;; + permissive) + args+=( '1:type:_selinux_types' ) + ;; + dontaudit) + args+=( '1:value:(on off)' ) + ;; + ibpkey) + args+=( + '(-x --subnet_prefix)'{-x,--subnet_prefix}'[specify subnet prefix for the specified infiniband ibpkey]:subnet prefix' + ':pkey:' + ) + ;; + ibendport) + args+=( + '(-z --ibdev_name)'{-z+,--ibdev_name=}'[specify name for the specified infiniband end port]:ibdev name' + ) + ;; + esac + ;; + esac + ;; + + semodule) + args=( + \*{-R,--reload}'[force a reload of policy]' + \*{-B,--build}'[build and reload policy]' + \*'--refresh[like --build but reuse existing linked policy if module files unchanged]' + \*{-D,--disable_dontaudit}'[remove dontaudits from policy]' + \*{-i+,--install=}'[install a new module]:module package:_files -g "*.pp(-.)"' + \!{-b,--base,-u,--upgrade}':module package:_files -g "*.pp(-.)"' + \*{-r+,--remove=}'[remove existing module at desired priority]:module name:_selinux_modules' + \*{-l+,--list-modules=-}'[display list of installed modules]::kind:(( + standard\:highest\ priority,\ enabled\ modules + full\:list\ all\ modules + ))' + \*{-X+,--priority=}'[set priority for following operations]:priority (1-999)' + \*{-e,--enable=}'[enable module]:module name:_selinux_modules' + \*{-d,--disable=}'[disable module]:module name:_selinux_modules' + \*{-E,--extract=}'[extract module]:module name:_selinux_modules' + '(-s --store)'{-s+,--store=}'[name of the store to operate on]:store' + '(-N -n --noreload)'{-N,-n,--noreload}"[don't reload policy after commit]" + '(-v --verbose)'{-v,--verbose}'[be verbose]' + '(-P --preserve_tunables)'{-P,--preserve_tunables}'[preserve tunables in policy]' + '(-C --ignore-module-cache)'{-C,--ignore-module-cache}'[rebuild CIL modules compiled from HLL files]' + '(-p --path)'{-p,--path}'[use an alternate path for the policy root]' + '(-S --store-path)'{-S+,--store-path=}'[use an alternate path for the policy store root]:path:_directories' + '(-c --cil)'{-c,--cil}'[extract module as cil; only affects module extraction]' + '(-H --hll)'{-H,--hll}'[extract module as hll; only affects module extraction]' + '(-m --checksum)'{-m,--checksum}'[add SHA256 checksum of modules to the list output]' + '!(--refresh)--rebuild-if-modules-changed' + "${ign}(-)"{-h,--help}'[display help information]' + ) + ;; + + semodule_unpackage) + args=( + ':pp file:_files -g "*.pp(-.)"' + ':mod file:_files -g "*.mod(-.)"' + ':fc file:_files -g "*.fc(-.)"' + ) + ;; + + sepolgen) + args=( $sepolgen ) + ;; + sepolicy) + _arguments -C \ + '-P+[specify policy to examine]' \ + "${ign}(- 1)-h[display help information]" \ + '1:command:(( + booleans\:"get description of booleans" + communicate\:"query if domains can communicate with each other" + generate\:"generate policy module template" + gui\:"graphical user interface for policies" + interface\:"list policy interfaces" + manpage\:"generate man pages for policies" + network\:"query policy network information" + transition\:"query policy to see how a source process domain can transition to the target process domain"))' \ + '*::: := ->option-or-argument' && ret=0 + case $state in + option-or-argument) + curcontext=${curcontext%:*}-$line[1]: + args=( '(-)'{-h,--help}'[display help information]' ) + case $line[1] in + transition|communicate) + args+=( + '(-s --source)'{-s+,--source=}'[specify source domain]:source:_selinux_types -a domain' + '(-t --target)'{-t+,--target=}'[specify target domain]:target:_selinux_types -a domain' + ) + ;| + manpage|network) + args+=( + {-d,--domain}'[specify domain]:*: :_selinux_types -a domain' + '!*'{-d-,--domain=-}': :_selinux_types -a domain' + ) + ;| + booleans) + args+=( + '(-)'{-a,--all}'[get all booleans descriptions]' + \*{-b,--boolean}'[specify boolean to show description]:*:boolean:_selinux_bools' + '!(-a --all -h --help)*'{-b-,--boolean=}': :_selinux_bools' + ) + ;; + communicate) + args+=( + '(-c --class)'{-c+,--class=}'[specify class to use for communications]:tclass [file]:_selinux_classes' + '(-S --sourceaccess)'{-S+,--sourceaccess=}'[specify permissions for the source type to use]:source access [open,write]' + '(-T --targetaccess)'{-T+,--targetaccess=}'[specify permissions for the target type to use]:target access [open,read]' + ) + ;; + generate) + args=( $sepolgen ) + ;; + interface) + args+=( + '(-c --compile)'{-c,--compile}'[run compile test for selected interface]' + '(-v --verbose)'{-v,--verbose}'[show verbose information]' + '(-f --file)'{-f+,--file=}'[specify interface file]:interface file:_files' + '(-a --list_admin)'{-a,--list_admin}'[list all domains with admin interface - DOMAIN_admin()]' + '(-u --list_user)'{-u,--list_user}'[list all domains with SELinux user role interface - DOMAIN_role()]' + '(-l --list)'{-l,--list}'[list all interfaces]' + {-i,--interfaces}'[specify interface names]:*:interface:_selinux_interfaces' + '!*'{-i-,--interfaces=-}':interface:_selinux_interfaces' + ) + ;; + manpage) + args+=( + '(-p --path)'{-p+,--path=}'[specify path in which the generated selinux man pages will be stored]:path:_directories' + '(-o --os)'{-o+,--os=}'[specify name of the OS for man pages]:OS' + '(-w --web)'(-w,--web)'[generate HTML man pages structure]' + '(-r --root)'{-r+,--root=}'[specify alternate root directory]:root [/]:_directories' + '--source_files[alternative root path needs to include file context files and policy.xml file]' + '(-a --all -d --domain)'{-a,--all}'[all domains]' + ) + ;; + network) + args+=( + '(-l --list)'{-l,--list}'[list all SELinux port types]' + {-p,--port}'[specify type related to the port]:*:port number' + '!*'{-p-,--port=-}':port number' + {-t,--type}'[show ports defined for this SELinux type]:*:port type:_selinux_types -a port_type' + '!*'{-t-,--type=-}':port type:_selinux_types -a port_type' + {-d,--domain}'[specify domain]:*:domain:_selinux_types -a domain' + '!*'{-d-,--domain=-}':domain:_selinux_types -a domain' + {-a,--application}'[show ports to which this application can bind and/or connect]:*:application:_selinux_types -a application_domain_type' + '!*'{-a-,--application=-}':domain:_selinux_types -a application_domain_type' # am not sure this is what is meant by applications + ) + ;; + esac + ;; + esac + ;; + + sesearch) + args=( + "${ign}(-h --help)"{-h,--help}'[display help information]' + "${ign}--version[display version information]" + '(-v --verbose)'{-v,--verbose}'[print extra informational messages]' + '--debug[enable debugging]' + '-A[search allow and allowxperm rules]' + '--allow[search allow rules]' + '--allowxperm[search allowxperm rules]' + '--auditallow[search auditallow rules]' + '--auditallowxperm[search auditallowxperm rules]' + '--dontaudit[search dontaudit rules]' + '--dontauditxperm[search dontauditxperm rules]' + '--neverallow[search neverallow rules]' + '--neverallowxperm[search neverallowxperm rules]' + '(-T --type_trans)'{-T,--type_trans}'[search type_transition rules]' + '--type_change[search type_change rules]' + '--type_member[search type_member rules]' + '--role_allow[find role allow rules]' + '--role_trans[find range_transition rules]' + '--range_trans[search range_transition rules]' + '(-s --source)'{-s+,--source=}'[source type/role of the TE/RBAC rule]: : _alternative + "types\:type\:_selinux_types" + "roles\:role\:_selinux_attributes"' + '(-t --target)'{-t+,--target=}'[target type/role of the TE/RBAC rule]: : _alternative + "types\:type\:_selinux_types" + "roles\:role\:_selinux_attributes"' + '(-c --class)'{-c+,--class=}'[comma separated list of object classes]:class:_sequence _selinux_classes' + '(-p --perms)'{-p+,--perms=}'[comma separated list of permissions]: :_sequence _selinux_permissions' + '(-x --xperms)'{-x+,--xperms=}'[comma separated list of extended permissions]:xperms' + '(-D --default)'{-D+,--default=}'[default of the rule. (type/role/range transition rules]:default' + '(-b --bool)'{-b+,--bool=}'[comma separated list of Booleans in the conditional expression]:bool ' + '-eb[match Boolean list exactly instead of matching any listed boolean]' + '-ep[match permission set exactly instead of matching any listed permission]' + '-ex[match extended permission set exactly instead of matching any listed permission]' + '-Sp[match rules where the listed permissions are a subset of the rule permissions]' + '-ds[match source attributes directly instead of matching member types/roles]' + '-dt[match target attributes directly instead of matching member types/roles]' + '-rs[use regular expression matching for the source type/role]' + '-rt[use regular expression matching for the target type/role]' + '-rc[use regular expression matching for the object class]' + '-rd[use regular expression matching for the default type/role]' + '-rb[use regular expression matching for booleans]' + ':policy:_files' + ) + ;; + + sestatus) + args=( '-b[booleans]' '-v[contexts of files and processes listed in the /etc/sestatus.conf]' ) + ;; + + setenforce) + _alternative \ + 'enable-args:enable:(Enforcing 1)' \ + 'disable-args:disable:(Permissive 0)' + return + ;; + + setsebool) + args=( + '-P[make changes persistent by writing pending values to disk]' + "-N[don't reload policy from disk]" + '-V[print verbose error messages]' + ':boolean:_selinux_bools' + ': : _values value + {1,on}"[enable]" + {0,off}"[disable]"' + ) + ;; + + validatetrans) + args=( + ':source context:_selinux_contexts' + ':target context:_selinux_contexts' + ':class:_selinux_classes' + ':new context:_selinux_contexts' + ) + ;; +esac + +_arguments -s $args diff --git a/Completion/Linux/Command/_setpriv b/Completion/Linux/Command/_setpriv index 9e38152b9..8b8d99785 100644 --- a/Completion/Linux/Command/_setpriv +++ b/Completion/Linux/Command/_setpriv @@ -93,7 +93,7 @@ _arguments -C -S -s \ '--reuid[set real and effective UNIX user id]:UNIX user:_users' \ '--securebits[set "process securebits"]: : _sequence __setpriv_prctl_securebits_set_elements' \ '--pdeathsig[keep, clear, or set parent death signal]: : __setpriv_death_signals' \ - '--selinux-label[request a selinux label]:SELinux labels: ' \ + '--selinux-label[request a selinux label]:SELinux label:_selinux_contexts' \ '--apparmor-profile[request an apparmor profile]:AppArmor profiles: ' \ '--reset-env[set environment as for a classic login shell]' \ '*:::command: _normal -p $service' \ diff --git a/Completion/Linux/Type/_selinux_contexts b/Completion/Linux/Type/_selinux_contexts index 4c2cf4288..bdad8e72b 100644 --- a/Completion/Linux/Type/_selinux_contexts +++ b/Completion/Linux/Type/_selinux_contexts @@ -1,14 +1,21 @@ #autoload -local -a parts suf +local -a parts users roles types + +zparseopts -E -D a:=types P:=users + +if ! compset -S ':*'; then + users+=( -qS : ) + roles+=( -qS : ) + [[ $(/dev/null || types+=( -qS : ) +fi parts=( users roles types ) while compset -P 1 '*:' && (( $+parts[1] )) ; do shift parts done if (( $+parts[1] )); then - compset -S ':*' || suf=( -S : ) - _selinux_$parts[1] $suf + _selinux_$parts[1] ${(P)parts[1]} else _message -e selinux-ranges 'selinux range' fi diff --git a/Completion/Linux/Type/_selinux_types b/Completion/Linux/Type/_selinux_types index ef31f45d2..69047c690 100644 --- a/Completion/Linux/Type/_selinux_types +++ b/Completion/Linux/Type/_selinux_types @@ -1,7 +1,19 @@ #autoload -local -a setypes expl +# Pass -a attribute to filter types, e.g.: +# -a domain - for process types +# -a file_type - for file types +# -a port_type - for network ports + +local -a setypes expl extra + +zparseopts -E -D -a extra a: + +if (( $#extra )); then + setypes=( ${${${(f)"$(_call_program selinux-types seinfo $extra --flat -x)"}#[[:blank:]]}:1} ) +else + setypes=( ${(f)"$(_call_program selinux-types seinfo --flat -t)"} ) +fi -setypes=( ${(f)"$(_call_program selinux-types seinfo --flat -t)"} ) _description selinux-types expl "selinux type" compadd "$@" "$expl[@]" -a setypes diff --git a/Completion/Unix/Command/_cp b/Completion/Unix/Command/_cp index da9428ce3..cb899cc28 100644 --- a/Completion/Unix/Command/_cp +++ b/Completion/Unix/Command/_cp @@ -32,7 +32,7 @@ if _pick_variant gnu=GNU unix --version; then '(-v --verbose)'{-v,--verbose}'[explain what is being done]' \ '(-x --one-file-system)'{-x,--one-file-system}'[stay on this file system]' \ '(--context)-Z[set destination SELinux security context]' \ - '(-Z)--context=-[set destination SELinux security context]:: :_selinux_contexts' \ + '(-Z)--context=-[set destination SELinux security context]:: :_selinux_contexts -a file_type' \ '(- *)--help' '(- *)--version' \ '*:file or directory:_files' else diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find index 560b77f7e..4f1c338ee 100644 --- a/Completion/Unix/Command/_find +++ b/Completion/Unix/Command/_find @@ -115,14 +115,14 @@ case $variant in '*-readable' '*-writable' '*-xtype:file type:((b\:block\ special\ file c\:character\ special\ file d\:directory p\:named\ pipe f\:normal\ file l\:symbolic\ link s\:socket))' - '-files0-from[start recursing from targets in given file]:NUL-separated targets file:_files' + '(*)-files0-from[start recursing from targets in given file]:NUL-separated targets file:_files' '*-fls:output file:_files' '*-fprint:output file:_files' '*-fprint0:output file:_files' '*-fprintf:output file:_files:output format' '*-printf:output format' ) - [[ $OSTYPE = linux-gnu ]] && args+=( '*-context:SELinux context (glob pattern):_selinux_contexts' ) + [[ $OSTYPE = linux-gnu ]] && args+=( '*-context:SELinux context (glob pattern):_selinux_contexts -a file_type' ) ;; esac diff --git a/Completion/Unix/Command/_install b/Completion/Unix/Command/_install index 364119961..238b8b5bc 100644 --- a/Completion/Unix/Command/_install +++ b/Completion/Unix/Command/_install @@ -25,7 +25,7 @@ if _pick_variant gnu='Free Soft' unix --version; then args+=( $common_args '(-b --backup)--backup=[create backup; optionally specify method]:: :->controls' - "${lx}--context=-[like -Z, or specify SELinux security context to set]::SELinux security context:_selinux_contexts" + "${lx}--context=-[like -Z, or specify SELinux security context to set]::SELinux security context:_selinux_contexts -a file_type" '-D[create all leading destination path components]' '(: -)--help[display help information]' "${lx}--preserve-context[preserve SELinux security context]" diff --git a/Completion/Unix/Command/_mount b/Completion/Unix/Command/_mount index 5a379b424..bf75aa118 100644 --- a/Completion/Unix/Command/_mount +++ b/Completion/Unix/Command/_mount @@ -334,9 +334,9 @@ if (( ! $+_fs_any )); then 'keybits[set number of bits in encryption key]:key size:(64 128 160 192 256)' 'offset[specify data start for loopback mount]:offset (bytes)' '(loud)silent' '(silent)loud' - '(fscontext defcontext)context:context' - '(context)'{fscontext,defcontext}':context' - 'rootcontext:context' + '(fscontext defcontext)context:context:_selinux_contexts -a file_type' + '(context)'{fscontext,defcontext}':context:_selinux_contexts -a file_type' + 'rootcontext:context:_selinux_contexts -a file_type' ) _fs_adfs=( 'uid[set owner of root]:user ID' diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index 3265e1eb8..c09435a1f 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -295,7 +295,7 @@ case $OSTYPE in linux-gnu) rw_ds_props+=( 'relatime:value:(on off)' ) ci_ds_props+=( - {,fs,def,root}'context:SELinux context:_selinux_contexts' + {,fs,def,root}'context:SELinux context:_selinux_contexts -a file_type' ) ;; esac -- cgit v1.2.3 From e32da8611197a56482ac3da7a85fc9e1d02e7b98 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 18 Nov 2023 16:08:28 -0800 Subject: Unposted (cf. 52296): correct description of "vared -e" --- Doc/Zsh/zle.yo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index c622483d7..495bd86a8 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -376,7 +376,7 @@ If the tt(-p) flag is given, the following string will be taken as the prompt to display at the left. If the tt(-r) flag is given, the following string gives the prompt to display at the right. If the tt(-h) flag is specified, the history can be accessed from ZLE. If the -tt(-e) flag is given, typing tt(^D) (Control-D) on an empty line +tt(-e) flag is given, typing tt(^D) (Control-D) in an empty buffer causes tt(vared) to exit immediately with a non-zero return value. The tt(-M) option gives a keymap to link to the tt(main) keymap during -- cgit v1.2.3 From fcf080ab578de00c799eb287ef8bdc201c313fee Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 18 Nov 2023 16:22:24 -0800 Subject: 52313: Src/exec.c: multios are not interactive and check for write errors. --- ChangeLog | 5 +++++ Src/exec.c | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 09b854e54..feeae6068 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-11-18 Bart Schaefer + + * 52313: Src/exec.c: subshells implementing multio reads/writes + are not interactive and should check for write errors. + 2023-11-17 Oliver Kiddle * 52307: Completion/Linux/Command/_selinux, diff --git a/Src/exec.c b/Src/exec.c index 97823760f..7d8135266 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2290,6 +2290,8 @@ closemn(struct multio **mfds, int fd, int type) return; } /* pid == 0 */ + opts[INTERACTIVE] = 0; + dont_queue_signals(); child_unblock(); closeallelse(mn); if (mn->rflag) { @@ -2302,7 +2304,8 @@ closemn(struct multio **mfds, int fd, int type) break; } for (i = 0; i < mn->ct; i++) - write_loop(mn->fds[i], buf, len); + if (write_loop(mn->fds[i], buf, len) < 0) + break; } } else { /* cat process */ @@ -2314,7 +2317,8 @@ closemn(struct multio **mfds, int fd, int type) else break; } - write_loop(mn->pipe, buf, len); + if (write_loop(mn->pipe, buf, len) < 0) + break; } } _exit(0); -- cgit v1.2.3 From 6aa15f57fd5bee298c8320dab19d167dac3d46ed Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 22 Nov 2023 00:07:37 +0100 Subject: 52315: completion options update --- ChangeLog | 4 ++ Completion/BSD/Command/_chflags | 25 ++++++--- Completion/Linux/Command/_btrfs | 41 +++++++++++---- Completion/Linux/Command/_ethtool | 58 +++++++++++++++----- Completion/Linux/Command/_gpasswd | 2 +- Completion/Linux/Command/_iptables | 66 +++++++++++++++++++---- Completion/Linux/Command/_strace | 1 + Completion/Linux/Command/_sysstat | 4 +- Completion/Linux/Command/_valgrind | 2 +- Completion/Redhat/Command/_rpm | 13 +++-- Completion/Solaris/Command/_pkg5 | 1 + Completion/Unix/Command/_awk | 1 + Completion/Unix/Command/_cat | 3 ++ Completion/Unix/Command/_dbus | 6 ++- Completion/Unix/Command/_dd | 2 +- Completion/Unix/Command/_dig | 18 +++++-- Completion/Unix/Command/_dmidecode | 1 + Completion/Unix/Command/_enscript | 2 +- Completion/Unix/Command/_flac | 1 + Completion/Unix/Command/_getent | 3 +- Completion/Unix/Command/_gnutls | 13 +++-- Completion/Unix/Command/_gpg | 5 ++ Completion/Unix/Command/_gprof | 2 +- Completion/Unix/Command/_install | 1 + Completion/Unix/Command/_less | 23 +++++++- Completion/Unix/Command/_lsof | 6 ++- Completion/Unix/Command/_lua | 1 + Completion/Unix/Command/_mpc | 14 ++++- Completion/Unix/Command/_nm | 8 +-- Completion/Unix/Command/_objdump | 14 +++-- Completion/Unix/Command/_pandoc | 68 ++++++++++++------------ Completion/Unix/Command/_perl | 1 + Completion/Unix/Command/_pgrep | 8 ++- Completion/Unix/Command/_ping | 2 + Completion/Unix/Command/_ps | 2 + Completion/Unix/Command/_pv | 4 +- Completion/Unix/Command/_readelf | 13 +++-- Completion/Unix/Command/_rsync | 15 ++++-- Completion/Unix/Command/_samba | 35 ++++++++----- Completion/Unix/Command/_sqlite | 4 +- Completion/Unix/Command/_strip | 102 ++++++++++++++++++++---------------- Completion/Unix/Command/_tiff | 2 + Completion/Unix/Command/_truss | 6 ++- Completion/Unix/Command/_user_admin | 17 +++++- Completion/Unix/Command/_vmstat | 2 +- Completion/Unix/Command/_vorbis | 5 -- Completion/Unix/Command/_w | 4 +- Completion/Unix/Command/_wget | 3 +- Completion/Unix/Command/_xmlsoft | 1 + Completion/Unix/Command/_xxd | 14 ++--- Completion/X/Command/_evince | 1 + Completion/X/Command/_qiv | 6 ++- Completion/X/Command/_xdvi | 18 +++++-- 53 files changed, 475 insertions(+), 199 deletions(-) diff --git a/ChangeLog b/ChangeLog index feeae6068..9132ef9e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-11-22 Oliver Kiddle + + * 52315: Completion/...: completion options update + 2023-11-18 Bart Schaefer * 52313: Src/exec.c: subshells implementing multio reads/writes diff --git a/Completion/BSD/Command/_chflags b/Completion/BSD/Command/_chflags index 924b09acd..905aa0645 100644 --- a/Completion/BSD/Command/_chflags +++ b/Completion/BSD/Command/_chflags @@ -1,22 +1,31 @@ #compdef chflags -local args own='-g *(-u$EUID)' +local own='-g *(-u$EUID)' +local -a args recurse (( ! EUID || $+_comp_priv_prefix )) && own= -if [[ $OSTYPE = (darwin|dragonfly|freebsd)* ]]; then - args=( - "-f[don't display diagnostic messages]" - '-v[verbose output]' - ) -fi +case $OSTYPE in + (darwin|dragonfly|freebsd)*) + args=( + "-f[don't display diagnostic messages]" + '-v[verbose output]' + ) + ;| + darwin*|freebsd*) + recurse=( "-x[don't cross mount points]" ) + ;| + netbsd*) + args=( '-d[if the change requested would not alter the flags, attempt no change]' ) + ;| +esac _arguments -s -A "-*" : $args \ ': :_file_flags' \ '*:file:_files "$own"' \ - opth \ '-h[act on symlinks]' \ - - optR \ + - optR $recurse \ '-R[recurse directories]' \ '(-L -P)-H[follow symlinks on the command line (specify with -R)]' \ '(-H -P)-L[follow all symlinks (specify with -R)]' \ diff --git a/Completion/Linux/Command/_btrfs b/Completion/Linux/Command/_btrfs index 1d87fd83a..d8b97a200 100644 --- a/Completion/Linux/Command/_btrfs +++ b/Completion/Linux/Command/_btrfs @@ -8,16 +8,16 @@ groups=( subvolume filesystem device scrub balance inspect-internal property quota qgroup replace rescue check restore send receive help version ) cmds_1=( create delete list snapshot get-default set-default find-new show sync help ) -cmds_2=( df du show sync defragment resize label usage help ) +cmds_2=( df du show sync defragment resize label mkswapfile usage help ) cmds_3=( add delete remove ready scan stats usage help ) cmds_4=( start cancel resume status help ) cmds_5=( start pause cancel resume status ) -cmds_6=( dump-{super,tree} {inode,logical,subvolid}-resolve min-dev-size rootid tree-stats help ) +cmds_6=( dump-{super,tree} {inode,logical,subvolid}-resolve map-swapfile min-dev-size rootid tree-stats help ) cmds_7=( get set list ) cmds_8=( enable disable rescan help ) -cmds_9=( assign remove create destroy show limit help ) +cmds_9=( assign remove create clear-stale destroy show limit help ) cmds_10=( start status cancel help ) -cmds_11=( chunk-recover fix-device-size super-recover zero-log create-control-device ) +cmds_11=( chunk-recover clear-uuid-tree fix-device-size super-recover zero-log create-control-device ) _arguments -C -A "-*" "$args[@]" \ '(- *)--help[print help information]' \ @@ -25,6 +25,7 @@ _arguments -C -A "-*" "$args[@]" \ '(-v --verbose -q --quiet --help --version)'{-v,--verbose}'[verbose output of operation]' \ '(-v --verbose -q --quiet --help --version)'{-q,--quiet}'[suppress all messages except errors]' \ '(--help --version)--format=[specify output format]:format:(text json)' \ + '(--help --version)--log=[set log level]:level:(default info verbose debug quiet)' \ '(--version)1: :->groups' \ '2: :->cmds' \ '*:: :->args' && ret=0 @@ -151,7 +152,7 @@ while (( $#state )); do filesystem:defragment) args+=( '!-v' '-r[defragment files recursively]' - '-c+[compress files while defragmenting]::compression algorithm:(zlib lzo zstd)' + '-c-[compress files while defragmenting]::compression algorithm:(zlib lzo zstd)' '-r[defragment files recursively]' '-f[flush after defragmenting]' '-s[start position]: :_numbers -u bytes -d "beginning of file" offset K M G T P E' @@ -171,6 +172,13 @@ while (( $#state )); do '1: :_guard "^-*" uuid or label' ) ;; + filesystem:mkswapfile) + args+=( + '-s[size]: :_numbers -d "2GiB" size K M G T P E' + '(-u --uuid)'{-u,--uuid}'[specify a uuid to use]:uuid:(clear random time)' + ':file:_files' + ) + ;; filesystem:usage) args+=( '-T[show data in tabular format]' );; device:(add|delete|ready|remove)) args+=( @@ -194,6 +202,7 @@ while (( $#state )); do args+=( '(-c --check)'{-c,--check}'[return non-zero if any stat counter is not zero]' '(-z --reset)'{-z,--reset}'[reset stats when done]' + '-T[show current stats in tabular format]' "1:device or mountpoint:_files -g '*(-%,/)'" ) ;; @@ -233,7 +242,7 @@ while (( $#state )); do ;; balance:status) args+=( '!-v' '!--verbose' '1:path:_files -/' );; balance:(pause|cancel|resume)) args+=( '1:path:_files -/' );; - property:set) args+=( '3:value' );& + property:set) args+=( '-f[force the change]' '3:value' );& property:get) args+=( '2:property:(ro label compression)' );& property:list) args+=( @@ -244,8 +253,9 @@ while (( $#state )); do quota:(enable|disable)) args+=( '1:path:_files -/' );; quota:rescan) args+=( - '-s[show status of currently running rescan]' - '-w[wait for rescan to finish]' + '(-s --status)'{-s,--status}'[show status of currently running rescan]' + '(-w --wait -W --wait-norescan)'{-w,--wait}'[wait for rescan to finish]' + '(-w --wait -W --wait-norescan)'{-w,--wait-norescan}'[wait for rescan to finish without starting it]' '1:path:_files -/' ) ;; @@ -268,11 +278,14 @@ while (( $#state )); do '-F[list impacted qgroups \(include ancestral qgroups\)]' '-f[list impacted qgroups \(exclude ancestral qgroups\)]' '--sort=-[sort qgroups]:sort:_values -s , sort \ - qgroupid rfer excl max_rfer max_excl' + qgroupid rfer excl max_rfer max_excl path' '--sync[do filesystem sync before getting information]' '1:path:_files -/' ) ;; + qgroup:clear-stale) + args+=( '(-q --quiet)'{-q,--quiet}'[print only errors]' '1:path:_files -/' ) + ;; qgroup:limit) args+=( '-c[limit amount of data after compression]' @@ -287,6 +300,7 @@ while (( $#state )); do '-r[read from specified source device only]:srcdev:_files' '-f[force overwriting of target]' "-B[don't background]" + '(-K --nodiscard)'{-K,--nodiscard}"[don't perform whole device TRIM]" ':srcdev or devid:_files' ':target:_files' ':path:->mounts' @@ -332,6 +346,12 @@ while (( $#state )); do '2:filesystem path:_files -/' ) ;; + inspect*:map-swapfile) + args+=( + '(-r --resume-offset)'{-r,--resume-offset}'[print only the value suitable as resume offset for file /sys/power/resume_offset]' + ':file:_files' + ) + ;; inspect*:min*) args+=( '--id[specify the device id to query]:device id [1]' );; inspect*:rootid) args+=( '1:path:_files -/' );; inspect*:tree*) args+=( '-b[print raw numbers in bytes]' );; @@ -395,6 +415,8 @@ while (( $#state )); do '*-c[use snapshot as clone source]:clone:_files -/' '-f[specify output file]:file:_files' '--no-data[send in NO_FILE_DATA mode]' + '--proto[specify protocol version]:version' + '--compressed-data[send data that is compressed on the filesystem directly without decompressing it]' '1:subvolume:_files -/' ) ;; @@ -405,6 +427,7 @@ while (( $#state )); do '(-C --chroot)'{-C,--chroot}'[confine the process to destination path using chroot(1)]' '(-E --max-errors)'{-E,--max-errors}'[terminate as soon as specified number of errors occur]:errors [1]' '(--dump)-m[specify root mount point of the destination filesystem]:mount point:_directories' + '--force-decompress[if the stream contains compressed data, always decompress it]' '(-m)--dump[dump stream metadata, one line per operation]' '1:mount:->mounts' ) diff --git a/Completion/Linux/Command/_ethtool b/Completion/Linux/Command/_ethtool index 95a8bbfb6..3e3fc0b1d 100644 --- a/Completion/Linux/Command/_ethtool +++ b/Completion/Linux/Command/_ethtool @@ -4,7 +4,7 @@ local curcontext="$curcontext" local -a state line expl cmds local -A opt_args -_arguments -C \ +_arguments -C -A "-*" \ '--debug[turn on debugging messages]:mask:((1\:parser\ information))' \ '--json[output results in JSON]' \ '(-I --include-statistics)'{-I,--include-statistics}'[include command-related statistics in the output]' \ @@ -59,12 +59,21 @@ _arguments -C \ '--cable-test[perform cable test and report the results]' \ '--cable-test-tdr[perform cable test and report Time Domain Reflectometer data]' \ '--show-tunnels[show tunnel-related device capabilities and state]' \ + '--show-module[show transceiver module settings]' \ + '--set-module[set transceiver module settings]' \ + '--get-plca-cfg[get PLCA configuration]' \ + '--set-plca-cfg[set PLCA configuration]' \ + '--get-plca-status[get PLCA status information]' \ + '--show-mm[show MAC merge layer state]' \ + '--set-mm[set MAC merge layer parameters]' \ + '--show-pse[show settings for power sourcing equipment]' \ + '--set-pse[set power sourcing equipment settings]' \ '--monitor[listen to netlink notifications and displays them]::command:( --all -s --change -k --show-features --show-offload -K --features --offload --show-priv-flags --set-priv-flags -g --show-ring -G --set-ring -l --show-channels -L --set-channels -c --show-coalesce -C --coalesce -a --show-pause -A --pause --show-eee --set-eee - --cable-test --cable-test-tdr + --cable-test --cable-test-tdr --show-module --set-module )' && return if [[ -n $state ]]; then @@ -79,22 +88,30 @@ if [[ -n $state ]]; then fi ;; autoneg|adaptive-[rt]x|raw|hex|sg|tso|ufo|gso|lro|eee|tx-lpi|downshift) ;& - fast-link-down|energy-detect-power-down|mode) + cqe-mode-[rt]x|fast-link-down|energy-detect-power-down|mode) ;& + [tr]x-push|enable|*-enabled) _wanted onoff expl 'enabled' compadd off on ;; rx-usecs|rx-frames|rx-usecs-irq|rx-frames-irq|tx-usecs|tx-frames) ;& tx-usecs-irq|tx-frames-irq|stats-block-usecs|pkt-rate-low|rx-usecs-low) ;& rx-frames-low|tx-usecs-low|tx-frames-low|pkt-rate-high|rx-usecs-high) ;& - rx-frames-high|tx-usecs-high|tx-frames-high|sample-interval|dmac|rx-mini) ;& - rx-jumbo|offset|length|magic|value|phyad|proto|tos|tclass|l4proto|src-port) ;& + rx-frames-high|tx-usecs-high|tx-frames-high|sample-interval|dmac) ;& + tx-aggr-max-bytes|tx-aggr-max-frame|tx-aggr-time-usec) ;& + rx-mini|rx-jumbo|rx-buf-len|cqe-size|tx-push-buf-len) ;& + offset|length|magic|value|phyad|proto|tos|tclass|l4proto|src-port) ;& dst-port|spi|l4data|vlan-etype|vlan|user-def|action|vf|queue|loc) ;& page|bank|i2c|first|last|step|pair|lanes) ;& - rx-copybreak|tx-copybreak|pfc-prevention-tout) ;& - other|combined|tx-timer|count|msecs) + rx-copybreak|tx-copybreak|tx-buf-size|pfc-prevention-tout) ;& + other|combined|tx-timer|count|msecs) ;& + node-id|node-cnt|to-tmr|burst-cnt|burst-tmr) ;& + tx-min-frag-size) _message -e numbers 'number' ;; + podl-pse-admin-control) + _wanted values expl 'value' compadd enable disable + ;; speed) - _wanted -x speed expl 'speed' compadd 10 100 1000 + _wanted -x speed expl 'speed' compadd 10 100 1000 ;; duplex) _wanted duplex expl 'duplex mode' compadd half full @@ -166,8 +183,14 @@ if [[ -n $state ]]; then context) _message -e contexts 'RSS context' ;; + power-mode-policy) + _wanted policies expl 'policy' compadd high auto + ;; *) case ${${(Mk)opt_args:#cmd?*}[1]#cmd?-} in + -a|--show-pause) + _arguments '--src=-:source:(aggregate emac pmac)' + ;; -A|--pause) _values -S ' ' -w 'pause parameter' \ 'autoneg[specify if pause autonegotiation is enabled]' \ @@ -177,14 +200,16 @@ if [[ -n $state ]]; then -C|--coalesce) _wanted settings expl 'coalescing setting' compadd -F line -M 'r:|-=* r:|=*' - \ adaptive-{r,t}x {r,t}x-{usecs,frames}{,-irq,-high,-low} \ - stats-block-usecs pkt-rate-{low,high} sample-interval + stats-block-usecs pkt-rate-{low,high} sample-interval cqe-mode-{r,t}x \ + tx-aggr-{max-bytes,max-frames,time-usecs} ;; -G|--set-ring) _values -S ' ' -w 'ring parameter' \ 'rx[change number of ring entries for the RX ring]' \ 'rx-mini[change number of ring entries for the RX Mini ring]' \ 'rx-jumbo[change number of ring entries for the RX Jumbo ring]' \ - 'tx[change number of ring entries for the TX ring]' + 'tx[change number of ring entries for the TX ring]' \ + rx-buf-len cqe-size tx-push rx-push tx-push-buf-len ;; -d|--register-dump) _values -S ' ' -w 'option' \ @@ -216,7 +241,9 @@ if [[ -n $state ]]; then (( CURRENT = 4 )) && _message -e length 'duration (seconds)' ;; -S|--statistics) - _arguments '(-)--all-groups' '(-)--groups:eth-phy: :eth-mac: :eth-ctrl: :rmon' + _arguments '(-)--all-groups' \ + '(-)--groups:eth-phy: :eth-mac: :eth-ctrl: :rmon' \ + '--src=-:source:(aggregate emac pmac)' \ ;; -t|--test) _values -S ' ' -w 'test mode' \ @@ -318,7 +345,7 @@ if [[ -n $state ]]; then ;; --[gs]et-tunable) _wanted options expl tunable compadd rx-copybreak tx-copybreak \ - pfc-prevention-tout + tx-buf-size pfc-prevention-tout ;; --reset) _wanted components expl component compadd flags dedicated all \ @@ -341,6 +368,13 @@ if [[ -n $state ]]; then --cable-test-tdr) _wanted options expl 'distance options' compadd first last step pair ;; + --set-module) + _wanted options expl tunable compadd power-mode-policy + ;; + --set-plca-cfg) + _wanted options expl tunable compadd enable node-id node-cnt \ + to-tmr burst-cnt burst-tmr + ;; esac ;; esac diff --git a/Completion/Linux/Command/_gpasswd b/Completion/Linux/Command/_gpasswd index 24fe361b0..d5d16ebba 100644 --- a/Completion/Linux/Command/_gpasswd +++ b/Completion/Linux/Command/_gpasswd @@ -5,7 +5,7 @@ _arguments -s \ '(-d --delete -a --add)'{-d,--delete}'[remove user from group]: : _users' \ '(-)'{-h,--help}'[display help]' \ '(-Q --root)'{-Q,--root}'[specify directory to chroot into]: : _files -/' \ - '(-r --remove-password)'{-r,--remove-password}'[remove the group password]' \ + '(-r --delete-password)'{-r,--delete-password}'[remove the group password]' \ '(-R --restrict)'{-R,--restrict}'[restrict access to GROUP to its members]' \ '(-M --members -A --administrators)'{-M,--members}'[set the list of members of GROUP]: :_sequence _users' \ '(-A --administrators -M --members)'{-A,--administrators}'[set the list of admins for GROUP]: :_sequence _users' \ diff --git a/Completion/Linux/Command/_iptables b/Completion/Linux/Command/_iptables index 27c801da1..892c48710 100644 --- a/Completion/Linux/Command/_iptables +++ b/Completion/Linux/Command/_iptables @@ -1,7 +1,7 @@ -#compdef iptables iptables-save iptables-restore ip6tables ip6tables-save ip6tables-restore +#compdef iptables iptables-save iptables-restore ip6tables ip6tables-save ip6tables-restore arptables ebtables -local curcontext="$curcontext" state line expl i ret=1 -local -a cmds rcmds ropts rules states prev args +local curcontext="$curcontext" i ret=1 +local -a state line expl cmds rcmds ropts rules states prev args case $service in iptables-save | ip6tables-save) @@ -24,12 +24,12 @@ cmds=( -P --policy -E --rename-chain -h --help -V --version ) ropts=( - -p --protocol -s --src --source -d --dst --destination -j --jump -i + -p --proto --protocol -s --src --source -d --dst --destination -j --jump -i --in-interface -o --out-interface -f --fragment -c --set-counters ) prev=( ${words[1,CURRENT-1]} ) -case ${prev[${prev[(I)-p|--protocol]}+1]}; in +case ${prev[${prev[(I)-p|--proto|--protocol]}+1]}; in tcp) args=( '--tcp-flags[match based on TCP flags in a packet]: :->tcp-flags: :->tcp-flags' @@ -92,7 +92,42 @@ while (( i=words[(ib.i.)-m|--match]+1 )) (( iaddress-types' + '--dst-type[match if the destination address is of given type]:type:->address-types' + '(--limit-iface-out)--limit-iface-in[limit to interface the packet is coming in]' + '(--limit-iface-in)--limit-iface-out[limit to interface the packet is going out]' + ) + ;; + ah) + args+=( '--ahspi[match SPIs in AH header]:*^!:spi' ) + [[ $service = ip6* ]] && args+=( + '--ahlen[total length of this header]:length (octets)' + '--ahres[match if the reserved field is filled with zero]' + ) + ;; + bpf) + args+=( + '--object-pinned[pass a path to a pinned eBPF object]:path:_files' + '--bytecode[pass BPF byte code as generated by nfbpf_compile]:code' + ) + ;; + cgroup) + args+=( + '--path[match cgroup2 membership]:path:_files -W /sys/fs/cgroup' + '--cgroup[match cgroup net_cls classid]:classid' + ) + ;; + cluster) + args+=( + '--cluster-total-nodes[set number of total nodes in cluster]:number' + '--cluster-local-node[set the local node number ID]:number' + '--cluster-local-nodemask[set the local node number ID mask]:mask' + '--cluster-hash-seed[set seed value of the Jenkins hash]:value' + ) + ;; + comment) args+=( '--comment[add comment to rule]:comment' ) ;; conntrack) args+=( '--ctstate[match packet state]:state:->cfstates' @@ -160,30 +195,34 @@ _arguments -C -s \ '(-)'{-V,--version}'[print version information]' \ '(-h --help -V --version)'{-t,--table}'[specify table]:table:(filter nat mangle raw security)' \ "($rcmds $cmds)"{-A,--append}'[append rules to end of specified chain]:chain:->chains' \ + {-C,--check}'[check for the existence of a rule]' \ "($rcmds $cmds -c --set-counters)"{-D,--delete}'[delete rules from specified chain]:chain:->chains::rule number:->rulenums' \ "($rcmds $cmds)"{-I,--insert}'[insert rules before specified rule number]:chain:->chains::rule number:->rulenums' \ "($rcmds $cmds)"{-R,--replace}'[replace a rule]:chain:->chains::rule number:->rulenums' \ - "($rcmds "${(j. .)cmds:#(-Z|--zero)}" $ropts)"{-L,--list}'[list rules in selected chain]::chain:->chains' \ + "($rcmds "${(j. .)cmds:#(-Z|--zero)}" $ropts)"{-L,--list}'[list rules in selected chain]::chain:->chains:rule number:->rulenums' \ + '(-L --list -S --list-rules)'{-S,--list-rules}'[list rules in the form of options to iptables]::chain:->chains::rule number:->rulenums' \ "($rcmds $cmds $ropts)"{-F,--flush}'[flush specified chain (delete all rules)]::chain:->chains' \ "($rcmds "${(j. .)cmds:#(-L|--list)}" $ropts)"{-Z,--zero}'[zero the packet and byte counters]::chain:->chains' \ "($rcmds $cmds)"{-N,--new,--new-chain}'[create a new user-defined chain]:chain name' \ "($rcmds $cmds)"{-X,--delete-chain}'[delete a user-defined chain]:: :->user-chains' \ "($rcmds $cmds)"{-P,--policy}'[set the policy for a chain to given target]:chain:->chains:target:->targets' \ "($rcmds $cmds)"{-E,--rename-chain}'[rename a user-defined chain]:old chain:->user-chains:new chain name' \ - "($cmds -p --protocol)"{-p,--protocol}'[specify protocol of rule]:*^!:protocol:(! tcp udp icmp all)' \ - "($cmds -s --src --source)"{-s,--src,--source}'[specify source]:*^!:network:_hosts' \ - "($cmds -d --dst --destination)"{-d,--dst,--destination}'[specify destination]:*^!:network:_hosts' \ + "($cmds -p --proto --protocol)"{-p,--proto,--protocol}'[specify protocol of rule]:*^!:protocol:(! tcp udp icmp all)' \ + "($cmds -s --src --source)"{-s,--src,--source}'[specify source]:*^!:network:_sequence _hosts' \ + "($cmds -d --dst --destination)"{-d,--dst,--destination}'[specify destination]:*^!:network:_sequence _hosts' \ "($cmds -j --jump)"{-j,--jump}'[specify rule target]:target:->targets' \ "($cmds -i --in-interface)"{-i,--in-interface}'[specify interface via which packet is received]:*^!:interface:_net_interfaces' \ "($cmds -o --out-interface)"{-o,--out-interface}'[specify interface via which packet is to be sent]:*^!:interface:_net_interfaces' \ "($cmds -f --fragment)"{-f,--fragment}'[match second or further fragments only]' \ "($cmds -D --delete -c --set-counters)"{-c,--set-counters}'[initialise packet and byte counters]:packets: :bytes' \ '(-v --verbose)'{-v,--verbose}'[enable verbose output]' \ + '(-w --wait)'{-w,--wait}'[specify maximum wait to acquire xtables lock before giving up]: :_numbers -u seconds -d 1 wait' \ + '(-W --wait-interval)'{-W,--wait-interval}'[specify wait time to try to acquire xtables lock]: :_numbers -u usecs -d "1 second" wait' \ '(-n --numeric)'{-n,--numeric}'[print IP addresses and port numbers in numeric format]' \ '(-x --exact)'{-x,--exact}'[expand numbers (display exact values)]' \ '--line-numbers[print line numbers when listing]' \ '--modprobe=[specify command to load modules with]:command:_command_names -e' \ - "($cmds)*"{-m,--match}'[extended match (may load extension)]:extension:(ah conntrack dscp esp helper icmp length limit mac mark multiport owner physdev pkttype state tcp tos ttl udp unclean)' \ + "($cmds)*"{-m,--match}'[extended match (may load extension)]:extension:(addrtype ah bpf cgroup cluster comment connbytes connlabel connlimit connmark conntrack cpu dccp devgroup dscp dsr ecn esp eui64 frag hashlimit hbh helper hl icmp icmp6 iprange ipv6header ipvs length limit mac mark mh multiport nfacct osf owner physdev pkttype policy quota rateest realm recent rpfilter rt sctp set socket state statistic string tcp tcpmss time tos ttl u32 udp unclean)' \ "$args[@]" && ret=0 case "$state" in @@ -230,6 +269,11 @@ case "$state" in [[ "$state" = cf* ]] && states+=( SNAT DNAT ) _values -s , 'state' $states && return ;; + address-types) + _wanted address-types expl 'address type' compadd \ + UNSPEC UNICAST LOCAL BROADCAST ANYCAST MULTICAST \ + BLACKHOLE UNREACHABLE PROHIBIT THROW NAT XRESOLVE && ret=0 + ;; port-list) compset -P '*,' if compset -S ',*'; then diff --git a/Completion/Linux/Command/_strace b/Completion/Linux/Command/_strace index b1c7e1c8f..37e14b6d6 100644 --- a/Completion/Linux/Command/_strace +++ b/Completion/Linux/Command/_strace @@ -17,6 +17,7 @@ _arguments -C -s \ '(-D)--daemonize=-[specify how to run tracer process]::method:(grandchild pgroup session)' \ '(-f --follow-forks)'{-f,--follow-forks}'[trace child processes as they are created by currently traced processes]' \ '(-I --interruptible)'{-I+,--interruptible=}'[specify when strace can be interrupted by signals]:interruptible:((1\:"no signals are blocked" 2\:"fatal signals are blocked while decoding syscall (default)" 3\:"fatal signals are always blocked (default with -o)" 4\:"fatal signals and SIGTSTP are always blocked"))' \ + '--kill-on-exit[kill all tracees if strace is killed]' \ \*{-e+,--trace=}'[select events to trace or how to trace]:system call:->expressions' \ \*{-P+,--path=}'[trace only system calls accessing given path]:path:_files' \ '(-z -Z --successful-only --failed-only)'{-z,--successful-only}'[trace only system calls that return success]' \ diff --git a/Completion/Linux/Command/_sysstat b/Completion/Linux/Command/_sysstat index 0baae0764..59a2f5da9 100644 --- a/Completion/Linux/Command/_sysstat +++ b/Completion/Linux/Command/_sysstat @@ -56,6 +56,7 @@ _sadf() { '--dev=-[specify block devices for which statistics are to be displayed]:block device:_files -g "*(-%)"' \ '--fs=-[specify filesystems for which statistics are to be displayed]:file system:_dir_list -s ,' \ '--iface=-[specify network interfaces for which statistics are to be displayed]:network interface:_sequence _net_interfaces' \ + '--int=-[specify interrupts for which statistics are to be displayed]: : _values -s "," interrupt 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15' \ '-s[set starting time of report]:starting time (HH\:MM\:SS)"' \ '(-t -U)-T[display timestamp in local time]' \ '(-T -U)-t[display timestamp in file\''s original localtime]' \ @@ -99,9 +100,10 @@ _sar() { '(--human -p)-h[make output easier to read: implies --human and -p]' \ '(- 1 2)--help[display usage information]' \ '--human[print sizes in human readable format]' \ - '*-I[report statistics for interrupts]: : _values -s "," interrupt 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 SUM ALL XALL' \ + '-I[report statistics for interrupts]:interrupt:(SUM ALL)' \ '-i[select records as close as possible to interval]:interval' \ '--iface=-[specify network interfaces for which statistics are to be displayed]:network interface:_sequence _net_interfaces' \ + '--int=-[specify interrupts for which statistics are to be displayed]: : _values -s "," interrupt 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15' \ '-j[display persistent device names]:type:(ID LABEL PATH UUID)' \ '-m[report power management statistics]:keyword:_sequence compadd - CPU FAN FREQ IN TEMP USB ALL' \ '-n[report network statistics]:keyword:_sequence compadd - DEV EDEV NFS NFSD SOCK IP EIP ICMP EICMP TCP ETCP UDP SOCK6 IP6 EIP6 ICMP6 EICMP6 UDP6 FC SOFT ALL' \ diff --git a/Completion/Linux/Command/_valgrind b/Completion/Linux/Command/_valgrind index b4bb3248e..e1498be6d 100644 --- a/Completion/Linux/Command/_valgrind +++ b/Completion/Linux/Command/_valgrind @@ -216,7 +216,7 @@ _arguments -C ${(P)args} $cmd \ '--vgdb=-[activate gdbserver]:enable [yes]:(yes no full)' \ '--vgdb-error=-[invoke gdbserver after specified number of errors]:errors [999999999]:errors' \ '--vgdb-stop-at=-[invoke gdbserver for given events]:event:_sequence compadd - startup exit valgrindabexit all none' \ - '--track-fds=-[track open file descriptors]:enable:(yes no)' \ + '--track-fds=-[track open file descriptors]:enable [no]:(yes no all)' \ '--time-stamp=-[add timestamps to log messages]:enable:(yes no)' \ '--log-fd=-[log messages to specified file descriptor]:file descriptor:_file_descriptors' \ '--log-file=-[log messages to specified file with pid appended]:file:_files' \ diff --git a/Completion/Redhat/Command/_rpm b/Completion/Redhat/Command/_rpm index d00f88429..97f65cd6c 100644 --- a/Completion/Redhat/Command/_rpm +++ b/Completion/Redhat/Command/_rpm @@ -74,6 +74,7 @@ _rpm () { selectopts=( {-a,--all}'[query all packages]' {-f,--file}'[query packages that own specified files]' + '--path[query packages that own specified files, installed or not]' {-p,--package}'[query uninstalled packages]' {-g,--group}'[query packages in one of specified groups]' --pkgid --hdrid --tid --querybynumber @@ -165,9 +166,7 @@ _rpm () { {-F+,--freshen}'[freshen mode]:*:upgrade:->upgrade' {-e+,--erase}'[uninstall mode]:*:uninstall:->uninstall' '--reinstall[reinstall mode]:*:install:->install' - '--setperms[set file permissions]:*:package:->setattrs' - '--setugids[set file owner/group]:*:package:->setattrs' - '--setcaps[set capabilities of files in the given package]:*:package:->setattrs' + '!--set'{perms,ugids,caps}':*:package:->setattrs' '--restore[restore owner, group, permissions and capabilities of files in the given package]:*:package:->setattrs' ) ;; @@ -261,13 +260,15 @@ _rpm () { install) _arguments -s -C \!{-i,--install,-U,--upgrade,-F,--freshen} $tmp \ $commonopts $pathopts \ + '(--nodb)--justdb[update the database but not the filesystem]' \ + '(--justdb)--nodb[update the filesystem but not the database]' \ '--excludepath=:file to exclude:_files -/' \ '--relocate:relocate:->relocate' \ '--prefix=[relocate the package]:package prefix directory:_files -/' \ '(-h --hash)'{-h,--hash}'[print hash marks as package installs]' \ '(--replacepkgs --replacefiles --oldpackage)--force' \ '(--force)--'{replacefiles,replacepkgs} \ - --{aid,allfiles,badreloc,excludedocs,ignorearch,ignoreos,ignoresize,includedocs,justdb,percent,test} \ + --{aid,allfiles,badreloc,excludedocs,ignorearch,ignoreos,ignoresize,includedocs,percent,test} \ --no{deps,filedigest,contexts,caps,order,suggest,pre,post,preun,postun,trigger{s,in,un,postun}} \ '(--nopre --nopost --nopreun --nopostun)--noscripts' \ '*:pkg file:->package_file' @@ -275,7 +276,9 @@ _rpm () { uninstall) _arguments -s -C \!{-e,--erase} \ "${commonopts[@]}" "${pathopts[@]}" \ - --{allmatches,justdb,repackage,test} \ + '(--nodb)--justdb[update the database but not the filesystem]' \ + '(--justdb)--nodb[update the filesystem but not the database]' \ + --{allmatches,repackage,test} \ --no{deps,scripts,preun,postun,trigger{s,un,postun}} \ '*:package:->package' ;; diff --git a/Completion/Solaris/Command/_pkg5 b/Completion/Solaris/Command/_pkg5 index bcd4e3daf..5524e4eda 100644 --- a/Completion/Solaris/Command/_pkg5 +++ b/Completion/Solaris/Command/_pkg5 @@ -378,6 +378,7 @@ _pkg5() { '--non-sticky[Make this publisher non-sticky]' \ '--search-after[Set publisher search-order]:publisher:_pkg5_pubs' \ '--search-before[Set publisher search-order]:publisher:_pkg5_pubs' \ + '--search-first[set the specified publisher first in the search order]' \ '--approve-ca-cert[Add trusted CA certificate]:CA cert path:_path_files' \ '--revoke-ca-cert[Revoke CA certificate]:CA cert hash:(${${certs#/etc/openssl/certs/}%.0})' \ '--unset-ca-cert[Remove trusted CA certificate]:CA cert hash:' \ diff --git a/Completion/Unix/Command/_awk b/Completion/Unix/Command/_awk index e8f4a2530..b69cc5cf8 100644 --- a/Completion/Unix/Command/_awk +++ b/Completion/Unix/Command/_awk @@ -50,6 +50,7 @@ case $variant in {-D-,--debug=-}'[enable debugging]::debugger command file:_files' {-g,--gen-pot}'[scan awk program and generate .po file on stdout]' '*'{-i+,--include}'[load source library]:library file:->script' + {-I,--trace}'[print internal byte code names as they are executed]' '*'{-l+,--load}'[load dynamic extension]:extension:->extension' {-M,--bignum}'[select arbitrary-precision arithmetic on numbers]' {-o-,--pretty-print=-}'[pretty-print awk program]::output file:_files' diff --git a/Completion/Unix/Command/_cat b/Completion/Unix/Command/_cat index 74d7278b8..526c49e31 100644 --- a/Completion/Unix/Command/_cat +++ b/Completion/Unix/Command/_cat @@ -38,6 +38,9 @@ elif [[ "$OSTYPE" == (*bsd|dragonfly|darwin)* ]]; then '-B+[read with buffer of specified size]:size (bytes)' '-f[only attempt to display regular files]' ) + [[ $OSTYPE = darwin* ]] && args+=( + '-l[set an exclusive advisory lock on standard output]' + ) elif [[ $OSTYPE = solaris* ]]; then args=( -A "-*" diff --git a/Completion/Unix/Command/_dbus b/Completion/Unix/Command/_dbus index 37b5458d7..d2a93152c 100644 --- a/Completion/Unix/Command/_dbus +++ b/Completion/Unix/Command/_dbus @@ -8,11 +8,13 @@ case $service in dbus-send) _arguments -A "--*" -C \ '(--session)--system' '(--system)--session' \ - '--address=-:bus address:->addresses' \ + '--bus=-:bus address:->addresses' \ + '--peer=-:bus address:->addresses' \ '--dest=-:connection:->connections' \ '--print-reply=-::format:(literal)' \ '--reply-timeout=-:timeout (ms)' \ - '--type=-:type:(method_call signal)' \ + '--sender=-:name' \ + '--type=-:type [signal]:(method_call signal)' \ '(* -)--help' \ ':object path:->objectpaths' \ ':message name:->methods' \ diff --git a/Completion/Unix/Command/_dd b/Completion/Unix/Command/_dd index 10682bc8e..c55efb68c 100644 --- a/Completion/Unix/Command/_dd +++ b/Completion/Unix/Command/_dd @@ -74,7 +74,7 @@ case $variant in vals+=( 'status[specify level of information to print to stderr]:level:(none noxfer progress)' ) - flags+=( fullblock noatime nocache count_bytes skip_bytes seek_bytes ) + flags+=( fullblock noatime nocache ) conv+=( excl nocreat fdatasync fsync ) units=( c:1 w:2 b:512 kB:1000 K:1024 MB:1000^2 M:1024\^2 GB G TB T PB P EB E ZB Z YB Y ) ;; diff --git a/Completion/Unix/Command/_dig b/Completion/Unix/Command/_dig index 3081e2cfd..c09bebbe5 100644 --- a/Completion/Unix/Command/_dig +++ b/Completion/Unix/Command/_dig @@ -6,8 +6,9 @@ local -a alts args '*+'{no,}'tcp[use TCP instead of UDP for queries]' '*+'{no,}'ignore[ignore truncation in UDP responses]' '*+domain=[set search list to single domain]:domain:_hosts' - '*+dscp=[set DSCP code point for query]:code point (0..63)' + '!*+dscp=:code point (0..63)' '*+'{no,}'search[use search list defined in resolv.conf]' + '!*+'{no,}defname '*+'{no,}'showsearch[show intermediate results in domain search]' '*+split[split hex/base64 fields into chunks]:width (characters) [56]' '*+'{no,}'aaonly[set aa flag in the query]' @@ -18,6 +19,7 @@ local -a alts args '*+'{no,}'class[display the CLASS whening printing the record]' '*+'{no,}'cookie[add a COOKIE option to the request]' '*+'{no,}'crypto[display cryptographic fields in DNSSEC records]' + '*+'{no,}'dns64prefix[get the DNS64 prefixes from ipv4only.arpa]' '*+edns=[specify EDNS version for query]:version (0-255)' '*+noedns[clear EDNS version to be sent]' '*+ednsflags=[set EDNS flags bits]:flags' @@ -27,11 +29,15 @@ local -a alts args '*+'{no,}'expandaaaa[expand AAAA records]' '*+'{no,}'expire[send an EDNS Expire option]' '*+'{no,}'header-only[send query without a question section]' + '*+'{no,}'https=[DNS-over-HTTPS POST mode]::endpoint [/dns-query]' + '!*+'{no,}'https-post=::endpoint [/dns-query]' + '*+'{no,}'https-get=[DNS-over-HTTPS GET mode]::endpoint [/dns-query]' + '*+'{no,}'http-plain=[DNS-over-HTTP POST mode]::endpoint [/dns-query]' + '*+'{no,}'http-plain-get=[DNS-over-HTTP GET mode]::endpoint [/dns-query]' '*+'{no,}'idnin[set processing of IDN domain names on input]' '*+'{no,}'idnout[set conversion of IDN puny code on output]' '*+'{no,}'keepalive[request EDNS TCP keepalive]' '*+'{no,}'keepopen[keep TCP socket open between queries]' - '*+'{no,}'mapped[allow mapped IPv4 over IPv6 to be used]' '*+'{no,}'recurse[set the RD (recursion desired) bit in the query]' '*+'{no,}'nssearch[search all authoritative nameservers]' '*+opcode[set DNS message opcode of the request]:opcode [QUERY]:(QUERY IQUERY STATUS NOTIFY UPDATE)' @@ -39,10 +45,12 @@ local -a alts args '*+'{no,}'trace[trace delegation down from root]' '*+'{no,}'cmd[print initial comment in output]' '*+'{no,}'short[print terse output]' + '*+'{no,}'showbadcookie[show BADCOOKIE message]' '*+'{no,}'identify[print IP and port of responder]' '*+'{no,}'comments[print comment lines in output]' '*+'{no,}'stats[print statistics]' '*+padding[set padding block size]:size [0]' + '*+qid=[specify query ID]:query ID' '*+'{no,}'qr[print query as it was sent]' '*+'{no,}'question[print question section of a query]' '*+'{no,}'raflag[set RA flag in the query]' @@ -52,6 +60,11 @@ local -a alts args '*+'{no,}'subnet[send EDNS client subnet option]:addr/prefix-length' '*+'{no,}'tcflag[set TC flag in the query]' '*+timeout=[set query timeout]:timeout (seconds) [5]' + '*+'{no,}'tls[DNS-over-TLS mode]' + '*+'{no,}"tls-ca=[enable remote server's TLS certificate validation]:file:_files" + '*+'{no,}"tls-hostname=[explicitly set the expected TLS hostname]:hostname" + '*+'{no,}'tls-certfile=[load client TLS certificate chain from file]:file:_files' + '*+'{no,}'tls-keyfile=[load client TLS private key from file]:file:_files' '*+tries=[specify number of UDP query attempts]:tries' '*+retry=[specify number of UDP query retries]:retries' '*+'{no,}'rrcomments[set display of per-record comments]' @@ -65,7 +78,6 @@ local -a alts args '*+'{no,}'nsid[include EDNS name server ID request in query]' '*+'{no,}'ttlid[display the TTL whening printing the record]' '*+'{no,}'ttlunits[display the TTL in human-readable units]' - '*+'{no,}'unexpected[print replies from unexpected sources]' '*+'{no,}'unknownformat[print RDATA in RFC 3597 "unknown" format]' '*+'{no,}'yaml[present the results as YAML]' '*+'{no,}'zflag[set Z flag in query]' diff --git a/Completion/Unix/Command/_dmidecode b/Completion/Unix/Command/_dmidecode index 047b74f6d..e2c511313 100644 --- a/Completion/Unix/Command/_dmidecode +++ b/Completion/Unix/Command/_dmidecode @@ -4,6 +4,7 @@ _arguments -s \ '(-d --dev-mem --from-dump)'{-d+,--dev-mem=}'[read memory from specified file]:memory device [/dev/mem]:_files' \ '(-)'{-h,--help}'[display usage information]' \ '(-q --quiet -u --dump)'{-q,--quiet}'[be less verbose]' \ + '--no-quirks[decode everything without quirks]' \ '(-t --type -H --handle -u --dump --dump-bin -s --string)'{-s+,--string=}'[only display value of specified DMI string]:DMI string:(bios-vendor bios-version bios-release-date system-manufacturer system-product-name system-version system-serial-number system-uuid baseboard-manufacturer baseboard-product-name baseboard-version baseboard-serial-number baseboard-asset-tag chassis-manufacturer chassis-type chassis-version chassis-serial-number chassis-asset-tag processor-family processor-manufacturer processor-version processor-frequency)' \ '(-s --string -H --handle --dump-bin)*'{-t+,--type=}'[only display entries of specified type]:entry type:(bios system baseboard chassis processor memory cache connector slot)' \ '(-s --string -t --type -H --handle --dump-bin)'{-H,--handle=}'[only display the entry of specified handle]:handle' \ diff --git a/Completion/Unix/Command/_enscript b/Completion/Unix/Command/_enscript index 3e09da5a4..4658ae4bc 100644 --- a/Completion/Unix/Command/_enscript +++ b/Completion/Unix/Command/_enscript @@ -128,7 +128,7 @@ case "$state" in local suf='{' compquote suf if [[ ${PREFIX} = *[%$]D${suf}[^}]# ]]; then - _strftime + _date_formats elif [[ ${(Q)PREFIX} = *\$\([^\)]# ]]; then compset -P '*\(' _parameters -g '*export*' -S '\)' diff --git a/Completion/Unix/Command/_flac b/Completion/Unix/Command/_flac index 82b6f0160..1773061ee 100644 --- a/Completion/Unix/Command/_flac +++ b/Completion/Unix/Command/_flac @@ -85,6 +85,7 @@ case $service in '(-p --qlp-coeff-precision-search -q --qlp-coeff-precision)'{-p,--qlp-coeff-precision-search}'[exhaustively search LP coeff quantization]' \ '(-p --qlp-coeff-precision-search -q --qlp-coeff-precision)'{-q,--qlp-coeff-precision=}'[specify precision]:precision (bits)' \ '(-r --rice-partition-order)'{-r,--rice-partition-order=}'[set min/max residual partition order]:order' \ + "--limit-min-bitrate[don't allow frames consisting of only constant subframes]" \ '--endian=:byte order:(big little)' \ '--channels=:channels' \ '--bps=:bits per sample' \ diff --git a/Completion/Unix/Command/_getent b/Completion/Unix/Command/_getent index b96852db3..5604e526e 100644 --- a/Completion/Unix/Command/_getent +++ b/Completion/Unix/Command/_getent @@ -8,6 +8,7 @@ typeset -A opt_args if _pick_variant -r is_gnu gnu='(Free Soft|GNU|GLIBC|Gentoo)' unix --version; then args+=( '(- 1 *)'{-\?,--help}'[display help information]' + '(-A --no-addrconfig)'{-A,--no-addrconfig}"[don't filter out unsupported IPv4/IPv6 addresses (with ahosts*)]" '(- 1 *)--usage[display a short usage message]' '(- 1 *)'{-V,--version}'[display version information]' '*'{-s+,--service=}'[specify service configuration to use]: :->services' @@ -23,7 +24,7 @@ case $state in services) # @todo GNU getent supports both `-s svc` and `-s db:svc`; we only complete # the former here - services=( {,/usr}/lib/{,*-linux-gnu/}libnss_*(N-.:fr:t:s/libnss_//) ) + services=( {,/usr}/lib{,64}/{,*-linux-gnu/}libnss_*(N-.:fr:t:s/libnss_//) ) _wanted services expl 'service or database:service' \ compadd ${(u)services%-*} \ && ret=0 diff --git a/Completion/Unix/Command/_gnutls b/Completion/Unix/Command/_gnutls index b9f91264d..9b8bcf6ea 100644 --- a/Completion/Unix/Command/_gnutls +++ b/Completion/Unix/Command/_gnutls @@ -4,8 +4,7 @@ local -a args args=( '(- :)'{-h,--help}'[display help information]' - '(- :)--version=[display version information]:information:((v\:simple c\:copyright n\:full))' - '(- :)-v[display version information]' + '(- :)'{-v+,--version=-}'[display version information]:information:((v\:simple c\:copyright n\:full))' '(- :)'{-\!,--more-help}'[display help information through a pager]' '(-d --debug)'{-d,--debug}'[enable debugging]:debug level' \*{-V,--verbose}'[more verbose output]' @@ -17,6 +16,11 @@ case "$service" in '(-p --port)'{-p,--port}'[specify port or service to connect to]:port:_ports' ) ;| + gnutls-*|certtool) + args+=( + '--attime=[perform validation at the timestamp instead of the system time]:timestamp' + ) + ;| gnutls-cli*) args+=( '(--app-proto --starttls-proto)'{--app-proto,--starttls-proto}"=[specify application protocol to use to obtain the server's certificate]:protocol:(https ftp smtp imap ldap xmpp lmtp pop3 nntp sieve postgres)" @@ -30,6 +34,7 @@ case "$service" in '(-u --udp)'{-u,--udp}'[use DTLS (datagram TLS) over UDP]' '--mtu=[set MTU for datagram TLS]:mtu' '--srtp-profiles=[offer SRTP profiles]:string' + '*--compress-cert=[compress certificate]:compression method' '(-b --heartbeat)'{-b,--heartbeat}'[activate heartbeat support]' '--x509fmtder[use DER format for certificates to read from]' '--priority=[specify TLS algorithms and protocols to enable]:(NORMAL PFS SECURE128 SECURE192 SUITEB128 SUITEB192 LEGACY PERFORMANCE NONE)' @@ -94,7 +99,8 @@ case "$service" in '--post-handshake-auth[enable post-handshake authentication under TLS1.3]' '--inline-commands[inline commands of the form ^^]' '--inline-commands-prefix=[change delimiter used for inline commands]:delimiter [^]' - '--fips140-mode[report status of FIPS140-2 mode in gnutls library]' + '--fips140-mode[report status of FIPS140-3 mode in gnutls library]' + '--list-config[report configuration of the library]' '--logfile=[redirect informational messages to a specific file]:file:_files' '--waitresumption[block waiting for the resumption data under TLS1.3]' '--ca-auto-retrieve[enable automatic retrieval of missing CA certificates]' @@ -127,6 +133,7 @@ case "$service" in '--ignore-ocsp-response-errors[ignore any errors when setting the OCSP response]' '--recordsize=[specify maximum record size to advertise]:record size (0-16384)' '--httpdata=[specify data to use as HTTP response]:file:_files' + '--timeout=[specify he timeout period for server]:timeout' ) ;; diff --git a/Completion/Unix/Command/_gpg b/Completion/Unix/Command/_gpg index 5d54865d5..2161d2d24 100644 --- a/Completion/Unix/Command/_gpg +++ b/Completion/Unix/Command/_gpg @@ -93,6 +93,7 @@ fi '--no-default-recipient[reset default recipient]' '*--encrypt-to[specify recipient]:key:->public-keys' '(--encrypt-to)--no-encrypt-to[disable the use of all --encrypt-to keys]' + '--group[set up email aliases]:spec' '-z[specify compression level]:compression level:((0\:no\ compression 1\:minimum 2 3 4 5 6\:default 7 8 9\:maximum))' '(-t --textmode)'{-t,--textmode}'[use canonical text mode]' '(-n --dry-run)'{-n,--dry-run}"[don't make any changes]" @@ -117,6 +118,7 @@ fi '--utf8-strings' '--no-utf8-strings[arguments are not in UTF8]' '(--no-options)--options[specify file to read options from]:options file:_files' "(--options)--no-options[don't read options file]" + '--log-file[write server mode logs to file]:file:_files' '--'{attribute,passphrase,command}'-fd:file descriptor:_file_descriptors' '--sk-comments[include secret key comments when exporting keys]' '(--emit-version)--no-emit-version[omit version string in clear text signatures]' @@ -170,6 +172,9 @@ fi '--ctapi-driver[file to use to access smartcard reader]:file:_files' '--pcsc-driver[file to use to access smartcard reader]:file:_files' '--auto-key-locate:parameters' + '--auto-key-import[import missing key from a signature]' + '--include-key-block[include the public key in signatures]' + '--disable-dirmngr[disable all access to the dirmngr]' '--dump-options[show all options]' ) diff --git a/Completion/Unix/Command/_gprof b/Completion/Unix/Command/_gprof index a7e602fd5..6b97506a6 100644 --- a/Completion/Unix/Command/_gprof +++ b/Completion/Unix/Command/_gprof @@ -4,7 +4,7 @@ local curcontext="$curcontext" state line ret=1 typeset -A opt_args _arguments -C -s -{a,b,c,D,h,i,l,L,r,s,T,v,w,x,y,z} \ - -{A,C,e,E,f,F,J,n,N,O,p,P,q,Q,R,S,t,Z}:'function name:->funcs' \ + -{A,B,C,e,E,f,F,J,n,N,O,p,P,q,Q,R,S,t,Z}:'function name:->funcs' \ '-I:directory:_dir_list' \ '-d-:debug level:' '-k:function names:->pair' \ '-m:minimum execution count:' \ diff --git a/Completion/Unix/Command/_install b/Completion/Unix/Command/_install index 238b8b5bc..881c99620 100644 --- a/Completion/Unix/Command/_install +++ b/Completion/Unix/Command/_install @@ -27,6 +27,7 @@ if _pick_variant gnu='Free Soft' unix --version; then '(-b --backup)--backup=[create backup; optionally specify method]:: :->controls' "${lx}--context=-[like -Z, or specify SELinux security context to set]::SELinux security context:_selinux_contexts -a file_type" '-D[create all leading destination path components]' + '--debug[explain how a file is copied. Implies -v]' '(: -)--help[display help information]' "${lx}--preserve-context[preserve SELinux security context]" '--strip-program=[specify program used to strip binaries]:strip program:_files' diff --git a/Completion/Unix/Command/_less b/Completion/Unix/Command/_less index 69f75fd0e..8772f5771 100644 --- a/Completion/Unix/Command/_less +++ b/Completion/Unix/Command/_less @@ -56,7 +56,7 @@ _arguments -S -s -A "[-+]*" \ '(-L --no-lessopen)'{-L,--no-lessopen}'[ignore the LESSOPEN environment variable]' \ '(-M --LONG-PROMPT -m --long-prompt)'{-m,--long-prompt}'[prompt verbosely]' \ '(-m --long-prompt -M --LONG-PROMPT)'{-M,--LONG-PROMPT}'[prompt very verbosely]' \ - '(-N --LINE-NUMBERS -n --line-numbers)'{-n,--line-numbers}"[don't keep track of line numbers]" \ + '(-N --LINE-NUMBERS -n --line-numbers)'{-n,--line-numbers}'[suppress line numbers in prompts and messages]' \ '(-n --line-numbers -N --LINE-NUMBERS)'{-N,--LINE-NUMBERS}'[show line numbers]' \ '(* -O --LOG-FILE -o --log-file)'{-o+,--log-file=}'[copy input to file]:file:_files' \ '(* -o --log-file -O --LOG-FILE)'{-O+,--LOG-FILE=}'[copy input to file, overwriting if necessary]:file:_files' \ @@ -83,18 +83,39 @@ _arguments -S -s -A "[-+]*" \ '(-\" --quotes)'{'-\"+',--quotes=}'[change quoting character]:quoting characters' \ '(-~ --tilde)'{-~,--tilde}"[don't display tildes after end of file]" \ '(-\# --shift)'{'-\#+',--shift=}"[specify amount to move when scrolling horizontally]:number" \ + '--exit-follow-on-close[exit F command on a pipe when writer closes pipe]' \ '--file-size[automatically determine the size of the input file]' \ + '--header=[set header size]:lines,columns' \ '--incsearch[search file as each pattern character is typed in]' \ + '--intr=[specify interrupt character instead of ^X]:char [^X]' \ '--line-num-width=[set the width of line number field]:width [7]' \ + '--modelines=[look for vim modelines]:lines to search' \ '--follow-name[the F command changes file if the input file is renamed]' \ '--mouse[enable mouse input]' \ '--no-histdups[remove duplicates from command history]' \ + "--no-number-headers[don't give line numbers to header lines]" \ + "--no-search-headers[don't search in header lines or columns]" \ + "--no-vbell[disable the terminal's visual bell]" \ + '--redraw-on-quit[redraw final screen when quitting]' \ '--rscroll=[set the character used to mark truncated lines]:character [>]' \ '--save-marks[retain marks across invocations of less]' \ + '--search-options=[set default options for every search]: : _values -s "" + "search option" + "E[multi-file]" "F[from first line]" "K[highlight]" + "N[non-matching]" "R[literal]" "W[wrap]" -' \ + '--show-preproc-errors[display a message if preprocessor exits with an error status]' \ + '--proc-backspace[process backspaces for bold/underline]' \ + '--SPECIAL-BACKSPACE[treat backspaces as control characters]' \ + '--proc-return[delete carriage returns before newline]' \ + '--SPECIAL-RETURN[treat carriage returns as control characters]' \ + '--proc-tab[expand tabs to spaces]' \ + '--SPECIAL-TAB[treat tabs as control characters]' \ '--status-col-width=[set the width of the -J status column]:width [2]' \ + '--status-line[highlight or color the entire line containing a mark]' \ '--use-backslash[subsequent options use backslash as escape char]' \ '--use-color[enable colored text]' \ '--wheel-lines=[specify lines to move for each click of the mouse wheel]:lines' \ + '--wordwrap[wrap lines at spaces]' \ "$files[@]" && ret=0 diff --git a/Completion/Unix/Command/_lsof b/Completion/Unix/Command/_lsof index 8afb55e1d..60f59a589 100644 --- a/Completion/Unix/Command/_lsof +++ b/Completion/Unix/Command/_lsof @@ -9,6 +9,7 @@ case $OSTYPE in '-E[display endpoint info for pipes, sockets and pseudoterminal files but not files of the endpoints]' '+E[display endpoint info for pipes, sockets and pseudoterminal files including files of the endpoints]' '-X[skip reporting of info on network connections]' + '*-Z[display or filter by SELinux security context]::context pattern:_selinux_contexts -a domain' ) ;; solaris*) @@ -23,7 +24,6 @@ _arguments -C -s -S $args \ '(-)'{-\?,-h}'[list help]' \ '-a[AND selections]' \ '-b[avoid kernel blocks]' \ - '-C[disable reporting of path name components]' \ '+c[truncate command name to specified characters]:characters' \ '-c[list files with specified command name beginning]:command name' \ '+d[search for open instances for contents of specified dir]:search directory:_files -/' \ @@ -31,16 +31,19 @@ _arguments -C -s -S $args \ '+D[recursively search from specified dir]:search directory:_files -/' \ '-D[direct use of device cache file]:function:((\?\:report\ device\ cache\ file\ paths b\:build\ the\ device\ cache\ file i\:ignore\ the\ device\ cache\ file r\:read\ the\ device\ cache\ file u\:read\ and\ update\ the\ device\ cache\ file))' \ '*-+e[exempt filesystem from blocking kernel calls]:file system:_directories' \ + '-+E[show endpoint information for pipes, sockets, ptys, mqueues and eventfds; with -E, omit endpoint files]' \ '-f[inhibit listing of kernel file structure info]::info type:->file-structures' \ '+f[enable listing of kernel file structure info]::info type:->file-structures' \ '-F[select output fields]:fields:->fields' \ '-g[select by process group id]::process group id:_sequence -s , _pgids' \ + '-H[print human readable sizes]' \ '(*)*-i[select internet files]::address:->addresses' \ '-K+[select listing of tasks of processes]::value:((i\:ignore\ tasks))' \ '-k[specify kernel name list file]:kernel file:_files' \ '-l[inhibit conversion of UIDs to user names]' \ '-L[list no link counts]' \ '+L[list all link counts]::max link count for listed files' \ + '+m[specify or write a mount supplement file]::mount supplement file:_files' \ '-m[specify kernel memory file]:kernel memory file:_files' \ '-M[disable reporting of portmapper registrations]' \ '+M[enable reporting of portmapper registrations]' \ @@ -49,6 +52,7 @@ _arguments -C -s -S $args \ '(-s)-o[list file offset]::digits for file offset' \ '-O[avoid overheads of bypassing potential blocking]' \ '-P[inhibit conversion of port numbers to port names]' \ + '-Q[ignore failed search terms]' \ '-p[list files for specified processes]:process ID:_sequence -s , _pids' \ '-r[repeat listing endlessly]::delay (seconds)' \ '+r[repeat listing until no files listed]::delay (seconds)' \ diff --git a/Completion/Unix/Command/_lua b/Completion/Unix/Command/_lua index 7254d3819..3a1ef4fd7 100644 --- a/Completion/Unix/Command/_lua +++ b/Completion/Unix/Command/_lua @@ -41,6 +41,7 @@ _lua() { _arguments -S -A '-*' : \ '*-e+[execute specified command string]:command string' \ '-E[ignore environment variables]' \ + '-W[turn warnings on]' \ '-i[enter interactive mode]' \ '*-l+[specify library or module to require]: :_lua_libraries' \ '-v[display version information]' \ diff --git a/Completion/Unix/Command/_mpc b/Completion/Unix/Command/_mpc index 7f7adc7b4..c3f93878c 100644 --- a/Completion/Unix/Command/_mpc +++ b/Completion/Unix/Command/_mpc @@ -26,6 +26,7 @@ _mpc_command() { mpc_cmds=( add:"append a song to the end of the current playlist" + albumart:"download album art for the given song and write to stdout" cdprev:"compact disk player-like previous command" channels:"list the channels that other clients have subscribed to" clear:"clear the current playlist" @@ -57,6 +58,7 @@ _mpc_command() { prio:"change song priorities in the queue" queued:"show the next queued song" random:"toggle random mode, or specify state" + readpicture:"download a picture from the given song and write to stdout" repeat:"toggle repeat mode, or specify state" single:"toggle single mode, or specify state" consume:"toggle consume mode, or specify state" @@ -205,6 +207,10 @@ _mpc_add() { _mpc_helper_files } +_mpc_albumart() { + _mpc_helper_files +} + _mpc_del() { _mpc_helper_songnumbers } @@ -304,8 +310,14 @@ _mpc_random() { _mpc_helper_bool } +_mpc_readpicture() { + _mpc_helper_files +} + _mpc_single() { - _mpc_helper_bool + local state + _description states expl state + compadd "$@" "$expl[@]" on once off } _mpc_consume() { diff --git a/Completion/Unix/Command/_nm b/Completion/Unix/Command/_nm index b142c1d54..a78eb7068 100644 --- a/Completion/Unix/Command/_nm +++ b/Completion/Unix/Command/_nm @@ -18,7 +18,7 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu '(-f --format -P --portability)-B[same as --format=bsd]' '(-u --undefined-only)--defined-only[display only defined symbols]' '(-n --numeric-sort -p --no-sort --size-sort -v)'{-n,--numeric-sort}'[sort symbols numerically by address]' - '(-p --no-sort -n -v --numeric-sort -r --reverse-sort --size-sort)'{-p,--no-sort}'[do not sort symbols]' + '(-p --no-sort -n -v --numeric-sort -r --reverse-sort --size-sort)'{-p,--no-sort}"[don't sort symbols]" '(-P --portability -B -f --format)'{-P,--portability}'[same as --format=posix]' '(-r --reverse-sort -p --no-sort)'{-r,--reverse-sort}'[reverse sort order]' '(-u --undefined-only --defined-only)'{-u,--undefined-only}'[display only undefined symbols]' @@ -60,10 +60,10 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu args+=( '!(--no-recurse-limit)--recurse-limit' '--no-recurse-limit[disable demangling recursion limit]' - '(-f --format -P -j)'{-f,--format}'[specify output format]:format:(bsd sysv posix just-symbols)' - '(-C --no-demangle)--demangle=-[decode symbol names]::style [auto]:(auto gnu lucid arm hp edg gnu-v3 java gnat rust dlang)' + '(-f --format -P -j --just-symbols)'{-f+,--format=}'[specify output format]:format [bsd]:(bsd sysv posix just-symbols)' + '(-C --no-demangle)--demangle=-[decode symbol names]::style [auto]:(none auto gnu-v3 java gnat dlang rust)' '--ifunc-chars=[specify characters to use for indirect function symbols]:characters for global/local indirect function symbols [ii]' - '(-B -f --format -P --portability -j --just-symbols)'{-j,--just-symbols}'[Same as --format=just-symbols]' + '(-B -f --format -P --portability -j --just-symbols)'{-j,--just-symbols}'[same as --format=just-symbols]' '--plugin[load specified plugin]:plugin' '--quiet[suppress no "no symbols" diagnostic]' '--special-syms[include special symbols in the output]' diff --git a/Completion/Unix/Command/_objdump b/Completion/Unix/Command/_objdump index e2dde7e4c..94c01eb83 100644 --- a/Completion/Unix/Command/_objdump +++ b/Completion/Unix/Command/_objdump @@ -38,8 +38,10 @@ case $variant in '*-W-[display DWARF info in the file]::dwarf section:->short-dwarf-names' '*--dwarf=-[display DWARF info in the file]::dwarf section:->dwarf-names' + '(-L --process-links)'{-L,--process-links}'[display the contents of non-debug sections in separate debuginfo files]' - '--ctf=[display compact C type format info for section]:section' + '--ctf=-[display compact C type format info for section]::section' + '--sframe=-[display SFrame info from section]::section name [.sframe]' '(-t --syms)'{-t,--syms}'[display the contents of the symbol table(s)]' '(-T --dynamic-syms)'{-T,--dynamic-syms}'[display the contents of the dynamic symbol table]' '(-R --dynamic-reloc)'{-R,--dynamic-reloc}'[display the dynamic relocation entries in the file]' @@ -59,11 +61,13 @@ case $variant in \*{-I+,--include=}'[add directory to search list for source files]:directory:_files -/' '(-l --line-numbers)'{-l,--line-numbers}'[include line numbers and filenames in output]' '(-F --file-offsets)'{-F,--file-offsets}'[include file offsets when displaying information]' - '(-C --demangle)-C[decode mangled/processed symbol names]' - '(-C --demangle)--demangle=-[decode mangled/processed symbol names]::style:(auto gnu lucid arm hp edg gnu-v3 java gnat rust dlang)' + '(--demangle)-C[decode symbol names]' + '(-C)--demangle=-[decode symbol names]::style [auto]:(none auto gnu-v3 java gnat dlang rust)' '!(--no-recurse-limit)--recurse-limit' '--no-recurse-limit[disable demangling recursion limit]' '(-w --wide)'{-w,--wide}'[format output for more than 80 columns]' + '-U+[specify how to display unicode characters]:method:(d l e x h i)' + '--unicode=[specify how to display unicode characters]:method:(default locale escape hex highlight invalid)' '(-z --disassemble-zeroes)'{-z,--disassemble-zeroes}"[don't skip blocks of zeroes when disassembling]" '--start-address=[only process data whose address is >= ADDR]:address' @@ -73,15 +77,17 @@ case $variant in '(--show-raw-insn --no-show-raw-insn)'--{,no-}show-raw-insn'[display hex alongside symbolic disassembly]' '--insn-width=[display specified number of bytes on a single line with -d]:width (bytes)' '--adjust-vma=[add offset to all displayed section addresses]:offset' + '--show-all-symbols[when disassembling, display all symbols at a given address]' '--special-syms[include special symbols in symbol dumps]' '--inlines[print all inlines for source line (with -l)]' '--prefix=[add prefix to absolute paths for -S]:prefix' '--prefix-strip=[strip initial directory names for -S]:level' "--dwarf-depth=[don't display DIEs at specified or greater depth]:depth" '--dwarf-start=[display DIEs at specified or deeper depth]:depth' - '--dwarf-check[perform additional dwarf internal consistency checks]' + '--dwarf-check[perform additional dwarf consistency checks]' '--ctf-parent=[use specified section as the CTF parent]:section' '--visualize-jumps=-[visualize jumps by drawing ASCII art lines]::color:(color extended-color off)' + '--disassembler-color=[control use of colored syntax highlighting in disassembly output]:color use [on]:(off terminal on extended)' ) ;; elfutils) diff --git a/Completion/Unix/Command/_pandoc b/Completion/Unix/Command/_pandoc index b0fff80d6..797e73eaa 100644 --- a/Completion/Unix/Command/_pandoc +++ b/Completion/Unix/Command/_pandoc @@ -113,7 +113,7 @@ _pandoc_defaults_file() { # choose reference location (( $+functions[_pandoc_reference_location] )) || -_pandoc_reference_location(){ +_pandoc_reference_location() { local -a policies policies=( 'block:place references at the end of the current (top-level) block' @@ -123,22 +123,16 @@ _pandoc_reference_location(){ _describe 'location' policies } -# choose top level division -(( $+functions[_pandoc_top_level_division] )) || -_pandoc_top_level_division(){ - _values 'top level division' default section chapter part -} - # choose email obfusication (( $+functions[_pandoc_email_obfusication] )) || _pandoc_email_obfusication(){ local -a policies policies=( - 'none:leave mailto: links as they are' - 'javascript:obfuscates them using JavaScript' - 'references:obfuscates them by printing their letters as decimal or hexadecimal character references' + 'none:leave mailto: links as-is' + 'javascript:obfuscate using JavaScript' + 'references:obfuscate by printing letters as decimal or hexadecimal character references' ) - _describe 'obfuscation policy [none]' policies + _describe 'e-mail obfuscation policy [none]' policies } # choose wrapping policy @@ -181,26 +175,26 @@ _pandoc_track_changes() { _arguments -s \ {-f+,-r+,--from=,--read=}'[specify input format]: :_pandoc_format -T input' \ {-t+,-w+,--to=,--write=}'[specify output format]: :_pandoc_format -T output' \ - {-o+,--output=}'[write output to FILE instead of stdout]:file:_files' \ + {-o+,--output=}'[write output to specified file instead of stdout]:file:_files' \ '--data-dir=[specify the user data directory to search for pandoc data files]:data directory:_files -/' \ {-d+,--defaults=}'[read default from YAML file]: :_pandoc_defaults_file' \ '--shift-heading-level-by=[shift heading levels by specified number]:positive or negative integer: ' \ '!--base-header-level=:number [1]:(1 2 3 4 5)' \ - '!--strip-empty-paragraphs[deprecated. Use the +empty_paragraphs extension instead]' \ - '--indented-code-classes=[classes to use for indented code blocks]:class list (comma-separated)' \ + '--indented-code-classes=[specify classes to use for indented code blocks]:class list (comma-separated)' \ '--default-image-extension=[specify a default extension to use when image paths/URLs have no extension]:extension: ' \ '--file-scope[parse each file individually before combining for multifile documents]' \ + '--sandbox=-[run in a sandbox, limiting IO operations]::enable:(true false)' \ {\*-F+,\*--filter=}'[specify an executable to be used as a filter transforming the pandoc AST after the input is parsed and before the output is written]: :_pandoc_filter' \ {\*-L+,\*--lua-filter=}"[transform the document by using pandoc's built-in lua filtering system]: :_pandoc_lua_filter" \ {\*-M+,\*--metadata=}'[set the metadata field KEY to the value VALUE]:key\:value: ' \ '*--metadata-file=[read metadata from file]:YAML or JSON file:_files' \ {-p,--preserve-tabs}'[preserve tabs instead of converting them to spaces]' \ '--tab-stop=[specify the number of spaces per tab]:spaces [4]' \ - '--track-changes=[specifies what to do with insertions, deletions, and comments produced by the MS Word "Track Changes" feature]: :_pandoc_track_changes' \ + '--track-changes=[specify what to do with insertions, deletions, and comments produced by the MS Word "Track Changes" feature]: :_pandoc_track_changes' \ '--extract-media=[extract media in source document to specified directory]:directory:_files -/' \ - '--abbreviations=[specifies a custom abbreviations file]:file:_files ' \ + '--abbreviations=[specify a custom abbreviations file]:file:_files ' \ {-s,--standalone}'[produce output with an appropriate header and footer]' \ - '--template=[use FILE as a custom template for the generated document. Implies --standalone]: :_pandoc_template' \ + '--template=[use specified file as a custom template for the generated document. Implies --standalone]: :_pandoc_template' \ {\*-V+,\*--variable=}'[set the variable KEY to the value VALUE]:key\:value: ' \ '(- :)'{-D+,--print-default-template=}'[print the system default template for an output]:format:( $(pandoc --list-output-formats) )' \ '(- :)--print-default-data-file=[print a system default data file]:file: ' \ @@ -211,43 +205,48 @@ _arguments -s \ {--toc,--table-of-contents}'[include an automatically generated table of contents]' \ '--toc-depth=[specify the number of section levels to include in the table of contents]:number' \ '--strip-comments[strip out HTML comments in the Markdown or Textile source]' \ - '--no-highlight[disables syntax highlighting for code blocks and inlines]' \ - '--highlight-style=[specifies the coloring style to be used in highlighted source code]:style|file:_pandoc_highlight_style' \ + '--no-highlight[disable syntax highlighting for code blocks and inlines]' \ + '--highlight-style=[specify coloring style to be used in highlighted source code]: :_pandoc_highlight_style' \ '(- :)--print-highlight-style=[prints a JSON version of a highlighting style]: :_pandoc_highlight_style' \ '--syntax-definition=[load a KDE XML syntax definition file]:file:_files -g "*.xml(-.)"' \ - {\*-H+,\*--include-in-header=}'[include contents of FILE, verbatim, at the end of the header, implies --standalone]:file:_files' \ - {\*-B+,\*--include-before-body=}'[include contents of FILE, verbatim, at the beginning of the document body, implies --standalone]:file:_files' \ - {\*-A+,\*--include-end-body=}'[include contents of FILE, verbatim, at the end of the document body, implies --standalone]:file:_files' \ + \*{-H+,--include-in-header=}'[include contents of file, verbatim, at the end of the header, implies --standalone]:file:_files' \ + \*{-B+,--include-before-body=}'[include contents of file, verbatim, at the beginning of the document body, implies --standalone]:file:_files' \ + \*{-A+,--include-end-body=}'[include contents of file, verbatim, at the end of the document body, implies --standalone]:file:_files' \ '--resource-path=[list of paths to search for images and other resources]:searchpath:_dir_list' \ '--request-header=[set the request header NAME to the value VAL when making HTTP requests]:name\:val: ' \ '--no-check-certificate[disable the certificate verification]' \ '--self-contained[produce a standalone HTML file with no external dependencies, using data: URIs to incorporate the contents of linked scripts, stylesheets, images, and videos. Implies --standalone]' \ + '--embed-resources=-[produce a standalone HTML document with no external dependencies]::enable:(true false)' \ '--html-q-tags[use tags for quotes in HTML]' \ '--ascii[use only ASCII characters in output, supported only for HTML and DocBook output]' \ '--reference-links[use reference-style links, rather than inline links]' \ '--reference-location=[specify where footnotes (and references, if reference-links is set) are placed (block|section|document)]: :_pandoc_reference_location' \ '--markdown-headings[specify style for level1 and 2 headings in markdown output]:style [atx]:(setext atx)' \ - '!--atx-headers[use ATX-style headers in Markdown and AsciiDoc output]' \ - '--top-level-division=[treat top-level headers as the given division type in LaTeX, ConTeXt, DocBook, and TEI output]: :_pandoc_top_level_division' \ + '--list-tables=-[render tables as list tables in RST output]::enable(true false)' \ + '--top-level-division=[treat top-level headers as given division type in LaTeX, ConTeXt, DocBook and TEI output]:top level division:(default section chapter part)' \ {-N,--number-sections}'[number section headings in LaTeX, ConTeXt, HTML, or EPUB output]' \ - '--number-offset=[offset for section headings in HTML output (ignored in other output formats)]:number[number,...] [0]' \ + '--number-offset=[specify offset for section headings in HTML output (ignored in other output formats)]:number[number,...] [0]' \ '--listings[use the listings package for LaTeX code blocks]' \ {-i,--incremental}'[make list items in slide shows display incrementally (one by one)]' \ - '--slide-level=[specifies that headers with the specified level create slides (for beamer, s5, slidy, slideous, dzslides)]:slide level:(1 2 3 4 5 6)' \ - '--section-divs[wrap sections in
tags (or
tags for html4)Use the section-divs package for LaTeX code blocks]' \ - '--email-obfusication=[treat top-level headers as the given division type in LaTeX, ConTeXt, DocBook, and TEI output (none|javascript|references)]: :_pandoc_email_obfusication' \ + '--slide-level=[divide into slides for headers above the specified level (for beamer, s5, slidy, slideous, dzslides)]: :_pandoc_header_levels' \ + '--section-divs[wrap sections in
tags (or
tags for html4)]' \ + '--email-obfusication=[specify method for obfusicating mailto: links in HTML documents]: :_pandoc_email_obfusication' \ '--id-prefix=[specify a prefix to be added to all identifiers and internal links in HTML and DocBook output]:string: ' \ {-T+,--title-prefix=}'[specify STRING as a prefix at the beginning of the title that appears in the HTML header]:string: ' \ {\*-c+,\*--css=}'[link to a CSS style sheet]: :_urls' \ - '--reference-doc=[use the specified file as a style reference in producing a docx or ODT file]:file: ' \ + '--reference-doc=[use specified file as a style reference in producing a docx or ODT file]:file:_files' \ '--epub-subdirectory=[specify the subdirectory in the OCF container that is to hold the EPUB-specific contents]:directory:_files -/' \ '--epub-cover-image=[use the specified image as the EPUB cover]:file:_files' \ + '--epub-title-page=-[determine whether title page is included in EPUB]::enable [true]:(true false)' \ '--epub-metadata=[look in the specified XML file for metadata for the EPUB]:file:_files -g "*.xml(-.)"' \ '*--epub-embed-font=[embed the specified font in the EPUB]:file:_files ' \ + '--split-level=[specify heading level at which to split an EPUB or chunked HTML into separate files]:heading level' \ + '--chunk-template=[specify filename template for a chunked html document]:template' \ '--epub-chapter-level=[specify the header level at which to split the EPUB into separate "chapter" files]:number:(1 2 3 4 5 6)' \ '--ipynb-output=[specify how to tread ipynb output cells]:method:(all none best)' \ - '--pdf-engine=[use the specified engine when producing PDF output]:program:_pandoc_pdf_engine' \ - '*--pdf-engine-opt=[use the given string as a command-line argument to the pdf-engine]:string:_pandoc_pdf_engine_opts' \ + '--pdf-engine=[use specified engine when producing PDF output]:program:_pandoc_pdf_engine' \ + '*--pdf-engine-opt=[use given string as a command-line argument to the pdf-engine]:string:_pandoc_pdf_engine_opts' \ + '(-C --citeproc)'{-C,--citeproc}'[process citations]' \ "*--bibliography=[set the bibliography field in the document's metadata to specified file]:file:_files -g '*.(bib|bibtex|copac|json|yaml|enl|xml|wos|medline|mods|ris)(-.)'" \ "--csl=[set the csl field in the document's metadata to specified file]:file:_files -g '*.csl(-.)'" \ '--citation-abbreviations=[set the citation-abbreviations field in the document'"'"'s metadata to FILE]:file:_files' \ @@ -257,10 +256,10 @@ _arguments -s \ '--webtex=[convert TeX formulas to tags that link to an external script that converts formulas to images]:: :_urls' \ '--mathjax=[use MathJax to display embedded TeX math in HTML output]:: :_urls' \ '--katex=[use KaTeX to display embedded TeX math in HTML output]:: :_urls' \ - '--gladtex[Enclose TeX math in tags in HTML output]' \ + '--gladtex[enclose TeX math in tags in HTML output]' \ '--trace[enable tracing]' \ - '--dump-args[print information about command-line arguments to stdout, then exit]' \ - '--ignore-args[ignore command-line arguments (for use in wrapper scripts)]' \ + '!--dump-args' \ + '!--ignore-args' \ '--verbose[give verbose debugging output]' \ '--quiet[suppress warning messages]' \ '--fail-if-warnings[exit with error status if there are any warnings]' \ @@ -271,6 +270,7 @@ _arguments -s \ '(- :)--list-extensions=[list supported extensions, one per line, preceded by a + or - indicating whether it is enabled by default in FORMAT]:format:_pandoc_all_formats' \ '(- :)--list-highlight-languages[list supported languages for syntax highlighting, one per line]' \ '(- :)--list-highlight-styles[list supported styles for syntax highlighting, one per line]' \ + '(- :)--print-highlight-style=[print JSON version of a highlighting style]: :_pandoc_highlight_style' \ '(- :)'{-v,--version}'[print version]' \ '(- :)'{-h,--help}'[print help]' \ '*:file:_files' diff --git a/Completion/Unix/Command/_perl b/Completion/Unix/Command/_perl index d7e8f1b51..1631560ce 100644 --- a/Completion/Unix/Command/_perl +++ b/Completion/Unix/Command/_perl @@ -17,6 +17,7 @@ _perl () { '(1 -e)*-E+[like -e but enable all optional features]:one line of program' \ '-f[disable executing $Config{sitelib}/sitecustomize.pl at startup]' \ '-F-[split() pattern for autosplit (-a)]:split() pattern, // is optional' \ + '-g[read all input in one go (slurp), rather than line-by-line (alias for -0777)]' \ '-h[list help summary]' \ '-i-[edit <> files in place (make backup if extension supplied)]:backup file extension: ' \ '*-I-[specify @INC/#include directory (may be used more than once)]:include path:_files -/' \ diff --git a/Completion/Unix/Command/_pgrep b/Completion/Unix/Command/_pgrep index 9c3ddf039..94c1dae1a 100644 --- a/Completion/Unix/Command/_pgrep +++ b/Completion/Unix/Command/_pgrep @@ -34,6 +34,7 @@ arguments=( '(-P --parent)'{-P+,--parent=}'[match only on specified parent process IDs]: :->ppid' '(-l)-q[suppress normal output]' '(-r --runstates)'{-r+,--runstates}'[match runstates]:run state:compadd -S "" D I R S T t W X Z' + '(-A --ignore-ancestors)'{-A,--ignore-ancestors}'[exclude our ancestors from results]' '-S[search also in system processes (kernel threads)]' '(-s --session)'{-s+,--session=}'[match only on specified process session IDs]: :->sid' # _signals is OK here - we do it differently below @@ -44,6 +45,7 @@ arguments=( '(-u --euid)'{-u+,--euid=}'[match only on specified effective user IDs]: :_sequence _users' '(-v --inverse)'{-v,--inverse}'[negate matching]' '(-x --exact)'{-x,--exact}'[match process name or command line (with -f) exactly]' + '--cgroup=[match by cgroup v2 names]:cgroup' '--ns=[match only on same namespaces as specified PID]: :_pids' '--nslist=[match only on specified namespaces (with --ns)]:namespace:(ipc mnt net pid user uts)' '(: * -)'{-V,--version}'[display version information]' @@ -55,6 +57,8 @@ arguments=( '(-w --lightweight)'{-w,--lightweight}'[show all thread IDs instead of PID]' ) [[ $service == pkill ]] && arguments+=( + '(-H --require-handler)'{-H,--require-handler}'[match only if signal handler is present]' + '(-q --queue)'{-q+,--queue=}'[specify value to be sent with the signal]:value' '(-e --echo)'{-e,--echo}'[display signalled process]' '-l[display kill command]' ) @@ -62,8 +66,8 @@ arguments=( case $OSTYPE in linux*) # Note: We deliberately exclude -v but not --inverse from pkill - pgopts=acdFfGghLlnoOPrstUuVvwx- - pkopts=ceFfGghLnoOPstUuVx- + pgopts=AacdFfGghLlnoOPrstUuVvwx- + pkopts=AceFfGgHhLnoOPstUuVx- arguments=( ${arguments:#((#s)|*\))(\*|)-[acl]*} '(-c --count)'{-c,--count}'[display count of matching processes]' diff --git a/Completion/Unix/Command/_ping b/Completion/Unix/Command/_ping index d36a0f3a9..84bd76b82 100644 --- a/Completion/Unix/Command/_ping +++ b/Completion/Unix/Command/_ping @@ -199,7 +199,9 @@ case ${variant}:${${service#ping}:-4} in '-A[adaptive]' '-b[allow pinging a broadcast address]' "-B[don't allow ping to change source address]" + '-C[call connect() syscall on socket creation]' '-D[print timestamp before each line]' + '-e+[define identifier for ping session]:identifier' '(-4)-F+[allocate and set 20-bit flow label]:flow label (hex)' '(-)-h[show usage information]' '-I+[specify source interface]:interface:_net_interfaces' diff --git a/Completion/Unix/Command/_ps b/Completion/Unix/Command/_ps index 905309a12..c3dfae47d 100644 --- a/Completion/Unix/Command/_ps +++ b/Completion/Unix/Command/_ps @@ -163,10 +163,12 @@ case $OSTYPE in '(-N --deselect)'{-N,--deselect}'[negate selection: all processes except those selected]' '*-C[select processes by command name]:command:_sequence -s , _command_names -e' '*--ppid[select processes by parent process ID]:parent process:_sequence -S , _pids' + '(-D --date-format)'{-D,--date-format=}'[set the date format of the lstart field to format]:format:_strftime' '(-f)-F[extra full format listing]' '--context[show SELinux security context format]' '-M[show security data]' '(--forest -H)'{--forest,-H}'[show process hierarchy]' + '-P[add psr column]' '--headers[repeat header lines, one per page of output]' '(--cols --columns --width)'{--cols,--columns,--width}'[set screen width]:width' '(--lines --rows)'{--lines,--rows}'[set screen height]' diff --git a/Completion/Unix/Command/_pv b/Completion/Unix/Command/_pv index d02d3a35d..b21625650 100644 --- a/Completion/Unix/Command/_pv +++ b/Completion/Unix/Command/_pv @@ -17,7 +17,9 @@ _arguments -s -S $args \ '(-I --fineta -F --format)'{-I,--fineta}'[show absolute estimated time of arrival]' \ '(-r --rate -F --format)'{-r,--rate}'[show data transfer rate counter]' \ '(-a --average-rate -F --format)'{-a,--average-rate}'[show data transfer average rate counter]' \ - '(-b --bytes -F --format)'{-b,--bytes}'[show number of bytes transferred]' \ + '(-m --average-rate-window)'{-m+,--average-rate-window=}'[compute average rate over period]:duration (seconds) [30]' \ + '(-b --bytes -8 --bits -F --format)'{-b,--bytes}'[show number of bytes transferred]' \ + '(-8 --bits -b --bytes -F --format)'{-8,--bits}'[show number of bits transferred]' \ '(-T --buffer-percent -F --format)'{-T,--buffer-percent}'[show percentage of transfer buffer in use]' \ '(-A --last-written -F --format)'{-A+,--last-written=}'[show number of bytes last written]:number (bytes)' \ '(-F --format -p --progress -t --timer -e --eta -I --fineta -r --rate -a --average-rate -b --bytes -T --buffer-percent -A --last-written -F --format)'{-F+,--format=}'[set output format]:format:->formats' \ diff --git a/Completion/Unix/Command/_readelf b/Completion/Unix/Command/_readelf index fc0fb7ce1..b3abdf0a5 100644 --- a/Completion/Unix/Command/_readelf +++ b/Completion/Unix/Command/_readelf @@ -16,10 +16,12 @@ args=( '(-V --version-info)'{-V,--version-info}'[show version sections (if present)]' '(-A --arch-specific)'{-A,--arch-specific}'[show architecture specific information (if any)]' '(-c --archive-index)'{-c,--archive-index}'[show symbol/file index in an archive]' + '(-D --use-dynamic)'{-D,--use-dynamic}'[use dynamic section info when showing symbols]' \*{-x,--hex-dump=}"[dump contents of specified section as bytes]:section:($sections)" \*{-p,--string-dump=}"[dump contents of specified section as strings]:section:($sections)" - '-w+[show the contents of DWARF2 debug sections]::debug section:(l L i a p r m f F s o O R t U u T g A c k K)' - '--debug-dump=[show the contents of DWARF2 debug sections]::section:(rawline decodedline info abbrev pubnames aranges macro frames frames-interp str loc Ranges pubtypes gdb_index trace_info trace_abbrev trace_aranges addr cu_index links follow-links)' + '-w+[show the contents of DWARF2 debug sections]::debug section:(a A r c L f F g i o m p t R l s O u T U k K N)' + '--debug-dump=[show the contents of DWARF2 debug sections]::section:(abbrev addr aranges cu_index decodedline frames frames-interp gdb_index info loc macro pubnames pubtypes Ranges rawline str str-offsets trace_abbrev trace_aranges trace_info links follow-links no-follow-links)' + '(-P --process-links)'{-P,--process-links}'[display the contents of non-debug sections in separate debuginfo files]' '(-I --histogram)'{-I,--histogram}'[show histogram of bucket list lengths]' '(-W --wide)'{-W,--wide}'[allow output width to exceed 80 characters]' '(- *)'{-H,--help}'[display help information]' @@ -35,7 +37,6 @@ case $variant in '(-s --syms --symbols)'{-s,--syms,--symbols}'[show symbol table]' '(-n --notes)'{-n,--notes}'[show core notes (if present)]' '(-u --unwind)'{-u,--unwind}'[show unwind info (if present)]' - '(-D --use-dynamic)'{-D,--use-dynamic}'[use dynamic section info when showing symbols]' ) ;| elfutils|binutils) @@ -50,11 +51,14 @@ case $variant in ;| binutils) args+=( + '--sym-base=[force base for symbol sizes]:base:(0 8 10 16)' '!(-C --demangle)--no-demangle' '(--demangle)-C[decode symbol names]' - '(-C)--demangle=-[decode symbol names]::style [auto]:(auto gnu lucid arm hp edg gnu-v3 java gnat)' + '(-C)--demangle=-[decode symbol names]::style [auto]:(none auto gnu-v3 java gnat dlang rust)' '!(--no-recurse-limit)--recurse-limit' '--no-recurse-limit[disable demangling recursion limit]' + '-U+[specify how to display unicode characters]:method:(d l e x h i)' + '--unicode=[specify how to display unicode characters]:method:(default locale escape hex highlight invalid)' '(-L --lint --enable-checks)'{-L,--lint,--enable-checks}'[display warning messages for possible problems]' \*{-R,--relocated-dump=}"[dump contents of specified section as relocated bytes]:section:($sections)" "--dwarf-depth=[don't show DIEs at greater than specified depth]:depth" @@ -63,6 +67,7 @@ case $variant in '--ctf-parent=[use specified section as the CTF parent]:section' '--ctf-symbols=[use specified section as the CTF external symbol table]:section' '--ctf-strings=[use specified section as the CTF external string table]:section' + '--sframe=-[display SFrame info from section]::section name [.sframe]' '(-T --silent-truncation)'{-T,--silent-truncation}"[if a symbol name is truncated, don't add ... suffix]" ) ;; diff --git a/Completion/Unix/Command/_rsync b/Completion/Unix/Command/_rsync index eb906e974..c65266dbd 100644 --- a/Completion/Unix/Command/_rsync +++ b/Completion/Unix/Command/_rsync @@ -141,8 +141,9 @@ _rsync() { '(-X --xattrs)'{-X,--xattrs}'[preserve extended attributes]' \ '--fake-super[use xattrs to save all file attributes]' \ '(-d --dirs)'{-d,--dirs}'[transfer directories without recursing]' \ - {--no-d,--no-dirs}'[turn off --dirs]' \ - "--mkpath[create the destination's path component]" \ + '(--no-d --no-dirs)'{--no-d,--no-dirs}'[turn off --dirs]' \ + '(--old-dirs --old-d)'{--old-dirs,--old-d}'[work like --dirs when talking to old rsync]' \ + "--mkpath[create destination's missing path components]" \ '(-l --links)'{-l,--links}'[copy symlinks as symlinks]' \ {--no-l,--no-links}'[turn off --links]' \ '(-L --copy-links)'{-L,--copy-links}'[transform symlinks into referent file/dir]' \ @@ -161,8 +162,10 @@ _rsync() { '(-g --group)'{-g,--group}'[preserve group]' \ {--no-g,--no-group}'[turn off --group]' \ '(--devices --specials)-D[same as --devices --specials]' \ - '(-D)--devices[preserve devices]' \ + '(-D --copy-devices --write-devices)--devices[preserve devices]' \ '--no-devices[turn off --devices]' \ + '(-D --devices)--copy-devices[copy device contents as a regular file]' \ + '(-D --devices)--write-devices[write to devices as files (implies --inplace)]' \ '(-D)--specials[preserve special files]' \ '--no-specials[turn off --specials]' \ '--no-D[turn off --devices and --specials]' \ @@ -179,7 +182,7 @@ _rsync() { '(-n --dry-run)'{-n,--dry-run}'[show what would have been transferred]' \ '(-W --whole-file)'{-W,--whole-file}'[copy files whole (without delta-transfer algorithm)]' \ {--no-W,--no-whole-file}'[turn off --whole-file]' \ - '(--cc --checksum-choice)'{--cc,--checksum-choice}'=[choose the checksum algorithms]:algorithm:_sequence -n 2 compadd - auto md4 md5 none' \ + '(--cc --checksum-choice)'{--cc,--checksum-choice}'=[choose the checksum algorithms]:algorithm:_sequence -n 2 compadd - auto xxh128 xxh3 xxh64 xxhash md4 md5 sha1 none' \ '(-x --one-file-system)'{-x,--one-file-system}"[don't cross filesystem boundaries]" \ '(-B --block-size)'{-B+,--block-size=}'[force a fixed checksum block-size]: :_numbers -f -u bytes -d 1g "block size" B K M G T P' \ '(-e --rsh)'{-e+,--rsh=}'[specify the remote shell to use]:remote-shell command:(rsh ssh)' \ @@ -233,7 +236,8 @@ _rsync() { '*--include=[do not exclude files matching pattern]:pattern' \ '--files-from=[read list of source-file names from specified file]:file:_files' \ '(-0 --from0)'{-0,--from0}'[all *-from file lists are delimited by nulls]' \ - '(-s --protect-args)'{-s,--protect-args}'[no space-splitting; only wildcard special-chars]' \ + '(-s --secluded-args)'{-s,--secluded-args}'[use the protocol to safely send arguments]' \ + "--trust-sender[trust the remote sender's file list]" \ '--copy-as=[specify user & optional group for the copy]:user:_rsync_users_groups' \ '--version[print version number]' \ '*'{-h,--human-readable}'[output numbers in a human-readable format]' \ @@ -251,6 +255,7 @@ _rsync() { '--list-only[list the files instead of copying them]' \ '--stop-after=[stop copying after specified time has elapsed]:time (minutes)' \ '--stop-at=[stop copying when specified point in time is reached]:date/time (YYYY-MM-DDTHH\:MM):_dates -F -S "T"' \ + '--fsync[fsync every written file]' \ '(--only-write-batch)--write-batch=[write a batched update to the specified file]:file:_files' \ '(--write-batch)--only-write-batch=[like --write-batch but w/o updating destination]:file:_files' \ '--protocol=[force an older protocol version to be used]:number' \ diff --git a/Completion/Unix/Command/_samba b/Completion/Unix/Command/_samba index 6c7a64e18..a36130cf9 100644 --- a/Completion/Unix/Command/_samba +++ b/Completion/Unix/Command/_samba @@ -5,16 +5,29 @@ local -a state line expl msgs args ign (( CURRENT == 2 )) || ign='!' args=( + '--debug-stdout[send debug output to stdout]' '(-d --debuglevel)'{-d+,--debuglevel=}'[set debug level]:debug level (1..10) [1]' '(-s --configfile)'{-s+,--configfile=}'[specify alternate smb.conf file]:config file:_files' '(-l --log-basename)'{-l+,--log-basename=}'[specify base name for log files]:base name:_files' '*--option=[set smb.conf option from command line]:option=value' + '--leak-report[enable talloc leak reporting on exit]' + '--leak-report-full[enable full talloc leak reporting on exit]' "${ign}(1 2 3 -)"{-\?,--help}'[display usage information]' "${ign}(1 2 3 -)--usage[display brief usage information]" "${ign}(1 2 3 - *)"{-V,--version}'[display version information]' ) case $service in + smbclient|nmblookup) + args+=( + '(2 -R --name-resolve)'{-R+,--name-resolve=}'[specify name resolution order]:name resolution order:_values -s " " "name resolution order" lmhosts host wins bcast' + '(-m --max-protocol)'{-m+,--max-protocol=}'[set the max protocol level]:level' + '(2 -O --socket-options)'{-O+,--socket-options=}'[specify socket options]:socket options' + '(2)--netbios-scope=[specify NetBIOS scope]:scope' + '(2 -W --workgroup)'{-W+,--workgroup=}'[specify workgroup name]:workgroup name' + '--realm=[set the realm name]:realm' + ) + ;| smbcontrol) _arguments -C -S $args \ '(-t --timeout)'{-t+,--timeout=}'[set timeout]:timeout (seconds)' \ @@ -42,12 +55,10 @@ case $service in smbclient) args+=( '(-N -A)2: :_guard "^-*" password' - '(2 -R --name-resolve)'{-R+,--name-resolve=}'[specify name resolution order]:name resolution order:_values -s " " "name resolution order" lmhosts host wins bcast' '(2 -M --message -L --list -D --directory -T --tar)'{-M+,--message=}'[send message]:host:_hosts' '(2 -I --ip-address)'{-I+,--ip-address=}'[specify IP address of server]:IP address' '(2 -E --stderr)'{-E,--stderr}'[output messages to stderr]' '(2 -M --message -D --directory -T --tar)'{-L+,--list=}'[list services on server]:host:_hosts' - '(-m --max-protocol)'{-m+,--max-protocol=}'[set the max protocol level]:level' '(2 -T --tar -M --message -L --list)'{-T+,--tar=}'[specify tar options]:tar options' '(2 -D --directory -M --message -L --list)'{-D+,--directory=}'[specify initial directory]:initial directory' '(2 -c --command)'{-c,--command=}'[specify commands]:command string' @@ -58,19 +69,18 @@ case $service in '(-q --quiet)'{-q,--quiet}'[suppress help message]' '(-B --browse)'{-B,--browse}'[browse SMB servers using DNS]' '(2 -d --debuglevel)'{-d+,--debuglevel=}'[specify debug level]:debug level:(0 1 2 3 4 5 6 7 8 9 10)' - '(2 -O --socket-options)'{-O+,--socket-options=}'[specify socket options]:socket options' '(2 -n --netbiosname)'{-n+,--netbiosname=}'[specify local NetBIOS name]:local machine name' - '(2 -W --workgroup)'{-W+,--workgroup=}'[specify workgroup]:workgroup' - '(2 -i --scope)'{-i+,--scope=}'[specify NetBIOS scope]:scope' '(2 -U --user)'{-U+,--user=}'[specify username]:username:_users' '(2 -N --no-pass)'{-N,--no-pass}'[suppress password prompt]' - '(-k --kerberos)'{-k,--kerberos}'[use kerberos (active directory) authentication]' + '--pw-nt-hash[the supplied password is the NT hash]' '(2 -A --authentication-file)'{-A+,--authentication-file=}'[specify file containing username/password]:file:_files' - '(-S --signing)'{-S+,--signing=}'[set the client signing state]:state:(on off required)' '(-P --machine-pass)'{-P,--machine-pass}'[use stored machine account password]' - '(-e --encrypt)'{-e,--encrypt}'[encrypt SMB transport]' - '(-C --use-ccache)'{-C,--use-ccache}'[use the winbind ccache for authentication]' - '--pw-nt-hash[the supplied password is the NT hash]' + '--simple-bind-dn=[specify DN to use for a simple bind]:DN' + '--use-kerberos=[use Kerberos authentication]:state:(desired required off)' + '--use-krb5-ccache=[specify credentials cache location for Kerberos]:file:_files' + '--use-winbind-ccache[use the winbind ccache for authentication]' + '--client-protection=[configure protection used for client connections]:protection:(sign encrypt off)' + '!(--use-kerberos)'{-k,--kerberos} ) (( CURRENT == 2 )) && args+=( '1:service name:_hosts -P // -S /' ) _arguments -s -S $args @@ -81,16 +91,13 @@ case $service in '(-f --flags)'{-f,--flags}'[list NMB flags returned]' \ '(-U --unicast)'{-U+,--unicast=}'[specify unicast address]:unicast address' \ '(-M --master-browser)'{-M,--master-browser}'[search for a master browser]' \ - '(-R --recursion)'{-R,--recursion}'[set recursion desired in packet]' \ + '--recursion[set recursion desired in packet]' \ '(-S --status)'{-S,--status}'[lookup node status as well]' \ '(-T --translate)'{-T,--translate}'[perform reverse DNS on IP addresses]' \ '(-r --root-port)'{-r,--root-port}'[use root port 137]' \ '(-A --lookup-by-ip)'{-A,--lookup-by-ip}'[query node status on IP address]' \ '(-d --debuglevel)'{-d+,--debuglevel=}'[specify debug level]:debug level:(0 1 2 3 4 5 6 7 8 9 10)' \ - '(-O --socket-options)'{-O+,--socket-options=}'[specify socket options to use]:socket option' \ '(-n --netbiosname)'{-n+,--netbiosname=}'[specify primary netbios name]:netbios name' \ - '(-W --workgroup)'{-W+,--workgroup=}'[specify workgroup name]:workgroup name' \ - '(-i --scope)'{-i+,--scope=}'[specify NetBIOS scope]:scope' \ '(h)*:NetBIOS name:_hosts' ;; smbstatus) diff --git a/Completion/Unix/Command/_sqlite b/Completion/Unix/Command/_sqlite index 6425732f1..6f0b1de94 100644 --- a/Completion/Unix/Command/_sqlite +++ b/Completion/Unix/Command/_sqlite @@ -12,7 +12,7 @@ dashes=( '' ) options=( '(-init --init)'$^dashes'-init[startup file]:file containing SQLite commands:_files' - $^dashes'-echo[echo commands]' + $^dashes'-echo[print inputs before execution]' ) exclusive=( {,-}-{no,}header ) @@ -72,12 +72,14 @@ if [[ -n $words[(r)-A*] ]]; then '(1 -a --append -f --file)'{-f+,--file=}'[specify archive file]:archive file:_files' '(1 -a --append -f --file)'{-a,--append=}'[operate on specified file opened using the apndvfs VFS]:archive file:_files' '(-C --directory)'{-C+,--directory=}'[change to specified directory to read/extract files]:directory:_directories' + '(-g --glob)'{-g,--glob}'[use glob matching for names in archive]' '(-n --dryrun)'{-n,--dryrun}'[show the SQL that would have occurred]' '*:file:_files' + '(commands)' \ '(-c --create)'{-c,--create}'[create a new archive]' '(-u --update)'{-u,--update}'[update or add files to an existing archive]' '(-i --insert)'{-i,--insert}'[like -u but always add even if mtime unchanged]' + '(-r --remove)'{-r,--remove}'[remove files from archive]' '(-t --list)'{-t,--list}'[list contents of archive]' '(-x --extract)'{-x,--extract}'[extract files from archive]' ) diff --git a/Completion/Unix/Command/_strip b/Completion/Unix/Command/_strip index 3e1a6b698..cc67ae49a 100644 --- a/Completion/Unix/Command/_strip +++ b/Completion/Unix/Command/_strip @@ -1,55 +1,68 @@ #compdef strip -local curcontext=$curcontext state line ret=1 +local curcontext=$curcontext state line variant ret=1 declare -A opt_args declare -a args -if _pick_variant gnu=GNU solaris --version; then - if [[ -prefix @* ]]; then - compset -P '@' +if _pick_variant -r variant gnu=GNU elftoolchain=elftoolchain $OSTYPE --version; then + case $variant in + gnu|elftoolchain) + args=( + '(-g -S -d --strip-debug)'{-g,-S,-d,--strip-debug}'[remove debugging symbols]' + '(-I --input-target)'{-I+,--input-target=}'[object code format of input]:bfd name:->bfdnames' + '*'{-K+,--keep-symbol=}'[keep given symbol]:symbol name' + '*'{-N+,--strip-symbol=}'[strip given symbol]:symbol name' + '(-O --output-target)'{-O+,--output-target=}'[object code format of output]:bfd name:->bfdnames' + '(-p --preserve-dates)'{-p,--preserve-dates}'[preserve access and modification dates]' + '*'{-R+,--remove-section=}'[remove given sections]:section name' + '(-s --strip-all)'{-s,--strip-all}'[remove all symbols]' + '(-w --wildcard)'{-w,--wildcard}'[permit wildcards in symbol names]' + '(-X --discard-locals)'{-X,--discard-locals}'[remove compiler-generated local symbols]' + '(-x --discard-all)'{-x,--discard-all}'[remove non-global symbols]' + '--only-keep-debug[remove everything except debugging information]' + '--strip-unneeded[remove symbols not needed for relocation processing]' + '(- 1 *)'{-V,--version}'[display version information and exit]' + ) + ;| + gnu) + if [[ -prefix @* ]]; then + compset -P '@' - local expl + local expl - _description files expl 'command-line-options file' - _files "$expl[@]" - return - fi - args=( - '(-F --target)'{-F+,--target=}'[object code format to use]:bfd name:->bfdnames' - '(-)--help[display usage information]' - '(-)--info[display list of architectures and object formats]' - '(-I --input-target)'{-I+,--input-target=}'[object code format of input]:bfd name:->bfdnames' - '(-O --output-target)'{-O+,--output-target=}'[object code format of output]:bfd name:->bfdnames' - '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-U,--disable-deterministic-archives}'[disable -D behavior]' - '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-D,--enable-deterministic-archives}'[produce deterministic output when stripping archives (zero file metadata)]' - '*'{-R+,--remove-section=}'[remove given sections]:section name' - '--remove-relocations=[remove relocations from specified section]:section' - '(-s --strip-all)'{-s,--strip-all}'[remove all symbols]' - '(-g -S -d --strip-debug)'{-g,-S,-d,--strip-debug}'[remove debugging symbols]' - '--strip-dwo[remove all DWARF .dwo sections]' - '--strip-unneeded[remove symbols not needed for relocation processing]' - '!(--no-merge-notes)'{-M,--merge-notes} - "--no-merge-notes[don't attempt to remove redundant notes]" - '*'{-K+,--keep-symbol=}'[keep given symbol]:symbol name' - '*'{-N+,--strip-symbol=}'[strip given symbol]:symbol name' - "*--keep-section=[don't strip given section]:section" - '(*)-o+[output file]:output file:_files' - '(-p --preserve-dates)'{-p,--preserve-dates}'[preserve access and modification dates]' - '(-w --wildcard)'{-w,--wildcard}'[permit wildcards in symbol names]' - '(-x --discard-all)'{-x,--discard-all}'[remove non-global symbols]' - '(-X --discard-locals)'{-X,--discard-locals}'[remove compiler-generated local symbols]' - '--keep-file-symbols[retain symbols specifying source file names]' - '--only-keep-debug[remove everything except debugging information]' - '(-)'{-V,--version}'[display version information and exit]' - '(-v --verbose)'{-v,--verbose}'[list all object files modified or members of archives]') -else - case $OSTYPE in + _description files expl 'command-line-options file' + _files "$expl[@]" + return + fi + args+=( + '(-F --target)'{-F+,--target=}'[object code format to use]:bfd name:->bfdnames' + '(-)--help[display usage information]' + '(-)--info[display list of architectures and object formats]' + '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-U,--disable-deterministic-archives}'[disable -D behavior]' + '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-D,--enable-deterministic-archives}'[produce deterministic output when stripping archives (zero file metadata)]' + '--remove-relocations=[remove relocations from specified section]:section' + '--strip-dwo[remove all DWARF .dwo sections]' + '!(--no-merge-notes)'{-M,--merge-notes} + "--no-merge-notes[don't attempt to remove redundant notes]" + "*--keep-section=[don't strip given section]:section" + '(*)-o+[output file]:output file:_files' + '--keep-section-symbols[retain section symbols]' + '--keep-file-symbols[retain symbols specifying source file names]' + '(-v --verbose)'{-v,--verbose}'[list all object files modified or members of archives]') + ;; + elftoolchain) + args+=( + '(- 1 *)'{-h,--help}'[display usage information]' + '(*)'{-o+,--output-file=}'[specify output file]:output file:_files' + ) + ;; solaris*) args=( '-l[strip line information only]' '-V[display version information on stderr and exit]' - '-x[do not strip the symbol table]') - ;; + '-x[do not strip the symbol table]' + ) + ;; darwin*) local -a arch arch=( ${(z)${${"$(_call_program architectures @@ -73,12 +86,13 @@ else '-no_uuid[remove only LC_UUID load command]' '-no_split_info[remove LC_SEGMENT_SPLIT_INFO load command]' '-no_code_signature_warning[not warn when code signature would be invalid in the output]' - '-arch[specify the architecture]:architecture:( $arch )' ) - ;; + '-arch[specify the architecture]:architecture:( $arch )' + ) + ;; esac fi -_arguments \ +_arguments -C \ $args \ '1:executable:_files -g "*(-*)"' \ '*::executable:_files -g "*(-*)"' && ret=0 diff --git a/Completion/Unix/Command/_tiff b/Completion/Unix/Command/_tiff index ef12777de..1aeff3ff7 100644 --- a/Completion/Unix/Command/_tiff +++ b/Completion/Unix/Command/_tiff @@ -159,6 +159,7 @@ tiffinfo) '-f+[force fill order]:fill order:(lsb2msb msb2lsb)' \ '-w[display raw data in words]' \ '-z[enable strip chopping]' \ + '-M+[set the memory allocation limit]:limit (MiB), 0 for unlimited' \ '*:input TIFF file:_files -g "*.(#i)tif(|f)(-.)"' && ret=0 ;; tiffmedian) @@ -172,6 +173,7 @@ tiffmedian) ;; tiffsplit) _arguments \ + '-M+[set the memory allocation limit]:limit (MiB), 0 for unlimited' \ ':input file:_files -g "*.(#i)tif(|f)(-.)"' \ ':output file prefix' && ret=0 ;; diff --git a/Completion/Unix/Command/_truss b/Completion/Unix/Command/_truss index b798f03cb..b69e174e6 100644 --- a/Completion/Unix/Command/_truss +++ b/Completion/Unix/Command/_truss @@ -16,7 +16,11 @@ args=( case $OSTYPE in solaris2.<11->) - args+=( '(-c)-A[include absolute timestamps in output]' ) + args+=( + '(-c)-A[include absolute timestamps in output]' + '-I[interpret system calls to well-known rather than underlying names]' + '-N[report only system calls that returned an error]' + ) ;| aix*|solaris*) args+=( diff --git a/Completion/Unix/Command/_user_admin b/Completion/Unix/Command/_user_admin index db1c977ad..d5a53af7c 100644 --- a/Completion/Unix/Command/_user_admin +++ b/Completion/Unix/Command/_user_admin @@ -12,7 +12,7 @@ case ${service%???}:${(M)service%???}:$OSTYPE in shells=( ${(M)commands:#*/(|[abckz]|tc|ba)sh} ) fi args+=( - '(-D -c --commend)'{-c+,--comment=}'[comment]:comment' + '(-D -c --comment)'{-c+,--comment=}'[comment]:comment' '(-D -d --home -b --base-dir)'{-d+,--home=}"[specify home directory]:home directory:_directories -W /" '(-D -e --expiredate)'{-e+,--expiredate}'[specify expiration date]:expiration date (YYYY-MM-DD)' '(-D -f --inactive)'{-f+,--inactive=}'[specify inactive days]:inactive days' @@ -41,6 +41,8 @@ case ${service%???}:${(M)service%???}:$OSTYPE in SYS_GID_MIN SYS_UID_MAX SYS_UID_MIN UID_MAX UID_MIN UMASK ) args+=( + '--btrfs-subvolume-home[use BTRFS subvolume for home directory]' + '(-F --add-subids-for-system)'{-F,--add-subids-for-system}'[add entries to sub[ud]id even when adding a system user]' '(-l --no-log-init)'{-l,--no-log-init}"[don't add user to lastlog and faillog databases]" '(-m --create-home -M --no-create-home)'{-M,--no-create-home}"[don't create user's home directory, regardless of /etc/login.defs]" '(-N --no-user-group -U --user-group)'{-N,--no-user-group}"[don't create a group with the same name as the user]" @@ -103,6 +105,7 @@ case ${service%???}:${(M)service%???}:$OSTYPE in user:mod:linux*) args+=( '(-a --append)'{-a,--append}'[add user to supplementary groups without removing from other groups]' + '(-r --remove)'{-r,--remove}'[remove user from supplementary groups without removing from other groups]' \*{-v,--add-subuids}'[add a range of subordinate uids]:uids (first-last)' \*{-V,--del-subuids}'[remove a range of subordinate uids]:uids (first-last)' \*{-w,--add-subgids}'[add a range of subordinate gids]:gids (first-last)' @@ -118,9 +121,16 @@ case ${service%???}:${(M)service%???}:$OSTYPE in ;| user:*:linux*) args+=( + '(-b --badname)'{-b,--badname}"[don't check for bad names]" '(-U --unlock --lock -L -p)'{-L,--lock}"[lock user's password]" '(-U --unlock --lock -L -p)'{-U,--unlock}"[unlock user's password]" - '(-Z --selinux-user)'{-Z,--selinux-user}"[specify SELinux user for the user's login]:user" + '(-Z --selinux-user)'{-Z,--selinux-user}"[specify SELinux user for the user's login]:user:_selinux_users" + "--selinux-range[specify SELinux MLS range for the user's login]:range" + ) + ;| + group:*:linux*) + args+=( + '(-U --users)'{-U+,--users=}'[specify users to add as members of the group]:user:_sequence _users' ) ;| group:*) @@ -164,6 +174,9 @@ case ${service%???}:${(M)service%???}:$OSTYPE in ':group:_groups' ) ;| + group:mod:linux*) + args+=( '(-a --append)'{-a,--append}'[append the users mentioned by -U without removing existing members]' ) + ;| ^*:linux*) args=( ${(R)args:#(|\*)(|\(*\))--*} ) # remove long options ;| diff --git a/Completion/Unix/Command/_vmstat b/Completion/Unix/Command/_vmstat index e05bc88bc..6db776e62 100644 --- a/Completion/Unix/Command/_vmstat +++ b/Completion/Unix/Command/_vmstat @@ -8,7 +8,7 @@ case $OSTYPE in '(-t --timestamp)'{-t,--timestamp}'[show timestamp]' '(-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))' - '(-C --full-cache)'{-C,--full-cache}'[add further cache lines to main cache]' + '(-y --no-first)'{-y,--no-first}'[skip first line of output]' '1: :_guard "[0-9]#" "interval (seconds)"' '2:count' + '(action)' \ '(- :)'{-h,--help}'[display help information]' diff --git a/Completion/Unix/Command/_vorbis b/Completion/Unix/Command/_vorbis index 6c94469f9..fca218a51 100644 --- a/Completion/Unix/Command/_vorbis +++ b/Completion/Unix/Command/_vorbis @@ -32,7 +32,6 @@ case $service in '(-q --quality)'{-q+,--quality=}'[set encoding quality]:quality:(0 1 2 3 4 5 6 7 8 9 10)' \ '--resample=[resample input to the given sample rate before encoding]:sample rate (Hz)' \ '--downmix[down mix input from stereo to mono]' \ - '--scale=[set input scaling factor]:scaling factor' \ '(-s --serial)'{-s+,--serial=}'[force a specific serial number in the output stream]:serial number' \ "--discard-comments[don't copy comments from FLAC file to output Ogg Vorbis file]" \ '--ignorelength[ignore the datalength in Wave headers]' \ @@ -74,10 +73,6 @@ case $service in '(-q --quiet -v --verbose)'{--quiet,-q}'[quiet mode]' \ '(-q --quiet)*'{-v,--verbose}'[increase verbosity]' \ '(- *)'{-V,--version}'[display version information]' \ - \*{-c-,--config=-}'[specify config options]: :_values option - "default_device\:device" - "shuffle\:value\:(0 1)" - "repeat\:value\:(0 1)"' \ '*:sound file or directory:->urls-or-files' && ret=0 ;; ogginfo) diff --git a/Completion/Unix/Command/_w b/Completion/Unix/Command/_w index 69751c5e5..e82c84f57 100644 --- a/Completion/Unix/Command/_w +++ b/Completion/Unix/Command/_w @@ -1,6 +1,6 @@ #compdef w -local args +local -a args case $OSTYPE in linux*) @@ -11,7 +11,7 @@ case $OSTYPE in '(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 -n --no-truncat)'{-n,--no-truncat}'[non-truncated listing (large)]' + '(H -p --pids)'{-p,--pids}'[show process IDs]' + H '(-)--help[display help information]' '(-)'{-V,--version}'[display version information]' diff --git a/Completion/Unix/Command/_wget b/Completion/Unix/Command/_wget index 50fd7791a..acc8d5c6e 100644 --- a/Completion/Unix/Command/_wget +++ b/Completion/Unix/Command/_wget @@ -23,6 +23,7 @@ _arguments -C -s \ '(--config)--no-config' '--rejected-log=:file:_files' \ '(--tries -t)'{--tries=,-t+}'[set number of retries]:number of retries' \ '--retry-connrefused[retry even if connection is refused]' \ + '--retry-on-host-error[consider host errors as non-fatal, transient errors]' \ '--retry-on-http-error=[specify list of HTTP errors to retry]:http error' \ '(--output-document -O)'{--output-document=,-O+}'[specify file to write documents to]:output file:_files' \ '(--continue -c)'{--continue,-c}'[continue getting an existing file]' \ @@ -98,7 +99,7 @@ _arguments -C -s \ '--content-disposition[honor the Content-Disposition header when choosing local file names]' \ '--content-on-error[output received content on server errors]' \ "--auth-no-challenge[send basic HTTP authentication without first waiting for server's challenge]" \ - '--secure-protocol=[choose secure protocol]:protocol:(SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv1_2 PFS)' \ + '--secure-protocol=[choose secure protocol]:protocol:(SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv1_2 TLSv1_3 PFS)' \ --https-only \ "--no-check-certificate[don't check the server certificate]" \ '--certificate=[specify client certificate]:client certificate file:_files' \ diff --git a/Completion/Unix/Command/_xmlsoft b/Completion/Unix/Command/_xmlsoft index 08b123e54..b8cf92700 100644 --- a/Completion/Unix/Command/_xmlsoft +++ b/Completion/Unix/Command/_xmlsoft @@ -40,6 +40,7 @@ case $service in '--maxdepth[increase the maximum depth]:depth' \ '--maxvars[increase the maximum variables]:variables' \ '--maxparserdepth[increase the maximum parser depth]:depth' \ + '--huge[relax hardcoded limits of the parser]' \ '--seed-rand[initialise random number generator]:seed' \ '--html[input document is an HTML file]' \ '--encoding[the input document character encoding]:encoding:(${encoding[@]})' \ diff --git a/Completion/Unix/Command/_xxd b/Completion/Unix/Command/_xxd index 31d26ab64..e9015a081 100644 --- a/Completion/Unix/Command/_xxd +++ b/Completion/Unix/Command/_xxd @@ -24,7 +24,7 @@ arguments=( # output options '(-b -bits -i -include -p -postscript -plain -ps -r -revert -u -uppercase)'{-b,-bits}'[output in binary digits, rather than hex]' '( -E -EBCDIC -i -include -p -postscript -plain -ps -r -revert )'{-E,-EBCDIC}'[print human-readable part in EBCDIC rather than ASCII]' - '(-i -include -p -postscript -plain -ps -r -revert)'{-e,-endian}'[little-endian dump]' + '(-i -include -p -postscript -plain -ps -r -revert)-e[little-endian dump]' '(-b -bits -E -EBCDIC -i -include -p -postscript -plain -ps -r -revert )'{-i,-include}'[output in C include file style]' '(-b -bits -E -EBCDIC -i -include -p -postscript -plain -ps -C -capitalize )'{-p,-postscript,-plain,-ps}'[read or write a plain hexdump (no line numbers or ASCII rendering)]' @@ -35,12 +35,14 @@ arguments=( '(- :)'{-v,-version}'[show program version]' '*'{-a,-autoskip}"[a single '*' replaces runs of NUL (toggleable)]" '(-C -capitalize)'{-C,-capitalize}'[capitalize variable names in C include file style]' - {-c+,-cols}'[specify number of octets per line]: :_guard "[0-9a-fA-Fx]#" "number of octets per line"' - {-g+,-groupsize}'[specify the number of octets per group]: :_guard "[0-9]#" "number of octets per group"' - {-l+,-len}'[specify number of octets to output]: :_guard "[0-9]#" "number of octets to output"' - {-o+,-offset}'[add specified offset to displayed file position]:offset' + '(-c -cols)'{-c+,-cols}'[specify number of octets per line]: :_guard "(0x|)[0-9a-fA-Fx]#" "number of octets per line"' + '(-g -groupsize)'{-g+,-groupsize}'[specify the number of octets per group]: :_guard "(0x|)[0-9a-fA-F]#" "number of octets per group"' + '(-l -len)'{-l+,-len}'[specify number of octets to output]: :_guard "(0x|)[0-9a-fA-F]#" "number of octets to output"' + '(-n -name)'{-n+,-name}'[override the variable name output when -i is used]:variable name' + '(-o -offset)'{-o+,-offset}'[add specified offset to displayed file position]:offset' '-d[show offset in decimal instead of hex]' - {-s,-skip,-seek}'[specify file offset to dump from]: :_guard "[0-9]#" "file offset to dump from (absolute or relative)"' + '-R+[colorize the output]:when:(always auto never)' + '(-s -skip -seek)'{-s+,-skip,-seek}'[specify file offset to dump from]: :_guard "(0x|)[0-9a-fA-F]#" "file offset to dump from (absolute or relative)"' ': :_files' ) diff --git a/Completion/X/Command/_evince b/Completion/X/Command/_evince index 21b493360..49f11f341 100644 --- a/Completion/X/Command/_evince +++ b/Completion/X/Command/_evince @@ -15,6 +15,7 @@ _arguments -s -S \ '--g-fatal-warnings[make all warnings fatal]' \ '--gtk-debug=[specify GTK+ debugging flags to set]:flag' \ '--gtk-no-debug=[specify GTK+ debugging flags to unset]:flag' \ + '(-o --new-window)'{-o,--new-window}'[open a new window]' \ '(-p --page-label -i --page-index -n --named-dest)'{-p,--page-label=}'[specify page label of the document to display]' \ '(-p --page-label -i --page-index -n --named-dest)'{-i,--page-index=}'[specify page number of the document to display]' \ '(-p --page-label -i --page-index -n --named-dest)'{-n,--named-dest=}'[specify named destination to display]' \ diff --git a/Completion/X/Command/_qiv b/Completion/X/Command/_qiv index 35ceec09a..5d0aa8faf 100644 --- a/Completion/X/Command/_qiv +++ b/Completion/X/Command/_qiv @@ -10,6 +10,7 @@ _arguments -s \ '(-C --cycle)'{-C,--cycle}"[don't cycle after last image]" \ '(-w --fixed_width -W --fixed_zoom)'{-w,--fixed_width}'[use window with specified width]:width' \ '(-w --fixed_width -W --fixed_zoom)'{-W,--fixed_zoom}'[use window with specified zoom factor]:zoom (percentage)' \ + '--highDPIfactor[specify resize factor to compensate for high (or also low) DPI screens]:factor' \ '(-x -y -z --root --root_t --root_s -f --file *)'{-x,--root}'[use image as the current desktop background, centered]:image file:_files' \ '(-x -y -z --root --root_t --root_s -f --file *)'{-y,--root_t}'[use image on the current desktop background, tiled]:image file:_files' \ '(-x -y -z --root --root_t --root_s -f --file *)'{-z,--root_s}'[use image as the current desktop background, stretched]:image file:_files' \ @@ -22,6 +23,9 @@ _arguments -s \ '(-n --no_filter)'{-n,--no_filter}'[disable filtering of images by extension]' \ '(-i --no_statusbar -I --statusbar)'{-i,--no_statusbar}'[disable statusbar]' \ '(-i --no_statusbar -I --statusbar)'{-I,--statusbar}'[enable statusbar]' \ + '(-J --showJPEGcomments)'{-J,--showJPEGcomments}'[enable display of JPEG comments]' \ + '(-E --showArtistName)'{-E,--showArtistName}'[enable display of artist (author) name]' \ + "--artist_ignore[don't show specified artist name]:artist" \ '(-p --transparency)'{-p,--transparency}'[enable transparency]' \ '(-a --do_grab)'{-a,--do_grab}'[grab the pointer in windowed mode]' \ '(-G --disable_grab)'{-G,--disable_grab}'[disable pointer grabbing in fullscreen mode]' \ @@ -47,4 +51,4 @@ _arguments -s \ '(-Y --source_profile)'{-Y,--source_profile}'[specify colour profile file as source profile]:colour profile file:_files' \ '(-Z --display_profile)'{-Z,--display_profile}'[specify colour profile file as display profile]:colour profile file:_files' \ '--vikeys[enable movement with h/j/k/l]' \ - '*:image file:_files -g "*.(#i)(bmp|eim|gif|ico|jp([eg]|eg)|pcx|png|p[pngb]m|pjpeg|svg|tif(|f)|wmf|x[pb]m)(-.)"' + '*:image file:_files -g "*.(#i)(bmp|eim|gif|hei[cf]|ico|jp([eg]|eg)|pcx|png|p[pngb]m|pjpeg|svg|tif(|f)|webp|wmf|x[pb]m)(-.)"' diff --git a/Completion/X/Command/_xdvi b/Completion/X/Command/_xdvi index c33e67bcc..ed5982bcc 100644 --- a/Completion/X/Command/_xdvi +++ b/Completion/X/Command/_xdvi @@ -2,15 +2,22 @@ _xt_arguments \ -+{allowshell,copy,expert,hush{,chars,checksums,specials},keep,l,no{ghostscript,grey,gssafer,makepk,postscript,scan},safer,thorough,underlink,version} \ - +{altfont,base,browser,cr,debug,density,gamma,gspalette,hl,icongeometry,interpreter,margin,mfmode,offsets,p,paper,shrink,S,sidemargin,topmargin,xoffset,yoffset,grid{1,2,3},mgs{,1,2,3,4,5}} \ + +{altfont,background,bg,browser,cr,debug,density,dvispath,editor,gamma,gspalette,hl,icongeometry,interpreter,margin,mfmode,offsets,p,paper,shrink,S,sidemargin,topmargin,xoffset,yoffset,grid{1,2,3},mgs{,1,2,3,4,5}} \ '-altfont:default font' \ - '-base:base URL' \ + -{bg,background}':color:_x_color' \ '-browser:WWW browser:_command_names -e' \ '-cr:cursor color:_x_color' \ - '-debug:debugging bitmask:((1\:bitmaps 2\:dvi\ translation 4\:pk\ reading 8\:batch\ operation 16\:events 32\:file\ opening 64\:PostScript\ communication 128\:Kpathsea\ statistics 256\:Kpathsea\ hash\ table\ lookups 512\:Kpathsea\ path\ definitions 1024\:Kpathsea\ path\ expansion 2048\:Kpathsea\ searches))' \ + '-debug:debugging bitmask:((1\:bitmaps 2\:dvi\ translation 4\:pk\ reading 8\:batch\ operation 16\:events 32\:file\ opening 64\:PostScript\ communication 128\:Kpathsea\ statistics 256\:Kpathsea\ hash\ table\ lookups 512\:Kpathsea\ path\ definitions 1024\:Kpathsea\ path\ expansion 2048\:Kpathsea\ searches ))' \ '-density:font shrink density' \ + '-dvispath:dvips program:_command_names -e' \ + '-editor:text editor:_cmdstring' \ + '-expertmode:display bitmask:((1\:statusline 2\:scrollbars 4\:pagelist 8\:toolbar 16\:menubar))' \ + -{fg,foreground}':color:_x_color' \ + '-findstring:string' \ + '-font:font:_x_font' \ + '-fullscreen' \ '-gamma:anti-aliasing factor [1.0]' \ - -grid{1,2,3}':grid color:_x_color' \ + '-gsalpha' \ '-gspalette:Ghostscript palette:(Color Greyscale Monochrome)' \ '-hl:page highlight color:_x_color' \ '-icongeometry:icon geometry:_x_geometry' \ @@ -21,6 +28,9 @@ _xt_arguments \ '-offsets:offset size' \ '-p:font size (pixel per inch)' \ '-paper:paper size (x or ...):(us usr legal foolscap a1 a2 a3 a4 a5 a6 a7 b1 b2 b3 b4 b5 b6 b7 c1 c2 c3 c4 c5 c6 c7 a1r a2r a3r a4r a5r a6r a7r)' \ + '-ps2pdfpath:ps2pdf program:_command_names -e' \ + '-rulecolor:color' \ + '-rv' \ '-shrink:shrink factor' \ '-S:font shrink density' \ '-sidemargin:side margin' \ -- cgit v1.2.3 From 7a84713bb7a1527d4ef9bfa8c745d1bfa7da9d59 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 22 Nov 2023 00:09:57 +0100 Subject: unposted: fix missing closing brace from 52301 --- ChangeLog | 2 ++ Completion/Unix/Command/_ri | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9132ef9e8..8932d60d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2023-11-22 Oliver Kiddle + * unposted: Completion/Unix/Command/_ri: fix missing closing brace + * 52315: Completion/...: completion options update 2023-11-18 Bart Schaefer diff --git a/Completion/Unix/Command/_ri b/Completion/Unix/Command/_ri index 28de7a9a9..fe458e25f 100644 --- a/Completion/Unix/Command/_ri +++ b/Completion/Unix/Command/_ri @@ -67,7 +67,7 @@ if [[ "$state" = ri-name ]]; then (class-methods) for dir in $ri_dirs[@]; do fnames=( $dir/$class_dir*-c.ri(-.:t) ) - ri_wants+=( ${${fnames%-c.ri//(#b)%(??)/$(print "\\x$match[1]")} ) + ri_wants+=( ${${fnames%-c.ri}//(#b)%(??)/$(print "\\x$match[1]")} ) done ;; (instance-methods) -- cgit v1.2.3 From fbec213cc5ab0d0316c98bd9ddb883bae3bbdbc5 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 23 Nov 2023 13:23:55 -0800 Subject: 52325: Clarify doc for edge cases of named references and nofork substitution Unposted whitespace change avoids a parse error in ${ ... } with comments. --- ChangeLog | 9 +++++++++ Doc/Zsh/expn.yo | 8 +++++++- Doc/Zsh/mod_ksh93.yo | 7 ------- Doc/Zsh/params.yo | 10 +++++++--- Src/subst.c | 2 +- Test/D10nofork.ztst | 2 +- 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8932d60d9..64155b175 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2023-11-23 Bart Schaefer + + * 52325: Doc/Zsh/expn.yo, Doc/Zsh/mod_ksh93.yo, Doc/Zsh/params.yo: + Clarify side-effects of $argv and named references to specials, + update ksh93 feature compatibility. + + unposted: Src/subst.c, Test/D10nofork.ztst: whitespace tweak to + avoid unexpected parse error when comments are used in ${ ... } + 2023-11-22 Oliver Kiddle * unposted: Completion/Unix/Command/_ri: fix missing closing brace diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 837a85db6..e5506d469 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1600,6 +1600,10 @@ example(tt(before local: OUTER) tt(by reference: OUTER) tt(after func: RESULT)) +Note, however, that named references to em(special) parameters acquire +the behavior of the special parameter, regardless of the scope where +the reference is declared. + When var(rname) includes an array subscript, the subscript expression is interpreted at the time tt(${)var(pname)tt(}) is expanded. Any form of subscript is allowed, including those that select individual @@ -1929,7 +1933,9 @@ Note that because the `tt(${|)...tt(})' and `tt(${ )...tt( })' forms must be parsed at once as both string tokens and commands, all other braces (`tt({)' or `tt(})') within the command either must be quoted, or must appear in syntactically valid pairs, such as around complex -commands, function bodies, or parameter references. +commands, function bodies, or parameter references. Furthermore, +comments are always recognized, even when tt(NO_INTERACTIVE_COMMENTS) +is in effect. texinode(Arithmetic Expansion)(Brace Expansion)(Command Substitution)(Expansion) sect(Arithmetic Expansion) diff --git a/Doc/Zsh/mod_ksh93.yo b/Doc/Zsh/mod_ksh93.yo index 99dab385f..9cd708d10 100644 --- a/Doc/Zsh/mod_ksh93.yo +++ b/Doc/Zsh/mod_ksh93.yo @@ -184,13 +184,6 @@ When a function of this name is defined, it is called whenever the parameter var(name) would be unset. The function must explicitly `tt(unset )var(name)', otherwise the variable remains set. -em(THIS FEATURE IS NOT YET IMPLEMENTED.) -) -item(tt(${ )var(list)tt(;}))( -Note the space after the opening brace (tt({)). This executes var(list) -in the current shell and substitutes its standard output in the manner -of `tt($LPAR())var(list)tt(RPAR())' but without forking. - em(THIS FEATURE IS NOT YET IMPLEMENTED.) ) item(tt(typeset -C )var(name)[tt(=)var(values)tt( ...)])( diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 5653b3bc9..68df4a16f 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -748,9 +748,13 @@ vindex(argv) item(tt(argv) )( Same as tt(*). Assigning to tt(argv) changes the local positional parameters, but tt(argv) is em(not) itself a local parameter. -Deleting tt(argv) with tt(unset) in any function deletes it everywhere, -although only the innermost positional parameter array is deleted (so -tt(*) and tt(@) in other scopes are not affected). +Deleting tt(argv) with tt(unset) in any function deletes it everywhere. +This can be avoided by declaring `tt(local +h argv)' before unsetting. +Even when not so declared, only the innermost positional parameter +array is deleted (so tt(*) and tt(@) in other scopes are not affected). + +A named reference to tt(argv) em(does not) permit a called function to +access the positional parameters of its caller. ) vindex(@) item(tt(@) )( diff --git a/Src/subst.c b/Src/subst.c index 4ef1d1269..3a1187350 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1956,7 +1956,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * Then fall through to the regular handling of $REPLY * to manage word splitting, expansion flags, etc. */ - char *outfmt = ">| %s { %s ;}"; /* 13 */ + char *outfmt = ">| %s {\n%s\n;}"; /* 13 */ if ((rplytmp = gettempname(NULL, 1))) { /* Prevent shenanigans with $TMPPREFIX */ char *tmpfile = quotestring(rplytmp, QT_BACKSLASH); diff --git a/Test/D10nofork.ztst b/Test/D10nofork.ztst index 024b8ffcc..d6a5588df 100644 --- a/Test/D10nofork.ztst +++ b/Test/D10nofork.ztst @@ -422,7 +422,7 @@ F:must do this before evaluating the next test block purr ${ { echo nested } } DONE 1:ignored braces, part 4 -?(eval):1: parse error near `}' +?(eval):3: parse error near `}' # "break" blocks function calls in outer loop # Could use print, but that might get fixed -- cgit v1.2.3 From 02a99863b0f9243479cdf9aae220c91cd8facae6 Mon Sep 17 00:00:00 2001 From: Sebastian Gniazdowski Date: Wed, 29 Nov 2023 15:28:56 -0800 Subject: 52145: Prompt theme with current time and abbreviated VCS_info. --- ChangeLog | 5 ++ Functions/Prompts/prompt_sprint2_setup | 128 +++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 Functions/Prompts/prompt_sprint2_setup diff --git a/ChangeLog b/ChangeLog index 64155b175..892072370 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-11-29 Bart Schaefer + + * Sebastian Gniazdowski: 52145: Functions/Prompts/prompt_sprint2_setup: + Contributed prompt theme with current time and abbreviated VCS_info. + 2023-11-23 Bart Schaefer * 52325: Doc/Zsh/expn.yo, Doc/Zsh/mod_ksh93.yo, Doc/Zsh/params.yo: diff --git a/Functions/Prompts/prompt_sprint2_setup b/Functions/Prompts/prompt_sprint2_setup new file mode 100644 index 000000000..0eaea4473 --- /dev/null +++ b/Functions/Prompts/prompt_sprint2_setup @@ -0,0 +1,128 @@ +# Created by Sebastian Gniazdowski + +prompt_sprint2_help () { + cat < + +You can provide only N first arguments, N=1..5. + +The default colors are: 39 green blue green yellow +EOF +} + +prompt_sprint2_setup () { + local col_time_line=${1:-'39'} + local col_parens=${2:-'green'} + local col_text=${3:-'blue'} + local col_at_colon=${4:-'green'} + local col_prompt=${5:-'yellow'} + + autoload -Uz vcs_info + + typeset -gA _psvar + + local cl_time_line="%B%F{$col_time_line}" + local cl_text="%b%F{$col_text}" + local cl_parens="%B%F{$col_parens}" + local cl_at_colon="%b%F{$col_at_colon}" + local cl_prompt="%B%F{$col_prompt}" + local cl_rst="%b%f" + + local _lpar="${cl_parens}[" + local _rpar="${cl_parens}]" + + local _time="$cl_time_line%D{%H:%M}" + _psvar[user]='%n' + local _user="$cl_text"'${_psvar[user]}' + _psvar[at]="@" + _psvar[host]='%m' + local _at="$cl_at_colon"'${_psvar[at]}'"$cl_text"'${_psvar[host]}' + _psvar[colon]=':' + local _path="$cl_at_colon"'${_psvar[colon]}'"$cl_text%28<*<%/%<<" + local _line="$cl_time_line%i" + local _prompt="$cl_prompt# " + + # You can instantly shorten the prompt by setting PSSHORT=1 + if [[ "$COLUMNS" -le 94 || "$PSSHORT" = "1" ]]; then + _psvar=() + else + _psvar[user]='%n' + _psvar[at]="@" + _psvar[host]='%m' + _psvar[colon]=':' + fi + + PS1="$_time$_lpar$_user$_at$_path$_rpar$_line$_prompt$cl_rst" + + PS2="$cl_parens> $cl_rst" + + RPS1='${vcs_info_msg_0_}' + prompt_opts=(cr subst percent) + + zstyle ':vcs_info:*' enable git svn darcs bzr hg + zstyle ':vcs_info:*' stagedstr "%F{green}●$cl_rst" + zstyle ':vcs_info:*' unstagedstr "%F{yellow}●$cl_rst" + zstyle ':vcs_info:*' check-for-changes true + zstyle ':vcs_info:*' formats '(%s)-[%b%u%c]-' + + add-zsh-hook precmd prompt_sprint2_precmd +} + +prompt_sprint2_precmd () { + setopt localoptions noxtrace noksharrays + + # You can instantly shorten the prompt by setting PSSHORT=1 + if [[ "$COLUMNS" -le 94 || "$PSSHORT" = "1" ]]; then + _psvar=() + else + _psvar[user]='%n' + _psvar[at]="@" + _psvar[host]='%m' + _psvar[colon]=':' + fi + + local -a changed_files + changed_files=( ) + git diff --quiet 2>/dev/null || changed_files=( ${(f)"$( git diff --name-only 2>/dev/null )"} ) + changed_files=( $^changed_files(N) ) + if [[ "${#changed_files}" -gt 0 ]]; then + local basedir + basedir="$(git rev-parse --show-toplevel)/" + changed_files=( ${(f)"$( find "${basedir}${^changed_files[@]}" -mtime +2 )"} ) + fi + + if [[ "${#changed_files}" -eq 0 ]]; then + zstyle ':vcs_info:*' formats ' (%s)-[%b%u%c]' + else + zstyle ':vcs_info:*' formats ' (%s)-[%b%u%B%F{yellow}-OLD-%c%%b%f]' + fi + + vcs_info +} + +prompt_sprint2_preview () { + local -a colors_time_line colors_text + colors_time_line=(red yellow green blue magenta cyan) + colors_text=(red yellow green blue magenta cyan) + + local ctime_line ctext i j + + if (( ! $#* )); then + for (( i = 1; i <= ${#colors_time_line}; i++ )); do + ctime_line="${colors_time_line[$i]}" + for (( j = 1; j <= ${#colors_text}; j++ )); do + ctext="${colors_text[$j]}" + prompt_preview_theme sprint2 "$ctime_line" "red" "$ctext" + (( i != ${#colors_time_line} || j != ${#colors_text} )) && print + done + done + else + prompt_preview_theme sprint2 "$@" + fi +} + +prompt_sprint2_setup "$@" + +# vim:ft=zsh -- cgit v1.2.3 From 10bb67df5a223691d977f94cf12db6533c1e3c55 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 2 Dec 2023 14:41:01 -0800 Subject: unposted: Fix email address in some entry attributions --- ChangeLog | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 892072370..d75b64da2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -210,7 +210,7 @@ * 52169: Src/subst.c, Src/utils.c: a few more improvemets of (#) -2023-09-23 Bart Schaefer +2023-09-23 Bart Schaefer * 52180: Doc/Zsh/expn.yo: clarify array behavior of ${|var|...} and the REPLY parameter @@ -1098,7 +1098,7 @@ * 50851: Doc/Zsh/options.yo, Src/exec.c, Src/options.c: restore state (such as typtab) when returning from a function with - localoptions (but do not take care of EMACS/VI options). + localoptions (but do not take care of EMAS/CVI options). 2022-10-31 Bart Schaefer @@ -3383,7 +3383,7 @@ * github #53: James Pike: Completion/Unix/Type/_remote_files: allow specifying directory name. -2020-07-07 Bart Schaefer +2020-07-07 Bart Schaefer * 46189: Test/comptest: Ignore exit status of final zpty_flush @@ -4942,7 +4942,7 @@ * 44779: Completion/Unix/Command/_git: completion for new git switch and git restore commands -2019-09-24 Bart Schaefer +2019-09-24 Bart Schaefer * unposted (see 44772): Functions/Zle/bracketed-paste-magic: quote the string argument to zle -U @@ -5079,7 +5079,7 @@ * unposted: Etc/FAQ.yo: typo. also updates to outdated notes on multibyte support. -2019-07-08 Bart Schaefer +2019-07-08 Bart Schaefer * 43755: Functions/Zle/smart-insert-last-word: (Belated commit) Fix state management for repeat uses to avoid clobbering command -- cgit v1.2.3 From 1ba0fff93cc1aea65b61eacef32c6cefe8d7b7c8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 2 Dec 2023 15:14:12 -0800 Subject: 52360: simplify and improve bad-descriptor detection in %prep section --- ChangeLog | 6 ++++++ Test/A04redirect.ztst | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index d75b64da2..337ea6fb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-12-02 Bart Schaefer + + * 52360: Test/A04redirect.ztst: Simplify bad-descriptor check in + %prep -- avoids accidentally using an open descriptor (derived + from German Riano: 52328) + 2023-11-29 Bart Schaefer * Sebastian Gniazdowski: 52145: Functions/Prompts/prompt_sprint2_setup: diff --git a/Test/A04redirect.ztst b/Test/A04redirect.ztst index 17f6dfa29..dc62efab3 100644 --- a/Test/A04redirect.ztst +++ b/Test/A04redirect.ztst @@ -3,9 +3,8 @@ %prep mkdir redir.tmp && cd redir.tmp - myfd=99 - (echo >&$myfd) 2>msg - bad_fd_msg="${$( Date: Sat, 2 Dec 2023 15:26:46 -0800 Subject: 52361: fix quoting of _ant target files --- ChangeLog | 5 ++++- Completion/Unix/Command/_ant | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 337ea6fb2..ba87b44c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,11 @@ 2023-12-02 Bart Schaefer + * 52361: Completion/Unix/Command/_ant: fix quoting of target files + (derived from Germán Riaño: 52329) + * 52360: Test/A04redirect.ztst: Simplify bad-descriptor check in %prep -- avoids accidentally using an open descriptor (derived - from German Riano: 52328) + from Germán Riaño: 52328) 2023-11-29 Bart Schaefer diff --git a/Completion/Unix/Command/_ant b/Completion/Unix/Command/_ant index 36c7c0e89..91428b854 100644 --- a/Completion/Unix/Command/_ant +++ b/Completion/Unix/Command/_ant @@ -122,13 +122,13 @@ case $state in read default_target junk fi # Output target again indicating its the default one. - print -n "'${default_target}:(Default target) ' " + print -rn -- "${(qq):-${default_target}:(Default target)} " ;; (Searching:*|Main:targets:|Subtargets:|BUILD:SUCCESSFUL|Total:time:*) ;; (*) # Return target and description - print -n "'$ln' " + print -rn -- "${(qq)ln} " ;; esac done -- cgit v1.2.3 From 9e6a54a3680f079fe5433d985c196e6c30ea57e8 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 4 Dec 2023 16:47:24 +0900 Subject: 52356: add missing function index entries --- ChangeLog | 5 +++++ Doc/Zsh/builtins.yo | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index ba87b44c3..881a83021 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-12-04 Jun-ichi Takimoto + + * 52356: (cf. 52327 Dennis Eriksen): Doc/Zsh/builtins.yo: add + missing function index entries + 2023-12-02 Bart Schaefer * 52361: Completion/Unix/Command/_ant: fix quoting of target files diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 8f310f6cf..cab265a25 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -683,6 +683,7 @@ the same as if the commands had been executed directly by the shell; if there are no var(args) or they contain no commands (i.e. are an empty string or whitespace) the return status is zero. ) +findex(exec) item(tt(exec) [ tt(-cl) ] [ tt(-a) var(argv0) ] [ var(command) [ var(arg) ... ] ])( Replace the current shell with var(command) rather than forking. If var(command) is a shell builtin command or a shell function, @@ -1633,6 +1634,7 @@ cancels both tt(-p) and tt(-u). The tt(-c) or tt(-l) flags cancel any and all of tt(-kpquz). ) +findex(readonly) cindex(parameters, marking readonly) item(tt(readonly))( Same as tt(typeset -r). With the tt(POSIX_BUILTINS) option set, same @@ -2413,6 +2415,7 @@ the mask is printed as an octal number. Note that in the symbolic form the permissions you specify are those which are to be allowed (not denied) to the users specified. ) +findex(unalias) cindex(aliases, removing) item(tt(unalias) [ tt(-ams) ] var(name) ...)( Removes aliases. This command works the same as tt(unhash -a), except that -- cgit v1.2.3 From 57d70d1b704ee0bb6b7cae8413940914abae4156 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 4 Dec 2023 20:24:26 -0800 Subject: unposted: Undo typo in previous commit --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 881a83021..68822c023 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1112,7 +1112,7 @@ * 50851: Doc/Zsh/options.yo, Src/exec.c, Src/options.c: restore state (such as typtab) when returning from a function with - localoptions (but do not take care of EMAS/CVI options). + localoptions (but do not take care of EMACS/VI options). 2022-10-31 Bart Schaefer -- cgit v1.2.3 From 0394b7cf1787f1fdeedf3e7fa1ad0ba976bdc862 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 5 Dec 2023 18:46:25 +0100 Subject: 52373: fix _numbers for suffixes containing % and update affected functions --- ChangeLog | 6 ++++++ Completion/Base/Utility/_numbers | 2 +- Completion/Solaris/Command/_dumpadm | 2 +- Completion/Unix/Command/_xz | 17 +++++++++-------- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68822c023..aa995e0d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-12-05 Oliver Kiddle + + * 52373: Completion/Base/Utility/_numbers, + Completion/Solaris/Command/_dumpadm, Completion/Unix/Command/_xz: + fix _numbers for suffixes containing % and update affected functions + 2023-12-04 Jun-ichi Takimoto * 52356: (cf. 52327 Dennis Eriksen): Doc/Zsh/builtins.yo: add diff --git a/Completion/Base/Utility/_numbers b/Completion/Base/Utility/_numbers index 97bb8b4c8..069fc75a4 100644 --- a/Completion/Base/Utility/_numbers +++ b/Completion/Base/Utility/_numbers @@ -73,7 +73,7 @@ elif [[ -prefix $~pat || $PREFIX = $~partial ]]; then zformat -f suffix "$suffixfmt" "x:${${argv[i+1]#:}%%:*}" \ "X:${${argv[i+1]#:}#*:}" "d:${#${argv[i+1]}[1]#:}" \ i:i r:$(( $# - i - 1)) - suffixes+="$suffix" + suffixes+="${suffix//\%/%%}" done [[ -n $suffixes ]] && formats+=( x:$suffixes ) diff --git a/Completion/Solaris/Command/_dumpadm b/Completion/Solaris/Command/_dumpadm index 44d681ae0..aa1c058bb 100644 --- a/Completion/Solaris/Command/_dumpadm +++ b/Completion/Solaris/Command/_dumpadm @@ -16,7 +16,7 @@ _arguments -s \ '-y[run savecore on reboot]' \ '-c[set dump content]:dump content:(($content))' \ '-d[set dump device]: : _alternative "tokens\:token\:(swap none)" "files\:block device\:_files -g \*\(-%b\)"' \ - '-m[set minfree size]:size' \ + '-m[set minfree size]: :_numbers size k m %' \ '-s[set the savecore directory]:directory:_files -/' \ '-r[alternate root directory]:directory:_files -/' \ '-z[enable saving core files in a compressed format]:compression:(on off)' diff --git a/Completion/Unix/Command/_xz b/Completion/Unix/Command/_xz index a4dfea1f5..6e68e0f69 100644 --- a/Completion/Unix/Command/_xz +++ b/Completion/Unix/Command/_xz @@ -22,20 +22,20 @@ case "$service" in '(I)*'{-v,--verbose}'[verbose mode]' \ '(I * --files --files0)--files=-[read list of files to process from file]::file:_files' \ '(I * --files --files0)--files0=-[read null terminated list of files to process from file]::file:_files' \ - '(I -F --format)'{-F,--format}'=[specify file format]:format:(auto xz lzma raw)' \ + '(I -F --format)'{-F+,--format=}'[specify file format]:format:(auto xz lzma lzip raw)' \ '(I -T --threads)'{-T+,--threads=}'[use specified number of threads]:threads [1]' \ - '(I -M --memlimit --memory)'{-M+,--memlimit=,--memory=}'[set memory usage limit]:memory usage' \ + '(I -M --memlimit --memory)'{-M+,--memlimit=,--memory=}'[set memory usage limit]: :_numbers -u bytes "memory limit" KiB MiB GiB %\:percentage\ of\ available\ RAM' \ '(I)--no-adjust[give error if settings exceed memory limit]' \ '(I -Q --no-warn)'{-Q,--no-warn}'[make warnings not affect exit status]' \ + 'comp' \ "(I decomp)"{-z,--compress}'[compress]' \ '(I decomp -e --extreme)'{-e,--extreme}'[try to improve compression ratio by using more CPU time]' \ '(I decomp -S --suffix)'{-S+,--suffix=}'[use specified suffix for compressed files]:suffix [.xz]' \ - '(I decomp -C --check)'{-C,--check}'=[integrity check type]:check type:(none crc32 crc64 sha256)' \ + '(I decomp -C --check)'{-C+,--check=}'[integrity check type]:check type:(none crc32 crc64 sha256)' \ '(I decomp)--block-size=[start a new .xz block after specified bytes of input]:size' \ '(I decomp)--block-list=[start a new .xz block after specified intervals of uncompressed data]:size' \ '(I decomp)--flush-timeout=[specify maximum time between flushing of output]:time (ms) [0]' \ - '(I decomp)--memlimit-compress=[set memory usage limit for compression]:memory usage' \ + '(I decomp)--memlimit-compress=[set memory usage limit for compression]: :_numbers -u bytes "memory limit" KiB MiB GiB %\:percentage\ of\ available\ RAM' \ + 'decomp' \ '(I comp level filters)'{-d,--decompress}'[decompress]' \ '(I comp level filters)'{-t,--test}'[test compressed file integrity]' \ @@ -43,7 +43,8 @@ case "$service" in "(I comp level filters)--ignore-check[don't verify integrity when decompressing]" \ '(I comp level filters)--single-stream[decompress only the first stream]' \ "(I comp level filters)--no-sparse[don't create sparse files when decompressing]" \ - '(I comp level filters)--memlimit-decompress=[set memory usage limit for decompression]:memory usage' \ + '(I comp level filters)--memlimit-decompress=[set memory usage limit for decompression]: :_numbers -u bytes "memory limit" KiB MiB GiB %\:percentage\ of\ available\ RAM' \ + '(I comp level filters)--memlimit-mt-decompress=[set memory usage limit for multi‐threaded decompression]: :_numbers -u bytes "memory limit" KiB MiB GiB %\:percentage\ of\ available\ RAM' \ + '(I)' \ '(* comp decomp level filters common)--info-memory[display amount of RAM and memory usage limits]' \ '(- *)'{-h,--help}'[display help message]' \ @@ -52,7 +53,7 @@ case "$service" in + '(level)' \ '(I filters decomp)-'{-best,-fast,1,2,3,4,5,6,7,8,9} \ + filters \ - '(I level decomp --extreme)'--{x86,powerpc,ia64,arm,armthumb,sparc}=-'[add a branch/call/jump filter]::option:->bcj-options' \ + '(I level decomp --extreme)'--{x86,powerpc,ia64,arm,armthumb,arm64,sparc}=-'[add a branch/call/jump filter]::option:->bcj-options' \ '(I level decomp --extreme)'--lzma{1,2}=-'[add lzma filter]::option:->lzma-options' \ '(I level decomp --extreme)--delta=-[add delta filter]::option:->delta-options' && ret=0 ;; @@ -64,10 +65,10 @@ case $state in [[ -n ${(k)opt_args[(i)decomp*]} ]] && unset decompress if [[ -z "$decompress" ]]; then _description files expl 'compressed file' - _files "$expl[@]" -g '*.(xz|txz|lzma|tlz)(-.)' && return + _files "$expl[@]" -g '*.(xz|txz||lz|lzma|tlz)(-.)' && return else _description files expl 'file to compress' - _files "$expl[@]" -g '^*.(xz|txz|lzma|tlz)(-.)' && return + _files "$expl[@]" -g '^*.(xz|txz|lz|lzma|tlz)(-.)' && return fi ;; lzma-options) -- cgit v1.2.3 From 618f842b464c090f4a6fb02a9f4d217be9270466 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 5 Dec 2023 18:49:42 +0100 Subject: 52326, 52372: add -q option to kill for sigqueue --- ChangeLog | 3 +++ Completion/Zsh/Command/_kill | 1 + Doc/Zsh/builtins.yo | 5 ++++- Src/jobs.c | 36 ++++++++++++++++++++++++++++++++++-- configure.ac | 1 + 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index aa995e0d2..cd3cd4e84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-12-05 Oliver Kiddle + * 52326, 52372: configure.ac, Src/jobs.c, Doc/Zsh/builtins.yo, + Completion/Zsh/Command/_kill: add -q option to kill for sigqueue + * 52373: Completion/Base/Utility/_numbers, Completion/Solaris/Command/_dumpadm, Completion/Unix/Command/_xz: fix _numbers for suffixes containing % and update affected functions diff --git a/Completion/Zsh/Command/_kill b/Completion/Zsh/Command/_kill index b9dfde3f0..084cf42c8 100644 --- a/Completion/Zsh/Command/_kill +++ b/Completion/Zsh/Command/_kill @@ -5,6 +5,7 @@ typeset -A opt_args _arguments -C \ '(-s -l 1)-n[specify signal number]:signal number' \ + '(-l)-q[send the specified integer with the signal using sigqueue]:value' \ '(-n -l 1)-s[specify signal name]:signal:_signals -s' \ '(-n -s)-l[list signal names or numbers of specified signals]:*:signal:_signals' \ '(-n -s -l)1::signal:_signals -p -s' \ diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index cab265a25..1aa807633 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1143,7 +1143,7 @@ findex(kill) cindex(killing jobs) cindex(jobs, killing) xitem(tt(kill) [ tt(-s) var(signal_name) | tt(-n) var(signal_number) | \ -tt(-)var(sig) ] var(job) ...) +tt(-)var(sig) ] [ tt(-q) var(value) ] var(job) ...) item(tt(kill) tt(-l) [ var(sig) ... ])( Sends either tt(SIGTERM) or the specified signal to the given jobs or processes. @@ -1170,6 +1170,9 @@ tt(kill -IO) and tt(kill -POLL) have the same effect. Many systems will allow process IDs to be negative to kill a process group or zero to kill the current process group. + +The tt(-q) option allows an integer value to be sent with the signal +on systems that support tt(sigqueue+LPAR()RPAR()). ) findex(let) item(tt(let) var(arg) ...)( diff --git a/Src/jobs.c b/Src/jobs.c index a3b9f667a..4e9767ee4 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -2677,9 +2677,35 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) { int sig = SIGTERM; int returnval = 0; +#ifdef HAVE_SIGQUEUE + union sigval sigqueue_info; +#endif + int use_sigqueue = 0, got_sig = 0; + + while (*argv && **argv == '-') { + if (!use_sigqueue && (*argv)[1] == 'q' && (*argv)[2] == '\0') { + char *endp; + + if (!*++argv) { + zwarnnam(nam, "-q: argument expected"); + return 1; + } +#ifdef HAVE_SIGQUEUE + sigqueue_info.sival_int = +#endif + zstrtol(*argv, &endp, 10); + if (*endp) { + zwarnnam(nam, "invalid number: %s", *argv); + return 1; + } + use_sigqueue = 1; + argv++; + continue; + } + if (got_sig) + break; /* check for, and interpret, a signal specifier */ - if (*argv && **argv == '-') { if (idigit((*argv)[1])) { char *endp; /* signal specified by number */ @@ -2796,6 +2822,7 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) } } argv++; + got_sig = 1; } /* Discard the standard "-" and "--" option breaks */ @@ -2844,7 +2871,12 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) returnval++; } else { int pid = atoi(*argv); - if (kill(pid, sig) == -1) { + if ( +#ifdef HAVE_SIGQUEUE + use_sigqueue ? sigqueue(pid, sig, sigqueue_info) : +#endif + kill(pid, sig) == -1) + { zwarnnam("kill", "kill %s failed: %e", *argv, errno); returnval++; } diff --git a/configure.ac b/configure.ac index c5263035e..9cb6e032b 100644 --- a/configure.ac +++ b/configure.ac @@ -1299,6 +1299,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ mkfifo _mktemp mkstemp \ waitpid wait3 \ sigaction sigblock sighold sigrelse sigsetmask sigprocmask \ + sigqueue \ killpg setpgid setpgrp tcsetpgrp tcgetattr nice \ gethostname gethostbyname2 getipnodebyname \ inet_aton inet_pton inet_ntop \ -- cgit v1.2.3 From 0ecc456fb2a4dda75e9910bb019d381406f040e8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 9 Dec 2023 19:36:47 -0800 Subject: 52365: record state of exited background jobs so as to be visible in TRAPCHLD --- ChangeLog | 5 +++++ Src/jobs.c | 19 +++++++++++++++++++ Src/signals.c | 16 +++------------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd3cd4e84..af62f6e2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-12-09 Bart Schaefer + + * 52365: Src/jobs.c, Src/signals.c: record state of exited + background jobs sooner so as to be visible in TRAPCHLD + 2023-12-05 Oliver Kiddle * 52326, 52372: configure.ac, Src/jobs.c, Doc/Zsh/builtins.yo, diff --git a/Src/jobs.c b/Src/jobs.c index 4e9767ee4..118c5e61b 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -660,6 +660,25 @@ update_job(Job jn) } } +/**/ +void +update_bg_job(Job jn, pid_t pid, int status) +{ + /* + * Accumulate a list of older jobs. We only do this for + * background jobs, which is something in the job table + * that's not marked as in the current shell or as shell builtin + * and is not equal to the current foreground job. + */ + if (jn && !(jn->stat & (STAT_CURSH|STAT_BUILTIN)) && + jn - jobtab != thisjob) { + if (WIFEXITED(status)) + addbgstatus(pid, WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + addbgstatus(pid, 0200 | WTERMSIG(status)); + } +} + /* set the previous job to something reasonable */ /**/ diff --git a/Src/signals.c b/Src/signals.c index a61368554..b1a843e2c 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -556,9 +556,11 @@ wait_for_processes(void) jn->gleader = 0; } } + update_bg_job(jn, pid, status); update_job(jn); } else if (findproc(pid, &jn, &pn, 1)) { pn->status = status; + update_bg_job(jn, pid, status); update_job(jn); } else { /* If not found, update the shell record of time spent by @@ -567,19 +569,7 @@ wait_for_processes(void) * terminates. */ get_usage(); - } - /* - * Accumulate a list of older jobs. We only do this for - * background jobs, which is something in the job table - * that's not marked as in the current shell or as shell builtin - * and is not equal to the current foreground job. - */ - if (jn && !(jn->stat & (STAT_CURSH|STAT_BUILTIN)) && - jn - jobtab != thisjob) { - if (WIFEXITED(status)) - addbgstatus(pid, WEXITSTATUS(status)); - else if (WIFSIGNALED(status)) - addbgstatus(pid, 0200 | WTERMSIG(status)); + update_bg_job(jn, pid, status); } unqueue_signals(); -- cgit v1.2.3 From 71b7008ceb504822ab1e415951868b986bf57d74 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 9 Dec 2023 19:47:09 -0800 Subject: 52366 + fix typo: rename find_targets as _ant_targets, replace one sed with substitution --- ChangeLog | 3 +++ Completion/Unix/Command/_ant | 11 ++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index af62f6e2a..84334a0af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-12-09 Bart Schaefer + * 52366 + fix typo: Completion/Unix/Command/_ant: rename + find_targets as _ant_targets, replace one sed with substitution + * 52365: Src/jobs.c, Src/signals.c: record state of exited background jobs sooner so as to be visible in TRAPCHLD diff --git a/Completion/Unix/Command/_ant b/Completion/Unix/Command/_ant index 91428b854..fd6112add 100644 --- a/Completion/Unix/Command/_ant +++ b/Completion/Unix/Command/_ant @@ -6,7 +6,8 @@ local curcontext="$curcontext" state line expl ret=1 typeset -A opt_args local buildfile classpath cp userjars importedfiles target='*:target:->target' targets tmp -find_targets() { +(( $+functions[_ant_targets] )) || +_ant_targets() { importedfiles=( $(sed -n "s/ *]* file=[\"']\([^\"']*\)[\"'].*/\1/p" < $1) ) # Tweaked to omit targets beginning with "-" that can't # be invoked from the command line; see zsh-workers/24129. @@ -14,12 +15,12 @@ find_targets() { if (( $#importedfiles )) ; then ( cd $1:h for file in $importedfiles ; do - expanded=( $(echo $file | sed -n "s|\${ant.home}|$ANT_HOME|p") ) - if [[ ! "bla$expanded" = "bla" ]]; then + expanded=${file//\${ant.home}/$ANT_HOME} + if [[ "$expanded" != "$file" ]]; then file=$expanded fi if [[ -f $file ]]; then - find_targets $file + _ant_targets $file fi done ) fi @@ -135,7 +136,7 @@ case $state in )//$'\015'}" _describe 'target' tmp && ret=0 else - targets=( $(find_targets $buildfile) ) + targets=( $(_ant_targets $buildfile) ) _wanted targets expl target compadd -a targets && ret=0 fi else -- cgit v1.2.3 From 4da0f689c42e5a60972a69255d5e7e4fdd41d0be Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 9 Dec 2023 19:48:48 -0800 Subject: unposted: Fix longstanding typo in comment --- Src/parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/parse.c b/Src/parse.c index c0a1e9f95..859f4d0fc 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -601,7 +601,7 @@ clear_hdocs(void) * | sublist [ SEPER | AMPER | AMPERBANG ] * * cmdsubst indicates our event is part of a command-style - * substitution terminated by the token indicationg, usual closing + * substitution terminated by the token indicated, usually closing * parenthesis. In other cases endtok is ENDINPUT. */ -- cgit v1.2.3 From 25f5618b17cf5e9b5add518dffd512fe8503c6b2 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 13 Dec 2023 11:27:32 +0100 Subject: 52382: avoid the non-standard \e in C code, preferring \033 --- ChangeLog | 4 ++++ Src/Modules/ksh93.c | 2 +- Src/Zle/zle_utils.c | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84334a0af..ca505ceea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-12-13 Oliver Kiddle + + * 52382: Src/Modules/ksh93.c, Src/Zle/zle_utils.c: avoid \e in C code + 2023-12-09 Bart Schaefer * 52366 + fix typo: Completion/Unix/Command/_ant: rename diff --git a/Src/Modules/ksh93.c b/Src/Modules/ksh93.c index 51999dd71..9af5e1d69 100644 --- a/Src/Modules/ksh93.c +++ b/Src/Modules/ksh93.c @@ -171,7 +171,7 @@ ksh93_wrapper(Eprog prog, FuncWrap w, char *name) /* bindkey -v forces VIMODE so this test is as good as any */ if (curkeymapname && isset(VIMODE) && strcmp(curkeymapname, "main") == 0) - strcpy(sh_edmode, "\e"); + strcpy(sh_edmode, "\033"); else strcpy(sh_edmode, ""); if (!sh_edchar) diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 51bb43339..e2b86e863 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -977,7 +977,7 @@ cuttext(ZLE_STRING_T line, int ct, int flags) unmetafy(mbcut, &cutll); mbcut = base64_encode(mbcut, cutll); - fprintf(shout, "\e]52;%c;%s\a", zmod.flags & MOD_CLIP ? 'c' : 'p', + fprintf(shout, "\033]52;%c;%s\a", zmod.flags & MOD_CLIP ? 'c' : 'p', mbcut); } else if (zmod.flags & MOD_VIBUF) { struct cutbuffer *b = &vibuf[zmod.vibuf]; -- cgit v1.2.3 From 58840922eeefc90f3e688853ac6ec365fadc3445 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 13 Dec 2023 11:34:12 +0100 Subject: 52392: use octal escape to match = without error messages from awk --- ChangeLog | 3 +++ Src/makepro.awk | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ca505ceea..7867d4926 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-12-13 Oliver Kiddle + * 52392: Src/makepro.awk: use octal escape to match = without + error messages from either GNU awk or Solaris awk + * 52382: Src/Modules/ksh93.c, Src/Zle/zle_utils.c: avoid \e in C code 2023-12-09 Bart Schaefer diff --git a/Src/makepro.awk b/Src/makepro.awk index f69660531..0d53c5850 100644 --- a/Src/makepro.awk +++ b/Src/makepro.awk @@ -121,7 +121,7 @@ BEGIN { # initialiser. dcltor = substr(line, 1, RLENGTH-1) line = substr(line, RLENGTH+1) - sub(/=.*$/, "", dcltor) + sub(/\075.*$/, "", dcltor) match(dcltor, /^([^_0-9A-Za-z]| const )*/) dcltor = substr(dcltor, 1, RLENGTH) "@+" substr(dcltor, RLENGTH+1) match(dcltor, /^.*@\+[_0-9A-Za-z]+/) -- cgit v1.2.3 From 10c3ed20c7068a0564a812ddc232c8f35500813d Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 13 Dec 2023 11:40:03 +0100 Subject: 52393: fix tests on Solaris by omitting -a option to diff as it is not supported there --- ChangeLog | 3 +++ Test/ztst.zsh | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7867d4926..f8762aefe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-12-13 Oliver Kiddle + * 52393: Test/ztst.zsh: fix tests on Solaris by omitting -a option + to diff as it is not supported there + * 52392: Src/makepro.awk: use octal escape to match = without error messages from either GNU awk or Solaris awk diff --git a/Test/ztst.zsh b/Test/ztst.zsh index ea1b016d5..1d05baddf 100755 --- a/Test/ztst.zsh +++ b/Test/ztst.zsh @@ -326,6 +326,7 @@ ZTST_diff() { emulate -L zsh setopt extendedglob + local -a diff_arg local diff_out integer diff_pat diff_ret @@ -342,6 +343,7 @@ ZTST_diff() { ;; esac shift + [[ $OSTYPE != solaris* ]] && diff_arg=( -a ) if (( diff_pat )); then local -a diff_lines1 diff_lines2 @@ -382,7 +384,7 @@ ZTST_diff() { diff_ret=1 fi else - diff_out=$(diff -a "$@") + diff_out=$(diff $diff_arg "$@") diff_ret="$?" if [[ "$diff_ret" != "0" ]]; then print -r -- "$diff_out" -- cgit v1.2.3 From 0b5850c162161512a7faceb7a8acad1c119c5630 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 13 Dec 2023 11:45:38 +0100 Subject: 52394: alter form of /dev/fd test to work where /bin/sh is ksh such as on Solaris 11 --- ChangeLog | 3 +++ configure.ac | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f8762aefe..4110765a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-12-13 Oliver Kiddle + * 52394: configure.ac: alter form of /dev/fd test to work where + /bin/sh is ksh such as on Solaris 11 + * 52393: Test/ztst.zsh: fix tests on Solaris by omitting -a option to diff as it is not supported there diff --git a/configure.ac b/configure.ac index 9cb6e032b..2a8221e1f 100644 --- a/configure.ac +++ b/configure.ac @@ -2016,7 +2016,7 @@ AH_TEMPLATE([PATH_DEV_FD], [Define to the path of the /dev/fd filesystem.]) AC_CACHE_CHECK(for /dev/fd filesystem, zsh_cv_sys_path_dev_fd, [for zsh_cv_sys_path_dev_fd in /proc/self/fd /dev/fd no; do - test x`echo ok|(exec 3<&0; cat $zsh_cv_sys_path_dev_fd/3 2>/dev/null;)` = xok && break + (exec 3<&0; test -e $zsh_cv_sys_path_dev_fd/3;) && break done]) if test x$zsh_cv_sys_path_dev_fd != xno; then AC_DEFINE_UNQUOTED(PATH_DEV_FD, "$zsh_cv_sys_path_dev_fd") -- cgit v1.2.3 From 4c89849c98172c951a9def3690e8647dae76308f Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 8 Dec 2023 21:58:07 +0100 Subject: 52383: Avoid incompatible pointer types in terminfo global variable checks --- ChangeLog | 3 +++ configure.ac | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4110765a0..5c60d4733 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-12-13 Oliver Kiddle + * Florian Weimer: 52383: configure.ac: Avoid incompatible pointer + types in terminfo global variable checks + * 52394: configure.ac: alter form of /dev/fd test to work where /bin/sh is ksh such as on Solaris 11 diff --git a/configure.ac b/configure.ac index 2a8221e1f..2871dcb7c 100644 --- a/configure.ac +++ b/configure.ac @@ -1768,27 +1768,27 @@ if test x$zsh_cv_path_term_header != xnone; then fi AC_MSG_CHECKING(if boolcodes is available) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = boolcodes; puts(*test);]])],[AC_DEFINE(HAVE_BOOLCODES) boolcodes=yes],[boolcodes=no]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = (char **)boolcodes; puts(*test);]])],[AC_DEFINE(HAVE_BOOLCODES) boolcodes=yes],[boolcodes=no]) AC_MSG_RESULT($boolcodes) AC_MSG_CHECKING(if numcodes is available) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = numcodes; puts(*test);]])],[AC_DEFINE(HAVE_NUMCODES) numcodes=yes],[numcodes=no]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = (char **)numcodes; puts(*test);]])],[AC_DEFINE(HAVE_NUMCODES) numcodes=yes],[numcodes=no]) AC_MSG_RESULT($numcodes) AC_MSG_CHECKING(if strcodes is available) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = strcodes; puts(*test);]])],[AC_DEFINE(HAVE_STRCODES) strcodes=yes],[strcodes=no]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = (char **)strcodes; puts(*test);]])],[AC_DEFINE(HAVE_STRCODES) strcodes=yes],[strcodes=no]) AC_MSG_RESULT($strcodes) AC_MSG_CHECKING(if boolnames is available) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = boolnames; puts(*test);]])],[AC_DEFINE(HAVE_BOOLNAMES) boolnames=yes],[boolnames=no]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = (char **)boolnames; puts(*test);]])],[AC_DEFINE(HAVE_BOOLNAMES) boolnames=yes],[boolnames=no]) AC_MSG_RESULT($boolnames) AC_MSG_CHECKING(if numnames is available) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = numnames; puts(*test);]])],[AC_DEFINE(HAVE_NUMNAMES) numnames=yes],[numnames=no]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = (char **)numnames; puts(*test);]])],[AC_DEFINE(HAVE_NUMNAMES) numnames=yes],[numnames=no]) AC_MSG_RESULT($numnames) AC_MSG_CHECKING(if strnames is available) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = strnames; puts(*test);]])],[AC_DEFINE(HAVE_STRNAMES) strnames=yes],[strnames=no]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = (char **)strnames; puts(*test);]])],[AC_DEFINE(HAVE_STRNAMES) strnames=yes],[strnames=no]) AC_MSG_RESULT($strnames) dnl There are apparently defective terminal library headers on some -- cgit v1.2.3 From a528af5c57436c730144e35d97547163c57c8420 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Sat, 16 Dec 2023 23:22:58 +0900 Subject: 52413: support Citrus version of iconv on macOS, DragonFly, NetBSD --- ChangeLog | 5 +++++ Completion/Unix/Command/_iconv | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5c60d4733..e7b785c7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2023-12-06 Jun-ichi Takimoto + + * 52413: Completion/Unix/Command/_iconv: support Citrus version + on macOS, DragonFly and NetBSD + 2023-12-13 Oliver Kiddle * Florian Weimer: 52383: configure.ac: Avoid incompatible pointer diff --git a/Completion/Unix/Command/_iconv b/Completion/Unix/Command/_iconv index bf04acfe4..fba0b9afe 100644 --- a/Completion/Unix/Command/_iconv +++ b/Completion/Unix/Command/_iconv @@ -63,7 +63,7 @@ else '1:file:_files' && return 0 if [[ $state = codeset ]]; then - if [[ $OSTYPE = freebsd* ]]; then + if [[ $OSTYPE = (freebsd|dragonfly|netbsd|darwin)* ]]; then codeset=( $(_call_program codesets $words[1] -l) ) elif [[ -f /usr/lib/iconv/iconv_data ]]; then # IRIX & Solaris codeset=( ${${(f)"$( Date: Fri, 5 Jan 2024 20:38:58 -0800 Subject: 52465: use NULL_GLOB when expanding zmv input pattern to avoid NOMATCH exit --- ChangeLog | 5 +++++ Doc/Zsh/contrib.yo | 8 ++++---- Functions/Misc/zmv | 8 +++++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7b785c7f..1c7e7786f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-01-05 Bart Schaefer + + * 52465: Doc/Zsh/contrib.yo, Functions/Misc/zmv: use NULL_GLOB + when expanding the input pattern to avoid NOMATCH exit + 2023-12-06 Jun-ichi Takimoto * 52413: Completion/Unix/Command/_iconv: support Citrus version diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index f43ac2257..e1781a5e1 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -4668,10 +4668,10 @@ renames `tt(foo.lis)' to `tt(foo.txt)', `tt(my.old.stuff.lis)' to The pattern is always treated as an tt(EXTENDED_GLOB) pattern. Any file whose name is not changed by the substitution is simply ignored. Any -error (a substitution resulted in an empty string, two substitutions gave -the same result, the destination was an existing regular file and tt(-f) -was not given) causes the entire function to abort without doing -anything. +error (no files matched the var(srcpat), substitution resulted in an empty +string, two substitutions gave the same result, the destination was an +existing regular file and tt(-f) was not given) causes the entire function +to abort without doing anything. In addition to pattern replacement, the variable tt($f) can be referred to in the second (replacement) argument. This makes it possible to diff --git a/Functions/Misc/zmv b/Functions/Misc/zmv index 269fe5ba5..5c03e9ea1 100644 --- a/Functions/Misc/zmv +++ b/Functions/Misc/zmv @@ -236,12 +236,18 @@ if [[ $pat = (#b)(*)\((\*\*##/)\)(*) ]]; then else fpat=$pat fi -files=(${~fpat}) [[ -n $hasglobqual ]] && pat=$opat errs=() +() { + # (#qN) breaks bareglobqual -Q option, so: + setopt localoptions nullglob + files=(${~fpat}) +} +(( ${#files} )) || errs=( "no files matched \`$fpat'" ) + for f in $files; do if [[ $pat = (#b)(*)\(\*\*##/\)(*) ]]; then # This looks like a recursive glob. This isn't good enough, -- cgit v1.2.3 From dde12593db1d1ed83e985c8ca5e82fee2ad400be Mon Sep 17 00:00:00 2001 From: Wu Zhenyu Date: Thu, 11 Jan 2024 22:03:52 +0800 Subject: Fix a typo $ valgrind --tool=massif --help | grep time-unit --time-unit=i|ms|B time unit: instructions executed, milliseconds --- ChangeLog | 5 +++++ Completion/Linux/Command/_valgrind | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1c7e7786f..043539756 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-01-14 Matthew Martin + + * github #109: Wu Zhenyu: Completion/Linux/Command/_valgrind: Fix + a typo + 2024-01-05 Bart Schaefer * 52465: Doc/Zsh/contrib.yo, Functions/Misc/zmv: use NULL_GLOB diff --git a/Completion/Linux/Command/_valgrind b/Completion/Linux/Command/_valgrind index e1498be6d..5eaaea338 100644 --- a/Completion/Linux/Command/_valgrind +++ b/Completion/Linux/Command/_valgrind @@ -165,7 +165,7 @@ args_massif=( "--time-unit=-[specify time unit]:unit [i]:(( i\:instructions\ executed ms\:milliseconds - b\:heap\ bytes\ alloc\'d/dealloc\'d + B\:heap\ bytes\ alloc\'d/dealloc\'d ))" '--detailed-freq=-[every Nth snapshot should be detailed]:snapshot interval [10]' '--max-snapshots=-[specofy maximum number of snapshots recorded]:maximum [100]' -- cgit v1.2.3 From 3406089647393c7593e37ee0661a179a9d848c49 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 24 Jan 2024 17:27:41 -0800 Subject: 52468: save and restore state of correct TTY when using read -s / -d --- ChangeLog | 5 +++++ Src/builtin.c | 30 +++++++++++++++--------------- Src/utils.c | 14 ++++++++++++++ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 043539756..b64c62830 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-01-24 Bart Schaefer + + * 52468: Src/builtin.c, Src/utils.c: save and restore state of + correct TTY when using read -s / -d + 2024-01-14 Matthew Martin * github #109: Wu Zhenyu: Completion/Linux/Command/_valgrind: Fix diff --git a/Src/builtin.c b/Src/builtin.c index 9e08a1dbc..5c5adb9d3 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6506,10 +6506,10 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) } else readfd = izle = 0; - if (OPT_ISSET(ops,'s') && SHTTY == readfd) { + if (OPT_ISSET(ops,'s') && isatty(readfd)) { struct ttyinfo ti; memset(&ti, 0, sizeof(struct ttyinfo)); - gettyinfo(&ti); + fdgettyinfo(readfd, &ti); saveti = ti; resettty = 1; #ifdef HAS_TIO @@ -6517,7 +6517,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) #else ti.sgttyb.sg_flags &= ~ECHO; #endif - settyinfo(&ti); + fdsettyinfo(readfd, &ti); } /* handle prompt */ @@ -6555,9 +6555,9 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) delim = (unsigned char) ((delimstr[0] == Meta) ? delimstr[1] ^ 32 : delimstr[0]); #endif - if (SHTTY == readfd) { + if (isatty(readfd)) { struct ttyinfo ti; - gettyinfo(&ti); + fdgettyinfo(readfd, &ti); if (! resettty) { saveti = ti; resettty = 1; @@ -6569,7 +6569,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) #else ti.sgttyb.sg_flags |= CBREAK; #endif - settyinfo(&ti); + fdsettyinfo(readfd, &ti); } } if (OPT_ISSET(ops,'t')) { @@ -6604,8 +6604,8 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) timeout)) { if (keys && !zleactive && !isem) settyinfo(&shttyinfo); - else if (resettty && SHTTY != -1) - settyinfo(&saveti); + else if (resettty) + fdsettyinfo(readfd, &saveti); if (haso) { if (shout) fclose(shout); @@ -6717,7 +6717,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) if (isem) while (val > 0 && read(SHTTY, &d, 1) == 1 && d != '\n'); else if (resettty) { - settyinfo(&shttyinfo); + fdsettyinfo(readfd, &saveti); resettty = 0; } if (haso) { @@ -6746,8 +6746,8 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) setsparam(reply, metafy(buf, bptr - buf, META_REALLOC)); else zfree(buf, bptr - buf + 1); - if (resettty && SHTTY != -1) - settyinfo(&saveti); + if (resettty) + fdsettyinfo(readfd, &saveti); return eof; } @@ -6957,8 +6957,8 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) *pp++ = NULL; setaparam(reply, p); } - if (resettty && SHTTY != -1) - settyinfo(&saveti); + if (resettty) + fdsettyinfo(readfd, &saveti); return c == EOF; } buf = bptr = (char *)zalloc(bsiz = 64); @@ -7086,8 +7086,8 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) break; } *bptr = '\0'; - if (resettty && SHTTY != -1) - settyinfo(&saveti); + if (resettty) + fdsettyinfo(readfd, &saveti); /* final assignment of reply, etc. */ if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) { zputs(buf, stdout); diff --git a/Src/utils.c b/Src/utils.c index 0f66984cd..1a4f4c14b 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1730,6 +1730,13 @@ freestr(void *a) /**/ mod_export void gettyinfo(struct ttyinfo *ti) +{ + fdgettyinfo(SHTTY, ti); +} + +/**/ +mod_export void +fdgettyinfo(int SHTTY, struct ttyinfo *ti) { if (SHTTY != -1) { #ifdef HAVE_TERMIOS_H @@ -1755,6 +1762,13 @@ gettyinfo(struct ttyinfo *ti) /**/ mod_export void settyinfo(struct ttyinfo *ti) +{ + fdsettyinfo(SHTTY, ti); +} + +/**/ +mod_export void +fdsettyinfo(int SHTTY, struct ttyinfo *ti) { if (SHTTY != -1) { #ifdef HAVE_TERMIOS_H -- cgit v1.2.3 From c72b4a74ef3e5031a72cab13d7d6365e8d7ef0fc Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 24 Jan 2024 17:32:45 -0800 Subject: 52473: zstyle -q for testing existence of a zstyle setting --- ChangeLog | 2 ++ Doc/Zsh/mod_zutil.yo | 7 +++++++ Src/Modules/zutil.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/ChangeLog b/ChangeLog index b64c62830..7b30da246 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-01-24 Bart Schaefer + * 52473: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c: zstyle -q + * 52468: Src/builtin.c, Src/utils.c: save and restore state of correct TTY when using read -s / -d diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo index 3cf9e5028..9946618d6 100644 --- a/Doc/Zsh/mod_zutil.yo +++ b/Doc/Zsh/mod_zutil.yo @@ -11,6 +11,7 @@ xitem(tt(zstyle) [ tt(-L) [ var(metapattern) [ var(style) ] ] ]) xitem(tt(zstyle) [ tt(-e) | tt(-) | tt(-)tt(-) ] var(pattern) var(style) var(string) ...) xitem(tt(zstyle -d) [ var(pattern) [ var(style) ... ] ]) xitem(tt(zstyle -g) var(name) [ var(pattern) [ var(style) ] ]) +xitem(tt(zstyle -q) var(context) var(style)) xitem(tt(zstyle -){tt(a)|tt(b)|tt(s)} var(context) var(style) var(name) [ var(sep) ]) xitem(tt(zstyle -){tt(T)|tt(t)} var(context) var(style) [ var(string) ... ]) item(tt(zstyle -m) var(context) var(style) var(pattern))( @@ -105,6 +106,12 @@ enditem() The other forms can be used to look up or test styles for a given context. startitem() +item(tt(zstyle -q) var(context) var(style))( +Return tt(0) if var(style) is defined in var(context). This does not +evaluate expressions defined by tt(zstyle -e) and does not examine any +values set by var(style). The expected use is to test whether a style +has been defined for var(context) before asserting a new style. +) item(tt(zstyle -s) var(context) var(style) var(name) [ var(sep) ])( The parameter var(name) is set to the value of the style interpreted as a string. If the value contains several strings they are concatenated with diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 8b863d5c8..293a62dcf 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -461,6 +461,28 @@ lookupstyle(char *ctxt, char *style) return found; } +static int +testforstyle(char *ctxt, char *style) +{ + Style s; + Stypat p; + int found = 0; + + s = (Style)zstyletab->getnode2(zstyletab, style); + if (s) { + MatchData match; + savematch(&match); + for (p = s->pats; p; p = p->next) + if (pattry(p->prog, ctxt)) { + found = 1; + break; + } + restorematch(&match); + } + + return !found; /* 0 == success */ +} + static int bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) { @@ -570,6 +592,7 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) case 't': min = 2; max = -1; break; case 'T': min = 2; max = -1; break; case 'm': min = 3; max = 3; break; + case 'q': min = 2; max = 2; break; case 'g': min = 1; max = 3; break; default: zwarnnam(nam, "invalid option: %s", args[0]); @@ -723,6 +746,15 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) return 1; } break; + case 'q': + { + int success; + queue_signals(); /* Protect PAT_STATIC */ + success = testforstyle(args[1], args[2]); + unqueue_signals(); + return success; + } + break; case 'g': { int ret = 1; -- cgit v1.2.3 From 0459cc2eafa5041d1fff362a4aa8f6022b957c03 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 24 Jan 2024 17:36:18 -0800 Subject: 52477: fix "zcurses mouse delay ..." and one other typo --- ChangeLog | 2 ++ Src/Modules/curses.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b30da246..66397f10a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-01-24 Bart Schaefer + * 52477: Src/Modules/curses.c: fix "zcurses mouse delay ..." + * 52473: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c: zstyle -q * 52468: Src/builtin.c, Src/utils.c: save and restore state of diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c index ad17ed65f..8950cc153 100644 --- a/Src/Modules/curses.c +++ b/Src/Modules/curses.c @@ -1302,7 +1302,7 @@ zccmd_mouse(const char *nam, char **args) zlong delay; if (!*++args || - ((delay = zstrtol(*args, &eptr, 10)), eptr != NULL)) { + ((delay = zstrtol(*args, &eptr, 10)), *eptr != '\0')) { zwarnnam(nam, "mouse delay requires an integer argument"); return 1; } @@ -1326,7 +1326,7 @@ zccmd_mouse(const char *nam, char **args) if (old_mask != zcurses_mouse_mask) zcurses_flags |= ZCF_MOUSE_MASK_CHANGED; } else { - zwarnnam(nam, "unrecognised mouse command: %s", *arg); + zwarnnam(nam, "unrecognised mouse command: %s", arg); return 1; } } -- cgit v1.2.3 From 0fccdf0d57fb8ed4b88df6681d15822f3c4e784f Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 24 Jan 2024 17:42:36 -0800 Subject: 52476 + cf. 52479: more FAQs about nofork substitution --- ChangeLog | 2 ++ Etc/FAQ.yo | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/ChangeLog b/ChangeLog index 66397f10a..d51d527b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-01-24 Bart Schaefer + * 52476 + cf. 52479: Etc/FAQ.yo: more about nofork substitution + * 52477: Src/Modules/curses.c: fix "zcurses mouse delay ..." * 52473: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c: zstyle -q diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 270a04608..7d46e9192 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -1067,6 +1067,44 @@ label(211) quoted, that is, included in a quoted string or prefixed by backslash. These substitutions first become usable after zsh 5.9. +sect(Comparisons of forking and non-forking command substitution) + + mytt(${ command }) and variants may change the caller's options by using + mytt(setopt) and may modify the caller's local parameters, including the + positional parameters mytt($1), mytt($2), etc., via both assignments and + mytt(set -- pos1 pos2 etc). Nothing that happens within mytt($(command)) + affects the caller. + + mytt($(command)) removes trailing newlines from the output of mytt(command) + when substituting, whereas mytt(${ command }) and its variants do not. + The latter is consistent with mytt(${|...}) from mksh but differs from + bash and ksh, so in emulation modes, newlines are stripped from command + output (not from mytt(REPLY) assignments). + + When mytt(command) is myem(not) a builtin, mytt(${ command }) does fork, and + typically forks the same number of times as mytt($(command)), because in + the latter case zsh usually optimizes the final fork into an exec. + + Redirecting input from files has subtle differences: + + mytt($( Date: Wed, 24 Jan 2024 17:56:21 -0800 Subject: 52482: strip trailing newlines in emulation modes of ${ command; } --- ChangeLog | 3 +++ Src/subst.c | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index d51d527b8..d46ce5fe5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-24 Bart Schaefer + * 52482: Src/subst.c: strip trailing newlines in emulation modes + of ${ command; }, for bash/ksh compatibility + * 52476 + cf. 52479: Etc/FAQ.yo: more about nofork substitution * 52477: Src/Modules/curses.c: fix "zcurses mouse delay ..." diff --git a/Src/subst.c b/Src/subst.c index 3a1187350..650c09de2 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2005,6 +2005,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, int onoerrs = noerrs, rplylen; noerrs = 2; rplylen = zstuff(&cmdarg, rplytmp); + if (! EMULATION(EMULATE_ZSH)) { + /* bash and ksh strip trailing newlines here */ + while (rplylen > 0 && cmdarg[rplylen-1] == '\n') + rplylen--; + cmdarg[rplylen] = 0; + } noerrs = onoerrs; if (rplylen >= 0) setsparam("REPLY", metafy(cmdarg, rplylen, META_REALLOC)); -- cgit v1.2.3 From 1f861ceba1d5740798caa0a3f208f3047c6e3ff5 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 24 Jan 2024 18:00:16 -0800 Subject: 52492: prevent indexing error on recursive arithmetic in array subscript Operator returns error when operand returns error --- ChangeLog | 3 +++ Src/math.c | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d46ce5fe5..b876cb6d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-24 Bart Schaefer + * 52492: Src/math.c: prevent indexing error when using recursive + arithmetic in array subscript (operator stops on operand error) + * 52482: Src/subst.c: strip trailing newlines in emulation modes of ${ command; }, for bash/ksh compatibility diff --git a/Src/math.c b/Src/math.c index a060181ed..50b69d6a1 100644 --- a/Src/math.c +++ b/Src/math.c @@ -352,6 +352,8 @@ getmathparam(struct mathvalue *mptr) } return zero_mnumber; } + if (errflag) + return zero_mnumber; } result = getnumvalue(mptr->pval); if (isset(FORCEFLOAT) && result.type == MN_INTEGER) { @@ -1367,8 +1369,11 @@ op(int what) } spval = &stack[sp].val; - if (stack[sp].val.type == MN_UNSET) + if (stack[sp].val.type == MN_UNSET) { *spval = getmathparam(stack + sp); + if (errflag) + return; + } switch (what) { case NOT: if (spval->type & MN_FLOAT) { -- cgit v1.2.3 From 2a538491ebdaaf41ad07e5b7a4d4d994faafb355 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 24 Jan 2024 18:06:44 -0800 Subject: 52496 + 52377: clarify SPROMPT behavior when CORRECT_ALL is set --- ChangeLog | 3 +++ Doc/Zsh/options.yo | 8 +++++++- Doc/Zsh/params.yo | 10 +++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b876cb6d1..ecb883c75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-24 Bart Schaefer + * 52496 + 52377: Doc/Zsh/options.yo, Doc/Zsh/params.yo: clarify + SPROMPT behavior when CORRECT_ALL is set + * 52492: Src/math.c: prevent indexing error when using recursive arithmetic in array subscript (operator stops on operand error) diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index cbd3d0f8e..c3af8dd33 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1214,6 +1214,9 @@ Note that, when the tt(HASH_LIST_ALL) option is not set or when some directories in the path are not readable, this may falsely report spelling errors the first time some commands are used. +Refer to the shell variable tt(SPROMPT) for an explanation of the +`tt([nyae])' (no/yes/abort/edit) prompt that is offered. + The shell variable tt(CORRECT_IGNORE) may be set to a pattern to match words that will never be offered as corrections. ) @@ -1222,7 +1225,10 @@ pindex(NO_CORRECT_ALL) pindex(CORRECTALL) pindex(NOCORRECTALL) item(tt(CORRECT_ALL) (tt(-O)))( -Try to correct the spelling of all arguments in a line. +Try to correct the spelling of all arguments in a line, in order from +left to right, treating each as a file name. Answering `tt(a)' or +`tt(e)' at any prompt stops all corrections, otherwise every correction +is prompted for. The shell variable tt(CORRECT_IGNORE_FILE) may be set to a pattern to match file names that will never be offered as corrections. diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 68df4a16f..a6fbe6723 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1635,9 +1635,13 @@ All other prompt escapes are also allowed. The actions available at the prompt are tt([nyae]): startsitem() -sitem(tt(n) +LPAR()`no'+RPAR() +LPAR()default+RPAR())(Discard the correction and run the command.) -sitem(tt(y) +LPAR()`yes'+RPAR())(Make the correction and run the command.) -sitem(tt(a) +LPAR()`abort'+RPAR())(Discard the entire command line without running it.) +sitem(tt(n) +LPAR()`no'+RPAR() +LPAR()default+RPAR())(Discard the correction. +If there are no more corrections, accept the command line, else (with +tt(CORRECT_ALL)) prompt for the next.) +sitem(tt(y) +LPAR()`yes'+RPAR())(Make the correction. If there are no more +corrections, accept the command line.) +sitem(tt(a) +LPAR()`abort'+RPAR())(Place the entire command line in the +history for later edit, but without accepting it.) sitem(tt(e) +LPAR()`edit'+RPAR())(Resume editing the command line.) endsitem() ) -- cgit v1.2.3 From 1a3ebb68d607c8f20077f50af16934b9236d5e41 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 25 Jan 2024 21:58:25 -0800 Subject: 52385: avoid "tr" in test output formatting --- ChangeLog | 4 ++++ Test/B03print.ztst | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ecb883c75..2caaecbdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-01-25 Bart Schaefer + + * 52385: Test/B03print.ztst: avoid "tr" in test output formatting + 2024-01-24 Bart Schaefer * 52496 + 52377: Doc/Zsh/options.yo, Doc/Zsh/params.yo: clarify diff --git a/Test/B03print.ztst b/Test/B03print.ztst index 4d2cf9764..93a9669b0 100644 --- a/Test/B03print.ztst +++ b/Test/B03print.ztst @@ -305,8 +305,9 @@ foo+=$'\tone\ttwo\tthree\tfour\n' foo+=$'\t\tone\t\ttwo\t\tthree\t\tfour' foo+='\0' # regression test for multibyte tab expand - print -x4 $foo | tr '\0' Z # avoid raw nul byte in expected output below - print -X4 $foo | tr '\0' Z + # avoid raw nul byte in expected output below + print ${"$(print -x4 $foo)"/$'\0'/Z} + print ${"$(print -X4 $foo)"/$'\0'/Z} 0:Tab expansion by print >one two three four > one two three four -- cgit v1.2.3 From 0119a57e9c3724a6ff72247d278163dc3e507328 Mon Sep 17 00:00:00 2001 From: Aurélien Olivier Date: Wed, 10 Jan 2024 21:28:51 +0100 Subject: github #108: add perlbrew completion --- ChangeLog | 5 + Completion/Unix/Command/_perlbrew | 315 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 320 insertions(+) create mode 100644 Completion/Unix/Command/_perlbrew diff --git a/ChangeLog b/ChangeLog index 2caaecbdd..1e8ddc599 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-01-26 Oliver Kiddle + + * github #108: Aurélien Olivier: Completion/Unix/Command/_perlbrew: + add perlbrew completion + 2024-01-25 Bart Schaefer * 52385: Test/B03print.ztst: avoid "tr" in test output formatting diff --git a/Completion/Unix/Command/_perlbrew b/Completion/Unix/Command/_perlbrew new file mode 100644 index 000000000..8bf9ba7cc --- /dev/null +++ b/Completion/Unix/Command/_perlbrew @@ -0,0 +1,315 @@ +#compdef perlbrew + +# +# A zsh completion script for perlbrew (https://metacpan.org/dist/App-perlbrew/) +# + +local curcontext="$curcontext" state state_descr line ret=1 +local -a args_common args_install +typeset -A opt_args +# others local variables +typeset -g perlbrew_subcommands + +## +## get the list of perl available versions +## +(( $+functions[_perlbrew_caching_policy] )) || +_perlbrew_caching_policy() { + # rebuild if cached data are more than one week old + local -a newer=( "$1"(Nmw-1) ) + return $#newer +} + +(( $+functions[_perl_available] )) || +_perl_available() { + local -a available_versions + local update_policy + + zstyle -s ":completion:${curcontext}:" cache-policy update_policy + if [[ -z "$update_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy _perlbrew_caching_policy + fi + + if _cache_invalid perlbrew-available-versions || ! _retrieve_cache perlbrew-available-versions; then + # this can be slow + available_versions=( ${${${${(f)"$(_call_program perl_releases perlbrew available)"}/\# (cp|p)erl/}/(#s)i /}// /} \ + perl-stable \ + perl-blead ) + _store_cache perlbrew-available-versions available_versions + fi + _values 'available version' ${(n)available_versions} +} + +## +## get the list of local perl installations +## +(( $+functions[_perl_installations] )) || +_perl_installations() { + local text + local -a installed alias_link + + case "$1" in + (-with-lib) + installed=( ${${${(f)"$(_call_program perl_installed perlbrew list)"}/(#s)\*/}// /} ) + text="perl installation" + ;; + (-only-lib) + installed=( ${(M)${${${(f)"$(_call_program perl_installed perlbrew list)"}/(#s)\*/}// /}:#*@*} ) + text="perl installation" + ;; + (-without-lib) + installed=( ${${${${(f)"$(_call_program perl_installed perlbrew list)"}/(#s)\*/}// /}:#*@*} ) + text="perl installation" + ;; + (-alias) + if [[ -n "$PERLBREW_ROOT" ]]; then + if [[ -d "$PERLBREW_ROOT/perls" ]]; then + alias_link=( $PERLBREW_ROOT/perls/*(@) ) + fi + fi + installed=( ${(q)${alias_link:t}[@]} ) + text="alias" + ;; + esac + + if [[ ${#installed[@]} -eq 0 ]]; then + _message 'no local perl installation found' + else + case "$2" in + (-comma-separated) + _values -s , "$text" $installed + ;; + (*) + _values "$text" $installed + ;; + esac + fi +} + +## +## completion for the alias subcommand +## +(( $+functions[_perlbrew_alias] )) || +_perlbrew_alias() { + local line state ret=1 + + _arguments -C \ + -f'[force]' \ + "1: :->actions" \ + "*::arg:->args" && ret 0 + + case "$state" in + (actions) + local -a alias_actions + alias_actions=( + "create:create an alias for the installation named " + "rename:rename the alias to a new name" + "delete:delete the given alias" + ) + _describe -t commands 'alias action' alias_actions && ret=0 + ;; + (args) + case $line[1] in + (create) + _arguments \ + '1:perl installation: _perl_installations -without-lib' \ + '2: : _message "alias name"' && ret=0 + ;; + (rename) + _arguments \ + '1:perl installation: _perl_installations -alias' \ + '2: : _message "new name"' && ret=0 + ;; + (delete) + _arguments \ + ':perl installation: _perl_installations -alias' && ret=0 + ;; + esac + ;; + esac +} + +## +## completion for the lib subcommand +## +(( $+functions[_perlbrew_lib] )) || +_perlbrew_lib() { + local line state ret=1 + + _arguments -C \ + "1: :->actions" \ + "*::arg:->args" && ret=0 + + case "$state" in + (actions) + local -a lib_actions + lib_actions=( + "list:list existing local libs" + "create:create a local lib" + "delete:delete a local lib" + ) + _describe -t commands 'lib action' lib_actions && ret=0 + ;; + (args) + case $line[1] in + (list) + _nothing && ret=0 + ;; + (create) + _message 'lib name' && ret=0 + ;; + (delete) + _arguments \ + ':perl installation: _perl_installations -only-lib' && ret=0 + ;; + esac + ;; + esac +} + +## +## main completion script +## + +args_common=( + '(-q --quiet)'{-q,--quiet}'[be quiet on informative output message]' \ + '(-v --verbose)'{-v,--verbose}'[tell me more about it]' \ + ':perlbrew command:->subcommands' \ + '*::: := ->option-or-argument' +) + +args_install=( + '(-f --force)'{-f,--force}'[force installation]' \ + -j"[number of building jobs run in parallel]::number" \ + '(-n --notest)'{-n,--notest}'[skip testing]' \ + --switch"[automatically switch to this perl version once installed]" \ + --as"[install the given version of perl by a name]:alias name" \ + --noman"[skip installation of manpages]" \ + --thread"[build perl with usethreads enabled]" \ + --multi"[build perl with usemultiplicity enabled]" \ + --64int"[build perl with use64bitint enabled]" \ + --64all"[build perl with use64bitall enabled]" \ + --ld"[build perl with uselongdouble enabled]" \ + --debug"[build perl with DEBUGGING enabled]" \ + --clang"[build perl using the clang compiler]" \ + --no-patchperl"[skip calling patchperl]" \ + {-D,-U,-A}"[switches passed to perl Configure script]:value:" \ + --destdir"[install perl as per 'make install DESTDIR=\$path']: :_files -/" \ + --sitecustomize"[specify a file to be installed as sitecustomize.pl]: :_files" \ + --mirror"[specify a CPAN-mirror url]:URL:_urls" +) + +_arguments -C $args_common && ret=0 + +case $state in + (subcommands) + + perlbrew_subcommands=( + "init:initialize perlbrew environment" + "info:show useful information about the perlbrew installation" + "install:install perl" + "uninstall:uninstall the given installation" + "available:list perls available to install" + "lib:manage local::lib directories" + "alias:give perl installations a new name" + "upgrade-perl:upgrade the current perl" + "list:list perl installations" + "use:use the specified perl in current shell" + "off:turn off perlbrew in current shell" + "switch:permanently use the specified perl as default" + "switch-off:permanently turn off perlbrew (revert to system perl)" + "exec:exec programs with specified perl environments" + "clone-modules:re-installs all CPAN modules from one installation to another" + "self-install:install perlbrew itself under PERLBREW_ROOT/bin" + "self-upgrade:upgrade perlbrew itself" + "install-patchperl:install patchperl" + "install-cpanm:install cpanm, a friendly companion" + "install-cpm:install cpm, a faster but still friendly companion" + "install-multiple:install multiple versions and flavors of perl" + "download:download the specified perl distribution tarball" + "clean:purge tarballs and build directories" + "version:display version" + "help:read more detailed instructions" + ) + + _describe -t commands 'perlbrew command' perlbrew_subcommands && ret=0 + + ;; + (option-or-argument) + curcontext=${curcontext%:*}-$line[1]: + case $line[1] in + (info) + _message 'perl module name' && ret=0 + ;; + (install) + _arguments \ + $args_install \ + '1:perl release: _perl_available' && ret=0 + ;; + (install-multiple) + _arguments \ + $args_install \ + '*'--both"[perl flavor]: :(thread multi ld 64int 64all debug clang )" \ + --common-variations"[equivalent to '--both thread --both ld --both 64int']" \ + --all-variations"[generates all the possible flavor combinations]" \ + --append"[appends the given string to the generated names]:string" \ + '*:perl release: _perl_available' && ret=0 + ;; + (uninstall) + _arguments \ + ":perl installation: _perl_installations -without-lib" && ret=0 + ;; + (use|switch) + _arguments \ + ':perl installation: _perl_installations -with-lib' && ret=0 + ;; + (available) + _arguments \ + '--all[list of all perls ever released, including development and RC versions]' \ + '*: :' && ret=0 + ;; + (alias) + _perlbrew_alias && ret=0 + ;; + (exec) + _arguments -C \ + --with'[specify one or more perl installations to use]: : _perl_installations -without-lib -comma-separated' \ + --min'[minimum perl version]:version number (n.nnnnn):' \ + --max'[maximum perl version]:version number (n.nnnnn):' \ + --halt-on-error'[stop on first nonzero exit status]' \ + "1:command:" \ + "*:args:" && ret=0 + ;; + (env) # NOTE: Low level command + _arguments \ + ':perl installation: _perl_installations -with-lib' && ret=0 + ;; + (symlink-executables) # NOTE: Low level command + _arguments \ + ':perl installation: _perl_installations -with-lib' && ret=0 + ;; + (lib) + _perlbrew_lib && ret=0 + ;; + (download) + _arguments \ + ':perl release: _perl_available' && ret=0 + ;; + (clone-modules) + _arguments \ + '--notest[skip all module tests]' \ + ':perl installation: _perl_installations -with-lib' \ + ':perl installation: _perl_installations -with-lib' && ret=0 + ;; + (init|list|off|switch-off|install-cpanm|install-patchperl|self-upgrade|\ + self-install|clean|version|upgrade-perl|list-modules) + _nothing && ret=0 + ;; + (*) + _default && ret=0 + ;; + esac + ;; +esac + +return ret -- cgit v1.2.3 From 742049a4cbd9c4f1683081cb812aef994415f112 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Thu, 18 Jan 2024 23:31:03 +0000 Subject: github #110: Fix incorrect completion for `dnf --showduplicates` --- ChangeLog | 3 +++ Completion/Redhat/Command/_dnf | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1e8ddc599..280eac2de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-26 Oliver Kiddle + * github #110: opensauce04: Completion/Redhat/Command/_dnf: + Fix incorrect completion for `dnf --showduplicates` + * github #108: Aurélien Olivier: Completion/Unix/Command/_perlbrew: add perlbrew completion diff --git a/Completion/Redhat/Command/_dnf b/Completion/Redhat/Command/_dnf index ce111f38f..a5edf8564 100644 --- a/Completion/Redhat/Command/_dnf +++ b/Completion/Redhat/Command/_dnf @@ -245,7 +245,7 @@ _dnf() { '--security[include security relevant packages]' '*--setopt=[override config option]:repoid.option=value: ' '--skip-broken[resolve depsolve problems by skipping packages]' - '--show-duplicates[show duplicate packages in repos]' + '--showduplicates[show duplicate packages in repos]' '(-v --verbose)'{-v,--verbose}'[set verbose, show debug messages]' '(- *)--version[show dnf version]' '(-y --assumeyes --assumeno)'{-y,--assumeyes}'[answer yes for all questions]' -- cgit v1.2.3 From 698af7bc1387462c8e87767d7eaeb7e30c6f0b2b Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 26 Jan 2024 07:33:38 +0100 Subject: 52405, 52502: add empty elements to $match for optional captures that don't match --- ChangeLog | 3 +++ Src/Modules/pcre.c | 5 ++++- Test/V07pcre.ztst | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 280eac2de..e73320081 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-26 Oliver Kiddle + * 52405, 52502: Src/Modules/pcre.c, Test/V07pcre.ztst: + add empty elements to $match for optional captures that don't match + * github #110: opensauce04: Completion/Redhat/Command/_dnf: Fix incorrect completion for `dnf --showduplicates` diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index e48ae3ae5..a49d1a307 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -391,6 +391,8 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pattern, NULL); ret = pcre2_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len, offset_start, 0, pcre_mdata, mcontext); + if (ret > 0) + ret = pcre2_get_ovector_count(pcre_mdata); } if (ret==0) return_value = 0; @@ -479,7 +481,8 @@ cond_pcre_match(char **a, int id) break; } else if (r>0) { - zpcre_get_substrings(pcre_pat, lhstr_plain, pcre_mdata, r, svar, avar, + uint32_t ovec_count = pcre2_get_ovector_count(pcre_mdata); + zpcre_get_substrings(pcre_pat, lhstr_plain, pcre_mdata, ovec_count, svar, avar, ".pcre.match", 0, isset(BASHREMATCH), !isset(BASHREMATCH)); return_value = 1; break; diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst index 585698d05..b8cd31c96 100644 --- a/Test/V07pcre.ztst +++ b/Test/V07pcre.ztst @@ -108,6 +108,11 @@ >0 xo→t →t >0 Xo→t →t + [[ foo =~ (pre)?f(o*)(opt(i)onal)?(y)* ]] + typeset -p match +0:Empty string for optional captures that don't match +>typeset -g -a match=( '' oo '' '' '' ) + string="The following zip codes: 78884 90210 99513" pcre_compile -m "\d{5}" pcre_match -b -- $string && print "$MATCH; ZPCRE_OP: $ZPCRE_OP" -- cgit v1.2.3 From ce033e2b9cadf51b4d043b0737fd3acee9f5eef2 Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Mon, 1 Jan 2024 19:10:16 +0100 Subject: 52440: zle.textobjects: Mark variables as const Because these variables are initialized with as constant string, they should be marked as *const* to make the compiler running with `-Wwrite-strings` more happy. --- ChangeLog | 4 ++++ Src/Zle/textobjects.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e73320081..22875c7e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-01-28 Oliver Kiddle + + * Jörg Sommer: 52440: Src/Zle/textobjects.c: Mark variables as const + 2024-01-26 Oliver Kiddle * 52405, 52502: Src/Modules/pcre.c, Test/V07pcre.ztst: diff --git a/Src/Zle/textobjects.c b/Src/Zle/textobjects.c index c93777b65..a68c5296e 100644 --- a/Src/Zle/textobjects.c +++ b/Src/Zle/textobjects.c @@ -283,9 +283,9 @@ selectargument(UNUSED(char **args)) free(linein); if (IS_THINGY(bindk, selectinshellword)) { - ZLE_CHAR_T *match = ZWS("`\'\""); - ZLE_CHAR_T *lmatch = ZWS("\'({"), *rmatch = ZWS("\')}"); - ZLE_CHAR_T *ematch = match, *found; + const ZLE_CHAR_T *match = ZWS("`\'\""); + const ZLE_CHAR_T *lmatch = ZWS("\'({"), *rmatch = ZWS("\')}"); + const ZLE_CHAR_T *ematch = match, *found; int start, end = zlecs; /* for 'in' widget, don't include initial blanks ... */ while (mark < zlecs && ZC_iblank(zleline[mark])) -- cgit v1.2.3 From 98affe1115dfdab932432c09160f46ca3d269fb7 Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Mon, 1 Jan 2024 19:10:18 +0100 Subject: 52441: zle_vi: Mark variables with const init as const Because these variables are initialized with as constant string, they should be marked as *const* to make the compiler running with `-Wwrite-strings` more happy. --- ChangeLog | 2 ++ Src/Zle/zle_vi.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 22875c7e9..16e012d5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-01-28 Oliver Kiddle + * Jörg Sommer: 52441: Src/Zle/zle_vi.c: Mark variables as const + * Jörg Sommer: 52440: Src/Zle/textobjects.c: Mark variables as const 2024-01-26 Oliver Kiddle diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index 24d9de6ea..6692df830 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -1014,7 +1014,7 @@ int visetbuffer(char **args) { ZLE_INT_T ch; - ZLE_CHAR_T *match = ZWS("_*+"); + const ZLE_CHAR_T *match = ZWS("_*+"); int registermod[] = { MOD_NULL, MOD_PRI, MOD_CLIP }; ZLE_CHAR_T *found; -- cgit v1.2.3 From 4929910267a00b8f9958d9e1710580e30d1d5a18 Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Mon, 1 Jan 2024 19:10:20 +0100 Subject: 52444: module: Mark name argument of some functions const --- ChangeLog | 3 +++ Src/module.c | 15 ++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16e012d5b..8cdd990d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-28 Oliver Kiddle + * Jörg Sommer: 52444: Src/module.c: Mark name argument of some + functions const + * Jörg Sommer: 52441: Src/Zle/zle_vi.c: Mark variables as const * Jörg Sommer: 52440: Src/Zle/textobjects.c: Mark variables as const diff --git a/Src/module.c b/Src/module.c index a6005f30b..b4b5d0a2c 100644 --- a/Src/module.c +++ b/Src/module.c @@ -356,7 +356,7 @@ finish_(UNUSED(Module m)) /**/ void -register_module(char *n, Module_void_func setup, +register_module(const char *n, Module_void_func setup, Module_features_func features, Module_enables_func enables, Module_void_func boot, @@ -846,7 +846,7 @@ Hookdef hooktab; /**/ Hookdef -gethookdef(char *n) +gethookdef(const char *n) { Hookdef p; @@ -974,7 +974,7 @@ deletehookdeffunc(Hookdef h, Hookfn f) /**/ mod_export int -deletehookfunc(char *n, Hookfn f) +deletehookfunc(const char *n, Hookfn f) { Hookdef h = gethookdef(n); @@ -1766,7 +1766,7 @@ dyn_finish_module(Module m) #else static Module_generic_func -module_func(Module m, char *name) +module_func(Module m, const char *name) { #ifdef DYNAMIC_NAME_CLASH_OK return (Module_generic_func) dlsym(m->u.handle, name); @@ -2443,7 +2443,7 @@ bin_zmodload(char *nam, char **args, Options ops, UNUSED(int func)) int ops_au = OPT_ISSET(ops,'a') || OPT_ISSET(ops,'u'); int ret = 1, autoopts; /* options only allowed with -F */ - char *fonly = "lP", *fp; + const char *fonly = "lP", *fp; if (ops_bcpf && !ops_au) { zwarnnam(nam, "-b, -c, -f, and -p must be combined with -a or -u"); @@ -3182,7 +3182,7 @@ bin_zmodload_features(const char *nam, char **args, Options ops) } else if (OPT_ISSET(ops, 'L')) printf("zmodload -F %s ", m->node.nam); for (fp = features, ep = enables; *fp; fp++, ep++) { - char *onoff; + const char *onoff; int term; if (*args) { char **argp; @@ -3452,7 +3452,8 @@ autofeatures(const char *cmdnam, const char *module, char **features, defm = NULL; for (; *features; features++) { - char *fnam, *typnam, *feature; + char *fnam, *feature; + const char *typnam; int add, fchar, flags = defflags; autofeaturefn_t fn; -- cgit v1.2.3 From fe276d3873c758ca17e06c31b3c05a3713cfe193 Mon Sep 17 00:00:00 2001 From: Jörg Sommer Date: Mon, 1 Jan 2024 19:10:21 +0100 Subject: 52442: mark hookdef.name as const At least *zle_main* uses const strings to initialize its structure *zlehooks*. --- ChangeLog | 2 ++ Src/zsh.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8cdd990d6..c85715ef3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-01-28 Oliver Kiddle + * Jörg Sommer: 52442: Src/zsh.h: Mark hookdef.name as const + * Jörg Sommer: 52444: Src/module.c: Mark name argument of some functions const diff --git a/Src/zsh.h b/Src/zsh.h index a0243e98e..fae62b8d0 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1578,7 +1578,7 @@ typedef int (*Hookfn) _((Hookdef, void *)); struct hookdef { Hookdef next; - char *name; + const char *name; Hookfn def; int flags; LinkList funcs; -- cgit v1.2.3 From 8e622c25b24fb0b0d6e705fab97960351e123c65 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 22 Jan 2024 23:19:23 +0100 Subject: unposted: remove unused variable to silence compiler warning --- ChangeLog | 3 +++ Src/Modules/zutil.c | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c85715ef3..240fb0581 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-28 Oliver Kiddle + * unposted: Src/Modules/zutil.c: remove unused variable to silence + compiler warning + * Jörg Sommer: 52442: Src/zsh.h: Mark hookdef.name as const * Jörg Sommer: 52444: Src/module.c: Mark name argument of some diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 293a62dcf..5eccea7a9 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -997,7 +997,7 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) case 'a': { char **ap, *cp; - int nbc = 0, colon = 0, pre = 0, suf = 0; + int nbc = 0, pre = 0, suf = 0; #ifdef MULTIBYTE_SUPPORT int prechars = 0; #endif /* MULTIBYTE_SUPPORT */ @@ -1012,7 +1012,6 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) int dchars = 0; #endif /* MULTIBYTE_SUPPORT */ - colon++; if ((d = cp - *ap - nbc) > pre) pre = d; #ifdef MULTIBYTE_SUPPORT -- cgit v1.2.3 From 3c5dacd503a2ac81059346b37d16ab5d1b6a1e04 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sun, 28 Jan 2024 00:34:05 +0100 Subject: 52499: support highlight groups These are defined in a .zle.hlgroups associative array and referenced using %H in prompt strings or hl= in zle_highlight/region_highlight. --- ChangeLog | 4 ++++ Src/prompt.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 240fb0581..2e0b085e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2024-01-28 Oliver Kiddle + * 52499: Src/prompt.c: support highlight groups defined in a + .zle.hlgroups associative array and referenced using %H in + prompt strings or hl= in zle_highlight/region_highlight + * unposted: Src/Modules/zutil.c: remove unused variable to silence compiler warning diff --git a/Src/prompt.c b/Src/prompt.c index 39fcf5eb7..e4c213a13 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -241,6 +241,39 @@ promptexpand(char *s, int ns, char *rs, char *Rs) return new_vars.buf; } +/* Parse the argument for %H */ +static char * +parsehighlight(char *arg, char endchar, zattr *atr) +{ + static int entered = 0; + char *var = ".zle.hlgroups"; + struct value vbuf; + Value v; + char *ep, *attrs; + if ((ep = strchr(arg, endchar))) + *ep = '\0'; + if (!entered && (v = getvalue(&vbuf, &var, 0)) && + PM_TYPE(v->pm->node.flags) == PM_HASHED) + { + Param node; + HashTable ht = v->pm->gsu.h->getfn(v->pm); + if ((node = (Param) ht->getnode(ht, arg))) { + attrs = node->gsu.s->getfn(node); + entered = 1; + if (match_highlight(attrs, atr) == attrs) + *atr = TXT_ERROR; + } else + *atr = TXT_ERROR; + } else + *atr = TXT_ERROR; + if (ep) + *ep = endchar; + else + ep = strchr(arg, '\0') - 1; + entered = 0; + return ep; +} + /* Parse the argument for %F and %K */ static zattr parsecolorchar(zattr arg, int is_fg) @@ -571,6 +604,13 @@ putpromptchar(int doprint, int endchar) tunsetattrs(TXTBGCOLOUR); applytextattributes(TSC_PROMPT); break; + case 'H': + bv->fm = parsehighlight(bv->fm + 2, '}', &atr); + if (atr != TXT_ERROR) { + treplaceattrs(atr); + applytextattributes(TSC_PROMPT); + } + break; case '[': if (idigit(*++bv->fm)) arg = zstrtol(bv->fm, &bv->fm, 10); @@ -1856,11 +1896,17 @@ match_highlight(const char *teststr, zattr *on_var) *on_var = 0; while (found && *teststr) { const struct highlight *hl; + zattr atr = 0; found = 0; - if (strpfx("fg=", teststr) || strpfx("bg=", teststr)) { + if (strpfx("hl=", teststr)) { + teststr += 3; + teststr = parsehighlight((char *)teststr, ',', &atr); + if (atr != TXT_ERROR) + *on_var = atr; + found = 1; + } else if (strpfx("fg=", teststr) || strpfx("bg=", teststr)) { int is_fg = (teststr[0] == 'f'); - zattr atr; teststr += 3; atr = match_colour(&teststr, is_fg, 0); -- cgit v1.2.3 From 85545af42b8f9278136125324c37c1f88b461421 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sun, 28 Jan 2024 00:47:10 +0100 Subject: 52500: add layer token to zle attributes This provide control over the precedence of highlighting where different regions overlap. --- ChangeLog | 4 ++ Src/Zle/zle.h | 2 + Src/Zle/zle_refresh.c | 115 +++++++++++++++++++++++++++++++------------------- Src/prompt.c | 13 +++++- 4 files changed, 88 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e0b085e5..7335590c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2024-01-28 Oliver Kiddle + * 52500: Src/Zle/zle.h, Src/Zle/zle_refresh.c, Src/prompt.c: + add layer token to zle attributes to provide control over + the precedence of highlighting + * 52499: Src/prompt.c: support highlight groups defined in a .zle.hlgroups associative array and referenced using %H in prompt strings or hl= in zle_highlight/region_highlight diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 1a3e4c241..010ead3d2 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -435,6 +435,8 @@ enum { struct region_highlight { /* Attributes turned on in the region */ zattr atr; + /* Priority for this region relative to others that overlap */ + int layer; /* Start of the region */ int start; /* Start of the region in metafied ZLE line */ diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index a587f696a..f076bdd61 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -210,6 +210,12 @@ int predisplaylen, postdisplaylen; static zattr default_attr, special_attr, ellipsis_attr; +/* + * Layer applied to highlighting for special characters + */ + +static int special_layer; + /* * Array of region highlights, no special termination. * The first N_SPECIAL_HIGHLIGHTS elements describe special uses of @@ -337,6 +343,13 @@ zle_set_highlight(void) } } + /* Default layers */ + region_highlights[0].layer = 20; /* region */ + region_highlights[1].layer = 20; /* isearch */ + region_highlights[2].layer = 10; /* suffix */ + region_highlights[3].layer = 15; /* paste */ + special_layer = 30; + if (atrs) { for (; *atrs; atrs++) { if (!strcmp(*atrs, "none")) { @@ -346,30 +359,34 @@ zle_set_highlight(void) paste_attr_set = region_attr_set = isearch_attr_set = suffix_attr_set = 1; } else if (strpfx("default:", *atrs)) { - match_highlight(*atrs + 8, &default_attr); + match_highlight(*atrs + 8, &default_attr, NULL); } else if (strpfx("special:", *atrs)) { - match_highlight(*atrs + 8, &special_attr); + match_highlight(*atrs + 8, &special_attr, &special_layer); special_attr_set = 1; } else if (strpfx("region:", *atrs)) { - match_highlight(*atrs + 7, ®ion_highlights[0].atr); + match_highlight(*atrs + 7, &(region_highlights[0].atr), + &(region_highlights[0].layer)); region_attr_set = 1; } else if (strpfx("isearch:", *atrs)) { - match_highlight(*atrs + 8, &(region_highlights[1].atr)); + match_highlight(*atrs + 8, &(region_highlights[1].atr), + &(region_highlights[1].layer)); isearch_attr_set = 1; } else if (strpfx("suffix:", *atrs)) { - match_highlight(*atrs + 7, &(region_highlights[2].atr)); + match_highlight(*atrs + 7, &(region_highlights[2].atr), + &(region_highlights[2].layer)); suffix_attr_set = 1; } else if (strpfx("paste:", *atrs)) { - match_highlight(*atrs + 6, &(region_highlights[3].atr)); + match_highlight(*atrs + 6, &(region_highlights[3].atr), + &(region_highlights[3].layer)); paste_attr_set = 1; } else if (strpfx("ellipsis:", *atrs)) { - match_highlight(*atrs + 9, &ellipsis_attr); + match_highlight(*atrs + 9, &ellipsis_attr, NULL); ellipsis_attr_set = 1; } } } - /* Defaults */ + /* Default attributes */ if (!special_attr_set) special_attr = TXTSTANDOUT; if (!region_attr_set) @@ -407,14 +424,13 @@ zle_free_highlight(void) char ** get_region_highlight(UNUSED(Param pm)) { - int arrsize = n_region_highlights; + int arrsize = n_region_highlights - N_SPECIAL_HIGHLIGHTS; char **retarr, **arrp; struct region_highlight *rhp; /* region_highlights may not have been set yet */ - if (!arrsize) + if (!n_region_highlights) return hmkarray(NULL); - arrsize -= N_SPECIAL_HIGHLIGHTS; DPUTS(arrsize < 0, "arrsize is negative from n_region_highlights"); arrp = retarr = (char **)zhalloc((arrsize+1)*sizeof(char *)); @@ -422,20 +438,18 @@ get_region_highlight(UNUSED(Param pm)) for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS; arrsize--; rhp++, arrp++) { - char digbuf1[DIGBUFSIZE], digbuf2[DIGBUFSIZE]; - int atrlen, alloclen; - const char memo_equals[] = "memo="; - - sprintf(digbuf1, "%d", rhp->start); - sprintf(digbuf2, "%d", rhp->end); - - atrlen = output_highlight(rhp->atr, NULL); - alloclen = atrlen + strlen(digbuf1) + strlen(digbuf2) + - 3; /* 2 spaces, 1 terminating NUL */ + char digbuf[2 * DIGBUFSIZE], layerbuf[7 + DIGBUFSIZE]; + int offset; + const char memo_equals[] = " memo="; + int alloclen = sprintf(digbuf, "%d %d", rhp->start, rhp->end) + + output_highlight(rhp->atr, NULL) + + 2; /* space and terminating NUL */ if (rhp->flags & ZRH_PREDISPLAY) - alloclen += 2; /* "P " */ + alloclen++; /* "P" */ + if (rhp->layer != 10) + alloclen += sprintf(layerbuf, ",layer=%d", rhp->layer); if (rhp->memo) - alloclen += 1 /* space */ + strlen(memo_equals) + strlen(rhp->memo); + alloclen += sizeof(memo_equals) - 1 + strlen(rhp->memo); *arrp = (char *)zhalloc(alloclen * sizeof(char)); /* * On input we allow a space after the flags. @@ -444,13 +458,14 @@ get_region_highlight(UNUSED(Param pm)) * into three words, and then check the first to * see if there are flags. However, it's arguable. */ - sprintf(*arrp, "%s%s %s ", + offset = sprintf(*arrp, "%s%s ", (rhp->flags & ZRH_PREDISPLAY) ? "P" : "", - digbuf1, digbuf2); - (void)output_highlight(rhp->atr, *arrp + strlen(*arrp)); + digbuf); + (void)output_highlight(rhp->atr, *arrp + offset); + if (rhp->layer != 10) + strcat(*arrp, layerbuf); if (rhp->memo) { - strcat(*arrp, " "); strcat(*arrp, memo_equals); strcat(*arrp, rhp->memo); } @@ -459,12 +474,10 @@ get_region_highlight(UNUSED(Param pm)) return retarr; } - /* * The parameter system requires the pm argument, but this * may be NULL if called directly. */ - /**/ void set_region_highlight(UNUSED(Param pm), char **aval) @@ -523,7 +536,8 @@ set_region_highlight(UNUSED(Param pm), char **aval) while (inblank(*strp)) strp++; - strp = (char*) match_highlight(strp, &rhp->atr); + rhp->layer = 10; /* default */ + strp = (char*) match_highlight(strp, &rhp->atr, &rhp->layer); while (inblank(*strp)) strp++; @@ -1180,27 +1194,40 @@ zrefresh(void) rpms.s = nbuf[rpms.ln = 0] + lpromptw; rpms.sen = *nbuf + winw; for (t = tmpline, tmppos = 0; tmppos < tmpll; t++, tmppos++) { - unsigned ireg; zattr base_attr = mixattrs(default_attr, prompt_attr); zattr all_attr; struct region_highlight *rhp; + int layer, nextlayer = 0; /* * Calculate attribute based on region. */ - for (ireg = 0, rhp = region_highlights; - ireg < n_region_highlights; - ireg++, rhp++) { - int offset; - if (rhp->flags & ZRH_PREDISPLAY) - offset = 0; /* include predisplay in start end */ - else - offset = predisplaylen; /* increment over it */ - if (rhp->start + offset <= tmppos && - tmppos < rhp->end + offset) { - base_attr = mixattrs(rhp->atr, base_attr); + do { + unsigned ireg; + layer = nextlayer; + nextlayer = special_layer; + for (ireg = 0, rhp = region_highlights; + ireg < n_region_highlights; + ireg++, rhp++) { + if (rhp->layer == layer) { + int offset; + if (rhp->flags & ZRH_PREDISPLAY) + offset = 0; /* include predisplay in start end */ + else + offset = predisplaylen; /* increment over it */ + if (rhp->start + offset <= tmppos && + tmppos < rhp->end + offset) { + base_attr = mixattrs(rhp->atr, base_attr); + if (layer > special_layer) + all_attr = mixattrs(rhp->atr, all_attr); + } + } else if (rhp->layer > layer && rhp->layer < nextlayer) { + nextlayer = rhp->layer; + } } - } - all_attr = mixattrs(special_attr, base_attr); + if (special_layer == layer) { + all_attr = mixattrs(special_attr, base_attr); + } + } while (nextlayer > layer); if (t == scs) /* if cursor is here, remember it */ rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln]; diff --git a/Src/prompt.c b/Src/prompt.c index e4c213a13..ec79067cd 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -260,7 +260,7 @@ parsehighlight(char *arg, char endchar, zattr *atr) if ((node = (Param) ht->getnode(ht, arg))) { attrs = node->gsu.s->getfn(node); entered = 1; - if (match_highlight(attrs, atr) == attrs) + if (match_highlight(attrs, atr, 0) == attrs) *atr = TXT_ERROR; } else *atr = TXT_ERROR; @@ -1884,12 +1884,13 @@ match_colour(const char **teststrp, int is_fg, int colour) /* * Match a set of highlights in the given teststr. * Set *on_var to reflect the values found. + * Set *layer to the layer * Return a pointer to the first character not consumed. */ /**/ mod_export const char * -match_highlight(const char *teststr, zattr *on_var) +match_highlight(const char *teststr, zattr *on_var, int *layer) { int found = 1; @@ -1918,6 +1919,14 @@ match_highlight(const char *teststr, zattr *on_var) /* skip out of range colours but keep scanning attributes */ if (atr != TXT_ERROR) *on_var |= atr; + } else if (layer && strpfx("layer=", teststr)) { + teststr += 6; + *layer = (int) zstrtol(teststr, (char **) &teststr, 10); + if (*teststr == ',') + teststr++; + else if (*teststr && *teststr != ' ') + break; + found = 1; } else { for (hl = highlights; hl->name; hl++) { if (strpfx(hl->name, teststr)) { -- cgit v1.2.3 From d7cf4f25ebe2ec00b5e557e8202d74fa86a36062 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 28 Jan 2024 17:14:23 -0800 Subject: 52509: manage internals of stdio objects when performing redirections. --- ChangeLog | 5 +++++ Src/utils.c | 22 ++++++++++++++++++++++ configure.ac | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7335590c9..6c52ccd22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-01-28 Bart Schaefer + + * 52509: configure.ac, Src/utils.c: manage internals of stdio + objects when performing redirections. + 2024-01-28 Oliver Kiddle * 52500: Src/Zle/zle.h, Src/Zle/zle_refresh.c, Src/prompt.c: diff --git a/Src/utils.c b/Src/utils.c index 1a4f4c14b..0fda92709 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2008,6 +2008,28 @@ redup(int x, int y) { int ret = y; +#ifdef HAVE_FPURGE + /* Make sure buffers are cleared when changing descriptor for a + * FILE object. No fflush() here because the only way anything + * can legitimately be left in the buffer is when an error has + * occurred, so attempting flush here would at best error again + * and at worst squirt out something unexpected. + */ + if (stdout && y == fileno(stdout)) + fpurge(stdout); + if (stderr && y == fileno(stderr)) + fpurge(stderr); + if (shout && y == fileno(shout)) + fpurge(shout); + if (xtrerr && y == fileno(xtrerr)) + fpurge(xtrerr); +#ifndef _IONBF + /* See init.c setupshin() -- stdin otherwise unbuffered */ + if (stdin && y == fileno(stdin)) + fpurge(stdin); +#endif +#endif + if(x < 0) zclose(y); else if (x != y) { diff --git a/configure.ac b/configure.ac index 2871dcb7c..175d90433 100644 --- a/configure.ac +++ b/configure.ac @@ -1295,7 +1295,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ select poll \ readlink faccessx fchdir ftruncate \ fstat lstat lchown fchown fchmod \ - fseeko ftello \ + fpurge fseeko ftello \ mkfifo _mktemp mkstemp \ waitpid wait3 \ sigaction sigblock sighold sigrelse sigsetmask sigprocmask \ -- cgit v1.2.3 From 18400b68e49b242da55ca3a465ea496d26f47938 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 28 Jan 2024 18:22:36 -0800 Subject: 52510: document how ${ ... } et al. affect use of "private"; add index entries --- ChangeLog | 3 +++ Doc/Zsh/expn.yo | 3 +++ Doc/Zsh/mod_private.yo | 3 +++ 3 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6c52ccd22..46cd45647 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-28 Bart Schaefer + * 52510: Doc/Zsh/expn.yo, Doc/Zsh/mod_private.yo: document how + ${ ... } et al. affect use of "private"; add index entries + * 52509: configure.ac, Src/utils.c: manage internals of stdio objects when performing redirections. diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index e5506d469..2acfd08c9 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1915,6 +1915,9 @@ from the final replacement in this case, and it is subject to filename generation in the same way as `tt($LPAR())...tt(RPAR())' but is em(not) split on tt(IFS) unless the tt(SH_WORD_SPLIT) option is set. +cindex(substitution, command, current shell) +cindex(substitution, command, non forking) +cindex(substitution, nofork) Substitutions of the form `tt(${|)var(param)tt(|)...tt(})' are similar, except that the substitution is replaced by the value of the parameter named by var(param). No implicit save or restore applies to var(param) diff --git a/Doc/Zsh/mod_private.yo b/Doc/Zsh/mod_private.yo index 184fa2be8..69a5f58be 100644 --- a/Doc/Zsh/mod_private.yo +++ b/Doc/Zsh/mod_private.yo @@ -84,6 +84,9 @@ created outside the local scope when it was not previously declared.) itemiz(An exported private remains in the environment of inner scopes but appears unset for the current shell in those scopes. Generally, exporting private parameters should be avoided.) +itemiz(Declaring a private parameter in a current shell command substitution +such as `tt(${ )...tt( })' limits the parameter to the scope of the command +substitution, just as if the parameter were declared in a function.) enditemize() Note that this differs from the static scope defined by compiled languages -- cgit v1.2.3 From 8801665e5b241c3adac9c36b6135d057c5ab2a59 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 3 Feb 2024 12:07:14 -0800 Subject: 52513: fixes and doc for using nofork substitutions with private parameters Also fixes a crash bug with {fd}>&N redirections and private parameters --- ChangeLog | 7 +++ Doc/Zsh/mod_private.yo | 9 +++- Src/Modules/param_private.c | 53 ++++++++++++-------- Src/params.c | 17 +++++-- Test/V10private.ztst | 118 +++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 170 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46cd45647..fbfae8589 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-02-03 Bart Schaefer + + * 52513: Doc/Zsh/mod_private.yo, Src/Modules/param_private.c, + Src/params.c, Test/v10private.ztst: nofork substitutions can + use private parameters; fix crash bug on {privateFD}>&N; add + tests and documentation + 2024-01-28 Bart Schaefer * 52510: Doc/Zsh/expn.yo, Doc/Zsh/mod_private.yo: document how diff --git a/Doc/Zsh/mod_private.yo b/Doc/Zsh/mod_private.yo index 69a5f58be..08ac4cafe 100644 --- a/Doc/Zsh/mod_private.yo +++ b/Doc/Zsh/mod_private.yo @@ -84,9 +84,14 @@ created outside the local scope when it was not previously declared.) itemiz(An exported private remains in the environment of inner scopes but appears unset for the current shell in those scopes. Generally, exporting private parameters should be avoided.) +itemiz(Current shell command substitutions such as `tt(${|)...tt(})', +`tt(${|)var(var)tt(|)...tt(})' and `tt(${ )...tt( })' may read and assign +private parameters from the enclosing function.) itemiz(Declaring a private parameter in a current shell command substitution -such as `tt(${ )...tt( })' limits the parameter to the scope of the command -substitution, just as if the parameter were declared in a function.) +limits that parameter to the scope of the command substitution, just as if +the parameter were declared in a function. This also prevents access by +any enclosed current shell command substitutions, but other substitutions +may use the private parameter because those have the same calling scope.) enditemize() Note that this differs from the static scope defined by compiled languages diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index 7ef6633da..5003d4627 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -298,7 +298,7 @@ pps_setfn(Param pm, char *x) { struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.s); GsuScalar gsu = (GsuScalar)(c->g); - if (locallevel == pm->level) + if (locallevel == pm->level || locallevel > private_wraplevel) gsu->setfn(pm, x); else setfn_error(pm); @@ -338,7 +338,7 @@ ppi_setfn(Param pm, zlong x) { struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.i); GsuInteger gsu = (GsuInteger)(c->g); - if (locallevel == pm->level) + if (locallevel == pm->level || locallevel > private_wraplevel) gsu->setfn(pm, x); else setfn_error(pm); @@ -378,7 +378,7 @@ ppf_setfn(Param pm, double x) { struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.f); GsuFloat gsu = (GsuFloat)(c->g); - if (locallevel == pm->level) + if (locallevel == pm->level || locallevel > private_wraplevel) gsu->setfn(pm, x); else setfn_error(pm); @@ -419,7 +419,7 @@ ppa_setfn(Param pm, char **x) { struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.a); GsuArray gsu = (GsuArray)(c->g); - if (locallevel == pm->level) + if (locallevel == pm->level || locallevel > private_wraplevel) gsu->setfn(pm, x); else setfn_error(pm); @@ -461,7 +461,7 @@ pph_setfn(Param pm, HashTable x) { struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.h); GsuHash gsu = (GsuHash)(c->g); - if (locallevel == pm->level) + if (locallevel == pm->level || locallevel > private_wraplevel) gsu->setfn(pm, x); else setfn_error(pm); @@ -539,19 +539,20 @@ static struct funcwrap wrapper[] = { WRAPDEF(wrap_private) }; +/**/ +static int private_wraplevel = 0; + /**/ static int wrap_private(Eprog prog, FuncWrap w, char *name) { - static int wraplevel = 0; - - if (wraplevel < locallevel /* && strcmp(name, "(anon)") != 0 */) { - int owl = wraplevel; - wraplevel = locallevel; + if (private_wraplevel < locallevel /* && strcmp(name, "(anon)") != 0 */) { + int owl = private_wraplevel; + private_wraplevel = locallevel; scanhashtable(paramtab, 0, 0, 0, scopeprivate, PM_UNSET); runshfunc(prog, w, name); scanhashtable(paramtab, 0, 0, 0, scopeprivate, 0); - wraplevel = owl; + private_wraplevel = owl; return 0; } return 1; @@ -573,22 +574,32 @@ getprivatenode(HashTable ht, const char *nam) pm = (Param) hn; /* how would an autoloaded private behave? return here? */ } - while (!fakelevel && pm && locallevel > pm->level && is_private(pm)) { + while (!fakelevel && pm && is_private(pm) && locallevel > pm->level) { + if (pm->level == private_wraplevel + 1) { + /* Variable is in the current function scope */ + break; + } +#if 0 if (!(pm->node.flags & PM_UNSET)) { /* * private parameters are always marked PM_UNSET before we - * increment locallevel, so the only way we get here is - * when createparam() wants a new parameter that is not at - * the current locallevel and it has therefore cleared the - * PM_UNSET flag. + * increment locallevel, so there are three possible ways + * to get here: + * 1) createparam() wants a new parameter that is not at + * the current locallevel and it has therefore cleared the + * PM_UNSET flag + * 2) locallevel has been incremented (startparamscope()) + * outside the usual function call stack (private_wraplevel) + * 3) dynamic scoping is fetching a value from a surrounding + * scope, we don't know if that's for assign or just expand + * The first of those is now caught in createparam() when + * testing PM_RO_BY_DESIGN and the second occurs only in + * nofork substitution or handling of ZLE specials. If the + * third is an assignment, the GSU setfn rejects it. */ DPUTS(pm->old, "BUG: PM_UNSET cleared in wrong scope"); - setfn_error(pm); - /* - * TODO: instead of throwing an error here, create a global - * parameter, insert as pm->old, handle WARN_CREATE_GLOBAL. - */ } +#endif pm = pm->old; } diff --git a/Src/params.c b/Src/params.c index 9f0cbcd67..a722a20f6 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1049,7 +1049,7 @@ createparam(char *name, int flags) /* POSIXBUILTINS horror: we need to retain 'export' flags */ (isset(POSIXBUILTINS) && (oldpm->node.flags & PM_EXPORTED))) { if (oldpm->node.flags & PM_RO_BY_DESIGN) { - zerr("%s: can't change parameter attribute", + zerr("%s: can't modify read-only parameter", name); return NULL; } @@ -3615,9 +3615,18 @@ assignnparam(char *s, mnumber val, int flags) pm = createparam(t, ss ? PM_ARRAY : isset(POSIXIDENTIFIERS) ? PM_SCALAR : (val.type & MN_INTEGER) ? PM_INTEGER : PM_FFLOAT); - if (!pm) - pm = (Param) paramtab->getnode(paramtab, t); - DPUTS(!pm, "BUG: parameter not created"); + if (errflag) { + /* assume error message already output */ + unqueue_signals(); + return NULL; + } + if (!pm && !(pm = (Param) paramtab->getnode(paramtab, t))) { + DPUTS(!pm, "BUG: parameter not created"); + if (!errflag) + zerr("%s: parameter not found", t); + unqueue_signals(); + return NULL; + } if (ss) { *ss = '['; } else if (val.type & MN_INTEGER) { diff --git a/Test/V10private.ztst b/Test/V10private.ztst index d902cac56..9eeda0f47 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -10,6 +10,8 @@ sed -e 's,# test_zsh_param_private,zmodload zsh/param/private,' < $ZTST_srcdir/B02typeset.ztst > private.TMP/B02 fi + setopt TYPESET_TO_UNSET + %test (zmodload -u zsh/param/private && zmodload zsh/param/private) @@ -246,7 +248,7 @@ F:note "typeset" rather than "private" in output from outer 1:privates are not visible in anonymous functions, part 3 >X top level >array_test not set -?(anon):4: array_test: can't change parameter attribute +?(anon):4: array_test: can't modify read-only parameter F:future revision will create a global with this assignment typeset -a array_test @@ -311,11 +313,30 @@ F:future revision will create a global with this assignment () { typeset -n ptr1=ptr2 - private -n ptr2 + private -n ptr2 # TYPESET_TO_UNSET makes this not a "placeholder" typeset -p ptr1 ptr2 typeset val=LOCAL () { - ptr1=val + ptr1=val # Test dies here as ptr2 is private and unset + typeset -n + printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" + } + typeset -p ptr1 ptr2 + } + typeset -p ptr2 +1:up-reference for private namerefs, end unset and not in scope +F:See K01nameref.ztst up-reference part 5 +F:Here ptr1 finds private ptr2 by scope mismatch +>typeset -n ptr1=ptr2 +*?*read-only variable: ptr2 + + () { + typeset -n ptr1=ptr2 + private -n ptr2= # Assignment makes this a placeholder, not unset + typeset -p ptr1 ptr2 + typeset val=LOCAL + () { + ptr1=val # This is a silent no-op, why? typeset -n printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" } @@ -323,8 +344,9 @@ F:future revision will create a global with this assignment } typeset -p ptr2 1:up-reference for private namerefs, end not in scope -F:See K01typeset.ztst up-reference part 5 -F:Here ptr1 finds private ptr2 by scope mismatch, assignment silently fails +F:See K01nameref.ztst up-reference part 5 +F:Here ptr1 finds private ptr2 by scope mismatch +F:Assignment silently fails, is that correct? >typeset -n ptr1=ptr2 >ptr1=ptr2 >ptr1= @@ -335,11 +357,11 @@ F:Here ptr1 finds private ptr2 by scope mismatch, assignment silently fails typeset ptr2 () { typeset -n ptr1=ptr2 - private -n ptr2 + private -n ptr2 # Set/unset is irrelevant, not referenced typeset -p ptr1 ptr2 typeset val=LOCAL () { - ptr1=val; + ptr1=val typeset -n printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" } @@ -401,6 +423,88 @@ F:Should we allow "public" namerefs to private parameters? 1:private may not change parameter type ?(anon):private:2: can't change type of private param: x + () { + private fd1 fd2 + exec {fd1}>&1 + print OK + () { exec {fd2}>&2 } + print BAD $fd2 + } +1:redirection cannot assign private in wrong scope +F:Better if caught in checkclobberparam() but exec.c doesn't know scope +>OK +?(anon): fd2: can't modify read-only parameter + + () { + private z=outer + print ${(t)z} $z + print ${| + print ${(t)z} $z + REPLY=$z + } + } +0:nofork may read private in calling function +>scalar-local-hide-special outer +>scalar-local-hide-special outer +>outer + + () { + private z=outer + print ${(t)z} $z + print ${| REPLY=${|z| z=nofork} } + print ${(t)z} $z + } +0:nofork may write to private in calling function +>scalar-local-hide-special outer +>nofork +>scalar-local-hide-special nofork + + () { + local q=outer + print ${| + private q=nofork + REPLY=${| REPLY=$q} + } + } +0:nofork cannot see private in surrounding nofork +>outer + + () { + private z=outer + print ${(t)z} $z + print ${|z| + private q + z=${|q| q=nofork} + } + print ${(t)z} $z + } +1:nofork may not change private in surrounding nofork +>scalar-local-hide-special outer +*?*: q: can't modify read-only parameter + + () { + private q=outer + print ${| + () { REPLY="{$q}" } + } + print ${|q| + () { q=nofork } + } + } +1:function may not access private from inside nofork +>{} +*?*: q: can't modify read-only parameter + + () { + print ${| + private q + () { q=nofork } + } + } +1:function may not access private declared in nofork +*?*: q: can't modify read-only parameter + %clean + unsetopt TYPESET_TO_UNSET rm -r private.TMP -- cgit v1.2.3 From ce8909b49428e260c15dce22d764f2831295645a Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 3 Feb 2024 19:52:39 -0800 Subject: unposted: Record as comments some notes about namespace usage exceptions. --- ChangeLog | 3 +++ Src/Zle/zle_tricky.c | 5 ++++- Src/parse.c | 2 ++ Src/pattern.c | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fbfae8589..386ef3ab9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-03 Bart Schaefer + * unposted: Src/Zle/zle_tricky.c, Src/parse.c, Src/pattern.c: + Record as comments some notes about namespace usage exceptions. + * 52513: Doc/Zsh/mod_private.yo, Src/Modules/param_private.c, Src/params.c, Test/v10private.ztst: nofork substitutions can use private parameters; fix crash bug on {privateFD}>&N; add diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 6ceb5d87f..ea2a52390 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -1499,6 +1499,7 @@ get_comp_string(void) if (varq) tt = clwords[clwpos]; + /* The only place we complete namespaces, see IIDENT below */ s = itype_end(tt, INAMESPC, 0); sav = *s; *s = '\0'; @@ -1570,6 +1571,8 @@ get_comp_string(void) i = 0; MB_METACHARINIT(); + /* All further uses of IIDENT in this file should change to * + * INAMESPACE if this case is changed. Too ugly to risk now. */ if (itype_end(s, IIDENT, 1) == s) nnb = s + MB_METACHARLEN(s); else @@ -1643,7 +1646,7 @@ get_comp_string(void) } else { /* In mathematical expression, we complete parameter names * * (even if they don't have a `$' in front of them). So we * - * have to find that name. */ + * have to find that name. See above regarding INAMESPC */ char *cspos = zlemetaline + zlemetacs, *wptr, *cptr; we = itype_end(cspos, IIDENT, 0) - zlemetaline; diff --git a/Src/parse.c b/Src/parse.c index 859f4d0fc..2b7e003fc 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1935,6 +1935,8 @@ par_simple(int *cmplx, int nr) if (*ptr == Outbrace && ptr > tokstr + 1) { + /* Should we allow namespace FDs, {.foo.bar}>&file ? * + * If so, change IIDENT to INAMESPACE here */ if (itype_end(tokstr+1, IIDENT, 0) >= ptr) { char *toksave = tokstr; diff --git a/Src/pattern.c b/Src/pattern.c index 2a1a514fb..1e0ae88d9 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -3691,6 +3691,7 @@ mb_patmatchrange(char *range, wchar_t ch, int zmb_ind, wint_t *indptr, int *mtp) return 1; break; case PP_IDENT: + /* Could use INAMESPC here? */ if (wcsitype(ch, IIDENT)) return 1; break; -- cgit v1.2.3 From c039a74e094bb6a4d965899f67fe34d2b84dda8d Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 3 Feb 2024 19:55:41 -0800 Subject: Typos in previous commit comments --- Src/Zle/zle_tricky.c | 2 +- Src/parse.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index ea2a52390..225ce8c74 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -1572,7 +1572,7 @@ get_comp_string(void) i = 0; MB_METACHARINIT(); /* All further uses of IIDENT in this file should change to * - * INAMESPACE if this case is changed. Too ugly to risk now. */ + * INAMESPC if this case is changed. Too ugly to risk now. */ if (itype_end(s, IIDENT, 1) == s) nnb = s + MB_METACHARLEN(s); else diff --git a/Src/parse.c b/Src/parse.c index 2b7e003fc..821812c78 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1936,7 +1936,7 @@ par_simple(int *cmplx, int nr) if (*ptr == Outbrace && ptr > tokstr + 1) { /* Should we allow namespace FDs, {.foo.bar}>&file ? * - * If so, change IIDENT to INAMESPACE here */ + * If so, change IIDENT to INAMESPC here */ if (itype_end(tokstr+1, IIDENT, 0) >= ptr) { char *toksave = tokstr; -- cgit v1.2.3 From 2744208ab3eab1741157e01484d08095bd8ef528 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 3 Feb 2024 20:10:52 -0800 Subject: unposted: elaboration on Roman's "slurp" implementation from zsh-users --- ChangeLog | 3 +++ Functions/Misc/zslurp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 Functions/Misc/zslurp diff --git a/ChangeLog b/ChangeLog index 386ef3ab9..238c12c16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-03 Bart Schaefer + * unposted: cf. Roman in users/29472: Functions/Misc/zslurp: + Efficient lossless read of stdin into $REPLY + * unposted: Src/Zle/zle_tricky.c, Src/parse.c, Src/pattern.c: Record as comments some notes about namespace usage exceptions. diff --git a/Functions/Misc/zslurp b/Functions/Misc/zslurp new file mode 100644 index 000000000..84df0c948 --- /dev/null +++ b/Functions/Misc/zslurp @@ -0,0 +1,31 @@ +#!/bin/zsh -f + +# Read stdin verbatim and as efficiently as possible into $REPLY, +# stopping without any change to $REPLY in the event of any error. +# Benchmarked by Roman Perepelitsa in zsh-users/29472 + +# Although this function faithfully records the input stream, later +# references to $REPLY with the multibyte option back in effect will +# (re-)interpret the content as multibyte characters. This may not be +# what is desired. + +emulate -L zsh -o no_multibyte + +### Alternate formulation, faster on bigger files +# # /dev/fd/0 is treated specially by -f so also check /dev/fd +# if [[ -d /dev/fd && -f /dev/fd/0 ]] && zmodload zsh/mapfile +# then +# local +h -Ar mapfile +# typeset -g REPLY="${mapfile[/dev/fd/0]}" && return +# fi +# # else fall through to read from pipe/socket + +zmodload zsh/system || return +local -a content +local -i i=0 +while true; do + sysread 'content[++i]' && continue + (( $? == 5 )) || return + break +done +typeset -g REPLY=${(j::)content} -- cgit v1.2.3 From c8f0946ddc428ff2d44e304d188b238c20c56484 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 3 Feb 2024 22:00:35 -0800 Subject: unposted: updates and fixed omissions for the printdefines utility --- ChangeLog | 2 ++ Util/printdefines | 74 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 238c12c16..4f059baa1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-02-03 Bart Schaefer + * unposted: Util/printdefines: updates and fix omissions + * unposted: cf. Roman in users/29472: Functions/Misc/zslurp: Efficient lossless read of stdin into $REPLY diff --git a/Util/printdefines b/Util/printdefines index c1306a19e..c127ad586 100644 --- a/Util/printdefines +++ b/Util/printdefines @@ -54,6 +54,7 @@ local -AHPrt paramflags=( # $((1<<12)) PM_ABSPATH_USED # (function): loaded using absolute path $((1<<13)) PM_UNIQUE # remove duplicates +# $((1<<13)) PM_SELFREF # Overload when namerefs resolved # $((1<<13)) PM_UNALIASED # (function) do not expand aliases $((1<<14)) PM_HIDE # Special behaviour hidden by local @@ -67,7 +68,8 @@ local -AHPrt paramflags=( $((1<<17)) PM_DONTIMPORT_SUID # do not import if running setuid # $((1<<17)) PM_LOADDIR # (function) filename gives load directory $((1<<18)) PM_SINGLE # special can only have a single instance - $((1<<18)) PM_ANONYMOUS # (function) anonymous function +# $((1<<18)) PM_NEWREF # Overload in for-loop namerefs +# $((1<<18)) PM_ANONYMOUS # (function) anonymous function $((1<<19)) PM_LOCAL # this parameter will be made local # $((1<<19)) PM_KSHSTORED # (function) stored in ksh form $((1<<20)) PM_SPECIAL # special builtin parameter @@ -82,33 +84,45 @@ local -AHPrt paramflags=( $((1<<25)) PM_REMOVABLE # special can be removed from paramtab $((1<<26)) PM_AUTOLOAD # autoloaded from module $((1<<27)) PM_NORESTORE # do not restore value of local special - $((1<<27)) PM_AUTOALL # autoload all features in module +# $((1<<27)) PM_AUTOALL # autoload all features in module $((1<<28)) PM_HASHELEM # is a hash-element $((1<<29)) PM_NAMEDDIR # has a corresponding nameddirtab entry $((1<<30)) PM_NAMEREF # pointer to a different parameter ) local -AHPrt chartokens=( - mapbase integer - $((83)) Meta - $((84)) Pound - $((85)) String - $((86)) Hat - $((87)) Star - $((88)) Inpar - $((89)) Inparmath - $((90)) Outbrace - $((91)) Inbrack - $((92)) Outbrack - $((93)) Tick - $((94)) Inang - $((95)) Outang - $((96)) OutangProc - $((97)) Quest - $((98)) Tilde - $((99)) Qtick - $((a0)) Bnullkeep - $((a1)) Nularg - $((a2)) Marker + mapbase 16 + $((0x83)) Meta + $((0x84)) Pound + $((0x85)) String + $((0x86)) Hat + $((0x87)) Star + $((0x88)) Inpar + $((0x89)) Inparmath + $((0x8a)) Outpar + $((0x8b)) Outparmath + $((0x8c)) Qstring + $((0x8d)) Equals + $((0x8e)) Bar + $((0x8f)) Inbrace + $((0x90)) Outbrace + $((0x91)) Inbrack + $((0x92)) Outbrack + $((0x93)) Tick + $((0x94)) Inang + $((0x95)) Outang + $((0x96)) OutangProc + $((0x97)) Quest + $((0x98)) Tilde + $((0x99)) Qtick + $((0x9a)) Comma + $((0x9b)) Dash # Only in patterns + $((0x9c)) Bang # Only in patterns + $((0x9d)) Snull + $((0x9e)) Dnull + $((0x9f)) Bnull + $((0xa0)) Bnullkeep + $((0xa1)) Nularg + $((0xa2)) Marker ) local -AHPrt fdtabletype=( mapbase integer @@ -120,6 +134,7 @@ local -AHPrt fdtabletype=( $((5)) FDT_FLOCK $((6)) FDT_FLOCK_EXEC $((7)) FDT_PROC_SUBST +#$((16)) FDT_SAVED_MASK ) local -AHPrt inputstates=( mapbase 2 @@ -129,6 +144,9 @@ local -AHPrt inputstates=( $((1<<3)) INP_CONT $((1<<4)) INP_ALCONT $((1<<5)) INP_HISTCONT + $((1<<6)) INP_LINENO + $((1<<7)) INP_APPEND + $((1<<8)) INP_RAW_KEEP ) local -AHPrt metafytypes=( mapbase integer @@ -175,12 +193,15 @@ local -AHPrt condtypes=( ) local -AHPrt wordcodes=( mapbase integer + $((0)) WC_END $((1)) WC_LIST $((2)) WC_SUBLIST $((3)) WC_PIPE $((4)) WC_REDIR $((5)) WC_ASSIGN +#$((5)) WC_SUBLIST_FREE $((6)) WC_SIMPLE +#$((6)) WC_LIST_FREE $((7)) WC_TYPESET $((8)) WC_SUBSH $((9)) WC_CURSH @@ -219,6 +240,7 @@ local -AHPrt builtintypes=( $((1<<1)) BINF_PLUSOPTS # +xyz legal $((1<<2)) BINF_PRINTOPTS $((1<<3)) BINF_ADDED # is in the builtins hash table + $((1<<4)) BINF_MAGICEQUALS $((1<<5)) BINF_PREFIX $((1<<6)) BINF_DASH $((1<<7)) BINF_BUILTIN @@ -246,9 +268,11 @@ local -AHPrt patflags=( $((0x0020)) PAT_PURES # Pattern is a pure string: set internally $((0x0040)) PAT_STATIC # Don't copy pattern to heap as per default $((0x0080)) PAT_SCAN # Scanning, so don't try must-match test + $((0x0100)) PAT_ZDUP # Copy pattern in real memory $((0x0200)) PAT_NOTSTART # Start of string is not real start $((0x0400)) PAT_NOTEND # End of string is not real end $((0x0800)) PAT_HAS_EXCLUDP # (internal): top-level path1~path2. + $((0x1000)) PAT_LCMATCHUC # equivalent to setting (#l) ) local -AHPrt patclasses=( mapbase integer @@ -314,6 +338,9 @@ local -AHPrt substmodifiers=( $((0x0100)) SUB_ALL # match complete string $((0x0200)) SUB_GLOBAL # global substitution ${..//all/these} $((0x0400)) SUB_DOSUBST # replacement string needs substituting + $((0x0800)) SUB_RETFAIL # return status 0 if no match + $((0x1000)) SUB_START # force match at start with SUB_END + $((0x2000)) SUB_LIST # no substitution, return list of matches $((0x4000)) SUB_EGLOB # use extended globbing in patterns ) local -AHPrt printparamflags=( @@ -333,6 +360,7 @@ local -AHPrt printwhenceflags=( $((1<<7)) PRINT_WHENCE_CSH $((1<<8)) PRINT_WHENCE_VERBOSE $((1<<9)) PRINT_WHENCE_SIMPLE +#$((1<<9)) PRINT_WITH_NAMESPACE $((1<<10)) PRINT_WHENCE_FUNCDEF $((1<<11)) PRINT_WHENCE_WORD ) -- cgit v1.2.3 From ec446a6f349c3f0a31ccd4cd21a257555bf53382 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 4 Feb 2024 16:25:14 +0100 Subject: 52516: fix crash in %H when hlgroups is empty typeset -A .zle.hlgroups; print -P %H --- ChangeLog | 4 ++++ Src/prompt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4f059baa1..1804037f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-02-04 Mikael Magnusson + + * 52516: Src/prompt.c: fix crash in %H when hlgroups is empty + 2024-02-03 Bart Schaefer * unposted: Util/printdefines: updates and fix omissions diff --git a/Src/prompt.c b/Src/prompt.c index ec79067cd..b1e5041bd 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -257,7 +257,7 @@ parsehighlight(char *arg, char endchar, zattr *atr) { Param node; HashTable ht = v->pm->gsu.h->getfn(v->pm); - if ((node = (Param) ht->getnode(ht, arg))) { + if (ht && (node = (Param) ht->getnode(ht, arg))) { attrs = node->gsu.s->getfn(node); entered = 1; if (match_highlight(attrs, atr, 0) == attrs) -- cgit v1.2.3 From 653be0823da9a6b085a0092ac3a7b8792afc142a Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 4 Feb 2024 16:44:21 +0100 Subject: 52517: ensure that %H is followed by { The previous code would accept any character after %H assuming it was a {, which was probably also a buffer overrun sometimes. --- ChangeLog | 2 ++ Src/prompt.c | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1804037f3..bb619cf49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ * 52516: Src/prompt.c: fix crash in %H when hlgroups is empty + * 52517: Src/prompt.c: ensure that %H is followed by { + 2024-02-03 Bart Schaefer * unposted: Util/printdefines: updates and fix omissions diff --git a/Src/prompt.c b/Src/prompt.c index b1e5041bd..0d674ceab 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -605,10 +605,12 @@ putpromptchar(int doprint, int endchar) applytextattributes(TSC_PROMPT); break; case 'H': - bv->fm = parsehighlight(bv->fm + 2, '}', &atr); - if (atr != TXT_ERROR) { - treplaceattrs(atr); - applytextattributes(TSC_PROMPT); + if (bv->fm[1] == '{') { + bv->fm = parsehighlight(bv->fm + 2, '}', &atr); + if (atr != TXT_ERROR) { + treplaceattrs(atr); + applytextattributes(TSC_PROMPT); + } } break; case '[': -- cgit v1.2.3 From 58ff6c68d5022c013d58caf1ee6d5c78dc7d67a8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 4 Feb 2024 16:13:31 -0800 Subject: 52521: mapfile (mis)handling of empty/unreadable files --- ChangeLog | 4 ++++ Etc/BUGS | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index bb619cf49..c553b02cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-02-04 Bart Schaefer + + * 52521: Etc/BUGS: mapfile handling of empty/unreadable files + 2024-02-04 Mikael Magnusson * 52516: Src/prompt.c: fix crash in %H when hlgroups is empty diff --git a/Etc/BUGS b/Etc/BUGS index e238c161c..b6ee30cbb 100644 --- a/Etc/BUGS +++ b/Etc/BUGS @@ -55,3 +55,6 @@ users/26071: Strange behavior about option completion of "git push --f" return value of the left side of the expression is always 148 (SIGTSTP) and thus the expression is likely to be incorrectly interpreted. ------------------------------------------------------------------------ +52521: Empty files and unreadable files cannot be removed using the +mapfile module "unset 'mapfile[filename]'", and are not distinguished +from files that do not exist. \ No newline at end of file -- cgit v1.2.3 From 791aaf88cca53036d19ad2e247c783744ccf3837 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 4 Feb 2024 20:46:49 -0800 Subject: cf. users/29635: additional detail of parameter expansion in math context. --- ChangeLog | 3 +++ Doc/Zsh/arith.yo | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index c553b02cf..964eeef23 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-04 Bart Schaefer + * unposted (cf. users/29635): Doc/Zsh/arith.yo: additional detail + of parameter expansion in math context. + * 52521: Etc/BUGS: mapfile handling of empty/unreadable files 2024-02-04 Mikael Magnusson diff --git a/Doc/Zsh/arith.yo b/Doc/Zsh/arith.yo index bc3e35ad5..9f5298821 100644 --- a/Doc/Zsh/arith.yo +++ b/Doc/Zsh/arith.yo @@ -206,6 +206,11 @@ example, example(((val2 = val1 * 2))) assigns twice the value of tt($val1) to the parameter named tt(val2). +If the expansion of tt($val1) is text rather than a number, then when +tt(val1) is referenced that text is itself evaluated as a math expression +as if surrounded by parentheses `tt(LPAR()$val1)tt(RPAR())'. Expansion +continues until there are no more parameter references, a number has +resulted, or an expression error occurs. An internal integer representation of a named parameter can be specified with the tt(integer) builtin. -- cgit v1.2.3 From 04ae7dc64cde2fa6b7354f685596ff570404a2c9 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Fri, 9 Feb 2024 19:26:54 +0100 Subject: 52526: metafy terminfo capabilities --- ChangeLog | 4 ++++ Src/Modules/terminfo.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 964eeef23..639f19369 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-02-09 Mikael Magnusson + + * 52526: Src/Modules/terminfo.c: metafy terminfo capabilities + 2024-02-04 Bart Schaefer * unposted (cf. users/29635): Doc/Zsh/arith.yo: additional detail diff --git a/Src/Modules/terminfo.c b/Src/Modules/terminfo.c index 4596b41d2..f9ab64fb3 100644 --- a/Src/Modules/terminfo.c +++ b/Src/Modules/terminfo.c @@ -160,7 +160,7 @@ getterminfo(UNUSED(HashTable ht), const char *name) pm->node.flags |= PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; } else if ((tistr = (char *)tigetstr(nameu)) != NULL && tistr != (char *)-1) { - pm->u.str = dupstring(tistr); + pm->u.str = metafy(tistr, -1, META_HEAPDUP); pm->node.flags |= PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; } else { @@ -280,7 +280,7 @@ scanterminfo(UNUSED(HashTable ht), ScanFunc func, int flags) for (capname = (char **)strnames; *capname; capname++) { if ((tistr = (char *)tigetstr(*capname)) != NULL && tistr != (char *)-1) { - pm->u.str = dupstring(tistr); + pm->u.str = metafy(tistr, -1, META_HEAPDUP); pm->node.nam = dupstring(*capname); func(&pm->node, flags); } -- cgit v1.2.3 From 14c230dc3216b7fe0f63d797347e14178d4ede2b Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 15 Feb 2024 14:48:04 +0100 Subject: 52533: add module to provide alternate readonly views of the content of .zle.hlgroups --- ChangeLog | 6 ++ Src/Modules/hlgroup.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++ Src/Modules/hlgroup.mdd | 7 ++ Src/prompt.c | 28 +++++++ 4 files changed, 252 insertions(+) create mode 100644 Src/Modules/hlgroup.c create mode 100644 Src/Modules/hlgroup.mdd diff --git a/ChangeLog b/ChangeLog index 639f19369..6d064eaf6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-02-15 Oliver Kiddle + + * 52533: Src/Modules/hlgroup.c, Src/Modules/hlgroup.mdd, + Src/prompt.c: add module to provide alternate readonly views of + the content of .zle.hlgroups + 2024-02-09 Mikael Magnusson * 52526: Src/Modules/terminfo.c: metafy terminfo capabilities diff --git a/Src/Modules/hlgroup.c b/Src/Modules/hlgroup.c new file mode 100644 index 000000000..6382f3216 --- /dev/null +++ b/Src/Modules/hlgroup.c @@ -0,0 +1,211 @@ +/* + * hlgroup.c - Supporting parameters for highlight groups + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 2024 Oliver Kiddle + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Oliver Kiddle or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Oliver Kiddle and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Oliver Kiddle and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Oliver Kiddle and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "hlgroup.mdh" +#include "hlgroup.pro" + +#define GROUPVAR ".zle.hlgroups" + +static const struct gsu_scalar pmesc_gsu = +{ strgetfn, nullstrsetfn, nullunsetfn }; + +/**/ +static char * +convertattr(char *attrstr, int sgr) +{ + zattr atr; + char *r, *s; + int len; + + match_highlight(attrstr, &atr, NULL); + s = zattrescape(atr, sgr ? NULL : &len); + + if (sgr) { + char *c = s, *t = s - 1; + + while (c[0] == '\033' && c[1] == '[') { + c += 2; + while (isdigit(*c) || *c == ';') + *++t = *c++; + t++; + if (*c != 'm') + break; + *t = ';'; + c++; + } + *t = '\0'; + len = t - s; + } + + r = dupstring_wlen(s, len); + free(s); + return r; +} + +/**/ +static HashNode +getgroup(const char *name, int sgr) +{ + Param pm = NULL; + HashNode hn; + HashTable hlg; + Value v; + struct value vbuf; + char *var = GROUPVAR; + + pm = (Param) hcalloc(sizeof(struct param)); + pm->gsu.s = &pmesc_gsu; + pm->node.nam = dupstring(name); + pm->node.flags = PM_SCALAR|PM_SPECIAL; + + if (!(v = getvalue(&vbuf, &var, 0)) || + PM_TYPE(v->pm->node.flags) != PM_HASHED || + !(hlg = v->pm->gsu.h->getfn(v->pm)) || + !(hn = gethashnode2(hlg, name))) + { + pm->u.str = dupstring(""); + pm->node.flags |= PM_UNSET; + } else { + pm->u.str = convertattr(((Param) hn)->u.str, sgr); + } + + return &pm->node; +} + +/**/ +static void +scangroup(ScanFunc func, int flags, int sgr) +{ + struct param pm; + int i; + HashNode hn; + HashTable hlg; + Value v; + struct value vbuf; + char *var = GROUPVAR; + + if (!(v = getvalue(&vbuf, &var, 0)) || + PM_TYPE(v->pm->node.flags) != PM_HASHED) + return; + hlg = v->pm->gsu.h->getfn(v->pm); + + memset((void *)&pm, 0, sizeof(struct param)); + pm.node.flags = PM_SCALAR; + pm.gsu.s = &pmesc_gsu; + + for (i = 0; i < hlg->hsize; i++) + for (hn = hlg->nodes[i]; hn; hn = hn->next) { + pm.u.str = convertattr(((Param) hn)->u.str, sgr); + pm.node.nam = hn->nam; + func(&pm.node, flags); + } +} +/**/ +static HashNode +getpmesc(UNUSED(HashTable ht), const char *name) +{ + return getgroup(name, 0); +} + +/**/ +static void +scanpmesc(UNUSED(HashTable ht), ScanFunc func, int flags) +{ + return scangroup(func, flags, 0); +} + +/**/ +static HashNode +getpmsgr(UNUSED(HashTable ht), const char *name) +{ + return getgroup(name, 1); +} + +/**/ +static void +scanpmsgr(UNUSED(HashTable ht), ScanFunc func, int flags) +{ + return scangroup(func, flags, 1); +} + +static struct paramdef partab[] = { + SPECIALPMDEF(".zle.esc", PM_READONLY_SPECIAL, 0, getpmesc, scanpmesc), + SPECIALPMDEF(".zle.sgr", PM_READONLY_SPECIAL, 0, getpmsgr, scanpmsgr) +}; + +static struct features module_features = { + NULL, 0, + NULL, 0, + NULL, 0, + partab, sizeof(partab)/sizeof(*partab), + 0 +}; + +/**/ +int +setup_(UNUSED(Module m)) +{ + return 0; +} + +/**/ +int +features_(Module m, char ***features) +{ + *features = featuresarray(m, &module_features); + return 0; +} + +/**/ +int +enables_(Module m, int **enables) +{ + return handlefeatures(m, &module_features, enables); +} + +/**/ +int +boot_(UNUSED(Module m)) +{ + return 0; +} + +/**/ +int +cleanup_(Module m) +{ + return setfeatureenables(m, &module_features, NULL); +} + +/**/ +int +finish_(UNUSED(Module m)) +{ + return 0; +} diff --git a/Src/Modules/hlgroup.mdd b/Src/Modules/hlgroup.mdd new file mode 100644 index 000000000..ee3ba7260 --- /dev/null +++ b/Src/Modules/hlgroup.mdd @@ -0,0 +1,7 @@ +name=zsh/hlgroup +link=either +load=yes + +autofeatures="p:.zle.esc p:.zle.sgr" + +objects="hlgroup.o" diff --git a/Src/prompt.c b/Src/prompt.c index 0d674ceab..7acbe0e47 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -241,6 +241,34 @@ promptexpand(char *s, int ns, char *rs, char *Rs) return new_vars.buf; } +/* Get the escape sequence for a given attribute. */ +/**/ +mod_export char * +zattrescape(zattr atr, int *len) +{ + struct buf_vars new_vars; + zattr savecurrent = txtcurrentattrs; + zattr saveunknown = txtunknownattrs; + + memset(&new_vars, 0, sizeof(new_vars)); + new_vars.last = bv; + bv = &new_vars; + new_vars.bufspc = 256; + new_vars.bp = new_vars.bufline = new_vars.buf = zshcalloc(new_vars.bufspc); + new_vars.dontcount = 1; + + txtunknownattrs = 0; + treplaceattrs(atr); + applytextattributes(TSC_PROMPT); + + bv = new_vars.last; + + txtpendingattrs = txtcurrentattrs = savecurrent; + txtunknownattrs = saveunknown; + + return unmetafy(new_vars.buf, len); +} + /* Parse the argument for %H */ static char * parsehighlight(char *arg, char endchar, zattr *atr) -- cgit v1.2.3 From 173c0b14ab9ad1f54e74a2573d8212a720df1762 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 15 Feb 2024 14:50:56 +0100 Subject: 52535: documentation for highlight groups and layers --- ChangeLog | 3 +++ Doc/Makefile.in | 3 ++- Doc/Zsh/mod_hlgroup.yo | 25 +++++++++++++++++++++++++ Doc/Zsh/prompt.yo | 8 ++++++++ Doc/Zsh/zle.yo | 11 +++++++++++ NEWS | 6 ++++++ 6 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 Doc/Zsh/mod_hlgroup.yo diff --git a/ChangeLog b/ChangeLog index 6d064eaf6..3cbf7d699 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-15 Oliver Kiddle + * 52535: Doc/Makefile.in, Doc/Zsh/prompt.yo, Doc/Zsh/zle.yo, + Doc/Zsh/mod_hlgroup.yo, NEWS: documentation for highlight groups + * 52533: Src/Modules/hlgroup.c, Src/Modules/hlgroup.mdd, Src/prompt.c: add module to provide alternate readonly views of the content of .zle.hlgroups diff --git a/Doc/Makefile.in b/Doc/Makefile.in index dabe11fe3..d9be182e9 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -63,7 +63,8 @@ Zsh/mod_attr.yo Zsh/mod_cap.yo Zsh/mod_clone.yo \ Zsh/mod_compctl.yo Zsh/mod_complete.yo Zsh/mod_complist.yo \ Zsh/mod_computil.yo Zsh/mod_curses.yo \ Zsh/mod_datetime.yo Zsh/mod_db_gdbm.yo Zsh/mod_deltochar.yo \ -Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_langinfo.yo \ +Zsh/mod_example.yo Zsh/mod_files.yo \ +Zsh/mod_hlgroup.yo Zsh/mod_langinfo.yo \ Zsh/mod_ksh93.yo Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo \ Zsh/mod_nearcolor.yo Zsh/mod_newuser.yo \ Zsh/mod_parameter.yo Zsh/mod_pcre.yo Zsh/mod_private.yo \ diff --git a/Doc/Zsh/mod_hlgroup.yo b/Doc/Zsh/mod_hlgroup.yo new file mode 100644 index 000000000..efe8934a1 --- /dev/null +++ b/Doc/Zsh/mod_hlgroup.yo @@ -0,0 +1,25 @@ +COMMENT(!MOD!zsh/hlgroup +Alternative views of highlighting groups +!MOD!) +The tt(zsh/hlgroup) module defines special parameters that represent +highlighting groups in different forms to ease the use of the groups when +configuring other tools. + +In each case, these are readonly associative arrays where accessing elements +uses values from the underlying tt(.zle.hlgroups) variable. + +startitem() +vindex(.zle.esc) +item(tt(.zle.esc))( +This associative array contains the literal escape sequences used to apply the +highlighting for each group. An example use would be when setting the +tt(LESS_TERMCAP_xx) environment variables for the tt(less) pager. +) +vindex(.zle.sgr) +item(tt(.zle.sgr))( +Where highlighting makes use of CSI escape sequences, this parameter contains +the "Select Graphic Rendition" number sequence. This is useful with, for +example the tt(GREP_COLORS) and tt(LSCOLORS) environment variables and the +tt(list-colors) style. +) +enditem() diff --git a/Doc/Zsh/prompt.yo b/Doc/Zsh/prompt.yo index 909012c8e..de988ab7c 100644 --- a/Doc/Zsh/prompt.yo +++ b/Doc/Zsh/prompt.yo @@ -246,6 +246,14 @@ item(tt(%K) LPAR()tt(%k)RPAR())( Start (stop) using a different bacKground colour. The syntax is identical to that for tt(%F) and tt(%f). ) +item(tt(%H))( +Change all character visual attributes using a highlighting specification from +the tt(.zle.hlgroups) associative array. The key is specified in following +braces so, for example tt(%H{error}) will use the highlighting specification +for the `error' group. If the key is not found in the associative array then +it has no effect. Highlighting specifications are in the same format as for +the tt(zle_highlight) parameter. +) item(tt(%{)...tt(%}))( Include a string as a literal escape sequence. The string within the braces should not change the cursor diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 495bd86a8..31eb3f3ba 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -2807,6 +2807,17 @@ item(tt(italic))( The characters in the given context are shown in a italic font. Not all terminals support italic fonts. ) +item(tt(hl=)var(group))( +Use the specified highlighting group. The var(group) is used as a key into +the associative array tt(.zle.hlgroups) to determine the actual highlighting. +) +item(tt(layer=)var(layer))( +The layer is used to determine precedence when multiple highlighting regions +overlap. The var(layer) is a decimal integer, with higher numbers taking +precedence over lower numbers. The default layer is 10 with 30 used as the +default for tt(special), 20 for tt(region) and tt(isearch) and 15 for +tt(paste). +) enditem() The characters described above as `special' are as follows. The diff --git a/NEWS b/NEWS index 4d4699f7e..d0a8584e2 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,12 @@ Changes since 5.9 In region_highlight and zle_highlight, italic and faint can be specified as font attributes for terminals that support them. +Highlighting groups can be referenced in region_highlight and +zle_highlight for common attribute combinations and a layer can be +specified to indicate precedence where highlighted regions overlap. +Highlighting groups are also supported in the prompt via a new %H +prompt escape. + Ellipsis markers shown by the line editor to indicate where the line doesn't fit in the terminal can be highlighted. -- cgit v1.2.3 From 2d2086557ef80117e939253a68580abe07c89fe2 Mon Sep 17 00:00:00 2001 From: Poncho Date: Wed, 14 Feb 2024 18:56:40 +0100 Subject: github #112: Completion: todo.sh uses shorthelp and not showhelp --- ChangeLog | 3 +++ Completion/Unix/Command/_todo.sh | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3cbf7d699..36029a2a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-15 Oliver Kiddle + * github #112: Poncho: Completion/Unix/Command/_todo.sh: + Completion: todo.sh uses shorthelp and not showhelp + * 52535: Doc/Makefile.in, Doc/Zsh/prompt.yo, Doc/Zsh/zle.yo, Doc/Zsh/mod_hlgroup.yo, NEWS: documentation for highlight groups diff --git a/Completion/Unix/Command/_todo.sh b/Completion/Unix/Command/_todo.sh index e26bfc94f..fc84ee076 100644 --- a/Completion/Unix/Command/_todo.sh +++ b/Completion/Unix/Command/_todo.sh @@ -74,7 +74,7 @@ case $state in "replace:replace in NUMBER the TEXT." "remdup:remove exact duplicates from todo.txt." "report:adds the number of open and done items to report.txt." - "showhelp:list the one-line usage of all built-in and add-on actions." + "shorthelp:list the one-line usage of all built-in and add-on actions." ) _describe -t todo-commands 'todo.sh command' cmdlist ;; -- cgit v1.2.3 From fb9a7cc5dd07910afa7ebea174b379350cae4c91 Mon Sep 17 00:00:00 2001 From: midchildan Date: Sat, 3 Feb 2024 01:28:00 +0900 Subject: 52520: add new features and improvements to the "incarg" ZLE widget - Decrement integers without defining a new widget - Preserve the number of leading zeros - Increment binaries, octals, and hexadecimals - Move the cursor to the end of the incremented integer - Create a sequence of integers across terminal panes - Add a Vim variant - Also add tests --- ChangeLog | 4 + Doc/Zsh/contrib.yo | 30 ++++- Functions/Zle/incarg | 273 ++++++++++++++++++++++++++++++++----- Test/X05zleincarg.ztst | 360 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 630 insertions(+), 37 deletions(-) create mode 100644 Test/X05zleincarg.ztst diff --git a/ChangeLog b/ChangeLog index 36029a2a8..faae11c80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2024-02-15 Oliver Kiddle + * 52520: midchildan: Doc/Zsh/contrib.yo, Functions/Zle/incarg, + Test/X05zleincarg.ztst: add new features and improvements to the + "incarg" ZLE widget + * github #112: Poncho: Completion/Unix/Command/_todo.sh: Completion: todo.sh uses shorthelp and not showhelp diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index e1781a5e1..718686587 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -2620,12 +2620,30 @@ zle -N history-pattern-search-forward history-pattern-search) tindex(incarg) vindex(incarg, use of) item(tt(incarg))( -Typing the keystrokes for this widget with the cursor placed on or to the -left of an integer causes that integer to be incremented by one. With a -numeric argument, the number is incremented by the amount of the -argument (decremented if the numeric argument is negative). The shell -parameter tt(incarg) may be set to change the default increment to -something other than one. +This widget allows you to increment integers on the current line. In addition +to decimals, it can handle hexadecimals prefixed with tt(0x), binaries with +tt(0b), and octals with tt(0o). + +By default, the target integer will be incremented by one. With a numeric +argument, the integer is incremented by the amount of the argument. The shell +parameter tt(incarg) may be set to change the default increment to something +other than one. + +The behavior of this widget changes depending on the widget name. + +When the widget is named tt(incarg), the widget will increment an integer +placed under the cursor placed or just to the left of it. tt(decarg), on the +other hand, decrements the integer. When the name is prefixed with tt(vim-), +the cursor will jump to the nearest integer after the cursor before incrementing +it. + +There's also a tt(sync-) prefix that can be added to the widget name. This +variant is used for creating a sequence of numbers on split terminals with +synchronized key input. The first pane won't increment the integer at all, but +each pane after that will have the integer incremented once more than the +previous pane. It currently supports tmux and iTerm2. + +The prefixes tt(vim-) and tt(sync-) can be combined into tt(vim-sync-). example(bindkey '^X+' incarg) ) diff --git a/Functions/Zle/incarg b/Functions/Zle/incarg index cff0cfe4c..1131b148b 100644 --- a/Functions/Zle/incarg +++ b/Functions/Zle/incarg @@ -1,43 +1,254 @@ -# Shell function to increment an integer either under the cursor or just -# to the left of it. Use +emulate -L zsh + +# A ZLE widget to increment an integer. +# +# In addition to decimals, it can handle hexadecimals prefixed with "0x", +# binaries with "0b", and octals with "0o". +# +# By default, the target integer will be incremented by one. With a numeric +# argument, the integer is incremented by the amount of the argument. The shell +# parameter "incarg" may be set to change the default increment to something +# other than one. +# +# The behavior of this widget changes depending on how it is named. +# +# - incarg / decarg +# +# incarg will increment an integer either under the cursor or just to the left +# of it. decarg, on the other hand, will decrement it. +# +# For example, +# +# echo 41 +# ^^^ cursor anywhere here +# +# with incarg gives +# +# echo 42 +# ^ cursor will move here +# +# - sync-incarg / sync-decarg +# +# The sync- variant is used for creating a sequence of numbers on split +# terminals with synchronized key input. The first pane won't be incremented +# at all, but each pane after that will have the number incremented once more +# than the previous pane. +# +# Currently supports tmux and iTerm2. +# +# - vim-incarg / vim-decarg +# +# This behaves like Vim's CTRL-A / CTRL-X. It moves the cursor to the nearest +# number after the cursor and increments or decrements it. +# +# - vim-sync-incarg / vim-sync-decarg +# +# This combines the behavior of the vim- and sync- variants. It's inspired by +# Vim's g_CTRL-A / g_CTRL-X. +# +# Example Usage: +# # autoload -Uz incarg -# zle -N incarg -# bindkey "..." incarg -# to define it. For example, -# echo 41 -# ^^^ cursor anywhere here -# with incarg gives -# echo 42 -# with the cursor in the same place. -# -# A numeric argument gives a number other than 1 to add (may be negative). -# If you're going to do it a lot with one particular number, you can set -# the parameter incarg to that number (a numeric argument still takes -# precedence). +# for widget in vim-{,sync-}{inc,dec}arg; do +# zle -N "$widget" incarg +# done +# bindkey -a \ +# '^A' vim-incarg \ +# '^X' vim-decarg \ +# 'g^A' vim-sync-incarg \ +# 'g^X' vim-sync-decarg -emulate -L zsh -setopt extendedglob +setopt localoptions extended_glob +local match mbegin mend MATCH MBEGIN MEND i -local rrest lrest num +# find the number and determine the base +integer pos=$(( CURSOR + 1 )) base=0 -rrest=${RBUFFER##[0-9]#} -if [[ $RBUFFER = [0-9]* ]]; then - if [[ -z $rrest ]]; then - num=$RBUFFER - else - num=${RBUFFER[1,-$#rrest-1]} +# avoid miscalculating positions when cursor is at the end of the line +while (( pos > 0 )) && [[ "$BUFFER[pos]" == '' ]]; do + (( pos-- )) +done + +# check for a prefix (e.g., 0x) before the cursor +for (( i = 0; i < 2; i++ )); do + case "$BUFFER[1,pos]" in + *0[xX][0-9a-fA-F]##) base=16 ;; + *0[oO][0-7]##) base=8 ;; + *0[bB][01]##) base=2 ;; + *[1-9]) base=10 ;; + *0) ;; # there may be a prefix right after the cursor + *) + # the non-Vim variant looks right before the cursor too, but not after it + if [[ "$WIDGET" != vi* ]]; then + if (( i == 0 )); then + (( pos-- )) + continue + else + return 1 + fi + fi + ;; + esac + + break +done + +# check for a prefix on the cursor +if (( base == 0 && pos < $#BUFFER )); then + case "$BUFFER[1,pos+1]" in + *0[xX][0-9a-fA-F]) base=16; (( pos++ )) ;; + *0[oO][0-7]) base=8; (( pos++ )) ;; + *0[bB][01]) base=2; (( pos++ )) ;; + esac +fi + +if (( base == 0 )); then + if [[ "$WIDGET" == vi* ]]; then + # jump to the nearest number after the cursor + while [[ "$BUFFER[pos]" == [^0-9] ]]; do + (( pos++ )) + (( pos > $#BUFFER )) && return 1 + done fi + + # check for a prefix right after the cursor and jump right after it, if any + if (( pos <= 1 )) || [[ "$BUFFER[pos-1]" == [^0-9] ]]; then + case "$BUFFER[pos,-1]" in + 0[xX][0-9a-fA-F]*) base=16; (( pos += 2 )) ;; + 0[oO][0-7]*) base=8; (( pos += 2 )) ;; + 0[bB][01]*) base=2; (( pos += 2 )) ;; + esac + fi +fi + +if (( base == 0 )); then + base=10 fi -lrest=${LBUFFER%%[0-9]#} -if [[ $LBUFFER = *[0-9] ]]; then - if [[ -z $lrest ]]; then - num="$LBUFFER$num" +# find the start of the number +integer first="$pos" +case "$base" in + 10) + while [[ "$BUFFER[first-1]" == [0-9] ]]; do + (( first-- )) + done + if [[ $BUFFER[first-1] = - ]]; then + (( first-- )) + fi + ;; + 2) + while [[ "$BUFFER[first-1]" == [01] ]]; do + (( first-- )) + done + ;; + 8) + while [[ "$BUFFER[first-1]" == [0-7] ]]; do + (( first-- )) + done + ;; + 16) + while [[ "$BUFFER[first-1]" == [0-9a-fA-F] ]]; do + (( first-- )) + done + ;; +esac + +# find the end of the number +integer last="$pos" +case "$base" in + 10) + while [[ "$BUFFER[last+1]" == [0-9] ]]; do + (( last++ )) + done + ;; + 2) + while [[ "$BUFFER[last+1]" == [01] ]]; do + (( last++ )) + done + ;; + 8) + while [[ "$BUFFER[last+1]" == [0-7] ]]; do + (( last++ )) + done + ;; + 16) + while [[ "$BUFFER[last+1]" == [0-9a-fA-F] ]]; do + (( last++ )) + done + ;; +esac + +# calculate the number of digits +integer ndigits=0 +case "$BUFFER[first,first+1]" in + 0*|-0) ndigits=$(( last - first + 1 )) ;; +esac + +# determine the amount to increment +integer delta=${NUMERIC:-${incarg:-1}} +if [[ "$WIDGET" = *decarg ]]; then + (( delta = -delta )) +fi +if [[ "$WIDGET" = *sync-* ]]; then + integer pane_index=0 + if [[ -n "$TMUX_PANE" ]]; then + pane_index="$(tmux display-message -pt "$TMUX_PANE" '#{pane_index}')" + elif [[ "$ITERM_SESSION_ID" =~ '^w[0-9]+t[0-9]+p([0-9]+)' ]]; then + pane_index="$match[1]" else - num="${LBUFFER[$#lrest+1,-1]}$num" + zle -M "[$WIDGET] unsupported terminal" + return 1 + fi + (( delta *= pane_index )) +fi + +local old="$BUFFER[first,last]" +integer oldlen=$#BUFFER + +local fmt1 fmt2 +case "$base" in + 10) fmt1=d; fmt2='#10' ;; + 2) fmt1=s; fmt2='##2' ;; + 8) fmt1=s; fmt2='##8' ;; + 16) fmt1="$BUFFER[first-1]"; fmt2='#16' ;; +esac + +local raw_result padded +raw_result="$( \ + printf "%0$ndigits$fmt1" $(( [$fmt2] "$base#$old" + delta )) 2> /dev/null)" +padded="${raw_result// /0}" + +integer oldnum="$base#$old" newnum="$base#$padded" 2> /dev/null +if (( base != 10 && newnum < 0 + || delta > 0 && newnum < oldnum + || delta < 0 && newnum > oldnum )); then + zle -M "[$WIDGET] The resulting number is either too big or too small." + return 1 +fi + +# adjust the number of leading zeros if the sign of the integer changed +local new +if (( base == 10 && ndigits == $#padded )); then + if (( oldnum < 0 && newnum >= 0 )); then + new="${padded#0}" + elif (( oldnum >= 0 && newnum < 0 )); then + new="-0${padded#-}" fi fi +if [[ -z "$new" ]]; then + new="$padded" +fi + +if zstyle -t ":zle:$WIDGET" debug; then + zle -M "[$WIDGET] base: $base delta: $delta old: '$old' new: '$new'" +fi + +BUFFER[first,last]="$new" -[[ -n $num ]] && (( num += ${NUMERIC:-${incarg:-1}} )) +integer offset=0 +if [[ "$WIDGET" == vi* ]]; then + offset=-1 +fi +(( CURSOR = last + $#BUFFER - oldlen + offset )) -BUFFER="$lrest$num$rrest" +return 0 diff --git a/Test/X05zleincarg.ztst b/Test/X05zleincarg.ztst new file mode 100644 index 000000000..2a6aa2d3f --- /dev/null +++ b/Test/X05zleincarg.ztst @@ -0,0 +1,360 @@ +# Tests the incarg ZLE widget + +%prep + ZSH_TEST_LANG=$(ZTST_find_UTF8) + if ( zmodload zsh/zpty 2>/dev/null ); then + . $ZTST_srcdir/comptest + comptestinit -v -z $ZTST_testdir/../Src/zsh + else + ZTST_unimplemented="the zsh/zpty module is not available" + fi + zpty_run ' + autoload -Uz incarg + for name in {,vim-}{,sync-}{inc,dec}arg; do + zle -N "$name" incarg + done + bindkey -v "^N" incarg + bindkey -v "^P" decarg + bindkey -v "^F" sync-incarg + bindkey -v "^B" sync-decarg + bindkey -a "^N" vim-incarg + bindkey -a "^P" vim-decarg + bindkey -a "^F" vim-sync-incarg + bindkey -a "^B" vim-sync-decarg + unset TMUX_PANE ITERM_SESSION_ID + tmux() { + echo "$TMUX_PANE" + } + ' + +%test + + zletest $'0\C-n' +0:increment an integer with incarg +>BUFFER: 1 +>CURSOR: 1 + + zletest $'0\C-p' +0:decrement an integer with decarg +>BUFFER: -1 +>CURSOR: 2 + + zletest $'echo 0\e0\C-n' +0:increment an integer with vim-incarg +>BUFFER: echo 1 +>CURSOR: 5 + + zletest $'echo 0\e0\C-p' +0:decrement an integer with vim-decarg +>BUFFER: echo -1 +>CURSOR: 6 + + zletest $'0\C-f' +0:sync-incarg does nothing on unsupported terminals +>BUFFER: 0 +>CURSOR: 1 + + zpty_run 'TMUX_PANE=0' + zletest $'0\C-f' + zpty_run 'unset TMUX_PANE' +0:sync-incarg on tmux in pane 0 +>BUFFER: 0 +>CURSOR: 1 + + zpty_run 'TMUX_PANE=1' + zletest $'0\C-f' + zpty_run 'unset TMUX_PANE' +0:sync-incarg on tmux in pane 1 +>BUFFER: 1 +>CURSOR: 1 + + zpty_run 'TMUX_PANE=2' + zletest $'0\C-f' + zpty_run 'unset TMUX_PANE' +0:sync-incarg on tmux in pane 2 +>BUFFER: 2 +>CURSOR: 1 + + zpty_run 'ITERM_SESSION_ID=w0t0p0:00000000-0000-0000-0000-000000000000' + zletest $'0\C-f' + zpty_run 'unset ITERM_SESSION_ID' +0:sync-incarg on tmux in pane 0 +>BUFFER: 0 +>CURSOR: 1 + + zpty_run 'ITERM_SESSION_ID=w0t0p1:00000000-0000-0000-0000-000000000000' + zletest $'0\C-f' + zpty_run 'unset ITERM_SESSION_ID' +0:sync-incarg on tmux in pane 1 +>BUFFER: 1 +>CURSOR: 1 + + zpty_run 'ITERM_SESSION_ID=w0t0p2:00000000-0000-0000-0000-000000000000' + zletest $'0\C-f' + zpty_run 'unset ITERM_SESSION_ID' +0:sync-incarg on tmux in pane 2 +>BUFFER: 2 +>CURSOR: 1 + + zpty_run 'TMUX_PANE=1' + zpty_run 'ITERM_SESSION_ID=w0t0p2:00000000-0000-0000-0000-000000000000' + zletest $'0\C-f' + zpty_run 'unset TMUX_PANE ITERM_SESSION_ID' +0:tmux pane number takes precedence over iTerm2's +>BUFFER: 1 +>CURSOR: 1 + + zletest $'0\e2\C-n' +0:Providing a numeric argument will change the incremented amount +>BUFFER: 2 +>CURSOR: 0 + + zpty_run 'incarg=3' + zletest $'0\e\C-n' + zpty_run 'unset incarg' +0:Setting the incarg variable will change the default incremented amount +>BUFFER: 3 +>CURSOR: 0 + + zpty_run 'incarg=3' + zletest $'0\e2\C-n' + zpty_run 'unset incarg' +0:A numeric argument will take precedence over the incarg variable +>BUFFER: 2 +>CURSOR: 0 + + zpty_run 'TMUX_PANE=2' + zletest $'0\e2\C-f' + zpty_run 'unset TMUX_PANE' +0:Providing a numeric argument will work for the sync- variants of incarg +>BUFFER: 4 +>CURSOR: 0 + + zletest $'000\C-n' +0:Incrementing a decimal integer preserves leading zeros +>BUFFER: 001 +>CURSOR: 3 + + zletest $'-001\C-n\C-n' +0:Leading zeros are preserved when the digit turns from negative to positive +>BUFFER: 001 +>CURSOR: 3 + + zletest $'001\C-p\C-p' +0:Leading zeros are preserved when the digit turns from positive to negative +>BUFFER: -001 +>CURSOR: 4 + + zletest $'001\e1000\C-n' +0:Incrementing an integer works when the result has more zeros than the original +>BUFFER: 1001 +>CURSOR: 3 + + zletest $'001\e2000\C-p' +0:Decrementing an integer with leading zeros works when the result has more digits than the original +>BUFFER: -1999 +>CURSOR: 4 + + zletest $'0b11\C-n' +0:Increment a binary integer +>BUFFER: 0b100 +>CURSOR: 5 + + zletest $'0B11\C-n' +0:Increment a binary integer with an upper case prefix +>BUFFER: 0B100 +>CURSOR: 5 + + zletest $'0b100\C-p' +0:Decrement a binary integer +>BUFFER: 0b11 +>CURSOR: 4 + + zletest $'0b0011\C-n' +0:Increment a binary integer preserves leading zeros +>BUFFER: 0b0100 +>CURSOR: 6 + + zletest $'0b001\e8\C-n' +0:Incrementing a binary integer work when the result has more zeros than the original +>BUFFER: 0b1001 +>CURSOR: 5 + + zletest $'0b0\C-p' +0:Decrementing a binary integer to a negative value will fail +>BUFFER: 0b0 +>CURSOR: 3 + + zletest $'0o7\C-n' +0:Increment an octal integer +>BUFFER: 0o10 +>CURSOR: 4 + + zletest $'0O7\C-n' +0:Increment an octal integer with an upper case prefix +>BUFFER: 0O10 +>CURSOR: 4 + + zletest $'0o10\C-p' +0:Decrement an octal integer +>BUFFER: 0o7 +>CURSOR: 3 + + zletest $'0o0\C-p' +0:Decrementing an octal integer to a negative value will fail +>BUFFER: 0o0 +>CURSOR: 3 + + zletest $'0x9\C-n' +0:Increment a hexadecimal integer +>BUFFER: 0xa +>CURSOR: 3 + + zletest $'0X9\C-n' +0:Increment a hexadecimal integer with an upper case prefix +>BUFFER: 0XA +>CURSOR: 3 + + zletest $'0xf\C-n' +0:Increment a hexadecimal integer with no numeric digit +>BUFFER: 0x10 +>CURSOR: 4 + + zletest $'0x10\C-p' +0:Decrement a hexadecimal integer +>BUFFER: 0xf +>CURSOR: 3 + + zletest $'0x0\C-p' +0:Decrementing an octal integer to a negative value will fail +>BUFFER: 0x0 +>CURSOR: 3 + + zletest $'0x0b1\C-n' +0:a number that starts with 0x0b is interpreted as a hexadecimal integer +>BUFFER: 0x0b2 +>CURSOR: 5 + + zletest $'10x9\e0\C-n' +0:[0-9]0x[0-9a-f] will become [0-9]1x[0-9a-f] when incremented from the left of x +>BUFFER: 11x9 +>CURSOR: 1 + + zletest $'10x9\eFx\C-n' +0:[0-9]0x[0-9a-f] will increment the hexadecimal 0x[0-9a-f] when the cursor is on x +>BUFFER: 10xa +>CURSOR: 3 + + zletest $'10x9\e\C-n' +0:[0-9]0x[0-9a-f] will increment the hexadecimal 0x[0-9a-f] when the cursor is on the right of x +>BUFFER: 10xa +>CURSOR: 3 + + zletest $'10b1\e0\C-n' +0:[0-9]0b[01] will become [0-9]1b[01] when incremented from the left of b +>BUFFER: 11b1 +>CURSOR: 1 + + zletest $'10b1\eFb\C-n' +0:[0-9]0b[01] will increment the binary 0b[01] when the cursor is on b +>BUFFER: 10b10 +>CURSOR: 4 + + zletest $'10b1\e\C-n' +0:[0-9]0b[01] will increment the binary 0b[01] when the cursor is on the right of b +>BUFFER: 10b10 +>CURSOR: 4 + + zletest $'10o7\e0\C-n' +0:[0-9]0o[0-7] will become [0-9]1o[0-7] when incremented from the left of o +>BUFFER: 11o7 +>CURSOR: 1 + + zletest $'10o7\eFo\C-n' +0:[0-9]0o[0-7] will increment the octal 0o[0-7] when the cursor is on o +>BUFFER: 10o10 +>CURSOR: 4 + + zletest $'10o7\e\C-n' +0:[0-9]0o[0-7] will increment the octal 0o[0-7] when the cursor is on the right of o +>BUFFER: 10o10 +>CURSOR: 4 + + zletest $'0b0x9\eF0\C-n' +0:0b0x[0-9a-f] will increment the binary 0b0 when the cursor is on the left of x +>BUFFER: 0b1x9 +>CURSOR: 2 + + zletest $'0b0x9\eFx\C-n' +0:0b0x[0-9a-f] will increment the hexadecimal 0x[0-9a-f] when the cursor is on top of x +>BUFFER: 0b0xa +>CURSOR: 4 + + zletest $'0b0x9\e\C-n' +0:0b0x[0-9a-f] will increment the hexadecimal 0x[0-9a-f] when the cursor is on the right of x +>BUFFER: 0b0xa +>CURSOR: 4 + + zletest $'echo 012ab\eF i\C-n' +0:incarg does nothing when the cursor is placed just to the left of an integer +>BUFFER: echo 012ab +>CURSOR: 4 + + zletest $'echo 012ab\eF0i\C-n' +0:incarg works when the cursor is placed at the leftmost digit of an integer +>BUFFER: echo 013ab +>CURSOR: 8 + + zletest $'echo 012ab\eF1i\C-n' +0:incarg works when the cursor is placed at the inner digit of an integer +>BUFFER: echo 013ab +>CURSOR: 8 + + zletest $'echo 012ab\eF2i\C-n' +0:incarg works when the cursor is placed at the rightmost digit of an integer +>BUFFER: echo 013ab +>CURSOR: 8 + + zletest $'echo 012ab\eFai\C-n' +0:incarg works when the cursor is placed just to the right of an integer +>BUFFER: echo 013ab +>CURSOR: 8 + + zletest $'echo 012ab\ei\C-n' +0:incarg does nothing when the cursor is placed more than a single letter away to the right +>BUFFER: echo 012ab +>CURSOR: 9 + + zletest $'echo 012ab\eF \C-n' +0:vim-incarg works when the cursor is placed to the left of an integer +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'echo 012ab\eF0\C-n' +0:vim-incarg works when the cursor is placed at the leftmost digit of an integer +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'echo 012ab\eF1\C-n' +0:vim-incarg works when the cursor is placed at the inner digit of an integer +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'echo 012ab\eF2\C-n' +0:incarg works when the cursor is placed at the rightmost digit of an integer +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'echo 012ab\eFa\C-n' +0:vim-incarg does nothing when the cursor is placed to the right of an integer +>BUFFER: echo 012ab +>CURSOR: 8 + + zletest $'echo 012ab\ei\C-n' +0:vim-incarg does nothing when the cursor is placed more than a single letter away to the right +>BUFFER: echo 012ab +>CURSOR: 9 + +%clean + + zmodload -ui zsh/zpty -- cgit v1.2.3 From 374051cae5fe304f1694ee0bf96b1fbb4fe2ae07 Mon Sep 17 00:00:00 2001 From: midchildan Date: Tue, 6 Feb 2024 01:16:01 +0900 Subject: 52523: fixes to preceding incarg patch --- Doc/Zsh/contrib.yo | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 718686587..ea00f0ccc 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -2633,7 +2633,7 @@ The behavior of this widget changes depending on the widget name. When the widget is named tt(incarg), the widget will increment an integer placed under the cursor placed or just to the left of it. tt(decarg), on the -other hand, decrements the integer. When the name is prefixed with tt(vim-), +other hand, decrements the integer. When the name is prefixed with tt(vi), the cursor will jump to the nearest integer after the cursor before incrementing it. @@ -2643,7 +2643,8 @@ synchronized key input. The first pane won't increment the integer at all, but each pane after that will have the integer incremented once more than the previous pane. It currently supports tmux and iTerm2. -The prefixes tt(vim-) and tt(sync-) can be combined into tt(vim-sync-). +The prefixes tt(vi) and tt(sync-) can be combined, for example, into +tt(vim-sync-). In this case, the tt(vi) prefix should come first. example(bindkey '^X+' incarg) ) -- cgit v1.2.3 From 74722b8d4ed20828950d396a523dcde1aa10b466 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Fri, 16 Feb 2024 08:42:42 +0100 Subject: 52546: incarg: avoid unneeded subshell --- ChangeLog | 4 ++++ Functions/Zle/incarg | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index faae11c80..e9bc0d9c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-02-16 Mikael Magnusson + + * 52546: Functions/Zle/incarg: incarg: avoid unneeded subshell + 2024-02-15 Oliver Kiddle * 52520: midchildan: Doc/Zsh/contrib.yo, Functions/Zle/incarg, diff --git a/Functions/Zle/incarg b/Functions/Zle/incarg index 1131b148b..9d56b21f6 100644 --- a/Functions/Zle/incarg +++ b/Functions/Zle/incarg @@ -214,8 +214,7 @@ case "$base" in esac local raw_result padded -raw_result="$( \ - printf "%0$ndigits$fmt1" $(( [$fmt2] "$base#$old" + delta )) 2> /dev/null)" +printf -v raw_result "%0$ndigits$fmt1" $(( [$fmt2] "$base#$old" + delta )) 2> /dev/null padded="${raw_result// /0}" integer oldnum="$base#$old" newnum="$base#$padded" 2> /dev/null -- cgit v1.2.3 From 8c59638522d8ed06cb962d41c11d1fade27abaa9 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 17 Feb 2024 20:27:56 -0800 Subject: 52556: fix crash when changing type of unset referent via named reference --- ChangeLog | 5 +++++ Src/builtin.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9bc0d9c5..11cc8dd6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-02-17 Bart Schaefer + + * 52556: Src/builtin.c: fix crash when applying a type change via + a named reference when the referent has been declared but unset + 2024-02-16 Mikael Magnusson * 52546: Functions/Zle/incarg: incarg: avoid unneeded subshell diff --git a/Src/builtin.c b/Src/builtin.c index 5c5adb9d3..dd352c146 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2031,8 +2031,10 @@ typeset_single(char *cname, char *pname, Param pm, int func, char *subscript; if (pm && (pm->node.flags & PM_NAMEREF) && !((off|on) & PM_NAMEREF)) { - if (!(off & PM_NAMEREF)) - pm = (Param)resolve_nameref(pm, NULL); + if (!(off & PM_NAMEREF)) { + if ((pm = (Param)resolve_nameref(pm, NULL))) + pname = pm->node.nam; + } if (pm && (pm->node.flags & PM_NAMEREF) && (on & ~(PM_NAMEREF|PM_LOCAL|PM_READONLY))) { /* Changing type of PM_SPECIAL|PM_AUTOLOAD is a fatal error. * -- cgit v1.2.3 From b3cad1c24cb588f5b0cbb617fe6f7fc0fade11af Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Sun, 18 Feb 2024 18:22:37 +0000 Subject: 52515: (+ tests in 52527) avoid sh errors when running shebang-less scripts with paths starting with - or + --- ChangeLog | 5 +++++ Src/exec.c | 17 +++++++++++++++-- Test/A05execution.ztst | 16 ++++++++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 11cc8dd6b..df94007fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-02-18 Stephane Chazelas + + * 52515: Src/exec.c (+ tests in 52527) avoid sh errors when + running shebang-less scripts with paths starting with - or + + 2024-02-17 Bart Schaefer * 52556: Src/builtin.c: fix crash when applying a type change via diff --git a/Src/exec.c b/Src/exec.c index 7d8135266..9c8bbb458 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -612,9 +612,22 @@ zexecve(char *pth, char **argv, char **newenvp) } } if (!isbinary) { - argv[-1] = "sh"; + char** args = argv; + if (argv[0][0] == '-' || argv[0][0] == '+') { + /* + * guard against +foo or -bar script paths being + * taken as options. POSIX says the script path + * must be passed as an *operand*. "--" would also + * make sure the next argument is treated as an + * operand with POSIX compliant sh implementations + * but "-" is more portable (to the Bourne shell in + * particular) and shorter. + */ + *--args = "-"; + } + *--args = "sh"; winch_unblock(); - execve("/bin/sh", argv - 1, newenvp); + execve("/bin/sh", args, newenvp); } } } else diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst index bcadc6d56..07a24f9c8 100644 --- a/Test/A05execution.ztst +++ b/Test/A05execution.ztst @@ -2,7 +2,7 @@ storepath=($path) - mkdir command.tmp command.tmp/dir1 command.tmp/dir2 + mkdir command.tmp command.tmp/dir{1,2} command.tmp/{+,-}dir cd command.tmp @@ -21,7 +21,10 @@ print '#!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxnyyy' >tstcmd-interp-too-long print "#!${sh}\necho should not execute; exit 1" >xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn - chmod 755 tstcmd dir1/tstcmd dir2/tstcmd + print 'echo no shebang in -dir' > -dir/tstcmd + print 'echo no shebang in +dir' > +dir/tstcmd + + chmod 755 tstcmd dir{1,2}/tstcmd ./{-,+}dir/tstcmd chmod 755 tstcmd-slashless tstcmd-arg tstcmd-interp-too-long chmod 755 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn @@ -422,3 +425,12 @@ F:anonymous function, and a descriptor leak when backgrounding a pipeline (exit 4); repeat 0 do done 0:'repeat 0' resets lastval + -dir/tstcmd + +dir/tstcmd + PATH=-dir tstcmd + PATH=+dir tstcmd +0:shebang-less scripts are to be run by sh even when their file paths start with - or + (workers/52515) +>no shebang in -dir +>no shebang in +dir +>no shebang in -dir +>no shebang in +dir -- cgit v1.2.3 From 00b12da9c08e6c41de5359d80dde28fce03bb2f7 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 18 Feb 2024 10:31:21 -0800 Subject: 52556: regression test for unset referent (left out of last commit) --- ChangeLog | 2 ++ Test/K01nameref.ztst | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 11cc8dd6b..94ebbef80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-02-17 Bart Schaefer + * 52556: Test/K01nameref.ztst: regression test for unset referent + * 52556: Src/builtin.c: fix crash when applying a type change via a named reference when the referent has been declared but unset diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index d8c098a98..ebb70dd92 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -64,6 +64,17 @@ F:Other type changes are fatal errors, should this also be? typeset -p ptr var 0:change type of referenced var >typeset -n ptr=var +>typeset -t var + + typeset var + unset var + typeset -n ptr=var + typeset -t ptr + typeset -p ptr var +0:change type of unset referenced var +F:regression - at one time this incorrectly applied the tag to "ptr" +F:note this causes "var" to become set +>typeset -n ptr=var >typeset -t var typeset -n ptr=var[2] -- cgit v1.2.3 From f1e7481b8690a6ef71a83853f05645cb774778ab Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Sun, 18 Feb 2024 18:52:50 +0000 Subject: 45837: fix process group restoration upon exit --- ChangeLog | 6 ++++++ Src/exec.c | 2 +- Src/init.c | 13 ++++++++----- Src/options.c | 7 ++++--- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9afb3e41c..cebc7c6ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-02-18 Stephane Chazelas + + * 45837: Src/exec.c, Src/init.c, Src/options.c: fix issue whereby + original process group is not restored properly upon exit when + exec {var} redirs are used or MONITOR is temporarily disabled. + 2024-02-18 Stephane Chazelas * 52515: Src/exec.c (+ tests in 52527) avoid sh errors when diff --git a/Src/exec.c b/Src/exec.c index 9c8bbb458..1565cb13e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -3768,7 +3768,7 @@ execcmd_exec(Estate state, Execcmd_params eparams, addfd(forked, save, mfds, fn->fd1, fil, 0, fn->varid); /* If this is 'exec < file', read from stdin, * * not terminal, unless `file' is a terminal. */ - if (nullexec == 1 && fn->fd1 == 0 && + if (nullexec == 1 && fn->fd1 == 0 && !fn->varid && isset(SHINSTDIN) && interact && !zleactive) init_io(NULL); break; diff --git a/Src/init.c b/Src/init.c index 799ad19f6..83b79d3d4 100644 --- a/Src/init.c +++ b/Src/init.c @@ -700,11 +700,14 @@ init_io(char *cmd) * process group leader. */ mypid = (zlong)getpid(); - if (opts[MONITOR] && (SHTTY != -1)) { - origpgrp = GETPGRP(); - acquire_pgrp(); /* might also clear opts[MONITOR] */ - } else - opts[MONITOR] = 0; + if (opts[MONITOR]) { + if (SHTTY == -1) + opts[MONITOR] = 0; + else if (!origpgrp) { + origpgrp = GETPGRP(); + acquire_pgrp(); /* might also clear opts[MONITOR] */ + } + } #else opts[MONITOR] = 0; #endif diff --git a/Src/options.c b/Src/options.c index a994b563e..a0e1aa024 100644 --- a/Src/options.c +++ b/Src/options.c @@ -881,11 +881,12 @@ dosetopt(int optno, int value, int force, char *new_opts) } else if (!force && optno == MONITOR && value) { if (new_opts[optno] == value) return 0; - if (SHTTY != -1) { + if (SHTTY == -1) + return -1; + if (!origpgrp) { origpgrp = GETPGRP(); acquire_pgrp(); - } else - return -1; + } #else } else if(optno == MONITOR && value) { return -1; -- cgit v1.2.3 From 336249e7eae1439a7d96e6aec413af1c78624859 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 18 Feb 2024 12:19:25 -0800 Subject: unposted: referent of named reference cannot start with digits This duplicates ksh behavior and doesn't change useful functionality. --- Src/params.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Src/params.c b/Src/params.c index a722a20f6..fce3af940 100644 --- a/Src/params.c +++ b/Src/params.c @@ -6348,6 +6348,8 @@ valid_refname(char *val) { char *t = itype_end(val, INAMESPC, 0); + if (idigit(*val)) + return 0; if (*t != 0) { if (*t == '[') { tokenize(t = dupstring(t+1)); -- cgit v1.2.3 From 4a86a54d2b17af3bd389e93810c10d0c39c20e92 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 18 Feb 2024 14:25:20 -0800 Subject: 52558: word splitting differences of nofork; update ToC; formatting fixes --- ChangeLog | 5 +++++ Etc/FAQ.yo | 60 ++++++++++++++++++++++++++++++++++++------------------------ 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index cebc7c6ba..f0e717370 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-02-18 Bart Schaefer + + * 52558: Etc/FAQ.yo: make note of word splitting differences + with nofork substitutions; update ToC; minor formatting fixes + 2024-02-18 Stephane Chazelas * 45837: Src/exec.c, Src/init.c, Src/options.c: fix issue whereby diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 7d46e9192..145ef02c9 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -101,6 +101,10 @@ Chapter 2: How does zsh differ from...? 2.6. Shouldn't zsh be more/less like ksh/(t)csh? 2.7. What is zsh's support for Unicode/UTF-8? 2.8. Why does my bash script report an error when I run it under zsh? +2.9. What is a `namespace' anyway? +2.10. What about named references? +2.11. What is zsh's support for non-forking command substitution? +2.12. Comparisons of forking and non-forking command substitution Chapter 3: How to get various things to work 3.1. Why does `$var' where `var="foo bar"' not do what I expect? @@ -1029,27 +1033,32 @@ label(211) This is for cases where you'd write mytt($(command)) but you don't want the overhead or other issues associated with forking a subshell. There are 3 variations: - enumeration( - myeit() Borrowed from mksh + itemization( + eit() Borrowed from mksh verb( ${| code } ) Runs code in the current shell context and then substitutes mytt(${REPLY}). + The result is not split into words unless the tt(SH_WORD_SPLIT) option + is set, for example by mytt(${=${| code }}). - myeit() An extension to #1 + eit() An extension to #1 verb( ${|var| code } ) - Runs code in the current shell and then substitutes mytt(${var}). + Runs code in the current shell and then substitutes mytt(${var}). If + mytt(${var}) names an array, the result is an array of those elements, + but no further splitting is done without tt(SH_WORD_SPLIT). - myeit() The traditional ksh form, except that the closing mytt(;) + eit() The traditional ksh form, except that the closing mytt(;) may usually be omitted: verb( ${ code } ) Runs code in the current shell and substitutes its standard output. (this is done with a temporary file ala mytt($(<=( code ))) but - without the fork implied by mytt(=(...))). + without the fork implied by mytt(=(...))). The result is not split + into words without tt(SH_WORD_SPLIT). ) In all three forms mytt(code) behaves myem(similarly) to an anonymous @@ -1079,31 +1088,34 @@ sect(Comparisons of forking and non-forking command substitution) when substituting, whereas mytt(${ command }) and its variants do not. The latter is consistent with mytt(${|...}) from mksh but differs from bash and ksh, so in emulation modes, newlines are stripped from command - output (not from mytt(REPLY) assignments). + output (not from tt(REPLY) assignments). + + When not enclosed in double quotes, the expansion of mytt($(command)) is + split on tt(IFS) into an array of words. In contrast, and unlike both + bash and ksh, unquoted non-forking substitutions behave like parameter + expansions with respect to the tt(SH_WORD_SPLIT) option. When mytt(command) is myem(not) a builtin, mytt(${ command }) does fork, and typically forks the same number of times as mytt($(command)), because in the latter case zsh usually optimizes the final fork into an exec. Redirecting input from files has subtle differences: - - mytt($(&1 >foo.out | bar)'?) to both files when the redirector appears twice. What's going on in the first example is exactly the same, however the second redirector is disguised as a pipe. So if you want to turn this effect off, you need - to unset the option mytt(MULTIOS), or alternatively write the following: + to unset the option tt(MULTIOS), or alternatively write the following: verb( % { print output; print error >&2 } 2>&1 >&- >foo.out | sed 's/error/erratic/' erratic -- cgit v1.2.3 From d2f63d0d92f17d935787e6b0d39d89fe591fa910 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 19 Feb 2024 08:50:27 +0900 Subject: * 52544: _diff_options: support macOS Ventura or newer --- ChangeLog | 5 +++++ Completion/Unix/Type/_diff_options | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f0e717370..4ed8e919d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-02-19 Jun-ichi Takimoto + + * 52544: Completion/Unix/Type/_diff_options: support macOS Ventura + or newer + 2024-02-18 Bart Schaefer * 52558: Etc/FAQ.yo: make note of word splitting differences diff --git a/Completion/Unix/Type/_diff_options b/Completion/Unix/Type/_diff_options index 45b777dfe..03ea1d7fe 100644 --- a/Completion/Unix/Type/_diff_options +++ b/Completion/Unix/Type/_diff_options @@ -25,7 +25,8 @@ _diff_palette() { return ret } -if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->.* ]]; then +if _pick_variant -r variant -c $cmd gnu=GNU unix -v || + [[ $OSTYPE = (freebsd<12->|darwin<22->).* ]]; then (( $#words > 2 )) && ign='!' # output formats @@ -73,15 +74,18 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12-> "($ofwl $ouc $oss)--unchanged-line-format=[set unchanged line format]:unchanged line format" '(--to-file)--from-file=[compare specified file to all operands]:from file:_files' '(--from-file)--to-file=[compare all operands to specified file]:to file:_files' - '--color=-[use colors in output]::when [auto]:(never always auto)' '--palette=[specify colors to use]:color:_diff_palette' "${ign}(1 2)-v[display version information]" ) else args+=( '!--speed-large-files' ) + if [[ $OSTYPE = darwin<22->.* ]]; then + args+=( '(-A --algorithm)'{-A+,--algorithm=}'[specify the algorithm to use]:algorithm:(myers patience stone)' ) + fi fi _arguments -s $args \ + '--color=-[use colors in output]::when [auto]:(never always auto)' \ '(-i --ignore-case)'{-i,--ignore-case}'[case insensitive]' \ '--ignore-file-name-case[ignore case when comparing file names]' \ '!(--ignore-file-name-case)--no-ignore-file-name-case' \ -- cgit v1.2.3 From a6ea12286709273e7896916dc8a107cd52f01d26 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 19 Feb 2024 11:10:04 +0000 Subject: 52549: document return works in a script --- ChangeLog | 7 ++++++- Doc/Zsh/builtins.yo | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ed8e919d..e3762340a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2024-02-19 Jun-ichi Takimoto +2024-02-19 Peter Stephenson + + * 52549: Doc/Zsh/builtins.yo: document that return already works + in a script. + +x2024-02-19 Jun-ichi Takimoto * 52544: Completion/Unix/Type/_diff_options: support macOS Ventura or newer diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 1aa807633..7a8654f27 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1649,7 +1649,9 @@ cindex(functions, returning from) item(tt(return) [ var(n) ])( Causes a shell function or `tt(.)' script to return to the invoking script with the return status specified by -an arithmetic expression var(n). +an arithmetic expression var(n). Also causes a non-interctive +shell to exit, allowing files containing shell code to be used +both as scripts and as autoloadable shell functions. For example, the following prints `tt(42)': example(() { integer foo=40; return "foo + 2" } -- cgit v1.2.3 From 6b21e5c0e201876f6659b563b56da9a993ae6c03 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 20 Feb 2024 20:16:03 -0800 Subject: 52559: revise "typeset -p" with respect to local readonly special parameters Update doc and tests to describe handling of global readonly specials and to account for side-effects on zsh/param/private. --- ChangeLog | 9 +++++++++ Doc/Zsh/builtins.yo | 8 ++++++++ Doc/Zsh/mod_private.yo | 7 ++++--- Src/Modules/param_private.c | 2 +- Src/params.c | 24 ++++++++++++++++++++++-- Test/B02typeset.ztst | 14 ++++++++++++++ Test/K01nameref.ztst | 4 ++-- Test/V10private.ztst | 13 +++++++++---- 8 files changed, 69 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3762340a..090644e8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2024-02-20 Bart Schaefer + + * 52559: Doc/Zsh/builtins.yo, Doc/Zsh/mod_private.yo, + Src/Modules/param_private.c, Src/params.c, Test/B02typeset.ztst, + Test/K01nameref.ztst, Test/V10private.ztst: revise "typeset -p" + with respect to local readonly special parameters; update doc + and tests to describe handling of global readonly specials and + to account for side-effects on zsh/param/private. + 2024-02-19 Peter Stephenson * 52549: Doc/Zsh/builtins.yo: document that return already works diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 7a8654f27..784089594 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2136,6 +2136,14 @@ tt(-p) may be followed by an optional integer argument. Currently only the value tt(1) is supported. In this case arrays and associative arrays are printed with newlines between indented elements for readability. + +The names and values of readonly special parameters +(most of the parameters marked `' in +ifzman(zmanref(zshparam))ifnzman(noderef(Parameters Set By The Shell)), +except those documented as settable) +are not printed with `tt(-)tt(p)' because to execute those typeset commands +would cause errors. However, these parameters are printed when they +have been made local to the scope where `tt(typeset -p)' is run. ) item(tt(-T) [ var(scalar)[tt(=)var(value)] var(array)[tt(=LPAR())var(value) ...tt(RPAR())] [ var(sep) ] ])( This flag has a different meaning when used with tt(-f); see below. diff --git a/Doc/Zsh/mod_private.yo b/Doc/Zsh/mod_private.yo index 08ac4cafe..24c099f38 100644 --- a/Doc/Zsh/mod_private.yo +++ b/Doc/Zsh/mod_private.yo @@ -16,9 +16,10 @@ The tt(private) builtin accepts all the same options and arguments as tt(local) (ifzman(zmanref(zshbuiltins))ifnzman(noderef(Shell Builtin Commands))) except for the `tt(-)tt(T)' option. Tied parameters may not be made private. -The `tt(-)tt(p)' option is presently a no-op because the state of -private parameters cannot reliably be reloaded. This also applies -to printing private parameters with `tt(typeset -p)'. +The `tt(-)tt(p)' option is presently disabled because the state of +private parameters cannot reliably be reloaded. When `tt(typeset -)tt(p)' +outputs a private parameter, it is treated as a local with the +`tt(-)tt(h)' (hide) option enabled. If used at the top level (outside a function scope), tt(private) creates a normal parameter in the same manner as tt(declare) or tt(typeset). A diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index 5003d4627..044617190 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -646,7 +646,7 @@ printprivatenode(HashNode hn, int printflags) static struct builtin bintab[] = { /* Copied from BUILTIN("local"), "P" added */ - BUILTIN("private", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_private, 0, -1, 0, "AE:%F:%HL:%PR:%TUZ:%ahi:%lnmprtux", "P") + BUILTIN("private", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_private, 0, -1, 0, "AE:%F:%HL:%PR:%TUZ:%ahi:%lnmrtux", "P") }; static struct features module_features = { diff --git a/Src/params.c b/Src/params.c index fce3af940..b329d2079 100644 --- a/Src/params.c +++ b/Src/params.c @@ -5896,6 +5896,7 @@ static const struct paramtypes pmtypes[] = { { PM_ARRAY, "array", 'a', 0}, { PM_HASHED, "association", 'A', 0}, { 0, "local", 0, PMTF_TEST_LEVEL}, + { PM_HIDE, "hide", 'h', 0 }, { PM_LEFT, "left justified", 'L', PMTF_USE_WIDTH}, { PM_RIGHT_B, "right justified", 'R', PMTF_USE_WIDTH}, { PM_RIGHT_Z, "zero filled", 'Z', PMTF_USE_WIDTH}, @@ -6025,13 +6026,21 @@ printparamnode(HashNode hn, int printflags) printflags |= PRINT_NAMEONLY; if (printflags & (PRINT_TYPESET|PRINT_POSIX_READONLY|PRINT_POSIX_EXPORT)) { - if (p->node.flags & (PM_RO_BY_DESIGN|PM_AUTOLOAD)) { + if (p->node.flags & PM_AUTOLOAD) { /* * It's not possible to restore the state of * these, so don't output. */ return; } + if (p->node.flags & PM_RO_BY_DESIGN) { + /* + * Compromise: cannot be restored out of context, + * but show anyway if printed in scope of declaration + */ + if (p->level != locallevel || p->level == 0) + return; + } /* * The zsh variants of export -p/readonly -p also report other * flags to indicate other attributes or scope. The POSIX variants @@ -6064,8 +6073,19 @@ printparamnode(HashNode hn, int printflags) for (pmptr = pmtypes, i = 0; i < PMTYPES_SIZE; i++, pmptr++) { int doprint = 0; if (pmptr->flags & PMTF_TEST_LEVEL) { - if (p->level) + if (p->level) { + /* + if ((p->node.flags & PM_SPECIAL) && + (p->node.flags & PM_LOCAL) && + !(p->node.flags & PM_HIDE)) { + if (doneminus) + putchar(' '); + printf("+h "); + doneminus = 0; + } + */ doprint = 1; + } } else if ((pmptr->binflag != PM_EXPORTED || p->level || (p->node.flags & (PM_LOCAL|PM_ARRAY|PM_HASHED))) && (p->node.flags & pmptr->binflag)) diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index 8b3988151..d90f17d13 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -959,6 +959,20 @@ > [three]='' >) + () { + local -h status + typeset -p status + } +0:parameter hiding preserved by "typeset -p" +>typeset -h status='' + + () { + local status + typeset -p status + } +0:read-only special params are output when localized +>typeset -i10 -r status=0 + (export PATH MANPATH path=(/bin) MANPATH=/ diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index ebb70dd92..ff48e2289 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -464,7 +464,7 @@ F:unexpected side-effects of previous tests } 0:up-reference part 3, hidden global >outside ->typeset var +>typeset -h var () { typeset notdef @@ -541,7 +541,7 @@ F:Same test, should part 5 output look like this? fi 0:up-reference part 3, autoloading with hidden special >nameref-local-nameref-local ->typeset parameters +>typeset -h parameters if [[ $options[typesettounset] != on ]]; then ZTST_skip='Ignoring zmodload bug that resets TYPESET_TO_UNSET' diff --git a/Test/V10private.ztst b/Test/V10private.ztst index 9eeda0f47..4140d4e96 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -28,7 +28,7 @@ print $scalar_test 0:basic scope hiding >toplevel ->local scalar_test +>local hide scalar_test >0 >toplevel @@ -54,7 +54,7 @@ print $+unset_test 0:variable defined only in scope >0 ->local unset_test +>local hide unset_test >setme >0 @@ -70,7 +70,7 @@ } print $array_test 0:nested scope with different type, correctly restored ->local array_test +>local hide array_test >in function >top level @@ -113,7 +113,7 @@ typeset -a hash_test=(top level) typeset -p hash_test inner () { - private -p hash_test + typeset -p hash_test print ${(t)hash_test} ${(kv)hash_test} } outer () { @@ -328,6 +328,7 @@ F:future revision will create a global with this assignment F:See K01nameref.ztst up-reference part 5 F:Here ptr1 finds private ptr2 by scope mismatch >typeset -n ptr1=ptr2 +>typeset -hn ptr2 *?*read-only variable: ptr2 () { @@ -348,10 +349,12 @@ F:See K01nameref.ztst up-reference part 5 F:Here ptr1 finds private ptr2 by scope mismatch F:Assignment silently fails, is that correct? >typeset -n ptr1=ptr2 +>typeset -hn ptr2='' >ptr1=ptr2 >ptr1= >ptr2= >typeset -n ptr1=ptr2 +>typeset -hn ptr2='' *?*no such variable: ptr2 typeset ptr2 @@ -372,11 +375,13 @@ F:Assignment silently fails, is that correct? F:See K01typeset.ztst up-reference part 5 F:Here ptr1 points to global ptr2 so assignment succeeds >typeset -n ptr1=ptr2 +>typeset -hn ptr2 >ptr1=ptr2 >ptr2=val >ptr1=val >ptr2=val >typeset -n ptr1=ptr2 +>typeset -hn ptr2 >typeset ptr2=val () { -- cgit v1.2.3 From 40d5200c8b882708ecd411bd88760e20deec82fd Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 22 Feb 2024 19:07:01 +0100 Subject: 52552: newer Java supports passing source files directly to java --- ChangeLog | 5 +++++ Completion/Unix/Command/_java | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 090644e8b..91503f01d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-02-22 Oliver Kiddle + + * 52552: Completion/Unix/Command/_java: newer Java supports + passing source files directly to java + 2024-02-20 Bart Schaefer * 52559: Doc/Zsh/builtins.yo, Doc/Zsh/mod_private.yo, diff --git a/Completion/Unix/Command/_java b/Completion/Unix/Command/_java index b2352df7b..325413d87 100644 --- a/Completion/Unix/Command/_java +++ b/Completion/Unix/Command/_java @@ -82,7 +82,10 @@ java) '(- 1)-X-[non-standard java option]:option' \ '(- 1)-jar[specify a program encapsulated as jar]:jar:_files -g \*.jar\(-.\)' \ '-splash\:-[show splash screen with specified image]:image:_files' \ - '(-):class:_java_class -m main ${(kv)opt_args[(i)(-classpath|-cp)]}' \ + '--source=[set the version of the source in source-file mode]:version' \ + '(-):arg: _alternative + "classes\:class\:{ (( ! $+opt_args[--source] )) && _java_class -m main ${(kv)opt_args[(i)(-classpath|-cp)]} }" + "files\:source file\:_files -g \*.java\(-.\)"' \ '*::args:= _normal' \ && return 0 ;; -- cgit v1.2.3 From 4b9cd6b8bd5f67500e716f8485aebd31a9f7cf47 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 23 Feb 2024 09:51:06 -0800 Subject: 52583: extra check for proper scope and existence of readonly specials --- ChangeLog | 6 ++++++ Src/params.c | 25 +++++++++++++++++++++++-- Test/V10private.ztst | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91503f01d..d520ec8c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-02-23 Bart Schaefer + + * 52583: Src/params.c, Test/V10private.ztst: do an extra check + for proper scope and parameter existence when assigning to a + non-local name that resolves to a readonly special. + 2024-02-22 Oliver Kiddle * 52552: Completion/Unix/Command/_java: newer Java supports diff --git a/Src/params.c b/Src/params.c index b329d2079..225acb8a1 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1004,8 +1004,29 @@ createparam(char *name, int flags) gethashnode2(paramtab, name) : paramtab->getnode(paramtab, name)); - if (oldpm && (oldpm->node.flags & PM_NAMEREF) && - !(flags & PM_NAMEREF) && (oldpm = upscope(oldpm, oldpm->base))) { + if (oldpm && (oldpm->node.flags & PM_RO_BY_DESIGN)) { + if (!(flags & PM_LOCAL)) { + /* Must call the API for namerefs and specials to work */ + pm = (Param) paramtab->getnode2(paramtab, oldpm->node.nam); + if (!pm || ((pm->node.flags & PM_NAMEREF) && + pm->level != locallevel)) { + zerr("%s: can't modify read-only parameter", name); + return NULL; + } + } + /** + * Implementation note: In the case of a readonly nameref, + * the right thing might be to insert a new global into + * the paramtab and point the local pm->old at it, rather + * than error. That is why gethashnode2() is called + * first, to avoid skipping up the stack prematurely. + **/ + } + + if (oldpm && !(flags & PM_NAMEREF) && + (!(oldpm->node.flags & PM_RO_BY_DESIGN) || !(flags & PM_LOCAL)) && + (oldpm->node.flags & PM_NAMEREF) && + (oldpm = upscope(oldpm, oldpm->base))) { Param lastpm; struct asgment stop; stop.flags = PM_NAMEREF | (flags & PM_LOCAL); diff --git a/Test/V10private.ztst b/Test/V10private.ztst index 4140d4e96..efa346002 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -311,6 +311,47 @@ F:future revision will create a global with this assignment >TOP >UP: + () { + typeset -a ary + local -P -n ref=ary + { + (){ + ref=XX # Should be an error + typeset -p ary ref + } + } always { + TRY_BLOCK_ERROR=0 + typeset -p ary ref + } + } + typeset -p ary +1:assignment to private nameref in wrong scope, part 1 +>typeset -a ary +>typeset -hn ref=ary +*?*ref: can't modify read-only parameter +*?*no such variable: ary + + () { + typeset -a ary + local -P -n ref=ary + { + (){ + typeset ref=XX # Should create a local + typeset -p ary ref + } + } always { + TRY_BLOCK_ERROR=0 + typeset -p ary ref + } + } + typeset -p ary +1:assignment to private nameref in wrong scope, part 2 +>typeset -g -a ary +>typeset ref=XX +>typeset -a ary +>typeset -hn ref=ary +*?*no such variable: ary + () { typeset -n ptr1=ptr2 private -n ptr2 # TYPESET_TO_UNSET makes this not a "placeholder" -- cgit v1.2.3 From 4c0ebc155ebab1e2babda2a218cba1131cf74109 Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Sat, 24 Feb 2024 20:41:33 -0800 Subject: 52591: printf builtin must pass metafied strings to math evaluation --- ChangeLog | 5 +++++ Src/builtin.c | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d520ec8c5..00a3c65ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-02-24 Bart Schaefer + + * Stephane: 52591: Src/builtin.c: printf builtin must pass + metafied strings to math evaluation + 2024-02-23 Bart Schaefer * 52583: Src/params.c, Test/V10private.ztst: do an extra check diff --git a/Src/builtin.c b/Src/builtin.c index dd352c146..f72d14da4 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5247,7 +5247,8 @@ bin_print(char *name, char **args, Options ops, int func) } } if (*argp) { - width = (int)mathevali(*argp++); + width = (int)mathevali(metafy(*argp, len[argp - args], META_USEHEAP)); + argp++; if (errflag) { errflag &= ~ERRFLAG_ERROR; ret = 1; @@ -5281,7 +5282,8 @@ bin_print(char *name, char **args, Options ops, int func) } if (*argp) { - prec = (int)mathevali(*argp++); + prec = (int)mathevali(metafy(*argp, len[argp - args], META_USEHEAP)); + argp++; if (errflag) { errflag &= ~ERRFLAG_ERROR; ret = 1; @@ -5465,7 +5467,7 @@ bin_print(char *name, char **args, Options ops, int func) *d++ = 'l'; #endif *d++ = 'l', *d++ = *c, *d = '\0'; - zlongval = (curarg) ? mathevali(curarg) : 0; + zlongval = (curarg) ? mathevali(metafy(curarg, curlen, META_HEAPDUP)) : 0; if (errflag) { zlongval = 0; errflag &= ~ERRFLAG_ERROR; @@ -5516,7 +5518,7 @@ bin_print(char *name, char **args, Options ops, int func) if (!curarg) zulongval = (zulong)0; else if (!zstrtoul_underscore(curarg, &zulongval)) - zulongval = mathevali(curarg); + zulongval = mathevali(metafy(curarg, curlen, META_HEAPDUP)); if (errflag) { zulongval = 0; errflag &= ~ERRFLAG_ERROR; -- cgit v1.2.3 From 69c0c646bbabb1caaeb62242e9323a62bf3cd57a Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 24 Feb 2024 20:45:29 -0800 Subject: 52596: metafy interpreter name for error message --- ChangeLog | 2 ++ Src/exec.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00a3c65ab..9f7289cea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-02-24 Bart Schaefer + * 52596: Src/exec.c: metafy interpreter name for error message + * Stephane: 52591: Src/builtin.c: printf builtin must pass metafied strings to math evaluation diff --git a/Src/exec.c b/Src/exec.c index 1565cb13e..c75aa78d6 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -551,7 +551,7 @@ zexecve(char *pth, char **argv, char **newenvp) break; if (t0 == ct) zerr("%s: bad interpreter: %s: %e", pth, - execvebuf + 2, eno); + metafy(execvebuf + 2, -1, META_NOALLOC), eno); else { while (inblank(execvebuf[t0])) execvebuf[t0--] = '\0'; @@ -574,8 +574,8 @@ zexecve(char *pth, char **argv, char **newenvp) execve(pprog, argv - 2, newenvp); } } - zerr("%s: bad interpreter: %s: %e", pth, ptr2, - eno); + zerr("%s: bad interpreter: %s: %e", pth, + metafy(ptr2, -1, META_NOALLOC), eno); } else if (*ptr) { *ptr = '\0'; argv[-2] = ptr2; -- cgit v1.2.3 From 6c50d155625d83bde35dc78bc6920c9795462d58 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 24 Feb 2024 21:16:15 -0800 Subject: 52597: fix character counts in context of operator and operand errors --- ChangeLog | 3 +++ Src/math.c | 25 ++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9f7289cea..684820f92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-24 Bart Schaefer + * 52597: Src/math.c: fix multibyte and metafied character counts + when providing context for operator and operand errors + * 52596: Src/exec.c: metafy interpreter name for error message * Stephane: 52591: Src/builtin.c: printf builtin must pass diff --git a/Src/math.c b/Src/math.c index 50b69d6a1..d97dae238 100644 --- a/Src/math.c +++ b/Src/math.c @@ -1557,21 +1557,32 @@ checkunary(int mtokc, char *mptr) errmsg = 2; } if (errmsg) { - int len, over = 0; + int len = 0, over = 0; char *errtype = errmsg == 2 ? "operator" : "operand"; while (inblank(*mptr)) mptr++; - len = ztrlen(mptr); - if (len > 10) { - len = 10; - over = 1; + if (isset(MULTIBYTE)) + MB_CHARINIT(); + while (over < 10 && mptr[len]) { + if (isset(MULTIBYTE)) + len += MB_METACHARLEN(mptr+len); + else + len += (mptr[len] == Meta ? 2 : 1); + ++over; + } + if ((over = mptr[len])) { + mptr = dupstring(mptr); + if (mptr[len] == Meta) + mptr[len+1] = 0; + else + mptr[len] = 0; } if (!*mptr) zerr("bad math expression: %s expected at end of string", errtype); else - zerr("bad math expression: %s expected at `%l%s'", - errtype, mptr, len, over ? "..." : ""); + zerr("bad math expression: %s expected at `%s%s'", + errtype, mptr, over ? "..." : ""); } unary = !(tp & OP_OPF); } -- cgit v1.2.3 From b68002d927b1577bbed453d7bbbe39b55acf7bd0 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 24 Feb 2024 21:28:35 -0800 Subject: Fix META_NOALLOC to META_STATIC in 'bad interpreter' metafy --- Src/exec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/exec.c b/Src/exec.c index c75aa78d6..0750738ce 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -551,7 +551,7 @@ zexecve(char *pth, char **argv, char **newenvp) break; if (t0 == ct) zerr("%s: bad interpreter: %s: %e", pth, - metafy(execvebuf + 2, -1, META_NOALLOC), eno); + metafy(execvebuf + 2, -1, META_STATIC), eno); else { while (inblank(execvebuf[t0])) execvebuf[t0--] = '\0'; @@ -575,7 +575,7 @@ zexecve(char *pth, char **argv, char **newenvp) } } zerr("%s: bad interpreter: %s: %e", pth, - metafy(ptr2, -1, META_NOALLOC), eno); + metafy(ptr2, -1, META_STATIC), eno); } else if (*ptr) { *ptr = '\0'; argv[-2] = ptr2; -- cgit v1.2.3 From 5331ff11c64d9d292f4fe817723af6e0a067fa1f Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 28 Feb 2024 00:21:11 +0100 Subject: 52594: support for POSIX real-time signals with kill and trap Also add new -L option to kill for a more verbose listing of signals --- ChangeLog | 9 ++++ Completion/Zsh/Command/_kill | 9 ++-- Doc/Zsh/builtins.yo | 6 ++- Doc/Zsh/params.yo | 5 +- Src/Modules/parameter.c | 2 +- Src/builtin.c | 30 ++++++------ Src/exec.c | 2 +- Src/hashtable.c | 20 ++++---- Src/init.c | 3 ++ Src/jobs.c | 113 +++++++++++++++++++++++++++++++++++++------ Src/params.c | 14 +++++- Src/signals.c | 84 +++++++++++++++++++++++++++++--- Src/signals.h | 9 ++++ Src/signames2.awk | 6 +-- 14 files changed, 249 insertions(+), 63 deletions(-) diff --git a/ChangeLog b/ChangeLog index 684820f92..53038c221 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2024-02-28 Oliver Kiddle + + * 52594: Completion/Zsh/Command/_kill, Doc/Zsh/builtins.yo, + Doc/Zsh/params.yo, Src/Modules/parameter.c, Src/builtin.c, + Src/exec.c, Src/hashtable.c, Src/init.c, Src/jobs.c, Src/params.c, + Src/signals.c, Src/signals.h, Src/signames2.awk: support for + POSIX real-time signals with kill and trap and add -L option to + kill for more verbose listing of signals + 2024-02-24 Bart Schaefer * 52597: Src/math.c: fix multibyte and metafied character counts diff --git a/Completion/Zsh/Command/_kill b/Completion/Zsh/Command/_kill index 084cf42c8..3b5c02151 100644 --- a/Completion/Zsh/Command/_kill +++ b/Completion/Zsh/Command/_kill @@ -4,10 +4,11 @@ local curcontext="$curcontext" line state ret=1 typeset -A opt_args _arguments -C \ - '(-s -l 1)-n[specify signal number]:signal number' \ - '(-l)-q[send the specified integer with the signal using sigqueue]:value' \ - '(-n -l 1)-s[specify signal name]:signal:_signals -s' \ - '(-n -s)-l[list signal names or numbers of specified signals]:*:signal:_signals' \ + '(-s -l -L 1)-n[specify signal number]:signal number' \ + '(-l -L)-q[send the specified integer with the signal using sigqueue]:value' \ + '(-n -l -L 1)-s[specify signal name]:signal:_signals -s' \ + '-l[list signal names or numbers of specified signals]:*:signal:_signals' \ + '(- *)-L[list each signal and corresponding number]' \ '(-n -s -l)1::signal:_signals -p -s' \ '*:processes:->processes' && ret=0 diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 784089594..6318053d8 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1144,7 +1144,8 @@ cindex(killing jobs) cindex(jobs, killing) xitem(tt(kill) [ tt(-s) var(signal_name) | tt(-n) var(signal_number) | \ tt(-)var(sig) ] [ tt(-q) var(value) ] var(job) ...) -item(tt(kill) tt(-l) [ var(sig) ... ])( +xitem(tt(kill) tt(-l) [ var(sig) ... ]) +item(tt(kill) tt(-L))( Sends either tt(SIGTERM) or the specified signal to the given jobs or processes. Signals are given by number or by names, with or without the `tt(SIG)' @@ -1158,7 +1159,8 @@ specified the signal names are listed. Otherwise, for each var(sig) that is a name, the corresponding signal number is listed. For each var(sig) that is a signal number or a number representing the exit status of a process which was terminated or -stopped by a signal the name of the signal is printed. +stopped by a signal the name of the signal is printed. The final +form with tt(-L) lists each signal name with its corresponding number. On some systems, alternative signal names are allowed for a few signals. Typical examples are tt(SIGCHLD) and tt(SIGCLD) or tt(SIGPOLL) and diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index a6fbe6723..8c5e67e70 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -953,7 +953,10 @@ has index 1, the signals are offset by 1 from the signal number used by the operating system. For example, on typical Unix-like systems tt(HUP) is signal number 1, but is referred to as tt($signals[2]). This is because of tt(EXIT) at position 1 in the array, which is used -internally by zsh but is not known to the operating system. +internally by zsh but is not known to the operating system. On many systems +there is a block of reserved or unused signal numbers before the POSIX +real-time signals so the array index can't be used as an accurate indicator +of their signal number. Use, for example, tt(kill -l SIGRTMIN) instead. ) vindex(TRY_BLOCK_ERROR) item(tt(TRY_BLOCK_ERROR) )( diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index a05ea2fe4..7441c30b8 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -309,7 +309,7 @@ setfunction(char *name, char *val, int dis) shfunc_set_sticky(shf); if (!strncmp(name, "TRAP", 4) && - (sn = getsignum(name + 4)) != -1) { + (sn = getsigidx(name + 4)) != -1) { if (settrap(sn, NULL, ZSIG_FUNC)) { freeeprog(shf->funcdef); zfree(shf, sizeof(*shf)); diff --git a/Src/builtin.c b/Src/builtin.c index f72d14da4..44dfed651 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3425,16 +3425,16 @@ bin_functions(char *name, char **argv, Options ops, int func) newsh->sticky = sticky_emulation_dup(shf->sticky, 0); /* is newsh a signal trap? (adapted from exec.c) */ if (!strncmp(s, "TRAP", 4)) { - int signum = getsignum(s + 4); - if (signum != -1) { - if (settrap(signum, NULL, ZSIG_FUNC)) { + int sigidx = getsigidx(s + 4); + if (sigidx != -1) { + if (settrap(sigidx, NULL, ZSIG_FUNC)) { freeeprog(newsh->funcdef); dircache_set(&newsh->filename, NULL); zfree(newsh, sizeof(*newsh)); return 1; } /* Remove any old node explicitly */ - removetrapnode(signum); + removetrapnode(sigidx); } } shfunctab->addnode(shfunctab, ztrdup(s), &newsh->node); @@ -3713,15 +3713,15 @@ bin_functions(char *name, char **argv, Options ops, int func) /* no flags, so just print */ printshfuncexpand(&shf->node, pflags, expand); } else if (on & PM_UNDEFINED) { - int signum = -1, ok = 1; + int sigidx = -1, ok = 1; if (!strncmp(*argv, "TRAP", 4) && - (signum = getsignum(*argv + 4)) != -1) { + (sigidx = getsigidx(*argv + 4)) != -1) { /* * Because of the possibility of alternative names, * we must remove the trap explicitly. */ - removetrapnode(signum); + removetrapnode(sigidx); } if (**argv == '/') { @@ -3757,8 +3757,8 @@ bin_functions(char *name, char **argv, Options ops, int func) shfunc_set_sticky(shf); add_autoload_function(shf, *argv); - if (signum != -1) { - if (settrap(signum, NULL, ZSIG_FUNC)) { + if (sigidx != -1) { + if (settrap(sigidx, NULL, ZSIG_FUNC)) { shfunctab->removenode(shfunctab, *argv); shfunctab->freenode(&shf->node); returnval = 1; @@ -7346,7 +7346,7 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) /* If given no arguments, list all currently-set traps */ if (!*argv) { queue_signals(); - for (sig = 0; sig < VSIGCOUNT; sig++) { + for (sig = 0; sig < TRAPCOUNT; sig++) { if (sigtrapped[sig] & ZSIG_FUNC) { HashNode hn; @@ -7372,13 +7372,13 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) /* If we have a signal number, unset the specified * * signals. With only -, remove all traps. */ - if ((getsignum(*argv) != -1) || (!strcmp(*argv, "-") && argv++)) { + if ((getsigidx(*argv) != -1) || (!strcmp(*argv, "-") && argv++)) { if (!*argv) { - for (sig = 0; sig < VSIGCOUNT; sig++) + for (sig = 0; sig < TRAPCOUNT; sig++) unsettrap(sig); } else { for (; *argv; argv++) { - sig = getsignum(*argv); + sig = getsigidx(*argv); if (sig == -1) { zwarnnam(name, "undefined signal: %s", *argv); break; @@ -7403,12 +7403,12 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) Eprog t; int flags; - sig = getsignum(*argv); + sig = getsigidx(*argv); if (sig == -1) { zwarnnam(name, "undefined signal: %s", *argv); break; } - if (idigit(**argv) || + if (idigit(**argv) || (sig >= VSIGCOUNT) || !strcmp(sigs[sig], *argv) || (!strncmp("SIG", *argv, 3) && !strcmp(sigs[sig], *argv+3))) { /* The signal was specified by number or by canonical name (with diff --git a/Src/exec.c b/Src/exec.c index 0750738ce..d85adbea5 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5427,7 +5427,7 @@ execfuncdef(Estate state, Eprog redir_prog) } else { /* is this shell function a signal trap? */ if (!strncmp(s, "TRAP", 4) && - (signum = getsignum(s + 4)) != -1) { + (signum = getsigidx(s + 4)) != -1) { if (settrap(signum, NULL, ZSIG_FUNC)) { freeeprog(shf->funcdef); dircache_set(&shf->filename, NULL); diff --git a/Src/hashtable.c b/Src/hashtable.c index bb165505e..75b06c4ad 100644 --- a/Src/hashtable.c +++ b/Src/hashtable.c @@ -836,10 +836,10 @@ static HashNode removeshfuncnode(UNUSED(HashTable ht), const char *nam) { HashNode hn; - int signum; + int sigidx; - if (!strncmp(nam, "TRAP", 4) && (signum = getsignum(nam + 4)) != -1) - hn = removetrap(signum); + if (!strncmp(nam, "TRAP", 4) && (sigidx = getsigidx(nam + 4)) != -1) + hn = removetrap(sigidx); else hn = removehashnode(shfunctab, nam); @@ -856,10 +856,10 @@ disableshfuncnode(HashNode hn, UNUSED(int flags)) { hn->flags |= DISABLED; if (!strncmp(hn->nam, "TRAP", 4)) { - int signum = getsignum(hn->nam + 4); - if (signum != -1) { - sigtrapped[signum] &= ~ZSIG_FUNC; - unsettrap(signum); + int sigidx = getsigidx(hn->nam + 4); + if (sigidx != -1) { + sigtrapped[sigidx] &= ~ZSIG_FUNC; + unsettrap(sigidx); } } } @@ -876,9 +876,9 @@ enableshfuncnode(HashNode hn, UNUSED(int flags)) shf->node.flags &= ~DISABLED; if (!strncmp(shf->node.nam, "TRAP", 4)) { - int signum = getsignum(shf->node.nam + 4); - if (signum != -1) { - settrap(signum, NULL, ZSIG_FUNC); + int sigidx = getsigidx(shf->node.nam + 4); + if (sigidx != -1) { + settrap(sigidx, NULL, ZSIG_FUNC); } } } diff --git a/Src/init.c b/Src/init.c index 83b79d3d4..ec21521b1 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1382,6 +1382,9 @@ setupshin(char *runscript) void init_signals(void) { + sigtrapped = (int *) hcalloc(TRAPCOUNT * sizeof(int)); + siglists = (Eprog *) hcalloc(TRAPCOUNT * sizeof(Eprog)); + if (interact) { int i; signal_setmask(signal_mask(0)); diff --git a/Src/jobs.c b/Src/jobs.c index 118c5e61b..49decc661 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1073,6 +1073,21 @@ should_report_time(Job j) return 0; } +/**/ +char * +sigmsg(int sig) +{ + static char *unknown = "unknown signal"; +#if defined(SIGRTMIN) && defined(SIGRTMAX) + static char rtmsg[] = "real-time event XXX"; + if (sig >= SIGRTMIN && sig <= SIGRTMAX) { + sprintf(rtmsg + sizeof(rtmsg) - 4, "%u", sig - SIGRTMIN + 1); + return rtmsg; + } +#endif + return sig <= SIGCOUNT ? sig_msg[sig] : unknown; +} + /* !(lng & 3) means jobs * * (lng & 1) means jobs -l * * (lng & 2) means jobs -p @@ -2694,7 +2709,7 @@ static const struct { int bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) { - int sig = SIGTERM; + int status, sig = SIGTERM; int returnval = 0; #ifdef HAVE_SIGQUEUE union sigval sigqueue_info; @@ -2740,23 +2755,29 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) if ((*argv)[1] == 'l' && (*argv)[2] == '\0') { if (argv[1]) { while (*++argv) { - sig = zstrtol(*argv, &signame, 10); + status = zstrtol(*argv, &signame, 10); if (signame == *argv) { + signame = casemodify(signame, CASMOD_UPPER); if (!strncmp(signame, "SIG", 3)) signame += 3; for (sig = 1; sig <= SIGCOUNT; sig++) - if (!strcasecmp(sigs[sig], signame)) + if (!strcmp(sigs[sig], signame)) break; if (sig > SIGCOUNT) { int i; for (i = 0; alt_sigs[i].name; i++) - if (!strcasecmp(alt_sigs[i].name, signame)) + if (!strcmp(alt_sigs[i].name, signame)) { sig = alt_sigs[i].num; break; } } +#if defined(SIGRTMIN) && defined(SIGRTMAX) + if (sig > SIGCOUNT && (sig = rtsigno(signame))) { + printf("%d\n", sig); + } else +#endif if (sig > SIGCOUNT) { zwarnnam(nam, "unknown signal: SIG%s", signame); @@ -2769,14 +2790,15 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) signame); returnval++; } else { - if (WIFSIGNALED(sig)) - sig = WTERMSIG(sig); - else if (WIFSTOPPED(sig)) - sig = WSTOPSIG(sig); + sig = status & ~0200; if (1 <= sig && sig <= SIGCOUNT) printf("%s\n", sigs[sig]); +#if defined(SIGRTMIN) && defined(SIGRTMAX) + else if ((signame = rtsigname(sig, 0))) + printf("%s\n", signame); +#endif else - printf("%d\n", sig); + printf("%d\n", status); } } } @@ -2785,10 +2807,42 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) printf("%s", sigs[1]); for (sig = 2; sig <= SIGCOUNT; sig++) printf(" %s", sigs[sig]); +#if defined(SIGRTMIN) && defined(SIGRTMAX) + for (sig = SIGRTMIN; sig <= SIGRTMAX; sig++) + printf(" %s", rtsigname(sig, 0)); +#endif putchar('\n'); return 0; } + /* with argument "-L" list signals with their numbers in a table */ + if ((*argv)[1] == 'L' && (*argv)[2] == '\0') { +#if defined(SIGRTMIN) && defined(SIGRTMAX) + const int width = SIGRTMAX >= 100 ? 3 : 2; +#else + const int width = SIGCOUNT >= 100 ? 3 : 2; +#endif + for (sig = 1; sig < SIGCOUNT +#if defined(SIGRTMIN) && defined(SIGRTMAX) + + 1 +#endif + ; sig++) + { + printf("%*d) %-10s%c", width, sig, sigs[sig], + sig % 5 ? ' ' : '\n'); + } +#if defined(SIGRTMIN) && defined(SIGRTMAX) + for (sig = SIGRTMIN; sig < SIGRTMAX; sig++) { + printf("%*d) %-10s%c", width, sig, rtsigname(sig, 0), + (sig - SIGRTMIN + SIGCOUNT + 1) % 5 ? ' ' : '\n'); + } + printf("%*d) RTMAX\n", width, sig); +#else + printf("%*d) %s\n", width, sig, sigs[sig]); +#endif + return 0; + } + if ((*argv)[1] == 'n' && (*argv)[2] == '\0') { char *endp; @@ -2833,9 +2887,13 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) break; } } - if (sig > SIGCOUNT) { + if (sig > SIGCOUNT +#if defined(SIGRTMIN) && defined(SIGRTMAX) + && !(sig = rtsigno(signame)) +#endif + ) { zwarnnam(nam, "unknown signal: SIG%s", signame); - zwarnnam(nam, "type kill -l for a list of signals"); + zwarnnam(nam, "type kill -L for a list of signals"); return 1; } } @@ -2916,18 +2974,19 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) return returnval < 126 ? returnval : 1; } -/* Get a signal number from a string */ + +/* Get index into table of traps from a string describing a signal */ /**/ mod_export int -getsignum(const char *s) +getsigidx(const char *s) { int x, i; /* check for a signal specified by number */ x = atoi(s); - if (idigit(*s) && x >= 0 && x < VSIGCOUNT) - return x; + if (idigit(*s) && x >= 0) + return SIGIDX(x); /* search for signal by name */ if (!strncmp(s, "SIG", 3)) @@ -2943,11 +3002,16 @@ getsignum(const char *s) return alt_sigs[i].num; } +#if defined(SIGRTMIN) && defined(SIGRTMAX) + if ((x = rtsigno(s))) + return SIGIDX(x); +#endif + /* no matching signal */ return -1; } -/* Get the name for a signal. */ +/* Get the name for a signal given the index into the traps table. */ /**/ mod_export const char * @@ -2961,6 +3025,11 @@ getsigname(int sig) return alt_sigs[i].name; } else +#if defined(SIGRTMIN) && defined(SIGRTMAX) + if (sig >= VSIGCOUNT) + return rtsigname(SIGNUM(sig), 0); + else +#endif return sigs[sig]; /* shouldn't reach here */ @@ -2985,10 +3054,22 @@ gettrapnode(int sig, int ignoredisable) else getptr = shfunctab->getnode; +#if defined(SIGRTMIN) && defined(SIGRTMAX) + if (sig >= VSIGCOUNT) + sprintf(fname, "TRAP%s", rtsigname(SIGNUM(sig), 0)); + else +#endif sprintf(fname, "TRAP%s", sigs[sig]); if ((hn = getptr(shfunctab, fname))) return hn; +#if defined(SIGRTMIN) && defined(SIGRTMAX) + if (sig >= VSIGCOUNT) { + sprintf(fname, "TRAP%s", rtsigname(SIGNUM(sig), 1)); + return getptr(shfunctab, fname); + } +#endif + for (i = 0; alt_sigs[i].name; i++) { if (alt_sigs[i].num == sig) { sprintf(fname, "TRAP%s", alt_sigs[i].name); diff --git a/Src/params.c b/Src/params.c index 225acb8a1..7c5e9d8ff 100644 --- a/Src/params.c +++ b/Src/params.c @@ -946,8 +946,18 @@ createparamtable(void) setsparam("ZSH_ARGZERO", ztrdup(posixzero)); setsparam("ZSH_VERSION", ztrdup_metafy(ZSH_VERSION)); setsparam("ZSH_PATCHLEVEL", ztrdup_metafy(ZSH_PATCHLEVEL)); - setaparam("signals", sigptr = zalloc((SIGCOUNT+4) * sizeof(char *))); - for (t = sigs; (*sigptr++ = ztrdup_metafy(*t++)); ); + setaparam("signals", sigptr = zalloc((TRAPCOUNT + 1) * sizeof(char *))); + t = sigs; +#if defined(SIGRTMIN) && defined(SIGRTMAX) + while (t - sigs <= SIGCOUNT) + *sigptr++ = ztrdup_metafy(*t++); + { + int sig; + for (sig = SIGRTMIN; sig <= SIGRTMAX; sig++) + *sigptr++ = ztrdup_metafy(rtsigname(sig, 0)); + } +#endif + while ((*sigptr++ = ztrdup_metafy(*t++))) /* empty */ ; noerrs = 0; } diff --git a/Src/signals.c b/Src/signals.c index b1a843e2c..d28853ea6 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -31,10 +31,12 @@ #include "signals.pro" /* Array describing the state of each signal: an element contains * - * 0 for the default action or some ZSIG_* flags ored together. */ + * 0 for the default action or some ZSIG_* flags ored together. * + * Contains TRAPCOUNT elements but can't be allocated statically * + * because that's a dynamic value on Linux */ /**/ -mod_export int sigtrapped[VSIGCOUNT]; +mod_export int *sigtrapped; /* * Trap programme lists for each signal. @@ -48,7 +50,7 @@ mod_export int sigtrapped[VSIGCOUNT]; */ /**/ -mod_export Eprog siglists[VSIGCOUNT]; +mod_export Eprog *siglists; /* Total count of trapped signals */ @@ -892,7 +894,7 @@ dosavetrap(int sig, int level) * Set a trap: note this does not handle manipulation of * the function table for TRAPNAL functions. * - * sig is the signal number. + * sig is index into the table of trapped signals. * * l is the list to be eval'd for a trap defined with the "trap" * builtin and should be NULL for a function trap. @@ -931,6 +933,10 @@ settrap(int sig, Eprog l, int flags) #endif sig != SIGCHLD) signal_ignore(sig); +#if defined(SIGRTMIN) && defined(SIGRTMAX) + else if (sig >= VSIGCOUNT && sig < TRAPCOUNT) + signal_ignore(SIGNUM(sig)); +#endif } else { nsigtrapped++; sigtrapped[sig] = ZSIG_TRAPPED; @@ -940,6 +946,10 @@ settrap(int sig, Eprog l, int flags) #endif sig != SIGCHLD) install_handler(sig); +#if defined(SIGRTMIN) && defined(SIGRTMAX) + if (sig >= VSIGCOUNT && sig < TRAPCOUNT) + install_handler(SIGNUM(sig)); +#endif } sigtrapped[sig] |= flags; /* @@ -1019,6 +1029,11 @@ removetrap(int sig) #endif sig != SIGCHLD) signal_default(sig); +#if defined(SIGRTMIN) && defined(SIGRTMAX) + else if (sig >= VSIGCOUNT && sig < TRAPCOUNT) + signal_default(SIGNUM(sig)); +#endif + if (sig == SIGEXIT) exit_trap_posix = 0; @@ -1172,7 +1187,7 @@ endtrapscope(void) static int handletrap(int sig) { - if (!sigtrapped[sig]) + if (!sigtrapped[SIGIDX(sig)]) return 0; if (trap_queueing_enabled) @@ -1189,7 +1204,7 @@ handletrap(int sig) return 1; } - dotrap(sig); + dotrap(SIGIDX(sig)); if (sig == SIGALRM) { @@ -1481,3 +1496,60 @@ dotrap(int sig) restore_queue_signals(q); } + +#if defined(SIGRTMIN) && defined(SIGRTMAX) + +/* Realtime signals, these are a contiguous block that can + * be separated from the other signals with an unused gap. */ + +/**/ +int +rtsigno(const char* signame) +{ + const int maxofs = SIGRTMAX - SIGRTMIN; + const char *end = signame + 5; + int offset; + struct rtdir { int sig; int dir; char op; } x = { 0, 0, 0 }; + if (!strncmp(signame, "RTMIN", 5)) { + x = (struct rtdir) { SIGRTMIN, 1, '+' }; + } else if (!strncmp(signame, "RTMAX", 5)) { + x = (struct rtdir) { SIGRTMAX, -1, '-' }; + } else + return 0; + + if (signame[5] == x.op) { + if ((offset = strtol(signame + 6, (char **) &end, 10)) > maxofs) + return 0; + x.sig += offset * x.dir; + } + if (*end) + return 0; + + return x.sig; +} + +/**/ +char * +rtsigname(int signo, int alt) +{ + char* buf = (char *) zhalloc(10); + int minofs = signo - SIGRTMIN; + int maxofs = SIGRTMAX - signo; + int offset; + int form = alt ^ (maxofs < minofs); + + if (signo < SIGRTMIN || signo > SIGRTMAX) + return NULL; + + strcpy(buf, "RT"); + strcpy(buf+2, form ? "MAX-" : "MIN+"); + offset = form ? maxofs : minofs; + if (offset) { + snprintf(buf + 6, 4, "%d", offset); + } else { + buf[5] = '\0'; + } + return buf; +} + +#endif diff --git a/Src/signals.h b/Src/signals.h index 41ac88cce..391f11fed 100644 --- a/Src/signals.h +++ b/Src/signals.h @@ -36,6 +36,15 @@ #define SIGZERR (SIGCOUNT+1) #define SIGDEBUG (SIGCOUNT+2) #define VSIGCOUNT (SIGCOUNT+3) +#if defined(SIGRTMIN) && defined(SIGRTMAX) +# define TRAPCOUNT (VSIGCOUNT + SIGRTMAX - SIGRTMIN + 1) +# define SIGNUM(x) ((x) >= VSIGCOUNT ? (x) - VSIGCOUNT + SIGRTMIN : (x)) +# define SIGIDX(x) ((x) >= SIGRTMIN && (x) <= SIGRTMAX ? (x) - SIGRTMIN + VSIGCOUNT : (x)) +#else +# define TRAPCOUNT VSIGCOUNT +# define SIGNUM(x) (x) +# define SIGIDX(x) (x) +#endif #define SIGEXIT 0 #ifdef SV_BSDSIG diff --git a/Src/signames2.awk b/Src/signames2.awk index 4d1557cd8..5738030c6 100644 --- a/Src/signames2.awk +++ b/Src/signames2.awk @@ -15,7 +15,7 @@ if (signam == "CHLD" && sig[signum] == "CLD") sig[signum] = "" if (signam == "POLL" && sig[signum] == "IO") sig[signum] = "" if (signam == "ABRT" && sig[signum] == "IOT") sig[signum] = "" - if (sig[signum] == "") { + if (signam !~ /RTM(IN|AX)/ && sig[signum] == "") { sig[signum] = signam if (0 + max < 0 + signum && signum < 60) max = signum @@ -66,10 +66,6 @@ END { printf "#include %czsh.mdh%c\n", 34, 34 printf "\n" printf "/**/\n" - printf "#define sigmsg(sig) ((sig) <= SIGCOUNT ? sig_msg[sig]" - printf " : %c%s%c)", 34, "unknown signal", 34 - printf "\n" - printf "/**/\n" printf "mod_export char *sig_msg[SIGCOUNT+2] = {\n" printf "\t%c%s%c,\n", 34, "done", 34 -- cgit v1.2.3 From 3078e07729930bfbff647b9b63452b58a54ecc70 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 28 Feb 2024 13:55:51 +0100 Subject: 52623: add some Solaris signal descriptions --- ChangeLog | 4 ++++ Src/signames2.awk | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 53038c221..7aaadfeb3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-02-28 Oliver Kiddle + + * 52623: Src/signames2.awk: add some Solaris signal descriptions + 2024-02-28 Oliver Kiddle * 52594: Completion/Zsh/Command/_kill, Doc/Zsh/builtins.yo, diff --git a/Src/signames2.awk b/Src/signames2.awk index 5738030c6..0b254f751 100644 --- a/Src/signames2.awk +++ b/Src/signames2.awk @@ -27,6 +27,7 @@ if (signam == "CONT") { msg[signum] = "continued" } if (signam == "EMT") { msg[signum] = "EMT instruction" } if (signam == "FPE") { msg[signum] = "floating point exception" } + if (signam == "FREEZE") { msg[signum] = "checkpoint freeze" } if (signam == "HUP") { msg[signum] = "hangup" } if (signam == "ILL") { msg[signum] = "illegal hardware instruction" } if (signam == "INFO") { msg[signum] = "status request from keyboard" } @@ -43,6 +44,7 @@ if (signam == "SEGV") { msg[signum] = "segmentation fault" } if (signam == "SYS") { msg[signum] = "invalid system call" } if (signam == "TERM") { msg[signum] = "terminated" } + if (signam == "THAW") { msg[signum] = "checkpoint thaw" } if (signam == "TRAP") { msg[signum] = "trace trap" } if (signam == "URG") { msg[signum] = "urgent condition" } if (signam == "USR1") { msg[signum] = "user-defined signal 1" } @@ -51,6 +53,7 @@ if (signam == "WINCH") { msg[signum] = "window size changed" } if (signam == "XCPU") { msg[signum] = "cpu limit exceeded" } if (signam == "XFSZ") { msg[signum] = "file size limit exceeded" } + if (signam == "XRES") { msg[signum] = "resource control exceeded" } } } -- cgit v1.2.3 From 69c58874611a586c68be14ce7965029dc00f41b7 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 28 Feb 2024 13:59:10 +0100 Subject: 52622 (tweaked, c.f. 52626): adjust number of columns and drop right-parenthesis in "kill -L" output --- ChangeLog | 3 +++ Src/jobs.c | 15 +++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7aaadfeb3..e836a3853 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-28 Oliver Kiddle + * 52622 (tweaked, c.f. 52626): Src/jobs.c: adjust number of columns + and drop right-parenthesis in "kill -L" output + * 52623: Src/signames2.awk: add some Solaris signal descriptions 2024-02-28 Oliver Kiddle diff --git a/Src/jobs.c b/Src/jobs.c index 49decc661..07facc60b 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -2822,23 +2822,26 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) #else const int width = SIGCOUNT >= 100 ? 3 : 2; #endif + const int cols = zterm_columns >= 30 ? + (zterm_columns < 90 ? zterm_columns / 15 : 6) : 1; + for (sig = 1; sig < SIGCOUNT #if defined(SIGRTMIN) && defined(SIGRTMAX) + 1 #endif ; sig++) { - printf("%*d) %-10s%c", width, sig, sigs[sig], - sig % 5 ? ' ' : '\n'); + printf("%*d %-10s%c", width, sig, sigs[sig], + sig % cols ? ' ' : '\n'); } #if defined(SIGRTMIN) && defined(SIGRTMAX) for (sig = SIGRTMIN; sig < SIGRTMAX; sig++) { - printf("%*d) %-10s%c", width, sig, rtsigname(sig, 0), - (sig - SIGRTMIN + SIGCOUNT + 1) % 5 ? ' ' : '\n'); + printf("%*d %-10s%c", width, sig, rtsigname(sig, 0), + (sig - SIGRTMIN + SIGCOUNT + 1) % cols ? ' ' : '\n'); } - printf("%*d) RTMAX\n", width, sig); + printf("%*d RTMAX\n", width, sig); #else - printf("%*d) %s\n", width, sig, sigs[sig]); + printf("%*d %s\n", width, sig, sigs[sig]); #endif return 0; } -- cgit v1.2.3 From 85172998f499cb789570714ffdd43f1ca3b53e58 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 28 Feb 2024 20:40:26 -0800 Subject: 52619 (plus tests): no empty element when appending array to unset scalar --- ChangeLog | 7 ++++++- Src/params.c | 2 +- Test/A06assign.ztst | 21 +++++++++++++++++---- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index e836a3853..9ab0218c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-02-28 Bart Schaefer + + * 52619 (plus tests): Src/params.c, Test/A06assign.ztst: there + is no empty element when appending array to unset scalar + 2024-02-28 Oliver Kiddle * 52622 (tweaked, c.f. 52626): Src/jobs.c: adjust number of columns @@ -54,7 +59,7 @@ x2024-02-19 Jun-ichi Takimoto * 52544: Completion/Unix/Type/_diff_options: support macOS Ventura or newer -2024-02-18 Bart Schaefer +2024-02-18 Bart Schaefer * 52558: Etc/FAQ.yo: make note of word splitting differences with nofork substitutions; update ToC; minor formatting fixes diff --git a/Src/params.c b/Src/params.c index 7c5e9d8ff..064dbd2bc 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3355,7 +3355,7 @@ assignaparam(char *s, char **val, int flags) } else if (!(PM_TYPE(v->pm->node.flags) & (PM_ARRAY|PM_HASHED)) && !(v->pm->node.flags & (PM_SPECIAL|PM_TIED))) { int uniq = v->pm->node.flags & PM_UNIQUE; - if (flags & ASSPM_AUGMENT) { + if ((flags & ASSPM_AUGMENT) && !(v->pm->node.flags & PM_UNSET)) { /* insert old value at the beginning of the val array */ char **new; int lv = arrlen(val); diff --git a/Test/A06assign.ztst b/Test/A06assign.ztst index f89edb888..3eff5331a 100644 --- a/Test/A06assign.ztst +++ b/Test/A06assign.ztst @@ -296,13 +296,26 @@ # tests of var+=(array) + a= + a+=(1 2 3) + print "${(q@)a}" +0:add array to empty parameter +>'' 1 2 3 + unset a a+=(1 2 3) - print -l $a + print "${(q@)a}" 0:add array to unset parameter ->1 ->2 ->3 +>1 2 3 + + () { + setopt localoptions typeset_to_unset + typeset a + a+=(1 2 3) + print "${(q@)a}" + } +0:add array to declared unset parameter +>1 2 3 a=(a) a+=(b) -- cgit v1.2.3 From 13f73d84d3a69085df148e7cfe03ed6448a1238b Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 1 Mar 2024 15:43:50 -0800 Subject: 52645: unset through a nameref keep up-scope parameters declared unset Othewise unset of a reference to a global wipes out all parameters of the same name. --- ChangeLog | 5 +++++ Src/builtin.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9ab0218c9..31e90dfd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-01 Bart Schaefer + + * 52645: Src/builtin.c: unset through a nameref keep up-scope + parameters declared, and not wipe out the entire parameter stack + 2024-02-28 Bart Schaefer * 52619 (plus tests): Src/params.c, Test/A06assign.ztst: there diff --git a/Src/builtin.c b/Src/builtin.c index 44dfed651..83144677b 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3932,8 +3932,14 @@ bin_unset(char *name, char **argv, Options ops, int func) } } else { if (!OPT_ISSET(ops,'n')) { + int ref = (pm->node.flags & PM_NAMEREF); if (!(pm = (Param)resolve_nameref(pm, NULL))) continue; + if (ref && pm->level < locallevel) { + /* Just mark unset, do not remove from table */ + pm->node.flags |= PM_DECLARED|PM_UNSET; + continue; + } } if (unsetparam_pm(pm, 0, 1)) returnval = 1; -- cgit v1.2.3 From 4fb96cc639f8f04a84dd488e61caacdecf11d65e Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 2 Mar 2024 09:22:43 -0800 Subject: 52612: %l replacment of zwarning() does literal string output --- ChangeLog | 6 ++++++ Src/parse.c | 9 ++++----- Src/subst.c | 4 +++- Src/utils.c | 22 ++++++++++++---------- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31e90dfd3..df90e441a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-03-02 Bart Schaefer + + * 52612: Src/parse.c, Src/subst.c, Src/utils.c: change the %l + replacment of zwarning() et al. to do literal string output; + change previous uses to %s and use new %l for ${var?$error} + 2024-03-01 Bart Schaefer * 52645: Src/builtin.c: unset through a nameref keep up-scope diff --git a/Src/parse.c b/Src/parse.c index 821812c78..40eb0ee0b 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -2730,11 +2730,10 @@ yyerror(int noerr) if (!t || !t[t0] || t[t0] == '\n') break; if (!(histdone & HISTFLAG_NOEXEC) && !(errflag & ERRFLAG_INT)) { - if (t0 == 20) - zwarn("parse error near `%l...'", t, 20); - else if (t0) - zwarn("parse error near `%l'", t, t0); - else + if (t0) { + t = metafy(t, t0, META_STATIC); + zwarn("parse error near `%s%s'", t, t0 == 20 ? "..." : ""); + } else zwarn("parse error"); } if (!noerr && noerrs != 2) diff --git a/Src/subst.c b/Src/subst.c index 650c09de2..49f7336bb 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3271,8 +3271,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, if (isset(EXECOPT)) { *idend = '\0'; if (*s){ + int l; singsub(&s); - zerr("%s: %s", idbeg, s); + s = unmetafy(s, &l); + zerr("%s: %l", idbeg, s, l); } else zerr("%s: %s", idbeg, "parameter not set"); /* diff --git a/Src/utils.c b/Src/utils.c index 0fda92709..c8831c85e 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -122,14 +122,20 @@ set_widearray(char *mb_array, Widechar_array wca) (implemented by zerrmsg()): Code Argument types Prints - %s const char * C string (null terminated) - %l const char *, int C string of given length (null not required) + %s const char * C string (metafied, null terminated) + (output "nice") + %l const char *, int C string of given length (not metafied) + (output raw) %L long decimal value %d int decimal value %z zlong decimal value %% (none) literal '%' %c int character at that codepoint - %e int strerror() message (argument is typically 'errno') + %e int strerror() message (argument usually 'errno') + (output raw) + + For %s and %l, the caller is responsible for assuring end-of-string + is not in the middle of a metafy pair (%s) or a multibyte character. */ static void @@ -310,14 +316,9 @@ zerrmsg(FILE *file, const char *fmt, va_list ap) nicezputs(str, file); break; case 'l': { - char *s; str = va_arg(ap, const char *); num = va_arg(ap, int); - num = metalen(str, num); - s = zhalloc(num + 1); - memcpy(s, str, num); - s[num] = '\0'; - nicezputs(s, file); + fwrite(str, num, 1, file); break; } case 'L': @@ -715,7 +716,8 @@ wcs_nicechar(wchar_t c, size_t *widthp, char **swidep) */ /**/ -mod_export int is_wcs_nicechar(wchar_t c) +mod_export int +is_wcs_nicechar(wchar_t c) { if (!WC_ISPRINT(c) && (c < 0x80 || !isset(PRINTEIGHTBIT))) { if (c == 0x7f || c == L'\n' || c == L'\t' || c < 0x20) -- cgit v1.2.3 From 145397b6dc6fc2cbb5fc529e36fb540b9fc7ec59 Mon Sep 17 00:00:00 2001 From: "Jun. T" Date: Sat, 2 Mar 2024 20:26:01 -0800 Subject: 52635: show file name when test has crashed --- ChangeLog | 2 ++ Test/runtests.zsh | 1 + 2 files changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index df90e441a..7273034ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-03-02 Bart Schaefer + * JunT.: 52635: Test/runtests.zsh: show file name when crashed + * 52612: Src/parse.c, Src/subst.c, Src/utils.c: change the %l replacment of zwarning() et al. to do literal string output; change previous uses to %s and use new %l for ${var?$error} diff --git a/Test/runtests.zsh b/Test/runtests.zsh index b66d579b6..538663f50 100644 --- a/Test/runtests.zsh +++ b/Test/runtests.zsh @@ -15,6 +15,7 @@ for file in "${(f)ZTST_testlist}"; do (( skipped++ )) elif (( $retval )); then (( failure++ )) + (( $retval > 128 )) && print "$file: failed: SIG$signals[$retval - 127]." else (( success++ )) fi -- cgit v1.2.3 From d1ff06f99185bb14554c6a48e0466aee6466ecac Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 2 Mar 2024 21:37:25 -0800 Subject: 52652: fix obscure bug unsetting the array part of a tied parameter pair --- ChangeLog | 3 +++ Src/params.c | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7273034ac..9718d0cae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-03-02 Bart Schaefer + * 52652: Src/params.c, Test/D04parameter.ztst: fix obscure bug + unsetting the array part of a tied parameter pair, update test + * JunT.: 52635: Test/runtests.zsh: show file name when crashed * 52612: Src/parse.c, Src/subst.c, Src/utils.c: change the %l diff --git a/Src/params.c b/Src/params.c index 064dbd2bc..e83e4aa5e 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3813,12 +3813,15 @@ unsetparam_pm(Param pm, int altflag, int exp) /* fudge things so removenode isn't called */ altpm->level = 1; } - unsetparam_pm(altpm, 1, exp); + unsetparam_pm(altpm, 1, exp); /* This resets pm to empty */ + pm->node.flags |= PM_UNSET; /* so we must repeat this */ } zsfree(altremove); - if (!(pm->node.flags & PM_SPECIAL)) + if (!(pm->node.flags & PM_SPECIAL)) { pm->gsu.s = &stdscalar_gsu; + pm->node.flags &= ~PM_ARRAY; + } } /* -- cgit v1.2.3 From 36a2d5cfa49a6b7d699269cb4f22d5f3d0255bc8 Mon Sep 17 00:00:00 2001 From: midchildan Date: Thu, 29 Feb 2024 22:34:33 +0900 Subject: 52641: incarg: add a backward variant and make it repeatable --- ChangeLog | 5 + Doc/Zsh/contrib.yo | 8 +- Functions/Zle/incarg | 64 ++++++++- Test/X05zleincarg.ztst | 358 ++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 347 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9718d0cae..5c839cd19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-05 Oliver Kiddle + + * 52641: midchildan: Doc/Zsh/contrib.yo, Functions/Zle/incarg, + Test/X05zleincarg.ztst: add a backward variant and make it repeatable + 2024-03-02 Bart Schaefer * 52652: Src/params.c, Test/D04parameter.ztst: fix obscure bug diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index ea00f0ccc..e682c800a 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -2635,7 +2635,8 @@ When the widget is named tt(incarg), the widget will increment an integer placed under the cursor placed or just to the left of it. tt(decarg), on the other hand, decrements the integer. When the name is prefixed with tt(vi), the cursor will jump to the nearest integer after the cursor before incrementing -it. +it. The tt(vi) prefix can also be combined with a tt(backward-) prefix to make +the widget search backwards for numbers. There's also a tt(sync-) prefix that can be added to the widget name. This variant is used for creating a sequence of numbers on split terminals with @@ -2643,8 +2644,9 @@ synchronized key input. The first pane won't increment the integer at all, but each pane after that will have the integer incremented once more than the previous pane. It currently supports tmux and iTerm2. -The prefixes tt(vi) and tt(sync-) can be combined, for example, into -tt(vim-sync-). In this case, the tt(vi) prefix should come first. +The prefixes tt(vi), tt(backward-), and tt(sync-) can be combined, for example, +into tt(vim-sync-) or tt(vim-backward-sync-). The tt(vi) prefix needs to be +at the very beginning. example(bindkey '^X+' incarg) ) diff --git a/Functions/Zle/incarg b/Functions/Zle/incarg index 9d56b21f6..0cfaf9ff5 100644 --- a/Functions/Zle/incarg +++ b/Functions/Zle/incarg @@ -41,11 +41,20 @@ emulate -L zsh # This behaves like Vim's CTRL-A / CTRL-X. It moves the cursor to the nearest # number after the cursor and increments or decrements it. # +# - vim-backward-incarg / vim-backward-decarg +# +# This behaves like vim-incarg & vim-decarg, but it searches backwards for a +# number. +# # - vim-sync-incarg / vim-sync-decarg # # This combines the behavior of the vim- and sync- variants. It's inspired by # Vim's g_CTRL-A / g_CTRL-X. # +# - vim-backward-sync-incarg / vim-backward-sync-decarg +# +# This combines the behavior of the vim-backward- and sync- variants. +# # Example Usage: # # autoload -Uz incarg @@ -58,9 +67,13 @@ emulate -L zsh # 'g^A' vim-sync-incarg \ # 'g^X' vim-sync-decarg +zle -f vichange + setopt localoptions extended_glob local match mbegin mend MATCH MBEGIN MEND i +[[ -z "$BUFFER" ]] && return 1 + # find the number and determine the base integer pos=$(( CURSOR + 1 )) base=0 @@ -104,11 +117,35 @@ fi if (( base == 0 )); then if [[ "$WIDGET" == vi* ]]; then - # jump to the nearest number after the cursor - while [[ "$BUFFER[pos]" == [^0-9] ]]; do - (( pos++ )) - (( pos > $#BUFFER )) && return 1 - done + if [[ "$WIDGET" == *backward-* ]]; then + # search backwards for a number + while true; do + case "$BUFFER[1,pos]" in + *0[xX][0-9a-fA-F]##) base=16 ;; + *0[oO][0-7]##) base=8 ;; + *0[bB][01]##) base=2 ;; + *[0-9]) base=10 ;; + *-) + case "$BUFFER[pos,-1]" in + -0[xX][0-9a-fA-F]*) ;; + -0[oO][0-7]*) ;; + -0[bB][01]*) ;; + -[0-9]*) base=10 ;; + esac + ;; + esac + (( base != 0 )) && break + + (( pos-- )) + (( pos <= 0 )) && return 1 + done + else + # jump to the nearest number after the cursor + while [[ "$BUFFER[pos]" == [^0-9] ]]; do + (( pos++ )) + (( pos > $#BUFFER )) && return 1 + done + fi fi # check for a prefix right after the cursor and jump right after it, if any @@ -204,6 +241,12 @@ fi local old="$BUFFER[first,last]" integer oldlen=$#BUFFER +integer oldnum="$base#$old" 2> /dev/null + +# -00 should increment to 01 instead of 001 +if [[ "$BUFFER[first]" == '-' ]] && (( oldnum == 0 )); then + (( ndigits-- )) +fi local fmt1 fmt2 case "$base" in @@ -214,10 +257,12 @@ case "$base" in esac local raw_result padded +# $(( )) outputs an error message to stderr when integer truncation occurs printf -v raw_result "%0$ndigits$fmt1" $(( [$fmt2] "$base#$old" + delta )) 2> /dev/null padded="${raw_result// /0}" +integer newnum="$base#$padded" 2> /dev/null -integer oldnum="$base#$old" newnum="$base#$padded" 2> /dev/null +# try to detect integer truncation if (( base != 10 && newnum < 0 || delta > 0 && newnum < oldnum || delta < 0 && newnum > oldnum )); then @@ -242,7 +287,12 @@ if zstyle -t ":zle:$WIDGET" debug; then zle -M "[$WIDGET] base: $base delta: $delta old: '$old' new: '$new'" fi -BUFFER[first,last]="$new" +if (( 0 < first && first <= last && last <= $#BUFFER )); then + BUFFER[first,last]="$new" +else + zle -M "[$WIDGET] The detected location of the integer was invalid. [location=BUFFER[$first,$last]]" + return 1 +fi integer offset=0 if [[ "$WIDGET" == vi* ]]; then diff --git a/Test/X05zleincarg.ztst b/Test/X05zleincarg.ztst index 2a6aa2d3f..cd9817c82 100644 --- a/Test/X05zleincarg.ztst +++ b/Test/X05zleincarg.ztst @@ -10,7 +10,7 @@ fi zpty_run ' autoload -Uz incarg - for name in {,vim-}{,sync-}{inc,dec}arg; do + for name in {,vim-,vim-backward-}{,sync-}{inc,dec}arg; do zle -N "$name" incarg done bindkey -v "^N" incarg @@ -21,6 +21,8 @@ bindkey -a "^P" vim-decarg bindkey -a "^F" vim-sync-incarg bindkey -a "^B" vim-sync-decarg + bindkey -a "^E" vim-backward-incarg + bindkey -a "^Y" vim-backward-decarg unset TMUX_PANE ITERM_SESSION_ID tmux() { echo "$TMUX_PANE" @@ -29,26 +31,40 @@ %test +# Basic increment & decrement + zletest $'0\C-n' -0:increment an integer with incarg +0:incarg increments an integer >BUFFER: 1 >CURSOR: 1 zletest $'0\C-p' -0:decrement an integer with decarg +0:decarg decrements an integer >BUFFER: -1 >CURSOR: 2 zletest $'echo 0\e0\C-n' -0:increment an integer with vim-incarg +0:vim-incarg increments an integer >BUFFER: echo 1 >CURSOR: 5 zletest $'echo 0\e0\C-p' -0:decrement an integer with vim-decarg +0:vim-decarg decrements an integer >BUFFER: echo -1 >CURSOR: 6 + zletest $'echo 0 foo\e\C-e' +0:vim-backward-incarg increments an integer +>BUFFER: echo 1 foo +>CURSOR: 5 + + zletest $'echo 0 foo\e\C-y' +0:vim-backward-decarg decrements an integer +>BUFFER: echo -1 foo +>CURSOR: 6 + +# sync- variants + zletest $'0\C-f' 0:sync-incarg does nothing on unsupported terminals >BUFFER: 0 @@ -57,42 +73,42 @@ zpty_run 'TMUX_PANE=0' zletest $'0\C-f' zpty_run 'unset TMUX_PANE' -0:sync-incarg on tmux in pane 0 +0:sync-incarg does nothing on tmux in pane 0 >BUFFER: 0 >CURSOR: 1 zpty_run 'TMUX_PANE=1' zletest $'0\C-f' zpty_run 'unset TMUX_PANE' -0:sync-incarg on tmux in pane 1 +0:sync-incarg increments by 1 on tmux in pane 1 >BUFFER: 1 >CURSOR: 1 zpty_run 'TMUX_PANE=2' zletest $'0\C-f' zpty_run 'unset TMUX_PANE' -0:sync-incarg on tmux in pane 2 +0:sync-incarg increments by 2 on tmux in pane 2 >BUFFER: 2 >CURSOR: 1 zpty_run 'ITERM_SESSION_ID=w0t0p0:00000000-0000-0000-0000-000000000000' zletest $'0\C-f' zpty_run 'unset ITERM_SESSION_ID' -0:sync-incarg on tmux in pane 0 +0:sync-incarg does nothing on tmux in pane 0 >BUFFER: 0 >CURSOR: 1 zpty_run 'ITERM_SESSION_ID=w0t0p1:00000000-0000-0000-0000-000000000000' zletest $'0\C-f' zpty_run 'unset ITERM_SESSION_ID' -0:sync-incarg on tmux in pane 1 +0:sync-incarg increments by 1 on tmux in pane 1 >BUFFER: 1 >CURSOR: 1 zpty_run 'ITERM_SESSION_ID=w0t0p2:00000000-0000-0000-0000-000000000000' zletest $'0\C-f' zpty_run 'unset ITERM_SESSION_ID' -0:sync-incarg on tmux in pane 2 +0:sync-incarg increments by 2 on tmux in pane 2 >BUFFER: 2 >CURSOR: 1 @@ -100,230 +116,281 @@ zpty_run 'ITERM_SESSION_ID=w0t0p2:00000000-0000-0000-0000-000000000000' zletest $'0\C-f' zpty_run 'unset TMUX_PANE ITERM_SESSION_ID' -0:tmux pane number takes precedence over iTerm2's +0:sync-incarg prioritizes tmux pane number over iTerm2's >BUFFER: 1 >CURSOR: 1 zletest $'0\e2\C-n' -0:Providing a numeric argument will change the incremented amount +0:incarg changes the incremented amount based on the numeric argument >BUFFER: 2 >CURSOR: 0 zpty_run 'incarg=3' zletest $'0\e\C-n' zpty_run 'unset incarg' -0:Setting the incarg variable will change the default incremented amount +0:incarg changes the default incremented amount based on the incarg variable >BUFFER: 3 >CURSOR: 0 zpty_run 'incarg=3' zletest $'0\e2\C-n' zpty_run 'unset incarg' -0:A numeric argument will take precedence over the incarg variable +0:incarg prioritizes the numeric argument over the incarg variable >BUFFER: 2 >CURSOR: 0 zpty_run 'TMUX_PANE=2' zletest $'0\e2\C-f' zpty_run 'unset TMUX_PANE' -0:Providing a numeric argument will work for the sync- variants of incarg +0:The sync- variants of incarg takes the numeric argument into account >BUFFER: 4 >CURSOR: 0 +# Leading zeros + zletest $'000\C-n' -0:Incrementing a decimal integer preserves leading zeros +0:incarg preserves leading zeros of decimal integers >BUFFER: 001 >CURSOR: 3 zletest $'-001\C-n\C-n' -0:Leading zeros are preserved when the digit turns from negative to positive +0:incarg preserves leading zeros when the digit turns from negative to positive >BUFFER: 001 >CURSOR: 3 zletest $'001\C-p\C-p' -0:Leading zeros are preserved when the digit turns from positive to negative +0:incarg preserves leading zeros when the digit turns from positive to negative >BUFFER: -001 >CURSOR: 4 zletest $'001\e1000\C-n' -0:Incrementing an integer works when the result has more zeros than the original +0:incarg works when the result has more number of digits than the original >BUFFER: 1001 >CURSOR: 3 zletest $'001\e2000\C-p' -0:Decrementing an integer with leading zeros works when the result has more digits than the original +0:decargs works on integers with leading zeros when the result has more digits than the original >BUFFER: -1999 >CURSOR: 4 + zletest $'-000\C-n' +0:incarg produces the correct number of zeros when incrementing integers starting with -0 +>BUFFER: 001 +>CURSOR: 3 + + zletest $'-000\C-p' +0:decarg produces the correct number of zeros when incrementing integers starting with -0 +>BUFFER: -001 +>CURSOR: 4 + + zpty_run 'incarg=0' + zletest $'-000\C-n' + zpty_run 'unset incarg' +0:incarg removes the sign when the target integer starts with -0 and the increment amount is 0 +>BUFFER: 000 +>CURSOR: 3 + + zletest $'-0\C-n' +0:incarg turns -0 into 1 +>BUFFER: 1 +>CURSOR: 1 + + zletest $'-0\C-p' +0:decarg turns -0 into -1 +>BUFFER: -1 +>CURSOR: 2 + + zpty_run 'incarg=0' + zletest $'-0\C-n' + zpty_run 'unset incarg' +0:incarg turns -0 into 0 when the increment amount is 0 +>BUFFER: 0 +>CURSOR: 1 + +# Binaries + zletest $'0b11\C-n' -0:Increment a binary integer +0:incarg can increment a binary integer >BUFFER: 0b100 >CURSOR: 5 zletest $'0B11\C-n' -0:Increment a binary integer with an upper case prefix +0:incarg can increment a binary integer with an upper case prefix >BUFFER: 0B100 >CURSOR: 5 zletest $'0b100\C-p' -0:Decrement a binary integer +0:decarg can decrement a binary integer >BUFFER: 0b11 >CURSOR: 4 zletest $'0b0011\C-n' -0:Increment a binary integer preserves leading zeros +0:incarg can preserve leading zeros of binaries >BUFFER: 0b0100 >CURSOR: 6 zletest $'0b001\e8\C-n' -0:Incrementing a binary integer work when the result has more zeros than the original +0:incarg works on binaries when the result has more zeros than the original >BUFFER: 0b1001 >CURSOR: 5 zletest $'0b0\C-p' -0:Decrementing a binary integer to a negative value will fail +0:decarg fails to produce a negative binary value >BUFFER: 0b0 >CURSOR: 3 +# Octals + zletest $'0o7\C-n' -0:Increment an octal integer +0:incarg can increment an octal integer >BUFFER: 0o10 >CURSOR: 4 zletest $'0O7\C-n' -0:Increment an octal integer with an upper case prefix +0:incarg can increment an octal integer with an upper case prefix >BUFFER: 0O10 >CURSOR: 4 zletest $'0o10\C-p' -0:Decrement an octal integer +0:decarg can decrement an octal integer >BUFFER: 0o7 >CURSOR: 3 zletest $'0o0\C-p' -0:Decrementing an octal integer to a negative value will fail +0:decarg fails to produce a negative octal value >BUFFER: 0o0 >CURSOR: 3 +# Hexadecimals + zletest $'0x9\C-n' -0:Increment a hexadecimal integer +0:incarg can increment a hexadecimal integer >BUFFER: 0xa >CURSOR: 3 zletest $'0X9\C-n' -0:Increment a hexadecimal integer with an upper case prefix +0:incarg can increment a hexadecimal integer with an upper case prefix >BUFFER: 0XA >CURSOR: 3 zletest $'0xf\C-n' -0:Increment a hexadecimal integer with no numeric digit +0:incarg can increment a hexadecimal integer with no numeric digit >BUFFER: 0x10 >CURSOR: 4 zletest $'0x10\C-p' -0:Decrement a hexadecimal integer +0:decarg can decrement a hexadecimal integer >BUFFER: 0xf >CURSOR: 3 zletest $'0x0\C-p' -0:Decrementing an octal integer to a negative value will fail +0:decarg fails to produce a negative hexadecimal value >BUFFER: 0x0 >CURSOR: 3 zletest $'0x0b1\C-n' -0:a number that starts with 0x0b is interpreted as a hexadecimal integer +0:incarg interprets integers starting with 0x0b as a hexadecimal >BUFFER: 0x0b2 >CURSOR: 5 + zletest $'0x0b1\e\C-e' +0:vim-backward-incarg interprets integers starting with 0x0b as a hexadecimal +>BUFFER: 0x0b2 +>CURSOR: 4 + +# Cursor position - incarg + + zletest $'echo 012ab\eF i\C-n' +0:incarg does nothing when the cursor is placed just to the left of an integer +>BUFFER: echo 012ab +>CURSOR: 4 + + zletest $'echo 012ab\eF0i\C-n' +0:incarg works when the cursor is placed at the leftmost digit of an integer +>BUFFER: echo 013ab +>CURSOR: 8 + + zletest $'echo 012ab\eF1i\C-n' +0:incarg works when the cursor is placed at the inner digit of an integer +>BUFFER: echo 013ab +>CURSOR: 8 + + zletest $'echo 012ab\eF2i\C-n' +0:incarg works when the cursor is placed at the rightmost digit of an integer +>BUFFER: echo 013ab +>CURSOR: 8 + + zletest $'echo 012ab\eFai\C-n' +0:incarg works when the cursor is placed just to the right of an integer +>BUFFER: echo 013ab +>CURSOR: 8 + + zletest $'echo 012ab\ei\C-n' +0:incarg does nothing when the cursor is placed more than a single letter away to the right +>BUFFER: echo 012ab +>CURSOR: 9 + zletest $'10x9\e0\C-n' -0:[0-9]0x[0-9a-f] will become [0-9]1x[0-9a-f] when incremented from the left of x +0:incarg turns [0-9]0x[0-9a-f] into [0-9]1x[0-9a-f] when the cursor is at the left of x >BUFFER: 11x9 >CURSOR: 1 zletest $'10x9\eFx\C-n' -0:[0-9]0x[0-9a-f] will increment the hexadecimal 0x[0-9a-f] when the cursor is on x +0:incarg takes [0-9]0x[0-9a-f] and increments the hexadecimal part when the cursor is on x >BUFFER: 10xa >CURSOR: 3 zletest $'10x9\e\C-n' -0:[0-9]0x[0-9a-f] will increment the hexadecimal 0x[0-9a-f] when the cursor is on the right of x +0:incarg takes [0-9]0x[0-9a-f] and increments the hexadecimal part when the cursor is at the right of x >BUFFER: 10xa >CURSOR: 3 zletest $'10b1\e0\C-n' -0:[0-9]0b[01] will become [0-9]1b[01] when incremented from the left of b +0:incarg turns [0-9]0b[01] into [0-9]1b[01] when the cursor is at the left of b >BUFFER: 11b1 >CURSOR: 1 zletest $'10b1\eFb\C-n' -0:[0-9]0b[01] will increment the binary 0b[01] when the cursor is on b +0:incarg takes [0-9]0b[01] and increments the binary part when the cursor is on b >BUFFER: 10b10 >CURSOR: 4 zletest $'10b1\e\C-n' -0:[0-9]0b[01] will increment the binary 0b[01] when the cursor is on the right of b +0:incarg takes [0-9]0b[01] and increments binary part when the cursor is at the right of b >BUFFER: 10b10 >CURSOR: 4 zletest $'10o7\e0\C-n' -0:[0-9]0o[0-7] will become [0-9]1o[0-7] when incremented from the left of o +0:incarg turns [0-9]0o[0-7] into [0-9]1o[0-7] when the cursor is at the left of o >BUFFER: 11o7 >CURSOR: 1 zletest $'10o7\eFo\C-n' -0:[0-9]0o[0-7] will increment the octal 0o[0-7] when the cursor is on o +0:incarg takes [0-9]0o[0-7] and increments the octal part when the cursor is on o >BUFFER: 10o10 >CURSOR: 4 zletest $'10o7\e\C-n' -0:[0-9]0o[0-7] will increment the octal 0o[0-7] when the cursor is on the right of o +0:incarg takes [0-9]0o[0-7] and increments the octal part when the cursor is at the right of o >BUFFER: 10o10 >CURSOR: 4 zletest $'0b0x9\eF0\C-n' -0:0b0x[0-9a-f] will increment the binary 0b0 when the cursor is on the left of x +0:incarg takes 0b0x[0-9a-f] and increments the binary part when the cursor is at the left of x >BUFFER: 0b1x9 >CURSOR: 2 zletest $'0b0x9\eFx\C-n' -0:0b0x[0-9a-f] will increment the hexadecimal 0x[0-9a-f] when the cursor is on top of x +0:incarg takes 0b0x[0-9a-f] and increments the hexadecimal part when the cursor is on x >BUFFER: 0b0xa >CURSOR: 4 zletest $'0b0x9\e\C-n' -0:0b0x[0-9a-f] will increment the hexadecimal 0x[0-9a-f] when the cursor is on the right of x +0:incarg takes 0b0x[0-9a-f] and increments the hexadecimal part when the cursor is at the right of x >BUFFER: 0b0xa >CURSOR: 4 - zletest $'echo 012ab\eF i\C-n' -0:incarg does nothing when the cursor is placed just to the left of an integer ->BUFFER: echo 012ab ->CURSOR: 4 - - zletest $'echo 012ab\eF0i\C-n' -0:incarg works when the cursor is placed at the leftmost digit of an integer ->BUFFER: echo 013ab ->CURSOR: 8 - - zletest $'echo 012ab\eF1i\C-n' -0:incarg works when the cursor is placed at the inner digit of an integer ->BUFFER: echo 013ab ->CURSOR: 8 - - zletest $'echo 012ab\eF2i\C-n' -0:incarg works when the cursor is placed at the rightmost digit of an integer ->BUFFER: echo 013ab ->CURSOR: 8 - - zletest $'echo 012ab\eFai\C-n' -0:incarg works when the cursor is placed just to the right of an integer ->BUFFER: echo 013ab ->CURSOR: 8 - - zletest $'echo 012ab\ei\C-n' -0:incarg does nothing when the cursor is placed more than a single letter away to the right ->BUFFER: echo 012ab ->CURSOR: 9 +# Cursor position - vim-incarg zletest $'echo 012ab\eF \C-n' 0:vim-incarg works when the cursor is placed to the left of an integer @@ -355,6 +422,141 @@ >BUFFER: echo 012ab >CURSOR: 9 +# Cursor position - vim-backward-incarg + + zletest $'echo 012ab\eF \C-e' +0:vim-backward-incarg does nothing when the cursor is placed just to the left of an integer +>BUFFER: echo 012ab +>CURSOR: 4 + + zletest $'echo 012ab\eF0\C-e' +0:vim-backward-incarg works when the cursor is placed at the leftmost digit of an integer +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'echo 012ab\eF1\C-e' +0:vim-backward-incarg works when the cursor is placed at the inner digit of an integer +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'echo 012ab\eF2\C-e' +0:vim-backward-incarg works when the cursor is placed at the rightmost digit of an integer +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'echo 012ab\eFa\C-e' +0:vim-backward-incarg works when the cursor is placed just to the right of an integer +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'echo 012ab\e\C-e' +0:vim-backward-incarg works when the cursor is placed more than a single letter away to the right +>BUFFER: echo 013ab +>CURSOR: 7 + + zletest $'10x9\eFx\C-e' +0:vim-backward-incarg will take [0-9]0x[0-9a-f] and increment the hexadecimal part when the cursor is on x +>BUFFER: 10xa +>CURSOR: 3 + + zletest $'10x9\e\C-e' +0:vim-backward-incarg will take [0-9]0x[0-9a-f] and increment the hexadecimal part when the cursor is on the right of x +>BUFFER: 10xa +>CURSOR: 3 + + zletest $'10b1\e0\C-e' +0:vim-backward-incarg will turn [0-9]0b[01] into [0-9]1b[01] when the cursor is at the left of b +>BUFFER: 11b1 +>CURSOR: 1 + + zletest $'10b1\eFb\C-e' +0:vim-backward-incarg will take [0-9]0b[01] and increment the binary part when the cursor is on b +>BUFFER: 10b10 +>CURSOR: 4 + + zletest $'10b1\e\C-e' +0:vim-backward-incarg will take [0-9]0b[01] and increment the binary part when the cursor is on the right of b +>BUFFER: 10b10 +>CURSOR: 4 + + zletest $'10o7\e0\C-e' +0:vim-backward-incarg will turn [0-9]0o[0-7] into [0-9]1o[0-7] when the cursor is at the left of o +>BUFFER: 11o7 +>CURSOR: 1 + + zletest $'10o7\eFo\C-e' +0:vim-backward-incarg will take [0-9]0o[0-7] and increment the octal part when the cursor is on o +>BUFFER: 10o10 +>CURSOR: 4 + + zletest $'10o7\e\C-e' +0:vim-backward-incarg will take [0-9]0o[0-7] and increment the octal part when the cursor is at the right of o +>BUFFER: 10o10 +>CURSOR: 4 + + zletest $'0b0x9\eF0\C-e' +0:vim-backward-incarg will take 0b0x[0-9a-f] and increment the binary 0b0 when the cursor is on the left of x +>BUFFER: 0b1x9 +>CURSOR: 2 + + zletest $'0b0x9\eFx\C-e' +0:vim-backward-incarg will take 0b0x[0-9a-f] and increment the hexadecimal part when the cursor is on x +>BUFFER: 0b0xa +>CURSOR: 4 + + zletest $'0b0x9\e\C-e' +0:vim-backward-incarg will take 0b0x[0-9a-f] and increment the hexadecimal part when the cursor is at the right of x +>BUFFER: 0b0xa +>CURSOR: 4 + +# Repeats + + zletest $'echo 0\e0\C-n.' +0:vim-incarg is compatible with the repeat command +>BUFFER: echo 2 +>CURSOR: 5 + + zletest $'echo 0\e0\C-p.' +0:vim-decarg is compatible with the repeat command +>BUFFER: echo -2 +>CURSOR: 6 + + zletest $'echo 0 foo\e\C-e.' +0:vim-backward-incarg is compatible with the repeat command +>BUFFER: echo 2 foo +>CURSOR: 5 + + zletest $'echo 0\e010\C-n.' +0:Repeats of vim-incarg takes the numeric argument into account +>BUFFER: echo 20 +>CURSOR: 6 + + zletest $'echo 0 foo\e10\C-e.' +0:Repeats of vim-backward-incarg takes the numeric argument into account +>BUFFER: echo 20 foo +>CURSOR: 6 + + zpty_run 'TMUX_PANE=0' + zletest $'echo 0\e0\C-f.' + zpty_run 'unset TMUX_PANE' +0:Repeats of vim-sync-incarg work in pane 0 +>BUFFER: echo 0 +>CURSOR: 5 + + zpty_run 'TMUX_PANE=1' + zletest $'echo 0\e0\C-f.' + zpty_run 'unset TMUX_PANE' +0:Repeats of vim-sync-incarg work in pane 1 +>BUFFER: echo 2 +>CURSOR: 5 + + zpty_run 'TMUX_PANE=2' + zletest $'echo 0\e0\C-f.' + zpty_run 'unset TMUX_PANE' +0:Repeats of vim-sync-incarg work in pane 2 +>BUFFER: echo 4 +>CURSOR: 5 + %clean zmodload -ui zsh/zpty -- cgit v1.2.3 From 05c7b21e2b30873d002b50b37e2fbd3803d4b608 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 5 Mar 2024 00:11:02 +0100 Subject: 52646: extend support for highlight groups to completion explanation strings and WATCHFMT --- ChangeLog | 7 +++++-- Completion/Zsh/Type/_ps1234 | 21 +++++++++++++-------- Doc/Zsh/compsys.yo | 4 ++-- Doc/Zsh/compwid.yo | 3 ++- Src/Modules/watch.c | 9 ++++++++- Src/Zle/complist.c | 7 +++++++ Src/Zle/zle_tricky.c | 8 ++++++++ Src/prompt.c | 8 +++++--- 8 files changed, 50 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5c839cd19..0dd7268d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2024-03-05 Oliver Kiddle + * 52646: Completion/Zsh/Type/_ps1234, Doc/Zsh/compsys.yo, + Doc/Zsh/compwid.yo, Src/Modules/watch.c, Src/Zle/complist.c, + Src/Zle/zle_tricky.c, Src/prompt.c: extend support for highlight + groups to completion explanation strings and WATCHFMT + * 52641: midchildan: Doc/Zsh/contrib.yo, Functions/Zle/incarg, Test/X05zleincarg.ztst: add a backward variant and make it repeatable @@ -31,8 +36,6 @@ * 52623: Src/signames2.awk: add some Solaris signal descriptions -2024-02-28 Oliver Kiddle - * 52594: Completion/Zsh/Command/_kill, Doc/Zsh/builtins.yo, Doc/Zsh/params.yo, Src/Modules/parameter.c, Src/builtin.c, Src/exec.c, Src/hashtable.c, Src/init.c, Src/jobs.c, Src/params.c, diff --git a/Completion/Zsh/Type/_ps1234 b/Completion/Zsh/Type/_ps1234 index 07dea5905..e4391dc00 100644 --- a/Completion/Zsh/Type/_ps1234 +++ b/Completion/Zsh/Type/_ps1234 @@ -1,17 +1,18 @@ #compdef -value-,PROMPT,-default- -value-,PROMPT2,-default- -value-,PROMPT3,-default- -value-,PROMPT4,-default- -value-,RPROMPT,-default- -value-,RPROMPT2,-default- -value-,PS1,-default- -value-,PS2,-default- -value-,PS3,-default- -value-,PS4,-default- -value-,RPS1,-default- -value-,RPS2,-default- -value-,SPROMPT,-default- -value-,PROMPT_EOL_MARK,-default- -local -a specs ccol -local expl grp cols bs suf pre changed=1 ret=1 +local -a specs ccol suf +local expl grp cols bs pre changed=1 ret=1 local -A ansi [[ -z $compstate[quote] ]] && bs='\' +suf=( -S '' ) # first strip off any complete prompt specifications leaving only the # current, incomplete, one while (( changed )); do changed=0 - compset -P '%[DFK](\\|){[^}]#}' && changed=1 # formats with arg: %x{...} - compset -P '%[0-9-\\]#[^DFK(0-9-<>\\\[]' && changed=1 # normal formats + compset -P '%[DFHK](\\|){[^}]#}' && changed=1 # formats with arg: %x{...} + compset -P '%[0-9-\\]#[^DFHK(0-9-<>\\\[]' && changed=1 # normal formats compset -P '%[0-9-\\]#(<[^<]#<|>[^>]#>|\[[^\]]#\])' && changed=1 # truncations compset -P '%[0-9-\\]#(\\|)\([0-9-]#[^0-9]?|[^%]' && changed=1 # start of ternary compset -P '[^%]##' && changed=1 # sundry other characters @@ -41,15 +42,15 @@ if compset -P '%[FK]'; then grp="$expl[expl[(i)-J]+1]" print -v ccol -f "($grp)=%s=%s" ${(kv)ansi} _comp_colors+=( $ccol ) - compadd "$expl[@]" $suf $pre -k ansi && ret=0 - if (( $#suf )) && compset -P "(<->|%v)"; then + compadd "$expl[@]" "$suf[@]" $pre -k ansi && ret=0 + if [[ $ISUFFIX != (\\|)}* ]] && compset -P "(<->|%v)"; then _wanted ansi-colors expl 'closing brace' compadd -S '' \} && ret=0 elif (( $+terminfo[colors] )); then (( cols = $terminfo[colors] - 1 )) (( cols = cols > 255 ? 255 : cols )) _description -V terminal-colors expl 'terminal color' grp="$expl[expl[(i)-J]+1]" - compadd "$expl[@]" $suf $pre {0..$cols} + compadd "$expl[@]" "$suf[@]" $pre {0..$cols} for c in {0..$cols}; do _comp_colors+=( "($grp)=${c}=${${${(%):-%F{$c\}}#?\[}%m}" ) done @@ -93,11 +94,14 @@ elif compset -P '%[0-9-\\]#(\\|)\([0-9-]#'; then 'w:day of week (Sunday = 0)' ) [[ $IPREFIX != *- ]] && _describe -t ternary-prompt-expressions \ - 'ternary prompt format test character' specs $suf && ret=0 + 'ternary prompt format test character' specs "$suf[@]" && ret=0 _message -e numbers number elif compset -P '%D(\\|){'; then compset -S '(\\|)}*' _date_formats zsh && ret=0 +elif compset -P '%H(\\|){'; then + compset -S '(\\|)}*' || suf=( -S "$bs}" ) + _wanted highlight-groups expl 'highlight group' compadd "$suf[@]" -k .zle.hlgroups && ret=0 elif [[ -prefix '%' ]] || ! zstyle -t ":completion:${curcontext}:prompt-format-specifiers" prefix-needed then @@ -152,6 +156,7 @@ then 'B:start bold' 'b:stop bold' 'E:clear to end of line' + 'H{:use highlight group' 'U:start underline' 'u:stop underline' 'S:start standout' diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 3f708eb5a..f75298a1b 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -2023,8 +2023,8 @@ position shown as a percentage of the total length otherwise. In each case the form with the uppercase letter will be replaced by a string of fixed width, padded to the right with spaces, while the lowercase form will be replaced by a variable width string. As in other prompt strings, the -escape sequences `tt(%S)', `tt(%s)', `tt(%B)', `tt(%b)', `tt(%U)', -`tt(%u)' for entering and leaving the display modes +escape sequence `tt(%H)` along with `tt(%S)', `tt(%s)', `tt(%B)', `tt(%b)', +`tt(%U)', `tt(%u)' for entering and leaving the display modes standout, bold and underline, and `tt(%F)', `tt(%f)', `tt(%K)', `tt(%k)' for changing the foreground background colour, are also available, as is the form `tt(%{)...tt(%})' for enclosing escape sequences which display with zero diff --git a/Doc/Zsh/compwid.yo b/Doc/Zsh/compwid.yo index 9461ace17..b0c9b0a5f 100644 --- a/Doc/Zsh/compwid.yo +++ b/Doc/Zsh/compwid.yo @@ -597,7 +597,8 @@ ifnzman((see noderef(Prompt Expansion)))\ ifzman(as described in the section EXPANSION OF PROMPT SEQUENCES in zmanref(zshmisc)): `tt(%B)', `tt(%S)', `tt(%U)', `tt(%F)', `tt(%K)' and their lower case -counterparts, as well as `tt(%{)...tt(%})'. `tt(%F)', `tt(%K)' and +counterparts, as well as `tt(%H)' and `tt(%{)...tt(%})'. `tt(%F)', +`tt(%K)', `tt(%H)' and `tt(%{)...tt(%})' take arguments in the same form as prompt expansion. (Note that the sequence `tt(%G)' is not available; an argument to `tt(%{)' should be used instead.) The sequence `tt(%%)' diff --git a/Src/Modules/watch.c b/Src/Modules/watch.c index 97d4fa608..ba17cf940 100644 --- a/Src/Modules/watch.c +++ b/Src/Modules/watch.c @@ -373,6 +373,13 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) case 'f': tunsetattrs(TXTFGCOLOUR); break; + case 'H': + if (*fmt == '{') { + fmt = parsehighlight(fmt + 1, '}', &atr); + if (atr && atr != TXT_ERROR) + treplaceattrs(atr); + } + break; case 'K': if (*fmt == '{') { fmt++; @@ -428,7 +435,7 @@ watchlog_match(char *teststr, char *actual, size_t buflen) int ret = 0; Patprog pprog; char *str = dupstring(teststr); - int len = strnlen(actual, buflen); + size_t len = strnlen(actual, buflen); char *user = metafy(actual, len, len == buflen ? META_HEAPDUP : META_USEHEAP); diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 9cb89a60d..5619160a9 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -1181,6 +1181,13 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop) if (dopr) tunsetattrs(TXTBGCOLOUR); break; + case ZWC('H'): + if (*p == '{') { + p = parsehighlight(p + 1, '}', &atr); + if (atr != TXT_ERROR && dopr) + treplaceattrs(atr); + } + break; case ZWC('{'): if (arg) cc += arg; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 225ce8c74..aa3c71bc2 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -2501,6 +2501,14 @@ printfmt(char *fmt, int n, int dopr, int doesc) case 'k': tunsetattrs(TXTBGCOLOUR); break; + case 'H': + if (p[1] == '{') { + p = parsehighlight(p + 2, '}', &atr); + --p; + if (atr != TXT_ERROR) + treplaceattrs(atr); + } + break; case '{': if (arg) cc += arg; diff --git a/Src/prompt.c b/Src/prompt.c index 7acbe0e47..e10b05215 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -270,7 +270,8 @@ zattrescape(zattr atr, int *len) } /* Parse the argument for %H */ -static char * +/**/ +mod_export char * parsehighlight(char *arg, char endchar, zattr *atr) { static int entered = 0; @@ -295,9 +296,9 @@ parsehighlight(char *arg, char endchar, zattr *atr) } else *atr = TXT_ERROR; if (ep) - *ep = endchar; + *ep++ = endchar; else - ep = strchr(arg, '\0') - 1; + ep = strchr(arg, '\0'); entered = 0; return ep; } @@ -635,6 +636,7 @@ putpromptchar(int doprint, int endchar) case 'H': if (bv->fm[1] == '{') { bv->fm = parsehighlight(bv->fm + 2, '}', &atr); + --bv->fm; if (atr != TXT_ERROR) { treplaceattrs(atr); applytextattributes(TSC_PROMPT); -- cgit v1.2.3 From 610b18875ad9f4498a57e9af6903bcac3b14ff46 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 4 Mar 2024 21:07:01 -0800 Subject: 52650 plus minor fixes: add -u for named references pointing to "upper" scope --- ChangeLog | 9 +++++++++ Doc/Zsh/builtins.yo | 8 ++++++-- Doc/Zsh/expn.yo | 19 +++++++++++++++++++ Doc/Zsh/func.yo | 13 ++++++++----- Doc/Zsh/mod_ksh93.yo | 2 +- Etc/FAQ.yo | 7 +++++++ Src/Modules/ksh93.c | 2 +- Src/builtin.c | 2 +- Src/exec.c | 22 +++++++++++++++++++++- Src/params.c | 32 +++++++++++++++++++------------ Test/K01nameref.ztst | 53 +++++++++++++++++++++++++++++++++++++++++++++++++--- Test/V10private.ztst | 4 ++-- 12 files changed, 145 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0dd7268d1..2d4d9922e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2024-03-04 Bart Schaefer + + * 52650 plus minor fixes: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, + Doc/Zsh/func.yo, Doc/Zsh/mod_ksh93.yo, Etc/FAQ.yo, + Src/Modules/ksh93.c, Src/builtin.c, Src/exec.c, Src/params.c, + Test/D04parameter.ztst, Test/K01nameref.ztst, + Test/V10private.ztst: add -u option for named references that + point to the "upper" scope, failed assignments have status 1 + 2024-03-05 Oliver Kiddle * 52646: Completion/Zsh/Type/_ps1234, Doc/Zsh/compsys.yo, diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 6318053d8..7a9684ac8 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2052,13 +2052,17 @@ cindex(named reference) cindex(reference, named) The flag tt(-n) creates a em(named reference) to another parameter. The second parameter need not exist at the time the reference is -created. Only tt(-g) and tt(-r) may be used in conjunction with +created. Only tt(-g), tt(-u), and tt(-r) may be used in conjunction with tt(-n). The var(name) so created may not be an array element nor use a subscript, but the var(value) assigned may be any valid parameter name syntax, even a subscripted array element (including an associative array element) or an array slice, which is evaluated when the named reference is expanded. It is an error for a named reference to refer -to itself, even indirectly through a chain of references. +to itself, even indirectly through a chain of references. When tt(-u) +is applied to a named reference, the parameter identified by var(value) +is always found in the calling function scope rather than the current +local scope. In this case, if there is no such parameter in the calling +scope, assignments to the named reference may fail, setting tt($?) to 1. See ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)) and ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)) for details of the behavior of named references. diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 2acfd08c9..183ca6e03 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1600,6 +1600,25 @@ example(tt(before local: OUTER) tt(by reference: OUTER) tt(after func: RESULT)) +To force a named reference to refer to the outer scope, even if a local +has already been declared, add the tt(-u) option when declaring the +named reference. In this case var(rname) should already exist in the +outer scope, otherwise the behavior of assignment through var(pname) +is not defined and may change the scope of the reference or fail with +a status of 1. Example of correct usage: +ifzman() +example(tt(caller=OUTER) +tt(func LPAR()RPAR() {) +tt( print before local: $caller) +tt( local caller=INNER) +tt( print after local: $caller) +tt( typeset -n -u outer=$1) +tt( print by reference: $outer) +tt( outer=RESULT) +tt(}) +tt(func caller) +tt(print after func: $caller)) + Note, however, that named references to em(special) parameters acquire the behavior of the special parameter, regardless of the scope where the reference is declared. diff --git a/Doc/Zsh/func.yo b/Doc/Zsh/func.yo index d4914df7a..7b71e34e9 100644 --- a/Doc/Zsh/func.yo +++ b/Doc/Zsh/func.yo @@ -31,10 +31,12 @@ referent parameter is in scope, and as early as possible in the function if the reference is to a parameter in a calling scope. A typical use of named references is to pass the name -of the referent as a positional parameter. For example, +of the referent as a positional parameter. In this case it is +good practice to use the tt(-u) option to reference the calling +scope. For example, ifzman() example(pop+LPAR()RPAR() { - local -n ref=$1 + local -nu ref=$1 local last=$ref[$#ref] ref[$#ref]=LPAR()RPAR() print -r -- $last @@ -43,9 +45,10 @@ array=LPAR() a list of five values RPAR() pop array) prints the word `tt(values)' and shortens `tt($array)' to -`tt(LPAR() a list of five RPAR())'. There are no local parameters in -tt(pop) at the time `tt(ref=$1)' is assigned, so `tt(ref)' becomes a -reference to `tt(array)' in the caller. +`tt(LPAR() a list of five RPAR())'. With tt(-nu), `tt(ref)' becomes a +reference to `tt(array)' in the caller. There are no local parameters in +tt(pop) at the time `tt(ref=$1)' is assigned, so in this example tt(-u) +could have been omitted, but it makes the intention clear. Functions execute in the same process as the caller and share all files diff --git a/Doc/Zsh/mod_ksh93.yo b/Doc/Zsh/mod_ksh93.yo index 9cd708d10..7508758aa 100644 --- a/Doc/Zsh/mod_ksh93.yo +++ b/Doc/Zsh/mod_ksh93.yo @@ -12,7 +12,7 @@ The single builtin provided by this module is: startitem() findex(nameref) cindex(named references, creating) -item(tt(nameref) [ tt(-r) ] var(pname)[tt(=)var(rname)])( +item(tt(nameref) [ tt(-gur) ] var(pname)[tt(=)var(rname)])( Equivalent to tt(typeset -n )var(pname)tt(=)var(rname) However, tt(nameref) is a builtin command rather than a reserved word, diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 145ef02c9..4a86050e6 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -1025,6 +1025,13 @@ label(210) HIT:SPOT ) + Dynamic scoping applies to named references, so for example a named + reference declared in global scope may be used in function scopes. + In ksh, local parameters have static scope, so named references in + zsh may have side-effects that do not occur in ksh. To limit those + effects, mytt(zmodload zsh/param/private) and declare all named + references mytt(private). + Named references may be used in zsh versions later than 5.9. sect(What is zsh's support for non-forking command substitution?) diff --git a/Src/Modules/ksh93.c b/Src/Modules/ksh93.c index 9af5e1d69..6760cbca0 100644 --- a/Src/Modules/ksh93.c +++ b/Src/Modules/ksh93.c @@ -38,7 +38,7 @@ */ static struct builtin bintab[] = { - BUILTIN("nameref", BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "gr", "n") + BUILTIN("nameref", BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "gur", "n") }; #include "zsh.mdh" diff --git a/Src/builtin.c b/Src/builtin.c index 83144677b..ba9cb03c2 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2699,7 +2699,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) off |= bit; } if (OPT_MINUS(ops,'n')) { - if ((on|off) & ~PM_READONLY) { + if ((on|off) & ~(PM_READONLY|PM_UPPER)) { zwarnnam(name, "no other attributes allowed with -n"); return 1; } diff --git a/Src/exec.c b/Src/exec.c index d85adbea5..0231bc361 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2604,6 +2604,17 @@ addvars(Estate state, Wordcode pc, int addflags) opts[ALLEXPORT] = allexp; } else pm = assignsparam(name, val, myflags); + if (!pm) { + lastval = 1; + /* + * This is cheating but some exec functions propagate + * assignment status only from command substitution + * + * zerr("%s: assignment failed", name); + */ + if (!cmdoutval) + cmdoutval = 1; + } if (errflag) { state->pc = opc; return; @@ -2628,7 +2639,16 @@ addvars(Estate state, Wordcode pc, int addflags) } fprintf(xtrerr, ") "); } - assignaparam(name, arr, myflags); + if (!assignaparam(name, arr, myflags)) { + lastval = 1; + /* + * See above RE "cheating" + * + * zerr("%s: array assignment failed", name); + */ + if (!cmdoutval) + cmdoutval = 1; + } if (errflag) { state->pc = opc; return; diff --git a/Src/params.c b/Src/params.c index e83e4aa5e..263cd0c52 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1060,8 +1060,7 @@ createparam(char *name, int flags) "BUG: local parameter is not unset"); oldpm = lastpm; } - } else - flags |= PM_NAMEREF; + } } DPUTS(oldpm && oldpm->level > locallevel, @@ -6267,10 +6266,12 @@ resolve_nameref(Param pm, const Asgment stop) } } else if ((hn = gethashnode2(realparamtab, seek))) { if (pm) { - if (!(stop && (stop->flags & (PM_LOCAL)))) - hn = (HashNode)upscope((Param)hn, - ((pm->node.flags & PM_NAMEREF) ? - pm->base : ((Param)hn)->level)); + if (!(stop && (stop->flags & (PM_LOCAL)))) { + int scope = ((pm->node.flags & PM_NAMEREF) ? + ((pm->node.flags & PM_UPPER) ? -1 : + pm->base) : ((Param)hn)->level); + hn = (HashNode)upscope((Param)hn, scope); + } /* user can't tag a nameref, safe for loop detection */ pm->node.flags |= PM_TAGGED; } @@ -6316,11 +6317,13 @@ setloopvar(char *name, char *value) static void setscope(Param pm) { - if (pm->node.flags & PM_NAMEREF) { + queue_signals(); + if (pm->node.flags & PM_NAMEREF) do { Param basepm; struct asgment stop; char *refname = GETREFNAME(pm); char *t = refname ? itype_end(refname, INAMESPC, 0) : NULL; + int q = queue_signal_level(); /* Temporarily change nameref to array parameter itself */ if (t && *t == '[') @@ -6330,9 +6333,11 @@ setscope(Param pm) stop.name = ""; stop.value.scalar = NULL; stop.flags = PM_NAMEREF; - if (locallevel) + if (locallevel && !(pm->node.flags & PM_UPPER)) stop.flags |= PM_LOCAL; + dont_queue_signals(); /* Prevent unkillable loops */ basepm = (Param)resolve_nameref(pm, &stop); + restore_queue_signals(q); if (t) { pm->width = t - refname; *t = '['; @@ -6345,7 +6350,7 @@ setscope(Param pm) if (upscope(pm, pm->base) == pm) { zerr("%s: invalid self reference", refname); unsetparam_pm(pm, 0, 1); - return; + break; } pm->node.flags &= ~PM_SELFREF; } else if (pm->base == pm->level) { @@ -6353,7 +6358,7 @@ setscope(Param pm) strcmp(pm->node.nam, refname) == 0) { zerr("%s: invalid self reference", refname); unsetparam_pm(pm, 0, 1); - return; + break; } } } else if ((t = GETREFNAME(basepm))) { @@ -6361,7 +6366,7 @@ setscope(Param pm) strcmp(pm->node.nam, t) == 0) { zerr("%s: invalid self reference", refname); unsetparam_pm(pm, 0, 1); - return; + break; } } } else @@ -6381,7 +6386,8 @@ setscope(Param pm) zerr("%s: invalid self reference", refname); unsetparam_pm(pm, 0, 1); } - } + } while (0); + unqueue_signals(); } /**/ @@ -6393,6 +6399,8 @@ upscope(Param pm, int reflevel) pm = up; up = up->old; } + if (reflevel < 0 && locallevel > 0) + return pm->level == locallevel ? up : pm; return pm; } diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index ff48e2289..47d32697c 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -492,7 +492,6 @@ F:unexpected side-effects of previous tests } typeset -p ptr2 1:up-reference part 5, stacked namerefs, end not in scope -F:What is the correct behavior for the scope of ptr1? >typeset -n ptr1=ptr2 >typeset -n ptr2 >ptr1=ptr2 @@ -529,6 +528,49 @@ F:Same test, should part 5 output look like this? >typeset -n ptr2 >typeset ptr2=val + () { + () { + local var + typeset -nu ptr1=var + ptr1=outer && print -u2 assignment expected to fail + typeset -n ptr2=var + ptr2=inner + typeset -n + printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" + } + typeset -p var + } + typeset -p var +1:up-reference part 7, upscope namerefs, end not in scope +>ptr1=var +>ptr2=var +>ptr1= +>ptr2=inner +*?*typeset*: no such variable: var +*?*typeset*: no such variable: var + + typeset var + () { + () { + local var + typeset -nu ptr1=var + ptr1=outer || print -u2 assignment expected to succeed + typeset -n ptr2=var + ptr2=inner + typeset -n + printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" + } + typeset -p var + } + typeset -p var +0:up-reference part 8, upscope namerefs, end in scope +>ptr1=var +>ptr2=var +>ptr1=outer +>ptr2=inner +>typeset -g var=outer +>typeset var=outer + if zmodload zsh/parameter; then () { zmodload -u zsh/parameter @@ -539,7 +581,7 @@ F:Same test, should part 5 output look like this? } else ZTST_skip='Cannot zmodload zsh/parameter, skipping autoload test' fi -0:up-reference part 3, autoloading with hidden special +0:up-reference part 9, autoloading with hidden special >nameref-local-nameref-local >typeset -h parameters @@ -762,12 +804,17 @@ F:relies on global TYPESET_TO_UNSET in %prep bar=xx typeset -n foo=bar - () { typeset -n foo; foo=zz; foo=zz; print $bar $zz } + () { + typeset -n foo; foo=zz + foo=zz || print -u2 foo: assignment failed + print $bar $zz + } () { typeset -n foo; foo=zz; local zz; foo=zz; print $bar $zz } 0:regression: local nameref may not in-scope a global parameter F:previously this could create an infinite recursion and crash >xx >xx zz +*?*foo: assignment failed typeset -nm foo=bar 1:create nameref by pattern match not allowed diff --git a/Test/V10private.ztst b/Test/V10private.ztst index efa346002..ed51316f3 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -378,7 +378,7 @@ F:Here ptr1 finds private ptr2 by scope mismatch typeset -p ptr1 ptr2 typeset val=LOCAL () { - ptr1=val # This is a silent no-op, why? + ptr1=val || print -u2 ptr1: assignment failed typeset -n printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" } @@ -388,7 +388,6 @@ F:Here ptr1 finds private ptr2 by scope mismatch 1:up-reference for private namerefs, end not in scope F:See K01nameref.ztst up-reference part 5 F:Here ptr1 finds private ptr2 by scope mismatch -F:Assignment silently fails, is that correct? >typeset -n ptr1=ptr2 >typeset -hn ptr2='' >ptr1=ptr2 @@ -396,6 +395,7 @@ F:Assignment silently fails, is that correct? >ptr2= >typeset -n ptr1=ptr2 >typeset -hn ptr2='' +*?*ptr1: assignment failed *?*no such variable: ptr2 typeset ptr2 -- cgit v1.2.3 From 700f675bf0dcd89f685b9c87b416ecb2e40e6a55 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 4 Mar 2024 21:15:29 -0800 Subject: Add missing test case from 52652 --- Test/D04parameter.ztst | 1 + 1 file changed, 1 insertion(+) diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 69a4fd3ec..0e2a04eb5 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -1222,6 +1222,7 @@ typeset -T STRING string print $STRING $string unset string + typeset -p string STRING=x:y:z print $STRING $string STRING=a:b -- cgit v1.2.3 From 0848b7534ed918503c36a4b217ab5f6053805763 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 4 Mar 2024 21:21:20 -0800 Subject: 52659: Fix crash on unset-through-nameref, add regression test --- ChangeLog | 3 +++ Src/builtin.c | 6 ++++-- Test/K01nameref.ztst | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d4d9922e..bd8eeafcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-03-04 Bart Schaefer + * 52659: Src/builtin.c, Test/K01nameref.ztst: Fix crash when unset + was called on a named referece, add regression test + * 52650 plus minor fixes: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/func.yo, Doc/Zsh/mod_ksh93.yo, Etc/FAQ.yo, Src/Modules/ksh93.c, Src/builtin.c, Src/exec.c, Src/params.c, diff --git a/Src/builtin.c b/Src/builtin.c index ba9cb03c2..0aae1fcde 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3935,9 +3935,11 @@ bin_unset(char *name, char **argv, Options ops, int func) int ref = (pm->node.flags & PM_NAMEREF); if (!(pm = (Param)resolve_nameref(pm, NULL))) continue; - if (ref && pm->level < locallevel) { + if (ref && pm->level < locallevel && + !(pm->node.flags & PM_READONLY)) { /* Just mark unset, do not remove from table */ - pm->node.flags |= PM_DECLARED|PM_UNSET; + stdunsetfn(pm, 0); + pm->node.flags |= PM_DECLARED; continue; } } diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index 47d32697c..e45b922e2 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -711,6 +711,31 @@ F:Checking for a bug in zmodload that affects later tests >typeset -n ref=two >typeset -n ref=var + typeset -g .K01.scalar='RW' + typeset -gA .K01.assoc=(x y) + typeset -ga .K01.array=(z) + typeset -gi .K01.integer=0 + typeset -gE .K01.double=0.0 + typeset -gF .K01.float=0.0 + typeset -gr .K01.readonly='RO' + typeset -n gref + for gref in ARGC .K01.{scalar,assoc,array,integer,double,float,readonly} + do + { unset gref } always { TRY_BLOCK_ERROR=0 } + done + typeset -p .K01.{scalar,assoc,array,integer,double,float,readonly} + unset .K01.{scalar,assoc,array,integer,double,float} +0:unset various types via nameref, including a readonly special +>typeset -g .K01.scalar +>typeset -g -A .K01.assoc +>typeset -g -a .K01.array +>typeset -g -i .K01.integer +>typeset -g -E .K01.double +>typeset -g -F .K01.float +>typeset -g -r .K01.readonly=RO +*?*read-only variable: ARGC +*?*read-only variable: .K01.readonly + unset -n ref unset one typeset -n ref -- cgit v1.2.3 From 83e9dd15c1d76fc5199b98572b271d471fc98dff Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 4 Mar 2024 21:25:26 -0800 Subject: unposted: fix typo in entry attribution --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bd8eeafcf..16ede3665 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -2024-03-04 Bart Schaefer +2024-03-04 Bart Schaefer * 52659: Src/builtin.c, Test/K01nameref.ztst: Fix crash when unset was called on a named referece, add regression test -- cgit v1.2.3 From d27ea2ae02275b255f9efbf929d1dc7932aebc57 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 4 Mar 2024 21:36:45 -0800 Subject: unposted (cf. 52617): only scalars can instantiate a declared named reference --- ChangeLog | 3 +++ Src/params.c | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16ede3665..6dc3e32ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-03-04 Bart Schaefer + * unposted (cf. 52617): Src/params.c: only scalars can instantiate + a declared named reference + * 52659: Src/builtin.c, Test/K01nameref.ztst: Fix crash when unset was called on a named referece, add regression test diff --git a/Src/params.c b/Src/params.c index 263cd0c52..4bcf41c22 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1050,8 +1050,14 @@ createparam(char *name, int flags) name = refname; oldpm = NULL; } else { - if (!(lastpm->node.flags & PM_READONLY)) - lastpm->node.flags |= PM_UNSET; + if (!(lastpm->node.flags & PM_READONLY)) { + if (flags) { + /* Only plain scalar assignment allowed */ + zerr("%s: can't change type of named reference", + name); /* Differs from ksh93u+ */ + return NULL; + } + } return lastpm; } } else { -- cgit v1.2.3 From c0a392b3924951a316f7183e89afd302c5f680e8 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 4 Mar 2024 21:39:29 -0800 Subject: unposted (cf. 52615): use META_NOALLOC for 52591 --- ChangeLog | 2 ++ Src/builtin.c | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6dc3e32ee..b4ebfedbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-03-04 Bart Schaefer + * unposted (cf. 52615): Src/builtin.c: use META_NOALLOC for 52591 + * unposted (cf. 52617): Src/params.c: only scalars can instantiate a declared named reference diff --git a/Src/builtin.c b/Src/builtin.c index 0aae1fcde..6f98990f9 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5255,7 +5255,7 @@ bin_print(char *name, char **args, Options ops, int func) } } if (*argp) { - width = (int)mathevali(metafy(*argp, len[argp - args], META_USEHEAP)); + width = (int)mathevali(metafy(*argp, len[argp - args], META_NOALLOC)); argp++; if (errflag) { errflag &= ~ERRFLAG_ERROR; @@ -5290,7 +5290,7 @@ bin_print(char *name, char **args, Options ops, int func) } if (*argp) { - prec = (int)mathevali(metafy(*argp, len[argp - args], META_USEHEAP)); + prec = (int)mathevali(metafy(*argp, len[argp - args], META_NOALLOC)); argp++; if (errflag) { errflag &= ~ERRFLAG_ERROR; @@ -5403,7 +5403,7 @@ bin_print(char *name, char **args, Options ops, int func) break; case 'q': stringval = curarg ? - quotestring(metafy(curarg, curlen, META_USEHEAP), + quotestring(metafy(curarg, curlen, META_NOALLOC), QT_BACKSLASH_SHOWNULL) : &nullstr; *d = 's'; print_val(unmetafy(stringval, &curlen)); @@ -5475,7 +5475,7 @@ bin_print(char *name, char **args, Options ops, int func) *d++ = 'l'; #endif *d++ = 'l', *d++ = *c, *d = '\0'; - zlongval = (curarg) ? mathevali(metafy(curarg, curlen, META_HEAPDUP)) : 0; + zlongval = (curarg) ? mathevali(metafy(curarg, curlen, META_NOALLOC)) : 0; if (errflag) { zlongval = 0; errflag &= ~ERRFLAG_ERROR; @@ -5526,7 +5526,7 @@ bin_print(char *name, char **args, Options ops, int func) if (!curarg) zulongval = (zulong)0; else if (!zstrtoul_underscore(curarg, &zulongval)) - zulongval = mathevali(metafy(curarg, curlen, META_HEAPDUP)); + zulongval = mathevali(metafy(curarg, curlen, META_NOALLOC)); if (errflag) { zulongval = 0; errflag &= ~ERRFLAG_ERROR; -- cgit v1.2.3 From b56250e9b99d9cd0e70261ff6e7f6f33583c1b04 Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Tue, 5 Mar 2024 19:57:35 +0000 Subject: 52685: fix typo in the name of bash's BASH_ENV variable. --- ChangeLog | 5 +++++ Doc/Zsh/restricted.yo | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b4ebfedbc..68f826342 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-05 Stephane Chazelas + + * 52685: Doc/Zsh/restricted.yo: fix typo in the name of bash's + BASH_ENV variable. + 2024-03-04 Bart Schaefer * unposted (cf. 52615): Src/builtin.c: use META_NOALLOC for 52591 diff --git a/Doc/Zsh/restricted.yo b/Doc/Zsh/restricted.yo index 7948cfe8a..a84fd28ea 100644 --- a/Doc/Zsh/restricted.yo +++ b/Doc/Zsh/restricted.yo @@ -68,7 +68,7 @@ If a `tt(perl)', `tt(python)', `tt(bash)', or other general purpose interpreted script is treated as a restricted command, the user can work around the restriction by setting specially crafted `tt(PERL5LIB)', `tt(PYTHONPATH)', -`tt(BASHENV)' (etc.) environment variables. On GNU systems, any +`tt(BASH_ENV)' (etc.) environment variables. On GNU systems, any command can be made to run arbitrary code when performing character set conversion (including zsh itself) by setting a `tt(GCONV_PATH)' environment variable. Those are only a few examples. -- cgit v1.2.3 From 330821de01ebf1115079222f719c9a28cc26ff57 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 5 Mar 2024 21:13:33 -0800 Subject: 52692: local typeset of the name of a named reference hides the reference --- ChangeLog | 7 +++++++ Doc/Zsh/params.yo | 5 +++-- Src/builtin.c | 15 ++++++++------- Src/params.c | 3 ++- Test/K01nameref.ztst | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 68 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68f826342..a3cec14ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-03-05 Bart Schaefer + + * 52692: Doc/Zsh/params.yo, Src/builtin.c, Src/params.c, + Test/K01nameref.ztst: local declaration (typeset) of the + name of a named reference hides the reference rather than + following it. Also fix two related crash bugs. + 2024-03-05 Stephane Chazelas * 52685: Doc/Zsh/restricted.yo: fix typo in the name of bash's diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 8c5e67e70..d179a0d1d 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -670,8 +670,9 @@ This manual was generated with Zsh tt(version()). When a em(named reference) is created with `tt(typeset -n)', all uses of var(pname) in assignments and expansions instead assign to or expand var(rname). This also applies to `tt(unset )var(pname)' and to -most subsequent uses of `tt(typeset)' with the exception of -`tt(typeset -n)' and `tt(typeset +n)', so to remove a named reference, +most subsequent uses of `tt(typeset)' with the exceptions of declaring +a local in a called function, or updating a current-scope parameter with +`tt(typeset -n)' or `tt(typeset +n)'. Thus to remove a named reference, use either `tt(unset -n )var(pname)' (preferred) or one of: ifzman() example(tt(typeset -n )var(pname=) diff --git a/Src/builtin.c b/Src/builtin.c index 6f98990f9..829b899f8 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2030,11 +2030,10 @@ typeset_single(char *cname, char *pname, Param pm, int func, int usepm, tc, keeplocal = 0, newspecial = NS_NONE, readonly, dont_set = 0; char *subscript; - if (pm && (pm->node.flags & PM_NAMEREF) && !((off|on) & PM_NAMEREF)) { - if (!(off & PM_NAMEREF)) { - if ((pm = (Param)resolve_nameref(pm, NULL))) - pname = pm->node.nam; - } + if (pm && (pm->node.flags & PM_NAMEREF) && !((off|on) & PM_NAMEREF) && + (pm->level == locallevel || !(on & PM_LOCAL))) { + if ((pm = (Param)resolve_nameref(pm, NULL))) + pname = pm->node.nam; if (pm && (pm->node.flags & PM_NAMEREF) && (on & ~(PM_NAMEREF|PM_LOCAL|PM_READONLY))) { /* Changing type of PM_SPECIAL|PM_AUTOLOAD is a fatal error. * @@ -3125,8 +3124,10 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) oldpm->u.str) asg->value.scalar = dupstring(oldpm->u.str); /* Defer read-only error to typeset_single() */ - if (!(hn->flags & PM_READONLY)) + if (!(hn->flags & PM_READONLY)) { unsetparam_pm(oldpm, 0, 1); + hn = NULL; + } } /* Passing a NULL pm to typeset_single() makes the * nameref read-only before assignment, which breaks @@ -3134,7 +3135,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) * so this is special-cased to permit that action * like assign-at-create for other parameter types. */ - if (!(hn->flags & PM_READONLY)) + if (hn && !(hn->flags & PM_READONLY)) hn = NULL; } } diff --git a/Src/params.c b/Src/params.c index 4bcf41c22..973df3fe5 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1034,7 +1034,8 @@ createparam(char *name, int flags) } if (oldpm && !(flags & PM_NAMEREF) && - (!(oldpm->node.flags & PM_RO_BY_DESIGN) || !(flags & PM_LOCAL)) && + (oldpm->level == locallevel ? + !(oldpm->node.flags & PM_RO_BY_DESIGN) : !(flags & PM_LOCAL)) && (oldpm->node.flags & PM_NAMEREF) && (oldpm = upscope(oldpm, oldpm->base))) { Param lastpm; diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index e45b922e2..bb0d11821 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -51,9 +51,19 @@ 0:remove nameref attribute >typeset ptr=var - typeset -n ptr - typeset -t ptr - typeset -p ptr + typeset -n ptr=gvar + () { + local ptr + typeset -p ptr + } + typeset -p ptr +0:Local non-reference hides outside reference +>typeset ptr +>typeset -n ptr=gvar + + typeset -n ptr + typeset -t ptr + typeset -p ptr 0:change type of a placeholder F:Other type changes are fatal errors, should this also be? >typeset -n ptr='' @@ -845,4 +855,39 @@ F:previously this could create an infinite recursion and crash 1:create nameref by pattern match not allowed *?*typeset:1: invalid reference +# +# The following tests are run in interactive mode, using PS1 as an +# assignable special with side-effects. This crashed at one time. +# + + # Note bypassing TYPESET_TO_UNSET here + $ZTST_testdir/../Src/zsh -fis <<<$' + typeset -n p=PS1 + () { + typeset -p p + local p + typeset -p p + p=xx + typeset -p p + } + ' +0:regression: assign to local that shadows global named reference +>typeset -g -n p=PS1 +>typeset p='' +>typeset p=xx +*?* + + # Note bypassing TYPESET_TO_UNSET here + $ZTST_testdir/../Src/zsh -fis <<<$' + () { + typeset p=PS1 + typeset -n p + p=zz + } + typeset -p PS1 + ' +0:regression - converting a string into a named reference +>typeset PS1=zz +*?* + %clean -- cgit v1.2.3 From fa9b3ad5977ede0a4635cd86276dd0f0c2f6f03e Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Fri, 8 Mar 2024 11:07:05 +0000 Subject: 52704: improve zsh_eval_context documentation --- ChangeLog | 6 ++++++ Doc/Zsh/params.yo | 11 ++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index a3cec14ab..ef6c9f02d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-03-08 Stephane Chazelas + + * 52704: Doc/Zsh/params.yo, mention new ${ ... } and ${|...} + operators and fix process substitution terminology in + documentation of $zsh_eval_context. + 2024-03-05 Bart Schaefer * 52692: Doc/Zsh/params.yo, Src/builtin.c, Src/params.c, diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index d179a0d1d..9516c84de 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1031,11 +1031,12 @@ Code specified by the tt(-c) option to the command line that invoked the shell. ) item(tt(cmdsubst))( -Command substitution using the tt(`)var(...)tt(`) or -tt($+LPAR())var(...)tt(RPAR()) construct. +Command substitution using of the tt(`)var(...)tt(`), +tt($+LPAR())var(...)tt(RPAR()), tt(${ )var(...)tt( }) or +tt(${|)var(...)tt(}) constructs. ) item(tt(equalsubst))( -File substitution using the tt(=+LPAR())var(...)tt(RPAR()) construct. +The tt(=+LPAR())var(...)tt(RPAR()) form of process substitution. ) item(tt(eval))( Code executed by the tt(eval) builtin. @@ -1063,13 +1064,13 @@ item(tt(globsort))( Code executed to order files by the tt(o) glob qualifier. ) item(tt(insubst))( -File substitution using the tt(LPAR())var(...)tt(RPAR()) construct. +The tt(>LPAR())var(...)tt(RPAR()) form of process substitution. ) item(tt(sched))( Code executed by the tt(sched) builtin. -- cgit v1.2.3 From 47c7bc9b1493c7374f076b5471cfd57ee30f4ba5 Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Sat, 9 Mar 2024 11:45:46 +0000 Subject: 52721: fix metafication and regexp/subject confusion in pcre_match error message --- ChangeLog | 5 +++++ Src/Modules/pcre.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ef6c9f02d..620c74fcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-09 Stephane Chazelas + + * 52721: fix metafication and regexp/subject confusion in + pcre_match error message. + 2024-03-08 Stephane Chazelas * 52704: Doc/Zsh/params.yo, mention new ${ ... } and ${|...} diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index a49d1a307..67157cc01 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -405,7 +405,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) else { PCRE2_UCHAR buffer[256]; pcre2_get_error_message(ret, buffer, sizeof(buffer)); - zwarnnam(nam, "error in pcre matching for /%s/: %s", plaintext, buffer); + zwarnnam(nam, "error in pcre matching for %s: %s", *args, buffer); } if (pcre_mdata) -- cgit v1.2.3 From ea5a5d6ec430cad1a73f3179fcc018c90a315c35 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 9 Mar 2024 22:02:57 -0800 Subject: 52725: updated named reference semantics --- ChangeLog | 4 ++++ Src/Modules/ksh93.c | 44 ++++++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 620c74fcf..a2609a1cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-03-09 Bart Schaefer + + * 52725: Src/Modules/ksh93.c: updated named reference semantics + 2024-03-09 Stephane Chazelas * 52721: fix metafication and regexp/subject confusion in diff --git a/Src/Modules/ksh93.c b/Src/Modules/ksh93.c index 6760cbca0..8d10317dc 100644 --- a/Src/Modules/ksh93.c +++ b/Src/Modules/ksh93.c @@ -113,18 +113,17 @@ static char sh_edmode[2]; * obviously includes those commented out here. */ static struct paramdef partab[] = { - PARAMDEF(".sh.command", PM_NAMEREF|PM_READONLY, "ZSH_DEBUG_CMD", &constant_gsu), - PARAMDEF(".sh.edchar", PM_SCALAR|PM_SPECIAL, &sh_edchar, &sh_edchar_gsu), - PARAMDEF(".sh.edcol", PM_NAMEREF|PM_READONLY, "CURSOR", &constant_gsu), - PARAMDEF(".sh.edmode", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_edmode, &sh_edmode_gsu), - PARAMDEF(".sh.edtext", PM_NAMEREF|PM_READONLY, "BUFFER", &constant_gsu), + PARAMDEF(".sh.edchar", PM_SCALAR|PM_SPECIAL, + &sh_edchar, &sh_edchar_gsu), + PARAMDEF(".sh.edmode", PM_SCALAR|PM_READONLY|PM_SPECIAL, + &sh_edmode, &sh_edmode_gsu), PARAMDEF(".sh.file", PM_NAMEREF|PM_READONLY, "ZSH_SCRIPT", &constant_gsu), - /* PARAMDEF(".sh.fun", PM_SCALAR|PM_UNSET, NULL, &constant_gsu), */ - /* PARAMDEF(".sh.level", PM_INTEGER|PM_UNSET, NULL, &constant_gsu), */ PARAMDEF(".sh.lineno", PM_NAMEREF|PM_READONLY, "LINENO", &constant_gsu), PARAMDEF(".sh.match", PM_ARRAY|PM_READONLY, NULL, &sh_match_gsu), - PARAMDEF(".sh.name", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_name, &sh_name_gsu), - PARAMDEF(".sh.subscript", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_subscript, &sh_subscript_gsu), + PARAMDEF(".sh.name", PM_SCALAR|PM_READONLY|PM_SPECIAL, + &sh_name, &sh_name_gsu), + PARAMDEF(".sh.subscript", PM_SCALAR|PM_READONLY|PM_SPECIAL, + &sh_subscript, &sh_subscript_gsu), PARAMDEF(".sh.subshell", PM_NAMEREF|PM_READONLY, "ZSH_SUBSHELL", &constant_gsu), /* SPECIALPMDEF(".sh.value", 0, NULL, NULL, NULL), */ PARAMDEF(".sh.version", PM_NAMEREF|PM_READONLY, "ZSH_PATCHLEVEL", &constant_gsu) @@ -156,15 +155,35 @@ ksh93_wrapper(Eprog prog, FuncWrap w, char *name) queue_signals(); ++locallevel; /* Make these local */ - if ((pm = createparam(".sh.level", PM_LOCAL|PM_UNSET))) { +#define LOCAL_NAMEREF (PM_LOCAL|PM_UNSET|PM_NAMEREF) + if ((pm = createparam(".sh.command", LOCAL_NAMEREF))) { pm->level = locallevel; /* Why is this necessary? */ - setiparam(".sh.level", num); + /* Force scoping by assignent hack */ + setloopvar(".sh.command", "ZSH_DEBUG_CMD"); + pm->node.flags |= PM_READONLY; } + /* .sh.edchar is in partab and below */ + if (zleactive && (pm = createparam(".sh.edcol", LOCAL_NAMEREF))) { + pm->level = locallevel; + setloopvar(".sh.edcol", "CURSOR"); + pm->node.flags |= (PM_NAMEREF|PM_READONLY); + } + /* .sh.edmode is in partab and below */ + if (zleactive && (pm = createparam(".sh.edtext", LOCAL_NAMEREF))) { + pm->level = locallevel; + setloopvar(".sh.edtext", "BUFFER"); + pm->node.flags |= PM_READONLY; + } + if ((pm = createparam(".sh.fun", PM_LOCAL|PM_UNSET))) { pm->level = locallevel; setsparam(".sh.fun", ztrdup(name)); pm->node.flags |= PM_READONLY; } + if ((pm = createparam(".sh.level", PM_LOCAL|PM_UNSET))) { + pm->level = locallevel; + setiparam(".sh.level", num); + } if (zleactive) { extern mod_import_variable char *curkeymapname; /* XXX */ extern mod_import_variable char *varedarg; /* XXX */ @@ -186,9 +205,10 @@ ksh93_wrapper(Eprog prog, FuncWrap w, char *name) *--ie = '\0'; } else sh_subscript = NULL; - if ((pm = createparam(".sh.value", PM_LOCAL|PM_NAMEREF|PM_UNSET))) { + if ((pm = createparam(".sh.value", LOCAL_NAMEREF))) { pm->level = locallevel; setloopvar(".sh.value", "BUFFER"); /* Hack */ + pm->node.flags |= PM_READONLY; } } else sh_name = sh_subscript = NULL; -- cgit v1.2.3 From 37f434498eb626a10e3009216afa306e5ae841c6 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 13 Mar 2024 00:35:10 +0100 Subject: 52724: fix .zle.sgr for empty sequences --- ChangeLog | 4 ++++ Src/Modules/hlgroup.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index a2609a1cf..f136bc6b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-03-13 Oliver Kiddle + + * 52724: Src/Modules/hlgroup.c: fix .zle.sgr for empty sequences + 2024-03-09 Bart Schaefer * 52725: Src/Modules/ksh93.c: updated named reference semantics diff --git a/Src/Modules/hlgroup.c b/Src/Modules/hlgroup.c index 6382f3216..9c0aedcf8 100644 --- a/Src/Modules/hlgroup.c +++ b/Src/Modules/hlgroup.c @@ -59,6 +59,10 @@ convertattr(char *attrstr, int sgr) *t = ';'; c++; } + if (t <= s) { /* always return at least "0" */ + *s = '0'; + t = s + 1; + } *t = '\0'; len = t - s; } -- cgit v1.2.3 From 7c875adb0968b308e9b989ae5ac8d245b58810f2 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 12 Mar 2024 18:00:19 -0700 Subject: 52742: fix bad interactions of "typeset -p" with GLOBAL_EXPORT --- ChangeLog | 5 +++++ Src/builtin.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index f136bc6b4..c8935fb61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-12 Bart Schaefer + + * 52742: Src/builtin.c: fix bad interactions of "typeset -p" with + GLOBAL_EXPORT, plus some other inconsistencies. + 2024-03-13 Oliver Kiddle * 52724: Src/Modules/hlgroup.c: fix .zle.sgr for empty sequences diff --git a/Src/builtin.c b/Src/builtin.c index 829b899f8..7bfb1ce1d 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2059,7 +2059,7 @@ typeset_single(char *cname, char *pname, Param pm, int func, * POSIXBUILTINS horror: we need to retain the 'readonly' or 'export' * flags of an unset parameter. */ - usepm = pm && (!(pm->node.flags & PM_UNSET) || + usepm = pm && (!(pm->node.flags & PM_UNSET) || OPT_ISSET(ops, 'p') || (isset(POSIXBUILTINS) && (pm->node.flags & (PM_READONLY|PM_EXPORTED)))); @@ -2195,7 +2195,7 @@ typeset_single(char *cname, char *pname, Param pm, int func, else if (newspecial != NS_NONE && strcmp(pname, "SECONDS") == 0) newspecial = NS_SECONDS; - if (isset(POSIXBUILTINS)) { + if (isset(POSIXBUILTINS) && !OPT_ISSET(ops,'p')) { /* * Stricter rules about retaining readonly attribute in this case. */ @@ -2224,7 +2224,8 @@ typeset_single(char *cname, char *pname, Param pm, int func, * ii. we are creating a new local parameter */ if (usepm) { - if (OPT_MINUS(ops,'p') && on && !(on & pm->node.flags)) + if (OPT_MINUS(ops,'p') && on && + !((on & pm->node.flags) || ((on & PM_LOCAL) && pm->level))) return NULL; else if (OPT_PLUS(ops,'p') && off && !(off & pm->node.flags)) return NULL; @@ -2339,7 +2340,8 @@ typeset_single(char *cname, char *pname, Param pm, int func, return NULL; pm->node.flags |= (on & PM_READONLY); return pm; - } + } else if (OPT_ISSET(ops,'p')) + return NULL; /* Nothing to print */ if ((asg->flags & ASG_ARRAY) ? !(on & (PM_ARRAY|PM_HASHED)) : @@ -2686,6 +2688,15 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) if (func == BIN_READONLY && isset(POSIXBUILTINS) && !OPT_PLUS(ops, 'g')) ops->ind['g'] = 1; +#if 0 + /* "local" rejects -m, this should too ... what about +m ? */ + if (locallevel && OPT_MINUS(ops, 'm') && + !(OPT_MINUS(ops, 'g') || OPT_ISSET(ops, 'p'))) { + zerrnam(name, "bad option: -m"); + return 1; + } +#endif + /* Translate the options into PM_* flags. * * Unfortunately, this depends on the order * * these flags are defined in zsh.h */ @@ -2788,10 +2799,18 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) return 0; } - if (!(OPT_ISSET(ops,'g') || OPT_ISSET(ops,'x') || OPT_ISSET(ops,'m')) || - OPT_PLUS(ops,'g') || *name == 'l' || - (!isset(GLOBALEXPORT) && !OPT_ISSET(ops,'g'))) - on |= PM_LOCAL; + /* Using *name here is cheating, "local" allows no -g option */ + if ((*name == 'l' || OPT_PLUS(ops,'g'))) + on |= PM_LOCAL; + else if (!OPT_ISSET(ops,'g')) { + if (OPT_MINUS(ops, 'x')) { + if (isset(GLOBALEXPORT)) + ops->ind['g'] = 1; + else if (locallevel) + on |= PM_LOCAL; + } else if (!(OPT_ISSET(ops,'x') || OPT_ISSET(ops,'m'))) + on |= PM_LOCAL; + } if ((on & PM_TIED) && !OPT_ISSET(ops, 'p')) { Param apm; -- cgit v1.2.3 From 8adfbfc1f05200d566b9830232d0dabf82c84283 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 12 Mar 2024 18:02:38 -0700 Subject: unposted: "typeset -p" has problems with special parameters having NULL values --- ChangeLog | 3 +++ Src/Modules/ksh93.c | 15 ++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c8935fb61..389054f14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-03-12 Bart Schaefer + * unposted: Src/Modules/ksh93.c: "typeset -p" has problems with + special parameters having NULL values, use a dummy static instead. + * 52742: Src/builtin.c: fix bad interactions of "typeset -p" with GLOBAL_EXPORT, plus some other inconsistencies. diff --git a/Src/Modules/ksh93.c b/Src/Modules/ksh93.c index 8d10317dc..3206c11f3 100644 --- a/Src/Modules/ksh93.c +++ b/Src/Modules/ksh93.c @@ -102,9 +102,10 @@ static const struct gsu_scalar sh_name_gsu = static const struct gsu_scalar sh_subscript_gsu = { strvargetfn, nullstrsetfn, nullunsetfn }; -static char *sh_name; -static char *sh_subscript; -static char *sh_edchar; +static char sh_unsetval[2]; /* Dummy to treat as NULL */ +static char *sh_name = sh_unsetval; +static char *sh_subscript = sh_unsetval; +static char *sh_edchar = sh_unsetval; static char sh_edmode[2]; /* @@ -193,7 +194,7 @@ ksh93_wrapper(Eprog prog, FuncWrap w, char *name) strcpy(sh_edmode, "\033"); else strcpy(sh_edmode, ""); - if (!sh_edchar) + if (sh_edchar == sh_unsetval) sh_edchar = dupstring(getsparam("KEYS")); if (varedarg) { char *ie = itype_end((sh_name = dupstring(varedarg)), INAMESPC, 0); @@ -204,16 +205,16 @@ ksh93_wrapper(Eprog prog, FuncWrap w, char *name) ie = sh_subscript + strlen(sh_subscript); *--ie = '\0'; } else - sh_subscript = NULL; + sh_subscript = sh_unsetval; if ((pm = createparam(".sh.value", LOCAL_NAMEREF))) { pm->level = locallevel; setloopvar(".sh.value", "BUFFER"); /* Hack */ pm->node.flags |= PM_READONLY; } } else - sh_name = sh_subscript = NULL; + sh_name = sh_subscript = sh_unsetval; } else { - sh_edchar = sh_name = sh_subscript = NULL; + sh_edchar = sh_name = sh_subscript = sh_unsetval; strcpy(sh_edmode, ""); /* TODO: * - disciplines -- cgit v1.2.3 From d1e041188db6900e7f8aca2e9fec71d74270babc Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 13 Mar 2024 11:36:16 -0700 Subject: unposted: update doc for "colors" for workers/47489,50212 (italic and bright) --- ChangeLog | 5 +++++ Doc/Zsh/contrib.yo | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 389054f14..87053e78f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-13 Bart Schaefer + + * unposted: Doc/Zsh/contrib.yo: update doc for "colors" to match + workers/47489,50212 (italic and bright) + 2024-03-12 Bart Schaefer * unposted: Src/Modules/ksh93.c: "typeset -p" has problems with diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index e682c800a..c1bea6022 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -4313,13 +4313,17 @@ tt(colors) more than once. The eight base colors are: tt(black), tt(red), tt(green), tt(yellow), tt(blue), tt(magenta), tt(cyan), and tt(white). Each of these has codes for foreground and background. In addition there are seven intensity attributes: -tt(bold), tt(faint), tt(standout), tt(underline), tt(blink), tt(reverse), +tt(bold), tt(faint), tt(italic), tt(underline), tt(blink), tt(reverse), and tt(conceal). Finally, there are seven codes used to negate attributes: tt(none) (reset all attributes to the defaults), tt(normal) -(neither bold nor faint), tt(no-standout), tt(no-underline), tt(no-blink), +(neither bold nor faint), tt(no-italic), tt(no-underline), tt(no-blink), tt(no-reverse), and tt(no-conceal). Some terminals do not support all combinations of colors and intensities. +Prior to zsh tt(5.8.1) the intensity tt(standout) was provided. It has +been replaced by the more specific tt(italic) and tt(reverse) to match +the specification, but some terminals may swap these or make one of them +produce blinking text even if the tt(blink) code is not usable. The associative arrays are: -- cgit v1.2.3 From 21fe2dce441116e90a6611527f1fcbccdc97a856 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 13 Mar 2024 21:10:23 -0700 Subject: 52753: Clarify "nocorrect" when introducing precommand modifiers. --- ChangeLog | 3 +++ Doc/Zsh/grammar.yo | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87053e78f..ab59d83d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-03-13 Bart Schaefer + * 52753: Doc/Zsh/grammar.yo: Clarify "nocorrect" when introducing + precommand modifiers. + * unposted: Doc/Zsh/contrib.yo: update doc for "colors" to match workers/47489,50212 (italic and bright) diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo index 915b93bc0..b80f9750c 100644 --- a/Doc/Zsh/grammar.yo +++ b/Doc/Zsh/grammar.yo @@ -100,14 +100,15 @@ More generally, a list can be seen as a set of any shell commands whatsoever, including the complex commands below; this is implied wherever the word `list' appears in later descriptions. For example, the commands in a shell function form a special sort of list. + texinode(Precommand Modifiers)(Complex Commands)(Simple Commands & Pipelines)(Shell Grammar) sect(Precommand Modifiers) cindex(precommand modifiers) cindex(modifiers, precommand) -A simple command may be preceded by a em(precommand modifier), -which will alter how the command is interpreted. These modifiers are -shell builtin commands with the exception of tt(nocorrect) which is -a reserved word. +With the exception of tt(nocorrect), which is a reserved word that +affects further parsing when it is found in command position, each +of the following builtin commands is a em(precommand modifier) which +may precede a simple command to alter how that command is interpreted. startitem() findex(-) @@ -158,8 +159,7 @@ before any parsing is done. It has no effect in non-interactive shells. ) findex(noglob) item(tt(noglob))( -Filename generation (globbing) is not performed on any of -the words. +Filename generation (globbing) is not performed on any of the words. ) enditem() texinode(Complex Commands)(Alternate Forms For Complex Commands)(Precommand Modifiers)(Shell Grammar) -- cgit v1.2.3 From 326e8635fe01239ddf14c09785eeca2394e32b95 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 14 Mar 2024 13:11:31 -0700 Subject: 52752: typeset -p fixes for local exports and "export -x" / "readonly -r" output. --- ChangeLog | 5 +++++ Src/params.c | 21 ++++++++++++++++++--- Test/B02typeset.ztst | 14 +++++++------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index ab59d83d7..5eca27d43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-14 Bart Schaefer + + * 52752: Src/params.c, Test/B02typeset.ztst: more typeset -p fixes + for local exports and improper "export -x" / "readonly -r" output. + 2024-03-13 Bart Schaefer * 52753: Doc/Zsh/grammar.yo: Clarify "nocorrect" when introducing diff --git a/Src/params.c b/Src/params.c index 973df3fe5..f65aa1e80 100644 --- a/Src/params.c +++ b/Src/params.c @@ -6044,6 +6044,7 @@ printparamnode(HashNode hn, int printflags) { Param p = (Param) hn; Param peer = NULL; + int altname = 0; if (!(p->node.flags & PM_HASHELEM) && !(printflags & PRINT_WITH_NAMESPACE) && *(p->node.nam) == '.') @@ -6089,16 +6090,26 @@ printparamnode(HashNode hn, int printflags) if (printflags & PRINT_POSIX_EXPORT) { if (!(p->node.flags & PM_EXPORTED)) return; + altname = 'x'; printf("export "); } else if (printflags & PRINT_POSIX_READONLY) { if (!(p->node.flags & PM_READONLY)) return; + altname = 'r'; printf("readonly "); - } else if (locallevel && p->level >= locallevel) { - printf("typeset "); /* printf("local "); */ } else if ((p->node.flags & PM_EXPORTED) && !(p->node.flags & (PM_ARRAY|PM_HASHED))) { - printf("export "); + if (p->level && p->level >= locallevel) + printf("local "); + else { + altname = 'x'; + printf("export "); + } + } else if (locallevel && p->level >= locallevel) { + if (p->node.flags & PM_EXPORTED) + printf("local "); + else + printf("typeset "); /* printf("local "); */ } else if (locallevel) { printf("typeset -g "); } else @@ -6112,6 +6123,10 @@ printparamnode(HashNode hn, int printflags) for (pmptr = pmtypes, i = 0; i < PMTYPES_SIZE; i++, pmptr++) { int doprint = 0; + + if (altname && altname == pmptr->typeflag) + continue; + if (pmptr->flags & PMTF_TEST_LEVEL) { if (p->level) { /* diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index d90f17d13..914eea92b 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -311,7 +311,7 @@ print $OUTER 0:Export of tied parameters >i:n:n:e:r ->typeset -xT OUTER outer=( i n n e r ) +>local -xT OUTER outer=( i n n e r ) >typeset -aT OUTER outer=( i n n e r ) >OUTER=i:n:n:e:r >outer=( i n n e r ) @@ -1099,12 +1099,12 @@ } 0: no array/hash in POSIX export/readonly -p >zsh: ->typeset -arx zsh_exported_readonly_array=( 2 ) ->typeset -Arx zsh_exported_readonly_hash=( [3]=3 ) ->typeset -rx zsh_exported_readonly_scalar=1 ->typeset -arx zsh_exported_readonly_array=( 2 ) ->typeset -Arx zsh_exported_readonly_hash=( [3]=3 ) ->typeset -rx zsh_exported_readonly_scalar=1 +>local -arx zsh_exported_readonly_array=( 2 ) +>local -Arx zsh_exported_readonly_hash=( [3]=3 ) +>local -rx zsh_exported_readonly_scalar=1 +>local -arx zsh_exported_readonly_array=( 2 ) +>local -Arx zsh_exported_readonly_hash=( [3]=3 ) +>local -rx zsh_exported_readonly_scalar=1 >sh: >export zsh_exported_readonly_scalar=1 >readonly zsh_exported_readonly_scalar=1 -- cgit v1.2.3 From 45b0a838aa6e05131523dee291c561cf86f04771 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 14 Mar 2024 13:22:11 -0700 Subject: unposted: Note bug that HIST_IGNORE_DUPS mishandles quoted whitespace. --- ChangeLog | 2 ++ Etc/BUGS | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5eca27d43..c3f770477 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-03-14 Bart Schaefer + * unposted: Etc/BUGS: HIST_IGNORE_DUPS mishandles quoted whitespace. + * 52752: Src/params.c, Test/B02typeset.ztst: more typeset -p fixes for local exports and improper "export -x" / "readonly -r" output. diff --git a/Etc/BUGS b/Etc/BUGS index b6ee30cbb..dee115ee0 100644 --- a/Etc/BUGS +++ b/Etc/BUGS @@ -57,4 +57,7 @@ and thus the expression is likely to be incorrectly interpreted. ------------------------------------------------------------------------ 52521: Empty files and unreadable files cannot be removed using the mapfile module "unset 'mapfile[filename]'", and are not distinguished -from files that do not exist. \ No newline at end of file +from files that do not exist. +------------------------------------------------------------------------ +52747,52755: HIST_IGNORE_DUPS et. al. ignore syntactically significant +quoted whitespace and can incorrectly exclude commands as duplicates. -- cgit v1.2.3 From 25182cc2e69ab1cfeeb3f0faa1d28d774393043b Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 17 Mar 2024 14:28:28 -0700 Subject: 52759: ${ ... } trims one trailing newline; "${ ... }" preserves that newline. --- ChangeLog | 5 +++++ Doc/Zsh/expn.yo | 3 +++ Etc/FAQ.yo | 21 ++++++++++++--------- Src/subst.c | 8 ++++++-- Test/D10nofork.ztst | 41 +++++++++++++++++++++++++++++++++++------ 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index c3f770477..7e5f68059 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2024-03-14 Bart Schaefer + * 52759: Doc/Zsh/expn.yo, Etc/FAQ.yo, Src/subst.c, + Test/D10nofork.ztst: change ${ ... } substitution to trim one + trailing newline; instead "${ ... }" (with quotes) preserves that + newline. All trailing newlines are still trimmed in emulations. + * unposted: Etc/BUGS: HIST_IGNORE_DUPS mishandles quoted whitespace. * 52752: Src/params.c, Test/B02typeset.ztst: more typeset -p fixes diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 183ca6e03..0e121e784 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1950,6 +1950,9 @@ the braces by whitespace, like `tt(${ )...tt( })', is replaced by its standard output. Like `tt(${|)...tt(})' and unlike `tt($LPAR())...tt(RPAR())', the command executes in the current shell context with function local behaviors and does not create a subshell. +Word splitting does not apply unless tt(SH_WORD_SPLIT) is set, but a +single trailing newline is stripped unless the substitution is enclosed +in double quotes. Note that because the `tt(${|)...tt(})' and `tt(${ )...tt( })' forms must be parsed at once as both string tokens and commands, all other diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 4a86050e6..4d71c8f30 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -1091,20 +1091,23 @@ sect(Comparisons of forking and non-forking command substitution) mytt(set -- pos1 pos2 etc). Nothing that happens within mytt($(command)) affects the caller. - mytt($(command)) removes trailing newlines from the output of mytt(command) - when substituting, whereas mytt(${ command }) and its variants do not. - The latter is consistent with mytt(${|...}) from mksh but differs from - bash and ksh, so in emulation modes, newlines are stripped from command - output (not from tt(REPLY) assignments). - When not enclosed in double quotes, the expansion of mytt($(command)) is split on tt(IFS) into an array of words. In contrast, and unlike both bash and ksh, unquoted non-forking substitutions behave like parameter expansions with respect to the tt(SH_WORD_SPLIT) option. - When mytt(command) is myem(not) a builtin, mytt(${ command }) does fork, and - typically forks the same number of times as mytt($(command)), because in - the latter case zsh usually optimizes the final fork into an exec. + Both of the mytt(${|...}) formats retain any trailing newlines, + except as handled by the tt(SH_WORD_SPLIT) option, consistent with + mytt(${|...}) from mksh. mytt(${ command }) removes a single final + newline, but mytt("${ command }") retains it. This differs from + bash and ksh, so in emulation modes, newlines are stripped even from + quoted command output. In all cases, mytt($(command)) removes all + trailing newlines from the output of mytt(command). + + When mytt(command) is myem(not) a builtin, mytt(${ command }) does + fork, and typically forks the same number of times as + mytt($(command)), because in the latter case zsh usually optimizes + the final fork into an exec. Redirecting input from files has subtle differences: itemization( diff --git a/Src/subst.c b/Src/subst.c index 49f7336bb..9d20a2d0e 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1900,6 +1900,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, /* The command string to be run by ${|...;} */ char *cmdarg = NULL; size_t slen = 0; + int trim = (!EMULATION(EMULATE_ZSH)) ? 2 : !qt; inbrace = 1; s++; @@ -2005,10 +2006,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, int onoerrs = noerrs, rplylen; noerrs = 2; rplylen = zstuff(&cmdarg, rplytmp); - if (! EMULATION(EMULATE_ZSH)) { + if (trim) { /* bash and ksh strip trailing newlines here */ - while (rplylen > 0 && cmdarg[rplylen-1] == '\n') + while (rplylen > 0 && cmdarg[rplylen-1] == '\n') { rplylen--; + if (trim == 1) + break; + } cmdarg[rplylen] = 0; } noerrs = onoerrs; diff --git a/Test/D10nofork.ztst b/Test/D10nofork.ztst index d6a5588df..fc6b84613 100644 --- a/Test/D10nofork.ztst +++ b/Test/D10nofork.ztst @@ -86,9 +86,39 @@ F:setting option inside is too late for that substitution ?(eval):8: no matches found: f?* purr ${| REPLY=$'trailing newlines remain\n\n' } -0:newline removal should not occur +0:newline removal should not occur, part 1 >trailing newlines remain > +> + + purr ${ echo $'one trailing newline\nremoved\n\n\n' } +0:newline removal in ${ ... }, zsh mode +>one trailing newline +>removed +> +> +> + + () { + emulate -L ksh + purl ${ echo $'all trailing newlines\nremoved\n\n\n' } + purr "${ echo $'all trailing newlines\nremoved\n\n\n' }" + } +0:newline removal in ${ ... }, emulation mode, shwordsplit +>all +>trailing +>newlines +>removed +>all trailing newlines +>removed + + purr "${ echo $'no trailing newlines\nremoved\n\n\n' }" +0:newline removal should not occur, part 2 +>no trailing newlines +>removed +> +> +> > () { @@ -159,7 +189,7 @@ F:Why not use this error in the previous case as well? 1:unbalanced braces, part 4+ ?(eval):1: closing brace expected - purr ${ purr STDOUT } + purr "${ purr STDOUT }" 0:capture stdout >STDOUT > @@ -322,7 +352,7 @@ F:Fiddly here to get EOF past the test syntax 0:here-string behavior >in a here string - <<<${ purr $'stdout as a here string' } + <<<"${ purr $'stdout as a here string' }" 0:another capture stdout >stdout as a here string > @@ -331,7 +361,7 @@ F:Fiddly here to get EOF past the test syntax wrap=${ purr "capture in environment assignment" } typeset -p wrap 0:assignment context >typeset -g wrap='REPLY in environment assignment' ->typeset -g wrap=$'capture in environment assignment\n' +>typeset -g wrap='capture in environment assignment' # Repeat return and exit tests with stdout capture @@ -410,7 +440,7 @@ F:must do this before evaluating the next test block 0:ignored braces, part 1 >buried} - purr ${ purr ${REPLY:-buried}}} + purr "${ purr ${REPLY:-buried}}}" 0:ignored braces, part 2 >buried >} @@ -418,7 +448,6 @@ F:must do this before evaluating the next test block purr ${ { echo nested ;} } 0:ignored braces, part 3 >nested -> purr ${ { echo nested } } DONE 1:ignored braces, part 4 -- cgit v1.2.3 From 57248b88830ce56adc243a40c7773fb3825cab34 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 18 Mar 2024 20:02:34 +0100 Subject: 52750: remove ansi2knr support for old pre-ansi K&R compilers --- ChangeLog | 11 ++++++ Config/defs.mk.in | 3 +- Etc/zsh-development-guide | 2 +- Src/Makemod.in.in | 23 +++--------- Src/Modules/files.c | 4 +-- Src/Modules/watch.c | 2 +- Src/Modules/zftp.c | 2 +- Src/Modules/zprof.c | 6 ++-- Src/Zle/compcore.c | 4 +-- Src/Zle/zle.h | 4 +-- Src/Zle/zle_keymap.c | 2 +- Src/Zle/zle_thingy.c | 2 +- Src/exec.c | 2 +- Src/glob.c | 8 ++--- Src/hist.c | 14 ++++---- Src/makepro.awk | 4 +-- Src/mem.c | 8 ++--- Src/mkbltnmlst.sh | 12 +++---- Src/modentry.c | 10 +++--- Src/parse.c | 2 +- Src/prototypes.h | 54 ++++++++++++++-------------- Src/signals.h | 6 ++-- Src/utils.c | 7 +++- Src/zsh.h | 92 +++++++++++++++++++++++------------------------ Src/zsh_system.h | 8 +---- aclocal.m4 | 50 -------------------------- configure.ac | 41 +-------------------- 27 files changed, 144 insertions(+), 239 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e5f68059..290b1f1b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2024-03-18 Oliver Kiddle + + * 52750: Config/defs.mk.in, Etc/zsh-development-guide, + Src/Makemod.in.in, Src/Modules/files.c, Src/Modules/watch.c, + Src/Modules/zftp.c, Src/Modules/zprof.c, Src/Zle/compcore.c, + Src/Zle/zle.h, Src/Zle/zle_keymap.c, Src/Zle/zle_thingy.c, + Src/exec.c, Src/glob.c, Src/hist.c, Src/makepro.awk, Src/mem.c, + Src/mkbltnmlst.sh, Src/modentry.c, Src/parse.c, Src/prototypes.h, + Src/signals.h, Src/utils.c, Src/zsh.h, Src/zsh_system.h, aclocal.m4, + configure.ac: remove ansi2knr support for old pre-ansi K&R compilers + 2024-03-14 Bart Schaefer * 52759: Doc/Zsh/expn.yo, Etc/FAQ.yo, Src/subst.c, diff --git a/Config/defs.mk.in b/Config/defs.mk.in index 2bc17482a..116875fb9 100644 --- a/Config/defs.mk.in +++ b/Config/defs.mk.in @@ -75,7 +75,6 @@ IMPOPT = @IMPOPT@ # utilities AWK = @AWK@ -ANSI2KNR = @ANSI2KNR@ YODL = @YODL@ @YODL_OPTIONS@ YODL2TXT = @YODL@2txt YODL2HTML = @YODL@2html @@ -100,7 +99,7 @@ LDFLAGS='$(LDFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \ DLCFLAGS='$(DLCFLAGS)' DLLDFLAGS='$(DLLDFLAGS)' \ LIBLDFLAGS='$(LIBLDFLAGS)' EXELDFLAGS='$(EXELDFLAGS)' \ LIBS='$(LIBS)' DL_EXT='$(DL_EXT)' DLLD='$(DLLD)' \ -AWK='$(AWK)' ANSI2KNR='$(ANSI2KNR)' \ +AWK='$(AWK)' \ YODL='$(YODL)' YODL2TXT='$(YODL2TXT)' YODL2HTML='$(YODL2HTML)' \ FUNCTIONS_INSTALL='$(FUNCTIONS_INSTALL)' tzsh='$(tzsh)' diff --git a/Etc/zsh-development-guide b/Etc/zsh-development-guide index 5cb542709..bdabe17d8 100644 --- a/Etc/zsh-development-guide +++ b/Etc/zsh-development-guide @@ -240,7 +240,7 @@ C coding style There must be an empty line, a line with "/**/", a line with the type of the function, and finally the name of the function with typed arguments. These lines must not be indented. The script generating - function prototypes and the ansi2knr program depend on this format. + function prototypes depends on this format. * Variable declarations must similarly be preceded by a line containing only "/**/", for the prototype generation script. diff --git a/Src/Makemod.in.in b/Src/Makemod.in.in index ea0cdc3a4..3343ae1d0 100644 --- a/Src/Makemod.in.in +++ b/Src/Makemod.in.in @@ -52,32 +52,17 @@ DLCOMPILE = $(CC) -c -I. -I$(dir_top)/Src -I$(sdir_top)/Src -I$(sdir_top)/Src/ LINK = $(CC) $(LDFLAGS) $(EXELDFLAGS) $(EXTRA_LDFLAGS) -o $@ DLLINK = $(DLLD) $(LDFLAGS) $(LIBLDFLAGS) $(DLLDFLAGS) -o $@ -KNR_OBJ=.o -KNROBJ=._foo_ +OBJ=.o -ANSIOBJ=.o -ANSI_OBJ=._foo_ +.SUFFIXES: .c .$(DL_EXT) ..o .o .syms .pro .epro -.SUFFIXES: .c .$(DL_EXT) ..o .._foo_ .o ._foo_ .syms .pro .epro - -.c$(ANSI@U@OBJ): +.c$(OBJ): $(COMPILE) -o $@ $< @rm -f $(dir_src)/stamp-modobjs -.c$(KNR@U@OBJ): - @ANSI2KNR@ $< > $@.c - $(COMPILE) -o $@ $@.c - rm -f $@.c - @rm -f $(dir_src)/stamp-modobjs - -.c.$(ANSI@U@OBJ): +.c.$(OBJ): $(DLCOMPILE) -o $@ $< -.c.$(KNR@U@OBJ): - @ANSI2KNR@ $< > $@.c - $(DLCOMPILE) -o $@ $@.c - rm -f $@.c - .c.syms: $(AWK) -f $(sdir_src)/makepro.awk $< $(subdir) > $@ diff --git a/Src/Modules/files.c b/Src/Modules/files.c index bf0e8f8a8..a3fec1daa 100644 --- a/Src/Modules/files.c +++ b/Src/Modules/files.c @@ -29,8 +29,8 @@ #include "files.mdh" -typedef int (*MoveFunc) _((char const *, char const *)); -typedef int (*RecurseFunc) _((char *, char *, struct stat const *, void *)); +typedef int (*MoveFunc) (char const *, char const *); +typedef int (*RecurseFunc) (char *, char *, struct stat const *, void *); struct recursivecmd; diff --git a/Src/Modules/watch.c b/Src/Modules/watch.c index ba17cf940..acc499518 100644 --- a/Src/Modules/watch.c +++ b/Src/Modules/watch.c @@ -584,7 +584,7 @@ readwtab(WATCH_STRUCT_UTMP **head, int initial_sz) if (sz) qsort((void *) *head, sz, sizeof(WATCH_STRUCT_UTMP), - (int (*) _((const void *, const void *)))ucmp); + (int (*) (const void *, const void *))ucmp); return sz; } diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 47a5e9de9..0c26828fd 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -127,7 +127,7 @@ typedef int (*readwrite_t)(int, char *, off_t, int); struct zftpcmd { const char *nam; - int (*fun) _((char *, char **, int)); + int (*fun) (char *, char **, int); int min, max, flags; }; diff --git a/Src/Modules/zprof.c b/Src/Modules/zprof.c index 56cdab888..171a15b90 100644 --- a/Src/Modules/zprof.c +++ b/Src/Modules/zprof.c @@ -163,9 +163,9 @@ bin_zprof(UNUSED(char *nam), UNUSED(char **args), Options ops, UNUSED(int func)) *ap = NULL; qsort(fs, ncalls, sizeof(f), - (int (*) _((const void *, const void *))) cmpsfuncs); + (int (*) (const void *, const void *)) cmpsfuncs); qsort(as, narcs, sizeof(a), - (int (*) _((const void *, const void *))) cmpparcs); + (int (*) (const void *, const void *)) cmpparcs); printf("num calls time self name\n-----------------------------------------------------------------------------------\n"); for (fp = fs, i = 1; *fp; fp++, i++) { @@ -179,7 +179,7 @@ bin_zprof(UNUSED(char *nam), UNUSED(char **args), Options ops, UNUSED(int func)) (*fp)->name); } qsort(fs, ncalls, sizeof(f), - (int (*) _((const void *, const void *))) cmptfuncs); + (int (*) (const void *, const void *)) cmptfuncs); for (fp = fs; *fp; fp++) { printf("\n-----------------------------------------------------------------------------------\n\n"); diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 9b87cad93..09282d42d 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -3253,7 +3253,7 @@ makearray(LinkList l, int type, int flags, int *np, int *nlp, int *llp) /* Now sort the array (it contains matches). */ matchorder = flags; qsort((void *) rp, n, sizeof(Cmatch), - (int (*) _((const void *, const void *)))matchcmp); + (int (*) (const void *, const void *))matchcmp); /* since the matches are sorted and the default is to remove * all duplicates, -1 (remove only consecutive dupes) is a no-op, @@ -3295,7 +3295,7 @@ makearray(LinkList l, int type, int flags, int *np, int *nlp, int *llp) sp = (Cmatch *) zhalloc((n + 1) * sizeof(Cmatch)); memcpy(sp, rp, (n + 1) * sizeof(Cmatch)); qsort((void *) sp, n, sizeof(Cmatch), - (int (*) _((const void *, const void *)))matchcmp); + (int (*) (const void *, const void *))matchcmp); for (asp = sp + 1; *asp; asp++) { Cmatch *ap = asp - 1, *bp = asp; if (matcheq(*ap, *bp)) { diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 010ead3d2..5bb9e7a5e 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -186,7 +186,7 @@ typedef struct thingy *Thingy; /* widgets (ZLE functions) */ -typedef int (*ZleIntFunc) _((char **)); +typedef int (*ZleIntFunc) (char **); struct widget { int flags; /* flags (see below) */ @@ -319,7 +319,7 @@ struct vichange { typedef struct keymap *Keymap; -typedef void (*KeyScanFunc) _((char *, Thingy, char *, void *)); +typedef void (*KeyScanFunc) (char *, Thingy, char *, void *); #define invicmdmode() (!strcmp(curkeymapname, "vicmd")) diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 041682ee9..5012917f5 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -745,7 +745,7 @@ bin_bindkey(char *name, char **argv, Options ops, UNUSED(int func)) static struct opn { char o; char selp; - int (*func) _((char *, char *, Keymap, char **, Options, char)); + int (*func) (char *, char *, Keymap, char **, Options, char); int min, max; } const opns[] = { { 'l', 0, bin_bindkey_lsmaps, 0, -1 }, diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index 1b036a8a0..f71435b01 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -344,7 +344,7 @@ bin_zle(char *name, char **args, Options ops, UNUSED(int func)) { static struct opn { char o; - int (*func) _((char *, char **, Options, char)); + int (*func) (char *, char **, Options, char); int min, max; } const opns[] = { { 'l', bin_zle_list, 0, -1 }, diff --git a/Src/exec.c b/Src/exec.c index 0231bc361..e955e85df 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -267,7 +267,7 @@ static char *blank_env[] = { NULL }; /* Execution functions. */ -static int (*execfuncs[WC_COUNT-WC_CURSH]) _((Estate, int)) = { +static int (*execfuncs[WC_COUNT-WC_CURSH]) (Estate, int) = { execcursh, exectime, NULL /* execfuncdef handled specially */, execfor, execselect, execwhile, execrepeat, execcase, execif, execcond, diff --git a/Src/glob.c b/Src/glob.c index bd199ace3..3e34f708e 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -133,7 +133,7 @@ typedef struct stat *Statptr; /* This makes the Ultrix compiler happy. Go figu #define TT_TERABYTES 5 -typedef int (*TestMatchFunc) _((char *, struct stat *, off_t, char *)); +typedef int (*TestMatchFunc) (char *, struct stat *, off_t, char *); struct qual { struct qual *next; /* Next qualifier, must match */ @@ -1264,7 +1264,7 @@ zglob(LinkList list, LinkNode np, int nountok) int sense, qualsfound; off_t data; char *sdata, *newcolonmod, *ptr; - int (*func) _((char *, Statptr, off_t, char *)); + int (*func) (char *, Statptr, off_t, char *); /* * Initialise state variables for current file pattern. @@ -1310,7 +1310,7 @@ zglob(LinkList list, LinkNode np, int nountok) if (*ptr == Dash) *ptr = '-'; while (*s && !newcolonmod) { - func = (int (*) _((char *, Statptr, off_t, char *)))0; + func = (int (*) (char *, Statptr, off_t, char *)) 0; if (*s == ',') { /* A comma separates alternative sets of qualifiers */ s++; @@ -1961,7 +1961,7 @@ zglob(LinkList list, LinkNode np, int nountok) /* Sort arguments in to lexical (and possibly numeric) order. * * This is reversed to facilitate insertion into the list. */ qsort((void *) & matchbuf[0], matchct, sizeof(struct gmatch), - (int (*) _((const void *, const void *)))gmatchcmp); + (int (*) (const void *, const void *)) gmatchcmp); } if (first < 0) { diff --git a/Src/hist.c b/Src/hist.c index 448dfddbc..1a00c30ed 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -34,25 +34,25 @@ * word control. */ /**/ -mod_export int (*hgetc) _((void)); +mod_export int (*hgetc) (void); /**/ -void (*hungetc) _((int)); +void (*hungetc) (int); /**/ -void (*hwaddc) _((int)); +void (*hwaddc) (int); /**/ -void (*hwbegin) _((int)); +void (*hwbegin) (int); /**/ -void (*hwabort) _((void)); +void (*hwabort) (void); /**/ -void (*hwend) _((void)); +void (*hwend) (void); /**/ -void (*addtoline) _((int)); +void (*addtoline) (int); /* != 0 means history substitution is turned off */ diff --git a/Src/makepro.awk b/Src/makepro.awk index 0d53c5850..56c4f4595 100644 --- a/Src/makepro.awk +++ b/Src/makepro.awk @@ -131,8 +131,8 @@ BEGIN { sub(/@-.*$/, "", dnam) # Put parens etc. back - gsub(/@[{]/, " _((", dcltor) - gsub(/@}/, "))", dcltor) + gsub(/@[{]/, " (", dcltor) + gsub(/@}/, ")", dcltor) gsub(/@/, ")", dcltor) gsub(/@!/, ",", dcltor) diff --git a/Src/mem.c b/Src/mem.c index fb4be47bf..0b6f76e46 100644 --- a/Src/mem.c +++ b/Src/mem.c @@ -1057,17 +1057,17 @@ zrealloc(void *ptr, size_t size) #if !defined(__hpux) && !defined(DGUX) && !defined(__osf__) # if defined(_BSD) # ifndef HAVE_BRK_PROTO - extern int brk _((caddr_t)); + extern int brk (caddr_t); # endif # ifndef HAVE_SBRK_PROTO - extern caddr_t sbrk _((int)); + extern caddr_t sbrk (int); # endif # else # ifndef HAVE_BRK_PROTO - extern int brk _((void *)); + extern int brk (void *); # endif # ifndef HAVE_SBRK_PROTO - extern void *sbrk _((int)); + extern void *sbrk (int); # endif # endif #endif diff --git a/Src/mkbltnmlst.sh b/Src/mkbltnmlst.sh index 067ecdaf9..1994ace60 100644 --- a/Src/mkbltnmlst.sh +++ b/Src/mkbltnmlst.sh @@ -122,12 +122,12 @@ for bin_mod in $bin_mods; do esac done echo " {" - echo " extern int setup_${q_bin_mod} _((Module));" - echo " extern int boot_${q_bin_mod} _((Module));" - echo " extern int features_${q_bin_mod} _((Module,char***));" - echo " extern int enables_${q_bin_mod} _((Module,int**));" - echo " extern int cleanup_${q_bin_mod} _((Module));" - echo " extern int finish_${q_bin_mod} _((Module));" + echo " extern int setup_${q_bin_mod} (Module);" + echo " extern int boot_${q_bin_mod} (Module);" + echo " extern int features_${q_bin_mod} (Module,char***);" + echo " extern int enables_${q_bin_mod} (Module,int**);" + echo " extern int cleanup_${q_bin_mod} (Module);" + echo " extern int finish_${q_bin_mod} (Module);" echo echo " register_module(\"$bin_mod\"," echo " setup_${q_bin_mod}," diff --git a/Src/modentry.c b/Src/modentry.c index 4d8217f43..23c499d94 100644 --- a/Src/modentry.c +++ b/Src/modentry.c @@ -1,10 +1,10 @@ #include "zsh.mdh" -int setup_ _((Module)); -int boot_ _((Module)); -int cleanup_ _((Module)); -int finish_ _((Module)); -int modentry _((int boot, Module m, void *ptr)); +int setup_ (Module); +int boot_ (Module); +int cleanup_ (Module); +int finish_ (Module); +int modentry (int boot, Module m, void *ptr); /**/ int diff --git a/Src/parse.c b/Src/parse.c index 40eb0ee0b..334365649 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -2392,7 +2392,7 @@ par_nl_wordlist(void) */ /**/ -void (*condlex) _((void)) = zshlex; +void (*condlex) (void) = zshlex; /* * cond : cond_1 { SEPER } [ DBAR { SEPER } cond ] diff --git a/Src/prototypes.h b/Src/prototypes.h index e3db4f5ee..3578482d0 100644 --- a/Src/prototypes.h +++ b/Src/prototypes.h @@ -28,9 +28,9 @@ */ #ifndef HAVE_STDLIB_H -char *malloc _((size_t)); -char *realloc _((void *, size_t)); -char *calloc _((size_t, size_t)); +char *malloc (size_t); +char *realloc (void *, size_t); +char *calloc (size_t, size_t); #endif #if !(defined(USES_TERMCAP_H) || defined(USES_TERM_H)) @@ -45,11 +45,11 @@ char *calloc _((size_t, size_t)); #else #define TC_CONST #endif -extern int tgetent _((char *bp, TC_CONST char *name)); -extern int tgetnum _((char *id)); -extern int tgetflag _((char *id)); -extern char *tgetstr _((char *id, char **area)); -extern int tputs _((TC_CONST char *cp, int affcnt, int (*outc) (int))); +extern int tgetent (char *bp, TC_CONST char *name); +extern int tgetnum (char *id); +extern int tgetflag (char *id); +extern char *tgetstr (char *id, char **area); +extern int tputs (TC_CONST char *cp, int affcnt, int (*outc) (int)); #undef TC_CONST #endif @@ -70,30 +70,30 @@ char *tgoto(const char *cap, int col, int row); #endif #ifdef __osf__ -char *mktemp _((char *)); +char *mktemp (char *); #endif #if defined(__osf__) && defined(__alpha) && defined(__GNUC__) /* Digital cc does not need these prototypes, gcc does need them */ # ifndef HAVE_IOCTL_PROTO -int ioctl _((int d, unsigned long request, void *argp)); +int ioctl (int d, unsigned long request, void *argp); # endif # ifndef HAVE_MKNOD_PROTO -int mknod _((const char *pathname, int mode, dev_t device)); +int mknod (const char *pathname, int mode, dev_t device); # endif -int nice _((int increment)); -int select _((int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout)); +int nice (int increment); +int select (int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout); #endif #if defined(DGUX) && defined(__STDC__) /* Just plain missing. */ -extern int getrlimit _((int resource, struct rlimit *rlp)); -extern int setrlimit _((int resource, const struct rlimit *rlp)); -extern int getrusage _((int who, struct rusage *rusage)); -extern int gettimeofday _((struct timeval *tv, struct timezone *tz)); -extern int wait3 _((union wait *wait_status, int options, struct rusage *rusage)); -extern int getdomainname _((char *name, int maxlength)); -extern int select _((int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout)); +extern int getrlimit (int resource, struct rlimit *rlp); +extern int setrlimit (int resource, const struct rlimit *rlp); +extern int getrusage (int who, struct rusage *rusage); +extern int gettimeofday (struct timeval *tv, struct timezone *tz); +extern int wait3 (union wait *wait_status, int options, struct rusage *rusage); +extern int getdomainname (char *name, int maxlength); +extern int select (int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout); #endif /* DGUX and __STDC__ */ #ifdef __NeXT__ @@ -101,34 +101,34 @@ extern pid_t getppid(void); #endif #if defined(__sun__) && !defined(__SVR4) /* SunOS */ -extern char *strerror _((int errnum)); +extern char *strerror (int errnum); #endif /**************************************************/ /*** prototypes for functions built in compat.c ***/ #ifndef HAVE_STRSTR -extern char *strstr _((const char *s, const char *t)); +extern char *strstr (const char *s, const char *t); #endif #ifndef HAVE_GETHOSTNAME -extern int gethostname _((char *name, size_t namelen)); +extern int gethostname (char *name, size_t namelen); #endif #ifndef HAVE_GETTIMEOFDAY -extern int gettimeofday _((struct timeval *tv, struct timezone *tz)); +extern int gettimeofday (struct timeval *tv, struct timezone *tz); #endif #ifndef HAVE_DIFFTIME -extern double difftime _((time_t t2, time_t t1)); +extern double difftime (time_t t2, time_t t1); #endif #ifndef HAVE_STRERROR -extern char *strerror _((int errnum)); +extern char *strerror (int errnum); #endif /*** end of prototypes for functions in compat.c ***/ /***************************************************/ #ifndef HAVE_MEMMOVE -extern void bcopy _((const void *, void *, size_t)); +extern void bcopy (const void *, void *, size_t); #endif diff --git a/Src/signals.h b/Src/signals.h index 391f11fed..7910f6b79 100644 --- a/Src/signals.h +++ b/Src/signals.h @@ -27,7 +27,7 @@ * */ -#define SIGNAL_HANDTYPE void (*)_((int)) +#define SIGNAL_HANDTYPE void (*)(int) #ifndef HAVE_KILLPG # define killpg(pgrp,sig) kill(-(pgrp),sig) @@ -145,7 +145,7 @@ #ifdef BSD_SIGNALS #define signal_block(S) sigblock(S) #else -extern sigset_t signal_block _((sigset_t)); +extern sigset_t signal_block (sigset_t); #endif /* BSD_SIGNALS */ -extern sigset_t signal_unblock _((sigset_t)); +extern sigset_t signal_unblock (sigset_t); diff --git a/Src/utils.c b/Src/utils.c index c8831c85e..ce4e875fd 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5277,6 +5277,7 @@ nicedupstring(char const *s) } +/**/ #ifndef MULTIBYTE_SUPPORT /* Unmetafy and output a string, displaying special characters readably. */ @@ -5311,8 +5312,9 @@ niceztrlen(char const *s) } return l; } -#endif +/**/ +#endif /**/ #ifdef MULTIBYTE_SUPPORT @@ -7633,6 +7635,7 @@ mode_to_octal(mode_t mode) return m; } +/**/ #ifdef MAILDIR_SUPPORT /* * Stat a file. If it's a maildir, check all messages @@ -7756,4 +7759,6 @@ mailstat(char *path, struct stat *st) *st = st_ret_last = st_ret; return 0; } + +/**/ #endif diff --git a/Src/zsh.h b/Src/zsh.h index fae62b8d0..090abf8f5 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -618,7 +618,7 @@ union linkroot { /* Specific elements of linked lists */ /*************************************/ -typedef void (*voidvoidfnptr_t) _((void)); +typedef void (*voidvoidfnptr_t) (void); /* * Element of the prepromptfns list. @@ -678,7 +678,7 @@ struct timedfn { #define COND_MOD 18 #define COND_MODI 19 -typedef int (*CondHandler) _((char **, int)); +typedef int (*CondHandler) (char **, int); struct conddef { Conddef next; /* next in list */ @@ -1164,28 +1164,28 @@ struct dirsav { /* Definitions for Hash Tables */ /*******************************/ -typedef void *(*VFunc) _((void *)); -typedef void (*FreeFunc) _((void *)); +typedef void *(*VFunc) (void *); +typedef void (*FreeFunc) (void *); -typedef unsigned (*HashFunc) _((const char *)); -typedef void (*TableFunc) _((HashTable)); +typedef unsigned (*HashFunc) (const char *); +typedef void (*TableFunc) (HashTable); /* * Note that this is deliberately "char *", not "const char *", * since the AddNodeFunc is passed a pointer to a string that * will be stored and later freed. */ -typedef void (*AddNodeFunc) _((HashTable, char *, void *)); -typedef HashNode (*GetNodeFunc) _((HashTable, const char *)); -typedef HashNode (*RemoveNodeFunc) _((HashTable, const char *)); -typedef void (*FreeNodeFunc) _((HashNode)); -typedef int (*CompareFunc) _((const char *, const char *)); +typedef void (*AddNodeFunc) (HashTable, char *, void *); +typedef HashNode (*GetNodeFunc) (HashTable, const char *); +typedef HashNode (*RemoveNodeFunc) (HashTable, const char *); +typedef void (*FreeNodeFunc) (HashNode); +typedef int (*CompareFunc) (const char *, const char *); /* type of function that is passed to * * scanhashtable or scanmatchtable */ -typedef void (*ScanFunc) _((HashNode, int)); -typedef void (*ScanTabFunc) _((HashTable, ScanFunc, int)); +typedef void (*ScanFunc) (HashNode, int); +typedef void (*ScanTabFunc) (HashTable, ScanFunc, int); -typedef void (*PrintTableStats) _((HashTable)); +typedef void (*PrintTableStats) (HashTable); /* Hash table for standard open hashing. Instances of struct hashtable can be * * created only by newhashtable(). In fact, this function creates an instance * @@ -1352,7 +1352,7 @@ struct funcstack { /* node in list of function call wrappers */ -typedef int (*WrapFunc) _((Eprog, FuncWrap, char *)); +typedef int (*WrapFunc) (Eprog, FuncWrap, char *); struct funcwrap { FuncWrap next; @@ -1428,8 +1428,8 @@ enum { * builtin structure. */ -typedef int (*HandlerFunc) _((char *, char **, Options, int)); -typedef int (*HandlerFuncAssign) _((char *, char **, LinkList, Options, int)); +typedef int (*HandlerFunc) (char *, char **, Options, int); +typedef int (*HandlerFuncAssign) (char *, char **, LinkList, Options, int); #define NULLBINCMD ((HandlerFunc) 0) struct builtin { @@ -1526,10 +1526,10 @@ struct module { /* Module record is an alias */ #define MOD_ALIAS (1<<6) -typedef int (*Module_generic_func) _((void)); -typedef int (*Module_void_func) _((Module)); -typedef int (*Module_features_func) _((Module, char ***)); -typedef int (*Module_enables_func) _((Module, int **)); +typedef int (*Module_generic_func) (void); +typedef int (*Module_void_func) (Module); +typedef int (*Module_features_func) (Module, char ***); +typedef int (*Module_enables_func) (Module, int **); struct linkedmod { char *name; @@ -1574,7 +1574,7 @@ struct feature_enables { /* C-function hooks */ -typedef int (*Hookfn) _((Hookdef, void *)); +typedef int (*Hookfn) (Hookdef, void *); struct hookdef { Hookdef next; @@ -1789,33 +1789,33 @@ typedef const struct gsu_array *GsuArray; typedef const struct gsu_hash *GsuHash; struct gsu_scalar { - char *(*getfn) _((Param)); - void (*setfn) _((Param, char *)); - void (*unsetfn) _((Param, int)); + char *(*getfn) (Param); + void (*setfn) (Param, char *); + void (*unsetfn) (Param, int); }; struct gsu_integer { - zlong (*getfn) _((Param)); - void (*setfn) _((Param, zlong)); - void (*unsetfn) _((Param, int)); + zlong (*getfn) (Param); + void (*setfn) (Param, zlong); + void (*unsetfn) (Param, int); }; struct gsu_float { - double (*getfn) _((Param)); - void (*setfn) _((Param, double)); - void (*unsetfn) _((Param, int)); + double (*getfn) (Param); + void (*setfn) (Param, double); + void (*unsetfn) (Param, int); }; struct gsu_array { - char **(*getfn) _((Param)); - void (*setfn) _((Param, char **)); - void (*unsetfn) _((Param, int)); + char **(*getfn) (Param); + void (*setfn) (Param, char **); + void (*unsetfn) (Param, int); }; struct gsu_hash { - HashTable (*getfn) _((Param)); - void (*setfn) _((Param, HashTable)); - void (*unsetfn) _((Param, int)); + HashTable (*getfn) (Param); + void (*setfn) (Param, HashTable); + void (*unsetfn) (Param, int); }; @@ -2984,7 +2984,7 @@ enum errflag_bits { /* Sorting */ /***********/ -typedef int (*CompareFn) _((const void *, const void *)); +typedef int (*CompareFn) (const void *, const void *); enum { SORTIT_ANYOLDHOW = 0, /* Defaults */ @@ -3042,13 +3042,13 @@ struct hist_stack { short *chwords; int chwordlen; int chwordpos; - int (*hgetc) _((void)); - void (*hungetc) _((int)); - void (*hwaddc) _((int)); - void (*hwbegin) _((int)); - void (*hwabort) _((void)); - void (*hwend) _((void)); - void (*addtoline) _((int)); + int (*hgetc) (void); + void (*hungetc) (int); + void (*hwaddc) (int); + void (*hwbegin) (int); + void (*hwabort) (void); + void (*hwend) (void); + void (*addtoline) (int); unsigned char *cstack; int csp; int hist_keep_comment; @@ -3218,7 +3218,7 @@ enum { /* compctl entry point pointers */ -typedef int (*CompctlReadFn) _((char *, char **, Options, char *)); +typedef int (*CompctlReadFn) (char *, char **, Options, char *); /* ZLE entry point pointer */ diff --git a/Src/zsh_system.h b/Src/zsh_system.h index 16f724401..5c004d53e 100644 --- a/Src/zsh_system.h +++ b/Src/zsh_system.h @@ -82,12 +82,6 @@ */ #define _STRPTIME_DONTZERO -#ifdef PROTOTYPES -# define _(Args) Args -#else -# define _(Args) () -#endif - #ifndef HAVE_ALLOCA # define alloca zhalloc #else @@ -101,7 +95,7 @@ # pragma alloca # else # ifndef alloca -char *alloca _((size_t)); +char *alloca (size_t); # endif # endif # endif diff --git a/aclocal.m4 b/aclocal.m4 index c26e2d834..792d533f2 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -2,56 +2,6 @@ # Copyright (C) 1992, 1994 Free Software Foundation, Inc. # Francois Pinard , 1992. -# @defmac fp_PROG_CC_STDC -# @maindex PROG_CC_STDC -# @ovindex CC -# If the C compiler in not in ANSI C mode by default, try to add an option -# to output variable @code{CC} to make it so. This macro tries various -# options that select ANSI C on some system or another. It considers the -# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and -# handles function prototypes correctly. -# -# If you use this macro, you should check after calling it whether the C -# compiler has been set to accept ANSI C; if not, the shell variable -# @code{fp_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source -# code in ANSI C, you can make an un-ANSIfied copy of it by using the -# program @code{ansi2knr}, which comes with Ghostscript. -# @end defmac - -define(fp_PROG_CC_STDC, -[AC_CACHE_CHECK(for ${CC-cc} option to accept ANSI C, -fp_cv_prog_cc_stdc, -[fp_cv_prog_cc_stdc=no -ac_save_CFLAGS="$CFLAGS" -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX -Ae or -Aa -D_HPUX_SOURCE -# SVR4 -Xc -# For HP-UX, we try -Ae first; this turns on ANSI but also extensions, -# as well as defining _HPUX_SOURCE, and we can then use long long. -# We keep the old version for backward compatibility. -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" -Xc -do - CFLAGS="$ac_save_CFLAGS $ac_arg" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ -[#ifndef __STDC__ -choke me -#endif -]], [[int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);};]])], -[fp_cv_prog_cc_stdc="$ac_arg"; break],[]) -done -CFLAGS="$ac_save_CFLAGS" -]) -case "x$fp_cv_prog_cc_stdc" in - x|xno) ;; - *) CC="$CC $fp_cv_prog_cc_stdc" ;; -esac -]) - AC_DEFUN(AC_PROG_LN, [AC_MSG_CHECKING(whether ln works) AC_CACHE_VAL(ac_cv_prog_LN, diff --git a/configure.ac b/configure.ac index 175d90433..ba3f2fe90 100644 --- a/configure.ac +++ b/configure.ac @@ -273,11 +273,6 @@ fi], AC_DEFINE(CONFIG_LOCALE) ) -dnl Do you want to compile as K&R C. -AC_ARG_ENABLE(ansi2knr, -AS_HELP_STRING([--enable-ansi2knr],[translate source to K&R C before compiling]), -[ansi2knr="$enableval"], [ansi2knr=default]) - ifdef([runhelpdir],[undefine([runhelpdir])])dnl AC_ARG_ENABLE(runhelpdir, AS_HELP_STRING([--enable-runhelpdir=DIR],[the directory in which to install run-help files]), @@ -483,7 +478,7 @@ fi dnl if the user hasn't specified CFLAGS, then dnl if compiler is gcc, then use -O2 and some warning flags dnl else use -O -if test -n "$auto_cflags" && test ."$ansi2knr" != .yes; then +if test -n "$auto_cflags"; then if test "${enable_zsh_debug}" = yes; then if test -n "$GCC"; then CFLAGS="$CFLAGS -Wall -Wmissing-prototypes -ggdb" @@ -558,28 +553,6 @@ case "$host_os" in esac fp_PROG_CC_STDC -AC_MSG_CHECKING([whether to use prototypes]) -if test ."$ansi2knr" = .yes || test ."$ansi2knr" = .no; then - msg="(overridden) " -else - msg= - if test ."$fp_cv_prog_cc_stdc" = .no; then - ansi2knr=yes - else - ansi2knr=no - fi -fi -AH_TEMPLATE([PROTOTYPES], -[Define to 1 if ANSI function prototypes are usable.]) -if test "$ansi2knr" = yes; then - AC_MSG_RESULT(${msg}no) - U=_ -else - AC_MSG_RESULT(${msg}yes) - AC_DEFINE(PROTOTYPES) - U= -fi -AC_SUBST(U) AC_FUNC_ALLOCA dnl Check how to get `alloca'. @@ -647,18 +620,6 @@ case "$LC_PAPER" in esac AC_SUBST(PAPERSIZE) -AC_CHECK_PROGS([ANSI2KNR], [ansi2knr], [: ansi2knr]) - -if test x"$ansi2knr" = xyes && test x"$ANSI2KNR" = x": ansi2knr"; then - echo "----------" - echo "configure fatal error:" - echo "ansi2knr was specified (--enable-ansi2knr) but the program could not be found." - echo "Either remove the configure option if it is not required or build the ansi2knr" - echo "program before reconfiguring Zsh. The source code for ansi2knr is also" - echo "available in the GPL directory on Zsh distribution sites." - exit 1 -fi - dnl ------------------ dnl CHECK HEADER FILES dnl ------------------ -- cgit v1.2.3 From 1e995cbb384ddc931ba025a0f1cbc210d259f588 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 18 Mar 2024 21:12:55 +0100 Subject: 52769: fix completion of ansible keywords and --step option --- ChangeLog | 3 +++ Completion/Unix/Command/_ansible | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 290b1f1b2..3782b0d2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-03-18 Oliver Kiddle + * 52769: Completion/Unix/Command/_ansible: fix completion of + ansible keywords and --step option + * 52750: Config/defs.mk.in, Etc/zsh-development-guide, Src/Makemod.in.in, Src/Modules/files.c, Src/Modules/watch.c, Src/Modules/zftp.c, Src/Modules/zprof.c, Src/Zle/compcore.c, diff --git a/Completion/Unix/Command/_ansible b/Completion/Unix/Command/_ansible index bf31819ad..e0d9fb9b6 100644 --- a/Completion/Unix/Command/_ansible +++ b/Completion/Unix/Command/_ansible @@ -69,6 +69,11 @@ case $service in "--skip-tags[only run plays and tasks whose tags don't match]" ) ;| + ansible-playbook|ansible-console) + args+=( + '--step[one-step-at-a-time: confirm each task before running]' + ) + ;| ansible|ansible-console) args+=( '--task-timeout[set the task timeout limit]:timeout (seconds)' @@ -97,11 +102,6 @@ case $service in '*::args:->config' ) ;; - ansible-console) - args+=( - '--step[one-step-at-a-time: confirm each task before running]' - ) - ;; ansible-doc) args+=( '!--metadata-dump' '!--no-fail-on-errors' # "internal use only" @@ -440,11 +440,11 @@ if [[ $state = plugins ]]; then typeset -ga ${plug} if zstyle -T ":completion:${curcontext}:plugins" verbose; then (( ${(P)#plugvar} )) || set -A ${plugvar} \ - ${${(f)"$(_call_program plugins ansible-doc -t $plug -l)"}/ ##/:} + ${${${(f)"$(_call_program plugins ansible-doc -t $plug -l)"}:# *}/(:|) ##/:} _describe -t plugins "${plug} plugin" $plugvar -M 'r:|.=* r:|=*' && ret=0 else (( ${(P)#plugvar} )) || set -A ${plugvar} \ - ${${(f)"$(_call_program plugins ansible-doc -t $plug -F)"}%% *} + ${${(f)"$(_call_program plugins ansible-doc -t $plug -F)"}%%(|:) *} _wanted plugins expl "${plug} plugin" compadd -M 'r:|.=* r:|=*' -a $plugvar && ret=0 fi fi -- cgit v1.2.3 From 93334b207ff7a7b0fe7d85ccea5b0aeccab0a4da Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 18 Mar 2024 21:34:11 +0100 Subject: 52770: handle newrole in SELinux completions --- ChangeLog | 2 ++ Completion/Linux/Command/_selinux | 31 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3782b0d2d..296b74de8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-03-18 Oliver Kiddle + * 52770: Completion/Linux/Command/_selinux: handle newrole + * 52769: Completion/Unix/Command/_ansible: fix completion of ansible keywords and --step option diff --git a/Completion/Linux/Command/_selinux b/Completion/Linux/Command/_selinux index e7d4d3b2e..a7ba68952 100644 --- a/Completion/Linux/Command/_selinux +++ b/Completion/Linux/Command/_selinux @@ -1,4 +1,4 @@ -#compdef audit2allow audit2why avcstat chcon checkmodule checkpolicy fixfiles getpidprevcon getsebool matchpathcon restorecon runcon sealert secon sedta seinfo selinuxconlist selinuxdefcon selinuxexeccon semanage semodule semodule_unpackage sepolgen sepolicy sesearch sestatus setenforce setsebool validatetrans +#compdef audit2allow audit2why avcstat chcon checkmodule checkpolicy fixfiles getpidprevcon getsebool matchpathcon newrole restorecon runcon sealert secon sedta seinfo selinuxconlist selinuxdefcon selinuxexeccon semanage semodule semodule_unpackage sepolgen sepolicy sesearch sestatus setenforce setsebool validatetrans # encompasses checkpolicy libselinux-utils policycoreutils # policycoreutils-devel policycoreutils-python-utils setools-console @@ -251,6 +251,21 @@ case $service in ) ;; + newrole) + local cmd cpp + cmd="$words[1]" + cpp='_comp_priv_prefix=( $cmd ${(kv)opt_args[(I)-([rtl]|-role|-type|-level)]} )' + args=( + '(-r --role)'{-r+,--role=}'[specify role]: :_selinux_roles' + '(-t --type)'{-t+,--type=}'[specify type]: :_selinux_types' + '(-l --level)'{-l+,--range=}'[specify level]:level' + '(-p --preserve-environment)'{-p,--preserve-environment}"[don't create new minimal environment]" + "${ign}(-)"{-V,--version}'[display version information]' + "(-)1: :{ $cpp; _command_names -e }" \ + "*:: :{ $cpp; _normal }" + ) + ;; + restorecon) args=( '*-e+[exclude a directory]:directory:_directories' @@ -276,10 +291,10 @@ case $service in runcon) args=( '(1 -c --compute)'{-c,--compute}'[compute process transition context before modifying]' - '(1 -t --type=TYPE)'{-t+,--type=}'[specify type]: :_selinux_types' - '(1 -u --user=USER)'{-u+,--user=}'[specify user identity]: :_selinux_users' - '(1 -r --role=ROLE)'{-r+,--role=}'[specify role]: :_selinux_roles' - '(1 -l --range=RANGE)'{-l+,--range=}'[specify level range]:range' + '(1 -t --type)'{-t+,--type=}'[specify type]: :_selinux_types' + '(1 -u --user)'{-u+,--user=}'[specify user identity]: :_selinux_users' + '(1 -r --role)'{-r+,--role=}'[specify role]: :_selinux_roles' + '(1 -l --range)'{-l+,--range=}'[specify level range]:range' '(-)1:security context:_selinux_contexts' '*:::args:_normal' ) @@ -460,7 +475,7 @@ case $service in '(-E --extract)'{-E,--extract}'[extract customizable commands, for use within a transaction]' ) ;| - boolean|dontaudit|export|import) + fcontext|ibendport|ibpkey|interface|login|module|node|permissive|port|user) args+=( '(-a --add)'{-a,--add}'[add a record]' ) ;| boolean|fcontext|ibendport|ibpkey|interface|login|node|permissive|port|user) @@ -573,8 +588,8 @@ case $service in \*{-B,--build}'[build and reload policy]' \*'--refresh[like --build but reuse existing linked policy if module files unchanged]' \*{-D,--disable_dontaudit}'[remove dontaudits from policy]' - \*{-i+,--install=}'[install a new module]:module package:_files -g "*.pp(-.)"' - \!{-b,--base,-u,--upgrade}':module package:_files -g "*.pp(-.)"' + \*{-i+,--install=}'[install a new module]:module package:_files -g "*.(pp|cil)(-.)"' + \!{-b,--base,-u,--upgrade}':module package:_files -g "*.(pp|cil)(-.)"' \*{-r+,--remove=}'[remove existing module at desired priority]:module name:_selinux_modules' \*{-l+,--list-modules=-}'[display list of installed modules]::kind:(( standard\:highest\ priority,\ enabled\ modules -- cgit v1.2.3 From cd5ae4a909ea7b09b860c3be29d46a0f616c147d Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 20 Mar 2024 23:30:47 +0100 Subject: unposted: remove reference to fp_PROG_CC_STDC macro which was removed in 52750 --- ChangeLog | 5 +++++ configure.ac | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 296b74de8..df8caca42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-20 Oliver Kiddle + + * unposted: configure.ac: remove reference to fp_PROG_CC_STDC + macro which was removed in 52750 + 2024-03-18 Oliver Kiddle * 52770: Completion/Linux/Command/_selinux: handle newrole diff --git a/configure.ac b/configure.ac index ba3f2fe90..78621042d 100644 --- a/configure.ac +++ b/configure.ac @@ -552,8 +552,6 @@ case "$host_os" in darwin[[0-9]].*) CPP="$CPP -traditional-cpp" ;; esac -fp_PROG_CC_STDC - AC_FUNC_ALLOCA dnl Check how to get `alloca'. dnl If the compiler supports union initialisation -- cgit v1.2.3 From 7139d3b286bba5874548eb6faca25cf9bb90f7be Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 20 Mar 2024 23:40:23 +0100 Subject: 52783: allow for unset hash element --- ChangeLog | 2 ++ Src/Modules/hlgroup.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index df8caca42..157abcc9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-03-20 Oliver Kiddle + * 52783: Src/Modules/hlgroup.c: allow for unset hash element + * unposted: configure.ac: remove reference to fp_PROG_CC_STDC macro which was removed in 52750 diff --git a/Src/Modules/hlgroup.c b/Src/Modules/hlgroup.c index 9c0aedcf8..9b656c24e 100644 --- a/Src/Modules/hlgroup.c +++ b/Src/Modules/hlgroup.c @@ -91,7 +91,8 @@ getgroup(const char *name, int sgr) if (!(v = getvalue(&vbuf, &var, 0)) || PM_TYPE(v->pm->node.flags) != PM_HASHED || !(hlg = v->pm->gsu.h->getfn(v->pm)) || - !(hn = gethashnode2(hlg, name))) + !(hn = gethashnode2(hlg, name)) || + (((Param) hn)->node.flags & PM_UNSET)) { pm->u.str = dupstring(""); pm->node.flags |= PM_UNSET; -- cgit v1.2.3 From 017738cd60743b21832e5ee66b849b5adea1a28d Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 21 Mar 2024 09:25:07 +0000 Subject: 52780: unneccessary returns in hlgroup --- ChangeLog | 4 ++++ Src/Modules/hlgroup.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 157abcc9e..4cb7ca634 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-03-21 Peter Stephenson + + * 52780: Src/Modules/hlgroup.c: remove unnecessary returns. + 2024-03-20 Oliver Kiddle * 52783: Src/Modules/hlgroup.c: allow for unset hash element diff --git a/Src/Modules/hlgroup.c b/Src/Modules/hlgroup.c index 9b656c24e..082762623 100644 --- a/Src/Modules/hlgroup.c +++ b/Src/Modules/hlgroup.c @@ -142,7 +142,7 @@ getpmesc(UNUSED(HashTable ht), const char *name) static void scanpmesc(UNUSED(HashTable ht), ScanFunc func, int flags) { - return scangroup(func, flags, 0); + scangroup(func, flags, 0); } /**/ @@ -156,7 +156,7 @@ getpmsgr(UNUSED(HashTable ht), const char *name) static void scanpmsgr(UNUSED(HashTable ht), ScanFunc func, int flags) { - return scangroup(func, flags, 1); + scangroup(func, flags, 1); } static struct paramdef partab[] = { -- cgit v1.2.3 From b727b74fe23c532050b959fe4ce0382c7213af6b Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Mon, 18 Mar 2024 15:59:43 +0100 Subject: 52768: Handle completer filenames with funny characters in them For example, a file called _foo;bar will cause this to happen: % hello [press tab]zsh: command not found: _foo zsh: command not found: bar --- ChangeLog | 5 +++++ Completion/compdump | 6 +++--- Completion/compinit | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cb7ca634..72e8efbe7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-23 Mikael Magnusson + + * 52768: Completion/compdump, Completion/compinit: Handle + completer filenames with funny characters in them + 2024-03-21 Peter Stephenson * 52780: Src/Modules/hlgroup.c: remove unnecessary returns. diff --git a/Completion/compdump b/Completion/compdump index 6daf92f9f..5af5174f1 100644 --- a/Completion/compdump +++ b/Completion/compdump @@ -113,7 +113,7 @@ integer _i=5 print -n autoload -Uz >& $_d_fd while (( $#_d_als )); do if (( ! $+_compautos[$_d_als[1]] )); then - print -n " $_d_als[1]" + print -rn " ${(q-)_d_als[1]}" if (( ! --_i && $#_d_als > 1 )); then _i=5 print -n ' \\\n ' @@ -126,13 +126,13 @@ print >& $_d_fd local _c for _c in "${(ok@)_compautos}"; do - print "autoload -Uz $_compautos[$_c] $_c" >& $_d_fd + print -r "autoload -Uz ${(q-)_compautos[$_c]} $_c" >& $_d_fd done print >& $_d_fd print "typeset -gUa _comp_assocs" >& $_d_fd -print "_comp_assocs=( ${(qq)_comp_assocs} )" >& $_d_fd +print -r "_comp_assocs=( ${(qq)_comp_assocs} )" >& $_d_fd exec {_d_fd}>&- mv -f $_d_file ${_d_file%.$HOST.$$} diff --git a/Completion/compinit b/Completion/compinit index 5cb527fac..51e9d88b8 100644 --- a/Completion/compinit +++ b/Completion/compinit @@ -301,7 +301,7 @@ compdef() { if [[ -z "$eval" ]] && [[ "$1" = *\=* ]]; then while (( $# )); do if [[ "$1" = *\=* ]]; then - cmd="${1%%\=*}" + cmd="${(q)${1%%\=*}}" svc="${1#*\=}" func="$_comps[${_services[(r)$svc]:-$svc}]" [[ -n ${_services[$svc]} ]] && @@ -412,7 +412,7 @@ compdef() { svc= fi if [[ -z "$new" || -z "${_comps[$1]}" ]]; then - _comps[$cmd]="$func" + _comps[$cmd]="${(q)func}" [[ -n "$svc" ]] && _services[$cmd]="${1#*\=}" fi ;; -- cgit v1.2.3 From c7ae3701607a00162e19a7ba1e23aef3158acdd0 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 26 Mar 2024 00:06:05 +0100 Subject: 52798: handle comments in ssh config --- ChangeLog | 5 +++++ Completion/Unix/Command/_ssh | 3 ++- Completion/Unix/Type/_ssh_hosts | 11 ++++------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 72e8efbe7..582f75635 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-03-25 Oliver Kiddle + + * 52798: Completion/Unix/Command/_ssh, + Completion/Unix/Type/_ssh_hosts: handle comments in ssh config + 2024-03-23 Mikael Magnusson * 52768: Completion/compdump, Completion/compinit: Handle diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index dc3979a58..5e6e60573 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -101,6 +101,7 @@ _ssh () { '--apple-use-keychain[update keychain when adding/removing identities]' ) _arguments -C -s : $args \ + '-C[process certificates only]' \ '-c[identity is subject to confirmation via SSH_ASKPASS]' \ '-D[delete all identities]' \ '-d[remove identity]' \ @@ -214,7 +215,7 @@ _ssh () { "(${${(@)cmds:#-p}} -v ${${(@)cms:#-[qt]}})-N+[provide new passphrase]:new passphrase" \ "(${${(@)cmds:#-c}} -v $cms)-C+[provide new comment]:new comment" \ "(-D -I -h -n -V -A)-f+[$file file]:$file file:_files" \ - "$p1(${${(@)cmds:#-[FE]}} ${${(@)cmn:#-v}} ${${(@)cms:#-E}})-l[show fingerprint of key file]" \ + "(${${(@)cmds:#-[FE]}} ${${(@)cmn:#-v}} ${${(@)cms:#-E}})-l[show fingerprint of key file]" \ "$p1(${${(@)cmds:#-[iep]}} $cms)-m+[specify conversion format]:format [RFC4716]:(PEM PKCS8 RFC4716)" \ "$p1*-O+[specify a key/value option]: : _values 'option' $options" \ "(${${(@)cmds:#-[lGT]}} ${${(@)cmn:#-[bv]}} -f)*-v[verbose mode]" \ diff --git a/Completion/Unix/Type/_ssh_hosts b/Completion/Unix/Type/_ssh_hosts index a4a08ad91..b50e1c16a 100644 --- a/Completion/Unix/Type/_ssh_hosts +++ b/Completion/Unix/Type/_ssh_hosts @@ -24,7 +24,7 @@ if [[ -r $config ]]; then while (( idx <= $#lines )); do IFS=$'=\t ' read -r key line <<<"${lines[idx]}" if [[ "$key" == ((#i)match) ]]; then - match_args=(${(z)line}) + match_args=( ${(Z.C.)line} ) while [[ $#match_args -ge 2 ]]; do if [[ "${match_args[1]}" == (#i)(canonical|final|(|original)host) ]]; then key="Host" @@ -36,13 +36,10 @@ if [[ -r $config ]]; then fi case "$key" in ((#i)include) - lines[idx]=("${(@f)$(cd $HOME/.ssh; cat ${(z)~line})}") 2>/dev/null;; + lines[idx]=( "${(@f)$(cd $HOME/.ssh; cat ${(Z.C.)~line} 2>/dev/null)}" ) ;; ((#i)host(|name)) - for host in ${(z)line}; do - case $host in - (*[*?]*) ;; - (*) config_hosts+=("$host") ;; - esac + for host in ${(Z.C.)line}; do + [[ $host != *[*?%]* ]] && config_hosts+=( $host ) done ;& (*) (( ++idx ));; esac -- cgit v1.2.3 From a967c4a4357e05710139ffaa87017ac00f9d04fa Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 1 Apr 2024 23:27:09 +0200 Subject: 52859: use _date_formats for fc and complete -m/-M for vared --- ChangeLog | 5 +++++ Completion/Zsh/Command/_fc | 2 +- Completion/Zsh/Command/_vared | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 582f75635..4e43cac03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-04-01 Oliver Kiddle + + * 52859: Completion/Zsh/Command/_fc, Completion/Zsh/Command/_vared: + use _date_formats for fc and complete -m/-M for vared + 2024-03-25 Oliver Kiddle * 52798: Completion/Unix/Command/_ssh, diff --git a/Completion/Zsh/Command/_fc b/Completion/Zsh/Command/_fc index 80e570c5d..626d35956 100644 --- a/Completion/Zsh/Command/_fc +++ b/Completion/Zsh/Command/_fc @@ -40,7 +40,7 @@ fc_hist=( '(-A -R -W -e -d -E -i -t -a -p -P)-f[mm/dd/yyyy format time-stamps]' '(-A -R -W -e -d -f -i -t -a -p -P)-E[dd.mm.yyyy format time-stamps]' '(-A -R -W -e -d -f -E -t -a -p -P)-i[yyyy-mm-dd format time-stamps]' - '(-A -R -W -e -d -f -E -i -a -p -P)-t[print time-stamps in specified format]:date format' + '(-A -R -W -e -d -f -E -i -a -p -P)-t[print time-stamps in specified format]: : _date_formats zsh' '(-A -R -W -e -a -p -P)-D[print elapsed times]' '(-A -R -W -I -e -d -f -i -l -m -n -r -D -E -t -P)-a[with -p, automatically pop history on function return]' diff --git a/Completion/Zsh/Command/_vared b/Completion/Zsh/Command/_vared index aba64880a..e7072ca6d 100644 --- a/Completion/Zsh/Command/_vared +++ b/Completion/Zsh/Command/_vared @@ -10,5 +10,7 @@ _arguments -s -A "-*" \ '-f+[specify finish widget]:widget:_widgets' \ '-h[allow access to history]' \ '-e[exit on EOF (^D)]' \ + '-M+[specify keymap to link to main]:keymap:compadd -a keymaps' \ + '-m+[specify keymap to link to vicmd]:keymap:compadd -a keymaps' \ '1:parameter spec:_vars' -- cgit v1.2.3 From f57ad185b31e927bffc8e24566ef0584bddce5bb Mon Sep 17 00:00:00 2001 From: OKURA Masafumi Date: Sun, 17 Mar 2024 23:44:54 +0900 Subject: github #115: completion(ruby): completer opts for irb IRB now has `--regexp-completor` and `--type-completor` options added by: https://github.com/ruby/irb/commit/1dec2708c92559487e51c5f3a3030b74a62270e5 --- ChangeLog | 3 +++ Completion/Unix/Command/_ruby | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4e43cac03..62b332aae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-04-01 Oliver Kiddle + * github #115: OKURA Masafumi: Completion/Unix/Command/_ruby: + IRB now has `--regexp-completor` and `--type-completor` options + * 52859: Completion/Zsh/Command/_fc, Completion/Zsh/Command/_vared: use _date_formats for fc and complete -m/-M for vared diff --git a/Completion/Unix/Command/_ruby b/Completion/Unix/Command/_ruby index b6b42637d..9955253b3 100644 --- a/Completion/Unix/Command/_ruby +++ b/Completion/Unix/Command/_ruby @@ -89,6 +89,8 @@ irb=( "(--colorize)--nocolorize[don't use color-highlighting]" '(--noautocomplete)--autocomplete[use auto-completion]' "(--autocomplete)--noautocomplete[don't use auto-completion]" + '(--regexp-completor)--type-completor[use regexp based completion]' + '(--type-completor)--regexp-completor[use type based completion]' '(--noscript)--script[script mode]' '(--script)--noscript[no script mode]' '--single-irb[share self with sub-irb]' -- cgit v1.2.3 From 5ba43e58c269100a6e3adcfc118ae93346ba0165 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 1 Apr 2024 22:29:07 -0700 Subject: 52781: HIST IGNORE_DUPS + HIST_REDUCE_BLANKS treats whitespace as significant --- ChangeLog | 5 +++++ Src/hashtable.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 62b332aae..63034fb5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-04-01 Bart Schaefer + + * 52781 (and typo fix): Src/hashtable.c: HIST IGNORE_DUPS treats + whitespace as significant when HIST_REDUCE_BLANKS is also set. + 2024-04-01 Oliver Kiddle * github #115: OKURA Masafumi: Completion/Unix/Command/_ruby: diff --git a/Src/hashtable.c b/Src/hashtable.c index 75b06c4ad..96675a393 100644 --- a/Src/hashtable.c +++ b/Src/hashtable.c @@ -1397,6 +1397,14 @@ histstrcmp(const char *str1, const char *str2) { while (inblank(*str1)) str1++; while (inblank(*str2)) str2++; + + /* If insignificant whitespace has already been eliminated, + * there is no reason to expend similar effort here. Also, + * this is more accurate in cases of quoted whitespace. + */ + if (isset(HISTREDUCEBLANKS)) + return strcmp(str1, str2); + while (*str1 && *str2) { if (inblank(*str1)) { if (!inblank(*str2)) -- cgit v1.2.3 From 76019f71742fab725011e4fd0402e941544cf5ab Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 1 Apr 2024 22:35:33 -0700 Subject: 52864: Change ${|var|...} to ${{var} ...}, limit local REPLY to ${|...} --- ChangeLog | 4 ++ Src/lex.c | 2 +- Src/subst.c | 140 +++++++++++++++++++++++++++++++++++---------------- Test/D10nofork.ztst | 52 ++++++++++++++++--- Test/V10private.ztst | 8 +-- 5 files changed, 150 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 63034fb5a..9476c50ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2024-04-01 Bart Schaefer + * 52864: Src/lex.c, Src/subst.c, Test/D10nofork.ztst, + Test/V10private.ztst: Change ${|var|...} to ${{var} ...}, + limit local REPLY behavior to ${|...}, update tests. + * 52781 (and typo fix): Src/hashtable.c: HIST IGNORE_DUPS treats whitespace as significant when HIST_REDUCE_BLANKS is also set. diff --git a/Src/lex.c b/Src/lex.c index 31b130b07..700af2da1 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -1423,7 +1423,7 @@ gettokstr(int c, int sub) if (lexstop) break; if (!cmdsubst && in_brace_param && act == LX2_STRING && - (c == '|' || c == Bar || inblank(c))) { + (c == '|' || c == Bar || c == '{' || c == Inbrace || inblank(c))) { cmdsubst = in_brace_param; cmdpush(CS_CURSH); } else if (in_pattern == 2 && c != '/') diff --git a/Src/subst.c b/Src/subst.c index 9d20a2d0e..f0d6c7a7b 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1866,10 +1866,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * joining the array into a string (for compatibility with ksh/bash). */ int quoted_array_with_offset = 0; - /* Indicates ${|...;} */ - char *rplyvar = NULL; - /* Indicates ${ ... ;} */ - char *rplytmp = NULL; + /* + * Nofork substitution controls + */ + char *rplyvar = NULL; /* Indicates ${|...;} or ${{var} ...;} */ + char *rplytmp = NULL; /* Indicates ${ ... ;} */ *s++ = '\0'; /* @@ -1897,14 +1898,16 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * flags in parentheses, but also one ksh hack. */ if (c == Inbrace) { - /* The command string to be run by ${|...;} */ - char *cmdarg = NULL; + /* For processing nofork command substitution string */ + char *cmdarg = NULL, *endvar = NULL, inchar = *++s; + char *outbracep = s, sav = *s; + Param rplypm = NULL; size_t slen = 0; int trim = (!EMULATION(EMULATE_ZSH)) ? 2 : !qt; - inbrace = 1; - s++; - /* Short-path for the nofork command substitution ${|cmd;} + inbrace = 1; /* Outer scope boolean, see above */ + + /* Handling for nofork command substitution e.g. ${|cmd;} * See other comments about kludges for why this is here. * * The command string is extracted and executed, and the @@ -1913,48 +1916,77 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * should not be part of command substitution in any case. * Use ${(U)${|cmd;}} as you would for ${(U)$(cmd;)}. */ - if (*s == '|' || *s == Bar || inblank(*s)) { - char *outbracep = s; - char sav = *s; + if (inchar == '|' || inchar == Bar || inblank(inchar)) { *s = Inbrace; - if (skipparens(Inbrace, Outbrace, &outbracep) == 0) { + if (skipparens(Inbrace, Outbrace, &outbracep) == 0) slen = outbracep - s - 1; - if ((*s = sav) != Bar) { - sav = *outbracep; - *outbracep = '\0'; - tokenize(s); - *outbracep = sav; + *s = sav; + if (inchar == '|') + inchar = Bar; /* Simplify later compares */ + } else if (inchar == '{' || inchar == Inbrace) { + *s = Inbrace; + if ((outbracep = itype_end(s+1, INAMESPC, 0))) { + if (*outbracep == Inbrack && + (outbracep = parse_subscript(++outbracep, 1, ']'))) + ++outbracep; + } + + /* If we reached the first close brace, find the last */ + if (outbracep && *outbracep == Outbrace) { + char outchar = inchar == Inbrace ? Outbrace : '}'; + endvar = outbracep++; + + /* Require space to avoid ${{var}} typo for ${${var}} */ + if (!inblank(*outbracep)) { + zerr("bad substitution"); + return NULL; } + + *endvar = '|'; /* Almost anything but braces/brackets */ + outbracep = s; + if (skipparens(Inbrace, outchar, &outbracep) == 0) + *endvar = Outbrace; + else { /* Never happens? */ + *endvar = outchar; + outbracep = endvar + 1; + } + slen = outbracep - s - 1; + if (inchar != Inbrace) + outbracep[-1] = Outbrace; + *s = sav; + inchar = Inbrace; /* Simplify later compares */ + } else { + zerr("bad substitution"); + return NULL; } } if (slen > 1) { char *outbracep = s + slen; + if (!itok(*s) || inblank(inchar)) { + /* This tokenize() is important */ + char sav = *outbracep; + *outbracep = '\0'; + tokenize(s); + *outbracep = sav; + } if (*outbracep == Outbrace) { - if ((rplyvar = itype_end(s+1, INAMESPC, 0))) { - if (*rplyvar == Inbrack && - (rplyvar = parse_subscript(++rplyvar, 1, ']'))) - ++rplyvar; - } - if (rplyvar == s+1 && *rplyvar == Bar) { - /* Is ${||...} a subtitution error or a syntax error? - zerr("bad substitution"); - return NULL; - */ + if (endvar == s+1) { + /* For consistency with ${} we allow ${{}...} */ rplyvar = NULL; } - if (rplyvar && *rplyvar == Bar) { - cmdarg = dupstrpfx(rplyvar+1, outbracep-rplyvar-1); - rplyvar = dupstrpfx(s+1,rplyvar-s-1); + if (endvar && *endvar == Outbrace) { + cmdarg = dupstrpfx(endvar+1, outbracep-endvar-1); + rplyvar = dupstrpfx(s+1,endvar-s-1); } else { cmdarg = dupstrpfx(s+1, outbracep-s-1); rplyvar = "REPLY"; } - if (inblank(*s)) { + if (inblank(inchar)) { /* - * Admittedly a hack. Take advantage of the enforced - * locality of REPLY and the semantics of $(level = locallevel; - /* if (rplyval) setsparam("REPLY", ztrdup(rplyval)); */ + if (inchar == Bar) { + /* rplyvar should be REPLY at this point, but create + * hardwired name anyway to expose any bugs elsewhere + */ + rplypm = createparam("REPLY", PM_LOCAL|PM_UNSET|PM_HIDE); + if (rplypm) /* Shouldn't createparam() do this? */ + rplypm->level = locallevel; + /* Future? Expose global value of $REPLY if any? */ + /* if (rplyval) setsparam("REPLY", ztrdup(rplyval)); */ + } else if (inblank(inchar)) { + rplypm = createparam(".zsh.cmdsubst", + PM_LOCAL|PM_UNSET|PM_HIDE| + PM_READONLY_SPECIAL); + if (rplypm) + rplypm->level = locallevel; + } + if (inchar != Inbrace && !rplypm) { + zerr("failed to create scope for command substitution"); + return NULL; + } } if (rplyvar && cmdarg && *cmdarg) { int obreaks = breaks; Eprog cmdprog; /* Execute the shell command */ + queue_signals(); untokenize(cmdarg); cmdprog = parse_string(cmdarg, 0); if (cmdprog) { + /* exec.c handles dont_queue_signals() */ execode(cmdprog, 1, 0, "cmdsubst"); cmdoutval = lastval; /* "return" behaves as if in a function */ @@ -2002,6 +2051,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } } else /* parse error */ errflag |= ERRFLAG_ERROR; + if (rplypm) + rplypm->node.flags &= ~PM_READONLY_SPECIAL; if (rplytmp && !errflag) { int onoerrs = noerrs, rplylen; noerrs = 2; @@ -2017,15 +2068,16 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } noerrs = onoerrs; if (rplylen >= 0) - setsparam("REPLY", metafy(cmdarg, rplylen, META_REALLOC)); + setsparam(rplyvar, metafy(cmdarg, rplylen, META_REALLOC)); } + unqueue_signals(); } if (rplytmp) unlink(rplytmp); if (rplyvar) { - if (strcmp(rplyvar, "REPLY") == 0) { - if ((val = dupstring(getsparam("REPLY")))) + if (inchar != Inbrace) { + if ((val = dupstring(getsparam(rplyvar)))) vunset = 0; else { vunset = 1; diff --git a/Test/D10nofork.ztst b/Test/D10nofork.ztst index fc6b84613..5bb10266f 100644 --- a/Test/D10nofork.ztst +++ b/Test/D10nofork.ztst @@ -14,6 +14,28 @@ 0:Basic substitution and REPLY scoping >INNER OUTER + reply=(x OUTER x) + purl ${{reply} reply=(\{ INNER \})} $reply +0:Basic substitution, brace quoting, and array result +>{ +>INNER +>} +>{ +>INNER +>} + + () { + setopt localoptions ignorebraces + purl ${{reply} reply=({ INNER })} $reply + } +0:Basic substitution, ignorebraces, and array result +>{ +>INNER +>} +>{ +>INNER +>} + purr ${| REPLY=first}:${| REPLY=second}:$REPLY 0:re-scoping of REPLY in one statement >first:second:OUTER @@ -229,7 +251,7 @@ F:Why not use this error in the previous case as well? >26 unset reply - purl ${|reply| reply=(1 2 ${| REPLY=3 } 4) } + purl ${{reply} reply=(1 2 ${| REPLY=3 } 4) } typeset -p reply 0:array behavior with global assignment >1 @@ -315,7 +337,7 @@ F:status of "print" should hide return unset zz outer=GLOBAL - purr "${|zz| + purr "${{zz} local outer=LOCAL zz=NONLOCAL } $outer $?" @@ -440,7 +462,8 @@ F:must do this before evaluating the next test block 0:ignored braces, part 1 >buried} - purr "${ purr ${REPLY:-buried}}}" + # Global $REPLY still set from earlier test + purr "${ purr ${REPLY:+buried}}}" 0:ignored braces, part 2 >buried >} @@ -453,6 +476,7 @@ F:must do this before evaluating the next test block 1:ignored braces, part 4 ?(eval):3: parse error near `}' + unsetopt ignorebraces # "break" blocks function calls in outer loop # Could use print, but that might get fixed repeat 3 do purr ${ @@ -467,11 +491,25 @@ F:must do this before evaluating the next test block ?1 ?2 - print -u $ZTST_fd ${ZTST_testname}: TEST COMPLETE -0:make sure we got to the end -F:some tests might silently break the test harness + # Cannot "purr": break skips pending function calls + # Use "repeat" to avoid infinite loop on failure + repeat 3 do; echo ${|REPLY=x; break }; done + repeat 3 do; echo ${{x} x=y; break }; done + repeat 3 do; echo ${ echo z; break }; done +0:break after assignment completes the assignment +>x +>y +>z + + # Subshell because error exits + ( purr ${ echo ${unset?oops} } ) +1:error handling (without crashing) +*?*unset: oops + + purr ${ .zsh.cmdsubst=error } +1:reserved parameter name (without crashing) +*?*.zsh.cmdsubst: can't modify read-only parameter %clean unfunction purr purl - unsetopt ignorebraces diff --git a/Test/V10private.ztst b/Test/V10private.ztst index ed51316f3..26004a2dc 100644 --- a/Test/V10private.ztst +++ b/Test/V10private.ztst @@ -497,7 +497,7 @@ F:Better if caught in checkclobberparam() but exec.c doesn't know scope () { private z=outer print ${(t)z} $z - print ${| REPLY=${|z| z=nofork} } + print ${| REPLY=${{z} z=nofork} } print ${(t)z} $z } 0:nofork may write to private in calling function @@ -518,9 +518,9 @@ F:Better if caught in checkclobberparam() but exec.c doesn't know scope () { private z=outer print ${(t)z} $z - print ${|z| + print ${{z} private q - z=${|q| q=nofork} + z=${{q} q=nofork} } print ${(t)z} $z } @@ -533,7 +533,7 @@ F:Better if caught in checkclobberparam() but exec.c doesn't know scope print ${| () { REPLY="{$q}" } } - print ${|q| + print ${{q} () { q=nofork } } } -- cgit v1.2.3 From 49c6978dbbb717847344e7cef99e4ee26f56d234 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 1 Apr 2024 22:38:27 -0700 Subject: 52865: Documentation update for 52864 --- ChangeLog | 3 +++ Doc/Zsh/expn.yo | 13 +++++++------ Doc/Zsh/params.yo | 4 ++-- Etc/FAQ.yo | 20 +++++++++++--------- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9476c50ab..643a33dac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-04-01 Bart Schaefer + * 52865: Doc/Zsh/expn.yo, Doc/Zsh/params.yo, Etc/FAQ.yo: + Documentation update for 52864 + * 52864: Src/lex.c, Src/subst.c, Test/D10nofork.ztst, Test/V10private.ztst: Change ${|var|...} to ${{var} ...}, limit local REPLY behavior to ${|...}, update tests. diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 0e121e784..7eade4a11 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1937,13 +1937,14 @@ split on tt(IFS) unless the tt(SH_WORD_SPLIT) option is set. cindex(substitution, command, current shell) cindex(substitution, command, non forking) cindex(substitution, nofork) -Substitutions of the form `tt(${|)var(param)tt(|)...tt(})' are similar, +Substitutions of the form `tt(${{)var(param)tt(}) ...tt(})' are similar, except that the substitution is replaced by the value of the parameter named by var(param). No implicit save or restore applies to var(param) -except as noted for tt(REPLY), and var(param) should em(not) be declared -within the command. If, after evaluating the expression, var(param) -names an array, array expansion rules apply. However, tt(REPLY) is -always expanded in scalar context, even if assigned an array. +and var(param) should em(not) be declared within the command. No space +is allowed within `tt(${{)' and space or newline is required after +`tt({)var(param)tt(})'. The var(param) may include a subscript, and if, +after evaluating the expression, var(param) names an array, then array +expansion rules apply to the final substitution. A command enclosed in braces preceded by a dollar sign, and set off from the braces by whitespace, like `tt(${ )...tt( })', is replaced by its @@ -1954,7 +1955,7 @@ Word splitting does not apply unless tt(SH_WORD_SPLIT) is set, but a single trailing newline is stripped unless the substitution is enclosed in double quotes. -Note that because the `tt(${|)...tt(})' and `tt(${ )...tt( })' forms +Note that because `tt(${|)...tt(})' and the two related substitutions must be parsed at once as both string tokens and commands, all other braces (`tt({)' or `tt(})') within the command either must be quoted, or must appear in syntactically valid pairs, such as around complex diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 9516c84de..02ce796a9 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1032,8 +1032,8 @@ the shell. ) item(tt(cmdsubst))( Command substitution using of the tt(`)var(...)tt(`), -tt($+LPAR())var(...)tt(RPAR()), tt(${ )var(...)tt( }) or -tt(${|)var(...)tt(}) constructs. +tt($+LPAR())var(...)tt(RPAR()),tt(${{)var(name)tt(}) var(...)tt(}), +tt(${|)var(...)tt(}), or tt(${ )var(...)tt( }) constructs. ) item(tt(equalsubst))( The tt(=+LPAR())var(...)tt(RPAR()) form of process substitution. diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 4d71c8f30..4e11637ea 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -1047,15 +1047,18 @@ label(211) ) Runs code in the current shell context and then substitutes mytt(${REPLY}). The result is not split into words unless the tt(SH_WORD_SPLIT) option - is set, for example by mytt(${=${| code }}). + is set, for example by mytt(${=${| code }}). mytt($REPLY) is a local + parameter within the substitution so its value in the surrounding scope + is not changed. eit() An extension to #1 verb( - ${|var| code } + ${{var} code } ) Runs code in the current shell and then substitutes mytt(${var}). If mytt(${var}) names an array, the result is an array of those elements, - but no further splitting is done without tt(SH_WORD_SPLIT). + but no further splitting is done without tt(SH_WORD_SPLIT). mytt(${var}) + is myem(not) local to the substitution. eit() The traditional ksh form, except that the closing mytt(;) may usually be omitted: @@ -1071,12 +1074,11 @@ label(211) In all three forms mytt(code) behaves myem(similarly) to an anonymous function invoked like: verb( - () { local REPLY; code } "$@" + () { code } "$@" ) - Thus, mytt($REPLY) is implicitly local and returns to its previous - value after the substitution ends, all other parameters declared from - inside the substitution are also local by default, and positional - parameters mytt($1), mytt($2), etc. are those of the calling context. + Thus, all parameters declared inside the substitution are local by + default, and positional parameters mytt($1), mytt($2), etc. are those + of the calling context. The most significant limitation is that braces (mytt({) and mytt(})) within the substitutions must either be in balanced pairs, or must be @@ -1096,7 +1098,7 @@ sect(Comparisons of forking and non-forking command substitution) bash and ksh, unquoted non-forking substitutions behave like parameter expansions with respect to the tt(SH_WORD_SPLIT) option. - Both of the mytt(${|...}) formats retain any trailing newlines, + Both mytt(${|...}) and mytt(${{var} ...}) retain any trailing newlines, except as handled by the tt(SH_WORD_SPLIT) option, consistent with mytt(${|...}) from mksh. mytt(${ command }) removes a single final newline, but mytt("${ command }") retains it. This differs from -- cgit v1.2.3 From a66e92918568881af110a3e2e3018b317c054e4a Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sat, 6 Apr 2024 00:19:53 +0200 Subject: 52878: Fix ${foo:^bar} where bar is an associative array --- ChangeLog | 5 +++++ Src/subst.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 643a33dac..df3f9b73c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-04-07 Mikael Magnusson + + * 52878: Src/subst.c: Fix ${foo:^bar} where bar is an associative + array + 2024-04-01 Bart Schaefer * 52865: Doc/Zsh/expn.yo, Doc/Zsh/params.yo, Etc/FAQ.yo: diff --git a/Src/subst.c b/Src/subst.c index f0d6c7a7b..a079672df 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3474,6 +3474,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } else { char *sval; zip = getaparam(s); + if (!zip) { + zip = gethparam(s); + } if (!zip) { sval = getsparam(s); if (sval) -- cgit v1.2.3 From acdcf9d8542a4461c0fceb98fdfef7380a128f78 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 8 May 2024 09:28:06 +0100 Subject: 52915: be explicit about pattern syntax in conditions --- ChangeLog | 5 +++++ Doc/Zsh/cond.yo | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index df3f9b73c..d3980ecfe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-05-08 Peter Stephenson + + * 52915: Doc/Zsh/cond.yo: be explicit about behaviour of globbing + patterns within conditions. + 2024-04-07 Mikael Magnusson * 52878: Src/subst.c: Fix ${foo:^bar} where bar is an associative diff --git a/Doc/Zsh/cond.yo b/Doc/Zsh/cond.yo index 000e576d0..db92cc766 100644 --- a/Doc/Zsh/cond.yo +++ b/Doc/Zsh/cond.yo @@ -241,7 +241,11 @@ ifnzman(\ noderef(Filename Generation)\ )\ , but there is no special behaviour -of `tt(/)' nor initial dots, and no glob qualifiers are allowed. +of `tt(/)' nor initial dot, and the patterns `tt(**/)' and `tt(***/)' behave +the same as `tt(*/)', in which the `tt(*)' has its standard behaviour +but may also match further `tt(/)' characters. Also, no bare glob +qualifiers are allowed, though the form `((#q)var(...))' is allowed as +shown above. In each of the above expressions, if var(file) is of the form `tt(/dev/fd/)var(n)', -- cgit v1.2.3 From efb7a962073988b4212820b02017980f5ec83f38 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 10 May 2024 11:21:31 +0100 Subject: 52924: Set zfsessions to NULL after free --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index d3980ecfe..6a753e3f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-05-10 Peter Stephenson + + * 52924: Src/Modules/zftp.c: NULL zfsessions after free. + 2024-05-08 Peter Stephenson * 52915: Doc/Zsh/cond.yo: be explicit about behaviour of globbing -- cgit v1.2.3 From f6e005a9ef55b1fbc5291729faa2ab46bf3d9e8f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 13 May 2024 11:26:06 +0100 Subject: Ooops, missed the actualy patch from the foregoing... --- Src/Modules/zftp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 0c26828fd..b60e5bf31 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -3147,6 +3147,7 @@ zftp_cleanup(void) lastmsg = NULL; zfunsetparam("ZFTP_SESSION"); freelinklist(zfsessions, (FreeFunc) freesession); + zfsessions = NULL; zfree(zfstatusp, sizeof(int)*zfsesscnt); zfstatusp = NULL; } -- cgit v1.2.3 From bd19d4e3948253af621fcb6e1a1f8a7b37115fdd Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 21 Apr 2024 00:53:50 +0200 Subject: 52895: Partial revert of 44274 which broke _baudrates _description does not accept -o numeric, which resulted in _description:zformat:89: invalid argument: expl The array is already sorted correctly in the completer so I don't see any need to have the completion sort it again anyway. --- ChangeLog | 5 +++++ Completion/Unix/Type/_baudrates | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6a753e3f9..d4610155f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-05-20 Mikael Magnusson + + * 52895: Completion/Unix/Type/_baudrates: Partial revert of + 44274 which broke _baudrates + 2024-05-10 Peter Stephenson * 52924: Src/Modules/zftp.c: NULL zfsessions after free. diff --git a/Completion/Unix/Type/_baudrates b/Completion/Unix/Type/_baudrates index a9d7fe541..416a4919f 100644 --- a/Completion/Unix/Type/_baudrates +++ b/Completion/Unix/Type/_baudrates @@ -72,6 +72,7 @@ if (( ${+opts[-f]} )); then done fi -# -1 removes dupes (which there shouldn't be) -_description -1 -o numeric baud-rates expl 'baud rate' +# -1V removes dupes (which there shouldn't be) and otherwise leaves the +# order in the $rates array intact. +_description -1V baud-rates expl 'baud rate' compadd "${argv[@]}" "$expl[@]" -- "${rates[@]}" -- cgit v1.2.3 From 7f196de9d7f1034a6a8cc7730280f21f7eb0a7f3 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 24 May 2024 19:22:44 -0700 Subject: 52904: Improve quoting of paths passed via _call_program to "git ls-files" --- ChangeLog | 5 +++++ Completion/Unix/Command/_git | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d4610155f..642b40821 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-05-24 Bart Schaefer + + * 52904: Completion/Unix/Command/_git: Improve quoting of paths + passed via _call_program to "git ls-files" + 2024-05-20 Mikael Magnusson * 52895: Completion/Unix/Type/_baudrates: Partial revert of diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 7370aaead..22b945e38 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -7531,7 +7531,7 @@ __git_files () { # First allow ls-files to pattern-match in case of remote repository. Use the # icase pathspec magic word to ensure that we support case-insensitive path # completion for users with the appropriate matcher configuration - files=(${(0)"$(_call_program files git ls-files -z --exclude-standard ${(q)opts} -- ${(q)${pref:+:\(icase\)$pref\*}:-.} 2>/dev/null)"}) + files=(${(0)"$(_call_program files git ls-files -z --exclude-standard ${(q)opts} -- ${(q)${pref:+:\(icase\)${(qq)pref}\*}:-.} 2>/dev/null)"}) __git_command_successful $pipestatus || return # If ls-files succeeded but returned nothing, try again with no pattern. Note -- cgit v1.2.3 From 300ce96080b0679038db946ef34ac5c2d26646b5 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 24 May 2024 19:24:23 -0700 Subject: 52910: Improve handling of **/ patterns --- ChangeLog | 2 ++ Functions/Misc/zmv | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 642b40821..7f3412f8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-05-24 Bart Schaefer + * 52910: Functions/Misc/zmv: Improve handling of **/ patterns + * 52904: Completion/Unix/Command/_git: Improve quoting of paths passed via _call_program to "git ls-files" diff --git a/Functions/Misc/zmv b/Functions/Misc/zmv index 5c03e9ea1..2002af5a6 100644 --- a/Functions/Misc/zmv +++ b/Functions/Misc/zmv @@ -249,13 +249,13 @@ errs=() (( ${#files} )) || errs=( "no files matched \`$fpat'" ) for f in $files; do - if [[ $pat = (#b)(*)\(\*\*##/\)(*) ]]; then + if [[ $pat = (#b)(*)(\(\*\*##/\)|\*\*##/)(*) ]]; then # This looks like a recursive glob. This isn't good enough, - # because we should really enforce that $match[1] and $match[2] + # because we should really enforce that $match[1] and $match[3] # don't match slashes unless they were explicitly given. But # it's a start. It's fine for the classic case where (**/) is # at the start of the pattern. - pat="$match[1](*/|)$match[2]" + pat="$match[1](*/|)$match[3]" fi [[ -e $f && $f = (#b)${~pat} ]] || continue set -- "$match[@]" -- cgit v1.2.3 From 9dcaf78997508f45105f11a28932fcb6b113d27e Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 24 May 2024 19:27:14 -0700 Subject: users/29882: Explain $RANDOM predictability --- ChangeLog | 2 ++ Etc/FAQ.yo | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7f3412f8e..bbd1c99be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-05-24 Bart Schaefer + * users/29882: Etc/FAQ.yo: Explain $RANDOM predictability + * 52910: Functions/Misc/zmv: Improve handling of **/ patterns * 52904: Completion/Unix/Command/_git: Improve quoting of paths diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 4e11637ea..2c83fe7fa 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -137,6 +137,7 @@ Chapter 3: How to get various things to work 3.28. How do I edit the input buffer in $EDITOR? 3.29. Why does `which' output for missing commands go to stdout? 3.30. Why doesn't the expansion mytt(*.{tex,aux,pdf}) do what I expect? +3.31. Why does mytt($RANDOM) return the same number more than once? Chapter 4: The mysteries of completion 4.1. What is completion? @@ -2219,6 +2220,37 @@ sect(Why doesn't the expansion mytt(*.{tex,aux,pdf}) do what I expect?) This is harder for the user to remember but easier for the shell to parse! +sect(Why does mytt($RANDOM) return the same number more than once?) + + As tt(zshparam(1)) says: + verb( + The values of RANDOM form an intentionally-repeatable + pseudo-random sequence; subshells that reference RANDOM + will result in identical pseudo-random values unless the + value of RANDOM is referenced or seeded in the parent shell + in between subshell invocations. + ) + + You can use a function, including an anonymous function, to always + evaluate mytt($RANDOM) in the parent shell. This example illustrates + the difference: + verb( + for i in {1..10}; do + echo subshell: $(echo $RANDOM) $RANDOM + () { echo parent: $(echo $1) $2 } $RANDOM $RANDOM; + done + ) + + Remember that for a pipe like mytt(A | B), zsh runs A in a subshell + and B in the current shell. This means that, for example: + verb( + for i in {1..10}; do + echo $RANDOM | tee + done + ) + also repeats the same value, because mytt($RANDOM) is evaluated in + the subshell and the parent sequence is left unchanged. + chapter(The mysteries of completion) sect(What is completion?) -- cgit v1.2.3 From 9a79a60c90ca0001f1d792dc01c0da0dcf179668 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sat, 8 Jun 2024 17:49:54 +0200 Subject: 52946: Revert "Handle completer filenames with funny characters in them" This reverts commit 88f47569030b12345aee3bd857e424351ee61726. --- ChangeLog | 4 ++++ Completion/compdump | 6 +++--- Completion/compinit | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index bbd1c99be..29546095d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-06-08 Mikael Magnusson + + * 52946: Completion/compdump, Completion/compinit: Revert 52768 + 2024-05-24 Bart Schaefer * users/29882: Etc/FAQ.yo: Explain $RANDOM predictability diff --git a/Completion/compdump b/Completion/compdump index 5af5174f1..6daf92f9f 100644 --- a/Completion/compdump +++ b/Completion/compdump @@ -113,7 +113,7 @@ integer _i=5 print -n autoload -Uz >& $_d_fd while (( $#_d_als )); do if (( ! $+_compautos[$_d_als[1]] )); then - print -rn " ${(q-)_d_als[1]}" + print -n " $_d_als[1]" if (( ! --_i && $#_d_als > 1 )); then _i=5 print -n ' \\\n ' @@ -126,13 +126,13 @@ print >& $_d_fd local _c for _c in "${(ok@)_compautos}"; do - print -r "autoload -Uz ${(q-)_compautos[$_c]} $_c" >& $_d_fd + print "autoload -Uz $_compautos[$_c] $_c" >& $_d_fd done print >& $_d_fd print "typeset -gUa _comp_assocs" >& $_d_fd -print -r "_comp_assocs=( ${(qq)_comp_assocs} )" >& $_d_fd +print "_comp_assocs=( ${(qq)_comp_assocs} )" >& $_d_fd exec {_d_fd}>&- mv -f $_d_file ${_d_file%.$HOST.$$} diff --git a/Completion/compinit b/Completion/compinit index 51e9d88b8..5cb527fac 100644 --- a/Completion/compinit +++ b/Completion/compinit @@ -301,7 +301,7 @@ compdef() { if [[ -z "$eval" ]] && [[ "$1" = *\=* ]]; then while (( $# )); do if [[ "$1" = *\=* ]]; then - cmd="${(q)${1%%\=*}}" + cmd="${1%%\=*}" svc="${1#*\=}" func="$_comps[${_services[(r)$svc]:-$svc}]" [[ -n ${_services[$svc]} ]] && @@ -412,7 +412,7 @@ compdef() { svc= fi if [[ -z "$new" || -z "${_comps[$1]}" ]]; then - _comps[$cmd]="${(q)func}" + _comps[$cmd]="$func" [[ -n "$svc" ]] && _services[$cmd]="${1#*\=}" fi ;; -- cgit v1.2.3 From a3b56d4f03e493985aa652248e9476c1f8181e4e Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 13 Jun 2024 11:12:41 +0900 Subject: 52951: make sure to close memstream for 'print -v' --- ChangeLog | 4 ++++ Src/builtin.c | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 29546095d..455cf38c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-06-13 Jun-ichi Takimoto + + * 52951: Src/builtin.c: make sure to close memstream for 'print -v' + 2024-06-08 Mikael Magnusson * 52946: Completion/compdump, Completion/compinit: Revert 52768 diff --git a/Src/builtin.c b/Src/builtin.c index 7bfb1ce1d..cd0ee7522 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5455,9 +5455,8 @@ bin_print(char *name, char **args, Options ops, int func) } zwarnnam(name, "%s: invalid directive", start); if (*c) c[1] = save; - /* Why do we care about a clean close here? */ - if (!CLOSE_CLEANLY(fout)) - zwarnnam(name, "write error: %e", errno); + if (fout != stdout) + fclose(fout); #ifdef HAVE_OPEN_MEMSTREAM if (buf) free(buf); -- cgit v1.2.3 From 98a877d32c5ec047c3985183db655cccc707920f Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 24 Jun 2024 12:54:08 +0900 Subject: 52968: use pdfroff to create intro.pdf roff2ps is removed in groff-1.23.0 (Jul. 2023). The "doubled output" problem was fixed in groff-1.22.3 (Nov. 2014). --- ChangeLog | 4 ++++ Doc/Makefile.in | 8 +++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 455cf38c3..36fae8a51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-06-24 Jun-ichi Takimoto + + * 52968: Doc/Makefile.in: use pdfroff to create intro.pdf + 2024-06-13 Jun-ichi Takimoto * 52951: Src/builtin.c: make sure to close memstream for 'print -v' diff --git a/Doc/Makefile.in b/Doc/Makefile.in index d9be182e9..401fb942b 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -118,15 +118,13 @@ zsh.pdf zsh_a4.pdf zsh_us.pdf: $(sdir)/zsh.texi $(TEXI2PDF) -o $@ -t @afourpaper $(sdir)/zsh.texi; \ fi -# Use roff2ps / ps2pdf because pdfroff produces doubled output. intro.pdf intro.a4.pdf intro.us.pdf: $(sdir)/intro.ms if test $@ = intro.us.pdf || \ { test $@ = intro.pdf && test "$(PAPERSIZE)" = us; }; then \ - roff2ps -ms -P-pletter < $(sdir)/intro.ms > intro.ps; \ + pdfroff -ms -P-pletter $(sdir)/intro.ms > $@; \ else \ - roff2ps -ms -P-pa4 < $(sdir)/intro.ms > intro.ps; \ - fi; \ - ps2pdf -sOutputFile=$@ intro.ps + pdfroff -ms -P-pa4 $(sdir)/intro.ms > $@; \ + fi texi: $(sdir)/zsh.texi .PHONY: texi -- cgit v1.2.3 From da733f5df691d01caff0a01addba234aad1b6864 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Fri, 28 Jun 2024 21:05:42 -0700 Subject: 52977: ERR_EXIT/ERR_RETURN are respected by the final command in && / || lists --- Src/exec.c | 1 + Test/C03traps.ztst | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/Src/exec.c b/Src/exec.c index e955e85df..a473938ec 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1568,6 +1568,7 @@ execlist(Estate state, int dont_change_job, int exiting) } state->pc = next; code = *state->pc++; + noerrexit = oldnoerrexit; } state->pc--; sublist_done: diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index de57765a0..87b7fd1f7 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -995,6 +995,33 @@ F:Must be tested with a top-level script rather than source or function ?loop 0 ?loop 1 + ( set -e; true && {false; echo NOT REACHED} ) + ( trap "print Trapped!" ERR; true && {false} ) + ( trap "print Trapped!" ERR; true && if true; then false; fi ) + ( trap "print Trapped!" ERR; true && {false} always {true} ) + ( true && (set -e; false; echo NOT REACHED) ) + ( true && (trap "print Trapped!" ERR; false) ) + ( true && { set -e; false; echo NOT REACHED } ) + ( true && { trap "print Trapped!" ERR; false } ) + ( set -e; true && (false; echo one) || echo two ) + ( set -e; true && { false; echo one; } || echo two ) +0:ERR_EXIT is triggered by last command in an AND-OR list +>Trapped! +>Trapped! +>Trapped! +>Trapped! +>Trapped! +>one +>one + + ( set -o ERR_RETURN; f() { false; echo NOT REACHED; }; f || true; echo OK ) + ( set -o ERR_RETURN; f() { true && false; echo NOT REACHED; }; f || true; echo OK ) + ( set -o ERR_RETURN; f() { true && { false }; echo NOT REACHED; }; f || true; echo OK ) +0:ERR_RETURN is triggered in function calls on the left of an AND-OR +>OK +>OK +>OK + if zmodload zsh/system 2>/dev/null; then ( trap 'echo TERM; exit 2' TERM -- cgit v1.2.3 From 2a54de167586c3b8b03019b5c52021c608bd310e Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 4 Jul 2024 11:51:09 +0900 Subject: 52985: avoid adding original param to restorelist --- ChangeLog | 4 ++++ Src/exec.c | 7 +++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 36fae8a51..d173df87e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-07-04 Jun-ichi Takimoto + + * 52985: Src/exec.c: avoid adding original param to restorelist + 2024-06-24 Jun-ichi Takimoto * 52968: Doc/Makefile.in: use pdfroff to create intro.pdf diff --git a/Src/exec.c b/Src/exec.c index a473938ec..097e0b368 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4409,7 +4409,7 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p) while (wc_code(ac = *pc) == WC_ASSIGN) { s = ecrawstr(state->prog, pc + 1, NULL); if ((pm = (Param) paramtab->getnode(paramtab, s))) { - Param tpm; + Param tpm = NULL; if (pm->env) delenv(pm); if (!(pm->node.flags & PM_SPECIAL)) { @@ -4426,7 +4426,6 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p) tpm = (Param) zshcalloc(sizeof *tpm); tpm->node.nam = ztrdup(pm->node.nam); copyparam(tpm, pm, 0); - pm = tpm; } else if (!(pm->node.flags & PM_READONLY) && (unset(RESTRICTED) || !(pm->node.flags & PM_RESTRICTED))) { /* @@ -4437,10 +4436,10 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p) tpm = (Param) hcalloc(sizeof *tpm); tpm->node.nam = pm->node.nam; copyparam(tpm, pm, 1); - pm = tpm; } addlinknode(*remove_p, dupstring(s)); - addlinknode(*restore_p, pm); + if (tpm) + addlinknode(*restore_p, tpm); } else addlinknode(*remove_p, dupstring(s)); -- cgit v1.2.3 From 09c5b10dc2affbe4e46f69e64d573b197c14b988 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 13 Jul 2024 23:04:22 -0500 Subject: Missed commit of ChangeLog for 52977 / da733f5d --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index d173df87e..5c6270d05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,12 @@ * 52985: Src/exec.c: avoid adding original param to restorelist +2024-06-28 Bart Schaefer + + * Philippe Altherr: 52977: Src/exec.c, Test/C03traps.ztst: fix + and test regression so that ERR_EXIT and ERR_RETURN are respected + by the final command in an && / || sequence. + 2024-06-24 Jun-ichi Takimoto * 52968: Doc/Makefile.in: use pdfroff to create intro.pdf -- cgit v1.2.3 From 0bb140f9911851e9712dba311925f9c9ab521fd2 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 28 Jul 2024 20:33:07 +0100 Subject: 52999: import OLDPWD from environment if set --- ChangeLog | 5 +++++ Src/init.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5c6270d05..22ccce77a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-07-28 Peter Stephenson + + * 52999: Franklin Yu (adapted): Src/init.c: Import OLDPWD from + the environment if set. + 2024-07-04 Jun-ichi Takimoto * 52985: Src/exec.c: avoid adding original param to restorelist diff --git a/Src/init.c b/Src/init.c index ec21521b1..0aecb5db9 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1245,7 +1245,11 @@ setupvals(char *cmd, char *runscript, char *zsh_name) pwd = metafy(zgetcwd(), -1, META_DUP); } - oldpwd = ztrdup(pwd); /* initialize `OLDPWD' = `PWD' */ + oldpwd = zgetenv("OLDPWD"); + if (oldpwd == NULL) + oldpwd = ztrdup(pwd); /* initialize `OLDPWD' = `PWD' */ + else + oldpwd = ztrdup(oldpwd); inittyptab(); /* initialize the ztypes table */ initlextabs(); /* initialize lexing tables */ -- cgit v1.2.3 From 5cb32ec5ab1eafdad62500e7e6bdada2c3205a59 Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Sat, 3 Aug 2024 20:07:51 -0400 Subject: 52989: _rsync: support rsync 3.2.4+ remote filename handling. --- ChangeLog | 6 ++++++ Completion/Unix/Command/_rsync | 10 +++++++++- Completion/Unix/Type/_remote_files | 20 +++++++++++++++----- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22ccce77a..f47690476 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-08-03 Eric Cook + + * 52989: Completion/Unix/Command/_rsync, + Completion/Unix/Type/_remote_files: support rsync 3.2.4+ remote + filename handling. + 2024-07-28 Peter Stephenson * 52999: Franklin Yu (adapted): Src/init.c: Import OLDPWD from diff --git a/Completion/Unix/Command/_rsync b/Completion/Unix/Command/_rsync index c65266dbd..81d25a3f4 100644 --- a/Completion/Unix/Command/_rsync +++ b/Completion/Unix/Command/_rsync @@ -60,7 +60,14 @@ elif compset -P 1 '*::' || compset -P 1 'rsync://*/'; then elif compset -P 'rsync://'; then _rsync_user_or_host / "$@" elif compset -P 1 '*:'; then - _remote_files -- ssh + if [[ -v opt_args[(i)client---old-args] || $RSYNC_OLD_ARGS = 1 ]]; then + _remote_files -- ssh + else + # the 3.2.4+ way that rsync handles filenames does not protect *, ? and [] + # so those characters still need to be escaped to prevent being treated as + # a pattern in the remote shell. + _remote_files -Q '[][*?]' -- ssh + fi else _rsync_user_or_host : "$@" fi @@ -236,6 +243,7 @@ _rsync() { '*--include=[do not exclude files matching pattern]:pattern' \ '--files-from=[read list of source-file names from specified file]:file:_files' \ '(-0 --from0)'{-0,--from0}'[all *-from file lists are delimited by nulls]' \ + '--old-args[disable the modern arg-protection idiom]' \ '(-s --secluded-args)'{-s,--secluded-args}'[use the protocol to safely send arguments]' \ "--trust-sender[trust the remote sender's file list]" \ '--copy-as=[specify user & optional group for the copy]:user:_rsync_users_groups' \ diff --git a/Completion/Unix/Type/_remote_files b/Completion/Unix/Type/_remote_files index 93e1b7f43..15c20e5c1 100644 --- a/Completion/Unix/Type/_remote_files +++ b/Completion/Unix/Type/_remote_files @@ -11,6 +11,8 @@ # - -g: specify a pattern to match against files # p, = and * glob qualifiers supported # - -h: specify the remote host, default is ${IPREFIX%:} +# - -Q: specify a pattern of characters to escape in the returned filenames, +# instead of shell metacharacters that ${(q)name} does # - -W: specify the parent directory to list files from, # default is the home directory # @@ -31,14 +33,14 @@ # There should be coloring based on all the different ls -F classifiers. -local expl rempat remfiles remdispf remdispd args cmd suf ret=1 +local expl rempat remfiles remdispf{,q} remdispd{,q} args cmd suf ret=1 local -a args cmd_args -local glob host dir dirprefix +local glob host dir esc dirprefix if zstyle -T ":completion:${curcontext}:files" remote-access; then # Parse options to _remote_files. Stops at the first "--". - zparseopts -D -E -a args / g:=glob h:=host W:=dir + zparseopts -D -E -a args / g:=glob h:=host W:=dir Q:=esc (( $#host)) && shift host || host="${IPREFIX%:}" args=( ${argv[1,(i)--]} ) @@ -85,6 +87,14 @@ if zstyle -T ":completion:${curcontext}:files" remote-access; then remdispf=( ${(M)remdispf:#${~glob[2]}} ) fi + if (( $#esc )); then + remdispfq=(${${remdispf%[*=|]}//(#b)(${~esc[2]})/\\$match[1]}) + remdispdq=(${${remdispd%/}//(#b)(${~esc[2]})/\\$match[1]}) + else + remdispfq=(${(q)remdispf%[*=|]}) + remdispdq=(${(q)remdispd%/}) + fi + local -a autoremove [[ -o autoremoveslash ]] && autoremove=(-r "/ \t\n\-") @@ -92,9 +102,9 @@ if zstyle -T ":completion:${curcontext}:files" remote-access; then while _tags; do while _next_label remote-files expl ${suf:-remote directory}; do [[ -n $suf ]] && - compadd "$args[@]" "$expl[@]" -d remdispf -- ${(q)remdispf%[*=|]} && ret=0 + compadd "$args[@]" "$expl[@]" -d remdispf -- $remdispfq && ret=0 compadd ${suf:+-S/} $autoremove "$args[@]" "$expl[@]" -d remdispd \ - -- ${(q)remdispd%/} && ret=0 + -- $remdispdq && ret=0 done (( ret )) || return 0 done -- cgit v1.2.3 From 4616ea398a5c1b04299dff9d25a8bc264c685540 Mon Sep 17 00:00:00 2001 From: Philippe Altherr Date: Sun, 4 Aug 2024 19:12:32 -0700 Subject: 53005: off-by-one error when resetting signals on subshell entrance --- ChangeLog | 5 +++++ Src/exec.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f47690476..41204dfd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-08-04 Bart Schaefer + + * Philippe Altherr: 53005: Src/exec.c: off-by-one error when + resetting signals on subshell entrance + 2024-08-03 Eric Cook * 52989: Completion/Unix/Command/_rsync, diff --git a/Src/exec.c b/Src/exec.c index 097e0b368..00278ac50 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1089,7 +1089,7 @@ entersubsh(int flags, struct entersubsh_ret *retp) int i, sig, monitor, job_control_ok; if (!(flags & ESUB_KEEPTRAP)) - for (sig = 0; sig < SIGCOUNT; sig++) + for (sig = 0; sig <= SIGCOUNT; sig++) if (!(sigtrapped[sig] & ZSIG_FUNC) && !(isset(POSIXTRAPS) && (sigtrapped[sig] & ZSIG_IGNORED))) unsettrap(sig); @@ -1203,7 +1203,7 @@ entersubsh(int flags, struct entersubsh_ret *retp) * Start loop at 1 because 0 is SIGEXIT */ if (intrap) - for (sig = 1; sig < SIGCOUNT; sig++) + for (sig = 1; sig <= SIGCOUNT; sig++) if (sigtrapped[sig] && sigtrapped[sig] != ZSIG_IGNORED) signal_unblock(signal_mask(sig)); if (!job_control_ok) -- cgit v1.2.3 From 65da4674410abac23e41f89f29f6613d74858854 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 5 Aug 2024 15:49:15 -0700 Subject: 53023: fix memory leak of unset private parameter --- ChangeLog | 4 ++++ Src/params.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 41204dfd6..56f6d0f35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-08-05 Bart Schaefer + + * 53023: Src/params.c: fix memory leak of unset private parameter + 2024-08-04 Bart Schaefer * Philippe Altherr: 53005: Src/exec.c: off-by-one error when diff --git a/Src/params.c b/Src/params.c index f65aa1e80..83bdb785d 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3790,7 +3790,7 @@ unsetparam_pm(Param pm, int altflag, int exp) altremove = NULL; pm->node.flags &= ~PM_DECLARED; /* like ksh, not like bash */ - if (!(pm->node.flags & PM_UNSET)) + if (!(pm->node.flags & PM_UNSET) || (pm->node.flags & PM_REMOVABLE)) pm->gsu.s->unsetfn(pm, exp); if (pm->env) delenv(pm); -- cgit v1.2.3 From 72751bfe1f9e37145c12e244ebb1729c27aff901 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 5 Aug 2024 15:59:48 -0700 Subject: 53025: fix memory leaks and pointer errors upon named reference self-reference --- ChangeLog | 3 +++ Src/loop.c | 2 +- Src/params.c | 12 +++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 56f6d0f35..2fa2f51a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-08-05 Bart Schaefer + * 53025: Src/loop.c, Src/params.c: fix two memory leaks and two + pointer errors when encountering a named reference self-reference + * 53023: Src/params.c: fix memory leak of unset private parameter 2024-08-04 Bart Schaefer diff --git a/Src/loop.c b/Src/loop.c index 0f3847541..84dc66476 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -165,7 +165,7 @@ execfor(Estate state, int do_exec) fprintf(xtrerr, "%s=%s\n", name, str); fflush(xtrerr); } - setloopvar(name, ztrdup(str)); + setloopvar(name, str); count++; } if (!count) diff --git a/Src/params.c b/Src/params.c index 83bdb785d..f143a790f 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2811,9 +2811,10 @@ assignstrvalue(Value v, char *val, int flags) break; } setscope(v->pm); - if ((!v->pm->env && !(v->pm->node.flags & PM_EXPORTED) && - !(isset(ALLEXPORT) && !(v->pm->node.flags & PM_HASHELEM))) || - (v->pm->node.flags & PM_ARRAY) || v->pm->ename) + if (errflag || + ((!v->pm->env && !(v->pm->node.flags & PM_EXPORTED) && + !(isset(ALLEXPORT) && !(v->pm->node.flags & PM_HASHELEM))) || + (v->pm->node.flags & PM_ARRAY) || v->pm->ename)) return; export_param(v->pm); } @@ -6330,9 +6331,10 @@ setloopvar(char *name, char *value) pm->node.flags &= ~PM_UNSET; pm->node.flags |= PM_NEWREF; setscope(pm); - pm->node.flags &= ~PM_NEWREF; + if (!errflag) + pm->node.flags &= ~PM_NEWREF; } else - setsparam(name, value); + setsparam(name, ztrdup(value)); } /**/ -- cgit v1.2.3 From b2f24ff0d2a9631f331c1841491ce60e69c20ca6 Mon Sep 17 00:00:00 2001 From: "Jun. T" Date: Tue, 6 Aug 2024 14:37:39 -0700 Subject: 53026: fix failure to free old value when setting new value of reference --- ChangeLog | 5 +++++ Src/params.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2fa2f51a3..667f17177 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-08-06 Bart Schaefer + + * Jun.T: 53026: Src/params.c: fix failure to free old value when + setting new value of reference + 2024-08-05 Bart Schaefer * 53025: Src/loop.c, Src/params.c: fix two memory leaks and two diff --git a/Src/params.c b/Src/params.c index f143a790f..acd577527 100644 --- a/Src/params.c +++ b/Src/params.c @@ -482,7 +482,8 @@ static initparam argvparam_pm = IPDEF9("", &pparams, NULL, \ #define GETREFNAME(PM) (((PM)->node.flags & PM_SPECIAL) ? \ (PM)->gsu.s->getfn(PM) : (PM)->u.str) #define SETREFNAME(PM,S) (((PM)->node.flags & PM_SPECIAL) ? \ - (PM)->gsu.s->setfn(PM,(S)) : ((PM)->u.str = (S))) + (PM)->gsu.s->setfn(PM,(S)) : \ + (zsfree((PM)->u.str), (PM)->u.str = (S))) static Param argvparam; -- cgit v1.2.3 From 8a811b369b8c7338a90bb85e12bc9f0cfb2b6b6d Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Tue, 13 Aug 2024 22:32:34 -0400 Subject: 53031: Completion/Unix/Command/_git: add missing terminator in case statement --- ChangeLog | 5 +++++ Completion/Unix/Command/_git | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 667f17177..1ed2100f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-08-13 Eric Cook + + * 53031: Christian Heusel: Completion/Unix/Command/_git: add + missing terminator in case statement + 2024-08-06 Bart Schaefer * Jun.T: 53026: Src/params.c: fix failure to free old value when diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 22b945e38..6c6d59b24 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -278,6 +278,7 @@ _git-bisect () { _arguments -C -s \ $log_options \ $revision_options && ret=0 + ;; (*) _nothing ;; -- cgit v1.2.3 From 5977d3cdd4b241ab7afff868ed58afc00b45c424 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 15 Aug 2024 18:06:19 -0700 Subject: unposted: fix parsing of Bang token in value side of array element assignment --- ChangeLog | 5 +++++ Src/lex.c | 3 ++- Test/A06assign.ztst | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1ed2100f1..eec96a494 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-08-15 Bart Schaefer + + * unposted (see 53034): Src/lex.c, Test/A06assign.ztst: fix parsing + of Bang token in value side of array element assignment + 2024-08-13 Eric Cook * 53031: Christian Heusel: Completion/Unix/Command/_git: add diff --git a/Src/lex.c b/Src/lex.c index 700af2da1..efbb62b66 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -1402,10 +1402,11 @@ gettokstr(int c, int sub) /* * Same logic as Dash, for ! to perform negation in range. */ - if (seen_brct) + if (seen_brct && brct) c = Bang; else c = '!'; + break; case LX2_OTHER: if (in_brace_param) { if (c == '/') { diff --git a/Test/A06assign.ztst b/Test/A06assign.ztst index 3eff5331a..9f779b9a8 100644 --- a/Test/A06assign.ztst +++ b/Test/A06assign.ztst @@ -743,3 +743,10 @@ print $a 0:overwrite [2] character (string: "") with "xx" >xx + + ( sleep 1 & + x[1]=$! + typeset -p x + ) +0:regression workers/53033: assigning $! to array element +*>typeset -g -a x=\( <-> \) -- cgit v1.2.3 From 606ef4b430a8848e89e07dbc3e3db47fc019a505 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Mon, 26 Aug 2024 20:29:36 +0900 Subject: unposted: remove reference to removed sample code the example in expn.yo was mdified by commit bb441f77a7 and does not use _wanted any more --- ChangeLog | 4 ++++ Doc/Zsh/compsys.yo | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index eec96a494..f05f967ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-08-26 Jun-ichi Takimoto + + * unposted: Doc/Zsh/compsys.yo: remove reference to removed code + 2024-08-15 Bart Schaefer * unposted (see 53034): Src/lex.c, Test/A06assign.ztst: fix parsing diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index f75298a1b..77627bacc 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -5448,10 +5448,6 @@ example(local expl _wanted tag expl 'description' \ compadd -- var(match1) var(match2)...) -See also the use of tt(_wanted) in the example function in -ifzman(the subsection `Dynamic named directories' in zmanref(zshexpn))\ -ifnzman(noderef(Dynamic named directories)). - Note that, as for tt(_requested), the var(command) must be able to accept options to be passed down to tt(compadd). -- cgit v1.2.3 From 678fb68879e52a7e608dbbb859f98c2f9ff171eb Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 31 Aug 2024 11:58:33 +0200 Subject: 53052: update setxkbmap completion with newer options --- ChangeLog | 5 + Completion/X/Command/_setxkbmap | 210 ++++++++++++++++++++++------------------ 2 files changed, 119 insertions(+), 96 deletions(-) diff --git a/ChangeLog b/ChangeLog index f05f967ab..a3080ea8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-08-31 Oliver Kiddle + + * 53052: Completion/X/Command/_setxkbmap: update completion with + newer options + 2024-08-26 Jun-ichi Takimoto * unposted: Doc/Zsh/compsys.yo: remove reference to removed code diff --git a/Completion/X/Command/_setxkbmap b/Completion/X/Command/_setxkbmap index 882a6f939..0850d5419 100644 --- a/Completion/X/Command/_setxkbmap +++ b/Completion/X/Command/_setxkbmap @@ -1,101 +1,119 @@ #compdef setxkbmap -# TODO: -# model, option, symbols and types suggestions -# take -layout and -variant into account - -_setxkbmap() { - emulate -L zsh - setopt extendedglob - - # xkb files may be in different places depending on system - local dir sourcedir fullname - local -a searchdirs=(${XDG_DATA_HOME:-~/.local/share} ${(s.:.)XDG_DATA_DIRS:-/usr/lib:/usr/share:/usr/local/lib:/usr/local/share}) - for dir in $searchdirs; do - fullname="$dir/X11/xkb" - if [ -d $fullname ] ; then - sourcedir=$fullname - break - fi - done - [ -d $sourcedir ] || return 1 - - local -a arguments - - arguments=( - '-compat[compatibility map]:compatibility:_setxkbmap_compat' - '-config[configuration file]:configuration:_files' - '-display[display]:display:_x_display' - '-geometry[geometry component]:geometry:_setxkbmap_geometry' - '-model[model name]:model:' - '-option[xkb option]:option:' - '(-)'-print'[print component names]' - '-rules[rules file]:rules:_files' - '-symbols[symbols components]:symbols:' - '(-)'{-help,-h}'[display help message]' - '-synch[force synchronization]' - '-types[types components]:types:' - '(-verbose -v)'{-verbose,-v}'[set verbosity level]:verbosity:(0 1 2 3 4 5 6 7 8 9)' - '*::keyboard:_setxkbmap_dispatcher' +local curcontext="$curcontext" sourcedir layout ret=1 +local -a state state_descr line expl matches suf +local -A opt_args + +_arguments -C \ + '(-)'{-\?,-help}'[display help message]' \ + '-compat[compatibility map]:compatibility:->compatmaps' \ + '-config[configuration file]:configuration:_files' \ + '-device[specify numeric id of the input device]:device:->devices' \ + '-display[display]:display:_x_display' \ + '-geometry[geometry component]:geometry:->geometries' \ + '*-I+[add a directory to be searched for layout or rules files]: :_directories' \ + '-keycodes[specify keycodes component name]:name' \ + '-keymap[specify keymap to load]:keymap' \ + '-layout[specify layout used to choose component names]:layout:->layouts' \ + '-model[specify model used to choose component names]:model:->models' \ + '*-option[add an xkb option]:option:->options' \ + '(-)'-print'[print a complete xkb_keymap description]' \ + '-query[print the current layout settings]' \ + '-rules[specify rules file to use]:rules:->rules' \ + '-symbols[specify symbols component name]:symbol' \ + '-synch[force synchronization]' \ + '-types[types components]:type:->types' \ + '(-verbose -v)'{-verbose,-v}'[set verbosity level]:verbosity:(0 1 2 3 4 5 6 7 8 9)' \ + '(-)-version[display version information]' \ + '-variant[specify layout variant used to choose component name]:variant:->variants' \ + '1:layout:->layouts' \ + '2:variant:->variants' \ + '*:option:->options' && ret=0 + +if [[ -n $state ]]; then + local open='(' close=')' + compquote open close + + layout=${opt_args[-layout]:-$line[1]} + if [[ $state = layouts ]]; then + compset -P '*,' + if compset -P 1 '*\('; then + layout="${${IPREFIX%$open}##*,}" + state=variants state_descr=variant + suf=( -S"$close$compstate[quote] " ) + else + suf=( -S$open -r ",('\" \t\n\-" ) + fi + fi + + _description $state expl $state_descr + if (( $+commands[localectl] )); then + case $state in + layouts) matches=( $(_call_program layouts localectl list-x11-keymap-layouts) ) ;; + models) matches=( $(_call_program layouts localectl list-x11-keymap-models) ) ;; + options) matches=( $(_call_program layouts localectl list-x11-keymap-options) ) ;; + variants) matches=( $(_call_program layouts localectl list-x11-keymap-variants $layout) ) ;; + esac + fi + if (( ! $#matches )); then + sourcedir=$(pkg-config xkeyboard-config --variable=xkb_base 2>/dev/null) + [[ -z $sourcedir ]] && sourcedir=( + ${XDG_DATA_HOME:-~/.local/share}/X11/xkb(N/) + ${(s.:.)XDG_DATA_DIRS:-/usr/lib:/usr/share:/usr/local/lib:/usr/local/share}/X11/xkb(N/) ) - _arguments $arguments -} - -_setxkbmap_dispatcher () { - - case $CURRENT in - 1) - _setxkbmap_layout - ;; - 2) - _setxkbmap_variant "$words[1]" - ;; + (( $#sourcedir )) && case $state in + layouts) matches=( $sourcedir/symbols/**/^README(.Ne."REPLY=\${REPLY#*/symbols/}".) ) ;; + compatmaps) matches=( $sourcedir/compat/^README(.:t) ) ;; + models) matches=( $(sed -n '/modelList/,/\/modelList/ s, *\(.*\),\1,p' $sourcedir/rules/(evdev|base).xml(.N[1])) ) ;; + options) matches=( $(sed -n '/optionList/,/\/optionList/ s, *\(.*\),\1,p' $sourcedir/rules/(evdev|base).xml(.N[1])) ) ;; + rules) matches=( $sourcedir/rules/*.lst(-.:t:r) ) ;; + types) matches=( $sourcedir/types/^README(.:t) ) ;; + variants) + [[ -n $layout && -r $sourcedir/symbols/$layout ]] && matches=( + ${${${(M)${(f)"$(<$sourcedir/symbols/$layout)"}:#*xkb_symbols*\"([^\"])##\"*}##*xkb_symbols([^\"])##\"}%%\"*} + ) + ;; + geometries) + if compset -P 1 '*\('; then + layout="${${IPREFIX%$open}##*,}" + suf=( -S"$close$compstate[quote] " ) + matches=( $(sed -n -e '/xkb_geometry/ s/[^"]*"\([^"]*\).*/\1/p' $sourcedir/geometry/${IPREFIX%%[\\(]#}(.N)) ) + else + suf=( -S$open -r "('\" \t\n\-" ) + matches=( $sourcedir/geometry/^README(.:t) ) + fi + ;; + devices) + # copied from _xinput + if (( $+commands[xinput] )); then + local -a ids names disp + local out + ids=( ${${(f)"$(_call_program input-devices xinput list --id-only)"}#? } ) + names=( ${${(f)"$(_call_program input-devices xinput list --name-only)"}#? } ) + disp=( ${(f)"$(_call_program input-devices xinput list --short)"} ) + + if [[ $PREFIX$SUFFIX = [^-]*[^0-9]* ]]; then + # match based on the names but insert IDs + compadd "$expl[@]" -M 'b:=* m:{[:lower:]}={[:upper:]}' -D ids -D disp -a names + compadd "$expl[@]" -U -ld disp -a ids && ret=0 + + zstyle -s ":completion:${curcontext}:input-devices" insert-ids out || out=menu + case "$out" in + menu) compstate[insert]=menu ;; + single) [[ $#ids -ne 1 && $compstate[insert] != menu ]] && + compstate[insert]= ;; + *) [[ ${#:-$PREFIX$SUFFIX} -gt ${#compstate[unambiguous]} ]] && + compstate[insert]=menu ;; + esac + else + compadd "$expl[@]" -M 'B:0=' -o nosort -ld disp -a ids && ret=0 + fi + fi + return ret + ;; esac -} - -_setxkbmap_files () { - local dir="$1" - local label="$2" - - local -a fullpath shortpath expl - - fullpath=($sourcedir/$dir/**/*~*README(.)) - shortpath=(${fullpath#$sourcedir\/$dir\/}) - - _wanted layout expl $label compadd -a - shortpath - -} - -(( $+functions[_setxkbmap_compat] )) || -_setxkbmap_compat() { - _setxkbmap_files "compat" "compatibility" -} - -(( $+functions[_setxkbmap_layout] )) || -_setxkbmap_layout () { - _setxkbmap_files "symbols" "layout" -} - -(( $+functions[_setxkbmap_geometry] )) || -_setxkbmap_geometry () { - _setxkbmap_files "geometry" "geometry" -} - -(( $+functions[_setxkbmap_variant] )) || -_setxkbmap_variant () { - local file=$sourcedir/symbols/${1} - local -a variants lines expl - - if [ ! -f $file ]; then - _message "no such layout: ${1}" - return 1 - fi - - lines=("${(f)$(< ${file})}") - variants=(${${${(M)lines:#*xkb_symbols*\"([^\"])##\"*}##*xkb_symbols([^\"])##\"}%%\"*}) - - _wanted variant expl 'variant' compadd -a variants - -} + fi + compadd "$expl[@]" $suf -a matches && ret=0 +fi -_setxkbmap "$@" +return ret -- cgit v1.2.3 From 6973d1d16f12923d3af5454b24cd1d2a73f4281a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 31 Aug 2024 12:01:33 +0200 Subject: 53057: complete glob qualifiers following an equals expansion --- ChangeLog | 3 +++ Completion/Zsh/Context/_equal | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a3080ea8f..4d8843b80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-08-31 Oliver Kiddle + * 53057: Completion/Zsh/Context/_equal: complete glob qualifiers + following an equals expansion + * 53052: Completion/X/Command/_setxkbmap: update completion with newer options diff --git a/Completion/Zsh/Context/_equal b/Completion/Zsh/Context/_equal index 58a415d56..5cdeea264 100644 --- a/Completion/Zsh/Context/_equal +++ b/Completion/Zsh/Context/_equal @@ -1,3 +1,11 @@ #compdef -equal- -_path_commands +local -a match mbegin mend + +if _have_glob_qual $PREFIX; then + compset -p ${#match[1]} + compset -S '[^\)\|\~]#(|\))' + _globquals +else + _path_commands +fi -- cgit v1.2.3 From 45f8ee1bee16115f5fc0f62d937e66c9b69ec548 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 31 Aug 2024 12:02:48 +0200 Subject: 53058: new completion for zstd --- ChangeLog | 2 + Completion/Unix/Command/_zstd | 118 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 Completion/Unix/Command/_zstd diff --git a/ChangeLog b/ChangeLog index 4d8843b80..6372bb05d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-08-31 Oliver Kiddle + * 53058: Completion/Unix/Command/_zstd: new completion for zstd + * 53057: Completion/Zsh/Context/_equal: complete glob qualifiers following an equals expansion diff --git a/Completion/Unix/Command/_zstd b/Completion/Unix/Command/_zstd new file mode 100644 index 000000000..92c4a8e41 --- /dev/null +++ b/Completion/Unix/Command/_zstd @@ -0,0 +1,118 @@ +#compdef zstd zstdmt unzstd zstdcat -redirect-,<,unzstd=unzstd -redirect-,>,zstd=unzstd -redirect-,<,zstd=zstd + +local ign +local -a levels implied noopt args blksize + +(( $#words > 2 )) && ign='!' + +[[ $compstate[context] = redirect ]] && noopt=( -- ) +case "$service" in + zstdmt) implied=( -T0 ) ;; + unzstd) (( $words[(I)(-z|--compress)] )) || implied=( -d ) ;; + zstdcat) + implied=( -dcf ) + (( $words[(I)(-z|--compress)] )) && implied=( -cf ) + ;; +esac +words[1]+=( $implied $noopt ) +(( CURRENT += $#implied + $#noopt )) + +if (( $words[(r)--ultra] )); then + levels=( -{20..22} ) +else + levels=( -{1..19} ) +fi + +blksize=( + '(M -B --block-size)'{-B+,--block-size=-}'[cut file into independent blocks of specified size]: :_numbers -d "no block" -u bytes size KiB MiB' +) +if (( $words[(r)--train] )); then + args=( $blksize + '(M)--train-cover=-[use the cover algorithm with optional arguments]::parameter' + '(M)--train-fastcover=-[use the fast cover algorithm with optional arguments]::parameter' + '(M)--train-legacy=-[use the legacy algorithm with selectivity]::selectivity [9]' + '-o[specify dictionary name]:dictionary name [dictionary]' + '(M)--maxdict=[limit dictionary to specified size]: :_numbers -u bytes -d 112640 size KiB MiB' + '(M)--dictID=[force dictionary ID to specified value]:value [random]' + '*:files:_files' + ) +elif (( $words[(I)-b[0-9]#] )); then + args=( $blksize + '(M)-e-[test all compression levels successively from -b level]: :_numbers -d 3 -l 1 -m 19 level' + '(M)-i-[specify minimum evaluation time]: :time (seconds) [3]' + '(M -B --block-size)'{-B+,--block-size=-}'[cut file into independent blocks of specified size]: :_numbers -d "no block" -u bytes size KiB MiB' \ + '(M)-S[output one benchmark result per input file]' + '(M)--priority=-[set process priority]:priority:(rt)' + '*:files:_files -g "^*.(|t)zst(-.)"' + ) +elif (( $words[(I)(-d|--decompress|--uncompress|-l|--list|-t|--test)] )); then + args=( + '(M --sparse -c --stdout)--no-sparse[sparse mode]' + '(M --no-sparse -o)--sparse[sparse mode]' + '(--sparse)-o[specify output file]:file:_files -g "^*.(|t)zst(-.)"' + "(M)--no-check[ignore checksums in compressed frame]" + '!(M --no-check)'{-C,--check} + '*:files:_files -g "*.(|t)zst(-.)"' + ) +else + args=( + "(M)--no-check[don't add/verify XXH64 integrity checksums]" + '!(M --no-check)'{-C,--check} + "(M)--no-content-size[don't include original file size in header]" + '!(M --no-content-size)--content-size' + "(M)--no-progress[don't show the progress bar but keep other messages]" + '!(M --no-progress)--progress' + "(M --adapt --fast --ultra ${levels[*]})"$^levels + '(M --fast)--ultra[enable levels beyond 19, up to 22]' + '--long=-[enable long distance matching with given window log]:window log [27]' + "(M --adapt --ultra ${levels[*]})--fast=-[switch to very fast compression levels]:level [1]" + "(M --fast ${levels[*]})--adapt=-[dynamically adapt compression level to I/O conditions]: :_values -s , 'range' + 'min\:level' '(min)max\:level'" + '(M)'--{no-,}row-match-finder'[force usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies]' + "(-D)--patch-from=[specify the file to be used as a reference point for zstd's diff engine]: :_files" + '(--single-thread -T --threads)'{-T-,--threads=}'[spawn specified number of threads]:threads [1]' + '(M -B --block-size)'{-B-,--block-size=-}'[select block size of each job]: :_numbers -u bytes -d 0\:automatic "block size" KiB MiB' + '(M -T --threads --rsyncable)--single-thread[use a single thread for both I/O and compression (result different than -T1)]' + '(M)--auto-threads=[use either physical cores or logical cores as default when specifying -T0]:cores [physical]:(physical logcial)' + '(M --single-thread)--rsyncable[compress using a rsync-friendly method]' + '(M)--exclude-compressed[only compress files that are not already compressed]' + '(M --size-hint)--stream-size=-[specify exact size of streaming input from stdin]: :_numbers -u bytes size KiB MiB' + '(M --stream-size)--size-hint=[indicate size of streamed input to optimize compression parameters]: :_numbers -u bytes size KiB MiB' + '(M)--target-compressed-block-size=[generate compressed block of approximately targeted size]: :_numbers -u bytes limit KiB MiB' + "(M)--no-dictID[don't write dictID into header (dictionary compression only)]" + '(M --no-compress-literals --compress-literals)'--{no-,}compress-literals'[force (un)compressed literals]' + '(M)--show-default-cparams[show compression parameters for each file]' + '(--test)-o[specify output file]:file:_files -g "*.(|t)zst(-.)"' + '--format=-[compress files to specified format]:format [zstd]:(zstd gzip xz lzma lz4)' + '--zstd=[specify advanced compression options]: :_values -s , "option" + strategy\:strategy "windowLog\:bits (10-31)" "hashLog\:bits (6-30)" + "chainLog\:bits (6-31)" "searchLog\:searches" "minMatch\:length" + "targetLength\:length" "overlapLog\:size" "ldmHashLog\:size" + "ldmMinMatch\:length" "ldmBucketSizeLog\:size" "ldmHashRateLog\:frequency"' + '*:files:_files -g "^*.(|t)zst(-.)"' + ) +fi + +_arguments -s -S : $args \ + "$ign(- *)"{-h,--help}'[display help message]' \ + "$ign(- *)"{-V,--version}'[display version number]' \ + '(--patch-from)-D[use specified dictionary for compression or decompression]:dictionary' \ + '(-f --force)'{-f,--force}'[force overwrite]' \ + '--rm[remove source file(s) after successful compression or decompression]' \ + '!(-k --keep --rm)'{-k,--keep} \ + '(-c --stdout --no-sparse --test)'{-c,--stdout}'[write on standard output]' \ + '(-M --memory)'{-M-,--memory=}'[set a memory usage limit]: :_numbers -u bytes limit KiB MiB' \ + \*{-v,--verbose}'[display more information]' \ + \*{-q,--quiet}'[suppress messages]' \ + '-r[operate recursively on directories]' \ + '--filelist=[read list of files to operate upon from file]: :_files' \ + '--output-dir-flat=[store processed files in directory]: :_directories' \ + '--output-dir-mirror=[store processed files in directory respecting original structure]: :_directories' \ + '--trace=[log tracing information to file]: :_files' \ + + '(M)' \ + \!{-z,--compress,--uncompress} \ + '(-B --block-size)'{-d,--decompress}'[decompress]' \ + '(-B --block-size)'{-l,--list}'[print information about zstd compressed files]' \ + '(-c --stdout -o --rm -B --block-size)'{-t,--test}'[test compressed file integrity]' \ + '(-c --stdout -D -k --keep --rm)--train=[create a dictionary from a training set of files]' \ + '(-c --stdout -k --keep --rm)-b-[benchmark file(s), using specified compression level]:: :_numbers -d 3 -l 1 -m 19 level' -- cgit v1.2.3 From 06e66b6b5af3778998aef0455aaaf6dfdf7e5145 Mon Sep 17 00:00:00 2001 From: Semnodime Date: Wed, 29 May 2024 06:33:55 +0200 Subject: github #120: Update _git to reflect `--recursive` being an alias `--recursive` and `--recurse-submodules` are aliased according to https://github.com/git/git/blob/99c33bed562b41de6ce9bd3fd561303d39645048/builtin/clone.c#L105 --- ChangeLog | 3 +++ Completion/Unix/Command/_git | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6372bb05d..753353153 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-08-31 Oliver Kiddle + * github #120: Semnodime: Completion/Unix/Command/_git: update + _git to reflect `--recursive` being an alias + * 53058: Completion/Unix/Command/_zstd: new completion for zstd * 53057: Completion/Zsh/Context/_equal: complete glob qualifiers diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 6c6d59b24..86b8a7455 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -665,7 +665,6 @@ _git-clone () { '(--single-branch)--no-single-branch[clone history leading up to each branch]' \ "--no-tags[don't clone any tags and make later fetches not follow them]" \ '--shallow-submodules[any cloned submodules will be shallow]' \ - '--recursive[initialize all contained submodules]' \ '(--recursive --recurse-submodules)'{--recursive,--recurse-submodules}'=-[initialize submodules in the clone]::file:__git_files' \ '--separate-git-dir[place .git dir outside worktree]:path to .git dir:_path_files -/' \ \*--server-option='[send specified string to the server when using protocol version 2]:option' \ -- cgit v1.2.3 From 58bda5913007f53c91ae60cd22483dd222ea5618 Mon Sep 17 00:00:00 2001 From: Clinton Bunch Date: Fri, 30 Aug 2024 08:06:06 -0500 Subject: 53056: new zsh/random module defining an SRANDOM parameter and zrand_float() and zrand_int() math functions --- ChangeLog | 6 + Completion/Zsh/Type/_module_math_func | 2 +- Doc/Makefile.in | 2 +- Doc/Zsh/mod_random.yo | 56 ++++++ Src/Modules/random.c | 322 ++++++++++++++++++++++++++++++++++ Src/Modules/random.mdd | 7 + Src/Modules/random_real.c | 213 ++++++++++++++++++++++ configure.ac | 2 + 8 files changed, 608 insertions(+), 2 deletions(-) create mode 100644 Doc/Zsh/mod_random.yo create mode 100644 Src/Modules/random.c create mode 100644 Src/Modules/random.mdd create mode 100644 Src/Modules/random_real.c diff --git a/ChangeLog b/ChangeLog index 753353153..51a859143 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2024-08-31 Oliver Kiddle + * Clinton Bunch: 53056: Completion/Zsh/Type/_module_math_func, + Doc/Makefile.in, Doc/Zsh/mod_random.yo, Src/Modules/random.c, + Src/Modules/random.mdd, Src/Modules/random_real.c, configure.ac: + new zsh/random module defining an SRANDOM parameter and + zrand_float() and zrand_int() math functions + * github #120: Semnodime: Completion/Unix/Command/_git: update _git to reflect `--recursive` being an alias diff --git a/Completion/Zsh/Type/_module_math_func b/Completion/Zsh/Type/_module_math_func index 5044bdf4c..e92b78b71 100644 --- a/Completion/Zsh/Type/_module_math_func +++ b/Completion/Zsh/Type/_module_math_func @@ -2,7 +2,7 @@ local mod local -a funcs alts -local -a modules=( example mathfunc system ) +local -a modules=( example mathfunc system random ) for mod in $modules; do funcs=( ${${${(f)"$(zmodload -Fl zsh/$mod 2>/dev/null)"}:#^+f:*}##+f:} ) diff --git a/Doc/Makefile.in b/Doc/Makefile.in index 401fb942b..fa2a336ad 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -68,7 +68,7 @@ Zsh/mod_hlgroup.yo Zsh/mod_langinfo.yo \ Zsh/mod_ksh93.yo Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo \ Zsh/mod_nearcolor.yo Zsh/mod_newuser.yo \ Zsh/mod_parameter.yo Zsh/mod_pcre.yo Zsh/mod_private.yo \ -Zsh/mod_regex.yo Zsh/mod_sched.yo Zsh/mod_socket.yo \ +Zsh/mod_regex.yo Zsh/mod_random.yo Zsh/mod_sched.yo Zsh/mod_socket.yo \ Zsh/mod_stat.yo Zsh/mod_system.yo Zsh/mod_tcp.yo \ Zsh/mod_termcap.yo Zsh/mod_terminfo.yo \ Zsh/mod_watch.yo \ diff --git a/Doc/Zsh/mod_random.yo b/Doc/Zsh/mod_random.yo new file mode 100644 index 000000000..d2892bf79 --- /dev/null +++ b/Doc/Zsh/mod_random.yo @@ -0,0 +1,56 @@ +COMMENT(!MOD!zsh/random +Some High-quality randomness parameters and functions. +!MOD!) +The tt(zsh/random) module gets random data from the kernel random pool. If no +kernel random pool can be found, the module will not load. + +subsect(Parameters) + +startitem() +vindex(SRANDOM) +item(tt(SRANDOM)) ( +A random positive 32-bit integer between 0 and 4,294,967,295. This parameter +is read-only. The name was chosen for compatibility with Bash and to +distinguish it from tt(RANDOM) which has a documented repeatable behavior. +) +enditem() + +subsect(Math Functions) + +startitem() +item(tt(zrand_float+LPAR()RPAR())) ( +Returns a random floating point number between 0 and 1 inclusive. +) +enditem() + +startitem() +item(tt(zrand_int)+LPAR()tt(upper), tt(lower), tt(inclusive)RPAR()) ( +Returns a random integer between tt(lower) and tt(upper). All parameters are +optional. If none are specified it is equivalent to +tt(SRANDOM). + +tt(upper) is the upper bound on the resultant number and defaults to +4,294,967,295. + +tt(lower) is the lower bound and defaults to 0. + +The defaults of these two arguments are also the maximum and minimum to which +either can be set. + +tt(inclusive) is a flag that controls whether the result is ever equal to +tt(upper). By default it is not. If this argument is set to a non-zero value +then it may be. + +This is to facilitate a construct like tt($a[zrand_int($#a)+1]) rather +than tt($a[zrand_int+LPAR()$#a-1+RPAR()+1]). +For example, if $#a is 16, you would use tt(zrand_int+LPAR()16RPAR()) which has +16 possible return values 0-15. Because the function can return zero, in order +to use it as an array index from 1-16 you need to add one. It would +be an array index range error for it to also potentially return 16 ($#a). You +could, however, use the construct tt(zrand_int+LPAR()16,1,1+RPAR()) instead of +adding 1 to achieve the same result, but it is more verbose. + +Most statistics algorithms seem to also expect 0 to tt(upper)-1, so this was +deemed the most commonly desired case and chosen as the default. +) +enditem() diff --git a/Src/Modules/random.c b/Src/Modules/random.c new file mode 100644 index 000000000..a153d8f64 --- /dev/null +++ b/Src/Modules/random.c @@ -0,0 +1,322 @@ +/* + * random.c - module to access kernel random sources. + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 2022 Clinton Bunch + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Clinton Bunch or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Clinton Bunch and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Clinton Bunch and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Clinton Bunch and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "random.mdh" + +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_SYS_RANDOM_H +#include +#endif + +/* Simplify select URANDOM specific code */ +#if !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_GETRANDOM) +#define USE_URANDOM +#endif + +/* buffer to pre-load integers for SRANDOM to lessen the context switches */ +static uint32_t rand_buff[8]; +static int buf_cnt = -1; + +#ifdef USE_URANDOM +/* File descriptor for /dev/urandom */ +int randfd = -1; +#endif /* USE_URANDOM */ + +static zlong get_srandom(UNUSED(Param p)); + +/**/ +ssize_t +getrandom_buffer(void *buf, size_t len) +{ + ssize_t ret; + size_t val = 0; + uint8_t *bufptr = buf; + + do { + errno = 0; +#ifdef HAVE_ARC4RANDOM_BUF + arc4random_buf(buf,len); + ret = len; +#elif defined(HAVE_GETRANDOM) + ret=getrandom(bufptr,(len - val),0); +#else + ret=read(randfd,bufptr,(len - val)); +#endif + if (ret < 0) { + if (errno != EINTR || errflag || retflag || breaks || contflag) { + zwarn("Unable to get random data: %e.", errno); + return -1; + } + } + bufptr += ret; + val += ret; + } while (ret < len); + return ret; +} + +/* + * Generate count number of random 32-bit integers between 0 and max-1 + * Got this algorithm from + *https://lemire.me/blog/2016/06/30/fast-random-shuffling/ + * adapting the public domain code. + * + */ + +/**/ +void +get_bound_random_buffer(uint32_t *buffer, size_t count, uint32_t max) +{ + uint64_t multi_result; + uint32_t threshold; + uint32_t leftover; + + size_t i; /* loop counter */ + + getrandom_buffer((void*) buffer, count*sizeof(uint32_t)); + if (max == UINT32_MAX) + return; + + for(i=0;i> 32; + } +} + +/* + * Provides for the SRANDOM parameter and returns an unsigned 32-bit random + * integer. + */ + +/**/ +static zlong +get_srandom(UNUSED(Param pm)) { + + if(buf_cnt <= 0) { + getrandom_buffer((void*) rand_buff,sizeof(rand_buff)); + buf_cnt=sizeof(rand_buff)/sizeof(rand_buff[0]); + } + return rand_buff[--buf_cnt]; +} + +/* + * Implements math function zrand_int takes 0 to 3 arguments an upper bound, + * a lower bound and a flag as to whether the range is inclusive or not. The + * default is exclusive. If neither upper or lower is specified this is no + * different than SRANDOM. + */ + +/**/ +static mnumber +math_zrand_int(UNUSED(char *name), int argc, mnumber *argv, UNUSED(int id)) +{ + mnumber ret; + uint32_t i; + zlong lower=0, upper=UINT32_MAX,incl=0, diff; + + ret.type = MN_INTEGER; + + switch (argc) { + case 0: ret.u.l=get_srandom(NULL); + return ret; + break; + case 3: incl = (argv[2].u.l != 0)?1:0; + case 2: lower = argv[1].u.l; + case 1: upper = argv[0].u.l; + default: diff = upper-lower+incl; + } + + if (lower < 0 || lower >= UINT32_MAX) { + zwarn("Lower bound (%z) out of range: 0-4294967295",lower); + } else if (upper < lower) { + zwarn("Upper bound (%z) must be greater than Lower Bound (%z)",upper,lower); + } else if (upper < 0 || upper >= UINT32_MAX) { + zwarn("Upper bound (%z) out of range: 0-4294967295",upper); + } + + if ( diff == 0 ) { + ret.u.l=upper; /* still not convinced this shouldn't be an error. */ + } else { + get_bound_random_buffer(&i,1,(uint32_t) diff); + ret.u.l=i+lower; + } + return ret; +} + +/* + * Implements the mathfunc zrand_float and returns a random floating-point + * number between 0 and 1. + * + */ + +/**/ +static mnumber +math_zrand_float(UNUSED(char *name), UNUSED(int argc), UNUSED(mnumber *argv), + UNUSED(int id)) +{ + mnumber ret; + double r; + + r = random_real(); + if (r < 0) { + zwarnnam(name, "Failed to get sufficient random data."); + } + ret.type = MN_FLOAT; + ret.u.d = r; + + return ret; +} + +static const struct gsu_integer srandom_gsu = +{ get_srandom, nullintsetfn, stdunsetfn }; + +static struct paramdef patab[] = { + {"SRANDOM", PM_INTEGER | PM_READONLY_SPECIAL | PM_HIDEVAL, NULL, + &srandom_gsu, NULL, NULL, NULL}, +}; + +static struct mathfunc mftab[] = { + NUMMATHFUNC("zrand_float", math_zrand_float, 0, 0, 0), + NUMMATHFUNC("zrand_int", math_zrand_int, 0, 3, 0), +}; + +static struct features module_features = { + NULL, 0, + NULL, 0, + mftab, sizeof(mftab)/sizeof(*mftab), + patab, sizeof(patab)/sizeof(*patab), + 0 +}; + +/**/ +int +setup_(UNUSED(Module m)) +{ +#ifdef USE_URANDOM + /* Check for the existence of /dev/urandom */ + + struct stat st; + + errno=0; + if (stat("/dev/urandom",&st) < 0) { + zwarn("Error getting kernel random pool: %e.", errno); + return 1; + } + + errno=0; + if (!(S_ISCHR(st.st_mode)) ) { + zwarn("Error getting kernel random pool: %e.", errno); + return 1; + } +#endif /* USE_URANDOM */ + return 0; +} + +/**/ +int +features_(Module m, char ***features) +{ + *features = featuresarray(m, &module_features); + return 0; +} + +/**/ +int +enables_(Module m, int **enables) +{ + return handlefeatures(m, &module_features, enables); +} + +/**/ +int +boot_(UNUSED(Module m)) +{ +#ifdef USE_URANDOM + /* + * Open /dev/urandom. Here because of a weird issue on HP-UX 11.31 + * When opening in setup_ open returned 0. In boot_, it returns + * an unused file descriptor. Decided against ifdef HPUX as it works + * here just as well for other platforms. + * + */ + + int tmpfd=-1; + + errno=0; + if ((tmpfd = open("/dev/urandom", O_RDONLY)) < 0) { + zwarn("Could not access kernel random pool: %e.",errno); + return 1; + } + randfd = movefd(tmpfd); + addmodulefd(randfd,FDT_MODULE); + if (randfd < 0) { + zwarn("Could not access kernel random pool."); + return 1; + } +#endif /* USE_URANDOM */ + return 0; +} + +/**/ +int +cleanup_(Module m) +{ + return setfeatureenables(m, &module_features, NULL); +} + +/**/ +int +finish_(UNUSED(Module m)) +{ +#ifdef USE_URANDOM + if (randfd >= 0) + zclose(randfd); +#endif /* USE_URANDOM */ + return 0; +} diff --git a/Src/Modules/random.mdd b/Src/Modules/random.mdd new file mode 100644 index 000000000..7a75f29ff --- /dev/null +++ b/Src/Modules/random.mdd @@ -0,0 +1,7 @@ +name=zsh/random +link=either +load=yes + +autofeatures="p:SRANDOM f:zrand_float f:zrand_int" + +objects="random.o random_real.o" diff --git a/Src/Modules/random_real.c b/Src/Modules/random_real.c new file mode 100644 index 000000000..4a8fcae19 --- /dev/null +++ b/Src/Modules/random_real.c @@ -0,0 +1,213 @@ +/* This file contains code under different copyrights separated by */ +/* ====@@@@@=== */ + +/* + * random_real.c - module to access kernel random sources. + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 2022 Clinton Bunch + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Clinton Bunch or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Clinton Bunch and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Clinton Bunch and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Clinton Bunch and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "random.mdh" + +#include +#include +#include + + +/* Count the number of leading zeros, hopefully in gcc/clang by HW + * instruction */ +#if defined(__GNUC__) || defined(__clang__) +#define clz64(x) __builtin_clzll(x) +#else +#define clz64(x) _zclz64(x) + +/**/ +int +_zclz64(uint64_t x) { + int n = 0; + + if (x == 0) + return 64; + + if (!(x & 0xFFFFFFFF00000000ull)) { + n+=32; + x<<=32; + } + if (!(x & 0xFFFF000000000000ull)) { + n+=16; + x<<=16; + } + if (!(x & 0xFF00000000000000ull)) { + n+=8; + x<<=8; + } + if (!(x & 0xF000000000000000ull)) { + n+=4; + x<<=4; + } + if (!(x & 0xC000000000000000ull)) { + n+=2; + x<<=1; + } + if (!(x & 0x8000000000000000ull)) { + n+=1; + } + return n; +} +#endif /* __GNU_C__ or __clang__ */ + +/**/ +uint64_t +random_64bit(void) { + uint64_t r; + + if(getrandom_buffer(&r,sizeof(r)) < 0) { + zwarn("zsh/random: Can't get sufficient random data."); + return 1; /* 0 will cause loop */ + } + + return r; +} + +/* ====@@@@@=== */ +/* Following code is under the below copyright, despite changes for error + * handling and removing GCCisms */ + +/*- + * Copyright (c) 2014 Taylor R. Campbell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Uniform random floats: How to generate a double-precision + * floating-point numbers in [0, 1] uniformly at random given a uniform + * random source of bits. + * + * See + * for explanation. + * + * Updated 2015-02-22 to replace ldexp(x, ) by x * ldexp(1, + * ), since glibc and NetBSD libm both have slow software + * bit-twiddling implementations of ldexp, but GCC can constant-fold + * the latter. + */ + +/* + * random_real: Generate a stream of bits uniformly at random and + * interpret it as the fractional part of the binary expansion of a + * number in [0, 1], 0.00001010011111010100...; then round it. + */ + +/**/ +double +random_real(void) +{ + int exponent = 0; + uint64_t significand = 0; + uint64_t r = 0; + unsigned shift; + + /* + * Read zeros into the exponent until we hit a one; the rest + * will go into the significand. + */ + while (significand == 0) { + exponent -= 64; + + /* Get random_64bit and check for error */ + errno = 0; + significand = random_64bit(); + if (errno) + return -1; + /* + * If the exponent falls below -1074 = emin + 1 - p, + * the exponent of the smallest subnormal, we are + * guaranteed the result will be rounded to zero. This + * case is so unlikely it will happen in realistic + * terms only if random_64bit is broken. + */ + if (exponent < -1074) + return 0; + } + + /* + * There is a 1 somewhere in significand, not necessarily in + * the most significant position. If there are leading zeros, + * shift them into the exponent and refill the less-significant + * bits of the significand. Can't predict one way or another + * whether there are leading zeros: there's a fifty-fifty + * chance, if random_64bit is uniformly distributed. + */ + shift = clz64(significand); + if (shift != 0) { + + errno = 0; + r = random_64bit(); + if (errno) + return -1; + + exponent -= shift; + significand <<= shift; + significand |= (r >> (64 - shift)); + } + + /* + * Set the sticky bit, since there is almost surely another 1 + * in the bit stream. Otherwise, we might round what looks + * like a tie to even when, almost surely, were we to look + * further in the bit stream, there would be a 1 breaking the + * tie. + */ + significand |= 1; + + /* + * Finally, convert to double (rounding) and scale by + * 2^exponent. + */ + return ldexp((double)significand, exponent); +} +/* ====@@@@@=== */ diff --git a/configure.ac b/configure.ac index 78621042d..a88101f2b 100644 --- a/configure.ac +++ b/configure.ac @@ -636,6 +636,7 @@ fi AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \ termios.h sys/param.h sys/filio.h string.h memory.h \ limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \ + sys/random.h \ locale.h errno.h stdio.h stdarg.h varargs.h stdlib.h \ unistd.h sys/capability.h \ utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \ @@ -1292,6 +1293,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ cygwin_conv_path \ nanosleep \ srand_deterministic \ + getrandom arc4random_buf \ setutxent getutxent endutxent getutent) AC_FUNC_STRCOLL -- cgit v1.2.3 From 6b9704e2c4e4c8524137a9c15bf9b166a975f3eb Mon Sep 17 00:00:00 2001 From: Clinton Bunch Date: Sat, 31 Aug 2024 09:10:12 -0500 Subject: 53060: silence build warnings --- ChangeLog | 3 +++ Doc/Zsh/mod_random.yo | 2 +- Src/Modules/random.c | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 51a859143..7e181e959 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-08-31 Oliver Kiddle + * Clinton Bunch: 53060: Doc/Zsh/mod_random.yo, + Src/Modules/random.c: silence build warnings + * Clinton Bunch: 53056: Completion/Zsh/Type/_module_math_func, Doc/Makefile.in, Doc/Zsh/mod_random.yo, Src/Modules/random.c, Src/Modules/random.mdd, Src/Modules/random_real.c, configure.ac: diff --git a/Doc/Zsh/mod_random.yo b/Doc/Zsh/mod_random.yo index d2892bf79..4f5622e61 100644 --- a/Doc/Zsh/mod_random.yo +++ b/Doc/Zsh/mod_random.yo @@ -41,7 +41,7 @@ tt(inclusive) is a flag that controls whether the result is ever equal to tt(upper). By default it is not. If this argument is set to a non-zero value then it may be. -This is to facilitate a construct like tt($a[zrand_int($#a)+1]) rather +This is to facilitate a construct like tt($a[zrand_int+LPAR()$#a+RPAR()+1]) rather than tt($a[zrand_int+LPAR()$#a-1+RPAR()+1]). For example, if $#a is 16, you would use tt(zrand_int+LPAR()16RPAR()) which has 16 possible return values 0-15. Because the function can return zero, in order diff --git a/Src/Modules/random.c b/Src/Modules/random.c index a153d8f64..88ac9543c 100644 --- a/Src/Modules/random.c +++ b/Src/Modules/random.c @@ -62,8 +62,10 @@ ssize_t getrandom_buffer(void *buf, size_t len) { ssize_t ret; +#ifndef HAVE_ARC4RANDOM_BUF size_t val = 0; uint8_t *bufptr = buf; +#endif do { errno = 0; @@ -81,8 +83,10 @@ getrandom_buffer(void *buf, size_t len) return -1; } } +#ifndef HAVE_ARC4RANDOM_BUF bufptr += ret; val += ret; +#endif } while (ret < len); return ret; } -- cgit v1.2.3 From 79593399c4bfa3eefb7eaa379fdc922b9c14c0df Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:14:40 +0200 Subject: 53080: remove code for systems that only have the old pre-POSIX signal() --- ChangeLog | 5 ++ Src/init.c | 12 ++-- Src/signals.c | 210 +--------------------------------------------------------- Src/signals.h | 16 ----- configure.ac | 31 --------- 5 files changed, 10 insertions(+), 264 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e181e959..3301c5287 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-09-14 Oliver Kiddle + + * 53080: configure.ac, Src/init.c, Src/signals.c, Src/signals.h: + remove code for systems that only have the old pre-POSIX signal() + 2024-08-31 Oliver Kiddle * Clinton Bunch: 53060: Doc/Zsh/mod_random.yo, diff --git a/Src/init.c b/Src/init.c index 0aecb5db9..8c7776c7a 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1386,6 +1386,8 @@ setupshin(char *runscript) void init_signals(void) { + struct sigaction act; + sigtrapped = (int *) hcalloc(TRAPCOUNT * sizeof(int)); siglists = (Eprog *) hcalloc(TRAPCOUNT * sizeof(Eprog)); @@ -1399,14 +1401,8 @@ init_signals(void) intr(); -#ifdef POSIX_SIGNALS - { - struct sigaction act; - if (!sigaction(SIGQUIT, NULL, &act) && - act.sa_handler == SIG_IGN) - sigtrapped[SIGQUIT] = ZSIG_IGNORED; - } -#endif + if (!sigaction(SIGQUIT, NULL, &act) && act.sa_handler == SIG_IGN) + sigtrapped[SIGQUIT] = ZSIG_IGNORED; #ifndef QDEBUG signal_ignore(SIGQUIT); diff --git a/Src/signals.c b/Src/signals.c index d28853ea6..6eecbf7d5 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -91,33 +91,6 @@ mod_export volatile int trap_queueing_enabled, trap_queue_front, trap_queue_rear /**/ mod_export int trap_queue[MAX_QUEUE_SIZE]; -/* This is only used on machines that don't understand signal sets. * - * On SYSV machines this will represent the signals that are blocked * - * (held) using sighold. On machines which can't block signals at * - * all, we will simulate this by ignoring them and remembering them * - * in this variable. */ -#if !defined(POSIX_SIGNALS) && !defined(BSD_SIGNALS) -static sigset_t blocked_set; -#endif - -#ifdef POSIX_SIGNALS -# define signal_jmp_buf sigjmp_buf -# define signal_setjmp(b) sigsetjmp((b),1) -# define signal_longjmp(b,n) siglongjmp((b),(n)) -#else -# define signal_jmp_buf jmp_buf -# define signal_setjmp(b) setjmp(b) -# define signal_longjmp(b,n) longjmp((b),(n)) -#endif - -#ifdef NO_SIGNAL_BLOCKING -# define signal_process(sig) signal_ignore(sig) -# define signal_reset(sig) install_handler(sig) -#else -# define signal_process(sig) ; -# define signal_reset(sig) ; -#endif - /* Install signal handler for given signal. * * If possible, we want to make sure that interrupted * * system calls are not restarted. */ @@ -126,10 +99,9 @@ static sigset_t blocked_set; mod_export void install_handler(int sig) { -#ifdef POSIX_SIGNALS struct sigaction act; - act.sa_handler = (SIGNAL_HANDTYPE) zhandler; + act.sa_handler = (void (*)(int)) zhandler; sigemptyset(&act.sa_mask); /* only block sig while in handler */ act.sa_flags = 0; # ifdef SA_INTERRUPT /* SunOS 4.x */ @@ -137,27 +109,6 @@ install_handler(int sig) act.sa_flags |= SA_INTERRUPT; /* make sure system calls are not restarted */ # endif sigaction(sig, &act, (struct sigaction *)NULL); -#else -# ifdef BSD_SIGNALS - struct sigvec vec; - - vec.sv_handler = (SIGNAL_HANDTYPE) zhandler; - vec.sv_mask = sigmask(sig); /* mask out this signal while in handler */ -# ifdef SV_INTERRUPT - vec.sv_flags = SV_INTERRUPT; /* make sure system calls are not restarted */ -# endif - sigvec(sig, &vec, (struct sigvec *)NULL); -# else -# ifdef SYSV_SIGNALS - /* we want sigset rather than signal because it will * - * block sig while in handler. signal usually doesn't */ - sigset(sig, zhandler); -# else /* NO_SIGNAL_BLOCKING (bummer) */ - signal(sig, zhandler); - -# endif /* SYSV_SIGNALS */ -# endif /* BSD_SIGNALS */ -#endif /* POSIX_SIGNALS */ } /* enable ^C interrupts */ @@ -219,50 +170,17 @@ signal_mask(int sig) /* Block the signals in the given signal * * set. Return the old signal set. */ -/**/ -#ifndef BSD_SIGNALS - /**/ mod_export sigset_t signal_block(sigset_t set) { sigset_t oset; -#ifdef POSIX_SIGNALS sigprocmask(SIG_BLOCK, &set, &oset); -#else -# ifdef SYSV_SIGNALS - int i; - - oset = blocked_set; - for (i = 1; i <= NSIG; ++i) { - if (sigismember(&set, i) && !sigismember(&blocked_set, i)) { - sigaddset(&blocked_set, i); - sighold(i); - } - } -# else /* NO_SIGNAL_BLOCKING */ -/* We will just ignore signals if the system doesn't have * - * the ability to block them. */ - int i; - - oset = blocked_set; - for (i = 1; i <= NSIG; ++i) { - if (sigismember(&set, i) && !sigismember(&blocked_set, i)) { - sigaddset(&blocked_set, i); - signal_ignore(i); - } - } -# endif /* SYSV_SIGNALS */ -#endif /* POSIX_SIGNALS */ - return oset; } -/**/ -#endif /* BSD_SIGNALS */ - /* Unblock the signals in the given signal * * set. Return the old signal set. */ @@ -272,39 +190,7 @@ signal_unblock(sigset_t set) { sigset_t oset; -#ifdef POSIX_SIGNALS sigprocmask(SIG_UNBLOCK, &set, &oset); -#else -# ifdef BSD_SIGNALS - sigfillset(&oset); - oset = sigsetmask(oset); - sigsetmask(oset & ~set); -# else -# ifdef SYSV_SIGNALS - int i; - - oset = blocked_set; - for (i = 1; i <= NSIG; ++i) { - if (sigismember(&set, i) && sigismember(&blocked_set, i)) { - sigdelset(&blocked_set, i); - sigrelse(i); - } - } -# else /* NO_SIGNAL_BLOCKING */ -/* On systems that can't block signals, we are just ignoring them. So * - * to unblock signals, we just reenable the signal handler for them. */ - int i; - - oset = blocked_set; - for (i = 1; i <= NSIG; ++i) { - if (sigismember(&set, i) && sigismember(&blocked_set, i)) { - sigdelset(&blocked_set, i); - install_handler(i); - } - } -# endif /* SYSV_SIGNALS */ -# endif /* BSD_SIGNALS */ -#endif /* POSIX_SIGNALS */ return oset; } @@ -318,61 +204,19 @@ signal_setmask(sigset_t set) { sigset_t oset; -#ifdef POSIX_SIGNALS sigprocmask(SIG_SETMASK, &set, &oset); -#else -# ifdef BSD_SIGNALS - oset = sigsetmask(set); -# else -# ifdef SYSV_SIGNALS - int i; - - oset = blocked_set; - for (i = 1; i <= NSIG; ++i) { - if (sigismember(&set, i) && !sigismember(&blocked_set, i)) { - sigaddset(&blocked_set, i); - sighold(i); - } else if (!sigismember(&set, i) && sigismember(&blocked_set, i)) { - sigdelset(&blocked_set, i); - sigrelse(i); - } - } -# else /* NO_SIGNAL_BLOCKING */ - int i; - - oset = blocked_set; - for (i = 1; i < NSIG; ++i) { - if (sigismember(&set, i) && !sigismember(&blocked_set, i)) { - sigaddset(&blocked_set, i); - signal_ignore(i); - } else if (!sigismember(&set, i) && sigismember(&blocked_set, i)) { - sigdelset(&blocked_set, i); - install_handler(i); - } - } -# endif /* SYSV_SIGNALS */ -# endif /* BSD_SIGNALS */ -#endif /* POSIX_SIGNALS */ return oset; } -#if defined(NO_SIGNAL_BLOCKING) -static int suspend_longjmp = 0; -static signal_jmp_buf suspend_jmp_buf; -#endif - /**/ int signal_suspend(UNUSED(int sig), int wait_cmd) { int ret; -#if defined(POSIX_SIGNALS) || defined(BSD_SIGNALS) sigset_t set; -# if defined(POSIX_SIGNALS) && defined(BROKEN_POSIX_SIGSUSPEND) sigset_t oset; -# endif sigemptyset(&set); @@ -384,9 +228,7 @@ signal_suspend(UNUSED(int sig), int wait_cmd) if (!(wait_cmd || isset(TRAPSASYNC) || (sigtrapped[SIGINT] & ~ZSIG_IGNORED))) sigaddset(&set, SIGINT); -#endif /* POSIX_SIGNALS || BSD_SIGNALS */ -#ifdef POSIX_SIGNALS # ifdef BROKEN_POSIX_SIGSUSPEND sigprocmask(SIG_SETMASK, &set, &oset); ret = pause(); @@ -394,26 +236,6 @@ signal_suspend(UNUSED(int sig), int wait_cmd) # else /* not BROKEN_POSIX_SIGSUSPEND */ ret = sigsuspend(&set); # endif /* BROKEN_POSIX_SIGSUSPEND */ -#else /* not POSIX_SIGNALS */ -# ifdef BSD_SIGNALS - ret = sigpause(set); -# else -# ifdef SYSV_SIGNALS - ret = sigpause(sig); - -# else /* NO_SIGNAL_BLOCKING */ - /* need to use signal_longjmp to make this race-free * - * between the child_unblock() and pause() */ - if (signal_setjmp(suspend_jmp_buf) == 0) { - suspend_longjmp = 1; /* we want to signal_longjmp after catching signal */ - child_unblock(); /* do we need to do wait_cmd stuff as well? */ - ret = pause(); - } - suspend_longjmp = 0; /* turn off using signal_longjmp since we are past * - * the pause() function. */ -# endif /* SYSV_SIGNALS */ -# endif /* BSD_SIGNALS */ -#endif /* POSIX_SIGNALS */ return ret; } @@ -586,33 +408,12 @@ zhandler(int sig) { sigset_t newmask, oldmask; -#if defined(NO_SIGNAL_BLOCKING) - int do_jump; - signal_jmp_buf jump_to; -#endif - last_signal = sig; - signal_process(sig); sigfillset(&newmask); /* Block all signals temporarily */ oldmask = signal_block(newmask); -#if defined(NO_SIGNAL_BLOCKING) - /* do we need to longjmp to signal_suspend */ - do_jump = suspend_longjmp; - /* In case a SIGCHLD somehow arrives */ - suspend_longjmp = 0; - - /* Traps can cause nested signal_suspend() */ - if (sig == SIGCHLD) { - if (do_jump) { - /* Copy suspend_jmp_buf */ - jump_to = suspend_jmp_buf; - } - } -#endif - /* Are we queueing signals now? */ if (queueing_enabled) { int temp_rear = ++queue_rear % MAX_QUEUE_SIZE; @@ -627,7 +428,6 @@ zhandler(int sig) /* save current signal mask */ signal_mask_queue[queue_rear] = oldmask; } - signal_reset(sig); return; } @@ -704,14 +504,6 @@ zhandler(int sig) break; } /* end of switch(sig) */ - signal_reset(sig); - -/* This is used to make signal_suspend() race-free */ -#if defined(NO_SIGNAL_BLOCKING) - if (do_jump) - signal_longjmp(jump_to, 1); -#endif - } /* handler */ diff --git a/Src/signals.h b/Src/signals.h index 7910f6b79..a9c12679f 100644 --- a/Src/signals.h +++ b/Src/signals.h @@ -27,8 +27,6 @@ * */ -#define SIGNAL_HANDTYPE void (*)(int) - #ifndef HAVE_KILLPG # define killpg(pgrp,sig) kill(-(pgrp),sig) #endif @@ -51,20 +49,6 @@ # define SV_INTERRUPT SV_BSDSIG #endif -/* If not a POSIX machine, then we create our * - * own POSIX style signal sets functions. */ -#ifndef POSIX_SIGNALS -# define sigemptyset(s) (*(s) = 0) -# if NSIG == 32 -# define sigfillset(s) (*(s) = ~(sigset_t)0, 0) -# else -# define sigfillset(s) (*(s) = (1 << NSIG) - 1, 0) -# endif -# define sigaddset(s,n) (*(s) |= (1 << ((n) - 1)), 0) -# define sigdelset(s,n) (*(s) &= ~(1 << ((n) - 1)), 0) -# define sigismember(s,n) ((*(s) & (1 << ((n) - 1))) != 0) -#endif /* ifndef POSIX_SIGNALS */ - #define child_block() signal_block(sigchld_mask) #define child_unblock() signal_unblock(sigchld_mask) diff --git a/configure.ac b/configure.ac index a88101f2b..eab95105c 100644 --- a/configure.ac +++ b/configure.ac @@ -1483,35 +1483,6 @@ case $host_os in darwin1[0-5]*) AC_DEFINE(SETENV_MANGLES_EQUAL) ;; esac -dnl ------------- -dnl CHECK SIGNALS -dnl ------------- -dnl What style of signal do you have (POSIX, BSD, or SYSV)? -AH_TEMPLATE([POSIX_SIGNALS], -[Define to 1 if you use POSIX style signal handling.]) -AH_TEMPLATE([BSD_SIGNALS], -[Define to 1 if you use BSD style signal handling (and can block signals).]) -AH_TEMPLATE([SYSV_SIGNALS], -[Define to 1 if you use SYS style signal handling (and can block signals).]) -AH_TEMPLATE([NO_SIGNAL_BLOCKING], -[Define to 1 if you have no signal blocking at all (bummer).]) -AC_MSG_CHECKING(what style of signals to use) -if test x$ac_cv_func_sigaction = xyes && test x$ac_cv_func_sigprocmask = xyes; then - signals_style=POSIX_SIGNALS - AC_DEFINE(POSIX_SIGNALS) -elif test x$ac_cv_func_sigblock = xyes && test x$ac_cv_func_sigsetmask = xyes; then - signals_style=BSD_SIGNALS - AC_DEFINE(BSD_SIGNALS) -elif test x$ac_cv_func_sighold = xyes && test x$ac_cv_func_sigrelse = xyes; then - signals_style=SYSV_SIGNALS - AC_DEFINE(SYSV_SIGNALS) -else - signals_style=NO_SIGNAL_BLOCKING - AC_DEFINE(NO_SIGNAL_BLOCKING) -fi -AC_DEFINE_UNQUOTED($signals_style) -AC_MSG_RESULT($signals_style) - dnl Where is located? Needed as input for signals.awk AC_CACHE_CHECK(where signal.h is located, zsh_cv_path_signal_h, [dnl Look at the output from the preprocessor. @@ -2324,7 +2295,6 @@ dnl for instance, BeOS R4.51 is broken. dnl ----------- AH_TEMPLATE([BROKEN_POSIX_SIGSUSPEND], Define to 1 if sigsuspend() is broken, ie BeOS R4.51.]) -if test x$signals_style = xPOSIX_SIGNALS; then AC_CACHE_CHECK(if POSIX sigsuspend() works, zsh_cv_sys_sigsuspend, [AC_RUN_IFELSE([AC_LANG_SOURCE([[ @@ -2356,7 +2326,6 @@ int main() { if test x$zsh_cv_sys_sigsuspend = xno; then AC_DEFINE(BROKEN_POSIX_SIGSUSPEND) fi -fi dnl ----------- dnl if found tcsetpgrp, test to see if it actually works -- cgit v1.2.3 From 8dd271fdec526241ad3ed9c7f2641127a939893c Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:21:58 +0200 Subject: 53081: remove old BeOS support code --- ChangeLog | 3 + INSTALL | 7 --- Src/init.c | 8 +-- Src/options.c | 9 --- Src/signals.c | 7 --- Src/zsh_system.h | 12 ---- configure.ac | 165 ------------------------------------------------------- 7 files changed, 5 insertions(+), 206 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3301c5287..335ae40d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-09-14 Oliver Kiddle + * 53081: INSTALL, configure.ac, Src/init.c, Src/options.c, + Src/signals.c, Src/zsh_system.h: remove old BeOS support code + * 53080: configure.ac, Src/init.c, Src/signals.c, Src/signals.h: remove code for systems that only have the old pre-POSIX signal() diff --git a/INSTALL b/INSTALL index f347a4480..8b139fa9b 100644 --- a/INSTALL +++ b/INSTALL @@ -576,13 +576,6 @@ shell is running in some privileged mode. This is turned off by default as on some systems non-standard headers (in particular AIX) are required. A direct fix for that problem would be appreciated. -A test for the function tcsetpgrp is turned on by default. The test -needs to run the function to determine if the implementation is -usable. However, this can cause problems when configure is run without -a controlling terminal (eg. from cron). To avoid this, use ---with-tcsetpgrp or --without-tcsetpgrp to tell configure whether the -function should be used. - Options For Configure --------------------- diff --git a/Src/init.c b/Src/init.c index 8c7776c7a..70e878e20 100644 --- a/Src/init.c +++ b/Src/init.c @@ -695,7 +695,6 @@ init_io(char *cmd) } else opts[USEZLE] = 0; -#ifdef JOB_CONTROL /* If interactive, make sure the shell is in the foreground and is the * process group leader. */ @@ -708,9 +707,6 @@ init_io(char *cmd) acquire_pgrp(); /* might also clear opts[MONITOR] */ } } -#else - opts[MONITOR] = 0; -#endif } /**/ @@ -718,7 +714,7 @@ mod_export void init_shout(void) { static char shoutbuf[BUFSIZ]; -#if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC) +#if defined(TIOCSETD) && defined(NTTYDISC) int ldisc; #endif @@ -729,7 +725,7 @@ init_shout(void) return; } -#if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC) +#if defined(TIOCSETD) && defined(NTTYDISC) ldisc = NTTYDISC; ioctl(SHTTY, TIOCSETD, (char *)&ldisc); #endif diff --git a/Src/options.c b/Src/options.c index a0e1aa024..8b37ab5e8 100644 --- a/Src/options.c +++ b/Src/options.c @@ -877,7 +877,6 @@ dosetopt(int optno, int value, int force, char *new_opts) } #endif /* HAVE_SETRESGID && HAVE_SETRESUID */ -#ifdef JOB_CONTROL } else if (!force && optno == MONITOR && value) { if (new_opts[optno] == value) return 0; @@ -887,14 +886,6 @@ dosetopt(int optno, int value, int force, char *new_opts) origpgrp = GETPGRP(); acquire_pgrp(); } -#else - } else if(optno == MONITOR && value) { - return -1; -#endif /* not JOB_CONTROL */ -#ifdef GETPWNAM_FAKED - } else if(optno == CDABLEVARS && value) { - return -1; -#endif /* GETPWNAM_FAKED */ } else if ((optno == EMACSMODE || optno == VIMODE) && value) { if (sticky && sticky->emulation) return -1; diff --git a/Src/signals.c b/Src/signals.c index 6eecbf7d5..86f1a49f6 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -216,7 +216,6 @@ signal_suspend(UNUSED(int sig), int wait_cmd) int ret; sigset_t set; - sigset_t oset; sigemptyset(&set); @@ -229,13 +228,7 @@ signal_suspend(UNUSED(int sig), int wait_cmd) (sigtrapped[SIGINT] & ~ZSIG_IGNORED))) sigaddset(&set, SIGINT); -# ifdef BROKEN_POSIX_SIGSUSPEND - sigprocmask(SIG_SETMASK, &set, &oset); - ret = pause(); - sigprocmask(SIG_SETMASK, &oset, NULL); -# else /* not BROKEN_POSIX_SIGSUSPEND */ ret = sigsuspend(&set); -# endif /* BROKEN_POSIX_SIGSUSPEND */ return ret; } diff --git a/Src/zsh_system.h b/Src/zsh_system.h index 5c004d53e..21446a9b1 100644 --- a/Src/zsh_system.h +++ b/Src/zsh_system.h @@ -369,8 +369,6 @@ struct timespec { # ifndef TIME_H_SELECT_H_CONFLICTS # include # endif -#elif defined(SELECT_IN_SYS_SOCKET_H) -# include #endif #if defined(__APPLE__) && defined(HAVE_SELECT) @@ -803,16 +801,6 @@ extern short ospeed; #endif #endif -/* Can't support job control without working tcsetgrp() */ -#ifdef BROKEN_TCSETPGRP -#undef JOB_CONTROL -#endif /* BROKEN_TCSETPGRP */ - -#ifdef BROKEN_KILL_ESRCH -#undef ESRCH -#define ESRCH EINVAL -#endif /* BROKEN_KILL_ESRCH */ - /* Can we do locale stuff? */ #undef USE_LOCALE #if defined(CONFIG_LOCALE) && defined(HAVE_SETLOCALE) && defined(LC_ALL) diff --git a/configure.ac b/configure.ac index eab95105c..b2721fa77 100644 --- a/configure.ac +++ b/configure.ac @@ -2119,20 +2119,6 @@ if test x$zsh_cv_header_sys_ioctl_h_ioctl_proto = xyes; then AC_DEFINE(IOCTL_IN_SYS_IOCTL) fi -dnl ------------------- -dnl select() defined in , ie BeOS R4.51 -dnl ------------------- -AH_TEMPLATE([SELECT_IN_SYS_SOCKET_H], -[Define to 1 if select() is defined in , ie BeOS R4.51]) -if test x$ac_cv_header_sys_select_h != xyes; then - AC_CACHE_CHECK(for select() in , - zsh_cv_header_socket_h_select_proto, - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[fd_set fd;]])],[zsh_cv_header_socket_h_select_proto=yes],[zsh_cv_header_socket_h_select_proto=no])]) - if test x$zsh_cv_header_socket_h_select_proto = xyes; then - AC_DEFINE(SELECT_IN_SYS_SOCKET_H) - fi -fi - dnl ----------- dnl named FIFOs dnl ----------- @@ -2266,154 +2252,6 @@ if test x$zsh_cv_sys_link = xyes; then AC_DEFINE(HAVE_LINK) fi -dnl ----------- -dnl test for whether kill(pid, 0) where pid doesn't exit -dnl should set errno to ESRCH, but some like BeOS R4.51 set to EINVAL -dnl ----------- -AC_CACHE_CHECK(if kill(pid, 0) returns ESRCH correctly, -zsh_cv_sys_killesrch, -[AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include -int main() -{ - int pid = (getpid() + 10000) & 0xffffff; - while (pid && (kill(pid, 0) == 0 || errno != ESRCH)) pid >>= 1; - return(errno!=ESRCH); -} -]])],[zsh_cv_sys_killesrch=yes],[zsh_cv_sys_killesrch=no],[zsh_cv_sys_killesrch=yes])]) -AH_TEMPLATE([BROKEN_KILL_ESRCH], -[Define to 1 if kill(pid, 0) doesn't return ESRCH, ie BeOS R4.51.]) -if test x$zsh_cv_sys_killesrch = xno; then - AC_DEFINE(BROKEN_KILL_ESRCH) -fi - -dnl ----------- -dnl if POSIX, test for working sigsuspend(). -dnl for instance, BeOS R4.51 is broken. -dnl ----------- -AH_TEMPLATE([BROKEN_POSIX_SIGSUSPEND], -Define to 1 if sigsuspend() is broken, ie BeOS R4.51.]) - AC_CACHE_CHECK(if POSIX sigsuspend() works, - zsh_cv_sys_sigsuspend, - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -int child=0; -void handler(sig) - int sig; -{if(sig==SIGCHLD) child=1;} -int main() { - struct sigaction act; - sigset_t set; - int pid, ret; - act.sa_handler = &handler; - sigfillset(&act.sa_mask); - act.sa_flags = 0; - sigaction(SIGCHLD, &act, 0); - sigfillset(&set); - sigprocmask(SIG_SETMASK, &set, 0); - pid=fork(); - if(pid==0) return 0; - if(pid>0) { - sigemptyset(&set); - ret=sigsuspend(&set); - return(child==0); - } -} -]])],[zsh_cv_sys_sigsuspend=yes],[zsh_cv_sys_sigsuspend=no],[zsh_cv_sys_sigsuspend=yes])]) - if test x$zsh_cv_sys_sigsuspend = xno; then - AC_DEFINE(BROKEN_POSIX_SIGSUSPEND) - fi - -dnl ----------- -dnl if found tcsetpgrp, test to see if it actually works -dnl for instance, BeOS R4.51 does not support it yet -dnl ----------- -AH_TEMPLATE([BROKEN_TCSETPGRP], -[Define to 1 if tcsetpgrp() doesn't work, ie BeOS R4.51.]) -AC_ARG_WITH(tcsetpgrp, -AS_HELP_STRING([--with-tcsetpgrp],[assumes that tcsetpgrp() exists and works correctly]),[ -case "x$withval" in - xyes) zsh_working_tcsetpgrp=yes;; - xno) zsh_working_tcsetpgrp=no;; - *) AC_MSG_ERROR(please use --with-tcsetpgrp=yes or --with-tcsetpgrp=no);; -esac],[zsh_working_tcsetpgrp=check]) -if test "x$ac_cv_func_tcsetpgrp" = xyes; then -case "x$zsh_working_tcsetpgrp" in - xcheck) - trap "" TTOU > /dev/null 2>&1 || : - AC_CACHE_CHECK(if tcsetpgrp() actually works, - zsh_cv_sys_tcsetpgrp, - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include -int main() { - int fd; - int ret; - fd=open("/dev/tty", O_RDWR); - if (fd < 0) return(2); - ret=tcsetpgrp(fd, tcgetpgrp(fd)); - if (ret < 0) return(1); - return(0); -} -]])],[zsh_cv_sys_tcsetpgrp=yes],[ -case $? in - 1) zsh_cv_sys_tcsetpgrp=no;; - 2) zsh_cv_sys_tcsetpgrp=notty;; - *) zsh_cv_sys_tcsetpgrp=error;; -esac - ],[zsh_cv_sys_tcsetpgrp=yes])]) - case "x$zsh_cv_sys_tcsetpgrp" in - xno) AC_DEFINE(BROKEN_TCSETPGRP);; - xyes) :;; - xnotty) AC_MSG_ERROR([no controlling tty -Try running configure with --with-tcsetpgrp or --without-tcsetpgrp]);; - *) AC_MSG_ERROR([unexpected return status]);; - esac - trap - TTOU > /dev/null 2>&1 || : - ;; - xyes) :;; - xno) AC_DEFINE(BROKEN_TCSETPGRP);; - *) AC_MSG_ERROR([unexpected value zsh_working_tcsetpgrp=$zsh_working_tcsetpgrp]);; -esac -fi - -dnl ----------- -dnl test for faked getpwnam() entry, ie a single entry returned for any username -dnl for instance, BeOS R4.51 is not multiuser yet, and fakes getpwnam() -dnl test by looking up two usernames that shouldn't succeed, and compare entry -dnl ----------- -AH_TEMPLATE([GETPWNAM_FAKED], -[Define to 1 if getpwnam() is faked, ie BeOS R4.51.]) -if test x$ac_cv_func_getpwnam = xyes; then - AC_CACHE_CHECK(if getpwnam() is faked, - zsh_cv_sys_getpwnam_faked, - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include -#include -#include -int main() { - struct passwd *pw1, *pw2; - char buf[1024], name[1024]; - sprintf(buf, "%d:%d", getpid(), rand()); - pw1=getpwnam(buf); - if (pw1) strcpy(name, pw1->pw_name); - sprintf(buf, "%d:%d", rand(), getpid()); - pw2=getpwnam(buf); - return(pw1!=0 && pw2!=0 && !strcmp(name, pw2->pw_name)); -} -]])],[zsh_cv_sys_getpwnam_faked=no],[zsh_cv_sys_getpwnam_faked=yes],[zsh_cv_sys_getpwnam_faked=no])]) - if test x$zsh_cv_sys_getpwnam_faked = xyes; then - AC_DEFINE(GETPWNAM_FAKED) - fi -fi - - dnl --------------- dnl check for the type of third argument of accept dnl --------------- @@ -3151,9 +2989,6 @@ AH_TOP([/***** begin user configuration section *****/ /* Define to 1 if you want user names to be cached */ #define CACHE_USERNAMES 1 -/* Define to 1 if system supports job control */ -#define JOB_CONTROL 1 - /* Define this if you use "suspended" instead of "stopped" */ #define USE_SUSPENDED 1 -- cgit v1.2.3 From 33976537684eb5d1111a0aeb58cabeb3d3acf393 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:27:07 +0200 Subject: 53082: remove a couple of unused #defines --- ChangeLog | 2 ++ configure.ac | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 335ae40d3..70c1213b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-09-14 Oliver Kiddle + * 53082: configure.ac: remove a couple of unused #defines + * 53081: INSTALL, configure.ac, Src/init.c, Src/options.c, Src/signals.c, Src/zsh_system.h: remove old BeOS support code diff --git a/configure.ac b/configure.ac index b2721fa77..aca355ff4 100644 --- a/configure.ac +++ b/configure.ac @@ -2982,13 +2982,6 @@ AH_TOP([/***** begin user configuration section *****/ /* Define this to be the location of your password file */ #define PASSWD_FILE "/etc/passwd" -/* Define this to be the name of your NIS/YP password * - * map (if applicable) */ -#define PASSWD_MAP "passwd.byname" - -/* Define to 1 if you want user names to be cached */ -#define CACHE_USERNAMES 1 - /* Define this if you use "suspended" instead of "stopped" */ #define USE_SUSPENDED 1 -- cgit v1.2.3 From 55ff6f88649a592eb42e04e7434fd89349d4518a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:30:30 +0200 Subject: 53083: handle Haiku specific resource limit for open vnode monitors --- ChangeLog | 3 +++ Src/Builtins/rlimits.c | 4 ++++ configure.ac | 1 + 3 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 70c1213b9..3ecb05e63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-09-14 Oliver Kiddle + * 53083: configure.ac, Src/Builtins/rlimits.c: handle Haiku + specific resource limit for open vnode monitors + * 53082: configure.ac: remove a couple of unused #defines * 53081: INSTALL, configure.ac, Src/init.c, Src/options.c, diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index 5f9c84b0f..f25dd2530 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -171,6 +171,10 @@ static const resinfo_T known_resources[] = { {RLIMIT_TCACHE, "cachedthreads", ZLIMTYPE_NUMBER, 1, 'N', "cached threads"}, # endif +# ifdef HAVE_RLIMIT_NOVMON /* Haiku */ + {RLIMIT_NOVMON, "vnodemonitors", ZLIMTYPE_NUMBER, 1, + 'N', "open vnode monitors"}, +# endif }; /* resinfo[RLIMIT_XXX] points to the corresponding entry diff --git a/configure.ac b/configure.ac index aca355ff4..220f353c3 100644 --- a/configure.ac +++ b/configure.ac @@ -1879,6 +1879,7 @@ zsh_LIMIT_PRESENT(RLIMIT_NPTS) zsh_LIMIT_PRESENT(RLIMIT_SWAP) zsh_LIMIT_PRESENT(RLIMIT_KQUEUES) zsh_LIMIT_PRESENT(RLIMIT_UMTXP) +zsh_LIMIT_PRESENT(RLIMIT_NOVMON) zsh_LIMITS_EQUAL(VMEM, vmem, RSS, rss) zsh_LIMITS_EQUAL(VMEM, vmem, AS, as) -- cgit v1.2.3 From 0cd2c953b486c85bc4b7983dee18065d0a53cb04 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:33:10 +0200 Subject: 53084: yet another approach to the /dev/fd autoconf test because of shells emulating /dev/fd --- ChangeLog | 3 +++ configure.ac | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3ecb05e63..a4bec3999 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-09-14 Oliver Kiddle + * 53084: configure.ac: yet another approach to the /dev/fd + autoconf test because of shells emulating /dev/fd + * 53083: configure.ac, Src/Builtins/rlimits.c: handle Haiku specific resource limit for open vnode monitors diff --git a/configure.ac b/configure.ac index 220f353c3..e8f434274 100644 --- a/configure.ac +++ b/configure.ac @@ -1949,7 +1949,7 @@ AH_TEMPLATE([PATH_DEV_FD], [Define to the path of the /dev/fd filesystem.]) AC_CACHE_CHECK(for /dev/fd filesystem, zsh_cv_sys_path_dev_fd, [for zsh_cv_sys_path_dev_fd in /proc/self/fd /dev/fd no; do - (exec 3<&0; test -e $zsh_cv_sys_path_dev_fd/3;) && break + test x`echo ok|(cat $zsh_cv_sys_path_dev_fd/3 3<&0 2>/dev/null;)` = xok && break done]) if test x$zsh_cv_sys_path_dev_fd != xno; then AC_DEFINE_UNQUOTED(PATH_DEV_FD, "$zsh_cv_sys_path_dev_fd") -- cgit v1.2.3 From 701fad5021db0b3d07eaf90013a1ad760aaca78c Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:38:23 +0200 Subject: 53085: support for BSDs in $ZSH_EXEPATH implementation --- ChangeLog | 3 +++ Src/init.c | 34 ++++++++++++++++++++++++++-------- configure.ac | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index a4bec3999..2d06a3ffb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-09-14 Oliver Kiddle + * 53085: configure.ac, Src/init.c: support for BSDs in + $ZSH_EXEPATH implementation + * 53084: configure.ac: yet another approach to the /dev/fd autoconf test because of shells emulating /dev/fd diff --git a/Src/init.c b/Src/init.c index 70e878e20..2f914f96b 100644 --- a/Src/init.c +++ b/Src/init.c @@ -36,6 +36,10 @@ #include "version.h" +#ifdef HAVE_SYS_SYSCTL_H +#include +#endif + /**/ int noexitct = 0; @@ -913,12 +917,6 @@ getmypath(const char *name, const char *cwd) char *buf; int namelen; - if (!name) - return NULL; - if (*name == '-') - ++name; - if ((namelen = strlen(name)) == 0) - return NULL; #if defined(__APPLE__) { uint32_t n = PATH_MAX; @@ -934,6 +932,19 @@ getmypath(const char *name, const char *cwd) else free(buf); } +#elif defined(KERN_PROC_PATHNAME) + { +#ifdef __NetBSD__ + int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_PATHNAME }; +#else + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; +#endif + size_t len = PATH_MAX; + buf = (char *) zalloc(PATH_MAX); + if (!sysctl(mib, 4, buf, &len, NULL, 0) && len > 1) + return buf; + free(buf); + } #elif defined(PROC_SELF_EXE) { ssize_t n; @@ -947,6 +958,13 @@ getmypath(const char *name, const char *cwd) free(buf); } #endif + + if (!name) + return NULL; + if (*name == '-') + ++name; + if ((namelen = strlen(name)) == 0) + return NULL; /* guess the absolute pathname of 'name' */ if (name[namelen-1] == '/') /* name should not end with '/' */ return NULL; @@ -964,7 +982,7 @@ getmypath(const char *name, const char *cwd) } #ifdef HAVE_REALPATH else { - /* search each dir in PARH */ + /* search each dir in PATH */ const char *path, *sep; char *real, *try; int pathlen, dirlen; @@ -978,7 +996,7 @@ getmypath(const char *name, const char *cwd) do { sep = strchr(path, ':'); dirlen = sep ? sep - path : strlen(path); - strncpy(try, path, dirlen); + memcpy(try, path, dirlen); try[dirlen] = '/'; try[dirlen+1] = '\0'; strcat(try, name); diff --git a/configure.ac b/configure.ac index e8f434274..2931f6615 100644 --- a/configure.ac +++ b/configure.ac @@ -636,7 +636,7 @@ fi AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \ termios.h sys/param.h sys/filio.h string.h memory.h \ limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \ - sys/random.h \ + sys/sysctl.h sys/random.h \ locale.h errno.h stdio.h stdarg.h varargs.h stdlib.h \ unistd.h sys/capability.h \ utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \ -- cgit v1.2.3 From 5ffaffdea354b7eea3aac9ed328c1a507f08e539 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:41:06 +0200 Subject: 53086: change flags used for building dynamic modules on Haiku OS --- ChangeLog | 3 +++ configure.ac | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d06a3ffb..262a34239 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-09-14 Oliver Kiddle + * 53086: configure.ac: change flags used for building dynamic + modules on Haiku OS + * 53085: configure.ac, Src/init.c: support for BSDs in $ZSH_EXEPATH implementation diff --git a/configure.ac b/configure.ac index 2931f6615..474f0ccee 100644 --- a/configure.ac +++ b/configure.ac @@ -2638,13 +2638,13 @@ int main(int argc, char *argv[]) fi case "$host_os" in osf*) DLLDFLAGS="${DLLDFLAGS=-shared -expect_unresolved '*'}" ;; - *freebsd*|*netbsd*|linux*|irix*|gnu*|interix*|dragonfly*) DLLDFLAGS="${DLLDFLAGS=-shared}" ;; + *freebsd*|*netbsd*|linux*|irix*|gnu*|interix*|dragonfly*|haiku*) DLLDFLAGS="${DLLDFLAGS=-shared}" ;; sunos*) DLLDFLAGS="${DLLDFLAGS=-assert nodefinitions}" ;; sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G $ldflags}" ;; aix*) DLLDFLAGS="${DLLDFLAGS=-G -bexpall -lc}" ;; solaris*|sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G}" ;; darwin*) DLLDFLAGS="${DLLDFLAGS=-bundle -flat_namespace -undefined suppress}" ;; - beos*|haiku*) DLLDFLAGS="${DLLDFLAGS=-nostart}" ;; + beos*) DLLDFLAGS="${DLLDFLAGS=-nostart}" ;; openbsd*) if test x$zsh_cv_sys_elf = xyes; then DLLDFLAGS="${DLLDFLAGS=-shared -fPIC}" -- cgit v1.2.3 From c8f01742899f8f7358b6e9188853dc91f790ef21 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:43:26 +0200 Subject: 53087: don't produce spurious error when zpty is missing --- ChangeLog | 3 +++ Test/X05zleincarg.ztst | 40 ++++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 262a34239..a155f7b1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-09-14 Oliver Kiddle + * 53087: Test/X05zleincarg.ztst: don't produce spurious error + when zpty is missing + * 53086: configure.ac: change flags used for building dynamic modules on Haiku OS diff --git a/Test/X05zleincarg.ztst b/Test/X05zleincarg.ztst index cd9817c82..f712e9426 100644 --- a/Test/X05zleincarg.ztst +++ b/Test/X05zleincarg.ztst @@ -5,29 +5,29 @@ if ( zmodload zsh/zpty 2>/dev/null ); then . $ZTST_srcdir/comptest comptestinit -v -z $ZTST_testdir/../Src/zsh + zpty_run ' + autoload -Uz incarg + for name in {,vim-,vim-backward-}{,sync-}{inc,dec}arg; do + zle -N "$name" incarg + done + bindkey -v "^N" incarg + bindkey -v "^P" decarg + bindkey -v "^F" sync-incarg + bindkey -v "^B" sync-decarg + bindkey -a "^N" vim-incarg + bindkey -a "^P" vim-decarg + bindkey -a "^F" vim-sync-incarg + bindkey -a "^B" vim-sync-decarg + bindkey -a "^E" vim-backward-incarg + bindkey -a "^Y" vim-backward-decarg + unset TMUX_PANE ITERM_SESSION_ID + tmux() { + echo "$TMUX_PANE" + } + ' else ZTST_unimplemented="the zsh/zpty module is not available" fi - zpty_run ' - autoload -Uz incarg - for name in {,vim-,vim-backward-}{,sync-}{inc,dec}arg; do - zle -N "$name" incarg - done - bindkey -v "^N" incarg - bindkey -v "^P" decarg - bindkey -v "^F" sync-incarg - bindkey -v "^B" sync-decarg - bindkey -a "^N" vim-incarg - bindkey -a "^P" vim-decarg - bindkey -a "^F" vim-sync-incarg - bindkey -a "^B" vim-sync-decarg - bindkey -a "^E" vim-backward-incarg - bindkey -a "^Y" vim-backward-decarg - unset TMUX_PANE ITERM_SESSION_ID - tmux() { - echo "$TMUX_PANE" - } - ' %test -- cgit v1.2.3 From 6bc8c60933b398fbae11901efac61394814da69e Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 14 Sep 2024 19:49:06 +0200 Subject: unposted (c.f. Emil Velikov: 53072): remove completion that has been imported by the upstream project --- ChangeLog | 3 + Completion/Linux/Command/_dkms | 165 ----------------------------------------- 2 files changed, 3 insertions(+), 165 deletions(-) delete mode 100644 Completion/Linux/Command/_dkms diff --git a/ChangeLog b/ChangeLog index a155f7b1f..5260a9665 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-09-14 Oliver Kiddle + * c.f. Emil Velikov: 53072: Completion/Linux/Command/_dkms: + remove completion that has been imported by the upstream project + * 53087: Test/X05zleincarg.ztst: don't produce spurious error when zpty is missing diff --git a/Completion/Linux/Command/_dkms b/Completion/Linux/Command/_dkms deleted file mode 100644 index 2a3c016c5..000000000 --- a/Completion/Linux/Command/_dkms +++ /dev/null @@ -1,165 +0,0 @@ -#compdef dkms - -local curcontext="$curcontext" ign cmds opts ret=1 -local -a state line expl args subcmds dirs -local -A opt_args - -subcmds=( - 'add:add a module/version combination to the tree for builds and installs' - 'remove:remove a module from the tree' - 'build:compile a module for a kernel' - 'unbuild:undoes the build of a module' - "install:install a build module for it's corresponding kernel" - 'uninstall:uninstall a module for a kernel' - 'match:install every module that is installed for a template kernel for another kernel' - 'mkdriverdisk:create a floppy driver disk image for use when updated drivers are needed to install an OS' - 'mktarball:tar up files in the DKMS tree for a specific module' - 'ldtarball:extract a tarball created with mktarball into the DKMS tree' - 'mkrpm:create an RPM package for a module' - 'mkdeb:create a debian binary package for a module' - 'mkdsc:create a debian source package for a module' - 'mkbmdeb:create a debian package containing just binary modules' - 'mkkmp:create a Kernel Module Package source RPM for a module' - 'status:display the current status of modules, versions and kernels within the tree' - 'autoinstall:try to install the latest revision of all modules that have been installed for other kernel revisions' -) - -args=( - '(1)-m[specify module]:module:->modules' - '(1)-v[specify module version]:version' - '(-q --quiet)'{-q,--quiet}'[suppress output]' - '(--all)*'{-a,--arch}'[specify system architecture]:architecture:->architectures' - '*--directive=:directive' - '--dkmstree=:path:_directories' - '--installtree=:path:_directories' - '--sourcetree=:path:_directories' - '--dkmsframework=:path:_directories' - '--force-version-override' - '1: : _describe -t commands command subcmds' -) - -cmd=${${${subcmds%%:*}:*words}[1]} -if [[ -n $cmd ]]; then - curcontext="${curcontext%:*}-$cmd:" -else - # exclude sub-commands based on any options specified so far - for cmds opts in \ - '(remove|build|install|uninstall|match|status|mk(^kmp))' 'k' \ - '(add|remove)' '-rpm_safe_upgrade' \ - 'mk(driverdisk|kmp)' '-spec' \ - 'mk(deb|dsc|bmdeb|rpm)' '-legacy-postinst' \ - 'mk(tarball|rpm|deb|dsc)' '-(source|binary)-only' \ - '(match|build|mkkmp)' '(k|-no-(prepare|clean)-kernel|-kernelsourcedir)' \ - '(|un)install' '-no-(depmod|initrd)' \ - 'mkdriverdisk' '([dr]|-distro|-release|-size|-media)' \ - '(add|build|install|ldtarball)' '-force' \ - 'match' '-templatekernel' \ - '*tarball' '-archive' \ - '(match|build|mkkmp)' '(j*|-no-(prepare|clean)-kernel|-kernelsourcedir)' \ - '(remove|build|install|status|mk(^kmp))' '-all' \ - 'build' '-config' - do - [[ -n ${(M)words:#-${~opts}*} ]] && - subcmds=( ${(M)subcmds:#${~cmds}:*} ) - done - args+=( '(1 -)'{-V,--version}'[display version information]' ) - ign='!' # hide some uncommon options but handle their arguments -fi - -case $cmd in - remove|build|install|uninstall|mk*|status) - args+=( ': :->modules' ) - ;| - |remove|(un|)build|install|uninstall|match|status|mk(^kmp)) - args+=( '(--all)*-k[specify kernel version]:kernel:->kernels' ) - ;| - |add|remove) args+=( "${ign}--rpm_safe_upgrade" ) ;| - |mk(driverdisk|kmp)) - args+=( "${ign}--spec=:spec file:_files -g '*.spec(-.)'" ) - ;| - |(mk|ld)tarball) - args+=( "${ign}--archive=:tarball:_files -g '*.tar(-.)'" ) - ;| - |mk(deb|dsc|bmdeb|rpm)) - args+=( "${ign}--legacy-postinst=:value [1]:(0 1)" ) - ;| - |mk(tarball|rpm|deb|dsc)) args+=( "${ign}(--source-only --binaries-only)--"{source,binaries}-only ) ;| - |match|build|mkkmp) - args+=( #TODO: check ignore needed in absence of parameters - "${ign}--no-prepare-kernel" - "${ign}--no-clean-kernel" - '--kernelsourcedir=:directory:_directories' - "${ign}-j+[specify maximum number of jobs to use when building]:jobs" - ) - ;| - |(|un)install) - args+=( - "${ign}--no-depmod" - "${ign}--no-initrd" - ) - ;| - |add) - args+=( - '-c[specify location of dkms.conf file]:location:_files' - ) - ;| - |remove|(un|)build|install|status|mk(^kmp)) - args+=( '(-a --arch -k)--all[specify all relevant kernels/arches]' ) - ;| - |build) - args+=( "${ign}--config=:kernel config file:_files" ) - ;| - |add|build|install|ldtarball) - args+=( '--force[force overwriting of extant files]' ) - ;| - |match) - args+=( "${ign}--templatekernel=:kernel:->kernels" ) - ;| - |mkdriverdisk) - args+=( - "${ign}(-d --distro)"{-d,--distro=}':distribution:(redhat'{,1,2,3}' suse unitedlinux)' - "${ign}(-r --release)"{-r,--release=}':release' - "${ign}--size=:size (kb) [1440]" - "${ign}--media=:media type [floppy]:(floppy iso tar)" - ) - ;| - add) - args+=( - '3:path:_directories' - '4:tarball:_files -g "*.tar(-.)"' - ) - ;; - install) - args+=( - '3:rpm file:_files -g "*.rpm(-.)"' - ) - ;; -esac - -_arguments -C $args && ret=0 - -case $state in - modules) - dirs=( ${(e)opt_args[--dkmstree]:-/var/lib/dkms}/*/*(/) ) - dirs=( ${${(M)dirs%/*/*}#/} ) - _description modules expl module - _multi_parts -i "$expl[@]" / dirs && ret=0 - ;; - kernels) - if compset -P 1 '*/'; then - _description architectures expl architecture - compadd "$expl[@]" /lib/modules/$IPREFIX/build/arch/*(/:t) && ret=0 - else - compset -S '/*' - dirs=( /lib/modules/*(/:t) ) - _description -V kernels expl kernel - compadd "$expl[@]" -r "/ \t\n\-" ${(on)dirs} && ret=0 - fi - ;; - architectures) - _description architectures expl architecture - compadd "$expl[@]" /lib/modules/$(uname -r)/build/arch/*(/:t) && ret=0 - ;; -esac - -return ret -- cgit v1.2.3 From 8ad625d90c2df0246aa921c51d248a3b28f43da9 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 14 Sep 2024 12:40:56 -0700 Subject: 53088: enable `time' on builtins, assignments, and current-shell actions --- ChangeLog | 6 +++++ Src/exec.c | 42 ++++++++++++++++++++++++++++++++-- Src/jobs.c | 41 +++++++++++++++++++++++++++++---- Test/A01grammar.ztst | 7 ------ Test/A08time.ztst | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 Test/A08time.ztst diff --git a/ChangeLog b/ChangeLog index 5260a9665..00a89d48f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-09-14 Bart Schaefer + + * 53088: Src/exec.c, Src/jobs.c, Test/A01grammar.ztst, + Test/A08time.ztst: enable `time' on builtins, assignments, and + other current-shell actions, including failed commands. Tests. + 2024-09-14 Oliver Kiddle * c.f. Emil Velikov: 53072: Completion/Linux/Command/_dkms: diff --git a/Src/exec.c b/Src/exec.c index 00278ac50..8aa7466f5 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -881,6 +881,10 @@ execute(LinkList args, int flags, int defpath) _realexit(); else zerr("command not found: %s", arg0); + /* This is bash behavior, but fails to restore interactive settings etc. + lastval = ((eno == EACCES || eno == ENOEXEC) ? 126 : 127); + return; + */ _exit((eno == EACCES || eno == ENOEXEC) ? 126 : 127); } @@ -1677,7 +1681,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) wordcode code = *state->pc++; static int lastwj, lpforked; - if (wc_code(code) != WC_PIPE) + if (wc_code(code) != WC_PIPE && !(how & Z_TIMED)) return lastval = (slflags & WC_SUBLIST_NOT) != 0; else if (slflags & WC_SUBLIST_NOT) last1 = 0; @@ -2939,6 +2943,14 @@ execcmd_exec(Estate state, Execcmd_params eparams, */ LinkList preargs; + /* + * for the "time" keyword + */ + child_times_t shti, chti; + struct timeval then; + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 0); + doneps4 = 0; /* @@ -3071,6 +3083,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, if (!(hn = resolvebuiltin(cmdarg, hn))) { if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } if (type != WC_TYPESET) @@ -3252,6 +3266,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, errflag |= ERRFLAG_ERROR; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } } @@ -3343,6 +3359,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, errflag |= ERRFLAG_ERROR; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } else if (!nullcmd || !*nullcmd || opts[SHNULLCMD]) { if (!args) @@ -3363,6 +3381,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, lastval = 0; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } else { /* @@ -3375,6 +3395,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, lastval = 1; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } cmdoutval = use_cmdoutval ? lastval : 0; @@ -3393,6 +3415,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, } if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } } else if (isset(RESTRICTED) && (cflags & BINF_EXEC) && do_exec) { @@ -3401,6 +3425,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, lastval = 1; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } @@ -3437,6 +3463,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, opts[AUTOCONTINUE] = oautocont; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } break; @@ -3448,6 +3476,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, if (!(hn = resolvebuiltin(cmdarg, hn))) { if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } break; @@ -3466,6 +3496,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, opts[AUTOCONTINUE] = oautocont; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } @@ -3545,6 +3577,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, opts[AUTOCONTINUE] = oautocont; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } } @@ -3575,6 +3609,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, opts[AUTOCONTINUE] = oautocont; if (forked) _realexit(); + if (how & Z_TIMED) + shelltime(&shti, &chti, &then, 1); return; } @@ -4377,6 +4413,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, errflag |= ERRFLAG_ERROR; } } + if ((is_cursh || do_exec) && (how & Z_TIMED)) + shelltime(&shti, &chti, &then, 1); if (newxtrerr) { int eno = errno; fil = fileno(newxtrerr); @@ -5265,7 +5303,7 @@ exectime(Estate state, UNUSED(int do_exec)) jb = thisjob; if (WC_TIMED_TYPE(state->pc[-1]) == WC_TIMED_EMPTY) { - shelltime(); + shelltime(NULL,NULL,NULL,0); return 0; } execpline(state, *state->pc++, Z_TIMED|Z_SYNC, 0); diff --git a/Src/jobs.c b/Src/jobs.c index 07facc60b..39c664388 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1894,7 +1894,7 @@ spawnjob(void) /**/ void -shelltime(void) +shelltime(child_times_t *shell, child_times_t *kids, struct timeval *then, int delta) { struct timezone dummy_tz; struct timeval dtimeval, now; @@ -1913,7 +1913,28 @@ shelltime(void) ti.ut = buf.tms_utime; ti.st = buf.tms_stime; #endif - printtime(dtime(&dtimeval, &shtimer, &now), &ti, "shell"); + if (shell) { + if (delta) { +#ifdef HAVE_GETRUSAGE + dtime(&ti.ru_utime, &shell->ru_utime, &ti.ru_utime); + dtime(&ti.ru_stime, &shell->ru_stime, &ti.ru_stime); +#else + ti.ut -= shell->ut; + ti.st -= shell->st; +#endif + } else + *shell = ti; + } + if (delta) + dtime(&dtimeval, then, &now); + else { + if (then) + *then = now; + dtime(&dtimeval, &shtimer, &now); + } + + if (!delta == !shell) + printtime(&dtimeval, &ti, "shell"); #ifdef HAVE_GETRUSAGE getrusage(RUSAGE_CHILDREN, &ti); @@ -1921,8 +1942,20 @@ shelltime(void) ti.ut = buf.tms_cutime; ti.st = buf.tms_cstime; #endif - printtime(&dtimeval, &ti, "children"); - + if (kids) { + if (delta) { +#ifdef HAVE_GETRUSAGE + dtime(&ti.ru_utime, &kids->ru_utime, &ti.ru_utime); + dtime(&ti.ru_stime, &kids->ru_stime, &ti.ru_stime); +#else + ti.ut -= shell->ut; + ti.st -= shell->st; +#endif + } else + *kids = ti; + } + if (!delta == !kids) + printtime(&dtimeval, &ti, "children"); } /* see if jobs need printing */ diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst index d57085798..660602caf 100644 --- a/Test/A01grammar.ztst +++ b/Test/A01grammar.ztst @@ -399,13 +399,6 @@ >This is name2 >This is still name2 - (time cat) >&/dev/null -0:`time' keyword (status only) - - TIMEFMT='%E %mE %uE %* %m%mm %u%uu'; time (:) -0:`time' keyword with custom TIMEFMT -*?[0-9]##.[0-9](#c2)s [0-9]##ms [0-9]##us %\* %m%mm %u%uu - if [[ -f foo && -d . && -n $ZTST_testdir ]]; then true else diff --git a/Test/A08time.ztst b/Test/A08time.ztst new file mode 100644 index 000000000..9fb1f3ebf --- /dev/null +++ b/Test/A08time.ztst @@ -0,0 +1,64 @@ +# +# This file contains tests for the "time" reserved word +# + +%prep + + unset TIMEFMT + +%test + + (time cat) >&/dev/null +0:`time' keyword (status only) + + ( TIMEFMT='%E %mE %uE %* %m%mm %u%uu'; time (:) ) +0:`time' keyword with custom TIMEFMT +*?[0-9]##.[0-9](#c2)s [0-9]##ms [0-9]##us %\* %m%mm %u%uu + + time x=1 +0:`time' simple assignment +*?shell* +*?children* + + time x=$(date) +0:`time' assignment with external command +*?shell* +*?children* + + x=0; time for ((i=1; i<=10000; ++i)); do ((x+=i)); done; echo $x +0:`time' for-loop with arithmetic condition +>50005000 +*?shell* +*?children* + + time echo $(x=0;for ((i=0; i<=100000; ++i)); do ((x+=i)); done; echo $x) +0:`time' of a builtin with argument command substitution +>5000050000 +*?shell* +*?children* + + time cat <(x=0;for ((i=0; i<=100000; ++i)); do ((x+=i)); done; echo $x) +0:`time' of external command with process substitution +>5000050000 +*?*user*system*cpu*total + + print -u $ZTST_fd 'This test takes 2 seconds' + time builtin nonesuch $(sleep 2) +1:`time' of nonexistent builtin with command substitution +*?*: no such builtin: nonesuch +*?shell* +*?children* + + time /no/such/commmand +127:`time' of nonexistent external +*?*no such file or directory: /no/such/commmand +*?*user*system*cpu*total + + ( setopt errexit; time false; print notreached ) +1:`time' of failed builtin with errexit +*?shell* +*?children* + + ( setopt errexit; time =false; print notreached ) +1:`time' of failed external with errexit +*?*user*system*cpu*total -- cgit v1.2.3 From ad4afde923bc6e809795c99544f5937d159c6bb9 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 18 Sep 2024 10:53:41 +0200 Subject: 53092: silence deprecated header warning on older Linux systems --- ChangeLog | 4 ++++ Src/init.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 00a89d48f..7ca08cf8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-09-18 Oliver Kiddle + + * 53092: Src/init.c: silence deprecated header warning on Linux + 2024-09-14 Bart Schaefer * 53088: Src/exec.c, Src/jobs.c, Test/A01grammar.ztst, diff --git a/Src/init.c b/Src/init.c index 2f914f96b..61f759ded 100644 --- a/Src/init.c +++ b/Src/init.c @@ -36,7 +36,7 @@ #include "version.h" -#ifdef HAVE_SYS_SYSCTL_H +#if defined(HAVE_SYS_SYSCTL_H) && !defined(__linux) #include #endif -- cgit v1.2.3 From 06f423f8a99a3a1d40551cc88cfdcb3a3fe84616 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 18 Sep 2024 10:56:39 +0200 Subject: 53093: silence compiler warning when USE_LSEEK is not defined --- ChangeLog | 3 +++ Src/input.c | 11 ++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7ca08cf8c..aae14e249 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-09-18 Oliver Kiddle + * 53093: Src/input.c: silence compiler warning when USE_LSEEK + is not defined + * 53092: Src/init.c: silence deprecated header warning on Linux 2024-09-14 Bart Schaefer diff --git a/Src/input.c b/Src/input.c index d8ac2c0e7..320fd6500 100644 --- a/Src/input.c +++ b/Src/input.c @@ -217,26 +217,23 @@ shinbufrestore(void) static int shingetchar(void) { - int nread, rsize = isset(SHINSTDIN) ? 1 : SHINBUFSIZE; + int nread; if (shinbufptr < shinbufendptr) return (unsigned char) *shinbufptr++; shinbufreset(); #ifdef USE_LSEEK - if (rsize == 1 && lseek(SHIN, 0, SEEK_CUR) != (off_t)-1) - rsize = SHINBUFSIZE; - if (rsize > 1) { + if (!isset(SHINSTDIN) || lseek(SHIN, 0, SEEK_CUR) != (off_t) -1) { do { errno = 0; - nread = read(SHIN, shinbuffer, rsize); + nread = read(SHIN, shinbuffer, SHINBUFSIZE); } while (nread < 0 && errno == EINTR); if (nread <= 0) return -1; if (isset(SHINSTDIN) && (shinbufendptr = memchr(shinbuffer, '\n', nread))) { - shinbufendptr++; - rsize = (shinbufendptr - shinbuffer); + int rsize = (++shinbufendptr - shinbuffer); if (nread > rsize && lseek(SHIN, -(nread - rsize), SEEK_CUR) < 0) zerr("lseek(%d, %d): %e", SHIN, -(nread - rsize), errno); -- cgit v1.2.3 From 62131ae0499da56ecad237e5f82007a73cfff4fd Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 18 Sep 2024 10:58:55 +0200 Subject: 53094: remove unused autoconf tests --- ChangeLog | 2 ++ Src/signals.h | 5 ----- configure.ac | 12 +++--------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index aae14e249..f1f23bd31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2024-09-18 Oliver Kiddle + * 53094: configure.ac, Src/signals.h: remove unused autoconf tests + * 53093: Src/input.c: silence compiler warning when USE_LSEEK is not defined diff --git a/Src/signals.h b/Src/signals.h index a9c12679f..0540d4b0b 100644 --- a/Src/signals.h +++ b/Src/signals.h @@ -126,10 +126,5 @@ #define queue_signal_level() queueing_enabled -#ifdef BSD_SIGNALS -#define signal_block(S) sigblock(S) -#else extern sigset_t signal_block (sigset_t); -#endif /* BSD_SIGNALS */ - extern sigset_t signal_unblock (sigset_t); diff --git a/configure.ac b/configure.ac index 474f0ccee..7073f4e2c 100644 --- a/configure.ac +++ b/configure.ac @@ -634,7 +634,7 @@ if test "x$enable_pcre" = xyes; then fi AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \ - termios.h sys/param.h sys/filio.h string.h memory.h \ + termios.h sys/param.h sys/filio.h \ limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \ sys/sysctl.h sys/random.h \ locale.h errno.h stdio.h stdarg.h varargs.h stdlib.h \ @@ -849,11 +849,6 @@ esac]) AC_SEARCH_LIBS(getpwnam, nsl) -dnl I am told that told that unicos reqire these for nis_list -if test `echo $host_os | sed 's/^\(unicos\).*/\1/'` = unicos; then - LIBS="-lcraylm -lkrb -lnisdb -lnsl -lrpcsvc $LIBS" -fi - if test "x$dynamic" = xyes; then AC_CHECK_LIB(dl, dlopen) fi @@ -1258,13 +1253,12 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ fpurge fseeko ftello \ mkfifo _mktemp mkstemp \ waitpid wait3 \ - sigaction sigblock sighold sigrelse sigsetmask sigprocmask \ sigqueue \ killpg setpgid setpgrp tcsetpgrp tcgetattr nice \ gethostname gethostbyname2 getipnodebyname \ inet_aton inet_pton inet_ntop \ getlogin getpwent getpwnam getpwuid getgrgid getgrnam \ - initgroups nis_list \ + initgroups \ setuid seteuid setreuid setresuid setsid \ setgid setegid setregid setresgid \ memcpy memmove strstr strerror strtoul \ @@ -1275,7 +1269,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ signgam tgamma \ log2 \ scalbn \ - putenv getenv setenv unsetenv xw\ + putenv getenv setenv unsetenv \ brk sbrk \ pathconf sysconf \ tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \ -- cgit v1.2.3 From 91c56ed27a7e191a257778af831e3d491cdb995c Mon Sep 17 00:00:00 2001 From: Philip Sequeira Date: Mon, 16 Sep 2024 04:13:38 -0400 Subject: 53095: fix completion for chmod/chown --reference with escaped filename --- ChangeLog | 4 ++++ Completion/Unix/Command/_chmod | 4 ++-- Completion/Unix/Command/_chown | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index f1f23bd31..d397fc249 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2024-09-18 Oliver Kiddle + * Philip Sequeira: 53095: Completion/Unix/Command/_chmod, + Completion/Unix/Command/_chown: fix completion for chmod/chown + --reference with escaped filename + * 53094: configure.ac, Src/signals.h: remove unused autoconf tests * 53093: Src/input.c: silence compiler warning when USE_LSEEK diff --git a/Completion/Unix/Command/_chmod b/Completion/Unix/Command/_chmod index 42e3fa63b..693f348dc 100644 --- a/Completion/Unix/Command/_chmod +++ b/Completion/Unix/Command/_chmod @@ -67,13 +67,13 @@ case "$variant" in ;; esac -_arguments -C -s -S $aopts "$args[@]" && ret=0 +_arguments -C -s -S -0 $aopts "$args[@]" && ret=0 case "$state" in files) if [[ -n $opt_args[--reference] ]]; then zmodload -F zsh/stat b:zstat 2>/dev/null - typeset -i8 ref=$(zstat +mode $opt_args[--reference]) + typeset -i8 ref=$(zstat +mode $opt_args[--reference]:Q) _wanted files expl file _files -g "*(-.^f${ref#??})" && ret=0 elif [[ $line[1] = [0-7]## ]]; then _wanted files expl file _files -g "*(-.^f$line[1])" && ret=0 diff --git a/Completion/Unix/Command/_chown b/Completion/Unix/Command/_chown index 4362d6e75..bcc6aec2f 100644 --- a/Completion/Unix/Command/_chown +++ b/Completion/Unix/Command/_chown @@ -71,7 +71,7 @@ case "$variant" in esac (( $+words[(r)--reference*] )) || args+=( '(--reference)1: :->owner' ) -_arguments -C -s -S $aopts "$args[@]" '*: :->files' && ret=0 +_arguments -C -s -S -0 $aopts "$args[@]" '*: :->files' && ret=0 case $state in owner) @@ -95,8 +95,8 @@ case $state in (( $+opt_args[-h] || $+opt_args[--no-dereference] )) || deref="-" if (( $+opt_args[--reference] )); then zmodload -F zsh/stat b:zstat 2>/dev/null - usr=$(zstat +uid $opt_args[--reference]) - grp=$(zstat +gid $opt_args[--reference]) + usr=$(zstat +uid $opt_args[--reference]:Q) + grp=$(zstat +gid $opt_args[--reference]:Q) _wanted files expl file _files -g "*($deref^u$usr,$deref^g$grp)" && ret=0 return ret fi -- cgit v1.2.3 From ec57ac0940c3f194c2c33e2860b2c2399d368837 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 21 Sep 2024 18:02:33 -0700 Subject: 53103: fix spurious test failure on Solaris --- ChangeLog | 4 ++++ Test/A08time.ztst | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d397fc249..228a03ec2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-09-21 Bart Schaefer + + * 53103: Test/A08time.ztst: fix spurious test failure on Solaris + 2024-09-18 Oliver Kiddle * Philip Sequeira: 53095: Completion/Unix/Command/_chmod, diff --git a/Test/A08time.ztst b/Test/A08time.ztst index 9fb1f3ebf..22a460f5e 100644 --- a/Test/A08time.ztst +++ b/Test/A08time.ztst @@ -59,6 +59,7 @@ *?shell* *?children* - ( setopt errexit; time =false; print notreached ) + ( setopt errexit; time expr 0; print notreached ) 1:`time' of failed external with errexit +>0 *?*user*system*cpu*total -- cgit v1.2.3 From 383526da422cf1c962d9be7e9e6ac166e226bf2b Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Wed, 2 Oct 2024 11:57:12 +0900 Subject: 53134: use -undefined dynamic_lookup on recent macOS --- ChangeLog | 4 ++++ configure.ac | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 228a03ec2..a2b9eadae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-09-02 Jun-ichi Takimoto + + * 53134: configure.ac: use -undefined dynamic_lookup on recent macOS + 2024-09-21 Bart Schaefer * 53103: Test/A08time.ztst: fix spurious test failure on Solaris diff --git a/configure.ac b/configure.ac index 7073f4e2c..bca99b7f8 100644 --- a/configure.ac +++ b/configure.ac @@ -2637,7 +2637,9 @@ int main(int argc, char *argv[]) sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G $ldflags}" ;; aix*) DLLDFLAGS="${DLLDFLAGS=-G -bexpall -lc}" ;; solaris*|sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G}" ;; - darwin*) DLLDFLAGS="${DLLDFLAGS=-bundle -flat_namespace -undefined suppress}" ;; + darwin[[0-9]].*|darwin1?.*|darwin2[01].*) + DLLDFLAGS="${DLLDFLAGS=-bundle -flat_namespace -undefined suppress}" ;; + darwin*) DLLDFLAGS="${DLLDFLAGS=-bundle -flat_namespace -undefined dynamic_lookup}" ;; beos*) DLLDFLAGS="${DLLDFLAGS=-nostart}" ;; openbsd*) if test x$zsh_cv_sys_elf = xyes; then -- cgit v1.2.3 From ac1fd06d7ce073c86f00d50fd74464bcb5194e97 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 16 Oct 2024 13:07:56 -0700 Subject: 53146: flags cannot be copied from an undefined function (cf. ca6f4466) --- ChangeLog | 5 +++++ Src/exec.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a2b9eadae..977e25159 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-10-16 Bart Schaefer + + * 53146: Src/exec.c: trace flags cannot be copied from an + undefined function (cf. workers/45131) + 2024-09-02 Jun-ichi Takimoto * 53134: configure.ac: use -undefined dynamic_lookup on recent macOS diff --git a/Src/exec.c b/Src/exec.c index 8aa7466f5..bc07e8c39 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5504,7 +5504,8 @@ execfuncdef(Estate state, Eprog redir_prog) if (funcstack && funcstack->tp == FS_FUNC && !strcmp(s, funcstack->name)) { Shfunc old = ((Shfunc)shfunctab->getnode(shfunctab, s)); - shf->node.flags |= old->node.flags & (PM_TAGGED|PM_TAGGED_LOCAL); + if (old) + shf->node.flags |= old->node.flags & (PM_TAGGED|PM_TAGGED_LOCAL); } shfunctab->addnode(shfunctab, ztrdup(s), shf); } -- cgit v1.2.3 From f282ff579284c7dd918438bc8e30fba4f6776c8c Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 5 Nov 2024 13:50:51 -0800 Subject: 53209 + tests: do not unmetafy via string pointers into global parameter table --- ChangeLog | 5 +++++ Src/params.c | 3 ++- Test/D04parameter.ztst | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 977e25159..35b01f95e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-11-05 Bart Schaefer + + * 53209 + comments + test: Src/params.c, Test/D04parameter.ztst: + do not unmetafy via string pointers into global parameter table + 2024-10-16 Bart Schaefer * 53146: Src/exec.c: trace flags cannot be copied from an diff --git a/Src/params.c b/Src/params.c index acd577527..6f137585b 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3064,8 +3064,9 @@ getsparam(char *s) mod_export char * getsparam_u(char *s) { + /* getsparam() returns pointer into global params table, so ... */ if ((s = getsparam(s))) - return unmetafy(s, NULL); + return unmeta(s); /* returns static pointer to copy */ return s; } diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 0e2a04eb5..7953827d6 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2834,3 +2834,11 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888 fi 1:${(#X)...}: array of out-of-range characters ?(eval):4: character not in range + + ( + export ZDOTDIR=${ echo $PWD/'\0360\0237\0224\0256' } + $ZTST_testdir/../Src/zsh -c 'echo $ZDOTDIR' + ) +0:regression for workers/53179 unicode ZDOTDIR +F:output ignorable as long as not an error +*>* -- cgit v1.2.3 From 9b8af0900fd8167543e5786b46e70d3f32d45e2b Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Mon, 11 Nov 2024 09:27:52 -0500 Subject: 53144: _sysctl: support completion with the dot delimiter on linux --- ChangeLog | 5 +++++ Completion/Unix/Command/_sysctl | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 35b01f95e..a0e742244 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-11-11 Eric Cook + + * 53144: Completion/Unix/Command/_sysctl: + support completion with the dot delimiter on linux + 2024-11-05 Bart Schaefer * 53209 + comments + test: Src/params.c, Test/D04parameter.ztst: diff --git a/Completion/Unix/Command/_sysctl b/Completion/Unix/Command/_sysctl index 442953c4d..09995c98e 100644 --- a/Completion/Unix/Command/_sysctl +++ b/Completion/Unix/Command/_sysctl @@ -23,10 +23,18 @@ case $OSTYPE in else args=( ${args:#((#s)|*\))(\*|)--*} ) # remove long options fi + local delimiter=. + sysctlvars=( /proc/sys/**/*(.e*'REPLY=${REPLY#/proc/sys/}'*) ) + if zstyle -t ":completion:${curcontext}:argument-rest" delimiter / || (( ${words[CURRENT][(Ie)/]} )); then + delimiter=/ + else + sysctlvars=(${sysctlvars//\//.}) + fi + _arguments -S -A "-*" : $args \ '(- :)'{-h,--help}'[display help text and exit]' \ '(- :)'{-V,--version}'[display version info and exit]' \ - '*:sysctl variable:_files -W /proc/sys' + "*:sysctl variable:_multi_parts -i -S = -q $delimiter sysctlvars" ;; freebsd<14->.*) args+=( -- cgit v1.2.3 From 393cb298aaa849bae62e7294fecb1b60d0dd3910 Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Mon, 11 Nov 2024 10:46:08 -0500 Subject: 53174: add Completion/Base/Utility/_as_if --- ChangeLog | 4 ++++ Completion/Base/Utility/_as_if | 10 ++++++++++ Doc/Zsh/compsys.yo | 8 ++++++++ 3 files changed, 22 insertions(+) create mode 100644 Completion/Base/Utility/_as_if diff --git a/ChangeLog b/ChangeLog index a0e742244..bdb60cf33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,10 @@ * 53144: Completion/Unix/Command/_sysctl: support completion with the dot delimiter on linux + * Matthew Martin: 53174 + comments: + Completion/Base/Utility/_as_if: complete `as if' + a different command were being completed + 2024-11-05 Bart Schaefer * 53209 + comments + test: Src/params.c, Test/D04parameter.ztst: diff --git a/Completion/Base/Utility/_as_if b/Completion/Base/Utility/_as_if new file mode 100644 index 000000000..c961aaa88 --- /dev/null +++ b/Completion/Base/Utility/_as_if @@ -0,0 +1,10 @@ +#autoload +local words=("$words[@]") CURRENT=$CURRENT +local _comp_command1 _comp_command2 _comp_command + +words[1]=("$@") +(( CURRENT += $# - 1 )) + +_set_command + +_dispatch "$_comp_command" "$_comp_command1" "$_comp_command2" -default- diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 77627bacc..9b7f91148 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -4290,6 +4290,14 @@ arguments. The first describes the first argument as a be completed. The last description gives all other arguments the description `var(page number)' but does not offer completions. ) +findex(_as_if) +item(tt(_as_if) var(command) [var(arg) ... ])( +This function is useful when one command should be completed as if it were +another command with particular arguments. For example to complete tt(foo) as +if it were tt(bar --baz), use + +example(compdef '_as_if bar --baz' foo) +) findex(_cache_invalid) item(tt(_cache_invalid) var(cache_identifier))( This function returns status zero if the completions cache corresponding to -- cgit v1.2.3 From 6973a9ea843b1504e4c39ed560ee6e99d829ee8f Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 12 Nov 2024 12:34:39 +0900 Subject: 53137 + 53213: support creating intro.html --- ChangeLog | 5 +++++ Doc/Makefile.in | 13 ++++++++++--- Doc/intro.ms | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index bdb60cf33..22ee71a4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-11-12 Jun-ichi Takimoto + + * 53137 + 53213: Doc/Makefile.in, Doc/intro.ms, allow creating + intro.html + 2024-11-11 Eric Cook * 53144: Completion/Unix/Command/_sysctl: diff --git a/Doc/Makefile.in b/Doc/Makefile.in index fa2a336ad..a986aa1c5 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -121,9 +121,16 @@ zsh.pdf zsh_a4.pdf zsh_us.pdf: $(sdir)/zsh.texi intro.pdf intro.a4.pdf intro.us.pdf: $(sdir)/intro.ms if test $@ = intro.us.pdf || \ { test $@ = intro.pdf && test "$(PAPERSIZE)" = us; }; then \ - pdfroff -ms -P-pletter $(sdir)/intro.ms > $@; \ + pdfroff -mspdf --no-kill-null-pages -P-pletter --pdf-output=$@ $<; \ else \ - pdfroff -ms -P-pa4 $(sdir)/intro.ms > $@; \ + pdfroff -mspdf --no-kill-null-pages -P-pa4 --pdf-output=$@ $<; \ + fi + +intro.html: $(sdir)/intro.ms + if groff -ms -Thtml -P-jintro $< > tmp.html; then \ + mv tmp.html $@; \ + else \ + rm -f tmp.html; false; \ fi texi: $(sdir)/zsh.texi @@ -170,7 +177,7 @@ a4_ps: zsh_a4.ps zsh_a4.ps: zsh_a4.dvi $(DVIPS) -t a4 -o $@ zsh_a4.dvi -html: zsh_toc.html +html: zsh_toc.html intro.html .PHONY: html zsh_toc.html: $(sdir)/zsh.texi texi2html.conf diff --git a/Doc/intro.ms b/Doc/intro.ms index 4dd08f601..49f6cc07f 100644 --- a/Doc/intro.ms +++ b/Doc/intro.ms @@ -3,8 +3,32 @@ .if \n(.g \{\ .if "\*(.T"ascii" .ftr C R .if "\*(.T"latin1" .ftr C R +.if "\*(.T"html" .nr HTML 1 .nr De \n[.ss] .\} +.\" ----- macro defintions ----- +.\" Ds/De: start/end of example +.\" Sh: section header +.\" XXX: It seems we can't use the same definition for both pdf and html +.\" (at least with groff-12.3.0). +.\" +.\" for HTML output +.ie \n[HTML] \{\ +.de Ds +.DS I .5i +.ft C +.. +.de De +.DE +.ft R +.. +.de Sh +.NH +\\$1 +.. +.\} +.\" for other output (such as PDF) +.el \{\ .de Ds .DS I .5i .ft C @@ -21,12 +45,13 @@ .el .ss .. .de Sh -.SH -\\$1 -.XS -\\$1 -.XE +.NH +.XN \\$1 .. +.\} +.\" +.\" ----- Cover page ----- +.if !\n[HTML] \{\ .nr HM 4i .ce 99 .ps 18 @@ -50,6 +75,9 @@ bas@phys.uva.nl\fP .sv |1i .pn 1 .bp +.\} +.\" +.\" ----- main text ----- .TL An Introduction to the Z Shell .AU @@ -2712,6 +2740,7 @@ I (Bas de Bakker) would be happy to receive mail if anyone has any tricks or ideas to add to this document, or if there are some points that could be made clearer or covered more thoroughly. Please notify me of any errors in this document. +.if !\n[HTML] \{\ .if o \{\ .bp .sv 1i @@ -2719,3 +2748,4 @@ me of any errors in this document. .pn 1 .bp .PX +.\} -- cgit v1.2.3 From ec8fc4024f5be0a76f5604ddc18380c7053d2649 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 12 Nov 2024 19:48:56 -0800 Subject: Karel Balej: 53240, 53241: updated completions for mpc add, mpc insert --- ChangeLog | 5 +++++ Completion/Unix/Command/_mpc | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 22ee71a4e..e72294ce1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-11-12 Bart Schaefer + + * Karel Balej: 53240, 53241: Completion/Unix/Command/_mpc: + updated completions for mpc add, mpc insert + 2024-11-12 Jun-ichi Takimoto * 53137 + 53213: Doc/Makefile.in, Doc/intro.ms, allow creating diff --git a/Completion/Unix/Command/_mpc b/Completion/Unix/Command/_mpc index c3f93878c..e3383e56d 100644 --- a/Completion/Unix/Command/_mpc +++ b/Completion/Unix/Command/_mpc @@ -178,6 +178,16 @@ _mpc_helper_files() { fi } +(( $+functions[_mpc_helper_all_files] )) || +_mpc_helper_all_files() { + local ret=1 + if [[ $words[CURRENT] == [/~]* ]]; then + _files + ret=$? + fi + _mpc_helper_files || return $ret +} + (( $+functions[_mpc_helper_directories] )) || _mpc_helper_directories() { if [[ -n $MPD_MUSIC_DIR ]]; then @@ -204,7 +214,11 @@ _mpc_helper_outputs() { } _mpc_add() { - _mpc_helper_files + _mpc_helper_all_files +} + +_mpc_insert() { + _mpc_helper_all_files } _mpc_albumart() { -- cgit v1.2.3 From b70b241cc5ca88cc129ff9ba14f8af2e889b90e6 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 21 Nov 2024 12:26:51 +0900 Subject: 53238 (+53239 Mikael): support dnf5 some options etc for dnf4 are also updated --- ChangeLog | 5 + Completion/Redhat/Command/_dnf | 149 +++++++---- Completion/Redhat/Command/_dnf5 | 570 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 669 insertions(+), 55 deletions(-) create mode 100644 Completion/Redhat/Command/_dnf5 diff --git a/ChangeLog b/ChangeLog index e72294ce1..334430002 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-11-21 Jun-ichi Takimoto + + * 53238 (+53239 Mikael): Completion/Redhat/Command/_dnf, + Completion/Redhat/Command/_dnf5: support dnf5 + 2024-11-12 Bart Schaefer * Karel Balej: 53240, 53241: Completion/Unix/Command/_mpc: diff --git a/Completion/Redhat/Command/_dnf b/Completion/Redhat/Command/_dnf index a5edf8564..c41795adf 100644 --- a/Completion/Redhat/Command/_dnf +++ b/Completion/Redhat/Command/_dnf @@ -1,7 +1,11 @@ -#compdef dnf dnf-2 dnf-3 -# -# based on dnf-4.2.18 -# +#compdef dnf dnf-2 dnf-3 dnf4 +# based on dnf-4.21.1 + +# avoid 'dnf --version' since it's rather slow for dnf4 +if [[ $service = dnf && $commands[dnf]:P = */dnf5 ]]; then + _dnf5 "$@" && return 0 + return 1 +fi _dnf_helper() { # Get the pathname of the python executable from the 1st line of dnf-2/dnf-3. @@ -68,25 +72,23 @@ _dnf_packages_or_rpms() { fi } -_dnf_groups_caching_policy() { - # TODO: Are there any reliable ways to validate the cache? - local -a newer=( "$1"(Nmw-1) ) # rebuild if more than a week old - return $#newer -} - _dnf_groups() { - local package_groups update_policy expl - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy _dnf_groups_caching_policy - fi - if _cache_invalid dnf-groups || ! _retrieve_cache dnf-groups; then - # this can be very slow - package_groups=( ${${${(M)${(f)"$(_call_program package-groups \ - $service group list -v 2>/dev/null)"}:# *}#*\(}%\)*} ) - _store_cache dnf-groups package_groups - fi - _wanted package-groups expl 'package group' compadd "$@" -a package_groups + # optional option: -T (available|installed) + local selected line groups section=none + zparseopts -D -E - T:=selected + selected=$selected[2] + [[ -z $selected ]] && selected=all + # XXX hidden groups are not included. + # --installed and --available can't be specified with --hidden + for line in ${(f)"$(_call_program package-groups + $service group list --$selected -qCv 2>/dev/null)"}; do + # a line for each group is of the following form: + # ' description of the group (group-id)' + if [[ $line = \ ##(#b)(*)\(([-_[:alnum:]]#)\) ]]; then + groups+=( "${match[2]}:${match[1]}" ) + fi + done + _describe -t groups "$selected group" groups } _dnf_repoquery() { @@ -194,7 +196,7 @@ _dnf_repository_packages() { fi } -_dnf() { +_dnf4() { local cache_file="/var/cache/dnf/packages.db" local -a opts=( '(-6)-4[resolve to IPv4 addresses only]' @@ -226,7 +228,7 @@ _dnf() { '*'{-x+,--exclude=}'[exclude specified packages]: : _sequence _dnf_packages -T all' '--forcearch=[force the use of the specified arch]:arch: ' '(-)'{-h,--help}'[show the help message]' - '--installroot=[set install root]:directory:_files -/' + '--installroot=[set install root]:directory:_files -/ -g "/*"' '--newpackage[include newpackage relevant packages]' '--noautoremove[disable removal of dependencies that are no longer used]' '--nobest[do not limit transactions to best candidates]' @@ -289,18 +291,21 @@ _dnf_command() { if (( CURRENT == 1 )); then _describe -t dnf-commands 'dnf command' dnf_cmds else - local curcontext=$curcontext cur=$words[CURRENT] cmd tmp expl ret=1 + local cur=$words[CURRENT] cmd=$words[1] tmp expl ret=1 # Deal with aliases (not comprehensive) - case $words[1] in + case $cmd in check-updgrade) cmd=check-update;; distrosync|dsync) cmd=distro-sync;; dg) cmd=downgrade;; + dsync) cmd=distro-sync;; erase|rm) cmd=remove;; groups|grp) cmd=group;; hist) cmd=history;; in) cmd=install;; + if) cmd=info;; + ls) cmd=list;; mc) cmd=makecache;; - prov|whatprovides) cmd=provides;; + prov|whatprovides|wp) cmd=provides;; rei) cmd=reinstall;; repoinfo) cmd=repolist;; rq) cmd=repoquery;; @@ -308,9 +313,9 @@ _dnf_command() { sh) cmd=shell;; update|up) cmd=upgrade;; update-minimal|up-min) cmd=upgrade-minimal;; - *) cmd="${${dnf_cmds[(r)$words[1]:*]%%:*}}";; + upif) cmd=updateinfo;; esac - (( $#cmd )) && curcontext="${curcontext%:*:*}:dnf-${cmd}:" + local curcontext="${curcontext%:*:*}:dnf-${cmd}:" case $cmd in alias) @@ -337,11 +342,9 @@ _dnf_command() { _describe -t options 'option' tmp && ret=0 ;; check-update) - if [[ $cur = -* ]]; then - _wanted options expl 'option' compadd - --changelogs && ret=0 - else - _dnf_packages -T installed && ret=0 - fi + _arguments : \ + '--changelogs[also print changelog delta of packages]' \ + '*: :_dnf_packages -T installed' && ret=0 ;; clean) tmp=( @@ -368,23 +371,38 @@ _dnf_command() { "mark:mark a group for installation or removal" ) _describe -t subcommands 'subcommand' tmp && ret=0 - elif (( CURRENT == 3 )) && [[ $cur = -* ]]; then - if [[ $words[2] == install ]]; then - _wanted options expl 'option' compadd - --with-optional && ret=0 - elif [[ $words[2] == list ]]; then - tmp=( - '--available:show only available groups' - '--installed:show only installed groups' - '--hidden:show also hidden groups' - '--ids:show also ID of groups' - ) - _describe -t options 'option' tmp && ret=0 - fi - elif (( CURRENT == 3 )) && [[ $words[2] == mark ]]; then - _wanted subcommands expl 'subcommand' \ - compadd - install remove && ret=0 else - _dnf_groups && ret=0 + case $words[2] in + summary) + _arguments : '--hidden' '2: :_dnf_groups' && ret=0 + ;; + info) + _dnf_groups && ret=0 + ;; + install) + _arguments : '--with-optional[also include optional packages]' \ + '*: :_dnf_groups -T available' && ret=0 + ;; + list) + _arguments : \ + '(--installed)--available[show only available groups]' \ + '(--available)--installed[show only installed groups]' \ + '--hidden[show also hidden groups]' \ + {--ids,-v}'[show also ID of groups]' \ + '*: :_dnf_groups' && ret=0 + ;; + remove|upgrade) + _dnf_groups -T installed && ret=0 + ;; + mark) + if (( CURRENT == 3 )); then + _wanted subcommands expl 'subcommand' \ + compadd - install remove && ret=0 + else + _dnf_groups && ret=0 + fi + ;; + esac fi ;; help) @@ -399,13 +417,32 @@ _dnf_command() { "list:list transactions" "info:describe the given transactions" "redo:repeat the specified transaction" + "replay:replay transaction stored in the specified file" "rollback:undo all since the given transaction" + "store:store the specified transaction in file" "undo:undo transactions" "userinstalled:list all packages installed by users" ) _describe -t subcommands 'subcommand' tmp && ret=0 - elif [[ $words[2] != userinstalled ]]; then - _message 'transaction' && ret=0 + else + case $words[2] in + list) + _arguments : '--reverse[output history in reverse order]' \ + '*:transaction ID or ID..ID: ' && ret=0 ;; + info) + _message 'transaction ID or ID..ID' && ret=0 ;; + redo|rollback|undo) + _message 'transaction or package' && ret=0 ;; + replay) + _arguments : \ + "--ignore-installed[don't check for installed packages being in the same state as recorded in transaction]" \ + "--ignore-extras[don't check for extra packages pulled into the transaction on the target system]" \ + '--skip-unavailable[skip packages that are in transaction but not in target system]' \ + '2:transaction file:_files' && ret=0 ;; + store) + _arguments : {-o+,--output=}'[store in specified file]: :_files' \ + '2:transaction: ' && ret=0 ;; + esac fi ;; info|list) @@ -413,7 +450,7 @@ _dnf_command() { if [[ $cur = -* ]]; then tmp=( --all --available --installed --extras --obsoletes --upgrades --autoremove --recent ) - _wanted options expl 'option' compadd -a tmp + _wanted options expl 'option' compadd -a tmp && ret=0 else _dnf_packages -T all && ret=0 fi @@ -449,6 +486,7 @@ _dnf_command() { tmp=( 'install:install a module profile including its packages' 'update:update packages associated with an active module stream' + 'switch-to:switch to a module stream and change versions of installed packages' 'remove:remove installed module profiles and their packages' 'enable:enable a module stream' 'disable:disable a module with all its streams' @@ -502,7 +540,7 @@ _dnf_command() { _dnf_repoquery && ret=0 ;; repository-packages) - _dnf_repository_packages + _dnf_repository_packages && ret=0 ;; search) if [[ $cur = -* ]]; then @@ -531,6 +569,7 @@ _dnf_command() { '--list[display list of advisories]' '--info[display detailed information of advisories]' + '(availability)' + '-all[include advisories about any versions of installed packages]' '--available[limit to advisories about newer versions of installed packages]' '--installed[limit to advisories about equal or older versions of installed packages]' '--updates[limit to advisories about newer and available versions of installed packages]' @@ -548,4 +587,4 @@ _dnf_command() { fi } -_dnf "$@" +_dnf4 "$@" diff --git a/Completion/Redhat/Command/_dnf5 b/Completion/Redhat/Command/_dnf5 new file mode 100644 index 000000000..e194dd5a7 --- /dev/null +++ b/Completion/Redhat/Command/_dnf5 @@ -0,0 +1,570 @@ +#compdef dnf5 +# based on dnf-5.2.6.2 + +# utility functions + +_dnf5_helper() { + _call_program specs $service "${(q-)@}" "${(q-)PREFIX}\*" \ + -qC --assumeno --nogpgcheck 2>/dev/null command' '*:: :->cmd_args' && ret=0 + + case $state in + command) _dnf5_commands && ret=0 ;; + cmd_args) _dnf5_subcmds_opts && ret=0 ;; + esac + return ret +} + +_dnf5 "$@" -- cgit v1.2.3 From 4ca2f3fd7d800d16c8691be4d459daefd236bdf2 Mon Sep 17 00:00:00 2001 From: Lukáš Zaoral Date: Fri, 22 Nov 2024 14:21:06 -0800 Subject: Remove stray invisible byte from 47731 entry --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 334430002..e8aa645fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3725,7 +3725,7 @@ x2024-02-19 Jun-ichi Takimoto * 47731 (+unposted): Functions/Misc/run-help-btrfs, Doc/Zsh/contrib.yo: add run-help assistant for btrfs command. - (based on the patch by Samir Benmendil in 43947⁩) + (based on the patch by Samir Benmendil in 43947) * Samir Benmendil: 43946: Functions/Misc/run-help-sudo: call run-help (instead of man) for the command given to sudo -- cgit v1.2.3 From 638e09af6e032e63d3a3f7e4ac4ffaf5bcf446d0 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 23 Nov 2024 22:29:19 +0100 Subject: 53244: rename user in test case to reduce likelihood of failure due to user existing --- ChangeLog | 5 +++++ Test/Y01completion.ztst | 16 ++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8aa645fa..0b5c03ce6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-11-23 Oliver Kiddle + + * 53244: Test/Y01completion.ztst: rename user in test case to + reduce likelihood of failure due to user existing + 2024-11-21 Jun-ichi Takimoto * 53238 (+53239 Mikael): Completion/Redhat/Command/_dnf, diff --git a/Test/Y01completion.ztst b/Test/Y01completion.ztst index fc18b19a4..769b8c9e4 100644 --- a/Test/Y01completion.ztst +++ b/Test/Y01completion.ztst @@ -112,16 +112,16 @@ F:regression test workers/51641 >NO:{file2} comptesteval $'zstyle -d \'*\' glob' - comptesteval '_users () { compadd user1 user2 }' + comptesteval '_users () { compadd zuser1 zuser2 }' comptest $': ~\t\t\t\t\t' 0:tilde ->line: {: ~user}{} ->line: {: ~user}{} ->NO:{user1} ->NO:{user2} ->line: {: ~user1}{} ->line: {: ~user2}{} ->line: {: ~user1}{} +>line: {: ~zuser}{} +>line: {: ~zuser}{} +>NO:{zuser1} +>NO:{zuser2} +>line: {: ~zuser1}{} +>line: {: ~zuser2}{} +>line: {: ~zuser1}{} comptesteval 'zsh_directory_name() { compadd "$expl[@]" -- name/1 name2 }' comptest $': ~[\t\t\t\t' -- cgit v1.2.3 From 3c0f932300adbc099658375137cffcaf10678cc1 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 23 Nov 2024 22:31:44 +0100 Subject: 53243: fix use of vi-fetch-history with a range --- ChangeLog | 3 +++ Src/Zle/zle_hist.c | 21 +++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b5c03ce6..31793f1a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-11-23 Oliver Kiddle + * 53243: Src/Zle/zle_hist.c: fix use of vi-fetch-history + with a range + * 53244: Test/Y01completion.ztst: rename user in test case to reduce likelihood of failure due to user existing diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c index 0fdad70d9..53c722621 100644 --- a/Src/Zle/zle_hist.c +++ b/Src/Zle/zle_hist.c @@ -1758,7 +1758,8 @@ acceptandinfernexthistory(char **args) { Histent he; - if (!(he = infernexthist(hist_ring, args))) + if (virangeflag || !(zlereadflags & ZLRF_HISTORY) || + !(he = infernexthist(hist_ring, args))) return 1; zpushnode(bufstack, ztrdup(he->node.nam)); done = 1; @@ -1770,8 +1771,11 @@ acceptandinfernexthistory(char **args) int infernexthistory(char **args) { - Histent he = quietgethist(histline); + Histent he; + if (virangeflag || !(zlereadflags & ZLRF_HISTORY)) + return 1; + he = quietgethist(histline); if (!he || !(he = infernexthist(he, args))) return 1; zle_setline(he); @@ -1784,12 +1788,14 @@ vifetchhistory(UNUSED(char **args)) { if (zmult < 0) return 1; - if (histline == curhist) { + if (histline == curhist || virangeflag || !(zlereadflags & ZLRF_HISTORY)) { if (!(zmod.flags & MOD_MULT)) { zlecs = zlell; zlecs = findbol(); return 0; } + if (virangeflag || !(zlereadflags & ZLRF_HISTORY)) + return 1; } if (!zle_goto_hist((zmod.flags & MOD_MULT) ? zmult : curhist, 0, 0) && isset(HISTBEEP)) { @@ -1933,6 +1939,9 @@ getvisrchstr(void) int vihistorysearchforward(char **args) { + if (virangeflag || !(zlereadflags & ZLRF_HISTORY)) + return 1; + if (*args) { int ose = visrchsense, ret; char *ost = visrchstr; @@ -1954,6 +1963,9 @@ vihistorysearchforward(char **args) int vihistorysearchbackward(char **args) { + if (virangeflag || !(zlereadflags & ZLRF_HISTORY)) + return 1; + if (*args) { int ose = visrchsense, ret; char *ost = visrchstr; @@ -1979,8 +1991,9 @@ virepeatsearch(UNUSED(char **args)) int n = zmult; char *zt; - if (!visrchstr) + if (!visrchstr || virangeflag || !(zlereadflags & ZLRF_HISTORY)) return 1; + if (zmult < 0) { n = -n; visrchsense = -visrchsense; -- cgit v1.2.3 From d7866eff3bb2dfa6f7adb88d9d0662d21c018246 Mon Sep 17 00:00:00 2001 From: Ryan Rotter Date: Mon, 4 Nov 2024 12:29:41 -0500 Subject: github #124: _dpkg: remove --largemem, --smallmem options These options were deleted in 2009: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468106 --- ChangeLog | 3 +++ Completion/Debian/Command/_dpkg | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31793f1a5..89124bdf5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-11-23 Oliver Kiddle + * github #124: Ryan Rotter: Completion/Debian/Command/_dpkg: + remove defunct --largemem, --smallmem options + * 53243: Src/Zle/zle_hist.c: fix use of vi-fetch-history with a range diff --git a/Completion/Debian/Command/_dpkg b/Completion/Debian/Command/_dpkg index 48ea2db97..617644993 100644 --- a/Completion/Debian/Command/_dpkg +++ b/Completion/Debian/Command/_dpkg @@ -64,8 +64,6 @@ _dpkg_options=( '(--skip-same-version -E)'{--skip-same-version,-E}'[skip packages with same version as installed]' '(--refuse-downgrade -G)'{--refuse-downgrade,-G}'[skip packages with earlier version than installed]' '(--auto-deconfigure -B)'{--auto-deconfigure,-B}'[install can break other packages]' - '--largemem[optimize for >4Mb RAM]' - '--smallmem[optimize for <4Mb RAM]' '--no-act[show potential actions but do not follow through]' '-D+[debug options]:debug options:(h 1 2 3)' '--debug=[debug options]:debug options:(help 1 2 3)' -- cgit v1.2.3 From 9269deb528235f12da56a7f35956d7bb1b1c7133 Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Mon, 14 Oct 2024 10:06:55 +0300 Subject: github #123: Make okular's completion support *.epub files. --- ChangeLog | 3 +++ Completion/X/Command/_okular | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 89124bdf5..543876167 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-11-23 Oliver Kiddle + * github #123: Shlomi Fish: Completion/X/Command/_okular: + Make okular's completion support *.epub files. + * github #124: Ryan Rotter: Completion/Debian/Command/_dpkg: remove defunct --largemem, --smallmem options diff --git a/Completion/X/Command/_okular b/Completion/X/Command/_okular index f08f81c6e..9d5a3d7ff 100644 --- a/Completion/X/Command/_okular +++ b/Completion/X/Command/_okular @@ -1,7 +1,7 @@ #compdef okular local extns -extns="(pdf|ps|eps|dvi)(|.gz|.bz2)|djvu|tif|tiff|chm|cbr|cbz" +extns="(pdf|ps|eps|dvi)(|.gz|.bz2)|djvu|tif|tiff|chm|cbr|cbz|epub" _arguments \ '(-p --page)'{-p,--page}'[page of the document to be shown]:page: ' \ -- cgit v1.2.3 From cdb457841ce4b61993a794c2eeacda3a56493723 Mon Sep 17 00:00:00 2001 From: "Wu, Zhenyu" Date: Mon, 23 Sep 2024 13:53:55 +0800 Subject: github #122: Add c17, iso9899:2017, c18, iso9899:2018, gnu17, gnu18, c++20, gnu++20, c++23, gnu++23 to gcc completion --- ChangeLog | 3 +++ Completion/Unix/Command/_gcc | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 543876167..b453b1408 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-11-23 Oliver Kiddle + * github #122: Wu, Zhenyu: Completion/Unix/Command/_gcc: Add + newer C and C++ language standards to gcc completion + * github #123: Shlomi Fish: Completion/X/Command/_okular: Make okular's completion support *.epub files. diff --git a/Completion/Unix/Command/_gcc b/Completion/Unix/Command/_gcc index 8690c5599..b7c9ba08a 100644 --- a/Completion/Unix/Command/_gcc +++ b/Completion/Unix/Command/_gcc @@ -2111,7 +2111,7 @@ args+=( '-s[remove all symbol table and relocation information from the executable]' '-static-libgcc[force static libgcc]' '-static[on systems that support dynamic linking, this prevents linking with the shared libraries]' - {'-std=-','--std='}'[assume that the input sources are for specified standard]:standard:(c90 c89 iso9899\:1990 iso9899\:199409 c99 iso9899\:1999 c11 iso9899\:2011 gnu90 gnu89 gnu99 gnu11 c++98 c++03 gnu++98 gnu++03 c++11 gnu++11 c++1y gnu++1y c++14 gnu++14 c++1z gnu++1z c++17 iso9899\:2017 gnu++17 c++2a gnu++2a)' + {'-std=-','--std='}'[assume that the input sources are for specified standard]:standard:(c90 c89 iso9899\:1990 iso9899\:199409 c99 iso9899\:1999 c11 iso9899\:2011 c17 iso9899\:2017 c18 iso9899\:2018 gnu90 gnu89 gnu99 gnu11 gnu17 gnu18 c++98 c++03 gnu++98 gnu++03 c++11 gnu++11 c++1y gnu++1y c++14 gnu++14 c++1z gnu++1z c++17 iso9899\:2017 gnu++17 c++2a gnu++2a c++20 gnu++20 c++23 gnu++23)' '-symbolic[bind references to global symbols when building a shared object]' '--sysroot=-[use as the root directory for headers and libraries]:directory:_files -/' '--target-help[display target specific command line options]' -- cgit v1.2.3 From 86d5f24a3d28541f242eb3807379301ea976de87 Mon Sep 17 00:00:00 2001 From: Clinton Bunch Date: Fri, 8 Nov 2024 19:08:48 -0600 Subject: 53228: Remove references to Patches "Archive" from FAQ --- ChangeLog | 3 +++ Etc/FAQ.yo | 13 ------------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index b453b1408..d62b6a49a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-11-23 Oliver Kiddle + * Clinton Bunch: 53228: Etc/FAQ.yo: Remove references to + Patches "Archive" from FAQ + * github #122: Wu, Zhenyu: Completion/Unix/Command/_gcc: Add newer C and C++ language standards to gcc completion diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 2c83fe7fa..73442416c 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -338,19 +338,6 @@ label(16) Please email email(zsh-workers@zsh.org) if you have information about other ports. - Starting from mid-October 1997, there is an archive of patches sent - to the maintainers' mailing list. Note that these may not all be - added to the shell, and some may already have been; you simply have - to search for something you might want which is not in the version - you have. Also, there may be some prerequisites earlier in the - archive. It can be found on the zsh WWW pages (as described in - link(1.1)(11)) at: - - description( - mydit() url(https://zsh.sourceforge.io/Patches/) -(https://zsh.sourceforge.io/Patches/) - ) - sect(I don't have root access: how do I make zsh my login shell?) Unfortunately, on many machines you can't use mytt(chsh) to change your -- cgit v1.2.3 From d905c7a0d7d8fb789e7f508eb4610ddfa280cf54 Mon Sep 17 00:00:00 2001 From: dana Date: Mon, 16 Dec 2024 10:37:55 -0600 Subject: 52108: docs: document benefits of `_normal -p` note: commit was severely delayed --- ChangeLog | 4 ++++ Doc/Zsh/compsys.yo | 12 +++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index d62b6a49a..8d8fb713d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-12-16 dana + + * 52108: Doc/Zsh/compsys.yo: document benefits of `_normal -p` + 2024-11-23 Oliver Kiddle * Clinton Bunch: 53228: Etc/FAQ.yo: Remove references to diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 9b7f91148..7ae67773b 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -4397,8 +4397,10 @@ the functions for the fields if they are called. findex(_command_names) item(tt(_command_names) [ tt(-e) | tt(-) ])( This function completes words that are valid at command position: names of -aliases, builtins, hashed commands, functions, and so on. With the tt(-e) -flag, only hashed commands are completed. The tt(-) flag is ignored. +aliases, builtins, hashed commands, functions, and so on. If the tt(-e) +flag is given, or if the list of precommands contains a non-builtin command +(e.g. because tt(_normal -p) has been used previously), only hashed commands +are completed. The tt(-) flag is ignored. ) findex(_comp_locale) item(tt(_comp_locale))( @@ -4784,7 +4786,11 @@ functions) regardless of prior precommands (e.g. `tt(zsh -c)'). ) item(tt(-p) var(precommand))( Append var(precommand) to the list of precommands. This option should be -used in nearly all cases in which tt(-P) is not applicable. +used in nearly all cases in which tt(-P) is not applicable. An advantage +of using this option is that it can automatically signal to +tt(_command_names) that subsequent completion should be limited to hashed +commands, which is usually the desired behaviour following commands like +tt(chroot) and tt(nohup). ) enditem() -- cgit v1.2.3 From 7798fd88ac42f55980fb9832f2f7e379392fe6aa Mon Sep 17 00:00:00 2001 From: dana Date: Mon, 16 Dec 2024 10:52:22 -0600 Subject: 53251: _man: fix page completion on macOS, update fall-back paths, etc. - fix broken page completion on macOS and FreeBSD (regression caused by workers/50278) - update fall-back paths to include /usr/local/share/man (fixes issues like workers/53249 for systems without `manpath` or equivalent) - fold macOS completion into FreeBSD's, as macOS 13+ uses it now with little modification - add -K option for FreeBSD and -h option for mandoc/NetBSD, complete pre-processor sequences, complete section lists with commas for man-db - exclude HTML pages for FreeBSD-likes --- ChangeLog | 3 + Completion/Unix/Command/_man | 131 ++++++++++++++++++++++++++----------------- 2 files changed, 82 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8d8fb713d..a58002d71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-12-16 dana + * 53251: Completion/Unix/Command/_man: fix page completion on + macOS, update fall-back paths, etc. + * 52108: Doc/Zsh/compsys.yo: document benefits of `_normal -p` 2024-11-23 Oliver Kiddle diff --git a/Completion/Unix/Command/_man b/Completion/Unix/Command/_man index 190811e41..2869e99e2 100644 --- a/Completion/Unix/Command/_man +++ b/Completion/Unix/Command/_man @@ -6,12 +6,16 @@ # - We assume that Linux distributions are using either man-db or mandoc # - @todo Would be nice to support completing the initial operand as a section # name (on non-Solaris systems) +# - @todo We don't support completing the man-db syntaxes .
+# (`ls.1`) and (
) (`ls(1)`) # - @todo We don't support the man-db feature of 'sub-pages' — that is, treating # pairs of operands like `git diff` as `git-diff` +# - @todo We don't really handle architecture-specific man pages at all # - @todo Option exclusivity isn't super accurate # - @todo Solaris man accepts a single hyphen as the first option to disable # paging (like AIX's -c); we don't support that -# - @todo Linux apropos/whatis take options; we don't complete them yet +# - @todo FreeBSD-like and Linux apropos/whatis take options; we don't complete +# them yet _man() { local dirs expl mrd awk variant noinsert @@ -21,8 +25,13 @@ _man() { if [[ $service == man ]]; then # We'll treat all mandoc-based systems (Alpine, various Illumos distros, - # etc.) as OpenBSD - _pick_variant -r variant openbsd='-S subsection' $OSTYPE --- + # etc.) as OpenBSD, and all FreeBSD-based man implementations (including + # Apple's) as FreeBSD + _pick_variant -r variant \ + freebsd='-S mansect' \ + openbsd='-S subsection' \ + $OSTYPE \ + --- modes=( -f -K -k -l -R -w -W @@ -36,49 +45,44 @@ _man() { --where --where-cat ) - [[ $variant == darwin* ]] && modes+=( -t ) args=( "(${(j< >)modes})"{-f,--whatis}'[display short description (like whatis)]' "(${(j< >)modes})"{-k,--apropos}'[search for keyword (like apropos)]' '(-M --manpath)'{-M+,--manpath=}'[specify manual search path]:manual search path:_sequence -s\: _directories' ) - if [[ $variant == (darwin|dragonfly|freebsd|linux)* ]]; then + if [[ $variant == (freebsd|linux)* ]]; then args+=( '(-a -S -s --all --sections)'{-a,--all}'[display all matching pages]' '(-P --pager)'{-P+,--pager=}'[specify output pager]:pager:_path_commands' - # @todo Could enumerate these - '(-p --preprocessor)'{-p+,--preprocessor=}'[specify roff preprocessor sequence]:preprocessor sequence' + '(-p --preprocessor)'{-p+,--preprocessor=}'[specify roff preprocessor sequence]: :_man_preprocs' ) else args+=( '(-s)-a[display all matching pages]' ) fi [[ $variant == (aix|solaris)* ]] || args+=( - '(-C --config-file)'{-C+,--config-file=}'[specify configuration file]:configuration file:_files' "(${(j< >)modes})"{-w,--path,--where}'[display file locations]' ) + [[ $variant == (aix|freebsd|solaris)* ]] || args+=( + '(-C --config-file)'{-C+,--config-file=}'[specify configuration file]:configuration file:_files' + ) [[ $variant == (aix|netbsd|openbsd)* ]] || args+=( # @todo FreeBSD allows this to be given multiple times '(-d --debug)'{-d,--debug}'[display debugging information]' ) - [[ $variant == (darwin|dragonfly|freebsd|linux|solaris|aix)* ]] && args+=( + [[ $variant == (freebsd|linux|solaris|aix)* ]] && args+=( '(-7 -H -t --ascii --html --troff)'{-t,--troff}'[format man page using troff]' ) - [[ $variant == (darwin|linux)* ]] && args+=( - "(${(j< >)modes})"{-K,--global-apropos}'[search for keyword in all pages]' - '(-m --systems)'{-m+,--systems=}'[search manual of specified system]:operating system' - ) - [[ $variant == (darwin|dragonfly|freebsd)* ]] && args+=( + [[ $variant == (freebsd)* ]] && args+=( '(: -)-h[display help information]' - '(-a)-S+[specify manual sections to search]: :->sects' - ) - [[ $variant == (dragonfly|freebsd)* ]] && args+=( # @todo Could enumerate these '-m[search manual of specified architecture]:architecture' '-o[use non-localized man pages]' + '(-a)-S+[specify manual sections to search]: :->sects' ) [[ $variant == (netbsd|openbsd)* ]] && args+=( '-c[disable paging]' + '-h[display only synopsis]' '-m[augment manual search path]:manual search path:_sequence -s\: _directories' '(-a)-s+[specify manual section to search]: :->sects' ) @@ -92,9 +96,11 @@ _man() { '(-H --html)'{-H-,--html=-}'[produce HTML output for specified browser]::Web browser:_path_commands' '(-i -I --ignore-case --match-case)'{-i,--ignore-case}'[search case-insensitively]' '(-i -I --ignore-case --match-case)'{-I,--match-case}'[search case-sensitively]' + "(${(j< >)modes})"{-K,--global-apropos}'[search for keyword in all pages]' '(-L --locale)'{-L+,--locale=}'[specify locale]:locale:_locales' "(${(j< >)modes})"{-l+,--local-file=}'[format and display specified file]:*:::manual file:_files' "!(${(j< >)modes})"{--location,--location-cat} + '(-m --systems)'{-m+,--systems=}'[search manual of specified system]:operating system' '--names-only[match only page names (with --regex or --wildcard)]' '(--nh --no-hyphenation)'{--nh,--no-hyphenation}'[disable hyphenation]' '(--nj --no-justification)'{--nj,--no-justification}'[disable justification]' @@ -117,21 +123,9 @@ _man() { # @todo Post-process how? '(-t --troff -Z --ditroff)'{-Z,--ditroff}'[post-process output for chosen device]' ) - [[ $variant == darwin* ]] && args+=( - # We use _files here because browsers are usually in /Applications, which - # typically isn't in PATH - '-B+[specify browser to use for HTML files]:Web browser:_files' - '-c[reformat source man page]' - # @todo -d should be exclusive with this above - '(-d)-D[display man page along with debugging information]' - '(-D -F --preformat)'{-F,--preformat}'[format man page only (do not display)]' - '-H+[specify command to render HTML as text]:HTML pager:_path_commands' - # --help and --version are undocumented but functional - '(: -)--help[display help information]' - # -s is also undocumented; it's provided for compatibility with Solaris - '!(-S)-s+: :->sects' - '(: -)'{-v,--version}'[display version information]' - "(${(j< >)modes})-W[display file locations, one per line, with no other information]" + # Currently macOS and Dragonfly don't have this, so check $OSTYPE too + [[ $variant == freebsd* && $OSTYPE == freebsd* ]] && args+=( + "(${(j< >)modes})-K+[perform full text search with specified regexp]:regexp" ) [[ $variant == netbsd* ]] && args+=( '-h[display only synopsis lines]' @@ -157,12 +151,9 @@ _man() { '-r[search remotely]' ) - # Strip (most) long options from non-Linux platforms - if [[ $variant == darwin* ]]; then - args=( ${(M)args:#((#s)|*\))(\*|)(-[^-]|--(help|path|pref|vers))*} ) - elif [[ $variant != linux* ]]; then - args=( ${(M)args:#((#s)|*\))(\*|)-[^-]*} ) - fi + # Strip long options from non-Linux platforms + [[ $variant == linux* ]] || + args=( ${(M)args:#((#s)|*\))(\*|)-[^-]*} ) fi _arguments -s -S : $args '*::: :->man' && return 0 @@ -179,8 +170,12 @@ _man() { fi if [[ -z $_manpath_cache[$MANPATH] ]]; then local mp - mp=( ${(s.:.)$({ command man -w || manpath } 2>/dev/null)} ) - [[ "$mp" == *:* ]] && mp=( ${(s.:.)mp} ) + if [[ $variant == netbsd* ]]; then + mp=( ${(s.:.)$(command man -p 2>/dev/null)} ) + elif [[ $variant != freebsd* ]]; then + mp=( ${(s.:.)$(command man -w 2>/dev/null)} ) + fi + (( $#mp )) || mp=( ${(s.:.)$(manpath 2>/dev/null)} ) if (( $#mp )); then _manpath_cache[$MANPATH]=${(j.:.)mp} elif (( $#manpath )); then @@ -199,8 +194,11 @@ _man() { _manpath+=( /usr/share/man ) fi - (( $#_manpath )) || - _manpath=( /usr/man(-/) /(opt|usr)/(pkg|dt|share|X11R6|local)/(cat|)man(-/) ) + (( $#_manpath )) || _manpath=( + /usr/man(-/) + /(opt|usr)/(pkg|dt|share|X11R6|local)/(cat|)man(-/) + /(opt|usr)/local/share/(cat|)man(-/) + ) # `sman' is the SGML manual directory for Solaris 7. # 1M is system administrator commands on SVR4 @@ -221,28 +219,36 @@ _man() { [[ $service != man ]] || [[ $state == sects ]] || (( $+opt_args[-a] )) then sect='*' + # man-db: multiple sections separated by colons or commas elif - [[ $variant == (darwin|linux)* ]] && + [[ $variant == linux* ]] && [[ -n ${opt_args[(i)-S|-s|--sections]} ]] then noinsert=1 sect=${opt_args[${opt_args[(i)-S|-s|--sections]}]//[:,]/|} + # mandoc, NetBSD: single section only elif - [[ $variant == (netbsd|openbsd|solaris)* ]] && (( $+opt_args[-s] )) + [[ $variant == (netbsd|openbsd)* ]] && (( $+opt_args[-s] )) then noinsert=1 - sect=${opt_args[-s]//,/|} - elif [[ $variant == (dragonfly|freebsd)* ]] && (( $+opt_args[-S] )); then + sect=$opt_args[-s] + # FreeBSD: multiple sections separated by colons + elif [[ $variant == freebsd* ]] && (( $+opt_args[-S] )); then noinsert=1 sect=${opt_args[-S]//:/|} + # Solaris: multiple sections separated by commas + elif + [[ $variant == solaris* ]] && (( $+opt_args[-s] )) + then + noinsert=1 + sect=${opt_args[-s]//,/|} # It's only a small help, but, per man-db, we can avoid treating an initial # operand like `8139too` as a section name by ensuring that only the first # character is a digit. This doesn't do much for stuff like `2to3`, but we can # at least special-case a few common patterns for now elif (( CURRENT > 1 )) && - [[ $variant != solaris* ]] && - [[ ${${(Q)words[1]}##(2to3|7z)*} == ([0-9](|[^0-9[:punct:]]*)|[lnopx]) ]] + [[ ${${(Q)words[1]}##(2to3|7z)*} == ([0-9](|[^0-9[:punct:]]*)|[hlnopx]) ]] then noinsert=1 sect=$words[1] @@ -253,7 +259,7 @@ _man() { # Colons may have been escaped sect=${(Q)sect} - if [[ $sect = (<->*|[lnopx]) || $sect = *\|* ]]; then + if [[ $sect = (<->*|[hlnopx]) || $sect = *\|* ]]; then sects=( ${(s.|.)sect} ) # Most man implementations support partial matching of a page's @@ -288,7 +294,11 @@ _man() { # Solaris 11 and on have a man-index directory that doesn't contain manpages dirs=( ${dirs:#*/man-index/} ) - sects=( ${(o)${${dirs##*(man|cat)}%.*}%/} ) + sects=( ${(ou)${${dirs##*(man|cat)}%.*}%/} ) + + # HTML man pages don't work on FreeBSD-likes. Not sure what they do work on + [[ $variant == freebsd* ]] && + sects=( ${sects:#h} ) # If we've got this far, we can build our look-up table for descriptions of # the more common sections. Unless otherwise labelled, the more specific ones @@ -322,6 +332,7 @@ _man() { 8 'maintenance commands and procedures' 9 'kernel features' 9lua 'Lua kernel bindings' # NetBSD + h 'HTML documentation' # Supported by which implementations? l 'local documentation' # AIX, etc. — TCL on some systems? n 'new documentation' # AIX, etc. o 'old documentation' # AIX, etc. @@ -376,9 +387,13 @@ _man() { done specs=( ${specs%:} ) - if [[ $variant == (darwin|dragonfly|freebsd|linux)* ]]; then + + if + [[ $variant == freebsd* ]] || + [[ $variant == linux* && $PREFIX$SUFFIX != *,* ]] + then _sequence -s : _describe -t sections 'manual section' specs - elif [[ $variant == solaris* ]]; then + elif [[ $variant == (linux|solaris)* ]]; then _sequence -s , _describe -t sections 'manual section' specs else _describe -t sections 'manual section' specs @@ -424,6 +439,7 @@ _man() { fi } +(( $+functions[_man_pages] )) || _man_pages() { local pages sopt tmp @@ -470,4 +486,15 @@ _man_pages() { esac } +(( $+functions[_man_preprocs] )) || +_man_preprocs() { + _values -S '' preprocessor \ + 'e[eqn]' \ + 'g[grap]' \ + 'p[pic]' \ + 'r[refer]' \ + 't[tbl]' \ + 'v[vgrind]' +} + _man "$@" -- cgit v1.2.3 From 6bb792dba89016c250bc9f2581c9c267dd322254 Mon Sep 17 00:00:00 2001 From: dana Date: Thu, 26 Dec 2024 09:36:45 -0600 Subject: 53257: use monotonic clock where appropriate update the following features to use the monotonic clock for calculating time deltas and intervals: * MAILCHECK parameter * PERIOD parameter * SECONDS parameter * %(nS.t.f) prompt-expansion sequence * time built-in's elapsed time and cpu % values * zsh/zftp ZFTP_TMOUT parameter * zsh/zprof timings also use CLOCK_MONOTONIC_RAW instead of CLOCK_MONOTONIC on macOS --- ChangeLog | 9 ++++++ Doc/Zsh/params.yo | 18 ++++++++---- Doc/Zsh/prompt.yo | 3 +- Src/Modules/zftp.c | 4 +-- Src/Modules/zprof.c | 19 ++++++------ Src/compat.c | 12 ++++++++ Src/exec.c | 21 +++++++------- Src/hist.c | 6 ++-- Src/init.c | 7 ++--- Src/jobs.c | 78 ++++++++++++++++++++++++++++++++++---------------- Src/params.c | 38 ++++++++++++------------ Src/prompt.c | 2 +- Src/signals.c | 3 +- Src/utils.c | 25 ++++++++++++---- Src/zsh.h | 4 +-- Test/A08time.ztst | 39 +++++++++++++++++++++++-- Test/D01prompt.ztst | 7 +++++ Test/D04parameter.ztst | 22 ++++++++++++++ 18 files changed, 225 insertions(+), 92 deletions(-) diff --git a/ChangeLog b/ChangeLog index a58002d71..989cc0aa3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2024-12-26 dana + + * 53257: Doc/Zsh/params.yo, Doc/Zsh/prompt.yo, + Src/Modules/zftp.c, Src/Modules/zprof.c, Src/compat.c, + Src/exec.c, Src/hist.c, Src/init.c, Src/jobs.c, Src/params.c, + Src/prompt.c, Src/signals.c, Src/utils.c, Src/zsh.h, + Test/A08time.ztst, Test/D01prompt.ztst, Test/D04parameter.ztst: + use monotonic clock where appropriate + 2024-12-16 dana * 53251: Completion/Unix/Command/_man: fix page completion on diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 02ce796a9..69298855f 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -926,7 +926,9 @@ referenced or seeded in the parent shell in between subshell invocations. ) vindex(SECONDS) item(tt(SECONDS) )( -The number of seconds since shell invocation. If this parameter +The number of seconds since shell invocation. On most platforms, this +is a monotonic value, so it is not affected by NTP time jumps or other +clock changes (though it may be affected by slewing). If this parameter is assigned a value, then the value returned upon reference will be the value that was assigned plus the number of seconds since the assignment. @@ -936,8 +938,10 @@ be changed using the tt(typeset) command. The type may be changed only to one of the floating point types or back to integer. For example, `tt(typeset -F SECONDS)' causes the value to be reported as a floating point number. The -value is available to microsecond accuracy, although the shell may -show more or fewer digits depending on the use of tt(typeset). See +value is nominally available to nanosecond precision, although this +varies by platform (and probably isn't accurate to 1 ns regardless), +and the shell may show more or fewer digits depending on the +use of tt(typeset). See the documentation for the builtin tt(typeset) in ifzman(zmanref(zshbuiltins))\ ifnzman(noderef(Shell Builtin Commands)) for more details. @@ -1735,8 +1739,12 @@ A star may be inserted between the percent sign and flags printing time (e.g., `tt(%*E)'); this causes the time to be printed in `var(hh)tt(:)var(mm)tt(:)var(ss)tt(.)var(ttt)' format (hours and minutes are only printed if they are not zero). -Alternatively, `tt(m)' or `tt(u)' may be used (e.g., `tt(%mE)') to produce -time output in milliseconds or microseconds, respectively. +Alternatively, `tt(m)', `tt(u)', or `tt(n)' may be used (e.g., +`tt(%mE)') to produce time output in milliseconds, microseconds, or +nanoseconds, respectively. Note that some timings on some platforms +are not actually nanosecond-precise (nor accurate to 1 ns when +they are); in fact on many systems user and kernel times are not +even microsecond-precise. ) vindex(TMOUT) item(tt(TMOUT))( diff --git a/Doc/Zsh/prompt.yo b/Doc/Zsh/prompt.yo index de988ab7c..108cb62e5 100644 --- a/Doc/Zsh/prompt.yo +++ b/Doc/Zsh/prompt.yo @@ -195,7 +195,8 @@ sitem(tt(%K))(the hour of the day on the 24-hour clock) sitem(tt(%L))(the hour of the day on the 12-hour clock) endsitem() -In addition, if the system supports the POSIX tt(gettimeofday) system +In addition, if the system supports the POSIX tt(clock_gettime) +or tt(gettimeofday) system call, tt(%.) provides decimal fractions of a second since the epoch with leading zeroes. By default three decimal places are provided, but a number of digits up to 9 may be given following the tt(%); hence tt(%6.) diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index b60e5bf31..230ad86f6 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -397,7 +397,7 @@ zfalarm(int tmout) signal(SIGALRM, zfhandler); oalremain = alarm(tmout); if (oalremain) - oaltime = time(NULL); + oaltime = zmonotime(NULL); /* * We'll leave sigtrapped, sigfuncs and TRAPXXX as they are; since the * shell's handler doesn't get the signal, they don't matter. @@ -431,7 +431,7 @@ zfunalarm(void) * I love the way alarm() uses unsigned int while time_t * is probably something completely different. */ - unsigned int tdiff = time(NULL) - oaltime; + time_t tdiff = zmonotime(NULL) - oaltime; alarm(oalremain < tdiff ? 1 : oalremain - tdiff); } else alarm(0); diff --git a/Src/Modules/zprof.c b/Src/Modules/zprof.c index 171a15b90..f5a50effc 100644 --- a/Src/Modules/zprof.c +++ b/Src/Modules/zprof.c @@ -239,8 +239,7 @@ zprof_wrapper(Eprog prog, FuncWrap w, char *name) struct sfunc sf, *sp; Pfunc f = NULL; Parc a = NULL; - struct timeval tv; - struct timezone dummy; + struct timespec ts; double prev = 0, now; char *name_for_lookups; @@ -278,19 +277,19 @@ zprof_wrapper(Eprog prog, FuncWrap w, char *name) stack = &sf; f->calls++; - tv.tv_sec = tv.tv_usec = 0; - gettimeofday(&tv, &dummy); - sf.beg = prev = ((((double) tv.tv_sec) * 1000.0) + - (((double) tv.tv_usec) / 1000.0)); + ts.tv_sec = ts.tv_nsec = 0; + zgettime_monotonic_if_available(&ts); + sf.beg = prev = ((((double) ts.tv_sec) * 1000.0) + + (((double) ts.tv_nsec) / 1000000.0)); } runshfunc(prog, w, name); if (active) { if (zprof_module && !(zprof_module->node.flags & MOD_UNLOAD)) { - tv.tv_sec = tv.tv_usec = 0; - gettimeofday(&tv, &dummy); + ts.tv_sec = ts.tv_nsec = 0; + zgettime_monotonic_if_available(&ts); - now = ((((double) tv.tv_sec) * 1000.0) + - (((double) tv.tv_usec) / 1000.0)); + now = ((((double) ts.tv_sec) * 1000.0) + + (((double) ts.tv_nsec) / 1000000.0)); f->self += now - sf.beg; for (sp = sf.prev; sp && sp->p != f; sp = sp->prev); if (!sp) diff --git a/Src/compat.c b/Src/compat.c index 8b31ad9f4..918d98e69 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -136,7 +136,19 @@ zgettime_monotonic_if_available(struct timespec *ts) #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) struct timespec dts; + +/* + * On at least some versions of macOS it appears that CLOCK_MONOTONIC is not + * actually monotonic -- there are reports that it can go backwards. + * CLOCK_MONOTONIC_RAW does not have this problem. On top of that, it is faster + * to read and it has nanosecond precision. We could use it on other systems + * too, but on Linux at least it seems that CLOCK_MONOTONIC is preferred + */ +#if defined(__APPLE__) && defined(CLOCK_MONOTONIC_RAW) + if (clock_gettime(CLOCK_MONOTONIC_RAW, &dts) < 0) { +#else if (clock_gettime(CLOCK_MONOTONIC, &dts) < 0) { +#endif zwarn("unable to retrieve CLOCK_MONOTONIC time: %e", errno); ret--; } else { diff --git a/Src/exec.c b/Src/exec.c index bc07e8c39..874ff41f7 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -348,10 +348,9 @@ setlimits(char *nam) /**/ static pid_t -zfork(struct timeval *tv) +zfork(struct timespec *ts) { pid_t pid; - struct timezone dummy_tz; /* * Is anybody willing to explain this test? @@ -360,8 +359,8 @@ zfork(struct timeval *tv) zerr("job table full"); return -1; } - if (tv) - gettimeofday(tv, &dummy_tz); + if (ts) + zgettime_monotonic_if_available(ts); /* * Queueing signals is necessary on Linux because fork() * manipulates mutexes, leading to deadlock in memory @@ -460,7 +459,7 @@ zfork(struct timeval *tv) int list_pipe = 0, simple_pline = 0; static pid_t list_pipe_pid; -static struct timeval list_pipe_start; +static struct timespec list_pipe_start; static int nowait, pline_level = 0; static int list_pipe_child = 0, list_pipe_job; static char list_pipe_text[JOBTEXTSIZE]; @@ -1863,7 +1862,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) (jobtab[list_pipe_job].stat & STAT_STOPPED)))) { pid_t pid = 0; int synch[2]; - struct timeval bgtime; + struct timespec bgtime; /* * A pipeline with the shell handling the right @@ -2284,7 +2283,7 @@ closemn(struct multio **mfds, int fd, int type) char buf[TCBUFSIZE]; int len, i; pid_t pid; - struct timeval bgtime; + struct timespec bgtime; /* * We need to block SIGCHLD in case the process @@ -2829,7 +2828,7 @@ execcmd_fork(Estate state, int how, int type, Wordcode varspc, pid_t pid; int synch[2], flags; struct entersubsh_ret esret; - struct timeval bgtime; + struct timespec bgtime; child_block(); esret.gleader = -1; @@ -2947,7 +2946,7 @@ execcmd_exec(Estate state, Execcmd_params eparams, * for the "time" keyword */ child_times_t shti, chti; - struct timeval then; + struct timespec then; if (how & Z_TIMED) shelltime(&shti, &chti, &then, 0); @@ -5060,7 +5059,7 @@ getproc(char *cmd, char **eptr) int out = *cmd == Inang; char *pnam; pid_t pid; - struct timeval bgtime; + struct timespec bgtime; #ifndef PATH_DEV_FD int fd; @@ -5149,7 +5148,7 @@ getpipe(char *cmd, int nullexec) Eprog prog; int pipes[2], out = *cmd == Inang; pid_t pid; - struct timeval bgtime; + struct timespec bgtime; char *ends; if (!(prog = parsecmd(cmd, &ends))) diff --git a/Src/hist.c b/Src/hist.c index 1a00c30ed..d0960a284 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2891,9 +2891,9 @@ flockhistfile(char *fn, int keep_trying) /* * Timeout is ten seconds. */ - end_time = time(NULL) + (time_t)10; + end_time = zmonotime(NULL) + (time_t)10; while (fcntl(flock_fd, F_SETLKW, &lck) == -1) { - if (!keep_trying || time(NULL) >= end_time || + if (!keep_trying || zmonotime(NULL) >= end_time || /* * Randomise wait to minimise clashes with shells exiting at * the same time. @@ -3137,7 +3137,7 @@ static int lockhistct; static int checklocktime(char *lockfile, long *sleep_usp, time_t then) { - time_t now = time(NULL); + time_t now = zmonotime(NULL); if (now + 10 < then) { /* File is more than 10 seconds in the future? */ diff --git a/Src/init.c b/Src/init.c index 61f759ded..378aee348 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1022,7 +1022,6 @@ setupvals(char *cmd, char *runscript, char *zsh_name) #ifdef USE_GETPWUID struct passwd *pswd; #endif - struct timezone dummy_tz; char *ptr; int i, j; #if defined(SITEFPATH_DIR) || defined(FPATH_DIR) || defined (ADDITIONAL_FPATH) || defined(FIXED_FPATH_DIR) @@ -1109,8 +1108,8 @@ setupvals(char *cmd, char *runscript, char *zsh_name) hatchar = '^'; termflags = TERM_UNKNOWN; curjob = prevjob = coprocin = coprocout = -1; - gettimeofday(&shtimer, &dummy_tz); /* init $SECONDS */ - srand((unsigned int)(shtimer.tv_sec + shtimer.tv_usec)); /* seed $RANDOM */ + zgettime_monotonic_if_available(&shtimer); /* init $SECONDS */ + srand((unsigned int)(shtimer.tv_sec + shtimer.tv_nsec)); /* seed $RANDOM */ /* Set default path */ path = (char **) zalloc(sizeof(*path) * 5); @@ -1297,7 +1296,7 @@ setupvals(char *cmd, char *runscript, char *zsh_name) #endif breaks = loops = 0; - lastmailcheck = time(NULL); + lastmailcheck = zmonotime(NULL); locallevel = sourcelevel = 0; sfcontext = SFC_NONE; trap_return = 0; diff --git a/Src/jobs.c b/Src/jobs.c index 39c664388..ad14f6312 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -136,7 +136,7 @@ int numpipestats, pipestats[MAX_PIPESTATS]; /**/ static struct timeval * -dtime(struct timeval *dt, struct timeval *t1, struct timeval *t2) +dtime_tv(struct timeval *dt, struct timeval *t1, struct timeval *t2) { dt->tv_sec = t2->tv_sec - t1->tv_sec; dt->tv_usec = t2->tv_usec - t1->tv_usec; @@ -147,6 +147,21 @@ dtime(struct timeval *dt, struct timeval *t1, struct timeval *t2) return dt; } +/* As above, but with timespecs */ + +/**/ +static struct timespec * +dtime_ts(struct timespec *dt, struct timespec *t1, struct timespec *t2) +{ + dt->tv_sec = t2->tv_sec - t1->tv_sec; + dt->tv_nsec = t2->tv_nsec - t1->tv_nsec; + if (dt->tv_nsec < 0) { + dt->tv_nsec += 1000000000.0; + dt->tv_sec -= 1.0; + } + return dt; +} + /* change job table entry from stopped to running */ /**/ @@ -349,7 +364,6 @@ get_usage(void) void update_process(Process pn, int status) { - struct timezone dummy_tz; #ifdef HAVE_GETRUSAGE struct timeval childs = child_usage.ru_stime; struct timeval childu = child_usage.ru_utime; @@ -360,12 +374,12 @@ update_process(Process pn, int status) /* get time-accounting info */ get_usage(); - gettimeofday(&pn->endtime, &dummy_tz); /* record time process exited */ + zgettime_monotonic_if_available(&pn->endtime); /* record time process exited */ pn->status = status; /* save the status returned by WAIT */ #ifdef HAVE_GETRUSAGE - dtime(&pn->ti.ru_stime, &childs, &child_usage.ru_stime); - dtime(&pn->ti.ru_utime, &childu, &child_usage.ru_utime); + dtime_tv(&pn->ti.ru_stime, &childs, &child_usage.ru_stime); + dtime_tv(&pn->ti.ru_utime, &childu, &child_usage.ru_utime); #else pn->ti.st = shtms.tms_cstime - childs; /* compute process system space time */ pn->ti.ut = shtms.tms_cutime - childu; /* compute process user space time */ @@ -753,7 +767,7 @@ printhhmmss(double secs) } static void -printtime(struct timeval *real, child_times_t *ti, char *desc) +printtime(struct timespec *real, child_times_t *ti, char *desc) { char *s; double elapsed_time, user_time, system_time; @@ -774,21 +788,21 @@ printtime(struct timeval *real, child_times_t *ti, char *desc) } /* go ahead and compute these, since almost every TIMEFMT will have them */ - elapsed_time = real->tv_sec + real->tv_usec / 1000000.0; + elapsed_time = real->tv_sec + real->tv_nsec / 1000000000.0; #ifdef HAVE_GETRUSAGE user_time = ti->ru_utime.tv_sec + ti->ru_utime.tv_usec / 1000000.0; system_time = ti->ru_stime.tv_sec + ti->ru_stime.tv_usec / 1000000.0; total_time = user_time + system_time; percent = 100.0 * total_time - / (real->tv_sec + real->tv_usec / 1000000.0); + / (real->tv_sec + real->tv_nsec / 1000000000.0); #else { long clktck = get_clktck(); user_time = ti->ut / (double) clktck; system_time = ti->st / (double) clktck; percent = 100.0 * (ti->ut + ti->st) - / (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0); + / (clktck * real->tv_sec + clktck * real->tv_nsec / 1000000000.0); } #endif @@ -844,6 +858,23 @@ printtime(struct timeval *real, child_times_t *ti, char *desc) break; } break; + case 'n': + switch (*++s) { + case 'E': + fprintf(stderr, "%0.fns", elapsed_time * 1000000000.0); + break; + case 'U': + fprintf(stderr, "%0.fns", user_time * 1000000000.0); + break; + case 'S': + fprintf(stderr, "%0.fns", system_time * 1000000000.0); + break; + default: + fprintf(stderr, "%%n"); + s--; + break; + } + break; case '*': switch (*++s) { case 'E': @@ -991,12 +1022,12 @@ static void dumptime(Job jn) { Process pn; - struct timeval dtimeval; + struct timespec dtimespec; if (!jn->procs) return; for (pn = jn->procs; pn; pn = pn->next) - printtime(dtime(&dtimeval, &pn->bgtime, &pn->endtime), &pn->ti, + printtime(dtime_ts(&dtimespec, &pn->bgtime, &pn->endtime), &pn->ti, pn->text); } @@ -1506,7 +1537,7 @@ deletejob(Job jn, int disowning) /**/ void -addproc(pid_t pid, char *text, int aux, struct timeval *bgtime, +addproc(pid_t pid, char *text, int aux, struct timespec *bgtime, int gleader, int list_pipe_job_used) { Process pn, *pnlist; @@ -1894,16 +1925,15 @@ spawnjob(void) /**/ void -shelltime(child_times_t *shell, child_times_t *kids, struct timeval *then, int delta) +shelltime(child_times_t *shell, child_times_t *kids, struct timespec *then, int delta) { - struct timezone dummy_tz; - struct timeval dtimeval, now; + struct timespec dtimespec, now; child_times_t ti; #ifndef HAVE_GETRUSAGE struct tms buf; #endif - gettimeofday(&now, &dummy_tz); + zgettime_monotonic_if_available(&now); #ifdef HAVE_GETRUSAGE getrusage(RUSAGE_SELF, &ti); @@ -1916,8 +1946,8 @@ shelltime(child_times_t *shell, child_times_t *kids, struct timeval *then, int d if (shell) { if (delta) { #ifdef HAVE_GETRUSAGE - dtime(&ti.ru_utime, &shell->ru_utime, &ti.ru_utime); - dtime(&ti.ru_stime, &shell->ru_stime, &ti.ru_stime); + dtime_tv(&ti.ru_utime, &shell->ru_utime, &ti.ru_utime); + dtime_tv(&ti.ru_stime, &shell->ru_stime, &ti.ru_stime); #else ti.ut -= shell->ut; ti.st -= shell->st; @@ -1926,15 +1956,15 @@ shelltime(child_times_t *shell, child_times_t *kids, struct timeval *then, int d *shell = ti; } if (delta) - dtime(&dtimeval, then, &now); + dtime_ts(&dtimespec, then, &now); else { if (then) *then = now; - dtime(&dtimeval, &shtimer, &now); + dtime_ts(&dtimespec, &shtimer, &now); } if (!delta == !shell) - printtime(&dtimeval, &ti, "shell"); + printtime(&dtimespec, &ti, "shell"); #ifdef HAVE_GETRUSAGE getrusage(RUSAGE_CHILDREN, &ti); @@ -1945,8 +1975,8 @@ shelltime(child_times_t *shell, child_times_t *kids, struct timeval *then, int d if (kids) { if (delta) { #ifdef HAVE_GETRUSAGE - dtime(&ti.ru_utime, &kids->ru_utime, &ti.ru_utime); - dtime(&ti.ru_stime, &kids->ru_stime, &ti.ru_stime); + dtime_tv(&ti.ru_utime, &kids->ru_utime, &ti.ru_utime); + dtime_tv(&ti.ru_stime, &kids->ru_stime, &ti.ru_stime); #else ti.ut -= shell->ut; ti.st -= shell->st; @@ -1955,7 +1985,7 @@ shelltime(child_times_t *shell, child_times_t *kids, struct timeval *then, int d *kids = ti; } if (!delta == !kids) - printtime(&dtimeval, &ti, "children"); + printtime(&dtimespec, &ti, "children"); } /* see if jobs need printing */ diff --git a/Src/params.c b/Src/params.c index 6f137585b..d1c06b893 100644 --- a/Src/params.c +++ b/Src/params.c @@ -137,11 +137,11 @@ unsigned char hatchar, hashchar; unsigned char keyboardhackchar = '\0'; /* $SECONDS = now.tv_sec - shtimer.tv_sec - * + (now.tv_usec - shtimer.tv_usec) / 1000000.0 + * + (now.tv_nsec - shtimer.tv_nsec) / 1000000000.0 * (rounded to an integer if the parameter is not set to float) */ /**/ -struct timeval shtimer; +struct timespec shtimer; /* 0 if this $TERM setup is usable, otherwise it contains TERM_* flags */ @@ -4496,13 +4496,12 @@ randomsetfn(UNUSED(Param pm), zlong v) zlong intsecondsgetfn(UNUSED(Param pm)) { - struct timeval now; - struct timezone dummy_tz; + struct timespec now; - gettimeofday(&now, &dummy_tz); + zgettime_monotonic_if_available(&now); return (zlong)(now.tv_sec - shtimer.tv_sec - - (now.tv_usec < shtimer.tv_usec ? 1 : 0)); + (now.tv_nsec < shtimer.tv_nsec ? 1 : 0)); } /* Function to set value of special parameter `SECONDS' */ @@ -4511,48 +4510,47 @@ intsecondsgetfn(UNUSED(Param pm)) void intsecondssetfn(UNUSED(Param pm), zlong x) { - struct timeval now; - struct timezone dummy_tz; + struct timespec now; zlong diff; - gettimeofday(&now, &dummy_tz); + zgettime_monotonic_if_available(&now); + diff = (zlong)now.tv_sec - x; shtimer.tv_sec = diff; if ((zlong)shtimer.tv_sec != diff) zwarn("SECONDS truncated on assignment"); - shtimer.tv_usec = now.tv_usec; + shtimer.tv_nsec = now.tv_nsec; } /**/ double floatsecondsgetfn(UNUSED(Param pm)) { - struct timeval now; - struct timezone dummy_tz; + struct timespec now; - gettimeofday(&now, &dummy_tz); + zgettime_monotonic_if_available(&now); return (double)(now.tv_sec - shtimer.tv_sec) + - (double)(now.tv_usec - shtimer.tv_usec) / 1000000.0; + (double)(now.tv_nsec - shtimer.tv_nsec) / 1000000000.0; } /**/ void floatsecondssetfn(UNUSED(Param pm), double x) { - struct timeval now; - struct timezone dummy_tz; + struct timespec now; + + zgettime_monotonic_if_available(&now); - gettimeofday(&now, &dummy_tz); shtimer.tv_sec = now.tv_sec - (zlong)x; - shtimer.tv_usec = now.tv_usec - (zlong)((x - (zlong)x) * 1000000.0); + shtimer.tv_nsec = now.tv_nsec - (zlong)((x - (zlong)x) * 1000000000.0); } /**/ double getrawseconds(void) { - return (double)shtimer.tv_sec + (double)shtimer.tv_usec / 1000000.0; + return (double)shtimer.tv_sec + (double)shtimer.tv_nsec / 1000000000.0; } /**/ @@ -4560,7 +4558,7 @@ void setrawseconds(double x) { shtimer.tv_sec = (zlong)x; - shtimer.tv_usec = (zlong)((x - (zlong)x) * 1000000.0); + shtimer.tv_nsec = (zlong)((x - (zlong)x) * 1000000000.0); } /**/ diff --git a/Src/prompt.c b/Src/prompt.c index e10b05215..f36aba9d3 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -469,7 +469,7 @@ putpromptchar(int doprint, int endchar) test = 1; break; case 'S': - if (time(NULL) - shtimer.tv_sec >= arg) + if (zmonotime(NULL) - shtimer.tv_sec >= arg) test = 1; break; case 'v': diff --git a/Src/signals.c b/Src/signals.c index 86f1a49f6..de42f302d 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -342,8 +342,7 @@ wait_for_processes(void) zwarn("job can't be suspended"); } else { #if defined(HAVE_WAIT3) && defined(HAVE_GETRUSAGE) - struct timezone dummy_tz; - gettimeofday(&pn->endtime, &dummy_tz); + zgettime_monotonic_if_available(&pn->endtime); #ifdef WIFCONTINUED if (WIFCONTINUED(status)) pn->status = SP_RUNNING; diff --git a/Src/utils.c b/Src/utils.c index ce4e875fd..5c91dfcda 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1570,14 +1570,14 @@ preprompt(void) /* If 1) the parameter PERIOD exists, 2) a hook function for * * "periodic" exists, 3) it's been greater than PERIOD since we * * executed any such hook, then execute it now. */ - if (period && ((zlong)time(NULL) > (zlong)lastperiodic + period) && + if (period && ((zlong)zmonotime(NULL) > (zlong)lastperiodic + period) && !callhookfunc("periodic", NULL, 1, NULL)) - lastperiodic = time(NULL); + lastperiodic = zmonotime(NULL); if (errflag) return; /* Check mail */ - currentmailcheck = time(NULL); + currentmailcheck = zmonotime(NULL); if (mailcheck && (zlong) difftime(currentmailcheck, lastmailcheck) > mailcheck) { char *mailfile; @@ -2761,6 +2761,19 @@ timespec_diff_us(const struct timespec *t1, const struct timespec *t2) return (reverse ? LONG_MIN : LONG_MAX); } +/* Like time(), but uses the monotonic clock */ + +/**/ +mod_export int +zmonotime(time_t *tloc) +{ + struct timespec ts; + zgettime_monotonic_if_available(&ts); + if (tloc) + *tloc = ts.tv_sec; + return ts.tv_sec; +} + /* * Sleep for the given number of microseconds --- must be within * range of a long at the moment, but this is only used for @@ -2794,7 +2807,9 @@ zsleep(long us) /** * Sleep for time (fairly) randomly up to max_us microseconds. - * Don't let the wallclock time extend beyond end_time. + * Don't let the time extend beyond end_time. end_time is compared to + * the current *monotonic* clock time, so do NOT base it on e.g. time(2); + * use zmonotime() or zgettime_monotonic_if_available(). * Return 1 if that seemed to work, else 0. * * For best results max_us should be a multiple of 2**16 or large @@ -2806,7 +2821,7 @@ int zsleep_random(long max_us, time_t end_time) { long r; - time_t now = time(NULL); + time_t now = zmonotime(NULL); /* * Randomish backoff. Doesn't need to be fundamentally diff --git a/Src/zsh.h b/Src/zsh.h index 090abf8f5..85b5c9bdc 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1115,8 +1115,8 @@ struct process { char text[JOBTEXTSIZE]; /* text to print when 'jobs' is run */ int status; /* return code from waitpid/wait3() */ child_times_t ti; - struct timeval bgtime; /* time job was spawned */ - struct timeval endtime; /* time job exited */ + struct timespec bgtime; /* time job was spawned */ + struct timespec endtime; /* time job exited */ }; struct execstack { diff --git a/Test/A08time.ztst b/Test/A08time.ztst index 22a460f5e..4a41cc76a 100644 --- a/Test/A08time.ztst +++ b/Test/A08time.ztst @@ -11,9 +11,44 @@ (time cat) >&/dev/null 0:`time' keyword (status only) - ( TIMEFMT='%E %mE %uE %* %m%mm %u%uu'; time (:) ) + ( TIMEFMT='%E %mE %uE %nE %* %m%mm %u%uu %n%nn'; time (:) ) 0:`time' keyword with custom TIMEFMT -*?[0-9]##.[0-9](#c2)s [0-9]##ms [0-9]##us %\* %m%mm %u%uu +*?[0-9]##.[0-9](#c2)s [0-9]##ms [0-9]##us [0-9]##ns %\* %m%mm %u%uu %n%nn + + ( TIMEFMT='x %U %S %E'; time (:) ) +0:TIMEFMT %[USE] use centisecond precision +*?x( <0-9>.<00-99>s)(#c3) + + ( TIMEFMT='x %*U %*S %*E'; time (:) ) +0:TIMEFMT %*[USE] use millisecond precision +*?x( <0-9>.<000-999>)(#c3) + + ( TIMEFMT='%nU %nS'; time (read -k3 -t0.1) ) +1:TIMEFMT %nU and %nS are limited to microsecond precision +*?[1-9][0-9]#000ns [1-9][0-9]#000ns + +# SECONDS (after - before) must be greater than the elapsed time, but not much +# greater. 25% was picked arbitrarily as something that hopefully will prevent +# the test from failing on slow machines + ( + typeset -F SECONDS + TIMEFMT=%nE + a=$SECONDS + t=$( (time (read -k3 -t0.1)) 2>&1 ) + b=$SECONDS + s=$(( b - a )) + t=$(( ${t%ns}.0 / 10**9 )) + echo $s $t $(( s > t )) $(( t > s - (s * 0.25) )) + ) +0:`time' elapsed time matches SECONDS +*>[0-9.]## [0-9.]## 1 1 + +# Again, the wide range here is an attempt to prevent this test from failing on +# slow machines. We don't care about the exact time, just that it's vaguely sane +# and that each representation has the same basis + ( TIMEFMT='%E %mE %uE %nE %*E'; time (read -k3 -t0.1) ) +1:TIMEFMT elapsed time values +*?0.<10-50>s <10-500>ms <100000-500000>us <100000000-500000000>ns 0.<100-500> time x=1 0:`time' simple assignment diff --git a/Test/D01prompt.ztst b/Test/D01prompt.ztst index 55861cca1..f42e19714 100644 --- a/Test/D01prompt.ztst +++ b/Test/D01prompt.ztst @@ -68,6 +68,13 @@ print -P '%(?.true.false)' 0:ternary prompt escapes >true +>false + + sec=$SECONDS + eval "print -P '%(${sec}S.true.false)'" + eval "print -P '%($((sec+30))S.true.false)'" +0:ternary prompt escape with test character S +>true >false print -P 'start %10<...1 >1 + # Integer + a=$SECONDS + sleep 1 + b=$SECONDS + print -r - $a $b $(( b > a )) + # Float + typeset -F SECONDS + a=$SECONDS + repeat 10 : + b=$SECONDS + print -r - $a $b $(( b > a )) + # Assignment + a=$SECONDS + SECONDS=8888 + repeat 10 : + b=$SECONDS + print -r - $(( a < 8888 )) $(( b > 8888 )) +0:SECONDS +*>[0-9]## [0-9]## 1 +*>[0-9]##.[0-9]## [0-9]##.[0-9]## 1 +*>1 1 + foo=("|" "?") [[ "|" = ${(j.|.)foo} ]] && print yes || print no [[ "|" = ${(j.|.)~foo} ]] && print yes || print no -- cgit v1.2.3 From d051857e03d474bf7a122148f323bd90d8c16b36 Mon Sep 17 00:00:00 2001 From: dana Date: Thu, 26 Dec 2024 09:39:11 -0600 Subject: 53260: zparseopts: add options -v (argv) and -G (GNU-style parsing) --- ChangeLog | 3 + Doc/Zsh/mod_zutil.yo | 44 ++++++++++-- Src/Modules/zutil.c | 116 +++++++++++++++++++++++++------ Test/V12zparseopts.ztst | 181 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 313 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 989cc0aa3..9a40cae5e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-12-26 dana + * 53260: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c, + Test/V12zparseopts.ztst: add -v and -G options to zparseopts + * 53257: Doc/Zsh/params.yo, Doc/Zsh/prompt.yo, Src/Modules/zftp.c, Src/Modules/zprof.c, Src/compat.c, Src/exec.c, Src/hist.c, Src/init.c, Src/jobs.c, Src/params.c, diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo index 9946618d6..76907352f 100644 --- a/Doc/Zsh/mod_zutil.yo +++ b/Doc/Zsh/mod_zutil.yo @@ -228,7 +228,7 @@ item(tt(zregexparse))( This implements some internals of the tt(_regex_arguments) function. ) findex(zparseopts) -item(tt(zparseopts) [ tt(-D) tt(-E) tt(-F) tt(-K) tt(-M) ] [ tt(-a) var(array) ] [ tt(-A) var(assoc) ] [ tt(-) ] var(spec) ...)( +item(tt(zparseopts) [ tt(-D) tt(-E) tt(-F) tt(-G) tt(-K) tt(-M) ] [ tt(-a) var(array) ] [ tt(-A) var(assoc) ] [ tt(-v) var(argv) ] [ tt(-) ] var(spec) ...)( This builtin simplifies the parsing of options in positional parameters, i.e. the set of arguments given by tt($*). Each var(spec) describes one option and must be of the form `var(opt)[tt(=)var(array)]'. If an option @@ -282,19 +282,19 @@ first colon. ) enditem() -In all cases, option-arguments must appear either immediately following the +By default, option-arguments may appear either immediately following the option in the same positional parameter or in the next one. Even an optional argument may appear in the next parameter, unless it begins with a `tt(-)'. -There is no special handling of `tt(=)' as with GNU-style argument parsers; -given the var(spec) `tt(-foo:)', the positional parameter `tt(-)tt(-foo=bar)' -is parsed as `tt(-)tt(-foo)' with an argument of `tt(=bar)'. +Additionally, there is no special consideration given to an `tt(=)' +between an option and its argument. To make parsing use the more common +GNU-style conventions, use the tt(-G) option. When the names of two options that take no arguments overlap, the longest one wins, so that parsing for the var(spec)s `tt(-foo -foobar)' (for example) is unambiguous. However, due to the aforementioned handling of option-arguments, ambiguities may arise when at least one overlapping var(spec) takes an argument, as in `tt(-foo: -foobar)'. In that case, the last matching -var(spec) wins. +var(spec) wins. (This is not an issue with GNU-style parsing.) The options of tt(zparseopts) itself cannot be stacked because, for example, the stack `tt(-DEK)' is indistinguishable from a var(spec) for @@ -338,6 +338,33 @@ Note that the appearance in the positional parameters of an option without its required argument always aborts parsing and returns an error as described above regardless of whether this option is used. ) +item(tt(-G))( +This option specifies that options are parsed in the GNU style, +similar to tt(getopt_long+LPAR()3+RPAR()). In particular: + +Given the var(spec) `tt(-foo:)', the positional parameter +`tt(-)tt(-foo=bar)' is interpreted as option `tt(-)tt(-foo)' with +argument `tt(bar)', rather than argument `tt(=bar)' as is the default, +whilst the positional parameter `tt(-)tt(-foobar)' is considered an +unknown option (unless another var(spec) describes it). This applies +to both singly and doubly hyphenated long options. + +An empty option-argument can be given to its long option in the same +parameter using a trailing `tt(=)'. + +An optional argument to a long option must be given with the +equals syntax, and an optional argument to a short option must +follow it immediately in the same parameter; in both cases the +following parameter is considered unrelated. + +Whenever a long option and its argument are stored in the same array +element, an `tt(=)' is used to separate them. + +A mandatory option-argument given in a separate parameter from its +option (as in `tt(-)tt(-foo) tt(bar)'), or any option-argument given to +a short option in the same parameter, is always treated the same +regardless of whether this option is in effect. +) item(tt(-K))( With this option, the arrays specified with the tt(-a) option and with the `tt(=)var(array)' forms are kept unchanged when none of the var(spec)s for @@ -355,6 +382,11 @@ is found, the values are stored as usual. This changes only the way the values are stored, not the way tt($*) is parsed, so results may be unpredictable if the `var(name)tt(+)' specifier is used inconsistently. ) +item(tt(-v) var(argv))( +With this option, the elements of the named array var(argv) are used as the +positional parameters to parse, rather than those given by tt($*). The +array may be modified according to the tt(-D) option. +) enditem() For example, diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 5eccea7a9..9b2721a09 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -1528,12 +1528,14 @@ struct zoptdesc { Zoptval vals, last; }; -#define ZOF_ARG 1 -#define ZOF_OPT 2 -#define ZOF_MULT 4 -#define ZOF_SAME 8 -#define ZOF_MAP 16 -#define ZOF_CYC 32 +#define ZOF_ARG 1 +#define ZOF_OPT 2 +#define ZOF_MULT 4 +#define ZOF_SAME 8 +#define ZOF_MAP 16 +#define ZOF_CYC 32 +#define ZOF_GNUS 64 +#define ZOF_GNUL 128 struct zoptarr { Zoptarr next; @@ -1568,9 +1570,29 @@ static Zoptdesc lookup_opt(char *str) { Zoptdesc p; - for (p = opt_descs; p; p = p->next) { - if ((p->flags & ZOF_ARG) ? strpfx(p->name, str) : !strcmp(p->name, str)) + /* + * Option takes argument, with GNU-style handling of =. This should only + * be set for long options, though we don't care about that here. Unlike + * the default behaviour, matching is unambiguous + */ + if (p->flags & ZOF_GNUL) { + if (!strcmp(p->name, str) || /* Inefficient, whatever */ + (strpfx(p->name, str) && str[strlen(p->name)] == '=')) + return p; + /* + * Option takes argument, default 'cuddled' style. This is weird with + * long options because we naively accept whatever option has a prefix + * match for the given parameter. Thus if you have specs `-foo:` and + * `-foobar:` (or even `-foobar` with no optarg), without the GNU + * setting, the behaviour depends on the order in which they were + * defined. It is documented to work this way though + */ + } else if (p->flags & ZOF_ARG) { + if (strpfx(p->name, str)) + return p; + /* Option takes no argument */ + } else if (!strcmp(p->name, str)) return p; } return NULL; @@ -1641,10 +1663,13 @@ add_opt_val(Zoptdesc d, char *arg) if (d->arr) d->arr->num += (arg ? 2 : 1); } else if (arg) { - char *s = (char *) zhalloc(strlen(d->name) + strlen(arg) + 2); + /* 3 here is '-' + '=' + NUL */ + char *s = (char *) zhalloc(strlen(d->name) + strlen(arg) + 3); *s = '-'; strcpy(s + 1, d->name); + if (d->flags & ZOF_GNUL) + strcat(s, "="); strcat(s, arg); v->str = s; if (d->arr) @@ -1713,7 +1738,8 @@ static int bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) { char *o, *p, *n, **pp, **aval, **ap, *assoc = NULL, **cp, **np; - int del = 0, flags = 0, extract = 0, fail = 0, keep = 0; + char *paramsname = NULL, **params; + int del = 0, flags = 0, extract = 0, fail = 0, gnu = 0, keep = 0; Zoptdesc sopts[256], d; Zoptarr a, defarr = NULL; Zoptval v; @@ -1758,6 +1784,14 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) } fail = 1; break; + case 'G': + if (o[2]) { + args--; + o = NULL; + break; + } + gnu = 1; + break; case 'K': if (o[2]) { args--; @@ -1808,6 +1842,20 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) return 1; } break; + case 'v': + if (paramsname) { + zwarnnam(nam, "argv array given more than once"); + return 1; + } + if (o[2]) + paramsname = o + 2; + else if (*args) + paramsname = *args++; + else { + zwarnnam(nam, "missing array name"); + return 1; + } + break; default: /* Anything else is an option description */ args--; @@ -1849,6 +1897,9 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) if (*p == ':') { f |= ZOF_ARG; *p = '\0'; + if (gnu) { + f |= o[1] ? ZOF_GNUL : ZOF_GNUS; + } if (*++p == ':') { p++; f |= ZOF_OPT; @@ -1901,8 +1952,10 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) return 1; } } - np = cp = pp = ((extract && del) ? arrdup(pparams) : pparams); + params = getaparam((paramsname = paramsname ? paramsname : "argv")); + np = cp = pp = ((extract && del) ? arrdup(params) : params); for (; (o = *pp); pp++) { + /* Not an option */ if (*o != '-') { if (extract) { if (del) @@ -1911,6 +1964,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) } else break; } + /* '-' or '--', end parsing */ if (!o[1] || (o[1] == '-' && !o[2])) { if (del && extract) *cp++ = o; @@ -1918,6 +1972,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) break; } if (!(d = lookup_opt(o + 1))) { + /* No match for whole param, try each character as a short option */ while (*++o) { if (!(d = sopts[(unsigned char) *o])) { if (fail) { @@ -1931,19 +1986,27 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) break; } if (d->flags & ZOF_ARG) { + /* Optarg in same parameter */ if (o[1]) { add_opt_val(d, o + 1); break; + /* + * Mandatory optarg or (if not GNU style) optional optarg in + * next parameter + */ } else if (!(d->flags & ZOF_OPT) || - (pp[1] && pp[1][0] != '-')) { + (!(d->flags & (ZOF_GNUL | ZOF_GNUS)) && + pp[1] && pp[1][0] != '-')) { if (!pp[1]) { zwarnnam(nam, "missing argument for option: -%s", d->name); return 1; } add_opt_val(d, *++pp); + /* Missing optional optarg */ } else add_opt_val(d, NULL); + /* No optarg required */ } else add_opt_val(d, NULL); } @@ -1956,21 +2019,37 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) break; } } else { + /* Whole param matches a defined option */ if (d->flags & ZOF_ARG) { char *e = o + strlen(d->name) + 1; - if (*e) + /* GNU style allows an empty optarg in the same parameter */ + if ((d->flags & ZOF_GNUL) && *e == '=') { + add_opt_val(d, ++e); + /* + * Non-empty optarg in same parameter. lookup_opt() test ensures + * that this won't be a GNU-style long option, where this would + * be invalid + */ + } else if (*e) { add_opt_val(d, e); - else if (!(d->flags & ZOF_OPT) || - (pp[1] && pp[1][0] != '-')) { + /* + * Mandatory optarg or (if not GNU style) optional optarg in + * next parameter + */ + } else if (!(d->flags & ZOF_OPT) || + (!(d->flags & (ZOF_GNUL | ZOF_GNUS)) && + pp[1] && pp[1][0] != '-')) { if (!pp[1]) { zwarnnam(nam, "missing argument for option: -%s", d->name); return 1; } add_opt_val(d, *++pp); + /* Missing optional optarg */ } else add_opt_val(d, NULL); + /* No optarg required */ } else add_opt_val(d, NULL); } @@ -2041,12 +2120,9 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) if (del) { if (extract) { *cp = NULL; - freearray(pparams); - pparams = zarrdup(np); + setaparam(paramsname, zarrdup(np)); } else { - pp = zarrdup(pp); - freearray(pparams); - pparams = pp; + setaparam(paramsname, zarrdup(pp)); } } return 0; diff --git a/Test/V12zparseopts.ztst b/Test/V12zparseopts.ztst index 816e1d041..a2743ea0e 100644 --- a/Test/V12zparseopts.ztst +++ b/Test/V12zparseopts.ztst @@ -103,6 +103,14 @@ 0:zparseopts -M >ret: 0, optv: --aaa bar, opts: --aaa bar, argv: 1 2 3 + () { + local -a optv argvv=( -a -b -c 1 2 3 ) + zparseopts -D -a optv -v argvv - a b c + print -r - ret: $?, optv: $optv, argvv: $argvv, argv: $argv + } -x -y -z 7 8 9 +0:zparseopts -v +>ret: 0, optv: -a -b -c, argvv: 1 2 3, argv: -x -y -z 7 8 9 + () { local -a optv aa ab zparseopts -a optv - a=aa b:=ab c:- z @@ -151,16 +159,35 @@ >ret: 0, optv: -+ -: -= -\, argv: 1 2 3 >ret: 0, optv: --::: foo, argv: 1 2 3 - for specs in '-foo: -foobar' '-foobar -foo:'; do + for specs in \ + '-foo: -foobar' '-foobar -foo:' '-foo: -foobar:' '-foobar: -foo:' + do + () { + local -a optv + zparseopts -a optv -D - $=specs + print -r - ret: $?, optv: $optv, argv: $argv + } --foobar 1 2 3 + done +0:overlapping option specs without -G (scan order) +>ret: 0, optv: --foobar, argv: 1 2 3 +>ret: 0, optv: --foo bar, argv: 1 2 3 +>ret: 0, optv: --foobar 1, argv: 2 3 +>ret: 0, optv: --foo bar, argv: 1 2 3 + + for specs in \ + '-foo: -foobar' '-foobar -foo:' '-foo: -foobar:' '-foobar: -foo:' + do () { local -a optv - zparseopts -a optv - $=specs + zparseopts -a optv -D -G - $=specs print -r - ret: $?, optv: $optv, argv: $argv } --foobar 1 2 3 done -0:overlapping option specs (scan order) ->ret: 0, optv: --foobar, argv: --foobar 1 2 3 ->ret: 0, optv: --foo bar, argv: --foobar 1 2 3 +0:overlapping option specs with -G (scan order) +>ret: 0, optv: --foobar, argv: 1 2 3 +>ret: 0, optv: --foobar, argv: 1 2 3 +>ret: 0, optv: --foobar 1, argv: 2 3 +>ret: 0, optv: --foobar 1, argv: 2 3 () { local -a optv @@ -170,3 +197,147 @@ 0:missing optarg ?(anon):zparseopts:2: missing argument for option: -c >ret: 1, optv: , argv: -ab1 -c + + for spec in -foo: -foo:- -foo::; do + () { + local -a optv + zparseopts -a optv -D -F - $=spec + print -r - ret: $?, optv: $optv, argv: $argv + } --foo=bar 1 2 3 + done +0:zparseopts without -G, =optarg handling +>ret: 0, optv: --foo =bar, argv: 1 2 3 +>ret: 0, optv: --foo=bar, argv: 1 2 3 +>ret: 0, optv: --foo=bar, argv: 1 2 3 + + for spec in -foo: -foo:- -foo::; do + () { + local -a optv + zparseopts -a optv -D -F -G - $=spec + print -r - ret: $?, optv: $optv, argv: $argv + } --foo=bar 1 2 3 + done +0:zparseopts -G, single parameter, with = +>ret: 0, optv: --foo bar, argv: 1 2 3 +>ret: 0, optv: --foo=bar, argv: 1 2 3 +>ret: 0, optv: --foo=bar, argv: 1 2 3 + + for spec in -foo: -foo:- -foo:: ; do + () { + local -a optv + zparseopts -a optv -D -F -G - $=spec + print -r - ret: $?, optv: $optv, argv: $argv + } --foobar 1 2 3 + done +0:zparseopts -G, single parameter, without = +?(anon):zparseopts:2: bad option: --foobar +>ret: 1, optv: , argv: --foobar 1 2 3 +?(anon):zparseopts:2: bad option: --foobar +>ret: 1, optv: , argv: --foobar 1 2 3 +?(anon):zparseopts:2: bad option: --foobar +>ret: 1, optv: , argv: --foobar 1 2 3 + + for spec in -foo: -foo:- -foo::; do + () { + local -a optv + zparseopts -a optv -D -F -G - $=spec + print -r - ret: $?, optv: $optv, argv: $argv + } --foo bar 1 2 3 + done +0:zparseopts -G, separate parameters +>ret: 0, optv: --foo bar, argv: 1 2 3 +>ret: 0, optv: --foo=bar, argv: 1 2 3 +>ret: 0, optv: --foo, argv: bar 1 2 3 + + for spec in -foo: -foo:- -foo::; do + () { + local -a optv + zparseopts -a optv -D -F -G - $=spec + print -r - ret: $?, optv: ${(j< >)${(q+)optv}}, argv: $argv + } --foo= 1 2 3 + done +0:zparseopts -G, empty optarg +>ret: 0, optv: --foo '', argv: 1 2 3 +>ret: 0, optv: '--foo=', argv: 1 2 3 +>ret: 0, optv: '--foo=', argv: 1 2 3 + + for gopt in '' -G; do + for spec args in \ + f: '-fbar 1 2 3' \ + f: '-f=bar 1 2 3' \ + f: '-f bar 1 2 3' \ + f:- '-fbar 1 2 3' \ + f:- '-f=bar 1 2 3' \ + f:- '-f bar 1 2 3' \ + f:: '-fbar 1 2 3' \ + f:: '-f=bar 1 2 3' \ + f:: '-f bar 1 2 3' + do + () { + local -a optv + zparseopts -a optv -D -F $gopt - $=spec + print -r - ret: $?, gopt: $gopt, optv: $optv, argv: $argv + } $=args + done + done +0:short options, with and without -G +>ret: 0, gopt: , optv: -f bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -f =bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -f bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -fbar, argv: 1 2 3 +>ret: 0, gopt: , optv: -f=bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -fbar, argv: 1 2 3 +>ret: 0, gopt: , optv: -fbar, argv: 1 2 3 +>ret: 0, gopt: , optv: -f=bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -fbar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -f bar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -f =bar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -f bar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -fbar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -f=bar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -fbar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -fbar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -f=bar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -f, argv: bar 1 2 3 + + for gopt in '' -G; do + for spec args in \ + foo: '-foobar 1 2 3' \ + foo: '-foo=bar 1 2 3' \ + foo: '-foo bar 1 2 3' \ + foo:- '-foobar 1 2 3' \ + foo:- '-foo=bar 1 2 3' \ + foo:- '-foo bar 1 2 3' \ + foo:: '-foobar 1 2 3' \ + foo:: '-foo=bar 1 2 3' \ + foo:: '-foo bar 1 2 3' + do + () { + local -a optv + zparseopts -a optv -D -F $gopt - $=spec + print -r - ret: $?, gopt: $gopt, optv: $optv, argv: $argv + } $=args + done + done +0:Sun-style long options, with and without -G +>ret: 0, gopt: , optv: -foo bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -foo =bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -foo bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -foobar, argv: 1 2 3 +>ret: 0, gopt: , optv: -foo=bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -foobar, argv: 1 2 3 +>ret: 0, gopt: , optv: -foobar, argv: 1 2 3 +>ret: 0, gopt: , optv: -foo=bar, argv: 1 2 3 +>ret: 0, gopt: , optv: -foobar, argv: 1 2 3 +?(anon):zparseopts:2: bad option: -f +>ret: 1, gopt: -G, optv: , argv: -foobar 1 2 3 +>ret: 0, gopt: -G, optv: -foo bar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -foo bar, argv: 1 2 3 +?(anon):zparseopts:2: bad option: -f +>ret: 1, gopt: -G, optv: , argv: -foobar 1 2 3 +>ret: 0, gopt: -G, optv: -foo=bar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -foo=bar, argv: 1 2 3 +?(anon):zparseopts:2: bad option: -f +>ret: 1, gopt: -G, optv: , argv: -foobar 1 2 3 +>ret: 0, gopt: -G, optv: -foo=bar, argv: 1 2 3 +>ret: 0, gopt: -G, optv: -foo, argv: bar 1 2 3 -- cgit v1.2.3 From 32cd93bcb04278a6a9c9d2e0af3e1d025841c6d4 Mon Sep 17 00:00:00 2001 From: dana Date: Mon, 30 Dec 2024 20:10:26 -0600 Subject: unposted: _zparseopts: update per workers/53260 --- ChangeLog | 5 +++++ Completion/Zsh/Command/_zparseopts | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9a40cae5e..cd29452a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-01-02 dana + + * unposted: Completion/Zsh/Command/_zparseopts: update + completion per workers/53260 + 2024-12-26 dana * 53260: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c, diff --git a/Completion/Zsh/Command/_zparseopts b/Completion/Zsh/Command/_zparseopts index e13a91081..ae81937c1 100644 --- a/Completion/Zsh/Command/_zparseopts +++ b/Completion/Zsh/Command/_zparseopts @@ -10,8 +10,10 @@ _arguments -A '-*' : \ '-D[remove parsed options from positional parameters]' \ "-E[don't stop parsing at first parameter not described by specs]" \ '-F[abort parsing and print error at first option-like parameter not described by specs]' \ + '-G[enable GNU-style parsing]' \ '-K[preserve contents of arrays/associations when specs are not matched]' \ '-M[enable mapping among equivalent options with opt1=opt2 spec form]' \ + '-v+[specify array from which to parse options]:array:_parameters -g "*array*"' \ '(-)-[end zparseopts options; specs follow]' \ '*: :->spec' \ && ret=0 -- cgit v1.2.3 From 98e486fb5642f04c0909d3cd487382f5901e984e Mon Sep 17 00:00:00 2001 From: dana Date: Thu, 2 Jan 2025 17:06:34 -0600 Subject: 53297: Test/A08time: allow %nU/%nS result to be 0 --- ChangeLog | 2 ++ Test/A08time.ztst | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cd29452a7..21dcd47e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2025-01-02 dana + * 53297: Test/A08time.ztst: allow %nU/%nS result to be 0 + * unposted: Completion/Zsh/Command/_zparseopts: update completion per workers/53260 diff --git a/Test/A08time.ztst b/Test/A08time.ztst index 4a41cc76a..071038d1f 100644 --- a/Test/A08time.ztst +++ b/Test/A08time.ztst @@ -25,7 +25,7 @@ ( TIMEFMT='%nU %nS'; time (read -k3 -t0.1) ) 1:TIMEFMT %nU and %nS are limited to microsecond precision -*?[1-9][0-9]#000ns [1-9][0-9]#000ns +*?(0|[1-9][0-9]#000)ns (0|[1-9][0-9]#000)ns # SECONDS (after - before) must be greater than the elapsed time, but not much # greater. 25% was picked arbitrarily as something that hopefully will prevent -- cgit v1.2.3 From 3f43a2ffd1cfff92ed4627b75d84fbfc1b9abbbc Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Fri, 3 Jan 2025 23:38:21 +0900 Subject: 53293: fix menu() and texinode() in yodl docs --- ChangeLog | 5 +++++ Doc/Zsh/compsys.yo | 10 +++++----- Doc/Zsh/index.yo | 2 +- Doc/Zsh/manual.yo | 3 ++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 21dcd47e5..c43adf70f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-01-03 Jun-ichi Takimoto + + * 53293: Doc/Zsh/compsys.yo, Doc/Zsh/index.yo, Doc/Zsh/manual.yo: + fix menu() and texinode() in yodl docs + 2025-01-02 dana * 53297: Test/A08time.ztst: allow %nU/%nS result to be 0 diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 7ae67773b..06b08cc72 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -89,9 +89,9 @@ menu(Initialization) menu(Completion System Configuration) menu(Control Functions) menu(Bindable Commands) -menu(Completion Functions) -menu(Completion Directories) +menu(Utility Functions) menu(Completion System Variables) +menu(Completion Directories) endmenu() texinode(Initialization)(Completion System Configuration)()(Completion System) @@ -3363,7 +3363,7 @@ endsitem() ) enditem() -texinode(Bindable Commands)(Completion Functions)(Control Functions)(Completion System) +texinode(Bindable Commands)(Utility Functions)(Control Functions)(Completion System) sect(Bindable Commands) cindex(completion system, bindable commands) @@ -3562,7 +3562,7 @@ emacs and vi respectively. ) enditem() -texinode(Completion Functions)(Completion System Variables)(Bindable Commands)(Completion System) +texinode(Utility Functions)(Completion System Variables)(Bindable Commands)(Completion System) sect(Utility Functions) cindex(completion system, utility functions) @@ -5481,7 +5481,7 @@ ifnzman(noderef(The zsh/zleparameter Module)). ) enditem() -texinode(Completion System Variables)(Completion Directories)(Completion Functions)(Completion System) +texinode(Completion System Variables)(Completion Directories)(Utility Functions)(Completion System) sect(Completion System Variables) cindex(completion system, variables) diff --git a/Doc/Zsh/index.yo b/Doc/Zsh/index.yo index 191e0f2f9..131d7a4f2 100644 --- a/Doc/Zsh/index.yo +++ b/Doc/Zsh/index.yo @@ -5,7 +5,7 @@ def(printindex)(2)(\ NL()\ NOTRANS(@printindex) ARG2\ )\ -texinode(Concept Index)(Variables Index)(Top)(Top) +texinode(Concept Index)(Variables Index)()(Top) printindex(Concept Index)(cp) texinode(Variables Index)(Options Index)(Concept Index)(Top) diff --git a/Doc/Zsh/manual.yo b/Doc/Zsh/manual.yo index dc4d6ed07..e54dd077c 100644 --- a/Doc/Zsh/manual.yo +++ b/Doc/Zsh/manual.yo @@ -126,7 +126,8 @@ menu(Initialization) menu(Completion System Configuration) menu(Control Functions) menu(Bindable Commands) -menu(Completion Functions) +menu(Utility Functions) +menu(Completion System Variables) menu(Completion Directories) Completion Using compctl -- cgit v1.2.3 From 263659acb73d0222e641dfd8d37e48e96582de02 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Fri, 3 Jan 2025 09:18:23 -0800 Subject: 53294: fix multibyte handling in "select" prompts --- ChangeLog | 4 ++++ Src/loop.c | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c43adf70f..63b9623d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2025-01-03 Bart Schaefer + + * 53294: Src/loop.c: fix multibyte handling in "select" prompts + 2025-01-03 Jun-ichi Takimoto * 53293: Doc/Zsh/compsys.yo, Doc/Zsh/index.yo, Doc/Zsh/manual.yo: diff --git a/Src/loop.c b/Src/loop.c index 84dc66476..979285abc 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -351,9 +351,16 @@ selectlist(LinkList l, size_t start) zleentry(ZLE_CMD_TRASH); arr = hlinklist2array(l, 0); - for (ap = arr; *ap; ap++) - if (strlen(*ap) > longest) - longest = strlen(*ap); + for (ap = arr; *ap; ap++) { +#ifdef MB_METASTRWIDTH + int aplen = MB_METASTRWIDTH(*ap); +#else + int aplen = 0; + (void) unmetafy(*ap, &aplen); +#endif + if (aplen > longest) + longest = aplen; + } t0 = ct = ap - arr; longest++; while (t0) @@ -368,7 +375,12 @@ selectlist(LinkList l, size_t start) for (t1 = start; t1 != colsz && t1 - start < zterm_lines - 2; t1++) { ap = arr + t1; do { +#ifdef MB_METASTRWIDTH + size_t t2 = MB_METASTRWIDTH(*ap) + 2; + (void) unmetafy(*ap, NULL); +#else size_t t2 = strlen(*ap) + 2; +#endif int t3; fprintf(stderr, "%d) %s", t3 = ap - arr + 1, *ap); -- cgit v1.2.3 From db01c79cf83290b9ac9d77e66d832551b7022f71 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 20 Jan 2025 10:57:58 -0800 Subject: Julian Prein: 53309: remove uncommon / obsolete options -t and -W --- ChangeLog | 5 +++++ Completion/Unix/Command/_uniq | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 63b9623d6..ba7054a8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-01-20 Bart Schaefer + + * Julian Prein: 53309: Completion/Unix/Command/_uniq: remove + uncommon / obsolete options -t and -W + 2025-01-03 Bart Schaefer * 53294: Src/loop.c: fix multibyte handling in "select" prompts diff --git a/Completion/Unix/Command/_uniq b/Completion/Unix/Command/_uniq index 479b3848d..d2e10494a 100644 --- a/Completion/Unix/Command/_uniq +++ b/Completion/Unix/Command/_uniq @@ -11,10 +11,8 @@ args=( '--group=-[show all items]::group separation [separate]:(separate prepend append both)' '(-i --ignore-case)'{-i,--ignore-case}'[ignore differences in case when comparing]' '(-s --skip-chars)'{-s,--skip-chars=}'[avoid comparing initial characters]:number of characters' - '(-t --separator)'{-t,--separator=}'[specify field delimiter]:separator' '(-u --unique)'{-u,--unique}'[only print unique lines]' '(-w --check-chars)'{-w,--check-chars=}'[specify maximum number of characters to compare]:characters' - '(-W --check-fields)'{-W,--check-fields=}'[specify maximum number of fields to compare]:fields' '(-z --zero-terminated)'{-z,--zero-terminated}'[delimit lines with null character, not newline]' '(- *)--help[display help information]' '(- *)--version[display version information]' -- cgit v1.2.3 From 87aba4d437f5fef46917c1235c00b9162d7bcbd0 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 27 Jan 2025 23:00:17 +0100 Subject: 53325: cover newer BSD releases in completion --- ChangeLog | 15 +++++++++++++++ Completion/BSD/Command/_acpiconf | 28 ++++++++++++++++++++++++++++ Completion/BSD/Command/_bsdconfig | 1 + Completion/BSD/Command/_pkgin | 2 ++ Completion/BSD/Command/_procstat | 35 ++++++++++++++++++----------------- Completion/BSD/Command/_sockstat | 5 +++++ Completion/BSD/Command/_systat | 1 + Completion/Unix/Command/_date | 17 ++++++++++++++--- Completion/Unix/Command/_df | 19 ++++++++++++------- Completion/Unix/Command/_dhclient | 1 + Completion/Unix/Command/_dmidecode | 6 ++++-- Completion/Unix/Command/_env | 14 +++++++++++--- Completion/Unix/Command/_iostat | 3 +++ Completion/Unix/Command/_last | 14 +++++++------- Completion/Unix/Command/_ls | 6 +++++- Completion/Unix/Command/_mv | 8 ++++---- Completion/Unix/Command/_ps | 2 +- Completion/Unix/Command/_script | 13 +++++++++++-- Completion/Unix/Command/_sed | 6 ++++-- Completion/Unix/Command/_vmstat | 6 +++++- Completion/Unix/Command/_w | 7 ++++++- Completion/Unix/Command/_wc | 2 +- Completion/Unix/Command/_zfs | 31 +++++++++++++++++++++++-------- 23 files changed, 182 insertions(+), 60 deletions(-) create mode 100644 Completion/BSD/Command/_acpiconf diff --git a/ChangeLog b/ChangeLog index ba7054a8e..2585d50e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2025-01-27 Oliver Kiddle + + * 53325: Completion/BSD/Command/_acpiconf, + Completion/BSD/Command/_bsdconfig, Completion/BSD/Command/_pkgin, + Completion/BSD/Command/_procstat, Completion/BSD/Command/_sockstat, + Completion/BSD/Command/_systat, Completion/Unix/Command/_date, + Completion/Unix/Command/_df, Completion/Unix/Command/_dhclient, + Completion/Unix/Command/_dmidecode, Completion/Unix/Command/_env, + Completion/Unix/Command/_iostat, Completion/Unix/Command/_last, + Completion/Unix/Command/_ls, Completion/Unix/Command/_mv, + Completion/Unix/Command/_ps, Completion/Unix/Command/_script, + Completion/Unix/Command/_sed, Completion/Unix/Command/_vmstat, + Completion/Unix/Command/_w, Completion/Unix/Command/_wc, + Completion/Unix/Command/_zfs: cover newer BSD releases in completion + 2025-01-20 Bart Schaefer * Julian Prein: 53309: Completion/Unix/Command/_uniq: remove diff --git a/Completion/BSD/Command/_acpiconf b/Completion/BSD/Command/_acpiconf new file mode 100644 index 000000000..817a2f1ad --- /dev/null +++ b/Completion/BSD/Command/_acpiconf @@ -0,0 +1,28 @@ +#compdef acpiconf + +local curcontext="$curcontext" sep ret=1 +local -a state line modes desc +local -A opt_args + +_arguments -s \ + '(-)-h[display usage information]' \ + '(-)-i[get battery information]:battery' \ + '(-)-k[ack or abort a pending suspend]:ack' \ + '(-)-s[enter specified sleep mode]: :->modes' && ret=0 + +if [[ -n $state ]]; then + modes=( $(_call_program modes sysctl -n hw.acpi.supported_sleep_state) ) + zstyle -s ":completion:${curcontext}:modes" list-separator sep || sep=-- + (( $#modes )) || modes=( S3 S4 ) + desc=( + "S1 $sep stop the processor clock" + "S2 $sep low wake latency sleep state" + "S3 $sep suspend to RAM" + "S4 $sep suspend to disk" + "S5 $sep soft off state" + ) + desc=( ${(M)desc:#(${(~j.|.)modes}) *} ) + _wanted modes expl 'mode' compadd -M 'B:S=' -ld desc - ${modes#S} && ret=0 +fi + +return ret diff --git a/Completion/BSD/Command/_bsdconfig b/Completion/BSD/Command/_bsdconfig index f88255575..5de8f777d 100644 --- a/Completion/BSD/Command/_bsdconfig +++ b/Completion/BSD/Command/_bsdconfig @@ -51,6 +51,7 @@ shortcuts=( vt_saver vt_screenmap vt_ttys + wifi wireless wlan ) _arguments -s -w -A '-*' : \ diff --git a/Completion/BSD/Command/_pkgin b/Completion/BSD/Command/_pkgin index 662bed181..c4ed3aa14 100644 --- a/Completion/BSD/Command/_pkgin +++ b/Completion/BSD/Command/_pkgin @@ -5,6 +5,8 @@ local -a state state_descr line expl cmds short pkgs local -A opt_args _arguments -s -S -C \ + '(-6)-4[only use IPv4 addresses]' \ + '(-4)-6[only use IPv6 addresses]' \ '-c+[enable chrooting pkgin in the given repository]:chroot path:_directories' \ '-d[download only]' \ '-f[force database update]' \ diff --git a/Completion/BSD/Command/_procstat b/Completion/BSD/Command/_procstat index a1708f6ac..867ddc501 100644 --- a/Completion/BSD/Command/_procstat +++ b/Completion/BSD/Command/_procstat @@ -1,26 +1,27 @@ #compdef procstat _arguments -s -A "-*" -S \ - '-b[show binary information]' \ - '-c[show command line arguments]' \ - '-e[show environment variables]' \ - '-f[show file descriptor information]' \ - '-i[show signal pending and disposition]' \ - '-j[show signal pending and blocked information for process threads]' \ - '-k[show stacks of kernel threads]' \ - '-l[show resource limits]' \ - "-L[show LWP info for the process pertaining to it's signal driven exit]" \ - '-r[show resource usage]' \ - '-s[show security credential information]' \ - '-S[show cpuset information]' \ - '-t[show thread information]' \ - '-v[show virtual memory mappings]' \ - '-x[show ELF auxiliary vector]' \ + '(1)-b[show binary information]' \ + '(1)-c[show command line arguments]' \ + '(1)-e[show environment variables]' \ + '(1)-f[show file descriptor information]' \ + '(1)-i[show signal pending and disposition]' \ + '(1)-j[show signal pending and blocked information for process threads]' \ + '(1)-k[show stacks of kernel threads]' \ + '(1)-l[show resource limits]' \ + "(1)-L[show LWP info for the process pertaining to it's signal driven exit]" \ + '(1)-r[show resource usage]' \ + '(1)-s[show security credential information]' \ + '(1)-S[show cpuset information]' \ + '(1)-t[show thread information]' \ + '(1)-v[show virtual memory mappings]' \ + '(1)-x[show ELF auxiliary vector]' \ '-h[suppress table headers]' \ - '(1)-a[all processes]' \ + '(2 *)-a[all processes]' \ '-w+[repeat information after specified interval]:delay (seconds)' \ '-C[print additional capability information for file descriptors]' \ '-H[statistics per-thread rather than per-process]' \ '-n[numeric form for signals]' \ - '1::core file:_path_files -g "*core*(-.)"' \ + '1::command:(advlock argument auxv basic binary cpuset credential environment fd file kstack pargs ptlwpinfo pwdx rlimit rlimitusage rusage sigfastblock signal thread tsignal vm)' \ + '2::core file:_path_files -g "*core*(-.)"' \ '*:process id:_pids' diff --git a/Completion/BSD/Command/_sockstat b/Completion/BSD/Command/_sockstat index f372fe1b3..b99d3681a 100644 --- a/Completion/BSD/Command/_sockstat +++ b/Completion/BSD/Command/_sockstat @@ -29,6 +29,11 @@ case $OSTYPE in '-q[quiet mode, do not print the header line]' ) ;| + freebsd<14->.*) + args+=( + '-I[show local address of socket to which the current socket is spliced]' + ) + ;| freebsd*) for proto in ${${(M)${(f)"$(.*) args+=( '-d+:daylight saving time value' @@ -77,6 +83,11 @@ else freebsd<14->.*|openbsd*) args+=( '-z+[specify timezone for output]:time zone:_time_zone') ;| + freebsd*) + args+=( + '(-R)-I-[display in ISO 8601 format]::precision [date]:(date hours minutes seconds ns)' + ) + ;| netbsd*) args+=( '-d[output date specified by string]:time string:' ) ;; diff --git a/Completion/Unix/Command/_df b/Completion/Unix/Command/_df index 21abff105..315758488 100644 --- a/Completion/Unix/Command/_df +++ b/Completion/Unix/Command/_df @@ -45,21 +45,25 @@ elif [[ "$OSTYPE" == (darwin|dragonfly|freebsd|netbsd*|openbsd)* ]]; then '-a[show all mount points]' '(-b -g -H -h -k -m --si)-g[use 1024^3-byte blocks]' '(-b -g -H -h -k -m --si)-m[use 1024*1024-byte blocks]' - ) - ;| - (darwin*|dragonfly*|freebsd*) - args+=( '(-b -g -H -h -k -m --si)-b[use 512-byte blocks (default)]' '(-b -g -H -h -k -m --si)-H[human-readable output (base 10)]' ) ;| - (darwin*|freebsd*) + (darwin*|freebsd*|netbsd*) args+=( '-c[display a grand total]' ) + ;| + (darwin*|freebsd*) + args+=( + '--libxo[generate output via libxo]' + '-,[separate thousands]' + ) ;| (darwin*) args+=( + '-I[suppress inode counts]' + '-Y[include file system type]' "-T+$spec" "!-t+$spec" # obsolete ) @@ -76,14 +80,15 @@ elif [[ "$OSTYPE" == (darwin|dragonfly|freebsd|netbsd*|openbsd)* ]]; then ;| (freebsd*) args+=( - '--libxo[generate output via libxo]' '(-b -g -H -h -k -m --si)--si[human-readable output (base 10)]' - '-,[separate thousands]' ) ;; (netbsd*) args+=( + '(-P -G -N)-f[display only the available free]' '(-G -i -P)-G[display all fields in statvfs]' + '(-G -P)-N[suppress the header line normally output]' + '-W[print widge name instead of the device]' ) ;; esac diff --git a/Completion/Unix/Command/_dhclient b/Completion/Unix/Command/_dhclient index e22586b04..f38e9a9e5 100644 --- a/Completion/Unix/Command/_dhclient +++ b/Completion/Unix/Command/_dhclient @@ -12,6 +12,7 @@ case $OSTYPE in args+=( '(-d)-b[immediately move to the background]' '-l+[specify leases file]:file:_files' + "-n[don't wait for ARP resolution]" '-p+[specify PID file]:file:_files' '-u[reject leases with unknown options]' '-q[quiet]' diff --git a/Completion/Unix/Command/_dmidecode b/Completion/Unix/Command/_dmidecode index e2c511313..62a950a7a 100644 --- a/Completion/Unix/Command/_dmidecode +++ b/Completion/Unix/Command/_dmidecode @@ -5,8 +5,10 @@ _arguments -s \ '(-)'{-h,--help}'[display usage information]' \ '(-q --quiet -u --dump)'{-q,--quiet}'[be less verbose]' \ '--no-quirks[decode everything without quirks]' \ - '(-t --type -H --handle -u --dump --dump-bin -s --string)'{-s+,--string=}'[only display value of specified DMI string]:DMI string:(bios-vendor bios-version bios-release-date system-manufacturer system-product-name system-version system-serial-number system-uuid baseboard-manufacturer baseboard-product-name baseboard-version baseboard-serial-number baseboard-asset-tag chassis-manufacturer chassis-type chassis-version chassis-serial-number chassis-asset-tag processor-family processor-manufacturer processor-version processor-frequency)' \ - '(-s --string -H --handle --dump-bin)*'{-t+,--type=}'[only display entries of specified type]:entry type:(bios system baseboard chassis processor memory cache connector slot)' \ + '(-t --type -H --handle -u --dump --dump-bin -s --string)'{-s+,--string=}'[only display value of specified DMI string]:DMI string:compadd -M "r\:|-=* r\:|=*" - $(_call_program strings dmidecode --list-strings)' \ + '--list-strings[list available string keywords]' \ + '(-s --string -H --handle --dump-bin)*'{-t+,--type=}'[only display entries of specified type]:entry type:compadd - $(_call_program types dmidecode --list-types)' \ + '--list-types[list available type keywords]' \ '(-s --string -t --type -H --handle --dump-bin)'{-H,--handle=}'[only display the entry of specified handle]:handle' \ '(-q --quiet -u --dump -s --string)'{-u,--dump}"[don't decode entries]" \ '(-s --string -t --type -H --handle)--dump-bin=[dump DMI data to a binary file]:file:_files' \ diff --git a/Completion/Unix/Command/_env b/Completion/Unix/Command/_env index 8cf0ad467..89a45e4a4 100644 --- a/Completion/Unix/Command/_env +++ b/Completion/Unix/Command/_env @@ -8,6 +8,7 @@ case $variant in gnu) (( $#words > 2 )) && ign='!' args=( + '(-a --argv0)'{-a+,--argv0=}'[pass argument as the zeroth argument of command]:argument' '(-)'{-i,--ignore-environment}'[start with empty environment]' '(* -0 --null)'{-0,--null}'[end each output line with NUL, not newline]' '(--ignore-environment -i --help --version)*'{-u+,--unset=}'[remove variable from the environment]:env var to remove:_parameters -g "*export*"' @@ -28,12 +29,19 @@ case $variant in '-U[add variables from user and system login.conf(5)]: :->user-class' ) ;| - freebsd*|darwin*) - args=( '-0[use NUL, not newline after each variable in output]' ) + freebsd*|netbsd*) + args+=( '-C+[change working directory]:directory:_directories' ) ;| - freebsd*|darwin*|dragonfly*) + freebsd*|darwin*|netbsd*) + args+=( '-0[use NUL, not newline after each variable in output]' ) + ;| + freebsd*|darwin*|dragonfly*|netbsd*|openbsd*) args+=( '(-i)*-u+[remove variable from the environment]:env var to remove:_parameters -g "*export*"' + ) + ;| + freebsd*|darwin*|dragonfly*) + args+=( '-P+[specify alternate executable search PATH]:path:_dir_list' '-S+[perform word splitting]:string to split' '*-v[verbose output]' diff --git a/Completion/Unix/Command/_iostat b/Completion/Unix/Command/_iostat index d3943fcb4..36a3b7904 100644 --- a/Completion/Unix/Command/_iostat +++ b/Completion/Unix/Command/_iostat @@ -50,6 +50,9 @@ case $OSTYPE:l in args+=( '-x[show extended disk statistics]' '-y[report data on waiting and active requests]' + '-z[replace drive and CPU statistics that are zero with spaces]' + "-H+[set page height explicitly]:height [$LINES]" + "-W+[set page width explicitly]:width [$COLUMNS]" ) ;; aix*) diff --git a/Completion/Unix/Command/_last b/Completion/Unix/Command/_last index 2013cc1c2..d76260c36 100644 --- a/Completion/Unix/Command/_last +++ b/Completion/Unix/Command/_last @@ -8,17 +8,16 @@ ttys=( ${ttys#/dev/} ) for pattern arg in \ '(solaris*|linux-gnu)' '(--hostlast)-a[display hostname in last column]' \ '((free|net|open)bsd*|darwin*|dragonfly*)' '-h+[limit sessions by hostname]:host:_hosts' \ - '((free|open)bsd*)' '-s[report duration in seconds]' \ - '(freebsd*|openbsd*)' '-d+[limit sessions to those active at snapshot time]:time ([[CC]YY][MMDD]hhmm[.SS])' \ + '((free|open)bsd*|darwin*)' '-s[report duration in seconds]' \ + '((free|open)bsd*|darwin*)' '-d+[limit sessions to those active at snapshot time]:time ([[CC]YY][MMDD]hhmm[.SS])' \ '((net|free|open)bsd*|darwin*|dragonfly*)' '-t+[limit sessions by tty]:tty:_ttys -D' \ 'openbsd*' '-c[calculate total time]' \ - '^darwin*' '(--file)-f+[specify account file]:file:_files' \ - '(solaris*|linux-gnu|freebsd*|openbsd*)' '(--limit)-n+[specify number of lines to show]:number' \ + '(solaris*|darwin*|linux-gnu|freebsd*|openbsd*)' '(--limit)-n+[specify number of lines to show]:number' \ '((open|net)bsd*|dragonfly*)' '-T[show more detailed time information including year and seconds]' \ 'netbsd*' '-x[assume file is in wtmpx(5) format]' \ 'netbsd*' '-n[show IP of remote hosts]' \ - 'freebsd*' '-w[show seconds in duration field]' \ - 'freebsd*' '-y[show year in session start time]' + '(freebsd*|darwin*)' '-w[show seconds in duration field]' \ + '(freebsd*|darwin*)' '-y[show year in session start time]' do [[ $OSTYPE = $~pattern ]] && args+=( $arg ) done @@ -58,4 +57,5 @@ else args+=( '*:user:_users' ) fi -_arguments -s -S $args +_arguments -s -S $args \ + '(--file)-f+[specify account file]:file:_files' diff --git a/Completion/Unix/Command/_ls b/Completion/Unix/Command/_ls index 392b8490b..a19ad30e2 100644 --- a/Completion/Unix/Command/_ls +++ b/Completion/Unix/Command/_ls @@ -61,12 +61,16 @@ if ! _pick_variant gnu=gnu unix --help; then '(-l -1 -C -m -x)-g[long listing but without owner information]' ) fi + if [[ $OSTYPE = (netbsd*|darwin*) ]]; then + arguments+=( + "-X[don't cross mount points when recursing]" + ) + fi if [[ $OSTYPE = netbsd* ]]; then arguments+=( '-M[output file sizes in comma-separated form]' '-O[output only leaf (non-directory) files]' '-P[print full pathname for each file]' - "-X[don't cross mount points when recursing]" ) fi if [[ $OSTYPE = (dragonfly*|freebsd*|openbsd*|darwin*) ]]; then diff --git a/Completion/Unix/Command/_mv b/Completion/Unix/Command/_mv index c52e7a5e4..983c25ea8 100644 --- a/Completion/Unix/Command/_mv +++ b/Completion/Unix/Command/_mv @@ -38,11 +38,11 @@ case $variant; in '(-f -n)-i[prompt before overwriting existing file]' ) ;| + darwin*|dragonfly*|freebsd*|netbsd*) + args+=( "-h[if target is a symlink to a directory, don't follow it]" ) + ;| darwin*|dragonfly*|freebsd*) - args+=( - "(-f -i)-n[don't overwrite existing file]" - "-h[if target is a symlink to a directory, don't follow it]" - ) + args+=( "(-f -i)-n[don't overwrite existing file]" ) ;| darwin*|dragonfly*|*bsd*) args+=( diff --git a/Completion/Unix/Command/_ps b/Completion/Unix/Command/_ps index c3dfae47d..158fb6b83 100644 --- a/Completion/Unix/Command/_ps +++ b/Completion/Unix/Command/_ps @@ -106,9 +106,9 @@ case $OSTYPE in ;| linux-gnu|netbsd*) bsdarg+=( 'k[specify sort order]' ) ;| linux-gnu|openbsd*) bsd+=( 'f[show process hierarchy]' ) ;| + darwin*|freebsd*|netbsd*) bsdarg+=( '*G[select processes by real group]' ) ;| darwin*|freebsd*) bsd+=( 'X[skip processes with no controlling terminal]' ) - bsdarg+=( '*G[select processes by real group]' ) ;| freebsd*|dragonfly*) bsd+=( 'f[show command and environment for swapped out processes]' ) diff --git a/Completion/Unix/Command/_script b/Completion/Unix/Command/_script index d38d56f2e..25f8ea35f 100644 --- a/Completion/Unix/Command/_script +++ b/Completion/Unix/Command/_script @@ -50,19 +50,28 @@ case $OSTYPE in '(-d -p -T)-r[record a session with input, output and timing data]' ) ;| + darwin*|netbsd*|freebsd*) + args+=( + '-e[return exit status of the child process]' + ) + ;| netbsd*|openbsd*) args+=( '-c[run specified command instead of a shell]:command:_cmdstring' ) ;| + darwin*|freebsd*) + args+=( + '(-a -r -k -t)-T[play back a recorded session, reporting only timestamps]: :_date_formats' + ) + ;| netbsd*) args+=( '-f[flush output after each write]' ) ;| freebsd*) args+=( - '-e[return exit status of the child process]' '-f[use filemon(4)]' - '(-a -r -k -t)-T[play back a recorded session, reporting only timestamps]: :_date_formats' + '-w[forward terminal size changes on SIGWINCH]' ) ;| darwin*|dragonfly*|freebsd*) diff --git a/Completion/Unix/Command/_sed b/Completion/Unix/Command/_sed index ef3aaf2fd..ecbec61d1 100644 --- a/Completion/Unix/Command/_sed +++ b/Completion/Unix/Command/_sed @@ -104,7 +104,7 @@ else case $OSTYPE in openbsd*|freebsd*|netbsd*|darwin*|dragonfly*) args+=( - '(-r -E)'{-E,-r}$extended + '(-r -E -H)'{-E,-r}$extended '-a[delay opening files listed with w function]' ) ;| @@ -115,8 +115,10 @@ else args+=( '-I+[edit files in-place, treating all files as a single input stream]:: :_guard "^(*[@/; \\\]*|?(#c6,)|-*)" "suffix for backup"' ) - ;; + ;| openbsd*) args+=( '-u[make output line buffered]' ) ;; + darwin*) args+=( '(-r -E)-H[use enhanced regular expressions]' ) ;; + netbsd*) args+=( '(-r -E)-g[use GNU regular expressions]' '!(-r -E -g)-G' ) ;; esac fi diff --git a/Completion/Unix/Command/_vmstat b/Completion/Unix/Command/_vmstat index 6db776e62..1d0ac855d 100644 --- a/Completion/Unix/Command/_vmstat +++ b/Completion/Unix/Command/_vmstat @@ -37,10 +37,14 @@ case $OSTYPE in '-f[report on the number fork syscalls since boot and pages of virtual memory for each]' ) ;| + freebsd*|dragonfly*|netbsd*) + specs+=( + '-n+[change the maximum number of disks to display]:number of disks to display [2]' + ) + ;| freebsd*|dragonfly*) specs+=( '-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 [2]' '*-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]' diff --git a/Completion/Unix/Command/_w b/Completion/Unix/Command/_w index e82c84f57..408cb76af 100644 --- a/Completion/Unix/Command/_w +++ b/Completion/Unix/Command/_w @@ -23,7 +23,7 @@ case $OSTYPE in openbsd*) args+=( '-a[translate network addresses into names]' ) ;| - (free|net)bsd*|dragonfly*) + (free|net)bsd*|dragonfly*|darwin*) args+=( '-n[show network addresses as numbers]' ) ;| *bsd*|dragonfly*) @@ -35,6 +35,11 @@ case $OSTYPE in freebsd*|dragonfly*) args+=( '-d[dump process list on a per controlling tty basis]' ) ;| + netbsd*) + args+=( + '-A[sort tty names alphabetically instead of utmp or utmpx order]' + ) + ;| solaris*) args+=( '!(-s -w -l)'{-l,-w} '-s[short output form]' diff --git a/Completion/Unix/Command/_wc b/Completion/Unix/Command/_wc index a1897e289..2a4f7ab05 100644 --- a/Completion/Unix/Command/_wc +++ b/Completion/Unix/Command/_wc @@ -18,7 +18,7 @@ if _pick_variant gnu=GNU unix --version; then else args=( -A "-*" "${(@)args:#(|\(*\))(|\*)--*}" ) case $OSTYPE in - freebsd*|netbsd*) args+=( '-L[print longest line lengths]' ) ;; + freebsd*|netbsd*|darwin*) args+=( '-L[print longest line lengths]' ) ;; openbsd*) args+=( '-h[human readable: use unit suffixes]' ) ;; solaris*) args+=( ${${(M)args:#*-m\[*}//-m\[/-C\[} ) ;; esac diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index c09435a1f..5a45c2920 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -79,7 +79,7 @@ rw_ds_props=( 'paths:mountpoint:_directories -W / -P /'" 'multilevel:value:(on off)' 'nbmand:value:(on off)' - 'primarycache:value:(all none metadata)' + {prefetch,primarycache}':value:(all none metadata)' 'quota: :->quotas' 'readonly:value:(on off)' 'recordsize:value:(512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M)' @@ -515,9 +515,11 @@ case $service:$words[1] in ;; zfs:set) - [[ $implementation = solaris ]] && args=( - '-r[recursively apply value]' \ - ) + if [[ $implementation = solaris ]]; then + args=( '-r[recursively apply value]' ) + else + args=( "-u[update property but don't mount or share dataset]" ) + fi _arguments -C -A "-*" -S $args \ ':property:->set-properties' \ '*:filesystem/volume:_zfs_dataset -t fs -t vol' @@ -598,13 +600,14 @@ case $service:$words[1] in zfs:mount) [[ $OSTYPE != freebsd* ]] && args=( '-O[overlay mount]' ) [[ $implementation = openzfs ]] && args+=( - '-l[load keys for encrypted filesystems as they are being mounted]' + '-l[load keys for encrypted filesystems as they are being mounted]' + '(-a)-R[mount filesystems along with all their children]' ) _arguments -A "-*" -S $args \ '-o+[specify temporary file system options]: :_values -s , "option" {,no}{atime,dev,exec,relatime,suid,xattr} ro rw' \ '-v[report mount progress]' \ '-f[force mount]' \ - '(:)-a[mount all available ZFS filesystems]' \ + '(: -R)-a[mount all available ZFS filesystems]' \ '(-a):filesystem:_zfs_dataset -t fs' ;; @@ -888,6 +891,12 @@ case $service:$words[1] in ':property:($delegatable_perms $ro_ds_props ${rw_ds_props%%:*})' ;; + zpool:(clear|online)) + [[ $OSTYPE = linux* ]] && args=( + "--power[power on the device's slot in the storage enclosure]" + ) + ;| + zpool:help) _arguments -A "-*" -S \ - commands \ @@ -905,6 +914,7 @@ case $service:$words[1] in '-L[display real paths for vdevs resolving all symbolic links]' '-o+[set given pool properties]: :_values -s , "property" "${(@M)ci_po_props\:#ashift*}"' \ '-P[display real paths for vdevs instead of only the last component of the path]' + --allow-ashift-mismatch --allow-in-use --allow-replication-mismatch ) elif [[ $implementation = solaris ]]; then args=( '-l[display configuration in /dev/chassis location form]' ) @@ -1004,7 +1014,7 @@ case $service:$words[1] in zpool:get) [[ $implementation = solaris ]] && args=( - '-s+[specify sources to display]: :_values -s "source" local default none' + '-s+[specify sources to display]: :_values -s , "source" local default none' ) _arguments -A "-*" -S $args \ '-H[suppress headers and tab-delimit fields]' \ @@ -1140,6 +1150,9 @@ case $service:$words[1] in [[ $implementation = openzfs ]] && args=( '-f[force disk into faulted state]' ) + [[ $OSTYPE = linux* ]] && args=( + "--power[power off the device's slot in the storage enclosure]" + ) _arguments -C -A "-*" -S $args \ '-t[offline until next reboot]' \ ':pool:_zfs_pool' \ @@ -1147,7 +1160,7 @@ case $service:$words[1] in ;; zpool:online) - _arguments -C -A "-*" -S \ + _arguments -C -A "-*" -S $args \ '-e[expand device to use all available space]' \ ':pool:_zfs_pool' \ '*:virtual device:->pool-devices' @@ -1234,8 +1247,10 @@ case $service:$words[1] in zpool:status) if [[ $implementation = openzfs ]]; then args=( + '--power[display vdev enclosure slot power status]' '-D[display a histogram of deduplication statistics]' '-c[run scripts on each vdev]:script:_files -W "($ZPOOL_SCRIPTS_PATH /etc/zfs/zpool.d ~/.zpool.d)"' + '-e[only show unhealthy vdevs]' '-i[display vdev initialization status]' '-g[display vdev GUIDs instead of the normal device names]' '-L[display real paths for vdevs resolving all symbolic links]' -- cgit v1.2.3 From f3b865b9155269ba0dee7ced93b061e78df507c1 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 27 Jan 2025 23:06:16 +0100 Subject: 53326: completion updates for core Linux utils --- ChangeLog | 14 ++++++++++++++ Completion/Linux/Command/_findmnt | 14 ++++++++++---- Completion/Linux/Command/_free | 1 + Completion/Linux/Command/_losetup | 3 ++- Completion/Linux/Command/_lsblk | 7 ++++++- Completion/Linux/Command/_pidof | 1 + Completion/Linux/Command/_slabtop | 2 +- Completion/Linux/Command/_wipefs | 3 ++- Completion/Unix/Command/_awk | 1 + Completion/Unix/Command/_chmod | 14 +++++++------- Completion/Unix/Command/_chown | 3 +-- Completion/Unix/Command/_cmp | 2 +- Completion/Unix/Command/_find | 1 - Completion/Unix/Command/_hexdump | 1 + Completion/Unix/Command/_last | 1 + Completion/Unix/Command/_mv | 3 ++- Completion/Unix/Command/_objdump | 6 ++++-- Completion/Unix/Command/_pgrep | 1 + Completion/Unix/Command/_ping | 5 ++++- Completion/Unix/Command/_ps | 1 + Completion/Unix/Command/_readelf | 7 +++++-- Completion/Unix/Command/_strip | 1 + Completion/Unix/Command/_uptime | 7 ++++--- Completion/Unix/Command/_w | 1 + 24 files changed, 72 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2585d50e8..c5db038e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2025-01-27 Oliver Kiddle + * 53326: Completion/Linux/Command/_findmnt, + Completion/Linux/Command/_free, Completion/Linux/Command/_losetup, + Completion/Linux/Command/_lsblk, Completion/Linux/Command/_pidof, + Completion/Linux/Command/_slabtop, Completion/Linux/Command/_wipefs, + Completion/Unix/Command/_awk, Completion/Unix/Command/_chmod, + Completion/Unix/Command/_chown, Completion/Unix/Command/_cmp, + Completion/Unix/Command/_find, Completion/Unix/Command/_hexdump, + Completion/Unix/Command/_last, Completion/Unix/Command/_mv, + Completion/Unix/Command/_objdump, Completion/Unix/Command/_pgrep, + Completion/Unix/Command/_ping, Completion/Unix/Command/_ps, + Completion/Unix/Command/_readelf, Completion/Unix/Command/_strip, + Completion/Unix/Command/_uptime, Completion/Unix/Command/_w: + completion updates for core Linux utils + * 53325: Completion/BSD/Command/_acpiconf, Completion/BSD/Command/_bsdconfig, Completion/BSD/Command/_pkgin, Completion/BSD/Command/_procstat, Completion/BSD/Command/_sockstat, diff --git a/Completion/Linux/Command/_findmnt b/Completion/Linux/Command/_findmnt index b29372c39..6155d4dc1 100644 --- a/Completion/Linux/Command/_findmnt +++ b/Completion/Linux/Command/_findmnt @@ -8,6 +8,7 @@ # local curcontext=$curcontext state state_descr line ret=1 typeset -A opt_args +local -a suf dedup _arguments -s -C \ '(H -A --all)'{-A,--all}'[print all filesystems]' \ @@ -45,6 +46,7 @@ _arguments -s -C \ '(H)2:: :->targets' \ + '(format)' \ '(H)'{-D,--df}'[imitate the output of df command]' \ + '(H)'{-I,--dfi}'[imitate the output of df with -i option]' \ '(H)'{-J,--json}'[use JSON output format]' \ '(H)'{-l,--list}'[use list output format]' \ '(H)'{-P,--pairs}'[use key="value" output format]' \ @@ -55,6 +57,7 @@ _arguments -s -C \ '(H)'{-N+,--task=}'[search /proc//mountinfo]: :_pids' \ '(H)'{-s,--fstab}'[search in /etc/fstab]' \ + '(H)' \ + '(* -)'{-H,--list-columns}'[list available columns]' \ '(- :)'{-h,--help}'[display help text and exit]' \ '(- :)'{-V,--version}'[display version and exit]' \ && ret=0 @@ -66,13 +69,16 @@ __findmnt_mountpoints () { case $state in columns) + dedup=( ${(Ms.,.)${PREFIX#+}##*,} ${(Ms.,.)SUFFIX%%,*} ) + suf=( -qS , ) + compset -S ',*' && suf=() compset -P '+' || _describe -t list-prefixes prefix \ - '( +:"not replace but extend the list" )' -S '' && ret=0 + '( +:"not replace but extend the list" )' -S '' && ret=0 + compset -P '*,' local -a columns=( - ${${${(f)"$(_call_program columns findmnt -h)"}[(r)Available*,-2]}[2,-1]} + ${${${${(f)"$(_call_program columns findmnt --list-columns)"}## #}//:/\\:}/ <[^>]#> #/:} ) - columns=( ${${${${${${columns## #}//:/\\:}//\[/\\[}//]/\\]}/ /[}/%/]} ) - _values -s , -M 'm:{a-z}={A-Z}' column $columns && ret=0 + _describe -t fields column columns -M 'm:{a-z}={A-Z}' $suf -F dedup && ret=0 ;; *) # call "findmnt $opts" to get possible sources/targets local opts='-lnve' diff --git a/Completion/Linux/Command/_free b/Completion/Linux/Command/_free index a0da97446..376b8a21f 100644 --- a/Completion/Linux/Command/_free +++ b/Completion/Linux/Command/_free @@ -2,6 +2,7 @@ _arguments -s \ '(-l --lohi)'{-l,--lohi}'[show detailed low and high memory statistics]' \ + '(-L --line)'{-L,--line}'[show output on a single line]' \ '(-t --total)'{-t,--total}'[show total for RAM + swap]' \ '(-v --committed)'{-v,--committed}'[show committed memory and commit limit]' \ '(-w --wide)'{-w,--wide}'[wide mode]' \ diff --git a/Completion/Linux/Command/_losetup b/Completion/Linux/Command/_losetup index f5a7ec1b1..d8e792aaf 100644 --- a/Completion/Linux/Command/_losetup +++ b/Completion/Linux/Command/_losetup @@ -18,7 +18,7 @@ _arguments -s -S \ - 'info' \ '(-v --verbose)'{-v,--verbose}'[verbose mode]' \ '(-o --offset -a --all)'{-a,--all}'[show the status of all loop devices]' \ - '(-O --output --output-all)'{-O+,--output=}'[specify columns to be printed with --list]:column:_sequence -s , compadd - name autoclear back-file back-ino back-maj\:min maj\:min offset partscan ro sizelimit dio log-sec' \ + '(-O --output --output-all)'{-O+,--output=}'[specify columns to be printed with --list]:column:_sequence -s , compadd -M "B\:+=" - name autoclear back-file back-ino back-maj\:min back-maj back-min maj\:min maj min offset partscan ref ro sizelimit dio log-sec' \ '(-O --output)--output-all[output all columns]' \ '(-J --json --raw -O --output -n --noheadings)'{-J,--json}'[use JSON --list output format]' \ '(-l --list)'{-l,--list}'[list currently used loop devices]' \ @@ -33,6 +33,7 @@ _arguments -s -S \ {-D,--detach-all}'[detach all associated loop devices]' \ - 'create' \ '--direct-io[open backing file with O_DIRECT]::enable:(on off)' \ + '--loop-ref=[specify loop device reference]:string' \ '(-f --find 1)'{-f,--find}'[find the first unused loop device]' \ '(-L --nooverlap)'{-L,--nooverlap}'[avoid possible conflict between devices]' \ '(-P --partscan)'{-P,--partscan}'[scan the partition table of newly created loop devices]' \ diff --git a/Completion/Linux/Command/_lsblk b/Completion/Linux/Command/_lsblk index 63aac743c..c8b30eb5e 100644 --- a/Completion/Linux/Command/_lsblk +++ b/Completion/Linux/Command/_lsblk @@ -8,6 +8,10 @@ typeset -A opt_args _arguments -C -s -S \ '(H -A --noempty)'{-A,--noempty}"[don't print empty devices]" \ '(H -E --dedup)'{-E+,--dedup=}'[de-duplicate output by specified column]:column:->columns' \ + '(H -Q --filter)'{-Q+,--filter=}'[only print lines matching expression]:expression' \ + '(H)--highlight=[color lines matching expression]:expression' \ + '(H)*--ct-filter=[restrict the next counter]:expression' \ + '(H)*--ct=[define a custom counter]:name\:param\:func' \ '(H -a --all)'{-a,--all}'[print all devices]' \ '(H -b --bytes)'{-b,--bytes}'[print size in bytes rather than in human readable format]' \ '(H -d --nodeps)'{-d,--nodeps}"[don't print slaves or holders]" \ @@ -40,6 +44,7 @@ _arguments -C -s -S \ '(H)'{-P,--pairs}'[use key="value" output format]' \ '(H)'{-r,--raw}'[use raw output format]' \ + 'H' \ + '(* -)'{-H,--list-columns}'[list the available columns]' \ '(* -)'{-h,--help}'[display help information]' \ '(* -)'{-V,--version}'[display version information]' && ret=0 @@ -56,7 +61,7 @@ case $state in ;| column*) values=( - ${${${${(f)"$(_call_program columns lsblk -h)"}[(r)Available*,-2]## #}[2,-1]//:/\\:}/ /:} + ${${${${(f)"$(_call_program columns lsblk --list-columns)"}## #}//:/\\:}/ <[^>]#> #/:} ) _describe -t fields column values -M 'm:{a-z}={A-Z}' $suf -F dedup && ret=0 ;; diff --git a/Completion/Linux/Command/_pidof b/Completion/Linux/Command/_pidof index 151a0e0f6..fdafd507d 100644 --- a/Completion/Linux/Command/_pidof +++ b/Completion/Linux/Command/_pidof @@ -17,6 +17,7 @@ case $variant in '(-w --with-workers)'{-w,--with-workers}'[show kernel workers too]' \ "(-x $exargs)"-x'[include shells running named scripts]' \ "($exargs)"\*{-o+,--omit-pid=}'[omit processes with PIDs]:pids:_sequence -s , _pids' \ + '(-t --lightweight)'{-t,--lightweight}'[list threads too]' \ '(-S --separator)'{-S+,--separator=}'[specify separator put between PIDs]:separator' \ '*:process:->procnames' \ && return 0 diff --git a/Completion/Linux/Command/_slabtop b/Completion/Linux/Command/_slabtop index 5c8919d12..2021ec332 100644 --- a/Completion/Linux/Command/_slabtop +++ b/Completion/Linux/Command/_slabtop @@ -1,5 +1,4 @@ #compdef slabtop -# based on procps-ng-3.3.15 local -a criteria=( 'a:number of active objects' @@ -18,5 +17,6 @@ _arguments -s \ '(-d --delay -o --once)'{-d+,--delay=}'[specify the delay between updates]:seconds: ' \ '(-s --sort)'{-s+,--sort=}'[specify the sort criteria]:criteria:(($criteria))' \ '(-d --delay -o --once)'{-o,--once}'[display the output once and exit]' \ + '--human[show human-readable output]' \ '(-)'{-V,--version}'[display version information and exit]' \ '(-)'{-h,--help}'[display usage information and exit]' diff --git a/Completion/Linux/Command/_wipefs b/Completion/Linux/Command/_wipefs index 8642aab92..5cc97e85f 100644 --- a/Completion/Linux/Command/_wipefs +++ b/Completion/Linux/Command/_wipefs @@ -2,7 +2,8 @@ _arguments -s -S \ '(H -a --all)'{-a,--all}'[wipe all magic strings]' \ - '(H -b --backup)'{-b,--backup}'[create a signature backup in $HOME]' \ + '(H --backup)-b[create a signature backup in $HOME]' \ + '(H -b)--backup=-[create a signature backup in $HOME]::path [$HOME]:_directories' \ '(H -f --force)'{-f,--force}'[force erasure]' \ '(H -i --no-headings -J --json -p --parsable)'{-i,--no-headings}"[don't print headings]" \ '(H -J --json -i --no-headings -p --parsable)'{-J,--json}'[use JSON output format]' \ diff --git a/Completion/Unix/Command/_awk b/Completion/Unix/Command/_awk index b69cc5cf8..694749d7d 100644 --- a/Completion/Unix/Command/_awk +++ b/Completion/Unix/Command/_awk @@ -51,6 +51,7 @@ case $variant in {-g,--gen-pot}'[scan awk program and generate .po file on stdout]' '*'{-i+,--include}'[load source library]:library file:->script' {-I,--trace}'[print internal byte code names as they are executed]' + '(-k --csv)'{-k,--csv}'[enable CSV special processing]' '*'{-l+,--load}'[load dynamic extension]:extension:->extension' {-M,--bignum}'[select arbitrary-precision arithmetic on numbers]' {-o-,--pretty-print=-}'[pretty-print awk program]::output file:_files' diff --git a/Completion/Unix/Command/_chmod b/Completion/Unix/Command/_chmod index 693f348dc..5ec60d707 100644 --- a/Completion/Unix/Command/_chmod +++ b/Completion/Unix/Command/_chmod @@ -19,6 +19,13 @@ case "$variant" in '*: :->files' ) ;; + gnu|freebsd*|openbsd*|netbsd*|darwin*|dragonfly*) + args+=( + '(-H -L -P)-L[follow all symlinks]' + '(-H -L -P)-H[follow symlinks on the command line]' + '(-H -L -P)-P[do not follow symlinks (default)]' + ) + ;| gnu) aopts=() args+=( @@ -49,13 +56,6 @@ case "$variant" in '-h[operate on symlinks themselves]' ) ;| - freebsd*|openbsd*|netbsd*|darwin*|dragonfly*) - args+=( - '(-H -L -P)-L[follow all symlinks]' - '(-H -L -P)-H[follow symlinks on the command line]' - '(-H -L -P)-P[do not follow symlinks (default)]' - ) - ;| darwin*) args+=( '(1)-C[return false if any specified files have ACLs]' diff --git a/Completion/Unix/Command/_chown b/Completion/Unix/Command/_chown index bcc6aec2f..c9fe8fadd 100644 --- a/Completion/Unix/Command/_chown +++ b/Completion/Unix/Command/_chown @@ -13,6 +13,7 @@ case "$variant" in '(-h --no-dereference)--dereference[dereference symlinks]' '(-h --no-dereference --dereference)'{-h,--no-dereference}'[operate on symlinks themselves]' '(-f --silent --quiet)'{-f,--silent,--quiet}"[don't report errors]" + '--from=[restrict changes to files by current ownership]: :->owner' '--preserve-root[fail to operate recursively on /]' '--reference=[copy ownership of specified file]:file:_files' '(-R --recursive)'{-R,--recursive}'[change files and directories recursively]' @@ -22,8 +23,6 @@ case "$variant" in '(- : *)--help[display help information]' '(- : *)--version[display version information]' ) - [[ $service = chown ]] && - args+=( '--from=[restrict changes to files by current ownership]: :->owner' ) ;; *) args=( diff --git a/Completion/Unix/Command/_cmp b/Completion/Unix/Command/_cmp index 20d309e32..d0a4caa41 100644 --- a/Completion/Unix/Command/_cmp +++ b/Completion/Unix/Command/_cmp @@ -15,7 +15,7 @@ case $variant in units=":_numbers -u bytes offset K M G T P E Z Y" ;| gnu) - args=( + args+=( '(- *)'{-v,--version}'[display version information]' '(- *)--help[display help information]' ) diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find index 4f1c338ee..95e4fac4e 100644 --- a/Completion/Unix/Command/_find +++ b/Completion/Unix/Command/_find @@ -109,7 +109,6 @@ case $variant in '-regextype:regexp syntax:(help findutils-default awk egrep ed emacs gnu-awk grep posix-awk posix-basic posix-egrep posix-extended posix-minimal-basic sed)' '*-warn' '*-nowarn' - '*-xautofs' '*-used:access after inode change (days)' '*-executable' '*-readable' diff --git a/Completion/Unix/Command/_hexdump b/Completion/Unix/Command/_hexdump index f700ca683..140422ac1 100644 --- a/Completion/Unix/Command/_hexdump +++ b/Completion/Unix/Command/_hexdump @@ -25,6 +25,7 @@ if [[ $OSTYPE = linux* ]]; then '(- *)'{-h,--help}'[display usage information]' '(- *)'{-V,--version}'[display version information]' ) + fmts+=( {--one-byte-hex,-X}'[one-byte hexadecimal display]' ) else # strip long options by taking every second element print -v fmts -f '%2$s' -- "$fmts[@]" diff --git a/Completion/Unix/Command/_last b/Completion/Unix/Command/_last index d76260c36..240b96e67 100644 --- a/Completion/Unix/Command/_last +++ b/Completion/Unix/Command/_last @@ -41,6 +41,7 @@ case $OSTYPE in '(-R --nohostname)'{-R,--nohostname}'[suppress display of hostname field]' '(-s --since)'{-s+,--since=}'[display lines since the specified time]:time (YYYYMMDDhhmmss)' '(-t --until)'{-t+,--until=}'[display lines until the specified time]:time (YYYYMMDDhhmmss)' + '(-T --tab-separated)'{-T,--tab-separated}'[use tabs as delimiters]' '(-p --present)'{-p+,--present=}'[display who were present at the specified time]:time (YYYYMMDDhhmmss)' '(-w --fullnames)'{-w,--fullnames}'[show full user and domain names]' '(-x --system)'{-x,--system}'[display shutdown/runlevel entries]' diff --git a/Completion/Unix/Command/_mv b/Completion/Unix/Command/_mv index 983c25ea8..e9227c334 100644 --- a/Completion/Unix/Command/_mv +++ b/Completion/Unix/Command/_mv @@ -14,6 +14,7 @@ case $variant; in {simple,never}"[always make simple backups]"' '(-b --backup -n --no-clobber)-b[make a backup of each existing destination file]' '(-v)--debug[explain how a file is copied]' + '--exchange[exchange source and destination]' '(-f --force -i --interactive -n --no-clobber)'{-f,--force}"[don't prompt before overwriting]" '(-f --force -i --interactive -n --no-clobber)'{-i,--interactive}'[prompt before overwriting existing file]' '(-f --force -i --interactive -n --no-clobber)'{-n,--no-clobber}"[don't overwrite existing file]" @@ -22,7 +23,7 @@ case $variant; in '(-S --suffix)'{-S+,--suffix=}'[specify the backup suffix]:backup suffix [~]' '(-t --target-directory)'{-t+,--target-directory=}'[move all source arguments into specified directory]:directory:_directories' '(-T --no-target-directory)'{-T,--no-target-directory}'[treat final argument as a normal file]' - '(-u)--update=-[move only when destination file is older or missing]::update files [older]:(all none older)' + '(-u)--update=-[move only when destination file is older or missing]::update files [older]:(all none none-fail older)' '(--update)-u[move only when destination file is older or missing]' '(-v --verbose)'{-v,--verbose}'[show file names after they are moved]' '(- *)--help[display usage information]' diff --git a/Completion/Unix/Command/_objdump b/Completion/Unix/Command/_objdump index 94c01eb83..71a615c97 100644 --- a/Completion/Unix/Command/_objdump +++ b/Completion/Unix/Command/_objdump @@ -32,6 +32,7 @@ case $variant in '(-D --disassemble-all)'{-D,--disassemble-all}'[display assembler contents of all sections]' '(-S --source)'{-S,--source}'[intermix source code with disassembly]' '--source-comment=-[prefix lines of source code with specified text]::text prefix [# ]' + '(-Z --decompress)'{-Z,--decompress}'[decompress section(s) before displaying their contents]' '(-g --debugging)'{-g,--debugging}'[display debug information in object file]' '(-e --debugging-tags)'{-e,--debugging-tags}'[display debug information using ctags style]' '(-G --stabs)'{-G,--stabs}'[display (in raw form) any STABS info in the file]' @@ -176,13 +177,14 @@ case "$state" in 'O[str-offsets]' \ "o[loc]" "R[ranges]" "t[pubtypes]" "U[trace_info]" "u[trace_abbrev]" \ "T[trace_aranges]" "g[gdb_index]" "A[addr]" "c[cu_index]" "k[links]" \ - "K[follow-links]" && ret=0 + "K[follow-links]" "D[use-debuginfod]" "E[do-not-use-debuginfod]" && ret=0 ;; dwarf-names) _sequence _wanted dwarf-sections expl "dwarf section" compadd - \ rawline decodedline info abbrev pubnames aranges macro frames \ frames-interp str str-offsets loc Ranges pubtypes gdb_index trace_info \ - trace_abbrev trace_aranges addr cu_index links follow-links && ret=0 + trace_abbrev trace_aranges addr cu_index links follow-links \ + use-debuginfod do-not-use-debuginfod && ret=0 ;; bfdnames) _wanted targets expl target compadd - \ diff --git a/Completion/Unix/Command/_pgrep b/Completion/Unix/Command/_pgrep index 94c1dae1a..798b6d6d4 100644 --- a/Completion/Unix/Command/_pgrep +++ b/Completion/Unix/Command/_pgrep @@ -48,6 +48,7 @@ arguments=( '--cgroup=[match by cgroup v2 names]:cgroup' '--ns=[match only on same namespaces as specified PID]: :_pids' '--nslist=[match only on specified namespaces (with --ns)]:namespace:(ipc mnt net pid user uts)' + '*--env=[match on environment variable]:var[=value]:_parameters -g "*export*" -qS=' '(: * -)'{-V,--version}'[display version information]' '-z+[match only on specified zone IDs]:zone:_sequence _zones' ) diff --git a/Completion/Unix/Command/_ping b/Completion/Unix/Command/_ping index 84bd76b82..95e1fd604 100644 --- a/Completion/Unix/Command/_ping +++ b/Completion/Unix/Command/_ping @@ -196,6 +196,7 @@ case ${variant}:${${service#ping}:-4} in ;; iputils:*) args+=( + '-3[RTT precision (do not round up the result time)]' '-A[adaptive]' '-b[allow pinging a broadcast address]' "-B[don't allow ping to change source address]" @@ -204,12 +205,14 @@ case ${variant}:${${service#ping}:-4} in '-e+[define identifier for ping session]:identifier' '(-4)-F+[allocate and set 20-bit flow label]:flow label (hex)' '(-)-h[show usage information]' + '(-n)-H[force reverse DNS name resolution even for numeric destination]' '-I+[specify source interface]:interface:_net_interfaces' '-m+[specify mark to tag outgoing packets]:mark' "-M+[specify path MTU discovery strategy]:strategy:(( do\:prohibit\ fragmentation,\ even\ local\ one want\:do\ PMTU\ discovery - dont\:don\'t\ set\ DF\ flag))" + dont\:don\'t\ set\ DF\ flag + probe\:set\ DF\ flag\ and\ bypass\ PMTU\ checks))" '(-4)-N+[send ICMPv6 node information queries instead of echo request]:sub option' '-O[report outstanding ICMP ECHO reply before sending next packet]' '-Q+[set Quality of Service-related bits in ICMP datagrams]:QoS TOS bits' diff --git a/Completion/Unix/Command/_ps b/Completion/Unix/Command/_ps index 158fb6b83..7d83f90ea 100644 --- a/Completion/Unix/Command/_ps +++ b/Completion/Unix/Command/_ps @@ -172,6 +172,7 @@ case $OSTYPE in '--headers[repeat header lines, one per page of output]' '(--cols --columns --width)'{--cols,--columns,--width}'[set screen width]:width' '(--lines --rows)'{--lines,--rows}'[set screen height]' + '--signames[display signal masks using signal names]' '--cumulative[include child process data with the parent]' '-n[set namelist file for WCHAN display]:file:_files' '(--no-headers --no-heading)'{--no-headers,--no-heading}'[suppress headers]' diff --git a/Completion/Unix/Command/_readelf b/Completion/Unix/Command/_readelf index b3abdf0a5..43cbc81c6 100644 --- a/Completion/Unix/Command/_readelf +++ b/Completion/Unix/Command/_readelf @@ -19,8 +19,8 @@ args=( '(-D --use-dynamic)'{-D,--use-dynamic}'[use dynamic section info when showing symbols]' \*{-x,--hex-dump=}"[dump contents of specified section as bytes]:section:($sections)" \*{-p,--string-dump=}"[dump contents of specified section as strings]:section:($sections)" - '-w+[show the contents of DWARF2 debug sections]::debug section:(a A r c L f F g i o m p t R l s O u T U k K N)' - '--debug-dump=[show the contents of DWARF2 debug sections]::section:(abbrev addr aranges cu_index decodedline frames frames-interp gdb_index info loc macro pubnames pubtypes Ranges rawline str str-offsets trace_abbrev trace_aranges trace_info links follow-links no-follow-links)' + '*-w+[show the contents of DWARF2 debug sections]::debug section:(a A r c f F g i k K N D E l L m o O p r R s t T u U)' + '*--debug-dump=[show the contents of DWARF2 debug sections]::section:(abbrev addr cu_index frames frames-interp gdb_index info links follow-links no-follow-links use-debuginfod do-not-use-debuginfod rawline decodedline macro loc str-offsets pubnames aranges Ranges str pubtype trace_aranges trace_abbrev trace_info)' '(-P --process-links)'{-P,--process-links}'[display the contents of non-debug sections in separate debuginfo files]' '(-I --histogram)'{-I,--histogram}'[show histogram of bucket list lengths]' '(-W --wide)'{-W,--wide}'[allow output width to exceed 80 characters]' @@ -59,8 +59,11 @@ case $variant in '--no-recurse-limit[disable demangling recursion limit]' '-U+[specify how to display unicode characters]:method:(d l e x h i)' '--unicode=[specify how to display unicode characters]:method:(default locale escape hex highlight invalid)' + '(-X --extra-sym-info)'{-X,--extra-sym-info}'[display extra information when showing symbols]' + '!(-X --extra-sym-info)--no-extra-sym-info' '(-L --lint --enable-checks)'{-L,--lint,--enable-checks}'[display warning messages for possible problems]' \*{-R,--relocated-dump=}"[dump contents of specified section as relocated bytes]:section:($sections)" + \*{-j,--display-section=}'[display contents of specified section]:section' "--dwarf-depth=[don't show DIEs at greater than specified depth]:depth" '--dwarf-start=[show DIEs starting at specified depth or deeper]:depth' '--ctf=[display compact C type format info from section]:section' diff --git a/Completion/Unix/Command/_strip b/Completion/Unix/Command/_strip index cc67ae49a..59cb537b9 100644 --- a/Completion/Unix/Command/_strip +++ b/Completion/Unix/Command/_strip @@ -41,6 +41,7 @@ if _pick_variant -r variant gnu=GNU elftoolchain=elftoolchain $OSTYPE --version; '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-U,--disable-deterministic-archives}'[disable -D behavior]' '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-D,--enable-deterministic-archives}'[produce deterministic output when stripping archives (zero file metadata)]' '--remove-relocations=[remove relocations from specified section]:section' + '--strip-section-headers[strip section headers from the output]' '--strip-dwo[remove all DWARF .dwo sections]' '!(--no-merge-notes)'{-M,--merge-notes} "--no-merge-notes[don't attempt to remove redundant notes]" diff --git a/Completion/Unix/Command/_uptime b/Completion/Unix/Command/_uptime index 58b4d991b..64d2e15fe 100644 --- a/Completion/Unix/Command/_uptime +++ b/Completion/Unix/Command/_uptime @@ -9,9 +9,10 @@ case $variant in _arguments -s -S : \ '(: -)'{-h,--help}'[display help information]' \ '(: -)'{-V,--version}'[display version information]' \ - + '(excl)' \ - {-p,--pretty}'[display uptime in pretty format]' \ - {-s,--since}'[display date/time of system boot]' + '(-c --container)'{-c,--container}'[show container uptime]' \ + '(-p --pretty -s --since -r --raw)'{-p,--pretty}'[display uptime in pretty format]' \ + '(-r --raw -p --pretty)'{-r,--raw}'[uptime values in raw format]' \ + '(-s --since -p --pretty)'{-s,--since}'[display date/time of system boot]' return ;; gnu) diff --git a/Completion/Unix/Command/_w b/Completion/Unix/Command/_w index 408cb76af..2da57a8f6 100644 --- a/Completion/Unix/Command/_w +++ b/Completion/Unix/Command/_w @@ -6,6 +6,7 @@ case $OSTYPE in linux*) args=( '(H -f --from)'{-f,--from}'[toggle display of remote hostname]' + '(-c --container)'{-c,--container}'[show container uptime]' '(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]' -- cgit v1.2.3 From 4e4274eda6012aead1f236502b163ba063bc465a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 27 Jan 2025 23:10:16 +0100 Subject: 53328: completion options update --- ChangeLog | 12 +++ Completion/Linux/Command/_cpupower | 1 - Completion/Linux/Command/_cryptsetup | 32 ++++++- Completion/Linux/Command/_ethtool | 12 ++- Completion/Linux/Command/_iptables | 166 ++++++++++++++++++++++++++++++++++- Completion/Linux/Command/_selinux | 17 ++-- Completion/Linux/Command/_sshfs | 13 +-- Completion/Linux/Command/_valgrind | 8 +- Completion/Unix/Command/_abcde | 2 +- Completion/Unix/Command/_dig | 47 +++++----- Completion/Unix/Command/_flac | 17 ++-- Completion/Unix/Command/_gnutls | 5 +- Completion/Unix/Command/_jq | 27 +++--- Completion/Unix/Command/_pv | 11 +++ Completion/Unix/Command/_sqlite | 2 + Completion/Unix/Command/_ssh | 12 ++- Completion/X/Command/_zeal | 1 + 17 files changed, 321 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index c5db038e6..cb90a5736 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2025-01-27 Oliver Kiddle + * 53328: Completion/Linux/Command/_cpupower, + Completion/Linux/Command/_cryptsetup, + Completion/Linux/Command/_ethtool, + Completion/Linux/Command/_iptables, + Completion/Linux/Command/_selinux, Completion/Linux/Command/_sshfs, + Completion/Linux/Command/_valgrind, Completion/Unix/Command/_abcde, + Completion/Unix/Command/_dig, Completion/Unix/Command/_flac, + Completion/Unix/Command/_gnutls, Completion/Unix/Command/_jq, + Completion/Unix/Command/_pv, Completion/Unix/Command/_sqlite, + Completion/Unix/Command/_ssh, Completion/X/Command/_zeal: + completion options update + * 53326: Completion/Linux/Command/_findmnt, Completion/Linux/Command/_free, Completion/Linux/Command/_losetup, Completion/Linux/Command/_lsblk, Completion/Linux/Command/_pidof, diff --git a/Completion/Linux/Command/_cpupower b/Completion/Linux/Command/_cpupower index d342b69d9..cb6f37fb0 100644 --- a/Completion/Linux/Command/_cpupower +++ b/Completion/Linux/Command/_cpupower @@ -20,7 +20,6 @@ cmds=( 'info:show global power parameters' 'set:set global power parameters' 'monitor:report frequency and idle statistics' - 'powercap-info:show powercapping related kernel and hardware configurations' 'help:print usage information' ) case $state in diff --git a/Completion/Linux/Command/_cryptsetup b/Completion/Linux/Command/_cryptsetup index f7149a76f..897eb94f9 100644 --- a/Completion/Linux/Command/_cryptsetup +++ b/Completion/Linux/Command/_cryptsetup @@ -13,7 +13,7 @@ _arguments -s \ '(-y --verify-passphrase)'{-y,--verify-passphrase}'[query for password twice]' \ '(-d --key-file)'{-d+,--key-file=}'[set keyfile]:key file:_files' \ '--master-key-file=[set master key]:key file:_files' \ - '--dump-master-key[dump luks master key]' \ + '--dump-volume-key[dump volume key instead of keyslots info]' \ '(-s --key-size)'{-s+,--key-size=}'[set key size]:size (bits)' \ '(-l --keyfile-size)'{-l+,--keyfile-size=}'[set keyfile size]:size (bytes)' \ '--keyfile-offset=[specify number of bytes to skip in keyfile]:offset (bytes)' \ @@ -37,8 +37,35 @@ _arguments -s \ '--shared[share device with another non-overlapping crypt segment]' \ '--uuid=[set device UUID]:uuid' \ '--allow-discards[allow discard (aka TRIM) requests for device]' \ + '--cancel-deferred[cancel previously set deferred device removal]' \ + '--disable-blkid[disable blkid on-disk signature detection and wiping]' \ + '--disable-external-tokens[disable loading of external LUKS2 token plugins]' \ + "--disable-veracrypt[don't scan for VeraCrypt compatible device]" \ + '--dump-json-metadata[dump info in JSON format (LUKS2 only)]' \ + '--dump-volume-key[dump volume key instead of keyslots info]' \ + '--external-tokens-path=[specify path to directory with external token handlers (plugins)]:path:_directories' \ + '--force-offline-reencrypt[force offline LUKS2 reencryption and bypass active device detection]' \ '--header=[device or file with separated LUKS header]:file:_files' \ - '--test-passphrase[do not activate device, just check passphrase]' \ + '--hw-opal[use HW OPAL encryption together with SW encryption]' \ + '--hw-opal-factory-reset[wipe WHOLE OPAL disk on luksErase]' \ + '--hw-opal-only[use only HW OPAL encryption]' \ + '--keep-key[do not change volume key]' \ + '--link-vk-to-keyring=[set keyring where to link volume key]:string' \ + '--new-keyfile=[read the key for a new slot from a file]:file:_files' \ + '--new-key-slot=[specify slot number for new key]:slot [first free]' \ + '--new-token-id=[token number]:number [any]' \ + '--progress-json[print progress data in json format]' \ + "--test-args[don't run action, just validate all command line parameters]" \ + '--volume-key-file=[use the volume key from file]:file:_files' \ + '--volume-key-keyring=[use the specified keyring key as a volume key]:key' \ + '(-B --block-size)'{-B+,--block-size=}'[reencryption block size]:block size (MiB)' \ + '(-N --new)'{-N,--new}'[create new header on not encrypted device]' \ + '--use-directio[use direct-io when accessing devices]' \ + '--use-fsync[use fsync after each block]' \ + '--write-log[update log file after every block]' \ + "--test-passphrase[don't activate device, just check passphrase]" \ + '--token-replace[replace the current token]' \ + '--token-type=[restrict allowed token types used to retrieve LUKS2 key]:string' \ '--tcrypt-hidden[use hidden header (hidden TCRYPT device)]' \ '--tcrypt-system[device is system TCRYPT drive (with bootloader)]' \ '--tcrypt-backup[use backup (secondary) TCRYPT header]' \ @@ -118,6 +145,7 @@ case $state in 'luksDump:dump header information' 'tcryptDump:dump TCRYPT device information' 'bitlkDump:dump BITLK device information' + 'fvault2Dump:dump FVAULT2 device information' 'luksSuspend:suspend LUKS device and wipe key' 'luksResume:resume suspended LUKS device' 'luksHeaderBackup:store binary backup of headers' diff --git a/Completion/Linux/Command/_ethtool b/Completion/Linux/Command/_ethtool index 3e3fc0b1d..8cff24e96 100644 --- a/Completion/Linux/Command/_ethtool +++ b/Completion/Linux/Command/_ethtool @@ -157,7 +157,7 @@ if [[ -n $state ]]; then _wanted files expl 'file' _files ;; rx-flow-hash) - _wanted flow-types expl 'flow type' compadd {tcp,udp,ah,esp,sctp}{4,6} + _wanted flow-types expl 'flow type' compadd {tcp,udp,ah,esp,sctp}{4,6} gtp{c{4,6}{,t},u{4,6}{,e,u,d}} ;; rule) _message -e ids 'rule id' @@ -177,6 +177,9 @@ if [[ -n $state ]]; then hfunc) _message -e functions 'hash function' ;; + xfrm) + _wanted transformations expl transformation compadd symmetric-xor none + ;; flags) _message -e masks mask ;; @@ -186,6 +189,9 @@ if [[ -n $state ]]; then power-mode-policy) _wanted policies expl 'policy' compadd high auto ;; + tcp-data-split) + _wanted states expl state compadd auto on off + ;; *) case ${${(Mk)opt_args:#cmd?*}[1]#cmd?-} in -a|--show-pause) @@ -209,7 +215,7 @@ if [[ -n $state ]]; then 'rx-mini[change number of ring entries for the RX Mini ring]' \ 'rx-jumbo[change number of ring entries for the RX Jumbo ring]' \ 'tx[change number of ring entries for the TX ring]' \ - rx-buf-len cqe-size tx-push rx-push tx-push-buf-len + rx-buf-len tcp-data-split cqe-size tx-push rx-push tx-push-buf-len ;; -d|--register-dump) _values -S ' ' -w 'option' \ @@ -306,7 +312,7 @@ if [[ -n $state ]]; then '(weight default)equal' \ '(equal default)weight' \ '(equal weight)default' \ - hkey hfunc delete + hkey hfunc xfrm delete ;; -f|--flash) if (( CURRENT == 4 )); then diff --git a/Completion/Linux/Command/_iptables b/Completion/Linux/Command/_iptables index 892c48710..0a901f0f2 100644 --- a/Completion/Linux/Command/_iptables +++ b/Completion/Linux/Command/_iptables @@ -128,6 +128,27 @@ while ) ;; comment) args+=( '--comment[add comment to rule]:comment' ) ;; + connbytes) + args+=( + '--connbytes:size (min\:[max])' + '--connbytes-dir:packets:(original reply both)' + '--connbytes-mode:mode:(packets bytes avgpkt)' + ) + ;; + connlabel) + args+=( + '--label[match if label name has been set on a connection]:label' + '--set[set label on connection]' + ) + ;; + connlimit) + args+=( + --connlimit-{upto,above}:connections + '--connlimit-mask:prefix length' + --connlimit-{s,d}addr + ) + ;; + connmark) args+=( --mark:value ) ;; conntrack) args+=( '--ctstate[match packet state]:state:->cfstates' @@ -136,18 +157,69 @@ while '--ctorigdst[match original destination address]:*^!:network:_hosts' '--ctreplsrc[match reply source address]:*^!:network:_hosts' '--ctrepldst[match reply destination address]:*^!:network:_hosts' + --ct{orig,repl}{src,dst}port':port:_ports' '--ctstatus[match internal conntrack states]:state:(NONE EXPECTED SEEN_REPLY ASSURED)' '--ctexpire[match remaining lifetime]:time' + '--ctdir:direction:(original reply)' + ) + ;; + cpu) args+=( --cpu:number ) ;; + dccp) + args+=( + --{s,d,source-,destination-}port:port:_ports + '--dccp-types:type:_sequence compadd - REQUEST RESPONSE DATA ACK DATAACK CLOSEREQ CLOSE RESET SYNC SYNCACK INVALID' + --dccp-option:option ) ;; + devgroup) args+=( --{src,dst}group:name ) ;; dscp) args+=( '--dscp[match DSCP field]:value' '--dscp-class[match the DiffServ class]:class' ) ;; + dst) args+=( --dst-len:length --dst-opts:type ) ;; + ecn) args+=( --ecn-{tcp-{cwr,ece},ip-ect} ) ;; esp) args+=( '--espspi[match SPIs in ESP header]:*^!:spi' ) ;; + frag) + args+=( + --fragid:id --fraglen:length + --frag{res,first,more,last} + ) + ;; + hashlimit) + args+=( + --hashlimit-{upto,above,burst}:amount + '--hashlimit-mode:object:_sequence compadd - srcip srcport dstip dstport' + --hashlimit-{src,dst}mask:prefix + --hashlimit-name:name + --hashlimit-htable-size:buckets + --hashlimit-htable-max:entries + --hashlimit-htable-{expire,gcinterval}:msec + --hashlimit-rate-match + --hashlimit-rate-intervale:sec + ) + ;; + hbh) args+=( --hbh-len:length --hbh-opts:type ) ;; helper) args+=( '--helper[match packets related to a conntrack-helper]:helper:(ftp)' ) ;; + hl) args+=( --hl-{eq,lt,gt}:value ) ;; + icmp) args+=( --icmp-type:type ) ;; + icmp6) args+=( --icmpv6-type:type ) ;; + iprange) args+=( --{src,dst}-range':IP range' ) ;; + ipv6header) + args+=( + --soft + '--header:header(hop dst route frag auth esp none prot)' + ) + ;; + ipvs) + args+=( + --ipvs --vproto:protocol --vaddr:address + --vport{,ctl}':port:_ports' + '--vdir:directory:(ORIGINAL REPLY)' + '--vmethod:method:(GATE IPIP MASQ)' + ) + ;; length) args+=( '--length[match packet length]:length' ) ;; limit) args+=( @@ -164,32 +236,120 @@ while '--ports[match where source and destination ports are equal]:ports:->port-list' ) ;; + nfacct) args+=( --nfacct-name:name ) ;; + osf) args+=( --genre:string --{ttl,log}:level ) ;; owner) args+=( '--uid-owner[match packet by user id of creating process]:user id' '--gid-owner[match packet by ggroup id of creating process]:group id' '--pid-owner[match packet by process id of creating process]:process id:_pids' '--sid-owner[match packet by session id of creating process]:session id' - '--cmd-owner[match packet by name of creating command]:command:_command_names -e' + --suppl-groups --socket-exists ) ;; physdev) args+=( '--physdev-in[specify bridge port via which packet is received]:name' '--physdev-out[specify bridge port via which packet is sent]:name' + --physdev-is-{in,out,bridged} ) ;; pkttype) args+=( '--pkt-type[match link-layer packet type]:type:(unicast broadcast multicast)' ) ;; + policy) + args+=( + '--dir:direction:(in out)' + '(--strict)--pol:policy:(none ipsec)' + '(--pol)--strict' + --reqid:id --spi:id + '--proto:encapsulation protocol:(ah esp ipcomp)' + '--mode:encapsulation mode:(tunnel transport)' + --tunnel-{src,dst}:addr --next + ) + ;; + quota) args+=( '--quota:quota (bytes)' ) ;; + rateest) + args+=( + --rateest-{delta,lt,gt,eq} + --rateest{,1,2}:name + --rateest-{bps,pps}{,1,2}:value + ) + ;; + realm) args+=( --realm:value ) ;; + recent) + args+=( + --name:name --r{source,dest} --mask:netmask + '(--rcheck --update --remove)--set' + '(--set --update --remove)--rcheck' + '(--set --rcheck --remove)--update' + '(--set --rcheck --update)--remove' + --seconds:seconds --reap --hitcount:hits --rttl + ) + ;; + rpfilter) args+=( --loose --validmark --accept-local --invert ) ;; + rt) + args+=( + --rt-type:type --rt-segsleft:number --rt-len:length + --rt-0-{res,not-strict} --rt-0-addrs:address + ) + ;; + sctp) + args+=( + --{s,d,source-,destination-}port:port:_ports + '--chunk-types:match type:(all any only):chunk type' + ) + ;; + set) + args+=( + '--match-set:set: :flag' + --return-nomatch --update-counters --update-subcounters + --{packet,byte}s-{eq,lt,gt}:value + ) + ;; + socket) args+=( --transparent --nowildcard --restore-skmark ) ;; state) args+=( '--state[match packet state]:state:->states' ) ;; + statistic) args+=( --mode:mode --{probability,every,packet}:value ) ;; + string) + args+=( + '--algo:strategy:(bm kmp)' + --{from,to}:offset + --{,hex}string:pattern + -icase + ) + ;; + tcp) + args+=( + --{s,d,source-,destination-}port:port:_ports + '--tcp-flags:mask:->tcp-flags:comp:->tcp-flags' + --syn --tcp-option:option + ) + ;; + tcpmss) args+=( --mss:value ) ;; + time) + args+=( + --date{start,stop}:date --time{start,stop}:time + --{month,week}days:day + --contiguous --kerneltz + ) + ;; tos) args+=( '--tos[match type of service field]:type of service:->tos' ) ;; - ttl) args+=( '--ttl[match type to live]:TTL value' ) ;; + ttl) args+=( '--ttl-'{eq,lt,gt}':TTL value' ) ;; + u32) args+=( '--u32:tests' ) ;; + udp) args+=( --{s,d,source-,destination-}port:port:_ports ) ;; esac done +if (( CURRENT > 2 )); then + if [[ $words[CURRENT-1] = (|\\)\! && ! -prefix - ]]; then + args+=( '*: :compadd -S "" - -' ) + else + args+=( '*:negation:(!)' ) + fi +fi + _arguments -C -s \ '(-)'{-h,--help}'[print program information]' \ '(-)'{-V,--version}'[print version information]' \ @@ -211,13 +371,13 @@ _arguments -C -s \ "($cmds -s --src --source)"{-s,--src,--source}'[specify source]:*^!:network:_sequence _hosts' \ "($cmds -d --dst --destination)"{-d,--dst,--destination}'[specify destination]:*^!:network:_sequence _hosts' \ "($cmds -j --jump)"{-j,--jump}'[specify rule target]:target:->targets' \ + "($cmds -g --goto)"{-g,--goto}'[jump to chain with no return]:target:->targets' \ "($cmds -i --in-interface)"{-i,--in-interface}'[specify interface via which packet is received]:*^!:interface:_net_interfaces' \ "($cmds -o --out-interface)"{-o,--out-interface}'[specify interface via which packet is to be sent]:*^!:interface:_net_interfaces' \ "($cmds -f --fragment)"{-f,--fragment}'[match second or further fragments only]' \ "($cmds -D --delete -c --set-counters)"{-c,--set-counters}'[initialise packet and byte counters]:packets: :bytes' \ '(-v --verbose)'{-v,--verbose}'[enable verbose output]' \ '(-w --wait)'{-w,--wait}'[specify maximum wait to acquire xtables lock before giving up]: :_numbers -u seconds -d 1 wait' \ - '(-W --wait-interval)'{-W,--wait-interval}'[specify wait time to try to acquire xtables lock]: :_numbers -u usecs -d "1 second" wait' \ '(-n --numeric)'{-n,--numeric}'[print IP addresses and port numbers in numeric format]' \ '(-x --exact)'{-x,--exact}'[expand numbers (display exact values)]' \ '--line-numbers[print line numbers when listing]' \ diff --git a/Completion/Linux/Command/_selinux b/Completion/Linux/Command/_selinux index a7ba68952..22d78db7d 100644 --- a/Completion/Linux/Command/_selinux +++ b/Completion/Linux/Command/_selinux @@ -1,4 +1,4 @@ -#compdef audit2allow audit2why avcstat chcon checkmodule checkpolicy fixfiles getpidprevcon getsebool matchpathcon newrole restorecon runcon sealert secon sedta seinfo selinuxconlist selinuxdefcon selinuxexeccon semanage semodule semodule_unpackage sepolgen sepolicy sesearch sestatus setenforce setsebool validatetrans +#compdef audit2allow audit2why avcstat chcon checkmodule checkpolicy fixfiles getpidprevcon getsebool matchpathcon newrole restorecon runcon sealert secon sedismod sedta seinfo selinuxconlist selinuxdefcon selinuxexeccon semanage semodule semodule_unpackage sepolgen sepolicy sesearch sestatus setenforce setsebool validatetrans # encompasses checkpolicy libselinux-utils policycoreutils # policycoreutils-devel policycoreutils-python-utils setools-console @@ -127,6 +127,7 @@ case $service in "${ign}(-h --help)"{-h,--help}'[display help information]' '(-U --handle-unknown)'{-U+,--handle-unknown=}'[specify how the kernel should handle unknown classes or permissions]:action:(deny allow reject)' '(-M --mls)'{-M,--mls}'[enable the MLS policy when checking and compiling the policy]' + '(-N --disable-neverallow)'{-N,--disable-neverallow}"[don't check neverallow rules]" '(-o --output)'{-o+,--output=}'[write a policy file]:file:_files' '-c+[specify the policy version]:policy version [latest]' ':input file:_files' @@ -154,7 +155,6 @@ case $service in '--perm-map=[specify file name of perm map]:file:_files' '--interface-info=[specify file name of interface information]:file:_files' '(-x --xperms)'{-x,--xperms}'[generate extended permission rules]' - '--debug[leave generated modules for -M]' '(-w --why)'{-w,--why}'[translate SELinux audit messages into a description of why the access was denied]' "${ign}(-h --help)"{-h,--help}'[display help information]' "${ign}--version[display version information]" @@ -193,7 +193,7 @@ case $service in ;; checkmodule) - args=( + args+=( "${ign}(-)"{-V,--version}'[show policy versions created by this program]' '-m[build a policy module instead of a base module]' '-c+[build a policy module targeting a modular policy version]:version (4-21)' @@ -201,7 +201,7 @@ case $service in ;; checkpolicy) - args=( + args+=( '(-F --conf)'{-F,--conf}'[write policy.conf file rather than binary policy file]' '(-d --debug)'{-d,--debug}'[enter debug mode after loading the policy]' '(-S --sort)'{-S,--sort}'[sort ocontexts before writing out the binary policy]' @@ -347,6 +347,10 @@ case $service in ) ;; + sedismod) + args=( ':pp file:_files -g "*.pp(-.)"' ) + ;; + sedta) args=( '(-p --policy)'{-p+,--policy=}'[specify path to SELinux policy to analyze]:policy:_files' @@ -410,7 +414,10 @@ case $service in selinuxdefcon) args=( + '-r+[specify role]:role' '-l+[specify mcs/mls level]:level' + '-s+[specify service]:service' + '-v[verbose output]' ':user:_users' ':context:_selinux_contexts' ) @@ -726,8 +733,6 @@ case $service in '--auditallowxperm[search auditallowxperm rules]' '--dontaudit[search dontaudit rules]' '--dontauditxperm[search dontauditxperm rules]' - '--neverallow[search neverallow rules]' - '--neverallowxperm[search neverallowxperm rules]' '(-T --type_trans)'{-T,--type_trans}'[search type_transition rules]' '--type_change[search type_change rules]' '--type_member[search type_member rules]' diff --git a/Completion/Linux/Command/_sshfs b/Completion/Linux/Command/_sshfs index 3467fbd8a..48b308066 100644 --- a/Completion/Linux/Command/_sshfs +++ b/Completion/Linux/Command/_sshfs @@ -15,12 +15,13 @@ _arguments -C -S : \ '(-d --debug -f)'{-d,--debug}'[enable debug output]' \ '-f[foreground]' \ '-s[disable multithreaded operation]' \ + '(-v --verbose)'{-v,--verbose}'[print ssh replies and messages]' \ ':remote directory:_user_at_host -S:' \ ':mountpoint:_files -/' && ret=0 if [[ $state == options ]]; then # TODO complete ssh(1) options - _values -s , "options to ssh, sshfs, mount, or FUSE" \ + _values -s , "option to ssh, sshfs, mount, or FUSE" \ 'port:number' \ 'compression: :(yes no)' \ reconnect delay_connect sshfs_sync no_readahead sync_readdir \ @@ -42,14 +43,15 @@ if [[ $state == options ]]; then 'ssh_protocol:version:(1 2)' \ sftp_server:path:_files \ directport:port:_ports \ - slave disable_hardlink transform_symlinks follow_symlinks no_check_root password_stdin \ - debug \ - allow_other allow_root auto_unmount nonempty default_permissions \ + passive disable_hardlink transform_symlinks follow_symlinks no_check_root password_stdin \ + max_conns:number \ + debug nonempty default_permissions \ fsname:filesystem\ name \ subtype:filesystem\ type \ large_read \ max_read:max\ size \ - hard_remove use_ino readdir_ino direct_io kernel_cache auto_cache noauto_cache \ + hard_remove use_ino readdir_ino direct_io \ + kernel_cache auto_cache noauto_cache \ 'umask:permissions' \ 'uid:owner' 'gid:group' \ 'entry_timeout:timeout (seconds) [1]' \ @@ -58,6 +60,7 @@ if [[ $state == options ]]; then 'ac_attr_timeout:timeout (seconds) [= attr_timeout]' \ noforget \ 'remember:time (seconds)' \ + allow_other allow_root auto_unmount \ nopath intr \ 'intr_signal:signal [10]' \ modules:module \ diff --git a/Completion/Linux/Command/_valgrind b/Completion/Linux/Command/_valgrind index 5eaaea338..6bf0e4450 100644 --- a/Completion/Linux/Command/_valgrind +++ b/Completion/Linux/Command/_valgrind @@ -40,7 +40,7 @@ common_report_errors=( '--error-exitcode=-[exit code to return if errors found]:exit code' \ '--error-markers=-[add lines with begin/end markers before/after]:markers (begin,end)' \ '(--show-error-list)-s[show detected errors list and suppression counts at exit]' \ - '--show-error-list=-[show detected errors list and suppression counts at exit]:enable [no]:(yes no)' + '--show-error-list=-[show detected errors list and suppression counts at exit]:enable [no]:(yes no all)' '--keep-debuginfo=-[keep symbols etc for unloaded code]:enable:(yes no)' \ '--show-below-main=-[continue stack traces below main()]:enable [no]:(yes no)' \ '--default-suppression=-[load default suppressions]:enable [yes]:(yes no)' \ @@ -115,6 +115,7 @@ args_memcheck=( $args_addrcheck $common_read_varinfo $common_report_errors + '--show-realloc-size-zero=-[show reallocs with a size of zero]:enable [yes]:(yes no)' ) args_cachegrind=( @@ -215,12 +216,13 @@ _arguments -C ${(P)args} $cmd \ '--child-silent-after-fork=-[omit child output between fork & exec]:enable:(yes no)' \ '--vgdb=-[activate gdbserver]:enable [yes]:(yes no full)' \ '--vgdb-error=-[invoke gdbserver after specified number of errors]:errors [999999999]:errors' \ - '--vgdb-stop-at=-[invoke gdbserver for given events]:event:_sequence compadd - startup exit valgrindabexit all none' \ + '--vgdb-stop-at=-[invoke gdbserver for given events]:event:_sequence compadd - startup exit abexit valgrindabexit all none' \ '--track-fds=-[track open file descriptors]:enable [no]:(yes no all)' \ '--time-stamp=-[add timestamps to log messages]:enable:(yes no)' \ '--log-fd=-[log messages to specified file descriptor]:file descriptor:_file_descriptors' \ '--log-file=-[log messages to specified file with pid appended]:file:_files' \ '--log-socket=-[log messages to socket]:ipaddr\:port' \ + '--enable-debuginfod=-[query debuginfod servers for missing debuginfo]:enable [yes]:(no yes)' \ '*--fullpath-after=-[show full source paths in call stacks]::prefix to remove from paths:_directories' \ '--extra-debuginfo-path=-[specify absolute path to search for additional debug symbols]:path:_directories' \ '--debuginfo-server=-[specify server to query for debug symbols]:server:_hosts' \ @@ -233,6 +235,7 @@ _arguments -C ${(P)args} $cmd \ '--run-libc-freeres=-[free up glibc memory at exit]:enable [yes]:(yes no)' \ '--run-cxx-freeres=-[free up libstdc++ memory at exit]:enable [yes]:(yes no)' \ '--sim-hints=-[activate unusual sim behaviours]:hint [none]:_sequence compadd - lax-ioctls lax-doors fuse-compatible enable-outer no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none' \ + '--scheduling-quantum=-[thread-scheduling timeslice in number of basic blocks]:blocks [100000]' \ '--fair-sched=-[schedule threads fairly on multicore systems]:enable [no]:(yes no try)' \ '--kernel-variant=-[handle non-standard kernel variants]:kernel variant:_sequence compadd - bproc android-no-hw-tls android-gpu-sgx5xx android-gpu-adreno3xx' \ '--merge-recursive-frames=-[merge frames between identical program counters in specified max frames]:frames [0]' \ @@ -247,6 +250,7 @@ _arguments -C ${(P)args} $cmd \ '--unw-stack-scan-thresh=-[enable stack-scan unwind if fewer than specified number of good frames found]:frames' \ '--resync-filter=-[attempt to avoid expensive address-space-resync operations]:enable:(yes no verbose)' \ '--max-threads=-[specify maximum number of threads that valgrind can handle]:threads [500]' \ + '--realloc-zero-bytes-frees=-[should calls to realloc() with a size of 0 free memory and return NULL]:enable:(yes no)' \ && return typeset -a tools diff --git a/Completion/Unix/Command/_abcde b/Completion/Unix/Command/_abcde index 3f748d373..6b09d87b5 100644 --- a/Completion/Unix/Command/_abcde +++ b/Completion/Unix/Command/_abcde @@ -21,7 +21,7 @@ _arguments -s -S -A "-*" \ '-m[create DOS-style playlists, modifying the resulting one by adding CRLF line endings those to work]' \ "-n[don't query CDDB database]" \ '-N[non interactive mode]' \ - '-o+[select output type]:output type [vorbis]:(vorbis ogg mp3 flac spx mpc m4a wav wv ape opus mka aiff)' \ + '-o+[select output type]:output type [vorbis]:_sequence compadd - vorbis ogg mp3 flac spx mpc m4a wav wv ape opus mka aiff' \ "-p[pads track numbers with 0's]" \ '-P[use Unix PIPES to read and encode in one step]' \ '-Q+[specify CD lookup methods]:lookup method [musicbrainz]:_sequence compadd - musicbrainz cddb cdtext' \ diff --git a/Completion/Unix/Command/_dig b/Completion/Unix/Command/_dig index c09bebbe5..440c5de90 100644 --- a/Completion/Unix/Command/_dig +++ b/Completion/Unix/Command/_dig @@ -5,8 +5,8 @@ local -a alts args [[ -prefix + ]] && args=( '*+'{no,}'tcp[use TCP instead of UDP for queries]' '*+'{no,}'ignore[ignore truncation in UDP responses]' - '*+domain=[set search list to single domain]:domain:_hosts' - '!*+dscp=:code point (0..63)' + '*+domain=-[set search list to single domain]:domain:_hosts' + '!*+dscp=-:code point (0..63)' '*+'{no,}'search[use search list defined in resolv.conf]' '!*+'{no,}defname '*+'{no,}'showsearch[show intermediate results in domain search]' @@ -20,27 +20,26 @@ local -a alts args '*+'{no,}'cookie[add a COOKIE option to the request]' '*+'{no,}'crypto[display cryptographic fields in DNSSEC records]' '*+'{no,}'dns64prefix[get the DNS64 prefixes from ipv4only.arpa]' - '*+edns=[specify EDNS version for query]:version (0-255)' + '*+edns=-[specify EDNS version for query]:version (0-255)' '*+noedns[clear EDNS version to be sent]' - '*+ednsflags=[set EDNS flags bits]:flags' + '*+ednsflags=-[set EDNS flags bits]:flags' '*+'{no,}'ednsnegotiation[set EDNS version negotiation]' - '*+ednsopt=[specify EDNS option]:code point' + '*+ednsopt=-[specify EDNS option]:code point' '*+noedns[clear EDNS options to be sent]' '*+'{no,}'expandaaaa[expand AAAA records]' '*+'{no,}'expire[send an EDNS Expire option]' '*+'{no,}'header-only[send query without a question section]' - '*+'{no,}'https=[DNS-over-HTTPS POST mode]::endpoint [/dns-query]' - '!*+'{no,}'https-post=::endpoint [/dns-query]' - '*+'{no,}'https-get=[DNS-over-HTTPS GET mode]::endpoint [/dns-query]' - '*+'{no,}'http-plain=[DNS-over-HTTP POST mode]::endpoint [/dns-query]' - '*+'{no,}'http-plain-get=[DNS-over-HTTP GET mode]::endpoint [/dns-query]' - '*+'{no,}'idnin[set processing of IDN domain names on input]' - '*+'{no,}'idnout[set conversion of IDN puny code on output]' + '*+'{no,}'https=-[DNS-over-HTTPS POST mode]::endpoint [/dns-query]' + '!*+'{no,}'https-post=-::endpoint [/dns-query]' + '*+'{no,}'https-get=-[DNS-over-HTTPS GET mode]::endpoint [/dns-query]' + '*+'{no,}'http-plain=-[DNS-over-HTTP POST mode]::endpoint [/dns-query]' + '*+'{no,}'http-plain-get=-[DNS-over-HTTP GET mode]::endpoint [/dns-query]' + '*+'{no,}'idn[convert international domain names]' '*+'{no,}'keepalive[request EDNS TCP keepalive]' '*+'{no,}'keepopen[keep TCP socket open between queries]' '*+'{no,}'recurse[set the RD (recursion desired) bit in the query]' '*+'{no,}'nssearch[search all authoritative nameservers]' - '*+opcode[set DNS message opcode of the request]:opcode [QUERY]:(QUERY IQUERY STATUS NOTIFY UPDATE)' + '*+opcode=-[set DNS message opcode of the request]:opcode [QUERY]:(QUERY IQUERY STATUS NOTIFY UPDATE)' '*+noopcode[clear DNS message opcode]' '*+'{no,}'trace[trace delegation down from root]' '*+'{no,}'cmd[print initial comment in output]' @@ -50,7 +49,9 @@ local -a alts args '*+'{no,}'comments[print comment lines in output]' '*+'{no,}'stats[print statistics]' '*+padding[set padding block size]:size [0]' - '*+qid=[specify query ID]:query ID' + '*+'{no,}'proxy=-[add PROXYv2 headers to queries]:src_addr[#src_port]-dst_addr[#dst_port]' + '*+'{no,}'proxy-plain=-[add PROXYv2 headers to queries ahead of any encryption]:src_addr[#src_port]-dst_addr[#dst_port]' + '*+qid=-[specify query ID]:query ID' '*+'{no,}'qr[print query as it was sent]' '*+'{no,}'question[print question section of a query]' '*+'{no,}'raflag[set RA flag in the query]' @@ -59,17 +60,17 @@ local -a alts args '*+'{no,}'all[set all print/display flags]' '*+'{no,}'subnet[send EDNS client subnet option]:addr/prefix-length' '*+'{no,}'tcflag[set TC flag in the query]' - '*+timeout=[set query timeout]:timeout (seconds) [5]' + '*+timeout=-[set query timeout]:timeout (seconds) [5]' '*+'{no,}'tls[DNS-over-TLS mode]' - '*+'{no,}"tls-ca=[enable remote server's TLS certificate validation]:file:_files" - '*+'{no,}"tls-hostname=[explicitly set the expected TLS hostname]:hostname" - '*+'{no,}'tls-certfile=[load client TLS certificate chain from file]:file:_files' - '*+'{no,}'tls-keyfile=[load client TLS private key from file]:file:_files' - '*+tries=[specify number of UDP query attempts]:tries' - '*+retry=[specify number of UDP query retries]:retries' + '*+'{no,}"tls-ca=-[enable remote server's TLS certificate validation]:file:_files" + '*+'{no,}"tls-hostname=-[explicitly set the expected TLS hostname]:hostname" + '*+'{no,}'tls-certfile=-[load client TLS certificate chain from file]:file:_files' + '*+'{no,}'tls-keyfile=-[load client TLS private key from file]:file:_files' + '*+tries=-[specify number of UDP query attempts]:tries' + '*+retry=-[specify number of UDP query retries]:retries' '*+'{no,}'rrcomments[set display of per-record comments]' - '*+ndots=[specify number of dots to be considered absolute]:dots' - '*+bufsize=[specify UDP buffer size]:size (bytes)' + '*+ndots=-[specify number of dots to be considered absolute]:dots' + '*+bufsize=-[specify UDP buffer size]:size (bytes)' '*+'{no,}'multiline[verbose multi-line output]' '*+'{no,}'onesoa[AXFR prints only one soa record]' '*+'{no,}"fail[don't try next server on SERVFAIL]" diff --git a/Completion/Unix/Command/_flac b/Completion/Unix/Command/_flac index 1773061ee..0197aaf92 100644 --- a/Completion/Unix/Command/_flac +++ b/Completion/Unix/Command/_flac @@ -14,9 +14,11 @@ shortops=( --show-total-samples --show-vendor-tag '--show-tag=:FLAC tag' + '--show-all-tags' '--remove-tag=:FLAC tag' '--remove-first-tag=:FLAC tag' --remove-all-tags + '--remove-all-tags-except=:tag' '*--set-tag=:FLAC tag and value: ' '*--set-tag-from-file=:tag' '--import-tags-from=:flat file:_files' @@ -60,7 +62,7 @@ case $service in '(H)--until=[stop at specified sample for each input]:stop (+-mm:ss.ss)' \ '(H)--ogg[use ogg as a transport layer]' \ '(H)--serial-number=[serial number to use for the FLAC stream]:serial number' \ - '(H --force-aiff-format --force-rf64-format --force-wave64-format)--format-raw-format' \ + '(H --force-aiff-format --force-rf64-format --force-wave64-format --force-legacy-wave-format --force-extensible-wave-format --force-aiff-c-none-format --force-aiff-c-sowt-format)--force-raw-format' \ '*:file:_files -F line -g "(#i)*.(${${opt_args[(i)decode-*]:+flac|oga}:-wav|aif|aiff|raw|rf64|w64})(-.)"' \ - 'H' \ '(-)'{-v,--version}'[display version information]' \ @@ -100,9 +102,13 @@ case $service in '(-F --decode-through-errors)'{-F,--decode-through-errors}'[continue decoding through stream errors]' \ '--apply-replaygain-which-is-not-lossless=:specification' \ '--cue=[set the beginning and ending cuepoints to decode]:cue point' \ - '(--force-raw-format --force-rf64-format --force-wave64-format)--force-aiff-format' \ - '(--force-raw-format --force-aiff-format --force-wave64-format)--force-rf64-format' \ - '(--force-raw-format --force-aiff-format --force-rf64-format)--force-wave64-format' \ + '(--force-raw-format --force-rf64-format --force-wave64-format --force-legacy-wave-format --force-extensible-wave-format --force-aiff-c-none-format --force-aiff-c-sowt-format)--force-aiff-format' \ + '(--force-raw-format --force-aiff-format --force-wave64-format --force-legacy-wave-format --force-extensible-wave-format --force-aiff-c-none-format --force-aiff-c-sowt-format)--force-rf64-format' \ + '(--force-raw-format --force-aiff-format --force-rf64-format --force-legacy-wave-format --force-extensible-wave-format --force-aiff-c-none-format --force-aiff-c-sowt-format)--force-wave64-format' \ + '(--force-raw-format --force-aiff-format --force-rf64-format --force-wave64-format --force-extensible-wave-format --force-aiff-c-none-format --force-aiff-c-sowt-format)--force-legacy-wave-format' \ + '(--force-raw-format --force-aiff-format --force-rf64-format --force-wave64-format --force-legacy-wave-format --force-aiff-c-none-format --force-aiff-c-sowt-format)--force-extensible-wave-format' \ + '(--force-raw-format --force-aiff-format --force-rf64-format --force-wave64-format --force-legacy-wave-format --force-extensible-wave-format --force-aiff-c-sowt-format)--force-aiff-c-none-format' \ + '(--force-raw-format --force-aiff-format --force-rf64-format --force-wave64-format --force-legacy-wave-format --force-extensible-wave-format --force-aiff-c-none-format)--force-aiff-c-sowt-format' ;; metaflac) _arguments -S $shared \ @@ -112,10 +118,11 @@ case $service in "*:FLAC file:_files -g \*.flac\(-.\)" \ - 'short' $shortops \ - 'list' $common --list \ + '--data-format=:format:(binary binary-headerless text)' \ '--application-data-format=:format:(text hexdump)' \ - 'remove' $common --remove \ - '(ops)' \ '(-)--help' '(-)--version' \ - --remove-all --merge-padding --sort-padding + --append --remove-all --merge-padding --sort-padding ;; esac diff --git a/Completion/Unix/Command/_gnutls b/Completion/Unix/Command/_gnutls index 9b8bcf6ea..4c1698857 100644 --- a/Completion/Unix/Command/_gnutls +++ b/Completion/Unix/Command/_gnutls @@ -24,6 +24,7 @@ case "$service" in gnutls-cli*) args+=( '(--app-proto --starttls-proto)'{--app-proto,--starttls-proto}"=[specify application protocol to use to obtain the server's certificate]:protocol:(https ftp smtp imap ldap xmpp lmtp pop3 nntp sieve postgres)" + '(-s --starttls)--starttls-name=[specify hostname presented to the application protocol for STARTTLS]:hostname' ':hostname:_hosts' ) ;| @@ -99,7 +100,7 @@ case "$service" in '--post-handshake-auth[enable post-handshake authentication under TLS1.3]' '--inline-commands[inline commands of the form ^^]' '--inline-commands-prefix=[change delimiter used for inline commands]:delimiter [^]' - '--fips140-mode[report status of FIPS140-3 mode in gnutls library]' + '--fips140-mode[report status of FIPS140-2 mode in gnutls library]' '--list-config[report configuration of the library]' '--logfile=[redirect informational messages to a specific file]:file:_files' '--waitresumption[block waiting for the resumption data under TLS1.3]' @@ -202,9 +203,11 @@ case "$service" in '--seed=[when generating a private key use the given seed]:seed (hex-encoded)' '--pubkey-info[print information on a public key]' '--to-p12[generate a PKCS #12 structure]' + '--pbmac1[use PBMAC1 in a PKCS #12 structure]' '(-8 --pkcs8)'{-8,--pkcs8}'[use PKCS #8 format for private keys]' '--hash=[specify hash algorithm for signing]:algorithm:(MD5 SHA1 RMD160)' '--salt-size=[specify the RSA-PSS key default salt size]:size' + '--label=[specify the RSA-OAEP label, encoded in hexadecimal]:label' {--inder,--inraw}'[use DER format for input certificates and private keys]' {--outder,--outraw}'[use DER format for output certificates and private keys]' '--template=[specify template file to use for non-interactive operation]:file:_files' diff --git a/Completion/Unix/Command/_jq b/Completion/Unix/Command/_jq index b8e41dd66..e8e6b0913 100644 --- a/Completion/Unix/Command/_jq +++ b/Completion/Unix/Command/_jq @@ -1,6 +1,7 @@ #compdef jq -# last updated for jq-1.5-1-a5b5cbe (debian package 1.5+dfsg-1.3) +local ign +(( $#words > 2 )) && ign='!' # Note: # Arguments to options must be in separate words. Thus, @@ -8,23 +9,27 @@ # is correct like that, without the usual {-f+,--from-file=} suffixes. # _arguments -S -s : \ - "--version[output jq's version number]" \ + "${ign}(- 1 *)"{-V,--version}'[display version information]' \ + "${ign}(- 1 *)"{-h,--help}'[display help information]' \ + "${ign}(- 1 *)--build-configuration[display jq's build configuration]" \ "--seq[use application/json-seq ASCII RS/LF scheme in input and output]" \ - "--stream[parse input streamily (changes output)]" \ - '(-s --slurp)'{-s,--slurp}'[join input JSON objects to array before filtering]' \ - '(-R --raw-input)'{-R,--raw-input}'[consider each input line as a JSON strings]' \ - '(-n --null-input)'{-n,--null-input}'[input is ignored]' \ + "(--stream-errors -n --null-input)--stream[parse the input value in streaming fashion]" \ + '(--stream -n --null-input)--stream-errors[parse the input value in streaming fashion with errors as an array]' \ + '(-s --slurp -n --null-input)'{-s,--slurp}'[read all inputs into an array and use it as single input value]' \ + '(-R --raw-input -n --null-input)'{-R,--raw-input}'[read each line as string instead of JSON]' \ + '(-n --null-input --stream --stream-errors -s --slurp -R --raw-input)'{-n,--null-input}'[use `null` as the single input value]' \ '(-c --compact-output)'{-c,--compact-output}"[don't pretty-print]" \ '(--indent)--tab[indent output using TAB characters]' \ - '(--tab)--indent[indent output using given number of spaces]:number of spaces (integer):(2 4 8)' \ + '(--tab)--indent[indent output using given number of spaces]:number of spaces (integer):(-1 0 1 2 3 4 5 6 7)' \ '(-C --color-output -M --monochrome-output)'{-C,--color-output}'[output in color]' \ '(-C --color-output -M --monochrome-output)'{-M,--monochrome-output}'[output without color]' \ - '(-a --ascii-output)'{-a,--ascii-output}'[restrict output to ASCII]' \ + '(-a --ascii-output)'{-a,--ascii-output}'[restrict output to ASCII using escape sequences]' \ '--unbuffered[flush output after each JSON object]' \ '(-S --sort-keys)'{-S,--sort-keys}'[output object keys in sorted order]' \ - '(-r --raw-output -j --join-output)'{-r,--raw-output}"[don't JSON-quote output if it's a string]" \ - '(-r --raw-output -j --join-output)'{-j,--join-output}"[like -r, without newlines between outputs]" \ - '(-f --from-file)'{-f,--from-file}'[read filter from file]:_files' \ + '(-r --raw-output -j --join-output --raw-output0)'{-r,--raw-output}"[don't JSON-quote output if it's a string]" \ + '(-r --raw-output -j --join-output)--raw-output0[like -r, with NUL after each output]' \ + '(-r --raw-output --raw-output0 -j --join-output)'{-j,--join-output}"[like -r, without newlines between outputs]" \ + '(-f --from-file)'{-f,--from-file}'[read filter from file]: :_files' \ '-L+[prepend a directory to the module search path]:_directories' \ '(-e --exit-status)'{-e,--exit-status}'[report "false" and "null" results via exit code]' \ '*--arg[pre-set a variable to a string]:variable name: :value (string)' \ diff --git a/Completion/Unix/Command/_pv b/Completion/Unix/Command/_pv index b21625650..0e1f148d5 100644 --- a/Completion/Unix/Command/_pv +++ b/Completion/Unix/Command/_pv @@ -20,6 +20,7 @@ _arguments -s -S $args \ '(-m --average-rate-window)'{-m+,--average-rate-window=}'[compute average rate over period]:duration (seconds) [30]' \ '(-b --bytes -8 --bits -F --format)'{-b,--bytes}'[show number of bytes transferred]' \ '(-8 --bits -b --bytes -F --format)'{-8,--bits}'[show number of bits transferred]' \ + '(-k --si)'{-k,--si}'[treat suffixes as multiples of 1000 rather than 1024]' \ '(-T --buffer-percent -F --format)'{-T,--buffer-percent}'[show percentage of transfer buffer in use]' \ '(-A --last-written -F --format)'{-A+,--last-written=}'[show number of bytes last written]:number (bytes)' \ '(-F --format -p --progress -t --timer -e --eta -I --fineta -r --rate -a --average-rate -b --bytes -T --buffer-percent -A --last-written -F --format)'{-F+,--format=}'[set output format]:format:->formats' \ @@ -28,19 +29,29 @@ _arguments -s -S $args \ '(-W --wait)'{-W,--wait}'[display nothing until first byte transferred]' \ '(-D --delay-start -R --remote)'{-D+,--delay-start=}'[display nothing until delay has passed]:delay (seconds)' \ '(-s --size)'{-s+,--size=}'[set estimated data size]: :_numbers -u bytes size K M G T' \ + '(-g --gauge)'{-g,--gauge}'[if size unknown, show rate vs max rate]' \ '(-l --line-mode -R --remote)'{-l,--line-mode}'[count lines instead of bytes]' \ '(-0 --null -l --line-mode)'{-0,--null}'[lines are null-terminated]' \ '(-i --interval)'{-i+,--interval=}'[update every after specified interval]:interval (seconds) [1]' \ + '(-m --average-rate-window)'{-m,--average-rate-window}'[compute average rate over past period]:period (seconds) [30]' \ '(-w --width)'{-w+,--width}'[assume terminal is specified characters wide]:width' \ '(-H --height)'{-H+,--height=}'[assume terminal is specified rows high]:height' \ '(-N --name)'{-N+,--name=}'[prefix visual information with given name]:name' \ + '(-x --extra-display)'{-x+,--extra-display=}'[also send progress to destination]:destination:_sequence - compadd windowtitle processtitle' \ + '(-v --stats)'{-v,--stats}'[output transfer statistics at the end]' \ '(-f --force -R --remote)'{-f,--force}'[output even if standard error is not a terminal]' \ '(-c --cursor -R --remote)'{-c,--cursor}'[use cursor positioning escape sequences]' \ + '(-o --output)'{-o+,--output=}'[write output to file instead of stdout]:file:_files' \ '(-L --rate-limit)'{-L+,--rate-limit=}'[limit transfer rate]: :_numbers -u "bytes per second" rate K M G T' \ '(-B --buffer-size)'{-B+,--buffer-size=}'[use a buffer size of given size]: :_numbers -u bytes size K M G T' \ '(-C --no-splice)'{-C,--no-splice}'[never use splice(), always use read/write]' \ '(-R --remote)*'{-E,--skip-errors}"[skip read errors in input${Edesc}]" \ + '(-Z --error-skip-block)'{-Z+,--error-skip-block=}'[skip whole blocks on errors]: :_numbers -u bytes "block size" K M G T' \ '(-S --stop-at-size -R --remote)'{-S,--stop-at-size}'[stop after --size bytes have been transferred]' \ + '(-Y --sync)'{-Y,--sync}'[flush cache to disk after every write]' \ + '(-K --direct-io)'{-K,--direct-io}'[use direct I/O to bypass cache]' \ + '(-X --discard)'{-X,--discard}'[discard input instead of writing to output]' \ + '(-U --store-and-forward)'{-U+,--store-and-forward=}'[write all input to file before writing to output]:file:_files' \ '(-R --remote -c --cursor -l --line-mode -f --force -D --delay-start -E --skip-errors -S --stop-at-size)'{-R+,--remote=}'[update settings of specified process]:process:_pids -m pv' \ '(-P --pidfile)'{-P+,--pidfile=}'[save process id in a file]:file:_files' \ "${ign}(- *)"{-h,--help}'[display usage information]' \ diff --git a/Completion/Unix/Command/_sqlite b/Completion/Unix/Command/_sqlite index 6f0b1de94..a83624083 100644 --- a/Completion/Unix/Command/_sqlite +++ b/Completion/Unix/Command/_sqlite @@ -56,6 +56,7 @@ options+=( $^dashes'-newline[set output row separator]:separator [\n]' $^dashes'-nofollow[refuse to open symbolic links to database files]' $^dashes'-nonce[set the safe-mode escape nonce]:string' + $^dashes'-no-rowid-in-view[disable rowid-in-view using sqlite3_config()]' $^dashes'-pagecache[specify size and number of slots for page cache memory]:size (bytes): :slots' $^dashes'-pcachetrace[trace all page cache operations]' $^dashes'-readonly[open the database read-only]' @@ -63,6 +64,7 @@ options+=( $^dashes'-stats[print memory stats before each finalize]' $^dashes'-unsafe-testing[allow unsafe commands and modes for testing]' $^dashes'-vfs[use specified default VFS]:vfs:(unix-dotfile unix-excl unix-none unix-namedsem)' + $^dashes'-vfstrace[enable tracing of all VFS calls]' $^dashes'-zip[open the file as a ZIP Archive]' ) diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index 5e6e60573..d8c27c65f 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -62,7 +62,7 @@ _ssh () { '(-v)*-q[quiet operation]' \ '*-R+[specify remote port forwarding]:remote port forwarding:->forward' \ '-S+[specify location of control socket for connection sharing]:path to control socket:_files' \ - '-Q+[query parameters]:query option:((cipher\:"supported symmetric ciphers" cipher-auth\:"supported symmetric ciphers that support authenticated encryption" compression mac\:"supported message integrity codes" kex\:"key exchange algorithms" kex-gss\:"GSSAPI key exchange algorithms" key\:"key types" key-cert\:"certificate key types" key-plain\:"non-certificate key types" key-sig\:"all key types and signature algorithms" protocol-version\:"supported SSH protocol versions" sig\:"supported signature algorithms" help\:"show supported queries" HostbasedAcceptedAlgorithms HostKeyAlgorithms KexAlgorithms MACs PubkeyAcceptedAlgorithms))' \ + '(- 1 *)-Q+[query parameters]:query option:((cipher\:"supported symmetric ciphers" cipher-auth\:"supported symmetric ciphers that support authenticated encryption" compression mac\:"supported message integrity codes" kex\:"key exchange algorithms" kex-gss\:"GSSAPI key exchange algorithms" key\:"key types" key-cert\:"certificate key types" key-plain\:"non-certificate key types" key-sig\:"all key types and signature algorithms" protocol-version\:"supported SSH protocol versions" sig\:"supported signature algorithms" help\:"show supported queries" HostbasedAcceptedAlgorithms HostKeyAlgorithms KexAlgorithms MACs PubkeyAcceptedAlgorithms))' \ '-s[invoke subsystem]' \ '(-t)-T[disable pseudo-tty allocation]' \ "(-T)*-t[force pseudo-tty allocation${tdesc}]" \ @@ -280,6 +280,7 @@ _ssh () { '-O+[specify a key/value option]: : _values option "hashalg[select a hash algorithm to use with -D]\:algorithm [both]\:(sha1 sha256)"' \ '-p+[specify port on remote host]:port number on remote host' \ + "-q[don't print server host name and banners in comments]" \ '-T+[specify timeout]: :_numbers -u seconds -d 5 timeout \:s\:seconds m\:minutes h\:hours d\:days w\:weeks' \ '-t+[specify key types to fetch from scanned hosts]:key type:_sequence compadd - rsa dsa ecdsa ed25519' \ '-v[verbose mode]' @@ -300,9 +301,13 @@ _ssh () { _arguments \ '-i+[select identity file]:SSH identity file:_files -g "*(-.^AR)"' \ '-f[copy keys without trying to check if they are already installed]' \ + '-F+[specify alternate config file]:config file:_files' \ '-n[dry run - no keys are actually copied]' \ '*-o+[specify ssh options]:option string:->option' \ '-p+[specify port on remote host]:port number on remote host' \ + '-s[upload public keys with sftp]' \ + '-t+[specify path on target system]:path [.ssh/authorized_keys]' \ + '-x[debug script by turning on command tracing]' \ '(- 1)'{-h,-\?}'[display usage information]' \ ':remote host name:->userhost' && ret=0 ;; @@ -359,6 +364,10 @@ _ssh () { (#i)canonicalizepermittedcnames=*) _message -e 'CNAME rule list (source_domain_list:target_domain_list, each pattern list comma separated)' && ret=0 ;; + (#i)channeltimeout=*) + _values 'channel type' \ + {agent-connection,direct-tcpip,forwarded-tcpip,session,tun-connection,x11-connection}:interval:'_numbers -u seconds timeout :s:seconds m:minutes h:hours d:days w:weeks' && ret=0 + ;; (#i)ciphers=*) state=ciphers ;; @@ -584,6 +593,7 @@ _ssh () { CanonicalizePermittedCNAMEs \ CASignatureAlgorithms \ CertificateFile \ + ChannelTimeout \ CheckHostIP \ Ciphers \ ClearAllForwardings \ diff --git a/Completion/X/Command/_zeal b/Completion/X/Command/_zeal index 334331d40..024b8c381 100644 --- a/Completion/X/Command/_zeal +++ b/Completion/X/Command/_zeal @@ -8,6 +8,7 @@ _arguments -S \ ':query:->queries' \ + '(opt)' \ {-h,--help}'[display help information]' \ + --help-all'[display help, including generic Qt options]' \ {-v,--version}'[display version information]' \ {-f,--force}'[force the application to run]' && ret=0 -- cgit v1.2.3 From 65285fac236dec95564bdd082ac637976c9d41c4 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 27 Jan 2025 23:14:34 +0100 Subject: 53327: update for git 2.47 --- ChangeLog | 2 + Completion/Unix/Command/_git | 136 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 116 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb90a5736..2a596af97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2025-01-27 Oliver Kiddle + * 53327: Completion/Unix/Command/_git: update for git 2.47 + * 53328: Completion/Linux/Command/_cpupower, Completion/Linux/Command/_cryptsetup, Completion/Linux/Command/_ethtool, diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 86b8a7455..a442b45d2 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -123,8 +123,9 @@ _git-am () { $apply_options \ '--quit[abort the patching operation but keep HEAD where it is]' \ '--show-current-patch=-[show the message being applied]::show [raw]:(diff raw)' \ + '--retry[try to apply current patch again]' \ '(--empty)--allow-empty[record the empty patch as an empty commit]' \ - '(--allow-empty)--empty=[select hanndling of empty patches]:handling:(stop drop keep)' \ + '(--allow-empty)--empty=[select handling of empty patches]:handling [stop]:(stop drop keep)' \ '(-i --interactive)'{-i,--interactive}'[apply patches interactively]' \ '(-n --no-verify)'{-n,--no-verify}'[bypass pre-applypatch and applypatch-msg hooks]' \ '--committer-date-is-author-date[use author date as committer date]' \ @@ -487,7 +488,7 @@ _git-checkout () { '(-)'{-p,--patch}'[interactively select hunks in diff between given tree-ish and working tree]' \ "--ignore-skip-worktree-bits[don't limit pathspecs to sparse entries only]" \ "--no-guess[don't second guess 'git checkout ']" '!(--no-guess)--guess' \ - "--ignore-other-worktrees[don't check if another worktree is holding the given ref]" \ + "--ignore-other-worktrees[don't check if another worktree is using this branch]" \ '--recurse-submodules=-[control recursive updating of submodules]::checkout:__git_commits' \ '--no-overlay[remove files from index or working tree that are not in the tree-ish]' \ '(-q --quiet --progress)--no-progress[suppress progress reporting]' \ @@ -546,7 +547,8 @@ _git-cherry-pick () { '--cleanup=[specify how to strip spaces and #comments from message]:mode:_git_cleanup_modes' \ '--allow-empty[preserve initially empty commits]' \ '--allow-empty-message[allow replaying a commit with an empty message]' \ - '--keep-redundant-commits[keep cherry-picked commits that will become empty]' \ + '!(--empty)--keep-redundant-commits' \ + '--empty=[how to handle commits that become empty]:handling:(stop drop keep)' \ '(-e --edit --ff)'{-e,--edit}'[edit commit before committing the cherry-pick]' \ '(--ff)-x[append information about what commit was cherry-picked]' \ '(-m --mainline)'{-m+,--mainline=}'[specify mainline when cherry-picking a merge commit]:parent number' \ @@ -667,6 +669,7 @@ _git-clone () { '--shallow-submodules[any cloned submodules will be shallow]' \ '(--recursive --recurse-submodules)'{--recursive,--recurse-submodules}'=-[initialize submodules in the clone]::file:__git_files' \ '--separate-git-dir[place .git dir outside worktree]:path to .git dir:_path_files -/' \ + '--ref-format=[specify reference format to use]:format:(files reftable)' \ \*--server-option='[send specified string to the server when using protocol version 2]:option' \ '(-4 --ipv4 -6 --ipv6)'{-4,--ipv4}'[use IPv4 addresses only]' \ '(-4 --ipv4 -6 --ipv6)'{-6,--ipv6}'[use IPv6 addresses only]' \ @@ -730,7 +733,7 @@ _git-commit () { {-p,--patch}'[use the interactive patch selection interface to choose which changes to commit]' \ '(--reset-author)--author[override the author name used in the commit]:author name' \ '--date=[override the author date used in the commit]:date' \ - '*--trailer=[add custom trailer(s)]:trailer:__git_trailers_tokens' \ + '*--trailer=[add custom trailer]:trailer:__git_trailers_tokens' \ '(-s --signoff)'{-s,--signoff}'[add Signed-off-by trailer at the end of the commit message]' \ '(-n --no-verify)'{-n,--no-verify}'[bypass pre-commit and commit-msg hooks]' \ '--allow-empty[allow recording an empty commit]' \ @@ -947,6 +950,7 @@ _git-format-patch () { # TODO: Should filter out --name-only, --name-status, and --check from # $diff_options. _arguments -C -S -s $endopt \ + '-1[format only the specified commit itself]' \ $diff_options \ '--[limit the number of patches to prepare]: :__git_guard_number "number of patches to prepare"' \ '(-o --output-directory --stdout)'{-o+,--output-directory=}'[store resulting files in given directory]: :_directories' \ @@ -967,8 +971,9 @@ _git-format-patch () { '--ignore-if-in-upstream[do not include a patch that matches a commit in the given range]' \ '(-v --reroll-count)'{-v+,--reroll-count=}'[mark the series as the -th iteration of the topic]: :__git_guard_number iteration' \ '--filename-max-length=[specify max length of output filename]:length' \ - '(-k --keep-subject --subject-prefix)--rfc[use \[RFC PATCH\] instead of \[PATCH\]]' \ + '(-k --keep-subject --subject-prefix)--rfc=-[use \[RFC PATCH\] instead of \[PATCH\]]::text [RFC]' \ "--cover-from-description=[generate parts of a cover letter based on a branch's description]:mode:(message default subject auto none)" \ + '--description-file=[use branch description from file]:file:_files' \ '(-k --keep-subject --rfc)--subject-prefix=[use the given prefix instead of \[PATCH\]]:prefix' \ '*--to=[add To: header to email headers]: :_email_addresses' \ '*--cc=[add Cc: header to email headers]: :_email_addresses' \ @@ -993,7 +998,7 @@ _git-format-patch () { case $state in (commit-or-commit-range) - if [[ -n ${opt_args[(I)--root]} ]]; then + if [[ -n ${opt_args[(I)(--root|-1)]} ]]; then __git_commits && ret=0 else __git_commit_ranges && ret=0 @@ -1009,6 +1014,7 @@ _git-gc () { _arguments -S -s $endopt \ '--aggressive[more aggressively optimize]' \ '--auto[check whether housekeeping is required]' \ + '--detach[perform garbage collection in the background]' \ '( --no-prune)--prune=-[prune loose objects older than given date]::date [2 weeks ago]:_git_approxidates' \ '(--prune )--no-prune[do not prune any loose objects]' \ '--cruft[pack unreferenced objects separately]' \ @@ -1190,7 +1196,8 @@ _git-init () { '--shared=[share repository amongst several users]:: :__git_repository_permissions' \ '--separate-git-dir=[create git dir elsewhere and link it using the gitdir mechanism]:: :_directories' \ '(-b --initial-branch)'{-b+,--initial-branch=}'[override the name of the initial branch]:branch name' \ - '--object-format=[specify the hash algorithm to use]:algortithm:(sha1 sha256)' \ + '--object-format=[specify hash algorithm to use]:algorithm:(sha1 sha256)' \ + '--ref-format[specify reference format to use]:format' \ ':: :_directories' } @@ -1207,7 +1214,7 @@ _git-interpret-trailers() { '--unfold[join whitespace-continued values]' \ '--parse[set parsing options]' \ "--no-divider[don't treat --- as the end of the commit message]" \ - '--trailer[specify trailer(s) to add]' \ + '*--trailer=[apply custom trailer]:trailer:__git_trailers_tokens' \ '*:file:_files' } @@ -1592,7 +1599,7 @@ _git-rebase () { '(-m --merge -s --strategy -X --strategy-option --auto-squash --no-auto-squash -r --rebase-merges -i --interactive -x --exec --empty --reapply-cherry-picks --edit-todo --reschedule-failed-exec)--apply[use apply strategies to rebase]' \ '(-m --merge --apply --whitespace -C)'{-m,--merge}'[use merging strategies to rebase]' \ '(-i --interactive --ignore-whitespace --apply --whitespace -C --committer-date-is-author-date)'{-i,--interactive}'[make a list of commits to be rebased and open in $EDITOR]' \ - '(--apply --whitespace -C)--empty=[specify how to handle commits that become empty]:handling:(drop keep ask)' \ + '(--apply --whitespace -C)--empty=[specify how to handle commits that become empty]:handling:(drop keep stop)' \ '(--apply --whitespace -C)'{-x+,--exec=}'[with -i\: append "exec " after each line]:command:_command_names -e' \ '(-r --rebase-merges --apply --whitespace -C)'{-r-,--rebase-merges=-}'[try to rebase merges instead of skipping them]::option:(rebase-cousins no-rebase-cousins)' \ '(--apply --whitespace -C)*'{-s+,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies' \ @@ -1756,7 +1763,7 @@ _git-shortlog () { declare -A opt_args local -a revision_options - __git_setup_revision_options + __git_setup_revision_options -d # TODO: should take all arguments found in setup_revisions() (probably more # or less what git-rev-list takes). @@ -1768,7 +1775,7 @@ _git-shortlog () { '-w-[linewrap the output]:: :->wrap' \ '*--group=[group commits by field]: : _values -S\: field author committer trailer\:trailer' \ '(-c --committer)'{-c,--committer}'[alias for --group=committer]' \ - $revision_options \ + ${revision_options:#\*--committer*} \ '(-)--[start file arguments]' \ '*:: :->commit-range-or-file' && ret=0 @@ -2295,7 +2302,7 @@ _git-switch() { "(-t --track --guess --orphan 1)--no-track[don't set upstream info for a new branch]" \ '(-c --create -C --force-create -d --detach --ignore-other-worktrees -m --merge --conflict -t --track --guess --no-track -t --track)--orphan[create new unparented branch]: :__git_branch_names' \ '!--overwrite-ignore' \ - "(-c --create -C --force-create -d --detach --orphan)--ignore-other-worktrees[don't check if another worktree is holding the given ref]" \ + "(-c --create -C --force-create -d --detach --orphan)--ignore-other-worktrees[don't check if another worktree is using this branch]" \ '1: :->branches' \ '2:start point:->start-points' && ret=0 @@ -2338,6 +2345,7 @@ _git-tag () { '--cleanup=[specify how to strip spaces and #comments from message]:mode:_git_cleanup_modes' \ '(-m --message -F --file)'{-F+,--file=}'[read tag message from given file]:message file:_files' \ '(-m --message -F --file)'{-m+,--message=}'[specify tag message]:message' \ + '*--trailer=[add custom trailer]:trailer:__git_trailers_tokens' \ ': :__git_tags' \ ':: :__git_commits' \ - deletion \ @@ -2516,6 +2524,7 @@ _git-config () { '(--global --system --local -f --file --blob --get-urlmatch --replace-all --add --unset --unset-all --rename-section --remove-section -e --edit --get-color --get-colorbool --show-scope)--show-origin[show origin of config]' \ '(--global --system --local -f --file --blob --get-urlmatch --replace-all --add --unset --unset-all --rename-section --remove-section -e --edit --get-color --get-colorbool --show-origin)--show-scope[show scope of config (worktree, local, global, system, command)]' \ '(2 --add -e --edit -l --list --name-only --rename-section --remove-section --replace-all --unset --unset-all)--default=[with --get, use specified default value when entry is missing]:default' \ + '--comment=[specify human-readable comment string]:comment' \ $name_arg \ $value_arg \ '::value regex' \ @@ -2596,6 +2605,7 @@ __git_config_option-or-value () { advice.ignoredHook:'show advice if a hook is ignored because the hook is not set as executable::->bool:true' advice.waitingForEditor:'print a message to the terminal whenever Git is waiting for editor input from the user::->bool:true' advice.nestedTag:'show advice if a user attempts to recursively tag a tag object::->bool:true' + attr.tree:'reference to tree in repository from which to read attributes:ref:->string' author.email:'email address used for author in commits::_email_addresses -c' author.name:'full name used for author in commits:name:->string' am.threeWay:'use 3-way merge if patch does not apply cleanly::->bool:false' @@ -2632,6 +2642,7 @@ __git_config_option-or-value () { core.symlinks:'create symbolic links for indexed symbolic links upon creation::->bool:true' core.gitProxy:'command to execute to establish a connection to remote server:proxy command:_cmdstring' core.ignoreStat:'ignore modification times of files::->bool:false' + core.maxTreeDepth:'maximum depth Git should recurse while traversing a tree' core.preferSymlinkRefs:'use symbolic links for symbolic-reference files::->bool:false' core.bare:'use a repository without a working tree::->bool:false' core.worktree:'path to the root of the work tree:work tree:_directories' @@ -2640,7 +2651,7 @@ __git_config_option-or-value () { core.sharedRepository:'what kind of sharing is done for this repository::->permission:false' core.warnAmbiguousRefs:'warn if a ref name is ambiguous::->bool:true' core.compression:'level of compression to apply to packs::->compression:-1' - core.loosecompression:'level of compression to apply to non-pack files::->compression:1' + core.looseCompression:'level of compression to apply to non-pack files::->compression:1' core.packedGitWindowSize:'size of mappings of pack files:pack window size:->bytes' core.packedGitLimit:'maximum number of bytes to map from pack files:maximum pack file map size:->bytes' core.packedRefsTimeout:"how long to retry locking the packed-refs file:retry time (milliseconds, or -1 for indefinite):->int:1000" @@ -2761,6 +2772,7 @@ __git_config_option-or-value () { diff.renameLimit:'number of files to consider when detecting copy/renames:limit (number of files):->int' diff.renames:'try to detect renames::->diff.renames:true' diff.ignoreSubmodules:'ignore submodules::->bool:false' + diff.statNameWidth:'limit on width of filename part in --stat output:width:->int' diff.statGraphWidth:'width of the graph part in --stat output:width:->int' diff.submodule:'output format for submodule differences::->diff.submodule:short' diff.suppressBlankEmpty:'inhibit printing space before empty output lines::->bool:false' @@ -2799,16 +2811,23 @@ __git_config_option-or-value () { format.signoff:'enable --signoff by default::->bool:false' 'gc.*.reflogexpire:grace period for git reflog expire::->days:90' 'gc.*.reflogexpireunreachable:grace period for git reflog expire for unreachable entries::->days:30' + fsck.hasDot:'warn if a tree contains an entry named ..::->bool:false' + fsck.hasDotdot:'warn if a tree contains an entry named ...::->bool:false' + fsck.hasDotgit:'warn if a tree contains an entry named .git::->bool:false' + fsck.largePathname:'warn on long path names::->int:4096' gc.aggressiveDepth:'maximum delta depth:maximum delta depth::->int:250' gc.aggressiveWindow:'window size used in delta compression algorithm::->int:250' gc.auto:'minimum limit for packing loose objects with --auto::->int:6700' gc.autoDetach:"make 'git gc --auto' run in the background::->bool:true" gc.autopacklimit:'minimum limit for packing packs with --auto::->int:50' gc.bigPackThreshold:"keep large packs:size threshold:->bytes" + gc.maxCruftSize:'limit size of new cruft packs when repacking:size:->int' gc.packrefs:'allow git gc to run git pack-refs::->gc.packrefs:true' gc.pruneexpire:'grace period for pruning:number of days, "now", or "never":->int' gc.reflogexpire:'grace period for git reflog expire::->days:90' gc.reflogexpireunreachable:'grace period for git reflog expire for unreachable entries::->days:30' + gc.repackFilter:'when repacking, use the specified filter to move certain objects into a separate packfile:filter:_git_rev-list_filters' + gc.repackFilterTo:'when repacking, pack prefix to store a pack containing filtered out objects:directory:_directories' gc.rerereresolved:'number of days to keep records of resolved merges::->days:60' gc.rerereunresolved:'number of days to keep records of unresolved merges::->days:15' gc.worktreePruneExpire:'grace period for pruning worktrees:number of days, "now", or "never":->int' # git default: 3.months.ago @@ -3000,6 +3019,7 @@ __git_config_option-or-value () { rebase.autoSquash:'autosquash by default::->bool:false' rebase.autoStash:'autostash by default::->bool:false' rebase.instructionFormat:'interactive rebase todo list format::__git_format_placeholders' + rebase.maxLabelLength:'when generating label names from commit subjects, length to truncate the names to:length:->int' rebase.missingCommitsCheck:'print a warning if some commits are removed' rebase.rescheduleFailedExec:"automatically re-schedule any 'exec' that fails::->bool" receive.autogc:'run git gc --auto after receiving data::->bool:true' @@ -3010,6 +3030,7 @@ __git_config_option-or-value () { receive.denyDeleteCurrent:'deny a ref update that deletes currently checked out branch::->bool:false' receive.denyCurrentBranch:'deny a ref update of currently checked out branch::->receive.denyCurrentBranch' receive.denyNonFastForwards:'deny a ref update that is not a fast-forward::->bool:false' + receive.fsck.largePathname:'warn on long path names::->int:4096' receive.updateserverinfo:'run git update-server-info after receiving data::->bool:false' 'remote.pushdefault:URL of a remote repository to pushto::__git_any_repositories' 'remote.*.url:URL of a remote repository::__git_any_repositories' @@ -3898,6 +3919,7 @@ _git-pack-refs () { '(--all )--no-all[do not pack all refs]' \ '( --no-prune)--prune[remove loose refs after packing them]' \ '(--prune )--no-prune[do not remove loose refs after packing them]' \ + '--auto[auto-pack refs as needed]' \ '*--include=[references to include]:reference pattern:_git_full_references' \ '*--exclude=[references to exclude]:reference pattern:_git_full_references' \ '--no-include[clear and reset the list of include patterns]' \ @@ -3942,6 +3964,7 @@ _git-reflog () { commands=( 'expire:prune old reflog entries' 'delete:delete entries from reflog' + 'list:list all refs that have a corresponding reflog' 'show:show log of ref' 'exists:check whether a ref has a reflog' ) @@ -3995,6 +4018,48 @@ _git-reflog () { fi } +(( $+functions[_git-refs] )) || +_git-refs() { + local curcontext=$curcontext state line ret=1 + declare -A opt_args + + _arguments -C \ + ': :->command' \ + '*:: :->option-or-argument' && ret=0 + + case $state in + (command) + declare -a commands + + commands=( + 'migrate:migrate ref store between different formats' + 'verify:verify reference database consistency' + ) + + _describe -t commands command commands && ret=0 + ;; + (option-or-argument) + curcontext=${curcontext%:*}-$line[1]: + + case $line[1] in + migrate) + _arguments -S -s $endopt \ + '--ref-format=[specify ref format to migrate the ref store to]:ref format:(files reftable)' \ + "--dry-run[perform the migration, but don't modify the repository]" && ret=0 + ;; + verify) + _arguments -S -s $endopt \ + '--strict[enable stricter error checking]' \ + '--verbose[when verifying the reference database consistency, be chatty]' && ret=0 + ;; + *) _default && ret=0 ;; + esac + ;; + esac + + return ret +} + (( $+functions[_git-remote] )) || _git-remote () { local curcontext=$curcontext state line ret=1 @@ -4109,6 +4174,7 @@ _git-repack () { '(-a -k --keep-unreachable)-A[pack all objects into a single pack, but unreachable objects become loose]' \ '--cruft[pack unreachable cruft objects separately]' \ '--cruft-expiration=[expire cruft objects older than specified time]: :_git_approxidates' \ + '--max-cruft-size=[with --cruft, limit the size of new cruft packs]: : __git_guard_bytes "maximum cruft size"' \ '-d[remove redundant packs after packing]' \ "--unpack-unreachable=[with -A, don't loosen objects older than specified date]: :_git_approxidates" \ '-f[pass --no-reuse-delta option to git pack-objects]' \ @@ -4125,11 +4191,13 @@ _git-repack () { '--depth=[maximum delta depth]:maximum delta depth' \ '--threads=[limit maximum number of threads]:threads' \ '--max-pack-size=-[maximum size of each output packfile]: : __git_guard_bytes "maximum pack size"' \ + '--filter=[object filtering]:filter:_git_rev-list_filters' \ '--pack-kept-objects[repack objects in packs marked with .keep]' \ '--keep-pack=[ignore named pack]:pack' \ '(-g --geometric)'{-g+,--geometric=}'[find a geometric progression with specified factor]:factor' \ '(-m --write-midx)'{-m,--write-midx}'[write a multi-pack index of the resulting packs]' \ - '--expire-to=[pack prefix to store a pack containing pruned objects]:directory:_directories' + '--expire-to=[pack prefix to store a pack containing pruned objects]:directory:_directories' \ + '--filter-to=[pack prefix to store a pack containing filtered out objects]:directory:_directories' } (( $+functions[_git-replace] )) || @@ -4351,6 +4419,7 @@ _git-merge-tree () { '--allow-unrelated-histories[allow merging unrelated histories]' \ '--stdin[perform multiple merges, one per line of input]' \ '--merge-base=[specify a merge-base for the merge]:commit:__git_commits' \ + '*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]: :_git_strategy_options' \ ':base-tree:__git_tree_ishs' \ ':branch 1:__git_tree_ishs' \ ':branch 2:__git_tree_ishs' @@ -4649,6 +4718,7 @@ _git-send-email () { '--8bit-encoding=[encoding to use for non-ASCII messages]: :__git_encodings' \ '--compose-encoding=[encoding to use for compose messages]: :__git_encodings' \ '--transfer-encoding=[specify transfer encoding to use]:transfer encoding:(quoted-printable 8bit base64)' \ + '--mailmap[use mailmap file to map email addresses to canonical real names and addresses]' \ '--envelope-sender=[specify the envelope sender used to send the emails]: :_email_addresses' \ '--sendmail-cmd=[specify command to run to send email]:command:_cmdstring' \ '--smtp-encryption=[specify encryption method to use]: :__git_sendemail_smtpencryption_values' \ @@ -4687,6 +4757,7 @@ _git-send-email () { '(--validate )--no-validate[do not perform sanity checks on patches]' \ '--force[send emails even if safety checks would prevent it]' \ '(- *)--dump-aliases[dump configured aliases and exit]' \ + '(- *)--translate-aliases[translate aliases from stdin according to alias file]' \ '*: : _alternative -O expl "files:file:_files" "commits:recent commit object name:__git_commit_objects_prefer_recent"' @@ -5002,6 +5073,9 @@ _git-apply () { '--check[check if patches are applicable (turns off "apply")]' \ '( --cached)--index[make sure that patch is applicable to index]' \ '(--index )--cached[apply patches without touching working tree]' \ + '(--theirs --union)--ours[for conflicts, use our version]' \ + '(--ours --union)--theirs[for conflicts, use their version]' \ + '(--theirs --ours)--union[for conflicts, use a union version]' \ '--build-fake-ancestor[build temporary index for blobs with ambiguous origin]:index:_files' \ '(-R --reverse)'{-R,--reverse}'[apply patches in reverse]' \ '-z[use NUL termination on output]' \ @@ -5117,6 +5191,7 @@ _git-index-pack () { $stdin_opts \ '--strict[die if the pack contains broken objects or links]' \ '--threads=[specify number of threads to use]:number of threads' \ + '!--fsck-objects' \ ':pack file:_files -g "*.pack(-.)"' } @@ -5140,7 +5215,13 @@ _git-merge-file () { '( --theirs --union)--ours[resolve conflicts favoring our side of the lines]' \ '(--ours --union)--theirs[resolve conflicts favoring their side of the lines]' \ '(--ours --theirs )--union[resolve conflicts favoring both sides of the lines]' \ + '--diff-algorithm=[choose a diff algorithm]:diff algorithm:((default\:"basic greedy diff algorithm" + myers\:"basic greedy diff algorithm" + minimal\:"spend extra time to make sure the smallest possible diff is produced" + patience\:"generate diffs with patience algorithm" + histogram\:"generate diffs with histogram algorithm"))' \ '--marker-size[specify length of conflict markers]: :__git_guard_number "marker length"' \ + '--object-id[use object IDs instead of filenames]' \ '(--zdiff3)--diff3[show conflicts in "diff3" style]' \ '(--diff3)--zdiff3[show conflicts in "zdiff3" style]' \ ':current file:_files' \ @@ -5353,6 +5434,7 @@ _git-update-index () { '--verbose[report what is being added and removed from the index]' \ '--clear-resolve-undo[forget saved unresolved conflicts]' \ '--index-version=[write index in specified on-disk format version]:version:(2 3 4)' \ + '--show-index-version[report on-disk index format version]' \ '--split-index[enable/disable split index]' \ '--untracked-cache[enable/disable untracked cache]' \ '--test-untracked-cache[test if the filesystem supports untracked cache]' \ @@ -5527,6 +5609,7 @@ _git-for-each-ref () { "*--no-contains=[print only refs that don't contain specified commit]:object:__git_commits" \ '--ignore-case[sorting and filtering are case-insensitive]' \ '(1)--stdin[read reference patterns from stdin]' \ + '--include-root-refs[also include HEAD ref and pseudorefs]' \ '(-s --shell -p --perl --python --tcl)'{-s,--shell}'[use string literals suitable for sh]' \ '(-s --shell -p --perl --python --tcl)'{-p,--perl}'[use string literals suitable for Perl]' \ '(-s --shell -p --perl --tcl)'--python'[use string literals suitable for Python]' \ @@ -5538,6 +5621,7 @@ _git-for-each-ref () { _git-for-each-repo() { _arguments -S \ '(-C --config)'{-C,--config=}'[specify config variable for list of paths]:config variable' \ + '--keep-going[keep going even if command fails in a repository]' \ ':git command:_git_commands' \ '*:: := _git' } @@ -5590,8 +5674,9 @@ _git-ls-remote () { _arguments -S -s $endopt \ '(-q --quiet)'{-q,--quiet}"[don't print remote URL]" \ '--upload-pack=[specify path to git-upload-pack on remote side]:remote path' \ - '(-h --heads)'{-h,--heads}'[show only refs under refs/heads]' \ - '(-t --tags)'{-t,--tags}'[show only refs under refs/tags]' \ + '(-b --branches)'{-b,--branches}'[limit to branches]' \ + '!(-b --branches)'{-h,--heads} \ + '(-t --tags)'{-t,--tags}'[limit to tags]' \ "--refs[don't show peeled tags]" \ '--exit-code[exit with status 2 when no matching refs are found in the remote repository]' \ '--get-url[expand the URL of the given repository taking into account any "url..insteadOf" config setting]' \ @@ -5717,6 +5802,7 @@ _git_rev-list_filters() { _values 'filter' \ 'blob\:none[omit all blobs]' \ 'blob\:limit[omit blobs larger than specified size]:size' \ + 'object\:type[omits objects not of the indicated type]:type:(tag commit tree blob)' \ 'sparse\:oid[uses a sparse-checkout specification contained in the blob]:blob-ish' \ 'tree\:0[omit blobs and trees with depth exceeding limit]' } @@ -5724,24 +5810,26 @@ _git_rev-list_filters() { (( $+functions[_git-show-index] )) || _git-show-index() { _arguments \ - '--object-format=[specify the hash algorithm to use]:algortithm:(sha1 sha256)' + '--object-format=[specify the hash algorithm to use]:algorithm:(sha1 sha256)' } (( $+functions[_git-show-ref] )) || _git-show-ref () { _arguments -S $endopt \ + '(exclude)*: :_guard "([^-]?#|)" pattern' \ - list \ '--head[show the HEAD reference, even if it would normally be filtered out]' \ - '--tags[show only refs/tags]' \ - '--heads[show only refs/heads]' \ + '--tags[show only tags]' \ + '--branches[show only branches]' '!(--branches)--heads' \ '(-d --dereference)'{-d,--dereference}'[dereference tags into object IDs as well]' \ '(-s --hash)'{-s+,--hash=-}'[only show the SHA-1 hash, not the reference name]:: :__git_guard_number length' \ '--verify[enable stricter reference checking]' \ '--abbrev=[use specified digits to display object names]:digits' \ '(-q --quiet)'{-q,--quiet}'[do not print any results]' \ - '*: :_guard "([^-]?#|)" pattern' \ - exclude \ - '--exclude-existing=-[filter out existing refs from stdin]:: :_guard "([^-]?#|)" pattern' + '(*)--exclude-existing=-[filter out existing refs from stdin]:: :_guard "([^-]?#|)" pattern' \ + - exists \ + '--exists[check for reference existence without resolving]' \ } (( $+functions[_git-unpack-file] )) || @@ -5766,7 +5854,7 @@ _git-verify-pack () { _arguments -S -s $endopt \ '(-v --verbose)'{-v,--verbose}'[show objects contained in pack]' \ '(-s --stat-only)'{-s,--stat-only}'[do not verify pack contents; only display histogram of delta chain length]' \ - '--object-format=[specify the hash algorithm to use]:algortithm:(sha1 sha256)' \ + '--object-format=[specify the hash algorithm to use]:algorithm:(sha1 sha256)' \ '*:index file:_files -g "*.idx(-.)"' } @@ -6312,6 +6400,7 @@ _git_commands () { pack-refs:'pack heads and tags for efficient repository access' prune:'prune all unreachable objects from the object database' reflog:'manage reflog information' + refs:'low-level access to refs' remote:'manage set of tracked repositories' repack:'pack unpacked objects in a repository' replace:'create, list, delete refs to replace objects') @@ -8669,6 +8758,9 @@ _git() { '--namespace=[set the Git namespace]:namespace' \ '--bare[use $PWD as repository]' \ '--no-replace-objects[do not use replacement refs to replace git objects]' \ + "--no-lazy-fetch[don't fetch missing objects from the promisor remote on demand]" \ + "--no-optional-locks[don't perform optional operations that require locks]" \ + '--no-advice[disable all advice hints from being printed]' \ '--literal-pathspecs[treat pathspecs literally, rather than as glob patterns]' \ '(-): :->command' \ '(-)*:: :->option-or-argument' && return -- cgit v1.2.3 From a07ff879c0ed41222671fe92c62436435703645d Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 27 Jan 2025 23:26:08 +0100 Subject: unposted: fix quoting in openldap completion --- ChangeLog | 2 ++ Completion/Unix/Command/_openldap | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2a596af97..ce445f2ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2025-01-27 Oliver Kiddle + * unposted: Completion/Unix/Command/_openldap: fix quoting + * 53327: Completion/Unix/Command/_git: update for git 2.47 * 53328: Completion/Linux/Command/_cpupower, diff --git a/Completion/Unix/Command/_openldap b/Completion/Unix/Command/_openldap index 233d0950e..3fb6c0e0b 100644 --- a/Completion/Unix/Command/_openldap +++ b/Completion/Unix/Command/_openldap @@ -36,7 +36,7 @@ case $service in none noplain noactive nodict noanonymous forwardsec passcred minssf\:factor maxssf\:factor maxbufsize\:factor' '(simple)-X+[specify SASL authorization identity]:authzid:->authzids' - '(simple)-Y+[specify SASL mechanism]:mechanism:compadd -M "m:{a-zA-Z}={A-Za-z}" EXTERNAL GSSAPI' # iana has a full list but cyrus support seems limited + '(simple)-Y+[specify SASL mechanism]:mechanism:compadd -M "m\:{a-zA-Z}={A-Za-z}" EXTERNAL GSSAPI' # iana has a full list but cyrus support seems limited '(simple)-R+[specify SASL realm]:realm' '(simple)-U+[specify SASL authentication identity]:authcid' '(simple)-I[use SASL Interactive mode]' -- cgit v1.2.3 From 9f9ceb7768b51334ccdd0f6e32b20399ba261933 Mon Sep 17 00:00:00 2001 From: Kouhei Yanagita Date: Mon, 25 Nov 2024 14:34:16 +0900 Subject: github #125: Add completion for irb --no-pager --- ChangeLog | 3 +++ Completion/Unix/Command/_ruby | 1 + 2 files changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index ce445f2ba..02d9739d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-01-27 Oliver Kiddle + * github #125: Kouhei Yanagita: Completion/Unix/Command/_ruby: + Add completion for irb --no-pager + * unposted: Completion/Unix/Command/_openldap: fix quoting * 53327: Completion/Unix/Command/_git: update for git 2.47 diff --git a/Completion/Unix/Command/_ruby b/Completion/Unix/Command/_ruby index 9955253b3..82111b455 100644 --- a/Completion/Unix/Command/_ruby +++ b/Completion/Unix/Command/_ruby @@ -69,6 +69,7 @@ irb=( $opts[(r)*-d\[*] '(--noinspect)--inspect[use inspect for output]' "(--inspect)--noinspect[don't use inspect for output]" + "--no-pager[don't use pager]" '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--prompt=,--prompt-mode=}'[switch prompt mode]:prompt mode:(default classic simple inf-ruby xmp null)' '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--inf-ruby-mode,--simple-prompt,--noprompt} '--tracer[display trace for each command execution]' -- cgit v1.2.3 From a61b105795620943206c1f85be801943cadbb1c3 Mon Sep 17 00:00:00 2001 From: "Wu, Zhenyu" Date: Tue, 26 Nov 2024 19:39:33 +0800 Subject: github #126: Fix some typos --- ChangeLog | 4 ++++ Completion/Base/Completer/_expand_alias | 2 +- Src/exec.c | 4 ++-- Src/init.c | 2 +- Src/parse.c | 2 +- Src/utils.c | 2 +- Src/zsh.h | 2 +- configure.ac | 4 ++-- 8 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02d9739d8..5ccfccd66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2025-01-27 Oliver Kiddle + * github #126: Wu, Zhenyu: Completion/Base/Completer/_expand_alias, + Src/exec.c, Src/init.c, Src/parse.c, Src/utils.c, Src/zsh.h, + configure.ac: Fix some typos + * github #125: Kouhei Yanagita: Completion/Unix/Command/_ruby: Add completion for irb --no-pager diff --git a/Completion/Base/Completer/_expand_alias b/Completion/Base/Completer/_expand_alias index 8240e4162..0f165a968 100644 --- a/Completion/Base/Completer/_expand_alias +++ b/Completion/Base/Completer/_expand_alias @@ -49,7 +49,7 @@ if [[ -n $tmp ]]; then if [[ $tmpa[1] = $word && $tmp = $aliases[$word] ]]; then # This is an active regular alias and the first word in the result # is the same as what was on the line already. Quote it so - # that it doesn't get reexanded on execution. + # that it doesn't get reexpanded on execution. # # Strictly we also need to check if the original word matches # a later word in the expansion and the previous words are diff --git a/Src/exec.c b/Src/exec.c index 874ff41f7..c1181c5eb 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1386,7 +1386,7 @@ execlist(Estate state, int dont_change_job, int exiting) *list_pipe_text = '\0'; } - /* Loop over all sets of comands separated by newline, * + /* Loop over all sets of commands separated by newline, * * semi-colon or ampersand (`sublists'). */ code = *state->pc++; if (wc_code(code) != WC_LIST) { @@ -3033,7 +3033,7 @@ execcmd_exec(Estate state, Execcmd_params eparams, /* * preargs contains args that have been expanded by prefork. * Running execcmd_getargs() causes any argument available - * in args to be exanded where necessary and transferred to + * in args to be expanded where necessary and transferred to * preargs. We call execcmd_getargs() every time we need to * analyse an argument not available in preargs, though there is * no guarantee a further argument will be available. diff --git a/Src/init.c b/Src/init.c index 378aee348..75d9dd136 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1282,7 +1282,7 @@ setupvals(char *cmd, char *runscript, char *zsh_name) adjustwinsize(0); #else /* columns and lines are normally zero, unless something different * - * was inhereted from the environment. If either of them are zero * + * was inherited from the environment. If either of them are zero * * the setiparam calls below set them to the defaults from termcap */ setiparam("COLUMNS", zterm_columns); setiparam("LINES", zterm_lines); diff --git a/Src/parse.c b/Src/parse.c index 334365649..8edc701f4 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -490,7 +490,7 @@ init_parse_status(void) /* * These variables are currently declared by the parser, so we * initialise them here. Possibly they are more naturally declared - * by the lexical anaylser; however, as they are used for signalling + * by the lexical analyser; however, as they are used for signalling * between the two it's a bit ambiguous. We clear them when * using the lexical analyser for strings as well as here. */ diff --git a/Src/utils.c b/Src/utils.c index 5c91dfcda..19fd61a8b 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2059,7 +2059,7 @@ redup(int x, int y) * Add an fd opened ithin a module. * * fdt is the type of the fd; see the FDT_ definitions in zsh.h. - * The most likely falures are: + * The most likely failures are: * * FDT_EXTERNAL: the fd can be used within the shell for normal I/O but * it will not be closed automatically or by normal shell syntax. diff --git a/Src/zsh.h b/Src/zsh.h index 85b5c9bdc..4e5c02980 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1667,7 +1667,7 @@ enum zpc_chars { ZPC_KSH_BANG, /* ! for !(...) in KSH_GLOB */ ZPC_KSH_BANG2, /* ! for !(...) in KSH_GLOB, untokenised */ ZPC_KSH_AT, /* @ for @(...) in KSH_GLOB */ - ZPC_COUNT /* Number of special chararacters */ + ZPC_COUNT /* Number of special characters */ }; /* diff --git a/configure.ac b/configure.ac index bca99b7f8..b5548c2b9 100644 --- a/configure.ac +++ b/configure.ac @@ -1342,7 +1342,7 @@ dnl Check if tgetent accepts NULL (and will allocate its own termcap buffer) dnl Some termcaps reportedly accept a zero buffer, but then dump core dnl in tgetstr(). dnl Under Cygwin test program crashes but exit code is still 0. So, -dnl we test for a file that porgram should create +dnl we test for a file that program should create AH_TEMPLATE([TGETENT_ACCEPTS_NULL], [Define to 1 if tgetent() accepts NULL as a buffer.]) AC_CACHE_CHECK(if tgetent accepts NULL, @@ -1495,7 +1495,7 @@ $AWK '{ if ($1 ~ /sig/) files[[$1]] = $1 } END { for (var in files) print var }'`" rm -f nametmp.c if test -z "$sigfile_list"; then - dnl In case we don't get the stuff from the preprocesor, use the old + dnl In case we don't get the stuff from the preprocessor, use the old dnl list of standard places. sigfile_list="/usr/include/sys/iso/signal_iso.h /usr/include/bsd/sys/signal.h -- cgit v1.2.3 From 45b79fa2cb353582fa6001c75c5f4e2ef4d5fa37 Mon Sep 17 00:00:00 2001 From: GI Date: Tue, 21 Jan 2025 13:51:53 -0500 Subject: github #128: Updated completion for neovim --- ChangeLog | 3 +++ Completion/Unix/Command/_vim | 26 ++++++++++++++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ccfccd66..f6b41f94a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-01-27 Oliver Kiddle + * github #128: GI : + Completion/Unix/Command/_vim: Updated completion for neovim + * github #126: Wu, Zhenyu: Completion/Base/Completer/_expand_alias, Src/exec.c, Src/init.c, Src/parse.c, Src/utils.c, Src/zsh.h, configure.ac: Fix some typos diff --git a/Completion/Unix/Command/_vim b/Completion/Unix/Command/_vim index 5c6054e70..5a805b9f6 100644 --- a/Completion/Unix/Command/_vim +++ b/Completion/Unix/Command/_vim @@ -41,11 +41,18 @@ arguments=( '-s[read normal-mode commands from script file]:script file:_files' '-w[append all typed commands to given file]:output file:_files' '-W[write all typed commands to given file, overwriting existing file]:output file:_files' - '--startuptime[write startup timing messages to given file]:log file:_files' '(- *)'{-h,--help}'[print help and exit]' '(- *)--version[print version information and exit]' '(* -q)-t+[edit file where tag is defined]:tag:_complete_tag' '(-t -q)*:file:_vim_files' + '--clean[start with defaults in non-compatible mode]' + '--remote[edit given files in a vim server if possible]:*:file:_vim_files' + '--remote-silent[as --remote but without complaining if not possible]:*:file:_vim_files' + '--remote-send[send given keys to vim server if possible]:keys: ' + '--remote-tab[as --remote but open tab page for each file]:*:file:_vim_files' + '--remote-tab-silent[as --remote-silent but open tab page for each file]:*:file:_vim_files' + '--remote-expr[evaluate given expression in a vim server and print result]:expression: ' + '--startuptime[write startup timing messages to given file]:log file:_files' ) if [[ $service = nvim ]]; then arguments+=( @@ -56,9 +63,11 @@ if [[ $service = nvim ]]; then '-i[use the specified shada file]:shada file:_files' '(- *)-v[print version information and exit]' '(- *)--api-info[print msgpack-encoded api-metadata and exit]' - '--headless[do not start user interface]' '--embed[use standard input and output as a msgpack-rpc channel]' + '--headless[do not start user interface]' '--listen[start RPC server on the specified socket or named pipe]:address' + '--remote-ui[display the UI of the server in the terminal]' + '--server[specify RPC server to send commands to]:server name:->server' ) else arguments+=( @@ -74,22 +83,15 @@ else '--ttyfail[exit if input or output is not a terminal]' '-X[do not connect to X server]' '-x[edit encrypted files]' - '--remote[edit given files in a vim server if possible]:*:file:_vim_files' - '--remote-silent[as --remote but without complaining if not possible]:*:file:_vim_files' '--remote-wait[as --remote but wait for files to have been edited]:*:file:_vim_files' '--remote-wait-silent[as --remote-wait but without complaining if not possible]:*:file:_vim_files' - '--remote-send[send given keys to vim server if possible]:keys: ' - '--remote-tab[as --remote but open tab page for each file]:*:file:_vim_files' - '--remote-tab-silent[as --remote-silent but open tab page for each file]:*:file:_vim_files' '--remote-tab-wait[as --remote-wait but open tab page for each file]:*:file:_vim_files' '--remote-tab-wait-silent[as --remote-wait-silent but open tab page for each file]:*:file:_vim_files' - '--remote-expr[evaluate given expression in a vim server and print result]:expression: ' '--literal[do not expand wildcards in arguments (this is useless with ZSH)]' '(- *)--serverlist[list available vim servers and exit]' '--servername[name of vim server to send to or name of server to become]:server name:->server' '--socketid[run GVIM in another window]' '-i[use specified viminfo file]:viminfo file [~/.viminfo]:_files' - '--clean[start with defaults in non-compatible mode]' ) fi [[ $service != *g* && $service != nvim ]] && arguments+='-g[start with GUI]' @@ -115,7 +117,11 @@ _arguments -C -S $arguments && ret=0 if [[ "$state" = server ]]; then local -a servers - servers=( ${(f)"$(_call_program servers $words[1] --serverlist 2>/dev/null)"} ) + if [[ $service == nvim ]]; then + servers=( /run/user/$UID/nvim.*(N=) ) + else + servers=( ${(f)"$(_call_program servers $words[1] --serverlist 2>/dev/null)"} ) + fi _wanted servers expl server compadd -M 'm:{a-z}={A-Z}' -a servers && ret=0 elif [[ $state = verbosity ]]; then _tags numbers files -- cgit v1.2.3 From 4f3d69e2a0bc6b4d98a4aa3ef37ebea44cbda51f Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 27 Jan 2025 23:50:27 +0100 Subject: 53329: adapt .zle.sgr for CSI sequences that use : instead of ; --- ChangeLog | 3 +++ Src/Modules/hlgroup.c | 11 ++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6b41f94a..d826e6c8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-01-27 Oliver Kiddle + * 53329: Src/Modules/hlgroup.c: adapt .zle.sgr for CSI sequences + that use : instead of ; + * github #128: GI : Completion/Unix/Command/_vim: Updated completion for neovim diff --git a/Src/Modules/hlgroup.c b/Src/Modules/hlgroup.c index 082762623..6c5a4bec4 100644 --- a/Src/Modules/hlgroup.c +++ b/Src/Modules/hlgroup.c @@ -50,9 +50,14 @@ convertattr(char *attrstr, int sgr) char *c = s, *t = s - 1; while (c[0] == '\033' && c[1] == '[') { - c += 2; - while (isdigit(*c) || *c == ';') - *++t = *c++; + for (c += 2; ; c++) { + if (isdigit(*c)) + *++t = *c; + else if (*c == ';' || *c == ':') + *++t = ';'; + else + break; + } t++; if (*c != 'm') break; -- cgit v1.2.3 From f7b5cc431bdda1f7123aca740bf7c535b98ca616 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 30 Jan 2025 12:30:40 +0100 Subject: 53332, 53334: Avoid strlen calls after sprintf --- ChangeLog | 6 ++++++ Src/Modules/stat.c | 3 +-- Src/Zle/compresult.c | 10 +++++----- Src/Zle/zle_misc.c | 3 +-- Src/builtin.c | 3 +-- Src/prompt.c | 35 +++++++++++++---------------------- 6 files changed, 27 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index d826e6c8b..f96e4f00c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2025-01-30 Oliver Kiddle + + * 53332, 53334: Src/builtin.c, Src/prompt.c, Src/Modules/stat.c, + Src/Zle/compresult.c, Src/Zle/zle_misc.c: + Avoid strlen calls after sprintf + 2025-01-27 Oliver Kiddle * 53329: Src/Modules/hlgroup.c: adapt .zle.sgr for CSI sequences diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c index c9f851974..5bf201dd3 100644 --- a/Src/Modules/stat.c +++ b/Src/Modules/stat.c @@ -236,9 +236,8 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags) char *optr = outbuf; if (flags & STF_NAME) { - sprintf(outbuf, (flags & (STF_PICK|STF_ARRAY)) ? + optr += sprintf(outbuf, (flags & (STF_PICK|STF_ARRAY)) ? "%s " : "%-8s", statelts[iwhich]); - optr += strlen(outbuf); } *optr = '\0'; diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c index cd8c7dd64..7dbc5676a 100644 --- a/Src/Zle/compresult.c +++ b/Src/Zle/compresult.c @@ -489,7 +489,7 @@ static char * build_pos_string(LinkList list) { LinkNode node; - int l; + int l, buflen; char buf[40], *s; long p; @@ -499,12 +499,12 @@ build_pos_string(LinkList list) /* This could be used to put an extra colon before the end-of-word * position if there is nothing missing. */ if (p < 0) - sprintf(buf, ":%ld", -p); + buflen = sprintf(buf, ":%ld", -p); else #endif - sprintf(buf, "%ld", p); - setdata(node, dupstring(buf)); - l += 1 + strlen(buf); + buflen = sprintf(buf, "%ld", p); + setdata(node, dupstring_wlen(buf, buflen)); + l += 1 + buflen; } s = (char *) zalloc(l * sizeof(char)); *s = 0; diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index eba28d1ec..e17a08d53 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -841,9 +841,8 @@ whatcursorposition(UNUSED(char **args)) strcpy(s, mbstr); s += len; } - sprintf(s, " (0%o, %u, 0x%x)", (unsigned int)c, + s += sprintf(s, " (0%o, %u, 0x%x)", (unsigned int)c, (unsigned int)c, (unsigned int)c); - s += strlen(s); } sprintf(s, " point %d of %d(%d%%) column %d", zlecs+1, zlell+1, zlell ? 100 * zlecs / zlell : 0, zlecs - bol); diff --git a/Src/builtin.c b/Src/builtin.c index cd0ee7522..18d74b09e 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4809,9 +4809,8 @@ bin_print(char *name, char **args, Options ops, int func) if (d) { int dirlen = strlen(d->dir); char *arg = zhalloc(len[n] - dirlen + strlen(d->node.nam) + 2); - sprintf(arg, "~%s%s", d->node.nam, args[n] + dirlen); + len[n] = sprintf(arg, "~%s%s", d->node.nam, args[n] + dirlen); args[n] = arg; - len[n] = strlen(args[n]); } unqueue_signals(); } diff --git a/Src/prompt.c b/Src/prompt.c index f36aba9d3..7467cdfb9 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -555,8 +555,7 @@ putpromptchar(int doprint, int endchar) if (jobtab[j].stat && jobtab[j].procs && !(jobtab[j].stat & STAT_NOPRINT)) numjobs++; addbufspc(DIGBUFSIZE); - sprintf(bv->bp, "%d", numjobs); - bv->bp += strlen(bv->bp); + bv->bp += sprintf(bv->bp, "%d", numjobs); break; case 'M': queue_signals(); @@ -782,20 +781,18 @@ putpromptchar(int doprint, int endchar) case 'L': addbufspc(DIGBUFSIZE); #if defined(ZLONG_IS_LONG_LONG) && defined(PRINTF_HAS_LLD) - sprintf(bv->bp, "%lld", shlvl); + bv->bp += sprintf(bv->bp, "%lld", shlvl); #else - sprintf(bv->bp, "%ld", (long)shlvl); + bv->bp += sprintf(bv->bp, "%ld", (long)shlvl); #endif - bv->bp += strlen(bv->bp); break; case '?': addbufspc(DIGBUFSIZE); #if defined(ZLONG_IS_LONG_LONG) && defined(PRINTF_HAS_LLD) - sprintf(bv->bp, "%lld", lastval); + bv->bp += sprintf(bv->bp, "%lld", lastval); #else - sprintf(bv->bp, "%ld", (long)lastval); + bv->bp += sprintf(bv->bp, "%ld", (long)lastval); #endif - bv->bp += strlen(bv->bp); break; case '%': case ')': @@ -886,8 +883,7 @@ putpromptchar(int doprint, int endchar) fsptr = fsptr->prev; } addbufspc(DIGBUFSIZE); - sprintf(bv->bp, "%d", depth); - bv->bp += strlen(bv->bp); + bv->bp += sprintf(bv->bp, "%d", depth); break; } case 'I': @@ -904,11 +900,10 @@ putpromptchar(int doprint, int endchar) lineno--; addbufspc(DIGBUFSIZE); #if defined(ZLONG_IS_LONG_LONG) && defined(PRINTF_HAS_LLD) - sprintf(bv->bp, "%lld", flineno); + bv->bp += sprintf(bv->bp, "%lld", flineno); #else - sprintf(bv->bp, "%ld", (long)flineno); + bv->bp += sprintf(bv->bp, "%ld", (long)flineno); #endif - bv->bp += strlen(bv->bp); break; } /* else we're in a file and lineno is already correct */ @@ -916,11 +911,10 @@ putpromptchar(int doprint, int endchar) case 'i': addbufspc(DIGBUFSIZE); #if defined(ZLONG_IS_LONG_LONG) && defined(PRINTF_HAS_LLD) - sprintf(bv->bp, "%lld", lineno); + bv->bp += sprintf(bv->bp, "%lld", lineno); #else - sprintf(bv->bp, "%ld", (long)lineno); + bv->bp += sprintf(bv->bp, "%ld", (long)lineno); #endif - bv->bp += strlen(bv->bp); break; case 'x': if (funcstack && funcstack->tp != FS_SOURCE && @@ -1990,7 +1984,7 @@ match_highlight(const char *teststr, zattr *on_var, int *layer) static int output_colour(int colour, int fg_bg, int truecol, char *buf) { - int atrlen = 3, len; + int atrlen = 3; char *ptr = buf; if (buf) { strcpy(ptr, fg_bg == COL_SEQ_FG ? "fg=" : "bg="); @@ -2008,14 +2002,11 @@ output_colour(int colour, int fg_bg, int truecol, char *buf) */ } else if (colour > 7) { char digbuf[DIGBUFSIZE]; - sprintf(digbuf, "%d", colour); - len = strlen(digbuf); - atrlen += len; + atrlen += sprintf(digbuf, "%d", colour); if (buf) strcpy(ptr, digbuf); } else { - len = strlen(ansi_colours[colour]); - atrlen += len; + atrlen += strlen(ansi_colours[colour]); if (buf) strcpy(ptr, ansi_colours[colour]); } -- cgit v1.2.3 From 86a0891952f8cd83138bc2b6fe760190c67c8ff9 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 30 Jan 2025 12:41:53 +0100 Subject: 53335: Remove unused dupstring_glen() function Also make use of the dupstring_wlen() variant in more places to avoid a strlen() --- ChangeLog | 5 +++++ Src/Zle/compcore.c | 22 +++++++++------------- Src/Zle/compctl.c | 4 ++-- Src/Zle/compmatch.c | 4 ++-- Src/Zle/computil.c | 13 ++++--------- Src/hist.c | 5 ++--- Src/string.c | 15 --------------- 7 files changed, 24 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index f96e4f00c..1dce0b334 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2025-01-30 Oliver Kiddle + * 53335: Src/hist.c, Src/string.c, Src/Zle/compcore.c, + Src/Zle/compctl.c, Src/Zle/compmatch.c, Src/Zle/computil.c: + Remove unused dupstring_glen() function and make use of the + dupstring_wlen() variant in more places to avoid a strlen() + * 53332, 53334: Src/builtin.c, Src/prompt.c, Src/Modules/stat.c, Src/Zle/compresult.c, Src/Zle/zle_misc.c: Avoid strlen calls after sprintf diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 09282d42d..fb703f801 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -708,7 +708,7 @@ callcompfunc(char *s, char *fn) sav = *ss; *ss = '\0'; - tmp = (linwhat == IN_MATH ? dupstring(s) : multiquote(s, 0)); + tmp = (linwhat == IN_MATH ? dupstring_wlen(s, offs) : multiquote(s, 0)); untokenize(tmp); compprefix = ztrdup(tmp); *ss = sav; @@ -1820,7 +1820,7 @@ set_comp_sep(void) */ sav = s[(i = swb - 1 - sqq + dq)]; s[i] = '\0'; - qp = (qttype == QT_SINGLE) ? dupstring(s) : rembslash(s); + qp = (qttype == QT_SINGLE) ? dupstring_wlen(s, i) : rembslash(s); s[i] = sav; if (swe < swb) swe = swb; @@ -2244,10 +2244,10 @@ addmatches(Cadata dat, char **argv) if (dat->aflags & CAF_MATCH) { lipre = dupstring(compiprefix); lisuf = dupstring(compisuffix); - lpre = dupstring(compprefix); - lsuf = dupstring(compsuffix); - llpl = strlen(lpre); - llsl = strlen(lsuf); + llpl = strlen(compprefix); + llsl = strlen(compsuffix); + lpre = dupstring_wlen(compprefix, llpl); + lsuf = dupstring_wlen(compsuffix, llsl); /* This used to reference compqiprefix and compqisuffix, why? */ if (llpl + (int)strlen(qipre) + (int)strlen(lipre) != origlpre @@ -2300,12 +2300,8 @@ addmatches(Cadata dat, char **argv) for (p = lpre + 2; *p && *p != ')'; p++); if (*p == ')') { - char sav = p[1]; - - p[1] = '\0'; - globflag = dupstring(lpre); gfl = p - lpre + 1; - p[1] = sav; + globflag = dupstring_wlen(lpre, gfl); lpre = p + 1; llpl -= gfl; @@ -2731,7 +2727,7 @@ add_match_data(int alt, char *str, char *orig, Cline line, sl = tsl; } if (qisl) { - Cline qsl = bld_parts(dupstring(qisuf), qisl, qisl, NULL, NULL); + Cline qsl = bld_parts(dupstring_wlen(qisuf, qisl), qisl, qisl, NULL, NULL); qsl->flags |= CLF_SUF; qsl->suffix = qsl->prefix; @@ -2814,7 +2810,7 @@ add_match_data(int alt, char *str, char *orig, Cline line, line = p; } if (qipl) { - Cline lp, p = bld_parts(dupstring(qipre), qipl, qipl, &lp, NULL); + Cline lp, p = bld_parts(dupstring_wlen(qipre, qipl), qipl, qipl, &lp, NULL); lp->next = line; line = p; diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index 08355d1b9..de3ccdfce 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -3201,8 +3201,8 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) memcpy(lpre, s, lpl); lpre[lpl] = '\0'; qlpre = quotename(lpre); - lsuf = dupstring(s + offs); - lsl = strlen(lsuf); + lsl = strlen(s + offs); + lsuf = dupstring_wlen(s + offs, lsl); qlsuf = quotename(lsuf); /* First check for ~.../... */ diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c index ddcecd589..b58bd1f05 100644 --- a/Src/Zle/compmatch.c +++ b/Src/Zle/compmatch.c @@ -1161,8 +1161,8 @@ comp_match(char *pfx, char *sfx, char *w, Patprog cp, Cline *clp, int qu, /* We still break it into parts here, trying to build a sensible * cline list for these matches, too. */ - w = dupstring(w); wl = strlen(w); + w = dupstring_wlen(w, wl); *clp = bld_parts(w, wl, wl, NULL, NULL); *exact = 0; } else { @@ -2127,7 +2127,7 @@ cmp_anchors(Cline o, Cline n, int join) (j = join_strs(o->wlen, o->word, n->wlen, n->word))) { o->flags |= CLF_JOIN; o->wlen = strlen(j); - o->word = dupstring(j); + o->word = dupstring_wlen(j, o->wlen); return 2; } diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 360667884..6ac458c91 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -1296,8 +1296,7 @@ parse_cadef(char *nam, char **args) int l = strlen(p) - 1; if (*p == '(' && p[l] == ')') { - axor = p = dupstring(p + 1); - p[l - 1] = '\0'; + axor = p = dupstring_wlen(p + 1, l - 1); } else axor = NULL; if (!*p) { @@ -1317,8 +1316,7 @@ parse_cadef(char *nam, char **args) p = *++args; l = strlen(p) - 1; if (*p == '(' && p[l] == ')') { - axor = p = dupstring(p + 1); - p[l - 1] = '\0'; + axor = p = dupstring_wlen(p + 1, l - 1); } else axor = NULL; if (!*p) { @@ -1339,7 +1337,7 @@ parse_cadef(char *nam, char **args) LinkList list = newlinklist(); LinkNode node; - char **xp, sav; + char **xp; while (*p && *p != ')') { for (p++; inblank(*p); p++); @@ -1351,11 +1349,8 @@ parse_cadef(char *nam, char **args) if (!*p) break; - sav = *p; - *p = '\0'; - addlinknode(list, dupstring(q)); + addlinknode(list, dupstring_wlen(q, p - q)); xnum++; - *p = sav; } /* Oops, end-of-string. */ if (*p != ')') { diff --git a/Src/hist.c b/Src/hist.c index d0960a284..fa1ede3f0 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -3553,9 +3553,8 @@ bufferwords(LinkList list, char *buf, int *index, int flags) } else if (buf) { if (IS_REDIROP(tok) && tokfd >= 0) { char b[20]; - - sprintf(b, "%d%s", tokfd, tokstrings[tok]); - addlinknode(list, dupstring(b)); + int l = sprintf(b, "%d%s", tokfd, tokstrings[tok]); + addlinknode(list, dupstring_wlen(b, l)); num++; } else if (tok != NEWLIN) { addlinknode(list, dupstring(tokstrings[tok])); diff --git a/Src/string.c b/Src/string.c index 5f439926e..0fa13ac0d 100644 --- a/Src/string.c +++ b/Src/string.c @@ -57,21 +57,6 @@ dupstring_wlen(const char *s, unsigned len) return t; } -/* Duplicate string on heap, returning length of string */ - -/**/ -mod_export char * -dupstring_glen(const char *s, unsigned *len_ret) -{ - char *t; - - if (!s) - return NULL; - t = (char *) zhalloc((*len_ret = strlen((char *)s)) + 1); - strcpy(t, s); - return t; -} - /**/ mod_export char * ztrdup(const char *s) -- cgit v1.2.3 From e3f7f2fc8527409f42330e44bf9ff44d8c50efe1 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 30 Jan 2025 12:47:08 +0100 Subject: 53336: avoid GNU make specific use of $< in a non-inference rule --- ChangeLog | 3 +++ Doc/Makefile.in | 6 +++--- Etc/Makefile.in | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1dce0b334..19e5b2497 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-01-30 Oliver Kiddle + * 53336: Doc/Makefile.in, Etc/Makefile.in: + avoid GNU make specific use of $< in a non-inference rule + * 53335: Src/hist.c, Src/string.c, Src/Zle/compcore.c, Src/Zle/compctl.c, Src/Zle/compmatch.c, Src/Zle/computil.c: Remove unused dupstring_glen() function and make use of the diff --git a/Doc/Makefile.in b/Doc/Makefile.in index a986aa1c5..d9eec58e8 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -121,13 +121,13 @@ zsh.pdf zsh_a4.pdf zsh_us.pdf: $(sdir)/zsh.texi intro.pdf intro.a4.pdf intro.us.pdf: $(sdir)/intro.ms if test $@ = intro.us.pdf || \ { test $@ = intro.pdf && test "$(PAPERSIZE)" = us; }; then \ - pdfroff -mspdf --no-kill-null-pages -P-pletter --pdf-output=$@ $<; \ + pdfroff -mspdf --no-kill-null-pages -P-pletter --pdf-output=$@ $(sdir)/intro.ms; \ else \ - pdfroff -mspdf --no-kill-null-pages -P-pa4 --pdf-output=$@ $<; \ + pdfroff -mspdf --no-kill-null-pages -P-pa4 --pdf-output=$@ $(sdir)/intro.ms; \ fi intro.html: $(sdir)/intro.ms - if groff -ms -Thtml -P-jintro $< > tmp.html; then \ + if groff -ms -Thtml -P-jintro $(sdir)/intro.ms > tmp.html; then \ mv tmp.html $@; \ else \ rm -f tmp.html; false; \ diff --git a/Etc/Makefile.in b/Etc/Makefile.in index 9adba95db..53729a0bc 100644 --- a/Etc/Makefile.in +++ b/Etc/Makefile.in @@ -43,10 +43,10 @@ INSTALL = @INSTALL@ all: FAQ FAQ.html FAQ: $(sdir)/FAQ.yo - $(YODL2TXT) -o FAQ.txt $< && mv FAQ.txt $@ + $(YODL2TXT) -o FAQ.txt $(sdir)/FAQ.yo && mv FAQ.txt $@ FAQ.html: $(sdir)/FAQ.yo - $(YODL2HTML) -o $@ $< + $(YODL2HTML) -o $@ $(sdir)/FAQ.yo # ========== DEPENDENCIES FOR CLEANUP ========== -- cgit v1.2.3 From 20990fa7e4bad34bd7e3c145f93f19cb811e8856 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 30 Jan 2025 12:51:37 +0100 Subject: 53337: allow nameref -p --- ChangeLog | 2 ++ Doc/Zsh/mod_ksh93.yo | 2 +- Src/Modules/ksh93.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19e5b2497..3ddb16ace 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2025-01-30 Oliver Kiddle + * 53337: Doc/Zsh/mod_ksh93.yo, Src/Modules/ksh93.c: allow nameref -p + * 53336: Doc/Makefile.in, Etc/Makefile.in: avoid GNU make specific use of $< in a non-inference rule diff --git a/Doc/Zsh/mod_ksh93.yo b/Doc/Zsh/mod_ksh93.yo index 7508758aa..7d22064ee 100644 --- a/Doc/Zsh/mod_ksh93.yo +++ b/Doc/Zsh/mod_ksh93.yo @@ -12,7 +12,7 @@ The single builtin provided by this module is: startitem() findex(nameref) cindex(named references, creating) -item(tt(nameref) [ tt(-gur) ] var(pname)[tt(=)var(rname)])( +item(tt(nameref) [ tt(-gpur) ] var(pname)[tt(=)var(rname)])( Equivalent to tt(typeset -n )var(pname)tt(=)var(rname) However, tt(nameref) is a builtin command rather than a reserved word, diff --git a/Src/Modules/ksh93.c b/Src/Modules/ksh93.c index 3206c11f3..fa0785cda 100644 --- a/Src/Modules/ksh93.c +++ b/Src/Modules/ksh93.c @@ -38,7 +38,7 @@ */ static struct builtin bintab[] = { - BUILTIN("nameref", BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "gur", "n") + BUILTIN("nameref", BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "gpru", "n") }; #include "zsh.mdh" -- cgit v1.2.3 From 13417c27014aee0bb201988ecd81421f2e987c8c Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 30 Jan 2025 12:53:48 +0100 Subject: 53338: complete typeset -n option --- ChangeLog | 2 ++ Completion/Zsh/Command/_typeset | 61 +++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ddb16ace..27ae19b06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2025-01-30 Oliver Kiddle + * 53338: Completion/Zsh/Command/_typeset: complete typeset -n option + * 53337: Doc/Zsh/mod_ksh93.yo, Src/Modules/ksh93.c: allow nameref -p * 53336: Doc/Makefile.in, Etc/Makefile.in: diff --git a/Completion/Zsh/Command/_typeset b/Completion/Zsh/Command/_typeset index 058842378..59ee8ec0a 100644 --- a/Completion/Zsh/Command/_typeset +++ b/Completion/Zsh/Command/_typeset @@ -1,59 +1,61 @@ -#compdef autoload declare export functions integer float local readonly typeset +#compdef autoload declare export functions integer float local nameref private readonly typeset local expl state state_descr line func i use curcontext="$curcontext" ret=1 local fopts="-f -k -z +k +z" -local popts="-A -E -F -L -R -T -Z -a -g -h -H -i -l -r -x" +local popts="-A -E -F -L -R -T -Z -a -g -h -H -i -l -n -r -x" local -A allargs opt_args local -a args allargs=( - A "($fopts -E -F -L -R -T -U -Z -a -i -m)-A[specify that arguments refer to associative arrays]" - E "($fopts -A -F -L -R -T -U -Z -a -i -m)-E[floating point, use engineering notation on output]" - F "($fopts -A -E -L -R -T -U -Z -a -i -m)-F[floating point, use fixed point decimal on output]" - L "($fopts -A -E -F -i)-L+[left justify and remove leading blanks from value]:width" - R "($fopts -A -E -F -i)-R+[right justify and fill with leading blanks]:width" - T "($fopts -A -E -F -a -g -h -i -l -m -t)-T[tie scalar to array or trace function]" + A "($fopts -E -F -L -R -T -U -Z -a -i -m -n)-A[specify that arguments refer to associative arrays]" + E "($fopts -A -F -L -R -T -U -Z -a -i -m -n)-E[floating point, use engineering notation on output]" + F "($fopts -A -E -L -R -T -U -Z -a -i -m -n)-F[floating point, use fixed point decimal on output]" + L "($fopts -A -E -F -i -n)-L+[left justify and remove leading blanks from value]:width" + R "($fopts -A -E -F -i -n)-R+[right justify and fill with leading blanks]:width" + T "($fopts -A -E -F -a -g -h -i -l -m -n -t)-T[tie scalar to array or trace function]" Tf "($popts -t)-T[trace execution of this function only]" - Tp "($fopts -A -E -F -a -g -h -i -l -m -t)-T[tie scalar to array]" + Tp "($fopts -A -E -F -a -g -h -i -l -m -n -t)-T[tie scalar to array]" U '(-A -E -F -i)-U[keep array values unique and suppress alias expansion for functions]' Uf '-U[suppress alias expansion for functions]' - Up '(-E -F -i)-+U[keep array values unique]' + Up '(-E -F -i -n)-+U[keep array values unique]' X '+X[immediately autoload function]' - Z "($fopts -A -E -F -i)-Z+[right justify and fill with leading zeros]:width" - a "($fopts -A -E -F -T -i)-a[specify that arguments refer to arrays]" + Z "($fopts -A -E -F -i -n)-Z+[right justify and fill with leading zeros]:width" + a "($fopts -A -E -F -T -i +i)-a[specify that arguments refer to arrays]" df "-d[default absolute path autoload to fpath]" f "($popts)-f[specify that arguments refer to functions]" - g "($fopts -T)-+g[do not restrict parameter to local scope]" - h "($fopts -T)-+h[hide specialness of parameter]" - H "($fopts -T)-+H[hide value of parameter in listings]" - i "($fopts -A -E -F -T)-+i[represent internally as an integer]" + g "($fopts -T)-+g[don't restrict parameter to local scope]" + h "($fopts -T -n)-+h[hide specialness of parameter]" + H "($fopts -T -n)-+H[hide value of parameter in listings]" + i "($fopts -A -E -F -T -n)-+i[represent internally as an integer]" k "($popts -w -z)-+k[mark function for ksh-style autoloading]" - l "($popts -T)-l[convert the value to lowercase]" - m '(-A -E -F -T -i)-m[treat arguments as patterns]' + l "($popts -T -n)-l[convert the value to lowercase]" + m '(-A -E -F -T -i -n)-m[treat arguments as patterns]' + n "($fopts -A -E -F -H +H -L -R -T -U +U -Z -a -i +i -h +h -l -m -t +t -x +x)-n[make parameter a reference to another parameter]" p '-p+[output parameters in form of calls to typeset]::option:((1\:multi-line\ output\ of\ arrays))' r '(-f)-+r[mark parameters as readonly]' rf '-r[remember autoload path]' Rf '-R[remember autoload path, error if not found]' - t '(-T)-+t[tag parameters and turn on execution tracing for functions]' + t '(-T -n)-+t[tag parameters and turn on execution tracing for functions]' tf '(-T)-+t[turn on execution tracing for functions]' - tp '(-T)-+t[tag parameters]' + tp '(-T -n)-+t[tag parameters]' u '-u[convert the value to uppercase or mark function for autoloading]' uf '-u[mark function for autoloadling]' up '-u[convert the value to uppercase]' w '(-k -z)-w[specify that arguments refer to files compiled with zcompile]' W '-+W[turn on WARN_NESTED_VAR for function]' - x "($fopts)-+x[export parameter]" + x "($fopts -n)-+x[export parameter]" z "($popts -k -w)-+z[mark function for zsh-style autoloading]" ) +allargs[rp]="$allargs[r]" -use="AEFHLRTUZafghiklmprtuxz" +use="AEFHLRTUZafghiklmnprtuxz" case ${service} in autoload) use="URTXdkrtwz" func=f ;; - float) use="EFHghlprtux";; + float) use="EFHghlprtux" func=p ;; functions) use="UkmTtuzW" func=f @@ -66,15 +68,20 @@ case ${service} in ;; integer) use="Hghilprtux" + func=p allargs[i]='-i+[specify arithmetic base for output]:: :_guard "[0-9]#" base' \ ;; - readonly) use="${use/r/}" ;; - local) use="${use//[fgkz]/}" ;; - export) use="${use//[fgkxz]/}" ;; + readonly) use="${use//[nr]/}" func=p ;; + local) use="${use//[fgkpz]/}" func=p ;; + export) use="${use//[fgknxz]/}" func=p ;; + nameref) use="gpur" func=p ;; + private) use="${use//[fgkpzT]/}" func=p ;; esac -[[ -z "${words[(r)-*[aA]*]}" ]] || func=p +[[ -z "${words[(r)-*[AEFHLRTZaghinrx]*]}" ]] || func=p [[ -z "${words[(r)-*f*]}" ]] || func=f +[[ $service = nameref || -n "${words[(r)-*n*]}" ]] && + allargs[up]='-u[reference the upper (calling function) scope]' # This function uses whacky features of _arguments which means we # need to look for options to the command beforehand. -- cgit v1.2.3 From 8cddd97297365f91e0f816f5364e06f77b0a2358 Mon Sep 17 00:00:00 2001 From: Eisuke Kawashima Date: Wed, 3 Apr 2024 00:36:22 +0900 Subject: github #118: completion(git-rebase): non-interactive mode also supports --autosquash --- ChangeLog | 3 +++ Completion/Unix/Command/_git | 11 ++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 27ae19b06..6e5689d8d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-01-30 Oliver Kiddle + * github #118: Eisuke Kawashima: Completion/Unix/Command/_git: + git rebase non-interactive mode also supports --autosquash + * 53338: Completion/Zsh/Command/_typeset: complete typeset -n option * 53337: Doc/Zsh/mod_ksh93.yo, Src/Modules/ksh93.c: allow nameref -p diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index a442b45d2..702360ef3 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -1565,14 +1565,6 @@ _git-range-diff () { (( $+functions[_git-rebase] )) || _git-rebase () { - local -a autosquash_opts - - if (( words[(I)-i|--interactive] )); then - autosquash_opts=( - '( --no-autosquash)--autosquash[check for auto-squash boundaries]' - '(--autosquash )--no-autosquash[do not check for auto-squash boundaries]') - fi - _arguments -s -S $endopt \ - actions \ '(-)--continue[continue after resolving merge conflict]' \ @@ -1605,7 +1597,8 @@ _git-rebase () { '(--apply --whitespace -C)*'{-s+,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies' \ '(--apply --whitespace -C)*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]: :_git_strategy_options' \ '(1 --keep-base --fork-point)--root[rebase all reachable commits]' \ - $autosquash_opts \ + '(--no-autosquash)--autosquash[check for auto-squash boundaries]' \ + "(--autosquash)--no-autosquash[don't check for auto-squash boundaries]" \ '(--autostash --no-autostash)--autostash[stash uncommitted changes before rebasing and apply them afterwards]' \ "(--autostash --no-autostash)--no-autostash[don't stash uncommitted changes before rebasing and apply them afterwards]" \ '(--root)--fork-point[use merge-base --fork-point to refine upstream]' \ -- cgit v1.2.3 From 51cb3f0f83649b7ca59d62447519f7ea53fb5ec4 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 4 Feb 2025 15:39:36 +0900 Subject: unposted: remove a few more files by 'make clean' Doc/zsh.{idx,kys} and Etc/FAQ{01-06}.html. These files are already in .gitignore --- ChangeLog | 5 +++++ Doc/Makefile.in | 2 +- Etc/Makefile.in | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6e5689d8d..59a04e638 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-02-04 Jun-ichi Takimoto + + * unposted: Doc/Makefile.in, Etc/Makefile.in: remove a few more + files by 'make clean' + 2025-01-30 Oliver Kiddle * github #118: Eisuke Kawashima: Completion/Unix/Command/_git: diff --git a/Doc/Makefile.in b/Doc/Makefile.in index d9eec58e8..f68f40a9e 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -414,7 +414,7 @@ uninstall.html: clean-here: rm -f *.html *.info* *.dvi *.ps *.pdf - rm -f *.aux *.cp *.cps *.fn *.fns *.ky *.log + rm -f *.aux *.cp *.cps *.fn *.fns *.ky *.kys *.log *.idx rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs rm -rf infodir rm -f texi2html.conf diff --git a/Etc/Makefile.in b/Etc/Makefile.in index 53729a0bc..c1032d118 100644 --- a/Etc/Makefile.in +++ b/Etc/Makefile.in @@ -53,7 +53,7 @@ FAQ.html: $(sdir)/FAQ.yo @CLEAN_MK@ mostlyclean-here: - rm -f FAQ.html + rm -f FAQ*.html distclean-here: rm -f Makefile -- cgit v1.2.3 From 7a54b36fa88aa35f44c42715503f716a1612e3b7 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 12 Feb 2025 20:03:07 -0800 Subject: 53348: Revise handling of incompatible typeset options when used with -n --- ChangeLog | 5 +++++ Doc/Zsh/builtins.yo | 10 ++++++---- Src/builtin.c | 15 ++++++++++++--- Test/K01nameref.ztst | 2 +- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 59a04e638..929abce32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-02-12 Bart Schaefer + + * 53348: Doc/Zsh/builtins.yo, Src/builtin.c, Test/K01nameref.ztst: + Revise handling of incompatible typeset options when used with -n + 2025-02-04 Jun-ichi Takimoto * unposted: Doc/Makefile.in, Etc/Makefile.in: remove a few more diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 7a9684ac8..69bb86a0f 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2052,8 +2052,10 @@ cindex(named reference) cindex(reference, named) The flag tt(-n) creates a em(named reference) to another parameter. The second parameter need not exist at the time the reference is -created. Only tt(-g), tt(-u), and tt(-r) may be used in conjunction with -tt(-n). The var(name) so created may not be an array element nor use +created. Only the tt(-H), tt(-g), and tt(-r) flags may be used in +conjunction with tt(-n), having their usual meanings. The tt(-u) +flag is special and may be applied to alter the scope of the reference. +The var(name) so created may not be an array element nor use a subscript, but the var(value) assigned may be any valid parameter name syntax, even a subscripted array element (including an associative array element) or an array slice, which is evaluated when the named @@ -2286,7 +2288,7 @@ special tt(PATH) parameter is not altered in any way. It is also possible to create a local parameter using `tt(typeset +h )var(special)', where the local copy of var(special) will retain its special properties regardless of having the tt(-h) attribute. Global special parameters loaded from shell -modules (currently those in tt(zsh/mapfile) and tt(zsh/parameter)) are +modules (for example, those in tt(zsh/mapfile) and tt(zsh/parameter)) are automatically given the tt(-h) attribute to avoid name clashes. ) item(tt(-H))( @@ -2349,7 +2351,7 @@ flag has a different meaning when used with tt(-f); see above. item(tt(-u))( Convert the result to upper case whenever the parameter is expanded. The value is em(not) converted when assigned. -This flag has a different meaning when used with tt(-f); see above. +This flag has different meanings when used with tt(-f) or tt(-n); see above. ) item(tt(-x))( Mark for automatic export to the environment of subsequently diff --git a/Src/builtin.c b/Src/builtin.c index 18d74b09e..2fab73b24 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2707,10 +2707,18 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) on |= bit; else if (OPT_PLUS(ops,optval)) off |= bit; + else + continue; + if (OPT_MINUS(ops,'n')) { + if ((on|off) & ~(PM_READONLY|PM_UPPER|PM_HIDEVAL)) { + zwarnnam(name, "-%c not allowed with -n", optval); + /* return 1; */ + } + } } if (OPT_MINUS(ops,'n')) { - if ((on|off) & ~(PM_READONLY|PM_UPPER)) { - zwarnnam(name, "no other attributes allowed with -n"); + if ((on|off) & ~(PM_READONLY|PM_UPPER|PM_HIDEVAL)) { + /* zwarnnam(name, "no other attributes allowed with -n"); */ return 1; } on |= PM_NAMEREF; @@ -3049,7 +3057,8 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) /* It's generally unwise to mass-change the types of * parameters, but for namerefs it would be fatal */ unqueue_signals(); - zerrnam(name, "invalid reference"); + zerrnam(name, "%cm not allowed with -n", + (OPT_PLUS(ops,'m') ? '+' : '-')); return 1; } if (!(on|roff)) diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index bb0d11821..bacc3ade2 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -853,7 +853,7 @@ F:previously this could create an infinite recursion and crash typeset -nm foo=bar 1:create nameref by pattern match not allowed -*?*typeset:1: invalid reference +*?*typeset:1: -m not allowed with -n # # The following tests are run in interactive mode, using PS1 as an -- cgit v1.2.3 From 6b25a593d9dab13fd0314467ff93ba88546b3470 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 12 Feb 2025 20:06:43 -0800 Subject: 53346 (cf. 53350): Util/helpfiles: fix use of "man" on file paths --- ChangeLog | 2 ++ Util/helpfiles | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 929abce32..2c11f7081 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2025-02-12 Bart Schaefer + * 53346 (cf. 53350): Util/helpfiles: fix use of "man" on file paths + * 53348: Doc/Zsh/builtins.yo, Src/builtin.c, Test/K01nameref.ztst: Revise handling of incompatible typeset options when used with -n diff --git a/Util/helpfiles b/Util/helpfiles index 9e837fe2d..58aa04bba 100755 --- a/Util/helpfiles +++ b/Util/helpfiles @@ -54,7 +54,7 @@ $ENV{'GROFF_NO_SGR'} = ''; # We need "classical" formatting of man pages. $mantmp = $destdir . '/man.tmp'; $coltmpbase = 'col.tmp'; $coltmp = $destdir . '/' . $coltmpbase; -$args = "$manfile >$mantmp"; +$args = "./$manfile >$mantmp"; unlink($mantmp); &Info('attempting man ', $args); if(system('man ' . $args) || !(-s $mantmp)) { -- cgit v1.2.3 From 3ce354c049d265371187147dc4541b56fd60d786 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 12 Feb 2025 20:11:47 -0800 Subject: 53360: domenuselect() fails if the previous completion did not generate a list (fix for segfault) --- ChangeLog | 3 +++ Src/Zle/complist.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2c11f7081..cc1caff26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-02-12 Bart Schaefer + * 53360: Src/Zle/complist.c: domenuselect() fails if the previous + completion did not generate a list (fix for segfault) + * 53346 (cf. 53350): Util/helpfiles: fix use of "man" on file paths * 53348: Doc/Zsh/builtins.yo, Src/builtin.c, Test/K01nameref.ztst: diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 5619160a9..091ad03b1 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -2391,6 +2391,9 @@ domenuselect(Hookdef dummy, Chdata dat) char *s; char status[MAX_STATUS], *modeline = NULL; + if (! hasoldlist) + return 2; + msearchstack = NULL; msearchstr = ""; msearchstate = MS_OK; -- cgit v1.2.3 From 2e08ea1aef9d47b2919d7e5bd2cb6bb01c8029fc Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 13 Feb 2025 23:11:09 +0100 Subject: 53358: adapt completion to reflect 53348 and extend exclusion lists to cover more + options --- ChangeLog | 5 ++++ Completion/Zsh/Command/_typeset | 56 ++++++++++++++++++++--------------------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc1caff26..990509ae1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-02-13 Oliver Kiddle + + * 53358: Completion/Zsh/Command/_typeset: adapt completion to + reflect 53348 and extend exclusion lists to cover more + options + 2025-02-12 Bart Schaefer * 53360: Src/Zle/complist.c: domenuselect() fails if the previous diff --git a/Completion/Zsh/Command/_typeset b/Completion/Zsh/Command/_typeset index 59ee8ec0a..1952a6338 100644 --- a/Completion/Zsh/Command/_typeset +++ b/Completion/Zsh/Command/_typeset @@ -2,48 +2,48 @@ local expl state state_descr line func i use curcontext="$curcontext" ret=1 local fopts="-f -k -z +k +z" -local popts="-A -E -F -L -R -T -Z -a -g -h -H -i -l -n -r -x" +local popts="-A +A -E +E -F +F -L +L -R +R -T -Z +Z -a +a -g +g -h +h -H +H -i +i -l +l -n +n -r +r -x +x" local -A allargs opt_args local -a args allargs=( - A "($fopts -E -F -L -R -T -U -Z -a -i -m -n)-A[specify that arguments refer to associative arrays]" - E "($fopts -A -F -L -R -T -U -Z -a -i -m -n)-E[floating point, use engineering notation on output]" - F "($fopts -A -E -L -R -T -U -Z -a -i -m -n)-F[floating point, use fixed point decimal on output]" - L "($fopts -A -E -F -i -n)-L+[left justify and remove leading blanks from value]:width" - R "($fopts -A -E -F -i -n)-R+[right justify and fill with leading blanks]:width" - T "($fopts -A -E -F -a -g -h -i -l -m -n -t)-T[tie scalar to array or trace function]" - Tf "($popts -t)-T[trace execution of this function only]" - Tp "($fopts -A -E -F -a -g -h -i -l -m -n -t)-T[tie scalar to array]" - U '(-A -E -F -i)-U[keep array values unique and suppress alias expansion for functions]' + A "($fopts -A +A -E +E -F +F -L +L -R +R -T -U +U -Z +Z -a +a -i +i -m +m -n +n)-+A[specify that arguments refer to associative arrays]" + E "($fopts -A +A -E +E -F +F -L +L -R +R -T -U +U -Z +Z -a +a -i +i -m +m -n +n)-+E[floating point, use engineering notation on output]" + F "($fopts -A +A -E +E -F +F -L +L -R +R -T -U +U -Z +Z -a +a -i +i -m +m -n +n)-+F[floating point, use fixed point decimal on output]" + L "($fopts -A +A -E +E -F +F -L +L -R +R -i -n +n)-+L+[left justify and remove leading blanks from value]:width" + R "($fopts -A +A -E +E -F +F -L +L -R +R -i -n +n)-+R+[right justify and fill with leading blanks]:width" + T "($fopts -A +A -E -F -a +a -g -h -i -l +l -m +m -n +n -t)-T[tie scalar to array or trace function]" + Tf "($popts -t +t -T +T)-+T[trace execution of this function only]" + Tp "($fopts -A +A -E +E -F +F -a +a -g -h -i -l +l -m +m -n +n -t)-T[tie scalar to array]" + U '(-A +A -E +E -F +F -i)-U[keep array values unique and suppress alias expansion for functions]' Uf '-U[suppress alias expansion for functions]' - Up '(-E -F -i -n)-+U[keep array values unique]' + Up '(-E +E -F +F -i -n +n)-+U[keep array values unique]' X '+X[immediately autoload function]' - Z "($fopts -A -E -F -i -n)-Z+[right justify and fill with leading zeros]:width" - a "($fopts -A -E -F -T -i +i)-a[specify that arguments refer to arrays]" + Z "($fopts -A +A -E +E -F +F -Z +Z -i -n +n)-+Z+[right justify and fill with leading zeros]:width" + a "($fopts -A +A -E +E -F +F -T -i +i)-+a[specify that arguments refer to arrays]" df "-d[default absolute path autoload to fpath]" - f "($popts)-f[specify that arguments refer to functions]" + f "($popts -f +f)-+f[specify that arguments refer to functions]" g "($fopts -T)-+g[don't restrict parameter to local scope]" - h "($fopts -T -n)-+h[hide specialness of parameter]" - H "($fopts -T -n)-+H[hide value of parameter in listings]" - i "($fopts -A -E -F -T -n)-+i[represent internally as an integer]" + h "($fopts -T -n +n)-+h[hide specialness of parameter]" + H "($fopts -T)-+H[hide value of parameter in listings]" + i "($fopts -A +A -E +E -F +F -T -n +n)-+i[represent internally as an integer]" k "($popts -w -z)-+k[mark function for ksh-style autoloading]" - l "($popts -T -n)-l[convert the value to lowercase]" - m '(-A -E -F -T -i -n)-m[treat arguments as patterns]' - n "($fopts -A -E -F -H +H -L -R -T -U +U -Z -a -i +i -h +h -l -m -t +t -x +x)-n[make parameter a reference to another parameter]" + l "($popts -T -n +n)-+l[convert the value to lowercase]" + m '(-A +A -E +E -F +F -T -i -n)-+m[treat arguments as patterns]' + n "($fopts -A +A -E +E -F +F -L -R -T -U +U -Z +Z -a +a -i +i -h +h -l +l -m +m -t +t -x +x)-+n[make parameter a reference to another parameter]" p '-p+[output parameters in form of calls to typeset]::option:((1\:multi-line\ output\ of\ arrays))' - r '(-f)-+r[mark parameters as readonly]' + r '(-f -r +r)-+r[mark parameters as readonly]' rf '-r[remember autoload path]' Rf '-R[remember autoload path, error if not found]' - t '(-T -n)-+t[tag parameters and turn on execution tracing for functions]' - tf '(-T)-+t[turn on execution tracing for functions]' - tp '(-T -n)-+t[tag parameters]' + t '(-T -n +n)-+t[tag parameters and turn on execution tracing for functions]' + tf '(-t +t -T +T)-+t[turn on execution tracing for functions]' + tp '(-T -n +n)-+t[tag parameters]' u '-u[convert the value to uppercase or mark function for autoloading]' uf '-u[mark function for autoloadling]' - up '-u[convert the value to uppercase]' + up '(-u +u)-+u[convert the value to uppercase]' w '(-k -z)-w[specify that arguments refer to files compiled with zcompile]' W '-+W[turn on WARN_NESTED_VAR for function]' - x "($fopts -n)-+x[export parameter]" + x "($fopts -n +n)-+x[export parameter]" z "($popts -k -w)-+z[mark function for zsh-style autoloading]" ) allargs[rp]="$allargs[r]" @@ -60,8 +60,8 @@ case ${service} in use="UkmTtuzW" func=f args=( - '(-k -t -T -u -U -W -x -z -M +M +k +t +W +z)-+M[define mathematical function]' - '(-k -m -t -T -u -U -W -x -z +M +k +t +W +z)-s[define mathematical function that takes a string argument]' + '(-k -t -T +T -u -U -W -x -z -M +M +k +t +W +z)-+M[define mathematical function]' + '(-k -m +m -t -T +T -u -U -W -x -z +M +k +t +W +z)-s[define mathematical function that takes a string argument]' '(-M)-x+[specify spaces to use for indentation]:spaces' '(-* +*)-c[copy shell function to another name]:old name:_functions:new name:_functions' ) -- cgit v1.2.3 From 8701313c615394654f47586c9a4961ac8893bf5b Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 15 Feb 2025 14:29:51 -0800 Subject: 53363: permit "typeset -n +m pattern" Also fix spurious error printing the value of a read-only named reference --- ChangeLog | 7 +++++++ Src/builtin.c | 7 +++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 990509ae1..05aa89c88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2025-02-15 Bart Schaefer + + * 53363: Src/builtin.c: permit "typeset -n +m pattern" + + * unposted: Src/builtin.c: fix spurious error printing the value + of a read-only named reference + 2025-02-13 Oliver Kiddle * 53358: Completion/Zsh/Command/_typeset: adapt completion to diff --git a/Src/builtin.c b/Src/builtin.c index 2fab73b24..6bdaddff0 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2254,7 +2254,7 @@ typeset_single(char *cname, char *pname, Param pm, int func, /* It seems as though these checks should not be specific to * PM_NAMEREF, but changing that changes historic behavior */ ((on & PM_NAMEREF) != (pm->node.flags & PM_NAMEREF) || - (asg && (pm->node.flags & PM_NAMEREF)))) { + (asg && (pm->node.flags & PM_NAMEREF))) && !OPT_ISSET(ops,'p')) { zerrnam(cname, "%s: read-only %s", pname, (pm->node.flags & PM_NAMEREF) ? "reference" : "variable"); return NULL; @@ -3053,12 +3053,11 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) /* With the -m option, treat arguments as glob patterns */ if (OPT_ISSET(ops,'m')) { if (!OPT_ISSET(ops,'p')) { - if (on & PM_NAMEREF) { + if ((on & PM_NAMEREF) && OPT_MINUS(ops,'m')) { /* It's generally unwise to mass-change the types of * parameters, but for namerefs it would be fatal */ unqueue_signals(); - zerrnam(name, "%cm not allowed with -n", - (OPT_PLUS(ops,'m') ? '+' : '-')); + zerrnam(name, "-m not allowed with -n"); return 1; } if (!(on|roff)) -- cgit v1.2.3 From e160cf85f05c3106189edf2158146b9f522d1f1c Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 27 Feb 2025 16:02:02 +0100 Subject: 53378: support new pipebuf resource limit on FreeBSD Also add other newer limits to the documentation. --- ChangeLog | 5 +++++ Doc/Zsh/builtins.yo | 14 ++++++++++++-- Src/Builtins/rlimits.c | 4 ++++ configure.ac | 1 + 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05aa89c88..80745557f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-02-27 Oliver Kiddle + + * 53378: Doc/Zsh/builtins.yo, Src/Builtins/rlimits.c, configure.ac: + support new pipebuf resource limit on FreeBSD + 2025-02-15 Bart Schaefer * 53363: Src/builtin.c: permit "typeset -n +m pattern" diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 69bb86a0f..103b6d842 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1218,19 +1218,26 @@ sitem(tt(datasize))(Maximum data size (including stack) for each process.) sitem(tt(descriptors))(Maximum value for a file descriptor.) sitem(tt(filesize))(Largest single file allowed.) sitem(tt(kqueues))(Maximum number of kqueues allocated.) +sitem(tt(maxfilelocks))(Maximum number of file locks.) sitem(tt(maxproc))(Maximum number of processes.) sitem(tt(maxpthreads))(Maximum number of threads per process.) sitem(tt(memorylocked))(Maximum amount of memory locked in RAM.) sitem(tt(memoryuse))(Maximum resident set size.) sitem(tt(msgqueue))(Maximum number of bytes in POSIX message queues.) +sitem(tt(nice))(Maximum nice value.) +sitem(tt(pipebuf))(Maximum size of buffers for pipes/fifos.) sitem(tt(posixlocks))(Maximum number of POSIX locks per user.) sitem(tt(pseudoterminals))(Maximum number of pseudo-terminals.) sitem(tt(resident))(Maximum resident set size.) +sitem(tt(rt_priority))(Maximum real-time priority.) +sitem(tt(rt_time))(Maximum CPU time without a blocking system call.) sitem(tt(sigpending))(Maximum number of pending signals.) sitem(tt(sockbufsize))(Maximum size of all socket buffers.) sitem(tt(stacksize))(Maximum stack size for each process.) sitem(tt(swapsize))(Maximum amount of swap used.) +sitem(tt(umtxp))(Maximum number of POSIX thread library objects.) sitem(tt(vmemorysize))(Maximum amount of virtual memory.) +sitem(tt(vnodemonitors))(Maximum number of open vnode monitors.) endsitem() Which of these resource limits are available depends on the system. @@ -2390,16 +2397,18 @@ Not all the following resources are supported on all systems. Running tt(ulimit -a) will show which are supported. startsitem() -sitem(tt(-a))(Lists all of the current resource limits.) +sitem(tt(-a))(List all of the current resource limits.) sitem(tt(-b))(Socket buffer size in bytes LPAR()N.B. not kilobytes+RPAR()) sitem(tt(-c))(512-byte blocks on the size of core dumps.) sitem(tt(-d))(Kilobytes on the size of the data segment.) +sitem(tt(-e))(Maximum nice value.) sitem(tt(-f))(512-byte blocks on the size of files written.) sitem(tt(-i))(The number of pending signals.) sitem(tt(-k))(The number of kqueues allocated.) sitem(tt(-l))(Kilobytes on the size of locked-in memory.) sitem(tt(-m))(Kilobytes on the size of physical memory.) -sitem(tt(-n))(open file descriptors.) +sitem(tt(-n))(Open file descriptors.) +sitem(tt(-o))(Maximum number of POSIX thread library objects.) sitem(tt(-p))(The number of pseudo-terminals.) sitem(tt(-q))(Bytes in POSIX message queues.) sitem(tt(-r))(Maximum real time priority. On some systems where this @@ -2413,6 +2422,7 @@ sitem(tt(-v))(Kilobytes on the size of virtual memory. On some systems this refers to the limit called `address space'.) sitem(tt(-w))(Kilobytes on the size of swapped out memory.) sitem(tt(-x))(The number of locks on files.) +sitem(tt(-y))(Maximum size of buffers for pipes/fifos.) endsitem() A resource may also be specified by integer in the form `tt(-N) diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index f25dd2530..65226dc9a 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -145,6 +145,10 @@ static const resinfo_T known_resources[] = { {RLIMIT_UMTXP, "umtxp", ZLIMTYPE_NUMBER, 1, 'o', "umtx shared locks"}, # endif +# ifdef HAVE_RLIMIT_PIPEBUF /* FreeBSD */ + {RLIMIT_PIPEBUF, "pipebuf", ZLIMTYPE_MEMORY, 1024, + 'y', "size of buffers for pipes/fifos"}, +#endif # ifdef HAVE_RLIMIT_POSIXLOCKS /* DragonFly */ {RLIMIT_POSIXLOCKS, "posixlocks", ZLIMTYPE_NUMBER, 1, diff --git a/configure.ac b/configure.ac index b5548c2b9..db0828a56 100644 --- a/configure.ac +++ b/configure.ac @@ -1873,6 +1873,7 @@ zsh_LIMIT_PRESENT(RLIMIT_NPTS) zsh_LIMIT_PRESENT(RLIMIT_SWAP) zsh_LIMIT_PRESENT(RLIMIT_KQUEUES) zsh_LIMIT_PRESENT(RLIMIT_UMTXP) +zsh_LIMIT_PRESENT(RLIMIT_PIPEBUF) zsh_LIMIT_PRESENT(RLIMIT_NOVMON) zsh_LIMITS_EQUAL(VMEM, vmem, RSS, rss) -- cgit v1.2.3 From 1818323f451f426f20ca47c50e8fc63824578479 Mon Sep 17 00:00:00 2001 From: Vadim Misbakh-Soloviov Date: Wed, 19 Feb 2025 17:20:14 +0700 Subject: github #129: fix _gpg completion 1) As for now, `--local-user` completion is irrelevant: it completes system users, while gpg expects private keys IDs 2) `secret-keys` completion was also broken and completed nothing. The reason of that to happen was in that fact that it assumed `uid` token would be next after `fpr` (same as it do in public-keys completion), while in current gnupg versions there is at least `grp` token, and potentially can be others. So, instead i+=2 I made `until "uid"` loop. --- ChangeLog | 3 +++ Completion/Unix/Command/_gpg | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 80745557f..cd00105cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-02-27 Oliver Kiddle + * github #129: Vadim Misbakh-Soloviov: + Completion/Unix/Command/_gpg: fix _gpg completion + * 53378: Doc/Zsh/builtins.yo, Src/Builtins/rlimits.c, configure.ac: support new pipebuf resource limit on FreeBSD diff --git a/Completion/Unix/Command/_gpg b/Completion/Unix/Command/_gpg index 2161d2d24..ea0a452f2 100644 --- a/Completion/Unix/Command/_gpg +++ b/Completion/Unix/Command/_gpg @@ -29,7 +29,7 @@ fi '(-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' + '(-u --local-user)'{-u+,--local-user}'[use name as the user ID to sign]:key:->secret-keys' '(-o --output)'{-o+,--output}'[write output to file]:output file:_files' '(-h --help)'{-h,--help}'[display usage information]' '--version[print info on program version and supported algorithms]' @@ -238,7 +238,11 @@ case "$state" in parts=("${(@s.:.)secret_keys_lines[$i]}") if [[ ${parts[1]} == "fpr" ]]; then current_uid="${parts[10]}" - i=$((i + 1)) + until [[ "${${(@s.:.)secret_keys_lines[$i]}[1]}" == "uid" ]] || [[ "${i}" -ge "${#secret_keys_lines[@]}" ]]; do + # it can be "grp" or other tokens. + # Let's iterate until we found "uid" or face an end of secret keys array + i=$((i + 1)) + done parts=("${(@s.:.)secret_keys_lines[$i]}") while [[ ${parts[1]} == "uid" ]]; do uids+=("${current_uid}") -- cgit v1.2.3 From f77e469ad60973f45e1ee178f1d66686d326a75a Mon Sep 17 00:00:00 2001 From: Ronan Pigott Date: Thu, 27 Feb 2025 12:01:45 -0700 Subject: 53393: Complete python module arguments Python modules can behave like commands in their own right. This allows modules to define _python_module-* functions that are used to complete module arguments. Also gets the ball rolling by defining completions for venv, http.server, and json.tool. --- ChangeLog | 8 ++++++++ Completion/Unix/Command/_python | 3 +++ Completion/Unix/Command/_python_module-http.server | 8 ++++++++ Completion/Unix/Command/_python_module-json.tool | 13 +++++++++++++ Completion/Unix/Command/_python_module-venv | 14 ++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 Completion/Unix/Command/_python_module-http.server create mode 100644 Completion/Unix/Command/_python_module-json.tool create mode 100644 Completion/Unix/Command/_python_module-venv diff --git a/ChangeLog b/ChangeLog index cd00105cc..a2ffa1381 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2025-02-28 Oliver Kiddle + + * Ronan Pigott: 53393: Completion/Unix/Command/_python, + Completion/Unix/Command/_python_module-http.server, + Completion/Unix/Command/_python_module-json.tool, + Completion/Unix/Command/_python_module-venv: + Complete python module arguments + 2025-02-27 Oliver Kiddle * github #129: Vadim Misbakh-Soloviov: diff --git a/Completion/Unix/Command/_python b/Completion/Unix/Command/_python index 6e209a199..a5d46cfd6 100644 --- a/Completion/Unix/Command/_python +++ b/Completion/Unix/Command/_python @@ -56,6 +56,9 @@ case "$state" in if [[ -z "$opt_args[(I)-(c|m)]" ]]; then shift words (( CURRENT-- )) + elif [[ -n "$opt_args[(I)-m]" ]]; then + local ret + _call_function ret _python_module-$opt_args[-m] && return ret fi _normal && return ;; diff --git a/Completion/Unix/Command/_python_module-http.server b/Completion/Unix/Command/_python_module-http.server new file mode 100644 index 000000000..e5ea4a8df --- /dev/null +++ b/Completion/Unix/Command/_python_module-http.server @@ -0,0 +1,8 @@ +#autoload + +_arguments -S \ + '(-h --help)'{-h,--help}'[show a help message and exit]' \ + '--cgi[run as CGI server]' \ + '(-b --bind)'{-b+,--bind=}'[bind to this address]:address:' \ + '(-d --directory)'{-d+,--directory=}'[serve this directory]:directory:_directories' \ + '(-p --protocol)'{-p+,--protocol=}'[conform to this HTTP version]:protcol version:(HTTP/1.0 HTTP/1.1)' diff --git a/Completion/Unix/Command/_python_module-json.tool b/Completion/Unix/Command/_python_module-json.tool new file mode 100644 index 000000000..61c22686b --- /dev/null +++ b/Completion/Unix/Command/_python_module-json.tool @@ -0,0 +1,13 @@ +#autoload + +_arguments -S \ + '(-h --help)'{-h,--help}'[show a help message and exit]' \ + '--sort-keys[sort the output of dictionaries alphabetically by key]' \ + '--no-ensure-ascii[disable escaping of non-ASCII characters]' \ + '--json-lines[parse input using the JSON Lines format]' \ + '--indent=[separate items with newlines and use this number of spaces for indentation]:spaces:' \ + '--tab[separate items with newlines and use tabs for indentation]' \ + '--no-indent[separate items with spaces rather than newlines]' \ + '--compact[suppress all whitespace separation]' \ + '1:infile:_files' \ + '2:outfile:_files' diff --git a/Completion/Unix/Command/_python_module-venv b/Completion/Unix/Command/_python_module-venv new file mode 100644 index 000000000..1af53cc41 --- /dev/null +++ b/Completion/Unix/Command/_python_module-venv @@ -0,0 +1,14 @@ +#autoload + +_arguments -S \ + '(-h --help)'{-h,--help}'[show a help message and exit]' \ + '--system-site-packages[give the virtual environment access to the system site-packages dir]' \ + '(--symlinks --copies)--symlinks[try to use symlinks rather than copies]' \ + '(--symlinks --copies)--copies[try to use copies rather than symlinks]' \ + '(--clear --upgrade)--clear[delete the contents of the environment directory if it already exists]' \ + '(--clear --upgrade)--upgrade[upgrade the environment directory to use this version of Python]' \ + '--without-pip[skip installing or upgrading pip]' \ + '--prompt[provides an alternative prompt prefix for the environment]' \ + '--upgrade-deps[upgrade core dependencies to the latest version]' \ + '--without-scm-ignore-files[skip adding SCM ignore files to the environment directory]' + '*::virtual environment:_directories' -- cgit v1.2.3 From eb8e217f1ba41c2146218bc74643a48c1a82d8b9 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 28 Feb 2025 20:58:34 +0100 Subject: 53395: complete snapshot ranges for zfs destroy --- ChangeLog | 4 ++++ Completion/Unix/Command/_zfs | 2 +- Completion/Unix/Type/_zfs_dataset | 32 ++++++++++++++++++++++++++++---- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2ffa1381..8cc81f4b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2025-02-28 Oliver Kiddle + * 53395: Completion/Unix/Type/_zfs_dataset, + Completion/Unix/Command/_zfs: + complete snapshot ranges for zfs destroy + * Ronan Pigott: 53393: Completion/Unix/Command/_python, Completion/Unix/Command/_python_module-http.server, Completion/Unix/Command/_python_module-json.tool, diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index 5a45c2920..ef4b80a41 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -434,7 +434,7 @@ case $service:$words[1] in '-R[recursively destroy all dependents]' \ '(-f)-d[delete or mark deferred]' \ '(-d)-f[force unmounts]' \ - ':dataset:_zfs_dataset -t fs -t vol ${=${opt_args[(i)-f]:--t snap}:/-f/} ${=${opt_args[(i)-*]:--t bookmark}:/-?/}' + ':dataset:_zfs_dataset -t fs -t vol ${=${opt_args[(i)-f]:--t snap -t range}:/-f/} ${=${opt_args[(i)-*]:--t bookmark}:/-?/}' ;; zfs:snap(|shot)) diff --git a/Completion/Unix/Type/_zfs_dataset b/Completion/Unix/Type/_zfs_dataset index 7edcfd5d7..0b3876148 100644 --- a/Completion/Unix/Type/_zfs_dataset +++ b/Completion/Unix/Type/_zfs_dataset @@ -1,6 +1,6 @@ #autoload -local -a type expl_type_arr rsrc rdst paths_allowed +local -a type expl_type_arr rsrc rdst paths_allowed suf local -a typearg datasetlist expl mlist local expl_type @@ -9,11 +9,16 @@ local expl_type # -r1 indicates that we're completing the source of a rename # -r2 indicates that we're completing the destination of a rename # -t takes arguments (what kinds of datasets) and can appear multiple times +# in addition to the usual types +# clone - cloned file systems +# mtpt - add mountpoints +# range - allow a range of snapshots zparseopts -D -E e:=expl_type_arr p=paths_allowed r1=rsrc r2=rdst t+:=type +suf=( -r '\n\t\- @\\#' ) [[ -n $type[(r)fs] ]] && typearg=( filesystem ) [[ -n $type[(r)vol] ]] && typearg+=( volume ) -[[ -n $type[(r)snap] ]] && typearg+=( snapshot ) +[[ -n $type[(r)snap] || -prefix *@ ]] && typearg+=( snapshot ) [[ -n $type[(r)share] && $implementation = solaris ]] && typearg+=( share ) [[ -n $type[(r)bookmark] && $implementation = openzfs ]] && typearg+=( bookmark ) @@ -62,7 +67,26 @@ fi if [[ -n $type[(r)clone] ]]; then datasetlist=( ${(f)"$(zfs list -H -o name,origin -t filesystem 2>/dev/null | awk -F$'\t' "\$2 != \"-\" {print \$1}")":#no cloned filesystems available} ) else - datasetlist=( ${(f)"$(zfs list -H -o name $typearg 2>/dev/null)":#no datasets available} ) + [[ -n $type[(r)range] && $implementation = openzfs ]] && + typearg+=( -s creation ) suf=( -S% -r '\n\t\- ,' ) + datasetlist=( ${(f)"$(zfs list -H -o name $typearg 2>/dev/null)":#no datasets available} ) +fi + +if [[ -n $type[(r)range] && -prefix *[%,] && $implementation = openzfs ]]; then + if [[ -n ${datasetlist[(r)${PREFIX%@*}@*]} ]]; then + datasetlist=( ${${(M)datasetlist:#${PREFIX%@*}@*}##*@} ) + compset -P '*[@,]' + # if we can find the starting snapshot filter to later ones + [[ -prefix *% ]] && (( ${#datasetlist[(r)${PREFIX%\%*},-1]} > 2 )) && + datasetlist=( ${${datasetlist[(r)${PREFIX%\%*},-1]}[2,-1]} ) + expl_type="" + compset -P '*%' && suf=( -qS, ) expl_type="end " + _description snapshots expl "${expl_type}snapshot" + compadd $suf "$expl[@]" -a datasetlist + else + _message -e snapshots 'snapshot' + fi + return fi expl_type=${typearg[2,-1]//,/\/} @@ -77,4 +101,4 @@ if [[ -n $expl_type_arr[2] ]]; then fi _description datasets expl "$expl_type" -_multi_parts "$@" "$expl[@]" -q / datasetlist +_multi_parts $suf "$@" "$expl[@]" -q / datasetlist -- cgit v1.2.3 From d315401a032cfada4ff733b20d708a5e76d75e48 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 2 Mar 2025 11:23:22 -0800 Subject: 53368: ignore no-op changes to EMACS/VI options --- ChangeLog | 4 ++++ Src/options.c | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8cc81f4b4..340a39479 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2025-03-02 Bart Schaefer + + * 53368: Src/options.c: ignore no-op changes to EMACS/VI options + 2025-02-28 Oliver Kiddle * 53395: Completion/Unix/Type/_zfs_dataset, diff --git a/Src/options.c b/Src/options.c index 8b37ab5e8..696ab5c69 100644 --- a/Src/options.c +++ b/Src/options.c @@ -887,8 +887,14 @@ dosetopt(int optno, int value, int force, char *new_opts) acquire_pgrp(); } } else if ((optno == EMACSMODE || optno == VIMODE) && value) { + /* What's going on here: + * 1) unsetopt of either emacs or vi is an effective no-op. + * 2) setopt of either emacs or vi toggles off the other. + * Hence we disallow changing these options in emulation mode, + * but only if the change is setopt rather than unsetopt. + */ if (sticky && sticky->emulation) - return -1; + return opts[optno] ? 0 : -1; zleentry(ZLE_CMD_SET_KEYMAP, optno); new_opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0; } else if (optno == SUNKEYBOARDHACK) { -- cgit v1.2.3 From 71f35afa1cd48d6c25a517797e543cb2aa23a47b Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 3 Mar 2025 01:15:00 +0100 Subject: 53394: drop OSC and DCS sequences in key input They are likely to be terminal query responses not keys. If they do match a keybinding that's not affected. Also does likewise for certain CSI sequences. --- ChangeLog | 5 +++++ Src/Zle/zle_keymap.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 340a39479..926f36d58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-03-03 Oliver Kiddle + + * 53394: Src/Zle/zle_keymap.c: drop OSC and DCS sequences in key + input as they are likely to be terminal query responses not keys + 2025-03-02 Bart Schaefer * 53368: Src/options.c: ignore no-op changes to EMACS/VI options diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 5012917f5..ce52abe66 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1580,7 +1580,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) Thingy func = t_undefinedkey; char *str = NULL; int lastlen = 0, lastc = lastchar; - int timeout = 0, csi = 0; + int timeout = 0, csi = 0, oscdcs = 0; keybuflen = 0; keybuf[0] = 0; @@ -1647,14 +1647,38 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) if (keybuf[keybuflen - 1] >= 0x40 && keybuf[keybuflen - 1] <= 0x7e && lastlen > csi - 2 && lastlen <= csi) { + if (keybuf[csi] == '?' && (keybuf[keybuflen - 1] == 'c' || + keybuf[keybuflen - 1] == 'u')) + { /* is a terminal query response - discard */ + keybuflen = csi - 2; + timeout = csi = 0; + continue; + } func = t_undefinedkey; lastlen = keybuflen; } csi = 0; } } + /* An OSC or DCS sequence is likely a late arriving terminal query + * response. Keep looping; if we reach an ST, discard the sequence + * - unless we first match a keybinding or a keytimeout elapses. */ + if (oscdcs) { + if (keybuf[keybuflen - 1] == '\007' || /* BEL sometimes used */ + (keybuf[keybuflen - 2] == '\033' && + keybuf[keybuflen - 1] == '\\') || + (keybuf[keybuflen - 2] == Meta && /* ST can be 0x9b */ + (unsigned char) keybuf[keybuflen - 1] == (0x9b ^ 32))) + { + keybuflen = oscdcs - 2; /* discard */ + timeout = oscdcs = 0; + continue; + } + } else if (keybuflen >= 2 && keybuf[keybuflen - 2] == '\033' && + (keybuf[keybuflen - 1] == ']' || keybuf[keybuflen - 1] == 'P')) + oscdcs = keybuflen; - if (!ispfx && !csi) + if (!ispfx && !csi && !oscdcs) break; } if(!lastlen && keybuflen) -- cgit v1.2.3 From 435cb1b748ce1f2f5c38edc1d64f4ee2424f9b3a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 3 Mar 2025 01:24:46 +0100 Subject: 53399: don't load ZLE early to set keymap When zsh is run with -o vi / -o emacs, instead of loading ZLE to force the change, only record the option state. Then when ZLE starts, the vi option determines the default keymap. --- ChangeLog | 3 +++ Src/Zle/zle_keymap.c | 5 ++++- Src/builtin.c | 2 +- Src/init.c | 30 +++++++----------------------- Src/options.c | 5 +++-- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 926f36d58..a37a0f2ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-03-03 Oliver Kiddle + * 53399: Src/Zle/zle_keymap.c, Src/builtin.c, Src/init.c, + Src/options.c: don't load ZLE early to set keymap + * 53394: Src/Zle/zle_keymap.c: drop OSC and DCS sequences in key input as they are likely to be terminal query responses not keys diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index ce52abe66..7f31f837c 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1452,7 +1452,10 @@ default_bindings(void) linkkeymap(oppmap, "viopp", 0); linkkeymap(vismap, "visual", 0); linkkeymap(smap, ".safe", 1); - linkkeymap(emap, "main", 0); + if (isset(VIMODE)) + linkkeymap(vmap, "main", 0); + else + linkkeymap(emap, "main", 0); /* the .safe map cannot be modified or deleted */ smap->flags |= KM_IMMUTABLE; diff --git a/Src/builtin.c b/Src/builtin.c index 6bdaddff0..5563bdba9 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6333,7 +6333,7 @@ bin_emulate(char *nam, char **argv, Options ops, UNUSED(int func)) savehackchar = keyboardhackchar; emulate(shname, opt_R, &new_emulation, new_opts); optlist = newlinklist(); - if (parseopts(nam, &argv, new_opts, &cmd, optlist, 0, NULL)) { + if (parseopts(nam, &argv, new_opts, &cmd, optlist, 0)) { ret = 1; goto restore; } diff --git a/Src/init.c b/Src/init.c index 75d9dd136..76de0b449 100644 --- a/Src/init.c +++ b/Src/init.c @@ -255,8 +255,7 @@ static char *argv0; /**/ static void -parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr, - int *needkeymap) +parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr) { char **x; LinkList paramlist; @@ -273,7 +272,7 @@ parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr, * matched by code at the end of the present function. */ - if (parseopts(zsh_name, &argv, opts, cmdptr, NULL, flags, needkeymap)) + if (parseopts(zsh_name, &argv, opts, cmdptr, NULL, flags)) exit(1); /* @@ -384,7 +383,7 @@ static void parseopts_setemulate(char *nam, int flags) /**/ mod_export int parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, - LinkList optlist, int flags, int *needkeymap) + LinkList optlist, int flags) { int optionbreak = 0; int action, optno; @@ -490,14 +489,8 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, return 1; } else if (optno == RESTRICTED && toplevel) { restricted = action; - } else if ((optno == EMACSMODE || optno == VIMODE) - && (!toplevel || needkeymap)){ - if (!toplevel) { - WARN_OPTION("can't change option: %s", *argv); - } else { - /* Need to wait for modules to be loadable */ - *needkeymap = optno; - } + } else if ((optno == EMACSMODE || optno == VIMODE) && !toplevel) { + WARN_OPTION("can't change option: %s", *argv); } else { if (dosetopt(optno, action, toplevel, new_opts) && !toplevel) { @@ -1864,7 +1857,7 @@ zsh_main(UNUSED(int argc), char **argv) { char **t, *runscript = NULL, *zsh_name; char *cmd; /* argument to -c */ - int t0, needkeymap = 0; + int t0; #ifdef USE_LOCALE setlocale(LC_ALL, ""); #endif @@ -1910,7 +1903,7 @@ zsh_main(UNUSED(int argc), char **argv) createoptiontable(); /* sets emulation, LOGINSHELL, PRIVILEGED, ZLE, INTERACTIVE, * SHINSTDIN and SINGLECOMMAND */ - parseargs(zsh_name, argv, &runscript, &cmd, &needkeymap); + parseargs(zsh_name, argv, &runscript, &cmd); SHTTY = -1; init_io(cmd); @@ -1919,15 +1912,6 @@ zsh_main(UNUSED(int argc), char **argv) init_signals(); init_bltinmods(); init_builtins(); - - if (needkeymap) - { - /* Saved for after module system initialisation */ - zleentry(ZLE_CMD_SET_KEYMAP, needkeymap); - opts[needkeymap] = 1; - opts[needkeymap == EMACSMODE ? VIMODE : EMACSMODE] = 0; - } - run_init_scripts(); setupshin(runscript); init_misc(cmd, zsh_name); diff --git a/Src/options.c b/Src/options.c index 696ab5c69..8b13f0c5d 100644 --- a/Src/options.c +++ b/Src/options.c @@ -895,8 +895,9 @@ dosetopt(int optno, int value, int force, char *new_opts) */ if (sticky && sticky->emulation) return opts[optno] ? 0 : -1; - zleentry(ZLE_CMD_SET_KEYMAP, optno); - new_opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0; + if (zle_load_state == 1) + zleentry(ZLE_CMD_SET_KEYMAP, optno); + new_opts[optno ^ EMACSMODE ^ VIMODE] = 0; } else if (optno == SUNKEYBOARDHACK) { /* for backward compatibility */ keyboardhackchar = (value ? '`' : '\0'); -- cgit v1.2.3 From d70b70ada6b84602dd7793e0416378d3b4d0a8ad Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Mon, 31 Mar 2025 15:17:42 -0700 Subject: 53413: "print -rP" in preview, in case of special characters --- ChangeLog | 5 +++++ Functions/Prompts/promptinit | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a37a0f2ed..8668a7af5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-03-31 Bart Schaefer + + * Frank Dana: 53413: Functions/Prompts/promptinit: "print -rP" + in preview, in case of special characters + 2025-03-03 Oliver Kiddle * 53399: Src/Zle/zle_keymap.c, Src/builtin.c, Src/init.c, diff --git a/Functions/Prompts/promptinit b/Functions/Prompts/promptinit index 0c06699e8..7383c6c68 100644 --- a/Functions/Prompts/promptinit +++ b/Functions/Prompts/promptinit @@ -246,7 +246,7 @@ prompt_preview_theme () { # while the ZLE is not active. [[ -o promptcr ]] && print -n $'\r' - :; print -P -- "${PS1}command arg1 arg2 ... argn" + :; print -rP -- "${PS1}command arg1 arg2 ... argn" [[ -n ${preexec_functions[(r)prompt_${1}_preexec]} ]] && prompt_${1}_preexec -- cgit v1.2.3 From b707a60351bb9224fb808b3155dfef3288eef039 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Mon, 31 Mar 2025 15:22:00 -0700 Subject: 53414: attempting to preview the "restore" keyword is nonsensical --- ChangeLog | 4 ++++ Functions/Prompts/prompt_restore_setup | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8668a7af5..ed79feb18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2025-03-31 Bart Schaefer + * Frank Dana: 53414: Functions/Prompts/prompt_restore_setup: + attempting to preview the "restore" keyword is nonsensical, + use a handler function to avoid messing up terminal output + * Frank Dana: 53413: Functions/Prompts/promptinit: "print -rP" in preview, in case of special characters diff --git a/Functions/Prompts/prompt_restore_setup b/Functions/Prompts/prompt_restore_setup index b77dbe815..c1f9bfb7e 100644 --- a/Functions/Prompts/prompt_restore_setup +++ b/Functions/Prompts/prompt_restore_setup @@ -1,3 +1,11 @@ -# Damn that was easy -zstyle -t :prompt-theme cleanup -zstyle -t :prompt-theme restore +prompt_restore_setup () { + # Damn that was easy + zstyle -t :prompt-theme cleanup + zstyle -t :prompt-theme restore +} + +prompt_restore_preview () { + echo "The prompt command 'restore' is not a theme and cannot be previewed." +} + +prompt_restore_setup "$@" -- cgit v1.2.3 From e7163e69d90f8dcd5cdeea054df929b635f89260 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Mon, 31 Mar 2025 15:25:34 -0700 Subject: 53431: fix assignment via named reference to parameters in outer scopes --- ChangeLog | 5 ++++- Src/params.c | 6 +++++- Test/K01nameref.ztst | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ed79feb18..af75d0ea7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,7 @@ -2025-03-31 Bart Schaefer +2025-03-31 Bart Schaefer + + * 53431: Src/params.c, Test/K01nameref.ztst: fix assignment via + named reference to parameters in outer scopes; add tests * Frank Dana: 53414: Functions/Prompts/prompt_restore_setup: attempting to preview the "restore" keyword is nonsensical, diff --git a/Src/params.c b/Src/params.c index d1c06b893..c10236a0d 100644 --- a/Src/params.c +++ b/Src/params.c @@ -6395,7 +6395,9 @@ setscope(Param pm) } } else pm->base = basepm->level; - } + } else if (pm->base < locallevel && refname && + (basepm = (Param)getparamnode(realparamtab, refname))) + pm->base = basepm->level; if (pm->base > pm->level) { if (EMULATION(EMULATE_KSH)) { zerr("%s: global reference cannot refer to local variable", @@ -6420,6 +6422,8 @@ upscope(Param pm, int reflevel) { Param up = pm->old; while (up && up->level >= reflevel) { + if (reflevel < 0 && up->level < locallevel) + break; pm = up; up = up->old; } diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index bacc3ade2..1603ab1b9 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -595,6 +595,53 @@ F:Same test, should part 5 output look like this? >nameref-local-nameref-local >typeset -h parameters + ( + inner() { local -n var="${1:?}"; var=(alpha beta gamma); } + outer() { local -a foo=(outer); inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +0:up-reference part 10, assignment to enclosing scope, types match +>typeset -a foo=( alpha beta gamma ) +>typeset -g foo=3 + + ( + inner() { local -n var="${1:?}"; var=(alpha beta gamma); } + outer() { local foo=outer; inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +1:up-reference part 11, assignment to enclosing scope, type mismatch +>typeset -g foo=3 +?inner: foo: attempt to assign array value to non-array + + ( + inner() { local -n var="${1:?}"; unset var; var=(alpha beta gamma); } + outer() { local foo=outer; inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +0:up-reference part 12, assignment to enclosing scope, unset by reference +>typeset -a foo=( alpha beta gamma ) +>typeset -g foo=3 + + ( + inner() { local "${1:?}"; local -nu var="$1"; var=(alpha beta gamma); } + outer() { local -a foo=(outer); inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +0:up-reference part 13, assignment to enclosing scope, skip local +>typeset -a foo=( alpha beta gamma ) +>typeset -g foo=3 + + ( + inner() { local "${1:?}"; local -nu var="$1"; + typeset -g var=(alpha beta gamma); } + outer() { local -a foo=(outer); inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +0f:up-reference part 14, typeset -g to enclosing scope, skip local +F:typeset cannot bypass a name in the local scope, even via nameref +>typeset -a foo=( alpha beta gamma ) +>typeset -g foo=3 + if [[ $options[typesettounset] != on ]]; then ZTST_skip='Ignoring zmodload bug that resets TYPESET_TO_UNSET' setopt typesettounset -- cgit v1.2.3 From 5858f6a12252eb82b7b5942e64dd8679854f0063 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 4 Apr 2025 12:49:31 +0200 Subject: 53445: extra-verbose mode support on some recent Linux and BSD systems --- ChangeLog | 5 +++++ Completion/Unix/Type/_path_commands | 34 +++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index af75d0ea7..24c02959c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-04-04 Oliver Kiddle + + * 53445: Completion/Unix/Type/_path_commands: extra-verbose mode + support on some recent Linux and BSD systems + 2025-03-31 Bart Schaefer * 53431: Src/params.c, Test/K01nameref.ztst: fix assignment via diff --git a/Completion/Unix/Type/_path_commands b/Completion/Unix/Type/_path_commands index 4d5a6c5af..59b146a88 100644 --- a/Completion/Unix/Type/_path_commands +++ b/Completion/Unix/Type/_path_commands @@ -24,13 +24,33 @@ return 1 } _call_whatis() { - case "$(whatis --version)" in - ("whatis from "*) - local -A args - zparseopts -D -A args s: r: - apropos "${args[-r]:-"$@"}" | fgrep "($args[-s]" + local sec impl variant sections=( 1 6 8 ) + case "$OSTYPE" in + (#i)dragonfly|(free|open)bsd*) impl=mandoc ;; + netbsd*) impl=apropos ;; + linux-gnu*) + sections=( 1 8 ) + # The same test as for man so has a good chance of being cached + _pick_variant -c man -r variant \ + freebsd='-S mansect' \ + openbsd='-S subsection' \ + $OSTYPE \ + --- + [[ $variant = $OSTYPE ]] && impl=man-db || impl=mandoc + ;; + esac + case $impl in + mandoc) + for sec in $sections; do + whatis -s $sec .\* + done + ;; + man-db) + whatis -s ${(j.,.)sections} -r .\* + ;; + apropos) + apropos -l ''|grep "([${(j..)sections}])" ;; - (*) whatis "$@";; esac } @@ -49,7 +69,7 @@ if zstyle -t ":completion:${curcontext}:" extra-verbose; then if ( [[ -n $first ]] || _cache_invalid command-descriptions ) && \ ! _retrieve_cache command-descriptions; then local line - for line in "${(f)$(_call_program command-descriptions _call_whatis -s 1 -r .\\\*\; _call_whatis -s 6 -r .\\\* 2>/dev/null)}"; do + for line in "${(f)$(_call_program command-descriptions _call_whatis)}"; do [[ -n ${line:#(#b)([^ ]#) #\([^ ]#\)( #\[[^ ]#\]|)[ -]#(*)} ]] && continue; [[ -z $match[1] || -z $match[3] || -z ${${match[1]}:#*:*} ]] && continue; _command_descriptions[$match[1]]=$match[3] -- cgit v1.2.3 From 73c70cece07a9d9e69cf09871877ab28b06d5cfb Mon Sep 17 00:00:00 2001 From: Kyle Andelin <7277377+andelink@users.noreply.github.com> Date: Fri, 4 Apr 2025 07:53:57 -0700 Subject: 53449: do not complete indices for empty array subscripts --- ChangeLog | 3 +++ Completion/Zsh/Context/_subscript | 3 +++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 24c02959c..471818e53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-04-04 Oliver Kiddle + * Kyle Andelin: 53449: Completion/Zsh/Context/_subscript: + do not complete indices for empty array subscripts + * 53445: Completion/Unix/Type/_path_commands: extra-verbose mode support on some recent Linux and BSD systems diff --git a/Completion/Zsh/Context/_subscript b/Completion/Zsh/Context/_subscript index 25cedd193..67bad2862 100644 --- a/Completion/Zsh/Context/_subscript +++ b/Completion/Zsh/Context/_subscript @@ -98,6 +98,9 @@ elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then while _tags; do if _requested indexes; then ind=( {1..${#${(P)${compstate[parameter]}}}} ) + if [[ ${ind[-1]} -eq 0 ]]; then + ind=() + fi if zstyle -T ":completion:${curcontext}:indexes" verbose; then list=() for i in "$ind[@]"; do -- cgit v1.2.3 From 18a49bd7c5058e2ffb958ffd002eac836a301895 Mon Sep 17 00:00:00 2001 From: dana Date: Sun, 13 Apr 2025 16:55:58 -0500 Subject: unposted: NEWS: update per w/53257 and w/53260 --- ChangeLog | 4 ++++ NEWS | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/ChangeLog b/ChangeLog index 471818e53..098671bf6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2025-04-13 dana + + * unposted: NEWS: update per w/53257 and w/53260 + 2025-04-04 Oliver Kiddle * Kyle Andelin: 53449: Completion/Zsh/Context/_subscript: diff --git a/NEWS b/NEWS index d0a8584e2..e039a652b 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,18 @@ Non-forking command substitutions with ${ ... } and ${| ... } are now available, and the latter extended with ${|param| ... } to return the result via assignment to the named param rather than always via $REPLY. +The shell now uses monotonic time instead of wall time for most +internal time tracking, making it immune to system clock changes due to +NTP, etc. For the most part this is transparent to users. However, as a +side effect, some features like $SECONDS and the time builtin gained +(nominal) nanosecond precision. + +The zsh/zutil module's zparseopts builtin learnt a -v option which can +be used to specify the array of arguments to parse instead of $@. + +The zparseopts builtin also learnt a -G option which enables GNU-style +argument parsing ('--opt=arg', etc.). + Changes since 5.8.1 ------------------- -- cgit v1.2.3 From e19cfe7caca143e66bd57acef43f3e64f7992d7b Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Fri, 23 Dec 2022 14:27:35 +0100 Subject: _typeset: fix typo --- Completion/Zsh/Command/_typeset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Completion/Zsh/Command/_typeset b/Completion/Zsh/Command/_typeset index 1952a6338..99b9e7e0d 100644 --- a/Completion/Zsh/Command/_typeset +++ b/Completion/Zsh/Command/_typeset @@ -39,7 +39,7 @@ allargs=( tf '(-t +t -T +T)-+t[turn on execution tracing for functions]' tp '(-T -n +n)-+t[tag parameters]' u '-u[convert the value to uppercase or mark function for autoloading]' - uf '-u[mark function for autoloadling]' + uf '-u[mark function for autoloading]' up '(-u +u)-+u[convert the value to uppercase]' w '(-k -z)-w[specify that arguments refer to files compiled with zcompile]' W '-+W[turn on WARN_NESTED_VAR for function]' -- cgit v1.2.3 From 86cc28004d1360210c70a05ce7b6b6bcf486886f Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Tue, 15 Apr 2025 10:29:21 -0400 Subject: 53485: NEWS: update for version 5.10 --- ChangeLog | 4 ++++ NEWS | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 098671bf6..d84d5832b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2025-04-15 Eric Cook + + * 53485: NEWS: update for version 5.10 + 2025-04-13 dana * unposted: NEWS: update per w/53257 and w/53260 diff --git a/NEWS b/NEWS index e039a652b..5bb9682db 100644 --- a/NEWS +++ b/NEWS @@ -7,12 +7,28 @@ Note also the list of incompatibilities in the README file. Changes since 5.9 ----------------- +Support for named references and namespaces has been added, similar to +those features in ksh but with some notable differences. The `nameref` +builtin and some ksh-equivalent namespace names are available by loading +the zsh/ksh93 module. See the documentation of that module for more. + +The parameter expansion flag ! was added for the referred-to name of a +named reference. + +The parameter ZSH_EXEPATH expands to the full path of the current zsh +process, reliably on Linux, Mac, {Net,Free,Dragonfly}BSD and falls +back to argv[0] elsewhere. + +The default keymap is now emacs. Users of the vi keymaps please check +README to see if you are affected. + In region_highlight and zle_highlight, italic and faint can be specified as font attributes for terminals that support them. -Highlighting groups can be referenced in region_highlight and -zle_highlight for common attribute combinations and a layer can be -specified to indicate precedence where highlighted regions overlap. +Highlighting groups can be referenced in region_highlight, +zle_highlight, WATCHFMT and completion explanation strings for +common attribute combinations and a layer can be specified to +indicate precedence where highlighted regions overlap. Highlighting groups are also supported in the prompt via a new %H prompt escape. @@ -24,13 +40,8 @@ consistent and better aligned with the POSIX-2017 specification of `set -e`. For details on what exactly changed, see the list of incompatibilities in the README file. -Support for named references and namespaces has been added, similar to -those features in ksh but with some notable differences. The `nameref` -builtin and some ksh-equivalent namespace names are available by loading -the zsh/ksh93 module. See the documentation of that module for more. - Non-forking command substitutions with ${ ... } and ${| ... } are now -available, and the latter extended with ${|param| ... } to return the +available, and the latter extended with ${{param} ... } to return the result via assignment to the named param rather than always via $REPLY. The shell now uses monotonic time instead of wall time for most @@ -45,6 +56,14 @@ be used to specify the array of arguments to parse instead of $@. The zparseopts builtin also learnt a -G option which enables GNU-style argument parsing ('--opt=arg', etc.). +The module zsh/pcre has been updated to use the pcre2 library. + +The new zsh/random module defines an SRANDOM parameter, zrand_float() +and zrand_int() math functions. + +The shell keyword time now works on builtins, assignments, and +current-shell actions. + Changes since 5.8.1 ------------------- -- cgit v1.2.3 From ba1473181fc13e032205a8c81a59b56b8e33df4d Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Tue, 15 Apr 2025 10:34:33 -0400 Subject: unposted: add missing Changelog entry for _typeset fix --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index d84d5832b..eb2924d45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,10 @@ * 53485: NEWS: update for version 5.10 +2025-04-14 Mikael Magnusson + + * unposted: _typeset: fix typo + 2025-04-13 dana * unposted: NEWS: update per w/53257 and w/53260 -- cgit v1.2.3 From bacc78ec3f9d75ff242d0592b2f44484e1198801 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 15 Apr 2025 10:03:23 -0700 Subject: 53454: fix interrupt handling in savehistfile() --- ChangeLog | 4 ++++ Src/hist.c | 13 ++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb2924d45..4b4913252 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2025-04-15 Bart Schaefer + + * 53454: Src/hist.c: fix interrupt handling in savehistfile() + 2025-04-15 Eric Cook * 53485: NEWS: update for version 5.10 diff --git a/Src/hist.c b/Src/hist.c index fa1ede3f0..00bdbb2b8 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2838,11 +2838,12 @@ readhistfile(char *fn, int err, int readflags) */ if (uselex || remeta) freeheap(); - if (errflag & ERRFLAG_INT) { - /* Can't assume fast read next time if interrupted. */ - lasthist.interrupted = 1; + if (errflag & ERRFLAG_INT) break; - } + } + if (errflag & ERRFLAG_INT) { + /* Can't assume fast read next time if interrupted. */ + lasthist.interrupted = 1; } if (start && readflags & HFILE_USE_OPTIONS) { zsfree(lasthist.text); @@ -3108,7 +3109,9 @@ savehistfile(char *fn, int err, int writeflags) hist_ignore_all_dups |= isset(HISTSAVENODUPS); readhistfile(fn, err, 0); hist_ignore_all_dups = isset(HISTIGNOREALLDUPS); - if (histlinect) + if (errflag & ERRFLAG_INT) + ret = -1; + else if (histlinect) savehistfile(fn, err, 0); pophiststack(); -- cgit v1.2.3 From 494fcd1799d4d2d236d3183de12b0c99ceb83b1c Mon Sep 17 00:00:00 2001 From: dana Date: Sun, 13 Apr 2025 17:15:53 -0500 Subject: 53482: zparseopts -G: always add options with optional args to array with = --- ChangeLog | 6 ++++++ Src/Modules/zutil.c | 6 +++--- Test/V12zparseopts.ztst | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b4913252..39b488e14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2025-04-19 dana + + * 53482: Src/Modules/zutil.c, + Src/Modules/Test/V12zparseopts.ztst: with `zparseopts -G`, + always add options options with optional args to array with = + 2025-04-15 Bart Schaefer * 53454: Src/hist.c: fix interrupt handling in savehistfile() diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 9b2721a09..ef99303d2 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -1662,15 +1662,15 @@ add_opt_val(Zoptdesc d, char *arg) v->str = NULL; if (d->arr) d->arr->num += (arg ? 2 : 1); - } else if (arg) { + } else if (arg || d->flags & ZOF_GNUL) { /* 3 here is '-' + '=' + NUL */ - char *s = (char *) zhalloc(strlen(d->name) + strlen(arg) + 3); + char *s = (char *) zhalloc(strlen(d->name) + strlen(arg ? arg : "") + 3); *s = '-'; strcpy(s + 1, d->name); if (d->flags & ZOF_GNUL) strcat(s, "="); - strcat(s, arg); + strcat(s, arg ? arg : ""); v->str = s; if (d->arr) d->arr->num += 1; diff --git a/Test/V12zparseopts.ztst b/Test/V12zparseopts.ztst index a2743ea0e..e465d0e0c 100644 --- a/Test/V12zparseopts.ztst +++ b/Test/V12zparseopts.ztst @@ -247,7 +247,7 @@ 0:zparseopts -G, separate parameters >ret: 0, optv: --foo bar, argv: 1 2 3 >ret: 0, optv: --foo=bar, argv: 1 2 3 ->ret: 0, optv: --foo, argv: bar 1 2 3 +>ret: 0, optv: --foo=, argv: bar 1 2 3 for spec in -foo: -foo:- -foo::; do () { @@ -340,4 +340,4 @@ ?(anon):zparseopts:2: bad option: -f >ret: 1, gopt: -G, optv: , argv: -foobar 1 2 3 >ret: 0, gopt: -G, optv: -foo=bar, argv: 1 2 3 ->ret: 0, gopt: -G, optv: -foo, argv: bar 1 2 3 +>ret: 0, gopt: -G, optv: -foo=, argv: bar 1 2 3 -- cgit v1.2.3 From 8c3c45732131433645686cdb6bbbb8974230c5a9 Mon Sep 17 00:00:00 2001 From: dana Date: Sun, 13 Apr 2025 18:00:54 -0500 Subject: 53483: zparseopts -G: accept only '--' as parsing terminator --- ChangeLog | 4 ++++ Doc/Zsh/mod_zutil.yo | 14 +++++++++----- Src/Modules/zutil.c | 6 +++--- Test/V12zparseopts.ztst | 25 +++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39b488e14..73127d0f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2025-04-19 dana + * 53483: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c, + Test/V12zparseopts.ztst: with `zparseopts -G`, accept only + '--' as parsing terminator + * 53482: Src/Modules/zutil.c, Src/Modules/Test/V12zparseopts.ztst: with `zparseopts -G`, always add options options with optional args to array with = diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo index 76907352f..19f9989f4 100644 --- a/Doc/Zsh/mod_zutil.yo +++ b/Doc/Zsh/mod_zutil.yo @@ -242,8 +242,8 @@ Note that it is an error to give any var(spec) without an Unless the tt(-E) option is given, parsing stops at the first string that isn't described by one of the var(spec)s. Even with tt(-E), -parsing always stops at a positional parameter equal to `tt(-)' or -`tt(-)tt(-)'. See also tt(-F). +parsing always stops at a positional parameter equal to `tt(-)tt(-)' or +(without tt(-G)) `tt(-)'. See also tt(-F). The var(opt) description must be one of the following. Any of the special characters can appear in the option name provided it is preceded by a @@ -314,9 +314,9 @@ as the values. item(tt(-D))( If this option is given, all options found are removed from the positional parameters of the calling shell or shell function, up to but not including -any not described by the var(spec)s. If the first such parameter is `tt(-)' -or `tt(-)tt(-)', it is removed as well. This is similar to using the -tt(shift) builtin. +any not described by the var(spec)s. If the first such parameter is +`tt(-)tt(-)' or (without tt(-G)) `tt(-)', it is removed as well. This is +similar to using the tt(shift) builtin. ) item(tt(-E))( This changes the parsing rules to em(not) stop at the first string @@ -364,6 +364,10 @@ A mandatory option-argument given in a separate parameter from its option (as in `tt(-)tt(-foo) tt(bar)'), or any option-argument given to a short option in the same parameter, is always treated the same regardless of whether this option is in effect. + +Lastly, when this option is active, only `tt(-)tt(-)' is treated as an +explicit option-parsing terminator in the parsed arguments; a single +`tt(-)' is considered a normal operand. ) item(tt(-K))( With this option, the arrays specified with the tt(-a) option and with the diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index ef99303d2..676fe1872 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -1955,8 +1955,8 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) params = getaparam((paramsname = paramsname ? paramsname : "argv")); np = cp = pp = ((extract && del) ? arrdup(params) : params); for (; (o = *pp); pp++) { - /* Not an option */ - if (*o != '-') { + /* Not an option. With GNU style, this includes '-' */ + if (*o != '-' || (gnu && !o[1])) { if (extract) { if (del) *cp++ = o; @@ -1964,7 +1964,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) } else break; } - /* '-' or '--', end parsing */ + /* '--' or (with non-GNU style, see above) '-', end parsing */ if (!o[1] || (o[1] == '-' && !o[2])) { if (del && extract) *cp++ = o; diff --git a/Test/V12zparseopts.ztst b/Test/V12zparseopts.ztst index e465d0e0c..e6139ea5e 100644 --- a/Test/V12zparseopts.ztst +++ b/Test/V12zparseopts.ztst @@ -341,3 +341,28 @@ >ret: 1, gopt: -G, optv: , argv: -foobar 1 2 3 >ret: 0, gopt: -G, optv: -foo=bar, argv: 1 2 3 >ret: 0, gopt: -G, optv: -foo=, argv: bar 1 2 3 + + for term in - --; do + # With -D -E -G + () { + local -a optv + zparseopts -a optv -D -E -F -G - -foo -bar + print -r - ret: $?, term: $term, optv: $optv, argv: $argv + } --foo x --bar $term --baz + for gopt in '' -G; do + # With -D + with/without -G + () { + local -a optv + zparseopts -a optv -D -F $gopt - -foo -bar + print -r - ret: $?, term: $term, gopt: $gopt, optv: $optv, argv: $argv + } --foo $term --bar + done + done +0:only -- acts as explicit parsing terminator with -G +?(anon):zparseopts:2: bad option: --baz +>ret: 1, term: -, optv: , argv: --foo x --bar - --baz +>ret: 0, term: -, gopt: , optv: --foo, argv: --bar +>ret: 0, term: -, gopt: -G, optv: --foo, argv: - --bar +>ret: 0, term: --, optv: --foo --bar, argv: x -- --baz +>ret: 0, term: --, gopt: , optv: --foo, argv: --bar +>ret: 0, term: --, gopt: -G, optv: --foo, argv: --bar -- cgit v1.2.3 From b86f5d4c62cc44cd4faa5954f03d0da094e5c513 Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Sat, 12 Apr 2025 12:37:00 -0400 Subject: 53463: _hosts: allow overriding the default matching control --- ChangeLog | 6 ++++++ Completion/Unix/Type/_hosts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 73127d0f2..f9a2aa15d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2025-04-20 Eric Cook + + * 53463: Completion/Unix/Type/_hosts: allow overriding the default + matching control + + 2025-04-19 dana * 53483: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c, diff --git a/Completion/Unix/Type/_hosts b/Completion/Unix/Type/_hosts index 4057fee10..d242e2931 100644 --- a/Completion/Unix/Type/_hosts +++ b/Completion/Unix/Type/_hosts @@ -75,4 +75,4 @@ if ! zstyle -a ":completion:${curcontext}:hosts" hosts _hosts; then fi _wanted hosts expl host \ - compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' -a "$@" - _hosts + compadd -a "$@" -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' - _hosts -- cgit v1.2.3 From dd21cda278a64d1949c284282d7305ea22564052 Mon Sep 17 00:00:00 2001 From: Eric Cook Date: Sun, 20 Apr 2025 20:40:22 -0400 Subject: unposted: Test release: zsh-5.9.0.2-test. --- ChangeLog | 4 ++++ Config/version.mk | 4 ++-- Etc/FAQ.yo | 2 +- NEWS | 4 ++++ README | 6 +++--- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9a2aa15d..eca61c227 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2025-04-20 Eric Cook + * unposted: Config/version.mk, Etc/FAQ.yo, NEWS, README: Test + release: zsh-5.9.0.2-test. + + * 53463: Completion/Unix/Type/_hosts: allow overriding the default matching control diff --git a/Config/version.mk b/Config/version.mk index e1b02e713..5706b9237 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.9.0.1-dev -VERSION_DATE='May 15, 2022' +VERSION=5.9.0.2-test +VERSION_DATE='April 13, 2025' diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 73442416c..1e4e6d76b 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -297,7 +297,7 @@ sect(On what machines will it run?) sect(What's the latest version?) - Zsh 5.9 is the latest production version. For details of all the + Zsh 5.10 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/NEWS b/NEWS index 5bb9682db..7c5e1e06b 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,10 @@ Note also the list of incompatibilities in the README file. Changes since 5.9 ----------------- +zsh 5.10 is dedicated to the memory of Sebastian Gniazdowski, who was +an enthusiastic new community member interested in making zsh easy to +extend with community code/`plugins'. + Support for named references and namespaces has been added, similar to those features in ksh but with some notable differences. The `nameref` builtin and some ksh-equivalent namespace names are available by loading diff --git a/README b/README index 8c11e6833..4da92eee8 100644 --- a/README +++ b/README @@ -5,12 +5,12 @@ THE Z SHELL (ZSH) Version ------- -This is version 5.9 of the shell. This is a security and feature release. -There are several visible improvements since 5.8.1, as well as bug fixes. +This is version 5.10 of the shell. This is a security and feature release. +There are several visible improvements since 5.9, as well as bug fixes. All zsh installations are encouraged to upgrade as soon as possible. Note in particular the changes highlighted under "Incompatibilities since -5.8.1" below. See NEWS for more information. +5.9" below. See NEWS for more information. Installing Zsh -------------- -- cgit v1.2.3 From ad677029f8dac0b2782309912f93e64eb670acb1 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Thu, 24 Apr 2025 20:08:08 +0200 Subject: unposted: fix seq numbers for old changelog entry --- ChangeLog | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index eca61c227..c718bb110 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4782,27 +4782,27 @@ x2024-02-19 Jun-ichi Takimoto 2020-03-25 Daniel Shahaf - * 45583/0008: Etc/BUGS, Src/utils.c, Test/B13whence.ztst: + * 45595/0008: Etc/BUGS, Src/utils.c, Test/B13whence.ztst: Extend tests to prove that what remains of xsymlinks() handles symlink loops gracefully. - * 45583/0007: Src/utils.c: Remove code that is now unreachable. + * 45595/0007: Src/utils.c: Remove code that is now unreachable. - * 45583/0006: Src/utils.c: Don't use xsymlinks() in 'whence -s'. + * 45595/0006: Src/utils.c: Don't use xsymlinks() in 'whence -s'. - * 45583/0005: Test/B13whence.ztst: Add a test for bin_whence's + * 45595/0005: Test/B13whence.ztst: Add a test for bin_whence's symlinks resolution. - * 45583/0004: Etc/BUGS, Src/utils.c, Test/D02glob.ztst: Fix + * 45595/0004: Etc/BUGS, Src/utils.c, Test/D02glob.ztst: Fix segfault on resolving symlink loops - * 45583/0003: Src/hist.c, Src/subst.c: chrealpath: Let caller + * 45595/0003: Src/hist.c, Src/subst.c: chrealpath: Let caller decide how the return value should be allocated. - * 45583/0002: Src/hist.c, Src/subst.c: chrealpath: Make symlink + * 45595/0002: Src/hist.c, Src/subst.c: chrealpath: Make symlink resolution optional. - * 45583/0001: Test/D02glob.ztst: Add tests for the segfault on + * 45595/0001: Test/D02glob.ztst: Add tests for the segfault on resolving a symlink loop bug (workers/45282). * 45590/0002 (in part): Test/B12limit.ztst: zsh/rlimits: Test -- cgit v1.2.3 From 2601c191865d3d49e3e57fbb9f6224bcbd22f7a4 Mon Sep 17 00:00:00 2001 From: dana Date: Sun, 27 Apr 2025 07:47:53 -0500 Subject: 53515: tests: correct ztst documentation error --- ChangeLog | 6 ++++-- Test/B01cd.ztst | 14 +++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index c718bb110..57050830f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,13 +1,15 @@ +2025-04-27 dana + + * 53515: Test/B01cd.ztst: correct ztst documentation error + 2025-04-20 Eric Cook * unposted: Config/version.mk, Etc/FAQ.yo, NEWS, README: Test release: zsh-5.9.0.2-test. - * 53463: Completion/Unix/Type/_hosts: allow overriding the default matching control - 2025-04-19 dana * 53483: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c, diff --git a/Test/B01cd.ztst b/Test/B01cd.ztst index bc6757549..e31341478 100644 --- a/Test/B01cd.ztst +++ b/Test/B01cd.ztst @@ -57,13 +57,13 @@ # subsequent whitespace being significant; lines are not subject to any # substitution unless the `q' flag (see below) is set. # -# Each line of a '>' and '?' chunk may be preceded by a '*', so the line -# starts '*>' or '*?'. This signifies that for any line with '*' in front -# the actual output should be pattern matched against the corresponding -# lines in the test output. Each line following '>' or '?' must be a -# valid pattern, so characters special to patterns such as parentheses -# must be quoted with a backslash. The EXTENDED_GLOB option is used for -# all such patterns. +# If any '>' or '?' line in a chunk is preceded by a '*', all lines in +# that chunk with the same symbol are pattern matched against the +# corresponding lines in the test output. For example, a '*>' anywhere +# in the chunk causes all other '>' lines to use pattern matching. +# Each line following '>' or '?' must be a valid pattern, so characters +# special to patterns such as parentheses must be quoted with a +# backslash. The EXTENDED_GLOB option is used for all such patterns. # # Each chunk of indented code is to be evaluated in one go and is to # be followed by a line starting (in the first column) with -- cgit v1.2.3 From 84ef0c523878625feeed8cd0a5c142929d8b4d06 Mon Sep 17 00:00:00 2001 From: dana Date: Sun, 27 Apr 2025 07:58:23 -0500 Subject: 53516: add zgetopt contrib function --- ChangeLog | 3 + Doc/Zsh/contrib.yo | 78 +++++++++++++++++++ Functions/Misc/zgetopt | 198 +++++++++++++++++++++++++++++++++++++++++++++++ NEWS | 5 +- Test/Z04zgetopt.ztst | 206 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 489 insertions(+), 1 deletion(-) create mode 100755 Functions/Misc/zgetopt create mode 100644 Test/Z04zgetopt.ztst diff --git a/ChangeLog b/ChangeLog index 57050830f..de8fc6f3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2025-04-27 dana + * 53516: Doc/Zsh/contrib.yo, Functions/Misc/zgetopt, NEWS, + Test/Z04zgetopt.ztst: add zgetopt contrib function + * 53515: Test/B01cd.ztst: correct ztst documentation error 2025-04-20 Eric Cook diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index c1bea6022..030b63029 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -4672,6 +4672,84 @@ Same as tt(zmv -C) and tt(zmv -L), respectively. These functions do not appear in the zsh distribution, but can be created by linking tt(zmv) to the names tt(zcp) and tt(zln) in some directory in your tt(fpath). ) +findex(zgetopt) +item(tt(zgetopt) [ tt(-a) ] [ tt(-A) var(array) ] [ tt(-l) var(spec) ] [ tt(-n) var(name) ] [ tt(-o) var(spec) ] tt(--) [ var(args) ])( +This is a wrapper around tt(zparseopts) (from tt(zsh/zutil)) which +provides an interface similar to the util-linux implementation of +tt(getopt+LPAR()1+RPAR()) (sometimes called `GNU tt(getopt)'). It +simplifies GNU-style argument parsing (including permutation) and +can make it easier to write functions and scripts with complex APIs, +particularly ones where the order of options is significant. + +The typical usage pattern is as follows: + +example(zgetopt -o abc: -l aaa,bbb,ccc: -- "$@" || return +while (( $# )); do + case $1 in + -a|--aaa+RPAR() ...; shift ;; # handle -a + -b|--bbb+RPAR() ...; shift ;; # handle -b + -c|--ccc+RPAR() ...; shift 2 ;; # handle -c and arg + --+RPAR() ...; shift; break ;; # end of options + esac +done +# handle operands) + +It can also be called as a stand-alone script from other shells +using the more traditional print-and-eval pattern: + +example(args="$( zgetopt -n myscript -o abc: -l aaa,bbb,ccc: -- "$@" )" || return +eval set -- "$args" +while [ $# -ne 0 ]; do ...; done) + +Options: + +startsitem() +sitem(tt(-A var(array)))(When called as a function, assign the parsed +arguments to the named array var(array). Defaults to tt(argv), which +overwrites the caller's positional parameters. Has no meaning when +called as a script, in which case the parsed and quoted arguments are +always printed to standard output. An empty string forces the +printing behaviour in either mode.) +sitem(tt(-a))(Use Sun-style single-hyphenated long options instead of +GNU-style double-hyphenated ones (tt(-foo) vs tt(--foo)). Note that +long options with optional optargs can't always be distinguished +accurately from short options with optional optargs when using this +option. Also, due to limitations of tt(zparseopts), a Sun-style long +option whose name is only one character long is always treated as a +short option.) +sitem(tt(-l var(spec)))(Specify long options to recognise when +parsing. These should be given using just the option name (no +dashes), suffixed by `tt(:)' or `tt(::)' if it takes a mandatory or +optional argument respectively. Multiple options can be defined +either by separating them by commas or by supplying -l again. +Example: tt(-l foo,bar: -l baz)) +sitem(tt(-n var(name)))(Specify the name to use in the error message +if argument parsing fails. Defaults to the name of the nearest +calling function or the base name of tt($ZSH_ARGZERO). Note that +errors related to the usage of tt(zgetopt) itself are always reported +as coming from tt(zgetopt).) +sitem(tt(-o var(spec)))(Specify short options to recognise when +parsing. These should be given as a single string, in the same format +used by the tt(getopts) built-in or the tt(getopt+LPAR()3+RPAR()) +library function, again using `tt(:)' or `tt(::)' to indicate a +mandatory or optional argument. The spec may be prefixed with `tt(+)' +to indicate that option parsing should stop at the first non-option +argument (equivalent to setting the environment variable +tt(POSIXLY_CORRECT)). Example: tt(-o ab:cd::)) +endsitem() + +At least one of tt(-o) or tt(-l) must be given. The function's own +options should be followed by zero or more arguments to parse. It is +critical that these be separated explicitly by `tt(--)', as in the +above examples, to ensure that the function can accurately +distinguish the arguments it's meant to parse from its own. + +Refer to the manual for util-linux's tt(getopt+LPAR()1+RPAR()) for +more information about the way arguments are parsed and results are +returned. Note however that this function is not intended to be a +complete re-implementation. In particular, it omits all +portability/compatibility features. +) item(tt(zkbd))( See `Keyboard Definition' ifzman(above)\ diff --git a/Functions/Misc/zgetopt b/Functions/Misc/zgetopt new file mode 100755 index 000000000..5fc1e7725 --- /dev/null +++ b/Functions/Misc/zgetopt @@ -0,0 +1,198 @@ +#!/bin/zsh -f + +# Wrapper around zparseopts which gives it an interface similar to util-linux's +# getopt(1). See zshcontrib(1) for documentation + +emulate -L zsh -o extended_glob +zmodload -i zsh/zutil || return 3 + +# Very stupid and brittle internal wrapper around zparseopts used to insert the +# caller name into its error messages, allowing us to implement --name. This +# MUST be called with -v, since argv has the options to zparseopts itself +__zgetopt_zparseopts() { + local __err __ret + + __err=$( zparseopts "$@" 2>&1 ) + __ret=$? + + zparseopts "$@" &> /dev/null && return + + # Raw error message should look like this: + # zgetopt_zparseopts:zparseopts:3: bad option: -x + [[ -n $__err ]] && print -ru2 - ${__err/#*:zparseopts:<->:/$name:} + return __ret +} + +local optspec pat i posix=0 +local -a match mbegin mend optvv argvv +local -a array alt lopts sopts name +local -a specs no_arg_opts req_arg_opts opt_arg_opts tmp + +# Same as leading + in short-opts spec +(( $+POSIXLY_CORRECT )) && posix=1 + +# This 0=... makes any error message we get here look a little nicer when we're +# called as a script. Unfortunately the function name overrides $0 in +# zwarnnam() in other scenarios, so this can't be used to implement --name +0=${0:t} zparseopts -D -F -G - \ + {A,-array}:-=array \ + {a,-alternative}=alt \ + {l,-longoptions,-long-options}+:-=lopts \ + {n,-name}:-=name \ + {o,-options}:-=sopts \ +|| { + print -ru2 "usage: ${0:t} [-A ] [-a] [-l ] [-n ] [-o ] -- " + return 2 +} + +# Default to the caller's name +(( $#name )) && name=( "${(@)name/#(-n|--name=)/}" ) +[[ -n $name ]] || name=( ${funcstack[2]:-${ZSH_ARGZERO:t}} ) + +(( $#array )) && array=( "${(@)array/#(-A|--array=)/}" ) + +if [[ $ZSH_EVAL_CONTEXT != toplevel ]]; then + [[ $array == *[^A-Za-z0-9_.]* ]] && { + print -ru2 - "${0:t}: invalid array name: $array" + return 2 + } + (( $#array )) || array=( argv ) + +elif [[ -n $array ]]; then + print -ru2 - "${0:t}: -A option not meaningful unless called as function" + return 2 +fi + +# getopt requires a short option spec; we'll require either short or long +(( $#sopts || $#lopts )) || { + print -ru2 - "${0:t}: missing option spec" + return 2 +} + +optspec=${(@)sopts/#(-o|--options=)/} +sopts=( ) + +for (( i = 1; i <= $#optspec; i++ )); do + # Leading '+': Act POSIXLY_CORRECT + if [[ $i == 1 && $optspec[i] == + ]]; then + posix=1 + # Leading '-': Should leave operands interspersed with options, but this is + # not really possible with zparseopts + elif [[ $i == 1 && $optspec[i] == - ]]; then + print -ru2 - "${0:t}: optspec with leading - (disable operand collection) not supported" + return 2 + # Special characters: [+=\\] because they're special to zparseopts, ':' + # because it's special to getopt, '-' because it's the parsing terminator + elif [[ $optspec[i] == [+:=\\-] ]]; then + print -ru2 - "${0:t}: invalid short-option name: $optspec[i]" + return 2 + # 'a' + elif [[ $optspec[i+1] != : ]]; then + sopts+=( $optspec[i] ) + # 'a:' + elif [[ $optspec[i+2] != : ]]; then + sopts+=( $optspec[i]: ) + (( i += 1 )) + # 'a::' + elif [[ $optspec[i+3] != : ]]; then + sopts+=( $optspec[i]:: ) + (( i += 2 )) + fi +done + +lopts=( ${(@)lopts/#(-l|--long(|-)options=)/} ) +lopts=( ${(@s<,>)lopts} ) + +# Don't allow characters that are special to zparseopts in long-option specs. +# See above +pat='(*[+=\\]*|:*|*:::##|*:[^:]*)' +[[ -n ${(@M)lopts:#$~pat} ]] && { + print -ru2 - "${0:t}: invalid long-option spec: ${${(@M)lopts:#$~pat}[1]}" + return 2 +} + +(( $#alt )) || lopts=( ${(@)lopts/#/-} ) + +specs=( $sopts $lopts ) + +# Used below to identify options with optional optargs +no_arg_opts=( ${(@)${(@M)specs:#*[^:]}/#/-} ) +req_arg_opts=( ${(@)${(@)${(@M)specs:#*[^:]:}/#/-}/%:#} ) +opt_arg_opts=( ${(@)${(@)${(@M)specs:#*::}/#/-}/%:#} ) + +# getopt returns all instances of each option given, so add + +specs=( ${(@)specs/%(#b)(:#)/+$match[1]} ) + +# POSIXLY_CORRECT: Stop parsing options after first non-option argument +if (( posix )); then + tmp=( "$@" ) + __zgetopt_zparseopts -D -F -G -a optvv -v tmp - $specs || return 1 + argvv=( "${(@)tmp}" ) + +# Default: Permute options following non-option arguments +else + tmp=( "$@" ) + __zgetopt_zparseopts -D -E -F -G -a optvv -v tmp - $specs || return 1 + argv=( "${(@)tmp}" ) + # -D + -E leaves an explicit -- in argv where-ever it might appear + local seen + while (( $# )); do + [[ -z $seen && $1 == -- ]] && seen=1 && shift && continue + argvv+=( "$1" ) + shift + done +fi + +# getopt outputs all optargs as separate parameters, even missing optional ones, +# so we scan through and add/separate those if needed. This can't be perfectly +# accurate if Sun-style (-a) long options are used with optional optargs -- e.g. +# if you have specs a:: and abc::, then argument -abc=d is ambiguous. We don't +# guarantee which one is prioritised +(( $#opt_arg_opts )) && { + local cur next + local -a old_optvv=( "${(@)optvv}" ) + optvv=( ) + + for (( i = 1; i <= $#old_optvv; i++ )); do + cur=$old_optvv[i] + next=$old_optvv[i+1] + # Option with no optarg + if [[ -n ${no_arg_opts[(r)$cur]} ]]; then + optvv+=( $cur ) + # Option with required optarg -- will appear in next element + elif [[ -n ${req_arg_opts[(r)$cur]} ]]; then + optvv+=( $cur "$next" ) + (( i++ )) + # Long option with optional optarg -- will appear in same element delimited + # by '=' (even if missing) + elif [[ $cur == *=* && -n ${opt_arg_opts[(r)${cur%%=*}]} ]]; then + optvv+=( ${cur%%=*} "${cur#*=}" ) + # Short option with optional optarg -- will appear in same element with no + # delimiter (thus the option appears alone if the optarg is missing) + elif [[ -n ${opt_arg_opts[(r)${(M)cur#-?}]} ]]; then + optvv+=( ${(M)cur#-?} "${cur#-?}" ) + # ??? + else + print -ru2 - "${0:t}: parse error, please report!" + print -ru2 - "${0:t}: specs: ${(j< >)${(@q+)specs}}" + print -ru2 - "${0:t}: old_optvv: ${(j< >)${(@q+)old_optvv}}" + print -ru2 - "${0:t}: cur: $cur" + optvv+=( $cur ) # I guess? + fi + done +} + +if [[ -n $array ]]; then + # Use EXIT trap to assign in caller's context + trap "$array=( ${(j< >)${(@q+)optvv}} -- ${(j< >)${(@q+)argvv}} )" EXIT + +elif [[ $ZSH_EVAL_CONTEXT != toplevel ]]; then + print -r - "${(@q+)optvv}" -- "${(@q+)argvv}" + +# If called as a script, use unconditional single-quoting. This is ugly but it's +# the closest to what getopt does and it offers compatibility with legacy shells +else + print -r - "${(@qq)optvv}" -- "${(@qq)argvv}" +fi + +return 0 diff --git a/NEWS b/NEWS index 7c5e1e06b..a1e74b9fb 100644 --- a/NEWS +++ b/NEWS @@ -51,7 +51,7 @@ result via assignment to the named param rather than always via $REPLY. The shell now uses monotonic time instead of wall time for most internal time tracking, making it immune to system clock changes due to NTP, etc. For the most part this is transparent to users. However, as a -side effect, some features like $SECONDS and the time builtin gained +side effect, some features like $SECONDS and the time keyword gained (nominal) nanosecond precision. The zsh/zutil module's zparseopts builtin learnt a -v option which can @@ -60,6 +60,9 @@ be used to specify the array of arguments to parse instead of $@. The zparseopts builtin also learnt a -G option which enables GNU-style argument parsing ('--opt=arg', etc.). +A new contrib function zgetopt was added. It wraps `zparseopts -G` to +provide an interface similar to util-linux's getopt(1). + The module zsh/pcre has been updated to use the pcre2 library. The new zsh/random module defines an SRANDOM parameter, zrand_float() diff --git a/Test/Z04zgetopt.ztst b/Test/Z04zgetopt.ztst new file mode 100644 index 000000000..c2bc22be0 --- /dev/null +++ b/Test/Z04zgetopt.ztst @@ -0,0 +1,206 @@ +%prep + + autoload -Uz zgetopt + +%test + + zgetopt -A '' -- a b c + zgetopt -A '' -o '' -- a b c + zgetopt -A '' -l '' -- a b c +0:-o or -l required +?zgetopt: missing option spec +>-- a b c +>-- a b c + + zgetopt -A '' -o - -- a b c + zgetopt -A '' -o -a -- a b c + zgetopt -A '' -o a- -- a b c + zgetopt -A '' -o a+ -- a b c + zgetopt -A '' -o a= -- a b c + zgetopt -A '' -o a\\ -- a b c + zgetopt -A '' -o :a -- a b c + zgetopt -A '' -o a::: -- a b c + zgetopt -A '' -o '' -- a b c + zgetopt -A '' -o + -- a b c +0:weird short-option specs +?zgetopt: optspec with leading - (disable operand collection) not supported +?zgetopt: optspec with leading - (disable operand collection) not supported +?zgetopt: invalid short-option name: - +?zgetopt: invalid short-option name: + +?zgetopt: invalid short-option name: = +?zgetopt: invalid short-option name: \ +?zgetopt: invalid short-option name: : +?zgetopt: invalid short-option name: : +>-- a b c +>-- a b c + + zgetopt -A '' -l a,+ -- a b c + zgetopt -A '' -l a,= -- a b c + zgetopt -A '' -l a,\\ -- a b c + zgetopt -A '' -l a,: -- a b c + zgetopt -A '' -l a,:b -- a b c + zgetopt -A '' -l a,b:b -- a b c + zgetopt -A '' -l a,b::: -- a b c + zgetopt -A '' -l '' -- a b c + zgetopt -A '' -l , -- a b c + zgetopt -A '' -l a,,,,,b -- a b c + zgetopt -A '' -l - -- a b c --- +0:weird long-option specs +?zgetopt: invalid long-option spec: + +?zgetopt: invalid long-option spec: = +?zgetopt: invalid long-option spec: \ +?zgetopt: invalid long-option spec: : +?zgetopt: invalid long-option spec: :b +?zgetopt: invalid long-option spec: b:b +?zgetopt: invalid long-option spec: b::: +>-- a b c +>-- a b c +>-- a b c +>--- -- a b c + + zgetopt -A '' -o ab:c:: -- a b c + zgetopt -A '' -o ab:c:: -- -a + zgetopt -A '' -o ab:c:: -- -a a b c + zgetopt -A '' -o ab:c:: -- -a a -b c + zgetopt -A '' -o ab:c:: -- -a a -b -c + zgetopt -A '' -o ab:c:: -- -a a -b -c d + zgetopt -A '' -o ab:c:: -- -a a -b -c -c + zgetopt -A '' -o ab:c:: -- -a a -b -c -c d + zgetopt -A '' -o ab:c:: -- -a a -b -c -cd +0:short options +>-- a b c +>-a -- +>-a -- a b c +>-a -b c -- a +>-a -b -c -- a +>-a -b -c -- a d +>-a -b -c -c '' -- a +>-a -b -c -c '' -- a d +>-a -b -c -c d -- a + + zgetopt -A '' -l aaa,bbb:,ccc:: -- a b c + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a b c + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb c + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb=c + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc d + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc --ccc + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc --ccc d + zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc --ccc=d +0:long options +>-- a b c +>--aaa -- +>--aaa -- a b c +>--aaa --bbb c -- a +>--aaa --bbb c -- a +>--aaa --bbb --ccc -- a +>--aaa --bbb --ccc -- a d +>--aaa --bbb --ccc --ccc '' -- a +>--aaa --bbb --ccc --ccc '' -- a d +>--aaa --bbb --ccc --ccc d -- a + + zgetopt -A '' -al aaa,bbb:,ccc:: -- a b c + zgetopt -A '' -al aaa,bbb:,ccc:: -- --aaa a b c + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a b c + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb c + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb=c + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc d + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc -ccc + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc -ccc d + zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc -ccc=d +0:long options with -a (Sun style) +>-- a b c +?(eval): bad option: --aaa +>-aaa -- +>-aaa -- a b c +>-aaa -bbb c -- a +>-aaa -bbb c -- a +>-aaa -bbb -ccc -- a +>-aaa -bbb -ccc -- a d +>-aaa -bbb -ccc -ccc '' -- a +>-aaa -bbb -ccc -ccc '' -- a d +>-aaa -bbb -ccc -ccc d -- a + + zgetopt -A '' -al a: -- -a=b +0:single-character long option with -a +>-a '=b' -- + + zgetopt -A '' -o '' +0:zero args to parse +>-- + + zgetopt -A '' -o '' -- -- a b c + zgetopt -A '' -o '' -- a b -- c + zgetopt -A '' -o '' -- a b c -- + zgetopt -A '' -o c -- a b -- -c + zgetopt -A '' -o c -- a b - -c +0:parsing terminator +>-- a b c +>-- a b c +>-- a b c +>-- a b -c +>-c -- a b - + + zgetopt -A '' -o a -- a -a b + zgetopt -A '' -o +a -- a -a b + POSIXLY_CORRECT=1 zgetopt -A '' -o a -- a -a b +0:POSIXLY_CORRECT +>-a -- a b +>-- a -a b +>-- a -a b + + zgetopt -A '' -o '' -- $'\a\'\a' +0:function-mode quoting style +>-- $'\C-G\'\C-G' + + zgetopt -A '' -o '' -- a -a b + zgetopt -A '' -o '' -- a --a b +1:bad options +?(eval): bad option: -a +?(eval): bad option: --a + + zgetopt -A '' ; echo $? # missing spec + zgetopt -A '' -o '' -x ; echo $? # bad option to zgetopt + zgetopt -A '' -o '' -- -y; echo $? # bad option to parse +0:return status +*?zgetopt: missing option spec +*>2 +*?zgetopt:zparseopts:*: bad option: -x +*?usage:* +*>2 +*?\(eval\): bad option: -y +*>1 + + () { zgetopt -o a -- "$@"; typeset -p argv } -a b c + () { local -a v; zgetopt -A v -o a -- "$@"; typeset -p argv v } -a b c +0:array output +>typeset -g -a argv=( -a -- b c ) +>typeset -g -a argv=( -a b c ) +>typeset -a v=( -a -- b c ) + + zgetopt -A '' -o a: -- -x + zgetopt -A '' -o a: -- -a + () { zgetopt -A '' -o a: -- "$@"; : } -x + func() { zgetopt -A '' -o a: -- "$@"; : }; func -x + f1() { zgetopt -A '' -o a: -- "$@"; : }; f2() { f1 "$@" }; f2 -x +0:automatic name +?(eval): bad option: -x +?(eval): missing argument for option: -a +?(anon): bad option: -x +?func: bad option: -x +?f1: bad option: -x + + zgetopt -n aaa -A '' -o a: -- -x + zgetopt -n aaa -A '' -o a: -- -a + () { zgetopt -n bbb -A '' -o a: -- "$@"; : } -x + func() { zgetopt -n ccc -A '' -o a: -- "$@"; : }; func -x + f1() { zgetopt -n ddd -A '' -o a: -- "$@"; : }; f2() { f1 "$@" }; f2 -x +0:manual name with -n +?aaa: bad option: -x +?aaa: missing argument for option: -a +?bbb: bad option: -x +?ccc: bad option: -x +?ddd: bad option: -x -- cgit v1.2.3 From 0e369f37d637874b45faa43a0896e70f45739abc Mon Sep 17 00:00:00 2001 From: dana Date: Sun, 27 Apr 2025 10:04:49 -0500 Subject: unposted: docs: adjust zgetopt wording per workers/53518 --- ChangeLog | 2 ++ Doc/Zsh/contrib.yo | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index de8fc6f3d..a02917bad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2025-04-27 dana + * unposted: Doc/Zsh/contrib.yo: adjust zgetopt wording + * 53516: Doc/Zsh/contrib.yo, Functions/Misc/zgetopt, NEWS, Test/Z04zgetopt.ztst: add zgetopt contrib function diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 030b63029..515b70f51 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -4710,13 +4710,13 @@ overwrites the caller's positional parameters. Has no meaning when called as a script, in which case the parsed and quoted arguments are always printed to standard output. An empty string forces the printing behaviour in either mode.) -sitem(tt(-a))(Use Sun-style single-hyphenated long options instead of -GNU-style double-hyphenated ones (tt(-foo) vs tt(--foo)). Note that -long options with optional optargs can't always be distinguished -accurately from short options with optional optargs when using this -option. Also, due to limitations of tt(zparseopts), a Sun-style long -option whose name is only one character long is always treated as a -short option.) +sitem(tt(-a))(Use `alternative'-style single-hyphenated long options +instead of GNU-style double-hyphenated ones (tt(-foo) vs tt(--foo)). +Note that long options with optional optargs can't always be +distinguished accurately from short options with optional optargs +when using this option. Also, due to limitations of tt(zparseopts), +a single-hyphenated long option whose name is only one character long +is always treated as a short option.) sitem(tt(-l var(spec)))(Specify long options to recognise when parsing. These should be given using just the option name (no dashes), suffixed by `tt(:)' or `tt(::)' if it takes a mandatory or -- cgit v1.2.3 From 9b68cf38f08fdf352fb1dc6fb97438210aee48b6 Mon Sep 17 00:00:00 2001 From: dana Date: Sun, 27 Apr 2025 10:36:49 -0500 Subject: unposted: document zparseopts's lack of support for abbreviating long options per workers/53520 --- ChangeLog | 4 ++++ Doc/Zsh/contrib.yo | 3 ++- Doc/Zsh/mod_zutil.yo | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a02917bad..441a5dd5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2025-04-27 dana + * unposted: Doc/Zsh/contrib.yo, Doc/Zsh/mod_zutil.yo: + document zparseopts's lack of support for abbreviating long + options + * unposted: Doc/Zsh/contrib.yo: adjust zgetopt wording * 53516: Doc/Zsh/contrib.yo, Functions/Misc/zgetopt, NEWS, diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 515b70f51..7822460e8 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -4748,7 +4748,8 @@ Refer to the manual for util-linux's tt(getopt+LPAR()1+RPAR()) for more information about the way arguments are parsed and results are returned. Note however that this function is not intended to be a complete re-implementation. In particular, it omits all -portability/compatibility features. +portability/compatibility features. Also, like tt(zparseopts) +itself, it does not support abbreviating long options. ) item(tt(zkbd))( See `Keyboard Definition' diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo index 19f9989f4..b296d878c 100644 --- a/Doc/Zsh/mod_zutil.yo +++ b/Doc/Zsh/mod_zutil.yo @@ -368,6 +368,9 @@ regardless of whether this option is in effect. Lastly, when this option is active, only `tt(-)tt(-)' is treated as an explicit option-parsing terminator in the parsed arguments; a single `tt(-)' is considered a normal operand. + +Note: Unlike most tt(getopt_long+LPAR()3+RPAR()) implementations, +tt(zparseopts) does not support abbreviating long options. ) item(tt(-K))( With this option, the arrays specified with the tt(-a) option and with the -- cgit v1.2.3 From 80de57d5a63870e61a3d48efa1406ac05bbd2b5b Mon Sep 17 00:00:00 2001 From: dana Date: Mon, 28 Apr 2025 16:18:42 -0500 Subject: 53527: remove zgetopt reverts most of 84ef0c523, 0e369f37d, and 9b68cf38f feature was not ready. may be re-added after 5.10 release --- ChangeLog | 5 ++ Doc/Zsh/contrib.yo | 79 ------------------- Functions/Misc/zgetopt | 198 ----------------------------------------------- NEWS | 3 - Test/Z04zgetopt.ztst | 206 ------------------------------------------------- 5 files changed, 5 insertions(+), 486 deletions(-) delete mode 100755 Functions/Misc/zgetopt delete mode 100644 Test/Z04zgetopt.ztst diff --git a/ChangeLog b/ChangeLog index 441a5dd5a..cdcf5d5e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-04-28 dana + + * 53527: Doc/Zsh/contrib.yo, Functions/Misc/zgetopt, NEWS, + Test/Z04zgetopt.ztst: remove zgetopt (feature not ready) + 2025-04-27 dana * unposted: Doc/Zsh/contrib.yo, Doc/Zsh/mod_zutil.yo: diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 7822460e8..c1bea6022 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -4672,85 +4672,6 @@ Same as tt(zmv -C) and tt(zmv -L), respectively. These functions do not appear in the zsh distribution, but can be created by linking tt(zmv) to the names tt(zcp) and tt(zln) in some directory in your tt(fpath). ) -findex(zgetopt) -item(tt(zgetopt) [ tt(-a) ] [ tt(-A) var(array) ] [ tt(-l) var(spec) ] [ tt(-n) var(name) ] [ tt(-o) var(spec) ] tt(--) [ var(args) ])( -This is a wrapper around tt(zparseopts) (from tt(zsh/zutil)) which -provides an interface similar to the util-linux implementation of -tt(getopt+LPAR()1+RPAR()) (sometimes called `GNU tt(getopt)'). It -simplifies GNU-style argument parsing (including permutation) and -can make it easier to write functions and scripts with complex APIs, -particularly ones where the order of options is significant. - -The typical usage pattern is as follows: - -example(zgetopt -o abc: -l aaa,bbb,ccc: -- "$@" || return -while (( $# )); do - case $1 in - -a|--aaa+RPAR() ...; shift ;; # handle -a - -b|--bbb+RPAR() ...; shift ;; # handle -b - -c|--ccc+RPAR() ...; shift 2 ;; # handle -c and arg - --+RPAR() ...; shift; break ;; # end of options - esac -done -# handle operands) - -It can also be called as a stand-alone script from other shells -using the more traditional print-and-eval pattern: - -example(args="$( zgetopt -n myscript -o abc: -l aaa,bbb,ccc: -- "$@" )" || return -eval set -- "$args" -while [ $# -ne 0 ]; do ...; done) - -Options: - -startsitem() -sitem(tt(-A var(array)))(When called as a function, assign the parsed -arguments to the named array var(array). Defaults to tt(argv), which -overwrites the caller's positional parameters. Has no meaning when -called as a script, in which case the parsed and quoted arguments are -always printed to standard output. An empty string forces the -printing behaviour in either mode.) -sitem(tt(-a))(Use `alternative'-style single-hyphenated long options -instead of GNU-style double-hyphenated ones (tt(-foo) vs tt(--foo)). -Note that long options with optional optargs can't always be -distinguished accurately from short options with optional optargs -when using this option. Also, due to limitations of tt(zparseopts), -a single-hyphenated long option whose name is only one character long -is always treated as a short option.) -sitem(tt(-l var(spec)))(Specify long options to recognise when -parsing. These should be given using just the option name (no -dashes), suffixed by `tt(:)' or `tt(::)' if it takes a mandatory or -optional argument respectively. Multiple options can be defined -either by separating them by commas or by supplying -l again. -Example: tt(-l foo,bar: -l baz)) -sitem(tt(-n var(name)))(Specify the name to use in the error message -if argument parsing fails. Defaults to the name of the nearest -calling function or the base name of tt($ZSH_ARGZERO). Note that -errors related to the usage of tt(zgetopt) itself are always reported -as coming from tt(zgetopt).) -sitem(tt(-o var(spec)))(Specify short options to recognise when -parsing. These should be given as a single string, in the same format -used by the tt(getopts) built-in or the tt(getopt+LPAR()3+RPAR()) -library function, again using `tt(:)' or `tt(::)' to indicate a -mandatory or optional argument. The spec may be prefixed with `tt(+)' -to indicate that option parsing should stop at the first non-option -argument (equivalent to setting the environment variable -tt(POSIXLY_CORRECT)). Example: tt(-o ab:cd::)) -endsitem() - -At least one of tt(-o) or tt(-l) must be given. The function's own -options should be followed by zero or more arguments to parse. It is -critical that these be separated explicitly by `tt(--)', as in the -above examples, to ensure that the function can accurately -distinguish the arguments it's meant to parse from its own. - -Refer to the manual for util-linux's tt(getopt+LPAR()1+RPAR()) for -more information about the way arguments are parsed and results are -returned. Note however that this function is not intended to be a -complete re-implementation. In particular, it omits all -portability/compatibility features. Also, like tt(zparseopts) -itself, it does not support abbreviating long options. -) item(tt(zkbd))( See `Keyboard Definition' ifzman(above)\ diff --git a/Functions/Misc/zgetopt b/Functions/Misc/zgetopt deleted file mode 100755 index 5fc1e7725..000000000 --- a/Functions/Misc/zgetopt +++ /dev/null @@ -1,198 +0,0 @@ -#!/bin/zsh -f - -# Wrapper around zparseopts which gives it an interface similar to util-linux's -# getopt(1). See zshcontrib(1) for documentation - -emulate -L zsh -o extended_glob -zmodload -i zsh/zutil || return 3 - -# Very stupid and brittle internal wrapper around zparseopts used to insert the -# caller name into its error messages, allowing us to implement --name. This -# MUST be called with -v, since argv has the options to zparseopts itself -__zgetopt_zparseopts() { - local __err __ret - - __err=$( zparseopts "$@" 2>&1 ) - __ret=$? - - zparseopts "$@" &> /dev/null && return - - # Raw error message should look like this: - # zgetopt_zparseopts:zparseopts:3: bad option: -x - [[ -n $__err ]] && print -ru2 - ${__err/#*:zparseopts:<->:/$name:} - return __ret -} - -local optspec pat i posix=0 -local -a match mbegin mend optvv argvv -local -a array alt lopts sopts name -local -a specs no_arg_opts req_arg_opts opt_arg_opts tmp - -# Same as leading + in short-opts spec -(( $+POSIXLY_CORRECT )) && posix=1 - -# This 0=... makes any error message we get here look a little nicer when we're -# called as a script. Unfortunately the function name overrides $0 in -# zwarnnam() in other scenarios, so this can't be used to implement --name -0=${0:t} zparseopts -D -F -G - \ - {A,-array}:-=array \ - {a,-alternative}=alt \ - {l,-longoptions,-long-options}+:-=lopts \ - {n,-name}:-=name \ - {o,-options}:-=sopts \ -|| { - print -ru2 "usage: ${0:t} [-A ] [-a] [-l ] [-n ] [-o ] -- " - return 2 -} - -# Default to the caller's name -(( $#name )) && name=( "${(@)name/#(-n|--name=)/}" ) -[[ -n $name ]] || name=( ${funcstack[2]:-${ZSH_ARGZERO:t}} ) - -(( $#array )) && array=( "${(@)array/#(-A|--array=)/}" ) - -if [[ $ZSH_EVAL_CONTEXT != toplevel ]]; then - [[ $array == *[^A-Za-z0-9_.]* ]] && { - print -ru2 - "${0:t}: invalid array name: $array" - return 2 - } - (( $#array )) || array=( argv ) - -elif [[ -n $array ]]; then - print -ru2 - "${0:t}: -A option not meaningful unless called as function" - return 2 -fi - -# getopt requires a short option spec; we'll require either short or long -(( $#sopts || $#lopts )) || { - print -ru2 - "${0:t}: missing option spec" - return 2 -} - -optspec=${(@)sopts/#(-o|--options=)/} -sopts=( ) - -for (( i = 1; i <= $#optspec; i++ )); do - # Leading '+': Act POSIXLY_CORRECT - if [[ $i == 1 && $optspec[i] == + ]]; then - posix=1 - # Leading '-': Should leave operands interspersed with options, but this is - # not really possible with zparseopts - elif [[ $i == 1 && $optspec[i] == - ]]; then - print -ru2 - "${0:t}: optspec with leading - (disable operand collection) not supported" - return 2 - # Special characters: [+=\\] because they're special to zparseopts, ':' - # because it's special to getopt, '-' because it's the parsing terminator - elif [[ $optspec[i] == [+:=\\-] ]]; then - print -ru2 - "${0:t}: invalid short-option name: $optspec[i]" - return 2 - # 'a' - elif [[ $optspec[i+1] != : ]]; then - sopts+=( $optspec[i] ) - # 'a:' - elif [[ $optspec[i+2] != : ]]; then - sopts+=( $optspec[i]: ) - (( i += 1 )) - # 'a::' - elif [[ $optspec[i+3] != : ]]; then - sopts+=( $optspec[i]:: ) - (( i += 2 )) - fi -done - -lopts=( ${(@)lopts/#(-l|--long(|-)options=)/} ) -lopts=( ${(@s<,>)lopts} ) - -# Don't allow characters that are special to zparseopts in long-option specs. -# See above -pat='(*[+=\\]*|:*|*:::##|*:[^:]*)' -[[ -n ${(@M)lopts:#$~pat} ]] && { - print -ru2 - "${0:t}: invalid long-option spec: ${${(@M)lopts:#$~pat}[1]}" - return 2 -} - -(( $#alt )) || lopts=( ${(@)lopts/#/-} ) - -specs=( $sopts $lopts ) - -# Used below to identify options with optional optargs -no_arg_opts=( ${(@)${(@M)specs:#*[^:]}/#/-} ) -req_arg_opts=( ${(@)${(@)${(@M)specs:#*[^:]:}/#/-}/%:#} ) -opt_arg_opts=( ${(@)${(@)${(@M)specs:#*::}/#/-}/%:#} ) - -# getopt returns all instances of each option given, so add + -specs=( ${(@)specs/%(#b)(:#)/+$match[1]} ) - -# POSIXLY_CORRECT: Stop parsing options after first non-option argument -if (( posix )); then - tmp=( "$@" ) - __zgetopt_zparseopts -D -F -G -a optvv -v tmp - $specs || return 1 - argvv=( "${(@)tmp}" ) - -# Default: Permute options following non-option arguments -else - tmp=( "$@" ) - __zgetopt_zparseopts -D -E -F -G -a optvv -v tmp - $specs || return 1 - argv=( "${(@)tmp}" ) - # -D + -E leaves an explicit -- in argv where-ever it might appear - local seen - while (( $# )); do - [[ -z $seen && $1 == -- ]] && seen=1 && shift && continue - argvv+=( "$1" ) - shift - done -fi - -# getopt outputs all optargs as separate parameters, even missing optional ones, -# so we scan through and add/separate those if needed. This can't be perfectly -# accurate if Sun-style (-a) long options are used with optional optargs -- e.g. -# if you have specs a:: and abc::, then argument -abc=d is ambiguous. We don't -# guarantee which one is prioritised -(( $#opt_arg_opts )) && { - local cur next - local -a old_optvv=( "${(@)optvv}" ) - optvv=( ) - - for (( i = 1; i <= $#old_optvv; i++ )); do - cur=$old_optvv[i] - next=$old_optvv[i+1] - # Option with no optarg - if [[ -n ${no_arg_opts[(r)$cur]} ]]; then - optvv+=( $cur ) - # Option with required optarg -- will appear in next element - elif [[ -n ${req_arg_opts[(r)$cur]} ]]; then - optvv+=( $cur "$next" ) - (( i++ )) - # Long option with optional optarg -- will appear in same element delimited - # by '=' (even if missing) - elif [[ $cur == *=* && -n ${opt_arg_opts[(r)${cur%%=*}]} ]]; then - optvv+=( ${cur%%=*} "${cur#*=}" ) - # Short option with optional optarg -- will appear in same element with no - # delimiter (thus the option appears alone if the optarg is missing) - elif [[ -n ${opt_arg_opts[(r)${(M)cur#-?}]} ]]; then - optvv+=( ${(M)cur#-?} "${cur#-?}" ) - # ??? - else - print -ru2 - "${0:t}: parse error, please report!" - print -ru2 - "${0:t}: specs: ${(j< >)${(@q+)specs}}" - print -ru2 - "${0:t}: old_optvv: ${(j< >)${(@q+)old_optvv}}" - print -ru2 - "${0:t}: cur: $cur" - optvv+=( $cur ) # I guess? - fi - done -} - -if [[ -n $array ]]; then - # Use EXIT trap to assign in caller's context - trap "$array=( ${(j< >)${(@q+)optvv}} -- ${(j< >)${(@q+)argvv}} )" EXIT - -elif [[ $ZSH_EVAL_CONTEXT != toplevel ]]; then - print -r - "${(@q+)optvv}" -- "${(@q+)argvv}" - -# If called as a script, use unconditional single-quoting. This is ugly but it's -# the closest to what getopt does and it offers compatibility with legacy shells -else - print -r - "${(@qq)optvv}" -- "${(@qq)argvv}" -fi - -return 0 diff --git a/NEWS b/NEWS index a1e74b9fb..d5f6ab620 100644 --- a/NEWS +++ b/NEWS @@ -60,9 +60,6 @@ be used to specify the array of arguments to parse instead of $@. The zparseopts builtin also learnt a -G option which enables GNU-style argument parsing ('--opt=arg', etc.). -A new contrib function zgetopt was added. It wraps `zparseopts -G` to -provide an interface similar to util-linux's getopt(1). - The module zsh/pcre has been updated to use the pcre2 library. The new zsh/random module defines an SRANDOM parameter, zrand_float() diff --git a/Test/Z04zgetopt.ztst b/Test/Z04zgetopt.ztst deleted file mode 100644 index c2bc22be0..000000000 --- a/Test/Z04zgetopt.ztst +++ /dev/null @@ -1,206 +0,0 @@ -%prep - - autoload -Uz zgetopt - -%test - - zgetopt -A '' -- a b c - zgetopt -A '' -o '' -- a b c - zgetopt -A '' -l '' -- a b c -0:-o or -l required -?zgetopt: missing option spec ->-- a b c ->-- a b c - - zgetopt -A '' -o - -- a b c - zgetopt -A '' -o -a -- a b c - zgetopt -A '' -o a- -- a b c - zgetopt -A '' -o a+ -- a b c - zgetopt -A '' -o a= -- a b c - zgetopt -A '' -o a\\ -- a b c - zgetopt -A '' -o :a -- a b c - zgetopt -A '' -o a::: -- a b c - zgetopt -A '' -o '' -- a b c - zgetopt -A '' -o + -- a b c -0:weird short-option specs -?zgetopt: optspec with leading - (disable operand collection) not supported -?zgetopt: optspec with leading - (disable operand collection) not supported -?zgetopt: invalid short-option name: - -?zgetopt: invalid short-option name: + -?zgetopt: invalid short-option name: = -?zgetopt: invalid short-option name: \ -?zgetopt: invalid short-option name: : -?zgetopt: invalid short-option name: : ->-- a b c ->-- a b c - - zgetopt -A '' -l a,+ -- a b c - zgetopt -A '' -l a,= -- a b c - zgetopt -A '' -l a,\\ -- a b c - zgetopt -A '' -l a,: -- a b c - zgetopt -A '' -l a,:b -- a b c - zgetopt -A '' -l a,b:b -- a b c - zgetopt -A '' -l a,b::: -- a b c - zgetopt -A '' -l '' -- a b c - zgetopt -A '' -l , -- a b c - zgetopt -A '' -l a,,,,,b -- a b c - zgetopt -A '' -l - -- a b c --- -0:weird long-option specs -?zgetopt: invalid long-option spec: + -?zgetopt: invalid long-option spec: = -?zgetopt: invalid long-option spec: \ -?zgetopt: invalid long-option spec: : -?zgetopt: invalid long-option spec: :b -?zgetopt: invalid long-option spec: b:b -?zgetopt: invalid long-option spec: b::: ->-- a b c ->-- a b c ->-- a b c ->--- -- a b c - - zgetopt -A '' -o ab:c:: -- a b c - zgetopt -A '' -o ab:c:: -- -a - zgetopt -A '' -o ab:c:: -- -a a b c - zgetopt -A '' -o ab:c:: -- -a a -b c - zgetopt -A '' -o ab:c:: -- -a a -b -c - zgetopt -A '' -o ab:c:: -- -a a -b -c d - zgetopt -A '' -o ab:c:: -- -a a -b -c -c - zgetopt -A '' -o ab:c:: -- -a a -b -c -c d - zgetopt -A '' -o ab:c:: -- -a a -b -c -cd -0:short options ->-- a b c ->-a -- ->-a -- a b c ->-a -b c -- a ->-a -b -c -- a ->-a -b -c -- a d ->-a -b -c -c '' -- a ->-a -b -c -c '' -- a d ->-a -b -c -c d -- a - - zgetopt -A '' -l aaa,bbb:,ccc:: -- a b c - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a b c - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb c - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb=c - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc d - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc --ccc - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc --ccc d - zgetopt -A '' -l aaa,bbb:,ccc:: -- --aaa a --bbb --ccc --ccc=d -0:long options ->-- a b c ->--aaa -- ->--aaa -- a b c ->--aaa --bbb c -- a ->--aaa --bbb c -- a ->--aaa --bbb --ccc -- a ->--aaa --bbb --ccc -- a d ->--aaa --bbb --ccc --ccc '' -- a ->--aaa --bbb --ccc --ccc '' -- a d ->--aaa --bbb --ccc --ccc d -- a - - zgetopt -A '' -al aaa,bbb:,ccc:: -- a b c - zgetopt -A '' -al aaa,bbb:,ccc:: -- --aaa a b c - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a b c - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb c - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb=c - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc d - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc -ccc - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc -ccc d - zgetopt -A '' -al aaa,bbb:,ccc:: -- -aaa a -bbb -ccc -ccc=d -0:long options with -a (Sun style) ->-- a b c -?(eval): bad option: --aaa ->-aaa -- ->-aaa -- a b c ->-aaa -bbb c -- a ->-aaa -bbb c -- a ->-aaa -bbb -ccc -- a ->-aaa -bbb -ccc -- a d ->-aaa -bbb -ccc -ccc '' -- a ->-aaa -bbb -ccc -ccc '' -- a d ->-aaa -bbb -ccc -ccc d -- a - - zgetopt -A '' -al a: -- -a=b -0:single-character long option with -a ->-a '=b' -- - - zgetopt -A '' -o '' -0:zero args to parse ->-- - - zgetopt -A '' -o '' -- -- a b c - zgetopt -A '' -o '' -- a b -- c - zgetopt -A '' -o '' -- a b c -- - zgetopt -A '' -o c -- a b -- -c - zgetopt -A '' -o c -- a b - -c -0:parsing terminator ->-- a b c ->-- a b c ->-- a b c ->-- a b -c ->-c -- a b - - - zgetopt -A '' -o a -- a -a b - zgetopt -A '' -o +a -- a -a b - POSIXLY_CORRECT=1 zgetopt -A '' -o a -- a -a b -0:POSIXLY_CORRECT ->-a -- a b ->-- a -a b ->-- a -a b - - zgetopt -A '' -o '' -- $'\a\'\a' -0:function-mode quoting style ->-- $'\C-G\'\C-G' - - zgetopt -A '' -o '' -- a -a b - zgetopt -A '' -o '' -- a --a b -1:bad options -?(eval): bad option: -a -?(eval): bad option: --a - - zgetopt -A '' ; echo $? # missing spec - zgetopt -A '' -o '' -x ; echo $? # bad option to zgetopt - zgetopt -A '' -o '' -- -y; echo $? # bad option to parse -0:return status -*?zgetopt: missing option spec -*>2 -*?zgetopt:zparseopts:*: bad option: -x -*?usage:* -*>2 -*?\(eval\): bad option: -y -*>1 - - () { zgetopt -o a -- "$@"; typeset -p argv } -a b c - () { local -a v; zgetopt -A v -o a -- "$@"; typeset -p argv v } -a b c -0:array output ->typeset -g -a argv=( -a -- b c ) ->typeset -g -a argv=( -a b c ) ->typeset -a v=( -a -- b c ) - - zgetopt -A '' -o a: -- -x - zgetopt -A '' -o a: -- -a - () { zgetopt -A '' -o a: -- "$@"; : } -x - func() { zgetopt -A '' -o a: -- "$@"; : }; func -x - f1() { zgetopt -A '' -o a: -- "$@"; : }; f2() { f1 "$@" }; f2 -x -0:automatic name -?(eval): bad option: -x -?(eval): missing argument for option: -a -?(anon): bad option: -x -?func: bad option: -x -?f1: bad option: -x - - zgetopt -n aaa -A '' -o a: -- -x - zgetopt -n aaa -A '' -o a: -- -a - () { zgetopt -n bbb -A '' -o a: -- "$@"; : } -x - func() { zgetopt -n ccc -A '' -o a: -- "$@"; : }; func -x - f1() { zgetopt -n ddd -A '' -o a: -- "$@"; : }; f2() { f1 "$@" }; f2 -x -0:manual name with -n -?aaa: bad option: -x -?aaa: missing argument for option: -a -?bbb: bad option: -x -?ccc: bad option: -x -?ddd: bad option: -x -- cgit v1.2.3 From 001cba48ce3b964cf01fb3e2af54b20eacbc9bf5 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Tue, 8 Mar 2022 12:34:20 -0600 Subject: unposted: README: add missed note about <<< redirection this was meant to be posted as part of workers/49813, but it was missed in the actual commit somehow. see workers/53528 --- ChangeLog | 2 ++ README | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index cdcf5d5e8..774a9ce6c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2025-04-28 dana + * unposted: README: add missed note about <<< redirection + * 53527: Doc/Zsh/contrib.yo, Functions/Misc/zgetopt, NEWS, Test/Z04zgetopt.ztst: remove zgetopt (feature not ready) diff --git a/README b/README index 4da92eee8..993a79abd 100644 --- a/README +++ b/README @@ -217,6 +217,11 @@ The ${name:offset:length} expansion syntax now behaves more similarly to other shells in that the offset and length are applied as array indices prior to scalar conversion in e.g. "${*:0:2}". +The optimization for the =(<<