blob: 3cf249c4edd1a721044692834609b76cde0086bf [file] [log] [blame]
Martin Roth387dec82017-09-17 19:20:46 -06001#!/usr/bin/env perl
Martin Roth60915b32018-08-10 21:04:05 -06002# SPDX-License-Identifier: GPL-2.0
3#
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004# (c) 2001, Dave Jones. (the file handling bit)
5# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
6# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
7# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
Martin Roth60915b32018-08-10 21:04:05 -06008# (c) 2010-2018 Joe Perches <joe@perches.com>
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01009
10use strict;
Martin Roth387dec82017-09-17 19:20:46 -060011use warnings;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010012use POSIX;
13use File::Basename;
14use Cwd 'abs_path';
Stefan Reinauerc6080c62016-07-29 16:01:40 -070015use Term::ANSIColor qw(:constants);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010016
17my $P = $0;
18my $D = dirname(abs_path($P));
19
20my $V = '0.32';
21
22use Getopt::Long qw(:config no_auto_abbrev);
23
24my $quiet = 0;
25my $tree = 1;
26my $chk_signoff = 1;
27my $chk_patch = 1;
28my $tst_only;
29my $emacs = 0;
30my $terse = 0;
Stefan Reinauerc6080c62016-07-29 16:01:40 -070031my $showfile = 0;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010032my $file = 0;
Stefan Reinauerc6080c62016-07-29 16:01:40 -070033my $git = 0;
34my %git_commits = ();
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010035my $check = 0;
36my $check_orig = 0;
37my $summary = 1;
38my $mailback = 0;
39my $summary_file = 0;
40my $show_types = 0;
Stefan Reinauerc6080c62016-07-29 16:01:40 -070041my $list_types = 0;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010042my $fix = 0;
43my $fix_inplace = 0;
Martin Rothedd591d2017-03-14 10:16:29 -060044my $root = $P; #coreboot
Elyes HAOUAS18ef5202022-01-29 08:27:14 +010045my $gitroot = $ENV{'GIT_DIR'};
46$gitroot = ".git" if !defined($gitroot);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010047my %debug;
48my %camelcase = ();
49my %use_type = ();
50my @use = ();
51my %ignore_type = ();
52my @ignore = ();
Martin Rothedd591d2017-03-14 10:16:29 -060053my @exclude = (); #coreboot
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010054my $help = 0;
55my $configuration_file = ".checkpatch.conf";
56my $max_line_length = 80;
57my $ignore_perl_version = 0;
58my $minimum_perl_version = 5.10.0;
59my $min_conf_desc_length = 4;
60my $spelling_file = "$D/spelling.txt";
Stefan Reinauerc6080c62016-07-29 16:01:40 -070061my $codespell = 0;
62my $codespellfile = "/usr/share/codespell/dictionary.txt";
Martin Rothedd591d2017-03-14 10:16:29 -060063my $conststructsfile = "$D/const_structs.checkpatch";
Martin Roth387dec82017-09-17 19:20:46 -060064my $typedefsfile = "";
65my $color = "auto";
Martin Rothedd591d2017-03-14 10:16:29 -060066my $allow_c99_comments = 1;
Elyes HAOUASf2a9c8d2022-01-29 08:31:06 +010067my $git_command ='git'; # coreboot
Elyes HAOUAS96771bf2022-01-29 07:28:45 +010068my $tabsize = 8;
Martin Roth1f3daea2017-08-30 13:53:58 -060069# For coreboot jenkins
70# If taint mode is enabled, Untaint the path - files must be in /bin, /usr/bin or /usr/local/bin
71if ( ${^TAINT} ) {
72 $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
73 delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV' };
74}
75
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010076sub help {
77 my ($exitcode) = @_;
78
79 print << "EOM";
80Usage: $P [OPTION]... [FILE]...
81Version: $V
82
83Options:
84 -q, --quiet quiet
Stefan Reinauerc6080c62016-07-29 16:01:40 -070085 --no-tree run without a kernel tree
Stefan Reinauer44d0fd92015-02-11 01:49:00 +010086 --no-signoff do not check for 'Signed-off-by' line
87 --patch treat FILE as patchfile (default)
88 --emacs emacs compile window format
89 --terse one line per report
Stefan Reinauerc6080c62016-07-29 16:01:40 -070090 --showfile emit diffed file position, not input file position
91 -g, --git treat FILE as a single commit or git revision range
92 single git commit with:
93 <rev>
94 <rev>^
95 <rev>~n
96 multiple git commits with:
97 <rev1>..<rev2>
98 <rev1>...<rev2>
99 <rev>-<count>
100 git merges are ignored
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100101 -f, --file treat FILE as regular source file
102 --subjective, --strict enable more subjective tests
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700103 --list-types list the possible message types
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100104 --types TYPE(,TYPE2...) show only these comma separated message types
105 --ignore TYPE(,TYPE2...) ignore various comma separated message types
Martin Rotha3cac872017-03-04 18:17:35 -0700106 --exclude DIR(,DIR22...) exclude directories
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700107 --show-types show the specific message type in the output
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100108 --max-line-length=n set the maximum line length, if exceeded, warn
109 --min-conf-desc-length=n set the min description length, if shorter, warn
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700110 --root=PATH PATH to the kernel tree root
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100111 --no-summary suppress the per-file summary
112 --mailback only produce a report in case of warnings/errors
113 --summary-file include the filename in summary
114 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
115 'values', 'possible', 'type', and 'attr' (default
116 is all off)
117 --test-only=WORD report only warnings/errors containing WORD
118 literally
119 --fix EXPERIMENTAL - may create horrible results
120 If correctable single-line errors exist, create
121 "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
122 with potential errors corrected to the preferred
123 checkpatch style
124 --fix-inplace EXPERIMENTAL - may create horrible results
125 Is the same as --fix, but overwrites the input
126 file. It's your fault if there's no backup or git
127 --ignore-perl-version override checking of perl version. expect
128 runtime errors.
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700129 --codespell Use the codespell dictionary for spelling/typos
130 (default:/usr/share/codespell/dictionary.txt)
131 --codespellfile Use this codespell dictionary
Martin Roth387dec82017-09-17 19:20:46 -0600132 --typedefsfile Read additional types from this file
133 --color[=WHEN] Use colors 'always', 'never', or only when output
134 is a terminal ('auto'). Default is 'auto'.
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100135 -h, --help, --version display this help and exit
136
137When FILE is - read standard input.
138EOM
139
140 exit($exitcode);
141}
142
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700143sub uniq {
144 my %seen;
145 return grep { !$seen{$_}++ } @_;
146}
147
148sub list_types {
149 my ($exitcode) = @_;
150
151 my $count = 0;
152
153 local $/ = undef;
154
155 open(my $script, '<', abs_path($P)) or
156 die "$P: Can't read '$P' $!\n";
157
158 my $text = <$script>;
159 close($script);
160
161 my @types = ();
Martin Roth387dec82017-09-17 19:20:46 -0600162 # Also catch when type or level is passed through a variable
163 for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700164 push (@types, $_);
165 }
166 @types = sort(uniq(@types));
167 print("#\tMessage type\n\n");
168 foreach my $type (@types) {
169 print(++$count . "\t" . $type . "\n");
170 }
171
172 exit($exitcode);
173}
174
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100175my $conf = which_conf($configuration_file);
176if (-f $conf) {
177 my @conf_args;
178 open(my $conffile, '<', "$conf")
179 or warn "$P: Can't find a readable $configuration_file file $!\n";
180
181 while (<$conffile>) {
182 my $line = $_;
183
184 $line =~ s/\s*\n?$//g;
185 $line =~ s/^\s*//g;
186 $line =~ s/\s+/ /g;
187
188 next if ($line =~ m/^\s*#/);
189 next if ($line =~ m/^\s*$/);
190
191 my @words = split(" ", $line);
192 foreach my $word (@words) {
193 last if ($word =~ m/^#/);
194 push (@conf_args, $word);
195 }
196 }
197 close($conffile);
198 unshift(@ARGV, @conf_args) if @conf_args;
199}
200
Martin Roth387dec82017-09-17 19:20:46 -0600201# Perl's Getopt::Long allows options to take optional arguments after a space.
202# Prevent --color by itself from consuming other arguments
203foreach (@ARGV) {
204 if ($_ eq "--color" || $_ eq "-color") {
205 $_ = "--color=$color";
206 }
207}
208
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100209GetOptions(
210 'q|quiet+' => \$quiet,
211 'tree!' => \$tree,
212 'signoff!' => \$chk_signoff,
213 'patch!' => \$chk_patch,
214 'emacs!' => \$emacs,
215 'terse!' => \$terse,
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700216 'showfile!' => \$showfile,
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100217 'f|file!' => \$file,
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700218 'g|git!' => \$git,
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100219 'subjective!' => \$check,
220 'strict!' => \$check,
221 'ignore=s' => \@ignore,
Martin Rothedd591d2017-03-14 10:16:29 -0600222 'exclude=s' => \@exclude, #coreboot
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100223 'types=s' => \@use,
224 'show-types!' => \$show_types,
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700225 'list-types!' => \$list_types,
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100226 'max-line-length=i' => \$max_line_length,
227 'min-conf-desc-length=i' => \$min_conf_desc_length,
228 'root=s' => \$root,
229 'summary!' => \$summary,
230 'mailback!' => \$mailback,
231 'summary-file!' => \$summary_file,
232 'fix!' => \$fix,
233 'fix-inplace!' => \$fix_inplace,
234 'ignore-perl-version!' => \$ignore_perl_version,
235 'debug=s' => \%debug,
236 'test-only=s' => \$tst_only,
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700237 'codespell!' => \$codespell,
238 'codespellfile=s' => \$codespellfile,
Martin Roth387dec82017-09-17 19:20:46 -0600239 'typedefsfile=s' => \$typedefsfile,
240 'color=s' => \$color,
241 'no-color' => \$color, #keep old behaviors of -nocolor
242 'nocolor' => \$color, #keep old behaviors of -nocolor
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100243 'h|help' => \$help,
244 'version' => \$help
245) or help(1);
246
247help(0) if ($help);
248
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700249list_types(0) if ($list_types);
250
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100251$fix = 1 if ($fix_inplace);
252$check_orig = $check;
253
254my $exit = 0;
255
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +0100256my $perl_version_ok = 1;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100257if ($^V && $^V lt $minimum_perl_version) {
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +0100258 $perl_version_ok = 0;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100259 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +0100260 exit(1) if (!$ignore_perl_version);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100261}
262
Martin Rothedd591d2017-03-14 10:16:29 -0600263#if no filenames are given, push '-' to read patch from stdin
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100264if ($#ARGV < 0) {
Martin Rothedd591d2017-03-14 10:16:29 -0600265 push(@ARGV, '-');
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100266}
267
Martin Roth387dec82017-09-17 19:20:46 -0600268if ($color =~ /^[01]$/) {
269 $color = !$color;
270} elsif ($color =~ /^always$/i) {
271 $color = 1;
272} elsif ($color =~ /^never$/i) {
273 $color = 0;
274} elsif ($color =~ /^auto$/i) {
275 $color = (-t STDOUT);
276} else {
277 die "Invalid color mode: $color\n";
278}
279
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100280sub hash_save_array_words {
281 my ($hashRef, $arrayRef) = @_;
282
283 my @array = split(/,/, join(',', @$arrayRef));
284 foreach my $word (@array) {
285 $word =~ s/\s*\n?$//g;
286 $word =~ s/^\s*//g;
287 $word =~ s/\s+/ /g;
288 $word =~ tr/[a-z]/[A-Z]/;
289
290 next if ($word =~ m/^\s*#/);
291 next if ($word =~ m/^\s*$/);
292
293 $hashRef->{$word}++;
294 }
295}
296
297sub hash_show_words {
298 my ($hashRef, $prefix) = @_;
299
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700300 if (keys %$hashRef) {
301 print "\nNOTE: $prefix message types:";
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100302 foreach my $word (sort keys %$hashRef) {
303 print " $word";
304 }
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700305 print "\n";
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100306 }
307}
308
309hash_save_array_words(\%ignore_type, \@ignore);
310hash_save_array_words(\%use_type, \@use);
311
312my $dbg_values = 0;
313my $dbg_possible = 0;
314my $dbg_type = 0;
315my $dbg_attr = 0;
316for my $key (keys %debug) {
317 ## no critic
318 eval "\${dbg_$key} = '$debug{$key}';";
319 die "$@" if ($@);
320}
321
322my $rpt_cleaners = 0;
323
324if ($terse) {
325 $emacs = 1;
326 $quiet++;
327}
328
329if ($tree) {
330 if (defined $root) {
331 if (!top_of_kernel_tree($root)) {
332 die "$P: $root: --root does not point at a valid tree\n";
333 }
334 } else {
335 if (top_of_kernel_tree('.')) {
336 $root = '.';
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700337 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100338 top_of_kernel_tree($1)) {
339 $root = $1;
340 }
341 }
342
343 if (!defined $root) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700344 print "Must be run from the top-level dir. of a kernel tree\n";
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100345 exit(2);
346 }
347}
348
349my $emitted_corrupt = 0;
350
351our $Ident = qr{
352 [A-Za-z_][A-Za-z\d_]*
353 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
354 }x;
355our $Storage = qr{extern|static|asmlinkage};
356our $Sparse = qr{
357 __user|
358 __kernel|
359 __force|
360 __iomem|
361 __must_check|
362 __init_refok|
363 __kprobes|
364 __ref|
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700365 __rcu|
366 __private
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100367 }x;
368our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
369our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
370our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
371our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
372our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
373
374# Notes to $Attribute:
375# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
376our $Attribute = qr{
377 const|
378 __percpu|
379 __nocast|
380 __safe|
Martin Rothedd591d2017-03-14 10:16:29 -0600381 __bitwise|
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100382 __packed__|
383 __packed2__|
384 __naked|
385 __maybe_unused|
386 __always_unused|
387 __noreturn|
388 __used|
389 __cold|
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700390 __pure|
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100391 __noclone|
392 __deprecated|
393 __read_mostly|
394 __kprobes|
395 $InitAttribute|
396 ____cacheline_aligned|
397 ____cacheline_aligned_in_smp|
398 ____cacheline_internodealigned_in_smp|
399 __weak
400 }x;
401our $Modifier;
402our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
403our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
404our $Lval = qr{$Ident(?:$Member)*};
405
406our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
407our $Binary = qr{(?i)0b[01]+$Int_type?};
408our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
409our $Int = qr{[0-9]+$Int_type?};
410our $Octal = qr{0[0-7]+$Int_type?};
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700411our $String = qr{"[X\t]*"};
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100412our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
413our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
414our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
415our $Float = qr{$Float_hex|$Float_dec|$Float_int};
416our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
417our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
418our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
419our $Arithmetic = qr{\+|-|\*|\/|%};
420our $Operators = qr{
421 <=|>=|==|!=|
422 =>|->|<<|>>|<|>|!|~|
423 &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
424 }x;
425
426our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
427
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700428our $BasicType;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100429our $NonptrType;
430our $NonptrTypeMisordered;
431our $NonptrTypeWithAttr;
432our $Type;
433our $TypeMisordered;
434our $Declare;
435our $DeclareMisordered;
436
437our $NON_ASCII_UTF8 = qr{
438 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
439 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
440 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
441 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
442 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
443 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
444 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
445}x;
446
447our $UTF8 = qr{
448 [\x09\x0A\x0D\x20-\x7E] # ASCII
449 | $NON_ASCII_UTF8
450}x;
451
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700452our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
453our $typeOtherOSTypedefs = qr{(?x:
454 u_(?:char|short|int|long) | # bsd
455 u(?:nchar|short|int|long) # sysv
456)};
457our $typeKernelTypedefs = qr{(?x:
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100458 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
459 atomic_t
460)};
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700461our $typeTypedefs = qr{(?x:
462 $typeC99Typedefs\b|
463 $typeOtherOSTypedefs\b|
464 $typeKernelTypedefs\b
465)};
466
467our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100468
469our $logFunctions = qr{(?x:
Martin Rothedd591d2017-03-14 10:16:29 -0600470 printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100471 (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
Martin Roth60915b32018-08-10 21:04:05 -0600472 TP_printk|
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100473 WARN(?:_RATELIMIT|_ONCE|)|
474 panic|
475 MODULE_[A-Z_]+|
476 seq_vprintf|seq_printf|seq_puts
477)};
478
479our $signature_tags = qr{(?xi:
480 Signed-off-by:|
481 Acked-by:|
482 Tested-by:|
483 Reviewed-by:|
484 Reported-by:|
485 Suggested-by:|
486 To:|
487 Cc:
488)};
489
490our @typeListMisordered = (
491 qr{char\s+(?:un)?signed},
492 qr{int\s+(?:(?:un)?signed\s+)?short\s},
493 qr{int\s+short(?:\s+(?:un)?signed)},
494 qr{short\s+int(?:\s+(?:un)?signed)},
495 qr{(?:un)?signed\s+int\s+short},
496 qr{short\s+(?:un)?signed},
497 qr{long\s+int\s+(?:un)?signed},
498 qr{int\s+long\s+(?:un)?signed},
499 qr{long\s+(?:un)?signed\s+int},
500 qr{int\s+(?:un)?signed\s+long},
501 qr{int\s+(?:un)?signed},
502 qr{int\s+long\s+long\s+(?:un)?signed},
503 qr{long\s+long\s+int\s+(?:un)?signed},
504 qr{long\s+long\s+(?:un)?signed\s+int},
505 qr{long\s+long\s+(?:un)?signed},
506 qr{long\s+(?:un)?signed},
507);
508
509our @typeList = (
510 qr{void},
511 qr{(?:(?:un)?signed\s+)?char},
512 qr{(?:(?:un)?signed\s+)?short\s+int},
513 qr{(?:(?:un)?signed\s+)?short},
514 qr{(?:(?:un)?signed\s+)?int},
515 qr{(?:(?:un)?signed\s+)?long\s+int},
516 qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
517 qr{(?:(?:un)?signed\s+)?long\s+long},
518 qr{(?:(?:un)?signed\s+)?long},
519 qr{(?:un)?signed},
520 qr{float},
521 qr{double},
522 qr{bool},
523 qr{struct\s+$Ident},
524 qr{union\s+$Ident},
525 qr{enum\s+$Ident},
526 qr{${Ident}_t},
527 qr{${Ident}_handler},
528 qr{${Ident}_handler_fn},
529 @typeListMisordered,
530);
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700531
532our $C90_int_types = qr{(?x:
533 long\s+long\s+int\s+(?:un)?signed|
534 long\s+long\s+(?:un)?signed\s+int|
535 long\s+long\s+(?:un)?signed|
536 (?:(?:un)?signed\s+)?long\s+long\s+int|
537 (?:(?:un)?signed\s+)?long\s+long|
538 int\s+long\s+long\s+(?:un)?signed|
539 int\s+(?:(?:un)?signed\s+)?long\s+long|
540
541 long\s+int\s+(?:un)?signed|
542 long\s+(?:un)?signed\s+int|
543 long\s+(?:un)?signed|
544 (?:(?:un)?signed\s+)?long\s+int|
545 (?:(?:un)?signed\s+)?long|
546 int\s+long\s+(?:un)?signed|
547 int\s+(?:(?:un)?signed\s+)?long|
548
549 int\s+(?:un)?signed|
550 (?:(?:un)?signed\s+)?int
551)};
552
553our @typeListFile = ();
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100554our @typeListWithAttr = (
555 @typeList,
556 qr{struct\s+$InitAttribute\s+$Ident},
557 qr{union\s+$InitAttribute\s+$Ident},
558);
559
560our @modifierList = (
561 qr{fastcall},
562);
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700563our @modifierListFile = ();
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100564
565our @mode_permission_funcs = (
566 ["module_param", 3],
567 ["module_param_(?:array|named|string)", 4],
568 ["module_param_array_named", 5],
569 ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
570 ["proc_create(?:_data|)", 2],
Martin Rothedd591d2017-03-14 10:16:29 -0600571 ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
572 ["IIO_DEV_ATTR_[A-Z_]+", 1],
573 ["SENSOR_(?:DEVICE_|)ATTR_2", 2],
574 ["SENSOR_TEMPLATE(?:_2|)", 3],
575 ["__ATTR", 2],
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100576);
577
578#Create a search pattern for all these functions to speed up a loop below
579our $mode_perms_search = "";
580foreach my $entry (@mode_permission_funcs) {
581 $mode_perms_search .= '|' if ($mode_perms_search ne "");
582 $mode_perms_search .= $entry->[0];
583}
Martin Roth60915b32018-08-10 21:04:05 -0600584$mode_perms_search = "(?:${mode_perms_search})";
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100585
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700586our $mode_perms_world_writable = qr{
587 S_IWUGO |
588 S_IWOTH |
589 S_IRWXUGO |
590 S_IALLUGO |
591 0[0-7][0-7][2367]
592}x;
593
Martin Rothedd591d2017-03-14 10:16:29 -0600594our %mode_permission_string_types = (
595 "S_IRWXU" => 0700,
596 "S_IRUSR" => 0400,
597 "S_IWUSR" => 0200,
598 "S_IXUSR" => 0100,
599 "S_IRWXG" => 0070,
600 "S_IRGRP" => 0040,
601 "S_IWGRP" => 0020,
602 "S_IXGRP" => 0010,
603 "S_IRWXO" => 0007,
604 "S_IROTH" => 0004,
605 "S_IWOTH" => 0002,
606 "S_IXOTH" => 0001,
607 "S_IRWXUGO" => 0777,
608 "S_IRUGO" => 0444,
609 "S_IWUGO" => 0222,
610 "S_IXUGO" => 0111,
611);
612
613#Create a search pattern for all these strings to speed up a loop below
614our $mode_perms_string_search = "";
615foreach my $entry (keys %mode_permission_string_types) {
616 $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
617 $mode_perms_string_search .= $entry;
618}
Martin Roth60915b32018-08-10 21:04:05 -0600619our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
620our $multi_mode_perms_string_search = qr{
621 ${single_mode_perms_string_search}
622 (?:\s*\|\s*${single_mode_perms_string_search})*
623}x;
624
625sub perms_to_octal {
626 my ($string) = @_;
627
628 return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
629
630 my $val = "";
631 my $oval = "";
632 my $to = 0;
633 my $curpos = 0;
634 my $lastpos = 0;
635 while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
636 $curpos = pos($string);
637 my $match = $2;
638 my $omatch = $1;
639 last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
640 $lastpos = $curpos;
641 $to |= $mode_permission_string_types{$match};
642 $val .= '\s*\|\s*' if ($val ne "");
643 $val .= $match;
644 $oval .= $omatch;
645 }
646 $oval =~ s/^\s*\|\s*//;
647 $oval =~ s/\s*\|\s*$//;
648 return sprintf("%04o", $to);
649}
Martin Rothedd591d2017-03-14 10:16:29 -0600650
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100651our $allowed_asm_includes = qr{(?x:
652 irq|
653 memory|
654 time|
655 reboot
656)};
657# memory.h: ARM has a custom one
658
659# Load common spelling mistakes and build regular expression list.
660my $misspellings;
661my %spelling_fix;
662
663if (open(my $spelling, '<', $spelling_file)) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100664 while (<$spelling>) {
665 my $line = $_;
666
667 $line =~ s/\s*\n?$//g;
668 $line =~ s/^\s*//g;
669
670 next if ($line =~ m/^\s*#/);
671 next if ($line =~ m/^\s*$/);
672
673 my ($suspect, $fix) = split(/\|\|/, $line);
674
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100675 $spelling_fix{$suspect} = $fix;
676 }
677 close($spelling);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100678} else {
679 warn "No typos will be found - file '$spelling_file': $!\n";
680}
681
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700682if ($codespell) {
683 if (open(my $spelling, '<', $codespellfile)) {
684 while (<$spelling>) {
685 my $line = $_;
686
687 $line =~ s/\s*\n?$//g;
688 $line =~ s/^\s*//g;
689
690 next if ($line =~ m/^\s*#/);
691 next if ($line =~ m/^\s*$/);
692 next if ($line =~ m/, disabled/i);
693
694 $line =~ s/,.*$//;
695
696 my ($suspect, $fix) = split(/->/, $line);
697
698 $spelling_fix{$suspect} = $fix;
699 }
700 close($spelling);
701 } else {
702 warn "No codespell typos will be found - file '$codespellfile': $!\n";
703 }
704}
705
706$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
707
Martin Roth387dec82017-09-17 19:20:46 -0600708sub read_words {
709 my ($wordsRef, $file) = @_;
Martin Rothedd591d2017-03-14 10:16:29 -0600710
Martin Roth387dec82017-09-17 19:20:46 -0600711 if (open(my $words, '<', $file)) {
712 while (<$words>) {
713 my $line = $_;
Martin Rothedd591d2017-03-14 10:16:29 -0600714
Martin Roth387dec82017-09-17 19:20:46 -0600715 $line =~ s/\s*\n?$//g;
716 $line =~ s/^\s*//g;
717
718 next if ($line =~ m/^\s*#/);
719 next if ($line =~ m/^\s*$/);
720 if ($line =~ /\s/) {
721 print("$file: '$line' invalid - ignored\n");
722 next;
723 }
724
725 $$wordsRef .= '|' if ($$wordsRef ne "");
726 $$wordsRef .= $line;
Martin Rothedd591d2017-03-14 10:16:29 -0600727 }
Martin Roth387dec82017-09-17 19:20:46 -0600728 close($file);
729 return 1;
Martin Rothedd591d2017-03-14 10:16:29 -0600730 }
Martin Roth387dec82017-09-17 19:20:46 -0600731
732 return 0;
Martin Rothedd591d2017-03-14 10:16:29 -0600733}
734
Martin Roth387dec82017-09-17 19:20:46 -0600735my $const_structs = "";
736read_words(\$const_structs, $conststructsfile)
737 or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
738
739my $typeOtherTypedefs = "";
740if (length($typedefsfile)) {
741 read_words(\$typeOtherTypedefs, $typedefsfile)
742 or warn "No additional types will be considered - file '$typedefsfile': $!\n";
743}
744$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
745
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100746sub build_types {
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700747 my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
748 my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100749 my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
750 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
751 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700752 $BasicType = qr{
753 (?:$typeTypedefs\b)|
754 (?:${all}\b)
755 }x;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100756 $NonptrType = qr{
757 (?:$Modifier\s+|const\s+)*
758 (?:
759 (?:typeof|__typeof__)\s*\([^\)]*\)|
760 (?:$typeTypedefs\b)|
761 (?:${all}\b)
762 )
763 (?:\s+$Modifier|\s+const)*
764 }x;
765 $NonptrTypeMisordered = qr{
766 (?:$Modifier\s+|const\s+)*
767 (?:
768 (?:${Misordered}\b)
769 )
770 (?:\s+$Modifier|\s+const)*
771 }x;
772 $NonptrTypeWithAttr = qr{
773 (?:$Modifier\s+|const\s+)*
774 (?:
775 (?:typeof|__typeof__)\s*\([^\)]*\)|
776 (?:$typeTypedefs\b)|
777 (?:${allWithAttr}\b)
778 )
779 (?:\s+$Modifier|\s+const)*
780 }x;
781 $Type = qr{
782 $NonptrType
783 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
784 (?:\s+$Inline|\s+$Modifier)*
785 }x;
786 $TypeMisordered = qr{
787 $NonptrTypeMisordered
788 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
789 (?:\s+$Inline|\s+$Modifier)*
790 }x;
791 $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
792 $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
793}
794build_types();
795
796our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
797
798# Using $balanced_parens, $LvalOrFunc, or $FuncArg
799# requires at least perl version v5.10.0
800# Any use must be runtime checked with $^V
801
802our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
803our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700804our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100805
806our $declaration_macros = qr{(?x:
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700807 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
Martin Roth387dec82017-09-17 19:20:46 -0600808 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
Martin Roth60915b32018-08-10 21:04:05 -0600809 (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
810 (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100811)};
812
813sub deparenthesize {
814 my ($string) = @_;
815 return "" if (!defined($string));
816
817 while ($string =~ /^\s*\(.*\)\s*$/) {
818 $string =~ s@^\s*\(\s*@@;
819 $string =~ s@\s*\)\s*$@@;
820 }
821
822 $string =~ s@\s+@ @g;
823
824 return $string;
825}
826
827sub seed_camelcase_file {
828 my ($file) = @_;
829
830 return if (!(-f $file));
831
832 local $/;
833
834 open(my $include_file, '<', "$file")
835 or warn "$P: Can't read '$file' $!\n";
836 my $text = <$include_file>;
837 close($include_file);
838
839 my @lines = split('\n', $text);
840
841 foreach my $line (@lines) {
842 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
843 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
844 $camelcase{$1} = 1;
845 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
846 $camelcase{$1} = 1;
847 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
848 $camelcase{$1} = 1;
849 }
850 }
851}
852
Martin Rothedd591d2017-03-14 10:16:29 -0600853sub is_maintained_obsolete {
854 my ($filename) = @_;
855
856 return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
857
858 my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
859
860 return $status =~ /obsolete/i;
861}
862
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100863my $camelcase_seeded = 0;
864sub seed_camelcase_includes {
865 return if ($camelcase_seeded);
866
867 my $files;
868 my $camelcase_cache = "";
869 my @include_files = ();
870
871 $camelcase_seeded = 1;
872
Elyes HAOUAS18ef5202022-01-29 08:27:14 +0100873 if (-e "$gitroot") {
Elyes HAOUASf2a9c8d2022-01-29 08:31:06 +0100874 my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100875 chomp $git_last_include_commit;
876 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
877 } else {
878 my $last_mod_date = 0;
879 $files = `find $root/include -name "*.h"`;
880 @include_files = split('\n', $files);
881 foreach my $file (@include_files) {
882 my $date = POSIX::strftime("%Y%m%d%H%M",
883 localtime((stat $file)[9]));
884 $last_mod_date = $date if ($last_mod_date < $date);
885 }
886 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
887 }
888
889 if ($camelcase_cache ne "" && -f $camelcase_cache) {
890 open(my $camelcase_file, '<', "$camelcase_cache")
891 or warn "$P: Can't read '$camelcase_cache' $!\n";
892 while (<$camelcase_file>) {
893 chomp;
894 $camelcase{$_} = 1;
895 }
896 close($camelcase_file);
897
898 return;
899 }
900
Elyes HAOUAS18ef5202022-01-29 08:27:14 +0100901 if (-e "$gitroot") {
Elyes HAOUASf2a9c8d2022-01-29 08:31:06 +0100902 $files = `${git_command} ls-files "include/*.h"`;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100903 @include_files = split('\n', $files);
904 }
905
906 foreach my $file (@include_files) {
907 seed_camelcase_file($file);
908 }
909
910 if ($camelcase_cache ne "") {
911 unlink glob ".checkpatch-camelcase.*";
912 open(my $camelcase_file, '>', "$camelcase_cache")
913 or warn "$P: Can't write '$camelcase_cache' $!\n";
914 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
915 print $camelcase_file ("$_\n");
916 }
917 close($camelcase_file);
918 }
919}
920
921sub git_commit_info {
922 my ($commit, $id, $desc) = @_;
923
Elyes HAOUAS18ef5202022-01-29 08:27:14 +0100924 return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100925
Elyes HAOUASf2a9c8d2022-01-29 08:31:06 +0100926 my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100927 $output =~ s/^\s*//gm;
928 my @lines = split("\n", $output);
929
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700930 return ($id, $desc) if ($#lines < 0);
931
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100932 if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
933# Maybe one day convert this block of bash into something that returns
934# all matching commit ids, but it's very slow...
935#
936# echo "checking commits $1..."
937# git rev-list --remotes | grep -i "^$1" |
938# while read line ; do
939# git log --format='%H %s' -1 $line |
940# echo "commit $(cut -c 1-12,41-)"
941# done
942 } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
Martin Roth387dec82017-09-17 19:20:46 -0600943 $id = undef;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100944 } else {
945 $id = substr($lines[0], 0, 12);
946 $desc = substr($lines[0], 41);
947 }
948
949 return ($id, $desc);
950}
951
952$chk_signoff = 0 if ($file);
953
954my @rawlines = ();
955my @lines = ();
956my @fixed = ();
957my @fixed_inserted = ();
958my @fixed_deleted = ();
959my $fixlinenr = -1;
960
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700961# If input is git commits, extract all commits from the commit expressions.
962# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
Elyes HAOUAS18ef5202022-01-29 08:27:14 +0100963die "$P: No git repository found\n" if ($git && !-e "$gitroot");
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700964
965if ($git) {
966 my @commits = ();
967 foreach my $commit_expr (@ARGV) {
968 my $git_range;
969 if ($commit_expr =~ m/^(.*)-(\d+)$/) {
970 $git_range = "-$2 $1";
971 } elsif ($commit_expr =~ m/\.\./) {
972 $git_range = "$commit_expr";
973 } else {
974 $git_range = "-1 $commit_expr";
975 }
Elyes HAOUASf2a9c8d2022-01-29 08:31:06 +0100976 my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700977 foreach my $line (split(/\n/, $lines)) {
978 $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
979 next if (!defined($1) || !defined($2));
980 my $sha1 = $1;
981 my $subject = $2;
982 unshift(@commits, $sha1);
983 $git_commits{$sha1} = $subject;
984 }
985 }
986 die "$P: no git commits after extraction!\n" if (@commits == 0);
987 @ARGV = @commits;
988}
989
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100990my $vname;
Martin Roth387dec82017-09-17 19:20:46 -0600991for my $filename (@ARGV) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +0100992 my $FILE;
Martin Rotha9868b22018-01-27 17:31:42 -0700993
994 # coreboot: Mark filename as untainted
995 $filename =~ /^(.*)$/s or die; $filename = $1;
996
Stefan Reinauerc6080c62016-07-29 16:01:40 -0700997 if ($git) {
998 open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
999 die "$P: $filename: git format-patch failed - $!\n";
1000 } elsif ($file) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001001 open($FILE, '-|', "diff -u /dev/null $filename") ||
1002 die "$P: $filename: diff failed - $!\n";
1003 } elsif ($filename eq '-') {
1004 open($FILE, '<&STDIN');
1005 } else {
1006 open($FILE, '<', "$filename") ||
1007 die "$P: $filename: open failed - $!\n";
1008 }
1009 if ($filename eq '-') {
1010 $vname = 'Your patch';
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001011 } elsif ($git) {
1012 $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001013 } else {
1014 $vname = $filename;
1015 }
1016 while (<$FILE>) {
1017 chomp;
1018 push(@rawlines, $_);
1019 }
1020 close($FILE);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001021
1022 if ($#ARGV > 0 && $quiet == 0) {
1023 print '-' x length($vname) . "\n";
1024 print "$vname\n";
1025 print '-' x length($vname) . "\n";
1026 }
1027
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001028 if (!process($filename)) {
1029 $exit = 1;
1030 }
1031 @rawlines = ();
1032 @lines = ();
1033 @fixed = ();
1034 @fixed_inserted = ();
1035 @fixed_deleted = ();
1036 $fixlinenr = -1;
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001037 @modifierListFile = ();
1038 @typeListFile = ();
1039 build_types();
1040}
1041
1042if (!$quiet) {
1043 hash_show_words(\%use_type, "Used");
1044 hash_show_words(\%ignore_type, "Ignored");
1045
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01001046 if (!$perl_version_ok) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001047 print << "EOM"
1048
1049NOTE: perl $^V is not modern enough to detect all possible issues.
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01001050 An upgrade to at least perl $minimum_perl_version is suggested.
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001051EOM
1052 }
1053 if ($exit) {
1054 print << "EOM"
1055
1056NOTE: If any of the errors are false positives, please report
1057 them to the maintainer, see CHECKPATCH in MAINTAINERS.
1058EOM
1059 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001060}
1061
1062exit($exit);
1063
1064sub top_of_kernel_tree {
1065 my ($root) = @_;
1066
1067 my @tree_check = (
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001068 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
1069 "README", "Documentation", "arch", "include", "drivers",
1070 "fs", "init", "ipc", "kernel", "lib", "scripts",
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001071 );
1072
1073 foreach my $check (@tree_check) {
1074 if (! -e $root . '/' . $check) {
1075 return 0;
1076 }
1077 }
1078 return 1;
1079}
1080
1081sub parse_email {
1082 my ($formatted_email) = @_;
1083
1084 my $name = "";
1085 my $address = "";
1086 my $comment = "";
1087
1088 if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
1089 $name = $1;
1090 $address = $2;
1091 $comment = $3 if defined $3;
1092 } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
1093 $address = $1;
1094 $comment = $2 if defined $2;
1095 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1096 $address = $1;
1097 $comment = $2 if defined $2;
Martin Roth60915b32018-08-10 21:04:05 -06001098 $formatted_email =~ s/\Q$address\E.*$//;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001099 $name = $formatted_email;
1100 $name = trim($name);
1101 $name =~ s/^\"|\"$//g;
1102 # If there's a name left after stripping spaces and
1103 # leading quotes, and the address doesn't have both
1104 # leading and trailing angle brackets, the address
1105 # is invalid. ie:
1106 # "joe smith joe@smith.com" bad
1107 # "joe smith <joe@smith.com" bad
1108 if ($name ne "" && $address !~ /^<[^>]+>$/) {
1109 $name = "";
1110 $address = "";
1111 $comment = "";
1112 }
1113 }
1114
1115 $name = trim($name);
1116 $name =~ s/^\"|\"$//g;
1117 $address = trim($address);
1118 $address =~ s/^\<|\>$//g;
1119
1120 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1121 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1122 $name = "\"$name\"";
1123 }
1124
1125 return ($name, $address, $comment);
1126}
1127
1128sub format_email {
1129 my ($name, $address) = @_;
1130
1131 my $formatted_email;
1132
1133 $name = trim($name);
1134 $name =~ s/^\"|\"$//g;
1135 $address = trim($address);
1136
1137 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1138 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1139 $name = "\"$name\"";
1140 }
1141
1142 if ("$name" eq "") {
1143 $formatted_email = "$address";
1144 } else {
1145 $formatted_email = "$name <$address>";
1146 }
1147
1148 return $formatted_email;
1149}
1150
1151sub which {
1152 my ($bin) = @_;
1153
1154 foreach my $path (split(/:/, $ENV{PATH})) {
1155 if (-e "$path/$bin") {
1156 return "$path/$bin";
1157 }
1158 }
1159
1160 return "";
1161}
1162
1163sub which_conf {
1164 my ($conf) = @_;
1165
1166 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1167 if (-e "$path/$conf") {
1168 return "$path/$conf";
1169 }
1170 }
1171
1172 return "";
1173}
1174
1175sub expand_tabs {
1176 my ($str) = @_;
1177
1178 my $res = '';
1179 my $n = 0;
1180 for my $c (split(//, $str)) {
1181 if ($c eq "\t") {
1182 $res .= ' ';
1183 $n++;
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01001184 for (; ($n % $tabsize) != 0; $n++) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001185 $res .= ' ';
1186 }
1187 next;
1188 }
1189 $res .= $c;
1190 $n++;
1191 }
1192
1193 return $res;
1194}
1195sub copy_spacing {
1196 (my $res = shift) =~ tr/\t/ /c;
1197 return $res;
1198}
1199
1200sub line_stats {
1201 my ($line) = @_;
1202
Julius Werner218906d2021-03-25 21:12:49 -07001203 # Drop the diff line leader
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001204 $line =~ s/^.//;
Julius Werner218906d2021-03-25 21:12:49 -07001205
1206 # Treat labels like whitespace when counting indentation
1207 $line =~ s/^( ?$Ident:)/" " x length($1)/e;
1208
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001209 $line = expand_tabs($line);
1210
1211 # Pick the indent from the front of the line.
1212 my ($white) = ($line =~ /^(\s*)/);
1213
1214 return (length($line), length($white));
1215}
1216
1217my $sanitise_quote = '';
1218
1219sub sanitise_line_reset {
1220 my ($in_comment) = @_;
1221
1222 if ($in_comment) {
1223 $sanitise_quote = '*/';
1224 } else {
1225 $sanitise_quote = '';
1226 }
1227}
1228sub sanitise_line {
1229 my ($line) = @_;
1230
1231 my $res = '';
1232 my $l = '';
1233
1234 my $qlen = 0;
1235 my $off = 0;
1236 my $c;
1237
1238 # Always copy over the diff marker.
1239 $res = substr($line, 0, 1);
1240
1241 for ($off = 1; $off < length($line); $off++) {
1242 $c = substr($line, $off, 1);
1243
Martin Roth60915b32018-08-10 21:04:05 -06001244 # Comments we are whacking completely including the begin
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001245 # and end, all to $;.
1246 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1247 $sanitise_quote = '*/';
1248
1249 substr($res, $off, 2, "$;$;");
1250 $off++;
1251 next;
1252 }
1253 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1254 $sanitise_quote = '';
1255 substr($res, $off, 2, "$;$;");
1256 $off++;
1257 next;
1258 }
1259 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1260 $sanitise_quote = '//';
1261
1262 substr($res, $off, 2, $sanitise_quote);
1263 $off++;
1264 next;
1265 }
1266
1267 # A \ in a string means ignore the next character.
1268 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1269 $c eq "\\") {
1270 substr($res, $off, 2, 'XX');
1271 $off++;
1272 next;
1273 }
1274 # Regular quotes.
1275 if ($c eq "'" || $c eq '"') {
1276 if ($sanitise_quote eq '') {
1277 $sanitise_quote = $c;
1278
1279 substr($res, $off, 1, $c);
1280 next;
1281 } elsif ($sanitise_quote eq $c) {
1282 $sanitise_quote = '';
1283 }
1284 }
1285
1286 #print "c<$c> SQ<$sanitise_quote>\n";
1287 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1288 substr($res, $off, 1, $;);
1289 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1290 substr($res, $off, 1, $;);
1291 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1292 substr($res, $off, 1, 'X');
1293 } else {
1294 substr($res, $off, 1, $c);
1295 }
1296 }
1297
1298 if ($sanitise_quote eq '//') {
1299 $sanitise_quote = '';
1300 }
1301
1302 # The pathname on a #include may be surrounded by '<' and '>'.
1303 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1304 my $clean = 'X' x length($1);
1305 $res =~ s@\<.*\>@<$clean>@;
1306
1307 # The whole of a #error is a string.
1308 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1309 my $clean = 'X' x length($1);
1310 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1311 }
1312
Martin Rothedd591d2017-03-14 10:16:29 -06001313 if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1314 my $match = $1;
1315 $res =~ s/\Q$match\E/"$;" x length($match)/e;
1316 }
1317
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001318 return $res;
1319}
1320
1321sub get_quoted_string {
1322 my ($line, $rawline) = @_;
1323
Martin Roth60915b32018-08-10 21:04:05 -06001324 return "" if (!defined($line) || !defined($rawline));
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001325 return "" if ($line !~ m/($String)/g);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001326 return substr($rawline, $-[0], $+[0] - $-[0]);
1327}
1328
1329sub ctx_statement_block {
1330 my ($linenr, $remain, $off) = @_;
1331 my $line = $linenr - 1;
1332 my $blk = '';
1333 my $soff = $off;
1334 my $coff = $off - 1;
1335 my $coff_set = 0;
1336
1337 my $loff = 0;
1338
1339 my $type = '';
1340 my $level = 0;
Julius Werner218906d2021-03-25 21:12:49 -07001341 my @stack = (['', $level]);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001342 my $p;
1343 my $c;
1344 my $len = 0;
1345
1346 my $remainder;
1347 while (1) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001348 #warn "CSB: blk<$blk> remain<$remain>\n";
1349 # If we are about to drop off the end, pull in more
1350 # context.
1351 if ($off >= $len) {
1352 for (; $remain > 0; $line++) {
1353 last if (!defined $lines[$line]);
1354 next if ($lines[$line] =~ /^-/);
1355 $remain--;
1356 $loff = $len;
1357 $blk .= $lines[$line] . "\n";
1358 $len = length($blk);
1359 $line++;
1360 last;
1361 }
1362 # Bail if there is no further context.
1363 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
1364 if ($off >= $len) {
1365 last;
1366 }
1367 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1368 $level++;
1369 $type = '#';
1370 }
1371 }
1372 $p = $c;
1373 $c = substr($blk, $off, 1);
1374 $remainder = substr($blk, $off);
1375
1376 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
1377
1378 # Handle nested #if/#else.
1379 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
1380 push(@stack, [ $type, $level ]);
Julius Werner218906d2021-03-25 21:12:49 -07001381 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/ && $#stack > 0) {
1382 ($type, $level) = @{$stack[$#stack]};
1383 } elsif ($remainder =~ /^#\s*endif\b/ && $#stack > 0) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001384 ($type, $level) = @{pop(@stack)};
1385 }
1386
1387 # Statement ends at the ';' or a close '}' at the
1388 # outermost level.
1389 if ($level == 0 && $c eq ';') {
1390 last;
1391 }
1392
1393 # An else is really a conditional as long as its not else if
1394 if ($level == 0 && $coff_set == 0 &&
1395 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1396 $remainder =~ /^(else)(?:\s|{)/ &&
1397 $remainder !~ /^else\s+if\b/) {
1398 $coff = $off + length($1) - 1;
1399 $coff_set = 1;
1400 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1401 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
1402 }
1403
1404 if (($type eq '' || $type eq '(') && $c eq '(') {
1405 $level++;
1406 $type = '(';
1407 }
1408 if ($type eq '(' && $c eq ')') {
1409 $level--;
1410 $type = ($level != 0)? '(' : '';
1411
1412 if ($level == 0 && $coff < $soff) {
1413 $coff = $off;
1414 $coff_set = 1;
1415 #warn "CSB: mark coff<$coff>\n";
1416 }
1417 }
1418 if (($type eq '' || $type eq '{') && $c eq '{') {
1419 $level++;
1420 $type = '{';
1421 }
1422 if ($type eq '{' && $c eq '}') {
1423 $level--;
1424 $type = ($level != 0)? '{' : '';
1425
1426 if ($level == 0) {
1427 if (substr($blk, $off + 1, 1) eq ';') {
1428 $off++;
1429 }
1430 last;
1431 }
1432 }
1433 # Preprocessor commands end at the newline unless escaped.
1434 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1435 $level--;
1436 $type = '';
1437 $off++;
1438 last;
1439 }
1440 $off++;
1441 }
1442 # We are truly at the end, so shuffle to the next line.
1443 if ($off == $len) {
1444 $loff = $len + 1;
1445 $line++;
1446 $remain--;
1447 }
1448
1449 my $statement = substr($blk, $soff, $off - $soff + 1);
1450 my $condition = substr($blk, $soff, $coff - $soff + 1);
1451
1452 #warn "STATEMENT<$statement>\n";
1453 #warn "CONDITION<$condition>\n";
1454
1455 #print "coff<$coff> soff<$off> loff<$loff>\n";
1456
1457 return ($statement, $condition,
1458 $line, $remain + 1, $off - $loff + 1, $level);
1459}
1460
1461sub statement_lines {
1462 my ($stmt) = @_;
1463
1464 # Strip the diff line prefixes and rip blank lines at start and end.
1465 $stmt =~ s/(^|\n)./$1/g;
1466 $stmt =~ s/^\s*//;
1467 $stmt =~ s/\s*$//;
1468
1469 my @stmt_lines = ($stmt =~ /\n/g);
1470
1471 return $#stmt_lines + 2;
1472}
1473
1474sub statement_rawlines {
1475 my ($stmt) = @_;
1476
1477 my @stmt_lines = ($stmt =~ /\n/g);
1478
1479 return $#stmt_lines + 2;
1480}
1481
1482sub statement_block_size {
1483 my ($stmt) = @_;
1484
1485 $stmt =~ s/(^|\n)./$1/g;
1486 $stmt =~ s/^\s*{//;
1487 $stmt =~ s/}\s*$//;
1488 $stmt =~ s/^\s*//;
1489 $stmt =~ s/\s*$//;
1490
1491 my @stmt_lines = ($stmt =~ /\n/g);
1492 my @stmt_statements = ($stmt =~ /;/g);
1493
1494 my $stmt_lines = $#stmt_lines + 2;
1495 my $stmt_statements = $#stmt_statements + 1;
1496
1497 if ($stmt_lines > $stmt_statements) {
1498 return $stmt_lines;
1499 } else {
1500 return $stmt_statements;
1501 }
1502}
1503
1504sub ctx_statement_full {
1505 my ($linenr, $remain, $off) = @_;
1506 my ($statement, $condition, $level);
1507
1508 my (@chunks);
1509
1510 # Grab the first conditional/block pair.
1511 ($statement, $condition, $linenr, $remain, $off, $level) =
1512 ctx_statement_block($linenr, $remain, $off);
1513 #print "F: c<$condition> s<$statement> remain<$remain>\n";
1514 push(@chunks, [ $condition, $statement ]);
1515 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1516 return ($level, $linenr, @chunks);
1517 }
1518
1519 # Pull in the following conditional/block pairs and see if they
1520 # could continue the statement.
1521 for (;;) {
1522 ($statement, $condition, $linenr, $remain, $off, $level) =
1523 ctx_statement_block($linenr, $remain, $off);
1524 #print "C: c<$condition> s<$statement> remain<$remain>\n";
1525 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1526 #print "C: push\n";
1527 push(@chunks, [ $condition, $statement ]);
1528 }
1529
1530 return ($level, $linenr, @chunks);
1531}
1532
1533sub ctx_block_get {
1534 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1535 my $line;
1536 my $start = $linenr - 1;
1537 my $blk = '';
1538 my @o;
1539 my @c;
1540 my @res = ();
1541
1542 my $level = 0;
1543 my @stack = ($level);
1544 for ($line = $start; $remain > 0; $line++) {
1545 next if ($rawlines[$line] =~ /^-/);
1546 $remain--;
1547
1548 $blk .= $rawlines[$line];
1549
1550 # Handle nested #if/#else.
1551 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1552 push(@stack, $level);
Julius Werner218906d2021-03-25 21:12:49 -07001553 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/ && $#stack > 0) {
1554 $level = $stack[$#stack];
1555 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/ && $#stack > 0) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001556 $level = pop(@stack);
1557 }
1558
1559 foreach my $c (split(//, $lines[$line])) {
1560 ##print "C<$c>L<$level><$open$close>O<$off>\n";
1561 if ($off > 0) {
1562 $off--;
1563 next;
1564 }
1565
1566 if ($c eq $close && $level > 0) {
1567 $level--;
1568 last if ($level == 0);
1569 } elsif ($c eq $open) {
1570 $level++;
1571 }
1572 }
1573
1574 if (!$outer || $level <= 1) {
1575 push(@res, $rawlines[$line]);
1576 }
1577
1578 last if ($level == 0);
1579 }
1580
1581 return ($level, @res);
1582}
1583sub ctx_block_outer {
1584 my ($linenr, $remain) = @_;
1585
1586 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1587 return @r;
1588}
1589sub ctx_block {
1590 my ($linenr, $remain) = @_;
1591
1592 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1593 return @r;
1594}
1595sub ctx_statement {
1596 my ($linenr, $remain, $off) = @_;
1597
1598 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1599 return @r;
1600}
1601sub ctx_block_level {
1602 my ($linenr, $remain) = @_;
1603
1604 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1605}
1606sub ctx_statement_level {
1607 my ($linenr, $remain, $off) = @_;
1608
1609 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1610}
1611
1612sub ctx_locate_comment {
1613 my ($first_line, $end_line) = @_;
1614
1615 # Catch a comment on the end of the line itself.
1616 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1617 return $current_comment if (defined $current_comment);
1618
1619 # Look through the context and try and figure out if there is a
1620 # comment.
1621 my $in_comment = 0;
1622 $current_comment = '';
1623 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1624 my $line = $rawlines[$linenr - 1];
1625 #warn " $line\n";
1626 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1627 $in_comment = 1;
1628 }
1629 if ($line =~ m@/\*@) {
1630 $in_comment = 1;
1631 }
1632 if (!$in_comment && $current_comment ne '') {
1633 $current_comment = '';
1634 }
1635 $current_comment .= $line . "\n" if ($in_comment);
1636 if ($line =~ m@\*/@) {
1637 $in_comment = 0;
1638 }
1639 }
1640
1641 chomp($current_comment);
1642 return($current_comment);
1643}
1644sub ctx_has_comment {
1645 my ($first_line, $end_line) = @_;
1646 my $cmt = ctx_locate_comment($first_line, $end_line);
1647
1648 ##print "LINE: $rawlines[$end_line - 1 ]\n";
1649 ##print "CMMT: $cmt\n";
1650
1651 return ($cmt ne '');
1652}
1653
1654sub raw_line {
1655 my ($linenr, $cnt) = @_;
1656
1657 my $offset = $linenr - 1;
1658 $cnt++;
1659
1660 my $line;
1661 while ($cnt) {
1662 $line = $rawlines[$offset++];
1663 next if (defined($line) && $line =~ /^-/);
1664 $cnt--;
1665 }
1666
Martin Roth96a48f12016-08-29 15:30:23 -06001667 # coreboot: This probably shouldn't happen, but it does.
1668 # Return a defined value so we don't get an error.
1669 if (defined $line) {
1670 return $line;
1671 } else {
1672 return "";
1673 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001674}
1675
Martin Roth60915b32018-08-10 21:04:05 -06001676sub get_stat_real {
1677 my ($linenr, $lc) = @_;
1678
1679 my $stat_real = raw_line($linenr, 0);
1680 for (my $count = $linenr + 1; $count <= $lc; $count++) {
1681 $stat_real = $stat_real . "\n" . raw_line($count, 0);
1682 }
1683
1684 return $stat_real;
1685}
1686
1687sub get_stat_here {
1688 my ($linenr, $cnt, $here) = @_;
1689
1690 my $herectx = $here . "\n";
1691 for (my $n = 0; $n < $cnt; $n++) {
1692 $herectx .= raw_line($linenr, $n) . "\n";
1693 }
1694
1695 return $herectx;
1696}
1697
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001698sub cat_vet {
1699 my ($vet) = @_;
1700 my ($res, $coded);
1701
1702 $res = '';
1703 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1704 $res .= $1;
1705 if ($2 ne '') {
1706 $coded = sprintf("^%c", unpack('C', $2) + 64);
1707 $res .= $coded;
1708 }
1709 }
1710 $res =~ s/$/\$/;
1711
1712 return $res;
1713}
1714
1715my $av_preprocessor = 0;
1716my $av_pending;
1717my @av_paren_type;
1718my $av_pend_colon;
1719
1720sub annotate_reset {
1721 $av_preprocessor = 0;
1722 $av_pending = '_';
1723 @av_paren_type = ('E');
1724 $av_pend_colon = 'O';
1725}
1726
1727sub annotate_values {
1728 my ($stream, $type) = @_;
1729
1730 my $res;
1731 my $var = '_' x length($stream);
1732 my $cur = $stream;
1733
1734 print "$stream\n" if ($dbg_values > 1);
1735
1736 while (length($cur)) {
1737 @av_paren_type = ('E') if ($#av_paren_type < 0);
1738 print " <" . join('', @av_paren_type) .
1739 "> <$type> <$av_pending>" if ($dbg_values > 1);
1740 if ($cur =~ /^(\s+)/o) {
1741 print "WS($1)\n" if ($dbg_values > 1);
1742 if ($1 =~ /\n/ && $av_preprocessor) {
1743 $type = pop(@av_paren_type);
1744 $av_preprocessor = 0;
1745 }
1746
1747 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1748 print "CAST($1)\n" if ($dbg_values > 1);
1749 push(@av_paren_type, $type);
1750 $type = 'c';
1751
1752 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1753 print "DECLARE($1)\n" if ($dbg_values > 1);
1754 $type = 'T';
1755
1756 } elsif ($cur =~ /^($Modifier)\s*/) {
1757 print "MODIFIER($1)\n" if ($dbg_values > 1);
1758 $type = 'T';
1759
1760 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1761 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1762 $av_preprocessor = 1;
1763 push(@av_paren_type, $type);
1764 if ($2 ne '') {
1765 $av_pending = 'N';
1766 }
1767 $type = 'E';
1768
1769 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1770 print "UNDEF($1)\n" if ($dbg_values > 1);
1771 $av_preprocessor = 1;
1772 push(@av_paren_type, $type);
1773
1774 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1775 print "PRE_START($1)\n" if ($dbg_values > 1);
1776 $av_preprocessor = 1;
1777
1778 push(@av_paren_type, $type);
1779 push(@av_paren_type, $type);
1780 $type = 'E';
1781
1782 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1783 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1784 $av_preprocessor = 1;
1785
1786 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1787
1788 $type = 'E';
1789
1790 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1791 print "PRE_END($1)\n" if ($dbg_values > 1);
1792
1793 $av_preprocessor = 1;
1794
1795 # Assume all arms of the conditional end as this
1796 # one does, and continue as if the #endif was not here.
1797 pop(@av_paren_type);
1798 push(@av_paren_type, $type);
1799 $type = 'E';
1800
1801 } elsif ($cur =~ /^(\\\n)/o) {
1802 print "PRECONT($1)\n" if ($dbg_values > 1);
1803
1804 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1805 print "ATTR($1)\n" if ($dbg_values > 1);
1806 $av_pending = $type;
1807 $type = 'N';
1808
1809 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1810 print "SIZEOF($1)\n" if ($dbg_values > 1);
1811 if (defined $2) {
1812 $av_pending = 'V';
1813 }
1814 $type = 'N';
1815
1816 } elsif ($cur =~ /^(if|while|for)\b/o) {
1817 print "COND($1)\n" if ($dbg_values > 1);
1818 $av_pending = 'E';
1819 $type = 'N';
1820
1821 } elsif ($cur =~/^(case)/o) {
1822 print "CASE($1)\n" if ($dbg_values > 1);
1823 $av_pend_colon = 'C';
1824 $type = 'N';
1825
1826 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1827 print "KEYWORD($1)\n" if ($dbg_values > 1);
1828 $type = 'N';
1829
1830 } elsif ($cur =~ /^(\()/o) {
1831 print "PAREN('$1')\n" if ($dbg_values > 1);
1832 push(@av_paren_type, $av_pending);
1833 $av_pending = '_';
1834 $type = 'N';
1835
1836 } elsif ($cur =~ /^(\))/o) {
1837 my $new_type = pop(@av_paren_type);
1838 if ($new_type ne '_') {
1839 $type = $new_type;
1840 print "PAREN('$1') -> $type\n"
1841 if ($dbg_values > 1);
1842 } else {
1843 print "PAREN('$1')\n" if ($dbg_values > 1);
1844 }
1845
1846 } elsif ($cur =~ /^($Ident)\s*\(/o) {
1847 print "FUNC($1)\n" if ($dbg_values > 1);
1848 $type = 'V';
1849 $av_pending = 'V';
1850
1851 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1852 if (defined $2 && $type eq 'C' || $type eq 'T') {
1853 $av_pend_colon = 'B';
1854 } elsif ($type eq 'E') {
1855 $av_pend_colon = 'L';
1856 }
1857 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1858 $type = 'V';
1859
1860 } elsif ($cur =~ /^($Ident|$Constant)/o) {
1861 print "IDENT($1)\n" if ($dbg_values > 1);
1862 $type = 'V';
1863
1864 } elsif ($cur =~ /^($Assignment)/o) {
1865 print "ASSIGN($1)\n" if ($dbg_values > 1);
1866 $type = 'N';
1867
1868 } elsif ($cur =~/^(;|{|})/) {
1869 print "END($1)\n" if ($dbg_values > 1);
1870 $type = 'E';
1871 $av_pend_colon = 'O';
1872
1873 } elsif ($cur =~/^(,)/) {
1874 print "COMMA($1)\n" if ($dbg_values > 1);
1875 $type = 'C';
1876
1877 } elsif ($cur =~ /^(\?)/o) {
1878 print "QUESTION($1)\n" if ($dbg_values > 1);
1879 $type = 'N';
1880
1881 } elsif ($cur =~ /^(:)/o) {
1882 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1883
1884 substr($var, length($res), 1, $av_pend_colon);
1885 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1886 $type = 'E';
1887 } else {
1888 $type = 'N';
1889 }
1890 $av_pend_colon = 'O';
1891
1892 } elsif ($cur =~ /^(\[)/o) {
1893 print "CLOSE($1)\n" if ($dbg_values > 1);
1894 $type = 'N';
1895
1896 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1897 my $variant;
1898
1899 print "OPV($1)\n" if ($dbg_values > 1);
1900 if ($type eq 'V') {
1901 $variant = 'B';
1902 } else {
1903 $variant = 'U';
1904 }
1905
1906 substr($var, length($res), 1, $variant);
1907 $type = 'N';
1908
1909 } elsif ($cur =~ /^($Operators)/o) {
1910 print "OP($1)\n" if ($dbg_values > 1);
1911 if ($1 ne '++' && $1 ne '--') {
1912 $type = 'N';
1913 }
1914
1915 } elsif ($cur =~ /(^.)/o) {
1916 print "C($1)\n" if ($dbg_values > 1);
1917 }
1918 if (defined $1) {
1919 $cur = substr($cur, length($1));
1920 $res .= $type x length($1);
1921 }
1922 }
1923
1924 return ($res, $var);
1925}
1926
1927sub possible {
1928 my ($possible, $line) = @_;
1929 my $notPermitted = qr{(?:
1930 ^(?:
1931 $Modifier|
1932 $Storage|
1933 $Type|
1934 DEFINE_\S+
1935 )$|
1936 ^(?:
1937 goto|
1938 return|
1939 case|
1940 else|
1941 asm|__asm__|
1942 do|
1943 \#|
1944 \#\#|
1945 )(?:\s|$)|
1946 ^(?:typedef|struct|enum)\b
1947 )}x;
1948 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1949 if ($possible !~ $notPermitted) {
1950 # Check for modifiers.
1951 $possible =~ s/\s*$Storage\s*//g;
1952 $possible =~ s/\s*$Sparse\s*//g;
1953 if ($possible =~ /^\s*$/) {
1954
1955 } elsif ($possible =~ /\s/) {
1956 $possible =~ s/\s*$Type\s*//g;
1957 for my $modifier (split(' ', $possible)) {
1958 if ($modifier !~ $notPermitted) {
1959 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001960 push(@modifierListFile, $modifier);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001961 }
1962 }
1963
1964 } else {
1965 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001966 push(@typeListFile, $possible);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001967 }
1968 build_types();
1969 } else {
1970 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
1971 }
1972}
1973
1974my $prefix = '';
1975
1976sub show_type {
1977 my ($type) = @_;
1978
Martin Rothedd591d2017-03-14 10:16:29 -06001979 $type =~ tr/[a-z]/[A-Z]/;
1980
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01001981 return defined $use_type{$type} if (scalar keys %use_type > 0);
1982
1983 return !defined $ignore_type{$type};
1984}
1985
1986sub report {
1987 my ($level, $type, $msg) = @_;
1988
1989 if (!show_type($type) ||
1990 (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1991 return 0;
1992 }
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001993 my $output = '';
Martin Roth387dec82017-09-17 19:20:46 -06001994 if ($color) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07001995 if ($level eq 'ERROR') {
1996 $output .= RED;
1997 } elsif ($level eq 'WARNING') {
1998 $output .= YELLOW;
1999 } else {
2000 $output .= GREEN;
2001 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002002 }
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002003 $output .= $prefix . $level . ':';
2004 if ($show_types) {
Martin Roth387dec82017-09-17 19:20:46 -06002005 $output .= BLUE if ($color);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002006 $output .= "$type:";
2007 }
Martin Roth387dec82017-09-17 19:20:46 -06002008 $output .= RESET if ($color);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002009 $output .= ' ' . $msg . "\n";
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002010
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002011 if ($showfile) {
2012 my @lines = split("\n", $output, -1);
2013 splice(@lines, 1, 1);
2014 $output = join("\n", @lines);
2015 }
2016 $output = (split('\n', $output))[0] . "\n" if ($terse);
2017
2018 push(our @report, $output);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002019
2020 return 1;
2021}
2022
2023sub report_dump {
2024 our @report;
2025}
2026
2027sub fixup_current_range {
2028 my ($lineRef, $offset, $length) = @_;
2029
2030 if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2031 my $o = $1;
2032 my $l = $2;
2033 my $no = $o + $offset;
2034 my $nl = $l + $length;
2035 $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2036 }
2037}
2038
2039sub fix_inserted_deleted_lines {
2040 my ($linesRef, $insertedRef, $deletedRef) = @_;
2041
2042 my $range_last_linenr = 0;
2043 my $delta_offset = 0;
2044
2045 my $old_linenr = 0;
2046 my $new_linenr = 0;
2047
2048 my $next_insert = 0;
2049 my $next_delete = 0;
2050
2051 my @lines = ();
2052
2053 my $inserted = @{$insertedRef}[$next_insert++];
2054 my $deleted = @{$deletedRef}[$next_delete++];
2055
2056 foreach my $old_line (@{$linesRef}) {
2057 my $save_line = 1;
2058 my $line = $old_line; #don't modify the array
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002059 if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002060 $delta_offset = 0;
2061 } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
2062 $range_last_linenr = $new_linenr;
2063 fixup_current_range(\$line, $delta_offset, 0);
2064 }
2065
2066 while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2067 $deleted = @{$deletedRef}[$next_delete++];
2068 $save_line = 0;
2069 fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2070 }
2071
2072 while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2073 push(@lines, ${$inserted}{'LINE'});
2074 $inserted = @{$insertedRef}[$next_insert++];
2075 $new_linenr++;
2076 fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2077 }
2078
2079 if ($save_line) {
2080 push(@lines, $line);
2081 $new_linenr++;
2082 }
2083
2084 $old_linenr++;
2085 }
2086
2087 return @lines;
2088}
2089
2090sub fix_insert_line {
2091 my ($linenr, $line) = @_;
2092
2093 my $inserted = {
2094 LINENR => $linenr,
2095 LINE => $line,
2096 };
2097 push(@fixed_inserted, $inserted);
2098}
2099
2100sub fix_delete_line {
2101 my ($linenr, $line) = @_;
2102
2103 my $deleted = {
2104 LINENR => $linenr,
2105 LINE => $line,
2106 };
2107
2108 push(@fixed_deleted, $deleted);
2109}
2110
2111sub ERROR {
2112 my ($type, $msg) = @_;
2113
2114 if (report("ERROR", $type, $msg)) {
2115 our $clean = 0;
2116 our $cnt_error++;
2117 return 1;
2118 }
2119 return 0;
2120}
2121sub WARN {
2122 my ($type, $msg) = @_;
2123
2124 if (report("WARNING", $type, $msg)) {
2125 our $clean = 0;
2126 our $cnt_warn++;
2127 return 1;
2128 }
2129 return 0;
2130}
2131sub CHK {
2132 my ($type, $msg) = @_;
2133
2134 if ($check && report("CHECK", $type, $msg)) {
2135 our $clean = 0;
2136 our $cnt_chk++;
2137 return 1;
2138 }
2139 return 0;
2140}
2141
2142sub check_absolute_file {
2143 my ($absolute, $herecurr) = @_;
2144 my $file = $absolute;
2145
2146 ##print "absolute<$absolute>\n";
2147
2148 # See if any suffix of this path is a path within the tree.
2149 while ($file =~ s@^[^/]*/@@) {
2150 if (-f "$root/$file") {
2151 ##print "file<$file>\n";
2152 last;
2153 }
2154 }
2155 if (! -f _) {
2156 return 0;
2157 }
2158
2159 # It is, so see if the prefix is acceptable.
2160 my $prefix = $absolute;
2161 substr($prefix, -length($file)) = '';
2162
2163 ##print "prefix<$prefix>\n";
2164 if ($prefix ne ".../") {
2165 WARN("USE_RELATIVE_PATH",
2166 "use relative pathname instead of absolute in changelog text\n" . $herecurr);
2167 }
2168}
2169
2170sub trim {
2171 my ($string) = @_;
2172
2173 $string =~ s/^\s+|\s+$//g;
2174
2175 return $string;
2176}
2177
2178sub ltrim {
2179 my ($string) = @_;
2180
2181 $string =~ s/^\s+//;
2182
2183 return $string;
2184}
2185
2186sub rtrim {
2187 my ($string) = @_;
2188
2189 $string =~ s/\s+$//;
2190
2191 return $string;
2192}
2193
2194sub string_find_replace {
2195 my ($string, $find, $replace) = @_;
2196
2197 $string =~ s/$find/$replace/g;
2198
2199 return $string;
2200}
2201
2202sub tabify {
2203 my ($leading) = @_;
2204
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01002205 my $source_indent = $tabsize;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002206 my $max_spaces_before_tab = $source_indent - 1;
2207 my $spaces_to_tab = " " x $source_indent;
2208
2209 #convert leading spaces to tabs
2210 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
2211 #Remove spaces before a tab
2212 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
2213
2214 return "$leading";
2215}
2216
2217sub pos_last_openparen {
2218 my ($line) = @_;
2219
2220 my $pos = 0;
2221
2222 my $opens = $line =~ tr/\(/\(/;
2223 my $closes = $line =~ tr/\)/\)/;
2224
2225 my $last_openparen = 0;
2226
2227 if (($opens == 0) || ($closes >= $opens)) {
2228 return -1;
2229 }
2230
2231 my $len = length($line);
2232
2233 for ($pos = 0; $pos < $len; $pos++) {
2234 my $string = substr($line, $pos);
2235 if ($string =~ /^($FuncArg|$balanced_parens)/) {
2236 $pos += length($1) - 1;
2237 } elsif (substr($line, $pos, 1) eq '(') {
2238 $last_openparen = $pos;
2239 } elsif (index($string, '(') == -1) {
2240 last;
2241 }
2242 }
2243
2244 return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2245}
2246
2247sub process {
2248 my $filename = shift;
2249
2250 my $linenr=0;
2251 my $prevline="";
2252 my $prevrawline="";
2253 my $stashline="";
2254 my $stashrawline="";
2255
2256 my $length;
2257 my $indent;
2258 my $previndent=0;
2259 my $stashindent=0;
2260
2261 our $clean = 1;
2262 my $signoff = 0;
2263 my $is_patch = 0;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002264 my $in_header_lines = $file ? 0 : 1;
2265 my $in_commit_log = 0; #Scanning lines before patch
Martin Rothedd591d2017-03-14 10:16:29 -06002266 my $has_commit_log = 0; #Encountered lines before patch
2267 my $commit_log_possible_stack_dump = 0;
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002268 my $commit_log_long_line = 0;
2269 my $commit_log_has_diff = 0;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002270 my $reported_maintainer_file = 0;
2271 my $non_utf8_charset = 0;
2272
2273 my $last_blank_line = 0;
2274 my $last_coalesced_string_linenr = -1;
2275
2276 our @report = ();
2277 our $cnt_lines = 0;
2278 our $cnt_error = 0;
2279 our $cnt_warn = 0;
2280 our $cnt_chk = 0;
2281
2282 # Trace the real file/line as we go.
2283 my $realfile = '';
2284 my $realline = 0;
2285 my $realcnt = 0;
2286 my $here = '';
Martin Rothedd591d2017-03-14 10:16:29 -06002287 my $context_function; #undef'd unless there's a known function
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002288 my $in_comment = 0;
2289 my $comment_edge = 0;
2290 my $first_line = 0;
2291 my $p1_prefix = '';
2292
2293 my $prev_values = 'E';
2294
2295 # suppression flags
2296 my %suppress_ifbraces;
2297 my %suppress_whiletrailers;
2298 my %suppress_export;
2299 my $suppress_statement = 0;
2300
2301 my %signatures = ();
2302
2303 # Pre-scan the patch sanitizing the lines.
2304 # Pre-scan the patch looking for any __setup documentation.
2305 #
2306 my @setup_docs = ();
2307 my $setup_docs = 0;
2308
2309 my $camelcase_file_seeded = 0;
2310
Martin Roth60915b32018-08-10 21:04:05 -06002311 my $checklicenseline = 1;
2312
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002313 sanitise_line_reset();
2314 my $line;
2315 foreach my $rawline (@rawlines) {
2316 $linenr++;
2317 $line = $rawline;
2318
2319 push(@fixed, $rawline) if ($fix);
2320
2321 if ($rawline=~/^\+\+\+\s+(\S+)/) {
2322 $setup_docs = 0;
Martin Rothedd591d2017-03-14 10:16:29 -06002323 if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002324 $setup_docs = 1;
2325 }
2326 #next;
2327 }
Martin Roth387dec82017-09-17 19:20:46 -06002328 if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002329 $realline=$1-1;
2330 if (defined $2) {
2331 $realcnt=$3+1;
2332 } else {
2333 $realcnt=1+1;
2334 }
2335 $in_comment = 0;
2336
2337 # Guestimate if this is a continuing comment. Run
2338 # the context looking for a comment "edge". If this
2339 # edge is a close comment then we must be in a comment
2340 # at context start.
2341 my $edge;
2342 my $cnt = $realcnt;
2343 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
2344 next if (defined $rawlines[$ln - 1] &&
2345 $rawlines[$ln - 1] =~ /^-/);
2346 $cnt--;
2347 #print "RAW<$rawlines[$ln - 1]>\n";
2348 last if (!defined $rawlines[$ln - 1]);
2349 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2350 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2351 ($edge) = $1;
2352 last;
2353 }
2354 }
2355 if (defined $edge && $edge eq '*/') {
2356 $in_comment = 1;
2357 }
2358
2359 # Guestimate if this is a continuing comment. If this
2360 # is the start of a diff block and this line starts
2361 # ' *' then it is very likely a comment.
2362 if (!defined $edge &&
2363 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2364 {
2365 $in_comment = 1;
2366 }
2367
2368 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2369 sanitise_line_reset($in_comment);
2370
2371 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2372 # Standardise the strings and chars within the input to
2373 # simplify matching -- only bother with positive lines.
2374 $line = sanitise_line($rawline);
2375 }
2376 push(@lines, $line);
2377
2378 if ($realcnt > 1) {
2379 $realcnt-- if ($line =~ /^(?:\+| |$)/);
2380 } else {
2381 $realcnt = 0;
2382 }
2383
2384 #print "==>$rawline\n";
2385 #print "-->$line\n";
2386
2387 if ($setup_docs && $line =~ /^\+/) {
2388 push(@setup_docs, $line);
2389 }
2390 }
2391
2392 $prefix = '';
2393
2394 $realcnt = 0;
2395 $linenr = 0;
2396 $fixlinenr = -1;
2397 foreach my $line (@lines) {
2398 $linenr++;
2399 $fixlinenr++;
2400 my $sline = $line; #copy of $line
2401 $sline =~ s/$;/ /g; #with comments as spaces
2402
2403 my $rawline = $rawlines[$linenr - 1];
2404
Martin Roth60915b32018-08-10 21:04:05 -06002405# check if it's a mode change, rename or start of a patch
2406 if (!$in_commit_log &&
2407 ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
2408 ($line =~ /^rename (?:from|to) \S+\s*$/ ||
2409 $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
2410 $is_patch = 1;
2411 }
2412
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002413#extract the line range in the file after the patch is applied
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002414 if (!$in_commit_log &&
Martin Roth387dec82017-09-17 19:20:46 -06002415 $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2416 my $context = $4;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002417 $is_patch = 1;
2418 $first_line = $linenr + 1;
2419 $realline=$1-1;
2420 if (defined $2) {
2421 $realcnt=$3+1;
2422 } else {
2423 $realcnt=1+1;
2424 }
2425 annotate_reset();
2426 $prev_values = 'E';
2427
2428 %suppress_ifbraces = ();
2429 %suppress_whiletrailers = ();
2430 %suppress_export = ();
2431 $suppress_statement = 0;
Martin Roth387dec82017-09-17 19:20:46 -06002432 if ($context =~ /\b(\w+)\s*\(/) {
2433 $context_function = $1;
2434 } else {
2435 undef $context_function;
2436 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002437 next;
2438
2439# track the line number as we move through the hunk, note that
2440# new versions of GNU diff omit the leading space on completely
2441# blank context lines so we need to count that too.
2442 } elsif ($line =~ /^( |\+|$)/) {
2443 $realline++;
2444 $realcnt-- if ($realcnt != 0);
2445
2446 # Measure the line length and indent.
2447 ($length, $indent) = line_stats($rawline);
2448
2449 # Track the previous line.
2450 ($prevline, $stashline) = ($stashline, $line);
2451 ($previndent, $stashindent) = ($stashindent, $indent);
2452 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2453
2454 #warn "line<$line>\n";
2455
2456 } elsif ($realcnt == 1) {
2457 $realcnt--;
2458 }
2459
2460 my $hunk_line = ($realcnt != 0);
2461
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002462 $here = "#$linenr: " if (!$file);
2463 $here = "#$realline: " if ($file);
2464
2465 my $found_file = 0;
2466 # extract the filename as it passes
2467 if ($line =~ /^diff --git.*?(\S+)$/) {
2468 $realfile = $1;
2469 $realfile =~ s@^([^/]*)/@@ if (!$file);
2470 $in_commit_log = 0;
2471 $found_file = 1;
2472 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2473 $realfile = $1;
2474 $realfile =~ s@^([^/]*)/@@ if (!$file);
2475 $in_commit_log = 0;
2476
2477 $p1_prefix = $1;
2478 if (!$file && $tree && $p1_prefix ne '' &&
2479 -e "$root/$p1_prefix") {
2480 WARN("PATCH_PREFIX",
2481 "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
2482 }
2483
2484 if ($realfile =~ m@^include/asm/@) {
2485 ERROR("MODIFIED_INCLUDE_ASM",
2486 "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2487 }
2488 $found_file = 1;
2489 }
2490
Martin Rothedd591d2017-03-14 10:16:29 -06002491 # coreboot
Martin Rotha3cac872017-03-04 18:17:35 -07002492 my $skipme = 0;
2493 foreach (@exclude) {
2494 if ($realfile =~ m@^(?:$_/)@) {
2495 $skipme = 1;
2496 }
2497 }
2498 if ($skipme) {
2499 next;
2500 }
2501
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002502#make up the handle for any error we report on this line
2503 if ($showfile) {
2504 $prefix = "$realfile:$realline: "
2505 } elsif ($emacs) {
2506 if ($file) {
2507 $prefix = "$filename:$realline: ";
2508 } else {
2509 $prefix = "$filename:$linenr: ";
2510 }
2511 }
2512
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002513 if ($found_file) {
Martin Rothedd591d2017-03-14 10:16:29 -06002514 if (is_maintained_obsolete($realfile)) {
2515 WARN("OBSOLETE",
2516 "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
2517 }
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002518 if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002519 $check = 1;
2520 } else {
2521 $check = $check_orig;
2522 }
Martin Roth60915b32018-08-10 21:04:05 -06002523 $checklicenseline = 1;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002524 next;
2525 }
2526
2527 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
2528
2529 my $hereline = "$here\n$rawline\n";
2530 my $herecurr = "$here\n$rawline\n";
2531 my $hereprev = "$here\n$prevrawline\n$rawline\n";
2532
2533 $cnt_lines++ if ($realcnt != 0);
2534
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002535# Check if the commit log has what seems like a diff which can confuse patch
2536 if ($in_commit_log && !$commit_log_has_diff &&
2537 (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2538 $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2539 $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2540 $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2541 ERROR("DIFF_IN_COMMIT_MSG",
2542 "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2543 $commit_log_has_diff = 1;
2544 }
2545
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002546# Check for incorrect file permissions
2547 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
2548 my $permhere = $here . "FILE: $realfile\n";
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002549 if ($realfile !~ m@scripts/@ &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002550 $realfile !~ /\.(py|pl|awk|sh)$/) {
2551 ERROR("EXECUTE_PERMISSIONS",
2552 "do not set execute permissions for source files\n" . $permhere);
2553 }
2554 }
2555
2556# Check the patch for a signoff:
2557 if ($line =~ /^\s*signed-off-by:/i) {
2558 $signoff++;
2559 $in_commit_log = 0;
2560 }
2561
2562# Check if MAINTAINERS is being updated. If so, there's probably no need to
2563# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2564 if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2565 $reported_maintainer_file = 1;
2566 }
2567
2568# Check signature styles
2569 if (!$in_header_lines &&
2570 $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
2571 my $space_before = $1;
2572 my $sign_off = $2;
2573 my $space_after = $3;
2574 my $email = $4;
2575 my $ucfirst_sign_off = ucfirst(lc($sign_off));
2576
2577 if ($sign_off !~ /$signature_tags/) {
2578 WARN("BAD_SIGN_OFF",
2579 "Non-standard signature: $sign_off\n" . $herecurr);
2580 }
2581 if (defined $space_before && $space_before ne "") {
2582 if (WARN("BAD_SIGN_OFF",
2583 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
2584 $fix) {
2585 $fixed[$fixlinenr] =
2586 "$ucfirst_sign_off $email";
2587 }
2588 }
2589 if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
2590 if (WARN("BAD_SIGN_OFF",
2591 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
2592 $fix) {
2593 $fixed[$fixlinenr] =
2594 "$ucfirst_sign_off $email";
2595 }
2596
2597 }
2598 if (!defined $space_after || $space_after ne " ") {
2599 if (WARN("BAD_SIGN_OFF",
2600 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
2601 $fix) {
2602 $fixed[$fixlinenr] =
2603 "$ucfirst_sign_off $email";
2604 }
2605 }
2606
2607 my ($email_name, $email_address, $comment) = parse_email($email);
2608 my $suggested_email = format_email(($email_name, $email_address));
2609 if ($suggested_email eq "") {
2610 ERROR("BAD_SIGN_OFF",
2611 "Unrecognized email address: '$email'\n" . $herecurr);
2612 } else {
2613 my $dequoted = $suggested_email;
2614 $dequoted =~ s/^"//;
2615 $dequoted =~ s/" </ </;
2616 # Don't force email to have quotes
2617 # Allow just an angle bracketed address
2618 if ("$dequoted$comment" ne $email &&
2619 "<$email_address>$comment" ne $email &&
2620 "$suggested_email$comment" ne $email) {
2621 WARN("BAD_SIGN_OFF",
2622 "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
2623 }
2624 }
2625
2626# Check for duplicate signatures
2627 my $sig_nospace = $line;
2628 $sig_nospace =~ s/\s//g;
2629 $sig_nospace = lc($sig_nospace);
2630 if (defined $signatures{$sig_nospace}) {
2631 WARN("BAD_SIGN_OFF",
2632 "Duplicate signature\n" . $herecurr);
2633 } else {
2634 $signatures{$sig_nospace} = 1;
2635 }
2636 }
2637
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002638# Check email subject for common tools that don't need to be mentioned
2639 if ($in_header_lines &&
2640 $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2641 WARN("EMAIL_SUBJECT",
2642 "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2643 }
2644
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002645# Check for unwanted Gerrit info
2646 if ($in_commit_log && $line =~ /^\s*change-id:/i) {
2647 ERROR("GERRIT_CHANGE_ID",
2648 "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
2649 }
2650
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002651# Check if the commit log is in a possible stack dump
2652 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2653 ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2654 $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2655 # timestamp
2656 $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
2657 # stack dump address
2658 $commit_log_possible_stack_dump = 1;
2659 }
2660
Elyes HAOUASac690492022-01-29 07:59:17 +01002661# coreboot: The line lengeth limit is 72
Paul Menzeldd1ee272021-12-09 12:49:35 +01002662# Check for line lengths > 72 in commit log, warn once
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002663 if ($in_commit_log && !$commit_log_long_line &&
Paul Menzeldd1ee272021-12-09 12:49:35 +01002664 length($line) > 72 &&
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002665 !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2666 # file delta changes
Elyes HAOUASac690492022-01-29 07:59:17 +01002667 $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002668 # filename then :
Elyes HAOUASac690492022-01-29 07:59:17 +01002669 $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
2670 # A Fixes: or Link: line or signature tag line
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002671 $commit_log_possible_stack_dump)) {
2672 WARN("COMMIT_LOG_LONG_LINE",
Paul Menzeldd1ee272021-12-09 12:49:35 +01002673 "Possible unwrapped commit description (prefer a maximum 72 chars per line)\n" . $herecurr);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002674 $commit_log_long_line = 1;
2675 }
2676
2677# Reset possible stack dump if a blank line is found
2678 if ($in_commit_log && $commit_log_possible_stack_dump &&
2679 $line =~ /^\s*$/) {
2680 $commit_log_possible_stack_dump = 0;
2681 }
2682
2683# Check for git id commit length and improperly formed commit descriptions
2684 if ($in_commit_log && !$commit_log_possible_stack_dump &&
Martin Rothedd591d2017-03-14 10:16:29 -06002685 $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
Martin Roth387dec82017-09-17 19:20:46 -06002686 $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002687 ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
Martin Rothedd591d2017-03-14 10:16:29 -06002688 ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002689 $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2690 $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2691 my $init_char = "c";
2692 my $orig_commit = "";
2693 my $short = 1;
2694 my $long = 0;
2695 my $case = 1;
2696 my $space = 1;
2697 my $hasdesc = 0;
2698 my $hasparens = 0;
2699 my $id = '0123456789ab';
2700 my $orig_desc = "commit description";
2701 my $description = "";
2702
2703 if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2704 $init_char = $1;
2705 $orig_commit = lc($2);
2706 } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2707 $orig_commit = lc($1);
2708 }
2709
2710 $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
2711 $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
2712 $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
2713 $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
2714 if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
2715 $orig_desc = $1;
2716 $hasparens = 1;
2717 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
2718 defined $rawlines[$linenr] &&
2719 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
2720 $orig_desc = $1;
2721 $hasparens = 1;
2722 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2723 defined $rawlines[$linenr] &&
2724 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2725 $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2726 $orig_desc = $1;
2727 $rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2728 $orig_desc .= " " . $1;
2729 $hasparens = 1;
2730 }
2731
2732 ($id, $description) = git_commit_info($orig_commit,
2733 $id, $orig_desc);
2734
Martin Roth387dec82017-09-17 19:20:46 -06002735 if (defined($id) &&
2736 ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002737 ERROR("GIT_COMMIT_ID",
2738 "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
2739 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002740 }
2741
2742# Check for added, moved or deleted files
2743 if (!$reported_maintainer_file && !$in_commit_log &&
2744 ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
2745 $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
2746 ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
2747 (defined($1) || defined($2))))) {
Martin Rothedd591d2017-03-14 10:16:29 -06002748 $is_patch = 1;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002749 $reported_maintainer_file = 1;
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002750 WARN("FILE_PATH_CHANGES",
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002751 "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
2752 }
2753
2754# Check for wrappage within a valid hunk of the file
2755 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2756 ERROR("CORRUPTED_PATCH",
2757 "patch seems to be corrupt (line wrapped?)\n" .
2758 $herecurr) if (!$emitted_corrupt++);
2759 }
2760
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002761# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2762 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2763 $rawline !~ m/^$UTF8*$/) {
2764 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2765
2766 my $blank = copy_spacing($rawline);
2767 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2768 my $hereptr = "$hereline$ptr\n";
2769
2770 CHK("INVALID_UTF8",
2771 "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
2772 }
2773
2774# Check if it's the start of a commit log
2775# (not a header line and we haven't seen the patch filename)
2776 if ($in_header_lines && $realfile =~ /^$/ &&
Martin Roth387dec82017-09-17 19:20:46 -06002777 !($rawline =~ /^\s+(?:\S|$)/ ||
2778 $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002779 $in_header_lines = 0;
2780 $in_commit_log = 1;
Martin Rothedd591d2017-03-14 10:16:29 -06002781 $has_commit_log = 1;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002782 }
2783
2784# Check if there is UTF-8 in a commit log when a mail header has explicitly
2785# declined it, i.e defined some charset where it is missing.
2786 if ($in_header_lines &&
2787 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2788 $1 !~ /utf-8/i) {
2789 $non_utf8_charset = 1;
2790 }
2791
2792 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
2793 $rawline =~ /$NON_ASCII_UTF8/) {
2794 WARN("UTF8_BEFORE_PATCH",
2795 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
2796 }
2797
Martin Rothedd591d2017-03-14 10:16:29 -06002798# Check for absolute kernel paths in commit message
2799 if ($tree && $in_commit_log) {
2800 while ($line =~ m{(?:^|\s)(/\S*)}g) {
2801 my $file = $1;
2802
2803 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2804 check_absolute_file($1, $herecurr)) {
2805 #
2806 } else {
2807 check_absolute_file($file, $herecurr);
2808 }
2809 }
2810 }
2811
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002812# Check for various typo / spelling mistakes
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002813 if (defined($misspellings) &&
2814 ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2815 while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002816 my $typo = $1;
2817 my $typo_fix = $spelling_fix{lc($typo)};
2818 $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
2819 $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
Martin Roth387dec82017-09-17 19:20:46 -06002820 my $msg_level = \&WARN;
2821 $msg_level = \&CHK if ($file);
2822 if (&{$msg_level}("TYPO_SPELLING",
2823 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002824 $fix) {
2825 $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
2826 }
2827 }
2828 }
2829
2830# ignore non-hunk lines and lines being removed
2831 next if (!$hunk_line || $line =~ /^-/);
2832
2833#trailing whitespace
2834 if ($line =~ /^\+.*\015/) {
2835 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2836 if (ERROR("DOS_LINE_ENDINGS",
2837 "DOS line endings\n" . $herevet) &&
2838 $fix) {
2839 $fixed[$fixlinenr] =~ s/[\s\015]+$//;
2840 }
2841 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2842 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2843 if (ERROR("TRAILING_WHITESPACE",
2844 "trailing whitespace\n" . $herevet) &&
2845 $fix) {
2846 $fixed[$fixlinenr] =~ s/\s+$//;
2847 }
2848
2849 $rpt_cleaners = 1;
2850 }
2851
2852# Check for FSF mailing addresses.
2853 if ($rawline =~ /\bwrite to the Free/i ||
Martin Rothedd591d2017-03-14 10:16:29 -06002854 $rawline =~ /\b675\s+Mass\s+Ave/i ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002855 $rawline =~ /\b59\s+Temple\s+Pl/i ||
2856 $rawline =~ /\b51\s+Franklin\s+St/i) {
2857 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Martin Roth387dec82017-09-17 19:20:46 -06002858 my $msg_level = \&ERROR;
2859 $msg_level = \&CHK if ($file);
2860 &{$msg_level}("FSF_MAILING_ADDRESS",
2861 "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)
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002862 }
2863
2864# check for Kconfig help text having a real description
2865# Only applies when adding the entry originally, after that we do not have
2866# sufficient context to determine whether it is indeed long enough.
2867 if ($realfile =~ /Kconfig/ &&
Martin Roth60915b32018-08-10 21:04:05 -06002868 # 'choice' is usually the last thing on the line (though
2869 # Kconfig supports named choices), so use a word boundary
2870 # (\b) rather than a whitespace character (\s)
2871 $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002872 my $length = 0;
2873 my $cnt = $realcnt;
2874 my $ln = $linenr + 1;
2875 my $f;
2876 my $is_start = 0;
2877 my $is_end = 0;
2878 for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
2879 $f = $lines[$ln - 1];
2880 $cnt-- if ($lines[$ln - 1] !~ /^-/);
2881 $is_end = $lines[$ln - 1] =~ /^\+/;
2882
2883 next if ($f =~ /^-/);
2884 last if (!$file && $f =~ /^\@\@/);
2885
Martin Roth60915b32018-08-10 21:04:05 -06002886 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002887 $is_start = 1;
Martin Roth60915b32018-08-10 21:04:05 -06002888 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
2889 if ($lines[$ln - 1] =~ "---help---") {
2890 WARN("CONFIG_DESCRIPTION",
2891 "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
2892 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002893 $length = -1;
2894 }
2895
2896 $f =~ s/^.//;
2897 $f =~ s/#.*//;
2898 $f =~ s/^\s+//;
2899 next if ($f =~ /^$/);
Martin Roth60915b32018-08-10 21:04:05 -06002900
2901 # This only checks context lines in the patch
2902 # and so hopefully shouldn't trigger false
2903 # positives, even though some of these are
2904 # common words in help texts
2905 if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
2906 if|endif|menu|endmenu|source)\b/x) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002907 $is_end = 1;
2908 last;
2909 }
2910 $length++;
2911 }
2912 if ($is_start && $is_end && $length < $min_conf_desc_length) {
2913 WARN("CONFIG_DESCRIPTION",
2914 "please write a paragraph that describes the config symbol fully\n" . $herecurr);
2915 }
2916 #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
2917 }
2918
Martin Roth387dec82017-09-17 19:20:46 -06002919# check for MAINTAINERS entries that don't have the right form
2920 if ($realfile =~ /^MAINTAINERS$/ &&
2921 $rawline =~ /^\+[A-Z]:/ &&
2922 $rawline !~ /^\+[A-Z]:\t\S/) {
2923 if (WARN("MAINTAINERS_STYLE",
2924 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
2925 $fix) {
2926 $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
2927 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002928 }
2929
Stefan Reinauerc6080c62016-07-29 16:01:40 -07002930# discourage the use of boolean for type definition attributes of Kconfig options
2931 if ($realfile =~ /Kconfig/ &&
2932 $line =~ /^\+\s*\bboolean\b/) {
2933 WARN("CONFIG_TYPE_BOOLEAN",
2934 "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
2935 }
2936
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01002937 if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2938 ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2939 my $flag = $1;
2940 my $replacement = {
2941 'EXTRA_AFLAGS' => 'asflags-y',
2942 'EXTRA_CFLAGS' => 'ccflags-y',
2943 'EXTRA_CPPFLAGS' => 'cppflags-y',
2944 'EXTRA_LDFLAGS' => 'ldflags-y',
2945 };
2946
2947 WARN("DEPRECATED_VARIABLE",
2948 "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
2949 }
2950
2951# check for DT compatible documentation
2952 if (defined $root &&
2953 (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
2954 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
2955
2956 my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
2957
2958 my $dt_path = $root . "/Documentation/devicetree/bindings/";
2959 my $vp_file = $dt_path . "vendor-prefixes.txt";
2960
2961 foreach my $compat (@compats) {
2962 my $compat2 = $compat;
2963 $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
2964 my $compat3 = $compat;
2965 $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
2966 `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
2967 if ( $? >> 8 ) {
2968 WARN("UNDOCUMENTED_DT_STRING",
2969 "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
2970 }
2971
2972 next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
2973 my $vendor = $1;
2974 `grep -Eq "^$vendor\\b" $vp_file`;
2975 if ( $? >> 8 ) {
2976 WARN("UNDOCUMENTED_DT_STRING",
2977 "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
2978 }
2979 }
2980 }
2981
Martin Roth60915b32018-08-10 21:04:05 -06002982# check for using SPDX license tag at beginning of files
2983 if ($realline == $checklicenseline) {
2984 if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
2985 $checklicenseline = 2;
2986 } elsif ($rawline =~ /^\+/) {
2987 my $comment = "";
2988 if ($realfile =~ /\.(h|s|S)$/) {
2989 $comment = '/*';
2990 } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
2991 $comment = '//';
2992 } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
2993 $comment = '#';
2994 } elsif ($realfile =~ /\.rst$/) {
2995 $comment = '..';
2996 }
2997
2998 if ($comment !~ /^$/ &&
2999 $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) {
3000 WARN("SPDX_LICENSE_TAG",
3001 "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
3002 }
3003 }
3004 }
3005
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003006# check we are in a valid source file if not then ignore this hunk
Martin Rothedd591d2017-03-14 10:16:29 -06003007 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003008
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003009# line length limit (with some exclusions)
3010#
3011# There are a few types of lines that may extend beyond $max_line_length:
3012# logging functions like pr_info that end in a string
3013# lines with a single string
3014# #defines that are a single string
Martin Roth60915b32018-08-10 21:04:05 -06003015# lines with an RFC3986 like URL
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003016#
3017# There are 3 different line length message types:
Martin Roth387dec82017-09-17 19:20:46 -06003018# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003019# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
3020# LONG_LINE all other lines longer than $max_line_length
3021#
3022# if LONG_LINE is ignored, the other 2 types are also ignored
3023#
3024
3025 if ($line =~ /^\+/ && $length > $max_line_length) {
3026 my $msg_type = "LONG_LINE";
3027
3028 # Check the allowed long line types first
3029
3030 # logging functions that end in a string that starts
3031 # before $max_line_length
3032 if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
3033 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3034 $msg_type = "";
3035
3036 # lines with only strings (w/ possible termination)
3037 # #defines with only strings
3038 } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
3039 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
3040 $msg_type = "";
3041
Martin Roth60915b32018-08-10 21:04:05 -06003042 # More special cases
3043 } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3044 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3045 $msg_type = "";
3046
3047 # URL ($rawline is used in case the URL is in a comment)
3048 } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
Martin Rothedd591d2017-03-14 10:16:29 -06003049 $msg_type = "";
3050
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003051 # Otherwise set the alternate message types
3052
3053 # a comment starts before $max_line_length
3054 } elsif ($line =~ /($;[\s$;]*)$/ &&
3055 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3056 $msg_type = "LONG_LINE_COMMENT"
3057
3058 # a quoted string starts before $max_line_length
3059 } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
3060 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3061 $msg_type = "LONG_LINE_STRING"
3062 }
3063
3064 if ($msg_type ne "" &&
3065 (show_type("LONG_LINE") || show_type($msg_type))) {
3066 WARN($msg_type,
3067 "line over $max_line_length characters\n" . $herecurr);
3068 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003069 }
3070
3071# check for adding lines without a newline.
3072 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
3073 WARN("MISSING_EOF_NEWLINE",
3074 "adding a line without newline at end of file\n" . $herecurr);
3075 }
3076
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003077# check we are in a valid source file C or perl if not then ignore this hunk
3078 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
3079
3080# at the beginning of a line any tabs must come first and anything
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01003081# more than $tabsize must use tabs.
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003082 if ($rawline =~ /^\+\s* \t\s*\S/ ||
3083 $rawline =~ /^\+\s* \s*/) {
3084 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3085 $rpt_cleaners = 1;
3086 if (ERROR("CODE_INDENT",
3087 "code indent should use tabs where possible\n" . $herevet) &&
3088 $fix) {
3089 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
3090 }
3091 }
3092
3093# check for space before tabs.
3094 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
3095 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3096 if (WARN("SPACE_BEFORE_TAB",
3097 "please, no space before tabs\n" . $herevet) &&
3098 $fix) {
3099 while ($fixed[$fixlinenr] =~
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01003100 s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003101 while ($fixed[$fixlinenr] =~
3102 s/(^\+.*) +\t/$1\t/) {}
3103 }
3104 }
3105
Martin Roth60915b32018-08-10 21:04:05 -06003106# check for assignments on the start of a line
3107 if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3108 CHK("ASSIGNMENT_CONTINUATIONS",
3109 "Assignment operator '$1' should be on the previous line\n" . $hereprev);
3110 }
3111
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003112# check for && or || at the start of a line
3113 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
3114 CHK("LOGICAL_CONTINUATIONS",
3115 "Logical continuations should be on the previous line\n" . $hereprev);
3116 }
3117
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003118# check indentation starts on a tab stop
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01003119 if ($perl_version_ok &&
Martin Roth60915b32018-08-10 21:04:05 -06003120 $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003121 my $indent = length($1);
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01003122 if ($indent % $tabsize) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003123 if (WARN("TABSTOP",
3124 "Statements should start on a tabstop\n" . $herecurr) &&
3125 $fix) {
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01003126 $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003127 }
3128 }
3129 }
3130
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003131# check multi-line statement indentation matches previous line
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01003132 if ($perl_version_ok &&
Martin Roth387dec82017-09-17 19:20:46 -06003133 $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003134 $prevline =~ /^\+(\t*)(.*)$/;
3135 my $oldindent = $1;
3136 my $rest = $2;
3137
3138 my $pos = pos_last_openparen($rest);
3139 if ($pos >= 0) {
3140 $line =~ /^(\+| )([ \t]*)/;
3141 my $newindent = $2;
3142
3143 my $goodtabindent = $oldindent .
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01003144 "\t" x ($pos / $tabsize) .
3145 " " x ($pos % $tabsize);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003146 my $goodspaceindent = $oldindent . " " x $pos;
3147
3148 if ($newindent ne $goodtabindent &&
3149 $newindent ne $goodspaceindent) {
3150
3151 if (CHK("PARENTHESIS_ALIGNMENT",
3152 "Alignment should match open parenthesis\n" . $hereprev) &&
3153 $fix && $line =~ /^\+/) {
3154 $fixed[$fixlinenr] =~
3155 s/^\+[ \t]*/\+$goodtabindent/;
3156 }
3157 }
3158 }
3159 }
3160
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003161# check for space after cast like "(int) foo" or "(struct foo) bar"
3162# avoid checking a few false positives:
3163# "sizeof(<type>)" or "__alignof__(<type>)"
3164# function pointer declarations like "(*foo)(int) = bar;"
3165# structure definitions like "(struct foo) { 0 };"
3166# multiline macros that define functions
3167# known attributes or the __attribute__ keyword
3168 if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
3169 (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003170 if (CHK("SPACING",
3171 "No space is necessary after a cast\n" . $herecurr) &&
3172 $fix) {
3173 $fixed[$fixlinenr] =~
3174 s/(\(\s*$Type\s*\))[ \t]+/$1/;
3175 }
3176 }
3177
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003178# Block comment styles
3179# Networking with an initial /*
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003180 if ($realfile =~ m@^(drivers/net/|net/)@ &&
3181 $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
3182 $rawline =~ /^\+[ \t]*\*/ &&
3183 $realline > 2) {
3184 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
3185 "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
3186 }
3187
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003188# Block comments use * on subsequent lines
3189 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3190 $prevrawline =~ /^\+.*?\/\*/ && #starting /*
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003191 $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
3192 $rawline =~ /^\+/ && #line is new
3193 $rawline !~ /^\+[ \t]*\*/) { #no leading *
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003194 WARN("BLOCK_COMMENT_STYLE",
3195 "Block comments use * on subsequent lines\n" . $hereprev);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003196 }
3197
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003198# Block comments use */ on trailing lines
3199 if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003200 $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
3201 $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/
3202 $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003203 WARN("BLOCK_COMMENT_STYLE",
3204 "Block comments use a trailing */ on a separate line\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003205 }
3206
Martin Rothedd591d2017-03-14 10:16:29 -06003207# Block comment * alignment
3208 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3209 $line =~ /^\+[ \t]*$;/ && #leading comment
3210 $rawline =~ /^\+[ \t]*\*/ && #leading *
3211 (($prevrawline =~ /^\+.*?\/\*/ && #leading /*
3212 $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */
3213 $prevrawline =~ /^\+[ \t]*\*/)) { #leading *
3214 my $oldindent;
3215 $prevrawline =~ m@^\+([ \t]*/?)\*@;
3216 if (defined($1)) {
3217 $oldindent = expand_tabs($1);
3218 } else {
3219 $prevrawline =~ m@^\+(.*/?)\*@;
3220 $oldindent = expand_tabs($1);
3221 }
3222 $rawline =~ m@^\+([ \t]*)\*@;
3223 my $newindent = $1;
3224 $newindent = expand_tabs($newindent);
3225 if (length($oldindent) ne length($newindent)) {
3226 WARN("BLOCK_COMMENT_STYLE",
3227 "Block comments should align the * on each line\n" . $hereprev);
3228 }
3229 }
3230
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003231# check for missing blank lines after struct/union declarations
3232# with exceptions for various attributes and macros
3233 if ($prevline =~ /^[\+ ]};?\s*$/ &&
3234 $line =~ /^\+/ &&
3235 !($line =~ /^\+\s*$/ ||
3236 $line =~ /^\+\s*EXPORT_SYMBOL/ ||
3237 $line =~ /^\+\s*MODULE_/i ||
3238 $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
3239 $line =~ /^\+[a-z_]*init/ ||
3240 $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
3241 $line =~ /^\+\s*DECLARE/ ||
Martin Roth60915b32018-08-10 21:04:05 -06003242 $line =~ /^\+\s*builtin_[\w_]*driver/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003243 $line =~ /^\+\s*__setup/)) {
3244 if (CHK("LINE_SPACING",
3245 "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3246 $fix) {
3247 fix_insert_line($fixlinenr, "\+");
3248 }
3249 }
3250
3251# check for multiple consecutive blank lines
3252 if ($prevline =~ /^[\+ ]\s*$/ &&
3253 $line =~ /^\+\s*$/ &&
3254 $last_blank_line != ($linenr - 1)) {
3255 if (CHK("LINE_SPACING",
3256 "Please don't use multiple blank lines\n" . $hereprev) &&
3257 $fix) {
3258 fix_delete_line($fixlinenr, $rawline);
3259 }
3260
3261 $last_blank_line = $linenr;
3262 }
3263
3264# check for missing blank lines after declarations
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003265# (declarations must have the same indentation and not be at the start of line)
3266 if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
3267 # use temporaries
3268 my $sl = $sline;
3269 my $pl = $prevline;
3270 # remove $Attribute/$Sparse uses to simplify comparisons
3271 $sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3272 $pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3273 if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003274 # function pointer declarations
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003275 $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003276 # foo bar; where foo is some local typedef or #define
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003277 $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003278 # known declaration macros
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003279 $pl =~ /^\+\s+$declaration_macros/) &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003280 # for "else if" which can look like "$Ident $Ident"
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003281 !($pl =~ /^\+\s+$c90_Keywords\b/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003282 # other possible extensions of declaration lines
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003283 $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003284 # not starting a section or a macro "\" extended line
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003285 $pl =~ /(?:\{\s*|\\)$/) &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003286 # looks like a declaration
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003287 !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003288 # function pointer declarations
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003289 $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003290 # foo bar; where foo is some local typedef or #define
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003291 $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003292 # known declaration macros
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003293 $sl =~ /^\+\s+$declaration_macros/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003294 # start of struct or union or enum
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003295 $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003296 # start or end of block or continuation of declaration
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003297 $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003298 # bitfield continuation
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003299 $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003300 # other possible extensions of declaration lines
Elyes HAOUAS249c4042022-01-29 08:11:50 +01003301 $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
3302 if (WARN("LINE_SPACING",
3303 "Missing a blank line after declarations\n" . $hereprev) &&
3304 $fix) {
3305 fix_insert_line($fixlinenr, "\+");
3306 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003307 }
3308 }
3309
3310# check for spaces at the beginning of a line.
3311# Exceptions:
3312# 1) within comments
3313# 2) indented preprocessor commands
3314# 3) hanging labels
3315 if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
3316 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3317 if (WARN("LEADING_SPACE",
3318 "please, no spaces at the start of a line\n" . $herevet) &&
3319 $fix) {
3320 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
3321 }
3322 }
3323
3324# check we are in a valid C source file if not then ignore this hunk
3325 next if ($realfile !~ /\.(h|c)$/);
3326
Martin Roth60915b32018-08-10 21:04:05 -06003327# check for unusual line ending [ or (
3328 if ($line =~ /^\+.*([\[\(])\s*$/) {
3329 CHK("OPEN_ENDED_LINE",
3330 "Lines should not end with a '$1'\n" . $herecurr);
3331 }
3332
Martin Roth387dec82017-09-17 19:20:46 -06003333# check if this appears to be the start function declaration, save the name
3334 if ($sline =~ /^\+\{\s*$/ &&
3335 $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
3336 $context_function = $1;
3337 }
3338
3339# check if this appears to be the end of function declaration
3340 if ($sline =~ /^\+\}\s*$/) {
3341 undef $context_function;
3342 }
3343
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003344# check indentation of any line with a bare else
3345# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3346# if the previous line is a break or return and is indented 1 tab more...
3347 if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3348 my $tabs = length($1) + 1;
3349 if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3350 ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3351 defined $lines[$linenr] &&
3352 $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3353 WARN("UNNECESSARY_ELSE",
3354 "else is not generally useful after a break or return\n" . $hereprev);
3355 }
3356 }
3357
3358# check indentation of a line with a break;
3359# if the previous line is a goto or return and is indented the same # of tabs
3360 if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3361 my $tabs = $1;
3362 if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3363 WARN("UNNECESSARY_BREAK",
3364 "break is not useful after a goto or return\n" . $hereprev);
3365 }
3366 }
3367
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003368# check for RCS/CVS revision markers
3369 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3370 WARN("CVS_KEYWORD",
3371 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3372 }
3373
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003374# check for old HOTPLUG __dev<foo> section markings
3375 if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
3376 WARN("HOTPLUG_SECTION",
3377 "Using $1 is unnecessary\n" . $herecurr);
3378 }
3379
3380# Check for potential 'bare' types
3381 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
3382 $realline_next);
3383#print "LINE<$line>\n";
Martin Roth387dec82017-09-17 19:20:46 -06003384 if ($linenr > $suppress_statement &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003385 $realcnt && $sline =~ /.\s*\S/) {
3386 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3387 ctx_statement_block($linenr, $realcnt, 0);
3388 $stat =~ s/\n./\n /g;
3389 $cond =~ s/\n./\n /g;
3390
3391#print "linenr<$linenr> <$stat>\n";
3392 # If this statement has no statement boundaries within
3393 # it there is no point in retrying a statement scan
3394 # until we hit end of it.
3395 my $frag = $stat; $frag =~ s/;+\s*$//;
3396 if ($frag !~ /(?:{|;)/) {
3397#print "skip<$line_nr_next>\n";
3398 $suppress_statement = $line_nr_next;
3399 }
3400
3401 # Find the real next line.
3402 $realline_next = $line_nr_next;
3403 if (defined $realline_next &&
3404 (!defined $lines[$realline_next - 1] ||
3405 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
3406 $realline_next++;
3407 }
3408
3409 my $s = $stat;
3410 $s =~ s/{.*$//s;
3411
3412 # Ignore goto labels.
3413 if ($s =~ /$Ident:\*$/s) {
3414
3415 # Ignore functions being called
3416 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3417
3418 } elsif ($s =~ /^.\s*else\b/s) {
3419
3420 # declarations always start with types
3421 } 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) {
3422 my $type = $1;
3423 $type =~ s/\s+/ /g;
3424 possible($type, "A:" . $s);
3425
3426 # definitions in global scope can only start with types
3427 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3428 possible($1, "B:" . $s);
3429 }
3430
3431 # any (foo ... *) is a pointer cast, and foo is a type
3432 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3433 possible($1, "C:" . $s);
3434 }
3435
3436 # Check for any sort of function declaration.
3437 # int foo(something bar, other baz);
3438 # void (*store_gdt)(x86_descr_ptr *);
3439 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
3440 my ($name_len) = length($1);
3441
3442 my $ctx = $s;
3443 substr($ctx, 0, $name_len + 1, '');
3444 $ctx =~ s/\)[^\)]*$//;
3445
3446 for my $arg (split(/\s*,\s*/, $ctx)) {
3447 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
3448
3449 possible($1, "D:" . $s);
3450 }
3451 }
3452 }
3453
3454 }
3455
3456#
3457# Checks which may be anchored in the context.
3458#
3459
3460# Check for switch () and associated case and default
3461# statements should be at the same indent.
3462 if ($line=~/\bswitch\s*\(.*\)/) {
3463 my $err = '';
3464 my $sep = '';
3465 my @ctx = ctx_block_outer($linenr, $realcnt);
3466 shift(@ctx);
3467 for my $ctx (@ctx) {
3468 my ($clen, $cindent) = line_stats($ctx);
3469 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
3470 $indent != $cindent) {
3471 $err .= "$sep$ctx\n";
3472 $sep = '';
3473 } else {
3474 $sep = "[...]\n";
3475 }
3476 }
3477 if ($err ne '') {
3478 ERROR("SWITCH_CASE_INDENT_LEVEL",
3479 "switch and case should be at the same indent\n$hereline$err");
3480 }
3481 }
3482
3483# if/while/etc brace do not go on next line, unless defining a do while loop,
3484# or if that brace on the next line is for something else
3485 if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
3486 my $pre_ctx = "$1$2";
3487
3488 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
3489
3490 if ($line =~ /^\+\t{6,}/) {
3491 WARN("DEEP_INDENTATION",
3492 "Too many leading tabs - consider code refactoring\n" . $herecurr);
3493 }
3494
3495 my $ctx_cnt = $realcnt - $#ctx - 1;
3496 my $ctx = join("\n", @ctx);
3497
3498 my $ctx_ln = $linenr;
3499 my $ctx_skip = $realcnt;
3500
3501 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3502 defined $lines[$ctx_ln - 1] &&
3503 $lines[$ctx_ln - 1] =~ /^-/)) {
3504 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3505 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3506 $ctx_ln++;
3507 }
3508
3509 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
3510 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3511
3512 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3513 ERROR("OPEN_BRACE",
3514 "that open brace { should be on the previous line\n" .
3515 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
3516 }
3517 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3518 $ctx =~ /\)\s*\;\s*$/ &&
3519 defined $lines[$ctx_ln - 1])
3520 {
3521 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
3522 if ($nindent > $indent) {
3523 WARN("TRAILING_SEMICOLON",
3524 "trailing semicolon indicates no statements, indent implies otherwise\n" .
3525 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
3526 }
3527 }
3528 }
3529
3530# Check relative indent for conditionals and blocks.
Martin Roth387dec82017-09-17 19:20:46 -06003531 if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003532 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3533 ctx_statement_block($linenr, $realcnt, 0)
3534 if (!defined $stat);
3535 my ($s, $c) = ($stat, $cond);
3536
3537 substr($s, 0, length($c), '');
3538
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003539 # remove inline comments
3540 $s =~ s/$;/ /g;
3541 $c =~ s/$;/ /g;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003542
3543 # Find out how long the conditional actually is.
3544 my @newlines = ($c =~ /\n/gs);
3545 my $cond_lines = 1 + $#newlines;
3546
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003547 # Make sure we remove the line prefixes as we have
3548 # none on the first line, and are going to readd them
3549 # where necessary.
3550 $s =~ s/\n./\n/gs;
3551 while ($s =~ /\n\s+\\\n/) {
3552 $cond_lines += $s =~ s/\n\s+\\\n/\n/g;
3553 }
3554
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003555 # We want to check the first line inside the block
3556 # starting at the end of the conditional, so remove:
3557 # 1) any blank line termination
3558 # 2) any opening brace { on end of the line
3559 # 3) any do (...) {
3560 my $continuation = 0;
3561 my $check = 0;
3562 $s =~ s/^.*\bdo\b//;
3563 $s =~ s/^\s*{//;
3564 if ($s =~ s/^\s*\\//) {
3565 $continuation = 1;
3566 }
3567 if ($s =~ s/^\s*?\n//) {
3568 $check = 1;
3569 $cond_lines++;
3570 }
3571
3572 # Also ignore a loop construct at the end of a
3573 # preprocessor statement.
3574 if (($prevline =~ /^.\s*#\s*define\s/ ||
3575 $prevline =~ /\\\s*$/) && $continuation == 0) {
3576 $check = 0;
3577 }
3578
3579 my $cond_ptr = -1;
3580 $continuation = 0;
3581 while ($cond_ptr != $cond_lines) {
3582 $cond_ptr = $cond_lines;
3583
3584 # If we see an #else/#elif then the code
3585 # is not linear.
3586 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3587 $check = 0;
3588 }
3589
3590 # Ignore:
3591 # 1) blank lines, they should be at 0,
3592 # 2) preprocessor lines, and
3593 # 3) labels.
3594 if ($continuation ||
3595 $s =~ /^\s*?\n/ ||
3596 $s =~ /^\s*#\s*?/ ||
3597 $s =~ /^\s*$Ident\s*:/) {
3598 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
3599 if ($s =~ s/^.*?\n//) {
3600 $cond_lines++;
3601 }
3602 }
3603 }
3604
3605 my (undef, $sindent) = line_stats("+" . $s);
3606 my $stat_real = raw_line($linenr, $cond_lines);
3607
3608 # Check if either of these lines are modified, else
3609 # this is not this patch's fault.
3610 if (!defined($stat_real) ||
3611 $stat !~ /^\+/ && $stat_real !~ /^\+/) {
3612 $check = 0;
3613 }
3614 if (defined($stat_real) && $cond_lines > 1) {
3615 $stat_real = "[...]\n$stat_real";
3616 }
3617
3618 #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";
3619
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003620 if ($check && $s ne '' &&
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01003621 (($sindent % $tabsize) != 0 ||
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003622 ($sindent < $indent) ||
Martin Roth387dec82017-09-17 19:20:46 -06003623 ($sindent == $indent &&
3624 ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
Elyes HAOUAS96771bf2022-01-29 07:28:45 +01003625 ($sindent > $indent + $tabsize))) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003626 WARN("SUSPECT_CODE_INDENT",
3627 "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
3628 }
Julius Werner218906d2021-03-25 21:12:49 -07003629
3630# Also check if the next statement after the previous condition has the same indent
3631 my ($stat_next, undef, $line_nr_next_next) =
3632 ctx_statement_block($line_nr_next, $remain_next, $off_next);
3633 my $s_next = $stat_next;
3634
3635 # Remove line prefixes
3636 $s_next =~ s/\n./\n/g;
3637
3638 # Remove any comments
3639 $s_next =~ s/$;//g;
3640
3641 # Remove any leading labels
3642 $s_next =~ s/\n( ?$Ident:)/"\n" . " " x length($1)/eg;
3643
3644 # Skip this check for in case next statement starts with 'else'
3645 if ($s_next !~ /\belse\b/) {
3646
3647 # Remove while that belongs to a do {} while
3648 if ($stat =~ /\bdo\b/) {
3649 $s_next =~ s/^.*\bwhile\b\s*($balanced_parens)\s*?//;
3650 }
3651
3652 # Remove blank lines
3653 $s_next =~ s/\s*\\?\n//g;
3654
3655 # Get the real next lines
3656 my $next_nof_lines = $line_nr_next_next - $line_nr_next;
3657 my $stat_next_real = raw_line($line_nr_next, $next_nof_lines);
3658 if (!defined($stat_next_real)) {
3659 $stat_next_real = "";
3660 } elsif ($next_nof_lines > 1) {
3661 $stat_next_real = "[...]\n$stat_next_real";
3662 }
3663 my (undef, $nindent) = line_stats('+' . $s_next);
3664
3665 #print "stat_next<$stat_next> stat<$stat> indent<$indent> nindent<$nindent> s_next<$s_next> stat_next_real<$stat_next_real>\n";
3666
3667 if ($nindent > $indent) {
3668 WARN("SUSPICIOUS_CODE_INDENT",
3669 "suspicious code indentation after conditional statements\n" .
3670 $herecurr . "$stat_real\n$stat_next_real\n");
3671 }
3672 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003673 }
3674
3675 # Track the 'values' across context and added lines.
3676 my $opline = $line; $opline =~ s/^./ /;
3677 my ($curr_values, $curr_vars) =
3678 annotate_values($opline . "\n", $prev_values);
3679 $curr_values = $prev_values . $curr_values;
3680 if ($dbg_values) {
3681 my $outline = $opline; $outline =~ s/\t/ /g;
3682 print "$linenr > .$outline\n";
3683 print "$linenr > $curr_values\n";
3684 print "$linenr > $curr_vars\n";
3685 }
3686 $prev_values = substr($curr_values, -1);
3687
3688#ignore lines not being added
3689 next if ($line =~ /^[^\+]/);
3690
Martin Rothedd591d2017-03-14 10:16:29 -06003691# check for dereferences that span multiple lines
3692 if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
3693 $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
3694 $prevline =~ /($Lval\s*(?:\.|->))\s*$/;
3695 my $ref = $1;
3696 $line =~ /^.\s*($Lval)/;
3697 $ref .= $1;
3698 $ref =~ s/\s//g;
3699 WARN("MULTILINE_DEREFERENCE",
3700 "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
3701 }
3702
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003703# check for declarations of signed or unsigned without int
Martin Rothedd591d2017-03-14 10:16:29 -06003704 while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003705 my $type = $1;
3706 my $var = $2;
3707 $var = "" if (!defined $var);
3708 if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3709 my $sign = $1;
3710 my $pointer = $2;
3711
3712 $pointer = "" if (!defined $pointer);
3713
3714 if (WARN("UNSPECIFIED_INT",
3715 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3716 $fix) {
3717 my $decl = trim($sign) . " int ";
3718 my $comp_pointer = $pointer;
3719 $comp_pointer =~ s/\s//g;
3720 $decl .= $comp_pointer;
3721 $decl = rtrim($decl) if ($var eq "");
3722 $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3723 }
3724 }
3725 }
3726
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003727# TEST: allow direct testing of the type matcher.
3728 if ($dbg_type) {
3729 if ($line =~ /^.\s*$Declare\s*$/) {
3730 ERROR("TEST_TYPE",
3731 "TEST: is type\n" . $herecurr);
3732 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3733 ERROR("TEST_NOT_TYPE",
3734 "TEST: is not type ($1 is)\n". $herecurr);
3735 }
3736 next;
3737 }
3738# TEST: allow direct testing of the attribute matcher.
3739 if ($dbg_attr) {
3740 if ($line =~ /^.\s*$Modifier\s*$/) {
3741 ERROR("TEST_ATTR",
3742 "TEST: is attr\n" . $herecurr);
3743 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3744 ERROR("TEST_NOT_ATTR",
3745 "TEST: is not attr ($1 is)\n". $herecurr);
3746 }
3747 next;
3748 }
3749
3750# check for initialisation to aggregates open brace on the next line
3751 if ($line =~ /^.\s*{/ &&
3752 $prevline =~ /(?:^|[^=])=\s*$/) {
3753 if (ERROR("OPEN_BRACE",
3754 "that open brace { should be on the previous line\n" . $hereprev) &&
3755 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3756 fix_delete_line($fixlinenr - 1, $prevrawline);
3757 fix_delete_line($fixlinenr, $rawline);
3758 my $fixedline = $prevrawline;
3759 $fixedline =~ s/\s*=\s*$/ = {/;
3760 fix_insert_line($fixlinenr, $fixedline);
3761 $fixedline = $line;
Martin Roth387dec82017-09-17 19:20:46 -06003762 $fixedline =~ s/^(.\s*)\{\s*/$1/;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003763 fix_insert_line($fixlinenr, $fixedline);
3764 }
3765 }
3766
3767#
3768# Checks which are anchored on the added line.
3769#
3770
3771# check for malformed paths in #include statements (uses RAW line)
3772 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3773 my $path = $1;
3774 if ($path =~ m{//}) {
3775 ERROR("MALFORMED_INCLUDE",
3776 "malformed #include filename\n" . $herecurr);
3777 }
3778 if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3779 ERROR("UAPI_INCLUDE",
3780 "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3781 }
3782 }
3783
3784# no C99 // comments
3785 if ($line =~ m{//}) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003786 if (ERROR("C99_COMMENTS",
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003787 "do not use C99 // comments\n" . $herecurr) &&
3788 $fix) {
3789 my $line = $fixed[$fixlinenr];
3790 if ($line =~ /\/\/(.*)$/) {
3791 my $comment = trim($1);
3792 $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
3793 }
3794 }
3795 }
3796 # Remove C99 comments.
3797 $line =~ s@//.*@@;
3798 $opline =~ s@//.*@@;
3799
3800# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
3801# the whole statement.
3802#print "APW <$lines[$realline_next - 1]>\n";
3803 if (defined $realline_next &&
3804 exists $lines[$realline_next - 1] &&
3805 !defined $suppress_export{$realline_next} &&
3806 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
3807 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
3808 # Handle definitions which produce identifiers with
3809 # a prefix:
3810 # XXX(foo);
3811 # EXPORT_SYMBOL(something_foo);
3812 my $name = $1;
3813 if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
3814 $name =~ /^${Ident}_$2/) {
3815#print "FOO C name<$name>\n";
3816 $suppress_export{$realline_next} = 1;
3817
3818 } elsif ($stat !~ /(?:
3819 \n.}\s*$|
3820 ^.DEFINE_$Ident\(\Q$name\E\)|
3821 ^.DECLARE_$Ident\(\Q$name\E\)|
3822 ^.LIST_HEAD\(\Q$name\E\)|
3823 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
3824 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
3825 )/x) {
3826#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
3827 $suppress_export{$realline_next} = 2;
3828 } else {
3829 $suppress_export{$realline_next} = 1;
3830 }
3831 }
3832 if (!defined $suppress_export{$linenr} &&
3833 $prevline =~ /^.\s*$/ &&
3834 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
3835 $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
3836#print "FOO B <$lines[$linenr - 1]>\n";
3837 $suppress_export{$linenr} = 2;
3838 }
3839 if (defined $suppress_export{$linenr} &&
3840 $suppress_export{$linenr} == 2) {
3841 WARN("EXPORT_SYMBOL",
3842 "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
3843 }
3844
3845# check for global initialisers.
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003846 if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003847 if (ERROR("GLOBAL_INITIALISERS",
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003848 "do not initialise globals to $1\n" . $herecurr) &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003849 $fix) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003850 $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003851 }
3852 }
3853# check for static initialisers.
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003854 if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003855 if (ERROR("INITIALISED_STATIC",
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003856 "do not initialise statics to $1\n" .
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003857 $herecurr) &&
3858 $fix) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003859 $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003860 }
3861 }
3862
3863# check for misordered declarations of char/short/int/long with signed/unsigned
3864 while ($sline =~ m{(\b$TypeMisordered\b)}g) {
3865 my $tmp = trim($1);
3866 WARN("MISORDERED_TYPE",
3867 "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
3868 }
3869
3870# check for static const char * arrays.
3871 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3872 WARN("STATIC_CONST_CHAR_ARRAY",
3873 "static const char * array should probably be static const char * const\n" .
3874 $herecurr);
3875 }
3876
3877# check for static char foo[] = "bar" declarations.
3878 if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
3879 WARN("STATIC_CONST_CHAR_ARRAY",
3880 "static char array declaration should probably be static const char\n" .
3881 $herecurr);
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01003882 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003883
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003884# check for const <foo> const where <foo> is not a pointer or array type
3885 if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
3886 my $found = $1;
3887 if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
3888 WARN("CONST_CONST",
3889 "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
3890 } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
3891 WARN("CONST_CONST",
3892 "'const $found const' should probably be 'const $found'\n" . $herecurr);
3893 }
3894 }
3895
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003896# check for non-global char *foo[] = {"bar", ...} declarations.
3897 if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
3898 WARN("STATIC_CONST_CHAR_ARRAY",
3899 "char * array declaration might be better as static const\n" .
3900 $herecurr);
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01003901 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003902
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003903# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
3904 if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
3905 my $array = $1;
3906 if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
3907 my $array_div = $1;
3908 if (WARN("ARRAY_SIZE",
3909 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
3910 $fix) {
3911 $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
3912 }
3913 }
3914 }
3915
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003916# check for function declarations without arguments like "int foo()"
3917 if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
3918 if (ERROR("FUNCTION_WITHOUT_ARGS",
3919 "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
3920 $fix) {
3921 $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
3922 }
3923 }
3924
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003925# check for new typedefs, only function parameters and sparse annotations
3926# make sense.
3927 if ($line =~ /\btypedef\s/ &&
3928 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
3929 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
3930 $line !~ /\b$typeTypedefs\b/ &&
Martin Rothedd591d2017-03-14 10:16:29 -06003931 $line !~ /\b__bitwise\b/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003932 WARN("NEW_TYPEDEFS",
3933 "do not add new typedefs\n" . $herecurr);
3934 }
3935
3936# * goes on variable not on type
3937 # (char*[ const])
3938 while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
3939 #print "AA<$1>\n";
3940 my ($ident, $from, $to) = ($1, $2, $2);
3941
3942 # Should start with a space.
3943 $to =~ s/^(\S)/ $1/;
3944 # Should not end with a space.
3945 $to =~ s/\s+$//;
3946 # '*'s should not have spaces between.
3947 while ($to =~ s/\*\s+\*/\*\*/) {
3948 }
3949
3950## print "1: from<$from> to<$to> ident<$ident>\n";
3951 if ($from ne $to) {
3952 if (ERROR("POINTER_LOCATION",
3953 "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
3954 $fix) {
3955 my $sub_from = $ident;
3956 my $sub_to = $ident;
3957 $sub_to =~ s/\Q$from\E/$to/;
3958 $fixed[$fixlinenr] =~
3959 s@\Q$sub_from\E@$sub_to@;
3960 }
3961 }
3962 }
3963 while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
3964 #print "BB<$1>\n";
3965 my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
3966
3967 # Should start with a space.
3968 $to =~ s/^(\S)/ $1/;
3969 # Should not end with a space.
3970 $to =~ s/\s+$//;
3971 # '*'s should not have spaces between.
3972 while ($to =~ s/\*\s+\*/\*\*/) {
3973 }
3974 # Modifiers should have spaces.
3975 $to =~ s/(\b$Modifier$)/$1 /;
3976
3977## print "2: from<$from> to<$to> ident<$ident>\n";
3978 if ($from ne $to && $ident !~ /^$Modifier$/) {
3979 if (ERROR("POINTER_LOCATION",
3980 "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
3981 $fix) {
3982
3983 my $sub_from = $match;
3984 my $sub_to = $match;
3985 $sub_to =~ s/\Q$from\E/$to/;
3986 $fixed[$fixlinenr] =~
3987 s@\Q$sub_from\E@$sub_to@;
3988 }
3989 }
3990 }
3991
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003992# avoid BUG() or BUG_ON()
3993 if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
Martin Roth387dec82017-09-17 19:20:46 -06003994 my $msg_level = \&WARN;
3995 $msg_level = \&CHK if ($file);
3996 &{$msg_level}("AVOID_BUG",
3997 "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07003998 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01003999
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004000# avoid LINUX_VERSION_CODE
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004001 if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4002 WARN("LINUX_VERSION_CODE",
4003 "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
4004 }
4005
4006# check for uses of printk_ratelimit
4007 if ($line =~ /\bprintk_ratelimit\s*\(/) {
4008 WARN("PRINTK_RATELIMITED",
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004009 "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004010 }
4011
Martin Roth60915b32018-08-10 21:04:05 -06004012# printk should use KERN_* levels
4013 if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4014 WARN("PRINTK_WITHOUT_KERN_LEVEL",
4015 "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004016 }
4017
4018 if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
4019 my $orig = $1;
4020 my $level = lc($orig);
4021 $level = "warn" if ($level eq "warning");
4022 my $level2 = $level;
4023 $level2 = "dbg" if ($level eq "debug");
4024 WARN("PREFER_PR_LEVEL",
4025 "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
4026 }
4027
4028 if ($line =~ /\bpr_warning\s*\(/) {
4029 if (WARN("PREFER_PR_LEVEL",
4030 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
4031 $fix) {
4032 $fixed[$fixlinenr] =~
4033 s/\bpr_warning\b/pr_warn/;
4034 }
4035 }
4036
4037 if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4038 my $orig = $1;
4039 my $level = lc($orig);
4040 $level = "warn" if ($level eq "warning");
4041 $level = "dbg" if ($level eq "debug");
4042 WARN("PREFER_DEV_LEVEL",
4043 "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4044 }
4045
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004046# ENOSYS means "bad syscall nr" and nothing else. This will have a small
4047# number of false positives, but assembly files are not checked, so at
4048# least the arch entry code will not trigger this warning.
4049 if ($line =~ /\bENOSYS\b/) {
4050 WARN("ENOSYS",
4051 "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
4052 }
4053
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004054# function brace can't be on same line, except for #defines of do while,
4055# or if closed on same line
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01004056 if ($perl_version_ok &&
Martin Roth60915b32018-08-10 21:04:05 -06004057 $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
4058 $sline !~ /\#\s*define\b.*do\s*\{/ &&
4059 $sline !~ /}/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004060 if (ERROR("OPEN_BRACE",
Martin Roth60915b32018-08-10 21:04:05 -06004061 "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004062 $fix) {
4063 fix_delete_line($fixlinenr, $rawline);
4064 my $fixed_line = $rawline;
4065 $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
4066 my $line1 = $1;
4067 my $line2 = $2;
4068 fix_insert_line($fixlinenr, ltrim($line1));
4069 fix_insert_line($fixlinenr, "\+{");
4070 if ($line2 !~ /^\s*$/) {
4071 fix_insert_line($fixlinenr, "\+\t" . trim($line2));
4072 }
4073 }
4074 }
4075
4076# open braces for enum, union and struct go on the same line.
4077 if ($line =~ /^.\s*{/ &&
4078 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
4079 if (ERROR("OPEN_BRACE",
4080 "open brace '{' following $1 go on the same line\n" . $hereprev) &&
4081 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4082 fix_delete_line($fixlinenr - 1, $prevrawline);
4083 fix_delete_line($fixlinenr, $rawline);
4084 my $fixedline = rtrim($prevrawline) . " {";
4085 fix_insert_line($fixlinenr, $fixedline);
4086 $fixedline = $rawline;
Martin Roth387dec82017-09-17 19:20:46 -06004087 $fixedline =~ s/^(.\s*)\{\s*/$1\t/;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004088 if ($fixedline !~ /^\+\s*$/) {
4089 fix_insert_line($fixlinenr, $fixedline);
4090 }
4091 }
4092 }
4093
4094# missing space after union, struct or enum definition
4095 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
4096 if (WARN("SPACING",
4097 "missing space after $1 definition\n" . $herecurr) &&
4098 $fix) {
4099 $fixed[$fixlinenr] =~
4100 s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
4101 }
4102 }
4103
4104# Function pointer declarations
4105# check spacing between type, funcptr, and args
4106# canonical declaration is "type (*funcptr)(args...)"
4107 if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
4108 my $declare = $1;
4109 my $pre_pointer_space = $2;
4110 my $post_pointer_space = $3;
4111 my $funcname = $4;
4112 my $post_funcname_space = $5;
4113 my $pre_args_space = $6;
4114
4115# the $Declare variable will capture all spaces after the type
4116# so check it for a missing trailing missing space but pointer return types
4117# don't need a space so don't warn for those.
4118 my $post_declare_space = "";
4119 if ($declare =~ /(\s+)$/) {
4120 $post_declare_space = $1;
4121 $declare = rtrim($declare);
4122 }
4123 if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
4124 WARN("SPACING",
4125 "missing space after return type\n" . $herecurr);
4126 $post_declare_space = " ";
4127 }
4128
4129# unnecessary space "type (*funcptr)(args...)"
4130# This test is not currently implemented because these declarations are
4131# equivalent to
4132# int foo(int bar, ...)
4133# and this is form shouldn't/doesn't generate a checkpatch warning.
4134#
4135# elsif ($declare =~ /\s{2,}$/) {
4136# WARN("SPACING",
4137# "Multiple spaces after return type\n" . $herecurr);
4138# }
4139
4140# unnecessary space "type ( *funcptr)(args...)"
4141 if (defined $pre_pointer_space &&
4142 $pre_pointer_space =~ /^\s/) {
4143 WARN("SPACING",
4144 "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
4145 }
4146
4147# unnecessary space "type (* funcptr)(args...)"
4148 if (defined $post_pointer_space &&
4149 $post_pointer_space =~ /^\s/) {
4150 WARN("SPACING",
4151 "Unnecessary space before function pointer name\n" . $herecurr);
4152 }
4153
4154# unnecessary space "type (*funcptr )(args...)"
4155 if (defined $post_funcname_space &&
4156 $post_funcname_space =~ /^\s/) {
4157 WARN("SPACING",
4158 "Unnecessary space after function pointer name\n" . $herecurr);
4159 }
4160
4161# unnecessary space "type (*funcptr) (args...)"
4162 if (defined $pre_args_space &&
4163 $pre_args_space =~ /^\s/) {
4164 WARN("SPACING",
4165 "Unnecessary space before function pointer arguments\n" . $herecurr);
4166 }
4167
4168 if (show_type("SPACING") && $fix) {
4169 $fixed[$fixlinenr] =~
4170 s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
4171 }
4172 }
4173
4174# check for spacing round square brackets; allowed:
4175# 1. with a type on the left -- int [] a;
4176# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4177# 3. inside a curly brace -- = { [0...10] = 5 }
Martin Rothedd591d2017-03-14 10:16:29 -06004178# 4. in an extended asm instruction -- : [r0]"r"(r0) (coreboot)
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004179 while ($line =~ /(.*?\s)\[/g) {
4180 my ($where, $prefix) = ($-[1], $1);
4181 if ($prefix !~ /$Type\s+$/ &&
4182 ($where != 0 || $prefix !~ /^.\s+$/) &&
Martin Rothedd591d2017-03-14 10:16:29 -06004183 $prefix !~ /[{,:]\s+$/) { #coreboot
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004184 if (ERROR("BRACKET_SPACE",
4185 "space prohibited before open square bracket '['\n" . $herecurr) &&
4186 $fix) {
4187 $fixed[$fixlinenr] =~
4188 s/^(\+.*?)\s+\[/$1\[/;
4189 }
4190 }
4191 }
4192
4193# check for spaces between functions and their parentheses.
4194 while ($line =~ /($Ident)\s+\(/g) {
4195 my $name = $1;
4196 my $ctx_before = substr($line, 0, $-[1]);
4197 my $ctx = "$ctx_before$name";
4198
4199 # Ignore those directives where spaces _are_ permitted.
4200 if ($name =~ /^(?:
4201 if|for|while|switch|return|case|
4202 volatile|__volatile__|
4203 __attribute__|format|__extension__|
4204 asm|__asm__)$/x)
4205 {
4206 # cpp #define statements have non-optional spaces, ie
4207 # if there is a space between the name and the open
4208 # parenthesis it is simply not a parameter group.
4209 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4210
4211 # cpp #elif statement condition may start with a (
4212 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4213
4214 # If this whole things ends with a type its most
4215 # likely a typedef for a function.
4216 } elsif ($ctx =~ /$Type$/) {
4217
4218 } else {
4219 if (WARN("SPACING",
4220 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
4221 $fix) {
4222 $fixed[$fixlinenr] =~
4223 s/\b$name\s+\(/$name\(/;
4224 }
4225 }
4226 }
4227
4228# Check operator spacing.
4229 if (!($line=~/\#\s*include/)) {
4230 my $fixed_line = "";
4231 my $line_fixed = 0;
4232
4233 my $ops = qr{
4234 <<=|>>=|<=|>=|==|!=|
4235 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
4236 =>|->|<<|>>|<|>|=|!|~|
4237 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
4238 \?:|\?|:
4239 }x;
4240 my @elements = split(/($ops|;)/, $opline);
4241
4242## print("element count: <" . $#elements . ">\n");
4243## foreach my $el (@elements) {
4244## print("el: <$el>\n");
4245## }
4246
4247 my @fix_elements = ();
4248 my $off = 0;
4249
4250 foreach my $el (@elements) {
4251 push(@fix_elements, substr($rawline, $off, length($el)));
4252 $off += length($el);
4253 }
4254
4255 $off = 0;
4256
4257 my $blank = copy_spacing($opline);
4258 my $last_after = -1;
4259
4260 for (my $n = 0; $n < $#elements; $n += 2) {
4261
4262 my $good = $fix_elements[$n] . $fix_elements[$n + 1];
4263
4264## print("n: <$n> good: <$good>\n");
4265
4266 $off += length($elements[$n]);
4267
4268 # Pick up the preceding and succeeding characters.
4269 my $ca = substr($opline, 0, $off);
4270 my $cc = '';
4271 if (length($opline) >= ($off + length($elements[$n + 1]))) {
4272 $cc = substr($opline, $off + length($elements[$n + 1]));
4273 }
4274 my $cb = "$ca$;$cc";
4275
4276 my $a = '';
4277 $a = 'V' if ($elements[$n] ne '');
4278 $a = 'W' if ($elements[$n] =~ /\s$/);
4279 $a = 'C' if ($elements[$n] =~ /$;$/);
4280 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
4281 $a = 'O' if ($elements[$n] eq '');
4282 $a = 'E' if ($ca =~ /^\s*$/);
4283
4284 my $op = $elements[$n + 1];
4285
4286 my $c = '';
4287 if (defined $elements[$n + 2]) {
4288 $c = 'V' if ($elements[$n + 2] ne '');
4289 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
4290 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
4291 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
4292 $c = 'O' if ($elements[$n + 2] eq '');
4293 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
4294 } else {
4295 $c = 'E';
4296 }
4297
4298 my $ctx = "${a}x${c}";
4299
4300 my $at = "(ctx:$ctx)";
4301
4302 my $ptr = substr($blank, 0, $off) . "^";
4303 my $hereptr = "$hereline$ptr\n";
4304
4305 # Pull out the value of this operator.
4306 my $op_type = substr($curr_values, $off + 1, 1);
4307
4308 # Get the full operator variant.
4309 my $opv = $op . substr($curr_vars, $off, 1);
4310
4311 # Ignore operators passed as parameters.
4312 if ($op_type ne 'V' &&
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004313 $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004314
4315# # Ignore comments
4316# } elsif ($op =~ /^$;+$/) {
4317
4318 # ; should have either the end of line or a space or \ after it
4319 } elsif ($op eq ';') {
4320 if ($ctx !~ /.x[WEBC]/ &&
4321 $cc !~ /^\\/ && $cc !~ /^;/) {
4322 if (ERROR("SPACING",
4323 "space required after that '$op' $at\n" . $hereptr)) {
4324 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
4325 $line_fixed = 1;
4326 }
4327 }
4328
4329 # // is a comment
4330 } elsif ($op eq '//') {
4331
4332 # : when part of a bitfield
4333 } elsif ($opv eq ':B') {
4334 # skip the bitfield test for now
4335
4336 # No spaces for:
4337 # ->
4338 } elsif ($op eq '->') {
4339 if ($ctx =~ /Wx.|.xW/) {
4340 if (ERROR("SPACING",
4341 "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4342 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4343 if (defined $fix_elements[$n + 2]) {
4344 $fix_elements[$n + 2] =~ s/^\s+//;
4345 }
4346 $line_fixed = 1;
4347 }
4348 }
4349
4350 # , must not have a space before and must have a space on the right.
4351 } elsif ($op eq ',') {
4352 my $rtrim_before = 0;
4353 my $space_after = 0;
4354 if ($ctx =~ /Wx./) {
4355 if (ERROR("SPACING",
4356 "space prohibited before that '$op' $at\n" . $hereptr)) {
4357 $line_fixed = 1;
4358 $rtrim_before = 1;
4359 }
4360 }
4361 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
4362 if (ERROR("SPACING",
4363 "space required after that '$op' $at\n" . $hereptr)) {
4364 $line_fixed = 1;
4365 $last_after = $n;
4366 $space_after = 1;
4367 }
4368 }
4369 if ($rtrim_before || $space_after) {
4370 if ($rtrim_before) {
4371 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4372 } else {
4373 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
4374 }
4375 if ($space_after) {
4376 $good .= " ";
4377 }
4378 }
4379
4380 # '*' as part of a type definition -- reported already.
4381 } elsif ($opv eq '*_') {
4382 #warn "'*' is part of type\n";
4383
4384 # unary operators should have a space before and
4385 # none after. May be left adjacent to another
4386 # unary operator, or a cast
4387 } elsif ($op eq '!' || $op eq '~' ||
4388 $opv eq '*U' || $opv eq '-U' ||
4389 $opv eq '&U' || $opv eq '&&U') {
4390 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
4391 if (ERROR("SPACING",
4392 "space required before that '$op' $at\n" . $hereptr)) {
4393 if ($n != $last_after + 2) {
4394 $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
4395 $line_fixed = 1;
4396 }
4397 }
4398 }
4399 if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4400 # A unary '*' may be const
4401
4402 } elsif ($ctx =~ /.xW/) {
4403 if (ERROR("SPACING",
4404 "space prohibited after that '$op' $at\n" . $hereptr)) {
4405 $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
4406 if (defined $fix_elements[$n + 2]) {
4407 $fix_elements[$n + 2] =~ s/^\s+//;
4408 }
4409 $line_fixed = 1;
4410 }
4411 }
4412
4413 # unary ++ and unary -- are allowed no space on one side.
4414 } elsif ($op eq '++' or $op eq '--') {
4415 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
4416 if (ERROR("SPACING",
4417 "space required one side of that '$op' $at\n" . $hereptr)) {
4418 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
4419 $line_fixed = 1;
4420 }
4421 }
4422 if ($ctx =~ /Wx[BE]/ ||
4423 ($ctx =~ /Wx./ && $cc =~ /^;/)) {
4424 if (ERROR("SPACING",
4425 "space prohibited before that '$op' $at\n" . $hereptr)) {
4426 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4427 $line_fixed = 1;
4428 }
4429 }
4430 if ($ctx =~ /ExW/) {
4431 if (ERROR("SPACING",
4432 "space prohibited after that '$op' $at\n" . $hereptr)) {
4433 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
4434 if (defined $fix_elements[$n + 2]) {
4435 $fix_elements[$n + 2] =~ s/^\s+//;
4436 }
4437 $line_fixed = 1;
4438 }
4439 }
4440
4441 # << and >> may either have or not have spaces both sides
4442 } elsif ($op eq '<<' or $op eq '>>' or
4443 $op eq '&' or $op eq '^' or $op eq '|' or
4444 $op eq '+' or $op eq '-' or
4445 $op eq '*' or $op eq '/' or
4446 $op eq '%')
4447 {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004448 if ($check) {
4449 if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4450 if (CHK("SPACING",
4451 "spaces preferred around that '$op' $at\n" . $hereptr)) {
4452 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4453 $fix_elements[$n + 2] =~ s/^\s+//;
4454 $line_fixed = 1;
4455 }
4456 } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4457 if (CHK("SPACING",
4458 "space preferred before that '$op' $at\n" . $hereptr)) {
4459 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4460 $line_fixed = 1;
4461 }
4462 }
4463 } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004464 if (ERROR("SPACING",
4465 "need consistent spacing around '$op' $at\n" . $hereptr)) {
4466 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4467 if (defined $fix_elements[$n + 2]) {
4468 $fix_elements[$n + 2] =~ s/^\s+//;
4469 }
4470 $line_fixed = 1;
4471 }
4472 }
4473
4474 # A colon needs no spaces before when it is
4475 # terminating a case value or a label.
4476 } elsif ($opv eq ':C' || $opv eq ':L') {
4477 if ($ctx =~ /Wx./) {
4478 if (ERROR("SPACING",
4479 "space prohibited before that '$op' $at\n" . $hereptr)) {
4480 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4481 $line_fixed = 1;
4482 }
4483 }
4484
4485 # All the others need spaces both sides.
4486 } elsif ($ctx !~ /[EWC]x[CWE]/) {
4487 my $ok = 0;
4488
4489 # Ignore email addresses <foo@bar>
4490 if (($op eq '<' &&
4491 $cc =~ /^\S+\@\S+>/) ||
4492 ($op eq '>' &&
4493 $ca =~ /<\S+\@\S+$/))
4494 {
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01004495 $ok = 1;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004496 }
4497
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004498 # for asm volatile statements
4499 # ignore a colon with another
4500 # colon immediately before or after
4501 if (($op eq ':') &&
4502 ($ca =~ /:$/ || $cc =~ /^:/)) {
4503 $ok = 1;
4504 }
4505
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004506 # messages are ERROR, but ?: are CHK
4507 if ($ok == 0) {
Martin Roth387dec82017-09-17 19:20:46 -06004508 my $msg_level = \&ERROR;
4509 $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004510
Martin Roth387dec82017-09-17 19:20:46 -06004511 if (&{$msg_level}("SPACING",
4512 "spaces required around that '$op' $at\n" . $hereptr)) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004513 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4514 if (defined $fix_elements[$n + 2]) {
4515 $fix_elements[$n + 2] =~ s/^\s+//;
4516 }
4517 $line_fixed = 1;
4518 }
4519 }
4520 }
4521 $off += length($elements[$n + 1]);
4522
4523## print("n: <$n> GOOD: <$good>\n");
4524
4525 $fixed_line = $fixed_line . $good;
4526 }
4527
4528 if (($#elements % 2) == 0) {
4529 $fixed_line = $fixed_line . $fix_elements[$#elements];
4530 }
4531
4532 if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4533 $fixed[$fixlinenr] = $fixed_line;
4534 }
4535
4536
4537 }
4538
4539# check for whitespace before a non-naked semicolon
4540 if ($line =~ /^\+.*\S\s+;\s*$/) {
4541 if (WARN("SPACING",
4542 "space prohibited before semicolon\n" . $herecurr) &&
4543 $fix) {
4544 1 while $fixed[$fixlinenr] =~
4545 s/^(\+.*\S)\s+;/$1;/;
4546 }
4547 }
4548
4549# check for multiple assignments
4550 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4551 CHK("MULTIPLE_ASSIGNMENTS",
4552 "multiple assignments should be avoided\n" . $herecurr);
4553 }
4554
4555## # check for multiple declarations, allowing for a function declaration
4556## # continuation.
4557## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
4558## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
4559##
4560## # Remove any bracketed sections to ensure we do not
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01004561## # falsely report the parameters of functions.
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004562## my $ln = $line;
4563## while ($ln =~ s/\([^\(\)]*\)//g) {
4564## }
4565## if ($ln =~ /,/) {
4566## WARN("MULTIPLE_DECLARATION",
4567## "declaring multiple variables together should be avoided\n" . $herecurr);
4568## }
4569## }
4570
4571#need space before brace following if, while, etc
Alexander Couzensebef00f2016-04-11 00:52:01 +02004572 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
4573 $line =~ /do\{/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004574 if (ERROR("SPACING",
4575 "space required before the open brace '{'\n" . $herecurr) &&
4576 $fix) {
Martin Roth387dec82017-09-17 19:20:46 -06004577 #coreboot - Open braces must be escaped in regex
4578 $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 \{/;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004579 }
4580 }
4581
4582## # check for blank lines before declarations
4583## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4584## $prevrawline =~ /^.\s*$/) {
4585## WARN("SPACING",
4586## "No blank lines before declarations\n" . $hereprev);
4587## }
4588##
4589
4590# closing brace should have a space following it when it has anything
4591# on the line
4592 if ($line =~ /}(?!(?:,|;|\)))\S/) {
4593 if (ERROR("SPACING",
4594 "space required after that close brace '}'\n" . $herecurr) &&
4595 $fix) {
4596 $fixed[$fixlinenr] =~
4597 s/}((?!(?:,|;|\)))\S)/} $1/;
4598 }
4599 }
4600
4601# check spacing on square brackets
4602 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
4603 if (ERROR("SPACING",
4604 "space prohibited after that open square bracket '['\n" . $herecurr) &&
4605 $fix) {
4606 $fixed[$fixlinenr] =~
4607 s/\[\s+/\[/;
4608 }
4609 }
4610 if ($line =~ /\s\]/) {
4611 if (ERROR("SPACING",
4612 "space prohibited before that close square bracket ']'\n" . $herecurr) &&
4613 $fix) {
4614 $fixed[$fixlinenr] =~
4615 s/\s+\]/\]/;
4616 }
4617 }
4618
4619# check spacing on parentheses
4620 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
4621 $line !~ /for\s*\(\s+;/) {
4622 if (ERROR("SPACING",
4623 "space prohibited after that open parenthesis '('\n" . $herecurr) &&
4624 $fix) {
4625 $fixed[$fixlinenr] =~
4626 s/\(\s+/\(/;
4627 }
4628 }
4629 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4630 $line !~ /for\s*\(.*;\s+\)/ &&
4631 $line !~ /:\s+\)/) {
4632 if (ERROR("SPACING",
4633 "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
4634 $fix) {
4635 $fixed[$fixlinenr] =~
4636 s/\s+\)/\)/;
4637 }
4638 }
4639
4640# check unnecessary parentheses around addressof/dereference single $Lvals
4641# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4642
4643 while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4644 my $var = $1;
4645 if (CHK("UNNECESSARY_PARENTHESES",
4646 "Unnecessary parentheses around $var\n" . $herecurr) &&
4647 $fix) {
4648 $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4649 }
4650 }
4651
4652# check for unnecessary parentheses around function pointer uses
4653# ie: (foo->bar)(); should be foo->bar();
4654# but not "if (foo->bar) (" to avoid some false positives
4655 if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4656 my $var = $2;
4657 if (CHK("UNNECESSARY_PARENTHESES",
4658 "Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4659 $fix) {
4660 my $var2 = deparenthesize($var);
4661 $var2 =~ s/\s//g;
4662 $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4663 }
4664 }
4665
Martin Roth387dec82017-09-17 19:20:46 -06004666# check for unnecessary parentheses around comparisons in if uses
Martin Roth60915b32018-08-10 21:04:05 -06004667# when !drivers/staging or command-line uses --strict
4668 if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01004669 $perl_version_ok && defined($stat) &&
Martin Roth387dec82017-09-17 19:20:46 -06004670 $stat =~ /(^.\s*if\s*($balanced_parens))/) {
4671 my $if_stat = $1;
4672 my $test = substr($2, 1, -1);
4673 my $herectx;
4674 while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
4675 my $match = $1;
4676 # avoid parentheses around potential macro args
4677 next if ($match =~ /^\s*\w+\s*$/);
4678 if (!defined($herectx)) {
4679 $herectx = $here . "\n";
4680 my $cnt = statement_rawlines($if_stat);
4681 for (my $n = 0; $n < $cnt; $n++) {
4682 my $rl = raw_line($linenr, $n);
4683 $herectx .= $rl . "\n";
4684 last if $rl =~ /^[ \+].*\{/;
4685 }
4686 }
4687 CHK("UNNECESSARY_PARENTHESES",
4688 "Unnecessary parentheses around '$match'\n" . $herectx);
4689 }
4690 }
4691
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004692#goto labels aren't indented, allow a single space however
4693 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
4694 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
4695 if (WARN("INDENTED_LABEL",
4696 "labels should not be indented\n" . $herecurr) &&
4697 $fix) {
4698 $fixed[$fixlinenr] =~
4699 s/^(.)\s+/$1/;
4700 }
4701 }
4702
4703# return is not a function
4704 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4705 my $spacing = $1;
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01004706 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004707 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
4708 my $value = $1;
4709 $value = deparenthesize($value);
4710 if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4711 ERROR("RETURN_PARENTHESES",
4712 "return is not a function, parentheses are not required\n" . $herecurr);
4713 }
4714 } elsif ($spacing !~ /\s+/) {
4715 ERROR("SPACING",
4716 "space required before the open parenthesis '('\n" . $herecurr);
4717 }
4718 }
4719
4720# unnecessary return in a void function
4721# at end-of-function, with the previous line a single leading tab, then return;
4722# and the line before that not a goto label target like "out:"
4723 if ($sline =~ /^[ \+]}\s*$/ &&
4724 $prevline =~ /^\+\treturn\s*;\s*$/ &&
4725 $linenr >= 3 &&
4726 $lines[$linenr - 3] =~ /^[ +]/ &&
4727 $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
4728 WARN("RETURN_VOID",
4729 "void function return statements are not generally useful\n" . $hereprev);
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01004730 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004731
4732# if statements using unnecessary parentheses - ie: if ((foo == bar))
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01004733 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004734 $line =~ /\bif\s*((?:\(\s*){2,})/) {
4735 my $openparens = $1;
4736 my $count = $openparens =~ tr@\(@\(@;
4737 my $msg = "";
4738 if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4739 my $comp = $4; #Not $1 because of $LvalOrFunc
4740 $msg = " - maybe == should be = ?" if ($comp eq "==");
4741 WARN("UNNECESSARY_PARENTHESES",
4742 "Unnecessary parentheses$msg\n" . $herecurr);
4743 }
4744 }
4745
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004746# comparisons with a constant or upper case identifier on the left
4747# avoid cases like "foo + BAR < baz"
4748# only fix matches surrounded by parentheses to avoid incorrect
4749# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01004750 if ($perl_version_ok &&
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004751 $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4752 my $lead = $1;
4753 my $const = $2;
4754 my $comp = $3;
4755 my $to = $4;
4756 my $newcomp = $comp;
4757 if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4758 $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4759 WARN("CONSTANT_COMPARISON",
4760 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4761 $fix) {
4762 if ($comp eq "<") {
4763 $newcomp = ">";
4764 } elsif ($comp eq "<=") {
4765 $newcomp = ">=";
4766 } elsif ($comp eq ">") {
4767 $newcomp = "<";
4768 } elsif ($comp eq ">=") {
4769 $newcomp = "<=";
4770 }
4771 $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4772 }
4773 }
4774
4775# Return of what appears to be an errno should normally be negative
4776 if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004777 my $name = $1;
4778 if ($name ne 'EOF' && $name ne 'ERROR') {
4779 WARN("USE_NEGATIVE_ERRNO",
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004780 "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004781 }
4782 }
4783
4784# Need a space before open parenthesis after if, while etc
4785 if ($line =~ /\b(if|while|for|switch)\(/) {
4786 if (ERROR("SPACING",
4787 "space required before the open parenthesis '('\n" . $herecurr) &&
4788 $fix) {
4789 $fixed[$fixlinenr] =~
4790 s/\b(if|while|for|switch)\(/$1 \(/;
4791 }
4792 }
4793
4794# Check for illegal assignment in if conditional -- and check for trailing
4795# statements after the conditional.
4796 if ($line =~ /do\s*(?!{)/) {
4797 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4798 ctx_statement_block($linenr, $realcnt, 0)
4799 if (!defined $stat);
4800 my ($stat_next) = ctx_statement_block($line_nr_next,
4801 $remain_next, $off_next);
4802 $stat_next =~ s/\n./\n /g;
4803 ##print "stat<$stat> stat_next<$stat_next>\n";
4804
4805 if ($stat_next =~ /^\s*while\b/) {
4806 # If the statement carries leading newlines,
4807 # then count those as offsets.
4808 my ($whitespace) =
4809 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4810 my $offset =
4811 statement_rawlines($whitespace) - 1;
4812
4813 $suppress_whiletrailers{$line_nr_next +
4814 $offset} = 1;
4815 }
4816 }
4817 if (!defined $suppress_whiletrailers{$linenr} &&
4818 defined($stat) && defined($cond) &&
4819 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4820 my ($s, $c) = ($stat, $cond);
4821
4822 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4823 ERROR("ASSIGN_IN_IF",
4824 "do not use assignment in if condition\n" . $herecurr);
4825 }
4826
4827 # Find out what is on the end of the line after the
4828 # conditional.
4829 substr($s, 0, length($c), '');
4830 $s =~ s/\n.*//g;
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01004831 $s =~ s/$;//g; # Remove any comments
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004832 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
4833 $c !~ /}\s*while\s*/)
4834 {
4835 # Find out how long the conditional actually is.
4836 my @newlines = ($c =~ /\n/gs);
4837 my $cond_lines = 1 + $#newlines;
4838 my $stat_real = '';
4839
4840 $stat_real = raw_line($linenr, $cond_lines)
4841 . "\n" if ($cond_lines);
4842 if (defined($stat_real) && $cond_lines > 1) {
4843 $stat_real = "[...]\n$stat_real";
4844 }
4845
4846 ERROR("TRAILING_STATEMENTS",
4847 "trailing statements should be on next line\n" . $herecurr . $stat_real);
4848 }
4849 }
4850
4851# Check for bitwise tests written as boolean
4852 if ($line =~ /
4853 (?:
4854 (?:\[|\(|\&\&|\|\|)
4855 \s*0[xX][0-9]+\s*
4856 (?:\&\&|\|\|)
4857 |
4858 (?:\&\&|\|\|)
4859 \s*0[xX][0-9]+\s*
4860 (?:\&\&|\|\||\)|\])
4861 )/x)
4862 {
4863 WARN("HEXADECIMAL_BOOLEAN_TEST",
4864 "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
4865 }
4866
4867# if and else should not have general statements after it
4868 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
4869 my $s = $1;
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01004870 $s =~ s/$;//g; # Remove any comments
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004871 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
4872 ERROR("TRAILING_STATEMENTS",
4873 "trailing statements should be on next line\n" . $herecurr);
4874 }
4875 }
4876# if should not continue a brace
4877 if ($line =~ /}\s*if\b/) {
4878 ERROR("TRAILING_STATEMENTS",
4879 "trailing statements should be on next line (or did you mean 'else if'?)\n" .
4880 $herecurr);
4881 }
4882# case and default should not have general statements after them
4883 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
4884 $line !~ /\G(?:
4885 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
4886 \s*return\s+
4887 )/xg)
4888 {
4889 ERROR("TRAILING_STATEMENTS",
4890 "trailing statements should be on next line\n" . $herecurr);
4891 }
4892
4893 # Check for }<nl>else {, these must be at the same
4894 # indent level to be relevant to each other.
4895 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
4896 $previndent == $indent) {
4897 if (ERROR("ELSE_AFTER_BRACE",
4898 "else should follow close brace '}'\n" . $hereprev) &&
4899 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4900 fix_delete_line($fixlinenr - 1, $prevrawline);
4901 fix_delete_line($fixlinenr, $rawline);
4902 my $fixedline = $prevrawline;
4903 $fixedline =~ s/}\s*$//;
4904 if ($fixedline !~ /^\+\s*$/) {
4905 fix_insert_line($fixlinenr, $fixedline);
4906 }
4907 $fixedline = $rawline;
4908 $fixedline =~ s/^(.\s*)else/$1} else/;
4909 fix_insert_line($fixlinenr, $fixedline);
4910 }
4911 }
4912
4913 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
4914 $previndent == $indent) {
4915 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
4916
4917 # Find out what is on the end of the line after the
4918 # conditional.
4919 substr($s, 0, length($c), '');
4920 $s =~ s/\n.*//g;
4921
4922 if ($s =~ /^\s*;/) {
4923 if (ERROR("WHILE_AFTER_BRACE",
4924 "while should follow close brace '}'\n" . $hereprev) &&
4925 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4926 fix_delete_line($fixlinenr - 1, $prevrawline);
4927 fix_delete_line($fixlinenr, $rawline);
4928 my $fixedline = $prevrawline;
4929 my $trailing = $rawline;
4930 $trailing =~ s/^\+//;
4931 $trailing = trim($trailing);
4932 $fixedline =~ s/}\s*$/} $trailing/;
4933 fix_insert_line($fixlinenr, $fixedline);
4934 }
4935 }
4936 }
4937
4938#Specific variable tests
4939 while ($line =~ m{($Constant|$Lval)}g) {
4940 my $var = $1;
4941
4942#gcc binary extension
4943 if ($var =~ /^$Binary$/) {
4944 if (WARN("GCC_BINARY_CONSTANT",
4945 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4946 $fix) {
4947 my $hexval = sprintf("0x%x", oct($var));
4948 $fixed[$fixlinenr] =~
4949 s/\b$var\b/$hexval/;
4950 }
4951 }
4952
4953#CamelCase
4954 if ($var !~ /^$Constant$/ &&
4955 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
4956#Ignore Page<foo> variants
4957 $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
4958#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
4959 $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
4960#Ignore some three character SI units explicitly, like MiB and KHz
4961 $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
4962 while ($var =~ m{($Ident)}g) {
4963 my $word = $1;
4964 next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
4965 if ($check) {
4966 seed_camelcase_includes();
4967 if (!$file && !$camelcase_file_seeded) {
4968 seed_camelcase_file($realfile);
4969 $camelcase_file_seeded = 1;
4970 }
4971 }
4972 if (!defined $camelcase{$word}) {
4973 $camelcase{$word} = 1;
4974 CHK("CAMELCASE",
4975 "Avoid CamelCase: <$word>\n" . $herecurr);
4976 }
4977 }
4978 }
4979 }
4980
4981#no spaces allowed after \ in define
4982 if ($line =~ /\#\s*define.*\\\s+$/) {
4983 if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
4984 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
4985 $fix) {
4986 $fixed[$fixlinenr] =~ s/\s+$//;
4987 }
4988 }
4989
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004990# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
4991# itself <asm/foo.h> (uses RAW line)
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01004992 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
4993 my $file = "$1.h";
4994 my $checkfile = "include/linux/$file";
4995 if (-f "$root/$checkfile" &&
4996 $realfile ne $checkfile &&
4997 $1 !~ /$allowed_asm_includes/)
4998 {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07004999 my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
5000 if ($asminclude > 0) {
5001 if ($realfile =~ m{^arch/}) {
5002 CHK("ARCH_INCLUDE_LINUX",
5003 "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5004 } else {
5005 WARN("INCLUDE_LINUX",
5006 "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5007 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005008 }
5009 }
5010 }
5011
5012# multi-statement macros should be enclosed in a do while loop, grab the
5013# first statement and ensure its the whole macro if its not enclosed
5014# in a known good container
5015 if ($realfile !~ m@/vmlinux.lds.h$@ &&
5016 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5017 my $ln = $linenr;
5018 my $cnt = $realcnt;
5019 my ($off, $dstat, $dcond, $rest);
5020 my $ctx = '';
5021 my $has_flow_statement = 0;
5022 my $has_arg_concat = 0;
5023 ($dstat, $dcond, $ln, $cnt, $off) =
5024 ctx_statement_block($linenr, $realcnt, 0);
5025 $ctx = $dstat;
5026 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5027 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5028
5029 $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005030 $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005031
Martin Rothedd591d2017-03-14 10:16:29 -06005032 $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5033 my $define_args = $1;
5034 my $define_stmt = $dstat;
5035 my @def_args = ();
5036
5037 if (defined $define_args && $define_args ne "") {
5038 $define_args = substr($define_args, 1, length($define_args) - 2);
5039 $define_args =~ s/\s*//g;
5040 @def_args = split(",", $define_args);
5041 }
5042
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005043 $dstat =~ s/$;//g;
5044 $dstat =~ s/\\\n.//g;
5045 $dstat =~ s/^\s*//s;
5046 $dstat =~ s/\s*$//s;
5047
5048 # Flatten any parentheses and braces
5049 while ($dstat =~ s/\([^\(\)]*\)/1/ ||
5050 $dstat =~ s/\{[^\{\}]*\}/1/ ||
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005051 $dstat =~ s/.\[[^\[\]]*\]/1/)
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005052 {
5053 }
5054
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01005055 # Flatten any obvious string concatenation.
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005056 while ($dstat =~ s/($String)\s*$Ident/$1/ ||
5057 $dstat =~ s/$Ident\s*($String)/$1/)
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005058 {
5059 }
5060
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005061 # Make asm volatile uses seem like a generic function
5062 $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
5063
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005064 my $exceptions = qr{
5065 $Declare|
5066 module_param_named|
5067 MODULE_PARM_DESC|
5068 DECLARE_PER_CPU|
5069 DEFINE_PER_CPU|
5070 __typeof__\(|
5071 union|
5072 struct|
5073 \.$Ident\s*=\s*|
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005074 ^\"|\"$|
5075 ^\[
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005076 }x;
5077 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
Martin Rothedd591d2017-03-14 10:16:29 -06005078
5079 $ctx =~ s/\n*$//;
Martin Rothedd591d2017-03-14 10:16:29 -06005080 my $stmt_cnt = statement_rawlines($ctx);
Martin Roth60915b32018-08-10 21:04:05 -06005081 my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
Martin Rothedd591d2017-03-14 10:16:29 -06005082
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005083 if ($dstat ne '' &&
5084 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
5085 $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
5086 $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5087 $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants
5088 $dstat !~ /$exceptions/ &&
5089 $dstat !~ /^\.$Ident\s*=/ && # .foo =
5090 $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
5091 $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
5092 $dstat !~ /^for\s*$Constant$/ && # for (...)
5093 $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
Martin Rothedd591d2017-03-14 10:16:29 -06005094 $dstat !~ /^do\s*{/ && # do {...
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005095 $dstat !~ /^\(\{/ && # ({...
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005096 $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5097 {
Martin Roth387dec82017-09-17 19:20:46 -06005098 if ($dstat =~ /^\s*if\b/) {
5099 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5100 "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5101 } elsif ($dstat =~ /;/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005102 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5103 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5104 } else {
5105 ERROR("COMPLEX_MACRO",
5106 "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5107 }
Martin Rothedd591d2017-03-14 10:16:29 -06005108
5109 }
5110
5111 # Make $define_stmt single line, comment-free, etc
5112 my @stmt_array = split('\n', $define_stmt);
5113 my $first = 1;
5114 $define_stmt = "";
5115 foreach my $l (@stmt_array) {
5116 $l =~ s/\\$//;
5117 if ($first) {
5118 $define_stmt = $l;
5119 $first = 0;
5120 } elsif ($l =~ /^[\+ ]/) {
5121 $define_stmt .= substr($l, 1);
5122 }
5123 }
5124 $define_stmt =~ s/$;//g;
5125 $define_stmt =~ s/\s+/ /g;
5126 $define_stmt = trim($define_stmt);
5127
5128# check if any macro arguments are reused (ignore '...' and 'type')
5129 foreach my $arg (@def_args) {
5130 next if ($arg =~ /\.\.\./);
5131 next if ($arg =~ /^type$/i);
Martin Roth387dec82017-09-17 19:20:46 -06005132 my $tmp_stmt = $define_stmt;
5133 $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
5134 $tmp_stmt =~ s/\#+\s*$arg\b//g;
5135 $tmp_stmt =~ s/\b$arg\s*\#\#//g;
Martin Roth60915b32018-08-10 21:04:05 -06005136 my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
Martin Rothedd591d2017-03-14 10:16:29 -06005137 if ($use_cnt > 1) {
5138 CHK("MACRO_ARG_REUSE",
5139 "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5140 }
5141# check if any macro arguments may have other precedence issues
Martin Roth387dec82017-09-17 19:20:46 -06005142 if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
Martin Rothedd591d2017-03-14 10:16:29 -06005143 ((defined($1) && $1 ne ',') ||
5144 (defined($2) && $2 ne ','))) {
5145 CHK("MACRO_ARG_PRECEDENCE",
5146 "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
5147 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005148 }
5149
5150# check for macros with flow control, but without ## concatenation
5151# ## concatenation is commonly a macro that defines a function so ignore those
5152 if ($has_flow_statement && !$has_arg_concat) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005153 my $cnt = statement_rawlines($ctx);
Martin Roth60915b32018-08-10 21:04:05 -06005154 my $herectx = get_stat_here($linenr, $cnt, $here);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005155
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005156 WARN("MACRO_WITH_FLOW_CONTROL",
5157 "Macros with flow control statements should be avoided\n" . "$herectx");
5158 }
5159
5160# check for line continuations outside of #defines, preprocessor #, and asm
5161
5162 } else {
5163 if ($prevline !~ /^..*\\$/ &&
5164 $line !~ /^\+\s*\#.*\\$/ && # preprocessor
5165 $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
5166 $line =~ /^\+.*\\$/) {
5167 WARN("LINE_CONTINUATIONS",
5168 "Avoid unnecessary line continuations\n" . $herecurr);
5169 }
5170 }
5171
5172# do {} while (0) macro tests:
5173# single-statement macros do not need to be enclosed in do while (0) loop,
5174# macro should not end with a semicolon
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005175 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005176 $realfile !~ m@/vmlinux.lds.h$@ &&
5177 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5178 my $ln = $linenr;
5179 my $cnt = $realcnt;
5180 my ($off, $dstat, $dcond, $rest);
5181 my $ctx = '';
5182 ($dstat, $dcond, $ln, $cnt, $off) =
5183 ctx_statement_block($linenr, $realcnt, 0);
5184 $ctx = $dstat;
5185
5186 $dstat =~ s/\\\n.//g;
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005187 $dstat =~ s/$;/ /g;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005188
5189 if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5190 my $stmts = $2;
5191 my $semis = $3;
5192
5193 $ctx =~ s/\n*$//;
5194 my $cnt = statement_rawlines($ctx);
Martin Roth60915b32018-08-10 21:04:05 -06005195 my $herectx = get_stat_here($linenr, $cnt, $here);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005196
5197 if (($stmts =~ tr/;/;/) == 1 &&
5198 $stmts !~ /^\s*(if|while|for|switch)\b/) {
5199 WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5200 "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5201 }
5202 if (defined $semis && $semis ne "") {
5203 WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5204 "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5205 }
5206 } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5207 $ctx =~ s/\n*$//;
5208 my $cnt = statement_rawlines($ctx);
Martin Roth60915b32018-08-10 21:04:05 -06005209 my $herectx = get_stat_here($linenr, $cnt, $here);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005210
5211 WARN("TRAILING_SEMICOLON",
5212 "macros should not use a trailing semicolon\n" . "$herectx");
5213 }
5214 }
5215
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005216# check for redundant bracing round if etc
5217 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
5218 my ($level, $endln, @chunks) =
5219 ctx_statement_full($linenr, $realcnt, 1);
5220 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5221 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5222 if ($#chunks > 0 && $level == 0) {
5223 my @allowed = ();
5224 my $allow = 0;
5225 my $seen = 0;
5226 my $herectx = $here . "\n";
5227 my $ln = $linenr - 1;
5228 for my $chunk (@chunks) {
5229 my ($cond, $block) = @{$chunk};
5230
5231 # If the condition carries leading newlines, then count those as offsets.
5232 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5233 my $offset = statement_rawlines($whitespace) - 1;
5234
5235 $allowed[$allow] = 0;
5236 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5237
5238 # We have looked at and allowed this specific line.
5239 $suppress_ifbraces{$ln + $offset} = 1;
5240
5241 $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5242 $ln += statement_rawlines($block) - 1;
5243
5244 substr($block, 0, length($cond), '');
5245
5246 $seen++ if ($block =~ /^\s*{/);
5247
5248 #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5249 if (statement_lines($cond) > 1) {
5250 #print "APW: ALLOWED: cond<$cond>\n";
5251 $allowed[$allow] = 1;
5252 }
5253 if ($block =~/\b(?:if|for|while)\b/) {
5254 #print "APW: ALLOWED: block<$block>\n";
5255 $allowed[$allow] = 1;
5256 }
5257 if (statement_block_size($block) > 1) {
5258 #print "APW: ALLOWED: lines block<$block>\n";
5259 $allowed[$allow] = 1;
5260 }
5261 $allow++;
5262 }
5263 if ($seen) {
5264 my $sum_allowed = 0;
5265 foreach (@allowed) {
5266 $sum_allowed += $_;
5267 }
5268 if ($sum_allowed == 0) {
5269 WARN("BRACES",
5270 "braces {} are not necessary for any arm of this statement\n" . $herectx);
5271 } elsif ($sum_allowed != $allow &&
5272 $seen != $allow) {
5273 CHK("BRACES",
5274 "braces {} should be used on all arms of this statement\n" . $herectx);
5275 }
5276 }
5277 }
5278 }
5279 if (!defined $suppress_ifbraces{$linenr - 1} &&
5280 $line =~ /\b(if|while|for|else)\b/) {
5281 my $allowed = 0;
5282
5283 # Check the pre-context.
5284 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5285 #print "APW: ALLOWED: pre<$1>\n";
5286 $allowed = 1;
5287 }
5288
5289 my ($level, $endln, @chunks) =
5290 ctx_statement_full($linenr, $realcnt, $-[0]);
5291
5292 # Check the condition.
5293 my ($cond, $block) = @{$chunks[0]};
5294 #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5295 if (defined $cond) {
5296 substr($block, 0, length($cond), '');
5297 }
5298 if (statement_lines($cond) > 1) {
5299 #print "APW: ALLOWED: cond<$cond>\n";
5300 $allowed = 1;
5301 }
5302 if ($block =~/\b(?:if|for|while)\b/) {
5303 #print "APW: ALLOWED: block<$block>\n";
5304 $allowed = 1;
5305 }
5306 if (statement_block_size($block) > 1) {
5307 #print "APW: ALLOWED: lines block<$block>\n";
5308 $allowed = 1;
5309 }
5310 # Check the post-context.
5311 if (defined $chunks[1]) {
5312 my ($cond, $block) = @{$chunks[1]};
5313 if (defined $cond) {
5314 substr($block, 0, length($cond), '');
5315 }
5316 if ($block =~ /^\s*\{/) {
5317 #print "APW: ALLOWED: chunk-1 block<$block>\n";
5318 $allowed = 1;
5319 }
5320 }
5321 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005322 my $cnt = statement_rawlines($block);
Martin Roth60915b32018-08-10 21:04:05 -06005323 my $herectx = get_stat_here($linenr, $cnt, $here);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005324
5325 WARN("BRACES",
5326 "braces {} are not necessary for single statement blocks\n" . $herectx);
5327 }
5328 }
5329
Martin Rothedd591d2017-03-14 10:16:29 -06005330# check for single line unbalanced braces
5331 if ($sline =~ /^.\s*\}\s*else\s*$/ ||
5332 $sline =~ /^.\s*else\s*\{\s*$/) {
5333 CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5334 }
5335
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005336# check for unnecessary blank lines around braces
5337 if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005338 if (CHK("BRACES",
5339 "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5340 $fix && $prevrawline =~ /^\+/) {
5341 fix_delete_line($fixlinenr - 1, $prevrawline);
5342 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005343 }
5344 if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005345 if (CHK("BRACES",
5346 "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5347 $fix) {
5348 fix_delete_line($fixlinenr, $rawline);
5349 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005350 }
5351
5352# no volatiles please
5353 my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
5354 if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5355 WARN("VOLATILE",
Martin Rothedd591d2017-03-14 10:16:29 -06005356 "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005357 }
5358
5359# Check for user-visible strings broken across lines, which breaks the ability
5360# to grep for the string. Make exceptions when the previous string ends in a
5361# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
5362# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005363 if ($line =~ /^\+\s*$String/ &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005364 $prevline =~ /"\s*$/ &&
5365 $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
5366 if (WARN("SPLIT_STRING",
5367 "quoted string split across lines\n" . $hereprev) &&
5368 $fix &&
5369 $prevrawline =~ /^\+.*"\s*$/ &&
5370 $last_coalesced_string_linenr != $linenr - 1) {
5371 my $extracted_string = get_quoted_string($line, $rawline);
5372 my $comma_close = "";
5373 if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
5374 $comma_close = $1;
5375 }
5376
5377 fix_delete_line($fixlinenr - 1, $prevrawline);
5378 fix_delete_line($fixlinenr, $rawline);
5379 my $fixedline = $prevrawline;
5380 $fixedline =~ s/"\s*$//;
5381 $fixedline .= substr($extracted_string, 1) . trim($comma_close);
5382 fix_insert_line($fixlinenr - 1, $fixedline);
5383 $fixedline = $rawline;
5384 $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
5385 if ($fixedline !~ /\+\s*$/) {
5386 fix_insert_line($fixlinenr, $fixedline);
5387 }
5388 $last_coalesced_string_linenr = $linenr;
5389 }
5390 }
5391
5392# check for missing a space in a string concatenation
5393 if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
5394 WARN('MISSING_SPACE',
5395 "break quoted strings at a space character\n" . $hereprev);
5396 }
5397
Martin Roth387dec82017-09-17 19:20:46 -06005398# check for an embedded function name in a string when the function is known
5399# This does not work very well for -f --file checking as it depends on patch
5400# context providing the function name or a single line form for in-file
5401# function declarations
Martin Rothedd591d2017-03-14 10:16:29 -06005402 if ($line =~ /^\+.*$String/ &&
5403 defined($context_function) &&
Martin Roth387dec82017-09-17 19:20:46 -06005404 get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5405 length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
Martin Rothedd591d2017-03-14 10:16:29 -06005406 WARN("EMBEDDED_FUNCTION_NAME",
Martin Roth387dec82017-09-17 19:20:46 -06005407 "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
Martin Rothedd591d2017-03-14 10:16:29 -06005408 }
5409
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005410# check for spaces before a quoted newline
5411 if ($rawline =~ /^.*\".*\s\\n/) {
5412 if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
5413 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
5414 $fix) {
5415 $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
5416 }
5417
5418 }
5419
5420# concatenated string without spaces between elements
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005421 if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005422 CHK("CONCATENATED_STRING",
5423 "Concatenated strings should use spaces between elements\n" . $herecurr);
5424 }
5425
5426# uncoalesced string fragments
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005427 if ($line =~ /$String\s*"/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005428 WARN("STRING_FRAGMENTS",
5429 "Consecutive strings are generally better as a single string\n" . $herecurr);
5430 }
5431
Martin Rothedd591d2017-03-14 10:16:29 -06005432# check for non-standard and hex prefixed decimal printf formats
5433 my $show_L = 1; #don't show the same defect twice
5434 my $show_Z = 1;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005435 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
Martin Rothedd591d2017-03-14 10:16:29 -06005436 my $string = substr($rawline, $-[1], $+[1] - $-[1]);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005437 $string =~ s/%%/__/g;
Martin Rothedd591d2017-03-14 10:16:29 -06005438 # check for %L
5439 if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005440 WARN("PRINTF_L",
Martin Rothedd591d2017-03-14 10:16:29 -06005441 "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5442 $show_L = 0;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005443 }
Martin Rothedd591d2017-03-14 10:16:29 -06005444 # check for %Z
5445 if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5446 WARN("PRINTF_Z",
5447 "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5448 $show_Z = 0;
5449 }
5450 # check for 0x<decimal>
5451 if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5452 ERROR("PRINTF_0XDECIMAL",
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005453 "Prefixing 0x with decimal output is defective\n" . $herecurr);
5454 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005455 }
5456
5457# check for line continuations in quoted strings with odd counts of "
Martin Roth60915b32018-08-10 21:04:05 -06005458 if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005459 WARN("LINE_CONTINUATIONS",
5460 "Avoid line continuations in quoted strings\n" . $herecurr);
5461 }
5462
5463# warn about #if 0
5464 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
5465 CHK("REDUNDANT_CODE",
5466 "if this code is redundant consider removing it\n" .
5467 $herecurr);
5468 }
5469
5470# check for needless "if (<foo>) fn(<foo>)" uses
5471 if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005472 my $tested = quotemeta($1);
5473 my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5474 if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5475 my $func = $1;
5476 if (WARN('NEEDLESS_IF',
5477 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5478 $fix) {
5479 my $do_fix = 1;
5480 my $leading_tabs = "";
5481 my $new_leading_tabs = "";
5482 if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5483 $leading_tabs = $1;
5484 } else {
5485 $do_fix = 0;
5486 }
5487 if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5488 $new_leading_tabs = $1;
5489 if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5490 $do_fix = 0;
5491 }
5492 } else {
5493 $do_fix = 0;
5494 }
5495 if ($do_fix) {
5496 fix_delete_line($fixlinenr - 1, $prevrawline);
5497 $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5498 }
5499 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005500 }
5501 }
5502
5503# check for unnecessary "Out of Memory" messages
5504 if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5505 $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5506 (defined $1 || defined $3) &&
5507 $linenr > 3) {
5508 my $testval = $2;
5509 my $testline = $lines[$linenr - 3];
5510
5511 my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5512# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5513
Martin Roth387dec82017-09-17 19:20:46 -06005514 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)/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005515 WARN("OOM_MESSAGE",
5516 "Possible unnecessary 'out of memory' message\n" . $hereprev);
5517 }
5518 }
5519
5520# check for logging functions with KERN_<LEVEL>
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005521 if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005522 $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5523 my $level = $1;
5524 if (WARN("UNNECESSARY_KERN_LEVEL",
5525 "Possible unnecessary $level\n" . $herecurr) &&
5526 $fix) {
5527 $fixed[$fixlinenr] =~ s/\s*$level\s*//;
5528 }
5529 }
5530
Martin Rothedd591d2017-03-14 10:16:29 -06005531# check for logging continuations
5532 if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
5533 WARN("LOGGING_CONTINUATION",
5534 "Avoid logging continuation uses where feasible\n" . $herecurr);
5535 }
5536
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005537# check for mask then right shift without a parentheses
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005538 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005539 $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5540 $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5541 WARN("MASK_THEN_SHIFT",
5542 "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5543 }
5544
5545# check for pointer comparisons to NULL
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005546 if ($perl_version_ok) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005547 while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5548 my $val = $1;
5549 my $equal = "!";
5550 $equal = "" if ($4 eq "!=");
5551 if (CHK("COMPARISON_TO_NULL",
5552 "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5553 $fix) {
5554 $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5555 }
5556 }
5557 }
5558
5559# check for bad placement of section $InitAttribute (e.g.: __initdata)
5560 if ($line =~ /(\b$InitAttribute\b)/) {
5561 my $attr = $1;
5562 if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
5563 my $ptr = $1;
5564 my $var = $2;
5565 if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
5566 ERROR("MISPLACED_INIT",
5567 "$attr should be placed after $var\n" . $herecurr)) ||
5568 ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
5569 WARN("MISPLACED_INIT",
5570 "$attr should be placed after $var\n" . $herecurr))) &&
5571 $fix) {
5572 $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;
5573 }
5574 }
5575 }
5576
5577# check for $InitAttributeData (ie: __initdata) with const
5578 if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5579 my $attr = $1;
5580 $attr =~ /($InitAttributePrefix)(.*)/;
5581 my $attr_prefix = $1;
5582 my $attr_type = $2;
5583 if (ERROR("INIT_ATTRIBUTE",
5584 "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5585 $fix) {
5586 $fixed[$fixlinenr] =~
5587 s/$InitAttributeData/${attr_prefix}initconst/;
5588 }
5589 }
5590
5591# check for $InitAttributeConst (ie: __initconst) without const
5592 if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5593 my $attr = $1;
5594 if (ERROR("INIT_ATTRIBUTE",
5595 "Use of $attr requires a separate use of const\n" . $herecurr) &&
5596 $fix) {
5597 my $lead = $fixed[$fixlinenr] =~
5598 /(^\+\s*(?:static\s+))/;
5599 $lead = rtrim($1);
5600 $lead = "$lead " if ($lead !~ /^\+$/);
5601 $lead = "${lead}const ";
5602 $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5603 }
5604 }
5605
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005606# check for __read_mostly with const non-pointer (should just be const)
5607 if ($line =~ /\b__read_mostly\b/ &&
5608 $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5609 if (ERROR("CONST_READ_MOSTLY",
5610 "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5611 $fix) {
5612 $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5613 }
5614 }
5615
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005616# don't use __constant_<foo> functions outside of include/uapi/
5617 if ($realfile !~ m@^include/uapi/@ &&
5618 $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5619 my $constant_func = $1;
5620 my $func = $constant_func;
5621 $func =~ s/^__constant_//;
5622 if (WARN("CONSTANT_CONVERSION",
5623 "$constant_func should be $func\n" . $herecurr) &&
5624 $fix) {
5625 $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5626 }
5627 }
5628
5629# prefer usleep_range over udelay
5630 if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
5631 my $delay = $1;
5632 # ignore udelay's < 10, however
5633 if (! ($delay < 10) ) {
5634 CHK("USLEEP_RANGE",
5635 "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
5636 }
5637 if ($delay > 2000) {
5638 WARN("LONG_UDELAY",
5639 "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
5640 }
5641 }
5642
5643# warn about unexpectedly long msleep's
5644 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
5645 if ($1 < 20) {
5646 WARN("MSLEEP",
5647 "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
5648 }
5649 }
5650
5651# check for comparisons of jiffies
5652 if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
5653 WARN("JIFFIES_COMPARISON",
5654 "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
5655 }
5656
5657# check for comparisons of get_jiffies_64()
5658 if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
5659 WARN("JIFFIES_COMPARISON",
5660 "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
5661 }
5662
5663# warn about #ifdefs in C files
5664# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
5665# print "#ifdef in C files should be avoided\n";
5666# print "$herecurr";
5667# $clean = 0;
5668# }
5669
5670# warn about spacing in #ifdefs
5671 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
5672 if (ERROR("SPACING",
5673 "exactly one space required after that #$1\n" . $herecurr) &&
5674 $fix) {
5675 $fixed[$fixlinenr] =~
5676 s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
5677 }
5678
5679 }
5680
5681# check for spinlock_t definitions without a comment.
5682 if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5683 $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
5684 my $which = $1;
5685 if (!ctx_has_comment($first_line, $linenr)) {
5686 CHK("UNCOMMENTED_DEFINITION",
5687 "$1 definition without comment\n" . $herecurr);
5688 }
5689 }
5690# check for memory barriers without a comment.
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005691
5692 my $barriers = qr{
5693 mb|
5694 rmb|
5695 wmb|
5696 read_barrier_depends
5697 }x;
5698 my $barrier_stems = qr{
5699 mb__before_atomic|
5700 mb__after_atomic|
5701 store_release|
5702 load_acquire|
5703 store_mb|
5704 (?:$barriers)
5705 }x;
5706 my $all_barriers = qr{
5707 (?:$barriers)|
5708 smp_(?:$barrier_stems)|
5709 virt_(?:$barrier_stems)
5710 }x;
5711
5712 if ($line =~ /\b(?:$all_barriers)\s*\(/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005713 if (!ctx_has_comment($first_line, $linenr)) {
5714 WARN("MEMORY_BARRIER",
5715 "memory barrier without comment\n" . $herecurr);
5716 }
5717 }
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005718
5719 my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5720
5721 if ($realfile !~ m@^include/asm-generic/@ &&
5722 $realfile !~ m@/barrier\.h$@ &&
5723 $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5724 $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5725 WARN("MEMORY_BARRIER",
5726 "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5727 }
5728
5729# check for waitqueue_active without a comment.
5730 if ($line =~ /\bwaitqueue_active\s*\(/) {
5731 if (!ctx_has_comment($first_line, $linenr)) {
5732 WARN("WAITQUEUE_ACTIVE",
5733 "waitqueue_active without comment\n" . $herecurr);
5734 }
5735 }
5736
Martin Roth60915b32018-08-10 21:04:05 -06005737# check for smp_read_barrier_depends and read_barrier_depends
5738 if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
5739 WARN("READ_BARRIER_DEPENDS",
5740 "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
5741 }
5742
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005743# check of hardware specific defines
5744 if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5745 CHK("ARCH_DEFINES",
5746 "architecture specific defines should be avoided\n" . $herecurr);
5747 }
5748
Martin Roth387dec82017-09-17 19:20:46 -06005749# check that the storage class is not after a type
5750 if ($line =~ /\b($Type)\s+($Storage)\b/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005751 WARN("STORAGE_CLASS",
Martin Roth387dec82017-09-17 19:20:46 -06005752 "storage class '$2' should be located before type '$1'\n" . $herecurr);
5753 }
5754# Check that the storage class is at the beginning of a declaration
5755 if ($line =~ /\b$Storage\b/ &&
5756 $line !~ /^.\s*$Storage/ &&
5757 $line =~ /^.\s*(.+?)\$Storage\s/ &&
5758 $1 !~ /[\,\)]\s*$/) {
5759 WARN("STORAGE_CLASS",
5760 "storage class should be at the beginning of the declaration\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005761 }
5762
5763# check the location of the inline attribute, that it is between
5764# storage class and type.
5765 if ($line =~ /\b$Type\s+$Inline\b/ ||
5766 $line =~ /\b$Inline\s+$Storage\b/) {
5767 ERROR("INLINE_LOCATION",
5768 "inline keyword should sit between storage class and type\n" . $herecurr);
5769 }
5770
5771# Check for __inline__ and __inline, prefer inline
5772 if ($realfile !~ m@\binclude/uapi/@ &&
5773 $line =~ /\b(__inline__|__inline)\b/) {
5774 if (WARN("INLINE",
5775 "plain inline is preferred over $1\n" . $herecurr) &&
5776 $fix) {
5777 $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5778
5779 }
5780 }
5781
5782# Check for __attribute__ packed, prefer __packed
5783 if ($realfile !~ m@\binclude/uapi/@ &&
5784 $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5785 WARN("PREFER_PACKED",
5786 "__packed is preferred over __attribute__((packed))\n" . $herecurr);
5787 }
5788
5789# Check for __attribute__ aligned, prefer __aligned
5790 if ($realfile !~ m@\binclude/uapi/@ &&
5791 $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5792 WARN("PREFER_ALIGNED",
5793 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
5794 }
5795
5796# Check for __attribute__ format(printf, prefer __printf
5797 if ($realfile !~ m@\binclude/uapi/@ &&
5798 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
5799 if (WARN("PREFER_PRINTF",
5800 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
5801 $fix) {
5802 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
5803
5804 }
5805 }
5806
5807# Check for __attribute__ format(scanf, prefer __scanf
5808 if ($realfile !~ m@\binclude/uapi/@ &&
5809 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
5810 if (WARN("PREFER_SCANF",
5811 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
5812 $fix) {
5813 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
5814 }
5815 }
5816
5817# Check for __attribute__ weak, or __weak declarations (may have link issues)
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005818 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005819 $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5820 ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5821 $line =~ /\b__weak\b/)) {
5822 ERROR("WEAK_DECLARATION",
5823 "Using weak declarations can have unintended link defects\n" . $herecurr);
5824 }
5825
Martin Rothedd591d2017-03-14 10:16:29 -06005826# check for c99 types like uint8_t used outside of uapi/ and tools/
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005827 if ($realfile !~ m@\binclude/uapi/@ &&
Martin Rothedd591d2017-03-14 10:16:29 -06005828 $realfile !~ m@\btools/@ &&
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005829 $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
5830 my $type = $1;
5831 if ($type =~ /\b($typeC99Typedefs)\b/) {
5832 $type = $1;
5833 my $kernel_type = 'u';
5834 $kernel_type = 's' if ($type =~ /^_*[si]/);
5835 $type =~ /(\d+)/;
5836 $kernel_type .= $1;
5837 if (CHK("PREFER_KERNEL_TYPES",
5838 "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
5839 $fix) {
5840 $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
5841 }
5842 }
5843 }
5844
5845# check for cast of C90 native int or longer types constants
5846 if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
5847 my $cast = $1;
5848 my $const = $2;
5849 if (WARN("TYPECAST_INT_CONSTANT",
5850 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
5851 $fix) {
5852 my $suffix = "";
5853 my $newconst = $const;
5854 $newconst =~ s/${Int_type}$//;
5855 $suffix .= 'U' if ($cast =~ /\bunsigned\b/);
5856 if ($cast =~ /\blong\s+long\b/) {
5857 $suffix .= 'LL';
5858 } elsif ($cast =~ /\blong\b/) {
5859 $suffix .= 'L';
5860 }
5861 $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
5862 }
5863 }
5864
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005865# check for sizeof(&)
5866 if ($line =~ /\bsizeof\s*\(\s*\&/) {
5867 WARN("SIZEOF_ADDRESS",
5868 "sizeof(& should be avoided\n" . $herecurr);
5869 }
5870
5871# check for sizeof without parenthesis
5872 if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
5873 if (WARN("SIZEOF_PARENTHESIS",
5874 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
5875 $fix) {
5876 $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
5877 }
5878 }
5879
5880# check for struct spinlock declarations
5881 if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
5882 WARN("USE_SPINLOCK_T",
5883 "struct spinlock should be spinlock_t\n" . $herecurr);
5884 }
5885
5886# check for seq_printf uses that could be seq_puts
5887 if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
5888 my $fmt = get_quoted_string($line, $rawline);
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005889 $fmt =~ s/%%//g;
5890 if ($fmt !~ /%/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005891 if (WARN("PREFER_SEQ_PUTS",
5892 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
5893 $fix) {
5894 $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
5895 }
5896 }
5897 }
5898
Martin Roth60915b32018-08-10 21:04:05 -06005899# check for vsprintf extension %p<foo> misuses
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005900 if ($perl_version_ok &&
Martin Roth387dec82017-09-17 19:20:46 -06005901 defined $stat &&
5902 $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
5903 $1 !~ /^_*volatile_*$/) {
Martin Roth60915b32018-08-10 21:04:05 -06005904 my $stat_real;
5905
Martin Roth387dec82017-09-17 19:20:46 -06005906 my $lc = $stat =~ tr@\n@@;
5907 $lc = $lc + $linenr;
5908 for (my $count = $linenr; $count <= $lc; $count++) {
Martin Roth60915b32018-08-10 21:04:05 -06005909 my $specifier;
5910 my $extension;
5911 my $bad_specifier = "";
Martin Roth387dec82017-09-17 19:20:46 -06005912 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
5913 $fmt =~ s/%%//g;
Martin Roth60915b32018-08-10 21:04:05 -06005914
5915 while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) {
5916 $specifier = $1;
5917 $extension = $2;
5918 if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOx]/) {
5919 $bad_specifier = $specifier;
5920 last;
5921 }
5922 if ($extension eq "x" && !defined($stat_real)) {
5923 if (!defined($stat_real)) {
5924 $stat_real = get_stat_real($linenr, $lc);
5925 }
5926 WARN("VSPRINTF_SPECIFIER_PX",
5927 "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n");
5928 }
Martin Roth387dec82017-09-17 19:20:46 -06005929 }
Martin Roth60915b32018-08-10 21:04:05 -06005930 if ($bad_specifier ne "") {
5931 my $stat_real = get_stat_real($linenr, $lc);
5932 my $ext_type = "Invalid";
5933 my $use = "";
5934 if ($bad_specifier =~ /p[Ff]/) {
5935 $ext_type = "Deprecated";
5936 $use = " - use %pS instead";
5937 $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
5938 }
5939
5940 WARN("VSPRINTF_POINTER_EXTENSION",
5941 "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
Martin Roth387dec82017-09-17 19:20:46 -06005942 }
Martin Roth387dec82017-09-17 19:20:46 -06005943 }
5944 }
5945
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005946# Check for misused memsets
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005947 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005948 defined $stat &&
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005949 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005950
5951 my $ms_addr = $2;
5952 my $ms_val = $7;
5953 my $ms_size = $12;
5954
5955 if ($ms_size =~ /^(0x|)0$/i) {
5956 ERROR("MEMSET",
5957 "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
5958 } elsif ($ms_size =~ /^(0x|)1$/i) {
5959 WARN("MEMSET",
5960 "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
5961 }
5962 }
5963
5964# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005965# if ($perl_version_ok &&
Martin Rothedd591d2017-03-14 10:16:29 -06005966# defined $stat &&
5967# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5968# if (WARN("PREFER_ETHER_ADDR_COPY",
5969# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
5970# $fix) {
5971# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
5972# }
5973# }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01005974
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005975# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005976# if ($perl_version_ok &&
Martin Rothedd591d2017-03-14 10:16:29 -06005977# defined $stat &&
5978# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5979# WARN("PREFER_ETHER_ADDR_EQUAL",
5980# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
5981# }
Stefan Reinauerc6080c62016-07-29 16:01:40 -07005982
5983# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
5984# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01005985# if ($perl_version_ok &&
Martin Rothedd591d2017-03-14 10:16:29 -06005986# defined $stat &&
5987# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5988#
5989# my $ms_val = $7;
5990#
5991# if ($ms_val =~ /^(?:0x|)0+$/i) {
5992# if (WARN("PREFER_ETH_ZERO_ADDR",
5993# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
5994# $fix) {
5995# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
5996# }
5997# } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
5998# if (WARN("PREFER_ETH_BROADCAST_ADDR",
5999# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6000# $fix) {
6001# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6002# }
6003# }
6004# }
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006005
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006006# typecasts on min/max could be min_t/max_t
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006007 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006008 defined $stat &&
6009 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6010 if (defined $2 || defined $7) {
6011 my $call = $1;
6012 my $cast1 = deparenthesize($2);
6013 my $arg1 = $3;
6014 my $cast2 = deparenthesize($7);
6015 my $arg2 = $8;
6016 my $cast;
6017
6018 if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6019 $cast = "$cast1 or $cast2";
6020 } elsif ($cast1 ne "") {
6021 $cast = $cast1;
6022 } else {
6023 $cast = $cast2;
6024 }
6025 WARN("MINMAX",
6026 "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6027 }
6028 }
6029
6030# check usleep_range arguments
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006031 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006032 defined $stat &&
6033 $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
6034 my $min = $1;
6035 my $max = $7;
6036 if ($min eq $max) {
6037 WARN("USLEEP_RANGE",
6038 "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
6039 } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
6040 $min > $max) {
6041 WARN("USLEEP_RANGE",
6042 "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
6043 }
6044 }
6045
6046# check for naked sscanf
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006047 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006048 defined $stat &&
6049 $line =~ /\bsscanf\b/ &&
6050 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6051 $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6052 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6053 my $lc = $stat =~ tr@\n@@;
6054 $lc = $lc + $linenr;
Martin Roth60915b32018-08-10 21:04:05 -06006055 my $stat_real = get_stat_real($linenr, $lc);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006056 WARN("NAKED_SSCANF",
6057 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6058 }
6059
6060# check for simple sscanf that should be kstrto<foo>
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006061 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006062 defined $stat &&
6063 $line =~ /\bsscanf\b/) {
6064 my $lc = $stat =~ tr@\n@@;
6065 $lc = $lc + $linenr;
Martin Roth60915b32018-08-10 21:04:05 -06006066 my $stat_real = get_stat_real($linenr, $lc);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006067 if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6068 my $format = $6;
6069 my $count = $format =~ tr@%@%@;
6070 if ($count == 1 &&
6071 $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6072 WARN("SSCANF_TO_KSTRTO",
6073 "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6074 }
6075 }
6076 }
6077
6078# check for new externs in .h files.
6079 if ($realfile =~ /\.h$/ &&
6080 $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6081 if (CHK("AVOID_EXTERNS",
6082 "extern prototypes should be avoided in .h files\n" . $herecurr) &&
6083 $fix) {
6084 $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
6085 }
6086 }
6087
6088# check for new externs in .c files.
6089 if ($realfile =~ /\.c$/ && defined $stat &&
6090 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6091 {
6092 my $function_name = $1;
6093 my $paren_space = $2;
6094
6095 my $s = $stat;
6096 if (defined $cond) {
6097 substr($s, 0, length($cond), '');
6098 }
6099 if ($s =~ /^\s*;/ &&
6100 $function_name ne 'uninitialized_var')
6101 {
6102 WARN("AVOID_EXTERNS",
6103 "externs should be avoided in .c files\n" . $herecurr);
6104 }
6105
6106 if ($paren_space =~ /\n/) {
6107 WARN("FUNCTION_ARGUMENTS",
6108 "arguments for function declarations should follow identifier\n" . $herecurr);
6109 }
6110
6111 } elsif ($realfile =~ /\.c$/ && defined $stat &&
6112 $stat =~ /^.\s*extern\s+/)
6113 {
6114 WARN("AVOID_EXTERNS",
6115 "externs should be avoided in .c files\n" . $herecurr);
6116 }
6117
Martin Roth387dec82017-09-17 19:20:46 -06006118# check for function declarations that have arguments without identifier names
6119 if (defined $stat &&
Martin Roth60915b32018-08-10 21:04:05 -06006120 $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
Martin Rothedd591d2017-03-14 10:16:29 -06006121 $1 ne "void") {
6122 my $args = trim($1);
6123 while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6124 my $arg = trim($1);
6125 if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
6126 WARN("FUNCTION_ARGUMENTS",
6127 "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6128 }
6129 }
6130 }
6131
Martin Roth387dec82017-09-17 19:20:46 -06006132# check for function definitions
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006133 if ($perl_version_ok &&
Martin Roth387dec82017-09-17 19:20:46 -06006134 defined $stat &&
6135 $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6136 $context_function = $1;
6137
6138# check for multiline function definition with misplaced open brace
6139 my $ok = 0;
6140 my $cnt = statement_rawlines($stat);
6141 my $herectx = $here . "\n";
6142 for (my $n = 0; $n < $cnt; $n++) {
6143 my $rl = raw_line($linenr, $n);
6144 $herectx .= $rl . "\n";
6145 $ok = 1 if ($rl =~ /^[ \+]\{/);
6146 $ok = 1 if ($rl =~ /\{/ && $n == 0);
6147 last if $rl =~ /^[ \+].*\{/;
6148 }
6149 if (!$ok) {
6150 ERROR("OPEN_BRACE",
6151 "open brace '{' following function definitions go on the next line\n" . $herectx);
6152 }
6153 }
6154
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006155# checks for new __setup's
6156 if ($rawline =~ /\b__setup\("([^"]*)"/) {
6157 my $name = $1;
6158
6159 if (!grep(/$name/, @setup_docs)) {
6160 CHK("UNDOCUMENTED_SETUP",
Martin Rothedd591d2017-03-14 10:16:29 -06006161 "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006162 }
6163 }
6164
6165# check for pointless casting of kmalloc return
6166 if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
6167 WARN("UNNECESSARY_CASTS",
6168 "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
6169 }
6170
6171# alloc style
6172# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006173 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006174 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6175 CHK("ALLOC_SIZEOF_STRUCT",
6176 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6177 }
6178
6179# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006180 if ($perl_version_ok &&
Martin Roth387dec82017-09-17 19:20:46 -06006181 defined $stat &&
6182 $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006183 my $oldfunc = $3;
6184 my $a1 = $4;
6185 my $a2 = $10;
6186 my $newfunc = "kmalloc_array";
6187 $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
6188 my $r1 = $a1;
6189 my $r2 = $a2;
6190 if ($a1 =~ /^sizeof\s*\S/) {
6191 $r1 = $a2;
6192 $r2 = $a1;
6193 }
6194 if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6195 !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
Martin Roth387dec82017-09-17 19:20:46 -06006196 my $cnt = statement_rawlines($stat);
Martin Roth60915b32018-08-10 21:04:05 -06006197 my $herectx = get_stat_here($linenr, $cnt, $here);
6198
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006199 if (WARN("ALLOC_WITH_MULTIPLY",
Martin Roth387dec82017-09-17 19:20:46 -06006200 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
6201 $cnt == 1 &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006202 $fix) {
6203 $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;
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006204 }
6205 }
6206 }
6207
6208# check for krealloc arg reuse
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006209 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006210 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
6211 WARN("KREALLOC_ARG_REUSE",
6212 "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6213 }
6214
6215# check for alloc argument mismatch
6216 if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
6217 WARN("ALLOC_ARRAY_ARGS",
6218 "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
6219 }
6220
6221# check for multiple semicolons
6222 if ($line =~ /;\s*;\s*$/) {
6223 if (WARN("ONE_SEMICOLON",
6224 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6225 $fix) {
6226 $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6227 }
6228 }
6229
Martin Rothedd591d2017-03-14 10:16:29 -06006230# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6231 if ($realfile !~ m@^include/uapi/@ &&
6232 $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006233 my $ull = "";
6234 $ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
6235 if (CHK("BIT_MACRO",
6236 "Prefer using the BIT$ull macro\n" . $herecurr) &&
6237 $fix) {
6238 $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
6239 }
6240 }
6241
6242# check for case / default statements not preceded by break/fallthrough/switch
6243 if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6244 my $has_break = 0;
6245 my $has_statement = 0;
6246 my $count = 0;
6247 my $prevline = $linenr;
6248 while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6249 $prevline--;
6250 my $rline = $rawlines[$prevline - 1];
6251 my $fline = $lines[$prevline - 1];
6252 last if ($fline =~ /^\@\@/);
6253 next if ($fline =~ /^\-/);
6254 next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6255 $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6256 next if ($fline =~ /^.[\s$;]*$/);
6257 $has_statement = 1;
6258 $count++;
Martin Roth60915b32018-08-10 21:04:05 -06006259 $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006260 }
6261 if (!$has_break && $has_statement) {
6262 WARN("MISSING_BREAK",
Martin Rothedd591d2017-03-14 10:16:29 -06006263 "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006264 }
6265 }
6266
6267# check for switch/default statements without a break;
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006268 if ($perl_version_ok &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006269 defined $stat &&
6270 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006271 my $cnt = statement_rawlines($stat);
Martin Roth60915b32018-08-10 21:04:05 -06006272 my $herectx = get_stat_here($linenr, $cnt, $here);
6273
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006274 WARN("DEFAULT_NO_BREAK",
6275 "switch default: should use break\n" . $herectx);
6276 }
6277
6278# check for gcc specific __FUNCTION__
6279 if ($line =~ /\b__FUNCTION__\b/) {
6280 if (WARN("USE_FUNC",
6281 "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
6282 $fix) {
6283 $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6284 }
6285 }
6286
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006287# check for uses of __DATE__, __TIME__, __TIMESTAMP__
6288 while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
6289 ERROR("DATE_TIME",
6290 "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
6291 }
6292
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006293# check for use of yield()
6294 if ($line =~ /\byield\s*\(\s*\)/) {
6295 WARN("YIELD",
6296 "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr);
6297 }
6298
6299# check for comparisons against true and false
6300 if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6301 my $lead = $1;
6302 my $arg = $2;
6303 my $test = $3;
6304 my $otype = $4;
6305 my $trail = $5;
6306 my $op = "!";
6307
6308 ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6309
6310 my $type = lc($otype);
6311 if ($type =~ /^(?:true|false)$/) {
6312 if (("$test" eq "==" && "$type" eq "true") ||
6313 ("$test" eq "!=" && "$type" eq "false")) {
6314 $op = "";
6315 }
6316
6317 CHK("BOOL_COMPARISON",
6318 "Using comparison to $otype is error prone\n" . $herecurr);
6319
6320## maybe suggesting a correct construct would better
6321## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6322
6323 }
6324 }
6325
Martin Roth60915b32018-08-10 21:04:05 -06006326# check for bool bitfields
6327 if ($sline =~ /^.\s+bool\s*$Ident\s*:\s*\d+\s*;/) {
6328 WARN("BOOL_BITFIELD",
6329 "Avoid using bool as bitfield. Prefer bool bitfields as unsigned int or u<8|16|32>\n" . $herecurr);
6330 }
6331
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006332# check for semaphores initialized locked
6333 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6334 WARN("CONSIDER_COMPLETION",
6335 "consider using a completion\n" . $herecurr);
6336 }
6337
6338# recommend kstrto* over simple_strto* and strict_strto*
6339 if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6340 WARN("CONSIDER_KSTRTO",
6341 "$1 is obsolete, use k$3 instead\n" . $herecurr);
6342 }
6343
6344# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6345 if ($line =~ /^.\s*__initcall\s*\(/) {
6346 WARN("USE_DEVICE_INITCALL",
6347 "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6348 }
6349
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006350# check for various structs that are normally const (ops, kgdb, device_tree)
Martin Roth387dec82017-09-17 19:20:46 -06006351# and avoid what seem like struct definitions 'struct foo {'
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006352 if ($line !~ /\bconst\b/ &&
Martin Roth387dec82017-09-17 19:20:46 -06006353 $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006354 WARN("CONST_STRUCT",
Martin Roth387dec82017-09-17 19:20:46 -06006355 "struct $1 should normally be const\n" . $herecurr);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006356 }
6357
6358# use of NR_CPUS is usually wrong
6359# ignore definitions of NR_CPUS and usage to define arrays as likely right
6360 if ($line =~ /\bNR_CPUS\b/ &&
6361 $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6362 $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6363 $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6364 $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6365 $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6366 {
6367 WARN("NR_CPUS",
6368 "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6369 }
6370
6371# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
6372 if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
6373 ERROR("DEFINE_ARCH_HAS",
6374 "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
6375 }
6376
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006377# likely/unlikely comparisons similar to "(likely(foo) > 0)"
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006378 if ($perl_version_ok &&
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006379 $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6380 WARN("LIKELY_MISUSE",
6381 "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6382 }
6383
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006384# whine mightly about in_atomic
6385 if ($line =~ /\bin_atomic\s*\(/) {
6386 if ($realfile =~ m@^drivers/@) {
6387 ERROR("IN_ATOMIC",
6388 "do not use in_atomic in drivers\n" . $herecurr);
6389 } elsif ($realfile !~ m@^kernel/@) {
6390 WARN("IN_ATOMIC",
6391 "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6392 }
6393 }
6394
Martin Rothedd591d2017-03-14 10:16:29 -06006395# check for mutex_trylock_recursive usage
6396 if ($line =~ /mutex_trylock_recursive/) {
6397 ERROR("LOCKING",
6398 "recursive locking is bad, do not use this ever.\n" . $herecurr);
6399 }
6400
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006401# check for lockdep_set_novalidate_class
6402 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
6403 $line =~ /__lockdep_no_validate__\s*\)/ ) {
6404 if ($realfile !~ m@^kernel/lockdep@ &&
6405 $realfile !~ m@^include/linux/lockdep@ &&
6406 $realfile !~ m@^drivers/base/core@) {
6407 ERROR("LOCKDEP",
6408 "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
6409 }
6410 }
6411
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006412 if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6413 $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006414 WARN("EXPORTED_WORLD_WRITABLE",
6415 "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
6416 }
6417
Martin Roth60915b32018-08-10 21:04:05 -06006418# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
6419# and whether or not function naming is typical and if
6420# DEVICE_ATTR permissions uses are unusual too
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006421 if ($perl_version_ok &&
Martin Roth60915b32018-08-10 21:04:05 -06006422 defined $stat &&
6423 $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
6424 my $var = $1;
6425 my $perms = $2;
6426 my $show = $3;
6427 my $store = $4;
6428 my $octal_perms = perms_to_octal($perms);
6429 if ($show =~ /^${var}_show$/ &&
6430 $store =~ /^${var}_store$/ &&
6431 $octal_perms eq "0644") {
6432 if (WARN("DEVICE_ATTR_RW",
6433 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
6434 $fix) {
6435 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
6436 }
6437 } elsif ($show =~ /^${var}_show$/ &&
6438 $store =~ /^NULL$/ &&
6439 $octal_perms eq "0444") {
6440 if (WARN("DEVICE_ATTR_RO",
6441 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
6442 $fix) {
6443 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
6444 }
6445 } elsif ($show =~ /^NULL$/ &&
6446 $store =~ /^${var}_store$/ &&
6447 $octal_perms eq "0200") {
6448 if (WARN("DEVICE_ATTR_WO",
6449 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
6450 $fix) {
6451 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
6452 }
6453 } elsif ($octal_perms eq "0644" ||
6454 $octal_perms eq "0444" ||
6455 $octal_perms eq "0200") {
6456 my $newshow = "$show";
6457 $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
6458 my $newstore = $store;
6459 $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
6460 my $rename = "";
6461 if ($show ne $newshow) {
6462 $rename .= " '$show' to '$newshow'";
6463 }
6464 if ($store ne $newstore) {
6465 $rename .= " '$store' to '$newstore'";
6466 }
6467 WARN("DEVICE_ATTR_FUNCTIONS",
6468 "Consider renaming function(s)$rename\n" . $herecurr);
6469 } else {
6470 WARN("DEVICE_ATTR_PERMS",
6471 "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
6472 }
6473 }
6474
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006475# Mode permission misuses where it seems decimal should be octal
6476# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
Martin Roth60915b32018-08-10 21:04:05 -06006477# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
6478# specific definition of not visible in sysfs.
6479# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
6480# use the default permissions
Elyes HAOUAS48cb78b2022-01-29 07:42:58 +01006481 if ($perl_version_ok &&
Martin Rothedd591d2017-03-14 10:16:29 -06006482 defined $stat &&
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006483 $line =~ /$mode_perms_search/) {
6484 foreach my $entry (@mode_permission_funcs) {
6485 my $func = $entry->[0];
6486 my $arg_pos = $entry->[1];
6487
Martin Rothedd591d2017-03-14 10:16:29 -06006488 my $lc = $stat =~ tr@\n@@;
6489 $lc = $lc + $linenr;
Martin Roth60915b32018-08-10 21:04:05 -06006490 my $stat_real = get_stat_real($linenr, $lc);
Martin Rothedd591d2017-03-14 10:16:29 -06006491
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006492 my $skip_args = "";
6493 if ($arg_pos > 1) {
6494 $arg_pos--;
6495 $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
6496 }
Martin Rothedd591d2017-03-14 10:16:29 -06006497 my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6498 if ($stat =~ /$test/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006499 my $val = $1;
6500 $val = $6 if ($skip_args ne "");
Martin Roth60915b32018-08-10 21:04:05 -06006501 if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
6502 (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
6503 ($val =~ /^$Octal$/ && length($val) ne 4))) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006504 ERROR("NON_OCTAL_PERMISSIONS",
Martin Rothedd591d2017-03-14 10:16:29 -06006505 "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6506 }
6507 if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006508 ERROR("EXPORTED_WORLD_WRITABLE",
Martin Rothedd591d2017-03-14 10:16:29 -06006509 "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006510 }
6511 }
6512 }
6513 }
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006514
Martin Rothedd591d2017-03-14 10:16:29 -06006515# check for uses of S_<PERMS> that could be octal for readability
Martin Roth60915b32018-08-10 21:04:05 -06006516 while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
6517 my $oval = $1;
6518 my $octal = perms_to_octal($oval);
Martin Rothedd591d2017-03-14 10:16:29 -06006519 if (WARN("SYMBOLIC_PERMS",
6520 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6521 $fix) {
Martin Roth60915b32018-08-10 21:04:05 -06006522 $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
Martin Rothedd591d2017-03-14 10:16:29 -06006523 }
6524 }
6525
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006526# validate content of MODULE_LICENSE against list from include/linux/module.h
6527 if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
6528 my $extracted_string = get_quoted_string($line, $rawline);
6529 my $valid_licenses = qr{
6530 GPL|
6531 GPL\ v2|
6532 GPL\ and\ additional\ rights|
6533 Dual\ BSD/GPL|
6534 Dual\ MIT/GPL|
6535 Dual\ MPL/GPL|
6536 Proprietary
6537 }x;
6538 if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
6539 WARN("MODULE_LICENSE",
6540 "unknown module license " . $extracted_string . "\n" . $herecurr);
6541 }
6542 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006543 }
6544
6545 # If we have no input at all, then there is nothing to report on
6546 # so just keep quiet.
6547 if ($#rawlines == -1) {
6548 exit(0);
6549 }
6550
6551 # In mailback mode only produce a report in the negative, for
6552 # things that appear to be patches.
6553 if ($mailback && ($clean == 1 || !$is_patch)) {
6554 exit(0);
6555 }
6556
Elyes HAOUAS919b0c72022-01-29 07:48:52 +01006557 # This is not a patch, and we are in 'no-patch' mode so
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006558 # just keep quiet.
6559 if (!$chk_patch && !$is_patch) {
6560 exit(0);
6561 }
6562
Martin Roth60915b32018-08-10 21:04:05 -06006563 if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006564 ERROR("NOT_UNIFIED_DIFF",
6565 "Does not appear to be a unified-diff format patch\n");
6566 }
Martin Rothedd591d2017-03-14 10:16:29 -06006567 if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006568 ERROR("MISSING_SIGN_OFF",
6569 "Missing Signed-off-by: line(s)\n");
6570 }
6571
6572 print report_dump();
6573 if ($summary && !($clean == 1 && $quiet == 1)) {
6574 print "$filename " if ($summary_file);
6575 print "total: $cnt_error errors, $cnt_warn warnings, " .
6576 (($check)? "$cnt_chk checks, " : "") .
6577 "$cnt_lines lines checked\n";
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006578 }
6579
6580 if ($quiet == 0) {
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006581 # If there were any defects found and not already fixing them
6582 if (!$clean and !$fix) {
6583 print << "EOM"
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006584
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006585NOTE: For some of the reported defects, checkpatch may be able to
6586 mechanically convert to the typical style using --fix or --fix-inplace.
6587EOM
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006588 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006589 # If there were whitespace errors which cleanpatch can fix
6590 # then suggest that.
6591 if ($rpt_cleaners) {
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006592 $rpt_cleaners = 0;
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006593 print << "EOM"
6594
6595NOTE: Whitespace errors detected.
6596 You may wish to use scripts/cleanpatch or scripts/cleanfile
6597EOM
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006598 }
6599 }
6600
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006601 if ($clean == 0 && $fix &&
6602 ("@rawlines" ne "@fixed" ||
6603 $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
6604 my $newfile = $filename;
6605 $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
6606 my $linecount = 0;
6607 my $f;
6608
6609 @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6610
6611 open($f, '>', $newfile)
6612 or die "$P: Can't open $newfile for write\n";
6613 foreach my $fixed_line (@fixed) {
6614 $linecount++;
6615 if ($file) {
6616 if ($linecount > 3) {
6617 $fixed_line =~ s/^\+//;
6618 print $f $fixed_line . "\n";
6619 }
6620 } else {
6621 print $f $fixed_line . "\n";
6622 }
6623 }
6624 close($f);
6625
6626 if (!$quiet) {
6627 print << "EOM";
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006628
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006629Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
6630
6631Do _NOT_ trust the results written to this file.
6632Do _NOT_ submit these changes without inspecting them for correctness.
6633
6634This EXPERIMENTAL file is simply a convenience to help rewrite patches.
6635No warranties, expressed or implied...
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006636EOM
6637 }
6638 }
6639
Stefan Reinauerc6080c62016-07-29 16:01:40 -07006640 if ($quiet == 0) {
6641 print "\n";
6642 if ($clean == 1) {
6643 print "$vname has no obvious style problems and is ready for submission.\n";
6644 } else {
6645 print "$vname has style problems, please review.\n";
6646 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006647 }
Stefan Reinauer44d0fd92015-02-11 01:49:00 +01006648 return $clean;
6649}