]>
Commit | Line | Data |
---|---|---|
0a920b5b | 1 | #!/usr/bin/perl -w |
dbf004d7 | 2 | # (c) 2001, Dave Jones. (the file handling bit) |
00df344f | 3 | # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) |
2a5a2c25 | 4 | # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) |
015830be | 5 | # (c) 2008-2010 Andy Whitcroft <apw@canonical.com> |
0a920b5b AW |
6 | # Licensed under the terms of the GNU GPL License version 2 |
7 | ||
8 | use strict; | |
c707a81d | 9 | use POSIX; |
36061e38 JP |
10 | use File::Basename; |
11 | use Cwd 'abs_path'; | |
57230297 | 12 | use Term::ANSIColor qw(:constants); |
0a920b5b AW |
13 | |
14 | my $P = $0; | |
36061e38 | 15 | my $D = dirname(abs_path($P)); |
0a920b5b | 16 | |
000d1cc1 | 17 | my $V = '0.32'; |
0a920b5b AW |
18 | |
19 | use Getopt::Long qw(:config no_auto_abbrev); | |
20 | ||
21 | my $quiet = 0; | |
22 | my $tree = 1; | |
23 | my $chk_signoff = 1; | |
24 | my $chk_patch = 1; | |
773647a0 | 25 | my $tst_only; |
6c72ffaa | 26 | my $emacs = 0; |
8905a67c | 27 | my $terse = 0; |
34d8815f | 28 | my $showfile = 0; |
6c72ffaa | 29 | my $file = 0; |
4a593c34 | 30 | my $git = 0; |
0dea9f1e | 31 | my %git_commits = (); |
6c72ffaa | 32 | my $check = 0; |
2ac73b4f | 33 | my $check_orig = 0; |
8905a67c AW |
34 | my $summary = 1; |
35 | my $mailback = 0; | |
13214adf | 36 | my $summary_file = 0; |
000d1cc1 | 37 | my $show_types = 0; |
3beb42ec | 38 | my $list_types = 0; |
3705ce5b | 39 | my $fix = 0; |
9624b8d6 | 40 | my $fix_inplace = 0; |
6c72ffaa | 41 | my $root; |
c2fdda0d | 42 | my %debug; |
3445686a | 43 | my %camelcase = (); |
91bfe484 JP |
44 | my %use_type = (); |
45 | my @use = (); | |
46 | my %ignore_type = (); | |
000d1cc1 | 47 | my @ignore = (); |
77f5b10a | 48 | my $help = 0; |
000d1cc1 | 49 | my $configuration_file = ".checkpatch.conf"; |
6cd7f386 | 50 | my $max_line_length = 80; |
d62a201f DH |
51 | my $ignore_perl_version = 0; |
52 | my $minimum_perl_version = 5.10.0; | |
56193274 | 53 | my $min_conf_desc_length = 4; |
66b47b4a | 54 | my $spelling_file = "$D/spelling.txt"; |
ebfd7d62 | 55 | my $codespell = 0; |
f1a63678 | 56 | my $codespellfile = "/usr/share/codespell/dictionary.txt"; |
57230297 | 57 | my $color = 1; |
77f5b10a HE |
58 | |
59 | sub help { | |
60 | my ($exitcode) = @_; | |
61 | ||
62 | print << "EOM"; | |
63 | Usage: $P [OPTION]... [FILE]... | |
64 | Version: $V | |
65 | ||
66 | Options: | |
67 | -q, --quiet quiet | |
68 | --no-tree run without a kernel tree | |
69 | --no-signoff do not check for 'Signed-off-by' line | |
70 | --patch treat FILE as patchfile (default) | |
71 | --emacs emacs compile window format | |
72 | --terse one line per report | |
34d8815f | 73 | --showfile emit diffed file position, not input file position |
4a593c34 DC |
74 | -g, --git treat FILE as a single commit or git revision range |
75 | single git commit with: | |
76 | <rev> | |
77 | <rev>^ | |
78 | <rev>~n | |
79 | multiple git commits with: | |
80 | <rev1>..<rev2> | |
81 | <rev1>...<rev2> | |
82 | <rev>-<count> | |
83 | git merges are ignored | |
77f5b10a HE |
84 | -f, --file treat FILE as regular source file |
85 | --subjective, --strict enable more subjective tests | |
3beb42ec | 86 | --list-types list the possible message types |
91bfe484 | 87 | --types TYPE(,TYPE2...) show only these comma separated message types |
000d1cc1 | 88 | --ignore TYPE(,TYPE2...) ignore various comma separated message types |
3beb42ec | 89 | --show-types show the specific message type in the output |
6cd7f386 | 90 | --max-line-length=n set the maximum line length, if exceeded, warn |
56193274 | 91 | --min-conf-desc-length=n set the min description length, if shorter, warn |
77f5b10a HE |
92 | --root=PATH PATH to the kernel tree root |
93 | --no-summary suppress the per-file summary | |
94 | --mailback only produce a report in case of warnings/errors | |
95 | --summary-file include the filename in summary | |
96 | --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of | |
97 | 'values', 'possible', 'type', and 'attr' (default | |
98 | is all off) | |
99 | --test-only=WORD report only warnings/errors containing WORD | |
100 | literally | |
3705ce5b JP |
101 | --fix EXPERIMENTAL - may create horrible results |
102 | If correctable single-line errors exist, create | |
103 | "<inputfile>.EXPERIMENTAL-checkpatch-fixes" | |
104 | with potential errors corrected to the preferred | |
105 | checkpatch style | |
9624b8d6 JP |
106 | --fix-inplace EXPERIMENTAL - may create horrible results |
107 | Is the same as --fix, but overwrites the input | |
108 | file. It's your fault if there's no backup or git | |
d62a201f DH |
109 | --ignore-perl-version override checking of perl version. expect |
110 | runtime errors. | |
ebfd7d62 | 111 | --codespell Use the codespell dictionary for spelling/typos |
f1a63678 | 112 | (default:/usr/share/codespell/dictionary.txt) |
ebfd7d62 | 113 | --codespellfile Use this codespell dictionary |
57230297 | 114 | --color Use colors when output is STDOUT (default: on) |
77f5b10a HE |
115 | -h, --help, --version display this help and exit |
116 | ||
117 | When FILE is - read standard input. | |
118 | EOM | |
119 | ||
120 | exit($exitcode); | |
121 | } | |
122 | ||
3beb42ec JP |
123 | sub uniq { |
124 | my %seen; | |
125 | return grep { !$seen{$_}++ } @_; | |
126 | } | |
127 | ||
128 | sub list_types { | |
129 | my ($exitcode) = @_; | |
130 | ||
131 | my $count = 0; | |
132 | ||
133 | local $/ = undef; | |
134 | ||
135 | open(my $script, '<', abs_path($P)) or | |
136 | die "$P: Can't read '$P' $!\n"; | |
137 | ||
138 | my $text = <$script>; | |
139 | close($script); | |
140 | ||
141 | my @types = (); | |
142 | for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) { | |
143 | push (@types, $_); | |
144 | } | |
145 | @types = sort(uniq(@types)); | |
146 | print("#\tMessage type\n\n"); | |
147 | foreach my $type (@types) { | |
148 | print(++$count . "\t" . $type . "\n"); | |
149 | } | |
150 | ||
151 | exit($exitcode); | |
152 | } | |
153 | ||
000d1cc1 JP |
154 | my $conf = which_conf($configuration_file); |
155 | if (-f $conf) { | |
156 | my @conf_args; | |
157 | open(my $conffile, '<', "$conf") | |
158 | or warn "$P: Can't find a readable $configuration_file file $!\n"; | |
159 | ||
160 | while (<$conffile>) { | |
161 | my $line = $_; | |
162 | ||
163 | $line =~ s/\s*\n?$//g; | |
164 | $line =~ s/^\s*//g; | |
165 | $line =~ s/\s+/ /g; | |
166 | ||
167 | next if ($line =~ m/^\s*#/); | |
168 | next if ($line =~ m/^\s*$/); | |
169 | ||
170 | my @words = split(" ", $line); | |
171 | foreach my $word (@words) { | |
172 | last if ($word =~ m/^#/); | |
173 | push (@conf_args, $word); | |
174 | } | |
175 | } | |
176 | close($conffile); | |
177 | unshift(@ARGV, @conf_args) if @conf_args; | |
178 | } | |
179 | ||
0a920b5b | 180 | GetOptions( |
6c72ffaa | 181 | 'q|quiet+' => \$quiet, |
0a920b5b AW |
182 | 'tree!' => \$tree, |
183 | 'signoff!' => \$chk_signoff, | |
184 | 'patch!' => \$chk_patch, | |
6c72ffaa | 185 | 'emacs!' => \$emacs, |
8905a67c | 186 | 'terse!' => \$terse, |
34d8815f | 187 | 'showfile!' => \$showfile, |
77f5b10a | 188 | 'f|file!' => \$file, |
4a593c34 | 189 | 'g|git!' => \$git, |
6c72ffaa AW |
190 | 'subjective!' => \$check, |
191 | 'strict!' => \$check, | |
000d1cc1 | 192 | 'ignore=s' => \@ignore, |
91bfe484 | 193 | 'types=s' => \@use, |
000d1cc1 | 194 | 'show-types!' => \$show_types, |
3beb42ec | 195 | 'list-types!' => \$list_types, |
6cd7f386 | 196 | 'max-line-length=i' => \$max_line_length, |
56193274 | 197 | 'min-conf-desc-length=i' => \$min_conf_desc_length, |
6c72ffaa | 198 | 'root=s' => \$root, |
8905a67c AW |
199 | 'summary!' => \$summary, |
200 | 'mailback!' => \$mailback, | |
13214adf | 201 | 'summary-file!' => \$summary_file, |
3705ce5b | 202 | 'fix!' => \$fix, |
9624b8d6 | 203 | 'fix-inplace!' => \$fix_inplace, |
d62a201f | 204 | 'ignore-perl-version!' => \$ignore_perl_version, |
c2fdda0d | 205 | 'debug=s' => \%debug, |
773647a0 | 206 | 'test-only=s' => \$tst_only, |
ebfd7d62 JP |
207 | 'codespell!' => \$codespell, |
208 | 'codespellfile=s' => \$codespellfile, | |
57230297 | 209 | 'color!' => \$color, |
77f5b10a HE |
210 | 'h|help' => \$help, |
211 | 'version' => \$help | |
212 | ) or help(1); | |
213 | ||
214 | help(0) if ($help); | |
0a920b5b | 215 | |
3beb42ec JP |
216 | list_types(0) if ($list_types); |
217 | ||
9624b8d6 | 218 | $fix = 1 if ($fix_inplace); |
2ac73b4f | 219 | $check_orig = $check; |
9624b8d6 | 220 | |
0a920b5b AW |
221 | my $exit = 0; |
222 | ||
d62a201f DH |
223 | if ($^V && $^V lt $minimum_perl_version) { |
224 | printf "$P: requires at least perl version %vd\n", $minimum_perl_version; | |
225 | if (!$ignore_perl_version) { | |
226 | exit(1); | |
227 | } | |
228 | } | |
229 | ||
0a920b5b | 230 | if ($#ARGV < 0) { |
77f5b10a | 231 | print "$P: no input files\n"; |
0a920b5b AW |
232 | exit(1); |
233 | } | |
234 | ||
91bfe484 JP |
235 | sub hash_save_array_words { |
236 | my ($hashRef, $arrayRef) = @_; | |
237 | ||
238 | my @array = split(/,/, join(',', @$arrayRef)); | |
239 | foreach my $word (@array) { | |
240 | $word =~ s/\s*\n?$//g; | |
241 | $word =~ s/^\s*//g; | |
242 | $word =~ s/\s+/ /g; | |
243 | $word =~ tr/[a-z]/[A-Z]/; | |
244 | ||
245 | next if ($word =~ m/^\s*#/); | |
246 | next if ($word =~ m/^\s*$/); | |
247 | ||
248 | $hashRef->{$word}++; | |
249 | } | |
250 | } | |
000d1cc1 | 251 | |
91bfe484 JP |
252 | sub hash_show_words { |
253 | my ($hashRef, $prefix) = @_; | |
000d1cc1 | 254 | |
3c816e49 | 255 | if (keys %$hashRef) { |
d8469f16 | 256 | print "\nNOTE: $prefix message types:"; |
58cb3cf6 | 257 | foreach my $word (sort keys %$hashRef) { |
91bfe484 JP |
258 | print " $word"; |
259 | } | |
d8469f16 | 260 | print "\n"; |
91bfe484 | 261 | } |
000d1cc1 JP |
262 | } |
263 | ||
91bfe484 JP |
264 | hash_save_array_words(\%ignore_type, \@ignore); |
265 | hash_save_array_words(\%use_type, \@use); | |
266 | ||
c2fdda0d AW |
267 | my $dbg_values = 0; |
268 | my $dbg_possible = 0; | |
7429c690 | 269 | my $dbg_type = 0; |
a1ef277e | 270 | my $dbg_attr = 0; |
c2fdda0d | 271 | for my $key (keys %debug) { |
21caa13c AW |
272 | ## no critic |
273 | eval "\${dbg_$key} = '$debug{$key}';"; | |
274 | die "$@" if ($@); | |
c2fdda0d AW |
275 | } |
276 | ||
d2c0a235 AW |
277 | my $rpt_cleaners = 0; |
278 | ||
8905a67c AW |
279 | if ($terse) { |
280 | $emacs = 1; | |
281 | $quiet++; | |
282 | } | |
283 | ||
6c72ffaa AW |
284 | if ($tree) { |
285 | if (defined $root) { | |
286 | if (!top_of_kernel_tree($root)) { | |
287 | die "$P: $root: --root does not point at a valid tree\n"; | |
288 | } | |
289 | } else { | |
290 | if (top_of_kernel_tree('.')) { | |
291 | $root = '.'; | |
292 | } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && | |
293 | top_of_kernel_tree($1)) { | |
294 | $root = $1; | |
295 | } | |
296 | } | |
297 | ||
298 | if (!defined $root) { | |
299 | print "Must be run from the top-level dir. of a kernel tree\n"; | |
300 | exit(2); | |
301 | } | |
0a920b5b AW |
302 | } |
303 | ||
6c72ffaa AW |
304 | my $emitted_corrupt = 0; |
305 | ||
2ceb532b AW |
306 | our $Ident = qr{ |
307 | [A-Za-z_][A-Za-z\d_]* | |
308 | (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* | |
309 | }x; | |
6c72ffaa AW |
310 | our $Storage = qr{extern|static|asmlinkage}; |
311 | our $Sparse = qr{ | |
312 | __user| | |
313 | __kernel| | |
314 | __force| | |
315 | __iomem| | |
54507b51 | 316 | __pmem| |
6c72ffaa AW |
317 | __must_check| |
318 | __init_refok| | |
417495ed | 319 | __kprobes| |
165e72a6 | 320 | __ref| |
ad315455 BF |
321 | __rcu| |
322 | __private | |
6c72ffaa | 323 | }x; |
e970b884 JP |
324 | our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; |
325 | our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; | |
326 | our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; | |
327 | our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; | |
328 | our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; | |
8716de38 | 329 | |
52131292 WS |
330 | # Notes to $Attribute: |
331 | # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check | |
6c72ffaa AW |
332 | our $Attribute = qr{ |
333 | const| | |
03f1df7d JP |
334 | __percpu| |
335 | __nocast| | |
336 | __safe| | |
337 | __bitwise__| | |
338 | __packed__| | |
339 | __packed2__| | |
340 | __naked| | |
341 | __maybe_unused| | |
342 | __always_unused| | |
343 | __noreturn| | |
344 | __used| | |
345 | __cold| | |
e23ef1f3 | 346 | __pure| |
03f1df7d JP |
347 | __noclone| |
348 | __deprecated| | |
6c72ffaa AW |
349 | __read_mostly| |
350 | __kprobes| | |
8716de38 | 351 | $InitAttribute| |
24e1d81a AW |
352 | ____cacheline_aligned| |
353 | ____cacheline_aligned_in_smp| | |
5fe3af11 AW |
354 | ____cacheline_internodealigned_in_smp| |
355 | __weak | |
6c72ffaa | 356 | }x; |
c45dcabd | 357 | our $Modifier; |
91cb5195 | 358 | our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; |
6c72ffaa AW |
359 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; |
360 | our $Lval = qr{$Ident(?:$Member)*}; | |
361 | ||
95e2c602 JP |
362 | our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; |
363 | our $Binary = qr{(?i)0b[01]+$Int_type?}; | |
364 | our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; | |
365 | our $Int = qr{[0-9]+$Int_type?}; | |
2435880f | 366 | our $Octal = qr{0[0-7]+$Int_type?}; |
c0a5c898 | 367 | our $String = qr{"[X\t]*"}; |
326b1ffc JP |
368 | our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; |
369 | our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; | |
370 | our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; | |
74349bcc | 371 | our $Float = qr{$Float_hex|$Float_dec|$Float_int}; |
2435880f | 372 | our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; |
326b1ffc | 373 | our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; |
447432f3 | 374 | our $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; |
23f780c9 | 375 | our $Arithmetic = qr{\+|-|\*|\/|%}; |
6c72ffaa AW |
376 | our $Operators = qr{ |
377 | <=|>=|==|!=| | |
378 | =>|->|<<|>>|<|>|!|~| | |
23f780c9 | 379 | &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic |
6c72ffaa AW |
380 | }x; |
381 | ||
91cb5195 JP |
382 | our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; |
383 | ||
ab7e23f3 | 384 | our $BasicType; |
8905a67c | 385 | our $NonptrType; |
1813087d | 386 | our $NonptrTypeMisordered; |
8716de38 | 387 | our $NonptrTypeWithAttr; |
8905a67c | 388 | our $Type; |
1813087d | 389 | our $TypeMisordered; |
8905a67c | 390 | our $Declare; |
1813087d | 391 | our $DeclareMisordered; |
8905a67c | 392 | |
15662b3e JP |
393 | our $NON_ASCII_UTF8 = qr{ |
394 | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte | |
171ae1a4 AW |
395 | | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs |
396 | | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte | |
397 | | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates | |
398 | | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 | |
399 | | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 | |
400 | | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 | |
401 | }x; | |
402 | ||
15662b3e JP |
403 | our $UTF8 = qr{ |
404 | [\x09\x0A\x0D\x20-\x7E] # ASCII | |
405 | | $NON_ASCII_UTF8 | |
406 | }x; | |
407 | ||
e6176fa4 | 408 | our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; |
021158b4 JP |
409 | our $typeOtherOSTypedefs = qr{(?x: |
410 | u_(?:char|short|int|long) | # bsd | |
411 | u(?:nchar|short|int|long) # sysv | |
412 | )}; | |
e6176fa4 | 413 | our $typeKernelTypedefs = qr{(?x: |
fb9e9096 | 414 | (?:__)?(?:u|s|be|le)(?:8|16|32|64)| |
8ed22cad AW |
415 | atomic_t |
416 | )}; | |
e6176fa4 JP |
417 | our $typeTypedefs = qr{(?x: |
418 | $typeC99Typedefs\b| | |
419 | $typeOtherOSTypedefs\b| | |
420 | $typeKernelTypedefs\b | |
421 | )}; | |
8ed22cad | 422 | |
6d32f7a3 JP |
423 | our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; |
424 | ||
691e669b | 425 | our $logFunctions = qr{(?x: |
6e60c02e | 426 | printk(?:_ratelimited|_once|)| |
7d0b6594 | 427 | (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| |
6e60c02e | 428 | WARN(?:_RATELIMIT|_ONCE|)| |
b0531722 | 429 | panic| |
06668727 JP |
430 | MODULE_[A-Z_]+| |
431 | seq_vprintf|seq_printf|seq_puts | |
691e669b JP |
432 | )}; |
433 | ||
20112475 JP |
434 | our $signature_tags = qr{(?xi: |
435 | Signed-off-by:| | |
436 | Acked-by:| | |
437 | Tested-by:| | |
438 | Reviewed-by:| | |
439 | Reported-by:| | |
8543ae12 | 440 | Suggested-by:| |
20112475 JP |
441 | To:| |
442 | Cc: | |
443 | )}; | |
444 | ||
1813087d JP |
445 | our @typeListMisordered = ( |
446 | qr{char\s+(?:un)?signed}, | |
447 | qr{int\s+(?:(?:un)?signed\s+)?short\s}, | |
448 | qr{int\s+short(?:\s+(?:un)?signed)}, | |
449 | qr{short\s+int(?:\s+(?:un)?signed)}, | |
450 | qr{(?:un)?signed\s+int\s+short}, | |
451 | qr{short\s+(?:un)?signed}, | |
452 | qr{long\s+int\s+(?:un)?signed}, | |
453 | qr{int\s+long\s+(?:un)?signed}, | |
454 | qr{long\s+(?:un)?signed\s+int}, | |
455 | qr{int\s+(?:un)?signed\s+long}, | |
456 | qr{int\s+(?:un)?signed}, | |
457 | qr{int\s+long\s+long\s+(?:un)?signed}, | |
458 | qr{long\s+long\s+int\s+(?:un)?signed}, | |
459 | qr{long\s+long\s+(?:un)?signed\s+int}, | |
460 | qr{long\s+long\s+(?:un)?signed}, | |
461 | qr{long\s+(?:un)?signed}, | |
462 | ); | |
463 | ||
8905a67c AW |
464 | our @typeList = ( |
465 | qr{void}, | |
0c773d9d JP |
466 | qr{(?:(?:un)?signed\s+)?char}, |
467 | qr{(?:(?:un)?signed\s+)?short\s+int}, | |
468 | qr{(?:(?:un)?signed\s+)?short}, | |
469 | qr{(?:(?:un)?signed\s+)?int}, | |
470 | qr{(?:(?:un)?signed\s+)?long\s+int}, | |
471 | qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, | |
472 | qr{(?:(?:un)?signed\s+)?long\s+long}, | |
473 | qr{(?:(?:un)?signed\s+)?long}, | |
474 | qr{(?:un)?signed}, | |
8905a67c AW |
475 | qr{float}, |
476 | qr{double}, | |
477 | qr{bool}, | |
8905a67c AW |
478 | qr{struct\s+$Ident}, |
479 | qr{union\s+$Ident}, | |
480 | qr{enum\s+$Ident}, | |
481 | qr{${Ident}_t}, | |
482 | qr{${Ident}_handler}, | |
483 | qr{${Ident}_handler_fn}, | |
1813087d | 484 | @typeListMisordered, |
8905a67c | 485 | ); |
938224b5 JP |
486 | |
487 | our $C90_int_types = qr{(?x: | |
488 | long\s+long\s+int\s+(?:un)?signed| | |
489 | long\s+long\s+(?:un)?signed\s+int| | |
490 | long\s+long\s+(?:un)?signed| | |
491 | (?:(?:un)?signed\s+)?long\s+long\s+int| | |
492 | (?:(?:un)?signed\s+)?long\s+long| | |
493 | int\s+long\s+long\s+(?:un)?signed| | |
494 | int\s+(?:(?:un)?signed\s+)?long\s+long| | |
495 | ||
496 | long\s+int\s+(?:un)?signed| | |
497 | long\s+(?:un)?signed\s+int| | |
498 | long\s+(?:un)?signed| | |
499 | (?:(?:un)?signed\s+)?long\s+int| | |
500 | (?:(?:un)?signed\s+)?long| | |
501 | int\s+long\s+(?:un)?signed| | |
502 | int\s+(?:(?:un)?signed\s+)?long| | |
503 | ||
504 | int\s+(?:un)?signed| | |
505 | (?:(?:un)?signed\s+)?int | |
506 | )}; | |
507 | ||
485ff23e | 508 | our @typeListFile = (); |
8716de38 JP |
509 | our @typeListWithAttr = ( |
510 | @typeList, | |
511 | qr{struct\s+$InitAttribute\s+$Ident}, | |
512 | qr{union\s+$InitAttribute\s+$Ident}, | |
513 | ); | |
514 | ||
c45dcabd AW |
515 | our @modifierList = ( |
516 | qr{fastcall}, | |
517 | ); | |
485ff23e | 518 | our @modifierListFile = (); |
8905a67c | 519 | |
2435880f JP |
520 | our @mode_permission_funcs = ( |
521 | ["module_param", 3], | |
522 | ["module_param_(?:array|named|string)", 4], | |
523 | ["module_param_array_named", 5], | |
524 | ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], | |
525 | ["proc_create(?:_data|)", 2], | |
526 | ["(?:CLASS|DEVICE|SENSOR)_ATTR", 2], | |
527 | ); | |
528 | ||
515a235e JP |
529 | #Create a search pattern for all these functions to speed up a loop below |
530 | our $mode_perms_search = ""; | |
531 | foreach my $entry (@mode_permission_funcs) { | |
532 | $mode_perms_search .= '|' if ($mode_perms_search ne ""); | |
533 | $mode_perms_search .= $entry->[0]; | |
534 | } | |
535 | ||
b392c64f JP |
536 | our $mode_perms_world_writable = qr{ |
537 | S_IWUGO | | |
538 | S_IWOTH | | |
539 | S_IRWXUGO | | |
540 | S_IALLUGO | | |
541 | 0[0-7][0-7][2367] | |
542 | }x; | |
543 | ||
7840a94c WS |
544 | our $allowed_asm_includes = qr{(?x: |
545 | irq| | |
cdcee686 SR |
546 | memory| |
547 | time| | |
548 | reboot | |
7840a94c WS |
549 | )}; |
550 | # memory.h: ARM has a custom one | |
551 | ||
66b47b4a KC |
552 | # Load common spelling mistakes and build regular expression list. |
553 | my $misspellings; | |
66b47b4a | 554 | my %spelling_fix; |
66b47b4a | 555 | |
36061e38 | 556 | if (open(my $spelling, '<', $spelling_file)) { |
36061e38 JP |
557 | while (<$spelling>) { |
558 | my $line = $_; | |
66b47b4a | 559 | |
36061e38 JP |
560 | $line =~ s/\s*\n?$//g; |
561 | $line =~ s/^\s*//g; | |
66b47b4a | 562 | |
36061e38 JP |
563 | next if ($line =~ m/^\s*#/); |
564 | next if ($line =~ m/^\s*$/); | |
565 | ||
566 | my ($suspect, $fix) = split(/\|\|/, $line); | |
66b47b4a | 567 | |
36061e38 JP |
568 | $spelling_fix{$suspect} = $fix; |
569 | } | |
570 | close($spelling); | |
36061e38 JP |
571 | } else { |
572 | warn "No typos will be found - file '$spelling_file': $!\n"; | |
66b47b4a | 573 | } |
66b47b4a | 574 | |
ebfd7d62 JP |
575 | if ($codespell) { |
576 | if (open(my $spelling, '<', $codespellfile)) { | |
577 | while (<$spelling>) { | |
578 | my $line = $_; | |
579 | ||
580 | $line =~ s/\s*\n?$//g; | |
581 | $line =~ s/^\s*//g; | |
582 | ||
583 | next if ($line =~ m/^\s*#/); | |
584 | next if ($line =~ m/^\s*$/); | |
585 | next if ($line =~ m/, disabled/i); | |
586 | ||
587 | $line =~ s/,.*$//; | |
588 | ||
589 | my ($suspect, $fix) = split(/->/, $line); | |
590 | ||
591 | $spelling_fix{$suspect} = $fix; | |
592 | } | |
593 | close($spelling); | |
594 | } else { | |
595 | warn "No codespell typos will be found - file '$codespellfile': $!\n"; | |
596 | } | |
597 | } | |
598 | ||
599 | $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; | |
600 | ||
8905a67c | 601 | sub build_types { |
485ff23e AD |
602 | my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; |
603 | my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; | |
1813087d | 604 | my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; |
8716de38 | 605 | my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; |
c8cb2ca3 | 606 | $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; |
ab7e23f3 | 607 | $BasicType = qr{ |
ab7e23f3 JP |
608 | (?:$typeTypedefs\b)| |
609 | (?:${all}\b) | |
610 | }x; | |
8905a67c | 611 | $NonptrType = qr{ |
d2172eb5 | 612 | (?:$Modifier\s+|const\s+)* |
cf655043 | 613 | (?: |
6b48db24 | 614 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
8ed22cad | 615 | (?:$typeTypedefs\b)| |
c45dcabd | 616 | (?:${all}\b) |
cf655043 | 617 | ) |
c8cb2ca3 | 618 | (?:\s+$Modifier|\s+const)* |
8905a67c | 619 | }x; |
1813087d JP |
620 | $NonptrTypeMisordered = qr{ |
621 | (?:$Modifier\s+|const\s+)* | |
622 | (?: | |
623 | (?:${Misordered}\b) | |
624 | ) | |
625 | (?:\s+$Modifier|\s+const)* | |
626 | }x; | |
8716de38 JP |
627 | $NonptrTypeWithAttr = qr{ |
628 | (?:$Modifier\s+|const\s+)* | |
629 | (?: | |
630 | (?:typeof|__typeof__)\s*\([^\)]*\)| | |
631 | (?:$typeTypedefs\b)| | |
632 | (?:${allWithAttr}\b) | |
633 | ) | |
634 | (?:\s+$Modifier|\s+const)* | |
635 | }x; | |
8905a67c | 636 | $Type = qr{ |
c45dcabd | 637 | $NonptrType |
1574a29f | 638 | (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? |
c8cb2ca3 | 639 | (?:\s+$Inline|\s+$Modifier)* |
8905a67c | 640 | }x; |
1813087d JP |
641 | $TypeMisordered = qr{ |
642 | $NonptrTypeMisordered | |
643 | (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? | |
644 | (?:\s+$Inline|\s+$Modifier)* | |
645 | }x; | |
91cb5195 | 646 | $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; |
1813087d | 647 | $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; |
8905a67c AW |
648 | } |
649 | build_types(); | |
6c72ffaa | 650 | |
7d2367af | 651 | our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; |
d1fe9c09 JP |
652 | |
653 | # Using $balanced_parens, $LvalOrFunc, or $FuncArg | |
654 | # requires at least perl version v5.10.0 | |
655 | # Any use must be runtime checked with $^V | |
656 | ||
657 | our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; | |
2435880f | 658 | our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; |
c0a5c898 | 659 | our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; |
7d2367af | 660 | |
f8422308 | 661 | our $declaration_macros = qr{(?x: |
3e838b6c | 662 | (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| |
f8422308 JP |
663 | (?:$Storage\s+)?LIST_HEAD\s*\(| |
664 | (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( | |
665 | )}; | |
666 | ||
7d2367af JP |
667 | sub deparenthesize { |
668 | my ($string) = @_; | |
669 | return "" if (!defined($string)); | |
5b9553ab JP |
670 | |
671 | while ($string =~ /^\s*\(.*\)\s*$/) { | |
672 | $string =~ s@^\s*\(\s*@@; | |
673 | $string =~ s@\s*\)\s*$@@; | |
674 | } | |
675 | ||
7d2367af | 676 | $string =~ s@\s+@ @g; |
5b9553ab | 677 | |
7d2367af JP |
678 | return $string; |
679 | } | |
680 | ||
3445686a JP |
681 | sub seed_camelcase_file { |
682 | my ($file) = @_; | |
683 | ||
684 | return if (!(-f $file)); | |
685 | ||
686 | local $/; | |
687 | ||
688 | open(my $include_file, '<', "$file") | |
689 | or warn "$P: Can't read '$file' $!\n"; | |
690 | my $text = <$include_file>; | |
691 | close($include_file); | |
692 | ||
693 | my @lines = split('\n', $text); | |
694 | ||
695 | foreach my $line (@lines) { | |
696 | next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); | |
697 | if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { | |
698 | $camelcase{$1} = 1; | |
11ea516a JP |
699 | } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { |
700 | $camelcase{$1} = 1; | |
701 | } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { | |
3445686a JP |
702 | $camelcase{$1} = 1; |
703 | } | |
704 | } | |
705 | } | |
706 | ||
707 | my $camelcase_seeded = 0; | |
708 | sub seed_camelcase_includes { | |
709 | return if ($camelcase_seeded); | |
710 | ||
711 | my $files; | |
c707a81d JP |
712 | my $camelcase_cache = ""; |
713 | my @include_files = (); | |
714 | ||
715 | $camelcase_seeded = 1; | |
351b2a1f | 716 | |
3645e328 | 717 | if (-e ".git") { |
351b2a1f JP |
718 | my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; |
719 | chomp $git_last_include_commit; | |
c707a81d | 720 | $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; |
3445686a | 721 | } else { |
c707a81d | 722 | my $last_mod_date = 0; |
3445686a | 723 | $files = `find $root/include -name "*.h"`; |
c707a81d JP |
724 | @include_files = split('\n', $files); |
725 | foreach my $file (@include_files) { | |
726 | my $date = POSIX::strftime("%Y%m%d%H%M", | |
727 | localtime((stat $file)[9])); | |
728 | $last_mod_date = $date if ($last_mod_date < $date); | |
729 | } | |
730 | $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; | |
731 | } | |
732 | ||
733 | if ($camelcase_cache ne "" && -f $camelcase_cache) { | |
734 | open(my $camelcase_file, '<', "$camelcase_cache") | |
735 | or warn "$P: Can't read '$camelcase_cache' $!\n"; | |
736 | while (<$camelcase_file>) { | |
737 | chomp; | |
738 | $camelcase{$_} = 1; | |
739 | } | |
740 | close($camelcase_file); | |
741 | ||
742 | return; | |
3445686a | 743 | } |
c707a81d | 744 | |
3645e328 | 745 | if (-e ".git") { |
c707a81d JP |
746 | $files = `git ls-files "include/*.h"`; |
747 | @include_files = split('\n', $files); | |
748 | } | |
749 | ||
3445686a JP |
750 | foreach my $file (@include_files) { |
751 | seed_camelcase_file($file); | |
752 | } | |
351b2a1f | 753 | |
c707a81d | 754 | if ($camelcase_cache ne "") { |
351b2a1f | 755 | unlink glob ".checkpatch-camelcase.*"; |
c707a81d JP |
756 | open(my $camelcase_file, '>', "$camelcase_cache") |
757 | or warn "$P: Can't write '$camelcase_cache' $!\n"; | |
351b2a1f JP |
758 | foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { |
759 | print $camelcase_file ("$_\n"); | |
760 | } | |
761 | close($camelcase_file); | |
762 | } | |
3445686a JP |
763 | } |
764 | ||
d311cd44 JP |
765 | sub git_commit_info { |
766 | my ($commit, $id, $desc) = @_; | |
767 | ||
768 | return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); | |
769 | ||
770 | my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; | |
771 | $output =~ s/^\s*//gm; | |
772 | my @lines = split("\n", $output); | |
773 | ||
0d7835fc JP |
774 | return ($id, $desc) if ($#lines < 0); |
775 | ||
d311cd44 JP |
776 | if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { |
777 | # Maybe one day convert this block of bash into something that returns | |
778 | # all matching commit ids, but it's very slow... | |
779 | # | |
780 | # echo "checking commits $1..." | |
781 | # git rev-list --remotes | grep -i "^$1" | | |
782 | # while read line ; do | |
783 | # git log --format='%H %s' -1 $line | | |
784 | # echo "commit $(cut -c 1-12,41-)" | |
785 | # done | |
786 | } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { | |
787 | } else { | |
788 | $id = substr($lines[0], 0, 12); | |
789 | $desc = substr($lines[0], 41); | |
790 | } | |
791 | ||
792 | return ($id, $desc); | |
793 | } | |
794 | ||
6c72ffaa AW |
795 | $chk_signoff = 0 if ($file); |
796 | ||
00df344f | 797 | my @rawlines = (); |
c2fdda0d | 798 | my @lines = (); |
3705ce5b | 799 | my @fixed = (); |
d752fcc8 JP |
800 | my @fixed_inserted = (); |
801 | my @fixed_deleted = (); | |
194f66fc JP |
802 | my $fixlinenr = -1; |
803 | ||
4a593c34 DC |
804 | # If input is git commits, extract all commits from the commit expressions. |
805 | # For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. | |
806 | die "$P: No git repository found\n" if ($git && !-e ".git"); | |
807 | ||
808 | if ($git) { | |
809 | my @commits = (); | |
0dea9f1e | 810 | foreach my $commit_expr (@ARGV) { |
4a593c34 | 811 | my $git_range; |
28898fd1 JP |
812 | if ($commit_expr =~ m/^(.*)-(\d+)$/) { |
813 | $git_range = "-$2 $1"; | |
4a593c34 DC |
814 | } elsif ($commit_expr =~ m/\.\./) { |
815 | $git_range = "$commit_expr"; | |
4a593c34 | 816 | } else { |
0dea9f1e JP |
817 | $git_range = "-1 $commit_expr"; |
818 | } | |
819 | my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; | |
820 | foreach my $line (split(/\n/, $lines)) { | |
28898fd1 JP |
821 | $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; |
822 | next if (!defined($1) || !defined($2)); | |
0dea9f1e JP |
823 | my $sha1 = $1; |
824 | my $subject = $2; | |
825 | unshift(@commits, $sha1); | |
826 | $git_commits{$sha1} = $subject; | |
4a593c34 DC |
827 | } |
828 | } | |
829 | die "$P: no git commits after extraction!\n" if (@commits == 0); | |
830 | @ARGV = @commits; | |
831 | } | |
832 | ||
c2fdda0d | 833 | my $vname; |
6c72ffaa | 834 | for my $filename (@ARGV) { |
21caa13c | 835 | my $FILE; |
4a593c34 DC |
836 | if ($git) { |
837 | open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || | |
838 | die "$P: $filename: git format-patch failed - $!\n"; | |
839 | } elsif ($file) { | |
21caa13c | 840 | open($FILE, '-|', "diff -u /dev/null $filename") || |
6c72ffaa | 841 | die "$P: $filename: diff failed - $!\n"; |
21caa13c AW |
842 | } elsif ($filename eq '-') { |
843 | open($FILE, '<&STDIN'); | |
6c72ffaa | 844 | } else { |
21caa13c | 845 | open($FILE, '<', "$filename") || |
6c72ffaa | 846 | die "$P: $filename: open failed - $!\n"; |
0a920b5b | 847 | } |
c2fdda0d AW |
848 | if ($filename eq '-') { |
849 | $vname = 'Your patch'; | |
4a593c34 | 850 | } elsif ($git) { |
0dea9f1e | 851 | $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; |
c2fdda0d AW |
852 | } else { |
853 | $vname = $filename; | |
854 | } | |
21caa13c | 855 | while (<$FILE>) { |
6c72ffaa AW |
856 | chomp; |
857 | push(@rawlines, $_); | |
858 | } | |
21caa13c | 859 | close($FILE); |
d8469f16 JP |
860 | |
861 | if ($#ARGV > 0 && $quiet == 0) { | |
862 | print '-' x length($vname) . "\n"; | |
863 | print "$vname\n"; | |
864 | print '-' x length($vname) . "\n"; | |
865 | } | |
866 | ||
c2fdda0d | 867 | if (!process($filename)) { |
6c72ffaa AW |
868 | $exit = 1; |
869 | } | |
870 | @rawlines = (); | |
13214adf | 871 | @lines = (); |
3705ce5b | 872 | @fixed = (); |
d752fcc8 JP |
873 | @fixed_inserted = (); |
874 | @fixed_deleted = (); | |
194f66fc | 875 | $fixlinenr = -1; |
485ff23e AD |
876 | @modifierListFile = (); |
877 | @typeListFile = (); | |
878 | build_types(); | |
0a920b5b AW |
879 | } |
880 | ||
d8469f16 | 881 | if (!$quiet) { |
3c816e49 JP |
882 | hash_show_words(\%use_type, "Used"); |
883 | hash_show_words(\%ignore_type, "Ignored"); | |
884 | ||
d8469f16 JP |
885 | if ($^V lt 5.10.0) { |
886 | print << "EOM" | |
887 | ||
888 | NOTE: perl $^V is not modern enough to detect all possible issues. | |
889 | An upgrade to at least perl v5.10.0 is suggested. | |
890 | EOM | |
891 | } | |
892 | if ($exit) { | |
893 | print << "EOM" | |
894 | ||
895 | NOTE: If any of the errors are false positives, please report | |
896 | them to the maintainer, see CHECKPATCH in MAINTAINERS. | |
897 | EOM | |
898 | } | |
899 | } | |
900 | ||
0a920b5b AW |
901 | exit($exit); |
902 | ||
903 | sub top_of_kernel_tree { | |
6c72ffaa AW |
904 | my ($root) = @_; |
905 | ||
906 | my @tree_check = ( | |
907 | "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", | |
908 | "README", "Documentation", "arch", "include", "drivers", | |
909 | "fs", "init", "ipc", "kernel", "lib", "scripts", | |
910 | ); | |
911 | ||
912 | foreach my $check (@tree_check) { | |
913 | if (! -e $root . '/' . $check) { | |
914 | return 0; | |
915 | } | |
0a920b5b | 916 | } |
6c72ffaa | 917 | return 1; |
8f26b837 | 918 | } |
0a920b5b | 919 | |
20112475 JP |
920 | sub parse_email { |
921 | my ($formatted_email) = @_; | |
922 | ||
923 | my $name = ""; | |
924 | my $address = ""; | |
925 | my $comment = ""; | |
926 | ||
927 | if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { | |
928 | $name = $1; | |
929 | $address = $2; | |
930 | $comment = $3 if defined $3; | |
931 | } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { | |
932 | $address = $1; | |
933 | $comment = $2 if defined $2; | |
934 | } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { | |
935 | $address = $1; | |
936 | $comment = $2 if defined $2; | |
937 | $formatted_email =~ s/$address.*$//; | |
938 | $name = $formatted_email; | |
3705ce5b | 939 | $name = trim($name); |
20112475 JP |
940 | $name =~ s/^\"|\"$//g; |
941 | # If there's a name left after stripping spaces and | |
942 | # leading quotes, and the address doesn't have both | |
943 | # leading and trailing angle brackets, the address | |
944 | # is invalid. ie: | |
945 | # "joe smith joe@smith.com" bad | |
946 | # "joe smith <joe@smith.com" bad | |
947 | if ($name ne "" && $address !~ /^<[^>]+>$/) { | |
948 | $name = ""; | |
949 | $address = ""; | |
950 | $comment = ""; | |
951 | } | |
952 | } | |
953 | ||
3705ce5b | 954 | $name = trim($name); |
20112475 | 955 | $name =~ s/^\"|\"$//g; |
3705ce5b | 956 | $address = trim($address); |
20112475 JP |
957 | $address =~ s/^\<|\>$//g; |
958 | ||
959 | if ($name =~ /[^\w \-]/i) { ##has "must quote" chars | |
960 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes | |
961 | $name = "\"$name\""; | |
962 | } | |
963 | ||
964 | return ($name, $address, $comment); | |
965 | } | |
966 | ||
967 | sub format_email { | |
968 | my ($name, $address) = @_; | |
969 | ||
970 | my $formatted_email; | |
971 | ||
3705ce5b | 972 | $name = trim($name); |
20112475 | 973 | $name =~ s/^\"|\"$//g; |
3705ce5b | 974 | $address = trim($address); |
20112475 JP |
975 | |
976 | if ($name =~ /[^\w \-]/i) { ##has "must quote" chars | |
977 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes | |
978 | $name = "\"$name\""; | |
979 | } | |
980 | ||
981 | if ("$name" eq "") { | |
982 | $formatted_email = "$address"; | |
983 | } else { | |
984 | $formatted_email = "$name <$address>"; | |
985 | } | |
986 | ||
987 | return $formatted_email; | |
988 | } | |
989 | ||
d311cd44 | 990 | sub which { |
bd474ca0 | 991 | my ($bin) = @_; |
d311cd44 | 992 | |
bd474ca0 JP |
993 | foreach my $path (split(/:/, $ENV{PATH})) { |
994 | if (-e "$path/$bin") { | |
995 | return "$path/$bin"; | |
996 | } | |
d311cd44 | 997 | } |
d311cd44 | 998 | |
bd474ca0 | 999 | return ""; |
d311cd44 JP |
1000 | } |
1001 | ||
000d1cc1 JP |
1002 | sub which_conf { |
1003 | my ($conf) = @_; | |
1004 | ||
1005 | foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { | |
1006 | if (-e "$path/$conf") { | |
1007 | return "$path/$conf"; | |
1008 | } | |
1009 | } | |
1010 | ||
1011 | return ""; | |
1012 | } | |
1013 | ||
0a920b5b AW |
1014 | sub expand_tabs { |
1015 | my ($str) = @_; | |
1016 | ||
1017 | my $res = ''; | |
1018 | my $n = 0; | |
1019 | for my $c (split(//, $str)) { | |
1020 | if ($c eq "\t") { | |
1021 | $res .= ' '; | |
1022 | $n++; | |
1023 | for (; ($n % 8) != 0; $n++) { | |
1024 | $res .= ' '; | |
1025 | } | |
1026 | next; | |
1027 | } | |
1028 | $res .= $c; | |
1029 | $n++; | |
1030 | } | |
1031 | ||
1032 | return $res; | |
1033 | } | |
6c72ffaa | 1034 | sub copy_spacing { |
773647a0 | 1035 | (my $res = shift) =~ tr/\t/ /c; |
6c72ffaa AW |
1036 | return $res; |
1037 | } | |
0a920b5b | 1038 | |
4a0df2ef AW |
1039 | sub line_stats { |
1040 | my ($line) = @_; | |
1041 | ||
1042 | # Drop the diff line leader and expand tabs | |
1043 | $line =~ s/^.//; | |
1044 | $line = expand_tabs($line); | |
1045 | ||
1046 | # Pick the indent from the front of the line. | |
1047 | my ($white) = ($line =~ /^(\s*)/); | |
1048 | ||
1049 | return (length($line), length($white)); | |
1050 | } | |
1051 | ||
773647a0 AW |
1052 | my $sanitise_quote = ''; |
1053 | ||
1054 | sub sanitise_line_reset { | |
1055 | my ($in_comment) = @_; | |
1056 | ||
1057 | if ($in_comment) { | |
1058 | $sanitise_quote = '*/'; | |
1059 | } else { | |
1060 | $sanitise_quote = ''; | |
1061 | } | |
1062 | } | |
00df344f AW |
1063 | sub sanitise_line { |
1064 | my ($line) = @_; | |
1065 | ||
1066 | my $res = ''; | |
1067 | my $l = ''; | |
1068 | ||
c2fdda0d | 1069 | my $qlen = 0; |
773647a0 AW |
1070 | my $off = 0; |
1071 | my $c; | |
00df344f | 1072 | |
773647a0 AW |
1073 | # Always copy over the diff marker. |
1074 | $res = substr($line, 0, 1); | |
1075 | ||
1076 | for ($off = 1; $off < length($line); $off++) { | |
1077 | $c = substr($line, $off, 1); | |
1078 | ||
1079 | # Comments we are wacking completly including the begin | |
1080 | # and end, all to $;. | |
1081 | if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { | |
1082 | $sanitise_quote = '*/'; | |
1083 | ||
1084 | substr($res, $off, 2, "$;$;"); | |
1085 | $off++; | |
1086 | next; | |
00df344f | 1087 | } |
81bc0e02 | 1088 | if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { |
773647a0 AW |
1089 | $sanitise_quote = ''; |
1090 | substr($res, $off, 2, "$;$;"); | |
1091 | $off++; | |
1092 | next; | |
c2fdda0d | 1093 | } |
113f04a8 DW |
1094 | if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { |
1095 | $sanitise_quote = '//'; | |
1096 | ||
1097 | substr($res, $off, 2, $sanitise_quote); | |
1098 | $off++; | |
1099 | next; | |
1100 | } | |
773647a0 AW |
1101 | |
1102 | # A \ in a string means ignore the next character. | |
1103 | if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && | |
1104 | $c eq "\\") { | |
1105 | substr($res, $off, 2, 'XX'); | |
1106 | $off++; | |
1107 | next; | |
00df344f | 1108 | } |
773647a0 AW |
1109 | # Regular quotes. |
1110 | if ($c eq "'" || $c eq '"') { | |
1111 | if ($sanitise_quote eq '') { | |
1112 | $sanitise_quote = $c; | |
00df344f | 1113 | |
773647a0 AW |
1114 | substr($res, $off, 1, $c); |
1115 | next; | |
1116 | } elsif ($sanitise_quote eq $c) { | |
1117 | $sanitise_quote = ''; | |
1118 | } | |
1119 | } | |
00df344f | 1120 | |
fae17dae | 1121 | #print "c<$c> SQ<$sanitise_quote>\n"; |
773647a0 AW |
1122 | if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { |
1123 | substr($res, $off, 1, $;); | |
113f04a8 DW |
1124 | } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { |
1125 | substr($res, $off, 1, $;); | |
773647a0 AW |
1126 | } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { |
1127 | substr($res, $off, 1, 'X'); | |
1128 | } else { | |
1129 | substr($res, $off, 1, $c); | |
1130 | } | |
c2fdda0d AW |
1131 | } |
1132 | ||
113f04a8 DW |
1133 | if ($sanitise_quote eq '//') { |
1134 | $sanitise_quote = ''; | |
1135 | } | |
1136 | ||
c2fdda0d | 1137 | # The pathname on a #include may be surrounded by '<' and '>'. |
c45dcabd | 1138 | if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { |
c2fdda0d AW |
1139 | my $clean = 'X' x length($1); |
1140 | $res =~ s@\<.*\>@<$clean>@; | |
1141 | ||
1142 | # The whole of a #error is a string. | |
c45dcabd | 1143 | } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { |
c2fdda0d | 1144 | my $clean = 'X' x length($1); |
c45dcabd | 1145 | $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; |
c2fdda0d AW |
1146 | } |
1147 | ||
00df344f AW |
1148 | return $res; |
1149 | } | |
1150 | ||
a6962d72 JP |
1151 | sub get_quoted_string { |
1152 | my ($line, $rawline) = @_; | |
1153 | ||
33acb54a | 1154 | return "" if ($line !~ m/($String)/g); |
a6962d72 JP |
1155 | return substr($rawline, $-[0], $+[0] - $-[0]); |
1156 | } | |
1157 | ||
8905a67c AW |
1158 | sub ctx_statement_block { |
1159 | my ($linenr, $remain, $off) = @_; | |
1160 | my $line = $linenr - 1; | |
1161 | my $blk = ''; | |
1162 | my $soff = $off; | |
1163 | my $coff = $off - 1; | |
773647a0 | 1164 | my $coff_set = 0; |
8905a67c | 1165 | |
13214adf AW |
1166 | my $loff = 0; |
1167 | ||
8905a67c AW |
1168 | my $type = ''; |
1169 | my $level = 0; | |
a2750645 | 1170 | my @stack = (); |
cf655043 | 1171 | my $p; |
8905a67c AW |
1172 | my $c; |
1173 | my $len = 0; | |
13214adf AW |
1174 | |
1175 | my $remainder; | |
8905a67c | 1176 | while (1) { |
a2750645 AW |
1177 | @stack = (['', 0]) if ($#stack == -1); |
1178 | ||
773647a0 | 1179 | #warn "CSB: blk<$blk> remain<$remain>\n"; |
8905a67c AW |
1180 | # If we are about to drop off the end, pull in more |
1181 | # context. | |
1182 | if ($off >= $len) { | |
1183 | for (; $remain > 0; $line++) { | |
dea33496 | 1184 | last if (!defined $lines[$line]); |
c2fdda0d | 1185 | next if ($lines[$line] =~ /^-/); |
8905a67c | 1186 | $remain--; |
13214adf | 1187 | $loff = $len; |
c2fdda0d | 1188 | $blk .= $lines[$line] . "\n"; |
8905a67c AW |
1189 | $len = length($blk); |
1190 | $line++; | |
1191 | last; | |
1192 | } | |
1193 | # Bail if there is no further context. | |
1194 | #warn "CSB: blk<$blk> off<$off> len<$len>\n"; | |
13214adf | 1195 | if ($off >= $len) { |
8905a67c AW |
1196 | last; |
1197 | } | |
f74bd194 AW |
1198 | if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { |
1199 | $level++; | |
1200 | $type = '#'; | |
1201 | } | |
8905a67c | 1202 | } |
cf655043 | 1203 | $p = $c; |
8905a67c | 1204 | $c = substr($blk, $off, 1); |
13214adf | 1205 | $remainder = substr($blk, $off); |
8905a67c | 1206 | |
773647a0 | 1207 | #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; |
4635f4fb AW |
1208 | |
1209 | # Handle nested #if/#else. | |
1210 | if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { | |
1211 | push(@stack, [ $type, $level ]); | |
1212 | } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { | |
1213 | ($type, $level) = @{$stack[$#stack - 1]}; | |
1214 | } elsif ($remainder =~ /^#\s*endif\b/) { | |
1215 | ($type, $level) = @{pop(@stack)}; | |
1216 | } | |
1217 | ||
8905a67c AW |
1218 | # Statement ends at the ';' or a close '}' at the |
1219 | # outermost level. | |
1220 | if ($level == 0 && $c eq ';') { | |
1221 | last; | |
1222 | } | |
1223 | ||
13214adf | 1224 | # An else is really a conditional as long as its not else if |
773647a0 AW |
1225 | if ($level == 0 && $coff_set == 0 && |
1226 | (!defined($p) || $p =~ /(?:\s|\}|\+)/) && | |
1227 | $remainder =~ /^(else)(?:\s|{)/ && | |
1228 | $remainder !~ /^else\s+if\b/) { | |
1229 | $coff = $off + length($1) - 1; | |
1230 | $coff_set = 1; | |
1231 | #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; | |
1232 | #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; | |
13214adf AW |
1233 | } |
1234 | ||
8905a67c AW |
1235 | if (($type eq '' || $type eq '(') && $c eq '(') { |
1236 | $level++; | |
1237 | $type = '('; | |
1238 | } | |
1239 | if ($type eq '(' && $c eq ')') { | |
1240 | $level--; | |
1241 | $type = ($level != 0)? '(' : ''; | |
1242 | ||
1243 | if ($level == 0 && $coff < $soff) { | |
1244 | $coff = $off; | |
773647a0 AW |
1245 | $coff_set = 1; |
1246 | #warn "CSB: mark coff<$coff>\n"; | |
8905a67c AW |
1247 | } |
1248 | } | |
1249 | if (($type eq '' || $type eq '{') && $c eq '{') { | |
1250 | $level++; | |
1251 | $type = '{'; | |
1252 | } | |
1253 | if ($type eq '{' && $c eq '}') { | |
1254 | $level--; | |
1255 | $type = ($level != 0)? '{' : ''; | |
1256 | ||
1257 | if ($level == 0) { | |
b998e001 PP |
1258 | if (substr($blk, $off + 1, 1) eq ';') { |
1259 | $off++; | |
1260 | } | |
8905a67c AW |
1261 | last; |
1262 | } | |
1263 | } | |
f74bd194 AW |
1264 | # Preprocessor commands end at the newline unless escaped. |
1265 | if ($type eq '#' && $c eq "\n" && $p ne "\\") { | |
1266 | $level--; | |
1267 | $type = ''; | |
1268 | $off++; | |
1269 | last; | |
1270 | } | |
8905a67c AW |
1271 | $off++; |
1272 | } | |
a3bb97a7 | 1273 | # We are truly at the end, so shuffle to the next line. |
13214adf | 1274 | if ($off == $len) { |
a3bb97a7 | 1275 | $loff = $len + 1; |
13214adf AW |
1276 | $line++; |
1277 | $remain--; | |
1278 | } | |
8905a67c AW |
1279 | |
1280 | my $statement = substr($blk, $soff, $off - $soff + 1); | |
1281 | my $condition = substr($blk, $soff, $coff - $soff + 1); | |
1282 | ||
1283 | #warn "STATEMENT<$statement>\n"; | |
1284 | #warn "CONDITION<$condition>\n"; | |
1285 | ||
773647a0 | 1286 | #print "coff<$coff> soff<$off> loff<$loff>\n"; |
13214adf AW |
1287 | |
1288 | return ($statement, $condition, | |
1289 | $line, $remain + 1, $off - $loff + 1, $level); | |
1290 | } | |
1291 | ||
cf655043 AW |
1292 | sub statement_lines { |
1293 | my ($stmt) = @_; | |
1294 | ||
1295 | # Strip the diff line prefixes and rip blank lines at start and end. | |
1296 | $stmt =~ s/(^|\n)./$1/g; | |
1297 | $stmt =~ s/^\s*//; | |
1298 | $stmt =~ s/\s*$//; | |
1299 | ||
1300 | my @stmt_lines = ($stmt =~ /\n/g); | |
1301 | ||
1302 | return $#stmt_lines + 2; | |
1303 | } | |
1304 | ||
1305 | sub statement_rawlines { | |
1306 | my ($stmt) = @_; | |
1307 | ||
1308 | my @stmt_lines = ($stmt =~ /\n/g); | |
1309 | ||
1310 | return $#stmt_lines + 2; | |
1311 | } | |
1312 | ||
1313 | sub statement_block_size { | |
1314 | my ($stmt) = @_; | |
1315 | ||
1316 | $stmt =~ s/(^|\n)./$1/g; | |
1317 | $stmt =~ s/^\s*{//; | |
1318 | $stmt =~ s/}\s*$//; | |
1319 | $stmt =~ s/^\s*//; | |
1320 | $stmt =~ s/\s*$//; | |
1321 | ||
1322 | my @stmt_lines = ($stmt =~ /\n/g); | |
1323 | my @stmt_statements = ($stmt =~ /;/g); | |
1324 | ||
1325 | my $stmt_lines = $#stmt_lines + 2; | |
1326 | my $stmt_statements = $#stmt_statements + 1; | |
1327 | ||
1328 | if ($stmt_lines > $stmt_statements) { | |
1329 | return $stmt_lines; | |
1330 | } else { | |
1331 | return $stmt_statements; | |
1332 | } | |
1333 | } | |
1334 | ||
13214adf AW |
1335 | sub ctx_statement_full { |
1336 | my ($linenr, $remain, $off) = @_; | |
1337 | my ($statement, $condition, $level); | |
1338 | ||
1339 | my (@chunks); | |
1340 | ||
cf655043 | 1341 | # Grab the first conditional/block pair. |
13214adf AW |
1342 | ($statement, $condition, $linenr, $remain, $off, $level) = |
1343 | ctx_statement_block($linenr, $remain, $off); | |
773647a0 | 1344 | #print "F: c<$condition> s<$statement> remain<$remain>\n"; |
cf655043 AW |
1345 | push(@chunks, [ $condition, $statement ]); |
1346 | if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { | |
1347 | return ($level, $linenr, @chunks); | |
1348 | } | |
1349 | ||
1350 | # Pull in the following conditional/block pairs and see if they | |
1351 | # could continue the statement. | |
13214adf | 1352 | for (;;) { |
13214adf AW |
1353 | ($statement, $condition, $linenr, $remain, $off, $level) = |
1354 | ctx_statement_block($linenr, $remain, $off); | |
cf655043 | 1355 | #print "C: c<$condition> s<$statement> remain<$remain>\n"; |
773647a0 | 1356 | last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); |
cf655043 AW |
1357 | #print "C: push\n"; |
1358 | push(@chunks, [ $condition, $statement ]); | |
13214adf AW |
1359 | } |
1360 | ||
1361 | return ($level, $linenr, @chunks); | |
8905a67c AW |
1362 | } |
1363 | ||
4a0df2ef | 1364 | sub ctx_block_get { |
f0a594c1 | 1365 | my ($linenr, $remain, $outer, $open, $close, $off) = @_; |
4a0df2ef AW |
1366 | my $line; |
1367 | my $start = $linenr - 1; | |
4a0df2ef AW |
1368 | my $blk = ''; |
1369 | my @o; | |
1370 | my @c; | |
1371 | my @res = (); | |
1372 | ||
f0a594c1 | 1373 | my $level = 0; |
4635f4fb | 1374 | my @stack = ($level); |
00df344f AW |
1375 | for ($line = $start; $remain > 0; $line++) { |
1376 | next if ($rawlines[$line] =~ /^-/); | |
1377 | $remain--; | |
1378 | ||
1379 | $blk .= $rawlines[$line]; | |
4635f4fb AW |
1380 | |
1381 | # Handle nested #if/#else. | |
01464f30 | 1382 | if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { |
4635f4fb | 1383 | push(@stack, $level); |
01464f30 | 1384 | } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { |
4635f4fb | 1385 | $level = $stack[$#stack - 1]; |
01464f30 | 1386 | } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { |
4635f4fb AW |
1387 | $level = pop(@stack); |
1388 | } | |
1389 | ||
01464f30 | 1390 | foreach my $c (split(//, $lines[$line])) { |
f0a594c1 AW |
1391 | ##print "C<$c>L<$level><$open$close>O<$off>\n"; |
1392 | if ($off > 0) { | |
1393 | $off--; | |
1394 | next; | |
1395 | } | |
4a0df2ef | 1396 | |
f0a594c1 AW |
1397 | if ($c eq $close && $level > 0) { |
1398 | $level--; | |
1399 | last if ($level == 0); | |
1400 | } elsif ($c eq $open) { | |
1401 | $level++; | |
1402 | } | |
1403 | } | |
4a0df2ef | 1404 | |
f0a594c1 | 1405 | if (!$outer || $level <= 1) { |
00df344f | 1406 | push(@res, $rawlines[$line]); |
4a0df2ef AW |
1407 | } |
1408 | ||
f0a594c1 | 1409 | last if ($level == 0); |
4a0df2ef AW |
1410 | } |
1411 | ||
f0a594c1 | 1412 | return ($level, @res); |
4a0df2ef AW |
1413 | } |
1414 | sub ctx_block_outer { | |
1415 | my ($linenr, $remain) = @_; | |
1416 | ||
f0a594c1 AW |
1417 | my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); |
1418 | return @r; | |
4a0df2ef AW |
1419 | } |
1420 | sub ctx_block { | |
1421 | my ($linenr, $remain) = @_; | |
1422 | ||
f0a594c1 AW |
1423 | my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); |
1424 | return @r; | |
653d4876 AW |
1425 | } |
1426 | sub ctx_statement { | |
f0a594c1 AW |
1427 | my ($linenr, $remain, $off) = @_; |
1428 | ||
1429 | my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); | |
1430 | return @r; | |
1431 | } | |
1432 | sub ctx_block_level { | |
653d4876 AW |
1433 | my ($linenr, $remain) = @_; |
1434 | ||
f0a594c1 | 1435 | return ctx_block_get($linenr, $remain, 0, '{', '}', 0); |
4a0df2ef | 1436 | } |
9c0ca6f9 AW |
1437 | sub ctx_statement_level { |
1438 | my ($linenr, $remain, $off) = @_; | |
1439 | ||
1440 | return ctx_block_get($linenr, $remain, 0, '(', ')', $off); | |
1441 | } | |
4a0df2ef AW |
1442 | |
1443 | sub ctx_locate_comment { | |
1444 | my ($first_line, $end_line) = @_; | |
1445 | ||
1446 | # Catch a comment on the end of the line itself. | |
beae6332 | 1447 | my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); |
4a0df2ef AW |
1448 | return $current_comment if (defined $current_comment); |
1449 | ||
1450 | # Look through the context and try and figure out if there is a | |
1451 | # comment. | |
1452 | my $in_comment = 0; | |
1453 | $current_comment = ''; | |
1454 | for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { | |
00df344f AW |
1455 | my $line = $rawlines[$linenr - 1]; |
1456 | #warn " $line\n"; | |
4a0df2ef AW |
1457 | if ($linenr == $first_line and $line =~ m@^.\s*\*@) { |
1458 | $in_comment = 1; | |
1459 | } | |
1460 | if ($line =~ m@/\*@) { | |
1461 | $in_comment = 1; | |
1462 | } | |
1463 | if (!$in_comment && $current_comment ne '') { | |
1464 | $current_comment = ''; | |
1465 | } | |
1466 | $current_comment .= $line . "\n" if ($in_comment); | |
1467 | if ($line =~ m@\*/@) { | |
1468 | $in_comment = 0; | |
1469 | } | |
1470 | } | |
1471 | ||
1472 | chomp($current_comment); | |
1473 | return($current_comment); | |
1474 | } | |
1475 | sub ctx_has_comment { | |
1476 | my ($first_line, $end_line) = @_; | |
1477 | my $cmt = ctx_locate_comment($first_line, $end_line); | |
1478 | ||
00df344f | 1479 | ##print "LINE: $rawlines[$end_line - 1 ]\n"; |
4a0df2ef AW |
1480 | ##print "CMMT: $cmt\n"; |
1481 | ||
1482 | return ($cmt ne ''); | |
1483 | } | |
1484 | ||
4d001e4d AW |
1485 | sub raw_line { |
1486 | my ($linenr, $cnt) = @_; | |
1487 | ||
1488 | my $offset = $linenr - 1; | |
1489 | $cnt++; | |
1490 | ||
1491 | my $line; | |
1492 | while ($cnt) { | |
1493 | $line = $rawlines[$offset++]; | |
1494 | next if (defined($line) && $line =~ /^-/); | |
1495 | $cnt--; | |
1496 | } | |
1497 | ||
1498 | return $line; | |
1499 | } | |
1500 | ||
6c72ffaa AW |
1501 | sub cat_vet { |
1502 | my ($vet) = @_; | |
1503 | my ($res, $coded); | |
9c0ca6f9 | 1504 | |
6c72ffaa AW |
1505 | $res = ''; |
1506 | while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { | |
1507 | $res .= $1; | |
1508 | if ($2 ne '') { | |
1509 | $coded = sprintf("^%c", unpack('C', $2) + 64); | |
1510 | $res .= $coded; | |
9c0ca6f9 AW |
1511 | } |
1512 | } | |
6c72ffaa | 1513 | $res =~ s/$/\$/; |
9c0ca6f9 | 1514 | |
6c72ffaa | 1515 | return $res; |
9c0ca6f9 AW |
1516 | } |
1517 | ||
c2fdda0d | 1518 | my $av_preprocessor = 0; |
cf655043 | 1519 | my $av_pending; |
c2fdda0d | 1520 | my @av_paren_type; |
1f65f947 | 1521 | my $av_pend_colon; |
c2fdda0d AW |
1522 | |
1523 | sub annotate_reset { | |
1524 | $av_preprocessor = 0; | |
cf655043 AW |
1525 | $av_pending = '_'; |
1526 | @av_paren_type = ('E'); | |
1f65f947 | 1527 | $av_pend_colon = 'O'; |
c2fdda0d AW |
1528 | } |
1529 | ||
6c72ffaa AW |
1530 | sub annotate_values { |
1531 | my ($stream, $type) = @_; | |
0a920b5b | 1532 | |
6c72ffaa | 1533 | my $res; |
1f65f947 | 1534 | my $var = '_' x length($stream); |
6c72ffaa AW |
1535 | my $cur = $stream; |
1536 | ||
c2fdda0d | 1537 | print "$stream\n" if ($dbg_values > 1); |
6c72ffaa | 1538 | |
6c72ffaa | 1539 | while (length($cur)) { |
773647a0 | 1540 | @av_paren_type = ('E') if ($#av_paren_type < 0); |
cf655043 | 1541 | print " <" . join('', @av_paren_type) . |
171ae1a4 | 1542 | "> <$type> <$av_pending>" if ($dbg_values > 1); |
6c72ffaa | 1543 | if ($cur =~ /^(\s+)/o) { |
c2fdda0d AW |
1544 | print "WS($1)\n" if ($dbg_values > 1); |
1545 | if ($1 =~ /\n/ && $av_preprocessor) { | |
cf655043 | 1546 | $type = pop(@av_paren_type); |
c2fdda0d | 1547 | $av_preprocessor = 0; |
6c72ffaa AW |
1548 | } |
1549 | ||
c023e473 | 1550 | } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { |
9446ef56 AW |
1551 | print "CAST($1)\n" if ($dbg_values > 1); |
1552 | push(@av_paren_type, $type); | |
addcdcea | 1553 | $type = 'c'; |
9446ef56 | 1554 | |
e91b6e26 | 1555 | } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { |
c2fdda0d | 1556 | print "DECLARE($1)\n" if ($dbg_values > 1); |
6c72ffaa AW |
1557 | $type = 'T'; |
1558 | ||
389a2fe5 AW |
1559 | } elsif ($cur =~ /^($Modifier)\s*/) { |
1560 | print "MODIFIER($1)\n" if ($dbg_values > 1); | |
1561 | $type = 'T'; | |
1562 | ||
c45dcabd | 1563 | } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { |
171ae1a4 | 1564 | print "DEFINE($1,$2)\n" if ($dbg_values > 1); |
c2fdda0d | 1565 | $av_preprocessor = 1; |
171ae1a4 AW |
1566 | push(@av_paren_type, $type); |
1567 | if ($2 ne '') { | |
1568 | $av_pending = 'N'; | |
1569 | } | |
1570 | $type = 'E'; | |
1571 | ||
c45dcabd | 1572 | } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { |
171ae1a4 AW |
1573 | print "UNDEF($1)\n" if ($dbg_values > 1); |
1574 | $av_preprocessor = 1; | |
1575 | push(@av_paren_type, $type); | |
6c72ffaa | 1576 | |
c45dcabd | 1577 | } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { |
cf655043 | 1578 | print "PRE_START($1)\n" if ($dbg_values > 1); |
c2fdda0d | 1579 | $av_preprocessor = 1; |
cf655043 AW |
1580 | |
1581 | push(@av_paren_type, $type); | |
1582 | push(@av_paren_type, $type); | |
171ae1a4 | 1583 | $type = 'E'; |
cf655043 | 1584 | |
c45dcabd | 1585 | } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { |
cf655043 AW |
1586 | print "PRE_RESTART($1)\n" if ($dbg_values > 1); |
1587 | $av_preprocessor = 1; | |
1588 | ||
1589 | push(@av_paren_type, $av_paren_type[$#av_paren_type]); | |
1590 | ||
171ae1a4 | 1591 | $type = 'E'; |
cf655043 | 1592 | |
c45dcabd | 1593 | } elsif ($cur =~ /^(\#\s*(?:endif))/o) { |
cf655043 AW |
1594 | print "PRE_END($1)\n" if ($dbg_values > 1); |
1595 | ||
1596 | $av_preprocessor = 1; | |
1597 | ||
1598 | # Assume all arms of the conditional end as this | |
1599 | # one does, and continue as if the #endif was not here. | |
1600 | pop(@av_paren_type); | |
1601 | push(@av_paren_type, $type); | |
171ae1a4 | 1602 | $type = 'E'; |
6c72ffaa AW |
1603 | |
1604 | } elsif ($cur =~ /^(\\\n)/o) { | |
c2fdda0d | 1605 | print "PRECONT($1)\n" if ($dbg_values > 1); |
6c72ffaa | 1606 | |
171ae1a4 AW |
1607 | } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { |
1608 | print "ATTR($1)\n" if ($dbg_values > 1); | |
1609 | $av_pending = $type; | |
1610 | $type = 'N'; | |
1611 | ||
6c72ffaa | 1612 | } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { |
c2fdda0d | 1613 | print "SIZEOF($1)\n" if ($dbg_values > 1); |
6c72ffaa | 1614 | if (defined $2) { |
cf655043 | 1615 | $av_pending = 'V'; |
6c72ffaa AW |
1616 | } |
1617 | $type = 'N'; | |
1618 | ||
14b111c1 | 1619 | } elsif ($cur =~ /^(if|while|for)\b/o) { |
c2fdda0d | 1620 | print "COND($1)\n" if ($dbg_values > 1); |
14b111c1 | 1621 | $av_pending = 'E'; |
6c72ffaa AW |
1622 | $type = 'N'; |
1623 | ||
1f65f947 AW |
1624 | } elsif ($cur =~/^(case)/o) { |
1625 | print "CASE($1)\n" if ($dbg_values > 1); | |
1626 | $av_pend_colon = 'C'; | |
1627 | $type = 'N'; | |
1628 | ||
14b111c1 | 1629 | } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { |
c2fdda0d | 1630 | print "KEYWORD($1)\n" if ($dbg_values > 1); |
6c72ffaa AW |
1631 | $type = 'N'; |
1632 | ||
1633 | } elsif ($cur =~ /^(\()/o) { | |
c2fdda0d | 1634 | print "PAREN('$1')\n" if ($dbg_values > 1); |
cf655043 AW |
1635 | push(@av_paren_type, $av_pending); |
1636 | $av_pending = '_'; | |
6c72ffaa AW |
1637 | $type = 'N'; |
1638 | ||
1639 | } elsif ($cur =~ /^(\))/o) { | |
cf655043 AW |
1640 | my $new_type = pop(@av_paren_type); |
1641 | if ($new_type ne '_') { | |
1642 | $type = $new_type; | |
c2fdda0d AW |
1643 | print "PAREN('$1') -> $type\n" |
1644 | if ($dbg_values > 1); | |
6c72ffaa | 1645 | } else { |
c2fdda0d | 1646 | print "PAREN('$1')\n" if ($dbg_values > 1); |
6c72ffaa AW |
1647 | } |
1648 | ||
c8cb2ca3 | 1649 | } elsif ($cur =~ /^($Ident)\s*\(/o) { |
c2fdda0d | 1650 | print "FUNC($1)\n" if ($dbg_values > 1); |
c8cb2ca3 | 1651 | $type = 'V'; |
cf655043 | 1652 | $av_pending = 'V'; |
6c72ffaa | 1653 | |
8e761b04 AW |
1654 | } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { |
1655 | if (defined $2 && $type eq 'C' || $type eq 'T') { | |
1f65f947 | 1656 | $av_pend_colon = 'B'; |
8e761b04 AW |
1657 | } elsif ($type eq 'E') { |
1658 | $av_pend_colon = 'L'; | |
1f65f947 AW |
1659 | } |
1660 | print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); | |
1661 | $type = 'V'; | |
1662 | ||
6c72ffaa | 1663 | } elsif ($cur =~ /^($Ident|$Constant)/o) { |
c2fdda0d | 1664 | print "IDENT($1)\n" if ($dbg_values > 1); |
6c72ffaa AW |
1665 | $type = 'V'; |
1666 | ||
1667 | } elsif ($cur =~ /^($Assignment)/o) { | |
c2fdda0d | 1668 | print "ASSIGN($1)\n" if ($dbg_values > 1); |
6c72ffaa AW |
1669 | $type = 'N'; |
1670 | ||
cf655043 | 1671 | } elsif ($cur =~/^(;|{|})/) { |
c2fdda0d | 1672 | print "END($1)\n" if ($dbg_values > 1); |
13214adf | 1673 | $type = 'E'; |
1f65f947 AW |
1674 | $av_pend_colon = 'O'; |
1675 | ||
8e761b04 AW |
1676 | } elsif ($cur =~/^(,)/) { |
1677 | print "COMMA($1)\n" if ($dbg_values > 1); | |
1678 | $type = 'C'; | |
1679 | ||
1f65f947 AW |
1680 | } elsif ($cur =~ /^(\?)/o) { |
1681 | print "QUESTION($1)\n" if ($dbg_values > 1); | |
1682 | $type = 'N'; | |
1683 | ||
1684 | } elsif ($cur =~ /^(:)/o) { | |
1685 | print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); | |
1686 | ||
1687 | substr($var, length($res), 1, $av_pend_colon); | |
1688 | if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { | |
1689 | $type = 'E'; | |
1690 | } else { | |
1691 | $type = 'N'; | |
1692 | } | |
1693 | $av_pend_colon = 'O'; | |
13214adf | 1694 | |
8e761b04 | 1695 | } elsif ($cur =~ /^(\[)/o) { |
13214adf | 1696 | print "CLOSE($1)\n" if ($dbg_values > 1); |
6c72ffaa AW |
1697 | $type = 'N'; |
1698 | ||
0d413866 | 1699 | } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { |
74048ed8 AW |
1700 | my $variant; |
1701 | ||
1702 | print "OPV($1)\n" if ($dbg_values > 1); | |
1703 | if ($type eq 'V') { | |
1704 | $variant = 'B'; | |
1705 | } else { | |
1706 | $variant = 'U'; | |
1707 | } | |
1708 | ||
1709 | substr($var, length($res), 1, $variant); | |
1710 | $type = 'N'; | |
1711 | ||
6c72ffaa | 1712 | } elsif ($cur =~ /^($Operators)/o) { |
c2fdda0d | 1713 | print "OP($1)\n" if ($dbg_values > 1); |
6c72ffaa AW |
1714 | if ($1 ne '++' && $1 ne '--') { |
1715 | $type = 'N'; | |
1716 | } | |
1717 | ||
1718 | } elsif ($cur =~ /(^.)/o) { | |
c2fdda0d | 1719 | print "C($1)\n" if ($dbg_values > 1); |
6c72ffaa AW |
1720 | } |
1721 | if (defined $1) { | |
1722 | $cur = substr($cur, length($1)); | |
1723 | $res .= $type x length($1); | |
1724 | } | |
9c0ca6f9 | 1725 | } |
0a920b5b | 1726 | |
1f65f947 | 1727 | return ($res, $var); |
0a920b5b AW |
1728 | } |
1729 | ||
8905a67c | 1730 | sub possible { |
13214adf | 1731 | my ($possible, $line) = @_; |
9a974fdb | 1732 | my $notPermitted = qr{(?: |
0776e594 AW |
1733 | ^(?: |
1734 | $Modifier| | |
1735 | $Storage| | |
1736 | $Type| | |
9a974fdb AW |
1737 | DEFINE_\S+ |
1738 | )$| | |
1739 | ^(?: | |
0776e594 AW |
1740 | goto| |
1741 | return| | |
1742 | case| | |
1743 | else| | |
1744 | asm|__asm__| | |
89a88353 AW |
1745 | do| |
1746 | \#| | |
1747 | \#\#| | |
9a974fdb | 1748 | )(?:\s|$)| |
0776e594 | 1749 | ^(?:typedef|struct|enum)\b |
9a974fdb AW |
1750 | )}x; |
1751 | warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); | |
1752 | if ($possible !~ $notPermitted) { | |
c45dcabd AW |
1753 | # Check for modifiers. |
1754 | $possible =~ s/\s*$Storage\s*//g; | |
1755 | $possible =~ s/\s*$Sparse\s*//g; | |
1756 | if ($possible =~ /^\s*$/) { | |
1757 | ||
1758 | } elsif ($possible =~ /\s/) { | |
1759 | $possible =~ s/\s*$Type\s*//g; | |
d2506586 | 1760 | for my $modifier (split(' ', $possible)) { |
9a974fdb AW |
1761 | if ($modifier !~ $notPermitted) { |
1762 | warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); | |
485ff23e | 1763 | push(@modifierListFile, $modifier); |
9a974fdb | 1764 | } |
d2506586 | 1765 | } |
c45dcabd AW |
1766 | |
1767 | } else { | |
1768 | warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); | |
485ff23e | 1769 | push(@typeListFile, $possible); |
c45dcabd | 1770 | } |
8905a67c | 1771 | build_types(); |
0776e594 AW |
1772 | } else { |
1773 | warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); | |
8905a67c AW |
1774 | } |
1775 | } | |
1776 | ||
6c72ffaa AW |
1777 | my $prefix = ''; |
1778 | ||
000d1cc1 | 1779 | sub show_type { |
cbec18af | 1780 | my ($type) = @_; |
91bfe484 | 1781 | |
cbec18af JP |
1782 | return defined $use_type{$type} if (scalar keys %use_type > 0); |
1783 | ||
1784 | return !defined $ignore_type{$type}; | |
000d1cc1 JP |
1785 | } |
1786 | ||
f0a594c1 | 1787 | sub report { |
cbec18af JP |
1788 | my ($level, $type, $msg) = @_; |
1789 | ||
1790 | if (!show_type($type) || | |
1791 | (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { | |
773647a0 AW |
1792 | return 0; |
1793 | } | |
57230297 JP |
1794 | my $output = ''; |
1795 | if (-t STDOUT && $color) { | |
1796 | if ($level eq 'ERROR') { | |
1797 | $output .= RED; | |
1798 | } elsif ($level eq 'WARNING') { | |
1799 | $output .= YELLOW; | |
1800 | } else { | |
1801 | $output .= GREEN; | |
1802 | } | |
1803 | } | |
1804 | $output .= $prefix . $level . ':'; | |
000d1cc1 | 1805 | if ($show_types) { |
57230297 JP |
1806 | $output .= BLUE if (-t STDOUT && $color); |
1807 | $output .= "$type:"; | |
000d1cc1 | 1808 | } |
57230297 JP |
1809 | $output .= RESET if (-t STDOUT && $color); |
1810 | $output .= ' ' . $msg . "\n"; | |
34d8815f JP |
1811 | |
1812 | if ($showfile) { | |
1813 | my @lines = split("\n", $output, -1); | |
1814 | splice(@lines, 1, 1); | |
1815 | $output = join("\n", @lines); | |
1816 | } | |
57230297 | 1817 | $output = (split('\n', $output))[0] . "\n" if ($terse); |
8905a67c | 1818 | |
57230297 | 1819 | push(our @report, $output); |
773647a0 AW |
1820 | |
1821 | return 1; | |
f0a594c1 | 1822 | } |
cbec18af | 1823 | |
f0a594c1 | 1824 | sub report_dump { |
13214adf | 1825 | our @report; |
f0a594c1 | 1826 | } |
000d1cc1 | 1827 | |
d752fcc8 JP |
1828 | sub fixup_current_range { |
1829 | my ($lineRef, $offset, $length) = @_; | |
1830 | ||
1831 | if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { | |
1832 | my $o = $1; | |
1833 | my $l = $2; | |
1834 | my $no = $o + $offset; | |
1835 | my $nl = $l + $length; | |
1836 | $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; | |
1837 | } | |
1838 | } | |
1839 | ||
1840 | sub fix_inserted_deleted_lines { | |
1841 | my ($linesRef, $insertedRef, $deletedRef) = @_; | |
1842 | ||
1843 | my $range_last_linenr = 0; | |
1844 | my $delta_offset = 0; | |
1845 | ||
1846 | my $old_linenr = 0; | |
1847 | my $new_linenr = 0; | |
1848 | ||
1849 | my $next_insert = 0; | |
1850 | my $next_delete = 0; | |
1851 | ||
1852 | my @lines = (); | |
1853 | ||
1854 | my $inserted = @{$insertedRef}[$next_insert++]; | |
1855 | my $deleted = @{$deletedRef}[$next_delete++]; | |
1856 | ||
1857 | foreach my $old_line (@{$linesRef}) { | |
1858 | my $save_line = 1; | |
1859 | my $line = $old_line; #don't modify the array | |
323b267f | 1860 | if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename |
d752fcc8 JP |
1861 | $delta_offset = 0; |
1862 | } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk | |
1863 | $range_last_linenr = $new_linenr; | |
1864 | fixup_current_range(\$line, $delta_offset, 0); | |
1865 | } | |
1866 | ||
1867 | while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { | |
1868 | $deleted = @{$deletedRef}[$next_delete++]; | |
1869 | $save_line = 0; | |
1870 | fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); | |
1871 | } | |
1872 | ||
1873 | while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { | |
1874 | push(@lines, ${$inserted}{'LINE'}); | |
1875 | $inserted = @{$insertedRef}[$next_insert++]; | |
1876 | $new_linenr++; | |
1877 | fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); | |
1878 | } | |
1879 | ||
1880 | if ($save_line) { | |
1881 | push(@lines, $line); | |
1882 | $new_linenr++; | |
1883 | } | |
1884 | ||
1885 | $old_linenr++; | |
1886 | } | |
1887 | ||
1888 | return @lines; | |
1889 | } | |
1890 | ||
f2d7e4d4 JP |
1891 | sub fix_insert_line { |
1892 | my ($linenr, $line) = @_; | |
1893 | ||
1894 | my $inserted = { | |
1895 | LINENR => $linenr, | |
1896 | LINE => $line, | |
1897 | }; | |
1898 | push(@fixed_inserted, $inserted); | |
1899 | } | |
1900 | ||
1901 | sub fix_delete_line { | |
1902 | my ($linenr, $line) = @_; | |
1903 | ||
1904 | my $deleted = { | |
1905 | LINENR => $linenr, | |
1906 | LINE => $line, | |
1907 | }; | |
1908 | ||
1909 | push(@fixed_deleted, $deleted); | |
1910 | } | |
1911 | ||
de7d4f0e | 1912 | sub ERROR { |
cbec18af JP |
1913 | my ($type, $msg) = @_; |
1914 | ||
1915 | if (report("ERROR", $type, $msg)) { | |
773647a0 AW |
1916 | our $clean = 0; |
1917 | our $cnt_error++; | |
3705ce5b | 1918 | return 1; |
773647a0 | 1919 | } |
3705ce5b | 1920 | return 0; |
de7d4f0e AW |
1921 | } |
1922 | sub WARN { | |
cbec18af JP |
1923 | my ($type, $msg) = @_; |
1924 | ||
1925 | if (report("WARNING", $type, $msg)) { | |
773647a0 AW |
1926 | our $clean = 0; |
1927 | our $cnt_warn++; | |
3705ce5b | 1928 | return 1; |
773647a0 | 1929 | } |
3705ce5b | 1930 | return 0; |
de7d4f0e AW |
1931 | } |
1932 | sub CHK { | |
cbec18af JP |
1933 | my ($type, $msg) = @_; |
1934 | ||
1935 | if ($check && report("CHECK", $type, $msg)) { | |
6c72ffaa AW |
1936 | our $clean = 0; |
1937 | our $cnt_chk++; | |
3705ce5b | 1938 | return 1; |
6c72ffaa | 1939 | } |
3705ce5b | 1940 | return 0; |
de7d4f0e AW |
1941 | } |
1942 | ||
6ecd9674 AW |
1943 | sub check_absolute_file { |
1944 | my ($absolute, $herecurr) = @_; | |
1945 | my $file = $absolute; | |
1946 | ||
1947 | ##print "absolute<$absolute>\n"; | |
1948 | ||
1949 | # See if any suffix of this path is a path within the tree. | |
1950 | while ($file =~ s@^[^/]*/@@) { | |
1951 | if (-f "$root/$file") { | |
1952 | ##print "file<$file>\n"; | |
1953 | last; | |
1954 | } | |
1955 | } | |
1956 | if (! -f _) { | |
1957 | return 0; | |
1958 | } | |
1959 | ||
1960 | # It is, so see if the prefix is acceptable. | |
1961 | my $prefix = $absolute; | |
1962 | substr($prefix, -length($file)) = ''; | |
1963 | ||
1964 | ##print "prefix<$prefix>\n"; | |
1965 | if ($prefix ne ".../") { | |
000d1cc1 JP |
1966 | WARN("USE_RELATIVE_PATH", |
1967 | "use relative pathname instead of absolute in changelog text\n" . $herecurr); | |
6ecd9674 AW |
1968 | } |
1969 | } | |
1970 | ||
3705ce5b JP |
1971 | sub trim { |
1972 | my ($string) = @_; | |
1973 | ||
b34c648b JP |
1974 | $string =~ s/^\s+|\s+$//g; |
1975 | ||
1976 | return $string; | |
1977 | } | |
1978 | ||
1979 | sub ltrim { | |
1980 | my ($string) = @_; | |
1981 | ||
1982 | $string =~ s/^\s+//; | |
1983 | ||
1984 | return $string; | |
1985 | } | |
1986 | ||
1987 | sub rtrim { | |
1988 | my ($string) = @_; | |
1989 | ||
1990 | $string =~ s/\s+$//; | |
3705ce5b JP |
1991 | |
1992 | return $string; | |
1993 | } | |
1994 | ||
52ea8506 JP |
1995 | sub string_find_replace { |
1996 | my ($string, $find, $replace) = @_; | |
1997 | ||
1998 | $string =~ s/$find/$replace/g; | |
1999 | ||
2000 | return $string; | |
2001 | } | |
2002 | ||
3705ce5b JP |
2003 | sub tabify { |
2004 | my ($leading) = @_; | |
2005 | ||
2006 | my $source_indent = 8; | |
2007 | my $max_spaces_before_tab = $source_indent - 1; | |
2008 | my $spaces_to_tab = " " x $source_indent; | |
2009 | ||
2010 | #convert leading spaces to tabs | |
2011 | 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; | |
2012 | #Remove spaces before a tab | |
2013 | 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; | |
2014 | ||
2015 | return "$leading"; | |
2016 | } | |
2017 | ||
d1fe9c09 JP |
2018 | sub pos_last_openparen { |
2019 | my ($line) = @_; | |
2020 | ||
2021 | my $pos = 0; | |
2022 | ||
2023 | my $opens = $line =~ tr/\(/\(/; | |
2024 | my $closes = $line =~ tr/\)/\)/; | |
2025 | ||
2026 | my $last_openparen = 0; | |
2027 | ||
2028 | if (($opens == 0) || ($closes >= $opens)) { | |
2029 | return -1; | |
2030 | } | |
2031 | ||
2032 | my $len = length($line); | |
2033 | ||
2034 | for ($pos = 0; $pos < $len; $pos++) { | |
2035 | my $string = substr($line, $pos); | |
2036 | if ($string =~ /^($FuncArg|$balanced_parens)/) { | |
2037 | $pos += length($1) - 1; | |
2038 | } elsif (substr($line, $pos, 1) eq '(') { | |
2039 | $last_openparen = $pos; | |
2040 | } elsif (index($string, '(') == -1) { | |
2041 | last; | |
2042 | } | |
2043 | } | |
2044 | ||
91cb5195 | 2045 | return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; |
d1fe9c09 JP |
2046 | } |
2047 | ||
0a920b5b AW |
2048 | sub process { |
2049 | my $filename = shift; | |
0a920b5b AW |
2050 | |
2051 | my $linenr=0; | |
2052 | my $prevline=""; | |
c2fdda0d | 2053 | my $prevrawline=""; |
0a920b5b | 2054 | my $stashline=""; |
c2fdda0d | 2055 | my $stashrawline=""; |
0a920b5b | 2056 | |
4a0df2ef | 2057 | my $length; |
0a920b5b AW |
2058 | my $indent; |
2059 | my $previndent=0; | |
2060 | my $stashindent=0; | |
2061 | ||
de7d4f0e | 2062 | our $clean = 1; |
0a920b5b AW |
2063 | my $signoff = 0; |
2064 | my $is_patch = 0; | |
29ee1b0c | 2065 | my $in_header_lines = $file ? 0 : 1; |
15662b3e | 2066 | my $in_commit_log = 0; #Scanning lines before patch |
bf4daf12 | 2067 | my $commit_log_possible_stack_dump = 0; |
2a076f40 | 2068 | my $commit_log_long_line = 0; |
e518e9a5 | 2069 | my $commit_log_has_diff = 0; |
13f1937e | 2070 | my $reported_maintainer_file = 0; |
fa64205d PS |
2071 | my $non_utf8_charset = 0; |
2072 | ||
365dd4ea | 2073 | my $last_blank_line = 0; |
5e4f6ba5 | 2074 | my $last_coalesced_string_linenr = -1; |
365dd4ea | 2075 | |
13214adf | 2076 | our @report = (); |
6c72ffaa AW |
2077 | our $cnt_lines = 0; |
2078 | our $cnt_error = 0; | |
2079 | our $cnt_warn = 0; | |
2080 | our $cnt_chk = 0; | |
2081 | ||
0a920b5b AW |
2082 | # Trace the real file/line as we go. |
2083 | my $realfile = ''; | |
2084 | my $realline = 0; | |
2085 | my $realcnt = 0; | |
2086 | my $here = ''; | |
2087 | my $in_comment = 0; | |
c2fdda0d | 2088 | my $comment_edge = 0; |
0a920b5b | 2089 | my $first_line = 0; |
1e855726 | 2090 | my $p1_prefix = ''; |
0a920b5b | 2091 | |
13214adf AW |
2092 | my $prev_values = 'E'; |
2093 | ||
2094 | # suppression flags | |
773647a0 | 2095 | my %suppress_ifbraces; |
170d3a22 | 2096 | my %suppress_whiletrailers; |
2b474a1a | 2097 | my %suppress_export; |
3e469cdc | 2098 | my $suppress_statement = 0; |
653d4876 | 2099 | |
7e51f197 | 2100 | my %signatures = (); |
323c1260 | 2101 | |
c2fdda0d | 2102 | # Pre-scan the patch sanitizing the lines. |
de7d4f0e | 2103 | # Pre-scan the patch looking for any __setup documentation. |
c2fdda0d | 2104 | # |
de7d4f0e AW |
2105 | my @setup_docs = (); |
2106 | my $setup_docs = 0; | |
773647a0 | 2107 | |
d8b07710 JP |
2108 | my $camelcase_file_seeded = 0; |
2109 | ||
773647a0 | 2110 | sanitise_line_reset(); |
c2fdda0d AW |
2111 | my $line; |
2112 | foreach my $rawline (@rawlines) { | |
773647a0 AW |
2113 | $linenr++; |
2114 | $line = $rawline; | |
c2fdda0d | 2115 | |
3705ce5b JP |
2116 | push(@fixed, $rawline) if ($fix); |
2117 | ||
773647a0 | 2118 | if ($rawline=~/^\+\+\+\s+(\S+)/) { |
de7d4f0e AW |
2119 | $setup_docs = 0; |
2120 | if ($1 =~ m@Documentation/kernel-parameters.txt$@) { | |
2121 | $setup_docs = 1; | |
2122 | } | |
773647a0 AW |
2123 | #next; |
2124 | } | |
2125 | if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { | |
2126 | $realline=$1-1; | |
2127 | if (defined $2) { | |
2128 | $realcnt=$3+1; | |
2129 | } else { | |
2130 | $realcnt=1+1; | |
2131 | } | |
c45dcabd | 2132 | $in_comment = 0; |
773647a0 AW |
2133 | |
2134 | # Guestimate if this is a continuing comment. Run | |
2135 | # the context looking for a comment "edge". If this | |
2136 | # edge is a close comment then we must be in a comment | |
2137 | # at context start. | |
2138 | my $edge; | |
01fa9147 AW |
2139 | my $cnt = $realcnt; |
2140 | for (my $ln = $linenr + 1; $cnt > 0; $ln++) { | |
2141 | next if (defined $rawlines[$ln - 1] && | |
2142 | $rawlines[$ln - 1] =~ /^-/); | |
2143 | $cnt--; | |
2144 | #print "RAW<$rawlines[$ln - 1]>\n"; | |
721c1cb6 | 2145 | last if (!defined $rawlines[$ln - 1]); |
fae17dae AW |
2146 | if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && |
2147 | $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { | |
2148 | ($edge) = $1; | |
2149 | last; | |
2150 | } | |
773647a0 AW |
2151 | } |
2152 | if (defined $edge && $edge eq '*/') { | |
2153 | $in_comment = 1; | |
2154 | } | |
2155 | ||
2156 | # Guestimate if this is a continuing comment. If this | |
2157 | # is the start of a diff block and this line starts | |
2158 | # ' *' then it is very likely a comment. | |
2159 | if (!defined $edge && | |
83242e0c | 2160 | $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) |
773647a0 AW |
2161 | { |
2162 | $in_comment = 1; | |
2163 | } | |
2164 | ||
2165 | ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; | |
2166 | sanitise_line_reset($in_comment); | |
2167 | ||
171ae1a4 | 2168 | } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { |
773647a0 | 2169 | # Standardise the strings and chars within the input to |
171ae1a4 | 2170 | # simplify matching -- only bother with positive lines. |
773647a0 | 2171 | $line = sanitise_line($rawline); |
de7d4f0e | 2172 | } |
773647a0 AW |
2173 | push(@lines, $line); |
2174 | ||
2175 | if ($realcnt > 1) { | |
2176 | $realcnt-- if ($line =~ /^(?:\+| |$)/); | |
2177 | } else { | |
2178 | $realcnt = 0; | |
2179 | } | |
2180 | ||
2181 | #print "==>$rawline\n"; | |
2182 | #print "-->$line\n"; | |
de7d4f0e AW |
2183 | |
2184 | if ($setup_docs && $line =~ /^\+/) { | |
2185 | push(@setup_docs, $line); | |
2186 | } | |
2187 | } | |
2188 | ||
6c72ffaa AW |
2189 | $prefix = ''; |
2190 | ||
773647a0 AW |
2191 | $realcnt = 0; |
2192 | $linenr = 0; | |
194f66fc | 2193 | $fixlinenr = -1; |
0a920b5b AW |
2194 | foreach my $line (@lines) { |
2195 | $linenr++; | |
194f66fc | 2196 | $fixlinenr++; |
1b5539b1 JP |
2197 | my $sline = $line; #copy of $line |
2198 | $sline =~ s/$;/ /g; #with comments as spaces | |
0a920b5b | 2199 | |
c2fdda0d | 2200 | my $rawline = $rawlines[$linenr - 1]; |
6c72ffaa | 2201 | |
0a920b5b | 2202 | #extract the line range in the file after the patch is applied |
e518e9a5 JP |
2203 | if (!$in_commit_log && |
2204 | $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { | |
0a920b5b | 2205 | $is_patch = 1; |
4a0df2ef | 2206 | $first_line = $linenr + 1; |
0a920b5b AW |
2207 | $realline=$1-1; |
2208 | if (defined $2) { | |
2209 | $realcnt=$3+1; | |
2210 | } else { | |
2211 | $realcnt=1+1; | |
2212 | } | |
c2fdda0d | 2213 | annotate_reset(); |
13214adf AW |
2214 | $prev_values = 'E'; |
2215 | ||
773647a0 | 2216 | %suppress_ifbraces = (); |
170d3a22 | 2217 | %suppress_whiletrailers = (); |
2b474a1a | 2218 | %suppress_export = (); |
3e469cdc | 2219 | $suppress_statement = 0; |
0a920b5b | 2220 | next; |
0a920b5b | 2221 | |
4a0df2ef AW |
2222 | # track the line number as we move through the hunk, note that |
2223 | # new versions of GNU diff omit the leading space on completely | |
2224 | # blank context lines so we need to count that too. | |
773647a0 | 2225 | } elsif ($line =~ /^( |\+|$)/) { |
0a920b5b | 2226 | $realline++; |
d8aaf121 | 2227 | $realcnt-- if ($realcnt != 0); |
0a920b5b | 2228 | |
4a0df2ef | 2229 | # Measure the line length and indent. |
c2fdda0d | 2230 | ($length, $indent) = line_stats($rawline); |
0a920b5b AW |
2231 | |
2232 | # Track the previous line. | |
2233 | ($prevline, $stashline) = ($stashline, $line); | |
2234 | ($previndent, $stashindent) = ($stashindent, $indent); | |
c2fdda0d AW |
2235 | ($prevrawline, $stashrawline) = ($stashrawline, $rawline); |
2236 | ||
773647a0 | 2237 | #warn "line<$line>\n"; |
6c72ffaa | 2238 | |
d8aaf121 AW |
2239 | } elsif ($realcnt == 1) { |
2240 | $realcnt--; | |
0a920b5b AW |
2241 | } |
2242 | ||
cc77cdca AW |
2243 | my $hunk_line = ($realcnt != 0); |
2244 | ||
6c72ffaa AW |
2245 | $here = "#$linenr: " if (!$file); |
2246 | $here = "#$realline: " if ($file); | |
773647a0 | 2247 | |
2ac73b4f | 2248 | my $found_file = 0; |
773647a0 | 2249 | # extract the filename as it passes |
3bf9a009 RV |
2250 | if ($line =~ /^diff --git.*?(\S+)$/) { |
2251 | $realfile = $1; | |
2b7ab453 | 2252 | $realfile =~ s@^([^/]*)/@@ if (!$file); |
270c49a0 | 2253 | $in_commit_log = 0; |
2ac73b4f | 2254 | $found_file = 1; |
3bf9a009 | 2255 | } elsif ($line =~ /^\+\+\+\s+(\S+)/) { |
773647a0 | 2256 | $realfile = $1; |
2b7ab453 | 2257 | $realfile =~ s@^([^/]*)/@@ if (!$file); |
270c49a0 | 2258 | $in_commit_log = 0; |
1e855726 WS |
2259 | |
2260 | $p1_prefix = $1; | |
e2f7aa4b AW |
2261 | if (!$file && $tree && $p1_prefix ne '' && |
2262 | -e "$root/$p1_prefix") { | |
000d1cc1 JP |
2263 | WARN("PATCH_PREFIX", |
2264 | "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); | |
1e855726 | 2265 | } |
773647a0 | 2266 | |
c1ab3326 | 2267 | if ($realfile =~ m@^include/asm/@) { |
000d1cc1 JP |
2268 | ERROR("MODIFIED_INCLUDE_ASM", |
2269 | "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); | |
773647a0 | 2270 | } |
2ac73b4f JP |
2271 | $found_file = 1; |
2272 | } | |
2273 | ||
34d8815f JP |
2274 | #make up the handle for any error we report on this line |
2275 | if ($showfile) { | |
2276 | $prefix = "$realfile:$realline: " | |
2277 | } elsif ($emacs) { | |
7d3a9f67 JP |
2278 | if ($file) { |
2279 | $prefix = "$filename:$realline: "; | |
2280 | } else { | |
2281 | $prefix = "$filename:$linenr: "; | |
2282 | } | |
34d8815f JP |
2283 | } |
2284 | ||
2ac73b4f | 2285 | if ($found_file) { |
7bd7e483 | 2286 | if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { |
2ac73b4f JP |
2287 | $check = 1; |
2288 | } else { | |
2289 | $check = $check_orig; | |
2290 | } | |
773647a0 AW |
2291 | next; |
2292 | } | |
2293 | ||
389834b6 | 2294 | $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); |
0a920b5b | 2295 | |
c2fdda0d AW |
2296 | my $hereline = "$here\n$rawline\n"; |
2297 | my $herecurr = "$here\n$rawline\n"; | |
2298 | my $hereprev = "$here\n$prevrawline\n$rawline\n"; | |
0a920b5b | 2299 | |
6c72ffaa AW |
2300 | $cnt_lines++ if ($realcnt != 0); |
2301 | ||
e518e9a5 JP |
2302 | # Check if the commit log has what seems like a diff which can confuse patch |
2303 | if ($in_commit_log && !$commit_log_has_diff && | |
2304 | (($line =~ m@^\s+diff\b.*a/[\w/]+@ && | |
2305 | $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || | |
2306 | $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || | |
2307 | $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { | |
2308 | ERROR("DIFF_IN_COMMIT_MSG", | |
2309 | "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); | |
2310 | $commit_log_has_diff = 1; | |
2311 | } | |
2312 | ||
3bf9a009 RV |
2313 | # Check for incorrect file permissions |
2314 | if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { | |
2315 | my $permhere = $here . "FILE: $realfile\n"; | |
04db4d25 JP |
2316 | if ($realfile !~ m@scripts/@ && |
2317 | $realfile !~ /\.(py|pl|awk|sh)$/) { | |
000d1cc1 JP |
2318 | ERROR("EXECUTE_PERMISSIONS", |
2319 | "do not set execute permissions for source files\n" . $permhere); | |
3bf9a009 RV |
2320 | } |
2321 | } | |
2322 | ||
20112475 | 2323 | # Check the patch for a signoff: |
d8aaf121 | 2324 | if ($line =~ /^\s*signed-off-by:/i) { |
4a0df2ef | 2325 | $signoff++; |
15662b3e | 2326 | $in_commit_log = 0; |
20112475 JP |
2327 | } |
2328 | ||
e0d975b1 JP |
2329 | # Check if MAINTAINERS is being updated. If so, there's probably no need to |
2330 | # emit the "does MAINTAINERS need updating?" message on file add/move/delete | |
2331 | if ($line =~ /^\s*MAINTAINERS\s*\|/) { | |
2332 | $reported_maintainer_file = 1; | |
2333 | } | |
2334 | ||
20112475 | 2335 | # Check signature styles |
270c49a0 | 2336 | if (!$in_header_lines && |
ce0338df | 2337 | $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { |
20112475 JP |
2338 | my $space_before = $1; |
2339 | my $sign_off = $2; | |
2340 | my $space_after = $3; | |
2341 | my $email = $4; | |
2342 | my $ucfirst_sign_off = ucfirst(lc($sign_off)); | |
2343 | ||
ce0338df JP |
2344 | if ($sign_off !~ /$signature_tags/) { |
2345 | WARN("BAD_SIGN_OFF", | |
2346 | "Non-standard signature: $sign_off\n" . $herecurr); | |
2347 | } | |
20112475 | 2348 | if (defined $space_before && $space_before ne "") { |
3705ce5b JP |
2349 | if (WARN("BAD_SIGN_OFF", |
2350 | "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && | |
2351 | $fix) { | |
194f66fc | 2352 | $fixed[$fixlinenr] = |
3705ce5b JP |
2353 | "$ucfirst_sign_off $email"; |
2354 | } | |
20112475 JP |
2355 | } |
2356 | if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { | |
3705ce5b JP |
2357 | if (WARN("BAD_SIGN_OFF", |
2358 | "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && | |
2359 | $fix) { | |
194f66fc | 2360 | $fixed[$fixlinenr] = |
3705ce5b JP |
2361 | "$ucfirst_sign_off $email"; |
2362 | } | |
2363 | ||
20112475 JP |
2364 | } |
2365 | if (!defined $space_after || $space_after ne " ") { | |
3705ce5b JP |
2366 | if (WARN("BAD_SIGN_OFF", |
2367 | "Use a single space after $ucfirst_sign_off\n" . $herecurr) && | |
2368 | $fix) { | |
194f66fc | 2369 | $fixed[$fixlinenr] = |
3705ce5b JP |
2370 | "$ucfirst_sign_off $email"; |
2371 | } | |
0a920b5b | 2372 | } |
20112475 JP |
2373 | |
2374 | my ($email_name, $email_address, $comment) = parse_email($email); | |
2375 | my $suggested_email = format_email(($email_name, $email_address)); | |
2376 | if ($suggested_email eq "") { | |
000d1cc1 JP |
2377 | ERROR("BAD_SIGN_OFF", |
2378 | "Unrecognized email address: '$email'\n" . $herecurr); | |
20112475 JP |
2379 | } else { |
2380 | my $dequoted = $suggested_email; | |
2381 | $dequoted =~ s/^"//; | |
2382 | $dequoted =~ s/" </ </; | |
2383 | # Don't force email to have quotes | |
2384 | # Allow just an angle bracketed address | |
2385 | if ("$dequoted$comment" ne $email && | |
2386 | "<$email_address>$comment" ne $email && | |
2387 | "$suggested_email$comment" ne $email) { | |
000d1cc1 JP |
2388 | WARN("BAD_SIGN_OFF", |
2389 | "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); | |
20112475 | 2390 | } |
0a920b5b | 2391 | } |
7e51f197 JP |
2392 | |
2393 | # Check for duplicate signatures | |
2394 | my $sig_nospace = $line; | |
2395 | $sig_nospace =~ s/\s//g; | |
2396 | $sig_nospace = lc($sig_nospace); | |
2397 | if (defined $signatures{$sig_nospace}) { | |
2398 | WARN("BAD_SIGN_OFF", | |
2399 | "Duplicate signature\n" . $herecurr); | |
2400 | } else { | |
2401 | $signatures{$sig_nospace} = 1; | |
2402 | } | |
0a920b5b AW |
2403 | } |
2404 | ||
a2fe16b9 JP |
2405 | # Check email subject for common tools that don't need to be mentioned |
2406 | if ($in_header_lines && | |
2407 | $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { | |
2408 | WARN("EMAIL_SUBJECT", | |
2409 | "A patch subject line should describe the change not the tool that found it\n" . $herecurr); | |
2410 | } | |
2411 | ||
9b3189eb JP |
2412 | # Check for old stable address |
2413 | if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { | |
2414 | ERROR("STABLE_ADDRESS", | |
2415 | "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); | |
2416 | } | |
2417 | ||
7ebd05ef CC |
2418 | # Check for unwanted Gerrit info |
2419 | if ($in_commit_log && $line =~ /^\s*change-id:/i) { | |
2420 | ERROR("GERRIT_CHANGE_ID", | |
2421 | "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); | |
2422 | } | |
2423 | ||
369c8dd3 JP |
2424 | # Check if the commit log is in a possible stack dump |
2425 | if ($in_commit_log && !$commit_log_possible_stack_dump && | |
2426 | ($line =~ /^\s*(?:WARNING:|BUG:)/ || | |
2427 | $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || | |
2428 | # timestamp | |
2429 | $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { | |
2430 | # stack dump address | |
2431 | $commit_log_possible_stack_dump = 1; | |
2432 | } | |
2433 | ||
2a076f40 JP |
2434 | # Check for line lengths > 75 in commit log, warn once |
2435 | if ($in_commit_log && !$commit_log_long_line && | |
369c8dd3 JP |
2436 | length($line) > 75 && |
2437 | !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || | |
2438 | # file delta changes | |
2439 | $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || | |
2440 | # filename then : | |
2441 | $line =~ /^\s*(?:Fixes:|Link:)/i || | |
2442 | # A Fixes: or Link: line | |
2443 | $commit_log_possible_stack_dump)) { | |
2a076f40 JP |
2444 | WARN("COMMIT_LOG_LONG_LINE", |
2445 | "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); | |
2446 | $commit_log_long_line = 1; | |
2447 | } | |
2448 | ||
bf4daf12 | 2449 | # Reset possible stack dump if a blank line is found |
369c8dd3 JP |
2450 | if ($in_commit_log && $commit_log_possible_stack_dump && |
2451 | $line =~ /^\s*$/) { | |
2452 | $commit_log_possible_stack_dump = 0; | |
2453 | } | |
bf4daf12 | 2454 | |
0d7835fc | 2455 | # Check for git id commit length and improperly formed commit descriptions |
369c8dd3 | 2456 | if ($in_commit_log && !$commit_log_possible_stack_dump && |
fe043ea1 | 2457 | ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || |
369c8dd3 JP |
2458 | ($line =~ /\b[0-9a-f]{12,40}\b/i && |
2459 | $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && | |
2460 | $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { | |
fe043ea1 JP |
2461 | my $init_char = "c"; |
2462 | my $orig_commit = ""; | |
0d7835fc JP |
2463 | my $short = 1; |
2464 | my $long = 0; | |
2465 | my $case = 1; | |
2466 | my $space = 1; | |
2467 | my $hasdesc = 0; | |
19c146a6 | 2468 | my $hasparens = 0; |
0d7835fc JP |
2469 | my $id = '0123456789ab'; |
2470 | my $orig_desc = "commit description"; | |
2471 | my $description = ""; | |
2472 | ||
fe043ea1 JP |
2473 | if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { |
2474 | $init_char = $1; | |
2475 | $orig_commit = lc($2); | |
2476 | } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { | |
2477 | $orig_commit = lc($1); | |
2478 | } | |
2479 | ||
0d7835fc JP |
2480 | $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); |
2481 | $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); | |
2482 | $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); | |
2483 | $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); | |
2484 | if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { | |
2485 | $orig_desc = $1; | |
19c146a6 | 2486 | $hasparens = 1; |
0d7835fc JP |
2487 | } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && |
2488 | defined $rawlines[$linenr] && | |
2489 | $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { | |
2490 | $orig_desc = $1; | |
19c146a6 | 2491 | $hasparens = 1; |
b671fde0 JP |
2492 | } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && |
2493 | defined $rawlines[$linenr] && | |
2494 | $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { | |
2495 | $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; | |
2496 | $orig_desc = $1; | |
2497 | $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; | |
2498 | $orig_desc .= " " . $1; | |
19c146a6 | 2499 | $hasparens = 1; |
0d7835fc JP |
2500 | } |
2501 | ||
2502 | ($id, $description) = git_commit_info($orig_commit, | |
2503 | $id, $orig_desc); | |
2504 | ||
19c146a6 | 2505 | if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) { |
0d7835fc JP |
2506 | ERROR("GIT_COMMIT_ID", |
2507 | "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); | |
2508 | } | |
d311cd44 JP |
2509 | } |
2510 | ||
13f1937e JP |
2511 | # Check for added, moved or deleted files |
2512 | if (!$reported_maintainer_file && !$in_commit_log && | |
2513 | ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || | |
2514 | $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || | |
2515 | ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && | |
2516 | (defined($1) || defined($2))))) { | |
2517 | $reported_maintainer_file = 1; | |
2518 | WARN("FILE_PATH_CHANGES", | |
2519 | "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); | |
2520 | } | |
2521 | ||
00df344f | 2522 | # Check for wrappage within a valid hunk of the file |
8905a67c | 2523 | if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { |
000d1cc1 JP |
2524 | ERROR("CORRUPTED_PATCH", |
2525 | "patch seems to be corrupt (line wrapped?)\n" . | |
6c72ffaa | 2526 | $herecurr) if (!$emitted_corrupt++); |
de7d4f0e AW |
2527 | } |
2528 | ||
6ecd9674 AW |
2529 | # Check for absolute kernel paths. |
2530 | if ($tree) { | |
2531 | while ($line =~ m{(?:^|\s)(/\S*)}g) { | |
2532 | my $file = $1; | |
2533 | ||
2534 | if ($file =~ m{^(.*?)(?::\d+)+:?$} && | |
2535 | check_absolute_file($1, $herecurr)) { | |
2536 | # | |
2537 | } else { | |
2538 | check_absolute_file($file, $herecurr); | |
2539 | } | |
2540 | } | |
2541 | } | |
2542 | ||
de7d4f0e AW |
2543 | # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php |
2544 | if (($realfile =~ /^$/ || $line =~ /^\+/) && | |
171ae1a4 AW |
2545 | $rawline !~ m/^$UTF8*$/) { |
2546 | my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); | |
2547 | ||
2548 | my $blank = copy_spacing($rawline); | |
2549 | my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; | |
2550 | my $hereptr = "$hereline$ptr\n"; | |
2551 | ||
34d99219 JP |
2552 | CHK("INVALID_UTF8", |
2553 | "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); | |
00df344f AW |
2554 | } |
2555 | ||
15662b3e JP |
2556 | # Check if it's the start of a commit log |
2557 | # (not a header line and we haven't seen the patch filename) | |
2558 | if ($in_header_lines && $realfile =~ /^$/ && | |
29ee1b0c JP |
2559 | !($rawline =~ /^\s+\S/ || |
2560 | $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) { | |
15662b3e JP |
2561 | $in_header_lines = 0; |
2562 | $in_commit_log = 1; | |
2563 | } | |
2564 | ||
fa64205d PS |
2565 | # Check if there is UTF-8 in a commit log when a mail header has explicitly |
2566 | # declined it, i.e defined some charset where it is missing. | |
2567 | if ($in_header_lines && | |
2568 | $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && | |
2569 | $1 !~ /utf-8/i) { | |
2570 | $non_utf8_charset = 1; | |
2571 | } | |
2572 | ||
2573 | if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && | |
15662b3e | 2574 | $rawline =~ /$NON_ASCII_UTF8/) { |
fa64205d | 2575 | WARN("UTF8_BEFORE_PATCH", |
15662b3e JP |
2576 | "8-bit UTF-8 used in possible commit log\n" . $herecurr); |
2577 | } | |
2578 | ||
66b47b4a | 2579 | # Check for various typo / spelling mistakes |
66d7a382 JP |
2580 | if (defined($misspellings) && |
2581 | ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { | |
ebfd7d62 | 2582 | while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { |
66b47b4a KC |
2583 | my $typo = $1; |
2584 | my $typo_fix = $spelling_fix{lc($typo)}; | |
2585 | $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); | |
2586 | $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); | |
2587 | my $msg_type = \&WARN; | |
2588 | $msg_type = \&CHK if ($file); | |
2589 | if (&{$msg_type}("TYPO_SPELLING", | |
2590 | "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && | |
2591 | $fix) { | |
2592 | $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; | |
2593 | } | |
2594 | } | |
2595 | } | |
2596 | ||
30670854 AW |
2597 | # ignore non-hunk lines and lines being removed |
2598 | next if (!$hunk_line || $line =~ /^-/); | |
0a920b5b | 2599 | |
0a920b5b | 2600 | #trailing whitespace |
9c0ca6f9 | 2601 | if ($line =~ /^\+.*\015/) { |
c2fdda0d | 2602 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
d5e616fc JP |
2603 | if (ERROR("DOS_LINE_ENDINGS", |
2604 | "DOS line endings\n" . $herevet) && | |
2605 | $fix) { | |
194f66fc | 2606 | $fixed[$fixlinenr] =~ s/[\s\015]+$//; |
d5e616fc | 2607 | } |
c2fdda0d AW |
2608 | } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { |
2609 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; | |
3705ce5b JP |
2610 | if (ERROR("TRAILING_WHITESPACE", |
2611 | "trailing whitespace\n" . $herevet) && | |
2612 | $fix) { | |
194f66fc | 2613 | $fixed[$fixlinenr] =~ s/\s+$//; |
3705ce5b JP |
2614 | } |
2615 | ||
d2c0a235 | 2616 | $rpt_cleaners = 1; |
0a920b5b | 2617 | } |
5368df20 | 2618 | |
4783f894 | 2619 | # Check for FSF mailing addresses. |
109d8cb2 | 2620 | if ($rawline =~ /\bwrite to the Free/i || |
3e2232f2 JP |
2621 | $rawline =~ /\b59\s+Temple\s+Pl/i || |
2622 | $rawline =~ /\b51\s+Franklin\s+St/i) { | |
4783f894 JT |
2623 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
2624 | my $msg_type = \&ERROR; | |
2625 | $msg_type = \&CHK if ($file); | |
2626 | &{$msg_type}("FSF_MAILING_ADDRESS", | |
3e2232f2 | 2627 | "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) |
4783f894 JT |
2628 | } |
2629 | ||
3354957a | 2630 | # check for Kconfig help text having a real description |
9fe287d7 AW |
2631 | # Only applies when adding the entry originally, after that we do not have |
2632 | # sufficient context to determine whether it is indeed long enough. | |
3354957a | 2633 | if ($realfile =~ /Kconfig/ && |
8d73e0e7 | 2634 | $line =~ /^\+\s*config\s+/) { |
3354957a | 2635 | my $length = 0; |
9fe287d7 AW |
2636 | my $cnt = $realcnt; |
2637 | my $ln = $linenr + 1; | |
2638 | my $f; | |
a1385803 | 2639 | my $is_start = 0; |
9fe287d7 | 2640 | my $is_end = 0; |
a1385803 | 2641 | for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { |
9fe287d7 AW |
2642 | $f = $lines[$ln - 1]; |
2643 | $cnt-- if ($lines[$ln - 1] !~ /^-/); | |
2644 | $is_end = $lines[$ln - 1] =~ /^\+/; | |
9fe287d7 AW |
2645 | |
2646 | next if ($f =~ /^-/); | |
8d73e0e7 | 2647 | last if (!$file && $f =~ /^\@\@/); |
a1385803 | 2648 | |
8d73e0e7 | 2649 | if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { |
a1385803 | 2650 | $is_start = 1; |
8d73e0e7 | 2651 | } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { |
a1385803 AW |
2652 | $length = -1; |
2653 | } | |
2654 | ||
9fe287d7 | 2655 | $f =~ s/^.//; |
3354957a AK |
2656 | $f =~ s/#.*//; |
2657 | $f =~ s/^\s+//; | |
2658 | next if ($f =~ /^$/); | |
9fe287d7 AW |
2659 | if ($f =~ /^\s*config\s/) { |
2660 | $is_end = 1; | |
2661 | last; | |
2662 | } | |
3354957a AK |
2663 | $length++; |
2664 | } | |
56193274 VB |
2665 | if ($is_start && $is_end && $length < $min_conf_desc_length) { |
2666 | WARN("CONFIG_DESCRIPTION", | |
2667 | "please write a paragraph that describes the config symbol fully\n" . $herecurr); | |
2668 | } | |
a1385803 | 2669 | #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; |
3354957a AK |
2670 | } |
2671 | ||
1ba8dfd1 KC |
2672 | # discourage the addition of CONFIG_EXPERIMENTAL in Kconfig. |
2673 | if ($realfile =~ /Kconfig/ && | |
2674 | $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) { | |
2675 | WARN("CONFIG_EXPERIMENTAL", | |
2676 | "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); | |
2677 | } | |
2678 | ||
327953e9 CJ |
2679 | # discourage the use of boolean for type definition attributes of Kconfig options |
2680 | if ($realfile =~ /Kconfig/ && | |
2681 | $line =~ /^\+\s*\bboolean\b/) { | |
2682 | WARN("CONFIG_TYPE_BOOLEAN", | |
2683 | "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); | |
2684 | } | |
2685 | ||
c68e5878 AL |
2686 | if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && |
2687 | ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { | |
2688 | my $flag = $1; | |
2689 | my $replacement = { | |
2690 | 'EXTRA_AFLAGS' => 'asflags-y', | |
2691 | 'EXTRA_CFLAGS' => 'ccflags-y', | |
2692 | 'EXTRA_CPPFLAGS' => 'cppflags-y', | |
2693 | 'EXTRA_LDFLAGS' => 'ldflags-y', | |
2694 | }; | |
2695 | ||
2696 | WARN("DEPRECATED_VARIABLE", | |
2697 | "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); | |
2698 | } | |
2699 | ||
bff5da43 | 2700 | # check for DT compatible documentation |
7dd05b38 FV |
2701 | if (defined $root && |
2702 | (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || | |
2703 | ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { | |
2704 | ||
bff5da43 RH |
2705 | my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; |
2706 | ||
cc93319b FV |
2707 | my $dt_path = $root . "/Documentation/devicetree/bindings/"; |
2708 | my $vp_file = $dt_path . "vendor-prefixes.txt"; | |
2709 | ||
bff5da43 RH |
2710 | foreach my $compat (@compats) { |
2711 | my $compat2 = $compat; | |
185d566b RH |
2712 | $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; |
2713 | my $compat3 = $compat; | |
2714 | $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; | |
2715 | `grep -Erq "$compat|$compat2|$compat3" $dt_path`; | |
bff5da43 RH |
2716 | if ( $? >> 8 ) { |
2717 | WARN("UNDOCUMENTED_DT_STRING", | |
2718 | "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); | |
2719 | } | |
2720 | ||
4fbf32a6 FV |
2721 | next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; |
2722 | my $vendor = $1; | |
cc93319b | 2723 | `grep -Eq "^$vendor\\b" $vp_file`; |
bff5da43 RH |
2724 | if ( $? >> 8 ) { |
2725 | WARN("UNDOCUMENTED_DT_STRING", | |
cc93319b | 2726 | "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); |
bff5da43 RH |
2727 | } |
2728 | } | |
2729 | } | |
2730 | ||
5368df20 | 2731 | # check we are in a valid source file if not then ignore this hunk |
de4c924c | 2732 | next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/); |
5368df20 | 2733 | |
47e0c88b JP |
2734 | # line length limit (with some exclusions) |
2735 | # | |
2736 | # There are a few types of lines that may extend beyond $max_line_length: | |
2737 | # logging functions like pr_info that end in a string | |
2738 | # lines with a single string | |
2739 | # #defines that are a single string | |
2740 | # | |
2741 | # There are 3 different line length message types: | |
2742 | # LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength | |
2743 | # LONG_LINE_STRING a string starts before but extends beyond $max_line_length | |
2744 | # LONG_LINE all other lines longer than $max_line_length | |
2745 | # | |
2746 | # if LONG_LINE is ignored, the other 2 types are also ignored | |
2747 | # | |
2748 | ||
b4749e96 | 2749 | if ($line =~ /^\+/ && $length > $max_line_length) { |
47e0c88b JP |
2750 | my $msg_type = "LONG_LINE"; |
2751 | ||
2752 | # Check the allowed long line types first | |
2753 | ||
2754 | # logging functions that end in a string that starts | |
2755 | # before $max_line_length | |
2756 | if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && | |
2757 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { | |
2758 | $msg_type = ""; | |
2759 | ||
2760 | # lines with only strings (w/ possible termination) | |
2761 | # #defines with only strings | |
2762 | } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || | |
2763 | $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { | |
2764 | $msg_type = ""; | |
2765 | ||
2766 | # Otherwise set the alternate message types | |
2767 | ||
2768 | # a comment starts before $max_line_length | |
2769 | } elsif ($line =~ /($;[\s$;]*)$/ && | |
2770 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { | |
2771 | $msg_type = "LONG_LINE_COMMENT" | |
2772 | ||
2773 | # a quoted string starts before $max_line_length | |
2774 | } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && | |
2775 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { | |
2776 | $msg_type = "LONG_LINE_STRING" | |
2777 | } | |
2778 | ||
2779 | if ($msg_type ne "" && | |
2780 | (show_type("LONG_LINE") || show_type($msg_type))) { | |
2781 | WARN($msg_type, | |
2782 | "line over $max_line_length characters\n" . $herecurr); | |
2783 | } | |
0a920b5b AW |
2784 | } |
2785 | ||
8905a67c AW |
2786 | # check for adding lines without a newline. |
2787 | if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { | |
000d1cc1 JP |
2788 | WARN("MISSING_EOF_NEWLINE", |
2789 | "adding a line without newline at end of file\n" . $herecurr); | |
8905a67c AW |
2790 | } |
2791 | ||
42e41c54 MF |
2792 | # Blackfin: use hi/lo macros |
2793 | if ($realfile =~ m@arch/blackfin/.*\.S$@) { | |
2794 | if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { | |
2795 | my $herevet = "$here\n" . cat_vet($line) . "\n"; | |
000d1cc1 JP |
2796 | ERROR("LO_MACRO", |
2797 | "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); | |
42e41c54 MF |
2798 | } |
2799 | if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { | |
2800 | my $herevet = "$here\n" . cat_vet($line) . "\n"; | |
000d1cc1 JP |
2801 | ERROR("HI_MACRO", |
2802 | "use the HI() macro, not (... >> 16)\n" . $herevet); | |
42e41c54 MF |
2803 | } |
2804 | } | |
2805 | ||
b9ea10d6 | 2806 | # check we are in a valid source file C or perl if not then ignore this hunk |
de4c924c | 2807 | next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); |
0a920b5b AW |
2808 | |
2809 | # at the beginning of a line any tabs must come first and anything | |
2810 | # more than 8 must use tabs. | |
c2fdda0d AW |
2811 | if ($rawline =~ /^\+\s* \t\s*\S/ || |
2812 | $rawline =~ /^\+\s* \s*/) { | |
2813 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; | |
d2c0a235 | 2814 | $rpt_cleaners = 1; |
3705ce5b JP |
2815 | if (ERROR("CODE_INDENT", |
2816 | "code indent should use tabs where possible\n" . $herevet) && | |
2817 | $fix) { | |
194f66fc | 2818 | $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; |
3705ce5b | 2819 | } |
0a920b5b AW |
2820 | } |
2821 | ||
08e44365 AP |
2822 | # check for space before tabs. |
2823 | if ($rawline =~ /^\+/ && $rawline =~ / \t/) { | |
2824 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; | |
3705ce5b JP |
2825 | if (WARN("SPACE_BEFORE_TAB", |
2826 | "please, no space before tabs\n" . $herevet) && | |
2827 | $fix) { | |
194f66fc | 2828 | while ($fixed[$fixlinenr] =~ |
d2207ccb | 2829 | s/(^\+.*) {8,8}\t/$1\t\t/) {} |
194f66fc | 2830 | while ($fixed[$fixlinenr] =~ |
c76f4cb3 | 2831 | s/(^\+.*) +\t/$1\t/) {} |
3705ce5b | 2832 | } |
08e44365 AP |
2833 | } |
2834 | ||
d1fe9c09 JP |
2835 | # check for && or || at the start of a line |
2836 | if ($rawline =~ /^\+\s*(&&|\|\|)/) { | |
2837 | CHK("LOGICAL_CONTINUATIONS", | |
2838 | "Logical continuations should be on the previous line\n" . $hereprev); | |
2839 | } | |
2840 | ||
a91e8994 JP |
2841 | # check indentation starts on a tab stop |
2842 | if ($^V && $^V ge 5.10.0 && | |
2843 | $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { | |
2844 | my $indent = length($1); | |
2845 | if ($indent % 8) { | |
2846 | if (WARN("TABSTOP", | |
2847 | "Statements should start on a tabstop\n" . $herecurr) && | |
2848 | $fix) { | |
2849 | $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; | |
2850 | } | |
2851 | } | |
2852 | } | |
2853 | ||
d1fe9c09 JP |
2854 | # check multi-line statement indentation matches previous line |
2855 | if ($^V && $^V ge 5.10.0 && | |
91cb5195 | 2856 | $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { |
d1fe9c09 JP |
2857 | $prevline =~ /^\+(\t*)(.*)$/; |
2858 | my $oldindent = $1; | |
2859 | my $rest = $2; | |
2860 | ||
2861 | my $pos = pos_last_openparen($rest); | |
2862 | if ($pos >= 0) { | |
b34a26f3 JP |
2863 | $line =~ /^(\+| )([ \t]*)/; |
2864 | my $newindent = $2; | |
d1fe9c09 JP |
2865 | |
2866 | my $goodtabindent = $oldindent . | |
2867 | "\t" x ($pos / 8) . | |
2868 | " " x ($pos % 8); | |
2869 | my $goodspaceindent = $oldindent . " " x $pos; | |
2870 | ||
2871 | if ($newindent ne $goodtabindent && | |
2872 | $newindent ne $goodspaceindent) { | |
3705ce5b JP |
2873 | |
2874 | if (CHK("PARENTHESIS_ALIGNMENT", | |
2875 | "Alignment should match open parenthesis\n" . $hereprev) && | |
2876 | $fix && $line =~ /^\+/) { | |
194f66fc | 2877 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
2878 | s/^\+[ \t]*/\+$goodtabindent/; |
2879 | } | |
d1fe9c09 JP |
2880 | } |
2881 | } | |
2882 | } | |
2883 | ||
6ab3a970 JP |
2884 | # check for space after cast like "(int) foo" or "(struct foo) bar" |
2885 | # avoid checking a few false positives: | |
2886 | # "sizeof(<type>)" or "__alignof__(<type>)" | |
2887 | # function pointer declarations like "(*foo)(int) = bar;" | |
2888 | # structure definitions like "(struct foo) { 0 };" | |
2889 | # multiline macros that define functions | |
2890 | # known attributes or the __attribute__ keyword | |
2891 | if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && | |
2892 | (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { | |
3705ce5b | 2893 | if (CHK("SPACING", |
f27c95db | 2894 | "No space is necessary after a cast\n" . $herecurr) && |
3705ce5b | 2895 | $fix) { |
194f66fc | 2896 | $fixed[$fixlinenr] =~ |
f27c95db | 2897 | s/(\(\s*$Type\s*\))[ \t]+/$1/; |
3705ce5b | 2898 | } |
aad4f614 JP |
2899 | } |
2900 | ||
86406b1c JP |
2901 | # Block comment styles |
2902 | # Networking with an initial /* | |
05880600 | 2903 | if ($realfile =~ m@^(drivers/net/|net/)@ && |
fdb4bcd6 | 2904 | $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && |
85ad978c JP |
2905 | $rawline =~ /^\+[ \t]*\*/ && |
2906 | $realline > 2) { | |
05880600 JP |
2907 | WARN("NETWORKING_BLOCK_COMMENT_STYLE", |
2908 | "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); | |
2909 | } | |
2910 | ||
86406b1c JP |
2911 | # Block comments use * on subsequent lines |
2912 | if ($prevline =~ /$;[ \t]*$/ && #ends in comment | |
2913 | $prevrawline =~ /^\+.*?\/\*/ && #starting /* | |
a605e32e | 2914 | $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ |
61135e96 | 2915 | $rawline =~ /^\+/ && #line is new |
a605e32e | 2916 | $rawline !~ /^\+[ \t]*\*/) { #no leading * |
86406b1c JP |
2917 | WARN("BLOCK_COMMENT_STYLE", |
2918 | "Block comments use * on subsequent lines\n" . $hereprev); | |
a605e32e JP |
2919 | } |
2920 | ||
86406b1c JP |
2921 | # Block comments use */ on trailing lines |
2922 | if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ | |
c24f9f19 JP |
2923 | $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ |
2924 | $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ | |
2925 | $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ | |
86406b1c JP |
2926 | WARN("BLOCK_COMMENT_STYLE", |
2927 | "Block comments use a trailing */ on a separate line\n" . $herecurr); | |
05880600 JP |
2928 | } |
2929 | ||
7f619191 JP |
2930 | # check for missing blank lines after struct/union declarations |
2931 | # with exceptions for various attributes and macros | |
2932 | if ($prevline =~ /^[\+ ]};?\s*$/ && | |
2933 | $line =~ /^\+/ && | |
2934 | !($line =~ /^\+\s*$/ || | |
2935 | $line =~ /^\+\s*EXPORT_SYMBOL/ || | |
2936 | $line =~ /^\+\s*MODULE_/i || | |
2937 | $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || | |
2938 | $line =~ /^\+[a-z_]*init/ || | |
2939 | $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || | |
2940 | $line =~ /^\+\s*DECLARE/ || | |
2941 | $line =~ /^\+\s*__setup/)) { | |
d752fcc8 JP |
2942 | if (CHK("LINE_SPACING", |
2943 | "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && | |
2944 | $fix) { | |
f2d7e4d4 | 2945 | fix_insert_line($fixlinenr, "\+"); |
d752fcc8 | 2946 | } |
7f619191 JP |
2947 | } |
2948 | ||
365dd4ea JP |
2949 | # check for multiple consecutive blank lines |
2950 | if ($prevline =~ /^[\+ ]\s*$/ && | |
2951 | $line =~ /^\+\s*$/ && | |
2952 | $last_blank_line != ($linenr - 1)) { | |
d752fcc8 JP |
2953 | if (CHK("LINE_SPACING", |
2954 | "Please don't use multiple blank lines\n" . $hereprev) && | |
2955 | $fix) { | |
f2d7e4d4 | 2956 | fix_delete_line($fixlinenr, $rawline); |
d752fcc8 JP |
2957 | } |
2958 | ||
365dd4ea JP |
2959 | $last_blank_line = $linenr; |
2960 | } | |
2961 | ||
3b617e3b | 2962 | # check for missing blank lines after declarations |
3f7bac03 JP |
2963 | if ($sline =~ /^\+\s+\S/ && #Not at char 1 |
2964 | # actual declarations | |
2965 | ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || | |
5a4e1fd3 JP |
2966 | # function pointer declarations |
2967 | $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || | |
3f7bac03 JP |
2968 | # foo bar; where foo is some local typedef or #define |
2969 | $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || | |
2970 | # known declaration macros | |
2971 | $prevline =~ /^\+\s+$declaration_macros/) && | |
2972 | # for "else if" which can look like "$Ident $Ident" | |
2973 | !($prevline =~ /^\+\s+$c90_Keywords\b/ || | |
2974 | # other possible extensions of declaration lines | |
2975 | $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || | |
2976 | # not starting a section or a macro "\" extended line | |
2977 | $prevline =~ /(?:\{\s*|\\)$/) && | |
2978 | # looks like a declaration | |
2979 | !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || | |
5a4e1fd3 JP |
2980 | # function pointer declarations |
2981 | $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || | |
3f7bac03 JP |
2982 | # foo bar; where foo is some local typedef or #define |
2983 | $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || | |
2984 | # known declaration macros | |
2985 | $sline =~ /^\+\s+$declaration_macros/ || | |
2986 | # start of struct or union or enum | |
3b617e3b | 2987 | $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || |
3f7bac03 JP |
2988 | # start or end of block or continuation of declaration |
2989 | $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || | |
2990 | # bitfield continuation | |
2991 | $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || | |
2992 | # other possible extensions of declaration lines | |
2993 | $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && | |
2994 | # indentation of previous and current line are the same | |
2995 | (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { | |
d752fcc8 JP |
2996 | if (WARN("LINE_SPACING", |
2997 | "Missing a blank line after declarations\n" . $hereprev) && | |
2998 | $fix) { | |
f2d7e4d4 | 2999 | fix_insert_line($fixlinenr, "\+"); |
d752fcc8 | 3000 | } |
3b617e3b JP |
3001 | } |
3002 | ||
5f7ddae6 | 3003 | # check for spaces at the beginning of a line. |
6b4c5beb AW |
3004 | # Exceptions: |
3005 | # 1) within comments | |
3006 | # 2) indented preprocessor commands | |
3007 | # 3) hanging labels | |
3705ce5b | 3008 | if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { |
5f7ddae6 | 3009 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
3705ce5b JP |
3010 | if (WARN("LEADING_SPACE", |
3011 | "please, no spaces at the start of a line\n" . $herevet) && | |
3012 | $fix) { | |
194f66fc | 3013 | $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; |
3705ce5b | 3014 | } |
5f7ddae6 RR |
3015 | } |
3016 | ||
b9ea10d6 AW |
3017 | # check we are in a valid C source file if not then ignore this hunk |
3018 | next if ($realfile !~ /\.(h|c)$/); | |
3019 | ||
032a4c0f | 3020 | # check indentation of any line with a bare else |
840080a0 | 3021 | # (but not if it is a multiple line "if (foo) return bar; else return baz;") |
032a4c0f JP |
3022 | # if the previous line is a break or return and is indented 1 tab more... |
3023 | if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { | |
3024 | my $tabs = length($1) + 1; | |
840080a0 JP |
3025 | if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || |
3026 | ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && | |
3027 | defined $lines[$linenr] && | |
3028 | $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { | |
032a4c0f JP |
3029 | WARN("UNNECESSARY_ELSE", |
3030 | "else is not generally useful after a break or return\n" . $hereprev); | |
3031 | } | |
3032 | } | |
3033 | ||
c00df19a JP |
3034 | # check indentation of a line with a break; |
3035 | # if the previous line is a goto or return and is indented the same # of tabs | |
3036 | if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { | |
3037 | my $tabs = $1; | |
3038 | if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { | |
3039 | WARN("UNNECESSARY_BREAK", | |
3040 | "break is not useful after a goto or return\n" . $hereprev); | |
3041 | } | |
3042 | } | |
3043 | ||
1ba8dfd1 KC |
3044 | # discourage the addition of CONFIG_EXPERIMENTAL in #if(def). |
3045 | if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) { | |
3046 | WARN("CONFIG_EXPERIMENTAL", | |
3047 | "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); | |
3048 | } | |
3049 | ||
c2fdda0d | 3050 | # check for RCS/CVS revision markers |
cf655043 | 3051 | if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { |
000d1cc1 JP |
3052 | WARN("CVS_KEYWORD", |
3053 | "CVS style keyword markers, these will _not_ be updated\n". $herecurr); | |
c2fdda0d | 3054 | } |
22f2a2ef | 3055 | |
42e41c54 MF |
3056 | # Blackfin: don't use __builtin_bfin_[cs]sync |
3057 | if ($line =~ /__builtin_bfin_csync/) { | |
3058 | my $herevet = "$here\n" . cat_vet($line) . "\n"; | |
000d1cc1 JP |
3059 | ERROR("CSYNC", |
3060 | "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); | |
42e41c54 MF |
3061 | } |
3062 | if ($line =~ /__builtin_bfin_ssync/) { | |
3063 | my $herevet = "$here\n" . cat_vet($line) . "\n"; | |
000d1cc1 JP |
3064 | ERROR("SSYNC", |
3065 | "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); | |
42e41c54 MF |
3066 | } |
3067 | ||
56e77d70 JP |
3068 | # check for old HOTPLUG __dev<foo> section markings |
3069 | if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { | |
3070 | WARN("HOTPLUG_SECTION", | |
3071 | "Using $1 is unnecessary\n" . $herecurr); | |
3072 | } | |
3073 | ||
9c0ca6f9 | 3074 | # Check for potential 'bare' types |
2b474a1a AW |
3075 | my ($stat, $cond, $line_nr_next, $remain_next, $off_next, |
3076 | $realline_next); | |
3e469cdc AW |
3077 | #print "LINE<$line>\n"; |
3078 | if ($linenr >= $suppress_statement && | |
1b5539b1 | 3079 | $realcnt && $sline =~ /.\s*\S/) { |
170d3a22 | 3080 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
f5fe35dd | 3081 | ctx_statement_block($linenr, $realcnt, 0); |
171ae1a4 AW |
3082 | $stat =~ s/\n./\n /g; |
3083 | $cond =~ s/\n./\n /g; | |
3084 | ||
3e469cdc AW |
3085 | #print "linenr<$linenr> <$stat>\n"; |
3086 | # If this statement has no statement boundaries within | |
3087 | # it there is no point in retrying a statement scan | |
3088 | # until we hit end of it. | |
3089 | my $frag = $stat; $frag =~ s/;+\s*$//; | |
3090 | if ($frag !~ /(?:{|;)/) { | |
3091 | #print "skip<$line_nr_next>\n"; | |
3092 | $suppress_statement = $line_nr_next; | |
3093 | } | |
f74bd194 | 3094 | |
2b474a1a AW |
3095 | # Find the real next line. |
3096 | $realline_next = $line_nr_next; | |
3097 | if (defined $realline_next && | |
3098 | (!defined $lines[$realline_next - 1] || | |
3099 | substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { | |
3100 | $realline_next++; | |
3101 | } | |
3102 | ||
171ae1a4 AW |
3103 | my $s = $stat; |
3104 | $s =~ s/{.*$//s; | |
cf655043 | 3105 | |
c2fdda0d | 3106 | # Ignore goto labels. |
171ae1a4 | 3107 | if ($s =~ /$Ident:\*$/s) { |
c2fdda0d AW |
3108 | |
3109 | # Ignore functions being called | |
171ae1a4 | 3110 | } elsif ($s =~ /^.\s*$Ident\s*\(/s) { |
c2fdda0d | 3111 | |
463f2864 AW |
3112 | } elsif ($s =~ /^.\s*else\b/s) { |
3113 | ||
c45dcabd | 3114 | # declarations always start with types |
d2506586 | 3115 | } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) { |
c45dcabd AW |
3116 | my $type = $1; |
3117 | $type =~ s/\s+/ /g; | |
3118 | possible($type, "A:" . $s); | |
3119 | ||
8905a67c | 3120 | # definitions in global scope can only start with types |
a6a84062 | 3121 | } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { |
c45dcabd | 3122 | possible($1, "B:" . $s); |
c2fdda0d | 3123 | } |
8905a67c AW |
3124 | |
3125 | # any (foo ... *) is a pointer cast, and foo is a type | |
65863862 | 3126 | while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { |
c45dcabd | 3127 | possible($1, "C:" . $s); |
8905a67c AW |
3128 | } |
3129 | ||
3130 | # Check for any sort of function declaration. | |
3131 | # int foo(something bar, other baz); | |
3132 | # void (*store_gdt)(x86_descr_ptr *); | |
171ae1a4 | 3133 | if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { |
8905a67c | 3134 | my ($name_len) = length($1); |
8905a67c | 3135 | |
cf655043 | 3136 | my $ctx = $s; |
773647a0 | 3137 | substr($ctx, 0, $name_len + 1, ''); |
8905a67c | 3138 | $ctx =~ s/\)[^\)]*$//; |
cf655043 | 3139 | |
8905a67c | 3140 | for my $arg (split(/\s*,\s*/, $ctx)) { |
c45dcabd | 3141 | if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { |
8905a67c | 3142 | |
c45dcabd | 3143 | possible($1, "D:" . $s); |
8905a67c AW |
3144 | } |
3145 | } | |
9c0ca6f9 | 3146 | } |
8905a67c | 3147 | |
9c0ca6f9 AW |
3148 | } |
3149 | ||
653d4876 AW |
3150 | # |
3151 | # Checks which may be anchored in the context. | |
3152 | # | |
00df344f | 3153 | |
653d4876 AW |
3154 | # Check for switch () and associated case and default |
3155 | # statements should be at the same indent. | |
00df344f AW |
3156 | if ($line=~/\bswitch\s*\(.*\)/) { |
3157 | my $err = ''; | |
3158 | my $sep = ''; | |
3159 | my @ctx = ctx_block_outer($linenr, $realcnt); | |
3160 | shift(@ctx); | |
3161 | for my $ctx (@ctx) { | |
3162 | my ($clen, $cindent) = line_stats($ctx); | |
3163 | if ($ctx =~ /^\+\s*(case\s+|default:)/ && | |
3164 | $indent != $cindent) { | |
3165 | $err .= "$sep$ctx\n"; | |
3166 | $sep = ''; | |
3167 | } else { | |
3168 | $sep = "[...]\n"; | |
3169 | } | |
3170 | } | |
3171 | if ($err ne '') { | |
000d1cc1 JP |
3172 | ERROR("SWITCH_CASE_INDENT_LEVEL", |
3173 | "switch and case should be at the same indent\n$hereline$err"); | |
de7d4f0e AW |
3174 | } |
3175 | } | |
3176 | ||
3177 | # if/while/etc brace do not go on next line, unless defining a do while loop, | |
3178 | # or if that brace on the next line is for something else | |
0fe3dc2b | 3179 | if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { |
773647a0 AW |
3180 | my $pre_ctx = "$1$2"; |
3181 | ||
9c0ca6f9 | 3182 | my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); |
8eef05dd JP |
3183 | |
3184 | if ($line =~ /^\+\t{6,}/) { | |
3185 | WARN("DEEP_INDENTATION", | |
3186 | "Too many leading tabs - consider code refactoring\n" . $herecurr); | |
3187 | } | |
3188 | ||
de7d4f0e AW |
3189 | my $ctx_cnt = $realcnt - $#ctx - 1; |
3190 | my $ctx = join("\n", @ctx); | |
3191 | ||
548596d5 AW |
3192 | my $ctx_ln = $linenr; |
3193 | my $ctx_skip = $realcnt; | |
773647a0 | 3194 | |
548596d5 AW |
3195 | while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && |
3196 | defined $lines[$ctx_ln - 1] && | |
3197 | $lines[$ctx_ln - 1] =~ /^-/)) { | |
3198 | ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; | |
3199 | $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); | |
de7d4f0e | 3200 | $ctx_ln++; |
de7d4f0e | 3201 | } |
548596d5 | 3202 | |
53210168 AW |
3203 | #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; |
3204 | #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; | |
de7d4f0e | 3205 | |
d752fcc8 | 3206 | if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { |
000d1cc1 JP |
3207 | ERROR("OPEN_BRACE", |
3208 | "that open brace { should be on the previous line\n" . | |
01464f30 | 3209 | "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); |
00df344f | 3210 | } |
773647a0 AW |
3211 | if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && |
3212 | $ctx =~ /\)\s*\;\s*$/ && | |
3213 | defined $lines[$ctx_ln - 1]) | |
3214 | { | |
9c0ca6f9 AW |
3215 | my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); |
3216 | if ($nindent > $indent) { | |
000d1cc1 JP |
3217 | WARN("TRAILING_SEMICOLON", |
3218 | "trailing semicolon indicates no statements, indent implies otherwise\n" . | |
01464f30 | 3219 | "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); |
9c0ca6f9 AW |
3220 | } |
3221 | } | |
00df344f AW |
3222 | } |
3223 | ||
4d001e4d | 3224 | # Check relative indent for conditionals and blocks. |
0fe3dc2b | 3225 | if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { |
3e469cdc AW |
3226 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
3227 | ctx_statement_block($linenr, $realcnt, 0) | |
3228 | if (!defined $stat); | |
4d001e4d AW |
3229 | my ($s, $c) = ($stat, $cond); |
3230 | ||
3231 | substr($s, 0, length($c), ''); | |
3232 | ||
9f5af480 JP |
3233 | # remove inline comments |
3234 | $s =~ s/$;/ /g; | |
3235 | $c =~ s/$;/ /g; | |
4d001e4d AW |
3236 | |
3237 | # Find out how long the conditional actually is. | |
6f779c18 AW |
3238 | my @newlines = ($c =~ /\n/gs); |
3239 | my $cond_lines = 1 + $#newlines; | |
4d001e4d | 3240 | |
9f5af480 JP |
3241 | # Make sure we remove the line prefixes as we have |
3242 | # none on the first line, and are going to readd them | |
3243 | # where necessary. | |
3244 | $s =~ s/\n./\n/gs; | |
3245 | while ($s =~ /\n\s+\\\n/) { | |
3246 | $cond_lines += $s =~ s/\n\s+\\\n/\n/g; | |
3247 | } | |
3248 | ||
4d001e4d AW |
3249 | # We want to check the first line inside the block |
3250 | # starting at the end of the conditional, so remove: | |
3251 | # 1) any blank line termination | |
3252 | # 2) any opening brace { on end of the line | |
3253 | # 3) any do (...) { | |
3254 | my $continuation = 0; | |
3255 | my $check = 0; | |
3256 | $s =~ s/^.*\bdo\b//; | |
3257 | $s =~ s/^\s*{//; | |
3258 | if ($s =~ s/^\s*\\//) { | |
3259 | $continuation = 1; | |
3260 | } | |
9bd49efe | 3261 | if ($s =~ s/^\s*?\n//) { |
4d001e4d AW |
3262 | $check = 1; |
3263 | $cond_lines++; | |
3264 | } | |
3265 | ||
3266 | # Also ignore a loop construct at the end of a | |
3267 | # preprocessor statement. | |
3268 | if (($prevline =~ /^.\s*#\s*define\s/ || | |
3269 | $prevline =~ /\\\s*$/) && $continuation == 0) { | |
3270 | $check = 0; | |
3271 | } | |
3272 | ||
9bd49efe | 3273 | my $cond_ptr = -1; |
740504c6 | 3274 | $continuation = 0; |
9bd49efe AW |
3275 | while ($cond_ptr != $cond_lines) { |
3276 | $cond_ptr = $cond_lines; | |
3277 | ||
f16fa28f AW |
3278 | # If we see an #else/#elif then the code |
3279 | # is not linear. | |
3280 | if ($s =~ /^\s*\#\s*(?:else|elif)/) { | |
3281 | $check = 0; | |
3282 | } | |
3283 | ||
9bd49efe AW |
3284 | # Ignore: |
3285 | # 1) blank lines, they should be at 0, | |
3286 | # 2) preprocessor lines, and | |
3287 | # 3) labels. | |
740504c6 AW |
3288 | if ($continuation || |
3289 | $s =~ /^\s*?\n/ || | |
9bd49efe AW |
3290 | $s =~ /^\s*#\s*?/ || |
3291 | $s =~ /^\s*$Ident\s*:/) { | |
740504c6 | 3292 | $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; |
30dad6eb AW |
3293 | if ($s =~ s/^.*?\n//) { |
3294 | $cond_lines++; | |
3295 | } | |
9bd49efe | 3296 | } |
4d001e4d AW |
3297 | } |
3298 | ||
3299 | my (undef, $sindent) = line_stats("+" . $s); | |
3300 | my $stat_real = raw_line($linenr, $cond_lines); | |
3301 | ||
3302 | # Check if either of these lines are modified, else | |
3303 | # this is not this patch's fault. | |
3304 | if (!defined($stat_real) || | |
3305 | $stat !~ /^\+/ && $stat_real !~ /^\+/) { | |
3306 | $check = 0; | |
3307 | } | |
3308 | if (defined($stat_real) && $cond_lines > 1) { | |
3309 | $stat_real = "[...]\n$stat_real"; | |
3310 | } | |
3311 | ||
9bd49efe | 3312 | #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; |
4d001e4d | 3313 | |
9f5af480 JP |
3314 | if ($check && $s ne '' && |
3315 | (($sindent % 8) != 0 || | |
3316 | ($sindent < $indent) || | |
3317 | ($sindent > $indent + 8))) { | |
000d1cc1 JP |
3318 | WARN("SUSPECT_CODE_INDENT", |
3319 | "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); | |
4d001e4d AW |
3320 | } |
3321 | } | |
3322 | ||
6c72ffaa AW |
3323 | # Track the 'values' across context and added lines. |
3324 | my $opline = $line; $opline =~ s/^./ /; | |
1f65f947 AW |
3325 | my ($curr_values, $curr_vars) = |
3326 | annotate_values($opline . "\n", $prev_values); | |
6c72ffaa | 3327 | $curr_values = $prev_values . $curr_values; |
c2fdda0d AW |
3328 | if ($dbg_values) { |
3329 | my $outline = $opline; $outline =~ s/\t/ /g; | |
cf655043 AW |
3330 | print "$linenr > .$outline\n"; |
3331 | print "$linenr > $curr_values\n"; | |
1f65f947 | 3332 | print "$linenr > $curr_vars\n"; |
c2fdda0d | 3333 | } |
6c72ffaa AW |
3334 | $prev_values = substr($curr_values, -1); |
3335 | ||
00df344f | 3336 | #ignore lines not being added |
3705ce5b | 3337 | next if ($line =~ /^[^\+]/); |
00df344f | 3338 | |
a1ce18e4 | 3339 | # check for declarations of signed or unsigned without int |
207a8e84 | 3340 | while ($line =~ m{($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { |
a1ce18e4 JP |
3341 | my $type = $1; |
3342 | my $var = $2; | |
207a8e84 JP |
3343 | $var = "" if (!defined $var); |
3344 | if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { | |
a1ce18e4 JP |
3345 | my $sign = $1; |
3346 | my $pointer = $2; | |
3347 | ||
3348 | $pointer = "" if (!defined $pointer); | |
3349 | ||
3350 | if (WARN("UNSPECIFIED_INT", | |
3351 | "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && | |
3352 | $fix) { | |
3353 | my $decl = trim($sign) . " int "; | |
207a8e84 JP |
3354 | my $comp_pointer = $pointer; |
3355 | $comp_pointer =~ s/\s//g; | |
3356 | $decl .= $comp_pointer; | |
3357 | $decl = rtrim($decl) if ($var eq ""); | |
3358 | $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; | |
a1ce18e4 JP |
3359 | } |
3360 | } | |
3361 | } | |
3362 | ||
653d4876 | 3363 | # TEST: allow direct testing of the type matcher. |
7429c690 AW |
3364 | if ($dbg_type) { |
3365 | if ($line =~ /^.\s*$Declare\s*$/) { | |
000d1cc1 JP |
3366 | ERROR("TEST_TYPE", |
3367 | "TEST: is type\n" . $herecurr); | |
7429c690 | 3368 | } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { |
000d1cc1 JP |
3369 | ERROR("TEST_NOT_TYPE", |
3370 | "TEST: is not type ($1 is)\n". $herecurr); | |
7429c690 | 3371 | } |
653d4876 AW |
3372 | next; |
3373 | } | |
a1ef277e AW |
3374 | # TEST: allow direct testing of the attribute matcher. |
3375 | if ($dbg_attr) { | |
9360b0e5 | 3376 | if ($line =~ /^.\s*$Modifier\s*$/) { |
000d1cc1 JP |
3377 | ERROR("TEST_ATTR", |
3378 | "TEST: is attr\n" . $herecurr); | |
9360b0e5 | 3379 | } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { |
000d1cc1 JP |
3380 | ERROR("TEST_NOT_ATTR", |
3381 | "TEST: is not attr ($1 is)\n". $herecurr); | |
a1ef277e AW |
3382 | } |
3383 | next; | |
3384 | } | |
653d4876 | 3385 | |
f0a594c1 | 3386 | # check for initialisation to aggregates open brace on the next line |
99423c20 AW |
3387 | if ($line =~ /^.\s*{/ && |
3388 | $prevline =~ /(?:^|[^=])=\s*$/) { | |
d752fcc8 JP |
3389 | if (ERROR("OPEN_BRACE", |
3390 | "that open brace { should be on the previous line\n" . $hereprev) && | |
f2d7e4d4 JP |
3391 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { |
3392 | fix_delete_line($fixlinenr - 1, $prevrawline); | |
3393 | fix_delete_line($fixlinenr, $rawline); | |
d752fcc8 JP |
3394 | my $fixedline = $prevrawline; |
3395 | $fixedline =~ s/\s*=\s*$/ = {/; | |
f2d7e4d4 | 3396 | fix_insert_line($fixlinenr, $fixedline); |
d752fcc8 JP |
3397 | $fixedline = $line; |
3398 | $fixedline =~ s/^(.\s*){\s*/$1/; | |
f2d7e4d4 | 3399 | fix_insert_line($fixlinenr, $fixedline); |
d752fcc8 | 3400 | } |
f0a594c1 AW |
3401 | } |
3402 | ||
653d4876 AW |
3403 | # |
3404 | # Checks which are anchored on the added line. | |
3405 | # | |
3406 | ||
3407 | # check for malformed paths in #include statements (uses RAW line) | |
c45dcabd | 3408 | if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { |
653d4876 AW |
3409 | my $path = $1; |
3410 | if ($path =~ m{//}) { | |
000d1cc1 | 3411 | ERROR("MALFORMED_INCLUDE", |
495e9d84 JP |
3412 | "malformed #include filename\n" . $herecurr); |
3413 | } | |
3414 | if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { | |
3415 | ERROR("UAPI_INCLUDE", | |
3416 | "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); | |
653d4876 | 3417 | } |
653d4876 | 3418 | } |
00df344f | 3419 | |
0a920b5b | 3420 | # no C99 // comments |
00df344f | 3421 | if ($line =~ m{//}) { |
3705ce5b JP |
3422 | if (ERROR("C99_COMMENTS", |
3423 | "do not use C99 // comments\n" . $herecurr) && | |
3424 | $fix) { | |
194f66fc | 3425 | my $line = $fixed[$fixlinenr]; |
3705ce5b JP |
3426 | if ($line =~ /\/\/(.*)$/) { |
3427 | my $comment = trim($1); | |
194f66fc | 3428 | $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; |
3705ce5b JP |
3429 | } |
3430 | } | |
0a920b5b | 3431 | } |
00df344f | 3432 | # Remove C99 comments. |
0a920b5b | 3433 | $line =~ s@//.*@@; |
6c72ffaa | 3434 | $opline =~ s@//.*@@; |
0a920b5b | 3435 | |
2b474a1a AW |
3436 | # EXPORT_SYMBOL should immediately follow the thing it is exporting, consider |
3437 | # the whole statement. | |
3438 | #print "APW <$lines[$realline_next - 1]>\n"; | |
3439 | if (defined $realline_next && | |
3440 | exists $lines[$realline_next - 1] && | |
3441 | !defined $suppress_export{$realline_next} && | |
3442 | ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || | |
3443 | $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { | |
3cbf62df AW |
3444 | # Handle definitions which produce identifiers with |
3445 | # a prefix: | |
3446 | # XXX(foo); | |
3447 | # EXPORT_SYMBOL(something_foo); | |
653d4876 | 3448 | my $name = $1; |
87a53877 | 3449 | if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && |
3cbf62df AW |
3450 | $name =~ /^${Ident}_$2/) { |
3451 | #print "FOO C name<$name>\n"; | |
3452 | $suppress_export{$realline_next} = 1; | |
3453 | ||
3454 | } elsif ($stat !~ /(?: | |
2b474a1a | 3455 | \n.}\s*$| |
48012058 AW |
3456 | ^.DEFINE_$Ident\(\Q$name\E\)| |
3457 | ^.DECLARE_$Ident\(\Q$name\E\)| | |
3458 | ^.LIST_HEAD\(\Q$name\E\)| | |
2b474a1a AW |
3459 | ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| |
3460 | \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() | |
48012058 | 3461 | )/x) { |
2b474a1a AW |
3462 | #print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; |
3463 | $suppress_export{$realline_next} = 2; | |
3464 | } else { | |
3465 | $suppress_export{$realline_next} = 1; | |
0a920b5b AW |
3466 | } |
3467 | } | |
2b474a1a AW |
3468 | if (!defined $suppress_export{$linenr} && |
3469 | $prevline =~ /^.\s*$/ && | |
3470 | ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || | |
3471 | $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { | |
3472 | #print "FOO B <$lines[$linenr - 1]>\n"; | |
3473 | $suppress_export{$linenr} = 2; | |
3474 | } | |
3475 | if (defined $suppress_export{$linenr} && | |
3476 | $suppress_export{$linenr} == 2) { | |
000d1cc1 JP |
3477 | WARN("EXPORT_SYMBOL", |
3478 | "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); | |
2b474a1a | 3479 | } |
0a920b5b | 3480 | |
5150bda4 | 3481 | # check for global initialisers. |
6d32f7a3 | 3482 | if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { |
d5e616fc | 3483 | if (ERROR("GLOBAL_INITIALISERS", |
6d32f7a3 | 3484 | "do not initialise globals to $1\n" . $herecurr) && |
d5e616fc | 3485 | $fix) { |
6d32f7a3 | 3486 | $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; |
d5e616fc | 3487 | } |
f0a594c1 | 3488 | } |
653d4876 | 3489 | # check for static initialisers. |
6d32f7a3 | 3490 | if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { |
d5e616fc | 3491 | if (ERROR("INITIALISED_STATIC", |
6d32f7a3 | 3492 | "do not initialise statics to $1\n" . |
d5e616fc JP |
3493 | $herecurr) && |
3494 | $fix) { | |
6d32f7a3 | 3495 | $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; |
d5e616fc | 3496 | } |
0a920b5b AW |
3497 | } |
3498 | ||
1813087d JP |
3499 | # check for misordered declarations of char/short/int/long with signed/unsigned |
3500 | while ($sline =~ m{(\b$TypeMisordered\b)}g) { | |
3501 | my $tmp = trim($1); | |
3502 | WARN("MISORDERED_TYPE", | |
3503 | "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); | |
3504 | } | |
3505 | ||
cb710eca JP |
3506 | # check for static const char * arrays. |
3507 | if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { | |
000d1cc1 JP |
3508 | WARN("STATIC_CONST_CHAR_ARRAY", |
3509 | "static const char * array should probably be static const char * const\n" . | |
cb710eca JP |
3510 | $herecurr); |
3511 | } | |
3512 | ||
3513 | # check for static char foo[] = "bar" declarations. | |
3514 | if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { | |
000d1cc1 JP |
3515 | WARN("STATIC_CONST_CHAR_ARRAY", |
3516 | "static char array declaration should probably be static const char\n" . | |
cb710eca JP |
3517 | $herecurr); |
3518 | } | |
3519 | ||
ab7e23f3 JP |
3520 | # check for const <foo> const where <foo> is not a pointer or array type |
3521 | if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { | |
3522 | my $found = $1; | |
3523 | if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { | |
3524 | WARN("CONST_CONST", | |
3525 | "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); | |
3526 | } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { | |
3527 | WARN("CONST_CONST", | |
3528 | "'const $found const' should probably be 'const $found'\n" . $herecurr); | |
3529 | } | |
3530 | } | |
3531 | ||
9b0fa60d JP |
3532 | # check for non-global char *foo[] = {"bar", ...} declarations. |
3533 | if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { | |
3534 | WARN("STATIC_CONST_CHAR_ARRAY", | |
3535 | "char * array declaration might be better as static const\n" . | |
3536 | $herecurr); | |
3537 | } | |
3538 | ||
b598b670 JP |
3539 | # check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) |
3540 | if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { | |
3541 | my $array = $1; | |
3542 | if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { | |
3543 | my $array_div = $1; | |
3544 | if (WARN("ARRAY_SIZE", | |
3545 | "Prefer ARRAY_SIZE($array)\n" . $herecurr) && | |
3546 | $fix) { | |
3547 | $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; | |
3548 | } | |
3549 | } | |
3550 | } | |
3551 | ||
b36190c5 JP |
3552 | # check for function declarations without arguments like "int foo()" |
3553 | if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { | |
3554 | if (ERROR("FUNCTION_WITHOUT_ARGS", | |
3555 | "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && | |
3556 | $fix) { | |
194f66fc | 3557 | $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; |
b36190c5 JP |
3558 | } |
3559 | } | |
3560 | ||
92e112fd JP |
3561 | # check for uses of DEFINE_PCI_DEVICE_TABLE |
3562 | if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) { | |
3563 | if (WARN("DEFINE_PCI_DEVICE_TABLE", | |
3564 | "Prefer struct pci_device_id over deprecated DEFINE_PCI_DEVICE_TABLE\n" . $herecurr) && | |
3565 | $fix) { | |
194f66fc | 3566 | $fixed[$fixlinenr] =~ s/\b(?:static\s+|)DEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=\s*/static const struct pci_device_id $1\[\] = /; |
92e112fd | 3567 | } |
93ed0e2d JP |
3568 | } |
3569 | ||
653d4876 AW |
3570 | # check for new typedefs, only function parameters and sparse annotations |
3571 | # make sense. | |
3572 | if ($line =~ /\btypedef\s/ && | |
8054576d | 3573 | $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && |
c45dcabd | 3574 | $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && |
8ed22cad | 3575 | $line !~ /\b$typeTypedefs\b/ && |
653d4876 | 3576 | $line !~ /\b__bitwise(?:__|)\b/) { |
000d1cc1 JP |
3577 | WARN("NEW_TYPEDEFS", |
3578 | "do not add new typedefs\n" . $herecurr); | |
0a920b5b AW |
3579 | } |
3580 | ||
3581 | # * goes on variable not on type | |
65863862 | 3582 | # (char*[ const]) |
bfcb2cc7 AW |
3583 | while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { |
3584 | #print "AA<$1>\n"; | |
3705ce5b | 3585 | my ($ident, $from, $to) = ($1, $2, $2); |
65863862 AW |
3586 | |
3587 | # Should start with a space. | |
3588 | $to =~ s/^(\S)/ $1/; | |
3589 | # Should not end with a space. | |
3590 | $to =~ s/\s+$//; | |
3591 | # '*'s should not have spaces between. | |
f9a0b3d1 | 3592 | while ($to =~ s/\*\s+\*/\*\*/) { |
65863862 | 3593 | } |
d8aaf121 | 3594 | |
3705ce5b | 3595 | ## print "1: from<$from> to<$to> ident<$ident>\n"; |
65863862 | 3596 | if ($from ne $to) { |
3705ce5b JP |
3597 | if (ERROR("POINTER_LOCATION", |
3598 | "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && | |
3599 | $fix) { | |
3600 | my $sub_from = $ident; | |
3601 | my $sub_to = $ident; | |
3602 | $sub_to =~ s/\Q$from\E/$to/; | |
194f66fc | 3603 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
3604 | s@\Q$sub_from\E@$sub_to@; |
3605 | } | |
65863862 | 3606 | } |
bfcb2cc7 AW |
3607 | } |
3608 | while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { | |
3609 | #print "BB<$1>\n"; | |
3705ce5b | 3610 | my ($match, $from, $to, $ident) = ($1, $2, $2, $3); |
65863862 AW |
3611 | |
3612 | # Should start with a space. | |
3613 | $to =~ s/^(\S)/ $1/; | |
3614 | # Should not end with a space. | |
3615 | $to =~ s/\s+$//; | |
3616 | # '*'s should not have spaces between. | |
f9a0b3d1 | 3617 | while ($to =~ s/\*\s+\*/\*\*/) { |
65863862 AW |
3618 | } |
3619 | # Modifiers should have spaces. | |
3620 | $to =~ s/(\b$Modifier$)/$1 /; | |
d8aaf121 | 3621 | |
3705ce5b | 3622 | ## print "2: from<$from> to<$to> ident<$ident>\n"; |
667026e7 | 3623 | if ($from ne $to && $ident !~ /^$Modifier$/) { |
3705ce5b JP |
3624 | if (ERROR("POINTER_LOCATION", |
3625 | "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && | |
3626 | $fix) { | |
3627 | ||
3628 | my $sub_from = $match; | |
3629 | my $sub_to = $match; | |
3630 | $sub_to =~ s/\Q$from\E/$to/; | |
194f66fc | 3631 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
3632 | s@\Q$sub_from\E@$sub_to@; |
3633 | } | |
65863862 | 3634 | } |
0a920b5b AW |
3635 | } |
3636 | ||
9d3e3c70 JP |
3637 | # avoid BUG() or BUG_ON() |
3638 | if ($line =~ /\b(?:BUG|BUG_ON)\b/) { | |
3639 | my $msg_type = \&WARN; | |
3640 | $msg_type = \&CHK if ($file); | |
3641 | &{$msg_type}("AVOID_BUG", | |
3642 | "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); | |
3643 | } | |
0a920b5b | 3644 | |
9d3e3c70 | 3645 | # avoid LINUX_VERSION_CODE |
8905a67c | 3646 | if ($line =~ /\bLINUX_VERSION_CODE\b/) { |
000d1cc1 JP |
3647 | WARN("LINUX_VERSION_CODE", |
3648 | "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); | |
8905a67c AW |
3649 | } |
3650 | ||
17441227 JP |
3651 | # check for uses of printk_ratelimit |
3652 | if ($line =~ /\bprintk_ratelimit\s*\(/) { | |
000d1cc1 | 3653 | WARN("PRINTK_RATELIMITED", |
101ee680 | 3654 | "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); |
17441227 JP |
3655 | } |
3656 | ||
00df344f AW |
3657 | # printk should use KERN_* levels. Note that follow on printk's on the |
3658 | # same line do not need a level, so we use the current block context | |
3659 | # to try and find and validate the current printk. In summary the current | |
25985edc | 3660 | # printk includes all preceding printk's which have no newline on the end. |
00df344f | 3661 | # we assume the first bad printk is the one to report. |
f0a594c1 | 3662 | if ($line =~ /\bprintk\((?!KERN_)\s*"/) { |
00df344f AW |
3663 | my $ok = 0; |
3664 | for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { | |
3665 | #print "CHECK<$lines[$ln - 1]\n"; | |
25985edc | 3666 | # we have a preceding printk if it ends |
00df344f AW |
3667 | # with "\n" ignore it, else it is to blame |
3668 | if ($lines[$ln - 1] =~ m{\bprintk\(}) { | |
3669 | if ($rawlines[$ln - 1] !~ m{\\n"}) { | |
3670 | $ok = 1; | |
3671 | } | |
3672 | last; | |
3673 | } | |
3674 | } | |
3675 | if ($ok == 0) { | |
000d1cc1 JP |
3676 | WARN("PRINTK_WITHOUT_KERN_LEVEL", |
3677 | "printk() should include KERN_ facility level\n" . $herecurr); | |
00df344f | 3678 | } |
0a920b5b AW |
3679 | } |
3680 | ||
243f3803 JP |
3681 | if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { |
3682 | my $orig = $1; | |
3683 | my $level = lc($orig); | |
3684 | $level = "warn" if ($level eq "warning"); | |
8f26b837 JP |
3685 | my $level2 = $level; |
3686 | $level2 = "dbg" if ($level eq "debug"); | |
243f3803 | 3687 | WARN("PREFER_PR_LEVEL", |
daa8b059 | 3688 | "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); |
243f3803 JP |
3689 | } |
3690 | ||
3691 | if ($line =~ /\bpr_warning\s*\(/) { | |
d5e616fc JP |
3692 | if (WARN("PREFER_PR_LEVEL", |
3693 | "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && | |
3694 | $fix) { | |
194f66fc | 3695 | $fixed[$fixlinenr] =~ |
d5e616fc JP |
3696 | s/\bpr_warning\b/pr_warn/; |
3697 | } | |
243f3803 JP |
3698 | } |
3699 | ||
dc139313 JP |
3700 | if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { |
3701 | my $orig = $1; | |
3702 | my $level = lc($orig); | |
3703 | $level = "warn" if ($level eq "warning"); | |
3704 | $level = "dbg" if ($level eq "debug"); | |
3705 | WARN("PREFER_DEV_LEVEL", | |
3706 | "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); | |
3707 | } | |
3708 | ||
91c9afaf AL |
3709 | # ENOSYS means "bad syscall nr" and nothing else. This will have a small |
3710 | # number of false positives, but assembly files are not checked, so at | |
3711 | # least the arch entry code will not trigger this warning. | |
3712 | if ($line =~ /\bENOSYS\b/) { | |
3713 | WARN("ENOSYS", | |
3714 | "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); | |
3715 | } | |
3716 | ||
653d4876 AW |
3717 | # function brace can't be on same line, except for #defines of do while, |
3718 | # or if closed on same line | |
8d182478 | 3719 | if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and |
4e5d56bd | 3720 | !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { |
8d182478 JP |
3721 | if (ERROR("OPEN_BRACE", |
3722 | "open brace '{' following function declarations go on the next line\n" . $herecurr) && | |
3723 | $fix) { | |
3724 | fix_delete_line($fixlinenr, $rawline); | |
3725 | my $fixed_line = $rawline; | |
3726 | $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; | |
3727 | my $line1 = $1; | |
3728 | my $line2 = $2; | |
3729 | fix_insert_line($fixlinenr, ltrim($line1)); | |
3730 | fix_insert_line($fixlinenr, "\+{"); | |
3731 | if ($line2 !~ /^\s*$/) { | |
3732 | fix_insert_line($fixlinenr, "\+\t" . trim($line2)); | |
3733 | } | |
3734 | } | |
0a920b5b | 3735 | } |
653d4876 | 3736 | |
8905a67c AW |
3737 | # open braces for enum, union and struct go on the same line. |
3738 | if ($line =~ /^.\s*{/ && | |
3739 | $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { | |
8d182478 JP |
3740 | if (ERROR("OPEN_BRACE", |
3741 | "open brace '{' following $1 go on the same line\n" . $hereprev) && | |
3742 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { | |
3743 | fix_delete_line($fixlinenr - 1, $prevrawline); | |
3744 | fix_delete_line($fixlinenr, $rawline); | |
3745 | my $fixedline = rtrim($prevrawline) . " {"; | |
3746 | fix_insert_line($fixlinenr, $fixedline); | |
3747 | $fixedline = $rawline; | |
3748 | $fixedline =~ s/^(.\s*){\s*/$1\t/; | |
3749 | if ($fixedline !~ /^\+\s*$/) { | |
3750 | fix_insert_line($fixlinenr, $fixedline); | |
3751 | } | |
3752 | } | |
8905a67c AW |
3753 | } |
3754 | ||
0c73b4eb | 3755 | # missing space after union, struct or enum definition |
3705ce5b JP |
3756 | if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { |
3757 | if (WARN("SPACING", | |
3758 | "missing space after $1 definition\n" . $herecurr) && | |
3759 | $fix) { | |
194f66fc | 3760 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
3761 | s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; |
3762 | } | |
0c73b4eb AW |
3763 | } |
3764 | ||
31070b5d JP |
3765 | # Function pointer declarations |
3766 | # check spacing between type, funcptr, and args | |
3767 | # canonical declaration is "type (*funcptr)(args...)" | |
91f72e9c | 3768 | if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { |
31070b5d JP |
3769 | my $declare = $1; |
3770 | my $pre_pointer_space = $2; | |
3771 | my $post_pointer_space = $3; | |
3772 | my $funcname = $4; | |
3773 | my $post_funcname_space = $5; | |
3774 | my $pre_args_space = $6; | |
3775 | ||
91f72e9c JP |
3776 | # the $Declare variable will capture all spaces after the type |
3777 | # so check it for a missing trailing missing space but pointer return types | |
3778 | # don't need a space so don't warn for those. | |
3779 | my $post_declare_space = ""; | |
3780 | if ($declare =~ /(\s+)$/) { | |
3781 | $post_declare_space = $1; | |
3782 | $declare = rtrim($declare); | |
3783 | } | |
3784 | if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { | |
31070b5d JP |
3785 | WARN("SPACING", |
3786 | "missing space after return type\n" . $herecurr); | |
91f72e9c | 3787 | $post_declare_space = " "; |
31070b5d JP |
3788 | } |
3789 | ||
3790 | # unnecessary space "type (*funcptr)(args...)" | |
91f72e9c JP |
3791 | # This test is not currently implemented because these declarations are |
3792 | # equivalent to | |
3793 | # int foo(int bar, ...) | |
3794 | # and this is form shouldn't/doesn't generate a checkpatch warning. | |
3795 | # | |
3796 | # elsif ($declare =~ /\s{2,}$/) { | |
3797 | # WARN("SPACING", | |
3798 | # "Multiple spaces after return type\n" . $herecurr); | |
3799 | # } | |
31070b5d JP |
3800 | |
3801 | # unnecessary space "type ( *funcptr)(args...)" | |
3802 | if (defined $pre_pointer_space && | |
3803 | $pre_pointer_space =~ /^\s/) { | |
3804 | WARN("SPACING", | |
3805 | "Unnecessary space after function pointer open parenthesis\n" . $herecurr); | |
3806 | } | |
3807 | ||
3808 | # unnecessary space "type (* funcptr)(args...)" | |
3809 | if (defined $post_pointer_space && | |
3810 | $post_pointer_space =~ /^\s/) { | |
3811 | WARN("SPACING", | |
3812 | "Unnecessary space before function pointer name\n" . $herecurr); | |
3813 | } | |
3814 | ||
3815 | # unnecessary space "type (*funcptr )(args...)" | |
3816 | if (defined $post_funcname_space && | |
3817 | $post_funcname_space =~ /^\s/) { | |
3818 | WARN("SPACING", | |
3819 | "Unnecessary space after function pointer name\n" . $herecurr); | |
3820 | } | |
3821 | ||
3822 | # unnecessary space "type (*funcptr) (args...)" | |
3823 | if (defined $pre_args_space && | |
3824 | $pre_args_space =~ /^\s/) { | |
3825 | WARN("SPACING", | |
3826 | "Unnecessary space before function pointer arguments\n" . $herecurr); | |
3827 | } | |
3828 | ||
3829 | if (show_type("SPACING") && $fix) { | |
194f66fc | 3830 | $fixed[$fixlinenr] =~ |
91f72e9c | 3831 | s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; |
31070b5d JP |
3832 | } |
3833 | } | |
3834 | ||
8d31cfce AW |
3835 | # check for spacing round square brackets; allowed: |
3836 | # 1. with a type on the left -- int [] a; | |
fe2a7dbc AW |
3837 | # 2. at the beginning of a line for slice initialisers -- [0...10] = 5, |
3838 | # 3. inside a curly brace -- = { [0...10] = 5 } | |
8d31cfce AW |
3839 | while ($line =~ /(.*?\s)\[/g) { |
3840 | my ($where, $prefix) = ($-[1], $1); | |
3841 | if ($prefix !~ /$Type\s+$/ && | |
fe2a7dbc | 3842 | ($where != 0 || $prefix !~ /^.\s+$/) && |
daebc534 | 3843 | $prefix !~ /[{,]\s+$/) { |
3705ce5b JP |
3844 | if (ERROR("BRACKET_SPACE", |
3845 | "space prohibited before open square bracket '['\n" . $herecurr) && | |
3846 | $fix) { | |
194f66fc | 3847 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
3848 | s/^(\+.*?)\s+\[/$1\[/; |
3849 | } | |
8d31cfce AW |
3850 | } |
3851 | } | |
3852 | ||
f0a594c1 | 3853 | # check for spaces between functions and their parentheses. |
6c72ffaa | 3854 | while ($line =~ /($Ident)\s+\(/g) { |
c2fdda0d | 3855 | my $name = $1; |
773647a0 AW |
3856 | my $ctx_before = substr($line, 0, $-[1]); |
3857 | my $ctx = "$ctx_before$name"; | |
c2fdda0d AW |
3858 | |
3859 | # Ignore those directives where spaces _are_ permitted. | |
773647a0 AW |
3860 | if ($name =~ /^(?: |
3861 | if|for|while|switch|return|case| | |
3862 | volatile|__volatile__| | |
3863 | __attribute__|format|__extension__| | |
3864 | asm|__asm__)$/x) | |
3865 | { | |
c2fdda0d AW |
3866 | # cpp #define statements have non-optional spaces, ie |
3867 | # if there is a space between the name and the open | |
3868 | # parenthesis it is simply not a parameter group. | |
c45dcabd | 3869 | } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { |
773647a0 AW |
3870 | |
3871 | # cpp #elif statement condition may start with a ( | |
c45dcabd | 3872 | } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { |
c2fdda0d AW |
3873 | |
3874 | # If this whole things ends with a type its most | |
3875 | # likely a typedef for a function. | |
773647a0 | 3876 | } elsif ($ctx =~ /$Type$/) { |
c2fdda0d AW |
3877 | |
3878 | } else { | |
3705ce5b JP |
3879 | if (WARN("SPACING", |
3880 | "space prohibited between function name and open parenthesis '('\n" . $herecurr) && | |
3881 | $fix) { | |
194f66fc | 3882 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
3883 | s/\b$name\s+\(/$name\(/; |
3884 | } | |
6c72ffaa | 3885 | } |
f0a594c1 | 3886 | } |
9a4cad4e | 3887 | |
653d4876 | 3888 | # Check operator spacing. |
0a920b5b | 3889 | if (!($line=~/\#\s*include/)) { |
3705ce5b JP |
3890 | my $fixed_line = ""; |
3891 | my $line_fixed = 0; | |
3892 | ||
9c0ca6f9 AW |
3893 | my $ops = qr{ |
3894 | <<=|>>=|<=|>=|==|!=| | |
3895 | \+=|-=|\*=|\/=|%=|\^=|\|=|&=| | |
3896 | =>|->|<<|>>|<|>|=|!|~| | |
1f65f947 | 3897 | &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| |
84731623 | 3898 | \?:|\?|: |
9c0ca6f9 | 3899 | }x; |
cf655043 | 3900 | my @elements = split(/($ops|;)/, $opline); |
3705ce5b JP |
3901 | |
3902 | ## print("element count: <" . $#elements . ">\n"); | |
3903 | ## foreach my $el (@elements) { | |
3904 | ## print("el: <$el>\n"); | |
3905 | ## } | |
3906 | ||
3907 | my @fix_elements = (); | |
00df344f | 3908 | my $off = 0; |
6c72ffaa | 3909 | |
3705ce5b JP |
3910 | foreach my $el (@elements) { |
3911 | push(@fix_elements, substr($rawline, $off, length($el))); | |
3912 | $off += length($el); | |
3913 | } | |
3914 | ||
3915 | $off = 0; | |
3916 | ||
6c72ffaa | 3917 | my $blank = copy_spacing($opline); |
b34c648b | 3918 | my $last_after = -1; |
6c72ffaa | 3919 | |
0a920b5b | 3920 | for (my $n = 0; $n < $#elements; $n += 2) { |
3705ce5b JP |
3921 | |
3922 | my $good = $fix_elements[$n] . $fix_elements[$n + 1]; | |
3923 | ||
3924 | ## print("n: <$n> good: <$good>\n"); | |
3925 | ||
4a0df2ef AW |
3926 | $off += length($elements[$n]); |
3927 | ||
25985edc | 3928 | # Pick up the preceding and succeeding characters. |
773647a0 AW |
3929 | my $ca = substr($opline, 0, $off); |
3930 | my $cc = ''; | |
3931 | if (length($opline) >= ($off + length($elements[$n + 1]))) { | |
3932 | $cc = substr($opline, $off + length($elements[$n + 1])); | |
3933 | } | |
3934 | my $cb = "$ca$;$cc"; | |
3935 | ||
4a0df2ef AW |
3936 | my $a = ''; |
3937 | $a = 'V' if ($elements[$n] ne ''); | |
3938 | $a = 'W' if ($elements[$n] =~ /\s$/); | |
cf655043 | 3939 | $a = 'C' if ($elements[$n] =~ /$;$/); |
4a0df2ef AW |
3940 | $a = 'B' if ($elements[$n] =~ /(\[|\()$/); |
3941 | $a = 'O' if ($elements[$n] eq ''); | |
773647a0 | 3942 | $a = 'E' if ($ca =~ /^\s*$/); |
4a0df2ef | 3943 | |
0a920b5b | 3944 | my $op = $elements[$n + 1]; |
4a0df2ef AW |
3945 | |
3946 | my $c = ''; | |
0a920b5b | 3947 | if (defined $elements[$n + 2]) { |
4a0df2ef AW |
3948 | $c = 'V' if ($elements[$n + 2] ne ''); |
3949 | $c = 'W' if ($elements[$n + 2] =~ /^\s/); | |
cf655043 | 3950 | $c = 'C' if ($elements[$n + 2] =~ /^$;/); |
4a0df2ef AW |
3951 | $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); |
3952 | $c = 'O' if ($elements[$n + 2] eq ''); | |
8b1b3378 | 3953 | $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); |
4a0df2ef AW |
3954 | } else { |
3955 | $c = 'E'; | |
0a920b5b AW |
3956 | } |
3957 | ||
4a0df2ef AW |
3958 | my $ctx = "${a}x${c}"; |
3959 | ||
3960 | my $at = "(ctx:$ctx)"; | |
3961 | ||
6c72ffaa | 3962 | my $ptr = substr($blank, 0, $off) . "^"; |
de7d4f0e | 3963 | my $hereptr = "$hereline$ptr\n"; |
0a920b5b | 3964 | |
74048ed8 | 3965 | # Pull out the value of this operator. |
6c72ffaa | 3966 | my $op_type = substr($curr_values, $off + 1, 1); |
0a920b5b | 3967 | |
1f65f947 AW |
3968 | # Get the full operator variant. |
3969 | my $opv = $op . substr($curr_vars, $off, 1); | |
3970 | ||
13214adf AW |
3971 | # Ignore operators passed as parameters. |
3972 | if ($op_type ne 'V' && | |
d7fe8065 | 3973 | $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { |
13214adf | 3974 | |
cf655043 AW |
3975 | # # Ignore comments |
3976 | # } elsif ($op =~ /^$;+$/) { | |
13214adf | 3977 | |
d8aaf121 | 3978 | # ; should have either the end of line or a space or \ after it |
13214adf | 3979 | } elsif ($op eq ';') { |
cf655043 AW |
3980 | if ($ctx !~ /.x[WEBC]/ && |
3981 | $cc !~ /^\\/ && $cc !~ /^;/) { | |
3705ce5b JP |
3982 | if (ERROR("SPACING", |
3983 | "space required after that '$op' $at\n" . $hereptr)) { | |
b34c648b | 3984 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; |
3705ce5b JP |
3985 | $line_fixed = 1; |
3986 | } | |
d8aaf121 AW |
3987 | } |
3988 | ||
3989 | # // is a comment | |
3990 | } elsif ($op eq '//') { | |
0a920b5b | 3991 | |
b00e4814 JP |
3992 | # : when part of a bitfield |
3993 | } elsif ($opv eq ':B') { | |
3994 | # skip the bitfield test for now | |
3995 | ||
1f65f947 AW |
3996 | # No spaces for: |
3997 | # -> | |
b00e4814 | 3998 | } elsif ($op eq '->') { |
4a0df2ef | 3999 | if ($ctx =~ /Wx.|.xW/) { |
3705ce5b JP |
4000 | if (ERROR("SPACING", |
4001 | "spaces prohibited around that '$op' $at\n" . $hereptr)) { | |
b34c648b | 4002 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
3705ce5b JP |
4003 | if (defined $fix_elements[$n + 2]) { |
4004 | $fix_elements[$n + 2] =~ s/^\s+//; | |
4005 | } | |
b34c648b | 4006 | $line_fixed = 1; |
3705ce5b | 4007 | } |
0a920b5b AW |
4008 | } |
4009 | ||
2381097b | 4010 | # , must not have a space before and must have a space on the right. |
0a920b5b | 4011 | } elsif ($op eq ',') { |
2381097b JP |
4012 | my $rtrim_before = 0; |
4013 | my $space_after = 0; | |
4014 | if ($ctx =~ /Wx./) { | |
4015 | if (ERROR("SPACING", | |
4016 | "space prohibited before that '$op' $at\n" . $hereptr)) { | |
4017 | $line_fixed = 1; | |
4018 | $rtrim_before = 1; | |
4019 | } | |
4020 | } | |
cf655043 | 4021 | if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { |
3705ce5b JP |
4022 | if (ERROR("SPACING", |
4023 | "space required after that '$op' $at\n" . $hereptr)) { | |
3705ce5b | 4024 | $line_fixed = 1; |
b34c648b | 4025 | $last_after = $n; |
2381097b JP |
4026 | $space_after = 1; |
4027 | } | |
4028 | } | |
4029 | if ($rtrim_before || $space_after) { | |
4030 | if ($rtrim_before) { | |
4031 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); | |
4032 | } else { | |
4033 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); | |
4034 | } | |
4035 | if ($space_after) { | |
4036 | $good .= " "; | |
3705ce5b | 4037 | } |
0a920b5b AW |
4038 | } |
4039 | ||
9c0ca6f9 | 4040 | # '*' as part of a type definition -- reported already. |
74048ed8 | 4041 | } elsif ($opv eq '*_') { |
9c0ca6f9 AW |
4042 | #warn "'*' is part of type\n"; |
4043 | ||
4044 | # unary operators should have a space before and | |
4045 | # none after. May be left adjacent to another | |
4046 | # unary operator, or a cast | |
4047 | } elsif ($op eq '!' || $op eq '~' || | |
74048ed8 | 4048 | $opv eq '*U' || $opv eq '-U' || |
0d413866 | 4049 | $opv eq '&U' || $opv eq '&&U') { |
cf655043 | 4050 | if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { |
3705ce5b JP |
4051 | if (ERROR("SPACING", |
4052 | "space required before that '$op' $at\n" . $hereptr)) { | |
b34c648b JP |
4053 | if ($n != $last_after + 2) { |
4054 | $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); | |
4055 | $line_fixed = 1; | |
4056 | } | |
3705ce5b | 4057 | } |
0a920b5b | 4058 | } |
a3340b35 | 4059 | if ($op eq '*' && $cc =~/\s*$Modifier\b/) { |
171ae1a4 AW |
4060 | # A unary '*' may be const |
4061 | ||
4062 | } elsif ($ctx =~ /.xW/) { | |
3705ce5b JP |
4063 | if (ERROR("SPACING", |
4064 | "space prohibited after that '$op' $at\n" . $hereptr)) { | |
b34c648b | 4065 | $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); |
3705ce5b JP |
4066 | if (defined $fix_elements[$n + 2]) { |
4067 | $fix_elements[$n + 2] =~ s/^\s+//; | |
4068 | } | |
b34c648b | 4069 | $line_fixed = 1; |
3705ce5b | 4070 | } |
0a920b5b AW |
4071 | } |
4072 | ||
4073 | # unary ++ and unary -- are allowed no space on one side. | |
4074 | } elsif ($op eq '++' or $op eq '--') { | |
773647a0 | 4075 | if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { |
3705ce5b JP |
4076 | if (ERROR("SPACING", |
4077 | "space required one side of that '$op' $at\n" . $hereptr)) { | |
b34c648b | 4078 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; |
3705ce5b JP |
4079 | $line_fixed = 1; |
4080 | } | |
773647a0 AW |
4081 | } |
4082 | if ($ctx =~ /Wx[BE]/ || | |
4083 | ($ctx =~ /Wx./ && $cc =~ /^;/)) { | |
3705ce5b JP |
4084 | if (ERROR("SPACING", |
4085 | "space prohibited before that '$op' $at\n" . $hereptr)) { | |
b34c648b | 4086 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
3705ce5b JP |
4087 | $line_fixed = 1; |
4088 | } | |
0a920b5b | 4089 | } |
773647a0 | 4090 | if ($ctx =~ /ExW/) { |
3705ce5b JP |
4091 | if (ERROR("SPACING", |
4092 | "space prohibited after that '$op' $at\n" . $hereptr)) { | |
b34c648b | 4093 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); |
3705ce5b JP |
4094 | if (defined $fix_elements[$n + 2]) { |
4095 | $fix_elements[$n + 2] =~ s/^\s+//; | |
4096 | } | |
b34c648b | 4097 | $line_fixed = 1; |
3705ce5b | 4098 | } |
653d4876 | 4099 | } |
0a920b5b | 4100 | |
0a920b5b | 4101 | # << and >> may either have or not have spaces both sides |
9c0ca6f9 AW |
4102 | } elsif ($op eq '<<' or $op eq '>>' or |
4103 | $op eq '&' or $op eq '^' or $op eq '|' or | |
4104 | $op eq '+' or $op eq '-' or | |
c2fdda0d AW |
4105 | $op eq '*' or $op eq '/' or |
4106 | $op eq '%') | |
0a920b5b | 4107 | { |
d2e025f3 JP |
4108 | if ($check) { |
4109 | if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { | |
4110 | if (CHK("SPACING", | |
4111 | "spaces preferred around that '$op' $at\n" . $hereptr)) { | |
4112 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; | |
4113 | $fix_elements[$n + 2] =~ s/^\s+//; | |
4114 | $line_fixed = 1; | |
4115 | } | |
4116 | } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { | |
4117 | if (CHK("SPACING", | |
4118 | "space preferred before that '$op' $at\n" . $hereptr)) { | |
4119 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); | |
4120 | $line_fixed = 1; | |
4121 | } | |
4122 | } | |
4123 | } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { | |
3705ce5b JP |
4124 | if (ERROR("SPACING", |
4125 | "need consistent spacing around '$op' $at\n" . $hereptr)) { | |
b34c648b JP |
4126 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
4127 | if (defined $fix_elements[$n + 2]) { | |
4128 | $fix_elements[$n + 2] =~ s/^\s+//; | |
4129 | } | |
3705ce5b JP |
4130 | $line_fixed = 1; |
4131 | } | |
0a920b5b AW |
4132 | } |
4133 | ||
1f65f947 AW |
4134 | # A colon needs no spaces before when it is |
4135 | # terminating a case value or a label. | |
4136 | } elsif ($opv eq ':C' || $opv eq ':L') { | |
4137 | if ($ctx =~ /Wx./) { | |
3705ce5b JP |
4138 | if (ERROR("SPACING", |
4139 | "space prohibited before that '$op' $at\n" . $hereptr)) { | |
b34c648b | 4140 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
3705ce5b JP |
4141 | $line_fixed = 1; |
4142 | } | |
1f65f947 AW |
4143 | } |
4144 | ||
0a920b5b | 4145 | # All the others need spaces both sides. |
cf655043 | 4146 | } elsif ($ctx !~ /[EWC]x[CWE]/) { |
1f65f947 AW |
4147 | my $ok = 0; |
4148 | ||
22f2a2ef | 4149 | # Ignore email addresses <foo@bar> |
1f65f947 AW |
4150 | if (($op eq '<' && |
4151 | $cc =~ /^\S+\@\S+>/) || | |
4152 | ($op eq '>' && | |
4153 | $ca =~ /<\S+\@\S+$/)) | |
4154 | { | |
4155 | $ok = 1; | |
4156 | } | |
4157 | ||
e0df7e1f JP |
4158 | # for asm volatile statements |
4159 | # ignore a colon with another | |
4160 | # colon immediately before or after | |
4161 | if (($op eq ':') && | |
4162 | ($ca =~ /:$/ || $cc =~ /^:/)) { | |
4163 | $ok = 1; | |
4164 | } | |
4165 | ||
84731623 | 4166 | # messages are ERROR, but ?: are CHK |
1f65f947 | 4167 | if ($ok == 0) { |
84731623 JP |
4168 | my $msg_type = \&ERROR; |
4169 | $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); | |
4170 | ||
4171 | if (&{$msg_type}("SPACING", | |
4172 | "spaces required around that '$op' $at\n" . $hereptr)) { | |
b34c648b JP |
4173 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
4174 | if (defined $fix_elements[$n + 2]) { | |
4175 | $fix_elements[$n + 2] =~ s/^\s+//; | |
4176 | } | |
3705ce5b JP |
4177 | $line_fixed = 1; |
4178 | } | |
22f2a2ef | 4179 | } |
0a920b5b | 4180 | } |
4a0df2ef | 4181 | $off += length($elements[$n + 1]); |
3705ce5b JP |
4182 | |
4183 | ## print("n: <$n> GOOD: <$good>\n"); | |
4184 | ||
4185 | $fixed_line = $fixed_line . $good; | |
4186 | } | |
4187 | ||
4188 | if (($#elements % 2) == 0) { | |
4189 | $fixed_line = $fixed_line . $fix_elements[$#elements]; | |
0a920b5b | 4190 | } |
3705ce5b | 4191 | |
194f66fc JP |
4192 | if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { |
4193 | $fixed[$fixlinenr] = $fixed_line; | |
3705ce5b JP |
4194 | } |
4195 | ||
4196 | ||
0a920b5b AW |
4197 | } |
4198 | ||
786b6326 | 4199 | # check for whitespace before a non-naked semicolon |
d2e248e7 | 4200 | if ($line =~ /^\+.*\S\s+;\s*$/) { |
786b6326 JP |
4201 | if (WARN("SPACING", |
4202 | "space prohibited before semicolon\n" . $herecurr) && | |
4203 | $fix) { | |
194f66fc | 4204 | 1 while $fixed[$fixlinenr] =~ |
786b6326 JP |
4205 | s/^(\+.*\S)\s+;/$1;/; |
4206 | } | |
4207 | } | |
4208 | ||
f0a594c1 AW |
4209 | # check for multiple assignments |
4210 | if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { | |
000d1cc1 JP |
4211 | CHK("MULTIPLE_ASSIGNMENTS", |
4212 | "multiple assignments should be avoided\n" . $herecurr); | |
f0a594c1 AW |
4213 | } |
4214 | ||
22f2a2ef AW |
4215 | ## # check for multiple declarations, allowing for a function declaration |
4216 | ## # continuation. | |
4217 | ## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && | |
4218 | ## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { | |
4219 | ## | |
4220 | ## # Remove any bracketed sections to ensure we do not | |
4221 | ## # falsly report the parameters of functions. | |
4222 | ## my $ln = $line; | |
4223 | ## while ($ln =~ s/\([^\(\)]*\)//g) { | |
4224 | ## } | |
4225 | ## if ($ln =~ /,/) { | |
000d1cc1 JP |
4226 | ## WARN("MULTIPLE_DECLARATION", |
4227 | ## "declaring multiple variables together should be avoided\n" . $herecurr); | |
22f2a2ef AW |
4228 | ## } |
4229 | ## } | |
f0a594c1 | 4230 | |
0a920b5b | 4231 | #need space before brace following if, while, etc |
6b8c69e4 | 4232 | if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || |
4e5d56bd | 4233 | $line =~ /do\{/) { |
3705ce5b JP |
4234 | if (ERROR("SPACING", |
4235 | "space required before the open brace '{'\n" . $herecurr) && | |
4236 | $fix) { | |
194f66fc | 4237 | $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/; |
3705ce5b | 4238 | } |
de7d4f0e AW |
4239 | } |
4240 | ||
c4a62ef9 JP |
4241 | ## # check for blank lines before declarations |
4242 | ## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && | |
4243 | ## $prevrawline =~ /^.\s*$/) { | |
4244 | ## WARN("SPACING", | |
4245 | ## "No blank lines before declarations\n" . $hereprev); | |
4246 | ## } | |
4247 | ## | |
4248 | ||
de7d4f0e AW |
4249 | # closing brace should have a space following it when it has anything |
4250 | # on the line | |
4251 | if ($line =~ /}(?!(?:,|;|\)))\S/) { | |
d5e616fc JP |
4252 | if (ERROR("SPACING", |
4253 | "space required after that close brace '}'\n" . $herecurr) && | |
4254 | $fix) { | |
194f66fc | 4255 | $fixed[$fixlinenr] =~ |
d5e616fc JP |
4256 | s/}((?!(?:,|;|\)))\S)/} $1/; |
4257 | } | |
0a920b5b AW |
4258 | } |
4259 | ||
22f2a2ef AW |
4260 | # check spacing on square brackets |
4261 | if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { | |
3705ce5b JP |
4262 | if (ERROR("SPACING", |
4263 | "space prohibited after that open square bracket '['\n" . $herecurr) && | |
4264 | $fix) { | |
194f66fc | 4265 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
4266 | s/\[\s+/\[/; |
4267 | } | |
22f2a2ef AW |
4268 | } |
4269 | if ($line =~ /\s\]/) { | |
3705ce5b JP |
4270 | if (ERROR("SPACING", |
4271 | "space prohibited before that close square bracket ']'\n" . $herecurr) && | |
4272 | $fix) { | |
194f66fc | 4273 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
4274 | s/\s+\]/\]/; |
4275 | } | |
22f2a2ef AW |
4276 | } |
4277 | ||
c45dcabd | 4278 | # check spacing on parentheses |
9c0ca6f9 AW |
4279 | if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && |
4280 | $line !~ /for\s*\(\s+;/) { | |
3705ce5b JP |
4281 | if (ERROR("SPACING", |
4282 | "space prohibited after that open parenthesis '('\n" . $herecurr) && | |
4283 | $fix) { | |
194f66fc | 4284 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
4285 | s/\(\s+/\(/; |
4286 | } | |
22f2a2ef | 4287 | } |
13214adf | 4288 | if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && |
c45dcabd AW |
4289 | $line !~ /for\s*\(.*;\s+\)/ && |
4290 | $line !~ /:\s+\)/) { | |
3705ce5b JP |
4291 | if (ERROR("SPACING", |
4292 | "space prohibited before that close parenthesis ')'\n" . $herecurr) && | |
4293 | $fix) { | |
194f66fc | 4294 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
4295 | s/\s+\)/\)/; |
4296 | } | |
22f2a2ef AW |
4297 | } |
4298 | ||
e2826fd0 JP |
4299 | # check unnecessary parentheses around addressof/dereference single $Lvals |
4300 | # ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar | |
4301 | ||
4302 | while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { | |
ea4acbb1 JP |
4303 | my $var = $1; |
4304 | if (CHK("UNNECESSARY_PARENTHESES", | |
4305 | "Unnecessary parentheses around $var\n" . $herecurr) && | |
4306 | $fix) { | |
4307 | $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; | |
4308 | } | |
4309 | } | |
4310 | ||
4311 | # check for unnecessary parentheses around function pointer uses | |
4312 | # ie: (foo->bar)(); should be foo->bar(); | |
4313 | # but not "if (foo->bar) (" to avoid some false positives | |
4314 | if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { | |
4315 | my $var = $2; | |
4316 | if (CHK("UNNECESSARY_PARENTHESES", | |
4317 | "Unnecessary parentheses around function pointer $var\n" . $herecurr) && | |
4318 | $fix) { | |
4319 | my $var2 = deparenthesize($var); | |
4320 | $var2 =~ s/\s//g; | |
4321 | $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; | |
4322 | } | |
4323 | } | |
e2826fd0 | 4324 | |
0a920b5b | 4325 | #goto labels aren't indented, allow a single space however |
4a0df2ef | 4326 | if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and |
0a920b5b | 4327 | !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { |
3705ce5b JP |
4328 | if (WARN("INDENTED_LABEL", |
4329 | "labels should not be indented\n" . $herecurr) && | |
4330 | $fix) { | |
194f66fc | 4331 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
4332 | s/^(.)\s+/$1/; |
4333 | } | |
0a920b5b AW |
4334 | } |
4335 | ||
5b9553ab | 4336 | # return is not a function |
507e5141 | 4337 | if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { |
c45dcabd | 4338 | my $spacing = $1; |
507e5141 | 4339 | if ($^V && $^V ge 5.10.0 && |
5b9553ab JP |
4340 | $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { |
4341 | my $value = $1; | |
4342 | $value = deparenthesize($value); | |
4343 | if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { | |
4344 | ERROR("RETURN_PARENTHESES", | |
4345 | "return is not a function, parentheses are not required\n" . $herecurr); | |
4346 | } | |
c45dcabd | 4347 | } elsif ($spacing !~ /\s+/) { |
000d1cc1 JP |
4348 | ERROR("SPACING", |
4349 | "space required before the open parenthesis '('\n" . $herecurr); | |
c45dcabd AW |
4350 | } |
4351 | } | |
507e5141 | 4352 | |
b43ae21b JP |
4353 | # unnecessary return in a void function |
4354 | # at end-of-function, with the previous line a single leading tab, then return; | |
4355 | # and the line before that not a goto label target like "out:" | |
4356 | if ($sline =~ /^[ \+]}\s*$/ && | |
4357 | $prevline =~ /^\+\treturn\s*;\s*$/ && | |
4358 | $linenr >= 3 && | |
4359 | $lines[$linenr - 3] =~ /^[ +]/ && | |
4360 | $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { | |
9819cf25 | 4361 | WARN("RETURN_VOID", |
b43ae21b JP |
4362 | "void function return statements are not generally useful\n" . $hereprev); |
4363 | } | |
9819cf25 | 4364 | |
189248d8 JP |
4365 | # if statements using unnecessary parentheses - ie: if ((foo == bar)) |
4366 | if ($^V && $^V ge 5.10.0 && | |
4367 | $line =~ /\bif\s*((?:\(\s*){2,})/) { | |
4368 | my $openparens = $1; | |
4369 | my $count = $openparens =~ tr@\(@\(@; | |
4370 | my $msg = ""; | |
4371 | if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { | |
4372 | my $comp = $4; #Not $1 because of $LvalOrFunc | |
4373 | $msg = " - maybe == should be = ?" if ($comp eq "=="); | |
4374 | WARN("UNNECESSARY_PARENTHESES", | |
4375 | "Unnecessary parentheses$msg\n" . $herecurr); | |
4376 | } | |
4377 | } | |
4378 | ||
c5595fa2 JP |
4379 | # comparisons with a constant or upper case identifier on the left |
4380 | # avoid cases like "foo + BAR < baz" | |
4381 | # only fix matches surrounded by parentheses to avoid incorrect | |
4382 | # conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" | |
4383 | if ($^V && $^V ge 5.10.0 && | |
4384 | $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { | |
4385 | my $lead = $1; | |
4386 | my $const = $2; | |
4387 | my $comp = $3; | |
4388 | my $to = $4; | |
4389 | my $newcomp = $comp; | |
f39e1769 | 4390 | if ($lead !~ /(?:$Operators|\.)\s*$/ && |
c5595fa2 JP |
4391 | $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && |
4392 | WARN("CONSTANT_COMPARISON", | |
4393 | "Comparisons should place the constant on the right side of the test\n" . $herecurr) && | |
4394 | $fix) { | |
4395 | if ($comp eq "<") { | |
4396 | $newcomp = ">"; | |
4397 | } elsif ($comp eq "<=") { | |
4398 | $newcomp = ">="; | |
4399 | } elsif ($comp eq ">") { | |
4400 | $newcomp = "<"; | |
4401 | } elsif ($comp eq ">=") { | |
4402 | $newcomp = "<="; | |
4403 | } | |
4404 | $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; | |
4405 | } | |
4406 | } | |
4407 | ||
f34e4a4f JP |
4408 | # Return of what appears to be an errno should normally be negative |
4409 | if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { | |
53a3c448 AW |
4410 | my $name = $1; |
4411 | if ($name ne 'EOF' && $name ne 'ERROR') { | |
000d1cc1 | 4412 | WARN("USE_NEGATIVE_ERRNO", |
f34e4a4f | 4413 | "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); |
53a3c448 AW |
4414 | } |
4415 | } | |
c45dcabd | 4416 | |
0a920b5b | 4417 | # Need a space before open parenthesis after if, while etc |
3705ce5b JP |
4418 | if ($line =~ /\b(if|while|for|switch)\(/) { |
4419 | if (ERROR("SPACING", | |
4420 | "space required before the open parenthesis '('\n" . $herecurr) && | |
4421 | $fix) { | |
194f66fc | 4422 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
4423 | s/\b(if|while|for|switch)\(/$1 \(/; |
4424 | } | |
0a920b5b AW |
4425 | } |
4426 | ||
f5fe35dd AW |
4427 | # Check for illegal assignment in if conditional -- and check for trailing |
4428 | # statements after the conditional. | |
170d3a22 | 4429 | if ($line =~ /do\s*(?!{)/) { |
3e469cdc AW |
4430 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
4431 | ctx_statement_block($linenr, $realcnt, 0) | |
4432 | if (!defined $stat); | |
170d3a22 AW |
4433 | my ($stat_next) = ctx_statement_block($line_nr_next, |
4434 | $remain_next, $off_next); | |
4435 | $stat_next =~ s/\n./\n /g; | |
4436 | ##print "stat<$stat> stat_next<$stat_next>\n"; | |
4437 | ||
4438 | if ($stat_next =~ /^\s*while\b/) { | |
4439 | # If the statement carries leading newlines, | |
4440 | # then count those as offsets. | |
4441 | my ($whitespace) = | |
4442 | ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); | |
4443 | my $offset = | |
4444 | statement_rawlines($whitespace) - 1; | |
4445 | ||
4446 | $suppress_whiletrailers{$line_nr_next + | |
4447 | $offset} = 1; | |
4448 | } | |
4449 | } | |
4450 | if (!defined $suppress_whiletrailers{$linenr} && | |
c11230f4 | 4451 | defined($stat) && defined($cond) && |
170d3a22 | 4452 | $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { |
171ae1a4 | 4453 | my ($s, $c) = ($stat, $cond); |
8905a67c | 4454 | |
b53c8e10 | 4455 | if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { |
000d1cc1 JP |
4456 | ERROR("ASSIGN_IN_IF", |
4457 | "do not use assignment in if condition\n" . $herecurr); | |
8905a67c AW |
4458 | } |
4459 | ||
4460 | # Find out what is on the end of the line after the | |
4461 | # conditional. | |
773647a0 | 4462 | substr($s, 0, length($c), ''); |
8905a67c | 4463 | $s =~ s/\n.*//g; |
13214adf | 4464 | $s =~ s/$;//g; # Remove any comments |
53210168 AW |
4465 | if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && |
4466 | $c !~ /}\s*while\s*/) | |
773647a0 | 4467 | { |
bb44ad39 AW |
4468 | # Find out how long the conditional actually is. |
4469 | my @newlines = ($c =~ /\n/gs); | |
4470 | my $cond_lines = 1 + $#newlines; | |
42bdf74c | 4471 | my $stat_real = ''; |
bb44ad39 | 4472 | |
42bdf74c HS |
4473 | $stat_real = raw_line($linenr, $cond_lines) |
4474 | . "\n" if ($cond_lines); | |
bb44ad39 AW |
4475 | if (defined($stat_real) && $cond_lines > 1) { |
4476 | $stat_real = "[...]\n$stat_real"; | |
4477 | } | |
4478 | ||
000d1cc1 JP |
4479 | ERROR("TRAILING_STATEMENTS", |
4480 | "trailing statements should be on next line\n" . $herecurr . $stat_real); | |
8905a67c AW |
4481 | } |
4482 | } | |
4483 | ||
13214adf AW |
4484 | # Check for bitwise tests written as boolean |
4485 | if ($line =~ / | |
4486 | (?: | |
4487 | (?:\[|\(|\&\&|\|\|) | |
4488 | \s*0[xX][0-9]+\s* | |
4489 | (?:\&\&|\|\|) | |
4490 | | | |
4491 | (?:\&\&|\|\|) | |
4492 | \s*0[xX][0-9]+\s* | |
4493 | (?:\&\&|\|\||\)|\]) | |
4494 | )/x) | |
4495 | { | |
000d1cc1 JP |
4496 | WARN("HEXADECIMAL_BOOLEAN_TEST", |
4497 | "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); | |
13214adf AW |
4498 | } |
4499 | ||
8905a67c | 4500 | # if and else should not have general statements after it |
13214adf AW |
4501 | if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { |
4502 | my $s = $1; | |
4503 | $s =~ s/$;//g; # Remove any comments | |
4504 | if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { | |
000d1cc1 JP |
4505 | ERROR("TRAILING_STATEMENTS", |
4506 | "trailing statements should be on next line\n" . $herecurr); | |
13214adf | 4507 | } |
0a920b5b | 4508 | } |
39667782 AW |
4509 | # if should not continue a brace |
4510 | if ($line =~ /}\s*if\b/) { | |
000d1cc1 | 4511 | ERROR("TRAILING_STATEMENTS", |
048b123f | 4512 | "trailing statements should be on next line (or did you mean 'else if'?)\n" . |
39667782 AW |
4513 | $herecurr); |
4514 | } | |
a1080bf8 AW |
4515 | # case and default should not have general statements after them |
4516 | if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && | |
4517 | $line !~ /\G(?: | |
3fef12d6 | 4518 | (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| |
a1080bf8 AW |
4519 | \s*return\s+ |
4520 | )/xg) | |
4521 | { | |
000d1cc1 JP |
4522 | ERROR("TRAILING_STATEMENTS", |
4523 | "trailing statements should be on next line\n" . $herecurr); | |
a1080bf8 | 4524 | } |
0a920b5b AW |
4525 | |
4526 | # Check for }<nl>else {, these must be at the same | |
4527 | # indent level to be relevant to each other. | |
8b8856f4 JP |
4528 | if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && |
4529 | $previndent == $indent) { | |
4530 | if (ERROR("ELSE_AFTER_BRACE", | |
4531 | "else should follow close brace '}'\n" . $hereprev) && | |
4532 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { | |
4533 | fix_delete_line($fixlinenr - 1, $prevrawline); | |
4534 | fix_delete_line($fixlinenr, $rawline); | |
4535 | my $fixedline = $prevrawline; | |
4536 | $fixedline =~ s/}\s*$//; | |
4537 | if ($fixedline !~ /^\+\s*$/) { | |
4538 | fix_insert_line($fixlinenr, $fixedline); | |
4539 | } | |
4540 | $fixedline = $rawline; | |
4541 | $fixedline =~ s/^(.\s*)else/$1} else/; | |
4542 | fix_insert_line($fixlinenr, $fixedline); | |
4543 | } | |
0a920b5b AW |
4544 | } |
4545 | ||
8b8856f4 JP |
4546 | if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && |
4547 | $previndent == $indent) { | |
c2fdda0d AW |
4548 | my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); |
4549 | ||
4550 | # Find out what is on the end of the line after the | |
4551 | # conditional. | |
773647a0 | 4552 | substr($s, 0, length($c), ''); |
c2fdda0d AW |
4553 | $s =~ s/\n.*//g; |
4554 | ||
4555 | if ($s =~ /^\s*;/) { | |
8b8856f4 JP |
4556 | if (ERROR("WHILE_AFTER_BRACE", |
4557 | "while should follow close brace '}'\n" . $hereprev) && | |
4558 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { | |
4559 | fix_delete_line($fixlinenr - 1, $prevrawline); | |
4560 | fix_delete_line($fixlinenr, $rawline); | |
4561 | my $fixedline = $prevrawline; | |
4562 | my $trailing = $rawline; | |
4563 | $trailing =~ s/^\+//; | |
4564 | $trailing = trim($trailing); | |
4565 | $fixedline =~ s/}\s*$/} $trailing/; | |
4566 | fix_insert_line($fixlinenr, $fixedline); | |
4567 | } | |
c2fdda0d AW |
4568 | } |
4569 | } | |
4570 | ||
95e2c602 | 4571 | #Specific variable tests |
323c1260 JP |
4572 | while ($line =~ m{($Constant|$Lval)}g) { |
4573 | my $var = $1; | |
95e2c602 JP |
4574 | |
4575 | #gcc binary extension | |
4576 | if ($var =~ /^$Binary$/) { | |
d5e616fc JP |
4577 | if (WARN("GCC_BINARY_CONSTANT", |
4578 | "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && | |
4579 | $fix) { | |
4580 | my $hexval = sprintf("0x%x", oct($var)); | |
194f66fc | 4581 | $fixed[$fixlinenr] =~ |
d5e616fc JP |
4582 | s/\b$var\b/$hexval/; |
4583 | } | |
95e2c602 JP |
4584 | } |
4585 | ||
4586 | #CamelCase | |
807bd26c | 4587 | if ($var !~ /^$Constant$/ && |
be79794b | 4588 | $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && |
22735ce8 | 4589 | #Ignore Page<foo> variants |
807bd26c | 4590 | $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && |
22735ce8 | 4591 | #Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) |
f5123576 JW |
4592 | $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && |
4593 | #Ignore some three character SI units explicitly, like MiB and KHz | |
4594 | $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { | |
7e781f67 JP |
4595 | while ($var =~ m{($Ident)}g) { |
4596 | my $word = $1; | |
4597 | next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); | |
d8b07710 JP |
4598 | if ($check) { |
4599 | seed_camelcase_includes(); | |
4600 | if (!$file && !$camelcase_file_seeded) { | |
4601 | seed_camelcase_file($realfile); | |
4602 | $camelcase_file_seeded = 1; | |
4603 | } | |
4604 | } | |
7e781f67 JP |
4605 | if (!defined $camelcase{$word}) { |
4606 | $camelcase{$word} = 1; | |
4607 | CHK("CAMELCASE", | |
4608 | "Avoid CamelCase: <$word>\n" . $herecurr); | |
4609 | } | |
3445686a | 4610 | } |
323c1260 JP |
4611 | } |
4612 | } | |
0a920b5b AW |
4613 | |
4614 | #no spaces allowed after \ in define | |
d5e616fc JP |
4615 | if ($line =~ /\#\s*define.*\\\s+$/) { |
4616 | if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", | |
4617 | "Whitespace after \\ makes next lines useless\n" . $herecurr) && | |
4618 | $fix) { | |
194f66fc | 4619 | $fixed[$fixlinenr] =~ s/\s+$//; |
d5e616fc | 4620 | } |
0a920b5b AW |
4621 | } |
4622 | ||
0e212e0a FF |
4623 | # warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes |
4624 | # itself <asm/foo.h> (uses RAW line) | |
c45dcabd | 4625 | if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { |
e09dec48 AW |
4626 | my $file = "$1.h"; |
4627 | my $checkfile = "include/linux/$file"; | |
4628 | if (-f "$root/$checkfile" && | |
4629 | $realfile ne $checkfile && | |
7840a94c | 4630 | $1 !~ /$allowed_asm_includes/) |
c45dcabd | 4631 | { |
0e212e0a FF |
4632 | my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; |
4633 | if ($asminclude > 0) { | |
4634 | if ($realfile =~ m{^arch/}) { | |
4635 | CHK("ARCH_INCLUDE_LINUX", | |
4636 | "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); | |
4637 | } else { | |
4638 | WARN("INCLUDE_LINUX", | |
4639 | "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); | |
4640 | } | |
e09dec48 | 4641 | } |
0a920b5b AW |
4642 | } |
4643 | } | |
4644 | ||
653d4876 AW |
4645 | # multi-statement macros should be enclosed in a do while loop, grab the |
4646 | # first statement and ensure its the whole macro if its not enclosed | |
cf655043 | 4647 | # in a known good container |
b8f96a31 AW |
4648 | if ($realfile !~ m@/vmlinux.lds.h$@ && |
4649 | $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { | |
d8aaf121 AW |
4650 | my $ln = $linenr; |
4651 | my $cnt = $realcnt; | |
c45dcabd AW |
4652 | my ($off, $dstat, $dcond, $rest); |
4653 | my $ctx = ''; | |
08a2843e JP |
4654 | my $has_flow_statement = 0; |
4655 | my $has_arg_concat = 0; | |
c45dcabd | 4656 | ($dstat, $dcond, $ln, $cnt, $off) = |
f74bd194 AW |
4657 | ctx_statement_block($linenr, $realcnt, 0); |
4658 | $ctx = $dstat; | |
c45dcabd | 4659 | #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; |
a3bb97a7 | 4660 | #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; |
c45dcabd | 4661 | |
08a2843e | 4662 | $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); |
62e15a6d | 4663 | $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); |
08a2843e | 4664 | |
f74bd194 | 4665 | $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; |
292f1a9b | 4666 | $dstat =~ s/$;//g; |
c45dcabd AW |
4667 | $dstat =~ s/\\\n.//g; |
4668 | $dstat =~ s/^\s*//s; | |
4669 | $dstat =~ s/\s*$//s; | |
de7d4f0e | 4670 | |
c45dcabd | 4671 | # Flatten any parentheses and braces |
bf30d6ed AW |
4672 | while ($dstat =~ s/\([^\(\)]*\)/1/ || |
4673 | $dstat =~ s/\{[^\{\}]*\}/1/ || | |
6b10df42 | 4674 | $dstat =~ s/.\[[^\[\]]*\]/1/) |
bf30d6ed | 4675 | { |
de7d4f0e | 4676 | } |
d8aaf121 | 4677 | |
e45bab8e | 4678 | # Flatten any obvious string concatentation. |
33acb54a JP |
4679 | while ($dstat =~ s/($String)\s*$Ident/$1/ || |
4680 | $dstat =~ s/$Ident\s*($String)/$1/) | |
e45bab8e AW |
4681 | { |
4682 | } | |
4683 | ||
42e15293 JP |
4684 | # Make asm volatile uses seem like a generic function |
4685 | $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; | |
4686 | ||
c45dcabd AW |
4687 | my $exceptions = qr{ |
4688 | $Declare| | |
4689 | module_param_named| | |
a0a0a7a9 | 4690 | MODULE_PARM_DESC| |
c45dcabd AW |
4691 | DECLARE_PER_CPU| |
4692 | DEFINE_PER_CPU| | |
383099fd | 4693 | __typeof__\(| |
22fd2d3e SS |
4694 | union| |
4695 | struct| | |
ea71a0a0 | 4696 | \.$Ident\s*=\s*| |
6b10df42 VZ |
4697 | ^\"|\"$| |
4698 | ^\[ | |
c45dcabd | 4699 | }x; |
5eaa20b9 | 4700 | #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; |
f74bd194 AW |
4701 | if ($dstat ne '' && |
4702 | $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), | |
4703 | $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); | |
3cc4b1c3 | 4704 | $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz |
356fd398 | 4705 | $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants |
f74bd194 AW |
4706 | $dstat !~ /$exceptions/ && |
4707 | $dstat !~ /^\.$Ident\s*=/ && # .foo = | |
e942e2c3 | 4708 | $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo |
72f115f9 | 4709 | $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) |
f74bd194 AW |
4710 | $dstat !~ /^for\s*$Constant$/ && # for (...) |
4711 | $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() | |
4712 | $dstat !~ /^do\s*{/ && # do {... | |
4e5d56bd | 4713 | $dstat !~ /^\(\{/ && # ({... |
f95a7e6a | 4714 | $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) |
f74bd194 AW |
4715 | { |
4716 | $ctx =~ s/\n*$//; | |
4717 | my $herectx = $here . "\n"; | |
4718 | my $cnt = statement_rawlines($ctx); | |
4719 | ||
4720 | for (my $n = 0; $n < $cnt; $n++) { | |
4721 | $herectx .= raw_line($linenr, $n) . "\n"; | |
c45dcabd AW |
4722 | } |
4723 | ||
f74bd194 AW |
4724 | if ($dstat =~ /;/) { |
4725 | ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", | |
4726 | "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); | |
4727 | } else { | |
000d1cc1 | 4728 | ERROR("COMPLEX_MACRO", |
388982b5 | 4729 | "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); |
d8aaf121 | 4730 | } |
653d4876 | 4731 | } |
5023d347 | 4732 | |
08a2843e JP |
4733 | # check for macros with flow control, but without ## concatenation |
4734 | # ## concatenation is commonly a macro that defines a function so ignore those | |
4735 | if ($has_flow_statement && !$has_arg_concat) { | |
4736 | my $herectx = $here . "\n"; | |
4737 | my $cnt = statement_rawlines($ctx); | |
4738 | ||
4739 | for (my $n = 0; $n < $cnt; $n++) { | |
4740 | $herectx .= raw_line($linenr, $n) . "\n"; | |
4741 | } | |
4742 | WARN("MACRO_WITH_FLOW_CONTROL", | |
4743 | "Macros with flow control statements should be avoided\n" . "$herectx"); | |
4744 | } | |
4745 | ||
481eb486 | 4746 | # check for line continuations outside of #defines, preprocessor #, and asm |
5023d347 JP |
4747 | |
4748 | } else { | |
4749 | if ($prevline !~ /^..*\\$/ && | |
481eb486 JP |
4750 | $line !~ /^\+\s*\#.*\\$/ && # preprocessor |
4751 | $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm | |
5023d347 JP |
4752 | $line =~ /^\+.*\\$/) { |
4753 | WARN("LINE_CONTINUATIONS", | |
4754 | "Avoid unnecessary line continuations\n" . $herecurr); | |
4755 | } | |
0a920b5b AW |
4756 | } |
4757 | ||
b13edf7f JP |
4758 | # do {} while (0) macro tests: |
4759 | # single-statement macros do not need to be enclosed in do while (0) loop, | |
4760 | # macro should not end with a semicolon | |
4761 | if ($^V && $^V ge 5.10.0 && | |
4762 | $realfile !~ m@/vmlinux.lds.h$@ && | |
4763 | $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { | |
4764 | my $ln = $linenr; | |
4765 | my $cnt = $realcnt; | |
4766 | my ($off, $dstat, $dcond, $rest); | |
4767 | my $ctx = ''; | |
4768 | ($dstat, $dcond, $ln, $cnt, $off) = | |
4769 | ctx_statement_block($linenr, $realcnt, 0); | |
4770 | $ctx = $dstat; | |
4771 | ||
4772 | $dstat =~ s/\\\n.//g; | |
1b36b201 | 4773 | $dstat =~ s/$;/ /g; |
b13edf7f JP |
4774 | |
4775 | if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { | |
4776 | my $stmts = $2; | |
4777 | my $semis = $3; | |
4778 | ||
4779 | $ctx =~ s/\n*$//; | |
4780 | my $cnt = statement_rawlines($ctx); | |
4781 | my $herectx = $here . "\n"; | |
4782 | ||
4783 | for (my $n = 0; $n < $cnt; $n++) { | |
4784 | $herectx .= raw_line($linenr, $n) . "\n"; | |
4785 | } | |
4786 | ||
ac8e97f8 JP |
4787 | if (($stmts =~ tr/;/;/) == 1 && |
4788 | $stmts !~ /^\s*(if|while|for|switch)\b/) { | |
b13edf7f JP |
4789 | WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", |
4790 | "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); | |
4791 | } | |
4792 | if (defined $semis && $semis ne "") { | |
4793 | WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", | |
4794 | "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); | |
4795 | } | |
f5ef95b1 JP |
4796 | } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { |
4797 | $ctx =~ s/\n*$//; | |
4798 | my $cnt = statement_rawlines($ctx); | |
4799 | my $herectx = $here . "\n"; | |
4800 | ||
4801 | for (my $n = 0; $n < $cnt; $n++) { | |
4802 | $herectx .= raw_line($linenr, $n) . "\n"; | |
4803 | } | |
4804 | ||
4805 | WARN("TRAILING_SEMICOLON", | |
4806 | "macros should not use a trailing semicolon\n" . "$herectx"); | |
b13edf7f JP |
4807 | } |
4808 | } | |
4809 | ||
080ba929 MF |
4810 | # make sure symbols are always wrapped with VMLINUX_SYMBOL() ... |
4811 | # all assignments may have only one of the following with an assignment: | |
4812 | # . | |
4813 | # ALIGN(...) | |
4814 | # VMLINUX_SYMBOL(...) | |
4815 | if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { | |
000d1cc1 JP |
4816 | WARN("MISSING_VMLINUX_SYMBOL", |
4817 | "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); | |
080ba929 MF |
4818 | } |
4819 | ||
f0a594c1 | 4820 | # check for redundant bracing round if etc |
13214adf AW |
4821 | if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { |
4822 | my ($level, $endln, @chunks) = | |
cf655043 | 4823 | ctx_statement_full($linenr, $realcnt, 1); |
13214adf | 4824 | #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; |
cf655043 AW |
4825 | #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; |
4826 | if ($#chunks > 0 && $level == 0) { | |
aad4f614 JP |
4827 | my @allowed = (); |
4828 | my $allow = 0; | |
13214adf | 4829 | my $seen = 0; |
773647a0 | 4830 | my $herectx = $here . "\n"; |
cf655043 | 4831 | my $ln = $linenr - 1; |
13214adf AW |
4832 | for my $chunk (@chunks) { |
4833 | my ($cond, $block) = @{$chunk}; | |
4834 | ||
773647a0 AW |
4835 | # If the condition carries leading newlines, then count those as offsets. |
4836 | my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); | |
4837 | my $offset = statement_rawlines($whitespace) - 1; | |
4838 | ||
aad4f614 | 4839 | $allowed[$allow] = 0; |
773647a0 AW |
4840 | #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; |
4841 | ||
4842 | # We have looked at and allowed this specific line. | |
4843 | $suppress_ifbraces{$ln + $offset} = 1; | |
4844 | ||
4845 | $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; | |
cf655043 AW |
4846 | $ln += statement_rawlines($block) - 1; |
4847 | ||
773647a0 | 4848 | substr($block, 0, length($cond), ''); |
13214adf AW |
4849 | |
4850 | $seen++ if ($block =~ /^\s*{/); | |
4851 | ||
aad4f614 | 4852 | #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; |
cf655043 AW |
4853 | if (statement_lines($cond) > 1) { |
4854 | #print "APW: ALLOWED: cond<$cond>\n"; | |
aad4f614 | 4855 | $allowed[$allow] = 1; |
13214adf AW |
4856 | } |
4857 | if ($block =~/\b(?:if|for|while)\b/) { | |
cf655043 | 4858 | #print "APW: ALLOWED: block<$block>\n"; |
aad4f614 | 4859 | $allowed[$allow] = 1; |
13214adf | 4860 | } |
cf655043 AW |
4861 | if (statement_block_size($block) > 1) { |
4862 | #print "APW: ALLOWED: lines block<$block>\n"; | |
aad4f614 | 4863 | $allowed[$allow] = 1; |
13214adf | 4864 | } |
aad4f614 | 4865 | $allow++; |
13214adf | 4866 | } |
aad4f614 JP |
4867 | if ($seen) { |
4868 | my $sum_allowed = 0; | |
4869 | foreach (@allowed) { | |
4870 | $sum_allowed += $_; | |
4871 | } | |
4872 | if ($sum_allowed == 0) { | |
4873 | WARN("BRACES", | |
4874 | "braces {} are not necessary for any arm of this statement\n" . $herectx); | |
4875 | } elsif ($sum_allowed != $allow && | |
4876 | $seen != $allow) { | |
4877 | CHK("BRACES", | |
4878 | "braces {} should be used on all arms of this statement\n" . $herectx); | |
4879 | } | |
13214adf AW |
4880 | } |
4881 | } | |
4882 | } | |
773647a0 | 4883 | if (!defined $suppress_ifbraces{$linenr - 1} && |
13214adf | 4884 | $line =~ /\b(if|while|for|else)\b/) { |
cf655043 AW |
4885 | my $allowed = 0; |
4886 | ||
4887 | # Check the pre-context. | |
4888 | if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { | |
4889 | #print "APW: ALLOWED: pre<$1>\n"; | |
4890 | $allowed = 1; | |
4891 | } | |
773647a0 AW |
4892 | |
4893 | my ($level, $endln, @chunks) = | |
4894 | ctx_statement_full($linenr, $realcnt, $-[0]); | |
4895 | ||
cf655043 AW |
4896 | # Check the condition. |
4897 | my ($cond, $block) = @{$chunks[0]}; | |
773647a0 | 4898 | #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; |
cf655043 | 4899 | if (defined $cond) { |
773647a0 | 4900 | substr($block, 0, length($cond), ''); |
cf655043 AW |
4901 | } |
4902 | if (statement_lines($cond) > 1) { | |
4903 | #print "APW: ALLOWED: cond<$cond>\n"; | |
4904 | $allowed = 1; | |
4905 | } | |
4906 | if ($block =~/\b(?:if|for|while)\b/) { | |
4907 | #print "APW: ALLOWED: block<$block>\n"; | |
4908 | $allowed = 1; | |
4909 | } | |
4910 | if (statement_block_size($block) > 1) { | |
4911 | #print "APW: ALLOWED: lines block<$block>\n"; | |
4912 | $allowed = 1; | |
4913 | } | |
4914 | # Check the post-context. | |
4915 | if (defined $chunks[1]) { | |
4916 | my ($cond, $block) = @{$chunks[1]}; | |
4917 | if (defined $cond) { | |
773647a0 | 4918 | substr($block, 0, length($cond), ''); |
cf655043 AW |
4919 | } |
4920 | if ($block =~ /^\s*\{/) { | |
4921 | #print "APW: ALLOWED: chunk-1 block<$block>\n"; | |
4922 | $allowed = 1; | |
4923 | } | |
4924 | } | |
4925 | if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { | |
69932487 | 4926 | my $herectx = $here . "\n"; |
f055663c | 4927 | my $cnt = statement_rawlines($block); |
cf655043 | 4928 | |
f055663c | 4929 | for (my $n = 0; $n < $cnt; $n++) { |
69932487 | 4930 | $herectx .= raw_line($linenr, $n) . "\n"; |
f0a594c1 | 4931 | } |
cf655043 | 4932 | |
000d1cc1 JP |
4933 | WARN("BRACES", |
4934 | "braces {} are not necessary for single statement blocks\n" . $herectx); | |
f0a594c1 AW |
4935 | } |
4936 | } | |
4937 | ||
0979ae66 | 4938 | # check for unnecessary blank lines around braces |
77b9a53a | 4939 | if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { |
f8e58219 JP |
4940 | if (CHK("BRACES", |
4941 | "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && | |
4942 | $fix && $prevrawline =~ /^\+/) { | |
4943 | fix_delete_line($fixlinenr - 1, $prevrawline); | |
4944 | } | |
0979ae66 | 4945 | } |
77b9a53a | 4946 | if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { |
f8e58219 JP |
4947 | if (CHK("BRACES", |
4948 | "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && | |
4949 | $fix) { | |
4950 | fix_delete_line($fixlinenr, $rawline); | |
4951 | } | |
0979ae66 JP |
4952 | } |
4953 | ||
4a0df2ef | 4954 | # no volatiles please |
6c72ffaa AW |
4955 | my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; |
4956 | if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { | |
000d1cc1 JP |
4957 | WARN("VOLATILE", |
4958 | "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); | |
4a0df2ef AW |
4959 | } |
4960 | ||
5e4f6ba5 JP |
4961 | # Check for user-visible strings broken across lines, which breaks the ability |
4962 | # to grep for the string. Make exceptions when the previous string ends in a | |
4963 | # newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' | |
4964 | # (common in inline assembly) or is a octal \123 or hexadecimal \xaf value | |
33acb54a | 4965 | if ($line =~ /^\+\s*$String/ && |
5e4f6ba5 JP |
4966 | $prevline =~ /"\s*$/ && |
4967 | $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { | |
4968 | if (WARN("SPLIT_STRING", | |
4969 | "quoted string split across lines\n" . $hereprev) && | |
4970 | $fix && | |
4971 | $prevrawline =~ /^\+.*"\s*$/ && | |
4972 | $last_coalesced_string_linenr != $linenr - 1) { | |
4973 | my $extracted_string = get_quoted_string($line, $rawline); | |
4974 | my $comma_close = ""; | |
4975 | if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { | |
4976 | $comma_close = $1; | |
4977 | } | |
4978 | ||
4979 | fix_delete_line($fixlinenr - 1, $prevrawline); | |
4980 | fix_delete_line($fixlinenr, $rawline); | |
4981 | my $fixedline = $prevrawline; | |
4982 | $fixedline =~ s/"\s*$//; | |
4983 | $fixedline .= substr($extracted_string, 1) . trim($comma_close); | |
4984 | fix_insert_line($fixlinenr - 1, $fixedline); | |
4985 | $fixedline = $rawline; | |
4986 | $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; | |
4987 | if ($fixedline !~ /\+\s*$/) { | |
4988 | fix_insert_line($fixlinenr, $fixedline); | |
4989 | } | |
4990 | $last_coalesced_string_linenr = $linenr; | |
4991 | } | |
4992 | } | |
4993 | ||
4994 | # check for missing a space in a string concatenation | |
4995 | if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { | |
4996 | WARN('MISSING_SPACE', | |
4997 | "break quoted strings at a space character\n" . $hereprev); | |
4998 | } | |
4999 | ||
5000 | # check for spaces before a quoted newline | |
5001 | if ($rawline =~ /^.*\".*\s\\n/) { | |
5002 | if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", | |
5003 | "unnecessary whitespace before a quoted newline\n" . $herecurr) && | |
5004 | $fix) { | |
5005 | $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; | |
5006 | } | |
5007 | ||
5008 | } | |
5009 | ||
f17dba4f | 5010 | # concatenated string without spaces between elements |
33acb54a | 5011 | if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { |
f17dba4f JP |
5012 | CHK("CONCATENATED_STRING", |
5013 | "Concatenated strings should use spaces between elements\n" . $herecurr); | |
5014 | } | |
5015 | ||
90ad30e5 | 5016 | # uncoalesced string fragments |
33acb54a | 5017 | if ($line =~ /$String\s*"/) { |
90ad30e5 JP |
5018 | WARN("STRING_FRAGMENTS", |
5019 | "Consecutive strings are generally better as a single string\n" . $herecurr); | |
5020 | } | |
5021 | ||
6e300757 | 5022 | # check for %L{u,d,i} and 0x%[udi] in strings |
5e4f6ba5 JP |
5023 | my $string; |
5024 | while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { | |
5025 | $string = substr($rawline, $-[1], $+[1] - $-[1]); | |
5026 | $string =~ s/%%/__/g; | |
6e300757 | 5027 | if ($string =~ /(?<!%)%[\*\d\.\$]*L[udi]/) { |
5e4f6ba5 JP |
5028 | WARN("PRINTF_L", |
5029 | "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); | |
5030 | last; | |
5031 | } | |
6e300757 JP |
5032 | if ($string =~ /0x%[\*\d\.\$\Llzth]*[udi]/) { |
5033 | ERROR("PRINTF_0xDECIMAL", | |
5034 | "Prefixing 0x with decimal output is defective\n" . $herecurr); | |
5035 | } | |
5e4f6ba5 JP |
5036 | } |
5037 | ||
5038 | # check for line continuations in quoted strings with odd counts of " | |
5039 | if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { | |
5040 | WARN("LINE_CONTINUATIONS", | |
5041 | "Avoid line continuations in quoted strings\n" . $herecurr); | |
5042 | } | |
5043 | ||
00df344f | 5044 | # warn about #if 0 |
c45dcabd | 5045 | if ($line =~ /^.\s*\#\s*if\s+0\b/) { |
000d1cc1 JP |
5046 | CHK("REDUNDANT_CODE", |
5047 | "if this code is redundant consider removing it\n" . | |
de7d4f0e | 5048 | $herecurr); |
4a0df2ef AW |
5049 | } |
5050 | ||
03df4b51 AW |
5051 | # check for needless "if (<foo>) fn(<foo>)" uses |
5052 | if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { | |
100425de JP |
5053 | my $tested = quotemeta($1); |
5054 | my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; | |
5055 | if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { | |
5056 | my $func = $1; | |
5057 | if (WARN('NEEDLESS_IF', | |
5058 | "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && | |
5059 | $fix) { | |
5060 | my $do_fix = 1; | |
5061 | my $leading_tabs = ""; | |
5062 | my $new_leading_tabs = ""; | |
5063 | if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { | |
5064 | $leading_tabs = $1; | |
5065 | } else { | |
5066 | $do_fix = 0; | |
5067 | } | |
5068 | if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { | |
5069 | $new_leading_tabs = $1; | |
5070 | if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { | |
5071 | $do_fix = 0; | |
5072 | } | |
5073 | } else { | |
5074 | $do_fix = 0; | |
5075 | } | |
5076 | if ($do_fix) { | |
5077 | fix_delete_line($fixlinenr - 1, $prevrawline); | |
5078 | $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; | |
5079 | } | |
5080 | } | |
4c432a8f GKH |
5081 | } |
5082 | } | |
f0a594c1 | 5083 | |
ebfdc409 JP |
5084 | # check for unnecessary "Out of Memory" messages |
5085 | if ($line =~ /^\+.*\b$logFunctions\s*\(/ && | |
5086 | $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && | |
5087 | (defined $1 || defined $3) && | |
5088 | $linenr > 3) { | |
5089 | my $testval = $2; | |
5090 | my $testline = $lines[$linenr - 3]; | |
5091 | ||
5092 | my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); | |
5093 | # print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); | |
5094 | ||
5095 | if ($c =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|(?:dev_)?alloc_skb)/) { | |
5096 | WARN("OOM_MESSAGE", | |
5097 | "Possible unnecessary 'out of memory' message\n" . $hereprev); | |
5098 | } | |
5099 | } | |
5100 | ||
f78d98f6 | 5101 | # check for logging functions with KERN_<LEVEL> |
dcaf1123 | 5102 | if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && |
f78d98f6 JP |
5103 | $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { |
5104 | my $level = $1; | |
5105 | if (WARN("UNNECESSARY_KERN_LEVEL", | |
5106 | "Possible unnecessary $level\n" . $herecurr) && | |
5107 | $fix) { | |
5108 | $fixed[$fixlinenr] =~ s/\s*$level\s*//; | |
5109 | } | |
5110 | } | |
5111 | ||
abb08a53 JP |
5112 | # check for mask then right shift without a parentheses |
5113 | if ($^V && $^V ge 5.10.0 && | |
5114 | $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && | |
5115 | $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so | |
5116 | WARN("MASK_THEN_SHIFT", | |
5117 | "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); | |
5118 | } | |
5119 | ||
b75ac618 JP |
5120 | # check for pointer comparisons to NULL |
5121 | if ($^V && $^V ge 5.10.0) { | |
5122 | while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { | |
5123 | my $val = $1; | |
5124 | my $equal = "!"; | |
5125 | $equal = "" if ($4 eq "!="); | |
5126 | if (CHK("COMPARISON_TO_NULL", | |
5127 | "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && | |
5128 | $fix) { | |
5129 | $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; | |
5130 | } | |
5131 | } | |
5132 | } | |
5133 | ||
8716de38 JP |
5134 | # check for bad placement of section $InitAttribute (e.g.: __initdata) |
5135 | if ($line =~ /(\b$InitAttribute\b)/) { | |
5136 | my $attr = $1; | |
5137 | if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { | |
5138 | my $ptr = $1; | |
5139 | my $var = $2; | |
5140 | if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && | |
5141 | ERROR("MISPLACED_INIT", | |
5142 | "$attr should be placed after $var\n" . $herecurr)) || | |
5143 | ($ptr !~ /\b(union|struct)\s+$attr\b/ && | |
5144 | WARN("MISPLACED_INIT", | |
5145 | "$attr should be placed after $var\n" . $herecurr))) && | |
5146 | $fix) { | |
194f66fc | 5147 | $fixed[$fixlinenr] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e; |
8716de38 JP |
5148 | } |
5149 | } | |
5150 | } | |
5151 | ||
e970b884 JP |
5152 | # check for $InitAttributeData (ie: __initdata) with const |
5153 | if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { | |
5154 | my $attr = $1; | |
5155 | $attr =~ /($InitAttributePrefix)(.*)/; | |
5156 | my $attr_prefix = $1; | |
5157 | my $attr_type = $2; | |
5158 | if (ERROR("INIT_ATTRIBUTE", | |
5159 | "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && | |
5160 | $fix) { | |
194f66fc | 5161 | $fixed[$fixlinenr] =~ |
e970b884 JP |
5162 | s/$InitAttributeData/${attr_prefix}initconst/; |
5163 | } | |
5164 | } | |
5165 | ||
5166 | # check for $InitAttributeConst (ie: __initconst) without const | |
5167 | if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { | |
5168 | my $attr = $1; | |
5169 | if (ERROR("INIT_ATTRIBUTE", | |
5170 | "Use of $attr requires a separate use of const\n" . $herecurr) && | |
5171 | $fix) { | |
194f66fc | 5172 | my $lead = $fixed[$fixlinenr] =~ |
e970b884 JP |
5173 | /(^\+\s*(?:static\s+))/; |
5174 | $lead = rtrim($1); | |
5175 | $lead = "$lead " if ($lead !~ /^\+$/); | |
5176 | $lead = "${lead}const "; | |
194f66fc | 5177 | $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; |
e970b884 JP |
5178 | } |
5179 | } | |
5180 | ||
c17893c7 JP |
5181 | # check for __read_mostly with const non-pointer (should just be const) |
5182 | if ($line =~ /\b__read_mostly\b/ && | |
5183 | $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { | |
5184 | if (ERROR("CONST_READ_MOSTLY", | |
5185 | "Invalid use of __read_mostly with const type\n" . $herecurr) && | |
5186 | $fix) { | |
5187 | $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; | |
5188 | } | |
5189 | } | |
5190 | ||
fbdb8138 JP |
5191 | # don't use __constant_<foo> functions outside of include/uapi/ |
5192 | if ($realfile !~ m@^include/uapi/@ && | |
5193 | $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { | |
5194 | my $constant_func = $1; | |
5195 | my $func = $constant_func; | |
5196 | $func =~ s/^__constant_//; | |
5197 | if (WARN("CONSTANT_CONVERSION", | |
5198 | "$constant_func should be $func\n" . $herecurr) && | |
5199 | $fix) { | |
194f66fc | 5200 | $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; |
fbdb8138 JP |
5201 | } |
5202 | } | |
5203 | ||
1a15a250 | 5204 | # prefer usleep_range over udelay |
37581c28 | 5205 | if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { |
43c1d77c | 5206 | my $delay = $1; |
1a15a250 | 5207 | # ignore udelay's < 10, however |
43c1d77c | 5208 | if (! ($delay < 10) ) { |
000d1cc1 | 5209 | CHK("USLEEP_RANGE", |
43c1d77c JP |
5210 | "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); |
5211 | } | |
5212 | if ($delay > 2000) { | |
5213 | WARN("LONG_UDELAY", | |
5214 | "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); | |
1a15a250 PP |
5215 | } |
5216 | } | |
5217 | ||
09ef8725 PP |
5218 | # warn about unexpectedly long msleep's |
5219 | if ($line =~ /\bmsleep\s*\((\d+)\);/) { | |
5220 | if ($1 < 20) { | |
000d1cc1 | 5221 | WARN("MSLEEP", |
43c1d77c | 5222 | "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); |
09ef8725 PP |
5223 | } |
5224 | } | |
5225 | ||
36ec1939 JP |
5226 | # check for comparisons of jiffies |
5227 | if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { | |
5228 | WARN("JIFFIES_COMPARISON", | |
5229 | "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); | |
5230 | } | |
5231 | ||
9d7a34a5 JP |
5232 | # check for comparisons of get_jiffies_64() |
5233 | if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { | |
5234 | WARN("JIFFIES_COMPARISON", | |
5235 | "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); | |
5236 | } | |
5237 | ||
00df344f | 5238 | # warn about #ifdefs in C files |
c45dcabd | 5239 | # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { |
00df344f AW |
5240 | # print "#ifdef in C files should be avoided\n"; |
5241 | # print "$herecurr"; | |
5242 | # $clean = 0; | |
5243 | # } | |
5244 | ||
22f2a2ef | 5245 | # warn about spacing in #ifdefs |
c45dcabd | 5246 | if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { |
3705ce5b JP |
5247 | if (ERROR("SPACING", |
5248 | "exactly one space required after that #$1\n" . $herecurr) && | |
5249 | $fix) { | |
194f66fc | 5250 | $fixed[$fixlinenr] =~ |
3705ce5b JP |
5251 | s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; |
5252 | } | |
5253 | ||
22f2a2ef AW |
5254 | } |
5255 | ||
4a0df2ef | 5256 | # check for spinlock_t definitions without a comment. |
171ae1a4 AW |
5257 | if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || |
5258 | $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { | |
4a0df2ef AW |
5259 | my $which = $1; |
5260 | if (!ctx_has_comment($first_line, $linenr)) { | |
000d1cc1 JP |
5261 | CHK("UNCOMMENTED_DEFINITION", |
5262 | "$1 definition without comment\n" . $herecurr); | |
4a0df2ef AW |
5263 | } |
5264 | } | |
5265 | # check for memory barriers without a comment. | |
402c2553 MT |
5266 | |
5267 | my $barriers = qr{ | |
5268 | mb| | |
5269 | rmb| | |
5270 | wmb| | |
5271 | read_barrier_depends | |
5272 | }x; | |
5273 | my $barrier_stems = qr{ | |
5274 | mb__before_atomic| | |
5275 | mb__after_atomic| | |
5276 | store_release| | |
5277 | load_acquire| | |
5278 | store_mb| | |
5279 | (?:$barriers) | |
5280 | }x; | |
5281 | my $all_barriers = qr{ | |
5282 | (?:$barriers)| | |
43e361f2 MT |
5283 | smp_(?:$barrier_stems)| |
5284 | virt_(?:$barrier_stems) | |
402c2553 MT |
5285 | }x; |
5286 | ||
5287 | if ($line =~ /\b(?:$all_barriers)\s*\(/) { | |
4a0df2ef | 5288 | if (!ctx_has_comment($first_line, $linenr)) { |
c1fd7bb9 JP |
5289 | WARN("MEMORY_BARRIER", |
5290 | "memory barrier without comment\n" . $herecurr); | |
4a0df2ef AW |
5291 | } |
5292 | } | |
3ad81779 | 5293 | |
f4073b0f MT |
5294 | my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; |
5295 | ||
5296 | if ($realfile !~ m@^include/asm-generic/@ && | |
5297 | $realfile !~ m@/barrier\.h$@ && | |
5298 | $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && | |
5299 | $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { | |
5300 | WARN("MEMORY_BARRIER", | |
5301 | "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); | |
5302 | } | |
5303 | ||
cb426e99 JP |
5304 | # check for waitqueue_active without a comment. |
5305 | if ($line =~ /\bwaitqueue_active\s*\(/) { | |
5306 | if (!ctx_has_comment($first_line, $linenr)) { | |
5307 | WARN("WAITQUEUE_ACTIVE", | |
5308 | "waitqueue_active without comment\n" . $herecurr); | |
5309 | } | |
5310 | } | |
3ad81779 PM |
5311 | |
5312 | # Check for expedited grace periods that interrupt non-idle non-nohz | |
5313 | # online CPUs. These expedited can therefore degrade real-time response | |
5314 | # if used carelessly, and should be avoided where not absolutely | |
5315 | # needed. It is always OK to use synchronize_rcu_expedited() and | |
5316 | # synchronize_sched_expedited() at boot time (before real-time applications | |
5317 | # start) and in error situations where real-time response is compromised in | |
5318 | # any case. Note that synchronize_srcu_expedited() does -not- interrupt | |
5319 | # other CPUs, so don't warn on uses of synchronize_srcu_expedited(). | |
5320 | # Of course, nothing comes for free, and srcu_read_lock() and | |
5321 | # srcu_read_unlock() do contain full memory barriers in payment for | |
5322 | # synchronize_srcu_expedited() non-interruption properties. | |
5323 | if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) { | |
5324 | WARN("EXPEDITED_RCU_GRACE_PERIOD", | |
5325 | "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr); | |
5326 | ||
5327 | } | |
5328 | ||
4a0df2ef | 5329 | # check of hardware specific defines |
c45dcabd | 5330 | if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { |
000d1cc1 JP |
5331 | CHK("ARCH_DEFINES", |
5332 | "architecture specific defines should be avoided\n" . $herecurr); | |
0a920b5b | 5333 | } |
653d4876 | 5334 | |
d4977c78 TK |
5335 | # Check that the storage class is at the beginning of a declaration |
5336 | if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { | |
000d1cc1 JP |
5337 | WARN("STORAGE_CLASS", |
5338 | "storage class should be at the beginning of the declaration\n" . $herecurr) | |
d4977c78 TK |
5339 | } |
5340 | ||
de7d4f0e AW |
5341 | # check the location of the inline attribute, that it is between |
5342 | # storage class and type. | |
9c0ca6f9 AW |
5343 | if ($line =~ /\b$Type\s+$Inline\b/ || |
5344 | $line =~ /\b$Inline\s+$Storage\b/) { | |
000d1cc1 JP |
5345 | ERROR("INLINE_LOCATION", |
5346 | "inline keyword should sit between storage class and type\n" . $herecurr); | |
de7d4f0e AW |
5347 | } |
5348 | ||
8905a67c | 5349 | # Check for __inline__ and __inline, prefer inline |
2b7ab453 JP |
5350 | if ($realfile !~ m@\binclude/uapi/@ && |
5351 | $line =~ /\b(__inline__|__inline)\b/) { | |
d5e616fc JP |
5352 | if (WARN("INLINE", |
5353 | "plain inline is preferred over $1\n" . $herecurr) && | |
5354 | $fix) { | |
194f66fc | 5355 | $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; |
d5e616fc JP |
5356 | |
5357 | } | |
8905a67c AW |
5358 | } |
5359 | ||
3d130fd0 | 5360 | # Check for __attribute__ packed, prefer __packed |
2b7ab453 JP |
5361 | if ($realfile !~ m@\binclude/uapi/@ && |
5362 | $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { | |
000d1cc1 JP |
5363 | WARN("PREFER_PACKED", |
5364 | "__packed is preferred over __attribute__((packed))\n" . $herecurr); | |
3d130fd0 JP |
5365 | } |
5366 | ||
39b7e287 | 5367 | # Check for __attribute__ aligned, prefer __aligned |
2b7ab453 JP |
5368 | if ($realfile !~ m@\binclude/uapi/@ && |
5369 | $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { | |
000d1cc1 JP |
5370 | WARN("PREFER_ALIGNED", |
5371 | "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); | |
39b7e287 JP |
5372 | } |
5373 | ||
5f14d3bd | 5374 | # Check for __attribute__ format(printf, prefer __printf |
2b7ab453 JP |
5375 | if ($realfile !~ m@\binclude/uapi/@ && |
5376 | $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { | |
d5e616fc JP |
5377 | if (WARN("PREFER_PRINTF", |
5378 | "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && | |
5379 | $fix) { | |
194f66fc | 5380 | $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; |
d5e616fc JP |
5381 | |
5382 | } | |
5f14d3bd JP |
5383 | } |
5384 | ||
6061d949 | 5385 | # Check for __attribute__ format(scanf, prefer __scanf |
2b7ab453 JP |
5386 | if ($realfile !~ m@\binclude/uapi/@ && |
5387 | $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { | |
d5e616fc JP |
5388 | if (WARN("PREFER_SCANF", |
5389 | "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && | |
5390 | $fix) { | |
194f66fc | 5391 | $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; |
d5e616fc | 5392 | } |
6061d949 JP |
5393 | } |
5394 | ||
619a908a JP |
5395 | # Check for __attribute__ weak, or __weak declarations (may have link issues) |
5396 | if ($^V && $^V ge 5.10.0 && | |
5397 | $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && | |
5398 | ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || | |
5399 | $line =~ /\b__weak\b/)) { | |
5400 | ERROR("WEAK_DECLARATION", | |
5401 | "Using weak declarations can have unintended link defects\n" . $herecurr); | |
5402 | } | |
5403 | ||
e6176fa4 JP |
5404 | # check for c99 types like uint8_t used outside of uapi/ |
5405 | if ($realfile !~ m@\binclude/uapi/@ && | |
5406 | $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { | |
5407 | my $type = $1; | |
5408 | if ($type =~ /\b($typeC99Typedefs)\b/) { | |
5409 | $type = $1; | |
5410 | my $kernel_type = 'u'; | |
5411 | $kernel_type = 's' if ($type =~ /^_*[si]/); | |
5412 | $type =~ /(\d+)/; | |
5413 | $kernel_type .= $1; | |
5414 | if (CHK("PREFER_KERNEL_TYPES", | |
5415 | "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && | |
5416 | $fix) { | |
5417 | $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; | |
5418 | } | |
5419 | } | |
5420 | } | |
5421 | ||
938224b5 JP |
5422 | # check for cast of C90 native int or longer types constants |
5423 | if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { | |
5424 | my $cast = $1; | |
5425 | my $const = $2; | |
5426 | if (WARN("TYPECAST_INT_CONSTANT", | |
5427 | "Unnecessary typecast of c90 int constant\n" . $herecurr) && | |
5428 | $fix) { | |
5429 | my $suffix = ""; | |
5430 | my $newconst = $const; | |
5431 | $newconst =~ s/${Int_type}$//; | |
5432 | $suffix .= 'U' if ($cast =~ /\bunsigned\b/); | |
5433 | if ($cast =~ /\blong\s+long\b/) { | |
5434 | $suffix .= 'LL'; | |
5435 | } elsif ($cast =~ /\blong\b/) { | |
5436 | $suffix .= 'L'; | |
5437 | } | |
5438 | $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; | |
5439 | } | |
5440 | } | |
5441 | ||
8f53a9b8 JP |
5442 | # check for sizeof(&) |
5443 | if ($line =~ /\bsizeof\s*\(\s*\&/) { | |
000d1cc1 JP |
5444 | WARN("SIZEOF_ADDRESS", |
5445 | "sizeof(& should be avoided\n" . $herecurr); | |
8f53a9b8 JP |
5446 | } |
5447 | ||
66c80b60 JP |
5448 | # check for sizeof without parenthesis |
5449 | if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { | |
d5e616fc JP |
5450 | if (WARN("SIZEOF_PARENTHESIS", |
5451 | "sizeof $1 should be sizeof($1)\n" . $herecurr) && | |
5452 | $fix) { | |
194f66fc | 5453 | $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; |
d5e616fc | 5454 | } |
66c80b60 JP |
5455 | } |
5456 | ||
88982fea JP |
5457 | # check for struct spinlock declarations |
5458 | if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { | |
5459 | WARN("USE_SPINLOCK_T", | |
5460 | "struct spinlock should be spinlock_t\n" . $herecurr); | |
5461 | } | |
5462 | ||
a6962d72 | 5463 | # check for seq_printf uses that could be seq_puts |
06668727 | 5464 | if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { |
a6962d72 | 5465 | my $fmt = get_quoted_string($line, $rawline); |
caac1d5f HA |
5466 | $fmt =~ s/%%//g; |
5467 | if ($fmt !~ /%/) { | |
d5e616fc JP |
5468 | if (WARN("PREFER_SEQ_PUTS", |
5469 | "Prefer seq_puts to seq_printf\n" . $herecurr) && | |
5470 | $fix) { | |
194f66fc | 5471 | $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; |
d5e616fc | 5472 | } |
a6962d72 JP |
5473 | } |
5474 | } | |
5475 | ||
554e165c | 5476 | # Check for misused memsets |
d1fe9c09 JP |
5477 | if ($^V && $^V ge 5.10.0 && |
5478 | defined $stat && | |
9e20a853 | 5479 | $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { |
d7c76ba7 JP |
5480 | |
5481 | my $ms_addr = $2; | |
d1fe9c09 JP |
5482 | my $ms_val = $7; |
5483 | my $ms_size = $12; | |
554e165c | 5484 | |
554e165c AW |
5485 | if ($ms_size =~ /^(0x|)0$/i) { |
5486 | ERROR("MEMSET", | |
d7c76ba7 | 5487 | "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); |
554e165c AW |
5488 | } elsif ($ms_size =~ /^(0x|)1$/i) { |
5489 | WARN("MEMSET", | |
d7c76ba7 JP |
5490 | "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); |
5491 | } | |
5492 | } | |
5493 | ||
98a9bba5 JP |
5494 | # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) |
5495 | if ($^V && $^V ge 5.10.0 && | |
10895d2c MK |
5496 | defined $stat && |
5497 | $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { | |
98a9bba5 | 5498 | if (WARN("PREFER_ETHER_ADDR_COPY", |
10895d2c | 5499 | "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && |
98a9bba5 | 5500 | $fix) { |
194f66fc | 5501 | $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; |
98a9bba5 JP |
5502 | } |
5503 | } | |
5504 | ||
b6117d17 MK |
5505 | # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) |
5506 | if ($^V && $^V ge 5.10.0 && | |
5507 | defined $stat && | |
5508 | $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { | |
5509 | WARN("PREFER_ETHER_ADDR_EQUAL", | |
5510 | "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") | |
5511 | } | |
5512 | ||
8617cd09 MK |
5513 | # check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr |
5514 | # check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr | |
5515 | if ($^V && $^V ge 5.10.0 && | |
5516 | defined $stat && | |
5517 | $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { | |
5518 | ||
5519 | my $ms_val = $7; | |
5520 | ||
5521 | if ($ms_val =~ /^(?:0x|)0+$/i) { | |
5522 | if (WARN("PREFER_ETH_ZERO_ADDR", | |
5523 | "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && | |
5524 | $fix) { | |
5525 | $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; | |
5526 | } | |
5527 | } elsif ($ms_val =~ /^(?:0xff|255)$/i) { | |
5528 | if (WARN("PREFER_ETH_BROADCAST_ADDR", | |
5529 | "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && | |
5530 | $fix) { | |
5531 | $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; | |
5532 | } | |
5533 | } | |
5534 | } | |
5535 | ||
d7c76ba7 | 5536 | # typecasts on min/max could be min_t/max_t |
d1fe9c09 JP |
5537 | if ($^V && $^V ge 5.10.0 && |
5538 | defined $stat && | |
d7c76ba7 | 5539 | $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { |
d1fe9c09 | 5540 | if (defined $2 || defined $7) { |
d7c76ba7 JP |
5541 | my $call = $1; |
5542 | my $cast1 = deparenthesize($2); | |
5543 | my $arg1 = $3; | |
d1fe9c09 JP |
5544 | my $cast2 = deparenthesize($7); |
5545 | my $arg2 = $8; | |
d7c76ba7 JP |
5546 | my $cast; |
5547 | ||
d1fe9c09 | 5548 | if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { |
d7c76ba7 JP |
5549 | $cast = "$cast1 or $cast2"; |
5550 | } elsif ($cast1 ne "") { | |
5551 | $cast = $cast1; | |
5552 | } else { | |
5553 | $cast = $cast2; | |
5554 | } | |
5555 | WARN("MINMAX", | |
5556 | "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); | |
554e165c AW |
5557 | } |
5558 | } | |
5559 | ||
4a273195 JP |
5560 | # check usleep_range arguments |
5561 | if ($^V && $^V ge 5.10.0 && | |
5562 | defined $stat && | |
5563 | $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { | |
5564 | my $min = $1; | |
5565 | my $max = $7; | |
5566 | if ($min eq $max) { | |
5567 | WARN("USLEEP_RANGE", | |
5568 | "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); | |
5569 | } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && | |
5570 | $min > $max) { | |
5571 | WARN("USLEEP_RANGE", | |
5572 | "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); | |
5573 | } | |
5574 | } | |
5575 | ||
823b794c JP |
5576 | # check for naked sscanf |
5577 | if ($^V && $^V ge 5.10.0 && | |
5578 | defined $stat && | |
6c8bd707 | 5579 | $line =~ /\bsscanf\b/ && |
823b794c JP |
5580 | ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && |
5581 | $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && | |
5582 | $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { | |
5583 | my $lc = $stat =~ tr@\n@@; | |
5584 | $lc = $lc + $linenr; | |
5585 | my $stat_real = raw_line($linenr, 0); | |
5586 | for (my $count = $linenr + 1; $count <= $lc; $count++) { | |
5587 | $stat_real = $stat_real . "\n" . raw_line($count, 0); | |
5588 | } | |
5589 | WARN("NAKED_SSCANF", | |
5590 | "unchecked sscanf return value\n" . "$here\n$stat_real\n"); | |
5591 | } | |
5592 | ||
afc819ab JP |
5593 | # check for simple sscanf that should be kstrto<foo> |
5594 | if ($^V && $^V ge 5.10.0 && | |
5595 | defined $stat && | |
5596 | $line =~ /\bsscanf\b/) { | |
5597 | my $lc = $stat =~ tr@\n@@; | |
5598 | $lc = $lc + $linenr; | |
5599 | my $stat_real = raw_line($linenr, 0); | |
5600 | for (my $count = $linenr + 1; $count <= $lc; $count++) { | |
5601 | $stat_real = $stat_real . "\n" . raw_line($count, 0); | |
5602 | } | |
5603 | if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { | |
5604 | my $format = $6; | |
5605 | my $count = $format =~ tr@%@%@; | |
5606 | if ($count == 1 && | |
5607 | $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { | |
5608 | WARN("SSCANF_TO_KSTRTO", | |
5609 | "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); | |
5610 | } | |
5611 | } | |
5612 | } | |
5613 | ||
70dc8a48 JP |
5614 | # check for new externs in .h files. |
5615 | if ($realfile =~ /\.h$/ && | |
5616 | $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { | |
d1d85780 JP |
5617 | if (CHK("AVOID_EXTERNS", |
5618 | "extern prototypes should be avoided in .h files\n" . $herecurr) && | |
70dc8a48 | 5619 | $fix) { |
194f66fc | 5620 | $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; |
70dc8a48 JP |
5621 | } |
5622 | } | |
5623 | ||
de7d4f0e | 5624 | # check for new externs in .c files. |
171ae1a4 | 5625 | if ($realfile =~ /\.c$/ && defined $stat && |
c45dcabd | 5626 | $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) |
171ae1a4 | 5627 | { |
c45dcabd AW |
5628 | my $function_name = $1; |
5629 | my $paren_space = $2; | |
171ae1a4 AW |
5630 | |
5631 | my $s = $stat; | |
5632 | if (defined $cond) { | |
5633 | substr($s, 0, length($cond), ''); | |
5634 | } | |
c45dcabd AW |
5635 | if ($s =~ /^\s*;/ && |
5636 | $function_name ne 'uninitialized_var') | |
5637 | { | |
000d1cc1 JP |
5638 | WARN("AVOID_EXTERNS", |
5639 | "externs should be avoided in .c files\n" . $herecurr); | |
171ae1a4 AW |
5640 | } |
5641 | ||
5642 | if ($paren_space =~ /\n/) { | |
000d1cc1 JP |
5643 | WARN("FUNCTION_ARGUMENTS", |
5644 | "arguments for function declarations should follow identifier\n" . $herecurr); | |
171ae1a4 | 5645 | } |
9c9ba34e AW |
5646 | |
5647 | } elsif ($realfile =~ /\.c$/ && defined $stat && | |
5648 | $stat =~ /^.\s*extern\s+/) | |
5649 | { | |
000d1cc1 JP |
5650 | WARN("AVOID_EXTERNS", |
5651 | "externs should be avoided in .c files\n" . $herecurr); | |
de7d4f0e AW |
5652 | } |
5653 | ||
5654 | # checks for new __setup's | |
5655 | if ($rawline =~ /\b__setup\("([^"]*)"/) { | |
5656 | my $name = $1; | |
5657 | ||
5658 | if (!grep(/$name/, @setup_docs)) { | |
000d1cc1 JP |
5659 | CHK("UNDOCUMENTED_SETUP", |
5660 | "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); | |
de7d4f0e | 5661 | } |
653d4876 | 5662 | } |
9c0ca6f9 AW |
5663 | |
5664 | # check for pointless casting of kmalloc return | |
caf2a54f | 5665 | if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { |
000d1cc1 JP |
5666 | WARN("UNNECESSARY_CASTS", |
5667 | "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); | |
9c0ca6f9 | 5668 | } |
13214adf | 5669 | |
a640d25c JP |
5670 | # alloc style |
5671 | # p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) | |
5672 | if ($^V && $^V ge 5.10.0 && | |
5673 | $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { | |
5674 | CHK("ALLOC_SIZEOF_STRUCT", | |
5675 | "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); | |
5676 | } | |
5677 | ||
60a55369 JP |
5678 | # check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc |
5679 | if ($^V && $^V ge 5.10.0 && | |
e367455a | 5680 | $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { |
60a55369 JP |
5681 | my $oldfunc = $3; |
5682 | my $a1 = $4; | |
5683 | my $a2 = $10; | |
5684 | my $newfunc = "kmalloc_array"; | |
5685 | $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); | |
e367455a JP |
5686 | my $r1 = $a1; |
5687 | my $r2 = $a2; | |
5688 | if ($a1 =~ /^sizeof\s*\S/) { | |
5689 | $r1 = $a2; | |
5690 | $r2 = $a1; | |
5691 | } | |
5692 | if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && | |
5693 | !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { | |
60a55369 JP |
5694 | if (WARN("ALLOC_WITH_MULTIPLY", |
5695 | "Prefer $newfunc over $oldfunc with multiply\n" . $herecurr) && | |
5696 | $fix) { | |
194f66fc | 5697 | $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; |
60a55369 JP |
5698 | |
5699 | } | |
5700 | } | |
5701 | } | |
5702 | ||
972fdea2 JP |
5703 | # check for krealloc arg reuse |
5704 | if ($^V && $^V ge 5.10.0 && | |
5705 | $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { | |
5706 | WARN("KREALLOC_ARG_REUSE", | |
5707 | "Reusing the krealloc arg is almost always a bug\n" . $herecurr); | |
5708 | } | |
5709 | ||
5ce59ae0 JP |
5710 | # check for alloc argument mismatch |
5711 | if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { | |
5712 | WARN("ALLOC_ARRAY_ARGS", | |
5713 | "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); | |
5714 | } | |
5715 | ||
caf2a54f JP |
5716 | # check for multiple semicolons |
5717 | if ($line =~ /;\s*;\s*$/) { | |
d5e616fc JP |
5718 | if (WARN("ONE_SEMICOLON", |
5719 | "Statements terminations use 1 semicolon\n" . $herecurr) && | |
5720 | $fix) { | |
194f66fc | 5721 | $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; |
d5e616fc | 5722 | } |
d1e2ad07 JP |
5723 | } |
5724 | ||
0ab90191 JP |
5725 | # check for #defines like: 1 << <digit> that could be BIT(digit) |
5726 | if ($line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { | |
5727 | my $ull = ""; | |
5728 | $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); | |
5729 | if (CHK("BIT_MACRO", | |
5730 | "Prefer using the BIT$ull macro\n" . $herecurr) && | |
5731 | $fix) { | |
5732 | $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; | |
5733 | } | |
5734 | } | |
5735 | ||
2d632745 JP |
5736 | # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE |
5737 | if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { | |
5738 | my $config = $1; | |
5739 | if (WARN("PREFER_IS_ENABLED", | |
5740 | "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && | |
5741 | $fix) { | |
5742 | $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; | |
5743 | } | |
5744 | } | |
5745 | ||
e81f239b | 5746 | # check for case / default statements not preceded by break/fallthrough/switch |
c34c09a8 JP |
5747 | if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { |
5748 | my $has_break = 0; | |
5749 | my $has_statement = 0; | |
5750 | my $count = 0; | |
5751 | my $prevline = $linenr; | |
e81f239b | 5752 | while ($prevline > 1 && ($file || $count < 3) && !$has_break) { |
c34c09a8 JP |
5753 | $prevline--; |
5754 | my $rline = $rawlines[$prevline - 1]; | |
5755 | my $fline = $lines[$prevline - 1]; | |
5756 | last if ($fline =~ /^\@\@/); | |
5757 | next if ($fline =~ /^\-/); | |
5758 | next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); | |
5759 | $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); | |
5760 | next if ($fline =~ /^.[\s$;]*$/); | |
5761 | $has_statement = 1; | |
5762 | $count++; | |
5763 | $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); | |
5764 | } | |
5765 | if (!$has_break && $has_statement) { | |
5766 | WARN("MISSING_BREAK", | |
5767 | "Possible switch case/default not preceeded by break or fallthrough comment\n" . $herecurr); | |
5768 | } | |
5769 | } | |
5770 | ||
d1e2ad07 JP |
5771 | # check for switch/default statements without a break; |
5772 | if ($^V && $^V ge 5.10.0 && | |
5773 | defined $stat && | |
5774 | $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { | |
5775 | my $ctx = ''; | |
5776 | my $herectx = $here . "\n"; | |
5777 | my $cnt = statement_rawlines($stat); | |
5778 | for (my $n = 0; $n < $cnt; $n++) { | |
5779 | $herectx .= raw_line($linenr, $n) . "\n"; | |
5780 | } | |
5781 | WARN("DEFAULT_NO_BREAK", | |
5782 | "switch default: should use break\n" . $herectx); | |
caf2a54f JP |
5783 | } |
5784 | ||
13214adf | 5785 | # check for gcc specific __FUNCTION__ |
d5e616fc JP |
5786 | if ($line =~ /\b__FUNCTION__\b/) { |
5787 | if (WARN("USE_FUNC", | |
5788 | "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && | |
5789 | $fix) { | |
194f66fc | 5790 | $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; |
d5e616fc | 5791 | } |
13214adf | 5792 | } |
773647a0 | 5793 | |
62ec818f JP |
5794 | # check for uses of __DATE__, __TIME__, __TIMESTAMP__ |
5795 | while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { | |
5796 | ERROR("DATE_TIME", | |
5797 | "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); | |
5798 | } | |
5799 | ||
2c92488a JP |
5800 | # check for use of yield() |
5801 | if ($line =~ /\byield\s*\(\s*\)/) { | |
5802 | WARN("YIELD", | |
5803 | "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); | |
5804 | } | |
5805 | ||
179f8f40 JP |
5806 | # check for comparisons against true and false |
5807 | if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { | |
5808 | my $lead = $1; | |
5809 | my $arg = $2; | |
5810 | my $test = $3; | |
5811 | my $otype = $4; | |
5812 | my $trail = $5; | |
5813 | my $op = "!"; | |
5814 | ||
5815 | ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); | |
5816 | ||
5817 | my $type = lc($otype); | |
5818 | if ($type =~ /^(?:true|false)$/) { | |
5819 | if (("$test" eq "==" && "$type" eq "true") || | |
5820 | ("$test" eq "!=" && "$type" eq "false")) { | |
5821 | $op = ""; | |
5822 | } | |
5823 | ||
5824 | CHK("BOOL_COMPARISON", | |
5825 | "Using comparison to $otype is error prone\n" . $herecurr); | |
5826 | ||
5827 | ## maybe suggesting a correct construct would better | |
5828 | ## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); | |
5829 | ||
5830 | } | |
5831 | } | |
5832 | ||
4882720b TG |
5833 | # check for semaphores initialized locked |
5834 | if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { | |
000d1cc1 JP |
5835 | WARN("CONSIDER_COMPLETION", |
5836 | "consider using a completion\n" . $herecurr); | |
773647a0 | 5837 | } |
6712d858 | 5838 | |
67d0a075 JP |
5839 | # recommend kstrto* over simple_strto* and strict_strto* |
5840 | if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { | |
000d1cc1 | 5841 | WARN("CONSIDER_KSTRTO", |
67d0a075 | 5842 | "$1 is obsolete, use k$3 instead\n" . $herecurr); |
773647a0 | 5843 | } |
6712d858 | 5844 | |
ae3ccc46 | 5845 | # check for __initcall(), use device_initcall() explicitly or more appropriate function please |
f3db6639 | 5846 | if ($line =~ /^.\s*__initcall\s*\(/) { |
000d1cc1 | 5847 | WARN("USE_DEVICE_INITCALL", |
ae3ccc46 | 5848 | "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); |
f3db6639 | 5849 | } |
6712d858 | 5850 | |
0f3c5aab JP |
5851 | # check for various structs that are normally const (ops, kgdb, device_tree) |
5852 | my $const_structs = qr{ | |
5853 | acpi_dock_ops| | |
79404849 ER |
5854 | address_space_operations| |
5855 | backlight_ops| | |
5856 | block_device_operations| | |
5857 | dentry_operations| | |
5858 | dev_pm_ops| | |
5859 | dma_map_ops| | |
5860 | extent_io_ops| | |
5861 | file_lock_operations| | |
5862 | file_operations| | |
5863 | hv_ops| | |
5864 | ide_dma_ops| | |
5865 | intel_dvo_dev_ops| | |
5866 | item_operations| | |
5867 | iwl_ops| | |
5868 | kgdb_arch| | |
5869 | kgdb_io| | |
5870 | kset_uevent_ops| | |
5871 | lock_manager_operations| | |
5872 | microcode_ops| | |
5873 | mtrr_ops| | |
5874 | neigh_ops| | |
5875 | nlmsvc_binding| | |
0f3c5aab | 5876 | of_device_id| |
79404849 ER |
5877 | pci_raw_ops| |
5878 | pipe_buf_operations| | |
5879 | platform_hibernation_ops| | |
5880 | platform_suspend_ops| | |
5881 | proto_ops| | |
5882 | rpc_pipe_ops| | |
5883 | seq_operations| | |
5884 | snd_ac97_build_ops| | |
5885 | soc_pcmcia_socket_ops| | |
5886 | stacktrace_ops| | |
5887 | sysfs_ops| | |
5888 | tty_operations| | |
6d07d01b | 5889 | uart_ops| |
79404849 ER |
5890 | usb_mon_operations| |
5891 | wd_ops}x; | |
6903ffb2 | 5892 | if ($line !~ /\bconst\b/ && |
0f3c5aab | 5893 | $line =~ /\bstruct\s+($const_structs)\b/) { |
000d1cc1 JP |
5894 | WARN("CONST_STRUCT", |
5895 | "struct $1 should normally be const\n" . | |
6903ffb2 | 5896 | $herecurr); |
2b6db5cb | 5897 | } |
773647a0 AW |
5898 | |
5899 | # use of NR_CPUS is usually wrong | |
5900 | # ignore definitions of NR_CPUS and usage to define arrays as likely right | |
5901 | if ($line =~ /\bNR_CPUS\b/ && | |
c45dcabd AW |
5902 | $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && |
5903 | $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && | |
171ae1a4 AW |
5904 | $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && |
5905 | $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && | |
5906 | $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) | |
773647a0 | 5907 | { |
000d1cc1 JP |
5908 | WARN("NR_CPUS", |
5909 | "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); | |
773647a0 | 5910 | } |
9c9ba34e | 5911 | |
52ea8506 JP |
5912 | # Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. |
5913 | if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { | |
5914 | ERROR("DEFINE_ARCH_HAS", | |
5915 | "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); | |
5916 | } | |
5917 | ||
acd9362c JP |
5918 | # likely/unlikely comparisons similar to "(likely(foo) > 0)" |
5919 | if ($^V && $^V ge 5.10.0 && | |
5920 | $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { | |
5921 | WARN("LIKELY_MISUSE", | |
5922 | "Using $1 should generally have parentheses around the comparison\n" . $herecurr); | |
5923 | } | |
5924 | ||
691d77b6 AW |
5925 | # whine mightly about in_atomic |
5926 | if ($line =~ /\bin_atomic\s*\(/) { | |
5927 | if ($realfile =~ m@^drivers/@) { | |
000d1cc1 JP |
5928 | ERROR("IN_ATOMIC", |
5929 | "do not use in_atomic in drivers\n" . $herecurr); | |
f4a87736 | 5930 | } elsif ($realfile !~ m@^kernel/@) { |
000d1cc1 JP |
5931 | WARN("IN_ATOMIC", |
5932 | "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); | |
691d77b6 AW |
5933 | } |
5934 | } | |
1704f47b | 5935 | |
481aea5c JP |
5936 | # whine about ACCESS_ONCE |
5937 | if ($^V && $^V ge 5.10.0 && | |
5938 | $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { | |
5939 | my $par = $1; | |
5940 | my $eq = $2; | |
5941 | my $fun = $3; | |
5942 | $par =~ s/^\(\s*(.*)\s*\)$/$1/; | |
5943 | if (defined($eq)) { | |
5944 | if (WARN("PREFER_WRITE_ONCE", | |
5945 | "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && | |
5946 | $fix) { | |
5947 | $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; | |
5948 | } | |
5949 | } else { | |
5950 | if (WARN("PREFER_READ_ONCE", | |
5951 | "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && | |
5952 | $fix) { | |
5953 | $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; | |
5954 | } | |
5955 | } | |
5956 | } | |
5957 | ||
1704f47b PZ |
5958 | # check for lockdep_set_novalidate_class |
5959 | if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || | |
5960 | $line =~ /__lockdep_no_validate__\s*\)/ ) { | |
5961 | if ($realfile !~ m@^kernel/lockdep@ && | |
5962 | $realfile !~ m@^include/linux/lockdep@ && | |
5963 | $realfile !~ m@^drivers/base/core@) { | |
000d1cc1 JP |
5964 | ERROR("LOCKDEP", |
5965 | "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); | |
1704f47b PZ |
5966 | } |
5967 | } | |
88f8831c | 5968 | |
b392c64f JP |
5969 | if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || |
5970 | $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { | |
000d1cc1 JP |
5971 | WARN("EXPORTED_WORLD_WRITABLE", |
5972 | "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); | |
88f8831c | 5973 | } |
2435880f | 5974 | |
515a235e JP |
5975 | # Mode permission misuses where it seems decimal should be octal |
5976 | # This uses a shortcut match to avoid unnecessary uses of a slow foreach loop | |
5977 | if ($^V && $^V ge 5.10.0 && | |
5978 | $line =~ /$mode_perms_search/) { | |
5979 | foreach my $entry (@mode_permission_funcs) { | |
5980 | my $func = $entry->[0]; | |
5981 | my $arg_pos = $entry->[1]; | |
5982 | ||
5983 | my $skip_args = ""; | |
5984 | if ($arg_pos > 1) { | |
5985 | $arg_pos--; | |
5986 | $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; | |
5987 | } | |
5988 | my $test = "\\b$func\\s*\\(${skip_args}([\\d]+)\\s*[,\\)]"; | |
5989 | if ($line =~ /$test/) { | |
5990 | my $val = $1; | |
5991 | $val = $6 if ($skip_args ne ""); | |
5992 | ||
5993 | if ($val !~ /^0$/ && | |
5994 | (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || | |
5995 | length($val) ne 4)) { | |
5996 | ERROR("NON_OCTAL_PERMISSIONS", | |
5997 | "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr); | |
c0a5c898 JP |
5998 | } elsif ($val =~ /^$Octal$/ && (oct($val) & 02)) { |
5999 | ERROR("EXPORTED_WORLD_WRITABLE", | |
6000 | "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); | |
515a235e | 6001 | } |
2435880f JP |
6002 | } |
6003 | } | |
6004 | } | |
5a6d20ce BA |
6005 | |
6006 | # validate content of MODULE_LICENSE against list from include/linux/module.h | |
6007 | if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { | |
6008 | my $extracted_string = get_quoted_string($line, $rawline); | |
6009 | my $valid_licenses = qr{ | |
6010 | GPL| | |
6011 | GPL\ v2| | |
6012 | GPL\ and\ additional\ rights| | |
6013 | Dual\ BSD/GPL| | |
6014 | Dual\ MIT/GPL| | |
6015 | Dual\ MPL/GPL| | |
6016 | Proprietary | |
6017 | }x; | |
6018 | if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { | |
6019 | WARN("MODULE_LICENSE", | |
6020 | "unknown module license " . $extracted_string . "\n" . $herecurr); | |
6021 | } | |
6022 | } | |
13214adf AW |
6023 | } |
6024 | ||
6025 | # If we have no input at all, then there is nothing to report on | |
6026 | # so just keep quiet. | |
6027 | if ($#rawlines == -1) { | |
6028 | exit(0); | |
0a920b5b AW |
6029 | } |
6030 | ||
8905a67c AW |
6031 | # In mailback mode only produce a report in the negative, for |
6032 | # things that appear to be patches. | |
6033 | if ($mailback && ($clean == 1 || !$is_patch)) { | |
6034 | exit(0); | |
6035 | } | |
6036 | ||
6037 | # This is not a patch, and we are are in 'no-patch' mode so | |
6038 | # just keep quiet. | |
6039 | if (!$chk_patch && !$is_patch) { | |
6040 | exit(0); | |
6041 | } | |
6042 | ||
06330fc4 | 6043 | if (!$is_patch && $file !~ /cover-letter\.patch$/) { |
000d1cc1 JP |
6044 | ERROR("NOT_UNIFIED_DIFF", |
6045 | "Does not appear to be a unified-diff format patch\n"); | |
0a920b5b | 6046 | } |
34d8815f | 6047 | if ($is_patch && $filename ne '-' && $chk_signoff && $signoff == 0) { |
000d1cc1 JP |
6048 | ERROR("MISSING_SIGN_OFF", |
6049 | "Missing Signed-off-by: line(s)\n"); | |
0a920b5b AW |
6050 | } |
6051 | ||
8905a67c | 6052 | print report_dump(); |
13214adf AW |
6053 | if ($summary && !($clean == 1 && $quiet == 1)) { |
6054 | print "$filename " if ($summary_file); | |
8905a67c AW |
6055 | print "total: $cnt_error errors, $cnt_warn warnings, " . |
6056 | (($check)? "$cnt_chk checks, " : "") . | |
6057 | "$cnt_lines lines checked\n"; | |
f0a594c1 | 6058 | } |
8905a67c | 6059 | |
d2c0a235 | 6060 | if ($quiet == 0) { |
ef212196 JP |
6061 | # If there were any defects found and not already fixing them |
6062 | if (!$clean and !$fix) { | |
6063 | print << "EOM" | |
6064 | ||
6065 | NOTE: For some of the reported defects, checkpatch may be able to | |
6066 | mechanically convert to the typical style using --fix or --fix-inplace. | |
6067 | EOM | |
6068 | } | |
d2c0a235 AW |
6069 | # If there were whitespace errors which cleanpatch can fix |
6070 | # then suggest that. | |
6071 | if ($rpt_cleaners) { | |
b0781216 | 6072 | $rpt_cleaners = 0; |
d8469f16 JP |
6073 | print << "EOM" |
6074 | ||
6075 | NOTE: Whitespace errors detected. | |
6076 | You may wish to use scripts/cleanpatch or scripts/cleanfile | |
6077 | EOM | |
d2c0a235 AW |
6078 | } |
6079 | } | |
6080 | ||
d752fcc8 JP |
6081 | if ($clean == 0 && $fix && |
6082 | ("@rawlines" ne "@fixed" || | |
6083 | $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { | |
9624b8d6 JP |
6084 | my $newfile = $filename; |
6085 | $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); | |
3705ce5b JP |
6086 | my $linecount = 0; |
6087 | my $f; | |
6088 | ||
d752fcc8 JP |
6089 | @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); |
6090 | ||
3705ce5b JP |
6091 | open($f, '>', $newfile) |
6092 | or die "$P: Can't open $newfile for write\n"; | |
6093 | foreach my $fixed_line (@fixed) { | |
6094 | $linecount++; | |
6095 | if ($file) { | |
6096 | if ($linecount > 3) { | |
6097 | $fixed_line =~ s/^\+//; | |
d752fcc8 | 6098 | print $f $fixed_line . "\n"; |
3705ce5b JP |
6099 | } |
6100 | } else { | |
6101 | print $f $fixed_line . "\n"; | |
6102 | } | |
6103 | } | |
6104 | close($f); | |
6105 | ||
6106 | if (!$quiet) { | |
6107 | print << "EOM"; | |
d8469f16 | 6108 | |
3705ce5b JP |
6109 | Wrote EXPERIMENTAL --fix correction(s) to '$newfile' |
6110 | ||
6111 | Do _NOT_ trust the results written to this file. | |
6112 | Do _NOT_ submit these changes without inspecting them for correctness. | |
6113 | ||
6114 | This EXPERIMENTAL file is simply a convenience to help rewrite patches. | |
6115 | No warranties, expressed or implied... | |
3705ce5b JP |
6116 | EOM |
6117 | } | |
6118 | } | |
6119 | ||
d8469f16 JP |
6120 | if ($quiet == 0) { |
6121 | print "\n"; | |
6122 | if ($clean == 1) { | |
6123 | print "$vname has no obvious style problems and is ready for submission.\n"; | |
6124 | } else { | |
6125 | print "$vname has style problems, please review.\n"; | |
6126 | } | |
0a920b5b AW |
6127 | } |
6128 | return $clean; | |
6129 | } |