diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:18:42 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:18:42 +0000 |
commit | 7a0415cfd70a02b2280d27556c6c54cef1c86e1a (patch) | |
tree | 37a88a1c4611ee37f2a3209873fc9a34a2624587 /Src/Zle/compctl.c | |
parent | 904b939cbd81a542303da2c58288b95b153106f5 (diff) | |
download | zsh-7a0415cfd70a02b2280d27556c6c54cef1c86e1a.tar.gz zsh-7a0415cfd70a02b2280d27556c6c54cef1c86e1a.tar.xz zsh-7a0415cfd70a02b2280d27556c6c54cef1c86e1a.zip |
zsh-3.1.5-pws-11 zsh-3.1.5-pws-11
Diffstat (limited to 'Src/Zle/compctl.c')
-rw-r--r-- | Src/Zle/compctl.c | 260 |
1 files changed, 204 insertions, 56 deletions
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index f71d67510..b5c8e4b3f 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -140,7 +140,7 @@ get_gmatcher(char *name, char **argv) while (*argv) { if ((m = parse_cmatcher(name, *argv)) == pcm_err) return 2; - *q = n = (Cmlist) halloc(sizeof(struct cmlist)); + *q = n = (Cmlist) zhalloc(sizeof(struct cmlist)); n->next = NULL; n->matcher = m; n->str = *argv++; @@ -578,6 +578,19 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl) *argv = "" - 1; } break; + case 'i': + if ((*argv)[1]) { + cct.widget = (*argv) + 1; + *argv = "" - 1; + } else if (!argv[1]) { + zwarnnam(name, "function name expected after -%c", NULL, + **argv); + return 1; + } else { + cct.widget = *++argv; + *argv = "" - 1; + } + break; case 'Y': cct.mask |= CC_EXPANDEXPL; goto expl; @@ -1197,6 +1210,7 @@ cc_assign(char *name, Compctl *ccptr, Compctl cct, int reass) zsfree(cc->glob); zsfree(cc->str); zsfree(cc->func); + zsfree(cc->widget); zsfree(cc->explain); zsfree(cc->ylist); zsfree(cc->prefix); @@ -1217,6 +1231,7 @@ cc_assign(char *name, Compctl *ccptr, Compctl cct, int reass) cc->glob = ztrdup(cct->glob); cc->str = ztrdup(cct->str); cc->func = ztrdup(cct->func); + cc->widget = ztrdup(cct->widget); cc->explain = ztrdup(cct->explain); cc->ylist = ztrdup(cct->ylist); cc->prefix = ztrdup(cct->prefix); @@ -1423,6 +1438,7 @@ printcompctl(char *s, Compctl cc, int printflags, int ispat) printif(cc->gname, 'J'); printif(cc->keyvar, 'k'); printif(cc->func, 'K'); + printif(cc->widget, 'i'); printif(cc->explain, (cc->mask & CC_EXPANDEXPL) ? 'Y' : 'X'); printif(cc->ylist, 'y'); printif(cc->prefix, 'P'); @@ -1644,7 +1660,7 @@ bin_compctl(char *name, char **argv, char *ops, int func) /**/ static int -bin_complist(char *name, char **argv, char *ops, int func) +bin_compgen(char *name, char **argv, char *ops, int func) { Compctl cc; int ret = 0; @@ -1663,7 +1679,7 @@ bin_complist(char *name, char **argv, char *ops, int func) zerrnam(name, "command names illegal", NULL, 0); ret = 1; } else - makecomplistcallptr(cc); + ret = makecomplistcallptr(cc); freecompctl(cc); return ret; @@ -1677,7 +1693,7 @@ bin_compadd(char *name, char **argv, char *ops, int func) char *ipre = NULL, *ppre = NULL, *psuf = NULL, *prpre = NULL; char *pre = NULL, *suf = NULL, *group = NULL, *m = NULL, *rs = NULL; char *ign = NULL, *rf = NULL, *expl = NULL; - int f = 0, a = 0, dm; + int f = 0, a = CAF_MATCH, dm; Cmatcher match = NULL; if (incompfunc != 1) { @@ -1710,7 +1726,7 @@ bin_compadd(char *name, char **argv, char *ops, int func) f |= CMF_NOLIST; break; case 'U': - a |= CAF_MENU; + a &= ~CAF_MATCH; break; case 'P': sp = ⪯ @@ -1749,9 +1765,6 @@ bin_compadd(char *name, char **argv, char *ops, int func) case 'a': a |= CAF_ALT; break; - case 'm': - a |= CAF_MATCH; - break; case 'M': sp = &m; e = "matching specification expected after -%c"; @@ -1805,11 +1818,11 @@ bin_compadd(char *name, char **argv, char *ops, int func) return 1; match = cpcmatcher(match); - addmatchesptr(ipre, ppre, psuf, prpre, pre, suf, group, - rs, rf, ign, f, a, match, expl, argv); + a = addmatchesptr(ipre, ppre, psuf, prpre, pre, suf, group, + rs, rf, ign, f, a, match, expl, argv); freecmatcher(match); - return 0; + return a; } /**/ @@ -1824,34 +1837,54 @@ bin_compcall(char *name, char **argv, char *ops, int func) (ops['D'] ? 0 : CFN_DEFAULT)); } +/* Definitions for the special parameters. Note that these have to match the + * order of the CP_* bits in comp.h */ + #define VAR(X) ((void *) (&(X))) static struct compparam { char *name; int type; void *var; } compparams[] = { + { "words", PM_ARRAY, VAR(compwords) }, { "CURRENT", PM_INTEGER, VAR(compcurrent) }, - { "CONTEXT", PM_SCALAR, VAR(compcontext) }, - { "COMMAND", PM_SCALAR, VAR(compcommand) }, { "PREFIX", PM_SCALAR, VAR(compprefix) }, { "SUFFIX", PM_SCALAR, VAR(compsuffix) }, { "IPREFIX", PM_SCALAR, VAR(compiprefix) }, - { "NMATCHES", PM_INTEGER, VAR(compnmatches) }, - { "MATCHER", PM_INTEGER, VAR(compmatcher) }, + { NULL, 0, NULL }, + + { "nmatches", PM_INTEGER, VAR(compnmatches) }, + { "matcher", PM_INTEGER, VAR(compmatcher) }, + { "matcher_string", PM_SCALAR, VAR(compmatcherstr) }, + { "total_matchers", PM_INTEGER, VAR(compmatchertot) }, + { "context", PM_SCALAR, VAR(compcontext) }, + { "parameter", PM_SCALAR, VAR(compparameter) }, + { "redirect", PM_SCALAR, VAR(compredirect) }, + { "quote", PM_SCALAR, VAR(compquote) }, + { "quoting", PM_SCALAR, VAR(compquoting) }, + { "restore", PM_SCALAR, VAR(comprestore) }, + { "list", PM_SCALAR, VAR(complist) }, + { "insert", PM_SCALAR, VAR(compinsert) }, + { "exact", PM_SCALAR, VAR(compexact) }, + { "exact_string", PM_SCALAR, VAR(compexactstr) }, + { "pattern_match", PM_SCALAR, VAR(comppatmatch) }, { NULL, 0, NULL } }; -/**/ -void makecompparams(void) +#define COMPSTATENAME "compstate" + +static struct compparam * +addcompparams(struct compparam *cp) { - struct compparam *cp; + Param *pp = comppms + (cp - compparams); - for (cp = compparams; cp->name; cp++) { + for (; cp->name; cp++, pp++) { Param pm = createparam(cp->name, cp->type | PM_SPECIAL|PM_REMOVABLE); if (!pm) pm = (Param) paramtab->getnode(paramtab, cp->name); - DPUTS(!pm, "param not set in makecompparams"); + DPUTS(!pm, "param not set in addcompparams"); + *pp = pm; pm->level = locallevel; pm->u.data = cp->var; switch(PM_TYPE(cp->type)) { @@ -1862,18 +1895,115 @@ void makecompparams(void) case PM_INTEGER: pm->sets.ifn = intvarsetfn; pm->gets.ifn = intvargetfn; + pm->ct = 10; + break; + case PM_ARRAY: + pm->sets.afn = arrvarsetfn; + pm->gets.afn = arrvargetfn; break; } pm->unsetfn = compunsetfn; } + return cp; +} + +/**/ +void +makecompparams(void) +{ + struct compparam *cp; + Param cpm; + HashTable tht; + + cp = addcompparams(compparams); + + if (!(cpm = createparam(COMPSTATENAME, PM_SPECIAL|PM_REMOVABLE|PM_HASHED))) + cpm = (Param) paramtab->getnode(paramtab, COMPSTATENAME); + DPUTS(!cpm, "param not set in makecompparams"); + + comppms[cp - compparams] = cpm; + tht = paramtab; + cpm->level = locallevel; + cpm->gets.hfn = get_compstate; + cpm->sets.hfn = set_compstate; + cpm->unsetfn = compunsetfn; + cpm->u.hash = paramtab = newparamtable(17, COMPSTATENAME); + addcompparams(cp + 1); + paramtab = tht; +} + +/**/ +static HashTable +get_compstate(Param pm) +{ + return pm->u.hash; +} + +/**/ +static void +set_compstate(Param pm, HashTable ht) +{ + struct compparam *cp; + Param *pp; + HashNode hn; + int i; + struct value v; + char *str; + + for (i = 0; i < ht->hsize; i++) + for (hn = ht->nodes[i]; hn; hn = hn->next) + for (cp = compparams + CP_REALPARAMS, + pp = comppms + CP_REALPARAMS; cp->name; cp++, pp++) + if (!strcmp(hn->nam, cp->name)) { + v.isarr = v.inv = v.a = 0; + v.b = -1; + v.arr = NULL; + v.pm = (Param) hn; + if (cp->type == PM_INTEGER) + *((long *) cp->var) = getintvalue(&v); + else if ((str = getstrvalue(&v))) { + zsfree(*((char **) cp->var)); + *((char **) cp->var) = ztrdup(str); + } + (*pp)->flags &= ~PM_UNSET; + + break; + } } /**/ static void compunsetfn(Param pm, int exp) { - if (exp) - stdunsetfn(pm, exp); + if (exp) { + if (PM_TYPE(pm->flags) == PM_SCALAR) { + zsfree(*((char **) pm->u.data)); + *((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 *)); + } + pm->flags |= PM_UNSET; + } +} + +/**/ +void +comp_setunset(int set, int unset) +{ + Param *p; + + if (!comppms) + return; + + set &= CP_ALLMASK; + unset &= CP_ALLMASK; + for (p = comppms; set || unset; set >>= 1, unset >>= 1, p++) { + if (set & 1) + (*p)->flags &= ~PM_UNSET; + if (unset & 1) + (*p)->flags |= PM_UNSET; + } } /**/ @@ -1883,29 +2013,51 @@ comp_wrapper(List list, FuncWrap w, char *name) if (incompfunc != 1) return 1; else { - char *octxt, *ocmd, *opre, *osuf, *oipre; + char *orest, *opre, *osuf, *oipre, **owords; long ocur; - + int unset = 0, m, sm; + Param *pp; + + m = CP_WORDS | CP_CURRENT | CP_PREFIX | CP_SUFFIX | + CP_IPREFIX | CP_RESTORE; + for (pp = comppms, sm = 1; m; pp++, m >>= 1, sm <<= 1) { + if ((m & 1) && ((*pp)->flags & PM_UNSET)) + unset |= sm; + } + orest = comprestore; + comprestore = ztrdup("auto"); ocur = compcurrent; - octxt = dupstring(compcontext); - ocmd = dupstring(compcommand); opre = dupstring(compprefix); osuf = dupstring(compsuffix); oipre = dupstring(compiprefix); + HEAPALLOC { + owords = arrdup(compwords); + } LASTALLOC; + runshfunc(list, w, name); - compcurrent = ocur; - zsfree(compcontext); - compcontext = ztrdup(octxt); - zsfree(compcommand); - compcommand = ztrdup(ocmd); - zsfree(compprefix); - compprefix = ztrdup(opre); - zsfree(compsuffix); - compsuffix = ztrdup(osuf); - zsfree(compiprefix); - compiprefix = ztrdup(oipre); + if (comprestore && !strcmp(comprestore, "auto")) { + compcurrent = ocur; + zsfree(compprefix); + compprefix = ztrdup(opre); + zsfree(compsuffix); + compsuffix = ztrdup(osuf); + zsfree(compiprefix); + compiprefix = ztrdup(oipre); + freearray(compwords); + PERMALLOC { + compwords = arrdup(owords); + } LASTALLOC; + comp_setunset(CP_COMPSTATE | + (~unset & (CP_WORDS | CP_CURRENT | CP_PREFIX | + CP_SUFFIX | CP_IPREFIX | CP_RESTORE)), + unset); + } else + comp_setunset(CP_COMPSTATE | (~unset & CP_RESTORE), + (unset & CP_RESTORE)); + zsfree(comprestore); + comprestore = orest; return 0; } @@ -1942,20 +2094,14 @@ comp_check(void) static void restrict_range(int b, int e) { - int i = e - b; + int i = e - b + 1; char **p = (char **) zcalloc((i + 1) * sizeof(char *)), **q, **pp; - for (q = p, pp = pparams + b + 1; i; i--, q++, pp++) + for (q = p, pp = compwords + b; i; i--, q++, pp++) *q = ztrdup(*pp); - zsfree(compcommand); - compcommand = ztrdup(pparams[b]); - freearray(pparams); - pparams = p; - zsfree(compcontext); - if ((compcurrent -= b + 1)) - compcontext = ztrdup("argument"); - else - compcontext = ztrdup("command"); + freearray(compwords); + compwords = p; + compcurrent -= b; } /**/ @@ -1988,7 +2134,7 @@ cond_position(char **a, int id) { if (comp_check()) { int b = cond_val(a, 0), e = (a[1] ? cond_val(a, 1) : b); - int l = arrlen(pparams), t, i = compcurrent - 1; + int l = arrlen(compwords), t, i = compcurrent - 1; if (b > 0) b--; @@ -2018,7 +2164,7 @@ cond_word(char **a, int id) { if (comp_check()) { int o = ((id & 2) ? compcurrent : 0) + cond_val(a, 0); - int l = arrlen(pparams); + int l = arrlen(compwords); char *s; if (o < 0) @@ -2028,7 +2174,7 @@ cond_word(char **a, int id) if (o < 0 || o >= l) return 0; - s = pparams[o]; + s = compwords[o]; return ((id & 1) ? cond_match(a, 1, s) : !strcmp(s, cond_str(a, 1))); } return 0; @@ -2068,7 +2214,7 @@ cond_words(char **a, int id) { if (comp_check()) { int b = cond_val(a, 0), e = (a[1] ? cond_val(a, 1) : -1); - int l = arrlen(pparams); + int l = arrlen(compwords); return (l >= b && l <= e); } @@ -2081,7 +2227,7 @@ cond_range(char **a, int id) { if (comp_check()) { char *s, **p; - int i, l = arrlen(pparams), t = 0, b = 0, e = l - 1; + int i, l = arrlen(compwords), t = 0, b = 0, e = l - 1; Comp c; i = compcurrent - 1; @@ -2095,7 +2241,7 @@ cond_range(char **a, int id) } else s = cond_str(a, 0); - for (i--, p = pparams + i; i >= 0; p--, i--) { + for (i--, p = compwords + i; i >= 0; p--, i--) { if (((id & 1) ? domatch(*p, c, 0) : !strcmp(*p, s))) { b = i + 1; t = 1; @@ -2112,7 +2258,7 @@ cond_range(char **a, int id) } else s = cond_str(a, 1); - for (i++, p = pparams + i; i < l; p++, i++) { + for (i++, p = compwords + i; i < l; p++, i++) { if (((id & 1) ? domatch(*p, c, 0) : !strcmp(*p, s))) { e = i - 1; tt = 1; @@ -2151,7 +2297,7 @@ cond_matcher(char **a, int id) static struct builtin bintab[] = { BUILTIN("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL), - BUILTIN("complist", 0, bin_complist, 1, -1, 0, NULL, NULL), + BUILTIN("compgen", 0, bin_compgen, 1, -1, 0, NULL, NULL), BUILTIN("compadd", 0, bin_compadd, 0, -1, 0, NULL, NULL), BUILTIN("compcall", 0, bin_compcall, 0, 0, 0, "TD", NULL), }; @@ -2185,6 +2331,7 @@ setup_compctl(Module m) { compctltab->printnode = printcompctlp; makecompparamsptr = makecompparams; + comp_setunsetptr = comp_setunset; return 0; } @@ -2217,6 +2364,7 @@ finish_compctl(Module m) { compctltab->printnode = NULL; makecompparamsptr = NULL; + comp_setunsetptr = NULL; return 0; } |