From 53ad86ef569bdcb91da9cd2a2a0322620c978389 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 4 Mar 2014 19:36:40 -0500 Subject: diff: simplify cpp funcname regex The current funcname matcher for C files requires one or more words before the function name, like: static int foo(int arg) { However, some coding styles look like this: static int foo(int arg) { and we do not match, even though the default regex would. This patch simplifies the regex significantly. Rather than trying to handle all the variants of keywords and return types, we simply look for an identifier at the start of the line that contains a "(", meaning it is either a function definition or a function call, and then not containing ";" which would indicate it is a call or declaration. This can be fooled by something like: if (foo) but it is unlikely to find that at the very start of a line with no identation (and without having a complete set of keywords, we cannot distinguish that from a function called "if" taking "foo" anyway). We had no tests at all for .c files, so this attempts to add a few obvious cases (including the one we are fixing here). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/t4018-diff-funcname.sh | 36 ++++++++++++++++++++++++++++++++++++ userdiff.c | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 38a092a0da..1e80b157d9 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -93,6 +93,29 @@ sed -e ' s/song;/song();/ ' Beer-correct.perl +cat >Beer.c <<\EOF +static int foo(void) +{ +label: + int x = old; +} + +struct foo; /* catch failure below */ +static int +gnu(int arg) +{ + int x = old; +} + +struct foo; /* catch failure below */ +int multiline(int arg, + char *arg2) +{ + int x = old; +} +EOF +sed s/old/new/ Beer-correct.c + test_expect_funcname () { lang=${2-java} test_expect_code 1 git diff --no-index -U1 \ @@ -127,6 +150,7 @@ test_expect_success 'set up .gitattributes declaring drivers to test' ' cat >.gitattributes <<-\EOF *.java diff=java *.perl diff=perl + *.c diff=cpp EOF ' @@ -158,6 +182,18 @@ test_expect_success 'perl pattern is not distracted by forward declaration' ' test_expect_funcname "package Beer;\$" perl ' +test_expect_success 'c pattern skips labels' ' + test_expect_funcname "static int foo(void)" c +' + +test_expect_success 'c pattern matches GNU-style functions' ' + test_expect_funcname "gnu(int arg)\$" c +' + +test_expect_success 'c pattern matches multiline functions' ' + test_expect_funcname "int multiline(int arg,\$" c +' + test_expect_success 'custom pattern' ' test_config diff.java.funcname "!static !String diff --git a/userdiff.c b/userdiff.c index 10b61ec37d..b9d52b79bc 100644 --- a/userdiff.c +++ b/userdiff.c @@ -127,7 +127,7 @@ PATTERNS("cpp", /* Jump targets or access declarations */ "!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:.*$\n" /* C/++ functions/methods at top level */ - "^([A-Za-z_][A-Za-z_0-9]*([ \t*]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n" + "^([A-Za-z_].*\\([^;]*)$\n" /* compound type at top level */ "^((struct|class|enum)[^;]*)$", /* -- */ -- cgit v1.2.1