[git commit] grep: don't bail out on first mismatch if '-w' option is set

Denys Vlasenko vda.linux at googlemail.com
Wed May 15 07:20:40 UTC 2013


commit: http://git.busybox.net/busybox/commit/?id=414db791d0dc79905e5afe20e503941b8f9778cc
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Bartosz Golaszewski <bartekgola at gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 findutils/grep.c     |   22 ++++++++++++++--------
 testsuite/grep.tests |    6 ++++++
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/findutils/grep.c b/findutils/grep.c
index 70f3516..b808ad9 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -373,6 +373,8 @@ static int grep_file(FILE *file)
  opt_f_not_found: ;
 				}
 			} else {
+				char *match_at;
+
 				if (!(gl->flg_mem_alocated_compiled & COMPILED)) {
 					gl->flg_mem_alocated_compiled |= COMPILED;
 #if !ENABLE_EXTRA_COMPAT
@@ -388,32 +390,36 @@ static int grep_file(FILE *file)
 				gl->matched_range.rm_so = 0;
 				gl->matched_range.rm_eo = 0;
 #endif
+				match_at = line;
+ opt_w_again:
 				if (
 #if !ENABLE_EXTRA_COMPAT
-					regexec(&gl->compiled_regex, line, 1, &gl->matched_range, 0) == 0
+					regexec(&gl->compiled_regex, match_at, 1, &gl->matched_range, 0) == 0
 #else
-					re_search(&gl->compiled_regex, line, line_len,
+					re_search(&gl->compiled_regex, match_at, line_len,
 							/*start:*/ 0, /*range:*/ line_len,
 							&gl->matched_range) >= 0
 #endif
 				) {
 					if (option_mask32 & OPT_x) {
 						found = (gl->matched_range.rm_so == 0
-						         && line[gl->matched_range.rm_eo] == '\0');
+						         && match_at[gl->matched_range.rm_eo] == '\0');
 					} else
 					if (!(option_mask32 & OPT_w)) {
 						found = 1;
 					} else {
 						char c = ' ';
 						if (gl->matched_range.rm_so)
-							c = line[gl->matched_range.rm_so - 1];
+							c = match_at[gl->matched_range.rm_so - 1];
 						if (!isalnum(c) && c != '_') {
-							c = line[gl->matched_range.rm_eo];
-							if (!c || (!isalnum(c) && c != '_'))
+							c = match_at[gl->matched_range.rm_eo];
+							if (!c || (!isalnum(c) && c != '_')) {
 								found = 1;
+							} else {
+								match_at += gl->matched_range.rm_eo;
+								goto opt_w_again;
+							}
 						}
-//BUG: "echo foop foo | grep -w foo" should match, but doesn't:
-//we bail out on first "mismatch" because it's not a word.
 					}
 				}
 			}
diff --git a/testsuite/grep.tests b/testsuite/grep.tests
index 4781f22..5696fa7 100755
--- a/testsuite/grep.tests
+++ b/testsuite/grep.tests
@@ -127,6 +127,12 @@ testing "grep -Fw doesn't stop on 1st mismatch" \
 	"foop foo\n" \
 	""
 
+testing "grep -w doesn't stop on 1st mismatch" \
+	"grep -w foo input" \
+	"foop foo\n" \
+	"foop foo\n" \
+	""
+
 # testing "test name" "commands" "expected result" "file input" "stdin"
 #   file input will be file called "input"
 #   test can create a file "actual" instead of writing to stdout


More information about the busybox-cvs mailing list