summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/comp.h2
-rw-r--r--Src/Zle/compcore.c59
-rw-r--r--Src/Zle/complete.c21
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;
}