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

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



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
 
   () {




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