diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-01-20 16:57:19 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-01-20 16:57:19 +0100 |
commit | 2f5b5beb28a3ffe9d12a19b79c453c640cee2f29 (patch) | |
tree | cb30f5a4afaa2923bb787f282ad20b004a408d71 | |
parent | 81fa999540740b5269a349a9e991eb506592ea75 (diff) | |
download | busybox-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.c | 37 | ||||
-rwxr-xr-x | testsuite/grep.tests | 12 |
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 | ||
118 | testing "grep -Fw matches only words" \ | ||
119 | "grep -Fw foo input" \ | ||
120 | "" \ | ||
121 | "foop\n" \ | ||
122 | "" | ||
123 | |||
124 | testing "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 |