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);  | 
