Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH Re: zparseopts default associative array
- X-seq: zsh-workers 32388
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: PATCH Re: zparseopts default associative array
- Date: Sat, 15 Feb 2014 13:15:18 -0800
- Cc: jdh <dhenman@xxxxxxxxx>
- In-reply-to: <20140214081434.1580@binki>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <CABABwVH+Yu-oFiE8OYkmNHxRGSwfYT8331oA0=0s9quom3CTGA@mail.gmail.com> <140213085618.ZM26934@torch.brasslantern.com> <20140214081434.1580@binki>
[Moving to zsh-workers]
On Feb 14, 8:14am, jdh wrote:
}
} Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> 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 = '-';
Messages sorted by:
Reverse Date,
Date,
Thread,
Author