grep: use REG_STARTEND for all matching if available
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>
Sat, 22 May 2010 21:35:07 +0000 (23:35 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 24 May 2010 18:22:07 +0000 (11:22 -0700)
Refactor REG_STARTEND handling inlook_ahead() into a new helper,
regmatch(), and use it for line matching, too. This allows regex
matching beyond NUL characters if regexec() supports the flag. NUL
characters themselves are not matched in any way, though.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
grep.c
t/t7008-grep-binary.sh
diff --git a/grep.c b/grep.c
index b95803bbb19a9094dae1d84b214ed04005ab9019..70a776f6fece05687bd684aeb7047615aa5a0064 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -356,6 +356,17 @@ static int fixmatch(const char *pattern, char *line, char *eol,
        }
 }
 
+static int regmatch(const regex_t *preg, char *line, char *eol,
+                   regmatch_t *match, int eflags)
+{
+#ifdef REG_STARTEND
+       match->rm_so = 0;
+       match->rm_eo = eol - line;
+       eflags |= REG_STARTEND;
+#endif
+       return regexec(preg, line, 1, match, eflags);
+}
+
 static int strip_timestamp(char *bol, char **eol_p)
 {
        char *eol = *eol_p;
@@ -408,7 +419,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
        if (p->fixed)
                hit = !fixmatch(p->pattern, bol, eol, p->ignore_case, pmatch);
        else
-               hit = !regexec(&p->regexp, bol, 1, pmatch, eflags);
+               hit = !regmatch(&p->regexp, bol, eol, pmatch, eflags);
 
        if (hit && p->word_regexp) {
                if ((pmatch[0].rm_so < 0) ||
@@ -735,15 +746,8 @@ static int look_ahead(struct grep_opt *opt,
                if (p->fixed) {
                        hit = !fixmatch(p->pattern, bol, bol + *left_p,
                                        p->ignore_case, &m);
-               } else {
-#ifdef REG_STARTEND
-                       m.rm_so = 0;
-                       m.rm_eo = *left_p;
-                       hit = !regexec(&p->regexp, bol, 1, &m, REG_STARTEND);
-#else
-                       hit = !regexec(&p->regexp, bol, 1, &m, 0);
-#endif
-               }
+               } else
+                       hit = !regmatch(&p->regexp, bol, bol + *left_p, &m, 0);
                if (!hit || m.rm_so < 0 || m.rm_eo < 0)
                        continue;
                if (earliest < 0 || m.rm_so < earliest)
index 9660842c446f78b4b35fa9162235753a85eeee9f..4f5e74fed77a484c4c0b7bd9de7f0b95cf714a22 100755 (executable)
@@ -59,4 +59,14 @@ test_expect_success 'git grep -Fi iLE a' '
        git grep -Fi iLE a
 '
 
+# This test actually passes on platforms where regexec() supports the
+# flag REG_STARTEND.
+test_expect_failure 'git grep ile a' '
+       git grep ile a
+'
+
+test_expect_failure 'git grep .fi a' '
+       git grep .fi a
+'
+
 test_done