diff options
author | Oliver Kiddle <opk@zsh.org> | 2021-10-30 23:27:29 +0200 |
---|---|---|
committer | Oliver Kiddle <opk@zsh.org> | 2021-10-30 23:35:04 +0200 |
commit | 632fee7cdfcd234a5c7c53f17777ca18e62d82e3 (patch) | |
tree | fca80472477f8a5a3ba75ab23e273d418decebb0 /Src/Zle | |
parent | 0b6e73d47736228a53e941d703ed902c4b915b3a (diff) | |
download | zsh-632fee7cdfcd234a5c7c53f17777ca18e62d82e3.tar.gz zsh-632fee7cdfcd234a5c7c53f17777ca18e62d82e3.tar.xz zsh-632fee7cdfcd234a5c7c53f17777ca18e62d82e3.zip |
49528: allow multiple -D options to compadd
Diffstat (limited to 'Src/Zle')
-rw-r--r-- | Src/Zle/comp.h | 2 | ||||
-rw-r--r-- | Src/Zle/compcore.c | 59 | ||||
-rw-r--r-- | Src/Zle/complete.c | 21 |
3 files changed, 60 insertions, 22 deletions
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index 2e3249b52..0c5fbd4f0 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -329,7 +329,7 @@ struct cadata { char *exp; /* explanation (-X) */ char *apar; /* array to store matches in (-A) */ char *opar; /* array to store originals in (-O) */ - char *dpar; /* array to delete non-matches in (-D) */ + char **dpar; /* arrays to delete non-matches in (-D) */ char *disp; /* array with display lists (-d) */ char *mesg; /* message to show unconditionally (-x) */ int dummies; /* add that many dummy matches */ diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 63136854e..2f3d53834 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -2081,10 +2081,10 @@ addmatches(Cadata dat, char **argv) /* ms: "match string" - string to use as completion. * Overloaded at one place as a temporary. */ char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL; - char **aign = NULL, **dparr = NULL, *oaq = autoq, *oppre = dat->ppre; + char **aign = NULL, ***dparr = NULL, *oaq = autoq, *oppre = dat->ppre; char *oqp = qipre, *oqs = qisuf, qc, **disp = NULL, *ibuf = NULL; char **arrays = NULL; - int lpl, lsl, bcp = 0, bcs = 0, bpadd = 0, bsadd = 0; + int dind, lpl, lsl, bcp = 0, bcs = 0, bpadd = 0, bsadd = 0; int ppl = 0, psl = 0, ilen = 0; int llpl = 0, llsl = 0, nm = mnum, gflags = 0, ohp = haspattern; int isexact, doadd, ois = instring, oib = inbackt; @@ -2092,7 +2092,7 @@ addmatches(Cadata dat, char **argv) struct cmlist mst; Cmlist oms = mstack; Patprog cp = NULL, *pign = NULL; - LinkList aparl = NULL, oparl = NULL, dparl = NULL; + LinkList aparl = NULL, oparl = NULL, *dparl = NULL; Brinfo bp, bpl = brbeg, obpl, bsl = brend, obsl; Heap oldheap; @@ -2186,11 +2186,24 @@ addmatches(Cadata dat, char **argv) if (dat->opar) oparl = newlinklist(); if (dat->dpar) { - if (*(dat->dpar) == '(') - dparr = NULL; - else if ((dparr = get_user_var(dat->dpar)) && !*dparr) - dparr = NULL; - dparl = newlinklist(); + int darr = 0, dparlen = arrlen(dat->dpar); + char **tail = dat->dpar + dparlen; + + dparr = (char ***)hcalloc((1 + dparlen) * sizeof(char **)); + dparl = (LinkList *)hcalloc((1 + dparlen) * sizeof(LinkList)); + queue_signals(); + while (darr < dparlen) { + if ((dparr[darr] = getaparam(dat->dpar[darr])) && *dparr[darr]) { + dparr[darr] = arrdup(dparr[darr]); + dparl[darr++] = newlinklist(); + } else { + /* swap in the last -D argument if we didn't get a non-empty array */ + dat->dpar[darr] = *--tail; + *tail = NULL; + --dparlen; + } + } + unqueue_signals(); } /* Store the matcher in our stack of matchers. */ if (dat->match) { @@ -2507,8 +2520,10 @@ addmatches(Cadata dat, char **argv) } if (!addit) { compignored++; - if (dparr && !*++dparr) - dparr = NULL; + for (dind = 0; dparl && dparl[dind]; dind++) { + if (dparr[dind] && !*++dparr[dind]) + dparr[dind] = NULL; + } goto next_array; } } @@ -2525,8 +2540,10 @@ addmatches(Cadata dat, char **argv) !(dat->flags & CMF_FILE) ? 1 : 2) : 0), &bpl, bcp, &bsl, bcs, &isexact))) { - if (dparr && !*++dparr) - dparr = NULL; + for (dind = 0; dparl && dparl[dind]; dind++) { + if (dparr[dind] && !*++dparr[dind]) + dparr[dind] = NULL; + } goto next_array; } if (doadd) { @@ -2553,10 +2570,14 @@ addmatches(Cadata dat, char **argv) addlinknode(aparl, ms); if (dat->opar) addlinknode(oparl, s); - if (dat->dpar && dparr) { - addlinknode(dparl, *dparr); - if (!*++dparr) - dparr = NULL; + if (dat->dpar) { + for (dind = 0; dparl[dind]; dind++) { + if (dparr[dind]) { + addlinknode(dparl[dind], *dparr[dind]); + if (!*++dparr[dind]) + dparr[dind] = NULL; + } + } } free_cline(lc); } @@ -2584,8 +2605,10 @@ addmatches(Cadata dat, char **argv) set_list_array(dat->apar, aparl); if (dat->opar) set_list_array(dat->opar, oparl); - if (dat->dpar) - set_list_array(dat->dpar, dparl); + if (dat->dpar) { + for (dind = 0; dparl[dind]; dind++) + set_list_array(dat->dpar[dind], dparl[dind]); + } if (dat->exp) addexpl(0); if (!hasallmatch && (dat->aflags & CAF_ALL)) { diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index 71d114de9..67a60963e 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -607,6 +607,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) char *oarg = NULL; /* argument of -o option */ int added; /* return value */ Cmatcher match = NULL; + size_t dparlen = 0, dparsize = 0; /* no. of -D options and array size */ if (incompfunc != 1) { zwarnnam(name, "can only be called from completion function"); @@ -614,7 +615,8 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) } dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg = dat.pre = dat.suf = dat.group = dat.rems = dat.remf = dat.disp = - dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL; + dat.ign = dat.exp = dat.apar = dat.opar = NULL; + dat.dpar = NULL; dat.match = NULL; dat.flags = 0; dat.aflags = CAF_MATCH; @@ -741,7 +743,12 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) e = "parameter name expected after -%c"; break; case 'D': - sp = &(dat.dpar); + if (dparsize <= dparlen + 1) { + dparsize = (dparsize + 1) * 2; + dat.dpar = (char **)zrealloc(dat.dpar, sizeof(char *) * dparsize); + } + sp = dat.dpar + dparlen++; + *sp = dat.dpar[dparlen] = NULL; e = "parameter name expected after -%c"; break; case 'd': @@ -768,11 +775,13 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) } else { zwarnnam(name, "number expected after -%c", *p); zsfree(mstr); + zfree(dat.dpar, dparsize); return 1; } if (dat.dummies < 0) { zwarnnam(name, "invalid number: %d", dat.dummies); zsfree(mstr); + zfree(dat.dpar, dparsize); return 1; } break; @@ -782,6 +791,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) default: zwarnnam(name, "bad option: -%c", *p); zsfree(mstr); + zfree(dat.dpar, dparsize); return 1; } if (sp) { @@ -802,6 +812,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) /* Missing argument: argv[N] == "-X", argv[N+1] == NULL. */ zwarnnam(name, e, *p); zsfree(mstr); + zfree(dat.dpar, dparsize); return 1; } if (m) { @@ -820,17 +831,21 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) { zsfree(mstr); + zfree(dat.dpar, dparsize); return 1; } zsfree(mstr); if (!*argv && !dat.group && !dat.mesg && - !(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL))) + !(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL))) { + zfree(dat.dpar, dparsize); return 1; + } dat.match = match = cpcmatcher(match); added = addmatches(&dat, argv); freecmatcher(match); + zfree(dat.dpar, dparsize); return added; } |