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 |
