1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-03 10:21:46 +02:00

21045: fix some uses of Meta characters in completion

This commit is contained in:
Peter Stephenson 2005-03-21 18:58:28 +00:00
parent e222689ea1
commit 2a59e22f73
3 changed files with 884 additions and 349 deletions

View file

@ -1,3 +1,8 @@
2005-03-21 Peter Stephenson <pws@csr.com>
* 21045: Src/Zle/compcore.c, Src/Zle/complete.c: more places
where completion didn't handled Meta characters.
2005-03-16 Peter Stephenson <pws@csr.com>
* 20983: Test/D02glob.ztst, Src/glob.c: fixed string segments

File diff suppressed because it is too large Load diff

View file

@ -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,57 +1155,72 @@ 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);