Skip to content

Commit f034901

Browse files
committed
Merge branch 'rs/include-comments-before-the-function-header'
"git grep -W", "git diff -W" and their friends learned a heuristic to extend a pre-context beyond the line that matches the "function pattern" (aka "diff.*.xfuncname") to include a comment block, if exists, that immediately precedes it. * rs/include-comments-before-the-function-header: grep: show non-empty lines before functions with -W grep: update boundary variable for pre-context t7810: improve check of -W with user-defined function lines xdiff: show non-empty lines before functions with -W xdiff: factor out is_func_rec() t4051: add test for comments preceding function lines
2 parents 3b49e1b + a5dc20b commit f034901

File tree

5 files changed

+76
-20
lines changed

5 files changed

+76
-20
lines changed

grep.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,31 +1476,52 @@ static void show_funcname_line(struct grep_opt *opt, struct grep_source *gs,
14761476
}
14771477
}
14781478

1479+
static int is_empty_line(const char *bol, const char *eol);
1480+
14791481
static void show_pre_context(struct grep_opt *opt, struct grep_source *gs,
14801482
char *bol, char *end, unsigned lno)
14811483
{
1482-
unsigned cur = lno, from = 1, funcname_lno = 0;
1483-
int funcname_needed = !!opt->funcname;
1484-
1485-
if (opt->funcbody && !match_funcname(opt, gs, bol, end))
1486-
funcname_needed = 2;
1484+
unsigned cur = lno, from = 1, funcname_lno = 0, orig_from;
1485+
int funcname_needed = !!opt->funcname, comment_needed = 0;
14871486

14881487
if (opt->pre_context < lno)
14891488
from = lno - opt->pre_context;
14901489
if (from <= opt->last_shown)
14911490
from = opt->last_shown + 1;
1491+
orig_from = from;
1492+
if (opt->funcbody) {
1493+
if (match_funcname(opt, gs, bol, end))
1494+
comment_needed = 1;
1495+
else
1496+
funcname_needed = 1;
1497+
from = opt->last_shown + 1;
1498+
}
14921499

14931500
/* Rewind. */
1494-
while (bol > gs->buf &&
1495-
cur > (funcname_needed == 2 ? opt->last_shown + 1 : from)) {
1501+
while (bol > gs->buf && cur > from) {
1502+
char *next_bol = bol;
14961503
char *eol = --bol;
14971504

14981505
while (bol > gs->buf && bol[-1] != '\n')
14991506
bol--;
15001507
cur--;
1508+
if (comment_needed && (is_empty_line(bol, eol) ||
1509+
match_funcname(opt, gs, bol, eol))) {
1510+
comment_needed = 0;
1511+
from = orig_from;
1512+
if (cur < from) {
1513+
cur++;
1514+
bol = next_bol;
1515+
break;
1516+
}
1517+
}
15011518
if (funcname_needed && match_funcname(opt, gs, bol, eol)) {
15021519
funcname_lno = cur;
15031520
funcname_needed = 0;
1521+
if (opt->funcbody)
1522+
comment_needed = 1;
1523+
else
1524+
from = orig_from;
15041525
}
15051526
}
15061527

t/t4051-diff-function-context.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ test_expect_success 'setup' '
8585

8686
check_diff changed_hello 'changed function'
8787

88+
test_expect_success ' context includes comment' '
89+
grep "^ .*Hello comment" changed_hello.diff
90+
'
91+
8892
test_expect_success ' context includes begin' '
8993
grep "^ .*Begin of hello" changed_hello.diff
9094
'

t/t4051/hello.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11

2+
/*
3+
* Hello comment.
4+
*/
25
static void hello(void) // Begin of hello
36
{
47
/*

t/t7810-grep.sh

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ test_expect_success setup '
6060
echo " line with leading space3"
6161
echo "line without leading space2"
6262
} >space &&
63+
cat >hello.ps1 <<-\EOF &&
64+
# No-op.
65+
function dummy() {}
66+
67+
# Say hello.
68+
function hello() {
69+
echo "Hello world."
70+
} # hello
71+
72+
# Still a no-op.
73+
function dummy() {}
74+
EOF
6375
git add . &&
6476
test_tick &&
6577
git commit -m initial
@@ -766,18 +778,27 @@ test_expect_success 'grep -W shows no trailing empty lines' '
766778
test_cmp expected actual
767779
'
768780

769-
cat >expected <<EOF
770-
hello.c= printf("Hello world.\n");
771-
hello.c: return 0;
772-
hello.c- /* char ?? */
773-
EOF
774-
775781
test_expect_success 'grep -W with userdiff' '
776782
test_when_finished "rm -f .gitattributes" &&
777-
git config diff.custom.xfuncname "(printf.*|})$" &&
778-
echo "hello.c diff=custom" >.gitattributes &&
779-
git grep -W return >actual &&
780-
test_cmp expected actual
783+
git config diff.custom.xfuncname "^function .*$" &&
784+
echo "hello.ps1 diff=custom" >.gitattributes &&
785+
git grep -W echo >function-context-userdiff-actual
786+
'
787+
788+
test_expect_success ' includes preceding comment' '
789+
grep "# Say hello" function-context-userdiff-actual
790+
'
791+
792+
test_expect_success ' includes function line' '
793+
grep "=function hello" function-context-userdiff-actual
794+
'
795+
796+
test_expect_success ' includes matching line' '
797+
grep ": echo" function-context-userdiff-actual
798+
'
799+
800+
test_expect_success ' includes last line of the function' '
801+
grep "} # hello" function-context-userdiff-actual
781802
'
782803

783804
for threads in $(test_seq 0 10)

xdiff/xemit.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ static long match_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri,
121121
return xecfg->find_func(rec, len, buf, sz, xecfg->find_func_priv);
122122
}
123123

124+
static int is_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri)
125+
{
126+
char dummy[1];
127+
return match_func_rec(xdf, xecfg, ri, dummy, sizeof(dummy)) >= 0;
128+
}
129+
124130
struct func_line {
125131
long len;
126132
char buf[80];
@@ -178,16 +184,14 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
178184

179185
/* Appended chunk? */
180186
if (i1 >= xe->xdf1.nrec) {
181-
char dummy[1];
182187
long i2 = xch->i2;
183188

184189
/*
185190
* We don't need additional context if
186191
* a whole function was added.
187192
*/
188193
while (i2 < xe->xdf2.nrec) {
189-
if (match_func_rec(&xe->xdf2, xecfg, i2,
190-
dummy, sizeof(dummy)) >= 0)
194+
if (is_func_rec(&xe->xdf2, xecfg, i2))
191195
goto post_context_calculation;
192196
i2++;
193197
}
@@ -200,6 +204,9 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
200204
}
201205

202206
fs1 = get_func_line(xe, xecfg, NULL, i1, -1);
207+
while (fs1 > 0 && !is_empty_rec(&xe->xdf1, fs1 - 1) &&
208+
!is_func_rec(&xe->xdf1, xecfg, fs1 - 1))
209+
fs1--;
203210
if (fs1 < 0)
204211
fs1 = 0;
205212
if (fs1 < s1) {

0 commit comments

Comments
 (0)