line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package XS::Check; |
2
|
5
|
|
|
5
|
|
301912
|
use warnings; |
|
5
|
|
|
|
|
44
|
|
|
5
|
|
|
|
|
174
|
|
3
|
5
|
|
|
5
|
|
26
|
use strict; |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
129
|
|
4
|
5
|
|
|
5
|
|
26
|
use Carp; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
290
|
|
5
|
5
|
|
|
5
|
|
30
|
use utf8; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
41
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.12'; |
7
|
5
|
|
|
5
|
|
2910
|
use C::Tokenize '0.14', ':all'; |
|
5
|
|
|
|
|
23663
|
|
|
5
|
|
|
|
|
1504
|
|
8
|
5
|
|
|
5
|
|
2563
|
use Text::LineNumber; |
|
5
|
|
|
|
|
1812
|
|
|
5
|
|
|
|
|
172
|
|
9
|
5
|
|
|
5
|
|
2468
|
use File::Slurper 'read_text'; |
|
5
|
|
|
|
|
73396
|
|
|
5
|
|
|
|
|
335
|
|
10
|
5
|
|
|
5
|
|
41
|
use Carp qw/croak carp cluck confess/; |
|
5
|
|
|
|
|
12
|
|
|
5
|
|
|
|
|
10743
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# ____ _ _ |
13
|
|
|
|
|
|
|
# | _ \ _ __(_)_ ____ _| |_ ___ |
14
|
|
|
|
|
|
|
# | |_) | '__| \ \ / / _` | __/ _ \ |
15
|
|
|
|
|
|
|
# | __/| | | |\ V / (_| | || __/ |
16
|
|
|
|
|
|
|
# |_| |_| |_| \_/ \__,_|\__\___| |
17
|
|
|
|
|
|
|
# |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub debugmsg |
20
|
|
|
|
|
|
|
{ |
21
|
0
|
|
|
0
|
0
|
0
|
my (undef, $file, $line) = caller (); |
22
|
0
|
|
|
|
|
0
|
printf ("%s:%d: ", $file, $line); |
23
|
0
|
|
|
|
|
0
|
print "@_\n"; |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub get_line_number |
27
|
|
|
|
|
|
|
{ |
28
|
19
|
|
|
19
|
0
|
36
|
my ($o) = @_; |
29
|
19
|
|
|
|
|
33
|
my $pos = pos ($o->{xs}); |
30
|
19
|
50
|
|
|
|
71
|
if (! defined ($pos)) { |
31
|
0
|
|
|
|
|
0
|
confess "Bad pos for XS text"; |
32
|
0
|
|
|
|
|
0
|
return "unknown"; |
33
|
|
|
|
|
|
|
} |
34
|
19
|
|
|
|
|
66
|
return $o->{tln}->off2lnr ($pos); |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# Report an error $message in $var |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub report |
40
|
|
|
|
|
|
|
{ |
41
|
19
|
|
|
19
|
0
|
60
|
my ($o, $message) = @_; |
42
|
19
|
|
|
|
|
52
|
my $file = $o->get_file (); |
43
|
19
|
|
|
|
|
60
|
my $line = $o->get_line_number (); |
44
|
19
|
50
|
|
|
|
386
|
confess "No message" unless $message; |
45
|
19
|
100
|
|
|
|
58
|
if (my $r = $o->{reporter}) { |
46
|
1
|
|
|
|
|
5
|
&$r (file => $file, line => $line, message => $message); |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
else { |
49
|
18
|
|
|
|
|
179
|
warn "$file$line: $message.\n"; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# Match a call to SvPV |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
my $svpv_re = qr/ |
56
|
|
|
|
|
|
|
( |
57
|
|
|
|
|
|
|
(?:$word_re(?:->|\.))*$word_re |
58
|
|
|
|
|
|
|
) |
59
|
|
|
|
|
|
|
\s*=[^;]* |
60
|
|
|
|
|
|
|
( |
61
|
|
|
|
|
|
|
SvPV(?:byte|utf8)? |
62
|
|
|
|
|
|
|
(?:x|_(?:force|nolen))? |
63
|
|
|
|
|
|
|
) |
64
|
|
|
|
|
|
|
\s*\(\s* |
65
|
|
|
|
|
|
|
($word_re) |
66
|
|
|
|
|
|
|
\s*,\s* |
67
|
|
|
|
|
|
|
($word_re) |
68
|
|
|
|
|
|
|
\s*\) |
69
|
|
|
|
|
|
|
/x; |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# Look for problems with calls to SvPV. |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub check_svpv |
74
|
|
|
|
|
|
|
{ |
75
|
18
|
|
|
18
|
0
|
73
|
my ($o) = @_; |
76
|
18
|
|
|
|
|
982
|
while ($o->{xs} =~ /($svpv_re)/g) { |
77
|
8
|
|
|
|
|
56
|
my ($match, $lvar, $svpv, $arg1, $arg2) = ($1, $2, $3, $4, $5); |
78
|
8
|
|
|
|
|
22
|
my $lvar_type = $o->get_type ($lvar); |
79
|
8
|
|
|
|
|
14
|
my $arg2_type = $o->get_type ($arg2); |
80
|
8
|
50
|
|
|
|
18
|
if ($o->{verbose}) { |
81
|
0
|
|
|
|
|
0
|
debugmsg ("<$match> $lvar_type $arg2_type"); |
82
|
|
|
|
|
|
|
} |
83
|
8
|
100
|
66
|
|
|
66
|
if ($lvar_type && $lvar_type !~ /\bconst\b/) { |
84
|
5
|
|
|
|
|
19
|
$o->report ("$lvar not a constant type"); |
85
|
|
|
|
|
|
|
} |
86
|
8
|
100
|
100
|
|
|
82
|
if ($arg2_type && $arg2_type !~ /\bSTRLEN\b/) { |
87
|
1
|
|
|
|
|
5
|
$o->report ("$arg2 is not a STRLEN variable ($arg2_type)"); |
88
|
|
|
|
|
|
|
} |
89
|
8
|
100
|
|
|
|
54
|
if ($svpv !~ /bytes?|utf8/) { |
90
|
5
|
|
|
|
|
11
|
$o->report ("Specify either SvPVbyte or SvPVutf8 to avoid ambiguity; see perldoc perlguts"); |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# Best equivalents. |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
my %equiv = ( |
98
|
|
|
|
|
|
|
# Newxc is for C++ programmers (cast malloc). |
99
|
|
|
|
|
|
|
malloc => 'Newx/Newxc', |
100
|
|
|
|
|
|
|
calloc => 'Newxz', |
101
|
|
|
|
|
|
|
free => 'Safefree', |
102
|
|
|
|
|
|
|
realloc => 'Renew', |
103
|
|
|
|
|
|
|
); |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# Look for calls to malloc/calloc/realloc/free and suggest replacing |
106
|
|
|
|
|
|
|
# them. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub check_malloc |
109
|
|
|
|
|
|
|
{ |
110
|
18
|
|
|
18
|
0
|
34
|
my ($o) = @_; |
111
|
18
|
|
|
|
|
134
|
while ($o->{xs} =~ /\b((?:m|c|re)alloc|free)\s*\(/g) { |
112
|
|
|
|
|
|
|
# Bad function |
113
|
1
|
|
|
|
|
3
|
my $badfun = $1; |
114
|
1
|
|
|
|
|
2
|
my $equiv = $equiv{$badfun}; |
115
|
1
|
50
|
|
|
|
4
|
if (! $equiv) { |
116
|
0
|
|
|
|
|
0
|
$o->report ("(BUG) No equiv for $badfun"); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
else { |
119
|
1
|
|
|
|
|
5
|
$o->report ("Change $badfun to $equiv"); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# Look for a Perl_ prefix before functions. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub check_perl_prefix |
127
|
|
|
|
|
|
|
{ |
128
|
18
|
|
|
18
|
0
|
30
|
my ($o) = @_; |
129
|
18
|
|
|
|
|
283
|
while ($o->{xs} =~ /\b(Perl_$word_re)\b/g) { |
130
|
2
|
|
|
|
|
11
|
$o->report ("Remove the 'Perl_' prefix from $1"); |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
# Regular expression to match a C declaration. |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
my $declare_re = qr/ |
137
|
|
|
|
|
|
|
( |
138
|
|
|
|
|
|
|
( |
139
|
|
|
|
|
|
|
(?: |
140
|
|
|
|
|
|
|
(?:$reserved_re|$word_re) |
141
|
|
|
|
|
|
|
(?:\b|\s+) |
142
|
|
|
|
|
|
|
| |
143
|
|
|
|
|
|
|
\*\s* |
144
|
|
|
|
|
|
|
)+ |
145
|
|
|
|
|
|
|
) |
146
|
|
|
|
|
|
|
( |
147
|
|
|
|
|
|
|
$word_re |
148
|
|
|
|
|
|
|
) |
149
|
|
|
|
|
|
|
) |
150
|
|
|
|
|
|
|
# Match initial value. |
151
|
|
|
|
|
|
|
\s*(?:=[^;]+)?; |
152
|
|
|
|
|
|
|
/x; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Read the declarations. |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub read_declarations |
157
|
|
|
|
|
|
|
{ |
158
|
18
|
|
|
18
|
0
|
34
|
my ($o) = @_; |
159
|
18
|
|
|
|
|
766
|
while ($o->{xs} =~ /$declare_re/g) { |
160
|
21
|
|
|
|
|
55
|
my $type = $2; |
161
|
21
|
|
|
|
|
33
|
my $var = $3; |
162
|
21
|
50
|
|
|
|
43
|
if ($o->{verbose}) { |
163
|
0
|
|
|
|
|
0
|
debugmsg ("type = $type for $var"); |
164
|
|
|
|
|
|
|
} |
165
|
21
|
50
|
|
|
|
42
|
if ($o->{vars}{$type}) { |
166
|
|
|
|
|
|
|
# This is very likely to produce false positives in a long |
167
|
|
|
|
|
|
|
# file. A better way to do this would be to have variables |
168
|
|
|
|
|
|
|
# associated with line numbers, so that x on line 10 is |
169
|
|
|
|
|
|
|
# different from x on line 20. |
170
|
0
|
|
|
|
|
0
|
warn "duplicate variable $var of type $type\n"; |
171
|
|
|
|
|
|
|
} |
172
|
21
|
|
|
|
|
438
|
$o->{vars}{$var} = $type; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
# Get the type of variable $var. |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub get_type |
179
|
|
|
|
|
|
|
{ |
180
|
16
|
|
|
16
|
0
|
30
|
my ($o, $var) = @_; |
181
|
|
|
|
|
|
|
# We currently do not have a way to store and retrieve types of |
182
|
|
|
|
|
|
|
# structure members |
183
|
16
|
50
|
|
|
|
55
|
if ($var =~ /->|\./) { |
184
|
0
|
|
|
|
|
0
|
$o->report ("Cannot get type of $var, please check manually"); |
185
|
0
|
|
|
|
|
0
|
return undef; |
186
|
|
|
|
|
|
|
} |
187
|
16
|
|
|
|
|
31
|
my $type = $o->{vars}{$var}; |
188
|
16
|
100
|
|
|
|
30
|
if (! $type) { |
189
|
1
|
|
|
|
|
6
|
$o->report ("(BUG) No type for $var"); |
190
|
|
|
|
|
|
|
} |
191
|
16
|
|
|
|
|
36
|
return $type; |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# Set up the line numbering object. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub line_numbers |
197
|
|
|
|
|
|
|
{ |
198
|
18
|
|
|
18
|
0
|
39
|
my ($o) = @_; |
199
|
18
|
|
|
|
|
76
|
my $tln = Text::LineNumber->new ($o->{xs}); |
200
|
18
|
|
|
|
|
571
|
$o->{tln} = $tln; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# This adds a colon to the end of the file, so it shouldn't really be |
204
|
|
|
|
|
|
|
# user-visible. |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub get_file |
207
|
|
|
|
|
|
|
{ |
208
|
19
|
|
|
19
|
0
|
31
|
my ($o) = @_; |
209
|
19
|
50
|
|
|
|
46
|
if (! $o->{file}) { |
210
|
19
|
|
|
|
|
51
|
return ''; |
211
|
|
|
|
|
|
|
} |
212
|
0
|
|
|
|
|
0
|
return "$o->{file}:"; |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
# Clear up old variables, inputs, etc. Don't delete everything since |
216
|
|
|
|
|
|
|
# we want to keep at least the field "reporter" from one call to |
217
|
|
|
|
|
|
|
# "check" to the next. |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
sub cleanup |
220
|
|
|
|
|
|
|
{ |
221
|
18
|
|
|
18
|
0
|
32
|
my ($o) = @_; |
222
|
18
|
|
|
|
|
35
|
for (qw/vars xs file/) { |
223
|
54
|
|
|
|
|
124
|
delete $o->{$_}; |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# Regex to match (void) in XS function call. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
my $void_re = qr/ |
230
|
|
|
|
|
|
|
$word_re\s* |
231
|
|
|
|
|
|
|
\(\s*void\s*\)\s* |
232
|
|
|
|
|
|
|
(?= |
233
|
|
|
|
|
|
|
# CODE:, PREINIT:, etc. |
234
|
|
|
|
|
|
|
[A-Z]+: |
235
|
|
|
|
|
|
|
# | |
236
|
|
|
|
|
|
|
# Normal C function start |
237
|
|
|
|
|
|
|
# \{ |
238
|
|
|
|
|
|
|
) |
239
|
|
|
|
|
|
|
/xsm; |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# Look for (void) XS functions |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub check_void_arg |
244
|
|
|
|
|
|
|
{ |
245
|
18
|
|
|
18
|
0
|
32
|
my ($o) = @_; |
246
|
18
|
|
|
|
|
174
|
while ($o->{xs} =~ /$void_re/g) { |
247
|
1
|
|
|
|
|
3
|
$o->report ("Don't use (void) in function arguments"); |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub |
252
|
|
|
|
|
|
|
check_hash_comments |
253
|
|
|
|
|
|
|
{ |
254
|
18
|
|
|
18
|
0
|
28
|
my ($o) = @_; |
255
|
18
|
|
|
|
|
51
|
while ($o->{xs} =~ /^#\s*(\w*)/gsm) { |
256
|
3
|
|
|
|
|
15
|
my $hash = $1; |
257
|
3
|
100
|
|
|
|
24
|
if ($hash !~ /^(?: |
258
|
|
|
|
|
|
|
define| |
259
|
|
|
|
|
|
|
else| |
260
|
|
|
|
|
|
|
endif| |
261
|
|
|
|
|
|
|
error| |
262
|
|
|
|
|
|
|
ifdef| |
263
|
|
|
|
|
|
|
ifndef| |
264
|
|
|
|
|
|
|
if| |
265
|
|
|
|
|
|
|
include| |
266
|
|
|
|
|
|
|
line| |
267
|
|
|
|
|
|
|
undef| |
268
|
|
|
|
|
|
|
warning| |
269
|
|
|
|
|
|
|
ZZZZZZZZZZZ)(\s+|$)/x) { |
270
|
1
|
|
|
|
|
6
|
$o->report ("Put whitespace before # in comments"); |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub |
276
|
|
|
|
|
|
|
check_c_pre |
277
|
|
|
|
|
|
|
{ |
278
|
18
|
|
|
18
|
0
|
30
|
my ($o) = @_; |
279
|
18
|
|
|
|
|
66
|
while ($o->{xs} =~ /^#\s*(\w*)/gsm) { |
280
|
3
|
|
|
|
|
8
|
my $hash = $1; |
281
|
3
|
50
|
|
|
|
18
|
if ($hash =~ /(?:if|else|endif)\s+/) { |
282
|
|
|
|
|
|
|
# Complicated! |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub check_fetch_deref |
288
|
|
|
|
|
|
|
{ |
289
|
18
|
|
|
18
|
0
|
29
|
my ($o) = @_; |
290
|
18
|
|
|
|
|
92
|
while ($o->{xs} =~ m!(\*\s*(?:a|h)v_fetch)!g) { |
291
|
1
|
|
|
|
|
4
|
$o->report ("Dereference of av/hv_fetch"); |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
sub check_av_len |
296
|
|
|
|
|
|
|
{ |
297
|
18
|
|
|
18
|
0
|
40
|
my ($o) = @_; |
298
|
18
|
|
|
|
|
57
|
while ($o->{xs} =~ m!^(.*av_len\s*\([^\)]*\)(.*))!g) { |
299
|
1
|
|
|
|
|
4
|
my $later = $2; |
300
|
1
|
50
|
|
|
|
3
|
if ($later !~ /\+\s*1/) { |
301
|
1
|
|
|
|
|
4
|
$o->report ("Add one to av_len"); |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
# _ _ _ _ _ _ |
307
|
|
|
|
|
|
|
# | | | |___ ___ _ __ __ _(_)___(_) |__ | | ___ |
308
|
|
|
|
|
|
|
# | | | / __|/ _ \ '__| \ \ / / / __| | '_ \| |/ _ \ |
309
|
|
|
|
|
|
|
# | |_| \__ \ __/ | \ V /| \__ \ | |_) | | __/ |
310
|
|
|
|
|
|
|
# \___/|___/\___|_| \_/ |_|___/_|_.__/|_|\___| |
311
|
|
|
|
|
|
|
# |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub new |
314
|
|
|
|
|
|
|
{ |
315
|
18
|
|
|
18
|
1
|
13435
|
my ($class, %options) = @_; |
316
|
18
|
|
|
|
|
44
|
my $o = bless {}; |
317
|
18
|
100
|
|
|
|
58
|
if (my $r = $options{reporter}) { |
318
|
2
|
100
|
|
|
|
7
|
if (ref $r ne 'CODE') { |
319
|
1
|
|
|
|
|
208
|
carp "reporter should be a code reference"; |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
else { |
322
|
1
|
|
|
|
|
13
|
$o->{reporter} = $r; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
} |
325
|
18
|
50
|
|
|
|
53
|
if (defined $options{verbose}) { |
326
|
0
|
|
|
|
|
0
|
$o->{verbose} = $options{verbose}; |
327
|
|
|
|
|
|
|
} |
328
|
18
|
|
|
|
|
45
|
return $o; |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
sub set_file |
332
|
|
|
|
|
|
|
{ |
333
|
0
|
|
|
0
|
1
|
0
|
my ($o, $file) = @_; |
334
|
0
|
0
|
|
|
|
0
|
if (! $file) { |
335
|
0
|
|
|
|
|
0
|
$file = undef; |
336
|
|
|
|
|
|
|
} |
337
|
0
|
|
|
|
|
0
|
$o->{file} = $file; |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
# Check the XS. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
sub check |
343
|
|
|
|
|
|
|
{ |
344
|
18
|
|
|
18
|
1
|
1341
|
my ($o, $xs) = @_; |
345
|
18
|
|
|
|
|
54
|
$o->{xs} = $xs; |
346
|
18
|
|
|
|
|
122
|
$o->{xs} = strip_comments ($o->{xs}); |
347
|
18
|
|
|
|
|
811
|
$o->line_numbers (); |
348
|
18
|
|
|
|
|
54
|
$o->read_declarations (); |
349
|
18
|
|
|
|
|
59
|
$o->check_svpv (); |
350
|
18
|
|
|
|
|
108
|
$o->check_malloc (); |
351
|
18
|
|
|
|
|
57
|
$o->check_perl_prefix (); |
352
|
18
|
|
|
|
|
69
|
$o->check_void_arg (); |
353
|
18
|
|
|
|
|
59
|
$o->check_c_pre (); |
354
|
18
|
|
|
|
|
48
|
$o->check_hash_comments (); |
355
|
18
|
|
|
|
|
43
|
$o->check_fetch_deref (); |
356
|
18
|
|
|
|
|
50
|
$o->check_av_len (); |
357
|
|
|
|
|
|
|
# Final line |
358
|
18
|
|
|
|
|
44
|
$o->cleanup (); |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
sub check_file |
362
|
|
|
|
|
|
|
{ |
363
|
0
|
|
|
0
|
1
|
|
my ($o, $file) = @_; |
364
|
0
|
|
|
|
|
|
$o->set_file ($file); |
365
|
0
|
|
|
|
|
|
my $xs = read_text ($file); |
366
|
0
|
|
|
|
|
|
$o->check ($xs); |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
1; |