From 2f5b5beb28a3ffe9d12a19b79c453c640cee2f29 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 20 Jan 2013 16:57:19 +0100 Subject: grep: fix grep -Fw not respecting the -w option. Closes 5792 Signed-off-by: Denys Vlasenko --- findutils/grep.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'findutils/grep.c') diff --git a/findutils/grep.c b/findutils/grep.c index de4fcf5ad..70f3516a5 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -344,10 +344,34 @@ static int grep_file(FILE *file) while (pattern_ptr) { gl = (grep_list_data_t *)pattern_ptr->data; if (FGREP_FLAG) { - found |= (((option_mask32 & OPT_i) - ? strcasestr(line, gl->pattern) - : strstr(line, gl->pattern) - ) != NULL); + char *match; + char *str = line; + opt_f_again: + match = ((option_mask32 & OPT_i) + ? strcasestr(str, gl->pattern) + : strstr(str, gl->pattern) + ); + if (match) { + if (option_mask32 & OPT_x) { + if (match != str) + goto opt_f_not_found; + if (str[strlen(gl->pattern)] != '\0') + goto opt_f_not_found; + } else + if (option_mask32 & OPT_w) { + char c = (match != str) ? match[-1] : ' '; + if (!isalnum(c) && c != '_') { + c = match[strlen(gl->pattern)]; + if (!c || (!isalnum(c) && c != '_')) + goto opt_f_found; + } + str = match + 1; + goto opt_f_again; + } + opt_f_found: + found = 1; + opt_f_not_found: ; + } } else { if (!(gl->flg_mem_alocated_compiled & COMPILED)) { gl->flg_mem_alocated_compiled |= COMPILED; @@ -376,7 +400,8 @@ static int grep_file(FILE *file) if (option_mask32 & OPT_x) { found = (gl->matched_range.rm_so == 0 && line[gl->matched_range.rm_eo] == '\0'); - } else if (!(option_mask32 & OPT_w)) { + } else + if (!(option_mask32 & OPT_w)) { found = 1; } else { char c = ' '; @@ -387,6 +412,8 @@ static int grep_file(FILE *file) if (!c || (!isalnum(c) && c != '_')) found = 1; } +//BUG: "echo foop foo | grep -w foo" should match, but doesn't: +//we bail out on first "mismatch" because it's not a word. } } } -- cgit v1.2.3