From 7a0415cfd70a02b2280d27556c6c54cef1c86e1a Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Thu, 15 Apr 1999 18:18:42 +0000 Subject: zsh-3.1.5-pws-11 --- Src/Makefile.in | 15 +- Src/Zle/comp.h | 39 ++- Src/Zle/comp1.c | 57 +++- Src/Zle/comp1.export | 15 + Src/Zle/compctl.c | 260 ++++++++++---- Src/Zle/zle_hist.c | 6 +- Src/Zle/zle_main.c | 4 + Src/Zle/zle_misc.c | 6 +- Src/Zle/zle_params.c | 21 +- Src/Zle/zle_refresh.c | 8 +- Src/Zle/zle_tricky.c | 912 +++++++++++++++++++++++++++++++------------------- Src/Zle/zle_word.c | 2 +- Src/builtin.c | 12 +- Src/compat.c | 10 +- Src/glob.c | 4 +- Src/mem.c | 18 +- Src/params.c | 149 ++++++--- Src/subst.c | 4 +- Src/system.h | 2 +- Src/utils.c | 6 +- Src/zsh.export | 6 +- 21 files changed, 1037 insertions(+), 519 deletions(-) (limited to 'Src') diff --git a/Src/Makefile.in b/Src/Makefile.in index 1b5256e16..0babdf47b 100644 --- a/Src/Makefile.in +++ b/Src/Makefile.in @@ -112,8 +112,10 @@ FORCE: # ========== LINKING IN MODULES ========== -modules-bltin: - if test @D@ = N; then \ +modules-bltin: Makefile + if test -f mymods.conf; then \ + cat mymods.conf > $@; \ + elif test @D@ = N; then \ cat $(sdir)/xmods.conf > $@; \ elif test @RTLD_GLOBAL_OK@ != yes; then \ echo comp1 > $@; \ @@ -175,18 +177,21 @@ uninstall.bin-L: # ========== DEPENDENCIES FOR CLEANUP ========== -@@clean.mk@@ +# Since module cleanup rules depend on Makemod, they come first. This +# forces module stuff to get cleaned before Makemod itself gets +# deleted. mostlyclean-here: rm -f stamp-modobjs stamp-modobjs.tmp clean-here: rm -f modules.index.tmp modules.stamp zsh ansi2knr.o ansi2knr + rm -f modules.index modules-bltin rm -f libzsh-*.$(DL_EXT) distclean-here: rm -f TAGS tags - rm -f modules.index modules-bltin Makefile + rm -f Makefile mymods.conf mostlyclean: mostlyclean-modules clean: clean-modules @@ -196,6 +201,8 @@ realclean: realclean-modules mostlyclean-modules clean-modules distclean-modules realclean-modules: Makemod @$(MAKE) -f Makemod $(MAKEDEFS) `echo $@ | sed 's/-modules//'` +@@clean.mk@@ + # ========== RECURSIVE MAKES ========== install.modules uninstall.modules \ diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index 76ac67114..d7f3610f1 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -103,6 +103,7 @@ struct compctl { char *glob; /* for -g (globbing) */ char *str; /* for -s (expansion) */ char *func; /* for -K (function) */ + char *widget; /* for -i (function) */ char *explain; /* for -X (explanation) */ char *ylist; /* for -y (user-defined desc. for listing) */ char *prefix, *suffix; /* for -P and -S (prefix, suffix) */ @@ -284,7 +285,37 @@ struct cline { /* Flags for compadd and addmatches(). */ #define CAF_QUOTE 1 -#define CAF_MENU 2 -#define CAF_NOSORT 4 -#define CAF_ALT 8 -#define CAF_MATCH 16 +#define CAF_NOSORT 2 +#define CAF_ALT 4 +#define CAF_MATCH 8 + +/* Flags for special parameters. */ + +#define CP_WORDS (1 << 0) +#define CP_CURRENT (1 << 1) +#define CP_PREFIX (1 << 2) +#define CP_SUFFIX (1 << 3) +#define CP_IPREFIX (1 << 4) +#define CP_COMPSTATE (1 << 5) + +#define CP_REALPARAMS 6 + +#define CP_NMATCHES (1 << 6) +#define CP_MATCHER (1 << 7) +#define CP_MATCHERSTR (1 << 8) +#define CP_MATCHERTOT (1 << 9) +#define CP_CONTEXT (1 << 10) +#define CP_PARAMETER (1 << 11) +#define CP_REDIRECT (1 << 12) +#define CP_QUOTE (1 << 13) +#define CP_QUOTING (1 << 14) +#define CP_RESTORE (1 << 15) +#define CP_LIST (1 << 16) +#define CP_INSERT (1 << 17) +#define CP_EXACT (1 << 18) +#define CP_EXACTSTR (1 << 19) +#define CP_PATMATCH (1 << 20) + +#define CP_NUM 21 + +#define CP_ALLMASK ((1 << CP_NUM) - 1) diff --git a/Src/Zle/comp1.c b/Src/Zle/comp1.c index 72f3cea53..ccccf5a34 100644 --- a/Src/Zle/comp1.c +++ b/Src/Zle/comp1.c @@ -46,10 +46,13 @@ Cmlist cmatcher; /**/ void (*makecompparamsptr) _((void)); +/**/ +void (*comp_setunsetptr) _((int, int)); + /* pointers to functions required by compctl and defined by zle */ /**/ -void (*addmatchesptr) _((char *, char *, char *, char *, char *, char *, char *, char *, char *, char *, int, int, Cmatcher, char *, char **)); +int (*addmatchesptr) _((char *, char *, char *, char *, char *, char *, char *, char *, char *, char *, int, int, Cmatcher, char *, char **)); /**/ char *(*comp_strptr) _((int*, int*, int)); @@ -58,7 +61,7 @@ char *(*comp_strptr) _((int*, int*, int)); int (*getcpatptr) _((char *, int, char *, int)); /**/ -void (*makecomplistcallptr) _((Compctl)); +int (*makecomplistcallptr) _((Compctl)); /**/ int (*makecomplistctlptr) _((int)); @@ -96,14 +99,29 @@ int incompfunc; /**/ long compcurrent, compnmatches, - compmatcher; + compmatcher, + compmatchertot; /**/ -char *compcontext, - *compcommand, +char **compwords, *compprefix, *compsuffix, - *compiprefix; + *compiprefix, + *compmatcherstr, + *compcontext, + *compparameter, + *compredirect, + *compquote, + *compquoting, + *comprestore, + *complist, + *compinsert, + *compexact, + *compexactstr, + *comppatmatch; + +/**/ +Param *comppms; /* The function rembslash() came from zle_tricky.c, but is now used * * in compctl.c, too. */ @@ -154,6 +172,7 @@ freecompctl(Compctl cc) zsfree(cc->glob); zsfree(cc->str); zsfree(cc->func); + zsfree(cc->widget); zsfree(cc->explain); zsfree(cc->ylist); zsfree(cc->prefix); @@ -408,9 +427,14 @@ setup_comp1(Module m) cc_first.refc = 10000; cc_first.mask = 0; cc_first.mask2 = CC_CCCONT; - compcontext = compcommand = compprefix = compsuffix = - compiprefix = NULL; + comppms = NULL; + compwords = NULL; + compprefix = compsuffix = compiprefix = compmatcherstr = + compcontext = compparameter = compredirect = compquote = + compquoting = comprestore = complist = compinsert = + compexact = compexactstr = comppatmatch = NULL; makecompparamsptr = NULL; + comp_setunsetptr = NULL; return 0; } @@ -437,11 +461,22 @@ finish_comp1(Module m) deletehashtable(compctltab); zfree(clwords, clwsize * sizeof(char *)); compctlreadptr = fallback_compctlread; - zsfree(compcontext); - zsfree(compcommand); + freearray(compwords); zsfree(compprefix); - zsfree(compiprefix); zsfree(compsuffix); + zsfree(compiprefix); + zsfree(compmatcherstr); + zsfree(compcontext); + zsfree(compparameter); + zsfree(compredirect); + zsfree(compquote); + zsfree(compquoting); + zsfree(comprestore); + zsfree(complist); + zsfree(compinsert); + zsfree(compexact); + zsfree(compexactstr); + zsfree(comppatmatch); return 0; } diff --git a/Src/Zle/comp1.export b/Src/Zle/comp1.export index 278006b6a..35b63e7d3 100644 --- a/Src/Zle/comp1.export +++ b/Src/Zle/comp1.export @@ -13,12 +13,27 @@ compcommand compcontext compctltab compcurrent +compexact +compexactstr +compinsert compiprefix +complist compmatcher +compmatcherstr +compmatchertot compnmatches +compparameter +comppatmatch +comppms compprefix +compredirect +compquote +compquoting +comprestore +comp_setunsetptr comp_strptr compsuffix +compwords freecmatcher freecmlist freecompcond 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; } diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c index a4b3866e5..2def5f03a 100644 --- a/Src/Zle/zle_hist.c +++ b/Src/Zle/zle_hist.c @@ -653,7 +653,7 @@ get_isrch_spot(int num, int *hlp, int *posp, int *csp, int *lenp, int *dirp, int static void doisearch(int dir) { - char *s, *ibuf = halloc(80), *sbuf = ibuf + FIRST_SEARCH_CHAR; + char *s, *ibuf = zhalloc(80), *sbuf = ibuf + FIRST_SEARCH_CHAR; int sbptr = 0, top_spot = 0, pos, sibuf = 80; int nomatch = 0, skip_line = 0, skip_pos = 0; int odir = dir, sens = zmult == 1 ? 3 : 1; @@ -936,7 +936,7 @@ static int visrchsense; static int getvisrchstr(void) { - char *sbuf = halloc(80); + char *sbuf = zhalloc(80); int sptr = 1, ret = 0, ssbuf = 80; Thingy cmd; char *okeymap = curkeymapname; @@ -1001,7 +1001,7 @@ getvisrchstr(void) } ins: if(sptr == ssbuf - 1) { - char *newbuf = halloc(ssbuf *= 2); + char *newbuf = zhalloc(ssbuf *= 2); strcpy(newbuf, sbuf); statusline = sbuf = newbuf; } diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 277d154a6..97d012f7b 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -154,10 +154,14 @@ zsetterm(void) # ifdef OXTABS ti.tio.c_oflag &= ~OXTABS; # else +# ifdef XTABS ti.tio.c_oflag &= ~XTABS; +# endif # endif # endif +#ifdef ONLCR ti.tio.c_oflag |= ONLCR; +#endif ti.tio.c_cc[VQUIT] = # ifdef VDISCARD ti.tio.c_cc[VDISCARD] = diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index ea8874010..1c25cd7eb 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -567,7 +567,7 @@ makequote(char *str, size_t *len) if (*l == '\'') qtct++; *len += 2 + qtct*3; - l = ol = (char *)halloc(*len); + l = ol = (char *)zhalloc(*len); *l++ = '\''; for (; str < end; str++) if (*str == '\'') { @@ -613,7 +613,7 @@ executenamedcommand(char *prmt) char *okeymap = curkeymapname; clearlist = 1; - cmdbuf = halloc(l + NAMLEN + 2); + cmdbuf = zhalloc(l + NAMLEN + 2); strcpy(cmdbuf, prmt); statusline = cmdbuf; selectkeymap("main", 1); @@ -794,7 +794,7 @@ makeparamsuffix(int br, int n) if(br) { suffixlen['#'] = suffixlen['%'] = suffixlen['?'] = n; suffixlen['-'] = suffixlen['+'] = suffixlen['='] = n; - /*{*/ suffixlen['}'] = n; + /*{*/ suffixlen['}'] = suffixlen['/'] = n; } } diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index 7e15d3d8b..2a35ac416 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -67,6 +67,8 @@ static struct zleparam { zleunsetfn, NULL }, { "keys", PM_ARRAY | PM_READONLY, NULL, FN(get_keys), zleunsetfn, NULL }, + { "NUMERIC", PM_INTEGER | PM_READONLY, FN(set_numeric), FN(get_numeric), + zleunsetfn, NULL }, { NULL, 0, NULL, NULL, NULL, NULL } }; @@ -97,6 +99,7 @@ makezleparams(int ro) case PM_INTEGER: pm->sets.ifn = (void (*) _((Param, long))) zp->setfn; pm->gets.ifn = (long (*) _((Param))) zp->getfn; + pm->ct = 10; break; } pm->unsetfn = zp->unsetfn; @@ -225,9 +228,9 @@ get_keys(Param pm) { char **r, **q, *p, *k, c; - r = (char **) halloc((strlen(keybuf) + 1) * sizeof(char *)); + r = (char **) zhalloc((strlen(keybuf) + 1) * sizeof(char *)); for (q = r, p = keybuf; (c = *p); q++, p++) { - k = *q = (char *) halloc(5); + k = *q = (char *) zhalloc(5); if (c & 0x80) { *k++ = 'M'; *k++ = '-'; @@ -244,3 +247,17 @@ get_keys(Param pm) return r; } + +/**/ +static void +set_numeric(Param pm, long x) +{ + zmult = x; +} + +/**/ +static long +get_numeric(Param pm) +{ + return zmult; +} diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 9e07676e8..b9f39b70b 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -266,7 +266,11 @@ zrefresh(void) /* Nov 96: I haven't checked how complete this is. sgtty stuff may or may not work */ +#if defined(SGTABTYPE) oxtabs = ((SGTTYFLAG & SGTABTYPE) == SGTABTYPE); +#else + oxtabs = 0; +#endif cleareol = 0; /* unset */ more_start = more_end = 0; /* unset */ @@ -615,7 +619,7 @@ refreshline(int ln) if (cleareol /* request to clear to end of line */ || !nllen /* no line buffer given */ || (ln == 0 && (put_rpmpt != oput_rpmpt))) { /* prompt changed */ - p1 = halloc(winw + 2); + p1 = zhalloc(winw + 2); if (nllen) strncpy(p1, nl, nllen); memset(p1 + nllen, ' ', winw - nllen); @@ -627,7 +631,7 @@ refreshline(int ln) nl = p1; /* don't keep the padding for prompt line */ nllen = winw; } else if (ollen > nllen) { /* make new line at least as long as old */ - p1 = halloc(ollen + 1); + p1 = zhalloc(ollen + 1); strncpy(p1, nl, nllen); memset(p1 + nllen, ' ', ollen - nllen); p1[ollen] = '\0'; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 4b42640e1..f01ffbf1c 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -73,9 +73,10 @@ static int wb, we; static int offs; /* These control the type of completion that will be done. They are * - * affected by the choice of ZLE command and by relevant shell options. */ + * affected by the choice of ZLE command and by relevant shell options. * + * usemenu is set to 2 if we have to start automenu. */ -static int usemenu, useglob; +static int usemenu, useglob, useexact, useline, uselist; /* != 0 if we are in the middle of a menu completion */ @@ -125,7 +126,7 @@ static int validlist; /* This flag is non-zero if we are completing a pattern (with globcomplete) */ -static int ispattern; +static int ispattern, haspattern; /* Two patterns used when doing glob-completion. The first one is built * * from the whole word we are completing and the second one from that * @@ -168,12 +169,6 @@ static int addwhat; static char *qword; -/* This is non-zero if we are doing a menu-completion and this is not the * - * first call (e.g. when automenu is set and menu-completion was entered * - * due to this). */ - -static int amenu; - /* The current group of matches. */ static Cmgroup mgroup; @@ -322,7 +317,7 @@ completecall(void) void completeword(void) { - usemenu = isset(MENUCOMPLETE); + usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); if (c == '\t' && usetab()) selfinsert(); @@ -351,7 +346,7 @@ menucomplete(void) void listchoices(void) { - usemenu = isset(MENUCOMPLETE); + usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); docomplete(COMP_LIST_COMPLETE); } @@ -371,7 +366,7 @@ deletecharorlist(void) Cmgroup mg = menugrp; Cmatch *mc = menucur; - usemenu = isset(MENUCOMPLETE); + usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); if (cs != ll) { fixsuffix(); @@ -398,7 +393,7 @@ expandword(void) void expandorcomplete(void) { - usemenu = isset(MENUCOMPLETE); + usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); if (c == '\t' && usetab()) selfinsert(); @@ -427,7 +422,7 @@ menuexpandorcomplete(void) void listexpand(void) { - usemenu = isset(MENUCOMPLETE); + usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); docomplete(COMP_LIST_EXPAND); } @@ -492,9 +487,9 @@ acceptandmenucomplete(void) } /* These are flags saying if we are completing in the command * - * position or in a redirection. */ + * position, in a redirection, or in a parameter expansion. */ -static int lincmd, linredir; +static int lincmd, linredir, ispar; /* The string for the redirection operator. */ @@ -513,10 +508,10 @@ static char *varname; static int insubscr; -/* 1 if we are completing in a string */ +/* 1 if we are completing in a quoted string (or inside `...`) */ /**/ -int instring; +int instring, inbackt; /* Convenience macro for calling bslashquote() (formerly quotename()). * * This uses the instring variable above. */ @@ -601,6 +596,87 @@ cmphaswilds(char *str) return 0; } +/* Check if we have to complete a parameter name. */ + +static char * +check_param(char *s, int set) +{ + char *p; + + ispar = 0; + /* Try to find a `$'. */ + for (p = s + offs; p > s && *p != String; p--); + if (*p == String) { + /* Handle $$'s */ + while (p > s && p[-1] == String) + p--; + while (p[1] == String && p[2] == String) + p += 2; + } + if (*p == String && p[1] != Inpar && p[1] != Inbrack) { + /* This is really a parameter expression (not $(...) or $[...]). */ + char *b = p + 1, *e = b; + int n = 0, br = 1; + + if (*b == Inbrace) { + /* If this is a ${...}, ignore the possible (...) flags. */ + b++, br++; + n = skipparens(Inpar, Outpar, &b); + } + + /* Ignore the stuff before the parameter name. */ + for (; *b; b++) + if (*b != '^' && *b != Hat && + *b != '=' && *b != Equals && + *b != '~' && *b != Tilde) + break; + if (*b == '#' || *b == Pound || *b == '+') + b++; + + e = b; + /* Find the end of the name. */ + if (*e == Quest || *e == Star || *e == String || *e == Qstring || + *e == '?' || *e == '*' || *e == '$' || + *e == '-' || *e == '!' || *e == '@') + e++; + else if (idigit(*e)) + while (idigit(*e)) + e++; + else if (iident(*e)) + while (iident(*e) || + (comppatmatch && *comppatmatch && + (*e == Star || *e == Quest))) + e++; + + /* Now make sure that the cursor is inside the name. */ + if (offs <= e - s && offs >= b - s && n <= 0) { + /* It is. */ + /* If we were called from makecomplistflags(), we have to set the + * global variables. */ + if (set) { + if (br >= 2) + mflags |= CMF_PARBR; + + /* Get the prefix (anything up to the character before the name). */ + lpsuf = dupstring(quotename(e, NULL, NULL, NULL)); + *e = '\0'; + lpsl = strlen(lpsuf); + ripre = dupstring(s); + ripre[b - s] = '\0'; + ipre = dupstring(quotename(ripre, NULL, NULL, NULL)); + untokenize(ipre); + } + /* And adjust wb, we, and offs again. */ + offs -= b - s; + wb = cs - offs; + we = wb + e - b; + ispar = (br >= 2 ? 2 : 1); + return b; + } + } + return NULL; +} + /* The main entry point for completion. */ /**/ @@ -625,9 +701,9 @@ docomplete(int lst) /* Check if we have to start a menu-completion (via automenu). */ - if ((amenu = (isset(AUTOMENU) && lastambig && - (!isset(BASHAUTOLIST) || lastambig == 2)))) - usemenu = 1; + if (isset(AUTOMENU) && lastambig && + (!isset(BASHAUTOLIST) || lastambig == 2)) + usemenu = 2; /* Expand history references before starting completion. If anything * * changed, do no more. */ @@ -910,7 +986,7 @@ addx(char **ptmp) (instring && (line[cs] == '"' || line[cs] == '\'')) || (addspace = (comppref && !iblank(line[cs])))) { *ptmp = (char *)line; - line = (unsigned char *)halloc(strlen((char *)line) + 3 + addspace); + line = (unsigned char *)zhalloc(strlen((char *)line) + 3 + addspace); memcpy(line, *ptmp, cs); line[cs] = 'x'; if (addspace) @@ -999,6 +1075,7 @@ get_comp_string(void) else if (*p == '\\' && p[1] && !(k & 1)) p++; instring = (j & 1) ? 2 : (k & 1); + inbackt = (i & 1); addx(&tmp); if (instring) { /* Yes, we are in a string. */ @@ -1010,7 +1087,7 @@ get_comp_string(void) * What?? Why that?? Well, we want to be able to complete * * inside strings. The lexer code gives us no help here, * * so we have to cheat. We remove the quotes, the lexer * - * will than treat the words in the strings normally and we * + * will then treat the words in the strings normally and we * * can complete them. * * This is completely the wrong thing to do, but it's * * occasionally useful, and we can't handle quotes properly * @@ -1551,7 +1628,7 @@ getcline(char *l, int ll, char *w, int wl, int fl) if ((r = freecl)) freecl = r->next; else - r = (Cline) halloc(sizeof(*r)); + r = (Cline) zhalloc(sizeof(*r)); r->next = NULL; r->line = l; @@ -1626,7 +1703,7 @@ add_bmatchers(Cmatcher m) for (; m; m = m->next) { if ((!m->flags && m->wlen > 0 && m->llen > 0) || (m->flags == CMF_RIGHT && m->wlen == -1 && !m->llen)) { - *q = n = (Cmlist) halloc(sizeof(struct cmlist)); + *q = n = (Cmlist) zhalloc(sizeof(struct cmlist)); n->matcher = m; q = &(n->next); } @@ -1796,7 +1873,7 @@ join_strs(int la, char *sa, int lb, char *sb) if (!t) break; } else { - if (rr <= mp->llen) { + if (rr <= 1) { char *or = rs; rs = realloc(rs, (rl += 20)); @@ -1850,7 +1927,7 @@ join_ends(Cline o, Cline n, int *olp, int *nlp) } else { /* Different anchors, see if we can find matching anchors * further down the lists. */ - Cline to, tn; + Cline to, tn = NULL; int t = 0; /* But first build the common prefix. */ @@ -3337,6 +3414,7 @@ match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp) } } while (ll && lw) { + t = 0; /* First try the matchers. */ for (ms = mstack; ms; ms = ms->next) { for (mp = ms->matcher; mp; mp = mp->next) { @@ -3578,6 +3656,7 @@ match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp) } } while (ll && lw) { + t = 0; for (ms = mstack; ms; ms = ms->next) { for (mp = ms->matcher; mp; mp = mp->next) { if (lm == mp) @@ -3774,7 +3853,7 @@ comp_match(char *pfx, char *sfx, char *w, Cline *clp, int qu, int *bpl, int *bsl * in the cline struct in the middle. */ pml = strlen(p); sml = strlen(s); - r = (char *) halloc(pml + sml + last->llen + 1); + r = (char *) zhalloc(pml + sml + last->llen + 1); strcpy(r, p); strncpy(r + pml, last->line, last->llen); strcpy(r + pml + last->llen, s); @@ -3824,7 +3903,7 @@ comp_match(char *pfx, char *sfx, char *w, Cline *clp, int qu, int *bpl, int *bsl static void inststrlen(char *str, int move, int len) { - if (!len) + if (!len || !str) return; if (len == -1) len = strlen(str); @@ -3902,30 +3981,28 @@ instmatch(Cmatch m) * the matches. */ /**/ -void +int addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, char *suf, char *group, char *rems, char *remf, char *ign, int flags, int aflags, Cmatcher match, char *exp, char **argv) { - char *s, *t, *e, *me, *ms, *lipre = NULL, *lpre, *lsuf, **aign = NULL; - int lpl, lsl, i, pl, sl, test, bpl, bsl, llpl, llsl; - Aminfo ai; + char *s, *t, *e, *me, *ms, *lipre = NULL, *lpre = NULL, *lsuf = NULL; + char **aign = NULL; + int lpl, lsl, i, pl, sl, test, bpl, bsl, llpl = 0, llsl = 0, nm = mnum; + Aminfo ai = NULL; Cline lc = NULL; - LinkList l; + LinkList l = NULL; Cmatch cm; struct cmlist mst; Cmlist oms = mstack; - - /* Use menu-completion (-U)? */ - if ((aflags & CAF_MENU) && isset(AUTOMENU)) - usemenu = 1; + Comp cp = NULL; /* Switch back to the heap that was used when the completion widget * was invoked. */ SWITCHHEAPS(compheap) { HEAPALLOC { if (exp) { - expl = (Cexpl) halloc(sizeof(struct cexpl)); + expl = (Cexpl) zhalloc(sizeof(struct cexpl)); expl->count = expl->fcount = 0; expl->str = dupstring(exp); } else @@ -3954,9 +4031,30 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, if (aflags & CAF_MATCH) { lipre = dupstring(compiprefix); lpre = dupstring(compprefix); - llpl = strlen(lpre); lsuf = dupstring(compsuffix); + llpl = strlen(lpre); llsl = strlen(lsuf); + /* Test if there is an existing -P prefix. */ + if (pre && *pre) { + pl = pfxlen(pre, lpre); + llpl -= pl; + lpre += pl; + } + if (comppatmatch && *comppatmatch) { + char *tmp = (char *) zhalloc(2 + llpl + llsl); + + strcpy(tmp, lpre); + tmp[llpl] = 'x'; + strcpy(tmp + llpl + 1, lsuf); + + tokenize(tmp); + remnulargs(tmp); + if (haswilds(tmp)) { + tmp[llpl] = Star; + if ((cp = parsereg(tmp))) + haspattern = 1; + } + } } /* Now duplicate the strings we have from the command line. */ if (ipre) @@ -3973,50 +4071,71 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, lsl = strlen(psuf); } else lsl = 0; - if (pre) - pre = dupstring(pre); - if (suf) - suf = dupstring(suf); - if (!prpre && (prpre = ppre)) { - singsub(&prpre); - untokenize(prpre); - } else - prpre = dupstring(prpre); - /* Select the group in which to store the matches. */ - if (group) { - endcmgroup(NULL); - begcmgroup(group, (aflags & CAF_NOSORT)); - if (aflags & CAF_NOSORT) - mgroup->flags |= CGF_NOSORT; - } else { - endcmgroup(NULL); - begcmgroup("default", 0); - } - /* Select the set of matches. */ - if (aflags & CAF_ALT) { - l = fmatches; - ai = fainfo; - } else { - l = matches; - ai = ainfo; + if (aflags & CAF_MATCH) { + s = ppre ? ppre : ""; + if (llpl <= lpl && strpfx(lpre, s)) { + llpl = 0; + lpre = ""; + } else if (llpl > lpl && strpfx(s, lpre)) { + llpl -= lpl; + lpre += lpl; + } else + *argv = NULL; + s = psuf ? psuf : ""; + if (llsl <= lsl && strsfx(lsuf, s)) { + llsl = 0; + lsuf = ""; + } else if (llsl > lsl && strsfx(s, lsuf)) { + lsuf[llsl - lsl] = '\0'; + llsl -= lsl; + } else + *argv = NULL; } - if (remf) { - remf = dupstring(remf); - rems = NULL; - } else if (rems) - rems = dupstring(rems); - /* Build the common -P prefix. */ - if (ai->pprefix) { + if (*argv) { if (pre) - ai->pprefix[pfxlen(ai->pprefix, pre)] = '\0'; - else - ai->pprefix[0] = '\0'; - } else - ai->pprefix = dupstring(pre ? pre : ""); - + pre = dupstring(pre); + if (suf) + suf = dupstring(suf); + if (!prpre && (prpre = ppre)) { + singsub(&prpre); + untokenize(prpre); + } else + prpre = dupstring(prpre); + /* Select the group in which to store the matches. */ + if (group) { + endcmgroup(NULL); + begcmgroup(group, (aflags & CAF_NOSORT)); + if (aflags & CAF_NOSORT) + mgroup->flags |= CGF_NOSORT; + } else { + endcmgroup(NULL); + begcmgroup("default", 0); + } + /* Select the set of matches. */ + if (aflags & CAF_ALT) { + l = fmatches; + ai = fainfo; + } else { + l = matches; + ai = ainfo; + } + if (remf) { + remf = dupstring(remf); + rems = NULL; + } else if (rems) + rems = dupstring(rems); + /* Build the common -P prefix. */ + if (ai->pprefix) { + if (pre) + ai->pprefix[pfxlen(ai->pprefix, pre)] = '\0'; + else + ai->pprefix[0] = '\0'; + } else + ai->pprefix = dupstring(pre ? pre : ""); + } /* Walk through the matches given. */ for (; (s = dupstring(*argv)); argv++) { - sl = strlen(s); + sl = pl = strlen(s); lc = NULL; ms = NULL; bpl = brpl; @@ -4042,19 +4161,26 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, } if (aflags & CAF_MATCH) { /* Do the matching. */ - test = (sl >= llpl + llsl && - strpfx(lpre, s) && strsfx(lsuf, s)); - if (!test && mstack && - (ms = comp_match(lpre, lsuf, s, - &lc, (aflags & CAF_QUOTE), - &bpl, &bsl))) - test = 1; - - if (!test) - continue; - pl = sl - llsl; - me = s + sl - llsl; - e = s + llpl; + if (cp) { + if ((test = domatch(s, cp, 0))) + e = me = s + sl; + else + continue; + } else { + test = (sl >= llpl + llsl && + strpfx(lpre, s) && strsfx(lsuf, s)); + if (!test && mstack && + (ms = comp_match(lpre, lsuf, s, + &lc, (aflags & CAF_QUOTE), + &bpl, &bsl))) + test = 1; + + if (!test) + continue; + pl = sl - llsl; + me = s + sl - llsl; + e = s + llpl; + } } else { e = s; me = s + sl; @@ -4072,14 +4198,15 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, if (!ms) { if (sl < ai->minlen) ai->minlen = sl; - if (!mstack && ai->firstm && + if (!cp && !mstack && ai->firstm && (i = sfxlen(ai->firstm->str, s)) < ai->suflen) ai->suflen = i; } t = s; if (ppre) t = dyncat(ppre, t); - if (!ms && mstack) { + lc = NULL; + if (!cp && !ms && (mstack || psuf)) { int bl = ((aflags & CAF_MATCH) ? llpl : 0); Cline *clp = &lc, tlc; char *ss = dupstring(s), *ee = me + (ss - s); @@ -4109,7 +4236,7 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, clp = &(tlc->next); } *clp = NULL; - } else if (mstack) { + } else if (!cp && mstack) { Cline tlc; if (ppre && *ppre) { @@ -4148,7 +4275,7 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, lc = tlc; } else ai->iprefix = ""; - if (!ms && !mstack) { + if (!ms && !mstack && !lc) { if ((aflags & CAF_MATCH) || ai->cpl > pl) ai->cpl = pl; if ((aflags & CAF_MATCH) || ai->csl > lsl) @@ -4164,12 +4291,12 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, ai->count++; /* Finally add the match. */ - cm = (Cmatch) halloc(sizeof(struct cmatch)); + cm = (Cmatch) zhalloc(sizeof(struct cmatch)); cm->ppre = ppre; cm->psuf = psuf; cm->prpre = prpre; cm->str = (ms ? ms : dupstring(s)); - cm->ipre = cm->ripre = ipre; + cm->ipre = cm->ripre = (ipre && *ipre ? ipre : NULL); cm->pre = pre; cm->suf = suf; cm->flags = flags; @@ -4179,7 +4306,7 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, cm->rems = rems; addlinknode(l, cm); - if (expl) { + if (exp) { if (l == matches) expl->count++; else @@ -4188,12 +4315,24 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, if (!ms) { if (!ai->firstm) ai->firstm = cm; - if ((aflags & CAF_MATCH) && !(e - (s + pl))) { - if (!ai->exact) + if (!cp && (aflags & CAF_MATCH) && !(e - (s + pl))) { + if (!ai->exact) { ai->exact = 1; - else { + zsfree(compexactstr); + compexactstr = e = (char *) zalloc(lpl + sl + lsl + 1); + if (ppre) { + strcpy(e, ppre); + e += lpl; + } + strcpy(e, s); + e += sl; + if (psuf) + strcpy(e, psuf); + comp_setunsetptr(CP_EXACTSTR, 0); + } else { ai->exact = 2; cm = NULL; + comp_setunsetptr(0, CP_EXACTSTR); } ai->exactm = cm; } @@ -4208,6 +4347,8 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, /* We switched back to the current heap, now restore the stack of * matchers. */ mstack = oms; + + return (mnum == nm); } /* This adds a match to the list of matches. The string to add is given * @@ -4252,6 +4393,7 @@ addmatch(char *s, char *t) if (incompfunc) s = dupstring(s); + e = s + sl; if (!addwhat) { test = 1; } else if (addwhat == -1 || addwhat == -5 || addwhat == -6 || @@ -4318,7 +4460,7 @@ addmatch(char *s, char *t) e += s - t; } if (cc) { - tt = (char *)halloc(lppl + lpsl + sl + 1); + tt = (char *)zhalloc(lppl + lpsl + sl + 1); tt[0] = '\0'; if (lppre) strcpy(tt, lppre); @@ -4353,7 +4495,7 @@ addmatch(char *s, char *t) (((addwhat & CC_DISCMDS) && (hn->flags & DISABLED)) || ((addwhat & CC_EXCMDS) && !(hn->flags & DISABLED)))) || ((addwhat & CC_BINDINGS) && !(hn->flags & DISABLED))))) { - if (sl >= rpl + rsl || mstack) { + if (sl >= rpl + rsl || mstack || cp) { if (cp) { test = domatch(s, patcomp, 0); e = s + sl; @@ -4413,7 +4555,7 @@ addmatch(char *s, char *t) t = s; if (lppre) t = dyncat(lppre, t); - if (!ms && mstack) { + if (!ispattern && !ms && mstack) { Cline *clp = &lc, tlc; char *ss = dupstring(s), *ee = e + (ss - s); @@ -4481,7 +4623,7 @@ addmatch(char *s, char *t) ai->count++; /* Allocate and fill the match structure. */ - cm = (Cmatch) halloc(sizeof(struct cmatch)); + cm = (Cmatch) zhalloc(sizeof(struct cmatch)); if (ispattern) { if (lpsuf && *lpsuf && strsfx(lpsuf, s)) { s[sl - lpsl] = '\0'; @@ -4532,11 +4674,29 @@ addmatch(char *s, char *t) /* Do we have an exact match? More than one? */ if (!ispattern && !(e - (s + pl))) { - if (!ai->exact) + if (!ai->exact) { ai->exact = 1; - else { + if (incompfunc) { + int lpl = (cm->ppre ? strlen(cm->ppre) : 0); + int lsl = (cm->psuf ? strlen(cm->psuf) : 0); + + zsfree(compexactstr); + compexactstr = e = (char *) zalloc(lpl + sl + lsl + 1); + if (cm->ppre) { + strcpy(e, cm->ppre); + e += lpl; + } + strcpy(e, s); + e += sl; + if (cm->psuf) + strcpy(e, cm->psuf); + comp_setunsetptr(CP_EXACTSTR, 0); + } + } else { ai->exact = 2; cm = NULL; + if (incompfunc) + comp_setunsetptr(0, CP_EXACTSTR); } ai->exactm = cm; } @@ -4688,7 +4848,6 @@ dumphashtable(HashTable ht, int what) for (i = 0; i < ht->hsize; i++) for (hn = ht->nodes[i]; hn; hn = hn->next) addmatch(hn->nam, (char *) hn); - } /* ScanFunc used by maketildelist() et al. */ @@ -4797,7 +4956,7 @@ gen_matches_files(int dirs, int execs, int all) strcpy(p + o, psuf); /* Do we have to use globbing? */ - if (ispattern || (ns && isset(GLOBCOMPLETE))) { + if (ispattern || (ns && comppatmatch && *comppatmatch)) { /* Yes, so append a `*' if needed. */ if (ns) { int tl = strlen(p); @@ -4847,6 +5006,15 @@ docompletion(char *s, int lst, int incmd) ainfo = fainfo = NULL; matchers = newlinklist(); + useline = (lst != COMP_LIST_COMPLETE); + useexact = (isset(RECEXACT) && usemenu != 1); + uselist = (useline ? + ((isset(AUTOLIST) && !isset(BASHAUTOLIST)) ? + (isset(LISTAMBIGUOUS) ? 3 : 2) : 0) : 1); + zsfree(comppatmatch); + comppatmatch = ztrdup(useglob ? "yes" : ""); + haspattern = 0; + /* Make sure we have the completion list and compctl. */ if (makecomplist(s, incmd, lst)) { /* Error condition: feeeeeeeeeeeeep(). */ @@ -4854,23 +5022,26 @@ docompletion(char *s, int lst, int incmd) clearlist = 1; goto compend; } - if (lst == COMP_LIST_COMPLETE) + if (!useline && uselist) /* All this and the guy only wants to see the list, sigh. */ showinglist = -2; - else { + else if (useline) { /* We have matches. */ if (nmatches > 1) - /* There are more than one match. */ + /* There is more than one match. */ do_ambiguous(); else if (nmatches == 1) { /* Only one match. */ - while (!amatches->mcount) - amatches = amatches->next; - do_single(amatches->matches[0]); + Cmgroup m = amatches; + + while (!m->mcount) + m = m->next; + do_single(m->matches[0]); invalidatelist(); } - } + } else + invalidatelist(); /* Print the explanation strings if needed. */ if (!showinglist && validlist && nmatches != 1) { @@ -4928,33 +5099,47 @@ callcompfunc(char *s, char *fn) int lv = lastval; if ((list = getshfunc(fn)) != &dummy_list) { - LinkList args = newlinklist(); char **p, *tmp; - int aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext; - - addlinknode(args, fn); - + int set, aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext; + Param *ocpms = comppms; + + comppms = (Param *) zalloc(CP_NUM * sizeof(Param)); + + set = -1 & ~(CP_PARAMETER | CP_REDIRECT | CP_QUOTE | CP_QUOTING | + CP_EXACTSTR | (useglob ? 0 : CP_PATMATCH)); zsfree(compcontext); - zsfree(compcommand); - compcommand = ""; - if (inwhat == IN_MATH) { + zsfree(compparameter); + zsfree(compredirect); + compparameter = compredirect = ""; + if (ispar) + compcontext = (ispar == 2 ? "brace_parameter" : "parameter"); + else if (inwhat == IN_MATH) { if (insubscr) { compcontext = "subscript"; - compcommand = varname ? varname : ""; + if (varname) { + compparameter = varname; + set |= CP_PARAMETER; + } } else compcontext = "math"; usea = 0; - } else if (lincmd) - compcontext = (insubscr ? "subscript" : "command"); - else if (linredir) { + } else if (lincmd) { + if (insubscr) { + compcontext = "subscript"; + set |= CP_PARAMETER; + } else + compcontext = "command"; + } else if (linredir) { compcontext = "redirect"; if (rdstr) - compcommand = rdstr; + compredirect = rdstr; + set |= CP_REDIRECT; } else switch (inwhat) { case IN_ENV: - compcontext = "value"; - compcommand = varname; + compcontext = "array_value"; + compparameter = varname; + set |= CP_PARAMETER; if (!clwpos) { clwpos = 1; zsfree(clwords[1]); @@ -4966,61 +5151,141 @@ callcompfunc(char *s, char *fn) compcontext = "condition"; break; default: - if (cmdstr) { - compcontext = "argument"; - compcommand = cmdstr; - } else { + if (cmdstr) + compcontext = "command"; + else { compcontext = "value"; + set |= CP_PARAMETER; if (clwords[0]) - compcommand = clwords[0]; + compparameter = clwords[0]; + aadd = 1; } - aadd = 1; } compcontext = ztrdup(compcontext); - tmp = quotename(compcommand, NULL, NULL, NULL); - untokenize(tmp); - compcommand = ztrdup(tmp); - if (usea && (!aadd || clwords[0])) - for (p = clwords + aadd; *p; p++) { - tmp = dupstring(*p); - untokenize(tmp); - addlinknode(args, tmp); + if (compwords) + freearray(compwords); + if (usea && (!aadd || clwords[0])) { + char **q; + + PERMALLOC { + q = compwords = (char **) + zalloc((clwnum - aadd + 1) * sizeof(char *)); + for (p = clwords + aadd; *p; p++, q++) { + tmp = dupstring(*p); + untokenize(tmp); + *q = ztrdup(tmp); + } + *q = NULL; + } LASTALLOC; + } else + compwords = (char **) zcalloc(sizeof(char *)); + + compparameter = ztrdup(compparameter); + compredirect = ztrdup(compredirect); + zsfree(compquote); + zsfree(compquoting); + if (instring) { + if (instring == 1) { + compquote = ztrdup("\'"); + compquoting = ztrdup("single"); + } else { + compquote = ztrdup("\""); + compquoting = ztrdup("double"); } + set |= CP_QUOTE | CP_QUOTING; + } else if (inbackt) { + compquote = ztrdup("`"); + compquoting = ztrdup("backtick"); + } else { + compquote = ztrdup(""); + compquoting = ztrdup(""); + } + untokenize(s = dupstring(s)); zsfree(compprefix); zsfree(compsuffix); if (unset(COMPLETEINWORD)) { - tmp = quotename(s, NULL, NULL, NULL); - untokenize(tmp); - compprefix = ztrdup(tmp); + compprefix = ztrdup(s); compsuffix = ztrdup(""); } else { char *ss = s + offs, sav; - - tmp = quotename(s, &ss, NULL, NULL); + sav = *ss; *ss = '\0'; - untokenize(tmp); - compprefix = ztrdup(tmp); + compprefix = ztrdup(s); *ss = sav; - untokenize(ss); compsuffix = ztrdup(ss); } zsfree(compiprefix); compiprefix = ztrdup(""); - compcurrent = (usea ? (clwpos + 1 - aadd) : 1); + compcurrent = (usea ? (clwpos + 1 - aadd) : 0); compnmatches = mnum; + + zsfree(complist); + switch (uselist) { + case 0: complist = ""; set &= ~CP_LIST; break; + case 1: complist = "list"; break; + case 2: complist = "autolist"; break; + case 3: complist = "ambiguous"; break; + } + complist = ztrdup(complist); + zsfree(compinsert); + if (useline) { + switch (usemenu) { + case 0: compinsert = "unambiguous"; break; + case 1: compinsert = "menu"; break; + case 2: compinsert = "automenu"; break; + } + } else { + compinsert = ""; + set &= ~CP_INSERT; + } + compinsert = ztrdup(compinsert); + if (useexact) + compexact = ztrdup("accept"); + else { + compexact = ztrdup(""); + set &= ~CP_EXACT; + } incompfunc = 1; startparamscope(); makecompparamsptr(); + comp_setunsetptr(set, ~set); makezleparams(1); sfcontext = SFC_CWIDGET; NEWHEAPS(compheap) { - doshfunc(fn, list, args, 0, 1); + doshfunc(fn, list, NULL, 0, 1); } OLDHEAPS; sfcontext = osc; endparamscope(); lastcmd = 0; incompfunc = icf; + + if (!complist) + uselist = 0; + else if (!strcmp(complist, "list")) + uselist = 1; + else if (!strcmp(complist, "auto") || !strcmp(complist, "autolist")) + uselist = 2; + else if (!strcmp(complist, "ambig") || !strcmp(complist, "ambiguous")) + uselist = 3; + else + uselist = 0; + if (!compinsert) + useline = 0; + else if (!strcmp(compinsert, "unambig") || + !strcmp(compinsert, "unambiguous")) + useline = 1, usemenu = 0; + else if (!strcmp(compinsert, "menu")) + useline = 1, usemenu = 1; + else if (!strcmp(compinsert, "auto") || + !strcmp(compinsert, "automenu")) + useline = 1, usemenu = 2; + else + useline = usemenu = 0; + useexact = (compexact && !strcmp(compexact, "accept")); + + zfree(comppms, CP_NUM * sizeof(Param)); + comppms = ocpms; } lastval = lv; } @@ -5047,7 +5312,11 @@ makecomplist(char *s, int incmd, int lst) { struct cmlist ms; Cmlist m; - char *os = s; + char *p, *os = s; + + /* Inside $... ? */ + if ((p = check_param(s, 0))) + os = s = p; /* We build a copy of the list of matchers to use to make sure that this * works even if a shell function called from the completion code changes @@ -5055,22 +5324,27 @@ makecomplist(char *s, int incmd, int lst) if ((m = cmatcher)) { Cmlist mm, *mp = &mm; + int n; - for (; m; m = m->next) { - *mp = (Cmlist) halloc(sizeof(struct cmlist)); + for (n = 0; m; m = m->next, n++) { + *mp = (Cmlist) zhalloc(sizeof(struct cmlist)); (*mp)->matcher = m->matcher; (*mp)->next = NULL; + (*mp)->str = dupstring(m->str); mp = &((*mp)->next); addlinknode(matchers, m->matcher); m->matcher->refc++; } m = mm; - } - compmatcher = 1; + compmatcher = 1; + compmatchertot = n; + } else + compmatcher = 0; /* Walk through the global matchers. */ for (;;) { bmatchers = NULL; + zsfree(compmatcherstr); if (m) { ms.next = NULL; ms.matcher = m->matcher; @@ -5080,9 +5354,11 @@ makecomplist(char *s, int incmd, int lst) * when building new parts for the string to insert into the * line. */ add_bmatchers(m->matcher); - } else + compmatcherstr = ztrdup(m->str); + } else { mstack = NULL; - + compmatcherstr = ztrdup(""); + } ainfo = (Aminfo) hcalloc(sizeof(struct aminfo)); fainfo = (Aminfo) hcalloc(sizeof(struct aminfo)); @@ -5139,33 +5415,6 @@ makecomplist(char *s, int incmd, int lst) /* This should probably be moved into tokenize(). */ -/**/ -static char * -ctokenize(char *p) -{ - char *r = p; - int bslash = 0; - - tokenize(p); - - for (p = r; *p; p++) { - if (*p == '\\') - bslash = 1; - else { - if (*p == '$' || *p == '=' || *p == '{' || *p == '}') { - if (bslash) - p[-1] = Bnull; - else - *p = (*p == '$' ? String : - (*p == '=' ? Equals : - (*p == '{' ? Inbrace : Outbrace))); - } - bslash = 0; - } - } - return r; -} - /**/ char * comp_str(int *ipl, int *pl, int untok) @@ -5177,17 +5426,17 @@ comp_str(int *ipl, int *pl, int untok) int lp, ls, lip; if (!untok) { - ctokenize(p); + tokenize(p); remnulargs(p); - ctokenize(s); + tokenize(s); remnulargs(s); - ctokenize(ip); + tokenize(ip); remnulargs(ip); } ls = strlen(s); lip = strlen(ip); lp = strlen(p); - str = halloc(lip + lp + ls + 1); + str = zhalloc(lip + lp + ls + 1); strcpy(str, ip); strcat(str, p); strcat(str, s); @@ -5201,9 +5450,11 @@ comp_str(int *ipl, int *pl, int untok) } /**/ -void +int makecomplistcall(Compctl cc) { + int nm = mnum; + SWITCHHEAPS(compheap) { HEAPALLOC { int ooffs = offs, lip, lp; @@ -5217,6 +5468,8 @@ makecomplistcall(Compctl cc) compnmatches = mnum; } LASTALLOC; } SWITCHBACKHEAPS; + + return (mnum == nm); } /* A simple counter to avoid endless recursion between old and new style * @@ -5243,24 +5496,20 @@ makecomplistctl(int flags) char *os = cmdstr, **ow = clwords, **p, **q; int on = clwnum, op = clwpos; - clwnum = arrlen(pparams) + 1; + clwnum = arrlen(compwords); clwpos = compcurrent - 1; - cmdstr = ztrdup(compcommand); + cmdstr = ztrdup(compwords[0]); clwords = (char **) zalloc((clwnum + 1) * sizeof(char *)); - clwords[0] = ztrdup(cmdstr); - for (p = pparams, q = clwords + 1; *p; p++, q++) { + for (p = compwords, q = clwords; *p; p++, q++) { t = dupstring(*p); - ctokenize(t); + tokenize(t); remnulargs(t); *q = ztrdup(t); } *q = NULL; offs = lip + lp; incompfunc = 2; - ret = makecomplistglobal(str, - (!clwpos && - !strcmp(compcontext, "command")), - COMP_COMPLETE, flags); + ret = makecomplistglobal(str, !clwpos, COMP_COMPLETE, flags); incompfunc = 1; offs = ooffs; compnmatches = mnum; @@ -5499,7 +5748,7 @@ makecomplistext(Compctl occ, char *os, int incmd) Compcond or, cc; Comp comp; int compadd, m = 0, d = 0, t, tt, i, j, a, b; - char *sc, *s, *ss; + char *sc = NULL, *s, *ss; /* This loops over the patterns separated by `-'s. */ for (compc = occ->ext; compc; compc = compc->next) { @@ -5669,7 +5918,7 @@ findnode(LinkList list, void *dat) static void makecomplistflags(Compctl cc, char *s, int incmd, int compadd) { - int t, sf1, sf2, ooffs, um = usemenu, delit, ispar = 0; + int t, sf1, sf2, ooffs, um = usemenu, delit, oaw; char *p, *sd = NULL, *tt, *s1, *s2, *os = dupstring(s); struct cmlist ms; @@ -5678,6 +5927,8 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if (incompfunc != 1 && findnode(ccstack, cc)) return; + MUSTUSEHEAP("complistflags"); + addlinknode(ccstack, cc); if (incompfunc != 1 && allccs) { @@ -5711,7 +5962,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if (cc->mask2 & CC_NOSORT) mgroup->flags |= CGF_NOSORT; if (cc->explain) { - expl = (Cexpl) halloc(sizeof(struct cexpl)); + expl = (Cexpl) zhalloc(sizeof(struct cexpl)); expl->count = expl->fcount = 0; } else @@ -5781,79 +6032,16 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) s[suffixll - sl] = '\0'; } /* Do we have one of the special characters `~' and `=' at the beginning? */ - if ((ic = *s) != Tilde && ic != Equals) + if (incompfunc || ((ic = *s) != Tilde && ic != Equals)) ic = 0; /* Check if we have to complete a parameter name... */ - - /* Try to find a `$'. */ - for (p = s + offs; p > s && *p != String; p--); - if (*p == String) { - /* Handle $$'s */ - while (p > s && p[-1] == String) - p--; - while (p[1] == String && p[2] == String) - p += 2; - } - if (*p == String && p[1] != Inpar && p[1] != Inbrack) { - /* This is really a parameter expression (not $(...) or $[...]). */ - char *b = p + 1, *e = b; - int n = 0, br = 1; - - if (*b == Inbrace) { - /* If this is a ${...}, ignore the possible (...) flags. */ - b++, br++; - n = skipparens(Inpar, Outpar, &b); - } - - /* Ignore the stuff before the parameter name. */ - for (; *b; b++) - if (*b != '^' && *b != Hat && - *b != '=' && *b != Equals && - *b != '~' && *b != Tilde) - break; - if (*b == '#' || *b == Pound || *b == '+') - b++; - - e = b; - /* Find the end of the name. */ - if (*e == Quest || *e == Star || *e == String || *e == Qstring || - *e == '?' || *e == '*' || *e == '$' || - *e == '-' || *e == '!' || *e == '@') - e++; - else if (idigit(*e)) - while (idigit(*e)) - e++; - else if (iident(*e)) - while (iident(*e) || - (useglob && (*e == Star || *e == Quest))) - e++; - - /* Now make sure that the cursor is inside the name. */ - if (offs <= e - s && offs >= b - s && n <= 0) { - /* It is. */ - if (br >= 2) - mflags |= CMF_PARBR; - - /* Get the prefix (anything up to the character before the name). */ - lpsuf = dupstring(quotename(e, NULL, NULL, NULL)); - *e = '\0'; - lpsl = strlen(lpsuf); - ripre = dupstring(s); - ripre[b - s] = '\0'; - ipre = dupstring(quotename(ripre, NULL, NULL, NULL)); - untokenize(ipre); - ispar = 1; - /* And adjust wb, we, and offs again. */ - offs -= b - s; - wb = cs - offs; - we = wb + e - b; - s = b; - /* And now make sure that we complete parameter names. */ - cc = &cc_dummy; - cc_dummy.refc = 10000; - cc_dummy.mask = CC_PARAMS | CC_ENVVARS; - } + if (!incompfunc && (p = check_param(s, 1))) { + s = p; + /* And now make sure that we complete parameter names. */ + cc = &cc_dummy; + cc_dummy.refc = 10000; + cc_dummy.mask = CC_PARAMS | CC_ENVVARS; } ooffs = offs; /* If we have to ignore the word, do that. */ @@ -5861,12 +6049,13 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) delit = 1; *s = '\0'; offs = 0; - if (isset(AUTOMENU)) usemenu = 1; + if (isset(AUTOMENU)) + usemenu = 1; } /* Compute line prefix/suffix. */ lpl = offs; - lpre = halloc(lpl + 1); + lpre = zhalloc(lpl + 1); memcpy(lpre, s, lpl); lpre[lpl] = '\0'; lsuf = dupstring(s + offs); @@ -5905,6 +6094,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if (!s1) s1 = p; } + rsl = strlen(rsuf); for (s2 = NULL, sf2 = t = 0, p = rsuf; *p && (!t || !sf2); p++) if (itok(*p)) t |= sf2 ? 4 : 2; @@ -5917,7 +6107,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) /* But if we were asked not to do glob completion, we never treat the * * thing as a pattern. */ - if (!useglob) + if (!comppatmatch || !*comppatmatch) ispattern = 0; if (ispattern) { @@ -5930,6 +6120,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) } else strcpy(p + rpl, rsuf); patcomp = parsereg(p); + haspattern = 1; } if (!patcomp) { untokenize(rpre); @@ -5963,6 +6154,8 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) line[cs] = 0; lppre = dupstring((char *) (line + wb)); line[cs] = save; + if (brbeg && *brbeg) + strcpy(lppre + brpl, lppre + brpl + strlen(brbeg)); if ((p = strrchr(lppre, '/'))) { p[1] = '\0'; lppl = strlen(lppre); @@ -5979,8 +6172,14 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) char save = line[we]; line[we] = 0; - lpsuf = strchr(dupstring((char *) (line + cs)), '/'); + lpsuf = dupstring((char *) (line + cs)); line[we] = save; + if (brend && *brend) { + char *p = lpsuf + brsl - (cs - wb); + + strcpy(p, p + strlen(brend)); + } + lpsuf = strchr(lpsuf, '/'); lpsl = (lpsuf ? strlen(lpsuf) : 0); } else { @@ -5994,7 +6193,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) /* And the suffix. */ fsuf = dupstrpfx(rsuf, s2 - rsuf); - if (useglob && (ispattern & 2)) { + if (comppatmatch && *comppatmatch && (ispattern & 2)) { int t2; /* We have to use globbing, so compute the pattern from * @@ -6079,10 +6278,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if ((pp = get_user_var(cc->withd))) { dirs = npp = - (char**) halloc(sizeof(char *)*(arrlen(pp)+1)); + (char**) zhalloc(sizeof(char *)*(arrlen(pp)+1)); while (*pp) { pl = strlen(*pp); - tp = (char *) halloc(strlen(*pp) + tl); + tp = (char *) zhalloc(strlen(*pp) + tl); strcpy(tp, *pp); tp[pl] = '/'; strcpy(tp + pl + 1, ppre); @@ -6098,7 +6297,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) char *tp; int pl = strlen(cc->withd); - ta[0] = tp = (char *) halloc(strlen(ppre) + pl + 2); + ta[0] = tp = (char *) zhalloc(strlen(ppre) + pl + 2); strcpy(tp, cc->withd); tp[pl] = '/'; strcpy(tp + pl + 1, ppre); @@ -6270,7 +6469,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if (isset(AUTOCD) && isset(CDABLEVARS)) dumphashtable(paramtab, -4); } - addwhat = (cc->mask & CC_QUOTEFLAG) ? -2 : CC_QUOTEFLAG; + oaw = addwhat = (cc->mask & CC_QUOTEFLAG) ? -2 : CC_QUOTEFLAG; if (cc->mask & CC_NAMED) /* Add named directories. */ @@ -6278,12 +6477,16 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if (cc->mask & CC_OPTIONS) /* Add option names. */ dumphashtable(optiontab, addwhat); - if (cc->mask & CC_VARS) + if (cc->mask & CC_VARS) { /* And parameter names. */ dumphashtable(paramtab, -9); - if (cc->mask & CC_BINDINGS) + addwhat = oaw; + } + if (cc->mask & CC_BINDINGS) { /* And zle function names... */ dumphashtable(thingytab, CC_BINDINGS); + addwhat = oaw; + } if (cc->keyvar) { /* This adds things given to the compctl -k flag * * (from a parameter or a list of words). */ @@ -6293,54 +6496,53 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) while (*usr) addmatch(*usr++, NULL); } - if (cc->mask & CC_USERS) + if (cc->mask & CC_USERS) { /* Add user names. */ maketildelist(); + addwhat = oaw; + } + if (cc->widget) + callcompfunc(os, cc->widget); if (cc->func) { - if (cc->func[0] == ' ') - /* Temporary hack for access to new style completione. */ - callcompfunc(os, cc->func + 1); - else { - /* This handles the compctl -K flag. */ - List list; - char **r; - int lv = lastval; + /* This handles the compctl -K flag. */ + List list; + char **r; + int lv = lastval; - /* Get the function. */ - if ((list = getshfunc(cc->func)) != &dummy_list) { - /* We have it, so build a argument list. */ - LinkList args = newlinklist(); - int osc = sfcontext; - - addlinknode(args, cc->func); + /* Get the function. */ + if ((list = getshfunc(cc->func)) != &dummy_list) { + /* We have it, so build a argument list. */ + LinkList args = newlinklist(); + int osc = sfcontext; - if (delit) { - p = dupstrpfx(os, ooffs); - untokenize(p); - addlinknode(args, p); - p = dupstring(os + ooffs); - untokenize(p); - addlinknode(args, p); - } else { - addlinknode(args, lpre); - addlinknode(args, lsuf); - } + addlinknode(args, cc->func); - /* This flag allows us to use read -l and -c. */ - if (incompfunc != 1) - incompctlfunc = 1; - sfcontext = SFC_COMPLETE; - /* Call the function. */ - doshfunc(cc->func, list, args, 0, 1); - sfcontext = osc; - incompctlfunc = 0; - /* And get the result from the reply parameter. */ - if ((r = get_user_var("reply"))) - while (*r) - addmatch(*r++, NULL); + if (delit) { + p = dupstrpfx(os, ooffs); + untokenize(p); + addlinknode(args, p); + p = dupstring(os + ooffs); + untokenize(p); + addlinknode(args, p); + } else { + addlinknode(args, lpre); + addlinknode(args, lsuf); } - lastval = lv; + + /* This flag allows us to use read -l and -c. */ + if (incompfunc != 1) + incompctlfunc = 1; + sfcontext = SFC_COMPLETE; + /* Call the function. */ + doshfunc(cc->func, list, args, 0, 1); + sfcontext = osc; + incompctlfunc = 0; + /* And get the result from the reply parameter. */ + if ((r = get_user_var("reply"))) + while (*r) + addmatch(*r++, NULL); } + lastval = lv; } if (cc->mask & (CC_JOBS | CC_RUNNING | CC_STOPPED)) { /* Get job names. */ @@ -6378,7 +6580,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) * get the words we have to expand. */ zleparse = 1; lexsave(); - tmpbuf = (char *)halloc(strlen(cc->str) + 5); + tmpbuf = (char *)zhalloc(strlen(cc->str) + 5); sprintf(tmpbuf, "foo %s", cc->str); /* KLUDGE! */ inpush(tmpbuf, 0, NULL); strinbeg(); @@ -6456,9 +6658,12 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if ((t = cc->mask & CC_BUILTINS)) /* Add builtins. */ dumphashtable(builtintab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS))); - if ((t = cc->mask & CC_EXTCMDS)) + if ((t = cc->mask & CC_EXTCMDS)) { /* Add external commands */ + if (isset(HASHLISTALL)) + cmdnamtab->filltable(cmdnamtab); dumphashtable(cmdnamtab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS))); + } if ((t = cc->mask & CC_RESWDS)) /* Add reserved words */ dumphashtable(reswdtab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS))); @@ -6486,7 +6691,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) for (ln = firstnode(matches); ln; ln = nextnode(ln)) { m = (Cmatch) getdata(ln); if (m->ppre) { - char *p = (char *) halloc(strlen(m->ppre) + strlen(m->str) + + char *p = (char *) zhalloc(strlen(m->ppre) + strlen(m->str) + strlen(m->psuf) + 1); sprintf(p, "%s%s%s", m->ppre, m->str, m->psuf); @@ -6654,7 +6859,7 @@ get_user_var(char *nam) if ((val = getsparam(nam))) { arr = (char **)ncalloc(2*sizeof(char *)); - arr[0] = val; + arr[0] = (incompfunc ? dupstring(val) : val); arr[1] = NULL; } return arr; @@ -6763,7 +6968,10 @@ makearray(LinkList l, int s, int *np, int *nlp) if ((*ap)->flags & CMF_NOLIST) nl++; *cp = NULL; - } + } else + for (ap = rp; *ap; ap++) + if ((*ap)->flags & CMF_NOLIST) + nl++; if (np) *np = n; if (nlp) @@ -6795,7 +7003,7 @@ begcmgroup(char *n, int nu) p = p->next; } } - mgroup = (Cmgroup) halloc(sizeof(struct cmgroup)); + mgroup = (Cmgroup) zhalloc(sizeof(struct cmgroup)); mgroup->name = dupstring(n); mgroup->flags = mgroup->lcount = mgroup->mcount = 0; mgroup->matches = NULL; @@ -6858,8 +7066,8 @@ dupmatch(Cmatch m) r->ppre = ztrdup(m->ppre); r->psuf = ztrdup(m->psuf); r->prpre = ztrdup(m->prpre); - r->pre = m->pre; - r->suf = m->suf; + r->pre = ztrdup(m->pre); + r->suf = ztrdup(m->suf); r->flags = m->flags; r->brpl = m->brpl; r->brsl = m->brsl; @@ -6975,6 +7183,8 @@ freematch(Cmatch m) zsfree(m->ripre); zsfree(m->ppre); zsfree(m->psuf); + zsfree(m->pre); + zsfree(m->suf); zsfree(m->prpre); zsfree(m->rems); zsfree(m->remf); @@ -7030,15 +7240,14 @@ freematches(void) static void do_ambiguous(void) { - int p = (usemenu || ispattern), atend = (cs == we); + int p = (usemenu || haspattern), atend = (cs == we); menucmp = 0; /* If we have to insert the first match, call do_single(). This is * * how REC_EXACT takes effect. We effectively turn the ambiguous * * completion into an unambiguous one. */ - if (ainfo && ainfo->exact == 1 && isset(RECEXACT) && !(fromcomp & FC_LINE) && - (usemenu == 0 || unset(AUTOMENU))) { + if (ainfo && ainfo->exact == 1 && useexact && !(fromcomp & FC_LINE)) { do_single(ainfo->exactm); invalidatelist(); return; @@ -7049,7 +7258,7 @@ do_ambiguous(void) * unambiguous prefix. */ lastambig = 1; - if(p) { + if (p) { /* p is set if we are in a position to start using menu completion * * due to one of the menu completion options, or due to the * * menu-complete-word command, or due to using GLOB_COMPLETE which * @@ -7152,7 +7361,7 @@ do_ambiguous(void) * prefix was inserted, return now, bypassing the list-displaying * * code. On the way, invalidate the list and note that we don't * * want to enter an AUTO_MENU imediately. */ - if(isset(LISTAMBIGUOUS) && la) { + if (uselist == 3 && la) { int fc = fromcomp; invalidatelist(); @@ -7165,8 +7374,7 @@ do_ambiguous(void) * if it is needed. */ if (isset(LISTBEEP)) feep(); - if (isset(AUTOLIST) && !isset(BASHAUTOLIST) && !amenu && !showinglist && - smatches >= 2) + if (uselist && usemenu != 2 && !showinglist && smatches >= 2) showinglist = -2; } @@ -7264,7 +7472,7 @@ do_single(Cmatch m) struct stat buf; /* Build the path name. */ - if (ispattern || ic || m->ripre) { + if (haspattern || ic || m->ripre) { int ne = noerrs; noerrs = 1; @@ -7620,14 +7828,14 @@ listmatches(void) char **pp = g->ylist; if ((e = g->expls)) { - if (pnl) { - putc('\n', shout); - pnl = 0; - } while (*e) { if ((*e)->count) { + if (pnl) { + putc('\n', shout); + pnl = 0; + } printfmt((*e)->str, (*e)->count, 1); - putc('\n', shout); + pnl = 1; } e++; } @@ -7670,7 +7878,7 @@ listmatches(void) } } else if (g->lcount) { - int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, j, a; + int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, j, a = 0; Cmatch *q; if (n && pnl) { @@ -7691,7 +7899,7 @@ listmatches(void) struct stat buf; char *pb; - pb = (char *) halloc((m->prpre ? strlen(m->prpre) : 0) + + pb = (char *) zhalloc((m->prpre ? strlen(m->prpre) : 0) + 3 + strlen(m->str)); sprintf(pb, "%s%s", (m->prpre ? m->prpre : "./"), m->str); diff --git a/Src/Zle/zle_word.c b/Src/Zle/zle_word.c index afd860066..f446d1769 100644 --- a/Src/Zle/zle_word.c +++ b/Src/Zle/zle_word.c @@ -465,7 +465,7 @@ transposewords(void) return; } for (p1 = p2; p1 && iword(line[p1 - 1]); p1--); - pp = temp = (char *)halloc(p4 - p1 + 1); + pp = temp = (char *)zhalloc(p4 - p1 + 1); struncpy(&pp, (char *) line + p3, p4 - p3); struncpy(&pp, (char *) line + p2, p3 - p2); struncpy(&pp, (char *) line + p1, p2 - p1); diff --git a/Src/builtin.c b/Src/builtin.c index fc9b113ca..c042537f4 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1072,12 +1072,14 @@ fixdir(char *src) *dest = '\0'; return; } - if (dest > d0 + 1 && src[0] == '.' && src[1] == '.' && + if (src[0] == '.' && src[1] == '.' && (src[2] == '\0' || src[2] == '/')) { - /* remove a foo/.. combination */ - for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--); - if (dest[-1] != '/') - dest--; + if (dest > d0 + 1) { + /* remove a foo/.. combination */ + for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--); + if (dest[-1] != '/') + dest--; + } src++; while (*++src == '/'); } else if (src[0] == '.' && (src[1] == '/' || src[1] == '\0')) { diff --git a/Src/compat.c b/Src/compat.c index b1bcbc21b..53ab6b7a3 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -115,7 +115,7 @@ zgetdir(struct dirsav *d) struct stat sbuf; ino_t pino; dev_t pdev; -#ifndef __CYGWIN__ +#if !defined(__CYGWIN__) && !defined(USE_GETCWD) struct dirent *de; DIR *dir; dev_t dev; @@ -123,7 +123,7 @@ zgetdir(struct dirsav *d) int len; #endif - buf = halloc(bufsiz = PATH_MAX); + buf = zhalloc(bufsiz = PATH_MAX); pos = bufsiz - 1; buf[pos] = '\0'; strcpy(nbuf, "../"); @@ -142,7 +142,7 @@ zgetdir(struct dirsav *d) #ifdef HAVE_FCHDIR else #endif -#ifndef __CYGWIN__ +#if !defined(__CYGWIN__) && !defined(USE_GETCWD) holdintr(); for (;;) { @@ -202,7 +202,7 @@ zgetdir(struct dirsav *d) len = strlen(nbuf + 2); pos -= len; while (pos <= 1) { - char *newbuf = halloc(2*bufsiz); + char *newbuf = zhalloc(2*bufsiz); memcpy(newbuf + bufsiz, buf, bufsiz); buf = newbuf; pos += bufsiz; @@ -228,7 +228,7 @@ zgetdir(struct dirsav *d) zchdir(buf + pos + 1); noholdintr(); -#else /* __CYGWIN__ case */ +#else /* __CYGWIN__, USE_GETCWD cases */ if (!getcwd(buf, bufsiz)) { if (d) { diff --git a/Src/glob.c b/Src/glob.c index 47fa63567..738753377 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -2177,7 +2177,7 @@ get_match_ret(char *s, int b, int e, int fl, char *replstr) if (replstr) { if ((fl & SUB_GLOBAL) && repllist) { /* We are replacing the chunk, just add this to the list */ - Repldata rd = (Repldata) halloc(sizeof(*rd)); + Repldata rd = (Repldata) zhalloc(sizeof(*rd)); rd->b = b; rd->e = e; addlinknode(repllist, rd); @@ -2481,7 +2481,7 @@ getmatch(char **sp, char *pat, int fl, int n, char *replstr) i = rd->e; /* start of next chunk of *sp */ } lleft += l - i; /* final chunk from *sp */ - start = t = halloc(lleft+1); + start = t = zhalloc(lleft+1); i = 0; for (nd = firstnode(repllist); nd; incnode(nd)) { rd = (Repldata) getdata(nd); diff --git a/Src/mem.c b/Src/mem.c index 703920215..ee0f5635f 100644 --- a/Src/mem.c +++ b/Src/mem.c @@ -34,7 +34,7 @@ There are two ways to allocate memory in zsh. The first way is to call zalloc/zcalloc, which call malloc/calloc directly. It is legal to call realloc() or free() on memory allocated this way. - The second way is to call halloc/hcalloc, which allocates memory + The second way is to call zhalloc/hcalloc, which allocates memory from one of the memory pools on the heap stack. Such memory pools will automatically created when the heap allocation routines are called. To be sure that they are freed at appropriate times @@ -55,7 +55,7 @@ it will all be freed when the pool is destroyed. In fact, attempting to free this memory may result in a core dump. The pair of pointers ncalloc and alloc may point to either - zalloc & zcalloc or halloc & hcalloc; permalloc() sets them to the + zalloc & zcalloc or zhalloc & hcalloc; permalloc() sets them to the former, and heapalloc() sets them to the latter. This can be useful. For example, the dupstruct() routine duplicates a syntax tree, allocating the new memory for the tree using alloc(). If you want @@ -78,7 +78,7 @@ /**/ int useheap; -/* Current allocation pointers. ncalloc() is either zalloc() or halloc(); * +/* Current allocation pointers. ncalloc() is either zalloc() or zhalloc(); * * alloc() is either zcalloc() or hcalloc(). */ /**/ @@ -110,7 +110,7 @@ global_heapalloc(void) int luh = useheap; alloc = hcalloc; - ncalloc = halloc; + ncalloc = zhalloc; useheap = 1; return luh; } @@ -262,7 +262,7 @@ popheap(void) /**/ void * -halloc(size_t size) +zhalloc(size_t size) { Heap h; size_t n; @@ -329,7 +329,7 @@ hrealloc(char *p, size_t old, size_t new) if (old == new) return p; if (!old && !p) - return halloc(new); + return zhalloc(new); /* find the heap with p */ @@ -343,7 +343,7 @@ hrealloc(char *p, size_t old, size_t new) if (p + old < arena(h) + h->used) { if (new > old) { - char *ptr = (char *) halloc(new); + char *ptr = (char *) zhalloc(new); memcpy(ptr, p, old); #ifdef ZSH_MEM_DEBUG memset(p, 0xff, old); @@ -380,7 +380,7 @@ hrealloc(char *p, size_t old, size_t new) h->used += new - old; return p; } else { - char *t = halloc(new); + char *t = zhalloc(new); memcpy(t, p, old > new ? new : old); h->used -= old; #ifdef ZSH_MEM_DEBUG @@ -398,7 +398,7 @@ hcalloc(size_t size) { void *ptr; - ptr = halloc(size); + ptr = zhalloc(size); memset(ptr, 0, size); return ptr; } diff --git a/Src/params.c b/Src/params.c index e8182815e..eb50c0b7e 100644 --- a/Src/params.c +++ b/Src/params.c @@ -680,6 +680,7 @@ static long getarg(char **str, int *inv, Value v, int a2, long *w) { int num = 1, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash; + int beg = 0, hasbeg = 0; char *s = *str, *sep = NULL, *t, sav, *d, **ta, **p, *tt; long r = 0; Comp c; @@ -731,6 +732,18 @@ getarg(char **str, int *inv, Value v, int a2, long *w) *t = sav; s = t; break; + case 'b': + hasbeg = 1; + t = get_strarg(++s); + if (!*t) + goto flagerr; + sav = *t; + *t = '\0'; + if ((beg = mathevalarg(s + 1, &d)) > 0) + beg--; + *t = sav; + s = t; + break; case 'p': escapes = 1; break; @@ -767,14 +780,15 @@ getarg(char **str, int *inv, Value v, int a2, long *w) else if (v->isarr & SCANPM_WANTVALS) *inv = 0; else { - if (ind) { - v->isarr |= SCANPM_WANTKEYS; - v->isarr &= ~SCANPM_WANTVALS; - } else if (rev) { - v->isarr |= SCANPM_WANTVALS; + if (v->isarr) { + if (ind) { + v->isarr |= SCANPM_WANTKEYS; + v->isarr &= ~SCANPM_WANTVALS; + } else if (rev) + v->isarr |= SCANPM_WANTVALS; + if (!down && ishash) + v->isarr &= ~SCANPM_MATCHMANY; } - if (!down && ishash) - v->isarr &= ~SCANPM_MATCHMANY; *inv = ind; } @@ -869,6 +883,8 @@ getarg(char **str, int *inv, Value v, int a2, long *w) tokenize(s); if ((c = parsereg(s))) { + int len; + if (v->isarr) { if (ishash) { scancomp = c; @@ -887,28 +903,43 @@ getarg(char **str, int *inv, Value v, int a2, long *w) ta = getarrvalue(v); if (!ta || !*ta) return 0; - if (down) - for (r = -1, p = ta + arrlen(ta) - 1; p >= ta; r--, p--) { - if (domatch(*p, c, 0) && !--num) - return r; - } else - for (r = 1, p = ta; *p; r++, p++) - if (domatch(*p, c, 0) && !--num) - return r; + len = arrlen(ta); + if (beg < 0) + beg += len; + if (beg >= 0 && beg < len) { + if (down) { + if (!hasbeg) + beg = len - 1; + for (r = 1 + beg, p = ta + beg; p >= ta; r--, p--) { + if (domatch(*p, c, 0) && !--num) + return r; + } + } else + for (r = 1 + beg, p = ta + beg; *p; r++, p++) + if (domatch(*p, c, 0) && !--num) + return r; + } } else if (word) { ta = sepsplit(d = s = getstrvalue(v), sep, 1); - if (down) { - for (p = ta + (r = arrlen(ta)) - 1; p >= ta; p--, r--) - if (domatch(*p, c, 0) && !--num) - break; - if (p < ta) - return 0; - } else { - for (r = 1, p = ta; *p; r++, p++) - if (domatch(*p, c, 0) && !--num) - break; - if (!*p) - return 0; + len = arrlen(ta); + if (beg < 0) + beg += len; + if (beg >= 0 && beg < len) { + if (down) { + if (!hasbeg) + beg = len - 1; + for (r = 1 + beg, p = ta + beg; p >= ta; p--, r--) + if (domatch(*p, c, 0) && !--num) + break; + if (p < ta) + return 0; + } else { + for (r = 1 + beg, p = ta + beg; *p; r++, p++) + if (domatch(*p, c, 0) && !--num) + break; + if (!*p) + return 0; + } } if (a2) r++; @@ -924,35 +955,46 @@ getarg(char **str, int *inv, Value v, int a2, long *w) d = getstrvalue(v); if (!d || !*d) return 0; - if (a2) { - if (down) - for (r = -2, t = d + strlen(d) - 1; t >= d; r--, t--) { - sav = *t; - *t = '\0'; - if (domatch(d, c, 0) && !--num) { + len = strlen(d); + if (beg < 0) + beg += len; + if (beg >= 0 && beg < len) { + if (a2) { + if (down) { + if (!hasbeg) + beg = len - 1; + for (r = beg, t = d + beg; t >= d; r--, t--) { + sav = *t; + *t = '\0'; + if (domatch(d, c, 0) && !--num) { + *t = sav; + return r; + } *t = sav; - return r; } - *t = sav; - } else - for (r = 0, t = d; *t; r++, t++) { - sav = *t; - *t = '\0'; - if (domatch(d, c, 0) && !--num) { + } else + for (r = beg, t = d + beg; *t; r++, t++) { + sav = *t; + *t = '\0'; + if (domatch(d, c, 0) && !--num) { + *t = sav; + return r; + } *t = sav; - return r; } - *t = sav; - } - } else { - if (down) - for (r = -1, t = d + strlen(d) - 1; t >= d; r--, t--) { - if (domatch(t, c, 0) && !--num) - return r; - } else - for (r = 1, t = d; *t; r++, t++) - if (domatch(t, c, 0) && !--num) - return r; + } else { + if (down) { + if (!hasbeg) + beg = len - 1; + for (r = beg + 1, t = d + beg; t >= d; r--, t--) { + if (domatch(t, c, 0) && !--num) + return r; + } + } else + for (r = beg + 1, t = d + beg; *t; r++, t++) + if (domatch(t, c, 0) && !--num) + return r; + } } return 0; } @@ -1177,7 +1219,8 @@ getstrvalue(Value v) } LASTALLOC_RETURN s; case PM_INTEGER: - convbase(s = buf, v->pm->gets.ifn(v->pm), v->pm->ct); + convbase(buf, v->pm->gets.ifn(v->pm), v->pm->ct); + s = dupstring(buf); break; case PM_SCALAR: s = v->pm->gets.cfn(v->pm); diff --git a/Src/subst.c b/Src/subst.c index 2e9b84718..6445776d1 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -529,7 +529,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, char if (lr == ls) return str; - r = ret = (char *)halloc(lr + 1); + r = ret = (char *)zhalloc(lr + 1); if (prenum) { if (postnum) { @@ -1831,7 +1831,7 @@ modify(char **str, char **ptr) tc = *tt; *tt = '\0'; nl = al + strlen(t) + strlen(copy); - ptr1 = tmp = (char *)halloc(nl + 1); + ptr1 = tmp = (char *)zhalloc(nl + 1); if (all) for (ptr2 = all; *ptr2;) *ptr1++ = *ptr2++; diff --git a/Src/system.h b/Src/system.h index 650690b51..2babafa7a 100644 --- a/Src/system.h +++ b/Src/system.h @@ -51,7 +51,7 @@ #endif #ifndef HAVE_ALLOCA -# define alloca halloc +# define alloca zhalloc #else # ifdef __GNUC__ # define alloca __builtin_alloca diff --git a/Src/utils.c b/Src/utils.c index 4ff4a91ba..d010df4e0 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -93,7 +93,7 @@ zerrnam(const char *cmd, const char *fmt, const char *str, int num) case 'l': { char *s; num = metalen(str, num); - s = halloc(num + 1); + s = zhalloc(num + 1); memcpy(s, str, num); s[num] = '\0'; nicezputs(s, stderr); @@ -2807,7 +2807,7 @@ metafy(char *buf, int len, int heap) break; case META_USEHEAP: case META_HEAPDUP: - buf = memcpy(halloc(len + meta + 1), buf, len); + buf = memcpy(zhalloc(len + meta + 1), buf, len); break; case META_STATIC: #ifdef DEBUG @@ -3372,7 +3372,7 @@ getkeystring(char *s, int *len, int fromwhere, int *misc) int meta = 0, control = 0; if (fromwhere != 4) - buf = halloc(strlen(s) + 1); + buf = zhalloc(strlen(s) + 1); else { buf = s; s += 2; diff --git a/Src/zsh.export b/Src/zsh.export index d31e7902e..dcee683f6 100644 --- a/Src/zsh.export +++ b/Src/zsh.export @@ -5,6 +5,8 @@ addconddefs addedx addhashnode addwrapper +arrvargetfn +arrvarsetfn aliastab alloc_stackp appstr @@ -69,6 +71,7 @@ getaparam gethashnode gethashnode2 gethparam +getintvalue getiparam getkeystring getlinknode @@ -82,7 +85,6 @@ global_heapalloc global_permalloc globlist gotwordptr -halloc hasam hashcmd hasher @@ -135,6 +137,7 @@ ncalloc new_heaps newhashtable newlinklist +newparamtable nicechar nicezputs niceztrdup @@ -250,6 +253,7 @@ zexit zfree zgetdir zgetenv +zhalloc zjoin zleactive zleparse -- cgit 1.4.1