blob: 05d3579c89dd8a8c4bf39ec3330755ebf01ffeef [file] [log] [blame]
Anas Nashif1eb244c2017-10-01 17:06:36 -04001#!/usr/bin/env perl
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002# (c) 2001, Dave Jones. (the file handling bit)
3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
6# Licensed under the terms of the GNU GPL License version 2
7
8use strict;
Anas Nashif1eb244c2017-10-01 17:06:36 -04009use warnings;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070010use POSIX;
Anas Nashifcbfb62c2015-10-14 06:08:54 -040011use File::Basename;
12use Cwd 'abs_path';
13use Term::ANSIColor qw(:constants);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070014
15my $P = $0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -040016my $D = dirname(abs_path($P));
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070017
18my $V = '0.32';
19
20use Getopt::Long qw(:config no_auto_abbrev);
21
22my $quiet = 0;
23my $tree = 1;
24my $chk_signoff = 1;
25my $chk_patch = 1;
26my $tst_only;
27my $emacs = 0;
28my $terse = 0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -040029my $showfile = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070030my $file = 0;
Anas Nashif0f3d5472016-11-07 15:57:57 -050031my $git = 0;
32my %git_commits = ();
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070033my $check = 0;
34my $check_orig = 0;
35my $summary = 1;
36my $mailback = 0;
37my $summary_file = 0;
38my $show_types = 0;
Anas Nashif0f3d5472016-11-07 15:57:57 -050039my $list_types = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070040my $fix = 0;
41my $fix_inplace = 0;
42my $root;
43my %debug;
44my %camelcase = ();
45my %use_type = ();
46my @use = ();
47my %ignore_type = ();
48my @ignore = ();
Anas Nashif0f3d5472016-11-07 15:57:57 -050049my @exclude = ();
Anas Nashif1eb244c2017-10-01 17:06:36 -040050my $help = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070051my $configuration_file = ".checkpatch.conf";
52my $max_line_length = 80;
53my $ignore_perl_version = 0;
54my $minimum_perl_version = 5.10.0;
55my $min_conf_desc_length = 4;
56my $spelling_file = "$D/spelling.txt";
Anas Nashifcbfb62c2015-10-14 06:08:54 -040057my $codespell = 0;
58my $codespellfile = "/usr/share/codespell/dictionary.txt";
Anas Nashif0f3d5472016-11-07 15:57:57 -050059my $conststructsfile = "$D/const_structs.checkpatch";
Anas Nashif1eb244c2017-10-01 17:06:36 -040060my $typedefsfile = "";
61my $color = "auto";
Anas Nashifda871292017-04-21 08:52:01 -040062my $allow_c99_comments = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070063
64sub help {
65 my ($exitcode) = @_;
66
67 print << "EOM";
68Usage: $P [OPTION]... [FILE]...
69Version: $V
70
71Options:
72 -q, --quiet quiet
73 --no-tree run without a kernel tree
74 --no-signoff do not check for 'Signed-off-by' line
75 --patch treat FILE as patchfile (default)
76 --emacs emacs compile window format
77 --terse one line per report
Anas Nashifcbfb62c2015-10-14 06:08:54 -040078 --showfile emit diffed file position, not input file position
Anas Nashif0f3d5472016-11-07 15:57:57 -050079 -g, --git treat FILE as a single commit or git revision range
80 single git commit with:
81 <rev>
82 <rev>^
83 <rev>~n
84 multiple git commits with:
85 <rev1>..<rev2>
86 <rev1>...<rev2>
87 <rev>-<count>
88 git merges are ignored
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070089 -f, --file treat FILE as regular source file
90 --subjective, --strict enable more subjective tests
Anas Nashif0f3d5472016-11-07 15:57:57 -050091 --list-types list the possible message types
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070092 --types TYPE(,TYPE2...) show only these comma separated message types
93 --ignore TYPE(,TYPE2...) ignore various comma separated message types
Anas Nashif92a12a12016-05-20 18:26:59 -040094 --exclude DIR(,DIR22...) exclude directories
Anas Nashif1eb244c2017-10-01 17:06:36 -040095 --show-types show the specific message type in the output
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070096 --max-line-length=n set the maximum line length, if exceeded, warn
97 --min-conf-desc-length=n set the min description length, if shorter, warn
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070098 --root=PATH PATH to the kernel tree root
99 --no-summary suppress the per-file summary
100 --mailback only produce a report in case of warnings/errors
101 --summary-file include the filename in summary
102 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
103 'values', 'possible', 'type', and 'attr' (default
104 is all off)
105 --test-only=WORD report only warnings/errors containing WORD
106 literally
107 --fix EXPERIMENTAL - may create horrible results
108 If correctable single-line errors exist, create
109 "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
110 with potential errors corrected to the preferred
111 checkpatch style
112 --fix-inplace EXPERIMENTAL - may create horrible results
113 Is the same as --fix, but overwrites the input
114 file. It's your fault if there's no backup or git
115 --ignore-perl-version override checking of perl version. expect
116 runtime errors.
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400117 --codespell Use the codespell dictionary for spelling/typos
118 (default:/usr/share/codespell/dictionary.txt)
119 --codespellfile Use this codespell dictionary
Anas Nashif1eb244c2017-10-01 17:06:36 -0400120 --typedefsfile Read additional types from this file
121 --color[=WHEN] Use colors 'always', 'never', or only when output
122 is a terminal ('auto'). Default is 'auto'.
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700123 -h, --help, --version display this help and exit
124
125When FILE is - read standard input.
126EOM
127
128 exit($exitcode);
129}
130
Anas Nashif0f3d5472016-11-07 15:57:57 -0500131sub uniq {
132 my %seen;
133 return grep { !$seen{$_}++ } @_;
134}
135
136sub list_types {
137 my ($exitcode) = @_;
138
139 my $count = 0;
140
141 local $/ = undef;
142
143 open(my $script, '<', abs_path($P)) or
144 die "$P: Can't read '$P' $!\n";
145
146 my $text = <$script>;
147 close($script);
148
149 my @types = ();
Anas Nashif1eb244c2017-10-01 17:06:36 -0400150 # Also catch when type or level is passed through a variable
151 for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
Anas Nashif0f3d5472016-11-07 15:57:57 -0500152 push (@types, $_);
153 }
154 @types = sort(uniq(@types));
155 print("#\tMessage type\n\n");
156 foreach my $type (@types) {
157 print(++$count . "\t" . $type . "\n");
158 }
159
160 exit($exitcode);
161}
162
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700163my $conf = which_conf($configuration_file);
164if (-f $conf) {
165 my @conf_args;
166 open(my $conffile, '<', "$conf")
167 or warn "$P: Can't find a readable $configuration_file file $!\n";
168
169 while (<$conffile>) {
170 my $line = $_;
171
172 $line =~ s/\s*\n?$//g;
173 $line =~ s/^\s*//g;
174 $line =~ s/\s+/ /g;
175
176 next if ($line =~ m/^\s*#/);
177 next if ($line =~ m/^\s*$/);
178
179 my @words = split(" ", $line);
180 foreach my $word (@words) {
181 last if ($word =~ m/^#/);
182 push (@conf_args, $word);
183 }
184 }
185 close($conffile);
186 unshift(@ARGV, @conf_args) if @conf_args;
187}
188
Anas Nashif1eb244c2017-10-01 17:06:36 -0400189# Perl's Getopt::Long allows options to take optional arguments after a space.
190# Prevent --color by itself from consuming other arguments
191foreach (@ARGV) {
192 if ($_ eq "--color" || $_ eq "-color") {
193 $_ = "--color=$color";
194 }
195}
196
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700197GetOptions(
198 'q|quiet+' => \$quiet,
199 'tree!' => \$tree,
200 'signoff!' => \$chk_signoff,
201 'patch!' => \$chk_patch,
202 'emacs!' => \$emacs,
203 'terse!' => \$terse,
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400204 'showfile!' => \$showfile,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700205 'f|file!' => \$file,
Anas Nashif0f3d5472016-11-07 15:57:57 -0500206 'g|git!' => \$git,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700207 'subjective!' => \$check,
208 'strict!' => \$check,
209 'ignore=s' => \@ignore,
Anas Nashif1eb244c2017-10-01 17:06:36 -0400210 'exclude=s' => \@exclude,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700211 'types=s' => \@use,
212 'show-types!' => \$show_types,
Anas Nashif0f3d5472016-11-07 15:57:57 -0500213 'list-types!' => \$list_types,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700214 'max-line-length=i' => \$max_line_length,
215 'min-conf-desc-length=i' => \$min_conf_desc_length,
216 'root=s' => \$root,
217 'summary!' => \$summary,
218 'mailback!' => \$mailback,
219 'summary-file!' => \$summary_file,
220 'fix!' => \$fix,
221 'fix-inplace!' => \$fix_inplace,
222 'ignore-perl-version!' => \$ignore_perl_version,
223 'debug=s' => \%debug,
224 'test-only=s' => \$tst_only,
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400225 'codespell!' => \$codespell,
226 'codespellfile=s' => \$codespellfile,
Anas Nashif1eb244c2017-10-01 17:06:36 -0400227 'typedefsfile=s' => \$typedefsfile,
228 'color=s' => \$color,
229 'no-color' => \$color, #keep old behaviors of -nocolor
230 'nocolor' => \$color, #keep old behaviors of -nocolor
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700231 'h|help' => \$help,
232 'version' => \$help
233) or help(1);
234
235help(0) if ($help);
236
Anas Nashif0f3d5472016-11-07 15:57:57 -0500237list_types(0) if ($list_types);
238
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700239$fix = 1 if ($fix_inplace);
240$check_orig = $check;
241
242my $exit = 0;
243
244if ($^V && $^V lt $minimum_perl_version) {
245 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
246 if (!$ignore_perl_version) {
247 exit(1);
248 }
249}
250
Anas Nashif0f3d5472016-11-07 15:57:57 -0500251#if no filenames are given, push '-' to read patch from stdin
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700252if ($#ARGV < 0) {
Anas Nashif0f3d5472016-11-07 15:57:57 -0500253 push(@ARGV, '-');
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700254}
255
Anas Nashif1eb244c2017-10-01 17:06:36 -0400256if ($color =~ /^[01]$/) {
257 $color = !$color;
258} elsif ($color =~ /^always$/i) {
259 $color = 1;
260} elsif ($color =~ /^never$/i) {
261 $color = 0;
262} elsif ($color =~ /^auto$/i) {
263 $color = (-t STDOUT);
264} else {
265 die "Invalid color mode: $color\n";
266}
267
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700268sub hash_save_array_words {
269 my ($hashRef, $arrayRef) = @_;
270
271 my @array = split(/,/, join(',', @$arrayRef));
272 foreach my $word (@array) {
273 $word =~ s/\s*\n?$//g;
274 $word =~ s/^\s*//g;
275 $word =~ s/\s+/ /g;
276 $word =~ tr/[a-z]/[A-Z]/;
277
278 next if ($word =~ m/^\s*#/);
279 next if ($word =~ m/^\s*$/);
280
281 $hashRef->{$word}++;
282 }
283}
284
285sub hash_show_words {
286 my ($hashRef, $prefix) = @_;
287
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400288 if (keys %$hashRef) {
289 print "\nNOTE: $prefix message types:";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700290 foreach my $word (sort keys %$hashRef) {
291 print " $word";
292 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400293 print "\n";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700294 }
295}
296
297hash_save_array_words(\%ignore_type, \@ignore);
298hash_save_array_words(\%use_type, \@use);
299
300my $dbg_values = 0;
301my $dbg_possible = 0;
302my $dbg_type = 0;
303my $dbg_attr = 0;
304for my $key (keys %debug) {
305 ## no critic
306 eval "\${dbg_$key} = '$debug{$key}';";
307 die "$@" if ($@);
308}
309
310my $rpt_cleaners = 0;
311
312if ($terse) {
313 $emacs = 1;
314 $quiet++;
315}
316
317if ($tree) {
318 if (defined $root) {
319 if (!top_of_kernel_tree($root)) {
320 die "$P: $root: --root does not point at a valid tree\n";
321 }
322 } else {
323 if (top_of_kernel_tree('.')) {
324 $root = '.';
325 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
326 top_of_kernel_tree($1)) {
327 $root = $1;
328 }
329 }
330
331 if (!defined $root) {
332 print "Must be run from the top-level dir. of a kernel tree\n";
333 exit(2);
334 }
335}
336
337my $emitted_corrupt = 0;
338
339our $Ident = qr{
340 [A-Za-z_][A-Za-z\d_]*
341 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
342 }x;
343our $Storage = qr{extern|static|asmlinkage};
344our $Sparse = qr{
345 __user|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700346 __force|
347 __iomem|
348 __must_check|
349 __init_refok|
350 __kprobes|
351 __ref|
Anas Nashif0f3d5472016-11-07 15:57:57 -0500352 __rcu|
353 __private
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700354 }x;
355our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
356our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
357our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
358our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
359our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
360
361# Notes to $Attribute:
362# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
363our $Attribute = qr{
364 const|
365 __percpu|
366 __nocast|
367 __safe|
Anas Nashif1eb244c2017-10-01 17:06:36 -0400368 __bitwise|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700369 __packed__|
370 __packed2__|
371 __naked|
372 __maybe_unused|
373 __always_unused|
374 __noreturn|
375 __used|
376 __cold|
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400377 __pure|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700378 __noclone|
379 __deprecated|
380 __read_mostly|
381 __kprobes|
382 $InitAttribute|
383 ____cacheline_aligned|
384 ____cacheline_aligned_in_smp|
385 ____cacheline_internodealigned_in_smp|
Andrew Boiefa94ee72017-09-28 16:54:35 -0700386 __weak|
Flavio Ceoline86ec972019-12-03 13:49:54 -0800387 __syscall
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700388 }x;
389our $Modifier;
390our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
391our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
392our $Lval = qr{$Ident(?:$Member)*};
393
394our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
395our $Binary = qr{(?i)0b[01]+$Int_type?};
396our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
397our $Int = qr{[0-9]+$Int_type?};
398our $Octal = qr{0[0-7]+$Int_type?};
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400399our $String = qr{"[X\t]*"};
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700400our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
401our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
402our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
403our $Float = qr{$Float_hex|$Float_dec|$Float_int};
404our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
405our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
406our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
407our $Arithmetic = qr{\+|-|\*|\/|%};
408our $Operators = qr{
409 <=|>=|==|!=|
410 =>|->|<<|>>|<|>|!|~|
411 &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
412 }x;
413
414our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
415
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400416our $BasicType;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700417our $NonptrType;
418our $NonptrTypeMisordered;
419our $NonptrTypeWithAttr;
420our $Type;
421our $TypeMisordered;
422our $Declare;
423our $DeclareMisordered;
424
425our $NON_ASCII_UTF8 = qr{
426 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
427 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
428 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
429 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
430 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
431 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
432 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
433}x;
434
435our $UTF8 = qr{
436 [\x09\x0A\x0D\x20-\x7E] # ASCII
437 | $NON_ASCII_UTF8
438}x;
439
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400440our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
441our $typeOtherOSTypedefs = qr{(?x:
442 u_(?:char|short|int|long) | # bsd
443 u(?:nchar|short|int|long) # sysv
444)};
445our $typeKernelTypedefs = qr{(?x:
Kumar Galaa48e8792017-04-21 10:53:05 -0500446 (?:__)?(?:u|s|be|le)(?:8|16|32|64)_t|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700447 atomic_t
448)};
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400449our $typeTypedefs = qr{(?x:
450 $typeC99Typedefs\b|
451 $typeOtherOSTypedefs\b|
452 $typeKernelTypedefs\b
453)};
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700454
Anas Nashif76b09132016-02-20 13:53:35 -0500455our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
456
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700457our $logFunctions = qr{(?x:
Anas Nashif1eb244c2017-10-01 17:06:36 -0400458 printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700459 (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
460 WARN(?:_RATELIMIT|_ONCE|)|
461 panic|
462 MODULE_[A-Z_]+|
463 seq_vprintf|seq_printf|seq_puts
464)};
465
466our $signature_tags = qr{(?xi:
467 Signed-off-by:|
468 Acked-by:|
469 Tested-by:|
470 Reviewed-by:|
471 Reported-by:|
472 Suggested-by:|
473 To:|
474 Cc:
475)};
476
477our @typeListMisordered = (
478 qr{char\s+(?:un)?signed},
479 qr{int\s+(?:(?:un)?signed\s+)?short\s},
480 qr{int\s+short(?:\s+(?:un)?signed)},
481 qr{short\s+int(?:\s+(?:un)?signed)},
482 qr{(?:un)?signed\s+int\s+short},
483 qr{short\s+(?:un)?signed},
484 qr{long\s+int\s+(?:un)?signed},
485 qr{int\s+long\s+(?:un)?signed},
486 qr{long\s+(?:un)?signed\s+int},
487 qr{int\s+(?:un)?signed\s+long},
488 qr{int\s+(?:un)?signed},
489 qr{int\s+long\s+long\s+(?:un)?signed},
490 qr{long\s+long\s+int\s+(?:un)?signed},
491 qr{long\s+long\s+(?:un)?signed\s+int},
492 qr{long\s+long\s+(?:un)?signed},
493 qr{long\s+(?:un)?signed},
494);
495
496our @typeList = (
497 qr{void},
498 qr{(?:(?:un)?signed\s+)?char},
499 qr{(?:(?:un)?signed\s+)?short\s+int},
500 qr{(?:(?:un)?signed\s+)?short},
501 qr{(?:(?:un)?signed\s+)?int},
502 qr{(?:(?:un)?signed\s+)?long\s+int},
503 qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
504 qr{(?:(?:un)?signed\s+)?long\s+long},
505 qr{(?:(?:un)?signed\s+)?long},
506 qr{(?:un)?signed},
507 qr{float},
508 qr{double},
509 qr{bool},
510 qr{struct\s+$Ident},
511 qr{union\s+$Ident},
512 qr{enum\s+$Ident},
513 qr{${Ident}_t},
514 qr{${Ident}_handler},
515 qr{${Ident}_handler_fn},
516 @typeListMisordered,
517);
Anas Nashif76b09132016-02-20 13:53:35 -0500518
519our $C90_int_types = qr{(?x:
520 long\s+long\s+int\s+(?:un)?signed|
521 long\s+long\s+(?:un)?signed\s+int|
522 long\s+long\s+(?:un)?signed|
523 (?:(?:un)?signed\s+)?long\s+long\s+int|
524 (?:(?:un)?signed\s+)?long\s+long|
525 int\s+long\s+long\s+(?:un)?signed|
526 int\s+(?:(?:un)?signed\s+)?long\s+long|
527
528 long\s+int\s+(?:un)?signed|
529 long\s+(?:un)?signed\s+int|
530 long\s+(?:un)?signed|
531 (?:(?:un)?signed\s+)?long\s+int|
532 (?:(?:un)?signed\s+)?long|
533 int\s+long\s+(?:un)?signed|
534 int\s+(?:(?:un)?signed\s+)?long|
535
536 int\s+(?:un)?signed|
537 (?:(?:un)?signed\s+)?int
538)};
539
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400540our @typeListFile = ();
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700541our @typeListWithAttr = (
542 @typeList,
543 qr{struct\s+$InitAttribute\s+$Ident},
544 qr{union\s+$InitAttribute\s+$Ident},
545);
546
547our @modifierList = (
548 qr{fastcall},
549);
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400550our @modifierListFile = ();
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700551
552our @mode_permission_funcs = (
553 ["module_param", 3],
554 ["module_param_(?:array|named|string)", 4],
555 ["module_param_array_named", 5],
556 ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
557 ["proc_create(?:_data|)", 2],
Anas Nashif0f3d5472016-11-07 15:57:57 -0500558 ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
559 ["IIO_DEV_ATTR_[A-Z_]+", 1],
560 ["SENSOR_(?:DEVICE_|)ATTR_2", 2],
561 ["SENSOR_TEMPLATE(?:_2|)", 3],
562 ["__ATTR", 2],
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700563);
564
565#Create a search pattern for all these functions to speed up a loop below
566our $mode_perms_search = "";
567foreach my $entry (@mode_permission_funcs) {
568 $mode_perms_search .= '|' if ($mode_perms_search ne "");
569 $mode_perms_search .= $entry->[0];
570}
571
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400572our $mode_perms_world_writable = qr{
573 S_IWUGO |
574 S_IWOTH |
575 S_IRWXUGO |
576 S_IALLUGO |
577 0[0-7][0-7][2367]
578}x;
579
Anas Nashif0f3d5472016-11-07 15:57:57 -0500580our %mode_permission_string_types = (
581 "S_IRWXU" => 0700,
582 "S_IRUSR" => 0400,
583 "S_IWUSR" => 0200,
584 "S_IXUSR" => 0100,
585 "S_IRWXG" => 0070,
586 "S_IRGRP" => 0040,
587 "S_IWGRP" => 0020,
588 "S_IXGRP" => 0010,
589 "S_IRWXO" => 0007,
590 "S_IROTH" => 0004,
591 "S_IWOTH" => 0002,
592 "S_IXOTH" => 0001,
593 "S_IRWXUGO" => 0777,
594 "S_IRUGO" => 0444,
595 "S_IWUGO" => 0222,
596 "S_IXUGO" => 0111,
597);
598
599#Create a search pattern for all these strings to speed up a loop below
600our $mode_perms_string_search = "";
601foreach my $entry (keys %mode_permission_string_types) {
602 $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
603 $mode_perms_string_search .= $entry;
604}
605
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700606our $allowed_asm_includes = qr{(?x:
607 irq|
608 memory|
609 time|
610 reboot
611)};
612# memory.h: ARM has a custom one
613
614# Load common spelling mistakes and build regular expression list.
615my $misspellings;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700616my %spelling_fix;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700617
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400618if (open(my $spelling, '<', $spelling_file)) {
619 while (<$spelling>) {
620 my $line = $_;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700621
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400622 $line =~ s/\s*\n?$//g;
623 $line =~ s/^\s*//g;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700624
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400625 next if ($line =~ m/^\s*#/);
626 next if ($line =~ m/^\s*$/);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700627
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400628 my ($suspect, $fix) = split(/\|\|/, $line);
629
630 $spelling_fix{$suspect} = $fix;
631 }
632 close($spelling);
633} else {
634 warn "No typos will be found - file '$spelling_file': $!\n";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700635}
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400636
637if ($codespell) {
638 if (open(my $spelling, '<', $codespellfile)) {
639 while (<$spelling>) {
640 my $line = $_;
641
642 $line =~ s/\s*\n?$//g;
643 $line =~ s/^\s*//g;
644
645 next if ($line =~ m/^\s*#/);
646 next if ($line =~ m/^\s*$/);
647 next if ($line =~ m/, disabled/i);
648
649 $line =~ s/,.*$//;
650
651 my ($suspect, $fix) = split(/->/, $line);
652
653 $spelling_fix{$suspect} = $fix;
654 }
655 close($spelling);
656 } else {
657 warn "No codespell typos will be found - file '$codespellfile': $!\n";
658 }
659}
660
661$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700662
Anas Nashif1eb244c2017-10-01 17:06:36 -0400663sub read_words {
664 my ($wordsRef, $file) = @_;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500665
Anas Nashif1eb244c2017-10-01 17:06:36 -0400666 if (open(my $words, '<', $file)) {
667 while (<$words>) {
668 my $line = $_;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500669
Anas Nashif1eb244c2017-10-01 17:06:36 -0400670 $line =~ s/\s*\n?$//g;
671 $line =~ s/^\s*//g;
672
673 next if ($line =~ m/^\s*#/);
674 next if ($line =~ m/^\s*$/);
675 if ($line =~ /\s/) {
676 print("$file: '$line' invalid - ignored\n");
677 next;
678 }
679
680 $$wordsRef .= '|' if ($$wordsRef ne "");
681 $$wordsRef .= $line;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500682 }
Anas Nashif1eb244c2017-10-01 17:06:36 -0400683 close($file);
684 return 1;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500685 }
Anas Nashif1eb244c2017-10-01 17:06:36 -0400686
687 return 0;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500688}
689
Anas Nashif1eb244c2017-10-01 17:06:36 -0400690my $const_structs = "";
691#read_words(\$const_structs, $conststructsfile)
692# or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
693
694my $typeOtherTypedefs = "";
695if (length($typedefsfile)) {
696 read_words(\$typeOtherTypedefs, $typedefsfile)
697 or warn "No additional types will be considered - file '$typedefsfile': $!\n";
698}
699$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
700
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700701sub build_types {
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400702 my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
703 my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700704 my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
705 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
706 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400707 $BasicType = qr{
708 (?:$typeTypedefs\b)|
709 (?:${all}\b)
710 }x;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700711 $NonptrType = qr{
712 (?:$Modifier\s+|const\s+)*
713 (?:
714 (?:typeof|__typeof__)\s*\([^\)]*\)|
715 (?:$typeTypedefs\b)|
716 (?:${all}\b)
717 )
718 (?:\s+$Modifier|\s+const)*
719 }x;
720 $NonptrTypeMisordered = qr{
721 (?:$Modifier\s+|const\s+)*
722 (?:
723 (?:${Misordered}\b)
724 )
725 (?:\s+$Modifier|\s+const)*
726 }x;
727 $NonptrTypeWithAttr = qr{
728 (?:$Modifier\s+|const\s+)*
729 (?:
730 (?:typeof|__typeof__)\s*\([^\)]*\)|
731 (?:$typeTypedefs\b)|
732 (?:${allWithAttr}\b)
733 )
734 (?:\s+$Modifier|\s+const)*
735 }x;
736 $Type = qr{
737 $NonptrType
738 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
739 (?:\s+$Inline|\s+$Modifier)*
740 }x;
741 $TypeMisordered = qr{
742 $NonptrTypeMisordered
743 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
744 (?:\s+$Inline|\s+$Modifier)*
745 }x;
746 $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
747 $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
748}
749build_types();
750
751our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
752
753# Using $balanced_parens, $LvalOrFunc, or $FuncArg
754# requires at least perl version v5.10.0
755# Any use must be runtime checked with $^V
756
757our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
758our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400759our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700760
761our $declaration_macros = qr{(?x:
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400762 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
Anas Nashif1eb244c2017-10-01 17:06:36 -0400763 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700764 (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(
765)};
766
767sub deparenthesize {
768 my ($string) = @_;
769 return "" if (!defined($string));
770
771 while ($string =~ /^\s*\(.*\)\s*$/) {
772 $string =~ s@^\s*\(\s*@@;
773 $string =~ s@\s*\)\s*$@@;
774 }
775
776 $string =~ s@\s+@ @g;
777
778 return $string;
779}
780
781sub seed_camelcase_file {
782 my ($file) = @_;
783
784 return if (!(-f $file));
785
786 local $/;
787
788 open(my $include_file, '<', "$file")
789 or warn "$P: Can't read '$file' $!\n";
790 my $text = <$include_file>;
791 close($include_file);
792
793 my @lines = split('\n', $text);
794
795 foreach my $line (@lines) {
796 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
797 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
798 $camelcase{$1} = 1;
799 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
800 $camelcase{$1} = 1;
801 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
802 $camelcase{$1} = 1;
803 }
804 }
805}
806
Anas Nashif1eb244c2017-10-01 17:06:36 -0400807sub is_maintained_obsolete {
808 my ($filename) = @_;
809
810 return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
811
812 my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
813
814 return $status =~ /obsolete/i;
815}
816
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700817my $camelcase_seeded = 0;
818sub seed_camelcase_includes {
819 return if ($camelcase_seeded);
820
821 my $files;
822 my $camelcase_cache = "";
823 my @include_files = ();
824
825 $camelcase_seeded = 1;
826
827 if (-e ".git") {
828 my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
829 chomp $git_last_include_commit;
830 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
831 } else {
832 my $last_mod_date = 0;
833 $files = `find $root/include -name "*.h"`;
834 @include_files = split('\n', $files);
835 foreach my $file (@include_files) {
836 my $date = POSIX::strftime("%Y%m%d%H%M",
837 localtime((stat $file)[9]));
838 $last_mod_date = $date if ($last_mod_date < $date);
839 }
840 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
841 }
842
843 if ($camelcase_cache ne "" && -f $camelcase_cache) {
844 open(my $camelcase_file, '<', "$camelcase_cache")
845 or warn "$P: Can't read '$camelcase_cache' $!\n";
846 while (<$camelcase_file>) {
847 chomp;
848 $camelcase{$_} = 1;
849 }
850 close($camelcase_file);
851
852 return;
853 }
854
855 if (-e ".git") {
856 $files = `git ls-files "include/*.h"`;
857 @include_files = split('\n', $files);
858 }
859
860 foreach my $file (@include_files) {
861 seed_camelcase_file($file);
862 }
863
864 if ($camelcase_cache ne "") {
865 unlink glob ".checkpatch-camelcase.*";
866 open(my $camelcase_file, '>', "$camelcase_cache")
867 or warn "$P: Can't write '$camelcase_cache' $!\n";
868 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
869 print $camelcase_file ("$_\n");
870 }
871 close($camelcase_file);
872 }
873}
874
875sub git_commit_info {
876 my ($commit, $id, $desc) = @_;
877
878 return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
879
880 my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
881 $output =~ s/^\s*//gm;
882 my @lines = split("\n", $output);
883
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400884 return ($id, $desc) if ($#lines < 0);
885
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700886 if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
887# Maybe one day convert this block of bash into something that returns
888# all matching commit ids, but it's very slow...
889#
890# echo "checking commits $1..."
891# git rev-list --remotes | grep -i "^$1" |
892# while read line ; do
893# git log --format='%H %s' -1 $line |
894# echo "commit $(cut -c 1-12,41-)"
895# done
896 } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
Anas Nashif1eb244c2017-10-01 17:06:36 -0400897 $id = undef;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700898 } else {
899 $id = substr($lines[0], 0, 12);
900 $desc = substr($lines[0], 41);
901 }
902
903 return ($id, $desc);
904}
905
906$chk_signoff = 0 if ($file);
907
908my @rawlines = ();
909my @lines = ();
910my @fixed = ();
911my @fixed_inserted = ();
912my @fixed_deleted = ();
913my $fixlinenr = -1;
914
Anas Nashif0f3d5472016-11-07 15:57:57 -0500915# If input is git commits, extract all commits from the commit expressions.
916# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
917die "$P: No git repository found\n" if ($git && !-e ".git");
918
919if ($git) {
920 my @commits = ();
921 foreach my $commit_expr (@ARGV) {
922 my $git_range;
923 if ($commit_expr =~ m/^(.*)-(\d+)$/) {
924 $git_range = "-$2 $1";
925 } elsif ($commit_expr =~ m/\.\./) {
926 $git_range = "$commit_expr";
927 } else {
928 $git_range = "-1 $commit_expr";
929 }
930 my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
931 foreach my $line (split(/\n/, $lines)) {
932 $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
933 next if (!defined($1) || !defined($2));
934 my $sha1 = $1;
935 my $subject = $2;
936 unshift(@commits, $sha1);
937 $git_commits{$sha1} = $subject;
938 }
939 }
940 die "$P: no git commits after extraction!\n" if (@commits == 0);
941 @ARGV = @commits;
942}
943
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700944my $vname;
945for my $filename (@ARGV) {
946 my $FILE;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500947 if ($git) {
948 open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
949 die "$P: $filename: git format-patch failed - $!\n";
950 } elsif ($file) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700951 open($FILE, '-|', "diff -u /dev/null $filename") ||
952 die "$P: $filename: diff failed - $!\n";
953 } elsif ($filename eq '-') {
954 open($FILE, '<&STDIN');
955 } else {
956 open($FILE, '<', "$filename") ||
957 die "$P: $filename: open failed - $!\n";
958 }
959 if ($filename eq '-') {
960 $vname = 'Your patch';
Anas Nashif0f3d5472016-11-07 15:57:57 -0500961 } elsif ($git) {
962 $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700963 } else {
964 $vname = $filename;
965 }
966 while (<$FILE>) {
967 chomp;
968 push(@rawlines, $_);
969 }
970 close($FILE);
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400971
972 if ($#ARGV > 0 && $quiet == 0) {
973 print '-' x length($vname) . "\n";
974 print "$vname\n";
975 print '-' x length($vname) . "\n";
976 }
977
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700978 if (!process($filename)) {
979 $exit = 1;
980 }
981 @rawlines = ();
982 @lines = ();
983 @fixed = ();
984 @fixed_inserted = ();
985 @fixed_deleted = ();
986 $fixlinenr = -1;
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400987 @modifierListFile = ();
988 @typeListFile = ();
989 build_types();
990}
991
992if (!$quiet) {
993 hash_show_words(\%use_type, "Used");
994 hash_show_words(\%ignore_type, "Ignored");
995
996 if ($^V lt 5.10.0) {
997 print << "EOM"
998
999NOTE: perl $^V is not modern enough to detect all possible issues.
1000 An upgrade to at least perl v5.10.0 is suggested.
1001EOM
1002 }
1003 if ($exit) {
1004 print << "EOM"
1005
1006NOTE: If any of the errors are false positives, please report
Anas Nashif1eb244c2017-10-01 17:06:36 -04001007 them to the maintainers.
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001008EOM
1009 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001010}
1011
1012exit($exit);
1013
1014sub top_of_kernel_tree {
1015 my ($root) = @_;
1016
1017 my @tree_check = (
Antony Pavlovf08148e2019-05-09 16:39:59 +03001018 "LICENSE", "CODEOWNERS", "Kconfig", "Makefile",
1019 "README.rst", "doc", "arch", "include", "drivers",
1020 "boards", "kernel", "lib", "scripts",
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001021 );
1022
1023 foreach my $check (@tree_check) {
1024 if (! -e $root . '/' . $check) {
1025 return 0;
1026 }
1027 }
1028 return 1;
1029}
1030
1031sub parse_email {
1032 my ($formatted_email) = @_;
1033
1034 my $name = "";
1035 my $address = "";
1036 my $comment = "";
1037
1038 if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
1039 $name = $1;
1040 $address = $2;
1041 $comment = $3 if defined $3;
1042 } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
1043 $address = $1;
1044 $comment = $2 if defined $2;
1045 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1046 $address = $1;
1047 $comment = $2 if defined $2;
1048 $formatted_email =~ s/$address.*$//;
1049 $name = $formatted_email;
1050 $name = trim($name);
1051 $name =~ s/^\"|\"$//g;
1052 # If there's a name left after stripping spaces and
1053 # leading quotes, and the address doesn't have both
1054 # leading and trailing angle brackets, the address
1055 # is invalid. ie:
1056 # "joe smith joe@smith.com" bad
1057 # "joe smith <joe@smith.com" bad
1058 if ($name ne "" && $address !~ /^<[^>]+>$/) {
1059 $name = "";
1060 $address = "";
1061 $comment = "";
1062 }
1063 }
1064
1065 $name = trim($name);
1066 $name =~ s/^\"|\"$//g;
1067 $address = trim($address);
1068 $address =~ s/^\<|\>$//g;
1069
1070 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1071 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1072 $name = "\"$name\"";
1073 }
1074
1075 return ($name, $address, $comment);
1076}
1077
1078sub format_email {
1079 my ($name, $address) = @_;
1080
1081 my $formatted_email;
1082
1083 $name = trim($name);
1084 $name =~ s/^\"|\"$//g;
1085 $address = trim($address);
1086
1087 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1088 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1089 $name = "\"$name\"";
1090 }
1091
1092 if ("$name" eq "") {
1093 $formatted_email = "$address";
1094 } else {
1095 $formatted_email = "$name <$address>";
1096 }
1097
1098 return $formatted_email;
1099}
1100
1101sub which {
1102 my ($bin) = @_;
1103
1104 foreach my $path (split(/:/, $ENV{PATH})) {
1105 if (-e "$path/$bin") {
1106 return "$path/$bin";
1107 }
1108 }
1109
1110 return "";
1111}
1112
1113sub which_conf {
1114 my ($conf) = @_;
1115
1116 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1117 if (-e "$path/$conf") {
1118 return "$path/$conf";
1119 }
1120 }
1121
1122 return "";
1123}
1124
1125sub expand_tabs {
1126 my ($str) = @_;
1127
1128 my $res = '';
1129 my $n = 0;
1130 for my $c (split(//, $str)) {
1131 if ($c eq "\t") {
1132 $res .= ' ';
1133 $n++;
1134 for (; ($n % 8) != 0; $n++) {
1135 $res .= ' ';
1136 }
1137 next;
1138 }
1139 $res .= $c;
1140 $n++;
1141 }
1142
1143 return $res;
1144}
1145sub copy_spacing {
1146 (my $res = shift) =~ tr/\t/ /c;
1147 return $res;
1148}
1149
1150sub line_stats {
1151 my ($line) = @_;
1152
1153 # Drop the diff line leader and expand tabs
1154 $line =~ s/^.//;
1155 $line = expand_tabs($line);
1156
1157 # Pick the indent from the front of the line.
1158 my ($white) = ($line =~ /^(\s*)/);
1159
1160 return (length($line), length($white));
1161}
1162
1163my $sanitise_quote = '';
1164
1165sub sanitise_line_reset {
1166 my ($in_comment) = @_;
1167
1168 if ($in_comment) {
1169 $sanitise_quote = '*/';
1170 } else {
1171 $sanitise_quote = '';
1172 }
1173}
1174sub sanitise_line {
1175 my ($line) = @_;
1176
1177 my $res = '';
1178 my $l = '';
1179
1180 my $qlen = 0;
1181 my $off = 0;
1182 my $c;
1183
1184 # Always copy over the diff marker.
1185 $res = substr($line, 0, 1);
1186
1187 for ($off = 1; $off < length($line); $off++) {
1188 $c = substr($line, $off, 1);
1189
1190 # Comments we are wacking completly including the begin
1191 # and end, all to $;.
1192 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1193 $sanitise_quote = '*/';
1194
1195 substr($res, $off, 2, "$;$;");
1196 $off++;
1197 next;
1198 }
1199 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1200 $sanitise_quote = '';
1201 substr($res, $off, 2, "$;$;");
1202 $off++;
1203 next;
1204 }
1205 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1206 $sanitise_quote = '//';
1207
1208 substr($res, $off, 2, $sanitise_quote);
1209 $off++;
1210 next;
1211 }
1212
1213 # A \ in a string means ignore the next character.
1214 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1215 $c eq "\\") {
1216 substr($res, $off, 2, 'XX');
1217 $off++;
1218 next;
1219 }
1220 # Regular quotes.
1221 if ($c eq "'" || $c eq '"') {
1222 if ($sanitise_quote eq '') {
1223 $sanitise_quote = $c;
1224
1225 substr($res, $off, 1, $c);
1226 next;
1227 } elsif ($sanitise_quote eq $c) {
1228 $sanitise_quote = '';
1229 }
1230 }
1231
1232 #print "c<$c> SQ<$sanitise_quote>\n";
1233 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1234 substr($res, $off, 1, $;);
1235 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1236 substr($res, $off, 1, $;);
1237 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1238 substr($res, $off, 1, 'X');
1239 } else {
1240 substr($res, $off, 1, $c);
1241 }
1242 }
1243
1244 if ($sanitise_quote eq '//') {
1245 $sanitise_quote = '';
1246 }
1247
1248 # The pathname on a #include may be surrounded by '<' and '>'.
1249 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1250 my $clean = 'X' x length($1);
1251 $res =~ s@\<.*\>@<$clean>@;
1252
1253 # The whole of a #error is a string.
1254 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1255 my $clean = 'X' x length($1);
1256 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1257 }
1258
Anas Nashif0f3d5472016-11-07 15:57:57 -05001259 if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1260 my $match = $1;
1261 $res =~ s/\Q$match\E/"$;" x length($match)/e;
1262 }
1263
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001264 return $res;
1265}
1266
1267sub get_quoted_string {
1268 my ($line, $rawline) = @_;
1269
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001270 return "" if ($line !~ m/($String)/g);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001271 return substr($rawline, $-[0], $+[0] - $-[0]);
1272}
1273
1274sub ctx_statement_block {
1275 my ($linenr, $remain, $off) = @_;
1276 my $line = $linenr - 1;
1277 my $blk = '';
1278 my $soff = $off;
1279 my $coff = $off - 1;
1280 my $coff_set = 0;
1281
1282 my $loff = 0;
1283
1284 my $type = '';
1285 my $level = 0;
1286 my @stack = ();
1287 my $p;
1288 my $c;
1289 my $len = 0;
1290
1291 my $remainder;
1292 while (1) {
1293 @stack = (['', 0]) if ($#stack == -1);
1294
1295 #warn "CSB: blk<$blk> remain<$remain>\n";
1296 # If we are about to drop off the end, pull in more
1297 # context.
1298 if ($off >= $len) {
1299 for (; $remain > 0; $line++) {
1300 last if (!defined $lines[$line]);
1301 next if ($lines[$line] =~ /^-/);
1302 $remain--;
1303 $loff = $len;
1304 $blk .= $lines[$line] . "\n";
1305 $len = length($blk);
1306 $line++;
1307 last;
1308 }
1309 # Bail if there is no further context.
1310 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
1311 if ($off >= $len) {
1312 last;
1313 }
1314 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1315 $level++;
1316 $type = '#';
1317 }
1318 }
1319 $p = $c;
1320 $c = substr($blk, $off, 1);
1321 $remainder = substr($blk, $off);
1322
1323 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
1324
1325 # Handle nested #if/#else.
1326 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
1327 push(@stack, [ $type, $level ]);
1328 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
1329 ($type, $level) = @{$stack[$#stack - 1]};
1330 } elsif ($remainder =~ /^#\s*endif\b/) {
1331 ($type, $level) = @{pop(@stack)};
1332 }
1333
1334 # Statement ends at the ';' or a close '}' at the
1335 # outermost level.
1336 if ($level == 0 && $c eq ';') {
1337 last;
1338 }
1339
1340 # An else is really a conditional as long as its not else if
1341 if ($level == 0 && $coff_set == 0 &&
1342 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1343 $remainder =~ /^(else)(?:\s|{)/ &&
1344 $remainder !~ /^else\s+if\b/) {
1345 $coff = $off + length($1) - 1;
1346 $coff_set = 1;
1347 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1348 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
1349 }
1350
1351 if (($type eq '' || $type eq '(') && $c eq '(') {
1352 $level++;
1353 $type = '(';
1354 }
1355 if ($type eq '(' && $c eq ')') {
1356 $level--;
1357 $type = ($level != 0)? '(' : '';
1358
1359 if ($level == 0 && $coff < $soff) {
1360 $coff = $off;
1361 $coff_set = 1;
1362 #warn "CSB: mark coff<$coff>\n";
1363 }
1364 }
1365 if (($type eq '' || $type eq '{') && $c eq '{') {
1366 $level++;
1367 $type = '{';
1368 }
1369 if ($type eq '{' && $c eq '}') {
1370 $level--;
1371 $type = ($level != 0)? '{' : '';
1372
1373 if ($level == 0) {
1374 if (substr($blk, $off + 1, 1) eq ';') {
1375 $off++;
1376 }
1377 last;
1378 }
1379 }
1380 # Preprocessor commands end at the newline unless escaped.
1381 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1382 $level--;
1383 $type = '';
1384 $off++;
1385 last;
1386 }
1387 $off++;
1388 }
1389 # We are truly at the end, so shuffle to the next line.
1390 if ($off == $len) {
1391 $loff = $len + 1;
1392 $line++;
1393 $remain--;
1394 }
1395
1396 my $statement = substr($blk, $soff, $off - $soff + 1);
1397 my $condition = substr($blk, $soff, $coff - $soff + 1);
1398
1399 #warn "STATEMENT<$statement>\n";
1400 #warn "CONDITION<$condition>\n";
1401
1402 #print "coff<$coff> soff<$off> loff<$loff>\n";
1403
1404 return ($statement, $condition,
1405 $line, $remain + 1, $off - $loff + 1, $level);
1406}
1407
1408sub statement_lines {
1409 my ($stmt) = @_;
1410
1411 # Strip the diff line prefixes and rip blank lines at start and end.
1412 $stmt =~ s/(^|\n)./$1/g;
1413 $stmt =~ s/^\s*//;
1414 $stmt =~ s/\s*$//;
1415
1416 my @stmt_lines = ($stmt =~ /\n/g);
1417
1418 return $#stmt_lines + 2;
1419}
1420
1421sub statement_rawlines {
1422 my ($stmt) = @_;
1423
1424 my @stmt_lines = ($stmt =~ /\n/g);
1425
1426 return $#stmt_lines + 2;
1427}
1428
1429sub statement_block_size {
1430 my ($stmt) = @_;
1431
1432 $stmt =~ s/(^|\n)./$1/g;
1433 $stmt =~ s/^\s*{//;
1434 $stmt =~ s/}\s*$//;
1435 $stmt =~ s/^\s*//;
1436 $stmt =~ s/\s*$//;
1437
1438 my @stmt_lines = ($stmt =~ /\n/g);
1439 my @stmt_statements = ($stmt =~ /;/g);
1440
1441 my $stmt_lines = $#stmt_lines + 2;
1442 my $stmt_statements = $#stmt_statements + 1;
1443
1444 if ($stmt_lines > $stmt_statements) {
1445 return $stmt_lines;
1446 } else {
1447 return $stmt_statements;
1448 }
1449}
1450
1451sub ctx_statement_full {
1452 my ($linenr, $remain, $off) = @_;
1453 my ($statement, $condition, $level);
1454
1455 my (@chunks);
1456
1457 # Grab the first conditional/block pair.
1458 ($statement, $condition, $linenr, $remain, $off, $level) =
1459 ctx_statement_block($linenr, $remain, $off);
1460 #print "F: c<$condition> s<$statement> remain<$remain>\n";
1461 push(@chunks, [ $condition, $statement ]);
1462 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1463 return ($level, $linenr, @chunks);
1464 }
1465
1466 # Pull in the following conditional/block pairs and see if they
1467 # could continue the statement.
1468 for (;;) {
1469 ($statement, $condition, $linenr, $remain, $off, $level) =
1470 ctx_statement_block($linenr, $remain, $off);
1471 #print "C: c<$condition> s<$statement> remain<$remain>\n";
1472 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1473 #print "C: push\n";
1474 push(@chunks, [ $condition, $statement ]);
1475 }
1476
1477 return ($level, $linenr, @chunks);
1478}
1479
1480sub ctx_block_get {
1481 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1482 my $line;
1483 my $start = $linenr - 1;
1484 my $blk = '';
1485 my @o;
1486 my @c;
1487 my @res = ();
1488
1489 my $level = 0;
1490 my @stack = ($level);
1491 for ($line = $start; $remain > 0; $line++) {
1492 next if ($rawlines[$line] =~ /^-/);
1493 $remain--;
1494
1495 $blk .= $rawlines[$line];
1496
1497 # Handle nested #if/#else.
1498 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1499 push(@stack, $level);
1500 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1501 $level = $stack[$#stack - 1];
1502 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1503 $level = pop(@stack);
1504 }
1505
1506 foreach my $c (split(//, $lines[$line])) {
1507 ##print "C<$c>L<$level><$open$close>O<$off>\n";
1508 if ($off > 0) {
1509 $off--;
1510 next;
1511 }
1512
1513 if ($c eq $close && $level > 0) {
1514 $level--;
1515 last if ($level == 0);
1516 } elsif ($c eq $open) {
1517 $level++;
1518 }
1519 }
1520
1521 if (!$outer || $level <= 1) {
1522 push(@res, $rawlines[$line]);
1523 }
1524
1525 last if ($level == 0);
1526 }
1527
1528 return ($level, @res);
1529}
1530sub ctx_block_outer {
1531 my ($linenr, $remain) = @_;
1532
1533 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1534 return @r;
1535}
1536sub ctx_block {
1537 my ($linenr, $remain) = @_;
1538
1539 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1540 return @r;
1541}
1542sub ctx_statement {
1543 my ($linenr, $remain, $off) = @_;
1544
1545 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1546 return @r;
1547}
1548sub ctx_block_level {
1549 my ($linenr, $remain) = @_;
1550
1551 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1552}
1553sub ctx_statement_level {
1554 my ($linenr, $remain, $off) = @_;
1555
1556 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1557}
1558
1559sub ctx_locate_comment {
1560 my ($first_line, $end_line) = @_;
1561
1562 # Catch a comment on the end of the line itself.
1563 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1564 return $current_comment if (defined $current_comment);
1565
1566 # Look through the context and try and figure out if there is a
1567 # comment.
1568 my $in_comment = 0;
1569 $current_comment = '';
1570 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1571 my $line = $rawlines[$linenr - 1];
1572 #warn " $line\n";
1573 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1574 $in_comment = 1;
1575 }
1576 if ($line =~ m@/\*@) {
1577 $in_comment = 1;
1578 }
1579 if (!$in_comment && $current_comment ne '') {
1580 $current_comment = '';
1581 }
1582 $current_comment .= $line . "\n" if ($in_comment);
1583 if ($line =~ m@\*/@) {
1584 $in_comment = 0;
1585 }
1586 }
1587
1588 chomp($current_comment);
1589 return($current_comment);
1590}
1591sub ctx_has_comment {
1592 my ($first_line, $end_line) = @_;
1593 my $cmt = ctx_locate_comment($first_line, $end_line);
1594
1595 ##print "LINE: $rawlines[$end_line - 1 ]\n";
1596 ##print "CMMT: $cmt\n";
1597
1598 return ($cmt ne '');
1599}
1600
1601sub raw_line {
1602 my ($linenr, $cnt) = @_;
1603
1604 my $offset = $linenr - 1;
1605 $cnt++;
1606
1607 my $line;
1608 while ($cnt) {
1609 $line = $rawlines[$offset++];
1610 next if (defined($line) && $line =~ /^-/);
1611 $cnt--;
1612 }
1613
1614 return $line;
1615}
1616
1617sub cat_vet {
1618 my ($vet) = @_;
1619 my ($res, $coded);
1620
1621 $res = '';
1622 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1623 $res .= $1;
1624 if ($2 ne '') {
1625 $coded = sprintf("^%c", unpack('C', $2) + 64);
1626 $res .= $coded;
1627 }
1628 }
1629 $res =~ s/$/\$/;
1630
1631 return $res;
1632}
1633
1634my $av_preprocessor = 0;
1635my $av_pending;
1636my @av_paren_type;
1637my $av_pend_colon;
1638
1639sub annotate_reset {
1640 $av_preprocessor = 0;
1641 $av_pending = '_';
1642 @av_paren_type = ('E');
1643 $av_pend_colon = 'O';
1644}
1645
1646sub annotate_values {
1647 my ($stream, $type) = @_;
1648
1649 my $res;
1650 my $var = '_' x length($stream);
1651 my $cur = $stream;
1652
1653 print "$stream\n" if ($dbg_values > 1);
1654
1655 while (length($cur)) {
1656 @av_paren_type = ('E') if ($#av_paren_type < 0);
1657 print " <" . join('', @av_paren_type) .
1658 "> <$type> <$av_pending>" if ($dbg_values > 1);
1659 if ($cur =~ /^(\s+)/o) {
1660 print "WS($1)\n" if ($dbg_values > 1);
1661 if ($1 =~ /\n/ && $av_preprocessor) {
1662 $type = pop(@av_paren_type);
1663 $av_preprocessor = 0;
1664 }
1665
1666 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1667 print "CAST($1)\n" if ($dbg_values > 1);
1668 push(@av_paren_type, $type);
1669 $type = 'c';
1670
1671 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1672 print "DECLARE($1)\n" if ($dbg_values > 1);
1673 $type = 'T';
1674
1675 } elsif ($cur =~ /^($Modifier)\s*/) {
1676 print "MODIFIER($1)\n" if ($dbg_values > 1);
1677 $type = 'T';
1678
1679 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1680 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1681 $av_preprocessor = 1;
1682 push(@av_paren_type, $type);
1683 if ($2 ne '') {
1684 $av_pending = 'N';
1685 }
1686 $type = 'E';
1687
1688 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1689 print "UNDEF($1)\n" if ($dbg_values > 1);
1690 $av_preprocessor = 1;
1691 push(@av_paren_type, $type);
1692
1693 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1694 print "PRE_START($1)\n" if ($dbg_values > 1);
1695 $av_preprocessor = 1;
1696
1697 push(@av_paren_type, $type);
1698 push(@av_paren_type, $type);
1699 $type = 'E';
1700
1701 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1702 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1703 $av_preprocessor = 1;
1704
1705 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1706
1707 $type = 'E';
1708
1709 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1710 print "PRE_END($1)\n" if ($dbg_values > 1);
1711
1712 $av_preprocessor = 1;
1713
1714 # Assume all arms of the conditional end as this
1715 # one does, and continue as if the #endif was not here.
1716 pop(@av_paren_type);
1717 push(@av_paren_type, $type);
1718 $type = 'E';
1719
1720 } elsif ($cur =~ /^(\\\n)/o) {
1721 print "PRECONT($1)\n" if ($dbg_values > 1);
1722
1723 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1724 print "ATTR($1)\n" if ($dbg_values > 1);
1725 $av_pending = $type;
1726 $type = 'N';
1727
1728 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1729 print "SIZEOF($1)\n" if ($dbg_values > 1);
1730 if (defined $2) {
1731 $av_pending = 'V';
1732 }
1733 $type = 'N';
1734
1735 } elsif ($cur =~ /^(if|while|for)\b/o) {
1736 print "COND($1)\n" if ($dbg_values > 1);
1737 $av_pending = 'E';
1738 $type = 'N';
1739
1740 } elsif ($cur =~/^(case)/o) {
1741 print "CASE($1)\n" if ($dbg_values > 1);
1742 $av_pend_colon = 'C';
1743 $type = 'N';
1744
1745 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1746 print "KEYWORD($1)\n" if ($dbg_values > 1);
1747 $type = 'N';
1748
1749 } elsif ($cur =~ /^(\()/o) {
1750 print "PAREN('$1')\n" if ($dbg_values > 1);
1751 push(@av_paren_type, $av_pending);
1752 $av_pending = '_';
1753 $type = 'N';
1754
1755 } elsif ($cur =~ /^(\))/o) {
1756 my $new_type = pop(@av_paren_type);
1757 if ($new_type ne '_') {
1758 $type = $new_type;
1759 print "PAREN('$1') -> $type\n"
1760 if ($dbg_values > 1);
1761 } else {
1762 print "PAREN('$1')\n" if ($dbg_values > 1);
1763 }
1764
1765 } elsif ($cur =~ /^($Ident)\s*\(/o) {
1766 print "FUNC($1)\n" if ($dbg_values > 1);
1767 $type = 'V';
1768 $av_pending = 'V';
1769
1770 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1771 if (defined $2 && $type eq 'C' || $type eq 'T') {
1772 $av_pend_colon = 'B';
1773 } elsif ($type eq 'E') {
1774 $av_pend_colon = 'L';
1775 }
1776 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1777 $type = 'V';
1778
1779 } elsif ($cur =~ /^($Ident|$Constant)/o) {
1780 print "IDENT($1)\n" if ($dbg_values > 1);
1781 $type = 'V';
1782
1783 } elsif ($cur =~ /^($Assignment)/o) {
1784 print "ASSIGN($1)\n" if ($dbg_values > 1);
1785 $type = 'N';
1786
1787 } elsif ($cur =~/^(;|{|})/) {
1788 print "END($1)\n" if ($dbg_values > 1);
1789 $type = 'E';
1790 $av_pend_colon = 'O';
1791
1792 } elsif ($cur =~/^(,)/) {
1793 print "COMMA($1)\n" if ($dbg_values > 1);
1794 $type = 'C';
1795
1796 } elsif ($cur =~ /^(\?)/o) {
1797 print "QUESTION($1)\n" if ($dbg_values > 1);
1798 $type = 'N';
1799
1800 } elsif ($cur =~ /^(:)/o) {
1801 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1802
1803 substr($var, length($res), 1, $av_pend_colon);
1804 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1805 $type = 'E';
1806 } else {
1807 $type = 'N';
1808 }
1809 $av_pend_colon = 'O';
1810
1811 } elsif ($cur =~ /^(\[)/o) {
1812 print "CLOSE($1)\n" if ($dbg_values > 1);
1813 $type = 'N';
1814
1815 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1816 my $variant;
1817
1818 print "OPV($1)\n" if ($dbg_values > 1);
1819 if ($type eq 'V') {
1820 $variant = 'B';
1821 } else {
1822 $variant = 'U';
1823 }
1824
1825 substr($var, length($res), 1, $variant);
1826 $type = 'N';
1827
1828 } elsif ($cur =~ /^($Operators)/o) {
1829 print "OP($1)\n" if ($dbg_values > 1);
1830 if ($1 ne '++' && $1 ne '--') {
1831 $type = 'N';
1832 }
1833
1834 } elsif ($cur =~ /(^.)/o) {
1835 print "C($1)\n" if ($dbg_values > 1);
1836 }
1837 if (defined $1) {
1838 $cur = substr($cur, length($1));
1839 $res .= $type x length($1);
1840 }
1841 }
1842
1843 return ($res, $var);
1844}
1845
1846sub possible {
1847 my ($possible, $line) = @_;
1848 my $notPermitted = qr{(?:
1849 ^(?:
1850 $Modifier|
1851 $Storage|
1852 $Type|
1853 DEFINE_\S+
1854 )$|
1855 ^(?:
1856 goto|
1857 return|
1858 case|
1859 else|
1860 asm|__asm__|
1861 do|
1862 \#|
1863 \#\#|
1864 )(?:\s|$)|
1865 ^(?:typedef|struct|enum)\b
1866 )}x;
1867 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1868 if ($possible !~ $notPermitted) {
1869 # Check for modifiers.
1870 $possible =~ s/\s*$Storage\s*//g;
1871 $possible =~ s/\s*$Sparse\s*//g;
1872 if ($possible =~ /^\s*$/) {
1873
1874 } elsif ($possible =~ /\s/) {
1875 $possible =~ s/\s*$Type\s*//g;
1876 for my $modifier (split(' ', $possible)) {
1877 if ($modifier !~ $notPermitted) {
1878 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001879 push(@modifierListFile, $modifier);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001880 }
1881 }
1882
1883 } else {
1884 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001885 push(@typeListFile, $possible);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001886 }
1887 build_types();
1888 } else {
1889 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
1890 }
1891}
1892
1893my $prefix = '';
1894
1895sub show_type {
1896 my ($type) = @_;
1897
Anas Nashif1eb244c2017-10-01 17:06:36 -04001898 $type =~ tr/[a-z]/[A-Z]/;
1899
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001900 return defined $use_type{$type} if (scalar keys %use_type > 0);
1901
1902 return !defined $ignore_type{$type};
1903}
1904
1905sub report {
1906 my ($level, $type, $msg) = @_;
1907
1908 if (!show_type($type) ||
1909 (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1910 return 0;
1911 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001912 my $output = '';
Anas Nashif1eb244c2017-10-01 17:06:36 -04001913 if ($color) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001914 if ($level eq 'ERROR') {
1915 $output .= RED;
1916 } elsif ($level eq 'WARNING') {
1917 $output .= YELLOW;
1918 } else {
1919 $output .= GREEN;
1920 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001921 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001922 $output .= $prefix . $level . ':';
1923 if ($show_types) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04001924 $output .= BLUE if ($color);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001925 $output .= "$type:";
1926 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04001927 $output .= RESET if ($color);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001928 $output .= ' ' . $msg . "\n";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001929
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001930 if ($showfile) {
1931 my @lines = split("\n", $output, -1);
1932 splice(@lines, 1, 1);
1933 $output = join("\n", @lines);
1934 }
1935 $output = (split('\n', $output))[0] . "\n" if ($terse);
1936
1937 push(our @report, $output);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001938
1939 return 1;
1940}
1941
1942sub report_dump {
1943 our @report;
1944}
1945
1946sub fixup_current_range {
1947 my ($lineRef, $offset, $length) = @_;
1948
1949 if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
1950 my $o = $1;
1951 my $l = $2;
1952 my $no = $o + $offset;
1953 my $nl = $l + $length;
1954 $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
1955 }
1956}
1957
1958sub fix_inserted_deleted_lines {
1959 my ($linesRef, $insertedRef, $deletedRef) = @_;
1960
1961 my $range_last_linenr = 0;
1962 my $delta_offset = 0;
1963
1964 my $old_linenr = 0;
1965 my $new_linenr = 0;
1966
1967 my $next_insert = 0;
1968 my $next_delete = 0;
1969
1970 my @lines = ();
1971
1972 my $inserted = @{$insertedRef}[$next_insert++];
1973 my $deleted = @{$deletedRef}[$next_delete++];
1974
1975 foreach my $old_line (@{$linesRef}) {
1976 my $save_line = 1;
1977 my $line = $old_line; #don't modify the array
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001978 if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001979 $delta_offset = 0;
1980 } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
1981 $range_last_linenr = $new_linenr;
1982 fixup_current_range(\$line, $delta_offset, 0);
1983 }
1984
1985 while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
1986 $deleted = @{$deletedRef}[$next_delete++];
1987 $save_line = 0;
1988 fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
1989 }
1990
1991 while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
1992 push(@lines, ${$inserted}{'LINE'});
1993 $inserted = @{$insertedRef}[$next_insert++];
1994 $new_linenr++;
1995 fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
1996 }
1997
1998 if ($save_line) {
1999 push(@lines, $line);
2000 $new_linenr++;
2001 }
2002
2003 $old_linenr++;
2004 }
2005
2006 return @lines;
2007}
2008
2009sub fix_insert_line {
2010 my ($linenr, $line) = @_;
2011
2012 my $inserted = {
2013 LINENR => $linenr,
2014 LINE => $line,
2015 };
2016 push(@fixed_inserted, $inserted);
2017}
2018
2019sub fix_delete_line {
2020 my ($linenr, $line) = @_;
2021
2022 my $deleted = {
2023 LINENR => $linenr,
2024 LINE => $line,
2025 };
2026
2027 push(@fixed_deleted, $deleted);
2028}
2029
2030sub ERROR {
2031 my ($type, $msg) = @_;
2032
2033 if (report("ERROR", $type, $msg)) {
2034 our $clean = 0;
2035 our $cnt_error++;
2036 return 1;
2037 }
2038 return 0;
2039}
2040sub WARN {
2041 my ($type, $msg) = @_;
2042
2043 if (report("WARNING", $type, $msg)) {
2044 our $clean = 0;
2045 our $cnt_warn++;
2046 return 1;
2047 }
2048 return 0;
2049}
2050sub CHK {
2051 my ($type, $msg) = @_;
2052
2053 if ($check && report("CHECK", $type, $msg)) {
2054 our $clean = 0;
2055 our $cnt_chk++;
2056 return 1;
2057 }
2058 return 0;
2059}
2060
2061sub check_absolute_file {
2062 my ($absolute, $herecurr) = @_;
2063 my $file = $absolute;
2064
2065 ##print "absolute<$absolute>\n";
2066
2067 # See if any suffix of this path is a path within the tree.
2068 while ($file =~ s@^[^/]*/@@) {
2069 if (-f "$root/$file") {
2070 ##print "file<$file>\n";
2071 last;
2072 }
2073 }
2074 if (! -f _) {
2075 return 0;
2076 }
2077
2078 # It is, so see if the prefix is acceptable.
2079 my $prefix = $absolute;
2080 substr($prefix, -length($file)) = '';
2081
2082 ##print "prefix<$prefix>\n";
2083 if ($prefix ne ".../") {
2084 WARN("USE_RELATIVE_PATH",
2085 "use relative pathname instead of absolute in changelog text\n" . $herecurr);
2086 }
2087}
2088
2089sub trim {
2090 my ($string) = @_;
2091
2092 $string =~ s/^\s+|\s+$//g;
2093
2094 return $string;
2095}
2096
2097sub ltrim {
2098 my ($string) = @_;
2099
2100 $string =~ s/^\s+//;
2101
2102 return $string;
2103}
2104
2105sub rtrim {
2106 my ($string) = @_;
2107
2108 $string =~ s/\s+$//;
2109
2110 return $string;
2111}
2112
2113sub string_find_replace {
2114 my ($string, $find, $replace) = @_;
2115
2116 $string =~ s/$find/$replace/g;
2117
2118 return $string;
2119}
2120
2121sub tabify {
2122 my ($leading) = @_;
2123
2124 my $source_indent = 8;
2125 my $max_spaces_before_tab = $source_indent - 1;
2126 my $spaces_to_tab = " " x $source_indent;
2127
2128 #convert leading spaces to tabs
2129 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
2130 #Remove spaces before a tab
2131 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
2132
2133 return "$leading";
2134}
2135
2136sub pos_last_openparen {
2137 my ($line) = @_;
2138
2139 my $pos = 0;
2140
2141 my $opens = $line =~ tr/\(/\(/;
2142 my $closes = $line =~ tr/\)/\)/;
2143
2144 my $last_openparen = 0;
2145
2146 if (($opens == 0) || ($closes >= $opens)) {
2147 return -1;
2148 }
2149
2150 my $len = length($line);
2151
2152 for ($pos = 0; $pos < $len; $pos++) {
2153 my $string = substr($line, $pos);
2154 if ($string =~ /^($FuncArg|$balanced_parens)/) {
2155 $pos += length($1) - 1;
2156 } elsif (substr($line, $pos, 1) eq '(') {
2157 $last_openparen = $pos;
2158 } elsif (index($string, '(') == -1) {
2159 last;
2160 }
2161 }
2162
2163 return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2164}
2165
2166sub process {
2167 my $filename = shift;
2168
2169 my $linenr=0;
2170 my $prevline="";
2171 my $prevrawline="";
2172 my $stashline="";
2173 my $stashrawline="";
2174
2175 my $length;
2176 my $indent;
2177 my $previndent=0;
2178 my $stashindent=0;
2179
2180 our $clean = 1;
2181 my $signoff = 0;
2182 my $is_patch = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002183 my $in_header_lines = $file ? 0 : 1;
2184 my $in_commit_log = 0; #Scanning lines before patch
Anas Nashif0f3d5472016-11-07 15:57:57 -05002185 my $has_commit_log = 0; #Encountered lines before patch
Anas Nashif1eb244c2017-10-01 17:06:36 -04002186 my $commit_log_possible_stack_dump = 0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002187 my $commit_log_long_line = 0;
2188 my $commit_log_has_diff = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002189 my $reported_maintainer_file = 0;
2190 my $non_utf8_charset = 0;
2191
2192 my $last_blank_line = 0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002193 my $last_coalesced_string_linenr = -1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002194
2195 our @report = ();
2196 our $cnt_lines = 0;
2197 our $cnt_error = 0;
2198 our $cnt_warn = 0;
2199 our $cnt_chk = 0;
2200
2201 # Trace the real file/line as we go.
2202 my $realfile = '';
2203 my $realline = 0;
2204 my $realcnt = 0;
2205 my $here = '';
Anas Nashif1eb244c2017-10-01 17:06:36 -04002206 my $context_function; #undef'd unless there's a known function
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002207 my $in_comment = 0;
2208 my $comment_edge = 0;
2209 my $first_line = 0;
2210 my $p1_prefix = '';
2211
2212 my $prev_values = 'E';
2213
2214 # suppression flags
2215 my %suppress_ifbraces;
2216 my %suppress_whiletrailers;
2217 my %suppress_export;
2218 my $suppress_statement = 0;
2219
2220 my %signatures = ();
2221
2222 # Pre-scan the patch sanitizing the lines.
2223 # Pre-scan the patch looking for any __setup documentation.
2224 #
2225 my @setup_docs = ();
2226 my $setup_docs = 0;
2227
2228 my $camelcase_file_seeded = 0;
2229
2230 sanitise_line_reset();
2231 my $line;
2232 foreach my $rawline (@rawlines) {
2233 $linenr++;
2234 $line = $rawline;
2235
2236 push(@fixed, $rawline) if ($fix);
2237
2238 if ($rawline=~/^\+\+\+\s+(\S+)/) {
2239 $setup_docs = 0;
Anas Nashif1eb244c2017-10-01 17:06:36 -04002240 if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002241 $setup_docs = 1;
2242 }
2243 #next;
2244 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04002245 if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002246 $realline=$1-1;
2247 if (defined $2) {
2248 $realcnt=$3+1;
2249 } else {
2250 $realcnt=1+1;
2251 }
2252 $in_comment = 0;
2253
2254 # Guestimate if this is a continuing comment. Run
2255 # the context looking for a comment "edge". If this
2256 # edge is a close comment then we must be in a comment
2257 # at context start.
2258 my $edge;
2259 my $cnt = $realcnt;
2260 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
2261 next if (defined $rawlines[$ln - 1] &&
2262 $rawlines[$ln - 1] =~ /^-/);
2263 $cnt--;
2264 #print "RAW<$rawlines[$ln - 1]>\n";
2265 last if (!defined $rawlines[$ln - 1]);
2266 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2267 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2268 ($edge) = $1;
2269 last;
2270 }
2271 }
2272 if (defined $edge && $edge eq '*/') {
2273 $in_comment = 1;
2274 }
2275
2276 # Guestimate if this is a continuing comment. If this
2277 # is the start of a diff block and this line starts
2278 # ' *' then it is very likely a comment.
2279 if (!defined $edge &&
2280 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2281 {
2282 $in_comment = 1;
2283 }
2284
2285 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2286 sanitise_line_reset($in_comment);
2287
2288 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2289 # Standardise the strings and chars within the input to
2290 # simplify matching -- only bother with positive lines.
2291 $line = sanitise_line($rawline);
2292 }
2293 push(@lines, $line);
2294
2295 if ($realcnt > 1) {
2296 $realcnt-- if ($line =~ /^(?:\+| |$)/);
2297 } else {
2298 $realcnt = 0;
2299 }
2300
2301 #print "==>$rawline\n";
2302 #print "-->$line\n";
2303
2304 if ($setup_docs && $line =~ /^\+/) {
2305 push(@setup_docs, $line);
2306 }
2307 }
2308
2309 $prefix = '';
2310
2311 $realcnt = 0;
2312 $linenr = 0;
2313 $fixlinenr = -1;
2314 foreach my $line (@lines) {
2315 $linenr++;
2316 $fixlinenr++;
2317 my $sline = $line; #copy of $line
2318 $sline =~ s/$;/ /g; #with comments as spaces
2319
2320 my $rawline = $rawlines[$linenr - 1];
2321
2322#extract the line range in the file after the patch is applied
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002323 if (!$in_commit_log &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04002324 $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2325 my $context = $4;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002326 $is_patch = 1;
2327 $first_line = $linenr + 1;
2328 $realline=$1-1;
2329 if (defined $2) {
2330 $realcnt=$3+1;
2331 } else {
2332 $realcnt=1+1;
2333 }
2334 annotate_reset();
2335 $prev_values = 'E';
2336
2337 %suppress_ifbraces = ();
2338 %suppress_whiletrailers = ();
2339 %suppress_export = ();
2340 $suppress_statement = 0;
Anas Nashif1eb244c2017-10-01 17:06:36 -04002341 if ($context =~ /\b(\w+)\s*\(/) {
2342 $context_function = $1;
2343 } else {
2344 undef $context_function;
2345 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002346 next;
2347
2348# track the line number as we move through the hunk, note that
2349# new versions of GNU diff omit the leading space on completely
2350# blank context lines so we need to count that too.
2351 } elsif ($line =~ /^( |\+|$)/) {
2352 $realline++;
2353 $realcnt-- if ($realcnt != 0);
2354
2355 # Measure the line length and indent.
2356 ($length, $indent) = line_stats($rawline);
2357
2358 # Track the previous line.
2359 ($prevline, $stashline) = ($stashline, $line);
2360 ($previndent, $stashindent) = ($stashindent, $indent);
2361 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2362
2363 #warn "line<$line>\n";
2364
2365 } elsif ($realcnt == 1) {
2366 $realcnt--;
2367 }
2368
2369 my $hunk_line = ($realcnt != 0);
2370
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002371 $here = "#$linenr: " if (!$file);
2372 $here = "#$realline: " if ($file);
2373
2374 my $found_file = 0;
2375 # extract the filename as it passes
2376 if ($line =~ /^diff --git.*?(\S+)$/) {
2377 $realfile = $1;
2378 $realfile =~ s@^([^/]*)/@@ if (!$file);
2379 $in_commit_log = 0;
2380 $found_file = 1;
2381 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2382 $realfile = $1;
2383 $realfile =~ s@^([^/]*)/@@ if (!$file);
2384 $in_commit_log = 0;
2385
2386 $p1_prefix = $1;
2387 if (!$file && $tree && $p1_prefix ne '' &&
2388 -e "$root/$p1_prefix") {
2389 WARN("PATCH_PREFIX",
2390 "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
2391 }
2392
2393 if ($realfile =~ m@^include/asm/@) {
2394 ERROR("MODIFIED_INCLUDE_ASM",
2395 "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2396 }
2397 $found_file = 1;
2398 }
Anas Nashif92a12a12016-05-20 18:26:59 -04002399 my $skipme = 0;
2400 foreach (@exclude) {
2401 if ($realfile =~ m@^(?:$_/)@) {
2402 $skipme = 1;
2403 }
2404 }
2405 if ($skipme) {
2406 next;
2407 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002408
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002409#make up the handle for any error we report on this line
2410 if ($showfile) {
2411 $prefix = "$realfile:$realline: "
2412 } elsif ($emacs) {
2413 if ($file) {
2414 $prefix = "$filename:$realline: ";
2415 } else {
2416 $prefix = "$filename:$linenr: ";
2417 }
2418 }
2419
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002420 if ($found_file) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04002421 if (is_maintained_obsolete($realfile)) {
2422 WARN("OBSOLETE",
2423 "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
2424 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002425 if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002426 $check = 1;
2427 } else {
2428 $check = $check_orig;
2429 }
2430 next;
2431 }
2432
2433 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
2434
2435 my $hereline = "$here\n$rawline\n";
2436 my $herecurr = "$here\n$rawline\n";
2437 my $hereprev = "$here\n$prevrawline\n$rawline\n";
2438
2439 $cnt_lines++ if ($realcnt != 0);
2440
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002441# Check if the commit log has what seems like a diff which can confuse patch
2442 if ($in_commit_log && !$commit_log_has_diff &&
2443 (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2444 $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2445 $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2446 $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2447 ERROR("DIFF_IN_COMMIT_MSG",
2448 "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2449 $commit_log_has_diff = 1;
2450 }
2451
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002452# Check for incorrect file permissions
2453 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
2454 my $permhere = $here . "FILE: $realfile\n";
2455 if ($realfile !~ m@scripts/@ &&
2456 $realfile !~ /\.(py|pl|awk|sh)$/) {
2457 ERROR("EXECUTE_PERMISSIONS",
2458 "do not set execute permissions for source files\n" . $permhere);
2459 }
2460 }
2461
2462# Check the patch for a signoff:
2463 if ($line =~ /^\s*signed-off-by:/i) {
2464 $signoff++;
2465 $in_commit_log = 0;
2466 }
2467
Anas Nashifc2de83c2017-09-08 09:51:01 -04002468# Check if CODEOWNERS is being updated. If so, there's probably no need to
2469# emit the "does CODEOWNERS need updating?" message on file add/move/delete
2470 if ($line =~ /^\s*CODEOWNERS\s*\|/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002471 $reported_maintainer_file = 1;
2472 }
2473
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002474# Check signature styles
2475 if (!$in_header_lines &&
2476 $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
2477 my $space_before = $1;
2478 my $sign_off = $2;
2479 my $space_after = $3;
2480 my $email = $4;
2481 my $ucfirst_sign_off = ucfirst(lc($sign_off));
2482
2483 if ($sign_off !~ /$signature_tags/) {
2484 WARN("BAD_SIGN_OFF",
2485 "Non-standard signature: $sign_off\n" . $herecurr);
2486 }
2487 if (defined $space_before && $space_before ne "") {
2488 if (WARN("BAD_SIGN_OFF",
2489 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
2490 $fix) {
2491 $fixed[$fixlinenr] =
2492 "$ucfirst_sign_off $email";
2493 }
2494 }
2495 if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
2496 if (WARN("BAD_SIGN_OFF",
2497 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
2498 $fix) {
2499 $fixed[$fixlinenr] =
2500 "$ucfirst_sign_off $email";
2501 }
2502
2503 }
2504 if (!defined $space_after || $space_after ne " ") {
2505 if (WARN("BAD_SIGN_OFF",
2506 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
2507 $fix) {
2508 $fixed[$fixlinenr] =
2509 "$ucfirst_sign_off $email";
2510 }
2511 }
2512
2513 my ($email_name, $email_address, $comment) = parse_email($email);
2514 my $suggested_email = format_email(($email_name, $email_address));
2515 if ($suggested_email eq "") {
2516 ERROR("BAD_SIGN_OFF",
2517 "Unrecognized email address: '$email'\n" . $herecurr);
2518 } else {
2519 my $dequoted = $suggested_email;
2520 $dequoted =~ s/^"//;
2521 $dequoted =~ s/" </ </;
2522 # Don't force email to have quotes
2523 # Allow just an angle bracketed address
2524 if ("$dequoted$comment" ne $email &&
2525 "<$email_address>$comment" ne $email &&
2526 "$suggested_email$comment" ne $email) {
2527 WARN("BAD_SIGN_OFF",
2528 "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
2529 }
2530 }
2531
2532# Check for duplicate signatures
2533 my $sig_nospace = $line;
2534 $sig_nospace =~ s/\s//g;
2535 $sig_nospace = lc($sig_nospace);
2536 if (defined $signatures{$sig_nospace}) {
2537 WARN("BAD_SIGN_OFF",
2538 "Duplicate signature\n" . $herecurr);
2539 } else {
2540 $signatures{$sig_nospace} = 1;
2541 }
2542 }
2543
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002544# Check email subject for common tools that don't need to be mentioned
2545 if ($in_header_lines &&
2546 $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2547 WARN("EMAIL_SUBJECT",
2548 "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2549 }
2550
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002551# Check for old stable address
2552 if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
2553 ERROR("STABLE_ADDRESS",
2554 "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
2555 }
2556
Anas Nashif1eb244c2017-10-01 17:06:36 -04002557# Check for unwanted Gerrit info
2558 if ($in_commit_log && $line =~ /^\s*change-id:/i) {
2559 ERROR("GERRIT_CHANGE_ID",
2560 "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
2561 }
2562
Anas Nashif76b09132016-02-20 13:53:35 -05002563# Check if the commit log is in a possible stack dump
2564 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2565 ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2566 $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2567 # timestamp
2568 $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
2569 # stack dump address
2570 $commit_log_possible_stack_dump = 1;
2571 }
2572
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002573# Check for line lengths > 75 in commit log, warn once
2574 if ($in_commit_log && !$commit_log_long_line &&
Anas Nashif76b09132016-02-20 13:53:35 -05002575 length($line) > 75 &&
2576 !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2577 # file delta changes
2578 $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2579 # filename then :
2580 $line =~ /^\s*(?:Fixes:|Link:)/i ||
2581 # A Fixes: or Link: line
2582 $commit_log_possible_stack_dump)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002583 WARN("COMMIT_LOG_LONG_LINE",
2584 "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
2585 $commit_log_long_line = 1;
2586 }
2587
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002588# Reset possible stack dump if a blank line is found
Anas Nashif76b09132016-02-20 13:53:35 -05002589 if ($in_commit_log && $commit_log_possible_stack_dump &&
2590 $line =~ /^\s*$/) {
2591 $commit_log_possible_stack_dump = 0;
2592 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002593
2594# Check for git id commit length and improperly formed commit descriptions
Anas Nashif76b09132016-02-20 13:53:35 -05002595 if ($in_commit_log && !$commit_log_possible_stack_dump &&
Anas Nashif0f3d5472016-11-07 15:57:57 -05002596 $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04002597 $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002598 ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
Anas Nashif0f3d5472016-11-07 15:57:57 -05002599 ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
Anas Nashif76b09132016-02-20 13:53:35 -05002600 $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2601 $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002602 my $init_char = "c";
2603 my $orig_commit = "";
2604 my $short = 1;
2605 my $long = 0;
2606 my $case = 1;
2607 my $space = 1;
2608 my $hasdesc = 0;
2609 my $hasparens = 0;
2610 my $id = '0123456789ab';
2611 my $orig_desc = "commit description";
2612 my $description = "";
2613
2614 if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2615 $init_char = $1;
2616 $orig_commit = lc($2);
2617 } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2618 $orig_commit = lc($1);
2619 }
2620
2621 $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
2622 $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
2623 $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
2624 $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
2625 if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
2626 $orig_desc = $1;
2627 $hasparens = 1;
2628 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
2629 defined $rawlines[$linenr] &&
2630 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
2631 $orig_desc = $1;
2632 $hasparens = 1;
2633 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2634 defined $rawlines[$linenr] &&
2635 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2636 $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2637 $orig_desc = $1;
2638 $rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2639 $orig_desc .= " " . $1;
2640 $hasparens = 1;
2641 }
2642
2643 ($id, $description) = git_commit_info($orig_commit,
2644 $id, $orig_desc);
2645
Anas Nashif1eb244c2017-10-01 17:06:36 -04002646 if (defined($id) &&
2647 ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002648 ERROR("GIT_COMMIT_ID",
2649 "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
2650 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002651 }
2652
2653# Check for added, moved or deleted files
2654 if (!$reported_maintainer_file && !$in_commit_log &&
2655 ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
2656 $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
2657 ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
2658 (defined($1) || defined($2))))) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04002659 $is_patch = 1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002660 $reported_maintainer_file = 1;
2661 WARN("FILE_PATH_CHANGES",
Anas Nashifc2de83c2017-09-08 09:51:01 -04002662 "added, moved or deleted file(s), does CODEOWNERS need updating?\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002663 }
2664
2665# Check for wrappage within a valid hunk of the file
2666 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2667 ERROR("CORRUPTED_PATCH",
2668 "patch seems to be corrupt (line wrapped?)\n" .
2669 $herecurr) if (!$emitted_corrupt++);
2670 }
2671
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002672# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2673 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2674 $rawline !~ m/^$UTF8*$/) {
2675 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2676
2677 my $blank = copy_spacing($rawline);
2678 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2679 my $hereptr = "$hereline$ptr\n";
2680
2681 CHK("INVALID_UTF8",
2682 "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
2683 }
2684
2685# Check if it's the start of a commit log
2686# (not a header line and we haven't seen the patch filename)
2687 if ($in_header_lines && $realfile =~ /^$/ &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04002688 !($rawline =~ /^\s+(?:\S|$)/ ||
2689 $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002690 $in_header_lines = 0;
2691 $in_commit_log = 1;
Anas Nashif0f3d5472016-11-07 15:57:57 -05002692 $has_commit_log = 1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002693 }
2694
2695# Check if there is UTF-8 in a commit log when a mail header has explicitly
2696# declined it, i.e defined some charset where it is missing.
2697 if ($in_header_lines &&
2698 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2699 $1 !~ /utf-8/i) {
2700 $non_utf8_charset = 1;
2701 }
2702
2703 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
2704 $rawline =~ /$NON_ASCII_UTF8/) {
2705 WARN("UTF8_BEFORE_PATCH",
2706 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
2707 }
2708
Anas Nashif1eb244c2017-10-01 17:06:36 -04002709# Check for absolute kernel paths in commit message
2710 if ($tree && $in_commit_log) {
2711 while ($line =~ m{(?:^|\s)(/\S*)}g) {
2712 my $file = $1;
2713
2714 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2715 check_absolute_file($1, $herecurr)) {
2716 #
2717 } else {
2718 check_absolute_file($file, $herecurr);
2719 }
2720 }
2721 }
2722
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002723# Check for various typo / spelling mistakes
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002724 if (defined($misspellings) &&
2725 ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2726 while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002727 my $typo = $1;
2728 my $typo_fix = $spelling_fix{lc($typo)};
2729 $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
2730 $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
Anas Nashif1eb244c2017-10-01 17:06:36 -04002731 my $msg_level = \&WARN;
2732 $msg_level = \&CHK if ($file);
2733 if (&{$msg_level}("TYPO_SPELLING",
2734 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002735 $fix) {
2736 $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
2737 }
2738 }
2739 }
2740
2741# ignore non-hunk lines and lines being removed
2742 next if (!$hunk_line || $line =~ /^-/);
2743
2744#trailing whitespace
2745 if ($line =~ /^\+.*\015/) {
2746 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2747 if (ERROR("DOS_LINE_ENDINGS",
2748 "DOS line endings\n" . $herevet) &&
2749 $fix) {
2750 $fixed[$fixlinenr] =~ s/[\s\015]+$//;
2751 }
2752 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2753 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2754 if (ERROR("TRAILING_WHITESPACE",
2755 "trailing whitespace\n" . $herevet) &&
2756 $fix) {
2757 $fixed[$fixlinenr] =~ s/\s+$//;
2758 }
2759
2760 $rpt_cleaners = 1;
2761 }
2762
2763# Check for FSF mailing addresses.
2764 if ($rawline =~ /\bwrite to the Free/i ||
Anas Nashif1eb244c2017-10-01 17:06:36 -04002765 $rawline =~ /\b675\s+Mass\s+Ave/i ||
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002766 $rawline =~ /\b59\s+Temple\s+Pl/i ||
2767 $rawline =~ /\b51\s+Franklin\s+St/i) {
2768 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Anas Nashif1eb244c2017-10-01 17:06:36 -04002769 my $msg_level = \&ERROR;
2770 $msg_level = \&CHK if ($file);
2771 &{$msg_level}("FSF_MAILING_ADDRESS",
2772 "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)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002773 }
2774
2775# check for Kconfig help text having a real description
2776# Only applies when adding the entry originally, after that we do not have
2777# sufficient context to determine whether it is indeed long enough.
2778 if ($realfile =~ /Kconfig/ &&
2779 $line =~ /^\+\s*config\s+/) {
2780 my $length = 0;
2781 my $cnt = $realcnt;
2782 my $ln = $linenr + 1;
2783 my $f;
2784 my $is_start = 0;
2785 my $is_end = 0;
2786 for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
2787 $f = $lines[$ln - 1];
2788 $cnt-- if ($lines[$ln - 1] !~ /^-/);
2789 $is_end = $lines[$ln - 1] =~ /^\+/;
2790
2791 next if ($f =~ /^-/);
2792 last if (!$file && $f =~ /^\@\@/);
2793
2794 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) {
2795 $is_start = 1;
2796 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
2797 $length = -1;
2798 }
2799
2800 $f =~ s/^.//;
2801 $f =~ s/#.*//;
2802 $f =~ s/^\s+//;
2803 next if ($f =~ /^$/);
2804 if ($f =~ /^\s*config\s/) {
2805 $is_end = 1;
2806 last;
2807 }
2808 $length++;
2809 }
2810 if ($is_start && $is_end && $length < $min_conf_desc_length) {
2811 WARN("CONFIG_DESCRIPTION",
2812 "please write a paragraph that describes the config symbol fully\n" . $herecurr);
2813 }
2814 #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
2815 }
2816
Anas Nashif1eb244c2017-10-01 17:06:36 -04002817# check for MAINTAINERS entries that don't have the right form
2818 if ($realfile =~ /^MAINTAINERS$/ &&
2819 $rawline =~ /^\+[A-Z]:/ &&
2820 $rawline !~ /^\+[A-Z]:\t\S/) {
2821 if (WARN("MAINTAINERS_STYLE",
2822 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
2823 $fix) {
2824 $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
2825 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002826 }
2827
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002828# discourage the use of boolean for type definition attributes of Kconfig options
2829 if ($realfile =~ /Kconfig/ &&
2830 $line =~ /^\+\s*\bboolean\b/) {
2831 WARN("CONFIG_TYPE_BOOLEAN",
2832 "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
2833 }
2834
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002835 if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2836 ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2837 my $flag = $1;
2838 my $replacement = {
2839 'EXTRA_AFLAGS' => 'asflags-y',
2840 'EXTRA_CFLAGS' => 'ccflags-y',
2841 'EXTRA_CPPFLAGS' => 'cppflags-y',
2842 'EXTRA_LDFLAGS' => 'ldflags-y',
2843 };
2844
2845 WARN("DEPRECATED_VARIABLE",
2846 "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
2847 }
Javier B Perez5eecd882016-06-14 16:47:27 -05002848# Kconfig use tabs and no spaces in line
Anas Nashif34ffa152016-10-18 18:17:58 -04002849 if ($realfile =~ /Kconfig/ && $rawline =~ /^\+ /) {
Javier B Perez5eecd882016-06-14 16:47:27 -05002850 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2851 WARN("LEADING_SPACE",
2852 "please, no spaces at the start of a line\n" . $herevet);
2853 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002854
2855# check for DT compatible documentation
2856 if (defined $root &&
2857 (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
2858 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
2859
2860 my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
2861
Antony Pavlov824519532019-05-09 16:40:56 +03002862 my $dt_path = $root . "/dts/bindings/";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002863 my $vp_file = $dt_path . "vendor-prefixes.txt";
2864
2865 foreach my $compat (@compats) {
2866 my $compat2 = $compat;
2867 $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
2868 my $compat3 = $compat;
2869 $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
2870 `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
2871 if ( $? >> 8 ) {
2872 WARN("UNDOCUMENTED_DT_STRING",
2873 "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
2874 }
2875
2876 next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
2877 my $vendor = $1;
2878 `grep -Eq "^$vendor\\b" $vp_file`;
2879 if ( $? >> 8 ) {
2880 WARN("UNDOCUMENTED_DT_STRING",
2881 "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
2882 }
2883 }
2884 }
2885
2886# check we are in a valid source file if not then ignore this hunk
Anas Nashif1eb244c2017-10-01 17:06:36 -04002887 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002888
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002889# line length limit (with some exclusions)
2890#
2891# There are a few types of lines that may extend beyond $max_line_length:
2892# logging functions like pr_info that end in a string
2893# lines with a single string
2894# #defines that are a single string
2895#
2896# There are 3 different line length message types:
Anas Nashif1eb244c2017-10-01 17:06:36 -04002897# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002898# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
2899# LONG_LINE all other lines longer than $max_line_length
2900#
2901# if LONG_LINE is ignored, the other 2 types are also ignored
2902#
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002903
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002904 if ($line =~ /^\+/ && $length > $max_line_length) {
2905 my $msg_type = "LONG_LINE";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002906
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002907 # Check the allowed long line types first
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002908
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002909 # logging functions that end in a string that starts
2910 # before $max_line_length
2911 if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
2912 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
2913 $msg_type = "";
2914
2915 # lines with only strings (w/ possible termination)
2916 # #defines with only strings
2917 } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
2918 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
2919 $msg_type = "";
2920
Anas Nashif0f3d5472016-11-07 15:57:57 -05002921 # EFI_GUID is another special case
2922 } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {
2923 $msg_type = "";
2924
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002925 # Otherwise set the alternate message types
2926
2927 # a comment starts before $max_line_length
2928 } elsif ($line =~ /($;[\s$;]*)$/ &&
2929 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
2930 $msg_type = "LONG_LINE_COMMENT"
2931
2932 # a quoted string starts before $max_line_length
2933 } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
2934 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
2935 $msg_type = "LONG_LINE_STRING"
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002936 }
2937
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002938 if ($msg_type ne "" &&
2939 (show_type("LONG_LINE") || show_type($msg_type))) {
2940 WARN($msg_type,
2941 "line over $max_line_length characters\n" . $herecurr);
2942 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002943 }
2944
2945# check for adding lines without a newline.
2946 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
2947 WARN("MISSING_EOF_NEWLINE",
2948 "adding a line without newline at end of file\n" . $herecurr);
2949 }
2950
2951# Blackfin: use hi/lo macros
2952 if ($realfile =~ m@arch/blackfin/.*\.S$@) {
2953 if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
2954 my $herevet = "$here\n" . cat_vet($line) . "\n";
2955 ERROR("LO_MACRO",
2956 "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
2957 }
2958 if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
2959 my $herevet = "$here\n" . cat_vet($line) . "\n";
2960 ERROR("HI_MACRO",
2961 "use the HI() macro, not (... >> 16)\n" . $herevet);
2962 }
2963 }
2964
2965# check we are in a valid source file C or perl if not then ignore this hunk
2966 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
2967
2968# at the beginning of a line any tabs must come first and anything
2969# more than 8 must use tabs.
2970 if ($rawline =~ /^\+\s* \t\s*\S/ ||
2971 $rawline =~ /^\+\s* \s*/) {
2972 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2973 $rpt_cleaners = 1;
2974 if (ERROR("CODE_INDENT",
2975 "code indent should use tabs where possible\n" . $herevet) &&
2976 $fix) {
2977 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
2978 }
2979 }
2980
2981# check for space before tabs.
2982 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
2983 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2984 if (WARN("SPACE_BEFORE_TAB",
2985 "please, no space before tabs\n" . $herevet) &&
2986 $fix) {
2987 while ($fixed[$fixlinenr] =~
2988 s/(^\+.*) {8,8}\t/$1\t\t/) {}
2989 while ($fixed[$fixlinenr] =~
2990 s/(^\+.*) +\t/$1\t/) {}
2991 }
2992 }
2993
2994# check for && or || at the start of a line
2995 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2996 CHK("LOGICAL_CONTINUATIONS",
2997 "Logical continuations should be on the previous line\n" . $hereprev);
2998 }
2999
Anas Nashif0f3d5472016-11-07 15:57:57 -05003000# check indentation starts on a tab stop
3001 if ($^V && $^V ge 5.10.0 &&
3002 $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {
3003 my $indent = length($1);
3004 if ($indent % 8) {
3005 if (WARN("TABSTOP",
3006 "Statements should start on a tabstop\n" . $herecurr) &&
3007 $fix) {
3008 $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
3009 }
3010 }
3011 }
3012
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003013# check multi-line statement indentation matches previous line
3014 if ($^V && $^V ge 5.10.0 &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04003015 $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003016 $prevline =~ /^\+(\t*)(.*)$/;
3017 my $oldindent = $1;
3018 my $rest = $2;
3019
3020 my $pos = pos_last_openparen($rest);
3021 if ($pos >= 0) {
3022 $line =~ /^(\+| )([ \t]*)/;
3023 my $newindent = $2;
3024
3025 my $goodtabindent = $oldindent .
3026 "\t" x ($pos / 8) .
3027 " " x ($pos % 8);
3028 my $goodspaceindent = $oldindent . " " x $pos;
3029
3030 if ($newindent ne $goodtabindent &&
3031 $newindent ne $goodspaceindent) {
3032
3033 if (CHK("PARENTHESIS_ALIGNMENT",
3034 "Alignment should match open parenthesis\n" . $hereprev) &&
3035 $fix && $line =~ /^\+/) {
3036 $fixed[$fixlinenr] =~
3037 s/^\+[ \t]*/\+$goodtabindent/;
3038 }
3039 }
3040 }
3041 }
3042
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003043# check for space after cast like "(int) foo" or "(struct foo) bar"
3044# avoid checking a few false positives:
3045# "sizeof(<type>)" or "__alignof__(<type>)"
3046# function pointer declarations like "(*foo)(int) = bar;"
3047# structure definitions like "(struct foo) { 0 };"
3048# multiline macros that define functions
3049# known attributes or the __attribute__ keyword
3050 if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
3051 (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003052 if (CHK("SPACING",
3053 "No space is necessary after a cast\n" . $herecurr) &&
3054 $fix) {
3055 $fixed[$fixlinenr] =~
3056 s/(\(\s*$Type\s*\))[ \t]+/$1/;
3057 }
3058 }
3059
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003060# Block comment styles
3061# Networking with an initial /*
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003062 if ($realfile =~ m@^(drivers/net/|net/)@ &&
3063 $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
3064 $rawline =~ /^\+[ \t]*\*/ &&
3065 $realline > 2) {
3066 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
3067 "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
3068 }
3069
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003070# Block comments use * on subsequent lines
3071 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3072 $prevrawline =~ /^\+.*?\/\*/ && #starting /*
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003073 $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
3074 $rawline =~ /^\+/ && #line is new
3075 $rawline !~ /^\+[ \t]*\*/) { #no leading *
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003076 WARN("BLOCK_COMMENT_STYLE",
3077 "Block comments use * on subsequent lines\n" . $hereprev);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003078 }
3079
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003080# Block comments use */ on trailing lines
3081 if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003082 $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
3083 $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/
3084 $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003085 WARN("BLOCK_COMMENT_STYLE",
3086 "Block comments use a trailing */ on a separate line\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003087 }
3088
Anas Nashif0f3d5472016-11-07 15:57:57 -05003089# Block comment * alignment
3090 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3091 $line =~ /^\+[ \t]*$;/ && #leading comment
3092 $rawline =~ /^\+[ \t]*\*/ && #leading *
3093 (($prevrawline =~ /^\+.*?\/\*/ && #leading /*
3094 $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */
3095 $prevrawline =~ /^\+[ \t]*\*/)) { #leading *
3096 my $oldindent;
3097 $prevrawline =~ m@^\+([ \t]*/?)\*@;
3098 if (defined($1)) {
3099 $oldindent = expand_tabs($1);
3100 } else {
3101 $prevrawline =~ m@^\+(.*/?)\*@;
3102 $oldindent = expand_tabs($1);
3103 }
3104 $rawline =~ m@^\+([ \t]*)\*@;
3105 my $newindent = $1;
3106 $newindent = expand_tabs($newindent);
3107 if (length($oldindent) ne length($newindent)) {
3108 WARN("BLOCK_COMMENT_STYLE",
3109 "Block comments should align the * on each line\n" . $hereprev);
3110 }
3111 }
3112
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003113# check for missing blank lines after struct/union declarations
3114# with exceptions for various attributes and macros
3115 if ($prevline =~ /^[\+ ]};?\s*$/ &&
3116 $line =~ /^\+/ &&
3117 !($line =~ /^\+\s*$/ ||
3118 $line =~ /^\+\s*EXPORT_SYMBOL/ ||
3119 $line =~ /^\+\s*MODULE_/i ||
3120 $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
3121 $line =~ /^\+[a-z_]*init/ ||
3122 $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
3123 $line =~ /^\+\s*DECLARE/ ||
3124 $line =~ /^\+\s*__setup/)) {
3125 if (CHK("LINE_SPACING",
3126 "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3127 $fix) {
3128 fix_insert_line($fixlinenr, "\+");
3129 }
3130 }
3131
3132# check for multiple consecutive blank lines
3133 if ($prevline =~ /^[\+ ]\s*$/ &&
3134 $line =~ /^\+\s*$/ &&
3135 $last_blank_line != ($linenr - 1)) {
3136 if (CHK("LINE_SPACING",
3137 "Please don't use multiple blank lines\n" . $hereprev) &&
3138 $fix) {
3139 fix_delete_line($fixlinenr, $rawline);
3140 }
3141
3142 $last_blank_line = $linenr;
3143 }
3144
3145# check for missing blank lines after declarations
3146 if ($sline =~ /^\+\s+\S/ && #Not at char 1
3147 # actual declarations
3148 ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
3149 # function pointer declarations
3150 $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
3151 # foo bar; where foo is some local typedef or #define
3152 $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
3153 # known declaration macros
3154 $prevline =~ /^\+\s+$declaration_macros/) &&
3155 # for "else if" which can look like "$Ident $Ident"
3156 !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
3157 # other possible extensions of declaration lines
3158 $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
3159 # not starting a section or a macro "\" extended line
3160 $prevline =~ /(?:\{\s*|\\)$/) &&
3161 # looks like a declaration
3162 !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
3163 # function pointer declarations
3164 $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
3165 # foo bar; where foo is some local typedef or #define
Marcus Shawcroftf62e6812017-02-19 09:15:57 +00003166 $sline =~ /^\+\s+(?:volatile\s+)?$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003167 # known declaration macros
3168 $sline =~ /^\+\s+$declaration_macros/ ||
3169 # start of struct or union or enum
3170 $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
3171 # start or end of block or continuation of declaration
3172 $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
3173 # bitfield continuation
3174 $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
3175 # other possible extensions of declaration lines
3176 $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
3177 # indentation of previous and current line are the same
3178 (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3179 if (WARN("LINE_SPACING",
3180 "Missing a blank line after declarations\n" . $hereprev) &&
3181 $fix) {
3182 fix_insert_line($fixlinenr, "\+");
3183 }
3184 }
3185
3186# check for spaces at the beginning of a line.
3187# Exceptions:
3188# 1) within comments
3189# 2) indented preprocessor commands
3190# 3) hanging labels
3191 if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
3192 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3193 if (WARN("LEADING_SPACE",
3194 "please, no spaces at the start of a line\n" . $herevet) &&
3195 $fix) {
3196 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
3197 }
3198 }
3199
3200# check we are in a valid C source file if not then ignore this hunk
3201 next if ($realfile !~ /\.(h|c)$/);
3202
Anas Nashif1eb244c2017-10-01 17:06:36 -04003203# check if this appears to be the start function declaration, save the name
3204 if ($sline =~ /^\+\{\s*$/ &&
3205 $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
3206 $context_function = $1;
3207 }
3208
3209# check if this appears to be the end of function declaration
3210 if ($sline =~ /^\+\}\s*$/) {
3211 undef $context_function;
3212 }
3213
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003214# check indentation of any line with a bare else
3215# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3216# if the previous line is a break or return and is indented 1 tab more...
3217 if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3218 my $tabs = length($1) + 1;
3219 if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3220 ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3221 defined $lines[$linenr] &&
3222 $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3223 WARN("UNNECESSARY_ELSE",
3224 "else is not generally useful after a break or return\n" . $hereprev);
3225 }
3226 }
3227
3228# check indentation of a line with a break;
3229# if the previous line is a goto or return and is indented the same # of tabs
3230 if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3231 my $tabs = $1;
3232 if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3233 WARN("UNNECESSARY_BREAK",
3234 "break is not useful after a goto or return\n" . $hereprev);
3235 }
3236 }
3237
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003238# check for RCS/CVS revision markers
3239 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3240 WARN("CVS_KEYWORD",
3241 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3242 }
3243
3244# Blackfin: don't use __builtin_bfin_[cs]sync
3245 if ($line =~ /__builtin_bfin_csync/) {
3246 my $herevet = "$here\n" . cat_vet($line) . "\n";
3247 ERROR("CSYNC",
3248 "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
3249 }
3250 if ($line =~ /__builtin_bfin_ssync/) {
3251 my $herevet = "$here\n" . cat_vet($line) . "\n";
3252 ERROR("SSYNC",
3253 "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
3254 }
3255
3256# check for old HOTPLUG __dev<foo> section markings
3257 if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
3258 WARN("HOTPLUG_SECTION",
3259 "Using $1 is unnecessary\n" . $herecurr);
3260 }
3261
3262# Check for potential 'bare' types
3263 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
3264 $realline_next);
3265#print "LINE<$line>\n";
Anas Nashif1eb244c2017-10-01 17:06:36 -04003266 if ($linenr > $suppress_statement &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003267 $realcnt && $sline =~ /.\s*\S/) {
3268 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3269 ctx_statement_block($linenr, $realcnt, 0);
3270 $stat =~ s/\n./\n /g;
3271 $cond =~ s/\n./\n /g;
3272
3273#print "linenr<$linenr> <$stat>\n";
3274 # If this statement has no statement boundaries within
3275 # it there is no point in retrying a statement scan
3276 # until we hit end of it.
3277 my $frag = $stat; $frag =~ s/;+\s*$//;
3278 if ($frag !~ /(?:{|;)/) {
3279#print "skip<$line_nr_next>\n";
3280 $suppress_statement = $line_nr_next;
3281 }
3282
3283 # Find the real next line.
3284 $realline_next = $line_nr_next;
3285 if (defined $realline_next &&
3286 (!defined $lines[$realline_next - 1] ||
3287 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
3288 $realline_next++;
3289 }
3290
3291 my $s = $stat;
3292 $s =~ s/{.*$//s;
3293
3294 # Ignore goto labels.
3295 if ($s =~ /$Ident:\*$/s) {
3296
3297 # Ignore functions being called
3298 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3299
3300 } elsif ($s =~ /^.\s*else\b/s) {
3301
3302 # declarations always start with types
3303 } 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) {
3304 my $type = $1;
3305 $type =~ s/\s+/ /g;
3306 possible($type, "A:" . $s);
3307
3308 # definitions in global scope can only start with types
3309 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3310 possible($1, "B:" . $s);
3311 }
3312
3313 # any (foo ... *) is a pointer cast, and foo is a type
3314 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3315 possible($1, "C:" . $s);
3316 }
3317
3318 # Check for any sort of function declaration.
3319 # int foo(something bar, other baz);
3320 # void (*store_gdt)(x86_descr_ptr *);
3321 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
3322 my ($name_len) = length($1);
3323
3324 my $ctx = $s;
3325 substr($ctx, 0, $name_len + 1, '');
3326 $ctx =~ s/\)[^\)]*$//;
3327
3328 for my $arg (split(/\s*,\s*/, $ctx)) {
3329 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
3330
3331 possible($1, "D:" . $s);
3332 }
3333 }
3334 }
3335
3336 }
3337
3338#
3339# Checks which may be anchored in the context.
3340#
3341
3342# Check for switch () and associated case and default
3343# statements should be at the same indent.
3344 if ($line=~/\bswitch\s*\(.*\)/) {
3345 my $err = '';
3346 my $sep = '';
3347 my @ctx = ctx_block_outer($linenr, $realcnt);
3348 shift(@ctx);
3349 for my $ctx (@ctx) {
3350 my ($clen, $cindent) = line_stats($ctx);
3351 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
3352 $indent != $cindent) {
3353 $err .= "$sep$ctx\n";
3354 $sep = '';
3355 } else {
3356 $sep = "[...]\n";
3357 }
3358 }
3359 if ($err ne '') {
3360 ERROR("SWITCH_CASE_INDENT_LEVEL",
3361 "switch and case should be at the same indent\n$hereline$err");
3362 }
3363 }
3364
3365# if/while/etc brace do not go on next line, unless defining a do while loop,
3366# or if that brace on the next line is for something else
3367 if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
3368 my $pre_ctx = "$1$2";
3369
3370 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
3371
3372 if ($line =~ /^\+\t{6,}/) {
3373 WARN("DEEP_INDENTATION",
3374 "Too many leading tabs - consider code refactoring\n" . $herecurr);
3375 }
3376
3377 my $ctx_cnt = $realcnt - $#ctx - 1;
3378 my $ctx = join("\n", @ctx);
3379
3380 my $ctx_ln = $linenr;
3381 my $ctx_skip = $realcnt;
3382
3383 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3384 defined $lines[$ctx_ln - 1] &&
3385 $lines[$ctx_ln - 1] =~ /^-/)) {
3386 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3387 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3388 $ctx_ln++;
3389 }
3390
3391 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
3392 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3393
3394 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3395 ERROR("OPEN_BRACE",
3396 "that open brace { should be on the previous line\n" .
3397 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
3398 }
3399 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3400 $ctx =~ /\)\s*\;\s*$/ &&
3401 defined $lines[$ctx_ln - 1])
3402 {
3403 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
3404 if ($nindent > $indent) {
3405 WARN("TRAILING_SEMICOLON",
3406 "trailing semicolon indicates no statements, indent implies otherwise\n" .
3407 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
3408 }
3409 }
3410 }
3411
3412# Check relative indent for conditionals and blocks.
Anas Nashif1eb244c2017-10-01 17:06:36 -04003413 if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003414 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3415 ctx_statement_block($linenr, $realcnt, 0)
3416 if (!defined $stat);
3417 my ($s, $c) = ($stat, $cond);
3418
3419 substr($s, 0, length($c), '');
3420
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003421 # remove inline comments
3422 $s =~ s/$;/ /g;
3423 $c =~ s/$;/ /g;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003424
3425 # Find out how long the conditional actually is.
3426 my @newlines = ($c =~ /\n/gs);
3427 my $cond_lines = 1 + $#newlines;
3428
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003429 # Make sure we remove the line prefixes as we have
3430 # none on the first line, and are going to readd them
3431 # where necessary.
3432 $s =~ s/\n./\n/gs;
3433 while ($s =~ /\n\s+\\\n/) {
3434 $cond_lines += $s =~ s/\n\s+\\\n/\n/g;
3435 }
3436
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003437 # We want to check the first line inside the block
3438 # starting at the end of the conditional, so remove:
3439 # 1) any blank line termination
3440 # 2) any opening brace { on end of the line
3441 # 3) any do (...) {
3442 my $continuation = 0;
3443 my $check = 0;
3444 $s =~ s/^.*\bdo\b//;
3445 $s =~ s/^\s*{//;
3446 if ($s =~ s/^\s*\\//) {
3447 $continuation = 1;
3448 }
3449 if ($s =~ s/^\s*?\n//) {
3450 $check = 1;
3451 $cond_lines++;
3452 }
3453
3454 # Also ignore a loop construct at the end of a
3455 # preprocessor statement.
3456 if (($prevline =~ /^.\s*#\s*define\s/ ||
3457 $prevline =~ /\\\s*$/) && $continuation == 0) {
3458 $check = 0;
3459 }
3460
3461 my $cond_ptr = -1;
3462 $continuation = 0;
3463 while ($cond_ptr != $cond_lines) {
3464 $cond_ptr = $cond_lines;
3465
3466 # If we see an #else/#elif then the code
3467 # is not linear.
3468 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3469 $check = 0;
3470 }
3471
3472 # Ignore:
3473 # 1) blank lines, they should be at 0,
3474 # 2) preprocessor lines, and
3475 # 3) labels.
3476 if ($continuation ||
3477 $s =~ /^\s*?\n/ ||
3478 $s =~ /^\s*#\s*?/ ||
3479 $s =~ /^\s*$Ident\s*:/) {
3480 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
3481 if ($s =~ s/^.*?\n//) {
3482 $cond_lines++;
3483 }
3484 }
3485 }
3486
3487 my (undef, $sindent) = line_stats("+" . $s);
3488 my $stat_real = raw_line($linenr, $cond_lines);
3489
3490 # Check if either of these lines are modified, else
3491 # this is not this patch's fault.
3492 if (!defined($stat_real) ||
3493 $stat !~ /^\+/ && $stat_real !~ /^\+/) {
3494 $check = 0;
3495 }
3496 if (defined($stat_real) && $cond_lines > 1) {
3497 $stat_real = "[...]\n$stat_real";
3498 }
3499
3500 #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";
3501
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003502 if ($check && $s ne '' &&
3503 (($sindent % 8) != 0 ||
3504 ($sindent < $indent) ||
Anas Nashif1eb244c2017-10-01 17:06:36 -04003505 ($sindent == $indent &&
3506 ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003507 ($sindent > $indent + 8))) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003508 WARN("SUSPECT_CODE_INDENT",
3509 "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
3510 }
3511 }
3512
3513 # Track the 'values' across context and added lines.
3514 my $opline = $line; $opline =~ s/^./ /;
3515 my ($curr_values, $curr_vars) =
3516 annotate_values($opline . "\n", $prev_values);
3517 $curr_values = $prev_values . $curr_values;
3518 if ($dbg_values) {
3519 my $outline = $opline; $outline =~ s/\t/ /g;
3520 print "$linenr > .$outline\n";
3521 print "$linenr > $curr_values\n";
3522 print "$linenr > $curr_vars\n";
3523 }
3524 $prev_values = substr($curr_values, -1);
3525
3526#ignore lines not being added
3527 next if ($line =~ /^[^\+]/);
3528
Anas Nashif1eb244c2017-10-01 17:06:36 -04003529# check for dereferences that span multiple lines
3530 if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
3531 $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
3532 $prevline =~ /($Lval\s*(?:\.|->))\s*$/;
3533 my $ref = $1;
3534 $line =~ /^.\s*($Lval)/;
3535 $ref .= $1;
3536 $ref =~ s/\s//g;
3537 WARN("MULTILINE_DEREFERENCE",
3538 "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
3539 }
3540
Anas Nashif0f3d5472016-11-07 15:57:57 -05003541# check for declarations of signed or unsigned without int
3542 while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3543 my $type = $1;
3544 my $var = $2;
3545 $var = "" if (!defined $var);
3546 if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3547 my $sign = $1;
3548 my $pointer = $2;
3549
3550 $pointer = "" if (!defined $pointer);
3551
3552 if (WARN("UNSPECIFIED_INT",
3553 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3554 $fix) {
3555 my $decl = trim($sign) . " int ";
3556 my $comp_pointer = $pointer;
3557 $comp_pointer =~ s/\s//g;
3558 $decl .= $comp_pointer;
3559 $decl = rtrim($decl) if ($var eq "");
3560 $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3561 }
3562 }
3563 }
3564
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003565# TEST: allow direct testing of the type matcher.
3566 if ($dbg_type) {
3567 if ($line =~ /^.\s*$Declare\s*$/) {
3568 ERROR("TEST_TYPE",
3569 "TEST: is type\n" . $herecurr);
3570 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3571 ERROR("TEST_NOT_TYPE",
3572 "TEST: is not type ($1 is)\n". $herecurr);
3573 }
3574 next;
3575 }
3576# TEST: allow direct testing of the attribute matcher.
3577 if ($dbg_attr) {
3578 if ($line =~ /^.\s*$Modifier\s*$/) {
3579 ERROR("TEST_ATTR",
3580 "TEST: is attr\n" . $herecurr);
3581 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3582 ERROR("TEST_NOT_ATTR",
3583 "TEST: is not attr ($1 is)\n". $herecurr);
3584 }
3585 next;
3586 }
3587
3588# check for initialisation to aggregates open brace on the next line
3589 if ($line =~ /^.\s*{/ &&
3590 $prevline =~ /(?:^|[^=])=\s*$/) {
3591 if (ERROR("OPEN_BRACE",
3592 "that open brace { should be on the previous line\n" . $hereprev) &&
3593 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3594 fix_delete_line($fixlinenr - 1, $prevrawline);
3595 fix_delete_line($fixlinenr, $rawline);
3596 my $fixedline = $prevrawline;
3597 $fixedline =~ s/\s*=\s*$/ = {/;
3598 fix_insert_line($fixlinenr, $fixedline);
3599 $fixedline = $line;
Anas Nashif1eb244c2017-10-01 17:06:36 -04003600 $fixedline =~ s/^(.\s*)\{\s*/$1/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003601 fix_insert_line($fixlinenr, $fixedline);
3602 }
3603 }
3604
3605#
3606# Checks which are anchored on the added line.
3607#
3608
3609# check for malformed paths in #include statements (uses RAW line)
3610 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3611 my $path = $1;
3612 if ($path =~ m{//}) {
3613 ERROR("MALFORMED_INCLUDE",
3614 "malformed #include filename\n" . $herecurr);
3615 }
3616 if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3617 ERROR("UAPI_INCLUDE",
3618 "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3619 }
3620 }
3621
3622# no C99 // comments
3623 if ($line =~ m{//}) {
3624 if (ERROR("C99_COMMENTS",
3625 "do not use C99 // comments\n" . $herecurr) &&
3626 $fix) {
3627 my $line = $fixed[$fixlinenr];
3628 if ($line =~ /\/\/(.*)$/) {
3629 my $comment = trim($1);
3630 $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
3631 }
3632 }
3633 }
3634 # Remove C99 comments.
3635 $line =~ s@//.*@@;
3636 $opline =~ s@//.*@@;
3637
3638# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
3639# the whole statement.
3640#print "APW <$lines[$realline_next - 1]>\n";
3641 if (defined $realline_next &&
3642 exists $lines[$realline_next - 1] &&
3643 !defined $suppress_export{$realline_next} &&
3644 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
3645 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
3646 # Handle definitions which produce identifiers with
3647 # a prefix:
3648 # XXX(foo);
3649 # EXPORT_SYMBOL(something_foo);
3650 my $name = $1;
3651 if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
3652 $name =~ /^${Ident}_$2/) {
3653#print "FOO C name<$name>\n";
3654 $suppress_export{$realline_next} = 1;
3655
3656 } elsif ($stat !~ /(?:
3657 \n.}\s*$|
3658 ^.DEFINE_$Ident\(\Q$name\E\)|
3659 ^.DECLARE_$Ident\(\Q$name\E\)|
3660 ^.LIST_HEAD\(\Q$name\E\)|
3661 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
3662 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
3663 )/x) {
3664#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
3665 $suppress_export{$realline_next} = 2;
3666 } else {
3667 $suppress_export{$realline_next} = 1;
3668 }
3669 }
3670 if (!defined $suppress_export{$linenr} &&
3671 $prevline =~ /^.\s*$/ &&
3672 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
3673 $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
3674#print "FOO B <$lines[$linenr - 1]>\n";
3675 $suppress_export{$linenr} = 2;
3676 }
3677 if (defined $suppress_export{$linenr} &&
3678 $suppress_export{$linenr} == 2) {
3679 WARN("EXPORT_SYMBOL",
3680 "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
3681 }
3682
3683# check for global initialisers.
Anas Nashif76b09132016-02-20 13:53:35 -05003684 if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003685 if (ERROR("GLOBAL_INITIALISERS",
Anas Nashif76b09132016-02-20 13:53:35 -05003686 "do not initialise globals to $1\n" . $herecurr) &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003687 $fix) {
Anas Nashif76b09132016-02-20 13:53:35 -05003688 $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003689 }
3690 }
3691# check for static initialisers.
Anas Nashif76b09132016-02-20 13:53:35 -05003692 if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003693 if (ERROR("INITIALISED_STATIC",
Anas Nashif76b09132016-02-20 13:53:35 -05003694 "do not initialise statics to $1\n" .
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003695 $herecurr) &&
3696 $fix) {
Anas Nashif76b09132016-02-20 13:53:35 -05003697 $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003698 }
3699 }
3700
3701# check for misordered declarations of char/short/int/long with signed/unsigned
3702 while ($sline =~ m{(\b$TypeMisordered\b)}g) {
3703 my $tmp = trim($1);
3704 WARN("MISORDERED_TYPE",
3705 "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
3706 }
3707
3708# check for static const char * arrays.
3709 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3710 WARN("STATIC_CONST_CHAR_ARRAY",
3711 "static const char * array should probably be static const char * const\n" .
3712 $herecurr);
3713 }
3714
3715# check for static char foo[] = "bar" declarations.
3716 if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
3717 WARN("STATIC_CONST_CHAR_ARRAY",
3718 "static char array declaration should probably be static const char\n" .
3719 $herecurr);
3720 }
3721
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003722# check for const <foo> const where <foo> is not a pointer or array type
3723 if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
3724 my $found = $1;
3725 if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
3726 WARN("CONST_CONST",
3727 "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
3728 } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
3729 WARN("CONST_CONST",
3730 "'const $found const' should probably be 'const $found'\n" . $herecurr);
3731 }
3732 }
3733
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003734# check for non-global char *foo[] = {"bar", ...} declarations.
3735 if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
3736 WARN("STATIC_CONST_CHAR_ARRAY",
3737 "char * array declaration might be better as static const\n" .
3738 $herecurr);
3739 }
3740
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003741# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
3742 if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
3743 my $array = $1;
3744 if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
3745 my $array_div = $1;
3746 if (WARN("ARRAY_SIZE",
3747 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
3748 $fix) {
3749 $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
3750 }
3751 }
3752 }
3753
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003754# check for function declarations without arguments like "int foo()"
3755 if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
3756 if (ERROR("FUNCTION_WITHOUT_ARGS",
3757 "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
3758 $fix) {
3759 $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
3760 }
3761 }
3762
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003763# check for new typedefs, only function parameters and sparse annotations
3764# make sense.
3765 if ($line =~ /\btypedef\s/ &&
3766 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
3767 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
3768 $line !~ /\b$typeTypedefs\b/ &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04003769 $line !~ /\b__bitwise\b/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003770 WARN("NEW_TYPEDEFS",
3771 "do not add new typedefs\n" . $herecurr);
3772 }
3773
3774# * goes on variable not on type
3775 # (char*[ const])
3776 while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
3777 #print "AA<$1>\n";
3778 my ($ident, $from, $to) = ($1, $2, $2);
3779
3780 # Should start with a space.
3781 $to =~ s/^(\S)/ $1/;
3782 # Should not end with a space.
3783 $to =~ s/\s+$//;
3784 # '*'s should not have spaces between.
3785 while ($to =~ s/\*\s+\*/\*\*/) {
3786 }
3787
3788## print "1: from<$from> to<$to> ident<$ident>\n";
3789 if ($from ne $to) {
3790 if (ERROR("POINTER_LOCATION",
3791 "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
3792 $fix) {
3793 my $sub_from = $ident;
3794 my $sub_to = $ident;
3795 $sub_to =~ s/\Q$from\E/$to/;
3796 $fixed[$fixlinenr] =~
3797 s@\Q$sub_from\E@$sub_to@;
3798 }
3799 }
3800 }
3801 while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
3802 #print "BB<$1>\n";
3803 my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
3804
3805 # Should start with a space.
3806 $to =~ s/^(\S)/ $1/;
3807 # Should not end with a space.
3808 $to =~ s/\s+$//;
3809 # '*'s should not have spaces between.
3810 while ($to =~ s/\*\s+\*/\*\*/) {
3811 }
3812 # Modifiers should have spaces.
3813 $to =~ s/(\b$Modifier$)/$1 /;
3814
3815## print "2: from<$from> to<$to> ident<$ident>\n";
3816 if ($from ne $to && $ident !~ /^$Modifier$/) {
3817 if (ERROR("POINTER_LOCATION",
3818 "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
3819 $fix) {
3820
3821 my $sub_from = $match;
3822 my $sub_to = $match;
3823 $sub_to =~ s/\Q$from\E/$to/;
3824 $fixed[$fixlinenr] =~
3825 s@\Q$sub_from\E@$sub_to@;
3826 }
3827 }
3828 }
3829
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003830# avoid BUG() or BUG_ON()
3831 if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04003832 my $msg_level = \&WARN;
3833 $msg_level = \&CHK if ($file);
3834 &{$msg_level}("AVOID_BUG",
3835 "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003836 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003837
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003838# avoid LINUX_VERSION_CODE
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003839 if ($line =~ /\bLINUX_VERSION_CODE\b/) {
3840 WARN("LINUX_VERSION_CODE",
3841 "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
3842 }
3843
3844# check for uses of printk_ratelimit
3845 if ($line =~ /\bprintk_ratelimit\s*\(/) {
3846 WARN("PRINTK_RATELIMITED",
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003847 "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003848 }
3849
3850# printk should use KERN_* levels. Note that follow on printk's on the
3851# same line do not need a level, so we use the current block context
3852# to try and find and validate the current printk. In summary the current
3853# printk includes all preceding printk's which have no newline on the end.
3854# we assume the first bad printk is the one to report.
3855 if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
3856 my $ok = 0;
3857 for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
3858 #print "CHECK<$lines[$ln - 1]\n";
3859 # we have a preceding printk if it ends
3860 # with "\n" ignore it, else it is to blame
3861 if ($lines[$ln - 1] =~ m{\bprintk\(}) {
3862 if ($rawlines[$ln - 1] !~ m{\\n"}) {
3863 $ok = 1;
3864 }
3865 last;
3866 }
3867 }
3868 if ($ok == 0) {
3869 WARN("PRINTK_WITHOUT_KERN_LEVEL",
3870 "printk() should include KERN_ facility level\n" . $herecurr);
3871 }
3872 }
3873
3874 if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
3875 my $orig = $1;
3876 my $level = lc($orig);
3877 $level = "warn" if ($level eq "warning");
3878 my $level2 = $level;
3879 $level2 = "dbg" if ($level eq "debug");
3880 WARN("PREFER_PR_LEVEL",
3881 "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
3882 }
3883
3884 if ($line =~ /\bpr_warning\s*\(/) {
3885 if (WARN("PREFER_PR_LEVEL",
3886 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
3887 $fix) {
3888 $fixed[$fixlinenr] =~
3889 s/\bpr_warning\b/pr_warn/;
3890 }
3891 }
3892
3893 if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
3894 my $orig = $1;
3895 my $level = lc($orig);
3896 $level = "warn" if ($level eq "warning");
3897 $level = "dbg" if ($level eq "debug");
3898 WARN("PREFER_DEV_LEVEL",
3899 "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
3900 }
3901
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003902# ENOSYS means "bad syscall nr" and nothing else. This will have a small
3903# number of false positives, but assembly files are not checked, so at
3904# least the arch entry code will not trigger this warning.
3905 if ($line =~ /\bENOSYS\b/) {
3906 WARN("ENOSYS",
3907 "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
3908 }
3909
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003910# function brace can't be on same line, except for #defines of do while,
3911# or if closed on same line
3912 if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003913 !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003914 if (ERROR("OPEN_BRACE",
3915 "open brace '{' following function declarations go on the next line\n" . $herecurr) &&
3916 $fix) {
3917 fix_delete_line($fixlinenr, $rawline);
3918 my $fixed_line = $rawline;
3919 $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
3920 my $line1 = $1;
3921 my $line2 = $2;
3922 fix_insert_line($fixlinenr, ltrim($line1));
3923 fix_insert_line($fixlinenr, "\+{");
3924 if ($line2 !~ /^\s*$/) {
3925 fix_insert_line($fixlinenr, "\+\t" . trim($line2));
3926 }
3927 }
3928 }
3929
3930# open braces for enum, union and struct go on the same line.
3931 if ($line =~ /^.\s*{/ &&
3932 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
3933 if (ERROR("OPEN_BRACE",
3934 "open brace '{' following $1 go on the same line\n" . $hereprev) &&
3935 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3936 fix_delete_line($fixlinenr - 1, $prevrawline);
3937 fix_delete_line($fixlinenr, $rawline);
3938 my $fixedline = rtrim($prevrawline) . " {";
3939 fix_insert_line($fixlinenr, $fixedline);
3940 $fixedline = $rawline;
Anas Nashif1eb244c2017-10-01 17:06:36 -04003941 $fixedline =~ s/^(.\s*)\{\s*/$1\t/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003942 if ($fixedline !~ /^\+\s*$/) {
3943 fix_insert_line($fixlinenr, $fixedline);
3944 }
3945 }
3946 }
3947
3948# missing space after union, struct or enum definition
3949 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
3950 if (WARN("SPACING",
3951 "missing space after $1 definition\n" . $herecurr) &&
3952 $fix) {
3953 $fixed[$fixlinenr] =~
3954 s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
3955 }
3956 }
3957
3958# Function pointer declarations
3959# check spacing between type, funcptr, and args
3960# canonical declaration is "type (*funcptr)(args...)"
3961 if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
3962 my $declare = $1;
3963 my $pre_pointer_space = $2;
3964 my $post_pointer_space = $3;
3965 my $funcname = $4;
3966 my $post_funcname_space = $5;
3967 my $pre_args_space = $6;
3968
3969# the $Declare variable will capture all spaces after the type
3970# so check it for a missing trailing missing space but pointer return types
3971# don't need a space so don't warn for those.
3972 my $post_declare_space = "";
3973 if ($declare =~ /(\s+)$/) {
3974 $post_declare_space = $1;
3975 $declare = rtrim($declare);
3976 }
3977 if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
3978 WARN("SPACING",
3979 "missing space after return type\n" . $herecurr);
3980 $post_declare_space = " ";
3981 }
3982
3983# unnecessary space "type (*funcptr)(args...)"
3984# This test is not currently implemented because these declarations are
3985# equivalent to
3986# int foo(int bar, ...)
3987# and this is form shouldn't/doesn't generate a checkpatch warning.
3988#
3989# elsif ($declare =~ /\s{2,}$/) {
3990# WARN("SPACING",
3991# "Multiple spaces after return type\n" . $herecurr);
3992# }
3993
3994# unnecessary space "type ( *funcptr)(args...)"
3995 if (defined $pre_pointer_space &&
3996 $pre_pointer_space =~ /^\s/) {
3997 WARN("SPACING",
3998 "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
3999 }
4000
4001# unnecessary space "type (* funcptr)(args...)"
4002 if (defined $post_pointer_space &&
4003 $post_pointer_space =~ /^\s/) {
4004 WARN("SPACING",
4005 "Unnecessary space before function pointer name\n" . $herecurr);
4006 }
4007
4008# unnecessary space "type (*funcptr )(args...)"
4009 if (defined $post_funcname_space &&
4010 $post_funcname_space =~ /^\s/) {
4011 WARN("SPACING",
4012 "Unnecessary space after function pointer name\n" . $herecurr);
4013 }
4014
4015# unnecessary space "type (*funcptr) (args...)"
4016 if (defined $pre_args_space &&
4017 $pre_args_space =~ /^\s/) {
4018 WARN("SPACING",
4019 "Unnecessary space before function pointer arguments\n" . $herecurr);
4020 }
4021
4022 if (show_type("SPACING") && $fix) {
4023 $fixed[$fixlinenr] =~
4024 s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
4025 }
4026 }
4027
4028# check for spacing round square brackets; allowed:
4029# 1. with a type on the left -- int [] a;
4030# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4031# 3. inside a curly brace -- = { [0...10] = 5 }
4032 while ($line =~ /(.*?\s)\[/g) {
4033 my ($where, $prefix) = ($-[1], $1);
4034 if ($prefix !~ /$Type\s+$/ &&
4035 ($where != 0 || $prefix !~ /^.\s+$/) &&
Anas Nashif98c50de2015-11-06 18:23:35 -05004036 $prefix !~ /[{,]\s+$/ &&
4037 $prefix !~ /:\s+$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004038 if (ERROR("BRACKET_SPACE",
4039 "space prohibited before open square bracket '['\n" . $herecurr) &&
4040 $fix) {
4041 $fixed[$fixlinenr] =~
4042 s/^(\+.*?)\s+\[/$1\[/;
4043 }
4044 }
4045 }
4046
4047# check for spaces between functions and their parentheses.
4048 while ($line =~ /($Ident)\s+\(/g) {
4049 my $name = $1;
4050 my $ctx_before = substr($line, 0, $-[1]);
4051 my $ctx = "$ctx_before$name";
4052
4053 # Ignore those directives where spaces _are_ permitted.
4054 if ($name =~ /^(?:
4055 if|for|while|switch|return|case|
4056 volatile|__volatile__|
4057 __attribute__|format|__extension__|
4058 asm|__asm__)$/x)
4059 {
4060 # cpp #define statements have non-optional spaces, ie
4061 # if there is a space between the name and the open
4062 # parenthesis it is simply not a parameter group.
4063 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4064
4065 # cpp #elif statement condition may start with a (
4066 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4067
4068 # If this whole things ends with a type its most
4069 # likely a typedef for a function.
4070 } elsif ($ctx =~ /$Type$/) {
4071
4072 } else {
4073 if (WARN("SPACING",
4074 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
4075 $fix) {
4076 $fixed[$fixlinenr] =~
4077 s/\b$name\s+\(/$name\(/;
4078 }
4079 }
4080 }
4081
4082# Check operator spacing.
4083 if (!($line=~/\#\s*include/)) {
4084 my $fixed_line = "";
4085 my $line_fixed = 0;
4086
4087 my $ops = qr{
4088 <<=|>>=|<=|>=|==|!=|
4089 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
4090 =>|->|<<|>>|<|>|=|!|~|
4091 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
4092 \?:|\?|:
4093 }x;
4094 my @elements = split(/($ops|;)/, $opline);
4095
4096## print("element count: <" . $#elements . ">\n");
4097## foreach my $el (@elements) {
4098## print("el: <$el>\n");
4099## }
4100
4101 my @fix_elements = ();
4102 my $off = 0;
4103
4104 foreach my $el (@elements) {
4105 push(@fix_elements, substr($rawline, $off, length($el)));
4106 $off += length($el);
4107 }
4108
4109 $off = 0;
4110
4111 my $blank = copy_spacing($opline);
4112 my $last_after = -1;
4113
4114 for (my $n = 0; $n < $#elements; $n += 2) {
4115
4116 my $good = $fix_elements[$n] . $fix_elements[$n + 1];
4117
4118## print("n: <$n> good: <$good>\n");
4119
4120 $off += length($elements[$n]);
4121
4122 # Pick up the preceding and succeeding characters.
4123 my $ca = substr($opline, 0, $off);
4124 my $cc = '';
4125 if (length($opline) >= ($off + length($elements[$n + 1]))) {
4126 $cc = substr($opline, $off + length($elements[$n + 1]));
4127 }
4128 my $cb = "$ca$;$cc";
4129
4130 my $a = '';
4131 $a = 'V' if ($elements[$n] ne '');
4132 $a = 'W' if ($elements[$n] =~ /\s$/);
4133 $a = 'C' if ($elements[$n] =~ /$;$/);
4134 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
4135 $a = 'O' if ($elements[$n] eq '');
4136 $a = 'E' if ($ca =~ /^\s*$/);
4137
4138 my $op = $elements[$n + 1];
4139
4140 my $c = '';
4141 if (defined $elements[$n + 2]) {
4142 $c = 'V' if ($elements[$n + 2] ne '');
4143 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
4144 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
4145 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
4146 $c = 'O' if ($elements[$n + 2] eq '');
4147 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
4148 } else {
4149 $c = 'E';
4150 }
4151
4152 my $ctx = "${a}x${c}";
4153
4154 my $at = "(ctx:$ctx)";
4155
4156 my $ptr = substr($blank, 0, $off) . "^";
4157 my $hereptr = "$hereline$ptr\n";
4158
4159 # Pull out the value of this operator.
4160 my $op_type = substr($curr_values, $off + 1, 1);
4161
4162 # Get the full operator variant.
4163 my $opv = $op . substr($curr_vars, $off, 1);
4164
4165 # Ignore operators passed as parameters.
4166 if ($op_type ne 'V' &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004167 $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004168
4169# # Ignore comments
4170# } elsif ($op =~ /^$;+$/) {
4171
4172 # ; should have either the end of line or a space or \ after it
4173 } elsif ($op eq ';') {
4174 if ($ctx !~ /.x[WEBC]/ &&
4175 $cc !~ /^\\/ && $cc !~ /^;/) {
4176 if (ERROR("SPACING",
4177 "space required after that '$op' $at\n" . $hereptr)) {
4178 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
4179 $line_fixed = 1;
4180 }
4181 }
4182
4183 # // is a comment
4184 } elsif ($op eq '//') {
4185
4186 # : when part of a bitfield
4187 } elsif ($opv eq ':B') {
4188 # skip the bitfield test for now
4189
4190 # No spaces for:
4191 # ->
4192 } elsif ($op eq '->') {
4193 if ($ctx =~ /Wx.|.xW/) {
4194 if (ERROR("SPACING",
4195 "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4196 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4197 if (defined $fix_elements[$n + 2]) {
4198 $fix_elements[$n + 2] =~ s/^\s+//;
4199 }
4200 $line_fixed = 1;
4201 }
4202 }
4203
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004204 # , must not have a space before and must have a space on the right.
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004205 } elsif ($op eq ',') {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004206 my $rtrim_before = 0;
4207 my $space_after = 0;
4208 if ($ctx =~ /Wx./) {
4209 if (ERROR("SPACING",
4210 "space prohibited before that '$op' $at\n" . $hereptr)) {
4211 $line_fixed = 1;
4212 $rtrim_before = 1;
4213 }
4214 }
Anas Nashife7ee0832016-02-20 14:13:16 -05004215 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/ && $cc !~ /^\)/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004216 if (ERROR("SPACING",
4217 "space required after that '$op' $at\n" . $hereptr)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004218 $line_fixed = 1;
4219 $last_after = $n;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004220 $space_after = 1;
4221 }
4222 }
4223 if ($rtrim_before || $space_after) {
4224 if ($rtrim_before) {
4225 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4226 } else {
4227 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
4228 }
4229 if ($space_after) {
4230 $good .= " ";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004231 }
4232 }
4233
4234 # '*' as part of a type definition -- reported already.
4235 } elsif ($opv eq '*_') {
4236 #warn "'*' is part of type\n";
4237
4238 # unary operators should have a space before and
4239 # none after. May be left adjacent to another
4240 # unary operator, or a cast
4241 } elsif ($op eq '!' || $op eq '~' ||
4242 $opv eq '*U' || $opv eq '-U' ||
4243 $opv eq '&U' || $opv eq '&&U') {
4244 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
4245 if (ERROR("SPACING",
4246 "space required before that '$op' $at\n" . $hereptr)) {
4247 if ($n != $last_after + 2) {
4248 $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
4249 $line_fixed = 1;
4250 }
4251 }
4252 }
4253 if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4254 # A unary '*' may be const
4255
4256 } elsif ($ctx =~ /.xW/) {
4257 if (ERROR("SPACING",
4258 "space prohibited after that '$op' $at\n" . $hereptr)) {
4259 $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
4260 if (defined $fix_elements[$n + 2]) {
4261 $fix_elements[$n + 2] =~ s/^\s+//;
4262 }
4263 $line_fixed = 1;
4264 }
4265 }
4266
4267 # unary ++ and unary -- are allowed no space on one side.
4268 } elsif ($op eq '++' or $op eq '--') {
4269 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
4270 if (ERROR("SPACING",
4271 "space required one side of that '$op' $at\n" . $hereptr)) {
4272 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
4273 $line_fixed = 1;
4274 }
4275 }
4276 if ($ctx =~ /Wx[BE]/ ||
4277 ($ctx =~ /Wx./ && $cc =~ /^;/)) {
4278 if (ERROR("SPACING",
4279 "space prohibited before that '$op' $at\n" . $hereptr)) {
4280 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4281 $line_fixed = 1;
4282 }
4283 }
4284 if ($ctx =~ /ExW/) {
4285 if (ERROR("SPACING",
4286 "space prohibited after that '$op' $at\n" . $hereptr)) {
4287 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
4288 if (defined $fix_elements[$n + 2]) {
4289 $fix_elements[$n + 2] =~ s/^\s+//;
4290 }
4291 $line_fixed = 1;
4292 }
4293 }
4294
4295 # << and >> may either have or not have spaces both sides
4296 } elsif ($op eq '<<' or $op eq '>>' or
4297 $op eq '&' or $op eq '^' or $op eq '|' or
4298 $op eq '+' or $op eq '-' or
4299 $op eq '*' or $op eq '/' or
4300 $op eq '%')
4301 {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004302 if ($check) {
4303 if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4304 if (CHK("SPACING",
4305 "spaces preferred around that '$op' $at\n" . $hereptr)) {
4306 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4307 $fix_elements[$n + 2] =~ s/^\s+//;
4308 $line_fixed = 1;
4309 }
4310 } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4311 if (CHK("SPACING",
4312 "space preferred before that '$op' $at\n" . $hereptr)) {
4313 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4314 $line_fixed = 1;
4315 }
4316 }
4317 } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004318 if (ERROR("SPACING",
4319 "need consistent spacing around '$op' $at\n" . $hereptr)) {
4320 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4321 if (defined $fix_elements[$n + 2]) {
4322 $fix_elements[$n + 2] =~ s/^\s+//;
4323 }
4324 $line_fixed = 1;
4325 }
4326 }
4327
4328 # A colon needs no spaces before when it is
4329 # terminating a case value or a label.
4330 } elsif ($opv eq ':C' || $opv eq ':L') {
4331 if ($ctx =~ /Wx./) {
4332 if (ERROR("SPACING",
4333 "space prohibited before that '$op' $at\n" . $hereptr)) {
4334 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4335 $line_fixed = 1;
4336 }
4337 }
4338
4339 # All the others need spaces both sides.
4340 } elsif ($ctx !~ /[EWC]x[CWE]/) {
4341 my $ok = 0;
4342
4343 # Ignore email addresses <foo@bar>
4344 if (($op eq '<' &&
4345 $cc =~ /^\S+\@\S+>/) ||
4346 ($op eq '>' &&
4347 $ca =~ /<\S+\@\S+$/))
4348 {
4349 $ok = 1;
4350 }
4351
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004352 # for asm volatile statements
4353 # ignore a colon with another
4354 # colon immediately before or after
4355 if (($op eq ':') &&
4356 ($ca =~ /:$/ || $cc =~ /^:/)) {
4357 $ok = 1;
4358 }
4359
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004360 # messages are ERROR, but ?: are CHK
4361 if ($ok == 0) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04004362 my $msg_level = \&ERROR;
4363 $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004364
Anas Nashif1eb244c2017-10-01 17:06:36 -04004365 if (&{$msg_level}("SPACING",
4366 "spaces required around that '$op' $at\n" . $hereptr)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004367 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4368 if (defined $fix_elements[$n + 2]) {
4369 $fix_elements[$n + 2] =~ s/^\s+//;
4370 }
4371 $line_fixed = 1;
4372 }
4373 }
4374 }
4375 $off += length($elements[$n + 1]);
4376
4377## print("n: <$n> GOOD: <$good>\n");
4378
4379 $fixed_line = $fixed_line . $good;
4380 }
4381
4382 if (($#elements % 2) == 0) {
4383 $fixed_line = $fixed_line . $fix_elements[$#elements];
4384 }
4385
4386 if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4387 $fixed[$fixlinenr] = $fixed_line;
4388 }
4389
4390
4391 }
4392
4393# check for whitespace before a non-naked semicolon
4394 if ($line =~ /^\+.*\S\s+;\s*$/) {
4395 if (WARN("SPACING",
4396 "space prohibited before semicolon\n" . $herecurr) &&
4397 $fix) {
4398 1 while $fixed[$fixlinenr] =~
4399 s/^(\+.*\S)\s+;/$1;/;
4400 }
4401 }
4402
4403# check for multiple assignments
4404 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4405 CHK("MULTIPLE_ASSIGNMENTS",
4406 "multiple assignments should be avoided\n" . $herecurr);
4407 }
4408
4409## # check for multiple declarations, allowing for a function declaration
4410## # continuation.
4411## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
4412## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
4413##
4414## # Remove any bracketed sections to ensure we do not
4415## # falsly report the parameters of functions.
4416## my $ln = $line;
4417## while ($ln =~ s/\([^\(\)]*\)//g) {
4418## }
4419## if ($ln =~ /,/) {
4420## WARN("MULTIPLE_DECLARATION",
4421## "declaring multiple variables together should be avoided\n" . $herecurr);
4422## }
4423## }
4424
4425#need space before brace following if, while, etc
Anas Nashif0f3d5472016-11-07 15:57:57 -05004426 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004427 $line =~ /do\{/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004428 if (ERROR("SPACING",
4429 "space required before the open brace '{'\n" . $herecurr) &&
4430 $fix) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04004431 $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004432 }
4433 }
4434
4435## # check for blank lines before declarations
4436## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4437## $prevrawline =~ /^.\s*$/) {
4438## WARN("SPACING",
4439## "No blank lines before declarations\n" . $hereprev);
4440## }
4441##
4442
4443# closing brace should have a space following it when it has anything
4444# on the line
4445 if ($line =~ /}(?!(?:,|;|\)))\S/) {
4446 if (ERROR("SPACING",
4447 "space required after that close brace '}'\n" . $herecurr) &&
4448 $fix) {
4449 $fixed[$fixlinenr] =~
4450 s/}((?!(?:,|;|\)))\S)/} $1/;
4451 }
4452 }
4453
4454# check spacing on square brackets
4455 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
4456 if (ERROR("SPACING",
4457 "space prohibited after that open square bracket '['\n" . $herecurr) &&
4458 $fix) {
4459 $fixed[$fixlinenr] =~
4460 s/\[\s+/\[/;
4461 }
4462 }
4463 if ($line =~ /\s\]/) {
4464 if (ERROR("SPACING",
4465 "space prohibited before that close square bracket ']'\n" . $herecurr) &&
4466 $fix) {
4467 $fixed[$fixlinenr] =~
4468 s/\s+\]/\]/;
4469 }
4470 }
4471
4472# check spacing on parentheses
4473 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
4474 $line !~ /for\s*\(\s+;/) {
4475 if (ERROR("SPACING",
4476 "space prohibited after that open parenthesis '('\n" . $herecurr) &&
4477 $fix) {
4478 $fixed[$fixlinenr] =~
4479 s/\(\s+/\(/;
4480 }
4481 }
4482 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4483 $line !~ /for\s*\(.*;\s+\)/ &&
4484 $line !~ /:\s+\)/) {
4485 if (ERROR("SPACING",
4486 "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
4487 $fix) {
4488 $fixed[$fixlinenr] =~
4489 s/\s+\)/\)/;
4490 }
4491 }
4492
4493# check unnecessary parentheses around addressof/dereference single $Lvals
4494# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4495
4496 while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004497 my $var = $1;
4498 if (CHK("UNNECESSARY_PARENTHESES",
4499 "Unnecessary parentheses around $var\n" . $herecurr) &&
4500 $fix) {
4501 $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4502 }
4503 }
4504
4505# check for unnecessary parentheses around function pointer uses
4506# ie: (foo->bar)(); should be foo->bar();
4507# but not "if (foo->bar) (" to avoid some false positives
4508 if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4509 my $var = $2;
4510 if (CHK("UNNECESSARY_PARENTHESES",
4511 "Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4512 $fix) {
4513 my $var2 = deparenthesize($var);
4514 $var2 =~ s/\s//g;
4515 $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4516 }
4517 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004518
Anas Nashif1eb244c2017-10-01 17:06:36 -04004519# check for unnecessary parentheses around comparisons in if uses
4520 if ($^V && $^V ge 5.10.0 && defined($stat) &&
4521 $stat =~ /(^.\s*if\s*($balanced_parens))/) {
4522 my $if_stat = $1;
4523 my $test = substr($2, 1, -1);
4524 my $herectx;
4525 while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
4526 my $match = $1;
4527 # avoid parentheses around potential macro args
4528 next if ($match =~ /^\s*\w+\s*$/);
4529 if (!defined($herectx)) {
4530 $herectx = $here . "\n";
4531 my $cnt = statement_rawlines($if_stat);
4532 for (my $n = 0; $n < $cnt; $n++) {
4533 my $rl = raw_line($linenr, $n);
4534 $herectx .= $rl . "\n";
4535 last if $rl =~ /^[ \+].*\{/;
4536 }
4537 }
4538 CHK("UNNECESSARY_PARENTHESES",
4539 "Unnecessary parentheses around '$match'\n" . $herectx);
4540 }
4541 }
4542
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004543#goto labels aren't indented, allow a single space however
4544 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
4545 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
4546 if (WARN("INDENTED_LABEL",
4547 "labels should not be indented\n" . $herecurr) &&
4548 $fix) {
4549 $fixed[$fixlinenr] =~
4550 s/^(.)\s+/$1/;
4551 }
4552 }
4553
4554# return is not a function
4555 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4556 my $spacing = $1;
4557 if ($^V && $^V ge 5.10.0 &&
4558 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
4559 my $value = $1;
4560 $value = deparenthesize($value);
4561 if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4562 ERROR("RETURN_PARENTHESES",
4563 "return is not a function, parentheses are not required\n" . $herecurr);
4564 }
4565 } elsif ($spacing !~ /\s+/) {
4566 ERROR("SPACING",
4567 "space required before the open parenthesis '('\n" . $herecurr);
4568 }
4569 }
4570
4571# unnecessary return in a void function
4572# at end-of-function, with the previous line a single leading tab, then return;
4573# and the line before that not a goto label target like "out:"
4574 if ($sline =~ /^[ \+]}\s*$/ &&
4575 $prevline =~ /^\+\treturn\s*;\s*$/ &&
4576 $linenr >= 3 &&
4577 $lines[$linenr - 3] =~ /^[ +]/ &&
4578 $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
4579 WARN("RETURN_VOID",
4580 "void function return statements are not generally useful\n" . $hereprev);
4581 }
4582
4583# if statements using unnecessary parentheses - ie: if ((foo == bar))
4584 if ($^V && $^V ge 5.10.0 &&
4585 $line =~ /\bif\s*((?:\(\s*){2,})/) {
4586 my $openparens = $1;
4587 my $count = $openparens =~ tr@\(@\(@;
4588 my $msg = "";
4589 if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4590 my $comp = $4; #Not $1 because of $LvalOrFunc
4591 $msg = " - maybe == should be = ?" if ($comp eq "==");
4592 WARN("UNNECESSARY_PARENTHESES",
4593 "Unnecessary parentheses$msg\n" . $herecurr);
4594 }
4595 }
4596
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004597# comparisons with a constant or upper case identifier on the left
4598# avoid cases like "foo + BAR < baz"
4599# only fix matches surrounded by parentheses to avoid incorrect
4600# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
4601 if ($^V && $^V ge 5.10.0 &&
4602 $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4603 my $lead = $1;
4604 my $const = $2;
4605 my $comp = $3;
4606 my $to = $4;
4607 my $newcomp = $comp;
Anas Nashif0f3d5472016-11-07 15:57:57 -05004608 if ($lead !~ /(?:$Operators|\.)\s*$/ &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004609 $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4610 WARN("CONSTANT_COMPARISON",
4611 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4612 $fix) {
4613 if ($comp eq "<") {
4614 $newcomp = ">";
4615 } elsif ($comp eq "<=") {
4616 $newcomp = ">=";
4617 } elsif ($comp eq ">") {
4618 $newcomp = "<";
4619 } elsif ($comp eq ">=") {
4620 $newcomp = "<=";
4621 }
4622 $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4623 }
4624 }
4625
4626# Return of what appears to be an errno should normally be negative
4627 if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004628 my $name = $1;
4629 if ($name ne 'EOF' && $name ne 'ERROR') {
4630 WARN("USE_NEGATIVE_ERRNO",
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004631 "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004632 }
4633 }
4634
4635# Need a space before open parenthesis after if, while etc
4636 if ($line =~ /\b(if|while|for|switch)\(/) {
4637 if (ERROR("SPACING",
4638 "space required before the open parenthesis '('\n" . $herecurr) &&
4639 $fix) {
4640 $fixed[$fixlinenr] =~
4641 s/\b(if|while|for|switch)\(/$1 \(/;
4642 }
4643 }
4644
4645# Check for illegal assignment in if conditional -- and check for trailing
4646# statements after the conditional.
4647 if ($line =~ /do\s*(?!{)/) {
4648 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4649 ctx_statement_block($linenr, $realcnt, 0)
4650 if (!defined $stat);
4651 my ($stat_next) = ctx_statement_block($line_nr_next,
4652 $remain_next, $off_next);
4653 $stat_next =~ s/\n./\n /g;
4654 ##print "stat<$stat> stat_next<$stat_next>\n";
4655
4656 if ($stat_next =~ /^\s*while\b/) {
4657 # If the statement carries leading newlines,
4658 # then count those as offsets.
4659 my ($whitespace) =
4660 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4661 my $offset =
4662 statement_rawlines($whitespace) - 1;
4663
4664 $suppress_whiletrailers{$line_nr_next +
4665 $offset} = 1;
4666 }
4667 }
4668 if (!defined $suppress_whiletrailers{$linenr} &&
4669 defined($stat) && defined($cond) &&
4670 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4671 my ($s, $c) = ($stat, $cond);
4672
4673 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4674 ERROR("ASSIGN_IN_IF",
4675 "do not use assignment in if condition\n" . $herecurr);
4676 }
4677
4678 # Find out what is on the end of the line after the
4679 # conditional.
4680 substr($s, 0, length($c), '');
4681 $s =~ s/\n.*//g;
4682 $s =~ s/$;//g; # Remove any comments
4683 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
4684 $c !~ /}\s*while\s*/)
4685 {
4686 # Find out how long the conditional actually is.
4687 my @newlines = ($c =~ /\n/gs);
4688 my $cond_lines = 1 + $#newlines;
4689 my $stat_real = '';
4690
4691 $stat_real = raw_line($linenr, $cond_lines)
4692 . "\n" if ($cond_lines);
4693 if (defined($stat_real) && $cond_lines > 1) {
4694 $stat_real = "[...]\n$stat_real";
4695 }
4696
4697 ERROR("TRAILING_STATEMENTS",
4698 "trailing statements should be on next line\n" . $herecurr . $stat_real);
4699 }
4700 }
4701
4702# Check for bitwise tests written as boolean
4703 if ($line =~ /
4704 (?:
4705 (?:\[|\(|\&\&|\|\|)
4706 \s*0[xX][0-9]+\s*
4707 (?:\&\&|\|\|)
4708 |
4709 (?:\&\&|\|\|)
4710 \s*0[xX][0-9]+\s*
4711 (?:\&\&|\|\||\)|\])
4712 )/x)
4713 {
4714 WARN("HEXADECIMAL_BOOLEAN_TEST",
4715 "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
4716 }
4717
4718# if and else should not have general statements after it
4719 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
4720 my $s = $1;
4721 $s =~ s/$;//g; # Remove any comments
4722 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
4723 ERROR("TRAILING_STATEMENTS",
4724 "trailing statements should be on next line\n" . $herecurr);
4725 }
4726 }
4727# if should not continue a brace
4728 if ($line =~ /}\s*if\b/) {
4729 ERROR("TRAILING_STATEMENTS",
4730 "trailing statements should be on next line (or did you mean 'else if'?)\n" .
4731 $herecurr);
4732 }
4733# case and default should not have general statements after them
4734 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
4735 $line !~ /\G(?:
4736 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
4737 \s*return\s+
4738 )/xg)
4739 {
4740 ERROR("TRAILING_STATEMENTS",
4741 "trailing statements should be on next line\n" . $herecurr);
4742 }
4743
4744 # Check for }<nl>else {, these must be at the same
4745 # indent level to be relevant to each other.
4746 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
4747 $previndent == $indent) {
4748 if (ERROR("ELSE_AFTER_BRACE",
4749 "else should follow close brace '}'\n" . $hereprev) &&
4750 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4751 fix_delete_line($fixlinenr - 1, $prevrawline);
4752 fix_delete_line($fixlinenr, $rawline);
4753 my $fixedline = $prevrawline;
4754 $fixedline =~ s/}\s*$//;
4755 if ($fixedline !~ /^\+\s*$/) {
4756 fix_insert_line($fixlinenr, $fixedline);
4757 }
4758 $fixedline = $rawline;
4759 $fixedline =~ s/^(.\s*)else/$1} else/;
4760 fix_insert_line($fixlinenr, $fixedline);
4761 }
4762 }
4763
4764 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
4765 $previndent == $indent) {
4766 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
4767
4768 # Find out what is on the end of the line after the
4769 # conditional.
4770 substr($s, 0, length($c), '');
4771 $s =~ s/\n.*//g;
4772
4773 if ($s =~ /^\s*;/) {
4774 if (ERROR("WHILE_AFTER_BRACE",
4775 "while should follow close brace '}'\n" . $hereprev) &&
4776 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4777 fix_delete_line($fixlinenr - 1, $prevrawline);
4778 fix_delete_line($fixlinenr, $rawline);
4779 my $fixedline = $prevrawline;
4780 my $trailing = $rawline;
4781 $trailing =~ s/^\+//;
4782 $trailing = trim($trailing);
4783 $fixedline =~ s/}\s*$/} $trailing/;
4784 fix_insert_line($fixlinenr, $fixedline);
4785 }
4786 }
4787 }
4788
4789#Specific variable tests
4790 while ($line =~ m{($Constant|$Lval)}g) {
4791 my $var = $1;
4792
4793#gcc binary extension
4794 if ($var =~ /^$Binary$/) {
4795 if (WARN("GCC_BINARY_CONSTANT",
4796 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4797 $fix) {
4798 my $hexval = sprintf("0x%x", oct($var));
4799 $fixed[$fixlinenr] =~
4800 s/\b$var\b/$hexval/;
4801 }
4802 }
4803
4804#CamelCase
4805 if ($var !~ /^$Constant$/ &&
4806 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
4807#Ignore Page<foo> variants
4808 $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
4809#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004810 $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
4811#Ignore some three character SI units explicitly, like MiB and KHz
4812 $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004813 while ($var =~ m{($Ident)}g) {
4814 my $word = $1;
4815 next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
4816 if ($check) {
4817 seed_camelcase_includes();
4818 if (!$file && !$camelcase_file_seeded) {
4819 seed_camelcase_file($realfile);
4820 $camelcase_file_seeded = 1;
4821 }
4822 }
4823 if (!defined $camelcase{$word}) {
4824 $camelcase{$word} = 1;
4825 CHK("CAMELCASE",
4826 "Avoid CamelCase: <$word>\n" . $herecurr);
4827 }
4828 }
4829 }
4830 }
4831
4832#no spaces allowed after \ in define
4833 if ($line =~ /\#\s*define.*\\\s+$/) {
4834 if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
4835 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
4836 $fix) {
4837 $fixed[$fixlinenr] =~ s/\s+$//;
4838 }
4839 }
4840
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004841# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
4842# itself <asm/foo.h> (uses RAW line)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004843 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
4844 my $file = "$1.h";
4845 my $checkfile = "include/linux/$file";
4846 if (-f "$root/$checkfile" &&
4847 $realfile ne $checkfile &&
4848 $1 !~ /$allowed_asm_includes/)
4849 {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004850 my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
4851 if ($asminclude > 0) {
4852 if ($realfile =~ m{^arch/}) {
4853 CHK("ARCH_INCLUDE_LINUX",
4854 "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4855 } else {
4856 WARN("INCLUDE_LINUX",
4857 "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4858 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004859 }
4860 }
4861 }
4862
4863# multi-statement macros should be enclosed in a do while loop, grab the
4864# first statement and ensure its the whole macro if its not enclosed
4865# in a known good container
4866 if ($realfile !~ m@/vmlinux.lds.h$@ &&
4867 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
4868 my $ln = $linenr;
4869 my $cnt = $realcnt;
4870 my ($off, $dstat, $dcond, $rest);
4871 my $ctx = '';
4872 my $has_flow_statement = 0;
4873 my $has_arg_concat = 0;
4874 ($dstat, $dcond, $ln, $cnt, $off) =
4875 ctx_statement_block($linenr, $realcnt, 0);
4876 $ctx = $dstat;
4877 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
4878 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
4879
4880 $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
Anas Nashif76b09132016-02-20 13:53:35 -05004881 $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004882
Anas Nashif0f3d5472016-11-07 15:57:57 -05004883 $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
4884 my $define_args = $1;
4885 my $define_stmt = $dstat;
4886 my @def_args = ();
4887
4888 if (defined $define_args && $define_args ne "") {
4889 $define_args = substr($define_args, 1, length($define_args) - 2);
4890 $define_args =~ s/\s*//g;
4891 @def_args = split(",", $define_args);
4892 }
4893
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004894 $dstat =~ s/$;//g;
4895 $dstat =~ s/\\\n.//g;
4896 $dstat =~ s/^\s*//s;
4897 $dstat =~ s/\s*$//s;
4898
4899 # Flatten any parentheses and braces
4900 while ($dstat =~ s/\([^\(\)]*\)/1/ ||
4901 $dstat =~ s/\{[^\{\}]*\}/1/ ||
Anas Nashif76b09132016-02-20 13:53:35 -05004902 $dstat =~ s/.\[[^\[\]]*\]/1/)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004903 {
4904 }
4905
4906 # Flatten any obvious string concatentation.
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004907 while ($dstat =~ s/($String)\s*$Ident/$1/ ||
4908 $dstat =~ s/$Ident\s*($String)/$1/)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004909 {
4910 }
4911
Anas Nashif0f3d5472016-11-07 15:57:57 -05004912 # Make asm volatile uses seem like a generic function
4913 $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
4914
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004915 my $exceptions = qr{
4916 $Declare|
4917 module_param_named|
4918 MODULE_PARM_DESC|
4919 DECLARE_PER_CPU|
4920 DEFINE_PER_CPU|
4921 __typeof__\(|
4922 union|
4923 struct|
4924 \.$Ident\s*=\s*|
Anas Nashif76b09132016-02-20 13:53:35 -05004925 ^\"|\"$|
4926 ^\[
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004927 }x;
4928 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
Anas Nashif0f3d5472016-11-07 15:57:57 -05004929
4930 $ctx =~ s/\n*$//;
4931 my $herectx = $here . "\n";
4932 my $stmt_cnt = statement_rawlines($ctx);
4933
4934 for (my $n = 0; $n < $stmt_cnt; $n++) {
4935 $herectx .= raw_line($linenr, $n) . "\n";
4936 }
4937
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004938 if ($dstat ne '' &&
4939 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
4940 $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
4941 $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
4942 $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants
4943 $dstat !~ /$exceptions/ &&
4944 $dstat !~ /^\.$Ident\s*=/ && # .foo =
4945 $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
4946 $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
4947 $dstat !~ /^for\s*$Constant$/ && # for (...)
4948 $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
4949 $dstat !~ /^do\s*{/ && # do {...
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004950 $dstat !~ /^\(\{/ && # ({...
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004951 $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
4952 {
Anas Nashif1eb244c2017-10-01 17:06:36 -04004953 if ($dstat =~ /^\s*if\b/) {
4954 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4955 "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
4956 } elsif ($dstat =~ /;/) {
4957 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004958 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
4959 } else {
Anas Nashif65f0c672018-05-08 10:19:30 -05004960 WARN("COMPLEX_MACRO",
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004961 "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
4962 }
Anas Nashif0f3d5472016-11-07 15:57:57 -05004963
4964 }
4965
4966 # Make $define_stmt single line, comment-free, etc
4967 my @stmt_array = split('\n', $define_stmt);
4968 my $first = 1;
4969 $define_stmt = "";
4970 foreach my $l (@stmt_array) {
4971 $l =~ s/\\$//;
4972 if ($first) {
4973 $define_stmt = $l;
4974 $first = 0;
4975 } elsif ($l =~ /^[\+ ]/) {
4976 $define_stmt .= substr($l, 1);
4977 }
4978 }
4979 $define_stmt =~ s/$;//g;
4980 $define_stmt =~ s/\s+/ /g;
4981 $define_stmt = trim($define_stmt);
4982
4983# check if any macro arguments are reused (ignore '...' and 'type')
4984 foreach my $arg (@def_args) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04004985 next if ($arg =~ /\.\.\./);
4986 next if ($arg =~ /^type$/i);
4987 my $tmp_stmt = $define_stmt;
4988 $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
4989 $tmp_stmt =~ s/\#+\s*$arg\b//g;
4990 $tmp_stmt =~ s/\b$arg\s*\#\#//g;
4991 my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g;
Anas Nashif0f3d5472016-11-07 15:57:57 -05004992 if ($use_cnt > 1) {
4993 CHK("MACRO_ARG_REUSE",
Anas Nashif1eb244c2017-10-01 17:06:36 -04004994 "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
4995 }
Anas Nashif0f3d5472016-11-07 15:57:57 -05004996# check if any macro arguments may have other precedence issues
Anas Nashif1eb244c2017-10-01 17:06:36 -04004997 if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
4998 ((defined($1) && $1 ne ',') ||
4999 (defined($2) && $2 ne ','))) {
Anas Nashif0f3d5472016-11-07 15:57:57 -05005000 CHK("MACRO_ARG_PRECEDENCE",
Anas Nashif1eb244c2017-10-01 17:06:36 -04005001 "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
Anas Nashif0f3d5472016-11-07 15:57:57 -05005002 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005003 }
5004
5005# check for macros with flow control, but without ## concatenation
5006# ## concatenation is commonly a macro that defines a function so ignore those
5007 if ($has_flow_statement && !$has_arg_concat) {
5008 my $herectx = $here . "\n";
5009 my $cnt = statement_rawlines($ctx);
5010
5011 for (my $n = 0; $n < $cnt; $n++) {
5012 $herectx .= raw_line($linenr, $n) . "\n";
5013 }
5014 WARN("MACRO_WITH_FLOW_CONTROL",
5015 "Macros with flow control statements should be avoided\n" . "$herectx");
5016 }
5017
5018# check for line continuations outside of #defines, preprocessor #, and asm
5019
5020 } else {
5021 if ($prevline !~ /^..*\\$/ &&
5022 $line !~ /^\+\s*\#.*\\$/ && # preprocessor
5023 $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
5024 $line =~ /^\+.*\\$/) {
5025 WARN("LINE_CONTINUATIONS",
5026 "Avoid unnecessary line continuations\n" . $herecurr);
5027 }
5028 }
5029
5030# do {} while (0) macro tests:
5031# single-statement macros do not need to be enclosed in do while (0) loop,
5032# macro should not end with a semicolon
5033 if ($^V && $^V ge 5.10.0 &&
5034 $realfile !~ m@/vmlinux.lds.h$@ &&
5035 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5036 my $ln = $linenr;
5037 my $cnt = $realcnt;
5038 my ($off, $dstat, $dcond, $rest);
5039 my $ctx = '';
5040 ($dstat, $dcond, $ln, $cnt, $off) =
5041 ctx_statement_block($linenr, $realcnt, 0);
5042 $ctx = $dstat;
5043
5044 $dstat =~ s/\\\n.//g;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005045 $dstat =~ s/$;/ /g;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005046
5047 if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5048 my $stmts = $2;
5049 my $semis = $3;
5050
5051 $ctx =~ s/\n*$//;
5052 my $cnt = statement_rawlines($ctx);
5053 my $herectx = $here . "\n";
5054
5055 for (my $n = 0; $n < $cnt; $n++) {
5056 $herectx .= raw_line($linenr, $n) . "\n";
5057 }
5058
5059 if (($stmts =~ tr/;/;/) == 1 &&
5060 $stmts !~ /^\s*(if|while|for|switch)\b/) {
5061 WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5062 "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5063 }
5064 if (defined $semis && $semis ne "") {
5065 WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5066 "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5067 }
5068 } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5069 $ctx =~ s/\n*$//;
5070 my $cnt = statement_rawlines($ctx);
5071 my $herectx = $here . "\n";
5072
5073 for (my $n = 0; $n < $cnt; $n++) {
5074 $herectx .= raw_line($linenr, $n) . "\n";
5075 }
5076
5077 WARN("TRAILING_SEMICOLON",
5078 "macros should not use a trailing semicolon\n" . "$herectx");
5079 }
5080 }
5081
5082# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
5083# all assignments may have only one of the following with an assignment:
5084# .
5085# ALIGN(...)
5086# VMLINUX_SYMBOL(...)
5087 if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
5088 WARN("MISSING_VMLINUX_SYMBOL",
5089 "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
5090 }
5091
5092# check for redundant bracing round if etc
5093 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
5094 my ($level, $endln, @chunks) =
5095 ctx_statement_full($linenr, $realcnt, 1);
5096 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5097 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5098 if ($#chunks > 0 && $level == 0) {
5099 my @allowed = ();
5100 my $allow = 0;
5101 my $seen = 0;
5102 my $herectx = $here . "\n";
5103 my $ln = $linenr - 1;
5104 for my $chunk (@chunks) {
5105 my ($cond, $block) = @{$chunk};
5106
5107 # If the condition carries leading newlines, then count those as offsets.
5108 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5109 my $offset = statement_rawlines($whitespace) - 1;
5110
5111 $allowed[$allow] = 0;
5112 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5113
5114 # We have looked at and allowed this specific line.
5115 $suppress_ifbraces{$ln + $offset} = 1;
5116
5117 $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5118 $ln += statement_rawlines($block) - 1;
5119
5120 substr($block, 0, length($cond), '');
5121
5122 $seen++ if ($block =~ /^\s*{/);
5123
5124 #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5125 if (statement_lines($cond) > 1) {
5126 #print "APW: ALLOWED: cond<$cond>\n";
5127 $allowed[$allow] = 1;
5128 }
5129 if ($block =~/\b(?:if|for|while)\b/) {
5130 #print "APW: ALLOWED: block<$block>\n";
5131 $allowed[$allow] = 1;
5132 }
5133 if (statement_block_size($block) > 1) {
5134 #print "APW: ALLOWED: lines block<$block>\n";
5135 $allowed[$allow] = 1;
5136 }
5137 $allow++;
5138 }
5139 if ($seen) {
5140 my $sum_allowed = 0;
5141 foreach (@allowed) {
5142 $sum_allowed += $_;
5143 }
5144 if ($sum_allowed == 0) {
5145 WARN("BRACES",
5146 "braces {} are not necessary for any arm of this statement\n" . $herectx);
5147 } elsif ($sum_allowed != $allow &&
5148 $seen != $allow) {
5149 CHK("BRACES",
5150 "braces {} should be used on all arms of this statement\n" . $herectx);
5151 }
5152 }
5153 }
5154 }
5155 if (!defined $suppress_ifbraces{$linenr - 1} &&
5156 $line =~ /\b(if|while|for|else)\b/) {
5157 my $allowed = 0;
5158
5159 # Check the pre-context.
5160 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5161 #print "APW: ALLOWED: pre<$1>\n";
5162 $allowed = 1;
5163 }
5164
5165 my ($level, $endln, @chunks) =
5166 ctx_statement_full($linenr, $realcnt, $-[0]);
5167
5168 # Check the condition.
5169 my ($cond, $block) = @{$chunks[0]};
5170 #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5171 if (defined $cond) {
5172 substr($block, 0, length($cond), '');
5173 }
5174 if (statement_lines($cond) > 1) {
5175 #print "APW: ALLOWED: cond<$cond>\n";
5176 $allowed = 1;
5177 }
5178 if ($block =~/\b(?:if|for|while)\b/) {
5179 #print "APW: ALLOWED: block<$block>\n";
5180 $allowed = 1;
5181 }
5182 if (statement_block_size($block) > 1) {
5183 #print "APW: ALLOWED: lines block<$block>\n";
5184 $allowed = 1;
5185 }
5186 # Check the post-context.
5187 if (defined $chunks[1]) {
5188 my ($cond, $block) = @{$chunks[1]};
5189 if (defined $cond) {
5190 substr($block, 0, length($cond), '');
5191 }
5192 if ($block =~ /^\s*\{/) {
5193 #print "APW: ALLOWED: chunk-1 block<$block>\n";
5194 $allowed = 1;
5195 }
5196 }
5197 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
5198 my $herectx = $here . "\n";
5199 my $cnt = statement_rawlines($block);
5200
5201 for (my $n = 0; $n < $cnt; $n++) {
5202 $herectx .= raw_line($linenr, $n) . "\n";
5203 }
5204
5205 WARN("BRACES",
5206 "braces {} are not necessary for single statement blocks\n" . $herectx);
5207 }
5208 }
5209
Anas Nashif1eb244c2017-10-01 17:06:36 -04005210# check for single line unbalanced braces
5211 if ($sline =~ /^.\s*\}\s*else\s*$/ ||
5212 $sline =~ /^.\s*else\s*\{\s*$/) {
5213 CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5214 }
5215
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005216# check for unnecessary blank lines around braces
5217 if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005218 if (CHK("BRACES",
5219 "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5220 $fix && $prevrawline =~ /^\+/) {
5221 fix_delete_line($fixlinenr - 1, $prevrawline);
5222 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005223 }
5224 if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005225 if (CHK("BRACES",
5226 "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5227 $fix) {
5228 fix_delete_line($fixlinenr, $rawline);
5229 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005230 }
5231
5232# no volatiles please
5233 my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
5234 if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5235 WARN("VOLATILE",
Anas Nashif1eb244c2017-10-01 17:06:36 -04005236 "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005237 }
5238
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005239# Check for user-visible strings broken across lines, which breaks the ability
5240# to grep for the string. Make exceptions when the previous string ends in a
5241# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
5242# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
5243 if ($line =~ /^\+\s*$String/ &&
5244 $prevline =~ /"\s*$/ &&
5245 $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
5246 if (WARN("SPLIT_STRING",
5247 "quoted string split across lines\n" . $hereprev) &&
5248 $fix &&
5249 $prevrawline =~ /^\+.*"\s*$/ &&
5250 $last_coalesced_string_linenr != $linenr - 1) {
5251 my $extracted_string = get_quoted_string($line, $rawline);
5252 my $comma_close = "";
5253 if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
5254 $comma_close = $1;
5255 }
5256
5257 fix_delete_line($fixlinenr - 1, $prevrawline);
5258 fix_delete_line($fixlinenr, $rawline);
5259 my $fixedline = $prevrawline;
5260 $fixedline =~ s/"\s*$//;
5261 $fixedline .= substr($extracted_string, 1) . trim($comma_close);
5262 fix_insert_line($fixlinenr - 1, $fixedline);
5263 $fixedline = $rawline;
5264 $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
5265 if ($fixedline !~ /\+\s*$/) {
5266 fix_insert_line($fixlinenr, $fixedline);
5267 }
5268 $last_coalesced_string_linenr = $linenr;
5269 }
5270 }
5271
5272# check for missing a space in a string concatenation
5273 if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
5274 WARN('MISSING_SPACE',
5275 "break quoted strings at a space character\n" . $hereprev);
5276 }
5277
Anas Nashif1eb244c2017-10-01 17:06:36 -04005278# check for an embedded function name in a string when the function is known
5279# This does not work very well for -f --file checking as it depends on patch
5280# context providing the function name or a single line form for in-file
5281# function declarations
5282 if ($line =~ /^\+.*$String/ &&
5283 defined($context_function) &&
5284 get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5285 length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
5286 WARN("EMBEDDED_FUNCTION_NAME",
5287 "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
5288 }
5289
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005290# check for spaces before a quoted newline
5291 if ($rawline =~ /^.*\".*\s\\n/) {
5292 if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
5293 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
5294 $fix) {
5295 $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
5296 }
5297
5298 }
5299
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005300# concatenated string without spaces between elements
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005301 if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005302 CHK("CONCATENATED_STRING",
5303 "Concatenated strings should use spaces between elements\n" . $herecurr);
5304 }
5305
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005306# uncoalesced string fragments
5307 if ($line =~ /$String\s*"/) {
5308 WARN("STRING_FRAGMENTS",
5309 "Consecutive strings are generally better as a single string\n" . $herecurr);
5310 }
5311
Anas Nashif1eb244c2017-10-01 17:06:36 -04005312# check for non-standard and hex prefixed decimal printf formats
5313 my $show_L = 1; #don't show the same defect twice
5314 my $show_Z = 1;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005315 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04005316 my $string = substr($rawline, $-[1], $+[1] - $-[1]);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005317 $string =~ s/%%/__/g;
Anas Nashif1eb244c2017-10-01 17:06:36 -04005318 # check for %L
5319 if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005320 WARN("PRINTF_L",
Anas Nashif1eb244c2017-10-01 17:06:36 -04005321 "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5322 $show_L = 0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005323 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04005324 # check for %Z
5325 if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5326 WARN("PRINTF_Z",
5327 "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5328 $show_Z = 0;
5329 }
5330 # check for 0x<decimal>
5331 if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5332 ERROR("PRINTF_0XDECIMAL",
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005333 "Prefixing 0x with decimal output is defective\n" . $herecurr);
5334 }
5335 }
5336
5337# check for line continuations in quoted strings with odd counts of "
5338 if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
5339 WARN("LINE_CONTINUATIONS",
5340 "Avoid line continuations in quoted strings\n" . $herecurr);
5341 }
5342
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005343# warn about #if 0
5344 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
5345 CHK("REDUNDANT_CODE",
5346 "if this code is redundant consider removing it\n" .
5347 $herecurr);
5348 }
5349
5350# check for needless "if (<foo>) fn(<foo>)" uses
5351 if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005352 my $tested = quotemeta($1);
5353 my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5354 if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5355 my $func = $1;
5356 if (WARN('NEEDLESS_IF',
5357 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5358 $fix) {
5359 my $do_fix = 1;
5360 my $leading_tabs = "";
5361 my $new_leading_tabs = "";
5362 if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5363 $leading_tabs = $1;
5364 } else {
5365 $do_fix = 0;
5366 }
5367 if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5368 $new_leading_tabs = $1;
5369 if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5370 $do_fix = 0;
5371 }
5372 } else {
5373 $do_fix = 0;
5374 }
5375 if ($do_fix) {
5376 fix_delete_line($fixlinenr - 1, $prevrawline);
5377 $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5378 }
5379 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005380 }
5381 }
5382
5383# check for unnecessary "Out of Memory" messages
5384 if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5385 $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5386 (defined $1 || defined $3) &&
5387 $linenr > 3) {
5388 my $testval = $2;
5389 my $testline = $lines[$linenr - 3];
5390
5391 my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5392# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5393
Anas Nashif1eb244c2017-10-01 17:06:36 -04005394 if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005395 WARN("OOM_MESSAGE",
5396 "Possible unnecessary 'out of memory' message\n" . $hereprev);
5397 }
5398 }
5399
5400# check for logging functions with KERN_<LEVEL>
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005401 if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005402 $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5403 my $level = $1;
5404 if (WARN("UNNECESSARY_KERN_LEVEL",
5405 "Possible unnecessary $level\n" . $herecurr) &&
5406 $fix) {
5407 $fixed[$fixlinenr] =~ s/\s*$level\s*//;
5408 }
5409 }
5410
Anas Nashif1eb244c2017-10-01 17:06:36 -04005411# check for logging continuations
5412 if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
5413 WARN("LOGGING_CONTINUATION",
5414 "Avoid logging continuation uses where feasible\n" . $herecurr);
5415 }
5416
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005417# check for mask then right shift without a parentheses
5418 if ($^V && $^V ge 5.10.0 &&
5419 $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5420 $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5421 WARN("MASK_THEN_SHIFT",
5422 "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5423 }
5424
5425# check for pointer comparisons to NULL
5426 if ($^V && $^V ge 5.10.0) {
5427 while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5428 my $val = $1;
5429 my $equal = "!";
5430 $equal = "" if ($4 eq "!=");
5431 if (CHK("COMPARISON_TO_NULL",
5432 "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5433 $fix) {
5434 $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5435 }
5436 }
5437 }
5438
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005439# check for bad placement of section $InitAttribute (e.g.: __initdata)
5440 if ($line =~ /(\b$InitAttribute\b)/) {
5441 my $attr = $1;
5442 if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
5443 my $ptr = $1;
5444 my $var = $2;
5445 if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
5446 ERROR("MISPLACED_INIT",
5447 "$attr should be placed after $var\n" . $herecurr)) ||
5448 ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
5449 WARN("MISPLACED_INIT",
5450 "$attr should be placed after $var\n" . $herecurr))) &&
5451 $fix) {
5452 $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;
5453 }
5454 }
5455 }
5456
5457# check for $InitAttributeData (ie: __initdata) with const
5458 if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5459 my $attr = $1;
5460 $attr =~ /($InitAttributePrefix)(.*)/;
5461 my $attr_prefix = $1;
5462 my $attr_type = $2;
5463 if (ERROR("INIT_ATTRIBUTE",
5464 "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5465 $fix) {
5466 $fixed[$fixlinenr] =~
5467 s/$InitAttributeData/${attr_prefix}initconst/;
5468 }
5469 }
5470
5471# check for $InitAttributeConst (ie: __initconst) without const
5472 if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5473 my $attr = $1;
5474 if (ERROR("INIT_ATTRIBUTE",
5475 "Use of $attr requires a separate use of const\n" . $herecurr) &&
5476 $fix) {
5477 my $lead = $fixed[$fixlinenr] =~
5478 /(^\+\s*(?:static\s+))/;
5479 $lead = rtrim($1);
5480 $lead = "$lead " if ($lead !~ /^\+$/);
5481 $lead = "${lead}const ";
5482 $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5483 }
5484 }
5485
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005486# check for __read_mostly with const non-pointer (should just be const)
5487 if ($line =~ /\b__read_mostly\b/ &&
5488 $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5489 if (ERROR("CONST_READ_MOSTLY",
5490 "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5491 $fix) {
5492 $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5493 }
5494 }
5495
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005496# don't use __constant_<foo> functions outside of include/uapi/
5497 if ($realfile !~ m@^include/uapi/@ &&
5498 $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5499 my $constant_func = $1;
5500 my $func = $constant_func;
5501 $func =~ s/^__constant_//;
5502 if (WARN("CONSTANT_CONVERSION",
5503 "$constant_func should be $func\n" . $herecurr) &&
5504 $fix) {
5505 $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5506 }
5507 }
5508
5509# prefer usleep_range over udelay
5510 if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
5511 my $delay = $1;
5512 # ignore udelay's < 10, however
5513 if (! ($delay < 10) ) {
5514 CHK("USLEEP_RANGE",
5515 "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
5516 }
5517 if ($delay > 2000) {
5518 WARN("LONG_UDELAY",
5519 "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
5520 }
5521 }
5522
5523# warn about unexpectedly long msleep's
5524 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
5525 if ($1 < 20) {
5526 WARN("MSLEEP",
5527 "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
5528 }
5529 }
5530
5531# check for comparisons of jiffies
5532 if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
5533 WARN("JIFFIES_COMPARISON",
5534 "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
5535 }
5536
5537# check for comparisons of get_jiffies_64()
5538 if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
5539 WARN("JIFFIES_COMPARISON",
5540 "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
5541 }
5542
5543# warn about #ifdefs in C files
5544# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
5545# print "#ifdef in C files should be avoided\n";
5546# print "$herecurr";
5547# $clean = 0;
5548# }
5549
5550# warn about spacing in #ifdefs
5551 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
5552 if (ERROR("SPACING",
5553 "exactly one space required after that #$1\n" . $herecurr) &&
5554 $fix) {
5555 $fixed[$fixlinenr] =~
5556 s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
5557 }
5558
5559 }
5560
5561# check for spinlock_t definitions without a comment.
5562 if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5563 $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
5564 my $which = $1;
5565 if (!ctx_has_comment($first_line, $linenr)) {
5566 CHK("UNCOMMENTED_DEFINITION",
5567 "$1 definition without comment\n" . $herecurr);
5568 }
5569 }
5570# check for memory barriers without a comment.
Anas Nashif76b09132016-02-20 13:53:35 -05005571
5572 my $barriers = qr{
5573 mb|
5574 rmb|
5575 wmb|
5576 read_barrier_depends
5577 }x;
5578 my $barrier_stems = qr{
5579 mb__before_atomic|
5580 mb__after_atomic|
5581 store_release|
5582 load_acquire|
5583 store_mb|
5584 (?:$barriers)
5585 }x;
5586 my $all_barriers = qr{
5587 (?:$barriers)|
5588 smp_(?:$barrier_stems)|
5589 virt_(?:$barrier_stems)
5590 }x;
5591
5592 if ($line =~ /\b(?:$all_barriers)\s*\(/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005593 if (!ctx_has_comment($first_line, $linenr)) {
5594 WARN("MEMORY_BARRIER",
5595 "memory barrier without comment\n" . $herecurr);
5596 }
5597 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005598
Anas Nashif76b09132016-02-20 13:53:35 -05005599 my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5600
5601 if ($realfile !~ m@^include/asm-generic/@ &&
5602 $realfile !~ m@/barrier\.h$@ &&
5603 $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5604 $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5605 WARN("MEMORY_BARRIER",
5606 "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5607 }
5608
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005609# check for waitqueue_active without a comment.
5610 if ($line =~ /\bwaitqueue_active\s*\(/) {
5611 if (!ctx_has_comment($first_line, $linenr)) {
5612 WARN("WAITQUEUE_ACTIVE",
5613 "waitqueue_active without comment\n" . $herecurr);
5614 }
5615 }
5616
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005617# check of hardware specific defines
5618 if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5619 CHK("ARCH_DEFINES",
5620 "architecture specific defines should be avoided\n" . $herecurr);
5621 }
5622
Anas Nashif1eb244c2017-10-01 17:06:36 -04005623# check that the storage class is not after a type
5624 if ($line =~ /\b($Type)\s+($Storage)\b/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005625 WARN("STORAGE_CLASS",
Anas Nashif1eb244c2017-10-01 17:06:36 -04005626 "storage class '$2' should be located before type '$1'\n" . $herecurr);
5627 }
5628# Check that the storage class is at the beginning of a declaration
5629 if ($line =~ /\b$Storage\b/ &&
5630 $line !~ /^.\s*$Storage/ &&
5631 $line =~ /^.\s*(.+?)\$Storage\s/ &&
5632 $1 !~ /[\,\)]\s*$/) {
5633 WARN("STORAGE_CLASS",
5634 "storage class should be at the beginning of the declaration\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005635 }
5636
5637# check the location of the inline attribute, that it is between
5638# storage class and type.
5639 if ($line =~ /\b$Type\s+$Inline\b/ ||
5640 $line =~ /\b$Inline\s+$Storage\b/) {
5641 ERROR("INLINE_LOCATION",
5642 "inline keyword should sit between storage class and type\n" . $herecurr);
5643 }
5644
5645# Check for __inline__ and __inline, prefer inline
5646 if ($realfile !~ m@\binclude/uapi/@ &&
5647 $line =~ /\b(__inline__|__inline)\b/) {
5648 if (WARN("INLINE",
5649 "plain inline is preferred over $1\n" . $herecurr) &&
5650 $fix) {
5651 $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5652
5653 }
5654 }
5655
5656# Check for __attribute__ packed, prefer __packed
5657 if ($realfile !~ m@\binclude/uapi/@ &&
5658 $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5659 WARN("PREFER_PACKED",
5660 "__packed is preferred over __attribute__((packed))\n" . $herecurr);
5661 }
5662
5663# Check for __attribute__ aligned, prefer __aligned
5664 if ($realfile !~ m@\binclude/uapi/@ &&
5665 $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5666 WARN("PREFER_ALIGNED",
5667 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
5668 }
5669
5670# Check for __attribute__ format(printf, prefer __printf
5671 if ($realfile !~ m@\binclude/uapi/@ &&
5672 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
5673 if (WARN("PREFER_PRINTF",
5674 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
5675 $fix) {
5676 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
5677
5678 }
5679 }
5680
5681# Check for __attribute__ format(scanf, prefer __scanf
5682 if ($realfile !~ m@\binclude/uapi/@ &&
5683 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
5684 if (WARN("PREFER_SCANF",
5685 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
5686 $fix) {
5687 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
5688 }
5689 }
5690
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005691# Check for __attribute__ weak, or __weak declarations (may have link issues)
5692 if ($^V && $^V ge 5.10.0 &&
5693 $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5694 ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5695 $line =~ /\b__weak\b/)) {
5696 ERROR("WEAK_DECLARATION",
5697 "Using weak declarations can have unintended link defects\n" . $herecurr);
5698 }
5699
Kumar Galaa48e8792017-04-21 10:53:05 -05005700# check for c99 types like uint8_t
5701 if ($line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005702 my $type = $1;
5703 if ($type =~ /\b($typeC99Typedefs)\b/) {
5704 $type = $1;
5705 my $kernel_type = 'u';
5706 $kernel_type = 's' if ($type =~ /^_*[si]/);
5707 $type =~ /(\d+)/;
Kumar Galaa48e8792017-04-21 10:53:05 -05005708 $kernel_type .= $1.'_t';
5709 WARN("PREFER_KERNEL_TYPES",
5710 "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr)
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005711 }
5712 }
5713
Anas Nashif76b09132016-02-20 13:53:35 -05005714# check for cast of C90 native int or longer types constants
5715 if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
5716 my $cast = $1;
5717 my $const = $2;
5718 if (WARN("TYPECAST_INT_CONSTANT",
5719 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
5720 $fix) {
5721 my $suffix = "";
5722 my $newconst = $const;
5723 $newconst =~ s/${Int_type}$//;
5724 $suffix .= 'U' if ($cast =~ /\bunsigned\b/);
5725 if ($cast =~ /\blong\s+long\b/) {
5726 $suffix .= 'LL';
5727 } elsif ($cast =~ /\blong\b/) {
5728 $suffix .= 'L';
5729 }
5730 $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
5731 }
5732 }
5733
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005734# check for sizeof(&)
5735 if ($line =~ /\bsizeof\s*\(\s*\&/) {
5736 WARN("SIZEOF_ADDRESS",
5737 "sizeof(& should be avoided\n" . $herecurr);
5738 }
5739
5740# check for sizeof without parenthesis
5741 if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
5742 if (WARN("SIZEOF_PARENTHESIS",
5743 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
5744 $fix) {
5745 $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
5746 }
5747 }
5748
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005749# check for struct spinlock declarations
5750 if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
5751 WARN("USE_SPINLOCK_T",
5752 "struct spinlock should be spinlock_t\n" . $herecurr);
5753 }
5754
5755# check for seq_printf uses that could be seq_puts
5756 if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
5757 my $fmt = get_quoted_string($line, $rawline);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005758 $fmt =~ s/%%//g;
5759 if ($fmt !~ /%/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005760 if (WARN("PREFER_SEQ_PUTS",
5761 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
5762 $fix) {
5763 $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
5764 }
5765 }
5766 }
5767
Anas Nashif1eb244c2017-10-01 17:06:36 -04005768 # check for vsprintf extension %p<foo> misuses
5769 if ($^V && $^V ge 5.10.0 &&
5770 defined $stat &&
5771 $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
5772 $1 !~ /^_*volatile_*$/) {
5773 my $bad_extension = "";
5774 my $lc = $stat =~ tr@\n@@;
5775 $lc = $lc + $linenr;
5776 for (my $count = $linenr; $count <= $lc; $count++) {
5777 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
5778 $fmt =~ s/%%//g;
5779 if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) {
5780 $bad_extension = $1;
5781 last;
5782 }
5783 }
5784 if ($bad_extension ne "") {
5785 my $stat_real = raw_line($linenr, 0);
5786 for (my $count = $linenr + 1; $count <= $lc; $count++) {
5787 $stat_real = $stat_real . "\n" . raw_line($count, 0);
5788 }
5789 WARN("VSPRINTF_POINTER_EXTENSION",
5790 "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n");
5791 }
5792 }
5793
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005794# Check for misused memsets
5795 if ($^V && $^V ge 5.10.0 &&
5796 defined $stat &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005797 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005798
5799 my $ms_addr = $2;
5800 my $ms_val = $7;
5801 my $ms_size = $12;
5802
5803 if ($ms_size =~ /^(0x|)0$/i) {
5804 ERROR("MEMSET",
5805 "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
5806 } elsif ($ms_size =~ /^(0x|)1$/i) {
5807 WARN("MEMSET",
5808 "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
5809 }
5810 }
5811
5812# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
Anas Nashif0f3d5472016-11-07 15:57:57 -05005813# if ($^V && $^V ge 5.10.0 &&
5814# defined $stat &&
5815# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5816# if (WARN("PREFER_ETHER_ADDR_COPY",
5817# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
5818# $fix) {
5819# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
5820# }
5821# }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005822
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005823# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
Anas Nashif0f3d5472016-11-07 15:57:57 -05005824# if ($^V && $^V ge 5.10.0 &&
5825# defined $stat &&
5826# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5827# WARN("PREFER_ETHER_ADDR_EQUAL",
5828# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
5829# }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005830
5831# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
5832# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
Anas Nashif0f3d5472016-11-07 15:57:57 -05005833# if ($^V && $^V ge 5.10.0 &&
5834# defined $stat &&
5835# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5836#
5837# my $ms_val = $7;
5838#
5839# if ($ms_val =~ /^(?:0x|)0+$/i) {
5840# if (WARN("PREFER_ETH_ZERO_ADDR",
5841# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
5842# $fix) {
5843# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
5844# }
5845# } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
5846# if (WARN("PREFER_ETH_BROADCAST_ADDR",
5847# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
5848# $fix) {
5849# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
5850# }
5851# }
5852# }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005853
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005854# typecasts on min/max could be min_t/max_t
5855 if ($^V && $^V ge 5.10.0 &&
5856 defined $stat &&
5857 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
5858 if (defined $2 || defined $7) {
5859 my $call = $1;
5860 my $cast1 = deparenthesize($2);
5861 my $arg1 = $3;
5862 my $cast2 = deparenthesize($7);
5863 my $arg2 = $8;
5864 my $cast;
5865
5866 if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
5867 $cast = "$cast1 or $cast2";
5868 } elsif ($cast1 ne "") {
5869 $cast = $cast1;
5870 } else {
5871 $cast = $cast2;
5872 }
5873 WARN("MINMAX",
5874 "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
5875 }
5876 }
5877
5878# check usleep_range arguments
5879 if ($^V && $^V ge 5.10.0 &&
5880 defined $stat &&
5881 $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
5882 my $min = $1;
5883 my $max = $7;
5884 if ($min eq $max) {
5885 WARN("USLEEP_RANGE",
5886 "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
5887 } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
5888 $min > $max) {
5889 WARN("USLEEP_RANGE",
5890 "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
5891 }
5892 }
5893
5894# check for naked sscanf
5895 if ($^V && $^V ge 5.10.0 &&
5896 defined $stat &&
5897 $line =~ /\bsscanf\b/ &&
5898 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
5899 $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
5900 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
5901 my $lc = $stat =~ tr@\n@@;
5902 $lc = $lc + $linenr;
5903 my $stat_real = raw_line($linenr, 0);
5904 for (my $count = $linenr + 1; $count <= $lc; $count++) {
5905 $stat_real = $stat_real . "\n" . raw_line($count, 0);
5906 }
5907 WARN("NAKED_SSCANF",
5908 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
5909 }
5910
5911# check for simple sscanf that should be kstrto<foo>
5912 if ($^V && $^V ge 5.10.0 &&
5913 defined $stat &&
5914 $line =~ /\bsscanf\b/) {
5915 my $lc = $stat =~ tr@\n@@;
5916 $lc = $lc + $linenr;
5917 my $stat_real = raw_line($linenr, 0);
5918 for (my $count = $linenr + 1; $count <= $lc; $count++) {
5919 $stat_real = $stat_real . "\n" . raw_line($count, 0);
5920 }
5921 if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
5922 my $format = $6;
5923 my $count = $format =~ tr@%@%@;
5924 if ($count == 1 &&
5925 $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
5926 WARN("SSCANF_TO_KSTRTO",
5927 "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
5928 }
5929 }
5930 }
5931
5932# check for new externs in .h files.
5933 if ($realfile =~ /\.h$/ &&
5934 $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
5935 if (CHK("AVOID_EXTERNS",
5936 "extern prototypes should be avoided in .h files\n" . $herecurr) &&
5937 $fix) {
5938 $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
5939 }
5940 }
5941
5942# check for new externs in .c files.
5943 if ($realfile =~ /\.c$/ && defined $stat &&
5944 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
5945 {
5946 my $function_name = $1;
5947 my $paren_space = $2;
5948
5949 my $s = $stat;
5950 if (defined $cond) {
5951 substr($s, 0, length($cond), '');
5952 }
5953 if ($s =~ /^\s*;/ &&
5954 $function_name ne 'uninitialized_var')
5955 {
5956 WARN("AVOID_EXTERNS",
5957 "externs should be avoided in .c files\n" . $herecurr);
5958 }
5959
5960 if ($paren_space =~ /\n/) {
5961 WARN("FUNCTION_ARGUMENTS",
5962 "arguments for function declarations should follow identifier\n" . $herecurr);
5963 }
5964
5965 } elsif ($realfile =~ /\.c$/ && defined $stat &&
5966 $stat =~ /^.\s*extern\s+/)
5967 {
5968 WARN("AVOID_EXTERNS",
5969 "externs should be avoided in .c files\n" . $herecurr);
5970 }
5971
Anas Nashif1eb244c2017-10-01 17:06:36 -04005972# check for function declarations that have arguments without identifier names
5973 if (defined $stat &&
Anas Nashif0f3d5472016-11-07 15:57:57 -05005974 $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s &&
5975 $1 ne "void") {
5976 my $args = trim($1);
5977 while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
5978 my $arg = trim($1);
5979 if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
5980 WARN("FUNCTION_ARGUMENTS",
5981 "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
5982 }
5983 }
5984 }
5985
Anas Nashif1eb244c2017-10-01 17:06:36 -04005986# check for function definitions
5987 if ($^V && $^V ge 5.10.0 &&
5988 defined $stat &&
5989 $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
5990 $context_function = $1;
5991
5992# check for multiline function definition with misplaced open brace
5993 my $ok = 0;
5994 my $cnt = statement_rawlines($stat);
5995 my $herectx = $here . "\n";
5996 for (my $n = 0; $n < $cnt; $n++) {
5997 my $rl = raw_line($linenr, $n);
5998 $herectx .= $rl . "\n";
5999 $ok = 1 if ($rl =~ /^[ \+]\{/);
6000 $ok = 1 if ($rl =~ /\{/ && $n == 0);
6001 last if $rl =~ /^[ \+].*\{/;
6002 }
6003 if (!$ok) {
6004 ERROR("OPEN_BRACE",
6005 "open brace '{' following function definitions go on the next line\n" . $herectx);
6006 }
6007 }
6008
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006009# checks for new __setup's
6010 if ($rawline =~ /\b__setup\("([^"]*)"/) {
6011 my $name = $1;
6012
6013 if (!grep(/$name/, @setup_docs)) {
6014 CHK("UNDOCUMENTED_SETUP",
Anas Nashif1eb244c2017-10-01 17:06:36 -04006015 "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006016 }
6017 }
6018
6019# check for pointless casting of kmalloc return
6020 if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
6021 WARN("UNNECESSARY_CASTS",
6022 "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
6023 }
6024
6025# alloc style
6026# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
6027 if ($^V && $^V ge 5.10.0 &&
6028 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6029 CHK("ALLOC_SIZEOF_STRUCT",
6030 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6031 }
6032
6033# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
6034 if ($^V && $^V ge 5.10.0 &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04006035 defined $stat &&
6036 $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006037 my $oldfunc = $3;
6038 my $a1 = $4;
6039 my $a2 = $10;
6040 my $newfunc = "kmalloc_array";
6041 $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
6042 my $r1 = $a1;
6043 my $r2 = $a2;
6044 if ($a1 =~ /^sizeof\s*\S/) {
6045 $r1 = $a2;
6046 $r2 = $a1;
6047 }
6048 if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6049 !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04006050 my $ctx = '';
6051 my $herectx = $here . "\n";
6052 my $cnt = statement_rawlines($stat);
6053 for (my $n = 0; $n < $cnt; $n++) {
6054 $herectx .= raw_line($linenr, $n) . "\n";
6055 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006056 if (WARN("ALLOC_WITH_MULTIPLY",
Anas Nashif1eb244c2017-10-01 17:06:36 -04006057 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
6058 $cnt == 1 &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006059 $fix) {
6060 $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;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006061 }
6062 }
6063 }
6064
6065# check for krealloc arg reuse
6066 if ($^V && $^V ge 5.10.0 &&
6067 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
6068 WARN("KREALLOC_ARG_REUSE",
6069 "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6070 }
6071
6072# check for alloc argument mismatch
6073 if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
6074 WARN("ALLOC_ARRAY_ARGS",
6075 "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
6076 }
6077
6078# check for multiple semicolons
6079 if ($line =~ /;\s*;\s*$/) {
6080 if (WARN("ONE_SEMICOLON",
6081 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6082 $fix) {
6083 $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6084 }
6085 }
6086
Anas Nashif0f3d5472016-11-07 15:57:57 -05006087# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6088 if ($realfile !~ m@^include/uapi/@ &&
6089 $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006090 my $ull = "";
6091 $ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
6092 if (CHK("BIT_MACRO",
6093 "Prefer using the BIT$ull macro\n" . $herecurr) &&
6094 $fix) {
6095 $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
6096 }
6097 }
6098
Anas Nashif0f3d5472016-11-07 15:57:57 -05006099# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
6100 if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
6101 my $config = $1;
6102 if (WARN("PREFER_IS_ENABLED",
6103 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
6104 $fix) {
6105 $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
6106 }
6107 }
6108
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006109# check for case / default statements not preceded by break/fallthrough/switch
6110 if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6111 my $has_break = 0;
6112 my $has_statement = 0;
6113 my $count = 0;
6114 my $prevline = $linenr;
6115 while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6116 $prevline--;
6117 my $rline = $rawlines[$prevline - 1];
6118 my $fline = $lines[$prevline - 1];
6119 last if ($fline =~ /^\@\@/);
6120 next if ($fline =~ /^\-/);
6121 next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6122 $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6123 next if ($fline =~ /^.[\s$;]*$/);
6124 $has_statement = 1;
6125 $count++;
6126 $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
6127 }
6128 if (!$has_break && $has_statement) {
6129 WARN("MISSING_BREAK",
Anas Nashif1eb244c2017-10-01 17:06:36 -04006130 "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006131 }
6132 }
6133
6134# check for switch/default statements without a break;
6135 if ($^V && $^V ge 5.10.0 &&
6136 defined $stat &&
6137 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6138 my $ctx = '';
6139 my $herectx = $here . "\n";
6140 my $cnt = statement_rawlines($stat);
6141 for (my $n = 0; $n < $cnt; $n++) {
6142 $herectx .= raw_line($linenr, $n) . "\n";
6143 }
6144 WARN("DEFAULT_NO_BREAK",
6145 "switch default: should use break\n" . $herectx);
6146 }
6147
6148# check for gcc specific __FUNCTION__
6149 if ($line =~ /\b__FUNCTION__\b/) {
6150 if (WARN("USE_FUNC",
6151 "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
6152 $fix) {
6153 $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6154 }
6155 }
6156
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006157# check for uses of __DATE__, __TIME__, __TIMESTAMP__
6158 while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
6159 ERROR("DATE_TIME",
6160 "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
6161 }
6162
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006163# check for use of yield()
6164 if ($line =~ /\byield\s*\(\s*\)/) {
6165 WARN("YIELD",
6166 "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr);
6167 }
6168
6169# check for comparisons against true and false
6170 if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6171 my $lead = $1;
6172 my $arg = $2;
6173 my $test = $3;
6174 my $otype = $4;
6175 my $trail = $5;
6176 my $op = "!";
6177
6178 ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6179
6180 my $type = lc($otype);
6181 if ($type =~ /^(?:true|false)$/) {
6182 if (("$test" eq "==" && "$type" eq "true") ||
6183 ("$test" eq "!=" && "$type" eq "false")) {
6184 $op = "";
6185 }
6186
6187 CHK("BOOL_COMPARISON",
6188 "Using comparison to $otype is error prone\n" . $herecurr);
6189
6190## maybe suggesting a correct construct would better
6191## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6192
6193 }
6194 }
6195
6196# check for semaphores initialized locked
6197 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6198 WARN("CONSIDER_COMPLETION",
6199 "consider using a completion\n" . $herecurr);
6200 }
6201
6202# recommend kstrto* over simple_strto* and strict_strto*
6203 if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6204 WARN("CONSIDER_KSTRTO",
6205 "$1 is obsolete, use k$3 instead\n" . $herecurr);
6206 }
6207
6208# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6209 if ($line =~ /^.\s*__initcall\s*\(/) {
6210 WARN("USE_DEVICE_INITCALL",
6211 "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6212 }
6213
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006214# check for various structs that are normally const (ops, kgdb, device_tree)
Anas Nashif1eb244c2017-10-01 17:06:36 -04006215# and avoid what seem like struct definitions 'struct foo {'
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006216 if ($line !~ /\bconst\b/ &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04006217 $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006218 WARN("CONST_STRUCT",
Anas Nashif1eb244c2017-10-01 17:06:36 -04006219 "struct $1 should normally be const\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006220 }
6221
6222# use of NR_CPUS is usually wrong
6223# ignore definitions of NR_CPUS and usage to define arrays as likely right
6224 if ($line =~ /\bNR_CPUS\b/ &&
6225 $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6226 $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6227 $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6228 $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6229 $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6230 {
6231 WARN("NR_CPUS",
6232 "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6233 }
6234
6235# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
6236 if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
6237 ERROR("DEFINE_ARCH_HAS",
6238 "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
6239 }
6240
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006241# likely/unlikely comparisons similar to "(likely(foo) > 0)"
6242 if ($^V && $^V ge 5.10.0 &&
6243 $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6244 WARN("LIKELY_MISUSE",
6245 "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006246 }
6247
6248# whine mightly about in_atomic
6249 if ($line =~ /\bin_atomic\s*\(/) {
6250 if ($realfile =~ m@^drivers/@) {
6251 ERROR("IN_ATOMIC",
6252 "do not use in_atomic in drivers\n" . $herecurr);
6253 } elsif ($realfile !~ m@^kernel/@) {
6254 WARN("IN_ATOMIC",
6255 "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6256 }
6257 }
6258
Anas Nashif0f3d5472016-11-07 15:57:57 -05006259# whine about ACCESS_ONCE
6260 if ($^V && $^V ge 5.10.0 &&
6261 $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) {
6262 my $par = $1;
6263 my $eq = $2;
6264 my $fun = $3;
6265 $par =~ s/^\(\s*(.*)\s*\)$/$1/;
6266 if (defined($eq)) {
6267 if (WARN("PREFER_WRITE_ONCE",
6268 "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) &&
6269 $fix) {
6270 $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/;
6271 }
6272 } else {
6273 if (WARN("PREFER_READ_ONCE",
6274 "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) &&
6275 $fix) {
6276 $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/;
6277 }
6278 }
6279 }
6280
Anas Nashif1eb244c2017-10-01 17:06:36 -04006281# check for mutex_trylock_recursive usage
6282 if ($line =~ /mutex_trylock_recursive/) {
6283 ERROR("LOCKING",
6284 "recursive locking is bad, do not use this ever.\n" . $herecurr);
6285 }
6286
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006287# check for lockdep_set_novalidate_class
6288 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
6289 $line =~ /__lockdep_no_validate__\s*\)/ ) {
6290 if ($realfile !~ m@^kernel/lockdep@ &&
6291 $realfile !~ m@^include/linux/lockdep@ &&
6292 $realfile !~ m@^drivers/base/core@) {
6293 ERROR("LOCKDEP",
6294 "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
6295 }
6296 }
6297
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006298 if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6299 $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006300 WARN("EXPORTED_WORLD_WRITABLE",
6301 "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
6302 }
6303
6304# Mode permission misuses where it seems decimal should be octal
6305# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
6306 if ($^V && $^V ge 5.10.0 &&
Anas Nashif0f3d5472016-11-07 15:57:57 -05006307 defined $stat &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006308 $line =~ /$mode_perms_search/) {
6309 foreach my $entry (@mode_permission_funcs) {
6310 my $func = $entry->[0];
6311 my $arg_pos = $entry->[1];
6312
Anas Nashif0f3d5472016-11-07 15:57:57 -05006313 my $lc = $stat =~ tr@\n@@;
6314 $lc = $lc + $linenr;
6315 my $stat_real = raw_line($linenr, 0);
6316 for (my $count = $linenr + 1; $count <= $lc; $count++) {
6317 $stat_real = $stat_real . "\n" . raw_line($count, 0);
6318 }
6319
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006320 my $skip_args = "";
6321 if ($arg_pos > 1) {
6322 $arg_pos--;
6323 $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
6324 }
Anas Nashif0f3d5472016-11-07 15:57:57 -05006325 my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6326 if ($stat =~ /$test/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006327 my $val = $1;
6328 $val = $6 if ($skip_args ne "");
Anas Nashif0f3d5472016-11-07 15:57:57 -05006329 if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
6330 ($val =~ /^$Octal$/ && length($val) ne 4)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006331 ERROR("NON_OCTAL_PERMISSIONS",
Anas Nashif0f3d5472016-11-07 15:57:57 -05006332 "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6333 }
6334 if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006335 ERROR("EXPORTED_WORLD_WRITABLE",
Anas Nashif0f3d5472016-11-07 15:57:57 -05006336 "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006337 }
6338 }
6339 }
6340 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006341
Anas Nashif0f3d5472016-11-07 15:57:57 -05006342# check for uses of S_<PERMS> that could be octal for readability
6343 if ($line =~ /\b$mode_perms_string_search\b/) {
6344 my $val = "";
6345 my $oval = "";
6346 my $to = 0;
6347 my $curpos = 0;
6348 my $lastpos = 0;
6349 while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
6350 $curpos = pos($line);
6351 my $match = $2;
6352 my $omatch = $1;
6353 last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
6354 $lastpos = $curpos;
6355 $to |= $mode_permission_string_types{$match};
6356 $val .= '\s*\|\s*' if ($val ne "");
6357 $val .= $match;
6358 $oval .= $omatch;
6359 }
6360 $oval =~ s/^\s*\|\s*//;
6361 $oval =~ s/\s*\|\s*$//;
6362 my $octal = sprintf("%04o", $to);
6363 if (WARN("SYMBOLIC_PERMS",
6364 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6365 $fix) {
6366 $fixed[$fixlinenr] =~ s/$val/$octal/;
6367 }
6368 }
6369
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006370# validate content of MODULE_LICENSE against list from include/linux/module.h
6371 if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
6372 my $extracted_string = get_quoted_string($line, $rawline);
6373 my $valid_licenses = qr{
6374 GPL|
6375 GPL\ v2|
6376 GPL\ and\ additional\ rights|
6377 Dual\ BSD/GPL|
6378 Dual\ MIT/GPL|
6379 Dual\ MPL/GPL|
6380 Proprietary
6381 }x;
6382 if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
6383 WARN("MODULE_LICENSE",
6384 "unknown module license " . $extracted_string . "\n" . $herecurr);
6385 }
6386 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006387 }
6388
6389 # If we have no input at all, then there is nothing to report on
6390 # so just keep quiet.
6391 if ($#rawlines == -1) {
6392 exit(0);
6393 }
6394
6395 # In mailback mode only produce a report in the negative, for
6396 # things that appear to be patches.
6397 if ($mailback && ($clean == 1 || !$is_patch)) {
6398 exit(0);
6399 }
6400
6401 # This is not a patch, and we are are in 'no-patch' mode so
6402 # just keep quiet.
6403 if (!$chk_patch && !$is_patch) {
6404 exit(0);
6405 }
6406
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006407 if (!$is_patch && $file !~ /cover-letter\.patch$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006408 ERROR("NOT_UNIFIED_DIFF",
6409 "Does not appear to be a unified-diff format patch\n");
6410 }
Anas Nashif0f3d5472016-11-07 15:57:57 -05006411 if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006412 ERROR("MISSING_SIGN_OFF",
6413 "Missing Signed-off-by: line(s)\n");
6414 }
6415
6416 print report_dump();
6417 if ($summary && !($clean == 1 && $quiet == 1)) {
6418 print "$filename " if ($summary_file);
6419 print "total: $cnt_error errors, $cnt_warn warnings, " .
6420 (($check)? "$cnt_chk checks, " : "") .
6421 "$cnt_lines lines checked\n";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006422 }
6423
6424 if ($quiet == 0) {
Anas Nashif0f3d5472016-11-07 15:57:57 -05006425 # If there were any defects found and not already fixing them
6426 if (!$clean and !$fix) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006427 print << "EOM"
6428
Anas Nashif0f3d5472016-11-07 15:57:57 -05006429NOTE: For some of the reported defects, checkpatch may be able to
6430 mechanically convert to the typical style using --fix or --fix-inplace.
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006431EOM
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006432 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04006433 # If there were whitespace errors which cleanpatch can fix
6434 # then suggest that.
6435 if ($rpt_cleaners) {
6436 $rpt_cleaners = 0;
6437 print << "EOM"
6438
6439NOTE: Whitespace errors detected.
6440 You may wish to use scripts/cleanpatch or scripts/cleanfile
6441EOM
6442 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006443 }
6444
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006445 if ($clean == 0 && $fix &&
6446 ("@rawlines" ne "@fixed" ||
6447 $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
6448 my $newfile = $filename;
6449 $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
6450 my $linecount = 0;
6451 my $f;
6452
6453 @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6454
6455 open($f, '>', $newfile)
6456 or die "$P: Can't open $newfile for write\n";
6457 foreach my $fixed_line (@fixed) {
6458 $linecount++;
6459 if ($file) {
6460 if ($linecount > 3) {
6461 $fixed_line =~ s/^\+//;
6462 print $f $fixed_line . "\n";
6463 }
6464 } else {
6465 print $f $fixed_line . "\n";
6466 }
6467 }
6468 close($f);
6469
6470 if (!$quiet) {
6471 print << "EOM";
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006472
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006473Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
6474
6475Do _NOT_ trust the results written to this file.
6476Do _NOT_ submit these changes without inspecting them for correctness.
6477
6478This EXPERIMENTAL file is simply a convenience to help rewrite patches.
6479No warranties, expressed or implied...
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006480EOM
6481 }
6482 }
6483
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006484 if ($quiet == 0) {
6485 print "\n";
6486 if ($clean == 1) {
6487 print "$vname has no obvious style problems and is ready for submission.\n";
6488 } else {
6489 print "$vname has style problems, please review.\n";
6490 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006491 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006492 return $clean;
6493}