aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-01-20 16:57:19 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2013-01-20 16:57:19 +0100
commit2f5b5beb28a3ffe9d12a19b79c453c640cee2f29 (patch)
treecb30f5a4afaa2923bb787f282ad20b004a408d71
parent81fa999540740b5269a349a9e991eb506592ea75 (diff)
downloadbusybox-w32-2f5b5beb28a3ffe9d12a19b79c453c640cee2f29.tar.gz
busybox-w32-2f5b5beb28a3ffe9d12a19b79c453c640cee2f29.tar.bz2
busybox-w32-2f5b5beb28a3ffe9d12a19b79c453c640cee2f29.zip
grep: fix grep -Fw not respecting the -w option. Closes 5792
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--findutils/grep.c37
-rwxr-xr-xtestsuite/grep.tests12
2 files changed, 44 insertions, 5 deletions
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)
344 while (pattern_ptr) { 344 while (pattern_ptr) {
345 gl = (grep_list_data_t *)pattern_ptr->data; 345 gl = (grep_list_data_t *)pattern_ptr->data;
346 if (FGREP_FLAG) { 346 if (FGREP_FLAG) {
347 found |= (((option_mask32 & OPT_i) 347 char *match;
348 ? strcasestr(line, gl->pattern) 348 char *str = line;
349 : strstr(line, gl->pattern) 349 opt_f_again:
350 ) != NULL); 350 match = ((option_mask32 & OPT_i)
351 ? strcasestr(str, gl->pattern)
352 : strstr(str, gl->pattern)
353 );
354 if (match) {
355 if (option_mask32 & OPT_x) {
356 if (match != str)
357 goto opt_f_not_found;
358 if (str[strlen(gl->pattern)] != '\0')
359 goto opt_f_not_found;
360 } else
361 if (option_mask32 & OPT_w) {
362 char c = (match != str) ? match[-1] : ' ';
363 if (!isalnum(c) && c != '_') {
364 c = match[strlen(gl->pattern)];
365 if (!c || (!isalnum(c) && c != '_'))
366 goto opt_f_found;
367 }
368 str = match + 1;
369 goto opt_f_again;
370 }
371 opt_f_found:
372 found = 1;
373 opt_f_not_found: ;
374 }
351 } else { 375 } else {
352 if (!(gl->flg_mem_alocated_compiled & COMPILED)) { 376 if (!(gl->flg_mem_alocated_compiled & COMPILED)) {
353 gl->flg_mem_alocated_compiled |= COMPILED; 377 gl->flg_mem_alocated_compiled |= COMPILED;
@@ -376,7 +400,8 @@ static int grep_file(FILE *file)
376 if (option_mask32 & OPT_x) { 400 if (option_mask32 & OPT_x) {
377 found = (gl->matched_range.rm_so == 0 401 found = (gl->matched_range.rm_so == 0
378 && line[gl->matched_range.rm_eo] == '\0'); 402 && line[gl->matched_range.rm_eo] == '\0');
379 } else if (!(option_mask32 & OPT_w)) { 403 } else
404 if (!(option_mask32 & OPT_w)) {
380 found = 1; 405 found = 1;
381 } else { 406 } else {
382 char c = ' '; 407 char c = ' ';
@@ -387,6 +412,8 @@ static int grep_file(FILE *file)
387 if (!c || (!isalnum(c) && c != '_')) 412 if (!c || (!isalnum(c) && c != '_'))
388 found = 1; 413 found = 1;
389 } 414 }
415//BUG: "echo foop foo | grep -w foo" should match, but doesn't:
416//we bail out on first "mismatch" because it's not a word.
390 } 417 }
391 } 418 }
392 } 419 }
diff --git a/testsuite/grep.tests b/testsuite/grep.tests
index 006a215e1..4781f2284 100755
--- a/testsuite/grep.tests
+++ b/testsuite/grep.tests
@@ -115,6 +115,18 @@ testing "grep -v -f EMPTY_FILE" \
115 "" \ 115 "" \
116 "test\n" 116 "test\n"
117 117
118testing "grep -Fw matches only words" \
119 "grep -Fw foo input" \
120 "" \
121 "foop\n" \
122 ""
123
124testing "grep -Fw doesn't stop on 1st mismatch" \
125 "grep -Fw foo input" \
126 "foop foo\n" \
127 "foop foo\n" \
128 ""
129
118# testing "test name" "commands" "expected result" "file input" "stdin" 130# testing "test name" "commands" "expected result" "file input" "stdin"
119# file input will be file called "input" 131# file input will be file called "input"
120# test can create a file "actual" instead of writing to stdout 132# test can create a file "actual" instead of writing to stdout