zsh-workers
 help / color / mirror / code / Atom feed
* PATCH Re: zparseopts default associative array
       [not found]   ` <20140214081434.1580@binki>
@ 2014-02-15 21:15     ` Bart Schaefer
  2014-02-15 22:19       ` Peter Stephenson
  0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2014-02-15 21:15 UTC (permalink / raw)
  To: zsh-workers; +Cc: jdh

[Moving to zsh-workers]

On Feb 14,  8:14am, jdh wrote:
}
} Bart Schaefer <schaefer@brasslantern.com> wrote:
} 
} > Yes, it would probably make sense for associative arrays if -K retained
} > individual elements
} 
} Not having that natural functionality cuts its utility down to
} almost nothing.

Obviously it's not THAT difficult to replace

  declare -A opt
  opt=(-a AAA -b BBB)
  zparseopts -K -A opt a: b:
  ... $opt[-a] ...

with

  declare -a opt_a opt_b
  opt_a=(-a AAA) opt_b=(-b BBB)
  zparseopts -K a:=opt_a b:=opt_b
  ... $opt_a[2] ...

} I am writing that based on the assumption that the normal usage
} would be to set the array to inital default values, and then simply
} overwrite only those values which were supplied on the command line.

Part of the original intention was that any elements in the array that
were NOT described by the optspecs would be erased.  However, as that
also only happens when at least one described option is parsed, it seems
plausible to abandon that side-effect as well.

I suspect I may have missed something with respect to multibyte and/or
(un)metafication in zalloc_default_array()?


diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo
index 726b0f0..ee9ec3a 100644
--- a/Doc/Zsh/mod_zutil.yo
+++ b/Doc/Zsh/mod_zutil.yo
@@ -251,10 +251,12 @@ any not described by the var(specs).  This is similar to using the tt(shift)
 builtin.
 )
 item(tt(-K))(
-With this option, the arrays specified with the tt(-a) and tt(-A)
-options and with the `tt(=)var(array)' forms are kept unchanged when none
-of the var(specs) for them is used.  This allows assignment of default
-values to them before calling tt(zparseopts).
+With this option, the arrays specified with the tt(-a) option and with the
+`tt(=)var(array)' forms are kept unchanged when none of the var(specs) for
+them is used.  Otherwise the entire array is replaced when any of the
+var(specs) is used.  Individual elements of associative arrays specified
+with the tt(-A) option are preserved by tt(-K).  This allows assignment of
+default values to arrays before calling tt(zparseopts).
 )
 item(tt(-M))(
 This changes the assignment rules to implement a map among equivalent
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 399c45f..46b29f2 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -1543,6 +1543,45 @@ add_opt_val(Zoptdesc d, char *arg)
     }
 }
 
+/*
+ * For "zparseopts -K -A assoc ..." this function copies the keys and
+ * values from the default and allocates the extra space for any parsed
+ * values having the same keys.  If there are no new values, creates an
+ * empty array.  Returns a pointer to the NULL element marking the end.
+ *
+ *  aval = pointer to the newly allocated array
+ *  assoc = name of the default hash param to copy
+ *  keep = whether we need to make the copy at all
+ *  num = count of new values to add space for
+ */
+static char **
+zalloc_default_array(char ***aval, char *assoc, int keep, int num)
+{
+    char **ap = 0;
+
+    *aval = 0;
+    if (keep && num) {
+	struct value vbuf;
+	Value v = fetchvalue(&vbuf, &assoc, 0,
+			     SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
+	if (v && v->isarr) {
+	    char **dp, **dval = getarrvalue(v);
+	    int dnum = (dval ? arrlen(dval) : 0) + 1;
+	    *aval = (char **) zalloc(((num * 2) + dnum) * sizeof(char *));
+	    for (ap = *aval, dp = dval; dp && *dp; dp++) {
+		*ap = (char *) zalloc(strlen(*dp) + 1);
+		strcpy(*ap++, *dp);
+	    }
+	    *ap = NULL;
+	}
+    }
+    if (!ap) {
+	ap = *aval = (char **) zalloc(((num * 2) + 1) * sizeof(char *));
+	*ap = NULL;
+    }
+    return ap;
+}
+
 static int
 bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 {
@@ -1825,8 +1864,8 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		num++;
 
 	if (!keep || num) {
-	    aval = (char **) zalloc(((num * 2) + 1) * sizeof(char *));
-	    for (ap = aval, d = opt_descs; d; d = d->next) {
+	    ap = zalloc_default_array(&aval, assoc, keep, num);
+	    for (d = opt_descs; d; d = d->next) {
 		if (d->vals) {
 		    *ap++ = n = (char *) zalloc(strlen(d->name) + 2);
 		    *n = '-';


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH Re: zparseopts default associative array
  2014-02-15 21:15     ` PATCH Re: zparseopts default associative array Bart Schaefer
@ 2014-02-15 22:19       ` Peter Stephenson
  2014-02-15 22:56         ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Peter Stephenson @ 2014-02-15 22:19 UTC (permalink / raw)
  To: zsh-workers

Bart Schaefer wrote:
> I suspect I may have missed something with respect to multibyte and/or
> (un)metafication in zalloc_default_array()?

I don't see why, since this is internal manipulation with any conversion
from input or to output formats occurring elsewhere (unless I'm missing
something, I haven't looked through the surrounding context with any care).

pws


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH Re: zparseopts default associative array
  2014-02-15 22:19       ` Peter Stephenson
@ 2014-02-15 22:56         ` Bart Schaefer
  0 siblings, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 2014-02-15 22:56 UTC (permalink / raw)
  To: zsh-workers

On Feb 15, 10:19pm, Peter Stephenson wrote:
} Subject: Re: PATCH Re: zparseopts default associative array
}
} Bart Schaefer wrote:
} > I suspect I may have missed something with respect to multibyte and/or
} > (un)metafication in zalloc_default_array()?
} 
} I don't see why, since this is internal manipulation with any conversion
} from input or to output formats occurring elsewhere (unless I'm missing
} something, I haven't looked through the surrounding context with any care).

Well, the array is going to end up with a mix of stuff copied directly
from getarrvalue() and stuff copied from the argument linklist passed
to bin_zparseopts().  It occured to me that those might not be in the
same internal representation when not plain strings.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-02-15 22:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CABABwVH+Yu-oFiE8OYkmNHxRGSwfYT8331oA0=0s9quom3CTGA@mail.gmail.com>
     [not found] ` <140213085618.ZM26934@torch.brasslantern.com>
     [not found]   ` <20140214081434.1580@binki>
2014-02-15 21:15     ` PATCH Re: zparseopts default associative array Bart Schaefer
2014-02-15 22:19       ` Peter Stephenson
2014-02-15 22:56         ` Bart Schaefer

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).