diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2003-06-23 22:05:24 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2003-06-23 22:05:24 +0000 |
commit | 943ad3c82d880acc9851f5086b4475401e539e42 (patch) | |
tree | e7102624316dbb10b7087ef49e74566a50b23c60 /usr.bin/grep/grep.c | |
parent | 1e3542cd612d942114a8eac614daad44324691a8 (diff) |
faster grep for simple patterns. derived from a patch by sean farley.
this makes searching for constant strings much faster by avoiding regex.
ok deraadt@
Diffstat (limited to 'usr.bin/grep/grep.c')
-rw-r--r-- | usr.bin/grep/grep.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/usr.bin/grep/grep.c b/usr.bin/grep/grep.c index ffc333d817b..bc75324af47 100644 --- a/usr.bin/grep/grep.c +++ b/usr.bin/grep/grep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grep.c,v 1.12 2003/06/23 07:52:18 deraadt Exp $ */ +/* $OpenBSD: grep.c,v 1.13 2003/06/23 22:05:23 tedu Exp $ */ /*- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav @@ -49,6 +49,7 @@ int matchall; /* shortcut */ int patterns, pattern_sz; char **pattern; regex_t *r_pattern; +fastgrep_t *fg_pattern; /* For regex errors */ char re_error[RE_ERROR_BUF + 1]; @@ -93,6 +94,8 @@ enum { int first; /* flag whether or not this is our first match */ int tail; /* lines left to print */ int lead; /* number of lines in leading context queue */ +int boleol; /* At least one pattern has a bol or eol */ +int maxPatternLen; /* Longest length of all patterns */ extern char *__progname; @@ -163,13 +166,16 @@ add_pattern(char *pat, size_t len) } if (patterns == pattern_sz) { pattern_sz *= 2; - pattern = grep_realloc(pattern, ++pattern_sz); + pattern = grep_realloc(pattern, ++pattern_sz * sizeof(int)); } if (pat[len - 1] == '\n') --len; pattern[patterns] = grep_malloc(len + 1); strlcpy(pattern[patterns], pat, len + 1); ++patterns; + + if (len > maxPatternLen) + maxPatternLen = len; } static void @@ -200,6 +206,24 @@ read_patterns(char *fn) fclose(f); } +static void +free_patterns(void) +{ + int i; + + for (i = 0; i < patterns; i++) { + if (fg_pattern[i].pattern) + free(fg_pattern[i].pattern); + else + regfree(&r_pattern[i]); + free(pattern[i]); + } + + free(fg_pattern); + free(r_pattern); + free(pattern); +} + int main(int argc, char *argv[]) { @@ -293,6 +317,7 @@ main(int argc, char *argv[]) break; case 'i': case 'y': + iflag = 1; cflags |= REG_ICASE; break; case 'l': @@ -382,11 +407,17 @@ main(int argc, char *argv[]) } cflags |= Eflag ? REG_EXTENDED : REG_BASIC; + fg_pattern = grep_malloc(patterns * sizeof(*fg_pattern)); r_pattern = grep_malloc(patterns * sizeof(regex_t)); for (i = 0; i < patterns; ++i) { - if ((c = regcomp(&r_pattern[i], pattern[i], cflags))) { - regerror(c, &r_pattern[i], re_error, RE_ERROR_BUF); - errx(1, "%s", re_error); + /* Check if cheating is allowed */ + if (fastcomp(&fg_pattern[i], pattern[i])) { + /* Fall back to full regex library */ + if ((c = regcomp(&r_pattern[i], pattern[i], cflags))) { + regerror(c, &r_pattern[i], re_error, + RE_ERROR_BUF); + errx(1, "%s", re_error); + } } } @@ -402,5 +433,7 @@ main(int argc, char *argv[]) for (c = 0; argc--; ++argv) c += procfile(*argv); + free_patterns(); + exit(!c); } |