grep: -W: don't extend context to trailing empty lines

Empty lines between functions are shown by grep -W, as it considers them
to be part of the function preceding them.  They are not interesting in
most languages.  The previous patches stopped showing them for diff -W.

Stop showing empty lines trailing a function with grep -W.  Grep scans
the lines of a buffer from top to bottom and prints matching lines
immediately.  Thus we need to peek ahead in order to determine if an
empty line is part of a function body and worth showing or not.

Remember how far ahead we peeked in order to avoid having to do so
repeatedly when handling multiple consecutive empty lines.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
René Scharfe 2016-05-28 17:06:19 +02:00 committed by Junio C Hamano
parent 799e09e5fb
commit 4aa2c4753d
2 changed files with 27 additions and 3 deletions

28
grep.c
View File

@ -1396,9 +1396,17 @@ static int fill_textconv_grep(struct userdiff_driver *driver,
return 0;
}
static int is_empty_line(const char *bol, const char *eol)
{
while (bol < eol && isspace(*bol))
bol++;
return bol == eol;
}
static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int collect_hits)
{
char *bol;
char *peek_bol = NULL;
unsigned long left;
unsigned lno = 1;
unsigned last_hit = 0;
@ -1543,8 +1551,24 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
show_function = 1;
goto next_line;
}
if (show_function && match_funcname(opt, gs, bol, eol))
show_function = 0;
if (show_function && (!peek_bol || peek_bol < bol)) {
unsigned long peek_left = left;
char *peek_eol = eol;
/*
* Trailing empty lines are not interesting.
* Peek past them to see if they belong to the
* body of the current function.
*/
peek_bol = bol;
while (is_empty_line(peek_bol, peek_eol)) {
peek_bol = peek_eol + 1;
peek_eol = end_of_line(peek_bol, &peek_left);
}
if (match_funcname(opt, gs, peek_bol, peek_eol))
show_function = 0;
}
if (show_function ||
(last_hit && lno <= last_hit + opt->post_context)) {
/* If the last hit is within the post context,

View File

@ -748,7 +748,7 @@ hello.c-#include <assert.h>
hello.c:#include <stdio.h>
EOF
test_expect_failure 'grep -W shows no trailing empty lines' '
test_expect_success 'grep -W shows no trailing empty lines' '
git grep -W stdio >actual &&
test_cmp expected actual
'