Skip to content

Commit 7eacc2b

Browse files
committed
Merge branch 'jn/userdiff-perl-updates'
* jn/userdiff-perl-updates: userdiff/perl: tighten BEGIN/END block pattern to reject here-doc delimiters tests: make test_expect_code quieter on success userdiff/perl: catch sub with brace on second line userdiff/perl: match full line of POD headers userdiff/perl: anchor "sub" and "package" patterns on the left t4018 (funcname patterns): minor cleanups t4018 (funcname patterns): make configuration easier to track t4018 (funcname patterns): make .gitattributes state easier to track
2 parents 8784e4d + f143d9c commit 7eacc2b

File tree

3 files changed

+152
-38
lines changed

3 files changed

+152
-38
lines changed

t/t4018-diff-funcname.sh

Lines changed: 131 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ test_description='Test custom diff function name patterns'
99

1010
LF='
1111
'
12-
13-
cat > Beer.java << EOF
12+
cat >Beer.java <<\EOF
1413
public class Beer
1514
{
1615
int special;
@@ -29,61 +28,163 @@ public class Beer
2928
}
3029
}
3130
EOF
31+
sed 's/beer\\/beer,\\/' <Beer.java >Beer-correct.java
32+
cat >Beer.perl <<\EOT
33+
package Beer;
34+
35+
use strict;
36+
use warnings;
37+
use parent qw(Exporter);
38+
our @EXPORT_OK = qw(round finalround);
39+
40+
sub other; # forward declaration
41+
42+
# hello
43+
44+
sub round {
45+
my ($n) = @_;
46+
print "$n bottles of beer on the wall ";
47+
print "$n bottles of beer\n";
48+
print "Take one down, pass it around, ";
49+
$n = $n - 1;
50+
print "$n bottles of beer on the wall.\n";
51+
}
52+
53+
sub finalround
54+
{
55+
print "Go to the store, buy some more\n";
56+
print "99 bottles of beer on the wall.\n");
57+
}
58+
59+
sub withheredocument {
60+
print <<"EOF"
61+
decoy here-doc
62+
EOF
63+
# some lines of context
64+
# to pad it out
65+
print "hello\n";
66+
}
67+
68+
__END__
69+
70+
=head1 NAME
71+
72+
Beer - subroutine to output fragment of a drinking song
73+
74+
=head1 SYNOPSIS
75+
76+
use Beer qw(round finalround);
77+
78+
sub song {
79+
for (my $i = 99; $i > 0; $i--) {
80+
round $i;
81+
}
82+
finalround;
83+
}
3284
33-
sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java
85+
song;
3486
35-
builtin_patterns="bibtex cpp csharp fortran html java objc pascal perl php python ruby tex"
36-
for p in $builtin_patterns
87+
=cut
88+
EOT
89+
sed -e '
90+
s/hello/goodbye/
91+
s/beer\\/beer,\\/
92+
s/more\\/more,\\/
93+
s/song;/song();/
94+
' <Beer.perl >Beer-correct.perl
95+
96+
test_config () {
97+
git config "$1" "$2" &&
98+
test_when_finished "git config --unset $1"
99+
}
100+
101+
test_expect_funcname () {
102+
lang=${2-java}
103+
test_expect_code 1 git diff --no-index -U1 \
104+
"Beer.$lang" "Beer-correct.$lang" >diff &&
105+
grep "^@@.*@@ $1" diff
106+
}
107+
108+
for p in bibtex cpp csharp fortran html java objc pascal perl php python ruby tex
37109
do
38110
test_expect_success "builtin $p pattern compiles" '
39-
echo "*.java diff=$p" > .gitattributes &&
40-
! { git diff --no-index Beer.java Beer-correct.java 2>&1 |
41-
grep "fatal" > /dev/null; }
111+
echo "*.java diff=$p" >.gitattributes &&
112+
test_expect_code 1 git diff --no-index \
113+
Beer.java Beer-correct.java 2>msg &&
114+
! grep fatal msg &&
115+
! grep error msg
42116
'
43117
test_expect_success "builtin $p wordRegex pattern compiles" '
44-
! { git diff --no-index --word-diff \
45-
Beer.java Beer-correct.java 2>&1 |
46-
grep "fatal" > /dev/null; }
118+
echo "*.java diff=$p" >.gitattributes &&
119+
test_expect_code 1 git diff --no-index --word-diff \
120+
Beer.java Beer-correct.java 2>msg &&
121+
! grep fatal msg &&
122+
! grep error msg
47123
'
48124
done
49125

50126
test_expect_success 'default behaviour' '
51127
rm -f .gitattributes &&
52-
git diff --no-index Beer.java Beer-correct.java |
53-
grep "^@@.*@@ public class Beer"
128+
test_expect_funcname "public class Beer\$"
129+
'
130+
131+
test_expect_success 'set up .gitattributes declaring drivers to test' '
132+
cat >.gitattributes <<-\EOF
133+
*.java diff=java
134+
*.perl diff=perl
135+
EOF
54136
'
55137

