zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: zparseopts varieties
Date: Tue, 26 Jan 2016 19:00:44 -0800	[thread overview]
Message-ID: <160126190044.ZM2079@torch.brasslantern.com> (raw)
In-Reply-To: <CAKc7PVCxCs7hfAvG=ZG1v=6Ez=yX-wQHnjyeuN17V-Ky+rdAvw@mail.gmail.com>

On Jan 26,  9:53am, Sebastian Gniazdowski wrote:
}
} Argument of -M will not be put into Mopt associative array:
} 
} % typeset -A Mopt; set -- -M arg; zparseopts -D -A Mopt "M::"; echo
} ${(kv)Mopt}; echo "1: $1, 2: $2"
} -M
} 1: arg, 2:

Curious.

The code to handle the argument in the next word is unreachable in the
optional case, and it appears to have been so ever since zparseopts was
invented; or, at least, as long as we've had code in version control.

Also, there's this:

torch% zparseopts -A opts -DE b: c
 ../../zsh-5.0/Src/params.c:2986: BUG: assigning to undeclared associative array

Which actually is probably a case of an over-aggressive DPUTS assertion
(that I added a few months ago) rather than an actual bug.

} Also, double colon (optionality of argument) cannot take array name:

This is intentional: you aren't meant to use an associative array with
the =array form, double colon or not.

torch% typeset -A Mopt
torch% set -- -b -c
torch% zparseopts b=Mopt
zsh: bad set of key/value pairs for associative array

It accidentally works to use the same associative array for an even number
of options, but the results are wrong -- the options alternate as keys
and values:

torch% zparseopts c=Mopt b=Mopt
torch% print -rl -- ${(k)Mopt}
-b
torch% print -rl -- ${(v)Mopt}
-c


I scanned the distributed functions for uses of zparseopts with "::" and
did not find any, so hopefully the following won't break anything.


diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo
index fd6f2f3..dc17161 100644
--- a/Doc/Zsh/mod_zutil.yo
+++ b/Doc/Zsh/mod_zutil.yo
@@ -179,13 +179,14 @@ item(tt(zregexparse))(
 This implements some internals of the tt(_regex_arguments) function.
 )
 findex(zparseopts)
-item(tt(zparseopts) [ tt(-DKME) ] [ tt(-a) var(array) ] [ tt(-A) var(assoc) ] var(spec) ...)(
+item(tt(zparseopts) [ tt(-D) tt(-K) tt(-M) tt(-E) ] [ tt(-a) var(array) ] [ tt(-A) var(assoc) ] 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
 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
-`tt(=)var(array)' is given, it is instead copied into that array.
+`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.
@@ -232,7 +233,10 @@ first colon.
 )
 enditem()
 
-The options of tt(zparseopts) itself are:
+The options of tt(zparseopts) itself cannot be stacked because, for
+example, the stack `tt(-DEK)' is indistinguishable from a var(spec) for
+the GNU-style long option `tt(--DEK)'.  The options of tt(zparseopts)
+itself are:
 
 startitem()
 item(tt(-a) var(array))(
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 376cd84..d98028a 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -1833,7 +1833,8 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		    if (o[1]) {
 			add_opt_val(d, o + 1);
 			break;
-		    } else if (!(d->flags & ZOF_OPT)) {
+		    } else if (!(d->flags & ZOF_OPT) ||
+			       (pp[1] && pp[1][0] != '-')) {
 			if (!pp[1]) {
 			    zwarnnam(nam, "missing argument for option: %s",
 				    d->name);
@@ -1859,7 +1860,8 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 
 		if (*e)
 		    add_opt_val(d, e);
-		else if (!(d->flags & ZOF_OPT)) {
+		else if (!(d->flags & ZOF_OPT) ||
+			 (pp[1] && pp[1][0] != '-')) {
 		    if (!pp[1]) {
 			zwarnnam(nam, "missing argument for option: %s",
 				d->name);


      reply	other threads:[~2016-01-27  3:00 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-26  8:53 Sebastian Gniazdowski
2016-01-27  3:00 ` Bart Schaefer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=160126190044.ZM2079@torch.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).