From 04ea11b033b38b8cde6e2f478845d0b756c330b4 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 10 Sep 2007 12:18:32 +0000 Subject: grep: fix grep -F -e str1 -e str2 (was matching str2 only) by replacing "=" by "|=" here: found |= strstr(line, gl->pattern) != NULL; grep: optimization: stop on first -e match grep: stop using bss. -40 bytes --- findutils/grep.c | 98 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 37 deletions(-) (limited to 'findutils/grep.c') diff --git a/findutils/grep.c b/findutils/grep.c index c45d0ed89..a051c2f18 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -85,24 +85,43 @@ enum { #define FGREP_FLAG (option_mask32 & OPT_F) #define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & OPT_L) -typedef unsigned char byte_t; - -static int max_matches; -static int reflags; -static byte_t invert_search; -static byte_t print_filename; -static byte_t open_errors; - +struct globals { + int max_matches; + int reflags; + smalluint invert_search; + smalluint print_filename; + smalluint open_errors; #if ENABLE_FEATURE_GREP_CONTEXT -static byte_t did_print_line; -static int lines_before; -static int lines_after; -static char **before_buf; -static int last_line_printed; -#endif /* ENABLE_FEATURE_GREP_CONTEXT */ -/* globals used internally */ -static llist_t *pattern_head; /* growable list of patterns to match */ -static const char *cur_file; /* the current file we are reading */ + smalluint did_print_line; + int lines_before; + int lines_after; + char **before_buf; + int last_line_printed; +#endif + /* globals used internally */ + llist_t *pattern_head; /* growable list of patterns to match */ + const char *cur_file; /* the current file we are reading */ +}; +#define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() \ + do { \ + struct G_sizecheck { \ + char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \ + }; \ + } while (0) +#define max_matches (G.max_matches ) +#define reflags (G.reflags ) +#define invert_search (G.invert_search ) +#define print_filename (G.print_filename ) +#define open_errors (G.open_errors ) +#define did_print_line (G.did_print_line ) +#define lines_before (G.lines_before ) +#define lines_after (G.lines_after ) +#define before_buf (G.before_buf ) +#define last_line_printed (G.last_line_printed ) +#define pattern_head (G.pattern_head ) +#define cur_file (G.cur_file ) + typedef struct grep_list_data_t { char *pattern; @@ -112,6 +131,7 @@ typedef struct grep_list_data_t { int flg_mem_alocated_compiled; } grep_list_data_t; + static void print_line(const char *line, int linenum, char decoration) { #if ENABLE_FEATURE_GREP_CONTEXT @@ -140,7 +160,7 @@ static void print_line(const char *line, int linenum, char decoration) static int grep_file(FILE *file) { char *line; - byte_t ret; + smalluint found; int linenum = 0; int nmatches = 0; regmatch_t regmatch; @@ -154,14 +174,14 @@ static int grep_file(FILE *file) while ((line = xmalloc_getline(file)) != NULL) { llist_t *pattern_ptr = pattern_head; - grep_list_data_t * gl; + grep_list_data_t *gl; linenum++; - ret = 0; + found = 0; while (pattern_ptr) { gl = (grep_list_data_t *)pattern_ptr->data; if (FGREP_FLAG) { - ret = strstr(line, gl->pattern) != NULL; + found |= strstr(line, gl->pattern) != NULL; } else { /* * test for a postitive-assertion match (regexec returns success (0) @@ -177,7 +197,7 @@ static int grep_file(FILE *file) regmatch.rm_eo = 0; if (regexec(&(gl->preg), line, 1, ®match, 0) == 0) { if (!(option_mask32 & OPT_w)) - ret = 1; + found = 1; else { char c = ' '; if (regmatch.rm_so) @@ -185,15 +205,20 @@ static int grep_file(FILE *file) if (!isalnum(c) && c != '_') { c = line[regmatch.rm_eo]; if (!c || (!isalnum(c) && c != '_')) - ret = 1; + found = 1; } } } } + /* If it's non-inverted search, we can stop + * at first match */ + if (found && !invert_search) + goto do_found; pattern_ptr = pattern_ptr->link; } /* while (pattern_ptr) */ - if (ret ^ invert_search) { + if (found ^ invert_search) { + do_found: /* keep track of matches */ nmatches++; @@ -310,18 +335,18 @@ static int grep_file(FILE *file) #if ENABLE_FEATURE_CLEAN_UP #define new_grep_list_data(p, m) add_grep_list_data(p, m) -static char * add_grep_list_data(char *pattern, int flg_used_mem) +static char *add_grep_list_data(char *pattern, int flg_used_mem) #else #define new_grep_list_data(p, m) add_grep_list_data(p) -static char * add_grep_list_data(char *pattern) +static char *add_grep_list_data(char *pattern) #endif { - grep_list_data_t *gl = xmalloc(sizeof(grep_list_data_t)); + grep_list_data_t *gl = xzalloc(sizeof(*gl)); gl->pattern = pattern; #if ENABLE_FEATURE_CLEAN_UP gl->flg_mem_alocated_compiled = flg_used_mem; #else - gl->flg_mem_alocated_compiled = 0; + /*gl->flg_mem_alocated_compiled = 0;*/ #endif return (char *)gl; } @@ -443,9 +468,11 @@ int grep_main(int argc, char **argv) if (!(option_mask32 & (OPT_o | OPT_w))) reflags = REG_NOSUB; - if (ENABLE_FEATURE_GREP_EGREP_ALIAS && - (applet_name[0] == 'e' || (option_mask32 & OPT_E))) + if (ENABLE_FEATURE_GREP_EGREP_ALIAS + && (applet_name[0] == 'e' || (option_mask32 & OPT_E)) + ) { reflags |= REG_EXTENDED; + } if (option_mask32 & OPT_i) reflags |= REG_ICASE; @@ -476,10 +503,8 @@ int grep_main(int argc, char **argv) /* If no files were specified, or '-' was specified, take input from * stdin. Otherwise, we grep through all the files specified. */ - if (argc == 0) - argc++; matched = 0; - while (argc--) { + do { cur_file = *argv++; file = stdin; if (!cur_file || (*cur_file == '-' && !cur_file[1])) { @@ -506,14 +531,13 @@ int grep_main(int argc, char **argv) matched += grep_file(file); fclose_if_not_stdin(file); grep_done: ; - } + } while (--argc > 0); /* destroy all the elments in the pattern list */ if (ENABLE_FEATURE_CLEAN_UP) { while (pattern_head) { llist_t *pattern_head_ptr = pattern_head; - grep_list_data_t *gl = - (grep_list_data_t *)pattern_head_ptr->data; + grep_list_data_t *gl = (grep_list_data_t *)pattern_head_ptr->data; pattern_head = pattern_head->link; if ((gl->flg_mem_alocated_compiled & PATTERN_MEM_A)) @@ -527,5 +551,5 @@ int grep_main(int argc, char **argv) /* 0 = success, 1 = failed, 2 = error */ if (open_errors) return 2; - return !matched; /* invert return value 0 = success, 1 = failed */ + return !matched; /* invert return value: 0 = success, 1 = failed */ } -- cgit v1.2.3