grep: use REG_STARTEND for all matching if available

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>
This commit is contained in:
René Scharfe 2010-05-22 23:35:07 +02:00 коммит произвёл Junio C Hamano
Родитель 52d799a79f
Коммит f96e56733a
2 изменённых файлов: 24 добавлений и 10 удалений

24
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) static int strip_timestamp(char *bol, char **eol_p)
{ {
char *eol = *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) if (p->fixed)
hit = !fixmatch(p->pattern, bol, eol, p->ignore_case, pmatch); hit = !fixmatch(p->pattern, bol, eol, p->ignore_case, pmatch);
else else
hit = !regexec(&p->regexp, bol, 1, pmatch, eflags); hit = !regmatch(&p->regexp, bol, eol, pmatch, eflags);
if (hit && p->word_regexp) { if (hit && p->word_regexp) {
if ((pmatch[0].rm_so < 0) || if ((pmatch[0].rm_so < 0) ||
@ -735,15 +746,8 @@ static int look_ahead(struct grep_opt *opt,
if (p->fixed) { if (p->fixed) {
hit = !fixmatch(p->pattern, bol, bol + *left_p, hit = !fixmatch(p->pattern, bol, bol + *left_p,
p->ignore_case, &m); p->ignore_case, &m);
} else { } else
#ifdef REG_STARTEND hit = !regmatch(&p->regexp, bol, bol + *left_p, &m, 0);
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
}
if (!hit || m.rm_so < 0 || m.rm_eo < 0) if (!hit || m.rm_so < 0 || m.rm_eo < 0)
continue; continue;
if (earliest < 0 || m.rm_so < earliest) if (earliest < 0 || m.rm_so < earliest)

Просмотреть файл

@ -59,4 +59,14 @@ test_expect_success 'git grep -Fi iLE a' '
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 test_done