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