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>
René Scharfe committed
May 28, 2016 at 17:06 UTC
4aa2c4753d152aef810eaf3f3f4fa1df7035d9b0
2 files changed
+27
-3
grep.c
+26
-2
@@ -1396,9 +1396,17 @@ static int fill_textconv_grep(struct userdiff_driver *driver,
1396
return 0;
1397
}
1398
1399
+static int is_empty_line(const char *bol, const char *eol)
1400
+{
1401
+ while (bol < eol && isspace(*bol))
1402
+ bol++;
1403
+ return bol == eol;
1404
+}
1405
+
1406
static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int collect_hits)
1407
{
1408
char *bol;
1409
+ char *peek_bol = NULL;
1410
unsigned long left;
1411
unsigned lno = 1;
1412
unsigned last_hit = 0;
@@ -1543,8 +1551,24 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
1551
show_function = 1;
1552
goto next_line;
1553
}
1546
- if (show_function && match_funcname(opt, gs, bol, eol))
1547
- show_function = 0;
1554
+ if (show_function && (!peek_bol || peek_bol < bol)) {
1555
+ unsigned long peek_left = left;
1556
+ char *peek_eol = eol;
1557
+
1558
+ /*
1559
+ * Trailing empty lines are not interesting.
1560
+ * Peek past them to see if they belong to the
1561
+ * body of the current function.
1562
+ */
1563
+ peek_bol = bol;
1564
+ while (is_empty_line(peek_bol, peek_eol)) {
1565
+ peek_bol = peek_eol + 1;
1566
+ peek_eol = end_of_line(peek_bol, &peek_left);
1567
+ }
1568
+
1569
+ if (match_funcname(opt, gs, peek_bol, peek_eol))
1570
+ show_function = 0;
1571
+ }
1572
if (show_function ||
1573
(last_hit && lno <= last_hit + opt->post_context)) {
1574
/* If the last hit is within the post context,
t/t7810-grep.sh
+1
-1
@@ -748,7 +748,7 @@ hello.c-#include <assert.h>
748
hello.c:#include <stdio.h>
749
EOF
750
751
-test_expect_failure 'grep -W shows no trailing empty lines' '
751
+test_expect_success 'grep -W shows no trailing empty lines' '
752
git grep -W stdio >actual &&
753
test_cmp expected actual
754
'