summaryrefslogtreecommitdiff
path: root/Src/Modules
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2014-02-15 13:49:26 -0800
committerBarton E. Schaefer <schaefer@zsh.org>2014-02-15 13:49:26 -0800
commit956d35ef12a061ec41396b1e0469bd166f6ef007 (patch)
treec0c11543b53c91aadd6fcd4ab854cb902251508e /Src/Modules
parentae0b56cdda382732abc7c657e14f36a1e3d4d302 (diff)
downloadzsh-956d35ef12a061ec41396b1e0469bd166f6ef007.tar.gz
zsh-956d35ef12a061ec41396b1e0469bd166f6ef007.zip
32388: zparseopts -K preserves individual associative array elements
Diffstat (limited to 'Src/Modules')
-rw-r--r--Src/Modules/zutil.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 399c45f46..46b29f237 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 = '-';