From a9bb13af357ee35f9abf1728a4d563260bfc6f74 Mon Sep 17 00:00:00 2001 From: Paul Ackersviller Date: Sat, 1 Dec 2007 21:12:28 +0000 Subject: Merge of 24127: pws fixed bug in matcher specs with left anchor and partial words. --- Src/Zle/compcore.c | 18 +++++++++--------- Src/Zle/compmatch.c | 50 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 0547f9b33..c25365b97 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -2090,7 +2090,7 @@ addmatches(Cadata dat, char **argv) ms = dupstring(s); else sl = strlen(ms = multiquote(s, 0)); - lc = bld_parts(ms, sl, -1, NULL); + lc = bld_parts(ms, sl, -1, NULL, NULL); isexact = 0; } else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc, (!(dat->aflags & CAF_QUOTE) ? @@ -2228,7 +2228,7 @@ add_match_data(int alt, char *str, char *orig, Cline line, for (pp = NULL, p = line; p->next; pp = p, p = p->next); if (psl) { - s = bld_parts(psuf, psl, psl, &sl); + s = bld_parts(psuf, psl, psl, &sl, NULL); if (sline) { Cline sp; @@ -2262,7 +2262,7 @@ add_match_data(int alt, char *str, char *orig, Cline line, if (isl) { Cline tsl; - s = bld_parts(isuf, isl, isl, &tsl); + s = bld_parts(isuf, isl, isl, &tsl, NULL); if (sl) sl->next = s; @@ -2281,7 +2281,7 @@ add_match_data(int alt, char *str, char *orig, Cline line, sl = tsl; } if (qisl) { - Cline qsl = bld_parts(dupstring(qisuf), qisl, qisl, NULL); + Cline qsl = bld_parts(dupstring(qisuf), qisl, qisl, NULL, NULL); qsl->flags |= CLF_SUF; qsl->suffix = qsl->prefix; @@ -2324,7 +2324,7 @@ add_match_data(int alt, char *str, char *orig, Cline line, if (pline) for (p = cp_cline(pline, 1), lp = p; lp->next; lp = lp->next); else - p = bld_parts(ppre, ppl, ppl, &lp); + p = bld_parts(ppre, ppl, ppl, &lp, NULL); if (lp->prefix && !(line->flags & (CLF_SUF | CLF_MID)) && !lp->llen && !lp->wlen && !lp->olen) { @@ -2352,19 +2352,19 @@ add_match_data(int alt, char *str, char *orig, Cline line, } } if (pl) { - Cline lp, p = bld_parts(pre, pl, pl, &lp); + Cline lp, p = bld_parts(pre, pl, pl, &lp, NULL); lp->next = line; line = p; } if (ipl) { - Cline lp, p = bld_parts(ipre, ipl, ipl, &lp); + Cline lp, p = bld_parts(ipre, ipl, ipl, &lp, NULL); lp->next = line; line = p; } if (qipl) { - Cline lp, p = bld_parts(dupstring(qipre), qipl, qipl, &lp); + Cline lp, p = bld_parts(dupstring(qipre), qipl, qipl, &lp, NULL); lp->next = line; line = p; @@ -2384,7 +2384,7 @@ add_match_data(int alt, char *str, char *orig, Cline line, if (ppl) memcpy(apre + qipl + ipl + pl, ppre, ppl); - p = bld_parts(apre, palen, palen, &lp); + p = bld_parts(apre, palen, palen, &lp, NULL); if (pline) for (lp->next = cp_cline(pline, 1); lp->next; lp = lp->next); diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c index 10fb5e20e..12042ed23 100644 --- a/Src/Zle/compmatch.c +++ b/Src/Zle/compmatch.c @@ -337,22 +337,26 @@ static void add_match_part(Cmatcher m, char *l, char *w, int wl, char *o, int ol, char *s, int sl, int osl, int sfx) { - Cline p, lp; + Cline p, lp, lprem; /* If the anchors are equal, we keep only one. */ if (l && !strncmp(l, w, wl)) l = NULL; - /* Split the new part into parts and turn the last one into a - * `suffix' if we have a left anchor. */ + /* + * Split the new part into parts and turn the last one into a + * `suffix' if we have a left anchor---don't do this if the last one + * came from a right anchor before the end of the part we're + * splitting. + */ - p = bld_parts(s, sl, osl, &lp); + p = bld_parts(s, sl, osl, &lp, &lprem); - if (m && (m->flags & CMF_LEFT)) { - lp->flags |= CLF_SUF; - lp->suffix = lp->prefix; - lp->prefix = NULL; + if (lprem && m && (m->flags & CMF_LEFT)) { + lprem->flags |= CLF_SUF; + lprem->suffix = lprem->prefix; + lprem->prefix = NULL; } /* cline lists for suffixes are sorted from back to front, so we have * to revert the list we got. */ @@ -418,7 +422,7 @@ add_match_sub(Cmatcher m, char *l, int ll, char *w, int wl) if (wl || ll) { Cline p, lp; - if ((p = n = bld_parts(w, wl, ll, &lp)) && n != lp) { + if ((p = n = bld_parts(w, wl, ll, &lp, NULL)) && n != lp) { for (; p->next != lp; p = p->next); if (matchsubs) { @@ -1019,7 +1023,7 @@ comp_match(char *pfx, char *sfx, char *w, Patprog cp, Cline *clp, int qu, * cline list for these matches, too. */ w = dupstring(w); wl = strlen(w); - *clp = bld_parts(w, wl, wl, NULL); + *clp = bld_parts(w, wl, wl, NULL, NULL); *exact = 0; } else { Cline pli, plil; @@ -1077,7 +1081,7 @@ comp_match(char *pfx, char *sfx, char *w, Patprog cp, Cline *clp, int qu, add_match_str(NULL, NULL, wpfx, wpl, 1); mli = bld_parts(w + rpl, wl - rpl - rsl, - (mpl - rpl) + (msl - rsl), &mlil); + (mpl - rpl) + (msl - rsl), &mlil, NULL); mlil->flags |= CLF_MID; mlil->slen = msl - rsl; mlil->next = revert_cline(matchparts); @@ -1157,11 +1161,19 @@ pattern_match(Cpattern p, char *s, unsigned char *in, unsigned char *out) /* This splits the given string into a list of cline structs, separated * at those places where one of the anchors of an `*' pattern was found. * plen gives the number of characters on the line that matched this - * string. In lp we return a pointer to the last cline struct we build. */ + * string. + * + * In *lp, if lp is not NULL, we return a pointer to the last cline struct we + * build. + * + * In *lprem, if lprem is not NULL, we return a pointer to the last + * cline struct we build if it came from the remainder of the + * line rather than from a right anchor match, else NULL. + */ /**/ Cline -bld_parts(char *str, int len, int plen, Cline *lp) +bld_parts(char *str, int len, int plen, Cline *lp, Cline *lprem) { Cline ret = NULL, *q = &ret, n = NULL; Cmlist ms; @@ -1220,9 +1232,17 @@ bld_parts(char *str, int len, int plen, Cline *lp) if (llen > olen) llen = olen; n->prefix = get_cline(NULL, llen, p, olen, NULL, 0, 0); + if (lprem) + *lprem = n; + } + else if (!ret) { + *q = n = + get_cline(NULL, 0, NULL, 0, NULL, 0, (plen <= 0 ? CLF_NEW : 0)); + if (lprem) + *lprem = n; + } else if (lprem) { + *lprem = NULL; } - else if (!ret) - *q = n = get_cline(NULL, 0, NULL, 0, NULL, 0, (plen <= 0 ? CLF_NEW : 0)); n->next = NULL; -- cgit 1.4.1