@matheusbsbs / matheus-bagliano / commits / 60ecac98ed
Fork 0

grep -p: support user defined regular expressions

Respect the userdiff attributes and config settings when looking for lines with function definitions in git grep -p. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Jul 2, 2009 at 00:07 UTC 60ecac98ed6f420c6bf823491074219087c749d4
5 files changed +50 -3
Documentation/git-grep.txt
+3
@@ -126,6 +126,9 @@ OPTIONS
126 --show-function::
127 Show the preceding line that contains the function name of
128 the match, unless the matching line is a function name itself.
129 + The name is determined in the same way as 'git diff' works out
130 + patch hunk headers (see 'Defining a custom hunk-header' in
131 + linkgit:gitattributes[5]).
132
133 -f <file>::
134 Read patterns from <file>, one per line.
builtin-grep.c
+7
@@ -11,6 +11,7 @@
11 #include "tree-walk.h"
12 #include "builtin.h"
13 #include "parse-options.h"
14 +#include "userdiff.h"
15 #include "grep.h"
16
17 #ifndef NO_EXTERNAL_GREP
@@ -30,6 +31,12 @@ static int grep_config(const char *var, const char *value, void *cb)
31 {
32 struct grep_opt *opt = cb;
33
34 + switch (userdiff_config(var, value)) {
35 + case 0: break;
36 + case -1: return -1;
37 + default: return 0;
38 + }
39 +
40 if (!strcmp(var, "color.grep")) {
41 opt->color = git_config_colorbool(var, value, -1);
42 return 0;
grep.c
+26 -3
@@ -1,5 +1,6 @@
1 #include "cache.h"
2 #include "grep.h"
3 +#include "userdiff.h"
4 #include "xdiff-interface.h"
5
6 void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat)
@@ -535,8 +536,15 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
536 printf("%.*s\n", rest, bol);
537 }
538
538 -static int match_funcname(char *bol, char *eol)
539 +static int match_funcname(struct grep_opt *opt, char *bol, char *eol)
540 {
541 + xdemitconf_t *xecfg = opt->priv;
542 + if (xecfg && xecfg->find_func) {
543 + char buf[1];
544 + return xecfg->find_func(bol, eol - bol, buf, 1,
545 + xecfg->find_func_priv) >= 0;
546 + }
547 +
548 if (bol == eol)
549 return 0;
550 if (isalpha(*bol) || *bol == '_' || *bol == '$')
@@ -557,7 +565,7 @@ static void show_funcname_line(struct grep_opt *opt, const char *name,
565 if (lno <= opt->last_shown)
566 break;
567
560 - if (match_funcname(bol, eol)) {
568 + if (match_funcname(opt, bol, eol)) {
569 show_line(opt, bol, eol, name, lno, '=');
570 break;
571 }
@@ -582,7 +590,7 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
590 while (bol > buf && bol[-1] != '\n')
591 bol--;
592 cur--;
585 - if (funcname_needed && match_funcname(bol, eol)) {
593 + if (funcname_needed && match_funcname(opt, bol, eol)) {
594 funcname_lno = cur;
595 funcname_needed = 0;
596 }
@@ -614,6 +622,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
622 int binary_match_only = 0;
623 unsigned count = 0;
624 enum grep_context ctx = GREP_CONTEXT_HEAD;
625 + xdemitconf_t xecfg;
626
627 opt->last_shown = 0;
628
@@ -630,6 +639,17 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
639 }
640 }
641
642 + memset(&xecfg, 0, sizeof(xecfg));
643 + if (opt->funcname && !opt->unmatch_name_only && !opt->status_only &&
644 + !opt->name_only && !binary_match_only && !collect_hits) {
645 + struct userdiff_driver *drv = userdiff_find_by_path(name);
646 + if (drv && drv->funcname.pattern) {
647 + const struct userdiff_funcname *pe = &drv->funcname;
648 + xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
649 + opt->priv = &xecfg;
650 + }
651 + }
652 +
653 while (left) {
654 char *eol, ch;
655 int hit;
@@ -711,6 +731,9 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
731 return 1;
732 }
733
734 + xdiff_clear_find_func(&xecfg);
735 + opt->priv = NULL;
736 +
737 /* NEEDSWORK:
738 * The real "grep -c foo *.c" gives many "bar.c:0" lines,
739 * which feels mostly useless but sometimes useful. Maybe
grep.h
+1
@@ -87,6 +87,7 @@ struct grep_opt {
87 unsigned post_context;
88 unsigned last_shown;
89 int show_hunk_mark;
90 + void *priv;
91 };
92
93 extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
t/t7002-grep.sh
+13
@@ -243,12 +243,25 @@ test_expect_success 'grep with CE_VALID file' '
243 git checkout t/t
244 '
245
246 +cat >expected <<EOF
247 +hello.c=#include <stdio.h>
248 +hello.c: return 0;
249 +EOF
250 +
251 +test_expect_success 'grep -p with userdiff' '
252 + git config diff.custom.funcname "^#" &&
253 + echo "hello.c diff=custom" >.gitattributes &&
254 + git grep -p return >actual &&
255 + test_cmp expected actual
256 +'
257 +
258 cat >expected <<EOF
259 hello.c=int main(int argc, const char **argv)
260 hello.c: return 0;
261 EOF
262
263 test_expect_success 'grep -p' '
264 + rm -f .gitattributes &&
265 git grep -p return >actual &&
266 test_cmp expected actual
267 '