diff options
| author | Daniel C. Sobral <dcs@FreeBSD.org> | 2000-07-31 06:30:37 +0000 |
|---|---|---|
| committer | Daniel C. Sobral <dcs@FreeBSD.org> | 2000-07-31 06:30:37 +0000 |
| commit | c2861446f004ff028acd2c3366c7500bf7538d58 (patch) | |
| tree | 374d245e893e4c27daa9c968ab9091888b8e227a /lib/libc/regex/engine.c | |
| parent | 1b139adb86a606c36a71bb5a7698a8c6ca9ff976 (diff) | |
Notes
Diffstat (limited to 'lib/libc/regex/engine.c')
| -rw-r--r-- | lib/libc/regex/engine.c | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/lib/libc/regex/engine.c b/lib/libc/regex/engine.c index be569b19afe7..04844ba6f437 100644 --- a/lib/libc/regex/engine.c +++ b/lib/libc/regex/engine.c @@ -35,6 +35,8 @@ * SUCH DAMAGE. * * @(#)engine.c 8.5 (Berkeley) 3/20/94 + * + * $FreeBSD$ */ /* @@ -152,6 +154,13 @@ int eflags; register const sopno gl = g->laststate; char *start; char *stop; + /* Boyer-Moore algorithms variables */ + register char *pp; + int cj, mj; + register char *mustfirst; + register char *mustlast; + register int *matchjump; + register int *charjump; /* simplify the situation where possible */ if (g->cflags®_NOSUB) @@ -168,12 +177,46 @@ int eflags; /* prescreening; this does wonders for this rather slow code */ if (g->must != NULL) { - for (dp = start; dp < stop; dp++) - if (*dp == g->must[0] && stop - dp >= g->mlen && - memcmp(dp, g->must, (size_t)g->mlen) == 0) - break; - if (dp == stop) /* we didn't find g->must */ - return(REG_NOMATCH); + if (g->charjump != NULL && g->matchjump != NULL) { + mustfirst = g->must; + mustlast = g->must + g->mlen - 1; + charjump = g->charjump; + matchjump = g->matchjump; + pp = mustlast; + for (dp = start+g->mlen-1; dp < stop;) { + /* Fast skip non-matches */ + while (dp < stop && charjump[*dp]) + dp += charjump[*dp]; + + if (dp >= stop) + break; + + /* Greedy matcher */ + /* We depend on not being used for + * for strings of length 1 + */ + while (*--dp == *--pp && pp != mustfirst); + + if (*dp == *pp) + break; + + /* Jump to next possible match */ + mj = matchjump[pp - mustfirst]; + cj = charjump[*dp]; + dp += (cj < mj ? mj : cj); + pp = mustlast; + } + if (pp != mustfirst) + return(REG_NOMATCH); + } else { + for (dp = start; dp < stop; dp++) + if (*dp == g->must[0] && + stop - dp >= g->mlen && + memcmp(dp, g->must, (size_t)g->mlen) == 0) + break; + if (dp == stop) /* we didn't find g->must */ + return(REG_NOMATCH); + } } /* match struct setup */ @@ -191,6 +234,10 @@ int eflags; SETUP(m->empty); CLEAR(m->empty); + /* Adjust start according to moffset, to speed things up */ + if (g->moffset > -1) + start = ((dp - g->moffset) < start) ? start : dp - g->moffset; + /* this loop does only one repetition except for backrefs */ for (;;) { endp = fast(m, start, stop, gf, gl); |
