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>maint
parent
2944e4e614
commit
60ecac98ed
|
@ -126,6 +126,9 @@ OPTIONS
|
||||||
--show-function::
|
--show-function::
|
||||||
Show the preceding line that contains the function name of
|
Show the preceding line that contains the function name of
|
||||||
the match, unless the matching line is a function name itself.
|
the match, unless the matching line is a function name itself.
|
||||||
|
The name is determined in the same way as 'git diff' works out
|
||||||
|
patch hunk headers (see 'Defining a custom hunk-header' in
|
||||||
|
linkgit:gitattributes[5]).
|
||||||
|
|
||||||
-f <file>::
|
-f <file>::
|
||||||
Read patterns from <file>, one per line.
|
Read patterns from <file>, one per line.
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "tree-walk.h"
|
#include "tree-walk.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
|
#include "userdiff.h"
|
||||||
#include "grep.h"
|
#include "grep.h"
|
||||||
|
|
||||||
#ifndef NO_EXTERNAL_GREP
|
#ifndef NO_EXTERNAL_GREP
|
||||||
|
@ -30,6 +31,12 @@ static int grep_config(const char *var, const char *value, void *cb)
|
||||||
{
|
{
|
||||||
struct grep_opt *opt = cb;
|
struct grep_opt *opt = cb;
|
||||||
|
|
||||||
|
switch (userdiff_config(var, value)) {
|
||||||
|
case 0: break;
|
||||||
|
case -1: return -1;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(var, "color.grep")) {
|
if (!strcmp(var, "color.grep")) {
|
||||||
opt->color = git_config_colorbool(var, value, -1);
|
opt->color = git_config_colorbool(var, value, -1);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
29
grep.c
29
grep.c
|
@ -1,5 +1,6 @@
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "grep.h"
|
#include "grep.h"
|
||||||
|
#include "userdiff.h"
|
||||||
#include "xdiff-interface.h"
|
#include "xdiff-interface.h"
|
||||||
|
|
||||||
void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat)
|
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,
|
||||||
printf("%.*s\n", rest, bol);
|
printf("%.*s\n", rest, bol);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_funcname(char *bol, char *eol)
|
static int match_funcname(struct grep_opt *opt, char *bol, char *eol)
|
||||||
{
|
{
|
||||||
|
xdemitconf_t *xecfg = opt->priv;
|
||||||
|
if (xecfg && xecfg->find_func) {
|
||||||
|
char buf[1];
|
||||||
|
return xecfg->find_func(bol, eol - bol, buf, 1,
|
||||||
|
xecfg->find_func_priv) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (bol == eol)
|
if (bol == eol)
|
||||||
return 0;
|
return 0;
|
||||||
if (isalpha(*bol) || *bol == '_' || *bol == '$')
|
if (isalpha(*bol) || *bol == '_' || *bol == '$')
|
||||||
|
@ -557,7 +565,7 @@ static void show_funcname_line(struct grep_opt *opt, const char *name,
|
||||||
if (lno <= opt->last_shown)
|
if (lno <= opt->last_shown)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (match_funcname(bol, eol)) {
|
if (match_funcname(opt, bol, eol)) {
|
||||||
show_line(opt, bol, eol, name, lno, '=');
|
show_line(opt, bol, eol, name, lno, '=');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -582,7 +590,7 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
|
||||||
while (bol > buf && bol[-1] != '\n')
|
while (bol > buf && bol[-1] != '\n')
|
||||||
bol--;
|
bol--;
|
||||||
cur--;
|
cur--;
|
||||||
if (funcname_needed && match_funcname(bol, eol)) {
|
if (funcname_needed && match_funcname(opt, bol, eol)) {
|
||||||
funcname_lno = cur;
|
funcname_lno = cur;
|
||||||
funcname_needed = 0;
|
funcname_needed = 0;
|
||||||
}
|
}
|
||||||
|
@ -614,6 +622,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||||
int binary_match_only = 0;
|
int binary_match_only = 0;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
enum grep_context ctx = GREP_CONTEXT_HEAD;
|
enum grep_context ctx = GREP_CONTEXT_HEAD;
|
||||||
|
xdemitconf_t xecfg;
|
||||||
|
|
||||||
opt->last_shown = 0;
|
opt->last_shown = 0;
|
||||||
|
|
||||||
|
@ -630,6 +639,17 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&xecfg, 0, sizeof(xecfg));
|
||||||
|
if (opt->funcname && !opt->unmatch_name_only && !opt->status_only &&
|
||||||
|
!opt->name_only && !binary_match_only && !collect_hits) {
|
||||||
|
struct userdiff_driver *drv = userdiff_find_by_path(name);
|
||||||
|
if (drv && drv->funcname.pattern) {
|
||||||
|
const struct userdiff_funcname *pe = &drv->funcname;
|
||||||
|
xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
|
||||||
|
opt->priv = &xecfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (left) {
|
while (left) {
|
||||||
char *eol, ch;
|
char *eol, ch;
|
||||||
int hit;
|
int hit;
|
||||||
|
@ -711,6 +731,9 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xdiff_clear_find_func(&xecfg);
|
||||||
|
opt->priv = NULL;
|
||||||
|
|
||||||
/* NEEDSWORK:
|
/* NEEDSWORK:
|
||||||
* The real "grep -c foo *.c" gives many "bar.c:0" lines,
|
* The real "grep -c foo *.c" gives many "bar.c:0" lines,
|
||||||
* which feels mostly useless but sometimes useful. Maybe
|
* which feels mostly useless but sometimes useful. Maybe
|
||||||
|
|
1
grep.h
1
grep.h
|
@ -87,6 +87,7 @@ struct grep_opt {
|
||||||
unsigned post_context;
|
unsigned post_context;
|
||||||
unsigned last_shown;
|
unsigned last_shown;
|
||||||
int show_hunk_mark;
|
int show_hunk_mark;
|
||||||
|
void *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
|
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
|
||||||
|
|
|
@ -243,12 +243,25 @@ test_expect_success 'grep with CE_VALID file' '
|
||||||
git checkout t/t
|
git checkout t/t
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat >expected <<EOF
|
||||||
|
hello.c=#include <stdio.h>
|
||||||
|
hello.c: return 0;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'grep -p with userdiff' '
|
||||||
|
git config diff.custom.funcname "^#" &&
|
||||||
|
echo "hello.c diff=custom" >.gitattributes &&
|
||||||
|
git grep -p return >actual &&
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
hello.c=int main(int argc, const char **argv)
|
hello.c=int main(int argc, const char **argv)
|
||||||
hello.c: return 0;
|
hello.c: return 0;
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
test_expect_success 'grep -p' '
|
test_expect_success 'grep -p' '
|
||||||
|
rm -f .gitattributes &&
|
||||||
git grep -p return >actual &&
|
git grep -p return >actual &&
|
||||||
test_cmp expected actual
|
test_cmp expected actual
|
||||||
'
|
'
|
||||||
|
|
Loading…
Reference in New Issue