diff options
author | dana <dana@dana.is> | 2025-04-28 16:18:42 -0500 |
---|---|---|
committer | dana <dana@dana.is> | 2025-04-28 16:23:29 -0500 |
commit | 80de57d5a63870e61a3d48efa1406ac05bbd2b5b (patch) | |
tree | f3daf3e4816e6a11ad57fc7f4e3ea8b1456e78d8 | |
parent | 9b68cf38f08fdf352fb1dc6fb97438210aee48b6 (diff) | |
download | zsh-80de57d5a63870e61a3d48efa1406ac05bbd2b5b.tar.gz zsh-80de57d5a63870e61a3d48efa1406ac05bbd2b5b.zip |
53527: remove zgetopt
reverts most of 84ef0c523, 0e369f37d, and 9b68cf38f
feature was not ready. may be re-added after 5.10 release
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Doc/Zsh/contrib.yo | 79 | ||||
-rwxr-xr-x | Functions/Misc/zgetopt | 198 | ||||
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | Test/Z04zgetopt.ztst | 206 |
5 files changed, 5 insertions, 486 deletions
@@ -1,3 +1,8 @@ +2025-04-28 dana <dana@dana.is> + + * 53527: Doc/Zsh/contrib.yo, Functions/Misc/zgetopt, NEWS, + Test/Z04zgetopt.ztst: remove zgetopt (feature not ready) + 2025-04-27 dana <dana@dana.is> * 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 <array>] [-a] [-l <spec>] [-n <name>] [-o <spec>] -- <args>" - 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 @@ -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 |