diff options
author | Junio C Hamano <gitster@pobox.com> | 2017-11-28 13:41:50 +0900 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-11-28 13:41:50 +0900 |
commit | f03490164811f19c8d2222a658398d67b14e905d (patch) | |
tree | 0427ffa7fee9b19daeb2bf0c92986a27ea9724d2 | |
parent | Merge branch 'ma/branch-list-paginate' (diff) | |
parent | grep: show non-empty lines before functions with -W (diff) | |
download | tgif-f03490164811f19c8d2222a658398d67b14e905d.tar.xz |
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
-rw-r--r-- | grep.c | 35 | ||||
-rwxr-xr-x | t/t4051-diff-function-context.sh | 4 | ||||
-rw-r--r-- | t/t4051/hello.c | 3 | ||||
-rwxr-xr-x | t/t7810-grep.sh | 41 | ||||
-rw-r--r-- | xdiff/xemit.c | 13 |
5 files changed, 76 insertions, 20 deletions
@@ -1476,31 +1476,52 @@ static void show_funcname_line(struct grep_opt *opt, struct grep_source *gs, } } +static int is_empty_line(const char *bol, const char *eol); + static void show_pre_context(struct grep_opt *opt, struct grep_source *gs, char *bol, char *end, unsigned lno) { - unsigned cur = lno, from = 1, funcname_lno = 0; - int funcname_needed = !!opt->funcname; - - if (opt->funcbody && !match_funcname(opt, gs, bol, end)) - funcname_needed = 2; + unsigned cur = lno, from = 1, funcname_lno = 0, orig_from; + int funcname_needed = !!opt->funcname, comment_needed = 0; if (opt->pre_context < lno) from = lno - opt->pre_context; if (from <= opt->last_shown) from = opt->last_shown + 1; + orig_from = from; + if (opt->funcbody) { + if (match_funcname(opt, gs, bol, end)) + comment_needed = 1; + else + funcname_needed = 1; + from = opt->last_shown + 1; + } /* Rewind. */ - while (bol > gs->buf && - cur > (funcname_needed == 2 ? opt->last_shown + 1 : from)) { + while (bol > gs->buf && cur > from) { + char *next_bol = bol; char *eol = --bol; while (bol > gs->buf && bol[-1] != '\n') bol--; cur--; + if (comment_needed && (is_empty_line(bol, eol) || + match_funcname(opt, gs, bol, eol))) { + comment_needed = 0; + from = orig_from; + if (cur < from) { + cur++; + bol = next_bol; + break; + } + } if (funcname_needed && match_funcname(opt, gs, bol, eol)) { funcname_lno = cur; funcname_needed = 0; + if (opt->funcbody) + comment_needed = 1; + else + from = orig_from; } } diff --git a/t/t4051-diff-function-context.sh b/t/t4051-diff-function-context.sh index 3e6b485ecb..2d76a971c4 100755 --- a/t/t4051-diff-function-context.sh +++ b/t/t4051-diff-function-context.sh @@ -85,6 +85,10 @@ test_expect_success 'setup' ' check_diff changed_hello 'changed function' +test_expect_success ' context includes comment' ' + grep "^ .*Hello comment" changed_hello.diff +' + test_expect_success ' context includes begin' ' grep "^ .*Begin of hello" changed_hello.diff ' diff --git a/t/t4051/hello.c b/t/t4051/hello.c index 63b1a1e4ef..73e767e178 100644 --- a/t/t4051/hello.c +++ b/t/t4051/hello.c @@ -1,4 +1,7 @@ +/* + * Hello comment. + */ static void hello(void) // Begin of hello { /* diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 2a6679c2f5..c02ca735b9 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -60,6 +60,18 @@ test_expect_success setup ' echo " line with leading space3" echo "line without leading space2" } >space && + cat >hello.ps1 <<-\EOF && + # No-op. + function dummy() {} + + # Say hello. + function hello() { + echo "Hello world." + } # hello + + # Still a no-op. + function dummy() {} + EOF git add . && test_tick && git commit -m initial @@ -766,18 +778,27 @@ test_expect_success 'grep -W shows no trailing empty lines' ' test_cmp expected actual ' -cat >expected <<EOF -hello.c= printf("Hello world.\n"); -hello.c: return 0; -hello.c- /* char ?? */ -EOF - test_expect_success 'grep -W with userdiff' ' test_when_finished "rm -f .gitattributes" && - git config diff.custom.xfuncname "(printf.*|})$" && - echo "hello.c diff=custom" >.gitattributes && - git grep -W return >actual && - test_cmp expected actual + git config diff.custom.xfuncname "^function .*$" && + echo "hello.ps1 diff=custom" >.gitattributes && + git grep -W echo >function-context-userdiff-actual +' + +test_expect_success ' includes preceding comment' ' + grep "# Say hello" function-context-userdiff-actual +' + +test_expect_success ' includes function line' ' + grep "=function hello" function-context-userdiff-actual +' + +test_expect_success ' includes matching line' ' + grep ": echo" function-context-userdiff-actual +' + +test_expect_success ' includes last line of the function' ' + grep "} # hello" function-context-userdiff-actual ' for threads in $(test_seq 0 10) diff --git a/xdiff/xemit.c b/xdiff/xemit.c index 6881445e4a..7778dc2b19 100644 --- a/xdiff/xemit.c +++ b/xdiff/xemit.c @@ -121,6 +121,12 @@ static long match_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri, return xecfg->find_func(rec, len, buf, sz, xecfg->find_func_priv); } +static int is_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri) +{ + char dummy[1]; + return match_func_rec(xdf, xecfg, ri, dummy, sizeof(dummy)) >= 0; +} + struct func_line { long len; char buf[80]; @@ -178,7 +184,6 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, /* Appended chunk? */ if (i1 >= xe->xdf1.nrec) { - char dummy[1]; long i2 = xch->i2; /* @@ -186,8 +191,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, * a whole function was added. */ while (i2 < xe->xdf2.nrec) { - if (match_func_rec(&xe->xdf2, xecfg, i2, - dummy, sizeof(dummy)) >= 0) + if (is_func_rec(&xe->xdf2, xecfg, i2)) goto post_context_calculation; i2++; } @@ -200,6 +204,9 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, } fs1 = get_func_line(xe, xecfg, NULL, i1, -1); + while (fs1 > 0 && !is_empty_rec(&xe->xdf1, fs1 - 1) && + !is_func_rec(&xe->xdf1, xecfg, fs1 - 1)) + fs1--; if (fs1 < 0) fs1 = 0; if (fs1 < s1) { |