Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [PATCH] zparseopts: allow omitting array



On Fri 3 Jan 2025, at 10:43, Bart Schaefer wrote:
> I had always presumed that the requirement for an array was to prevent
> people from making baffling mistakes.

i considered that, but it feels like a weird type of mistake to design the api
around

On Fri 3 Jan 2025, at 10:43, Bart Schaefer wrote:
> You mean the test cases?  Or a more-previous message?

just the command i used to demonstrate the issue, where all it's doing is
validating the options; the array is unused. i've done this in real-world
scripts where i was passing $@ to another command as-is but i still wanted to
test whether only a certain sub-set of its supported options were given

On Fri 3 Jan 2025, at 10:43, Bart Schaefer wrote:
> Anyway I think I'd prefer that the array be optional only when one of
> -D or -F is present.  I'm undecided about -E.

that would work for me, revised below. or we can forget it if you're still
unconvinced, i don't feel that strongly tbh

dana


diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo
index 76907352f..d02fffeb6 100644
--- a/Doc/Zsh/mod_zutil.yo
+++ b/Doc/Zsh/mod_zutil.yo
@@ -233,12 +233,15 @@ 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
 described by var(opt) is found in the positional parameters it is copied
-into the var(array) specified with the tt(-a) option; if the optional
+into the var(array) or var(assoc) specified with the tt(-a) or tt(-A)
+option respectively; if the optional
 `tt(=)var(array)' is given, it is instead copied into that array, which
 should be declared as a normal array and never as an associative array.
 
 Note that it is an error to give any var(spec) without an
-`tt(=)var(array)' unless one of the tt(-a) or tt(-A) options is used.
+`tt(=)var(array)' unless one of the tt(-a), tt(-A), tt(-D), or
+tt(-F) options is used.  (tt(-D) or tt(-F) without an array can be
+used for discarding unused options or for error checking.)
 
 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),
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 9b2721a09..0b37e8ffa 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -1924,7 +1924,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	} else if (*p) {
 	    zwarnnam(nam, "invalid option description: %s", args[-1]);
 	    return 1;
-	} else if (!(a = defarr) && !assoc) {
+	} else if (!(a = defarr) && !assoc && !del && !fail) {
 	    zwarnnam(nam, "no default array defined: %s", args[-1]);
 	    return 1;
 	}
diff --git a/Test/V12zparseopts.ztst b/Test/V12zparseopts.ztst
index a2743ea0e..a4bbe2b34 100644
--- a/Test/V12zparseopts.ztst
+++ b/Test/V12zparseopts.ztst
@@ -119,6 +119,18 @@
 0:multiple arrays
 >ret: 0, optv: -c-d, aa: -a, ab: -b 1, argv: -ab1 -c -d
 
+  () { zparseopts    - a b c; print -r - ret: $?, argv: $argv } -ab -c x
+  () { zparseopts -E - a b c; print -r - ret: $?, argv: $argv } -ab -c x
+  () { zparseopts -D - a b c; print -r - ret: $?, argv: $argv } -ab -c x
+  () { zparseopts -F - a b c; print -r - ret: $?, argv: $argv } -ab -c x
+0:no array (only valid with -D or -F)
+?(anon):zparseopts: no default array defined: a
+>ret: 1, argv: -ab -c x
+?(anon):zparseopts: no default array defined: a
+>ret: 1, argv: -ab -c x
+>ret: 0, argv: x
+>ret: 0, argv: -ab -c x
+
   for 1 in '-a - -b - - -b' '-a -- -b -- -- -b' '-a 1 -b - - -b'; do
     # -D alone strips - out
     () {




Messages sorted by: Reverse Date, Date, Thread, Author