56138
test_expect_success 'preset java pattern' '
57-
echo "*.java diff=java" >.gitattributes &&
58-
git diff --no-index Beer.java Beer-correct.java |
59-
grep "^@@.*@@ public static void main("
139+
test_expect_funcname "public static void main("
60140
'
61141

62-
git config diff.java.funcname '!static
63-
!String
64-
[^ ].*s.*'
142+
test_expect_success 'preset perl pattern' '
143+
test_expect_funcname "sub round {\$" perl
144+
'
145+
146+
test_expect_success 'perl pattern accepts K&R style brace placement, too' '
147+
test_expect_funcname "sub finalround\$" perl
148+
'
149+
150+
test_expect_success 'but is not distracted by end of <<here document' '
151+
test_expect_funcname "sub withheredocument {\$" perl
152+
'
153+
154+
test_expect_success 'perl pattern is not distracted by sub within POD' '
155+
test_expect_funcname "=head" perl
156+
'
157+
158+
test_expect_success 'perl pattern gets full line of POD header' '
159+
test_expect_funcname "=head1 SYNOPSIS\$" perl
160+
'
161+
162+
test_expect_success 'perl pattern is not distracted by forward declaration' '
163+
test_expect_funcname "package Beer;\$" perl
164+
'
65165

66166
test_expect_success 'custom pattern' '
67-
git diff --no-index Beer.java Beer-correct.java |
68-
grep "^@@.*@@ int special;$"
167+
test_config diff.java.funcname "!static
168+
!String
169+
[^ ].*s.*" &&
170+
test_expect_funcname "int special;\$"
69171
'
70172

71173
test_expect_success 'last regexp must not be negated' '
72-
git config diff.java.funcname "!static" &&
73-
git diff --no-index Beer.java Beer-correct.java 2>&1 |
74-
grep "fatal: Last expression must not be negated:"
174+
test_config diff.java.funcname "!static" &&
175+
test_expect_code 128 git diff --no-index Beer.java Beer-correct.java 2>msg &&
176+
grep ": Last expression must not be negated:" msg
75177
'
76178

77179
test_expect_success 'pattern which matches to end of line' '
78-
git config diff.java.funcname "Beer$" &&
79-
git diff --no-index Beer.java Beer-correct.java |
80-
grep "^@@.*@@ Beer"
180+
test_config diff.java.funcname "Beer\$" &&
181+
test_expect_funcname "Beer\$"
81182
'
82183

83184
test_expect_success 'alternation in pattern' '
84-
git config diff.java.xfuncname "^[ ]*((public|static).*)$" &&
85-
git diff --no-index Beer.java Beer-correct.java |
86-
grep "^@@.*@@ public static void main("
185+
test_config diff.java.funcname "Beer$" &&
186+
test_config diff.java.xfuncname "^[ ]*((public|static).*)$" &&
187+
test_expect_funcname "public static void main("
87188
'
88189

89190
test_done

t/test-lib.sh

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -731,12 +731,11 @@ test_expect_code () {
731731
exit_code=$?
732732
if test $exit_code = $want_code
733733
then
734-
echo >&2 "test_expect_code: command exited with $exit_code: $*"
735734
return 0
736-
else
737-
echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*"
738-
return 1
739735
fi
736+
737+
echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*"
738+
return 1
740739
}
741740

742741
# test_cmp is a helper function to compare actual and expected output.

userdiff.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,24 @@ PATTERNS("pascal",
6060
"|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+"
6161
"|<>|<=|>=|:=|\\.\\."),
6262
PATTERNS("perl",
63-
"^[ \t]*package .*;\n"
64-
"^[ \t]*sub .* \\{\n"
65-
"^[A-Z]+ \\{\n" /* BEGIN, END, ... */
66-
"^=head[0-9] ", /* POD */
63+
"^package .*\n"
64+
"^sub [[:alnum:]_':]+[ \t]*"
65+
"(\\([^)]*\\)[ \t]*)?" /* prototype */
66+
/*
67+
* Attributes. A regex can't count nested parentheses,
68+
* so just slurp up whatever we see, taking care not
69+
* to accept lines like "sub foo; # defined elsewhere".
70+
*
71+
* An attribute could contain a semicolon, but at that
72+
* point it seems reasonable enough to give up.
73+
*/
74+
"(:[^;#]*)?"
75+
"(\\{[ \t]*)?" /* brace can come here or on the next line */
76+
"(#.*)?$\n" /* comment */
77+
"^(BEGIN|END|INIT|CHECK|UNITCHECK|AUTOLOAD|DESTROY)[ \t]*"
78+
"(\\{[ \t]*)?" /* brace can come here or on the next line */
79+
"(#.*)?$\n"
80+
"^=head[0-9] .*", /* POD */
6781
/* -- */
6882
"[[:alpha:]_'][[:alnum:]_']*"
6983
"|0[xb]?[0-9a-fA-F_]*"

0 commit comments

Comments
 (0)