diff options
Diffstat (limited to 'Src/Zle/complete.c')
-rw-r--r-- | Src/Zle/complete.c | 402 |
1 files changed, 280 insertions, 122 deletions
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index f625c34cd..d1f3366e7 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -33,16 +33,21 @@ /* global variables for shell parameters in new style completion */ /**/ -mod_export zlong compcurrent; +mod_export +zlong compcurrent, + complistmax; /**/ -zlong complistmax, - complistlines; +zlong complistlines, + compignored; /**/ mod_export char **compwords, + **compredirs, *compprefix, *compsuffix, + *complastprefix, + *complastsuffix, *compisuffix, *compqiprefix, *compqisuffix, @@ -181,66 +186,99 @@ parse_cmatcher(char *name, char *s) { Cmatcher ret = NULL, r = NULL, n; Cpattern line, word, left, right; - int fl, ll, wl, lal, ral, err; + int fl, fl2, ll, wl, lal, ral, err, both; if (!*s) return NULL; while (*s) { + lal = ral = both = fl2 = 0; + left = right = NULL; + while (*s && inblank(*s)) s++; if (!*s) break; switch (*s) { + case 'b': fl2 = CMF_INTER; case 'l': fl = CMF_LEFT; break; + case 'e': fl2 = CMF_INTER; case 'r': fl = CMF_RIGHT; break; case 'm': fl = 0; break; + case 'B': fl2 = CMF_INTER; case 'L': fl = CMF_LEFT | CMF_LINE; break; + case 'E': fl2 = CMF_INTER; case 'R': fl = CMF_RIGHT | CMF_LINE; break; case 'M': fl = CMF_LINE; break; default: - zwarnnam(name, "unknown match specification character `%c'", NULL, *s); + if (name) + zwarnnam(name, "unknown match specification character `%c'", + NULL, *s); return pcm_err; } if (s[1] != ':') { - zwarnnam(name, "missing `:'", NULL, 0); + if (name) + zwarnnam(name, "missing `:'", NULL, 0); return pcm_err; } s += 2; if (!*s) { - zwarnnam(name, "missing patterns", NULL, 0); + if (name) + zwarnnam(name, "missing patterns", NULL, 0); return pcm_err; } - if (fl & CMF_LEFT) { + if ((fl & CMF_LEFT) && !fl2) { left = parse_pattern(name, &s, &lal, '|', &err); if (err) return pcm_err; + + if ((both = (*s && s[1] == '|'))) + s++; + if (!*s || !*++s) { - zwarnnam(name, "missing line pattern", NULL, 0); + if (name) + zwarnnam(name, "missing line pattern", NULL, 0); return pcm_err; } } else left = NULL; - line = parse_pattern(name, &s, &ll, ((fl & CMF_RIGHT) ? '|' : '='), + line = parse_pattern(name, &s, &ll, + (((fl & CMF_RIGHT) && !fl2) ? '|' : '='), &err); if (err) return pcm_err; - if ((fl & CMF_RIGHT) && (!*s || !*++s)) { - zwarnnam(name, "missing right anchor", NULL, 0); - } else if (!(fl & CMF_RIGHT)) { + if (both) { + right = line; + ral = ll; + line = NULL; + ll = 0; + } + if ((fl & CMF_RIGHT) && !fl2 && (!*s || !*++s)) { + if (name) + zwarnnam(name, "missing right anchor", NULL, 0); + } else if (!(fl & CMF_RIGHT) || fl2) { if (!*s) { - zwarnnam(name, "missing word pattern", NULL, 0); + if (name) + zwarnnam(name, "missing word pattern", NULL, 0); return pcm_err; } s++; } - if (fl & CMF_RIGHT) { + if ((fl & CMF_RIGHT) && !fl2) { + if (*s == '|') { + left = line; + lal = ll; + line = NULL; + ll = 0; + s++; + } right = parse_pattern(name, &s, &ral, '=', &err); if (err) return pcm_err; if (!*s) { - zwarnnam(name, "missing word pattern", NULL, 0); + if (name) + zwarnnam(name, "missing word pattern", NULL, 0); return pcm_err; } s++; @@ -249,7 +287,8 @@ parse_cmatcher(char *name, char *s) if (*s == '*') { if (!(fl & (CMF_LEFT | CMF_RIGHT))) { - zwarnnam(name, "need anchor for `*'", NULL, 0); + if (name) + zwarnnam(name, "need anchor for `*'", NULL, 0); return pcm_err; } word = NULL; @@ -262,16 +301,18 @@ parse_cmatcher(char *name, char *s) word = parse_pattern(name, &s, &wl, 0, &err); if (!word && !line) { - zwarnnam(name, "need non-empty word or line pattern", NULL, 0); + if (name) + zwarnnam(name, "need non-empty word or line pattern", + NULL, 0); return pcm_err; } } if (err) return pcm_err; - n = (Cmatcher) zcalloc(sizeof(*ret)); + n = (Cmatcher) hcalloc(sizeof(*ret)); n->next = NULL; - n->flags = fl; + n->flags = fl | fl2; n->line = line; n->llen = ll; n->word = word; @@ -365,7 +406,7 @@ parse_class(Cpattern p, unsigned char *s, unsigned char e) n = !n; while (*s && (k || *s != e)) { - if (s[1] == '-' && s[2] != e) { + if (s[1] == '-' && s[2] && s[2] != e) { /* a run of characters */ for (j = (int) *s; j <= (int) s[2]; j++) p->tab[j] = (eq ? i++ : n); @@ -380,7 +421,7 @@ parse_class(Cpattern p, unsigned char *s, unsigned char e) /**/ static int -bin_compadd(char *name, char **argv, char *ops, int func) +bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) { struct cadata dat; char *p, **sp, *e, *m = NULL, *mstr = NULL; @@ -391,12 +432,13 @@ bin_compadd(char *name, char **argv, char *ops, int func) zwarnnam(name, "can only be called from completion function", NULL, 0); return 1; } - dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = + 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.match = NULL; dat.flags = 0; dat.aflags = CAF_MATCH; + dat.dummies = 0; for (; *argv && **argv == '-'; argv++) { if (!(*argv)[1]) { @@ -414,12 +456,21 @@ bin_compadd(char *name, char **argv, char *ops, int func) case 'Q': dat.aflags |= CAF_QUOTE; break; + case 'C': + dat.aflags |= CAF_ALL; + break; case 'f': dat.flags |= CMF_FILE; break; case 'e': dat.flags |= CMF_ISPAR; break; + case 'a': + dat.aflags |= CAF_ARRAYS; + break; + case 'k': + dat.aflags |= CAF_ARRAYS|CAF_KEYS; + break; case 'F': sp = &(dat.ign); e = "string expected after -%c"; @@ -476,9 +527,6 @@ bin_compadd(char *name, char **argv, char *ops, int func) sp = &(dat.prpre); e = "string expected after -%c"; break; - case 'a': - dat.aflags |= CAF_ALT; - break; case 'M': sp = &m; e = "matching specification expected after -%c"; @@ -488,6 +536,10 @@ bin_compadd(char *name, char **argv, char *ops, int func) sp = &(dat.exp); e = "string expected after -%c"; break; + case 'x': + sp = &(dat.mesg); + e = "string expected after -%c"; + break; case 'r': dat.flags |= CMF_REMOVE; sp = &(dat.rems); @@ -517,6 +569,23 @@ bin_compadd(char *name, char **argv, char *ops, int func) case 'l': dat.flags |= CMF_DISPLINE; break; + case 'E': + if (p[1]) { + dat.dummies = atoi(p + 1); + p = "" - 1; + } else if (argv[1]) { + argv++; + dat.dummies = atoi(*argv); + p = "" - 1; + } else { + zwarnnam(name, "number expected after -%c", NULL, *p); + return 1; + } + if (dat.dummies < 0) { + zwarnnam(name, "invalid number: %d", NULL, dat.dummies); + return 1; + } + break; case '-': argv++; goto ca_args; @@ -539,25 +608,28 @@ bin_compadd(char *name, char **argv, char *ops, int func) return 1; } if (dm) { - if (mstr) - mstr = tricat(mstr, " ", m); - else + if (mstr) { + char *tmp = tricat(mstr, " ", m); + zsfree(mstr); + mstr = tmp; + } else mstr = ztrdup(m); m = NULL; } } } } + + ca_args: + if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) { zsfree(mstr); return 1; } zsfree(mstr); - ca_args: - - if (!*argv && !dat.group && - !(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON))) + if (!*argv && !dat.group && !dat.mesg && + !(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL))) return 1; dat.match = match = cpcmatcher(match); @@ -635,7 +707,7 @@ restrict_range(int b, int e) e = wl; i = e - b + 1; - p = (char **) zcalloc((i + 1) * sizeof(char *)); + p = (char **) zshcalloc((i + 1) * sizeof(char *)); for (q = p, pp = compwords + b; i; i--, q++, pp++) *q = ztrdup(*pp); @@ -716,7 +788,7 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod) if (!na) return 1; if (na > 0 && - strlen(test == CVT_PRENUM ? compprefix : compsuffix) >= na) { + (int)strlen(test == CVT_PRENUM ? compprefix : compsuffix) >= na) { if (mod) { if (test == CVT_PRENUM) ignore_prefix(na); @@ -742,25 +814,39 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod) char *p, sav; if (!(l = strlen(compprefix))) - return 0; + return ((na == 1 || na == -1) && pattry(pp, compprefix)); if (na < 0) { p = compprefix + l; na = -na; add = -1; } else { p = compprefix + 1; + if (*p == Meta) + p++; add = 1; } - for (; l; l--, p += add) { + for (;;) { sav = *p; *p = '\0'; test = pattry(pp, compprefix); *p = sav; if (test && !--na) break; + if (add > 0) { + if (p == compprefix + l) + return 0; + if (*p == Meta) + p += 2; + else + p++; + } else { + if (p == compprefix) + return 0; + p--; + if (p > compprefix && p[-1] == Meta) + p--; + } } - if (!l) - return 0; if (mod) ignore_prefix(p - compprefix); } else { @@ -768,21 +854,37 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod) char *p; if (!(ol = l = strlen(compsuffix))) - return 0; + return ((na == 1 || na == -1) && pattry(pp, compsuffix)); if (na < 0) { p = compsuffix; na = -na; add = 1; } else { p = compsuffix + l - 1; + if (p > compsuffix && p[-1] == Meta) + p--; add = -1; } - for (; l; l--, p += add) + for (;;) { if (pattry(pp, p) && !--na) break; - if (!l) - return 0; + if (add > 0) { + if (p == compsuffix + l) + return 0; + if (*p == Meta) + p += 2; + else + p++; + } else { + if (p == compsuffix) + return 0; + p--; + if (p > compsuffix && p[-1] == Meta) + p--; + } + } + if (mod) ignore_suffix(ol - (p - compsuffix)); } @@ -794,7 +896,7 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod) /**/ static int -bin_compset(char *name, char **argv, char *ops, int func) +bin_compset(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) { int test = 0, na = 0, nb = 0; char *sa = NULL, *sb = NULL; @@ -871,51 +973,82 @@ bin_compset(char *name, char **argv, char *ops, int func) * order of the CP_* bits in comp.h */ #define VAL(X) ((void *) (&(X))) +#define GSU(X) ((GsuScalar)(void *) (&(X))) struct compparam { char *name; int type; - void *var, *set, *get; + void *var; + GsuScalar gsu; }; +static const struct gsu_scalar compvarscalar_gsu = +{ strvargetfn, strvarsetfn, compunsetfn }; +static const struct gsu_scalar complist_gsu = +{ get_complist, set_complist, compunsetfn }; +static const struct gsu_scalar unambig_gsu = +{ get_unambig, nullstrsetfn, compunsetfn }; +static const struct gsu_scalar unambig_pos_gsu = +{ get_unambig_pos, nullstrsetfn, compunsetfn }; +static const struct gsu_scalar insert_pos_gsu = +{ get_insert_pos, nullstrsetfn, compunsetfn }; + +static const struct gsu_integer compvarinteger_gsu = +{ intvargetfn, intvarsetfn, compunsetfn }; +static const struct gsu_integer nmatches_gsu = +{ get_nmatches, NULL, compunsetfn }; +static const struct gsu_integer unambig_curs_gsu = +{ get_unambig_curs, NULL, compunsetfn }; +static const struct gsu_integer listlines_gsu = +{ get_listlines, NULL, compunsetfn }; + +static const struct gsu_array compvararray_gsu = +{ arrvargetfn, arrvarsetfn, compunsetfn }; + + static struct compparam comprparams[] = { - { "words", PM_ARRAY, VAL(compwords), NULL, NULL }, - { "CURRENT", PM_INTEGER, VAL(compcurrent), NULL, NULL }, - { "PREFIX", PM_SCALAR, VAL(compprefix), NULL, NULL }, - { "SUFFIX", PM_SCALAR, VAL(compsuffix), NULL, NULL }, - { "IPREFIX", PM_SCALAR, VAL(compiprefix), NULL, NULL }, - { "ISUFFIX", PM_SCALAR, VAL(compisuffix), NULL, NULL }, - { "QIPREFIX", PM_SCALAR | PM_READONLY, VAL(compqiprefix), NULL, NULL }, - { "QISUFFIX", PM_SCALAR | PM_READONLY, VAL(compqisuffix), NULL, NULL }, - { NULL, 0, NULL, NULL, NULL } + { "words", PM_ARRAY, VAL(compwords), NULL }, + { "redirections", PM_ARRAY, VAL(compredirs), NULL }, + { "CURRENT", PM_INTEGER, VAL(compcurrent), NULL }, + { "PREFIX", PM_SCALAR, VAL(compprefix), NULL }, + { "SUFFIX", PM_SCALAR, VAL(compsuffix), NULL }, + { "IPREFIX", PM_SCALAR, VAL(compiprefix), NULL }, + { "ISUFFIX", PM_SCALAR, VAL(compisuffix), NULL }, + { "QIPREFIX", PM_SCALAR | PM_READONLY, VAL(compqiprefix), NULL }, + { "QISUFFIX", PM_SCALAR | PM_READONLY, VAL(compqisuffix), NULL }, + { NULL, 0, NULL, NULL } }; static struct compparam compkparams[] = { - { "nmatches", PM_INTEGER | PM_READONLY, NULL, NULL, VAL(get_nmatches) }, - { "context", PM_SCALAR, VAL(compcontext), NULL, NULL }, - { "parameter", PM_SCALAR, VAL(compparameter), NULL, NULL }, - { "redirect", PM_SCALAR, VAL(compredirect), NULL, NULL }, - { "quote", PM_SCALAR | PM_READONLY, VAL(compquote), NULL, NULL }, - { "quoting", PM_SCALAR | PM_READONLY, VAL(compquoting), NULL, NULL }, - { "restore", PM_SCALAR, VAL(comprestore), NULL, NULL }, - { "list", PM_SCALAR, NULL, VAL(set_complist), VAL(get_complist) }, - { "insert", PM_SCALAR, VAL(compinsert), NULL, NULL }, - { "exact", PM_SCALAR, VAL(compexact), NULL, NULL }, - { "exact_string", PM_SCALAR, VAL(compexactstr), NULL, NULL }, - { "pattern_match", PM_SCALAR, VAL(comppatmatch), NULL, NULL }, - { "pattern_insert", PM_SCALAR, VAL(comppatinsert), NULL, NULL }, - { "unambiguous", PM_SCALAR | PM_READONLY, NULL, NULL, VAL(get_unambig) }, - { "unambiguous_cursor", PM_INTEGER | PM_READONLY, NULL, NULL, - VAL(get_unambig_curs) }, - { "list_max", PM_INTEGER, VAL(complistmax), NULL, NULL }, - { "last_prompt", PM_SCALAR, VAL(complastprompt), NULL, NULL }, - { "to_end", PM_SCALAR, VAL(comptoend), NULL, NULL }, - { "old_list", PM_SCALAR, VAL(compoldlist), NULL, NULL }, - { "old_insert", PM_SCALAR, VAL(compoldins), NULL, NULL }, - { "vared", PM_SCALAR, VAL(compvared), NULL, NULL }, - { "alternate_nmatches", PM_INTEGER | PM_READONLY, NULL, NULL, VAL(get_anmatches) }, - { "list_lines", PM_INTEGER | PM_READONLY, NULL, NULL, VAL(get_listlines) }, - { "all_quotes", PM_SCALAR | PM_READONLY, VAL(compqstack), NULL, NULL }, - { NULL, 0, NULL, NULL, NULL } + { "nmatches", PM_INTEGER | PM_READONLY, NULL, GSU(nmatches_gsu) }, + { "context", PM_SCALAR, VAL(compcontext), NULL }, + { "parameter", PM_SCALAR, VAL(compparameter), NULL }, + { "redirect", PM_SCALAR, VAL(compredirect), NULL }, + { "quote", PM_SCALAR | PM_READONLY, VAL(compquote), NULL }, + { "quoting", PM_SCALAR | PM_READONLY, VAL(compquoting), NULL }, + { "restore", PM_SCALAR, VAL(comprestore), NULL }, + { "list", PM_SCALAR, NULL, GSU(complist_gsu) }, + { "insert", PM_SCALAR, VAL(compinsert), NULL }, + { "exact", PM_SCALAR, VAL(compexact), NULL }, + { "exact_string", PM_SCALAR, VAL(compexactstr), NULL }, + { "pattern_match", PM_SCALAR, VAL(comppatmatch), NULL }, + { "pattern_insert", PM_SCALAR, VAL(comppatinsert), NULL }, + { "unambiguous", PM_SCALAR | PM_READONLY, NULL, GSU(unambig_gsu) }, + { "unambiguous_cursor", PM_INTEGER | PM_READONLY, NULL, + GSU(unambig_curs_gsu) }, + { "unambiguous_positions", PM_SCALAR | PM_READONLY, NULL, + GSU(unambig_pos_gsu) }, + { "insert_positions", PM_SCALAR | PM_READONLY, NULL, + GSU(insert_pos_gsu) }, + { "list_max", PM_INTEGER, VAL(complistmax), NULL }, + { "last_prompt", PM_SCALAR, VAL(complastprompt), NULL }, + { "to_end", PM_SCALAR, VAL(comptoend), NULL }, + { "old_list", PM_SCALAR, VAL(compoldlist), NULL }, + { "old_insert", PM_SCALAR, VAL(compoldins), NULL }, + { "vared", PM_SCALAR, VAL(compvared), NULL }, + { "list_lines", PM_INTEGER | PM_READONLY, NULL, GSU(listlines_gsu) }, + { "all_quotes", PM_SCALAR | PM_READONLY, VAL(compqstack), NULL }, + { "ignored", PM_INTEGER | PM_READONLY, VAL(compignored), NULL }, + { NULL, 0, NULL, NULL } }; #define COMPSTATENAME "compstate" @@ -935,27 +1068,25 @@ addcompparams(struct compparam *cp, Param *pp) if ((pm->u.data = cp->var)) { switch(PM_TYPE(cp->type)) { case PM_SCALAR: - pm->sets.cfn = strvarsetfn; - pm->gets.cfn = strvargetfn; + pm->gsu.s = &compvarscalar_gsu; break; case PM_INTEGER: - pm->sets.ifn = intvarsetfn; - pm->gets.ifn = intvargetfn; - pm->ct = 10; + pm->gsu.i = &compvarinteger_gsu; + pm->base = 10; break; case PM_ARRAY: - pm->sets.afn = arrvarsetfn; - pm->gets.afn = arrvargetfn; + pm->gsu.a = &compvararray_gsu; break; } } else { - pm->sets.cfn = (void (*) _((Param, char *))) cp->set; - pm->gets.cfn = (char *(*) _((Param))) cp->get; + pm->gsu.s = cp->gsu; } - pm->unsetfn = compunsetfn; } } +static const struct gsu_hash compstate_gsu = +{ get_compstate, set_compstate, compunsetfn }; + /**/ void makecompparams(void) @@ -973,9 +1104,7 @@ makecompparams(void) comprpms[CPN_COMPSTATE] = cpm; tht = paramtab; cpm->level = locallevel + 1; - cpm->gets.hfn = get_compstate; - cpm->sets.hfn = set_compstate; - cpm->unsetfn = compunsetfn; + cpm->gsu.h = &compstate_gsu; cpm->u.hash = paramtab = newparamtable(31, COMPSTATENAME); addcompparams(compkparams, compkpms); paramtab = tht; @@ -990,7 +1119,7 @@ get_compstate(Param pm) /**/ static void -set_compstate(Param pm, HashTable ht) +set_compstate(UNUSED(Param pm), HashTable ht) { struct compparam *cp; Param *pp; @@ -999,13 +1128,16 @@ set_compstate(Param pm, HashTable ht) struct value v; char *str; + if (!ht) + return; + for (i = 0; i < ht->hsize; i++) for (hn = ht->nodes[i]; hn; hn = hn->next) for (cp = compkparams, pp = compkpms; cp->name; cp++, pp++) if (!strcmp(hn->nam, cp->name)) { - v.isarr = v.inv = v.a = 0; - v.b = -1; + v.isarr = v.inv = v.start = 0; + v.end = -1; v.arr = NULL; v.pm = (Param) hn; if (cp->type == PM_INTEGER) @@ -1023,58 +1155,73 @@ set_compstate(Param pm, HashTable ht) /**/ static zlong -get_nmatches(Param pm) +get_nmatches(UNUSED(Param pm)) { - return num_matches(1); + return (permmatches(0) ? 0 : nmatches); } /**/ static zlong -get_anmatches(Param pm) -{ - return num_matches(0); -} - -/**/ -static zlong -get_listlines(Param pm) +get_listlines(UNUSED(Param pm)) { return list_lines(); } /**/ static void -set_complist(Param pm, char *v) +set_complist(UNUSED(Param pm), char *v) { comp_list(v); } /**/ static char * -get_complist(Param pm) +get_complist(UNUSED(Param pm)) { return complist; } /**/ static char * -get_unambig(Param pm) +get_unambig(UNUSED(Param pm)) { - return unambig_data(NULL); + return unambig_data(NULL, NULL, NULL); } /**/ static zlong -get_unambig_curs(Param pm) +get_unambig_curs(UNUSED(Param pm)) { int c; - unambig_data(&c); + unambig_data(&c, NULL, NULL); return c; } /**/ +static char * +get_unambig_pos(UNUSED(Param pm)) +{ + char *p; + + unambig_data(NULL, &p, NULL); + + return p; +} + +/**/ +static char * +get_insert_pos(UNUSED(Param pm)) +{ + char *p; + + unambig_data(NULL, NULL, &p); + + return p; +} + +/**/ static void compunsetfn(Param pm, int exp) { @@ -1085,7 +1232,7 @@ compunsetfn(Param pm, int exp) *((char **) pm->u.data) = ztrdup(""); } else if (PM_TYPE(pm->flags) == PM_ARRAY) { freearray(*((char ***) pm->u.data)); - *((char ***) pm->u.data) = zcalloc(sizeof(char *)); + *((char ***) pm->u.data) = zshcalloc(sizeof(char *)); } else if (PM_TYPE(pm->flags) == PM_HASHED) { deleteparamtable(pm->u.hash); pm->u.hash = NULL; @@ -1148,13 +1295,13 @@ comp_wrapper(Eprog prog, FuncWrap w, char *name) if (incompfunc != 1) return 1; else { - char *orest, *opre, *osuf, *oipre, *oisuf, **owords; + char *orest, *opre, *osuf, *oipre, *oisuf, **owords, **oredirs; char *oqipre, *oqisuf, *oq, *oqi, *oqs, *oaq; zlong ocur; unsigned int runset = 0, kunset = 0, m, sm; Param *pp; - m = CP_WORDS | CP_CURRENT | CP_PREFIX | CP_SUFFIX | + m = CP_WORDS | CP_REDIRS | CP_CURRENT | CP_PREFIX | CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX | CP_QIPREFIX | CP_QISUFFIX; for (pp = comprpms, sm = 1; m; pp++, m >>= 1, sm <<= 1) { if ((m & 1) && ((*pp)->flags & PM_UNSET)) @@ -1176,6 +1323,7 @@ comp_wrapper(Eprog prog, FuncWrap w, char *name) oqs = ztrdup(compqstack); oaq = ztrdup(autoq); owords = zarrdup(compwords); + oredirs = zarrdup(compredirs); runshfunc(prog, w, name); @@ -1202,11 +1350,14 @@ comp_wrapper(Eprog prog, FuncWrap w, char *name) zsfree(autoq); autoq = oaq; freearray(compwords); + freearray(compredirs); compwords = owords; + compredirs = oredirs; comp_setunset(CP_COMPSTATE | - (~runset & (CP_WORDS | CP_CURRENT | CP_PREFIX | - CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX | - CP_QIPREFIX | CP_QISUFFIX)), + (~runset & (CP_WORDS | CP_REDIRS | + CP_CURRENT | CP_PREFIX | + CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX | + CP_QIPREFIX | CP_QISUFFIX)), (runset & CP_ALLREALS), (~kunset & CP_RESTORE), (kunset & CP_ALLKEYS)); } else { @@ -1223,6 +1374,7 @@ comp_wrapper(Eprog prog, FuncWrap w, char *name) zsfree(oqs); zsfree(oaq); freearray(owords); + freearray(oredirs); } zsfree(comprestore); comprestore = orest; @@ -1294,12 +1446,12 @@ struct hookdef comphooks[] = { /**/ int -setup_(Module m) +setup_(UNUSED(Module m)) { hasperm = 0; comprpms = compkpms = NULL; - compwords = NULL; + compwords = compredirs = NULL; compprefix = compsuffix = compiprefix = compisuffix = compqiprefix = compqisuffix = compcontext = compparameter = compredirect = compquote = @@ -1307,7 +1459,9 @@ setup_(Module m) compexact = compexactstr = comppatmatch = comppatinsert = complastprompt = comptoend = compoldlist = compoldins = compvared = compqstack = NULL; - + complastprefix = ztrdup(""); + complastsuffix = ztrdup(""); + complistmax = 0; hascompmod = 1; return 0; @@ -1352,12 +1506,16 @@ cleanup_(Module m) /**/ int -finish_(Module m) +finish_(UNUSED(Module m)) { if (compwords) freearray(compwords); + if (compredirs) + freearray(compredirs); zsfree(compprefix); zsfree(compsuffix); + zsfree(complastprefix); + zsfree(complastsuffix); zsfree(compiprefix); zsfree(compisuffix); zsfree(compqiprefix); |