[PATCH] zparseopts -M: use last as-given option name in arrays

dana <[email protected]>
Newsgroups gmane.comp.shells.zsh.devel
Message-ID <[email protected]>
something i noticed with `zparseopts -M`:

  % fn() { local -a v; zparseopts -av -M - a:=-aaa -aaa:; typeset -p v }
  % fn -a foo
  typeset -a v=( -a foo )
  % fn --aaa foo -a bar
  typeset -a v=( --aaa bar )

with -a+ it uses the as-given option name in the array each time, but
with -a (as above) it uses whatever name was used first

this feels weird to me. i think it should either (a) always use the
mapped-to name like it does for the association keys or (b) use the
last/effective as-given name like it does in arrays with +

both options sound good to me and they're both very simple changes, so
i'm torn. but based on users/16032 i think the latter is closer to what
bart intended? so i've done that here. tell me if we'd like it better
another way though

dana


diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo
index a18985a4b..6e5403d70 100644
--- a/Doc/Zsh/mod_zutil.yo
+++ b/Doc/Zsh/mod_zutil.yo
@@ -396,7 +396,10 @@ item(tt(-M))(
 This changes the assignment rules to implement a map among equivalent
 option names.  If any var(spec) uses the `tt(=)var(array)' form, the
 string var(array) is interpreted as the name of another var(spec),
-which is used to choose where to store the values.  If no other var(spec)
+which is used to choose where to store the values.
+Values stored in an associative array (tt(-A)) use the name of the
+mapped-to option, whereas values stored in an array use the last
+as-given option name.  If no other var(spec)
 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.
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index f13ac95ac..72cc5ee54 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -1654,9 +1654,9 @@ add_opt_val(Zoptdesc d, char *arg)
     if (!v) {
 	v = (Zoptval) zhalloc(sizeof(*v));
 	v->next = v->onext = NULL;
-	v->name = n;
 	new = 1;
     }
+    v->name = n; // insert the last given name into arrays
     v->arg = arg;
     if ((d->flags & ZOF_ARG) && !(d->flags & (ZOF_OPT | ZOF_SAME))) {
 	v->str = NULL;
diff --git a/Test/V12zparseopts.ztst b/Test/V12zparseopts.ztst
index 6a880b49c..17b0a01d2 100644
--- a/Test/V12zparseopts.ztst
+++ b/Test/V12zparseopts.ztst
@@ -127,13 +127,20 @@
 >ret: 0, opts: -a '' -b 1 -z '', argv: 1 2 3
 >ret: 0, opts: -b 1 -z '', argv: 1 2 3
 
-  () {
+  fn() {
     local -a optv
     local -A opts
     zparseopts -D -M -a optv -A opts - a:=-aaa -aaa:
     print -r - ret: $?, optv: $optv, opts: "$( order_assoc opts )", argv: $argv
-  } --aaa foo -a bar 1 2 3
+  }
+  fn -a foo 1 2 3
+  fn --aaa foo 1 2 3
+  fn --aaa foo -a bar 1 2 3
+  fn -a foo --aaa bar 1 2 3
 0:zparseopts -M
+>ret: 0, optv: -a foo, opts: --aaa foo, argv: 1 2 3
+>ret: 0, optv: --aaa foo, opts: --aaa foo, argv: 1 2 3
+>ret: 0, optv: -a bar, opts: --aaa bar, argv: 1 2 3
 >ret: 0, optv: --aaa bar, opts: --aaa bar, argv: 1 2 3
 
   () {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.