[RFC/PATCH] Fix "grep -w"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We used to find the first match of the pattern and then if the
match is not for the entire word, declared that the whole line
does not match.

But that is wrong.  The command "git grep -w -e mmap" should
find that a line "foo_mmap bar mmap baz" matches, by tring the
second instance of pattern "mmap" on the same line.

Signed-off-by: Junio C Hamano <junkio@xxxxxxx>

---

 builtin-grep.c  |   10 ++++++++++
 t/t7002-grep.sh |   45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/builtin-grep.c b/builtin-grep.c
index 69b7c48..b5feda4 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -412,6 +412,7 @@ static int match_one_pattern(struct grep
 	int hit = 0;
 	regmatch_t pmatch[10];
 
+ again:
 	if (!opt->fixed) {
 		regex_t *exp = &p->regexp;
 		hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
@@ -438,6 +439,15 @@ static int match_one_pattern(struct grep
 		if (pmatch[0].rm_eo != (eol-bol) &&
 		    word_char(bol[pmatch[0].rm_eo]))
 			hit = 0;
+
+		if (!hit && pmatch[0].rm_eo + bol < eol) {
+			/* there could be more than one match on the
+			 * line, and the first match might not be
+			 * strict word match.  But later ones could be!
+			 */
+			bol += pmatch[0].rm_eo;
+			goto again;
+		}
 	}
 	return hit;
 }
diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh
new file mode 100755
index 0000000..0a0e302
--- /dev/null
+++ b/t/t7002-grep.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Junio C Hamano
+#
+
+test_description='git grep -w
+'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	{
+		echo foo mmap bar
+		echo foo_mmap bar
+		echo foo_mmap bar mmap
+		echo foo mmap bar_mmap
+		echo foo_mmap bar mmap baz
+	} >file &&
+	git add file &&
+	git commit -m initial
+'
+
+test_expect_success 'grep -w HEAD' '
+	git grep -n -w -e mmap HEAD >actual &&
+	{
+		echo HEAD:file:1:foo mmap bar
+		echo HEAD:file:3:foo_mmap bar mmap
+		echo HEAD:file:4:foo mmap bar_mmap
+		echo HEAD:file:5:foo_mmap bar mmap baz
+	} >expected &&
+	diff expected actual
+'
+
+test_expect_success 'grep -w in working tree' '
+	git grep -n -w -e mmap >actual &&
+	{
+		echo file:1:foo mmap bar
+		echo file:3:foo_mmap bar mmap
+		echo file:4:foo mmap bar_mmap
+		echo file:5:foo_mmap bar mmap baz
+	} >expected &&
+	diff expected actual
+'
+
+test_done

-
: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]