From 956d35ef12a061ec41396b1e0469bd166f6ef007 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sat, 15 Feb 2014 13:49:26 -0800 Subject: 32388: zparseopts -K preserves individual associative array elements --- Src/Modules/zutil.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'Src/Modules/zutil.c') 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 = '-'; -- cgit v1.2.3 From 38be9fe84a884d44c30bbcea0595799882aff898 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sun, 9 Mar 2014 00:29:02 -0800 Subject: 32468: save/restore match/mbegin/mend when doing pattern lookups against zstyle contexts --- ChangeLog | 6 +++ Src/Modules/zutil.c | 116 +++++++++++++++++++++++++++------------------------- 2 files changed, 67 insertions(+), 55 deletions(-) (limited to 'Src/Modules/zutil.c') diff --git a/ChangeLog b/ChangeLog index 839e5af69..5aeacd26b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ +2014-03-09 Barton E. Schaefer + + * 32468: Src/Modules/zutil.c: save/restore match/mbegin/mend + when doing pattern lookups against zstyle contexts + 2014-03-03 Barton E. Schaefer * users/18550: Doc/Zsh/compsys.yo: matcher-list clarifications + 2014-03-03 Simon Ruderich * 32289: Doc: Add zsh version to footer in HTML documentation. diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 46b29f237..1cca0c4b8 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -30,6 +30,55 @@ #include "zutil.mdh" #include "zutil.pro" +typedef struct { + char **match; + char **mbegin; + char **mend; +} MatchData; + +static void +savematch(MatchData *m) +{ + char **a; + + queue_signals(); + a = getaparam("match"); + m->match = a ? zarrdup(a) : NULL; + a = getaparam("mbegin"); + m->mbegin = a ? zarrdup(a) : NULL; + a = getaparam("mend"); + m->mend = a ? zarrdup(a) : NULL; + unqueue_signals(); +} + +static void +restorematch(MatchData *m) +{ + if (m->match) + setaparam("match", m->match); + else + unsetparam("match"); + if (m->mbegin) + setaparam("mbegin", m->mbegin); + else + unsetparam("mbegin"); + if (m->mend) + setaparam("mend", m->mend); + else + unsetparam("mend"); +} + +static void +freematch(MatchData *m) +{ + if (m->match) + freearray(m->match); + if (m->mbegin) + freearray(m->mbegin); + if (m->mend) + freearray(m->mend); +} + /* Style stuff. */ typedef struct stypat *Stypat; @@ -370,15 +419,21 @@ lookupstyle(char *ctxt, char *style) { Style s; Stypat p; + char **found = NULL; s = (Style)zstyletab->getnode2(zstyletab, style); - if (!s) - return NULL; - for (p = s->pats; p; p = p->next) - if (pattry(p->prog, ctxt)) - return (p->eval ? evalstyle(p) : p->vals); + if (s) { + MatchData match; + savematch(&match); + for (p = s->pats; p; p = p->next) + if (pattry(p->prog, ctxt)) { + found = (p->eval ? evalstyle(p) : p->vals); + break; + } + restorematch(&match); + } - return NULL; + return found; } static int @@ -914,55 +969,6 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) /* Zregexparse stuff. */ -typedef struct { - char **match; - char **mbegin; - char **mend; -} MatchData; - -static void -savematch(MatchData *m) -{ - char **a; - - queue_signals(); - a = getaparam("match"); - m->match = a ? zarrdup(a) : NULL; - a = getaparam("mbegin"); - m->mbegin = a ? zarrdup(a) : NULL; - a = getaparam("mend"); - m->mend = a ? zarrdup(a) : NULL; - unqueue_signals(); -} - -static void -restorematch(MatchData *m) -{ - if (m->match) - setaparam("match", m->match); - else - unsetparam("match"); - if (m->mbegin) - setaparam("mbegin", m->mbegin); - else - unsetparam("mbegin"); - if (m->mend) - setaparam("mend", m->mend); - else - unsetparam("mend"); -} - -static void -freematch(MatchData *m) -{ - if (m->match) - freearray(m->match); - if (m->mbegin) - freearray(m->mbegin); - if (m->mend) - freearray(m->mend); -} - typedef struct { int cutoff; char *pattern; -- cgit v1.2.3