This fixes bug 4520: 'grep -w fails when pattern is a strict substring
of a word'. If '-w' option is set - grep will retry to match against
the rest of the string after it finds a match not enclosed by delimiting
symbols.

Signed-off-by: Bartosz Golaszewski <bartekg...@gmail.com>
---
 findutils/grep.c |   25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/findutils/grep.c b/findutils/grep.c
index 70f3516..fe8dab8 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -312,10 +312,9 @@ static int grep_file(FILE *file)
        smalluint found;
        int linenum = 0;
        int nmatches = 0;
-#if !ENABLE_EXTRA_COMPAT
-       char *line;
-#else
        char *line = NULL;
+       char *lineptr = NULL;
+#if ENABLE_EXTRA_COMPAT
        ssize_t line_len;
        size_t line_alloc_len;
 # define rm_so start[0]
@@ -388,32 +387,36 @@ static int grep_file(FILE *file)
                                gl->matched_range.rm_so = 0;
                                gl->matched_range.rm_eo = 0;
 #endif
+                               lineptr = line;
+ opt_w_again:
                                if (
 #if !ENABLE_EXTRA_COMPAT
-                                       regexec(&gl->compiled_regex, line, 1, 
&gl->matched_range, 0) == 0
+                                       regexec(&gl->compiled_regex, lineptr, 
1, &gl->matched_range, 0) == 0
 #else
-                                       re_search(&gl->compiled_regex, line, 
line_len,
+                                       re_search(&gl->compiled_regex, lineptr, 
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');
+                                                                && 
lineptr[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 = 
lineptr[gl->matched_range.rm_so - 1];
                                                if (!isalnum(c) && c != '_') {
-                                                       c = 
line[gl->matched_range.rm_eo];
-                                                       if (!c || (!isalnum(c) 
&& c != '_'))
+                                                       c = 
lineptr[gl->matched_range.rm_eo];
+                                                       if (!c || (!isalnum(c) 
&& c != '_')) {
                                                                found = 1;
+                                                       } else {
+                                                               lineptr += 
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.
                                        }
                                }
                        }
-- 
1.7.10.4

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to