blob: af39d69b663df20585ee7403f54f9d1631a972e6 [file] [log] [blame]
Anas Nashif1eb244c2017-10-01 17:06:36 -04001#!/usr/bin/env perl
Peter Bigot5b10fac2020-03-26 11:16:33 -05002# SPDX-License-Identifier: GPL-2.0
3#
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004# (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>
Peter Bigot5b10fac2020-03-26 11:16:33 -05008# (c) 2010-2018 Joe Perches <joe@perches.com>
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07009
10use strict;
Anas Nashif1eb244c2017-10-01 17:06:36 -040011use warnings;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070012use POSIX;
Anas Nashifcbfb62c2015-10-14 06:08:54 -040013use File::Basename;
14use Cwd 'abs_path';
15use Term::ANSIColor qw(:constants);
Peter Bigot5b10fac2020-03-26 11:16:33 -050016use Encode qw(decode encode);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070017
18my $P = $0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -040019my $D = dirname(abs_path($P));
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070020
21my $V = '0.32';
22
23use Getopt::Long qw(:config no_auto_abbrev);
24
25my $quiet = 0;
26my $tree = 1;
27my $chk_signoff = 1;
28my $chk_patch = 1;
29my $tst_only;
30my $emacs = 0;
31my $terse = 0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -040032my $showfile = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070033my $file = 0;
Anas Nashif0f3d5472016-11-07 15:57:57 -050034my $git = 0;
35my %git_commits = ();
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070036my $check = 0;
37my $check_orig = 0;
38my $summary = 1;
39my $mailback = 0;
40my $summary_file = 0;
41my $show_types = 0;
Anas Nashif0f3d5472016-11-07 15:57:57 -050042my $list_types = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070043my $fix = 0;
44my $fix_inplace = 0;
45my $root;
46my %debug;
47my %camelcase = ();
48my %use_type = ();
49my @use = ();
50my %ignore_type = ();
51my @ignore = ();
Anas Nashif0f3d5472016-11-07 15:57:57 -050052my @exclude = ();
Anas Nashif1eb244c2017-10-01 17:06:36 -040053my $help = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070054my $configuration_file = ".checkpatch.conf";
55my $max_line_length = 80;
56my $ignore_perl_version = 0;
57my $minimum_perl_version = 5.10.0;
58my $min_conf_desc_length = 4;
59my $spelling_file = "$D/spelling.txt";
Anas Nashifcbfb62c2015-10-14 06:08:54 -040060my $codespell = 0;
61my $codespellfile = "/usr/share/codespell/dictionary.txt";
Anas Nashif0f3d5472016-11-07 15:57:57 -050062my $conststructsfile = "$D/const_structs.checkpatch";
Peter A. Bigote49e3c82020-08-10 10:37:32 -050063my $typedefsfile;
Anas Nashif1eb244c2017-10-01 17:06:36 -040064my $color = "auto";
Anas Nashifda871292017-04-21 08:52:01 -040065my $allow_c99_comments = 0;
Peter Bigot5b10fac2020-03-26 11:16:33 -050066# git output parsing needs US English output, so first set backtick child process LANGUAGE
67my $git_command ='export LANGUAGE=en_US.UTF-8; git';
Peter A. Bigote49e3c82020-08-10 10:37:32 -050068my $tabsize = 8;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070069
70sub help {
71 my ($exitcode) = @_;
72
73 print << "EOM";
74Usage: $P [OPTION]... [FILE]...
75Version: $V
76
77Options:
78 -q, --quiet quiet
79 --no-tree run without a kernel tree
80 --no-signoff do not check for 'Signed-off-by' line
81 --patch treat FILE as patchfile (default)
82 --emacs emacs compile window format
83 --terse one line per report
Anas Nashifcbfb62c2015-10-14 06:08:54 -040084 --showfile emit diffed file position, not input file position
Anas Nashif0f3d5472016-11-07 15:57:57 -050085 -g, --git treat FILE as a single commit or git revision range
86 single git commit with:
87 <rev>
88 <rev>^
89 <rev>~n
90 multiple git commits with:
91 <rev1>..<rev2>
92 <rev1>...<rev2>
93 <rev>-<count>
94 git merges are ignored
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070095 -f, --file treat FILE as regular source file
96 --subjective, --strict enable more subjective tests
Anas Nashif0f3d5472016-11-07 15:57:57 -050097 --list-types list the possible message types
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070098 --types TYPE(,TYPE2...) show only these comma separated message types
99 --ignore TYPE(,TYPE2...) ignore various comma separated message types
Anas Nashif92a12a12016-05-20 18:26:59 -0400100 --exclude DIR(,DIR22...) exclude directories
Anas Nashif1eb244c2017-10-01 17:06:36 -0400101 --show-types show the specific message type in the output
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500102 --max-line-length=n set the maximum line length, (default $max_line_length)
103 if exceeded, warn on patches
104 requires --strict for use with --file
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700105 --min-conf-desc-length=n set the min description length, if shorter, warn
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500106 --tab-size=n set the number of spaces for tab (default $tabsize)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700107 --root=PATH PATH to the kernel tree root
108 --no-summary suppress the per-file summary
109 --mailback only produce a report in case of warnings/errors
110 --summary-file include the filename in summary
111 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
112 'values', 'possible', 'type', and 'attr' (default
113 is all off)
114 --test-only=WORD report only warnings/errors containing WORD
115 literally
116 --fix EXPERIMENTAL - may create horrible results
117 If correctable single-line errors exist, create
118 "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
119 with potential errors corrected to the preferred
120 checkpatch style
121 --fix-inplace EXPERIMENTAL - may create horrible results
122 Is the same as --fix, but overwrites the input
123 file. It's your fault if there's no backup or git
124 --ignore-perl-version override checking of perl version. expect
125 runtime errors.
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400126 --codespell Use the codespell dictionary for spelling/typos
127 (default:/usr/share/codespell/dictionary.txt)
128 --codespellfile Use this codespell dictionary
Anas Nashif1eb244c2017-10-01 17:06:36 -0400129 --typedefsfile Read additional types from this file
130 --color[=WHEN] Use colors 'always', 'never', or only when output
131 is a terminal ('auto'). Default is 'auto'.
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700132 -h, --help, --version display this help and exit
133
134When FILE is - read standard input.
135EOM
136
137 exit($exitcode);
138}
139
Anas Nashif0f3d5472016-11-07 15:57:57 -0500140sub uniq {
141 my %seen;
142 return grep { !$seen{$_}++ } @_;
143}
144
145sub list_types {
146 my ($exitcode) = @_;
147
148 my $count = 0;
149
150 local $/ = undef;
151
152 open(my $script, '<', abs_path($P)) or
153 die "$P: Can't read '$P' $!\n";
154
155 my $text = <$script>;
156 close($script);
157
158 my @types = ();
Anas Nashif1eb244c2017-10-01 17:06:36 -0400159 # Also catch when type or level is passed through a variable
160 for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
Anas Nashif0f3d5472016-11-07 15:57:57 -0500161 push (@types, $_);
162 }
163 @types = sort(uniq(@types));
164 print("#\tMessage type\n\n");
165 foreach my $type (@types) {
166 print(++$count . "\t" . $type . "\n");
167 }
168
169 exit($exitcode);
170}
171
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700172my $conf = which_conf($configuration_file);
173if (-f $conf) {
174 my @conf_args;
175 open(my $conffile, '<', "$conf")
176 or warn "$P: Can't find a readable $configuration_file file $!\n";
177
178 while (<$conffile>) {
179 my $line = $_;
180
181 $line =~ s/\s*\n?$//g;
182 $line =~ s/^\s*//g;
183 $line =~ s/\s+/ /g;
184
185 next if ($line =~ m/^\s*#/);
186 next if ($line =~ m/^\s*$/);
187
188 my @words = split(" ", $line);
189 foreach my $word (@words) {
190 last if ($word =~ m/^#/);
191 push (@conf_args, $word);
192 }
193 }
194 close($conffile);
195 unshift(@ARGV, @conf_args) if @conf_args;
196}
197
Anas Nashif1eb244c2017-10-01 17:06:36 -0400198# Perl's Getopt::Long allows options to take optional arguments after a space.
199# Prevent --color by itself from consuming other arguments
200foreach (@ARGV) {
201 if ($_ eq "--color" || $_ eq "-color") {
202 $_ = "--color=$color";
203 }
204}
205
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700206GetOptions(
207 'q|quiet+' => \$quiet,
208 'tree!' => \$tree,
209 'signoff!' => \$chk_signoff,
210 'patch!' => \$chk_patch,
211 'emacs!' => \$emacs,
212 'terse!' => \$terse,
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400213 'showfile!' => \$showfile,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700214 'f|file!' => \$file,
Anas Nashif0f3d5472016-11-07 15:57:57 -0500215 'g|git!' => \$git,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700216 'subjective!' => \$check,
217 'strict!' => \$check,
218 'ignore=s' => \@ignore,
Anas Nashif1eb244c2017-10-01 17:06:36 -0400219 'exclude=s' => \@exclude,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700220 'types=s' => \@use,
221 'show-types!' => \$show_types,
Anas Nashif0f3d5472016-11-07 15:57:57 -0500222 'list-types!' => \$list_types,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700223 'max-line-length=i' => \$max_line_length,
224 'min-conf-desc-length=i' => \$min_conf_desc_length,
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500225 'tab-size=i' => \$tabsize,
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700226 'root=s' => \$root,
227 'summary!' => \$summary,
228 'mailback!' => \$mailback,
229 'summary-file!' => \$summary_file,
230 'fix!' => \$fix,
231 'fix-inplace!' => \$fix_inplace,
232 'ignore-perl-version!' => \$ignore_perl_version,
233 'debug=s' => \%debug,
234 'test-only=s' => \$tst_only,
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400235 'codespell!' => \$codespell,
236 'codespellfile=s' => \$codespellfile,
Anas Nashif1eb244c2017-10-01 17:06:36 -0400237 'typedefsfile=s' => \$typedefsfile,
238 'color=s' => \$color,
239 'no-color' => \$color, #keep old behaviors of -nocolor
240 'nocolor' => \$color, #keep old behaviors of -nocolor
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700241 'h|help' => \$help,
242 'version' => \$help
243) or help(1);
244
245help(0) if ($help);
246
Anas Nashif0f3d5472016-11-07 15:57:57 -0500247list_types(0) if ($list_types);
248
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700249$fix = 1 if ($fix_inplace);
250$check_orig = $check;
251
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500252die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
253
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700254my $exit = 0;
255
Peter Bigot5b10fac2020-03-26 11:16:33 -0500256my $perl_version_ok = 1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700257if ($^V && $^V lt $minimum_perl_version) {
Peter Bigot5b10fac2020-03-26 11:16:33 -0500258 $perl_version_ok = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700259 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
Peter Bigot5b10fac2020-03-26 11:16:33 -0500260 exit(1) if (!$ignore_perl_version);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700261}
262
Anas Nashif0f3d5472016-11-07 15:57:57 -0500263#if no filenames are given, push '-' to read patch from stdin
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700264if ($#ARGV < 0) {
Anas Nashif0f3d5472016-11-07 15:57:57 -0500265 push(@ARGV, '-');
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700266}
267
Anas Nashif1eb244c2017-10-01 17:06:36 -0400268if ($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 {
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500277 die "$P: Invalid color mode: $color\n";
Anas Nashif1eb244c2017-10-01 17:06:36 -0400278}
279
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500280# skip TAB size 1 to avoid additional checks on $tabsize - 1
281die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
282
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700283sub hash_save_array_words {
284 my ($hashRef, $arrayRef) = @_;
285
286 my @array = split(/,/, join(',', @$arrayRef));
287 foreach my $word (@array) {
288 $word =~ s/\s*\n?$//g;
289 $word =~ s/^\s*//g;
290 $word =~ s/\s+/ /g;
291 $word =~ tr/[a-z]/[A-Z]/;
292
293 next if ($word =~ m/^\s*#/);
294 next if ($word =~ m/^\s*$/);
295
296 $hashRef->{$word}++;
297 }
298}
299
300sub hash_show_words {
301 my ($hashRef, $prefix) = @_;
302
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400303 if (keys %$hashRef) {
304 print "\nNOTE: $prefix message types:";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700305 foreach my $word (sort keys %$hashRef) {
306 print " $word";
307 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400308 print "\n";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700309 }
310}
311
312hash_save_array_words(\%ignore_type, \@ignore);
313hash_save_array_words(\%use_type, \@use);
314
315my $dbg_values = 0;
316my $dbg_possible = 0;
317my $dbg_type = 0;
318my $dbg_attr = 0;
319for my $key (keys %debug) {
320 ## no critic
321 eval "\${dbg_$key} = '$debug{$key}';";
322 die "$@" if ($@);
323}
324
325my $rpt_cleaners = 0;
326
327if ($terse) {
328 $emacs = 1;
329 $quiet++;
330}
331
332if ($tree) {
333 if (defined $root) {
334 if (!top_of_kernel_tree($root)) {
335 die "$P: $root: --root does not point at a valid tree\n";
336 }
337 } else {
338 if (top_of_kernel_tree('.')) {
339 $root = '.';
340 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
341 top_of_kernel_tree($1)) {
342 $root = $1;
343 }
344 }
345
346 if (!defined $root) {
347 print "Must be run from the top-level dir. of a kernel tree\n";
348 exit(2);
349 }
350}
351
352my $emitted_corrupt = 0;
353
354our $Ident = qr{
355 [A-Za-z_][A-Za-z\d_]*
356 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
357 }x;
358our $Storage = qr{extern|static|asmlinkage};
359our $Sparse = qr{
360 __user|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700361 __force|
362 __iomem|
363 __must_check|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700364 __kprobes|
365 __ref|
Peter Bigot5b10fac2020-03-26 11:16:33 -0500366 __refconst|
367 __refdata|
Anas Nashif0f3d5472016-11-07 15:57:57 -0500368 __rcu|
369 __private
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700370 }x;
371our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
372our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
373our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
374our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
375our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
376
377# Notes to $Attribute:
378# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
379our $Attribute = qr{
380 const|
381 __percpu|
382 __nocast|
383 __safe|
Anas Nashif1eb244c2017-10-01 17:06:36 -0400384 __bitwise|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700385 __packed__|
386 __packed2__|
387 __naked|
388 __maybe_unused|
389 __always_unused|
390 __noreturn|
391 __used|
392 __cold|
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400393 __pure|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700394 __noclone|
395 __deprecated|
396 __read_mostly|
Peter Bigot5b10fac2020-03-26 11:16:33 -0500397 __ro_after_init|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700398 __kprobes|
399 $InitAttribute|
400 ____cacheline_aligned|
401 ____cacheline_aligned_in_smp|
402 ____cacheline_internodealigned_in_smp|
Andrew Boiefa94ee72017-09-28 16:54:35 -0700403 __weak|
Flavio Ceoline86ec972019-12-03 13:49:54 -0800404 __syscall
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700405 }x;
406our $Modifier;
407our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
408our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
409our $Lval = qr{$Ident(?:$Member)*};
410
411our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
412our $Binary = qr{(?i)0b[01]+$Int_type?};
413our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
414our $Int = qr{[0-9]+$Int_type?};
415our $Octal = qr{0[0-7]+$Int_type?};
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400416our $String = qr{"[X\t]*"};
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700417our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
418our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
419our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
420our $Float = qr{$Float_hex|$Float_dec|$Float_int};
421our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
422our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
423our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
424our $Arithmetic = qr{\+|-|\*|\/|%};
425our $Operators = qr{
426 <=|>=|==|!=|
427 =>|->|<<|>>|<|>|!|~|
428 &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
429 }x;
430
431our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
432
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400433our $BasicType;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700434our $NonptrType;
435our $NonptrTypeMisordered;
436our $NonptrTypeWithAttr;
437our $Type;
438our $TypeMisordered;
439our $Declare;
440our $DeclareMisordered;
441
442our $NON_ASCII_UTF8 = qr{
443 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
444 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
445 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
446 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
447 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
448 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
449 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
450}x;
451
452our $UTF8 = qr{
453 [\x09\x0A\x0D\x20-\x7E] # ASCII
454 | $NON_ASCII_UTF8
455}x;
456
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400457our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
458our $typeOtherOSTypedefs = qr{(?x:
459 u_(?:char|short|int|long) | # bsd
460 u(?:nchar|short|int|long) # sysv
461)};
462our $typeKernelTypedefs = qr{(?x:
Kumar Gala93da8dc2020-06-02 12:38:11 -0500463 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700464 atomic_t
465)};
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400466our $typeTypedefs = qr{(?x:
467 $typeC99Typedefs\b|
468 $typeOtherOSTypedefs\b|
469 $typeKernelTypedefs\b
470)};
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700471
Anas Nashif76b09132016-02-20 13:53:35 -0500472our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
473
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700474our $logFunctions = qr{(?x:
Anas Nashif1eb244c2017-10-01 17:06:36 -0400475 printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700476 (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
Peter Bigot5b10fac2020-03-26 11:16:33 -0500477 TP_printk|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700478 WARN(?:_RATELIMIT|_ONCE|)|
479 panic|
480 MODULE_[A-Z_]+|
481 seq_vprintf|seq_printf|seq_puts
482)};
483
Peter Bigot5b10fac2020-03-26 11:16:33 -0500484our $allocFunctions = qr{(?x:
485 (?:(?:devm_)?
486 (?:kv|k|v)[czm]alloc(?:_node|_array)? |
487 kstrdup(?:_const)? |
488 kmemdup(?:_nul)?) |
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500489 (?:\w+)?alloc_skb(?:_ip_align)? |
Peter Bigot5b10fac2020-03-26 11:16:33 -0500490 # dev_alloc_skb/netdev_alloc_skb, et al
491 dma_alloc_coherent
492)};
493
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700494our $signature_tags = qr{(?xi:
495 Signed-off-by:|
Peter Bigot5b10fac2020-03-26 11:16:33 -0500496 Co-developed-by:|
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700497 Acked-by:|
498 Tested-by:|
499 Reviewed-by:|
500 Reported-by:|
501 Suggested-by:|
502 To:|
503 Cc:
504)};
505
506our @typeListMisordered = (
507 qr{char\s+(?:un)?signed},
508 qr{int\s+(?:(?:un)?signed\s+)?short\s},
509 qr{int\s+short(?:\s+(?:un)?signed)},
510 qr{short\s+int(?:\s+(?:un)?signed)},
511 qr{(?:un)?signed\s+int\s+short},
512 qr{short\s+(?:un)?signed},
513 qr{long\s+int\s+(?:un)?signed},
514 qr{int\s+long\s+(?:un)?signed},
515 qr{long\s+(?:un)?signed\s+int},
516 qr{int\s+(?:un)?signed\s+long},
517 qr{int\s+(?:un)?signed},
518 qr{int\s+long\s+long\s+(?:un)?signed},
519 qr{long\s+long\s+int\s+(?:un)?signed},
520 qr{long\s+long\s+(?:un)?signed\s+int},
521 qr{long\s+long\s+(?:un)?signed},
522 qr{long\s+(?:un)?signed},
523);
524
525our @typeList = (
526 qr{void},
527 qr{(?:(?:un)?signed\s+)?char},
528 qr{(?:(?:un)?signed\s+)?short\s+int},
529 qr{(?:(?:un)?signed\s+)?short},
530 qr{(?:(?:un)?signed\s+)?int},
531 qr{(?:(?:un)?signed\s+)?long\s+int},
532 qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
533 qr{(?:(?:un)?signed\s+)?long\s+long},
534 qr{(?:(?:un)?signed\s+)?long},
535 qr{(?:un)?signed},
536 qr{float},
537 qr{double},
538 qr{bool},
539 qr{struct\s+$Ident},
540 qr{union\s+$Ident},
541 qr{enum\s+$Ident},
542 qr{${Ident}_t},
543 qr{${Ident}_handler},
544 qr{${Ident}_handler_fn},
545 @typeListMisordered,
546);
Anas Nashif76b09132016-02-20 13:53:35 -0500547
548our $C90_int_types = qr{(?x:
549 long\s+long\s+int\s+(?:un)?signed|
550 long\s+long\s+(?:un)?signed\s+int|
551 long\s+long\s+(?:un)?signed|
552 (?:(?:un)?signed\s+)?long\s+long\s+int|
553 (?:(?:un)?signed\s+)?long\s+long|
554 int\s+long\s+long\s+(?:un)?signed|
555 int\s+(?:(?:un)?signed\s+)?long\s+long|
556
557 long\s+int\s+(?:un)?signed|
558 long\s+(?:un)?signed\s+int|
559 long\s+(?:un)?signed|
560 (?:(?:un)?signed\s+)?long\s+int|
561 (?:(?:un)?signed\s+)?long|
562 int\s+long\s+(?:un)?signed|
563 int\s+(?:(?:un)?signed\s+)?long|
564
565 int\s+(?:un)?signed|
566 (?:(?:un)?signed\s+)?int
567)};
568
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400569our @typeListFile = ();
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700570our @typeListWithAttr = (
571 @typeList,
572 qr{struct\s+$InitAttribute\s+$Ident},
573 qr{union\s+$InitAttribute\s+$Ident},
574);
575
576our @modifierList = (
577 qr{fastcall},
578);
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400579our @modifierListFile = ();
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700580
581our @mode_permission_funcs = (
582 ["module_param", 3],
583 ["module_param_(?:array|named|string)", 4],
584 ["module_param_array_named", 5],
585 ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
586 ["proc_create(?:_data|)", 2],
Anas Nashif0f3d5472016-11-07 15:57:57 -0500587 ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
588 ["IIO_DEV_ATTR_[A-Z_]+", 1],
589 ["SENSOR_(?:DEVICE_|)ATTR_2", 2],
590 ["SENSOR_TEMPLATE(?:_2|)", 3],
591 ["__ATTR", 2],
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700592);
593
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500594my $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
595
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700596#Create a search pattern for all these functions to speed up a loop below
597our $mode_perms_search = "";
598foreach my $entry (@mode_permission_funcs) {
599 $mode_perms_search .= '|' if ($mode_perms_search ne "");
600 $mode_perms_search .= $entry->[0];
601}
Peter Bigot5b10fac2020-03-26 11:16:33 -0500602$mode_perms_search = "(?:${mode_perms_search})";
603
604our %deprecated_apis = (
605 "synchronize_rcu_bh" => "synchronize_rcu",
606 "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited",
607 "call_rcu_bh" => "call_rcu",
608 "rcu_barrier_bh" => "rcu_barrier",
609 "synchronize_sched" => "synchronize_rcu",
610 "synchronize_sched_expedited" => "synchronize_rcu_expedited",
611 "call_rcu_sched" => "call_rcu",
612 "rcu_barrier_sched" => "rcu_barrier",
613 "get_state_synchronize_sched" => "get_state_synchronize_rcu",
614 "cond_synchronize_sched" => "cond_synchronize_rcu",
615);
616
617#Create a search pattern for all these strings to speed up a loop below
618our $deprecated_apis_search = "";
619foreach my $entry (keys %deprecated_apis) {
620 $deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
621 $deprecated_apis_search .= $entry;
622}
623$deprecated_apis_search = "(?:${deprecated_apis_search})";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700624
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400625our $mode_perms_world_writable = qr{
626 S_IWUGO |
627 S_IWOTH |
628 S_IRWXUGO |
629 S_IALLUGO |
630 0[0-7][0-7][2367]
631}x;
632
Anas Nashif0f3d5472016-11-07 15:57:57 -0500633our %mode_permission_string_types = (
634 "S_IRWXU" => 0700,
635 "S_IRUSR" => 0400,
636 "S_IWUSR" => 0200,
637 "S_IXUSR" => 0100,
638 "S_IRWXG" => 0070,
639 "S_IRGRP" => 0040,
640 "S_IWGRP" => 0020,
641 "S_IXGRP" => 0010,
642 "S_IRWXO" => 0007,
643 "S_IROTH" => 0004,
644 "S_IWOTH" => 0002,
645 "S_IXOTH" => 0001,
646 "S_IRWXUGO" => 0777,
647 "S_IRUGO" => 0444,
648 "S_IWUGO" => 0222,
649 "S_IXUGO" => 0111,
650);
651
652#Create a search pattern for all these strings to speed up a loop below
653our $mode_perms_string_search = "";
654foreach my $entry (keys %mode_permission_string_types) {
655 $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
656 $mode_perms_string_search .= $entry;
657}
Peter Bigot5b10fac2020-03-26 11:16:33 -0500658our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
659our $multi_mode_perms_string_search = qr{
660 ${single_mode_perms_string_search}
661 (?:\s*\|\s*${single_mode_perms_string_search})*
662}x;
663
664sub perms_to_octal {
665 my ($string) = @_;
666
667 return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
668
669 my $val = "";
670 my $oval = "";
671 my $to = 0;
672 my $curpos = 0;
673 my $lastpos = 0;
674 while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
675 $curpos = pos($string);
676 my $match = $2;
677 my $omatch = $1;
678 last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
679 $lastpos = $curpos;
680 $to |= $mode_permission_string_types{$match};
681 $val .= '\s*\|\s*' if ($val ne "");
682 $val .= $match;
683 $oval .= $omatch;
684 }
685 $oval =~ s/^\s*\|\s*//;
686 $oval =~ s/\s*\|\s*$//;
687 return sprintf("%04o", $to);
688}
Anas Nashif0f3d5472016-11-07 15:57:57 -0500689
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700690our $allowed_asm_includes = qr{(?x:
691 irq|
692 memory|
693 time|
694 reboot
695)};
696# memory.h: ARM has a custom one
697
698# Load common spelling mistakes and build regular expression list.
699my $misspellings;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700700my %spelling_fix;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700701
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400702if (open(my $spelling, '<', $spelling_file)) {
703 while (<$spelling>) {
704 my $line = $_;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700705
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400706 $line =~ s/\s*\n?$//g;
707 $line =~ s/^\s*//g;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700708
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400709 next if ($line =~ m/^\s*#/);
710 next if ($line =~ m/^\s*$/);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700711
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400712 my ($suspect, $fix) = split(/\|\|/, $line);
713
714 $spelling_fix{$suspect} = $fix;
715 }
716 close($spelling);
717} else {
718 warn "No typos will be found - file '$spelling_file': $!\n";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700719}
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400720
721if ($codespell) {
722 if (open(my $spelling, '<', $codespellfile)) {
723 while (<$spelling>) {
724 my $line = $_;
725
726 $line =~ s/\s*\n?$//g;
727 $line =~ s/^\s*//g;
728
729 next if ($line =~ m/^\s*#/);
730 next if ($line =~ m/^\s*$/);
731 next if ($line =~ m/, disabled/i);
732
733 $line =~ s/,.*$//;
734
735 my ($suspect, $fix) = split(/->/, $line);
736
737 $spelling_fix{$suspect} = $fix;
738 }
739 close($spelling);
740 } else {
741 warn "No codespell typos will be found - file '$codespellfile': $!\n";
742 }
743}
744
745$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700746
Anas Nashif1eb244c2017-10-01 17:06:36 -0400747sub read_words {
748 my ($wordsRef, $file) = @_;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500749
Anas Nashif1eb244c2017-10-01 17:06:36 -0400750 if (open(my $words, '<', $file)) {
751 while (<$words>) {
752 my $line = $_;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500753
Anas Nashif1eb244c2017-10-01 17:06:36 -0400754 $line =~ s/\s*\n?$//g;
755 $line =~ s/^\s*//g;
756
757 next if ($line =~ m/^\s*#/);
758 next if ($line =~ m/^\s*$/);
759 if ($line =~ /\s/) {
760 print("$file: '$line' invalid - ignored\n");
761 next;
762 }
763
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500764 $$wordsRef .= '|' if (defined $$wordsRef);
Anas Nashif1eb244c2017-10-01 17:06:36 -0400765 $$wordsRef .= $line;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500766 }
Anas Nashif1eb244c2017-10-01 17:06:36 -0400767 close($file);
768 return 1;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500769 }
Anas Nashif1eb244c2017-10-01 17:06:36 -0400770
771 return 0;
Anas Nashif0f3d5472016-11-07 15:57:57 -0500772}
773
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500774my $const_structs;
775#if (show_type("CONST_STRUCT")) {
776# read_words(\$const_structs, $conststructsfile)
777# or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
778#}
Anas Nashif1eb244c2017-10-01 17:06:36 -0400779
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500780if (defined($typedefsfile)) {
781 my $typeOtherTypedefs;
Anas Nashif1eb244c2017-10-01 17:06:36 -0400782 read_words(\$typeOtherTypedefs, $typedefsfile)
783 or warn "No additional types will be considered - file '$typedefsfile': $!\n";
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500784 $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
Anas Nashif1eb244c2017-10-01 17:06:36 -0400785}
Anas Nashif1eb244c2017-10-01 17:06:36 -0400786
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700787sub build_types {
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400788 my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
789 my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700790 my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
791 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
792 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400793 $BasicType = qr{
794 (?:$typeTypedefs\b)|
795 (?:${all}\b)
796 }x;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700797 $NonptrType = qr{
798 (?:$Modifier\s+|const\s+)*
799 (?:
800 (?:typeof|__typeof__)\s*\([^\)]*\)|
801 (?:$typeTypedefs\b)|
802 (?:${all}\b)
803 )
804 (?:\s+$Modifier|\s+const)*
805 }x;
806 $NonptrTypeMisordered = qr{
807 (?:$Modifier\s+|const\s+)*
808 (?:
809 (?:${Misordered}\b)
810 )
811 (?:\s+$Modifier|\s+const)*
812 }x;
813 $NonptrTypeWithAttr = qr{
814 (?:$Modifier\s+|const\s+)*
815 (?:
816 (?:typeof|__typeof__)\s*\([^\)]*\)|
817 (?:$typeTypedefs\b)|
818 (?:${allWithAttr}\b)
819 )
820 (?:\s+$Modifier|\s+const)*
821 }x;
822 $Type = qr{
823 $NonptrType
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500824 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700825 (?:\s+$Inline|\s+$Modifier)*
826 }x;
827 $TypeMisordered = qr{
828 $NonptrTypeMisordered
Peter A. Bigote49e3c82020-08-10 10:37:32 -0500829 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700830 (?:\s+$Inline|\s+$Modifier)*
831 }x;
832 $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
833 $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
834}
835build_types();
836
837our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
838
839# Using $balanced_parens, $LvalOrFunc, or $FuncArg
840# requires at least perl version v5.10.0
841# Any use must be runtime checked with $^V
842
843our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
844our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400845our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700846
847our $declaration_macros = qr{(?x:
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400848 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
Anas Nashif1eb244c2017-10-01 17:06:36 -0400849 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
Peter Bigot5b10fac2020-03-26 11:16:33 -0500850 (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700851)};
852
853sub deparenthesize {
854 my ($string) = @_;
855 return "" if (!defined($string));
856
857 while ($string =~ /^\s*\(.*\)\s*$/) {
858 $string =~ s@^\s*\(\s*@@;
859 $string =~ s@\s*\)\s*$@@;
860 }
861
862 $string =~ s@\s+@ @g;
863
864 return $string;
865}
866
867sub seed_camelcase_file {
868 my ($file) = @_;
869
870 return if (!(-f $file));
871
872 local $/;
873
874 open(my $include_file, '<', "$file")
875 or warn "$P: Can't read '$file' $!\n";
876 my $text = <$include_file>;
877 close($include_file);
878
879 my @lines = split('\n', $text);
880
881 foreach my $line (@lines) {
882 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
883 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
884 $camelcase{$1} = 1;
885 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
886 $camelcase{$1} = 1;
887 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
888 $camelcase{$1} = 1;
889 }
890 }
891}
892
Peter Bigot5b10fac2020-03-26 11:16:33 -0500893our %maintained_status = ();
894
Anas Nashif1eb244c2017-10-01 17:06:36 -0400895sub is_maintained_obsolete {
896 my ($filename) = @_;
897
898 return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
899
Peter Bigot5b10fac2020-03-26 11:16:33 -0500900 if (!exists($maintained_status{$filename})) {
901 $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
902 }
Anas Nashif1eb244c2017-10-01 17:06:36 -0400903
Peter Bigot5b10fac2020-03-26 11:16:33 -0500904 return $maintained_status{$filename} =~ /obsolete/i;
905}
906
907sub is_SPDX_License_valid {
908 my ($license) = @_;
909
910 return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
911
912 my $root_path = abs_path($root);
913 my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
914 return 0 if ($status ne "");
915 return 1;
Anas Nashif1eb244c2017-10-01 17:06:36 -0400916}
917
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700918my $camelcase_seeded = 0;
919sub seed_camelcase_includes {
920 return if ($camelcase_seeded);
921
922 my $files;
923 my $camelcase_cache = "";
924 my @include_files = ();
925
926 $camelcase_seeded = 1;
927
928 if (-e ".git") {
Peter Bigot5b10fac2020-03-26 11:16:33 -0500929 my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700930 chomp $git_last_include_commit;
931 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
932 } else {
933 my $last_mod_date = 0;
934 $files = `find $root/include -name "*.h"`;
935 @include_files = split('\n', $files);
936 foreach my $file (@include_files) {
937 my $date = POSIX::strftime("%Y%m%d%H%M",
938 localtime((stat $file)[9]));
939 $last_mod_date = $date if ($last_mod_date < $date);
940 }
941 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
942 }
943
944 if ($camelcase_cache ne "" && -f $camelcase_cache) {
945 open(my $camelcase_file, '<', "$camelcase_cache")
946 or warn "$P: Can't read '$camelcase_cache' $!\n";
947 while (<$camelcase_file>) {
948 chomp;
949 $camelcase{$_} = 1;
950 }
951 close($camelcase_file);
952
953 return;
954 }
955
956 if (-e ".git") {
Peter Bigot5b10fac2020-03-26 11:16:33 -0500957 $files = `${git_command} ls-files "include/*.h"`;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700958 @include_files = split('\n', $files);
959 }
960
961 foreach my $file (@include_files) {
962 seed_camelcase_file($file);
963 }
964
965 if ($camelcase_cache ne "") {
966 unlink glob ".checkpatch-camelcase.*";
967 open(my $camelcase_file, '>', "$camelcase_cache")
968 or warn "$P: Can't write '$camelcase_cache' $!\n";
969 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
970 print $camelcase_file ("$_\n");
971 }
972 close($camelcase_file);
973 }
974}
975
976sub git_commit_info {
977 my ($commit, $id, $desc) = @_;
978
979 return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
980
Peter Bigot5b10fac2020-03-26 11:16:33 -0500981 my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700982 $output =~ s/^\s*//gm;
983 my @lines = split("\n", $output);
984
Anas Nashifcbfb62c2015-10-14 06:08:54 -0400985 return ($id, $desc) if ($#lines < 0);
986
Peter Bigot5b10fac2020-03-26 11:16:33 -0500987 if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700988# Maybe one day convert this block of bash into something that returns
989# all matching commit ids, but it's very slow...
990#
991# echo "checking commits $1..."
992# git rev-list --remotes | grep -i "^$1" |
993# while read line ; do
994# git log --format='%H %s' -1 $line |
995# echo "commit $(cut -c 1-12,41-)"
996# done
997 } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
Anas Nashif1eb244c2017-10-01 17:06:36 -0400998 $id = undef;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700999 } else {
1000 $id = substr($lines[0], 0, 12);
1001 $desc = substr($lines[0], 41);
1002 }
1003
1004 return ($id, $desc);
1005}
1006
1007$chk_signoff = 0 if ($file);
1008
1009my @rawlines = ();
1010my @lines = ();
1011my @fixed = ();
1012my @fixed_inserted = ();
1013my @fixed_deleted = ();
1014my $fixlinenr = -1;
1015
Anas Nashif0f3d5472016-11-07 15:57:57 -05001016# If input is git commits, extract all commits from the commit expressions.
1017# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
1018die "$P: No git repository found\n" if ($git && !-e ".git");
1019
1020if ($git) {
1021 my @commits = ();
1022 foreach my $commit_expr (@ARGV) {
1023 my $git_range;
1024 if ($commit_expr =~ m/^(.*)-(\d+)$/) {
1025 $git_range = "-$2 $1";
1026 } elsif ($commit_expr =~ m/\.\./) {
1027 $git_range = "$commit_expr";
1028 } else {
1029 $git_range = "-1 $commit_expr";
1030 }
Peter Bigot5b10fac2020-03-26 11:16:33 -05001031 my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
Anas Nashif0f3d5472016-11-07 15:57:57 -05001032 foreach my $line (split(/\n/, $lines)) {
1033 $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
1034 next if (!defined($1) || !defined($2));
1035 my $sha1 = $1;
1036 my $subject = $2;
1037 unshift(@commits, $sha1);
1038 $git_commits{$sha1} = $subject;
1039 }
1040 }
1041 die "$P: no git commits after extraction!\n" if (@commits == 0);
1042 @ARGV = @commits;
1043}
1044
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001045my $vname;
Peter Bigot5b10fac2020-03-26 11:16:33 -05001046$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001047for my $filename (@ARGV) {
1048 my $FILE;
Anas Nashif0f3d5472016-11-07 15:57:57 -05001049 if ($git) {
1050 open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
1051 die "$P: $filename: git format-patch failed - $!\n";
1052 } elsif ($file) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001053 open($FILE, '-|', "diff -u /dev/null $filename") ||
1054 die "$P: $filename: diff failed - $!\n";
1055 } elsif ($filename eq '-') {
1056 open($FILE, '<&STDIN');
1057 } else {
1058 open($FILE, '<', "$filename") ||
1059 die "$P: $filename: open failed - $!\n";
1060 }
1061 if ($filename eq '-') {
1062 $vname = 'Your patch';
Anas Nashif0f3d5472016-11-07 15:57:57 -05001063 } elsif ($git) {
1064 $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001065 } else {
1066 $vname = $filename;
1067 }
1068 while (<$FILE>) {
1069 chomp;
1070 push(@rawlines, $_);
Peter A. Bigote49e3c82020-08-10 10:37:32 -05001071 $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001072 }
1073 close($FILE);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001074
1075 if ($#ARGV > 0 && $quiet == 0) {
1076 print '-' x length($vname) . "\n";
1077 print "$vname\n";
1078 print '-' x length($vname) . "\n";
1079 }
1080
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001081 if (!process($filename)) {
1082 $exit = 1;
1083 }
1084 @rawlines = ();
1085 @lines = ();
1086 @fixed = ();
1087 @fixed_inserted = ();
1088 @fixed_deleted = ();
1089 $fixlinenr = -1;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001090 @modifierListFile = ();
1091 @typeListFile = ();
1092 build_types();
1093}
1094
1095if (!$quiet) {
1096 hash_show_words(\%use_type, "Used");
1097 hash_show_words(\%ignore_type, "Ignored");
1098
Peter Bigot5b10fac2020-03-26 11:16:33 -05001099 if (!$perl_version_ok) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001100 print << "EOM"
1101
1102NOTE: perl $^V is not modern enough to detect all possible issues.
Peter Bigot5b10fac2020-03-26 11:16:33 -05001103 An upgrade to at least perl $minimum_perl_version is suggested.
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001104EOM
1105 }
1106 if ($exit) {
1107 print << "EOM"
1108
1109NOTE: If any of the errors are false positives, please report
Anas Nashif1eb244c2017-10-01 17:06:36 -04001110 them to the maintainers.
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001111EOM
1112 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001113}
1114
1115exit($exit);
1116
1117sub top_of_kernel_tree {
1118 my ($root) = @_;
1119
1120 my @tree_check = (
Antony Pavlovf08148e2019-05-09 16:39:59 +03001121 "LICENSE", "CODEOWNERS", "Kconfig", "Makefile",
1122 "README.rst", "doc", "arch", "include", "drivers",
1123 "boards", "kernel", "lib", "scripts",
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001124 );
1125
1126 foreach my $check (@tree_check) {
1127 if (! -e $root . '/' . $check) {
1128 return 0;
1129 }
1130 }
1131 return 1;
1132}
1133
1134sub parse_email {
1135 my ($formatted_email) = @_;
1136
1137 my $name = "";
1138 my $address = "";
1139 my $comment = "";
1140
1141 if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
1142 $name = $1;
1143 $address = $2;
1144 $comment = $3 if defined $3;
1145 } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
1146 $address = $1;
1147 $comment = $2 if defined $2;
1148 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1149 $address = $1;
1150 $comment = $2 if defined $2;
Peter Bigot5b10fac2020-03-26 11:16:33 -05001151 $formatted_email =~ s/\Q$address\E.*$//;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001152 $name = $formatted_email;
1153 $name = trim($name);
1154 $name =~ s/^\"|\"$//g;
1155 # If there's a name left after stripping spaces and
1156 # leading quotes, and the address doesn't have both
1157 # leading and trailing angle brackets, the address
1158 # is invalid. ie:
1159 # "joe smith joe@smith.com" bad
1160 # "joe smith <joe@smith.com" bad
1161 if ($name ne "" && $address !~ /^<[^>]+>$/) {
1162 $name = "";
1163 $address = "";
1164 $comment = "";
1165 }
1166 }
1167
1168 $name = trim($name);
1169 $name =~ s/^\"|\"$//g;
1170 $address = trim($address);
1171 $address =~ s/^\<|\>$//g;
1172
1173 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1174 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1175 $name = "\"$name\"";
1176 }
1177
1178 return ($name, $address, $comment);
1179}
1180
1181sub format_email {
1182 my ($name, $address) = @_;
1183
1184 my $formatted_email;
1185
1186 $name = trim($name);
1187 $name =~ s/^\"|\"$//g;
1188 $address = trim($address);
1189
1190 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1191 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1192 $name = "\"$name\"";
1193 }
1194
1195 if ("$name" eq "") {
1196 $formatted_email = "$address";
1197 } else {
1198 $formatted_email = "$name <$address>";
1199 }
1200
1201 return $formatted_email;
1202}
1203
1204sub which {
1205 my ($bin) = @_;
1206
1207 foreach my $path (split(/:/, $ENV{PATH})) {
1208 if (-e "$path/$bin") {
1209 return "$path/$bin";
1210 }
1211 }
1212
1213 return "";
1214}
1215
1216sub which_conf {
1217 my ($conf) = @_;
1218
1219 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1220 if (-e "$path/$conf") {
1221 return "$path/$conf";
1222 }
1223 }
1224
1225 return "";
1226}
1227
1228sub expand_tabs {
1229 my ($str) = @_;
1230
1231 my $res = '';
1232 my $n = 0;
1233 for my $c (split(//, $str)) {
1234 if ($c eq "\t") {
1235 $res .= ' ';
1236 $n++;
Peter A. Bigote49e3c82020-08-10 10:37:32 -05001237 for (; ($n % $tabsize) != 0; $n++) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001238 $res .= ' ';
1239 }
1240 next;
1241 }
1242 $res .= $c;
1243 $n++;
1244 }
1245
1246 return $res;
1247}
1248sub copy_spacing {
1249 (my $res = shift) =~ tr/\t/ /c;
1250 return $res;
1251}
1252
1253sub line_stats {
1254 my ($line) = @_;
1255
1256 # Drop the diff line leader and expand tabs
1257 $line =~ s/^.//;
1258 $line = expand_tabs($line);
1259
1260 # Pick the indent from the front of the line.
1261 my ($white) = ($line =~ /^(\s*)/);
1262
1263 return (length($line), length($white));
1264}
1265
1266my $sanitise_quote = '';
1267
1268sub sanitise_line_reset {
1269 my ($in_comment) = @_;
1270
1271 if ($in_comment) {
1272 $sanitise_quote = '*/';
1273 } else {
1274 $sanitise_quote = '';
1275 }
1276}
1277sub sanitise_line {
1278 my ($line) = @_;
1279
1280 my $res = '';
1281 my $l = '';
1282
1283 my $qlen = 0;
1284 my $off = 0;
1285 my $c;
1286
1287 # Always copy over the diff marker.
1288 $res = substr($line, 0, 1);
1289
1290 for ($off = 1; $off < length($line); $off++) {
1291 $c = substr($line, $off, 1);
1292
Peter Bigot5b10fac2020-03-26 11:16:33 -05001293 # Comments we are whacking completely including the begin
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001294 # and end, all to $;.
1295 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1296 $sanitise_quote = '*/';
1297
1298 substr($res, $off, 2, "$;$;");
1299 $off++;
1300 next;
1301 }
1302 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1303 $sanitise_quote = '';
1304 substr($res, $off, 2, "$;$;");
1305 $off++;
1306 next;
1307 }
1308 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1309 $sanitise_quote = '//';
1310
1311 substr($res, $off, 2, $sanitise_quote);
1312 $off++;
1313 next;
1314 }
1315
1316 # A \ in a string means ignore the next character.
1317 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1318 $c eq "\\") {
1319 substr($res, $off, 2, 'XX');
1320 $off++;
1321 next;
1322 }
1323 # Regular quotes.
1324 if ($c eq "'" || $c eq '"') {
1325 if ($sanitise_quote eq '') {
1326 $sanitise_quote = $c;
1327
1328 substr($res, $off, 1, $c);
1329 next;
1330 } elsif ($sanitise_quote eq $c) {
1331 $sanitise_quote = '';
1332 }
1333 }
1334
1335 #print "c<$c> SQ<$sanitise_quote>\n";
1336 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1337 substr($res, $off, 1, $;);
1338 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1339 substr($res, $off, 1, $;);
1340 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1341 substr($res, $off, 1, 'X');
1342 } else {
1343 substr($res, $off, 1, $c);
1344 }
1345 }
1346
1347 if ($sanitise_quote eq '//') {
1348 $sanitise_quote = '';
1349 }
1350
1351 # The pathname on a #include may be surrounded by '<' and '>'.
1352 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1353 my $clean = 'X' x length($1);
1354 $res =~ s@\<.*\>@<$clean>@;
1355
1356 # The whole of a #error is a string.
1357 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1358 my $clean = 'X' x length($1);
1359 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1360 }
1361
Anas Nashif0f3d5472016-11-07 15:57:57 -05001362 if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1363 my $match = $1;
1364 $res =~ s/\Q$match\E/"$;" x length($match)/e;
1365 }
1366
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001367 return $res;
1368}
1369
1370sub get_quoted_string {
1371 my ($line, $rawline) = @_;
1372
Peter Bigot5b10fac2020-03-26 11:16:33 -05001373 return "" if (!defined($line) || !defined($rawline));
Anas Nashifcbfb62c2015-10-14 06:08:54 -04001374 return "" if ($line !~ m/($String)/g);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001375 return substr($rawline, $-[0], $+[0] - $-[0]);
1376}
1377
1378sub ctx_statement_block {
1379 my ($linenr, $remain, $off) = @_;
1380 my $line = $linenr - 1;
1381 my $blk = '';
1382 my $soff = $off;
1383 my $coff = $off - 1;
1384 my $coff_set = 0;
1385
1386 my $loff = 0;
1387
1388 my $type = '';
1389 my $level = 0;
1390 my @stack = ();
1391 my $p;
1392 my $c;
1393 my $len = 0;
1394
1395 my $remainder;
1396 while (1) {
1397 @stack = (['', 0]) if ($#stack == -1);
1398
1399 #warn "CSB: blk<$blk> remain<$remain>\n";
1400 # If we are about to drop off the end, pull in more
1401 # context.
1402 if ($off >= $len) {
1403 for (; $remain > 0; $line++) {
1404 last if (!defined $lines[$line]);
1405 next if ($lines[$line] =~ /^-/);
1406 $remain--;
1407 $loff = $len;
1408 $blk .= $lines[$line] . "\n";
1409 $len = length($blk);
1410 $line++;
1411 last;
1412 }
1413 # Bail if there is no further context.
1414 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
1415 if ($off >= $len) {
1416 last;
1417 }
1418 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1419 $level++;
1420 $type = '#';
1421 }
1422 }
1423 $p = $c;
1424 $c = substr($blk, $off, 1);
1425 $remainder = substr($blk, $off);
1426
1427 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
1428
1429 # Handle nested #if/#else.
1430 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
1431 push(@stack, [ $type, $level ]);
1432 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
1433 ($type, $level) = @{$stack[$#stack - 1]};
1434 } elsif ($remainder =~ /^#\s*endif\b/) {
1435 ($type, $level) = @{pop(@stack)};
1436 }
1437
1438 # Statement ends at the ';' or a close '}' at the
1439 # outermost level.
1440 if ($level == 0 && $c eq ';') {
1441 last;
1442 }
1443
1444 # An else is really a conditional as long as its not else if
1445 if ($level == 0 && $coff_set == 0 &&
1446 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1447 $remainder =~ /^(else)(?:\s|{)/ &&
1448 $remainder !~ /^else\s+if\b/) {
1449 $coff = $off + length($1) - 1;
1450 $coff_set = 1;
1451 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1452 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
1453 }
1454
1455 if (($type eq '' || $type eq '(') && $c eq '(') {
1456 $level++;
1457 $type = '(';
1458 }
1459 if ($type eq '(' && $c eq ')') {
1460 $level--;
1461 $type = ($level != 0)? '(' : '';
1462
1463 if ($level == 0 && $coff < $soff) {
1464 $coff = $off;
1465 $coff_set = 1;
1466 #warn "CSB: mark coff<$coff>\n";
1467 }
1468 }
1469 if (($type eq '' || $type eq '{') && $c eq '{') {
1470 $level++;
1471 $type = '{';
1472 }
1473 if ($type eq '{' && $c eq '}') {
1474 $level--;
1475 $type = ($level != 0)? '{' : '';
1476
1477 if ($level == 0) {
1478 if (substr($blk, $off + 1, 1) eq ';') {
1479 $off++;
1480 }
1481 last;
1482 }
1483 }
1484 # Preprocessor commands end at the newline unless escaped.
1485 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1486 $level--;
1487 $type = '';
1488 $off++;
1489 last;
1490 }
1491 $off++;
1492 }
1493 # We are truly at the end, so shuffle to the next line.
1494 if ($off == $len) {
1495 $loff = $len + 1;
1496 $line++;
1497 $remain--;
1498 }
1499
1500 my $statement = substr($blk, $soff, $off - $soff + 1);
1501 my $condition = substr($blk, $soff, $coff - $soff + 1);
1502
1503 #warn "STATEMENT<$statement>\n";
1504 #warn "CONDITION<$condition>\n";
1505
1506 #print "coff<$coff> soff<$off> loff<$loff>\n";
1507
1508 return ($statement, $condition,
1509 $line, $remain + 1, $off - $loff + 1, $level);
1510}
1511
1512sub statement_lines {
1513 my ($stmt) = @_;
1514
1515 # Strip the diff line prefixes and rip blank lines at start and end.
1516 $stmt =~ s/(^|\n)./$1/g;
1517 $stmt =~ s/^\s*//;
1518 $stmt =~ s/\s*$//;
1519
1520 my @stmt_lines = ($stmt =~ /\n/g);
1521
1522 return $#stmt_lines + 2;
1523}
1524
1525sub statement_rawlines {
1526 my ($stmt) = @_;
1527
1528 my @stmt_lines = ($stmt =~ /\n/g);
1529
1530 return $#stmt_lines + 2;
1531}
1532
1533sub statement_block_size {
1534 my ($stmt) = @_;
1535
1536 $stmt =~ s/(^|\n)./$1/g;
1537 $stmt =~ s/^\s*{//;
1538 $stmt =~ s/}\s*$//;
1539 $stmt =~ s/^\s*//;
1540 $stmt =~ s/\s*$//;
1541
1542 my @stmt_lines = ($stmt =~ /\n/g);
1543 my @stmt_statements = ($stmt =~ /;/g);
1544
1545 my $stmt_lines = $#stmt_lines + 2;
1546 my $stmt_statements = $#stmt_statements + 1;
1547
1548 if ($stmt_lines > $stmt_statements) {
1549 return $stmt_lines;
1550 } else {
1551 return $stmt_statements;
1552 }
1553}
1554
1555sub ctx_statement_full {
1556 my ($linenr, $remain, $off) = @_;
1557 my ($statement, $condition, $level);
1558
1559 my (@chunks);
1560
1561 # Grab the first conditional/block pair.
1562 ($statement, $condition, $linenr, $remain, $off, $level) =
1563 ctx_statement_block($linenr, $remain, $off);
1564 #print "F: c<$condition> s<$statement> remain<$remain>\n";
1565 push(@chunks, [ $condition, $statement ]);
1566 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1567 return ($level, $linenr, @chunks);
1568 }
1569
1570 # Pull in the following conditional/block pairs and see if they
1571 # could continue the statement.
1572 for (;;) {
1573 ($statement, $condition, $linenr, $remain, $off, $level) =
1574 ctx_statement_block($linenr, $remain, $off);
1575 #print "C: c<$condition> s<$statement> remain<$remain>\n";
1576 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1577 #print "C: push\n";
1578 push(@chunks, [ $condition, $statement ]);
1579 }
1580
1581 return ($level, $linenr, @chunks);
1582}
1583
1584sub ctx_block_get {
1585 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1586 my $line;
1587 my $start = $linenr - 1;
1588 my $blk = '';
1589 my @o;
1590 my @c;
1591 my @res = ();
1592
1593 my $level = 0;
1594 my @stack = ($level);
1595 for ($line = $start; $remain > 0; $line++) {
1596 next if ($rawlines[$line] =~ /^-/);
1597 $remain--;
1598
1599 $blk .= $rawlines[$line];
1600
1601 # Handle nested #if/#else.
1602 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1603 push(@stack, $level);
1604 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1605 $level = $stack[$#stack - 1];
1606 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1607 $level = pop(@stack);
1608 }
1609
1610 foreach my $c (split(//, $lines[$line])) {
1611 ##print "C<$c>L<$level><$open$close>O<$off>\n";
1612 if ($off > 0) {
1613 $off--;
1614 next;
1615 }
1616
1617 if ($c eq $close && $level > 0) {
1618 $level--;
1619 last if ($level == 0);
1620 } elsif ($c eq $open) {
1621 $level++;
1622 }
1623 }
1624
1625 if (!$outer || $level <= 1) {
1626 push(@res, $rawlines[$line]);
1627 }
1628
1629 last if ($level == 0);
1630 }
1631
1632 return ($level, @res);
1633}
1634sub ctx_block_outer {
1635 my ($linenr, $remain) = @_;
1636
1637 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1638 return @r;
1639}
1640sub ctx_block {
1641 my ($linenr, $remain) = @_;
1642
1643 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1644 return @r;
1645}
1646sub ctx_statement {
1647 my ($linenr, $remain, $off) = @_;
1648
1649 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1650 return @r;
1651}
1652sub ctx_block_level {
1653 my ($linenr, $remain) = @_;
1654
1655 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1656}
1657sub ctx_statement_level {
1658 my ($linenr, $remain, $off) = @_;
1659
1660 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1661}
1662
1663sub ctx_locate_comment {
1664 my ($first_line, $end_line) = @_;
1665
Peter A. Bigote49e3c82020-08-10 10:37:32 -05001666 # If c99 comment on the current line, or the line before or after
1667 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1668 return $current_comment if (defined $current_comment);
1669 ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1670 return $current_comment if (defined $current_comment);
1671 ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1672 return $current_comment if (defined $current_comment);
1673
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001674 # Catch a comment on the end of the line itself.
Peter A. Bigote49e3c82020-08-10 10:37:32 -05001675 ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001676 return $current_comment if (defined $current_comment);
1677
1678 # Look through the context and try and figure out if there is a
1679 # comment.
1680 my $in_comment = 0;
1681 $current_comment = '';
1682 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1683 my $line = $rawlines[$linenr - 1];
1684 #warn " $line\n";
1685 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1686 $in_comment = 1;
1687 }
1688 if ($line =~ m@/\*@) {
1689 $in_comment = 1;
1690 }
1691 if (!$in_comment && $current_comment ne '') {
1692 $current_comment = '';
1693 }
1694 $current_comment .= $line . "\n" if ($in_comment);
1695 if ($line =~ m@\*/@) {
1696 $in_comment = 0;
1697 }
1698 }
1699
1700 chomp($current_comment);
1701 return($current_comment);
1702}
1703sub ctx_has_comment {
1704 my ($first_line, $end_line) = @_;
1705 my $cmt = ctx_locate_comment($first_line, $end_line);
1706
1707 ##print "LINE: $rawlines[$end_line - 1 ]\n";
1708 ##print "CMMT: $cmt\n";
1709
1710 return ($cmt ne '');
1711}
1712
1713sub raw_line {
1714 my ($linenr, $cnt) = @_;
1715
1716 my $offset = $linenr - 1;
1717 $cnt++;
1718
1719 my $line;
1720 while ($cnt) {
1721 $line = $rawlines[$offset++];
1722 next if (defined($line) && $line =~ /^-/);
1723 $cnt--;
1724 }
1725
1726 return $line;
1727}
1728
Peter Bigot5b10fac2020-03-26 11:16:33 -05001729sub get_stat_real {
1730 my ($linenr, $lc) = @_;
1731
1732 my $stat_real = raw_line($linenr, 0);
1733 for (my $count = $linenr + 1; $count <= $lc; $count++) {
1734 $stat_real = $stat_real . "\n" . raw_line($count, 0);
1735 }
1736
1737 return $stat_real;
1738}
1739
1740sub get_stat_here {
1741 my ($linenr, $cnt, $here) = @_;
1742
1743 my $herectx = $here . "\n";
1744 for (my $n = 0; $n < $cnt; $n++) {
1745 $herectx .= raw_line($linenr, $n) . "\n";
1746 }
1747
1748 return $herectx;
1749}
1750
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001751sub cat_vet {
1752 my ($vet) = @_;
1753 my ($res, $coded);
1754
1755 $res = '';
1756 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1757 $res .= $1;
1758 if ($2 ne '') {
1759 $coded = sprintf("^%c", unpack('C', $2) + 64);
1760 $res .= $coded;
1761 }
1762 }
1763 $res =~ s/$/\$/;
1764
1765 return $res;
1766}
1767
1768my $av_preprocessor = 0;
1769my $av_pending;
1770my @av_paren_type;
1771my $av_pend_colon;
1772
1773sub annotate_reset {
1774 $av_preprocessor = 0;
1775 $av_pending = '_';
1776 @av_paren_type = ('E');
1777 $av_pend_colon = 'O';
1778}
1779
1780sub annotate_values {
1781 my ($stream, $type) = @_;
1782
1783 my $res;
1784 my $var = '_' x length($stream);
1785 my $cur = $stream;
1786
1787 print "$stream\n" if ($dbg_values > 1);
1788
1789 while (length($cur)) {
1790 @av_paren_type = ('E') if ($#av_paren_type < 0);
1791 print " <" . join('', @av_paren_type) .
1792 "> <$type> <$av_pending>" if ($dbg_values > 1);
1793 if ($cur =~ /^(\s+)/o) {
1794 print "WS($1)\n" if ($dbg_values > 1);
1795 if ($1 =~ /\n/ && $av_preprocessor) {
1796 $type = pop(@av_paren_type);
1797 $av_preprocessor = 0;
1798 }
1799
1800 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1801 print "CAST($1)\n" if ($dbg_values > 1);
1802 push(@av_paren_type, $type);
1803 $type = 'c';
1804
1805 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1806 print "DECLARE($1)\n" if ($dbg_values > 1);
1807 $type = 'T';
1808
1809 } elsif ($cur =~ /^($Modifier)\s*/) {
1810 print "MODIFIER($1)\n" if ($dbg_values > 1);
1811 $type = 'T';
1812
1813 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1814 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1815 $av_preprocessor = 1;
1816 push(@av_paren_type, $type);
1817 if ($2 ne '') {
1818 $av_pending = 'N';
1819 }
1820 $type = 'E';
1821
1822 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1823 print "UNDEF($1)\n" if ($dbg_values > 1);
1824 $av_preprocessor = 1;
1825 push(@av_paren_type, $type);
1826
1827 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1828 print "PRE_START($1)\n" if ($dbg_values > 1);
1829 $av_preprocessor = 1;
1830
1831 push(@av_paren_type, $type);
1832 push(@av_paren_type, $type);
1833 $type = 'E';
1834
1835 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1836 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1837 $av_preprocessor = 1;
1838
1839 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1840
1841 $type = 'E';
1842
1843 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1844 print "PRE_END($1)\n" if ($dbg_values > 1);
1845
1846 $av_preprocessor = 1;
1847
1848 # Assume all arms of the conditional end as this
1849 # one does, and continue as if the #endif was not here.
1850 pop(@av_paren_type);
1851 push(@av_paren_type, $type);
1852 $type = 'E';
1853
1854 } elsif ($cur =~ /^(\\\n)/o) {
1855 print "PRECONT($1)\n" if ($dbg_values > 1);
1856
1857 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1858 print "ATTR($1)\n" if ($dbg_values > 1);
1859 $av_pending = $type;
1860 $type = 'N';
1861
1862 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1863 print "SIZEOF($1)\n" if ($dbg_values > 1);
1864 if (defined $2) {
1865 $av_pending = 'V';
1866 }
1867 $type = 'N';
1868
1869 } elsif ($cur =~ /^(if|while|for)\b/o) {
1870 print "COND($1)\n" if ($dbg_values > 1);
1871 $av_pending = 'E';
1872 $type = 'N';
1873
1874 } elsif ($cur =~/^(case)/o) {
1875 print "CASE($1)\n" if ($dbg_values > 1);
1876 $av_pend_colon = 'C';
1877 $type = 'N';
1878
1879 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1880 print "KEYWORD($1)\n" if ($dbg_values > 1);
1881 $type = 'N';
1882
1883 } elsif ($cur =~ /^(\()/o) {
1884 print "PAREN('$1')\n" if ($dbg_values > 1);
1885 push(@av_paren_type, $av_pending);
1886 $av_pending = '_';
1887 $type = 'N';
1888
1889 } elsif ($cur =~ /^(\))/o) {
1890 my $new_type = pop(@av_paren_type);
1891 if ($new_type ne '_') {
1892 $type = $new_type;
1893 print "PAREN('$1') -> $type\n"
1894 if ($dbg_values > 1);
1895 } else {
1896 print "PAREN('$1')\n" if ($dbg_values > 1);
1897 }
1898
1899 } elsif ($cur =~ /^($Ident)\s*\(/o) {
1900 print "FUNC($1)\n" if ($dbg_values > 1);
1901 $type = 'V';
1902 $av_pending = 'V';
1903
1904 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1905 if (defined $2 && $type eq 'C' || $type eq 'T') {
1906 $av_pend_colon = 'B';
1907 } elsif ($type eq 'E') {
1908 $av_pend_colon = 'L';
1909 }
1910 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1911 $type = 'V';
1912
1913 } elsif ($cur =~ /^($Ident|$Constant)/o) {
1914 print "IDENT($1)\n" if ($dbg_values > 1);
1915 $type = 'V';
1916
1917 } elsif ($cur =~ /^($Assignment)/o) {
1918 print "ASSIGN($1)\n" if ($dbg_values > 1);
1919 $type = 'N';
1920
1921 } elsif ($cur =~/^(;|{|})/) {
1922 print "END($1)\n" if ($dbg_values > 1);
1923 $type = 'E';
1924 $av_pend_colon = 'O';
1925
1926 } elsif ($cur =~/^(,)/) {
1927 print "COMMA($1)\n" if ($dbg_values > 1);
1928 $type = 'C';
1929
1930 } elsif ($cur =~ /^(\?)/o) {
1931 print "QUESTION($1)\n" if ($dbg_values > 1);
1932 $type = 'N';
1933
1934 } elsif ($cur =~ /^(:)/o) {
1935 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1936
1937 substr($var, length($res), 1, $av_pend_colon);
1938 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1939 $type = 'E';
1940 } else {
1941 $type = 'N';
1942 }
1943 $av_pend_colon = 'O';
1944
1945 } elsif ($cur =~ /^(\[)/o) {
1946 print "CLOSE($1)\n" if ($dbg_values > 1);
1947 $type = 'N';
1948
1949 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1950 my $variant;
1951
1952 print "OPV($1)\n" if ($dbg_values > 1);
1953 if ($type eq 'V') {
1954 $variant = 'B';
1955 } else {
1956 $variant = 'U';
1957 }
1958
1959 substr($var, length($res), 1, $variant);
1960 $type = 'N';
1961
1962 } elsif ($cur =~ /^($Operators)/o) {
1963 print "OP($1)\n" if ($dbg_values > 1);
1964 if ($1 ne '++' && $1 ne '--') {
1965 $type = 'N';
1966 }
1967
1968 } elsif ($cur =~ /(^.)/o) {
1969 print "C($1)\n" if ($dbg_values > 1);
1970 }
1971 if (defined $1) {
1972 $cur = substr($cur, length($1));
1973 $res .= $type x length($1);
1974 }
1975 }
1976
1977 return ($res, $var);
1978}
1979
1980sub possible {
1981 my ($possible, $line) = @_;
1982 my $notPermitted = qr{(?:
1983 ^(?:
1984 $Modifier|
1985 $Storage|
1986 $Type|
1987 DEFINE_\S+
1988 )$|
1989 ^(?:
1990 goto|
1991 return|
1992 case|
1993 else|
1994 asm|__asm__|
1995 do|
1996 \#|
1997 \#\#|
1998 )(?:\s|$)|
1999 ^(?:typedef|struct|enum)\b
2000 )}x;
2001 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
2002 if ($possible !~ $notPermitted) {
2003 # Check for modifiers.
2004 $possible =~ s/\s*$Storage\s*//g;
2005 $possible =~ s/\s*$Sparse\s*//g;
2006 if ($possible =~ /^\s*$/) {
2007
2008 } elsif ($possible =~ /\s/) {
2009 $possible =~ s/\s*$Type\s*//g;
2010 for my $modifier (split(' ', $possible)) {
2011 if ($modifier !~ $notPermitted) {
2012 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002013 push(@modifierListFile, $modifier);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002014 }
2015 }
2016
2017 } else {
2018 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002019 push(@typeListFile, $possible);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002020 }
2021 build_types();
2022 } else {
2023 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
2024 }
2025}
2026
2027my $prefix = '';
2028
2029sub show_type {
2030 my ($type) = @_;
2031
Anas Nashif1eb244c2017-10-01 17:06:36 -04002032 $type =~ tr/[a-z]/[A-Z]/;
2033
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002034 return defined $use_type{$type} if (scalar keys %use_type > 0);
2035
2036 return !defined $ignore_type{$type};
2037}
2038
2039sub report {
2040 my ($level, $type, $msg) = @_;
2041
2042 if (!show_type($type) ||
2043 (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2044 return 0;
2045 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002046 my $output = '';
Anas Nashif1eb244c2017-10-01 17:06:36 -04002047 if ($color) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002048 if ($level eq 'ERROR') {
2049 $output .= RED;
2050 } elsif ($level eq 'WARNING') {
2051 $output .= YELLOW;
2052 } else {
2053 $output .= GREEN;
2054 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002055 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002056 $output .= $prefix . $level . ':';
2057 if ($show_types) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04002058 $output .= BLUE if ($color);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002059 $output .= "$type:";
2060 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04002061 $output .= RESET if ($color);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002062 $output .= ' ' . $msg . "\n";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002063
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002064 if ($showfile) {
2065 my @lines = split("\n", $output, -1);
2066 splice(@lines, 1, 1);
2067 $output = join("\n", @lines);
2068 }
2069 $output = (split('\n', $output))[0] . "\n" if ($terse);
2070
2071 push(our @report, $output);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002072
2073 return 1;
2074}
2075
2076sub report_dump {
2077 our @report;
2078}
2079
2080sub fixup_current_range {
2081 my ($lineRef, $offset, $length) = @_;
2082
2083 if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2084 my $o = $1;
2085 my $l = $2;
2086 my $no = $o + $offset;
2087 my $nl = $l + $length;
2088 $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2089 }
2090}
2091
2092sub fix_inserted_deleted_lines {
2093 my ($linesRef, $insertedRef, $deletedRef) = @_;
2094
2095 my $range_last_linenr = 0;
2096 my $delta_offset = 0;
2097
2098 my $old_linenr = 0;
2099 my $new_linenr = 0;
2100
2101 my $next_insert = 0;
2102 my $next_delete = 0;
2103
2104 my @lines = ();
2105
2106 my $inserted = @{$insertedRef}[$next_insert++];
2107 my $deleted = @{$deletedRef}[$next_delete++];
2108
2109 foreach my $old_line (@{$linesRef}) {
2110 my $save_line = 1;
2111 my $line = $old_line; #don't modify the array
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002112 if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002113 $delta_offset = 0;
2114 } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
2115 $range_last_linenr = $new_linenr;
2116 fixup_current_range(\$line, $delta_offset, 0);
2117 }
2118
2119 while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2120 $deleted = @{$deletedRef}[$next_delete++];
2121 $save_line = 0;
2122 fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2123 }
2124
2125 while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2126 push(@lines, ${$inserted}{'LINE'});
2127 $inserted = @{$insertedRef}[$next_insert++];
2128 $new_linenr++;
2129 fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2130 }
2131
2132 if ($save_line) {
2133 push(@lines, $line);
2134 $new_linenr++;
2135 }
2136
2137 $old_linenr++;
2138 }
2139
2140 return @lines;
2141}
2142
2143sub fix_insert_line {
2144 my ($linenr, $line) = @_;
2145
2146 my $inserted = {
2147 LINENR => $linenr,
2148 LINE => $line,
2149 };
2150 push(@fixed_inserted, $inserted);
2151}
2152
2153sub fix_delete_line {
2154 my ($linenr, $line) = @_;
2155
2156 my $deleted = {
2157 LINENR => $linenr,
2158 LINE => $line,
2159 };
2160
2161 push(@fixed_deleted, $deleted);
2162}
2163
2164sub ERROR {
2165 my ($type, $msg) = @_;
2166
2167 if (report("ERROR", $type, $msg)) {
2168 our $clean = 0;
2169 our $cnt_error++;
2170 return 1;
2171 }
2172 return 0;
2173}
2174sub WARN {
2175 my ($type, $msg) = @_;
2176
2177 if (report("WARNING", $type, $msg)) {
2178 our $clean = 0;
2179 our $cnt_warn++;
2180 return 1;
2181 }
2182 return 0;
2183}
2184sub CHK {
2185 my ($type, $msg) = @_;
2186
2187 if ($check && report("CHECK", $type, $msg)) {
2188 our $clean = 0;
2189 our $cnt_chk++;
2190 return 1;
2191 }
2192 return 0;
2193}
2194
2195sub check_absolute_file {
2196 my ($absolute, $herecurr) = @_;
2197 my $file = $absolute;
2198
2199 ##print "absolute<$absolute>\n";
2200
2201 # See if any suffix of this path is a path within the tree.
2202 while ($file =~ s@^[^/]*/@@) {
2203 if (-f "$root/$file") {
2204 ##print "file<$file>\n";
2205 last;
2206 }
2207 }
2208 if (! -f _) {
2209 return 0;
2210 }
2211
2212 # It is, so see if the prefix is acceptable.
2213 my $prefix = $absolute;
2214 substr($prefix, -length($file)) = '';
2215
2216 ##print "prefix<$prefix>\n";
2217 if ($prefix ne ".../") {
2218 WARN("USE_RELATIVE_PATH",
2219 "use relative pathname instead of absolute in changelog text\n" . $herecurr);
2220 }
2221}
2222
2223sub trim {
2224 my ($string) = @_;
2225
2226 $string =~ s/^\s+|\s+$//g;
2227
2228 return $string;
2229}
2230
2231sub ltrim {
2232 my ($string) = @_;
2233
2234 $string =~ s/^\s+//;
2235
2236 return $string;
2237}
2238
2239sub rtrim {
2240 my ($string) = @_;
2241
2242 $string =~ s/\s+$//;
2243
2244 return $string;
2245}
2246
2247sub string_find_replace {
2248 my ($string, $find, $replace) = @_;
2249
2250 $string =~ s/$find/$replace/g;
2251
2252 return $string;
2253}
2254
2255sub tabify {
2256 my ($leading) = @_;
2257
Peter A. Bigote49e3c82020-08-10 10:37:32 -05002258 my $source_indent = $tabsize;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002259 my $max_spaces_before_tab = $source_indent - 1;
2260 my $spaces_to_tab = " " x $source_indent;
2261
2262 #convert leading spaces to tabs
2263 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
2264 #Remove spaces before a tab
2265 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
2266
2267 return "$leading";
2268}
2269
2270sub pos_last_openparen {
2271 my ($line) = @_;
2272
2273 my $pos = 0;
2274
2275 my $opens = $line =~ tr/\(/\(/;
2276 my $closes = $line =~ tr/\)/\)/;
2277
2278 my $last_openparen = 0;
2279
2280 if (($opens == 0) || ($closes >= $opens)) {
2281 return -1;
2282 }
2283
2284 my $len = length($line);
2285
2286 for ($pos = 0; $pos < $len; $pos++) {
2287 my $string = substr($line, $pos);
2288 if ($string =~ /^($FuncArg|$balanced_parens)/) {
2289 $pos += length($1) - 1;
2290 } elsif (substr($line, $pos, 1) eq '(') {
2291 $last_openparen = $pos;
2292 } elsif (index($string, '(') == -1) {
2293 last;
2294 }
2295 }
2296
2297 return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2298}
2299
2300sub process {
2301 my $filename = shift;
2302
2303 my $linenr=0;
2304 my $prevline="";
2305 my $prevrawline="";
2306 my $stashline="";
2307 my $stashrawline="";
2308
2309 my $length;
2310 my $indent;
2311 my $previndent=0;
2312 my $stashindent=0;
2313
2314 our $clean = 1;
2315 my $signoff = 0;
Peter Bigot5b10fac2020-03-26 11:16:33 -05002316 my $author = '';
2317 my $authorsignoff = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002318 my $is_patch = 0;
Peter Bigot5b10fac2020-03-26 11:16:33 -05002319 my $is_binding_patch = -1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002320 my $in_header_lines = $file ? 0 : 1;
2321 my $in_commit_log = 0; #Scanning lines before patch
Peter A. Bigote49e3c82020-08-10 10:37:32 -05002322 my $has_patch_separator = 0; #Found a --- line
Anas Nashif0f3d5472016-11-07 15:57:57 -05002323 my $has_commit_log = 0; #Encountered lines before patch
Peter Bigot5b10fac2020-03-26 11:16:33 -05002324 my $commit_log_lines = 0; #Number of commit log lines
Anas Nashif1eb244c2017-10-01 17:06:36 -04002325 my $commit_log_possible_stack_dump = 0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002326 my $commit_log_long_line = 0;
2327 my $commit_log_has_diff = 0;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002328 my $reported_maintainer_file = 0;
2329 my $non_utf8_charset = 0;
2330
2331 my $last_blank_line = 0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002332 my $last_coalesced_string_linenr = -1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002333
2334 our @report = ();
2335 our $cnt_lines = 0;
2336 our $cnt_error = 0;
2337 our $cnt_warn = 0;
2338 our $cnt_chk = 0;
2339
2340 # Trace the real file/line as we go.
2341 my $realfile = '';
2342 my $realline = 0;
2343 my $realcnt = 0;
2344 my $here = '';
Anas Nashif1eb244c2017-10-01 17:06:36 -04002345 my $context_function; #undef'd unless there's a known function
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002346 my $in_comment = 0;
2347 my $comment_edge = 0;
2348 my $first_line = 0;
2349 my $p1_prefix = '';
2350
2351 my $prev_values = 'E';
2352
2353 # suppression flags
2354 my %suppress_ifbraces;
2355 my %suppress_whiletrailers;
2356 my %suppress_export;
2357 my $suppress_statement = 0;
2358
2359 my %signatures = ();
2360
2361 # Pre-scan the patch sanitizing the lines.
2362 # Pre-scan the patch looking for any __setup documentation.
2363 #
2364 my @setup_docs = ();
2365 my $setup_docs = 0;
2366
2367 my $camelcase_file_seeded = 0;
2368
Peter Bigot5b10fac2020-03-26 11:16:33 -05002369 my $checklicenseline = 1;
2370
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002371 sanitise_line_reset();
2372 my $line;
2373 foreach my $rawline (@rawlines) {
2374 $linenr++;
2375 $line = $rawline;
2376
2377 push(@fixed, $rawline) if ($fix);
2378
2379 if ($rawline=~/^\+\+\+\s+(\S+)/) {
2380 $setup_docs = 0;
Peter A. Bigote49e3c82020-08-10 10:37:32 -05002381 if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002382 $setup_docs = 1;
2383 }
2384 #next;
2385 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04002386 if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002387 $realline=$1-1;
2388 if (defined $2) {
2389 $realcnt=$3+1;
2390 } else {
2391 $realcnt=1+1;
2392 }
2393 $in_comment = 0;
2394
2395 # Guestimate if this is a continuing comment. Run
2396 # the context looking for a comment "edge". If this
2397 # edge is a close comment then we must be in a comment
2398 # at context start.
2399 my $edge;
2400 my $cnt = $realcnt;
2401 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
2402 next if (defined $rawlines[$ln - 1] &&
2403 $rawlines[$ln - 1] =~ /^-/);
2404 $cnt--;
2405 #print "RAW<$rawlines[$ln - 1]>\n";
2406 last if (!defined $rawlines[$ln - 1]);
2407 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2408 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2409 ($edge) = $1;
2410 last;
2411 }
2412 }
2413 if (defined $edge && $edge eq '*/') {
2414 $in_comment = 1;
2415 }
2416
2417 # Guestimate if this is a continuing comment. If this
2418 # is the start of a diff block and this line starts
2419 # ' *' then it is very likely a comment.
2420 if (!defined $edge &&
2421 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2422 {
2423 $in_comment = 1;
2424 }
2425
2426 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2427 sanitise_line_reset($in_comment);
2428
2429 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2430 # Standardise the strings and chars within the input to
2431 # simplify matching -- only bother with positive lines.
2432 $line = sanitise_line($rawline);
2433 }
2434 push(@lines, $line);
2435
2436 if ($realcnt > 1) {
2437 $realcnt-- if ($line =~ /^(?:\+| |$)/);
2438 } else {
2439 $realcnt = 0;
2440 }
2441
2442 #print "==>$rawline\n";
2443 #print "-->$line\n";
2444
2445 if ($setup_docs && $line =~ /^\+/) {
2446 push(@setup_docs, $line);
2447 }
2448 }
2449
2450 $prefix = '';
2451
2452 $realcnt = 0;
2453 $linenr = 0;
2454 $fixlinenr = -1;
2455 foreach my $line (@lines) {
2456 $linenr++;
2457 $fixlinenr++;
2458 my $sline = $line; #copy of $line
2459 $sline =~ s/$;/ /g; #with comments as spaces
2460
2461 my $rawline = $rawlines[$linenr - 1];
2462
Peter Bigot5b10fac2020-03-26 11:16:33 -05002463# check if it's a mode change, rename or start of a patch
2464 if (!$in_commit_log &&
2465 ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
2466 ($line =~ /^rename (?:from|to) \S+\s*$/ ||
2467 $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
2468 $is_patch = 1;
2469 }
2470
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002471#extract the line range in the file after the patch is applied
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002472 if (!$in_commit_log &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04002473 $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2474 my $context = $4;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002475 $is_patch = 1;
2476 $first_line = $linenr + 1;
2477 $realline=$1-1;
2478 if (defined $2) {
2479 $realcnt=$3+1;
2480 } else {
2481 $realcnt=1+1;
2482 }
2483 annotate_reset();
2484 $prev_values = 'E';
2485
2486 %suppress_ifbraces = ();
2487 %suppress_whiletrailers = ();
2488 %suppress_export = ();
2489 $suppress_statement = 0;
Anas Nashif1eb244c2017-10-01 17:06:36 -04002490 if ($context =~ /\b(\w+)\s*\(/) {
2491 $context_function = $1;
2492 } else {
2493 undef $context_function;
2494 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002495 next;
2496
2497# track the line number as we move through the hunk, note that
2498# new versions of GNU diff omit the leading space on completely
2499# blank context lines so we need to count that too.
2500 } elsif ($line =~ /^( |\+|$)/) {
2501 $realline++;
2502 $realcnt-- if ($realcnt != 0);
2503
2504 # Measure the line length and indent.
2505 ($length, $indent) = line_stats($rawline);
2506
2507 # Track the previous line.
2508 ($prevline, $stashline) = ($stashline, $line);
2509 ($previndent, $stashindent) = ($stashindent, $indent);
2510 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2511
2512 #warn "line<$line>\n";
2513
2514 } elsif ($realcnt == 1) {
2515 $realcnt--;
2516 }
2517
2518 my $hunk_line = ($realcnt != 0);
2519
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002520 $here = "#$linenr: " if (!$file);
2521 $here = "#$realline: " if ($file);
2522
2523 my $found_file = 0;
2524 # extract the filename as it passes
2525 if ($line =~ /^diff --git.*?(\S+)$/) {
2526 $realfile = $1;
2527 $realfile =~ s@^([^/]*)/@@ if (!$file);
2528 $in_commit_log = 0;
2529 $found_file = 1;
2530 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2531 $realfile = $1;
2532 $realfile =~ s@^([^/]*)/@@ if (!$file);
2533 $in_commit_log = 0;
2534
2535 $p1_prefix = $1;
2536 if (!$file && $tree && $p1_prefix ne '' &&
2537 -e "$root/$p1_prefix") {
2538 WARN("PATCH_PREFIX",
2539 "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
2540 }
2541
2542 if ($realfile =~ m@^include/asm/@) {
2543 ERROR("MODIFIED_INCLUDE_ASM",
2544 "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2545 }
2546 $found_file = 1;
2547 }
Anas Nashif92a12a12016-05-20 18:26:59 -04002548 my $skipme = 0;
2549 foreach (@exclude) {
2550 if ($realfile =~ m@^(?:$_/)@) {
2551 $skipme = 1;
2552 }
2553 }
2554 if ($skipme) {
2555 next;
2556 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002557
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002558#make up the handle for any error we report on this line
2559 if ($showfile) {
2560 $prefix = "$realfile:$realline: "
2561 } elsif ($emacs) {
2562 if ($file) {
2563 $prefix = "$filename:$realline: ";
2564 } else {
2565 $prefix = "$filename:$linenr: ";
2566 }
2567 }
2568
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002569 if ($found_file) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04002570 if (is_maintained_obsolete($realfile)) {
2571 WARN("OBSOLETE",
2572 "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
2573 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002574 if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002575 $check = 1;
2576 } else {
2577 $check = $check_orig;
2578 }
Peter Bigot5b10fac2020-03-26 11:16:33 -05002579 $checklicenseline = 1;
2580
2581 if ($realfile !~ /^MAINTAINERS/) {
2582 my $last_binding_patch = $is_binding_patch;
2583
2584 $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2585
2586 if (($last_binding_patch != -1) &&
2587 ($last_binding_patch ^ $is_binding_patch)) {
2588 WARN("DT_SPLIT_BINDING_PATCH",
Peter A. Bigote49e3c82020-08-10 10:37:32 -05002589 "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
Peter Bigot5b10fac2020-03-26 11:16:33 -05002590 }
2591 }
2592
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002593 next;
2594 }
2595
2596 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
2597
2598 my $hereline = "$here\n$rawline\n";
2599 my $herecurr = "$here\n$rawline\n";
2600 my $hereprev = "$here\n$prevrawline\n$rawline\n";
2601
2602 $cnt_lines++ if ($realcnt != 0);
2603
Peter Bigot5b10fac2020-03-26 11:16:33 -05002604# Verify the existence of a commit log if appropriate
2605# 2 is used because a $signature is counted in $commit_log_lines
2606 if ($in_commit_log) {
2607 if ($line !~ /^\s*$/) {
2608 $commit_log_lines++; #could be a $signature
2609 }
2610 } elsif ($has_commit_log && $commit_log_lines < 2) {
2611 WARN("COMMIT_MESSAGE",
2612 "Missing commit description - Add an appropriate one\n");
2613 $commit_log_lines = 2; #warn only once
2614 }
2615
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002616# Check if the commit log has what seems like a diff which can confuse patch
2617 if ($in_commit_log && !$commit_log_has_diff &&
2618 (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2619 $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2620 $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2621 $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2622 ERROR("DIFF_IN_COMMIT_MSG",
2623 "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2624 $commit_log_has_diff = 1;
2625 }
2626
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002627# Check for incorrect file permissions
2628 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
2629 my $permhere = $here . "FILE: $realfile\n";
2630 if ($realfile !~ m@scripts/@ &&
2631 $realfile !~ /\.(py|pl|awk|sh)$/) {
2632 ERROR("EXECUTE_PERMISSIONS",
2633 "do not set execute permissions for source files\n" . $permhere);
2634 }
2635 }
2636
Peter Bigot5b10fac2020-03-26 11:16:33 -05002637# Check the patch for a From:
2638 if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2639 $author = $1;
2640 $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2641 $author =~ s/"//g;
2642 }
2643
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002644# Check the patch for a signoff:
2645 if ($line =~ /^\s*signed-off-by:/i) {
2646 $signoff++;
2647 $in_commit_log = 0;
Peter Bigot5b10fac2020-03-26 11:16:33 -05002648 if ($author ne '') {
2649 my $l = $line;
2650 $l =~ s/"//g;
2651 if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
2652 $authorsignoff = 1;
2653 }
2654 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002655 }
2656
Peter A. Bigote49e3c82020-08-10 10:37:32 -05002657# Check for patch separator
2658 if ($line =~ /^---$/) {
2659 $has_patch_separator = 1;
2660 $in_commit_log = 0;
2661 }
2662
Anas Nashifc2de83c2017-09-08 09:51:01 -04002663# Check if CODEOWNERS is being updated. If so, there's probably no need to
2664# emit the "does CODEOWNERS need updating?" message on file add/move/delete
2665 if ($line =~ /^\s*CODEOWNERS\s*\|/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002666 $reported_maintainer_file = 1;
2667 }
2668
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002669# Check signature styles
2670 if (!$in_header_lines &&
2671 $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
2672 my $space_before = $1;
2673 my $sign_off = $2;
2674 my $space_after = $3;
2675 my $email = $4;
2676 my $ucfirst_sign_off = ucfirst(lc($sign_off));
2677
2678 if ($sign_off !~ /$signature_tags/) {
2679 WARN("BAD_SIGN_OFF",
2680 "Non-standard signature: $sign_off\n" . $herecurr);
2681 }
2682 if (defined $space_before && $space_before ne "") {
2683 if (WARN("BAD_SIGN_OFF",
2684 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
2685 $fix) {
2686 $fixed[$fixlinenr] =
2687 "$ucfirst_sign_off $email";
2688 }
2689 }
2690 if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
2691 if (WARN("BAD_SIGN_OFF",
2692 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
2693 $fix) {
2694 $fixed[$fixlinenr] =
2695 "$ucfirst_sign_off $email";
2696 }
2697
2698 }
2699 if (!defined $space_after || $space_after ne " ") {
2700 if (WARN("BAD_SIGN_OFF",
2701 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
2702 $fix) {
2703 $fixed[$fixlinenr] =
2704 "$ucfirst_sign_off $email";
2705 }
2706 }
2707
2708 my ($email_name, $email_address, $comment) = parse_email($email);
2709 my $suggested_email = format_email(($email_name, $email_address));
2710 if ($suggested_email eq "") {
2711 ERROR("BAD_SIGN_OFF",
2712 "Unrecognized email address: '$email'\n" . $herecurr);
2713 } else {
2714 my $dequoted = $suggested_email;
2715 $dequoted =~ s/^"//;
2716 $dequoted =~ s/" </ </;
2717 # Don't force email to have quotes
2718 # Allow just an angle bracketed address
2719 if ("$dequoted$comment" ne $email &&
2720 "<$email_address>$comment" ne $email &&
2721 "$suggested_email$comment" ne $email) {
2722 WARN("BAD_SIGN_OFF",
2723 "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
2724 }
2725 }
2726
2727# Check for duplicate signatures
2728 my $sig_nospace = $line;
2729 $sig_nospace =~ s/\s//g;
2730 $sig_nospace = lc($sig_nospace);
2731 if (defined $signatures{$sig_nospace}) {
2732 WARN("BAD_SIGN_OFF",
2733 "Duplicate signature\n" . $herecurr);
2734 } else {
2735 $signatures{$sig_nospace} = 1;
2736 }
Peter Bigot5b10fac2020-03-26 11:16:33 -05002737
2738# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
2739 if ($sign_off =~ /^co-developed-by:$/i) {
2740 if ($email eq $author) {
2741 WARN("BAD_SIGN_OFF",
2742 "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
2743 }
2744 if (!defined $lines[$linenr]) {
2745 WARN("BAD_SIGN_OFF",
2746 "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
2747 } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
2748 WARN("BAD_SIGN_OFF",
2749 "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
2750 } elsif ($1 ne $email) {
2751 WARN("BAD_SIGN_OFF",
2752 "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
2753 }
2754 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002755 }
2756
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002757# Check email subject for common tools that don't need to be mentioned
2758 if ($in_header_lines &&
2759 $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2760 WARN("EMAIL_SUBJECT",
2761 "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2762 }
2763
Peter A. Bigote49e3c82020-08-10 10:37:32 -05002764# Check for Gerrit Change-Ids not in any patch context
2765 if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04002766 ERROR("GERRIT_CHANGE_ID",
Peter A. Bigote49e3c82020-08-10 10:37:32 -05002767 "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr);
Anas Nashif1eb244c2017-10-01 17:06:36 -04002768 }
2769
Anas Nashif76b09132016-02-20 13:53:35 -05002770# Check if the commit log is in a possible stack dump
2771 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2772 ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2773 $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2774 # timestamp
Peter Bigot5b10fac2020-03-26 11:16:33 -05002775 $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
2776 $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
2777 $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
2778 # stack dump address styles
Anas Nashif76b09132016-02-20 13:53:35 -05002779 $commit_log_possible_stack_dump = 1;
2780 }
2781
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002782# Check for line lengths > 75 in commit log, warn once
2783 if ($in_commit_log && !$commit_log_long_line &&
Anas Nashif76b09132016-02-20 13:53:35 -05002784 length($line) > 75 &&
2785 !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2786 # file delta changes
2787 $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2788 # filename then :
2789 $line =~ /^\s*(?:Fixes:|Link:)/i ||
2790 # A Fixes: or Link: line
2791 $commit_log_possible_stack_dump)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002792 WARN("COMMIT_LOG_LONG_LINE",
2793 "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
2794 $commit_log_long_line = 1;
2795 }
2796
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002797# Reset possible stack dump if a blank line is found
Anas Nashif76b09132016-02-20 13:53:35 -05002798 if ($in_commit_log && $commit_log_possible_stack_dump &&
2799 $line =~ /^\s*$/) {
2800 $commit_log_possible_stack_dump = 0;
2801 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002802
2803# Check for git id commit length and improperly formed commit descriptions
Anas Nashif76b09132016-02-20 13:53:35 -05002804 if ($in_commit_log && !$commit_log_possible_stack_dump &&
Peter A. Bigote49e3c82020-08-10 10:37:32 -05002805 $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04002806 $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002807 ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
Anas Nashif0f3d5472016-11-07 15:57:57 -05002808 ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
Anas Nashif76b09132016-02-20 13:53:35 -05002809 $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2810 $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002811 my $init_char = "c";
2812 my $orig_commit = "";
2813 my $short = 1;
2814 my $long = 0;
2815 my $case = 1;
2816 my $space = 1;
2817 my $hasdesc = 0;
2818 my $hasparens = 0;
2819 my $id = '0123456789ab';
2820 my $orig_desc = "commit description";
2821 my $description = "";
2822
2823 if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2824 $init_char = $1;
2825 $orig_commit = lc($2);
2826 } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2827 $orig_commit = lc($1);
2828 }
2829
2830 $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
2831 $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
2832 $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
2833 $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
2834 if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
2835 $orig_desc = $1;
2836 $hasparens = 1;
2837 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
2838 defined $rawlines[$linenr] &&
2839 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
2840 $orig_desc = $1;
2841 $hasparens = 1;
2842 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2843 defined $rawlines[$linenr] &&
2844 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2845 $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2846 $orig_desc = $1;
2847 $rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2848 $orig_desc .= " " . $1;
2849 $hasparens = 1;
2850 }
2851
2852 ($id, $description) = git_commit_info($orig_commit,
2853 $id, $orig_desc);
2854
Anas Nashif1eb244c2017-10-01 17:06:36 -04002855 if (defined($id) &&
2856 ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002857 ERROR("GIT_COMMIT_ID",
2858 "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
2859 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002860 }
2861
2862# Check for added, moved or deleted files
2863 if (!$reported_maintainer_file && !$in_commit_log &&
2864 ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
2865 $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
2866 ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
2867 (defined($1) || defined($2))))) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04002868 $is_patch = 1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002869 $reported_maintainer_file = 1;
2870 WARN("FILE_PATH_CHANGES",
Anas Nashifc2de83c2017-09-08 09:51:01 -04002871 "added, moved or deleted file(s), does CODEOWNERS need updating?\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002872 }
2873
Peter Bigot5b10fac2020-03-26 11:16:33 -05002874# Check for adding new DT bindings not in schema format
2875 if (!$in_commit_log &&
2876 ($line =~ /^new file mode\s*\d+\s*$/) &&
2877 ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
2878 WARN("DT_SCHEMA_BINDING_PATCH",
2879 "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
2880 }
2881
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002882# Check for wrappage within a valid hunk of the file
2883 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2884 ERROR("CORRUPTED_PATCH",
2885 "patch seems to be corrupt (line wrapped?)\n" .
2886 $herecurr) if (!$emitted_corrupt++);
2887 }
2888
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002889# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2890 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2891 $rawline !~ m/^$UTF8*$/) {
2892 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2893
2894 my $blank = copy_spacing($rawline);
2895 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2896 my $hereptr = "$hereline$ptr\n";
2897
2898 CHK("INVALID_UTF8",
2899 "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
2900 }
2901
2902# Check if it's the start of a commit log
2903# (not a header line and we haven't seen the patch filename)
2904 if ($in_header_lines && $realfile =~ /^$/ &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04002905 !($rawline =~ /^\s+(?:\S|$)/ ||
2906 $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002907 $in_header_lines = 0;
2908 $in_commit_log = 1;
Anas Nashif0f3d5472016-11-07 15:57:57 -05002909 $has_commit_log = 1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002910 }
2911
2912# Check if there is UTF-8 in a commit log when a mail header has explicitly
2913# declined it, i.e defined some charset where it is missing.
2914 if ($in_header_lines &&
2915 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2916 $1 !~ /utf-8/i) {
2917 $non_utf8_charset = 1;
2918 }
2919
2920 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
2921 $rawline =~ /$NON_ASCII_UTF8/) {
2922 WARN("UTF8_BEFORE_PATCH",
2923 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
2924 }
2925
Anas Nashif1eb244c2017-10-01 17:06:36 -04002926# Check for absolute kernel paths in commit message
2927 if ($tree && $in_commit_log) {
2928 while ($line =~ m{(?:^|\s)(/\S*)}g) {
2929 my $file = $1;
2930
2931 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2932 check_absolute_file($1, $herecurr)) {
2933 #
2934 } else {
2935 check_absolute_file($file, $herecurr);
2936 }
2937 }
2938 }
2939
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002940# Check for various typo / spelling mistakes
Anas Nashifcbfb62c2015-10-14 06:08:54 -04002941 if (defined($misspellings) &&
2942 ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2943 while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002944 my $typo = $1;
2945 my $typo_fix = $spelling_fix{lc($typo)};
2946 $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
2947 $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
Anas Nashif1eb244c2017-10-01 17:06:36 -04002948 my $msg_level = \&WARN;
2949 $msg_level = \&CHK if ($file);
2950 if (&{$msg_level}("TYPO_SPELLING",
2951 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002952 $fix) {
2953 $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
2954 }
2955 }
2956 }
2957
Peter Bigot5b10fac2020-03-26 11:16:33 -05002958# check for invalid commit id
2959 if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
2960 my $id;
2961 my $description;
2962 ($id, $description) = git_commit_info($2, undef, undef);
2963 if (!defined($id)) {
2964 WARN("UNKNOWN_COMMIT_ID",
2965 "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
2966 }
2967 }
2968
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002969# ignore non-hunk lines and lines being removed
2970 next if (!$hunk_line || $line =~ /^-/);
2971
2972#trailing whitespace
2973 if ($line =~ /^\+.*\015/) {
2974 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2975 if (ERROR("DOS_LINE_ENDINGS",
2976 "DOS line endings\n" . $herevet) &&
2977 $fix) {
2978 $fixed[$fixlinenr] =~ s/[\s\015]+$//;
2979 }
2980 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2981 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2982 if (ERROR("TRAILING_WHITESPACE",
2983 "trailing whitespace\n" . $herevet) &&
2984 $fix) {
2985 $fixed[$fixlinenr] =~ s/\s+$//;
2986 }
2987
2988 $rpt_cleaners = 1;
2989 }
2990
2991# Check for FSF mailing addresses.
2992 if ($rawline =~ /\bwrite to the Free/i ||
Anas Nashif1eb244c2017-10-01 17:06:36 -04002993 $rawline =~ /\b675\s+Mass\s+Ave/i ||
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07002994 $rawline =~ /\b59\s+Temple\s+Pl/i ||
2995 $rawline =~ /\b51\s+Franklin\s+St/i) {
2996 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Anas Nashif1eb244c2017-10-01 17:06:36 -04002997 my $msg_level = \&ERROR;
2998 $msg_level = \&CHK if ($file);
2999 &{$msg_level}("FSF_MAILING_ADDRESS",
3000 "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003001 }
3002
3003# check for Kconfig help text having a real description
3004# Only applies when adding the entry originally, after that we do not have
3005# sufficient context to determine whether it is indeed long enough.
3006 if ($realfile =~ /Kconfig/ &&
Peter Bigot5b10fac2020-03-26 11:16:33 -05003007 # 'choice' is usually the last thing on the line (though
3008 # Kconfig supports named choices), so use a word boundary
3009 # (\b) rather than a whitespace character (\s)
3010 $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003011 my $length = 0;
3012 my $cnt = $realcnt;
3013 my $ln = $linenr + 1;
3014 my $f;
3015 my $is_start = 0;
3016 my $is_end = 0;
3017 for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
3018 $f = $lines[$ln - 1];
3019 $cnt-- if ($lines[$ln - 1] !~ /^-/);
3020 $is_end = $lines[$ln - 1] =~ /^\+/;
3021
3022 next if ($f =~ /^-/);
3023 last if (!$file && $f =~ /^\@\@/);
3024
Peter Bigot5b10fac2020-03-26 11:16:33 -05003025 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003026 $is_start = 1;
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003027 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003028 $length = -1;
3029 }
3030
3031 $f =~ s/^.//;
3032 $f =~ s/#.*//;
3033 $f =~ s/^\s+//;
3034 next if ($f =~ /^$/);
Peter Bigot5b10fac2020-03-26 11:16:33 -05003035
3036 # This only checks context lines in the patch
3037 # and so hopefully shouldn't trigger false
3038 # positives, even though some of these are
3039 # common words in help texts
3040 if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3041 if|endif|menu|endmenu|source)\b/x) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003042 $is_end = 1;
3043 last;
3044 }
3045 $length++;
3046 }
3047 if ($is_start && $is_end && $length < $min_conf_desc_length) {
3048 WARN("CONFIG_DESCRIPTION",
3049 "please write a paragraph that describes the config symbol fully\n" . $herecurr);
3050 }
3051 #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
3052 }
3053
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003054# check MAINTAINERS entries
3055 if ($realfile =~ /^MAINTAINERS$/) {
3056# check MAINTAINERS entries for the right form
3057 if ($rawline =~ /^\+[A-Z]:/ &&
3058 $rawline !~ /^\+[A-Z]:\t\S/) {
3059 if (WARN("MAINTAINERS_STYLE",
3060 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3061 $fix) {
3062 $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3063 }
3064 }
3065# check MAINTAINERS entries for the right ordering too
3066 my $preferred_order = 'MRLSWQBCPTFXNK';
3067 if ($rawline =~ /^\+[A-Z]:/ &&
3068 $prevrawline =~ /^[\+ ][A-Z]:/) {
3069 $rawline =~ /^\+([A-Z]):\s*(.*)/;
3070 my $cur = $1;
3071 my $curval = $2;
3072 $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
3073 my $prev = $1;
3074 my $prevval = $2;
3075 my $curindex = index($preferred_order, $cur);
3076 my $previndex = index($preferred_order, $prev);
3077 if ($curindex < 0) {
3078 WARN("MAINTAINERS_STYLE",
3079 "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
3080 } else {
3081 if ($previndex >= 0 && $curindex < $previndex) {
3082 WARN("MAINTAINERS_STYLE",
3083 "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
3084 } elsif ((($prev eq 'F' && $cur eq 'F') ||
3085 ($prev eq 'X' && $cur eq 'X')) &&
3086 ($prevval cmp $curval) > 0) {
3087 WARN("MAINTAINERS_STYLE",
3088 "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
3089 }
3090 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04003091 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003092 }
3093
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003094# discourage the use of boolean for type definition attributes of Kconfig options
3095 if ($realfile =~ /Kconfig/ &&
3096 $line =~ /^\+\s*\bboolean\b/) {
3097 WARN("CONFIG_TYPE_BOOLEAN",
3098 "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
3099 }
3100
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003101 if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3102 ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3103 my $flag = $1;
3104 my $replacement = {
3105 'EXTRA_AFLAGS' => 'asflags-y',
3106 'EXTRA_CFLAGS' => 'ccflags-y',
3107 'EXTRA_CPPFLAGS' => 'cppflags-y',
3108 'EXTRA_LDFLAGS' => 'ldflags-y',
3109 };
3110
3111 WARN("DEPRECATED_VARIABLE",
3112 "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3113 }
Javier B Perez5eecd882016-06-14 16:47:27 -05003114# Kconfig use tabs and no spaces in line
Anas Nashif34ffa152016-10-18 18:17:58 -04003115 if ($realfile =~ /Kconfig/ && $rawline =~ /^\+ /) {
Javier B Perez5eecd882016-06-14 16:47:27 -05003116 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3117 WARN("LEADING_SPACE",
3118 "please, no spaces at the start of a line\n" . $herevet);
3119 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003120
3121# check for DT compatible documentation
3122 if (defined $root &&
3123 (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
3124 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
3125
3126 my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3127
Antony Pavlov824519532019-05-09 16:40:56 +03003128 my $dt_path = $root . "/dts/bindings/";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003129 my $vp_file = $dt_path . "vendor-prefixes.txt";
3130
3131 foreach my $compat (@compats) {
3132 my $compat2 = $compat;
3133 $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3134 my $compat3 = $compat;
3135 $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3136 `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3137 if ( $? >> 8 ) {
3138 WARN("UNDOCUMENTED_DT_STRING",
3139 "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3140 }
3141
3142 next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
3143 my $vendor = $1;
Stephanos Ioannidis95c6da02020-05-05 09:20:51 +09003144 `grep -Eq "^$vendor\\b" $vp_file`;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003145 if ( $? >> 8 ) {
3146 WARN("UNDOCUMENTED_DT_STRING",
3147 "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3148 }
3149 }
3150 }
3151
Peter Bigot5b10fac2020-03-26 11:16:33 -05003152# check for using SPDX license tag at beginning of files
3153 if ($realline == $checklicenseline) {
3154 if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
3155 $checklicenseline = 2;
3156 } elsif ($rawline =~ /^\+/) {
3157 my $comment = "";
3158 if ($realfile =~ /\.(h|s|S)$/) {
3159 $comment = '/*';
3160 } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
3161 $comment = '//';
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003162 } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
Peter Bigot5b10fac2020-03-26 11:16:33 -05003163 $comment = '#';
3164 } elsif ($realfile =~ /\.rst$/) {
3165 $comment = '..';
3166 }
3167
3168# check SPDX comment style for .[chsS] files
3169 if ($realfile =~ /\.[chsS]$/ &&
3170 $rawline =~ /SPDX-License-Identifier:/ &&
3171 $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3172 WARN("SPDX_LICENSE_TAG",
3173 "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3174 }
3175
3176 if ($comment !~ /^$/ &&
3177 $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
3178 WARN("SPDX_LICENSE_TAG",
3179 "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
3180 } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
3181 my $spdx_license = $1;
3182 if (!is_SPDX_License_valid($spdx_license)) {
3183 WARN("SPDX_LICENSE_TAG",
3184 "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3185 }
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003186 if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
3187 not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
3188 my $msg_level = \&WARN;
3189 $msg_level = \&CHK if ($file);
3190 if (&{$msg_level}("SPDX_LICENSE_TAG",
3191
3192 "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
3193 $fix) {
3194 $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
3195 }
3196 }
Peter Bigot5b10fac2020-03-26 11:16:33 -05003197 }
3198 }
3199 }
3200
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003201# check we are in a valid source file if not then ignore this hunk
Anas Nashif1eb244c2017-10-01 17:06:36 -04003202 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003203
Peter Bigot5b10fac2020-03-26 11:16:33 -05003204# check for using SPDX-License-Identifier on the wrong line number
3205 if ($realline != $checklicenseline &&
3206 $rawline =~ /\bSPDX-License-Identifier:/ &&
3207 substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3208 WARN("SPDX_LICENSE_TAG",
3209 "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3210 }
3211
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003212# line length limit (with some exclusions)
3213#
3214# There are a few types of lines that may extend beyond $max_line_length:
3215# logging functions like pr_info that end in a string
3216# lines with a single string
3217# #defines that are a single string
Peter Bigot5b10fac2020-03-26 11:16:33 -05003218# lines with an RFC3986 like URL
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003219#
3220# There are 3 different line length message types:
Anas Nashif1eb244c2017-10-01 17:06:36 -04003221# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003222# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
3223# LONG_LINE all other lines longer than $max_line_length
3224#
3225# if LONG_LINE is ignored, the other 2 types are also ignored
3226#
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003227
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003228 if ($line =~ /^\+/ && $length > $max_line_length) {
3229 my $msg_type = "LONG_LINE";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003230
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003231 # Check the allowed long line types first
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003232
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003233 # logging functions that end in a string that starts
3234 # before $max_line_length
3235 if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
3236 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3237 $msg_type = "";
3238
3239 # lines with only strings (w/ possible termination)
3240 # #defines with only strings
3241 } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
3242 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
3243 $msg_type = "";
3244
Peter Bigot5b10fac2020-03-26 11:16:33 -05003245 # More special cases
3246 } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3247 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3248 $msg_type = "";
3249
3250 # URL ($rawline is used in case the URL is in a comment)
3251 } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
Anas Nashif0f3d5472016-11-07 15:57:57 -05003252 $msg_type = "";
3253
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003254 # Otherwise set the alternate message types
3255
3256 # a comment starts before $max_line_length
3257 } elsif ($line =~ /($;[\s$;]*)$/ &&
3258 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3259 $msg_type = "LONG_LINE_COMMENT"
3260
3261 # a quoted string starts before $max_line_length
3262 } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
3263 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3264 $msg_type = "LONG_LINE_STRING"
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003265 }
3266
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003267 if ($msg_type ne "" &&
3268 (show_type("LONG_LINE") || show_type($msg_type))) {
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003269 my $msg_level = \&WARN;
3270 $msg_level = \&CHK if ($file);
3271 &{$msg_level}($msg_type,
3272 "line length of $length exceeds $max_line_length columns\n" . $herecurr);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003273 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003274 }
3275
3276# check for adding lines without a newline.
3277 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
3278 WARN("MISSING_EOF_NEWLINE",
3279 "adding a line without newline at end of file\n" . $herecurr);
3280 }
3281
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003282# check we are in a valid source file C or perl if not then ignore this hunk
3283 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
3284
3285# at the beginning of a line any tabs must come first and anything
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003286# more than $tabsize must use tabs.
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003287 if ($rawline =~ /^\+\s* \t\s*\S/ ||
3288 $rawline =~ /^\+\s* \s*/) {
3289 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3290 $rpt_cleaners = 1;
3291 if (ERROR("CODE_INDENT",
3292 "code indent should use tabs where possible\n" . $herevet) &&
3293 $fix) {
3294 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
3295 }
3296 }
3297
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003298# check for repeated words separated by a single space
3299 if ($rawline =~ /^\+/) {
3300 while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3301
3302 my $first = $1;
3303 my $second = $2;
3304
3305 if ($first =~ /(?:struct|union|enum)/) {
3306 pos($rawline) += length($first) + length($second) + 1;
3307 next;
3308 }
3309
3310 next if ($first ne $second);
3311 next if ($first eq 'long');
3312
3313 if (WARN("REPEATED_WORD",
3314 "Possible repeated word: '$first'\n" . $herecurr) &&
3315 $fix) {
3316 $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3317 }
3318 }
3319
3320 # if it's a repeated word on consecutive lines in a comment block
3321 if ($prevline =~ /$;+\s*$/ &&
3322 $prevrawline =~ /($word_pattern)\s*$/) {
3323 my $last_word = $1;
3324 if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3325 if (WARN("REPEATED_WORD",
3326 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3327 $fix) {
3328 $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3329 }
3330 }
3331 }
3332 }
3333
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003334# check for space before tabs.
3335 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
3336 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3337 if (WARN("SPACE_BEFORE_TAB",
3338 "please, no space before tabs\n" . $herevet) &&
3339 $fix) {
3340 while ($fixed[$fixlinenr] =~
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003341 s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003342 while ($fixed[$fixlinenr] =~
3343 s/(^\+.*) +\t/$1\t/) {}
3344 }
3345 }
3346
Peter Bigot5b10fac2020-03-26 11:16:33 -05003347# check for assignments on the start of a line
3348 if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3349 CHK("ASSIGNMENT_CONTINUATIONS",
3350 "Assignment operator '$1' should be on the previous line\n" . $hereprev);
3351 }
3352
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003353# check for && or || at the start of a line
3354 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
3355 CHK("LOGICAL_CONTINUATIONS",
3356 "Logical continuations should be on the previous line\n" . $hereprev);
3357 }
3358
Anas Nashif0f3d5472016-11-07 15:57:57 -05003359# check indentation starts on a tab stop
Peter Bigot5b10fac2020-03-26 11:16:33 -05003360 if ($perl_version_ok &&
3361 $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
Anas Nashif0f3d5472016-11-07 15:57:57 -05003362 my $indent = length($1);
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003363 if ($indent % $tabsize) {
Anas Nashif0f3d5472016-11-07 15:57:57 -05003364 if (WARN("TABSTOP",
3365 "Statements should start on a tabstop\n" . $herecurr) &&
3366 $fix) {
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003367 $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
Anas Nashif0f3d5472016-11-07 15:57:57 -05003368 }
3369 }
3370 }
3371
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003372# check multi-line statement indentation matches previous line
Peter Bigot5b10fac2020-03-26 11:16:33 -05003373 if ($perl_version_ok &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04003374 $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003375 $prevline =~ /^\+(\t*)(.*)$/;
3376 my $oldindent = $1;
3377 my $rest = $2;
3378
3379 my $pos = pos_last_openparen($rest);
3380 if ($pos >= 0) {
3381 $line =~ /^(\+| )([ \t]*)/;
3382 my $newindent = $2;
3383
3384 my $goodtabindent = $oldindent .
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003385 "\t" x ($pos / $tabsize) .
3386 " " x ($pos % $tabsize);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003387 my $goodspaceindent = $oldindent . " " x $pos;
3388
3389 if ($newindent ne $goodtabindent &&
3390 $newindent ne $goodspaceindent) {
3391
3392 if (CHK("PARENTHESIS_ALIGNMENT",
3393 "Alignment should match open parenthesis\n" . $hereprev) &&
3394 $fix && $line =~ /^\+/) {
3395 $fixed[$fixlinenr] =~
3396 s/^\+[ \t]*/\+$goodtabindent/;
3397 }
3398 }
3399 }
3400 }
3401
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003402# check for space after cast like "(int) foo" or "(struct foo) bar"
3403# avoid checking a few false positives:
3404# "sizeof(<type>)" or "__alignof__(<type>)"
3405# function pointer declarations like "(*foo)(int) = bar;"
3406# structure definitions like "(struct foo) { 0 };"
3407# multiline macros that define functions
3408# known attributes or the __attribute__ keyword
3409 if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
3410 (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003411 if (CHK("SPACING",
3412 "No space is necessary after a cast\n" . $herecurr) &&
3413 $fix) {
3414 $fixed[$fixlinenr] =~
3415 s/(\(\s*$Type\s*\))[ \t]+/$1/;
3416 }
3417 }
3418
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003419# Block comment styles
3420# Networking with an initial /*
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003421 if ($realfile =~ m@^(drivers/net/|net/)@ &&
3422 $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
3423 $rawline =~ /^\+[ \t]*\*/ &&
3424 $realline > 2) {
3425 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
3426 "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
3427 }
3428
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003429# Block comments use * on subsequent lines
3430 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3431 $prevrawline =~ /^\+.*?\/\*/ && #starting /*
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003432 $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
3433 $rawline =~ /^\+/ && #line is new
3434 $rawline !~ /^\+[ \t]*\*/) { #no leading *
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003435 WARN("BLOCK_COMMENT_STYLE",
3436 "Block comments use * on subsequent lines\n" . $hereprev);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003437 }
3438
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003439# Block comments use */ on trailing lines
3440 if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003441 $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
3442 $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/
3443 $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003444 WARN("BLOCK_COMMENT_STYLE",
3445 "Block comments use a trailing */ on a separate line\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003446 }
3447
Anas Nashif0f3d5472016-11-07 15:57:57 -05003448# Block comment * alignment
3449 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3450 $line =~ /^\+[ \t]*$;/ && #leading comment
3451 $rawline =~ /^\+[ \t]*\*/ && #leading *
3452 (($prevrawline =~ /^\+.*?\/\*/ && #leading /*
3453 $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */
3454 $prevrawline =~ /^\+[ \t]*\*/)) { #leading *
3455 my $oldindent;
3456 $prevrawline =~ m@^\+([ \t]*/?)\*@;
3457 if (defined($1)) {
3458 $oldindent = expand_tabs($1);
3459 } else {
3460 $prevrawline =~ m@^\+(.*/?)\*@;
3461 $oldindent = expand_tabs($1);
3462 }
3463 $rawline =~ m@^\+([ \t]*)\*@;
3464 my $newindent = $1;
3465 $newindent = expand_tabs($newindent);
3466 if (length($oldindent) ne length($newindent)) {
3467 WARN("BLOCK_COMMENT_STYLE",
3468 "Block comments should align the * on each line\n" . $hereprev);
3469 }
3470 }
3471
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003472# check for missing blank lines after struct/union declarations
3473# with exceptions for various attributes and macros
3474 if ($prevline =~ /^[\+ ]};?\s*$/ &&
3475 $line =~ /^\+/ &&
3476 !($line =~ /^\+\s*$/ ||
3477 $line =~ /^\+\s*EXPORT_SYMBOL/ ||
3478 $line =~ /^\+\s*MODULE_/i ||
3479 $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
3480 $line =~ /^\+[a-z_]*init/ ||
3481 $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
3482 $line =~ /^\+\s*DECLARE/ ||
Peter Bigot5b10fac2020-03-26 11:16:33 -05003483 $line =~ /^\+\s*builtin_[\w_]*driver/ ||
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003484 $line =~ /^\+\s*__setup/)) {
3485 if (CHK("LINE_SPACING",
3486 "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3487 $fix) {
3488 fix_insert_line($fixlinenr, "\+");
3489 }
3490 }
3491
3492# check for multiple consecutive blank lines
3493 if ($prevline =~ /^[\+ ]\s*$/ &&
3494 $line =~ /^\+\s*$/ &&
3495 $last_blank_line != ($linenr - 1)) {
3496 if (CHK("LINE_SPACING",
3497 "Please don't use multiple blank lines\n" . $hereprev) &&
3498 $fix) {
3499 fix_delete_line($fixlinenr, $rawline);
3500 }
3501
3502 $last_blank_line = $linenr;
3503 }
3504
3505# check for missing blank lines after declarations
3506 if ($sline =~ /^\+\s+\S/ && #Not at char 1
3507 # actual declarations
3508 ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
3509 # function pointer declarations
3510 $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
3511 # foo bar; where foo is some local typedef or #define
3512 $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
3513 # known declaration macros
3514 $prevline =~ /^\+\s+$declaration_macros/) &&
3515 # for "else if" which can look like "$Ident $Ident"
3516 !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
3517 # other possible extensions of declaration lines
3518 $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
3519 # not starting a section or a macro "\" extended line
3520 $prevline =~ /(?:\{\s*|\\)$/) &&
3521 # looks like a declaration
3522 !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
3523 # function pointer declarations
3524 $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
3525 # foo bar; where foo is some local typedef or #define
Marcus Shawcroftf62e6812017-02-19 09:15:57 +00003526 $sline =~ /^\+\s+(?:volatile\s+)?$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003527 # known declaration macros
3528 $sline =~ /^\+\s+$declaration_macros/ ||
3529 # start of struct or union or enum
Peter Bigot5b10fac2020-03-26 11:16:33 -05003530 $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003531 # start or end of block or continuation of declaration
3532 $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
3533 # bitfield continuation
3534 $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
3535 # other possible extensions of declaration lines
3536 $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
3537 # indentation of previous and current line are the same
3538 (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3539 if (WARN("LINE_SPACING",
3540 "Missing a blank line after declarations\n" . $hereprev) &&
3541 $fix) {
3542 fix_insert_line($fixlinenr, "\+");
3543 }
3544 }
3545
3546# check for spaces at the beginning of a line.
3547# Exceptions:
3548# 1) within comments
3549# 2) indented preprocessor commands
3550# 3) hanging labels
3551 if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
3552 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3553 if (WARN("LEADING_SPACE",
3554 "please, no spaces at the start of a line\n" . $herevet) &&
3555 $fix) {
3556 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
3557 }
3558 }
3559
3560# check we are in a valid C source file if not then ignore this hunk
3561 next if ($realfile !~ /\.(h|c)$/);
3562
Peter Bigot5b10fac2020-03-26 11:16:33 -05003563# check for unusual line ending [ or (
3564 if ($line =~ /^\+.*([\[\(])\s*$/) {
3565 CHK("OPEN_ENDED_LINE",
3566 "Lines should not end with a '$1'\n" . $herecurr);
3567 }
3568
Anas Nashif1eb244c2017-10-01 17:06:36 -04003569# check if this appears to be the start function declaration, save the name
3570 if ($sline =~ /^\+\{\s*$/ &&
3571 $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
3572 $context_function = $1;
3573 }
3574
3575# check if this appears to be the end of function declaration
3576 if ($sline =~ /^\+\}\s*$/) {
3577 undef $context_function;
3578 }
3579
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003580# check indentation of any line with a bare else
3581# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3582# if the previous line is a break or return and is indented 1 tab more...
3583 if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3584 my $tabs = length($1) + 1;
3585 if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3586 ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3587 defined $lines[$linenr] &&
3588 $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3589 WARN("UNNECESSARY_ELSE",
3590 "else is not generally useful after a break or return\n" . $hereprev);
3591 }
3592 }
3593
3594# check indentation of a line with a break;
3595# if the previous line is a goto or return and is indented the same # of tabs
3596 if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3597 my $tabs = $1;
3598 if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3599 WARN("UNNECESSARY_BREAK",
3600 "break is not useful after a goto or return\n" . $hereprev);
3601 }
3602 }
3603
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003604# check for RCS/CVS revision markers
3605 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3606 WARN("CVS_KEYWORD",
3607 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3608 }
3609
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003610# check for old HOTPLUG __dev<foo> section markings
3611 if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
3612 WARN("HOTPLUG_SECTION",
3613 "Using $1 is unnecessary\n" . $herecurr);
3614 }
3615
3616# Check for potential 'bare' types
3617 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
3618 $realline_next);
3619#print "LINE<$line>\n";
Anas Nashif1eb244c2017-10-01 17:06:36 -04003620 if ($linenr > $suppress_statement &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003621 $realcnt && $sline =~ /.\s*\S/) {
3622 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3623 ctx_statement_block($linenr, $realcnt, 0);
3624 $stat =~ s/\n./\n /g;
3625 $cond =~ s/\n./\n /g;
3626
3627#print "linenr<$linenr> <$stat>\n";
3628 # If this statement has no statement boundaries within
3629 # it there is no point in retrying a statement scan
3630 # until we hit end of it.
3631 my $frag = $stat; $frag =~ s/;+\s*$//;
3632 if ($frag !~ /(?:{|;)/) {
3633#print "skip<$line_nr_next>\n";
3634 $suppress_statement = $line_nr_next;
3635 }
3636
3637 # Find the real next line.
3638 $realline_next = $line_nr_next;
3639 if (defined $realline_next &&
3640 (!defined $lines[$realline_next - 1] ||
3641 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
3642 $realline_next++;
3643 }
3644
3645 my $s = $stat;
3646 $s =~ s/{.*$//s;
3647
3648 # Ignore goto labels.
3649 if ($s =~ /$Ident:\*$/s) {
3650
3651 # Ignore functions being called
3652 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3653
3654 } elsif ($s =~ /^.\s*else\b/s) {
3655
3656 # declarations always start with types
3657 } 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) {
3658 my $type = $1;
3659 $type =~ s/\s+/ /g;
3660 possible($type, "A:" . $s);
3661
3662 # definitions in global scope can only start with types
3663 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3664 possible($1, "B:" . $s);
3665 }
3666
3667 # any (foo ... *) is a pointer cast, and foo is a type
3668 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3669 possible($1, "C:" . $s);
3670 }
3671
3672 # Check for any sort of function declaration.
3673 # int foo(something bar, other baz);
3674 # void (*store_gdt)(x86_descr_ptr *);
3675 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
3676 my ($name_len) = length($1);
3677
3678 my $ctx = $s;
3679 substr($ctx, 0, $name_len + 1, '');
3680 $ctx =~ s/\)[^\)]*$//;
3681
3682 for my $arg (split(/\s*,\s*/, $ctx)) {
3683 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
3684
3685 possible($1, "D:" . $s);
3686 }
3687 }
3688 }
3689
3690 }
3691
3692#
3693# Checks which may be anchored in the context.
3694#
3695
3696# Check for switch () and associated case and default
3697# statements should be at the same indent.
3698 if ($line=~/\bswitch\s*\(.*\)/) {
3699 my $err = '';
3700 my $sep = '';
3701 my @ctx = ctx_block_outer($linenr, $realcnt);
3702 shift(@ctx);
3703 for my $ctx (@ctx) {
3704 my ($clen, $cindent) = line_stats($ctx);
3705 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
3706 $indent != $cindent) {
3707 $err .= "$sep$ctx\n";
3708 $sep = '';
3709 } else {
3710 $sep = "[...]\n";
3711 }
3712 }
3713 if ($err ne '') {
3714 ERROR("SWITCH_CASE_INDENT_LEVEL",
3715 "switch and case should be at the same indent\n$hereline$err");
3716 }
3717 }
3718
3719# if/while/etc brace do not go on next line, unless defining a do while loop,
3720# or if that brace on the next line is for something else
Peter Bigotafe8a372020-03-26 11:32:25 -05003721 if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[A-Z_]+|)FOR_EACH[A-Z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003722 my $pre_ctx = "$1$2";
3723
3724 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
3725
3726 if ($line =~ /^\+\t{6,}/) {
3727 WARN("DEEP_INDENTATION",
3728 "Too many leading tabs - consider code refactoring\n" . $herecurr);
3729 }
3730
3731 my $ctx_cnt = $realcnt - $#ctx - 1;
3732 my $ctx = join("\n", @ctx);
3733
3734 my $ctx_ln = $linenr;
3735 my $ctx_skip = $realcnt;
3736
3737 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3738 defined $lines[$ctx_ln - 1] &&
3739 $lines[$ctx_ln - 1] =~ /^-/)) {
3740 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3741 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3742 $ctx_ln++;
3743 }
3744
3745 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
3746 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3747
3748 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3749 ERROR("OPEN_BRACE",
3750 "that open brace { should be on the previous line\n" .
3751 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
3752 }
3753 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3754 $ctx =~ /\)\s*\;\s*$/ &&
3755 defined $lines[$ctx_ln - 1])
3756 {
3757 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
3758 if ($nindent > $indent) {
3759 WARN("TRAILING_SEMICOLON",
3760 "trailing semicolon indicates no statements, indent implies otherwise\n" .
3761 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
3762 }
3763 }
3764 }
3765
3766# Check relative indent for conditionals and blocks.
Peter Bigotafe8a372020-03-26 11:32:25 -05003767 if ($line =~ /\b(?:(?:if|while|for|(?:[A-Z_]+|)FOR_EACH[A-Z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003768 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3769 ctx_statement_block($linenr, $realcnt, 0)
3770 if (!defined $stat);
3771 my ($s, $c) = ($stat, $cond);
3772
3773 substr($s, 0, length($c), '');
3774
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003775 # remove inline comments
3776 $s =~ s/$;/ /g;
3777 $c =~ s/$;/ /g;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003778
3779 # Find out how long the conditional actually is.
3780 my @newlines = ($c =~ /\n/gs);
3781 my $cond_lines = 1 + $#newlines;
3782
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003783 # Make sure we remove the line prefixes as we have
3784 # none on the first line, and are going to readd them
3785 # where necessary.
3786 $s =~ s/\n./\n/gs;
3787 while ($s =~ /\n\s+\\\n/) {
3788 $cond_lines += $s =~ s/\n\s+\\\n/\n/g;
3789 }
3790
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003791 # We want to check the first line inside the block
3792 # starting at the end of the conditional, so remove:
3793 # 1) any blank line termination
3794 # 2) any opening brace { on end of the line
3795 # 3) any do (...) {
3796 my $continuation = 0;
3797 my $check = 0;
3798 $s =~ s/^.*\bdo\b//;
3799 $s =~ s/^\s*{//;
3800 if ($s =~ s/^\s*\\//) {
3801 $continuation = 1;
3802 }
3803 if ($s =~ s/^\s*?\n//) {
3804 $check = 1;
3805 $cond_lines++;
3806 }
3807
3808 # Also ignore a loop construct at the end of a
3809 # preprocessor statement.
3810 if (($prevline =~ /^.\s*#\s*define\s/ ||
3811 $prevline =~ /\\\s*$/) && $continuation == 0) {
3812 $check = 0;
3813 }
3814
3815 my $cond_ptr = -1;
3816 $continuation = 0;
3817 while ($cond_ptr != $cond_lines) {
3818 $cond_ptr = $cond_lines;
3819
3820 # If we see an #else/#elif then the code
3821 # is not linear.
3822 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3823 $check = 0;
3824 }
3825
3826 # Ignore:
3827 # 1) blank lines, they should be at 0,
3828 # 2) preprocessor lines, and
3829 # 3) labels.
3830 if ($continuation ||
3831 $s =~ /^\s*?\n/ ||
3832 $s =~ /^\s*#\s*?/ ||
3833 $s =~ /^\s*$Ident\s*:/) {
3834 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
3835 if ($s =~ s/^.*?\n//) {
3836 $cond_lines++;
3837 }
3838 }
3839 }
3840
3841 my (undef, $sindent) = line_stats("+" . $s);
3842 my $stat_real = raw_line($linenr, $cond_lines);
3843
3844 # Check if either of these lines are modified, else
3845 # this is not this patch's fault.
3846 if (!defined($stat_real) ||
3847 $stat !~ /^\+/ && $stat_real !~ /^\+/) {
3848 $check = 0;
3849 }
3850 if (defined($stat_real) && $cond_lines > 1) {
3851 $stat_real = "[...]\n$stat_real";
3852 }
3853
3854 #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";
3855
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003856 if ($check && $s ne '' &&
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003857 (($sindent % $tabsize) != 0 ||
Anas Nashifcbfb62c2015-10-14 06:08:54 -04003858 ($sindent < $indent) ||
Anas Nashif1eb244c2017-10-01 17:06:36 -04003859 ($sindent == $indent &&
3860 ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
Peter A. Bigote49e3c82020-08-10 10:37:32 -05003861 ($sindent > $indent + $tabsize))) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003862 WARN("SUSPECT_CODE_INDENT",
3863 "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
3864 }
3865 }
3866
3867 # Track the 'values' across context and added lines.
3868 my $opline = $line; $opline =~ s/^./ /;
3869 my ($curr_values, $curr_vars) =
3870 annotate_values($opline . "\n", $prev_values);
3871 $curr_values = $prev_values . $curr_values;
3872 if ($dbg_values) {
3873 my $outline = $opline; $outline =~ s/\t/ /g;
3874 print "$linenr > .$outline\n";
3875 print "$linenr > $curr_values\n";
3876 print "$linenr > $curr_vars\n";
3877 }
3878 $prev_values = substr($curr_values, -1);
3879
3880#ignore lines not being added
3881 next if ($line =~ /^[^\+]/);
3882
Anas Nashif1eb244c2017-10-01 17:06:36 -04003883# check for dereferences that span multiple lines
3884 if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
3885 $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
3886 $prevline =~ /($Lval\s*(?:\.|->))\s*$/;
3887 my $ref = $1;
3888 $line =~ /^.\s*($Lval)/;
3889 $ref .= $1;
3890 $ref =~ s/\s//g;
3891 WARN("MULTILINE_DEREFERENCE",
3892 "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
3893 }
3894
Anas Nashif0f3d5472016-11-07 15:57:57 -05003895# check for declarations of signed or unsigned without int
3896 while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3897 my $type = $1;
3898 my $var = $2;
3899 $var = "" if (!defined $var);
3900 if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3901 my $sign = $1;
3902 my $pointer = $2;
3903
3904 $pointer = "" if (!defined $pointer);
3905
3906 if (WARN("UNSPECIFIED_INT",
3907 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3908 $fix) {
3909 my $decl = trim($sign) . " int ";
3910 my $comp_pointer = $pointer;
3911 $comp_pointer =~ s/\s//g;
3912 $decl .= $comp_pointer;
3913 $decl = rtrim($decl) if ($var eq "");
3914 $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3915 }
3916 }
3917 }
3918
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003919# TEST: allow direct testing of the type matcher.
3920 if ($dbg_type) {
3921 if ($line =~ /^.\s*$Declare\s*$/) {
3922 ERROR("TEST_TYPE",
3923 "TEST: is type\n" . $herecurr);
3924 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3925 ERROR("TEST_NOT_TYPE",
3926 "TEST: is not type ($1 is)\n". $herecurr);
3927 }
3928 next;
3929 }
3930# TEST: allow direct testing of the attribute matcher.
3931 if ($dbg_attr) {
3932 if ($line =~ /^.\s*$Modifier\s*$/) {
3933 ERROR("TEST_ATTR",
3934 "TEST: is attr\n" . $herecurr);
3935 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3936 ERROR("TEST_NOT_ATTR",
3937 "TEST: is not attr ($1 is)\n". $herecurr);
3938 }
3939 next;
3940 }
3941
3942# check for initialisation to aggregates open brace on the next line
3943 if ($line =~ /^.\s*{/ &&
3944 $prevline =~ /(?:^|[^=])=\s*$/) {
3945 if (ERROR("OPEN_BRACE",
3946 "that open brace { should be on the previous line\n" . $hereprev) &&
3947 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3948 fix_delete_line($fixlinenr - 1, $prevrawline);
3949 fix_delete_line($fixlinenr, $rawline);
3950 my $fixedline = $prevrawline;
3951 $fixedline =~ s/\s*=\s*$/ = {/;
3952 fix_insert_line($fixlinenr, $fixedline);
3953 $fixedline = $line;
Anas Nashif1eb244c2017-10-01 17:06:36 -04003954 $fixedline =~ s/^(.\s*)\{\s*/$1/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07003955 fix_insert_line($fixlinenr, $fixedline);
3956 }
3957 }
3958
3959#
3960# Checks which are anchored on the added line.
3961#
3962
3963# check for malformed paths in #include statements (uses RAW line)
3964 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3965 my $path = $1;
3966 if ($path =~ m{//}) {
3967 ERROR("MALFORMED_INCLUDE",
3968 "malformed #include filename\n" . $herecurr);
3969 }
3970 if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3971 ERROR("UAPI_INCLUDE",
3972 "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3973 }
3974 }
3975
3976# no C99 // comments
3977 if ($line =~ m{//}) {
3978 if (ERROR("C99_COMMENTS",
3979 "do not use C99 // comments\n" . $herecurr) &&
3980 $fix) {
3981 my $line = $fixed[$fixlinenr];
3982 if ($line =~ /\/\/(.*)$/) {
3983 my $comment = trim($1);
3984 $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
3985 }
3986 }
3987 }
3988 # Remove C99 comments.
3989 $line =~ s@//.*@@;
3990 $opline =~ s@//.*@@;
3991
3992# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
3993# the whole statement.
3994#print "APW <$lines[$realline_next - 1]>\n";
3995 if (defined $realline_next &&
3996 exists $lines[$realline_next - 1] &&
3997 !defined $suppress_export{$realline_next} &&
3998 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
3999 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
4000 # Handle definitions which produce identifiers with
4001 # a prefix:
4002 # XXX(foo);
4003 # EXPORT_SYMBOL(something_foo);
4004 my $name = $1;
4005 if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
4006 $name =~ /^${Ident}_$2/) {
4007#print "FOO C name<$name>\n";
4008 $suppress_export{$realline_next} = 1;
4009
4010 } elsif ($stat !~ /(?:
4011 \n.}\s*$|
4012 ^.DEFINE_$Ident\(\Q$name\E\)|
4013 ^.DECLARE_$Ident\(\Q$name\E\)|
4014 ^.LIST_HEAD\(\Q$name\E\)|
4015 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
4016 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
4017 )/x) {
4018#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
4019 $suppress_export{$realline_next} = 2;
4020 } else {
4021 $suppress_export{$realline_next} = 1;
4022 }
4023 }
4024 if (!defined $suppress_export{$linenr} &&
4025 $prevline =~ /^.\s*$/ &&
4026 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
4027 $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
4028#print "FOO B <$lines[$linenr - 1]>\n";
4029 $suppress_export{$linenr} = 2;
4030 }
4031 if (defined $suppress_export{$linenr} &&
4032 $suppress_export{$linenr} == 2) {
4033 WARN("EXPORT_SYMBOL",
4034 "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
4035 }
4036
4037# check for global initialisers.
Anas Nashif76b09132016-02-20 13:53:35 -05004038 if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004039 if (ERROR("GLOBAL_INITIALISERS",
Anas Nashif76b09132016-02-20 13:53:35 -05004040 "do not initialise globals to $1\n" . $herecurr) &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004041 $fix) {
Anas Nashif76b09132016-02-20 13:53:35 -05004042 $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004043 }
4044 }
4045# check for static initialisers.
Anas Nashif76b09132016-02-20 13:53:35 -05004046 if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004047 if (ERROR("INITIALISED_STATIC",
Anas Nashif76b09132016-02-20 13:53:35 -05004048 "do not initialise statics to $1\n" .
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004049 $herecurr) &&
4050 $fix) {
Anas Nashif76b09132016-02-20 13:53:35 -05004051 $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004052 }
4053 }
4054
4055# check for misordered declarations of char/short/int/long with signed/unsigned
4056 while ($sline =~ m{(\b$TypeMisordered\b)}g) {
4057 my $tmp = trim($1);
4058 WARN("MISORDERED_TYPE",
4059 "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
4060 }
4061
Peter Bigot5b10fac2020-03-26 11:16:33 -05004062# check for unnecessary <signed> int declarations of short/long/long long
4063 while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4064 my $type = trim($1);
4065 next if ($type !~ /\bint\b/);
4066 next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4067 my $new_type = $type;
4068 $new_type =~ s/\b\s*int\s*\b/ /;
4069 $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4070 $new_type =~ s/^const\s+//;
4071 $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4072 $new_type = "const $new_type" if ($type =~ /^const\b/);
4073 $new_type =~ s/\s+/ /g;
4074 $new_type = trim($new_type);
4075 if (WARN("UNNECESSARY_INT",
4076 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4077 $fix) {
4078 $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4079 }
4080 }
4081
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004082# check for static const char * arrays.
4083 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4084 WARN("STATIC_CONST_CHAR_ARRAY",
4085 "static const char * array should probably be static const char * const\n" .
4086 $herecurr);
Peter Bigot5b10fac2020-03-26 11:16:33 -05004087 }
4088
4089# check for initialized const char arrays that should be static const
4090 if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
4091 if (WARN("STATIC_CONST_CHAR_ARRAY",
4092 "const array should probably be static const\n" . $herecurr) &&
4093 $fix) {
4094 $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
4095 }
4096 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004097
4098# check for static char foo[] = "bar" declarations.
4099 if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4100 WARN("STATIC_CONST_CHAR_ARRAY",
4101 "static char array declaration should probably be static const char\n" .
4102 $herecurr);
Peter Bigot5b10fac2020-03-26 11:16:33 -05004103 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004104
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004105# check for const <foo> const where <foo> is not a pointer or array type
4106 if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4107 my $found = $1;
4108 if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4109 WARN("CONST_CONST",
4110 "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4111 } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4112 WARN("CONST_CONST",
4113 "'const $found const' should probably be 'const $found'\n" . $herecurr);
4114 }
4115 }
4116
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004117# check for non-global char *foo[] = {"bar", ...} declarations.
4118 if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
4119 WARN("STATIC_CONST_CHAR_ARRAY",
4120 "char * array declaration might be better as static const\n" .
4121 $herecurr);
4122 }
4123
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004124# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4125 if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4126 my $array = $1;
4127 if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
4128 my $array_div = $1;
4129 if (WARN("ARRAY_SIZE",
4130 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4131 $fix) {
4132 $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4133 }
4134 }
4135 }
4136
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004137# check for function declarations without arguments like "int foo()"
Peter A. Bigote49e3c82020-08-10 10:37:32 -05004138 if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004139 if (ERROR("FUNCTION_WITHOUT_ARGS",
4140 "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4141 $fix) {
4142 $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4143 }
4144 }
4145
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004146# check for new typedefs, only function parameters and sparse annotations
4147# make sense.
4148 if ($line =~ /\btypedef\s/ &&
4149 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4150 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
4151 $line !~ /\b$typeTypedefs\b/ &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04004152 $line !~ /\b__bitwise\b/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004153 WARN("NEW_TYPEDEFS",
4154 "do not add new typedefs\n" . $herecurr);
4155 }
4156
4157# * goes on variable not on type
4158 # (char*[ const])
4159 while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4160 #print "AA<$1>\n";
4161 my ($ident, $from, $to) = ($1, $2, $2);
4162
4163 # Should start with a space.
4164 $to =~ s/^(\S)/ $1/;
4165 # Should not end with a space.
4166 $to =~ s/\s+$//;
4167 # '*'s should not have spaces between.
4168 while ($to =~ s/\*\s+\*/\*\*/) {
4169 }
4170
4171## print "1: from<$from> to<$to> ident<$ident>\n";
4172 if ($from ne $to) {
4173 if (ERROR("POINTER_LOCATION",
4174 "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
4175 $fix) {
4176 my $sub_from = $ident;
4177 my $sub_to = $ident;
4178 $sub_to =~ s/\Q$from\E/$to/;
4179 $fixed[$fixlinenr] =~
4180 s@\Q$sub_from\E@$sub_to@;
4181 }
4182 }
4183 }
4184 while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4185 #print "BB<$1>\n";
4186 my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4187
4188 # Should start with a space.
4189 $to =~ s/^(\S)/ $1/;
4190 # Should not end with a space.
4191 $to =~ s/\s+$//;
4192 # '*'s should not have spaces between.
4193 while ($to =~ s/\*\s+\*/\*\*/) {
4194 }
4195 # Modifiers should have spaces.
4196 $to =~ s/(\b$Modifier$)/$1 /;
4197
4198## print "2: from<$from> to<$to> ident<$ident>\n";
4199 if ($from ne $to && $ident !~ /^$Modifier$/) {
4200 if (ERROR("POINTER_LOCATION",
4201 "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
4202 $fix) {
4203
4204 my $sub_from = $match;
4205 my $sub_to = $match;
4206 $sub_to =~ s/\Q$from\E/$to/;
4207 $fixed[$fixlinenr] =~
4208 s@\Q$sub_from\E@$sub_to@;
4209 }
4210 }
4211 }
4212
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004213# avoid BUG() or BUG_ON()
4214 if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04004215 my $msg_level = \&WARN;
4216 $msg_level = \&CHK if ($file);
4217 &{$msg_level}("AVOID_BUG",
4218 "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004219 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004220
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004221# avoid LINUX_VERSION_CODE
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004222 if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4223 WARN("LINUX_VERSION_CODE",
4224 "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
4225 }
4226
4227# check for uses of printk_ratelimit
4228 if ($line =~ /\bprintk_ratelimit\s*\(/) {
4229 WARN("PRINTK_RATELIMITED",
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004230 "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004231 }
4232
Peter Bigot5b10fac2020-03-26 11:16:33 -05004233# printk should use KERN_* levels
4234 if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4235 WARN("PRINTK_WITHOUT_KERN_LEVEL",
4236 "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004237 }
4238
4239 if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
4240 my $orig = $1;
4241 my $level = lc($orig);
4242 $level = "warn" if ($level eq "warning");
4243 my $level2 = $level;
4244 $level2 = "dbg" if ($level eq "debug");
4245 WARN("PREFER_PR_LEVEL",
4246 "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
4247 }
4248
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004249 if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4250 my $orig = $1;
4251 my $level = lc($orig);
4252 $level = "warn" if ($level eq "warning");
4253 $level = "dbg" if ($level eq "debug");
4254 WARN("PREFER_DEV_LEVEL",
4255 "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4256 }
4257
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004258# ENOSYS means "bad syscall nr" and nothing else. This will have a small
4259# number of false positives, but assembly files are not checked, so at
4260# least the arch entry code will not trigger this warning.
4261 if ($line =~ /\bENOSYS\b/) {
4262 WARN("ENOSYS",
4263 "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
4264 }
4265
Peter A. Bigote49e3c82020-08-10 10:37:32 -05004266# ENOTSUPP is not a standard error code and should be avoided in new patches.
4267# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
4268# Similarly to ENOSYS warning a small number of false positives is expected.
4269 if (!$file && $line =~ /\bENOTSUPP\b/) {
4270 if (WARN("ENOTSUPP",
4271 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
4272 $fix) {
4273 $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
4274 }
4275 }
4276
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004277# function brace can't be on same line, except for #defines of do while,
4278# or if closed on same line
Peter Bigot5b10fac2020-03-26 11:16:33 -05004279 if ($perl_version_ok &&
4280 $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
4281 $sline !~ /\#\s*define\b.*do\s*\{/ &&
4282 $sline !~ /}/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004283 if (ERROR("OPEN_BRACE",
Peter Bigot5b10fac2020-03-26 11:16:33 -05004284 "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004285 $fix) {
4286 fix_delete_line($fixlinenr, $rawline);
4287 my $fixed_line = $rawline;
4288 $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
4289 my $line1 = $1;
4290 my $line2 = $2;
4291 fix_insert_line($fixlinenr, ltrim($line1));
4292 fix_insert_line($fixlinenr, "\+{");
4293 if ($line2 !~ /^\s*$/) {
4294 fix_insert_line($fixlinenr, "\+\t" . trim($line2));
4295 }
4296 }
4297 }
4298
4299# open braces for enum, union and struct go on the same line.
4300 if ($line =~ /^.\s*{/ &&
4301 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
4302 if (ERROR("OPEN_BRACE",
4303 "open brace '{' following $1 go on the same line\n" . $hereprev) &&
4304 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4305 fix_delete_line($fixlinenr - 1, $prevrawline);
4306 fix_delete_line($fixlinenr, $rawline);
4307 my $fixedline = rtrim($prevrawline) . " {";
4308 fix_insert_line($fixlinenr, $fixedline);
4309 $fixedline = $rawline;
Anas Nashif1eb244c2017-10-01 17:06:36 -04004310 $fixedline =~ s/^(.\s*)\{\s*/$1\t/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004311 if ($fixedline !~ /^\+\s*$/) {
4312 fix_insert_line($fixlinenr, $fixedline);
4313 }
4314 }
4315 }
4316
4317# missing space after union, struct or enum definition
4318 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
4319 if (WARN("SPACING",
4320 "missing space after $1 definition\n" . $herecurr) &&
4321 $fix) {
4322 $fixed[$fixlinenr] =~
4323 s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
4324 }
4325 }
4326
4327# Function pointer declarations
4328# check spacing between type, funcptr, and args
4329# canonical declaration is "type (*funcptr)(args...)"
4330 if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
4331 my $declare = $1;
4332 my $pre_pointer_space = $2;
4333 my $post_pointer_space = $3;
4334 my $funcname = $4;
4335 my $post_funcname_space = $5;
4336 my $pre_args_space = $6;
4337
4338# the $Declare variable will capture all spaces after the type
4339# so check it for a missing trailing missing space but pointer return types
4340# don't need a space so don't warn for those.
4341 my $post_declare_space = "";
4342 if ($declare =~ /(\s+)$/) {
4343 $post_declare_space = $1;
4344 $declare = rtrim($declare);
4345 }
4346 if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
4347 WARN("SPACING",
4348 "missing space after return type\n" . $herecurr);
4349 $post_declare_space = " ";
4350 }
4351
4352# unnecessary space "type (*funcptr)(args...)"
4353# This test is not currently implemented because these declarations are
4354# equivalent to
4355# int foo(int bar, ...)
4356# and this is form shouldn't/doesn't generate a checkpatch warning.
4357#
4358# elsif ($declare =~ /\s{2,}$/) {
4359# WARN("SPACING",
4360# "Multiple spaces after return type\n" . $herecurr);
4361# }
4362
4363# unnecessary space "type ( *funcptr)(args...)"
4364 if (defined $pre_pointer_space &&
4365 $pre_pointer_space =~ /^\s/) {
4366 WARN("SPACING",
4367 "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
4368 }
4369
4370# unnecessary space "type (* funcptr)(args...)"
4371 if (defined $post_pointer_space &&
4372 $post_pointer_space =~ /^\s/) {
4373 WARN("SPACING",
4374 "Unnecessary space before function pointer name\n" . $herecurr);
4375 }
4376
4377# unnecessary space "type (*funcptr )(args...)"
4378 if (defined $post_funcname_space &&
4379 $post_funcname_space =~ /^\s/) {
4380 WARN("SPACING",
4381 "Unnecessary space after function pointer name\n" . $herecurr);
4382 }
4383
4384# unnecessary space "type (*funcptr) (args...)"
4385 if (defined $pre_args_space &&
4386 $pre_args_space =~ /^\s/) {
4387 WARN("SPACING",
4388 "Unnecessary space before function pointer arguments\n" . $herecurr);
4389 }
4390
4391 if (show_type("SPACING") && $fix) {
4392 $fixed[$fixlinenr] =~
4393 s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
4394 }
4395 }
4396
4397# check for spacing round square brackets; allowed:
4398# 1. with a type on the left -- int [] a;
4399# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4400# 3. inside a curly brace -- = { [0...10] = 5 }
4401 while ($line =~ /(.*?\s)\[/g) {
4402 my ($where, $prefix) = ($-[1], $1);
4403 if ($prefix !~ /$Type\s+$/ &&
4404 ($where != 0 || $prefix !~ /^.\s+$/) &&
Peter Bigot5b10fac2020-03-26 11:16:33 -05004405 $prefix !~ /[{,:]\s+$/ &&
Anas Nashif98c50de2015-11-06 18:23:35 -05004406 $prefix !~ /:\s+$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004407 if (ERROR("BRACKET_SPACE",
4408 "space prohibited before open square bracket '['\n" . $herecurr) &&
4409 $fix) {
4410 $fixed[$fixlinenr] =~
4411 s/^(\+.*?)\s+\[/$1\[/;
4412 }
4413 }
4414 }
4415
4416# check for spaces between functions and their parentheses.
4417 while ($line =~ /($Ident)\s+\(/g) {
4418 my $name = $1;
4419 my $ctx_before = substr($line, 0, $-[1]);
4420 my $ctx = "$ctx_before$name";
4421
4422 # Ignore those directives where spaces _are_ permitted.
4423 if ($name =~ /^(?:
4424 if|for|while|switch|return|case|
4425 volatile|__volatile__|
4426 __attribute__|format|__extension__|
4427 asm|__asm__)$/x)
4428 {
4429 # cpp #define statements have non-optional spaces, ie
4430 # if there is a space between the name and the open
4431 # parenthesis it is simply not a parameter group.
4432 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4433
4434 # cpp #elif statement condition may start with a (
4435 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4436
4437 # If this whole things ends with a type its most
4438 # likely a typedef for a function.
4439 } elsif ($ctx =~ /$Type$/) {
4440
4441 } else {
4442 if (WARN("SPACING",
4443 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
4444 $fix) {
4445 $fixed[$fixlinenr] =~
4446 s/\b$name\s+\(/$name\(/;
4447 }
4448 }
4449 }
4450
4451# Check operator spacing.
4452 if (!($line=~/\#\s*include/)) {
4453 my $fixed_line = "";
4454 my $line_fixed = 0;
4455
4456 my $ops = qr{
4457 <<=|>>=|<=|>=|==|!=|
4458 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
4459 =>|->|<<|>>|<|>|=|!|~|
4460 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
4461 \?:|\?|:
4462 }x;
4463 my @elements = split(/($ops|;)/, $opline);
4464
4465## print("element count: <" . $#elements . ">\n");
4466## foreach my $el (@elements) {
4467## print("el: <$el>\n");
4468## }
4469
4470 my @fix_elements = ();
4471 my $off = 0;
4472
4473 foreach my $el (@elements) {
4474 push(@fix_elements, substr($rawline, $off, length($el)));
4475 $off += length($el);
4476 }
4477
4478 $off = 0;
4479
4480 my $blank = copy_spacing($opline);
4481 my $last_after = -1;
4482
4483 for (my $n = 0; $n < $#elements; $n += 2) {
4484
4485 my $good = $fix_elements[$n] . $fix_elements[$n + 1];
4486
4487## print("n: <$n> good: <$good>\n");
4488
4489 $off += length($elements[$n]);
4490
4491 # Pick up the preceding and succeeding characters.
4492 my $ca = substr($opline, 0, $off);
4493 my $cc = '';
4494 if (length($opline) >= ($off + length($elements[$n + 1]))) {
4495 $cc = substr($opline, $off + length($elements[$n + 1]));
4496 }
4497 my $cb = "$ca$;$cc";
4498
4499 my $a = '';
4500 $a = 'V' if ($elements[$n] ne '');
4501 $a = 'W' if ($elements[$n] =~ /\s$/);
4502 $a = 'C' if ($elements[$n] =~ /$;$/);
4503 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
4504 $a = 'O' if ($elements[$n] eq '');
4505 $a = 'E' if ($ca =~ /^\s*$/);
4506
4507 my $op = $elements[$n + 1];
4508
4509 my $c = '';
4510 if (defined $elements[$n + 2]) {
4511 $c = 'V' if ($elements[$n + 2] ne '');
4512 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
4513 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
4514 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
4515 $c = 'O' if ($elements[$n + 2] eq '');
4516 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
4517 } else {
4518 $c = 'E';
4519 }
4520
4521 my $ctx = "${a}x${c}";
4522
4523 my $at = "(ctx:$ctx)";
4524
4525 my $ptr = substr($blank, 0, $off) . "^";
4526 my $hereptr = "$hereline$ptr\n";
4527
4528 # Pull out the value of this operator.
4529 my $op_type = substr($curr_values, $off + 1, 1);
4530
4531 # Get the full operator variant.
4532 my $opv = $op . substr($curr_vars, $off, 1);
4533
4534 # Ignore operators passed as parameters.
4535 if ($op_type ne 'V' &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004536 $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004537
4538# # Ignore comments
4539# } elsif ($op =~ /^$;+$/) {
4540
4541 # ; should have either the end of line or a space or \ after it
4542 } elsif ($op eq ';') {
4543 if ($ctx !~ /.x[WEBC]/ &&
4544 $cc !~ /^\\/ && $cc !~ /^;/) {
4545 if (ERROR("SPACING",
4546 "space required after that '$op' $at\n" . $hereptr)) {
4547 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
4548 $line_fixed = 1;
4549 }
4550 }
4551
4552 # // is a comment
4553 } elsif ($op eq '//') {
4554
4555 # : when part of a bitfield
4556 } elsif ($opv eq ':B') {
4557 # skip the bitfield test for now
4558
4559 # No spaces for:
4560 # ->
4561 } elsif ($op eq '->') {
4562 if ($ctx =~ /Wx.|.xW/) {
4563 if (ERROR("SPACING",
4564 "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4565 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4566 if (defined $fix_elements[$n + 2]) {
4567 $fix_elements[$n + 2] =~ s/^\s+//;
4568 }
4569 $line_fixed = 1;
4570 }
4571 }
4572
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004573 # , must not have a space before and must have a space on the right.
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004574 } elsif ($op eq ',') {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004575 my $rtrim_before = 0;
4576 my $space_after = 0;
4577 if ($ctx =~ /Wx./) {
4578 if (ERROR("SPACING",
4579 "space prohibited before that '$op' $at\n" . $hereptr)) {
4580 $line_fixed = 1;
4581 $rtrim_before = 1;
4582 }
4583 }
Anas Nashife7ee0832016-02-20 14:13:16 -05004584 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/ && $cc !~ /^\)/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004585 if (ERROR("SPACING",
4586 "space required after that '$op' $at\n" . $hereptr)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004587 $line_fixed = 1;
4588 $last_after = $n;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004589 $space_after = 1;
4590 }
4591 }
4592 if ($rtrim_before || $space_after) {
4593 if ($rtrim_before) {
4594 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4595 } else {
4596 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
4597 }
4598 if ($space_after) {
4599 $good .= " ";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004600 }
4601 }
4602
4603 # '*' as part of a type definition -- reported already.
4604 } elsif ($opv eq '*_') {
4605 #warn "'*' is part of type\n";
4606
4607 # unary operators should have a space before and
4608 # none after. May be left adjacent to another
4609 # unary operator, or a cast
4610 } elsif ($op eq '!' || $op eq '~' ||
4611 $opv eq '*U' || $opv eq '-U' ||
4612 $opv eq '&U' || $opv eq '&&U') {
4613 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
4614 if (ERROR("SPACING",
4615 "space required before that '$op' $at\n" . $hereptr)) {
4616 if ($n != $last_after + 2) {
4617 $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
4618 $line_fixed = 1;
4619 }
4620 }
4621 }
4622 if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4623 # A unary '*' may be const
4624
4625 } elsif ($ctx =~ /.xW/) {
4626 if (ERROR("SPACING",
4627 "space prohibited after that '$op' $at\n" . $hereptr)) {
4628 $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
4629 if (defined $fix_elements[$n + 2]) {
4630 $fix_elements[$n + 2] =~ s/^\s+//;
4631 }
4632 $line_fixed = 1;
4633 }
4634 }
4635
4636 # unary ++ and unary -- are allowed no space on one side.
4637 } elsif ($op eq '++' or $op eq '--') {
4638 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
4639 if (ERROR("SPACING",
4640 "space required one side of that '$op' $at\n" . $hereptr)) {
4641 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
4642 $line_fixed = 1;
4643 }
4644 }
4645 if ($ctx =~ /Wx[BE]/ ||
4646 ($ctx =~ /Wx./ && $cc =~ /^;/)) {
4647 if (ERROR("SPACING",
4648 "space prohibited before that '$op' $at\n" . $hereptr)) {
4649 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4650 $line_fixed = 1;
4651 }
4652 }
4653 if ($ctx =~ /ExW/) {
4654 if (ERROR("SPACING",
4655 "space prohibited after that '$op' $at\n" . $hereptr)) {
4656 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
4657 if (defined $fix_elements[$n + 2]) {
4658 $fix_elements[$n + 2] =~ s/^\s+//;
4659 }
4660 $line_fixed = 1;
4661 }
4662 }
4663
4664 # << and >> may either have or not have spaces both sides
4665 } elsif ($op eq '<<' or $op eq '>>' or
4666 $op eq '&' or $op eq '^' or $op eq '|' or
4667 $op eq '+' or $op eq '-' or
4668 $op eq '*' or $op eq '/' or
4669 $op eq '%')
4670 {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004671 if ($check) {
4672 if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4673 if (CHK("SPACING",
4674 "spaces preferred around that '$op' $at\n" . $hereptr)) {
4675 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4676 $fix_elements[$n + 2] =~ s/^\s+//;
4677 $line_fixed = 1;
4678 }
4679 } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4680 if (CHK("SPACING",
4681 "space preferred before that '$op' $at\n" . $hereptr)) {
4682 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4683 $line_fixed = 1;
4684 }
4685 }
4686 } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004687 if (ERROR("SPACING",
4688 "need consistent spacing around '$op' $at\n" . $hereptr)) {
4689 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4690 if (defined $fix_elements[$n + 2]) {
4691 $fix_elements[$n + 2] =~ s/^\s+//;
4692 }
4693 $line_fixed = 1;
4694 }
4695 }
4696
4697 # A colon needs no spaces before when it is
4698 # terminating a case value or a label.
4699 } elsif ($opv eq ':C' || $opv eq ':L') {
4700 if ($ctx =~ /Wx./) {
4701 if (ERROR("SPACING",
4702 "space prohibited before that '$op' $at\n" . $hereptr)) {
4703 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4704 $line_fixed = 1;
4705 }
4706 }
4707
4708 # All the others need spaces both sides.
4709 } elsif ($ctx !~ /[EWC]x[CWE]/) {
4710 my $ok = 0;
4711
4712 # Ignore email addresses <foo@bar>
4713 if (($op eq '<' &&
4714 $cc =~ /^\S+\@\S+>/) ||
4715 ($op eq '>' &&
4716 $ca =~ /<\S+\@\S+$/))
4717 {
Peter A. Bigote49e3c82020-08-10 10:37:32 -05004718 $ok = 1;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004719 }
4720
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004721 # for asm volatile statements
4722 # ignore a colon with another
4723 # colon immediately before or after
4724 if (($op eq ':') &&
4725 ($ca =~ /:$/ || $cc =~ /^:/)) {
4726 $ok = 1;
4727 }
4728
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004729 # messages are ERROR, but ?: are CHK
4730 if ($ok == 0) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04004731 my $msg_level = \&ERROR;
4732 $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004733
Anas Nashif1eb244c2017-10-01 17:06:36 -04004734 if (&{$msg_level}("SPACING",
4735 "spaces required around that '$op' $at\n" . $hereptr)) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004736 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4737 if (defined $fix_elements[$n + 2]) {
4738 $fix_elements[$n + 2] =~ s/^\s+//;
4739 }
4740 $line_fixed = 1;
4741 }
4742 }
4743 }
4744 $off += length($elements[$n + 1]);
4745
4746## print("n: <$n> GOOD: <$good>\n");
4747
4748 $fixed_line = $fixed_line . $good;
4749 }
4750
4751 if (($#elements % 2) == 0) {
4752 $fixed_line = $fixed_line . $fix_elements[$#elements];
4753 }
4754
4755 if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4756 $fixed[$fixlinenr] = $fixed_line;
4757 }
4758
4759
4760 }
4761
4762# check for whitespace before a non-naked semicolon
4763 if ($line =~ /^\+.*\S\s+;\s*$/) {
4764 if (WARN("SPACING",
4765 "space prohibited before semicolon\n" . $herecurr) &&
4766 $fix) {
4767 1 while $fixed[$fixlinenr] =~
4768 s/^(\+.*\S)\s+;/$1;/;
4769 }
4770 }
4771
4772# check for multiple assignments
4773 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4774 CHK("MULTIPLE_ASSIGNMENTS",
4775 "multiple assignments should be avoided\n" . $herecurr);
4776 }
4777
4778## # check for multiple declarations, allowing for a function declaration
4779## # continuation.
4780## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
4781## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
4782##
4783## # Remove any bracketed sections to ensure we do not
4784## # falsly report the parameters of functions.
4785## my $ln = $line;
4786## while ($ln =~ s/\([^\(\)]*\)//g) {
4787## }
4788## if ($ln =~ /,/) {
4789## WARN("MULTIPLE_DECLARATION",
4790## "declaring multiple variables together should be avoided\n" . $herecurr);
4791## }
4792## }
4793
4794#need space before brace following if, while, etc
Anas Nashif0f3d5472016-11-07 15:57:57 -05004795 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
Peter Bigot5b10fac2020-03-26 11:16:33 -05004796 $line =~ /\b(?:else|do)\{/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004797 if (ERROR("SPACING",
4798 "space required before the open brace '{'\n" . $herecurr) &&
4799 $fix) {
Peter Bigot5b10fac2020-03-26 11:16:33 -05004800 $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004801 }
4802 }
4803
4804## # check for blank lines before declarations
4805## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4806## $prevrawline =~ /^.\s*$/) {
4807## WARN("SPACING",
4808## "No blank lines before declarations\n" . $hereprev);
4809## }
4810##
4811
4812# closing brace should have a space following it when it has anything
4813# on the line
Peter Bigot5b10fac2020-03-26 11:16:33 -05004814 if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004815 if (ERROR("SPACING",
4816 "space required after that close brace '}'\n" . $herecurr) &&
4817 $fix) {
4818 $fixed[$fixlinenr] =~
4819 s/}((?!(?:,|;|\)))\S)/} $1/;
4820 }
4821 }
4822
4823# check spacing on square brackets
4824 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
4825 if (ERROR("SPACING",
4826 "space prohibited after that open square bracket '['\n" . $herecurr) &&
4827 $fix) {
4828 $fixed[$fixlinenr] =~
4829 s/\[\s+/\[/;
4830 }
4831 }
4832 if ($line =~ /\s\]/) {
4833 if (ERROR("SPACING",
4834 "space prohibited before that close square bracket ']'\n" . $herecurr) &&
4835 $fix) {
4836 $fixed[$fixlinenr] =~
4837 s/\s+\]/\]/;
4838 }
4839 }
4840
4841# check spacing on parentheses
4842 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
4843 $line !~ /for\s*\(\s+;/) {
4844 if (ERROR("SPACING",
4845 "space prohibited after that open parenthesis '('\n" . $herecurr) &&
4846 $fix) {
4847 $fixed[$fixlinenr] =~
4848 s/\(\s+/\(/;
4849 }
4850 }
4851 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4852 $line !~ /for\s*\(.*;\s+\)/ &&
4853 $line !~ /:\s+\)/) {
4854 if (ERROR("SPACING",
4855 "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
4856 $fix) {
4857 $fixed[$fixlinenr] =~
4858 s/\s+\)/\)/;
4859 }
4860 }
4861
4862# check unnecessary parentheses around addressof/dereference single $Lvals
4863# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4864
4865 while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004866 my $var = $1;
4867 if (CHK("UNNECESSARY_PARENTHESES",
4868 "Unnecessary parentheses around $var\n" . $herecurr) &&
4869 $fix) {
4870 $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4871 }
4872 }
4873
4874# check for unnecessary parentheses around function pointer uses
4875# ie: (foo->bar)(); should be foo->bar();
4876# but not "if (foo->bar) (" to avoid some false positives
4877 if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4878 my $var = $2;
4879 if (CHK("UNNECESSARY_PARENTHESES",
4880 "Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4881 $fix) {
4882 my $var2 = deparenthesize($var);
4883 $var2 =~ s/\s//g;
4884 $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4885 }
4886 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004887
Anas Nashif1eb244c2017-10-01 17:06:36 -04004888# check for unnecessary parentheses around comparisons in if uses
Peter Bigot5b10fac2020-03-26 11:16:33 -05004889# when !drivers/staging or command-line uses --strict
4890 if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
4891 $perl_version_ok && defined($stat) &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04004892 $stat =~ /(^.\s*if\s*($balanced_parens))/) {
4893 my $if_stat = $1;
4894 my $test = substr($2, 1, -1);
4895 my $herectx;
4896 while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
4897 my $match = $1;
4898 # avoid parentheses around potential macro args
4899 next if ($match =~ /^\s*\w+\s*$/);
4900 if (!defined($herectx)) {
4901 $herectx = $here . "\n";
4902 my $cnt = statement_rawlines($if_stat);
4903 for (my $n = 0; $n < $cnt; $n++) {
4904 my $rl = raw_line($linenr, $n);
4905 $herectx .= $rl . "\n";
4906 last if $rl =~ /^[ \+].*\{/;
4907 }
4908 }
4909 CHK("UNNECESSARY_PARENTHESES",
4910 "Unnecessary parentheses around '$match'\n" . $herectx);
4911 }
4912 }
4913
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004914#goto labels aren't indented, allow a single space however
4915 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
4916 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
4917 if (WARN("INDENTED_LABEL",
4918 "labels should not be indented\n" . $herecurr) &&
4919 $fix) {
4920 $fixed[$fixlinenr] =~
4921 s/^(.)\s+/$1/;
4922 }
4923 }
4924
4925# return is not a function
4926 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4927 my $spacing = $1;
Peter Bigot5b10fac2020-03-26 11:16:33 -05004928 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004929 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
4930 my $value = $1;
4931 $value = deparenthesize($value);
4932 if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4933 ERROR("RETURN_PARENTHESES",
4934 "return is not a function, parentheses are not required\n" . $herecurr);
4935 }
4936 } elsif ($spacing !~ /\s+/) {
4937 ERROR("SPACING",
4938 "space required before the open parenthesis '('\n" . $herecurr);
4939 }
4940 }
4941
4942# unnecessary return in a void function
4943# at end-of-function, with the previous line a single leading tab, then return;
4944# and the line before that not a goto label target like "out:"
4945 if ($sline =~ /^[ \+]}\s*$/ &&
4946 $prevline =~ /^\+\treturn\s*;\s*$/ &&
4947 $linenr >= 3 &&
4948 $lines[$linenr - 3] =~ /^[ +]/ &&
4949 $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
4950 WARN("RETURN_VOID",
4951 "void function return statements are not generally useful\n" . $hereprev);
4952 }
4953
4954# if statements using unnecessary parentheses - ie: if ((foo == bar))
Peter Bigot5b10fac2020-03-26 11:16:33 -05004955 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004956 $line =~ /\bif\s*((?:\(\s*){2,})/) {
4957 my $openparens = $1;
4958 my $count = $openparens =~ tr@\(@\(@;
4959 my $msg = "";
4960 if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4961 my $comp = $4; #Not $1 because of $LvalOrFunc
4962 $msg = " - maybe == should be = ?" if ($comp eq "==");
4963 WARN("UNNECESSARY_PARENTHESES",
4964 "Unnecessary parentheses$msg\n" . $herecurr);
4965 }
4966 }
4967
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004968# comparisons with a constant or upper case identifier on the left
4969# avoid cases like "foo + BAR < baz"
4970# only fix matches surrounded by parentheses to avoid incorrect
4971# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
Peter Bigot5b10fac2020-03-26 11:16:33 -05004972 if ($perl_version_ok &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004973 $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4974 my $lead = $1;
4975 my $const = $2;
4976 my $comp = $3;
4977 my $to = $4;
4978 my $newcomp = $comp;
Anas Nashif0f3d5472016-11-07 15:57:57 -05004979 if ($lead !~ /(?:$Operators|\.)\s*$/ &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04004980 $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4981 WARN("CONSTANT_COMPARISON",
4982 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4983 $fix) {
4984 if ($comp eq "<") {
4985 $newcomp = ">";
4986 } elsif ($comp eq "<=") {
4987 $newcomp = ">=";
4988 } elsif ($comp eq ">") {
4989 $newcomp = "<";
4990 } elsif ($comp eq ">=") {
4991 $newcomp = "<=";
4992 }
4993 $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4994 }
4995 }
4996
4997# Return of what appears to be an errno should normally be negative
4998 if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07004999 my $name = $1;
5000 if ($name ne 'EOF' && $name ne 'ERROR') {
5001 WARN("USE_NEGATIVE_ERRNO",
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005002 "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005003 }
5004 }
5005
5006# Need a space before open parenthesis after if, while etc
5007 if ($line =~ /\b(if|while|for|switch)\(/) {
5008 if (ERROR("SPACING",
5009 "space required before the open parenthesis '('\n" . $herecurr) &&
5010 $fix) {
5011 $fixed[$fixlinenr] =~
5012 s/\b(if|while|for|switch)\(/$1 \(/;
5013 }
5014 }
5015
5016# Check for illegal assignment in if conditional -- and check for trailing
5017# statements after the conditional.
5018 if ($line =~ /do\s*(?!{)/) {
5019 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
5020 ctx_statement_block($linenr, $realcnt, 0)
5021 if (!defined $stat);
5022 my ($stat_next) = ctx_statement_block($line_nr_next,
5023 $remain_next, $off_next);
5024 $stat_next =~ s/\n./\n /g;
5025 ##print "stat<$stat> stat_next<$stat_next>\n";
5026
5027 if ($stat_next =~ /^\s*while\b/) {
5028 # If the statement carries leading newlines,
5029 # then count those as offsets.
5030 my ($whitespace) =
5031 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5032 my $offset =
5033 statement_rawlines($whitespace) - 1;
5034
5035 $suppress_whiletrailers{$line_nr_next +
5036 $offset} = 1;
5037 }
5038 }
5039 if (!defined $suppress_whiletrailers{$linenr} &&
5040 defined($stat) && defined($cond) &&
5041 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5042 my ($s, $c) = ($stat, $cond);
5043
5044 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
Peter A. Bigote49e3c82020-08-10 10:37:32 -05005045 if (ERROR("ASSIGN_IN_IF",
5046 "do not use assignment in if condition\n" . $herecurr) &&
5047 $fix && $perl_version_ok) {
5048 if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
5049 my $space = $1;
5050 my $not = $2;
5051 my $statement = $3;
5052 my $assigned = $4;
5053 my $test = $8;
5054 my $against = $9;
5055 my $brace = $15;
5056 fix_delete_line($fixlinenr, $rawline);
5057 fix_insert_line($fixlinenr, "$space$statement;");
5058 my $newline = "${space}if (";
5059 $newline .= '!' if defined($not);
5060 $newline .= '(' if (defined $not && defined($test) && defined($against));
5061 $newline .= "$assigned";
5062 $newline .= " $test $against" if (defined($test) && defined($against));
5063 $newline .= ')' if (defined $not && defined($test) && defined($against));
5064 $newline .= ')';
5065 $newline .= " {" if (defined($brace));
5066 fix_insert_line($fixlinenr + 1, $newline);
5067 }
5068 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005069 }
5070
5071 # Find out what is on the end of the line after the
5072 # conditional.
5073 substr($s, 0, length($c), '');
5074 $s =~ s/\n.*//g;
Peter A. Bigote49e3c82020-08-10 10:37:32 -05005075 $s =~ s/$;//g; # Remove any comments
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005076 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
5077 $c !~ /}\s*while\s*/)
5078 {
5079 # Find out how long the conditional actually is.
5080 my @newlines = ($c =~ /\n/gs);
5081 my $cond_lines = 1 + $#newlines;
5082 my $stat_real = '';
5083
5084 $stat_real = raw_line($linenr, $cond_lines)
5085 . "\n" if ($cond_lines);
5086 if (defined($stat_real) && $cond_lines > 1) {
5087 $stat_real = "[...]\n$stat_real";
5088 }
5089
5090 ERROR("TRAILING_STATEMENTS",
5091 "trailing statements should be on next line\n" . $herecurr . $stat_real);
5092 }
5093 }
5094
5095# Check for bitwise tests written as boolean
5096 if ($line =~ /
5097 (?:
5098 (?:\[|\(|\&\&|\|\|)
5099 \s*0[xX][0-9]+\s*
5100 (?:\&\&|\|\|)
5101 |
5102 (?:\&\&|\|\|)
5103 \s*0[xX][0-9]+\s*
5104 (?:\&\&|\|\||\)|\])
5105 )/x)
5106 {
5107 WARN("HEXADECIMAL_BOOLEAN_TEST",
5108 "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
5109 }
5110
5111# if and else should not have general statements after it
5112 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
5113 my $s = $1;
Peter A. Bigote49e3c82020-08-10 10:37:32 -05005114 $s =~ s/$;//g; # Remove any comments
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005115 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5116 ERROR("TRAILING_STATEMENTS",
5117 "trailing statements should be on next line\n" . $herecurr);
5118 }
5119 }
5120# if should not continue a brace
5121 if ($line =~ /}\s*if\b/) {
5122 ERROR("TRAILING_STATEMENTS",
5123 "trailing statements should be on next line (or did you mean 'else if'?)\n" .
5124 $herecurr);
5125 }
5126# case and default should not have general statements after them
5127 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5128 $line !~ /\G(?:
5129 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5130 \s*return\s+
5131 )/xg)
5132 {
5133 ERROR("TRAILING_STATEMENTS",
5134 "trailing statements should be on next line\n" . $herecurr);
5135 }
5136
5137 # Check for }<nl>else {, these must be at the same
5138 # indent level to be relevant to each other.
5139 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
5140 $previndent == $indent) {
5141 if (ERROR("ELSE_AFTER_BRACE",
5142 "else should follow close brace '}'\n" . $hereprev) &&
5143 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5144 fix_delete_line($fixlinenr - 1, $prevrawline);
5145 fix_delete_line($fixlinenr, $rawline);
5146 my $fixedline = $prevrawline;
5147 $fixedline =~ s/}\s*$//;
5148 if ($fixedline !~ /^\+\s*$/) {
5149 fix_insert_line($fixlinenr, $fixedline);
5150 }
5151 $fixedline = $rawline;
5152 $fixedline =~ s/^(.\s*)else/$1} else/;
5153 fix_insert_line($fixlinenr, $fixedline);
5154 }
5155 }
5156
5157 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5158 $previndent == $indent) {
5159 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5160
5161 # Find out what is on the end of the line after the
5162 # conditional.
5163 substr($s, 0, length($c), '');
5164 $s =~ s/\n.*//g;
5165
5166 if ($s =~ /^\s*;/) {
5167 if (ERROR("WHILE_AFTER_BRACE",
5168 "while should follow close brace '}'\n" . $hereprev) &&
5169 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5170 fix_delete_line($fixlinenr - 1, $prevrawline);
5171 fix_delete_line($fixlinenr, $rawline);
5172 my $fixedline = $prevrawline;
5173 my $trailing = $rawline;
5174 $trailing =~ s/^\+//;
5175 $trailing = trim($trailing);
5176 $fixedline =~ s/}\s*$/} $trailing/;
5177 fix_insert_line($fixlinenr, $fixedline);
5178 }
5179 }
5180 }
5181
5182#Specific variable tests
5183 while ($line =~ m{($Constant|$Lval)}g) {
5184 my $var = $1;
5185
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005186#CamelCase
5187 if ($var !~ /^$Constant$/ &&
5188 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
5189#Ignore Page<foo> variants
5190 $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
Peter Bigot5b10fac2020-03-26 11:16:33 -05005191#Ignore SI style variants like nS, mV and dB
5192#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5193 $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005194#Ignore some three character SI units explicitly, like MiB and KHz
5195 $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005196 while ($var =~ m{($Ident)}g) {
5197 my $word = $1;
5198 next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5199 if ($check) {
5200 seed_camelcase_includes();
5201 if (!$file && !$camelcase_file_seeded) {
5202 seed_camelcase_file($realfile);
5203 $camelcase_file_seeded = 1;
5204 }
5205 }
5206 if (!defined $camelcase{$word}) {
5207 $camelcase{$word} = 1;
5208 CHK("CAMELCASE",
5209 "Avoid CamelCase: <$word>\n" . $herecurr);
5210 }
5211 }
5212 }
5213 }
5214
5215#no spaces allowed after \ in define
5216 if ($line =~ /\#\s*define.*\\\s+$/) {
5217 if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5218 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5219 $fix) {
5220 $fixed[$fixlinenr] =~ s/\s+$//;
5221 }
5222 }
5223
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005224# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
5225# itself <asm/foo.h> (uses RAW line)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005226 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5227 my $file = "$1.h";
5228 my $checkfile = "include/linux/$file";
5229 if (-f "$root/$checkfile" &&
5230 $realfile ne $checkfile &&
5231 $1 !~ /$allowed_asm_includes/)
5232 {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005233 my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
5234 if ($asminclude > 0) {
5235 if ($realfile =~ m{^arch/}) {
5236 CHK("ARCH_INCLUDE_LINUX",
5237 "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5238 } else {
5239 WARN("INCLUDE_LINUX",
5240 "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5241 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005242 }
5243 }
5244 }
5245
5246# multi-statement macros should be enclosed in a do while loop, grab the
5247# first statement and ensure its the whole macro if its not enclosed
5248# in a known good container
5249 if ($realfile !~ m@/vmlinux.lds.h$@ &&
5250 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5251 my $ln = $linenr;
5252 my $cnt = $realcnt;
5253 my ($off, $dstat, $dcond, $rest);
5254 my $ctx = '';
5255 my $has_flow_statement = 0;
5256 my $has_arg_concat = 0;
5257 ($dstat, $dcond, $ln, $cnt, $off) =
5258 ctx_statement_block($linenr, $realcnt, 0);
5259 $ctx = $dstat;
5260 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5261 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5262
5263 $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
Anas Nashif76b09132016-02-20 13:53:35 -05005264 $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005265
Anas Nashif0f3d5472016-11-07 15:57:57 -05005266 $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5267 my $define_args = $1;
5268 my $define_stmt = $dstat;
5269 my @def_args = ();
5270
5271 if (defined $define_args && $define_args ne "") {
5272 $define_args = substr($define_args, 1, length($define_args) - 2);
5273 $define_args =~ s/\s*//g;
Peter Bigot5b10fac2020-03-26 11:16:33 -05005274 $define_args =~ s/\\\+?//g;
Anas Nashif0f3d5472016-11-07 15:57:57 -05005275 @def_args = split(",", $define_args);
5276 }
5277
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005278 $dstat =~ s/$;//g;
5279 $dstat =~ s/\\\n.//g;
5280 $dstat =~ s/^\s*//s;
5281 $dstat =~ s/\s*$//s;
5282
5283 # Flatten any parentheses and braces
5284 while ($dstat =~ s/\([^\(\)]*\)/1/ ||
5285 $dstat =~ s/\{[^\{\}]*\}/1/ ||
Anas Nashif76b09132016-02-20 13:53:35 -05005286 $dstat =~ s/.\[[^\[\]]*\]/1/)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005287 {
5288 }
5289
Peter A. Bigote49e3c82020-08-10 10:37:32 -05005290 # Flatten any obvious string concatenation.
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005291 while ($dstat =~ s/($String)\s*$Ident/$1/ ||
5292 $dstat =~ s/$Ident\s*($String)/$1/)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005293 {
5294 }
5295
Anas Nashif0f3d5472016-11-07 15:57:57 -05005296 # Make asm volatile uses seem like a generic function
5297 $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
5298
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005299 my $exceptions = qr{
5300 $Declare|
5301 module_param_named|
5302 MODULE_PARM_DESC|
5303 DECLARE_PER_CPU|
5304 DEFINE_PER_CPU|
5305 __typeof__\(|
5306 union|
5307 struct|
5308 \.$Ident\s*=\s*|
Anas Nashif76b09132016-02-20 13:53:35 -05005309 ^\"|\"$|
5310 ^\[
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005311 }x;
5312 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
Anas Nashif0f3d5472016-11-07 15:57:57 -05005313
5314 $ctx =~ s/\n*$//;
Anas Nashif0f3d5472016-11-07 15:57:57 -05005315 my $stmt_cnt = statement_rawlines($ctx);
Peter Bigot5b10fac2020-03-26 11:16:33 -05005316 my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
Anas Nashif0f3d5472016-11-07 15:57:57 -05005317
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005318 if ($dstat ne '' &&
5319 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
5320 $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
5321 $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5322 $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants
5323 $dstat !~ /$exceptions/ &&
5324 $dstat !~ /^\.$Ident\s*=/ && # .foo =
5325 $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
5326 $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
5327 $dstat !~ /^for\s*$Constant$/ && # for (...)
5328 $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
5329 $dstat !~ /^do\s*{/ && # do {...
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005330 $dstat !~ /^\(\{/ && # ({...
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005331 $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5332 {
Anas Nashif1eb244c2017-10-01 17:06:36 -04005333 if ($dstat =~ /^\s*if\b/) {
5334 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5335 "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5336 } elsif ($dstat =~ /;/) {
5337 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005338 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5339 } else {
Anas Nashif65f0c672018-05-08 10:19:30 -05005340 WARN("COMPLEX_MACRO",
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005341 "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5342 }
Anas Nashif0f3d5472016-11-07 15:57:57 -05005343
5344 }
5345
5346 # Make $define_stmt single line, comment-free, etc
5347 my @stmt_array = split('\n', $define_stmt);
5348 my $first = 1;
5349 $define_stmt = "";
5350 foreach my $l (@stmt_array) {
5351 $l =~ s/\\$//;
5352 if ($first) {
5353 $define_stmt = $l;
5354 $first = 0;
5355 } elsif ($l =~ /^[\+ ]/) {
5356 $define_stmt .= substr($l, 1);
5357 }
5358 }
5359 $define_stmt =~ s/$;//g;
5360 $define_stmt =~ s/\s+/ /g;
5361 $define_stmt = trim($define_stmt);
5362
5363# check if any macro arguments are reused (ignore '...' and 'type')
5364 foreach my $arg (@def_args) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04005365 next if ($arg =~ /\.\.\./);
5366 next if ($arg =~ /^type$/i);
5367 my $tmp_stmt = $define_stmt;
Peter Bigot5b10fac2020-03-26 11:16:33 -05005368 $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
Anas Nashif1eb244c2017-10-01 17:06:36 -04005369 $tmp_stmt =~ s/\#+\s*$arg\b//g;
5370 $tmp_stmt =~ s/\b$arg\s*\#\#//g;
Peter Bigot5b10fac2020-03-26 11:16:33 -05005371 my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
Anas Nashif0f3d5472016-11-07 15:57:57 -05005372 if ($use_cnt > 1) {
5373 CHK("MACRO_ARG_REUSE",
Anas Nashif1eb244c2017-10-01 17:06:36 -04005374 "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5375 }
Anas Nashif0f3d5472016-11-07 15:57:57 -05005376# check if any macro arguments may have other precedence issues
Anas Nashif1eb244c2017-10-01 17:06:36 -04005377 if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
5378 ((defined($1) && $1 ne ',') ||
5379 (defined($2) && $2 ne ','))) {
Anas Nashif0f3d5472016-11-07 15:57:57 -05005380 CHK("MACRO_ARG_PRECEDENCE",
Anas Nashif1eb244c2017-10-01 17:06:36 -04005381 "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
Anas Nashif0f3d5472016-11-07 15:57:57 -05005382 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005383 }
5384
5385# check for macros with flow control, but without ## concatenation
5386# ## concatenation is commonly a macro that defines a function so ignore those
5387 if ($has_flow_statement && !$has_arg_concat) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005388 my $cnt = statement_rawlines($ctx);
Peter Bigot5b10fac2020-03-26 11:16:33 -05005389 my $herectx = get_stat_here($linenr, $cnt, $here);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005390
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005391 WARN("MACRO_WITH_FLOW_CONTROL",
5392 "Macros with flow control statements should be avoided\n" . "$herectx");
5393 }
5394
5395# check for line continuations outside of #defines, preprocessor #, and asm
5396
5397 } else {
5398 if ($prevline !~ /^..*\\$/ &&
5399 $line !~ /^\+\s*\#.*\\$/ && # preprocessor
5400 $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
5401 $line =~ /^\+.*\\$/) {
5402 WARN("LINE_CONTINUATIONS",
5403 "Avoid unnecessary line continuations\n" . $herecurr);
5404 }
5405 }
5406
5407# do {} while (0) macro tests:
5408# single-statement macros do not need to be enclosed in do while (0) loop,
5409# macro should not end with a semicolon
Peter Bigot5b10fac2020-03-26 11:16:33 -05005410 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005411 $realfile !~ m@/vmlinux.lds.h$@ &&
5412 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5413 my $ln = $linenr;
5414 my $cnt = $realcnt;
5415 my ($off, $dstat, $dcond, $rest);
5416 my $ctx = '';
5417 ($dstat, $dcond, $ln, $cnt, $off) =
5418 ctx_statement_block($linenr, $realcnt, 0);
5419 $ctx = $dstat;
5420
5421 $dstat =~ s/\\\n.//g;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005422 $dstat =~ s/$;/ /g;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005423
5424 if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5425 my $stmts = $2;
5426 my $semis = $3;
5427
5428 $ctx =~ s/\n*$//;
5429 my $cnt = statement_rawlines($ctx);
Peter Bigot5b10fac2020-03-26 11:16:33 -05005430 my $herectx = get_stat_here($linenr, $cnt, $here);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005431
5432 if (($stmts =~ tr/;/;/) == 1 &&
5433 $stmts !~ /^\s*(if|while|for|switch)\b/) {
5434 WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5435 "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5436 }
5437 if (defined $semis && $semis ne "") {
5438 WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5439 "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5440 }
5441 } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5442 $ctx =~ s/\n*$//;
5443 my $cnt = statement_rawlines($ctx);
Peter Bigot5b10fac2020-03-26 11:16:33 -05005444 my $herectx = get_stat_here($linenr, $cnt, $here);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005445
5446 WARN("TRAILING_SEMICOLON",
5447 "macros should not use a trailing semicolon\n" . "$herectx");
5448 }
5449 }
5450
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005451# check for redundant bracing round if etc
5452 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
5453 my ($level, $endln, @chunks) =
5454 ctx_statement_full($linenr, $realcnt, 1);
5455 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5456 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5457 if ($#chunks > 0 && $level == 0) {
5458 my @allowed = ();
5459 my $allow = 0;
5460 my $seen = 0;
5461 my $herectx = $here . "\n";
5462 my $ln = $linenr - 1;
5463 for my $chunk (@chunks) {
5464 my ($cond, $block) = @{$chunk};
5465
5466 # If the condition carries leading newlines, then count those as offsets.
5467 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5468 my $offset = statement_rawlines($whitespace) - 1;
5469
5470 $allowed[$allow] = 0;
5471 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5472
5473 # We have looked at and allowed this specific line.
5474 $suppress_ifbraces{$ln + $offset} = 1;
5475
5476 $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5477 $ln += statement_rawlines($block) - 1;
5478
5479 substr($block, 0, length($cond), '');
5480
5481 $seen++ if ($block =~ /^\s*{/);
5482
5483 #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5484 if (statement_lines($cond) > 1) {
5485 #print "APW: ALLOWED: cond<$cond>\n";
5486 $allowed[$allow] = 1;
5487 }
5488 if ($block =~/\b(?:if|for|while)\b/) {
5489 #print "APW: ALLOWED: block<$block>\n";
5490 $allowed[$allow] = 1;
5491 }
5492 if (statement_block_size($block) > 1) {
5493 #print "APW: ALLOWED: lines block<$block>\n";
5494 $allowed[$allow] = 1;
5495 }
5496 $allow++;
5497 }
5498 if ($seen) {
5499 my $sum_allowed = 0;
5500 foreach (@allowed) {
5501 $sum_allowed += $_;
5502 }
5503 if ($sum_allowed == 0) {
5504 WARN("BRACES",
5505 "braces {} are not necessary for any arm of this statement\n" . $herectx);
5506 } elsif ($sum_allowed != $allow &&
5507 $seen != $allow) {
5508 CHK("BRACES",
5509 "braces {} should be used on all arms of this statement\n" . $herectx);
5510 }
5511 }
5512 }
5513 }
5514 if (!defined $suppress_ifbraces{$linenr - 1} &&
5515 $line =~ /\b(if|while|for|else)\b/) {
5516 my $allowed = 0;
5517
5518 # Check the pre-context.
5519 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5520 #print "APW: ALLOWED: pre<$1>\n";
5521 $allowed = 1;
5522 }
5523
5524 my ($level, $endln, @chunks) =
5525 ctx_statement_full($linenr, $realcnt, $-[0]);
5526
5527 # Check the condition.
5528 my ($cond, $block) = @{$chunks[0]};
5529 #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5530 if (defined $cond) {
5531 substr($block, 0, length($cond), '');
5532 }
5533 if (statement_lines($cond) > 1) {
5534 #print "APW: ALLOWED: cond<$cond>\n";
5535 $allowed = 1;
5536 }
5537 if ($block =~/\b(?:if|for|while)\b/) {
5538 #print "APW: ALLOWED: block<$block>\n";
5539 $allowed = 1;
5540 }
5541 if (statement_block_size($block) > 1) {
5542 #print "APW: ALLOWED: lines block<$block>\n";
5543 $allowed = 1;
5544 }
5545 # Check the post-context.
5546 if (defined $chunks[1]) {
5547 my ($cond, $block) = @{$chunks[1]};
5548 if (defined $cond) {
5549 substr($block, 0, length($cond), '');
5550 }
5551 if ($block =~ /^\s*\{/) {
5552 #print "APW: ALLOWED: chunk-1 block<$block>\n";
5553 $allowed = 1;
5554 }
5555 }
5556 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005557 my $cnt = statement_rawlines($block);
Peter Bigot5b10fac2020-03-26 11:16:33 -05005558 my $herectx = get_stat_here($linenr, $cnt, $here);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005559
5560 WARN("BRACES",
5561 "braces {} are not necessary for single statement blocks\n" . $herectx);
5562 }
5563 }
5564
Anas Nashif1eb244c2017-10-01 17:06:36 -04005565# check for single line unbalanced braces
5566 if ($sline =~ /^.\s*\}\s*else\s*$/ ||
5567 $sline =~ /^.\s*else\s*\{\s*$/) {
5568 CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5569 }
5570
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005571# check for unnecessary blank lines around braces
5572 if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005573 if (CHK("BRACES",
5574 "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5575 $fix && $prevrawline =~ /^\+/) {
5576 fix_delete_line($fixlinenr - 1, $prevrawline);
5577 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005578 }
5579 if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005580 if (CHK("BRACES",
5581 "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5582 $fix) {
5583 fix_delete_line($fixlinenr, $rawline);
5584 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005585 }
5586
5587# no volatiles please
5588 my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
5589 if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5590 WARN("VOLATILE",
Anas Nashif1eb244c2017-10-01 17:06:36 -04005591 "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005592 }
5593
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005594# Check for user-visible strings broken across lines, which breaks the ability
5595# to grep for the string. Make exceptions when the previous string ends in a
5596# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
5597# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
5598 if ($line =~ /^\+\s*$String/ &&
5599 $prevline =~ /"\s*$/ &&
5600 $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
5601 if (WARN("SPLIT_STRING",
5602 "quoted string split across lines\n" . $hereprev) &&
5603 $fix &&
5604 $prevrawline =~ /^\+.*"\s*$/ &&
5605 $last_coalesced_string_linenr != $linenr - 1) {
5606 my $extracted_string = get_quoted_string($line, $rawline);
5607 my $comma_close = "";
5608 if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
5609 $comma_close = $1;
5610 }
5611
5612 fix_delete_line($fixlinenr - 1, $prevrawline);
5613 fix_delete_line($fixlinenr, $rawline);
5614 my $fixedline = $prevrawline;
5615 $fixedline =~ s/"\s*$//;
5616 $fixedline .= substr($extracted_string, 1) . trim($comma_close);
5617 fix_insert_line($fixlinenr - 1, $fixedline);
5618 $fixedline = $rawline;
5619 $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
5620 if ($fixedline !~ /\+\s*$/) {
5621 fix_insert_line($fixlinenr, $fixedline);
5622 }
5623 $last_coalesced_string_linenr = $linenr;
5624 }
5625 }
5626
5627# check for missing a space in a string concatenation
5628 if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
5629 WARN('MISSING_SPACE',
5630 "break quoted strings at a space character\n" . $hereprev);
5631 }
5632
Anas Nashif1eb244c2017-10-01 17:06:36 -04005633# check for an embedded function name in a string when the function is known
5634# This does not work very well for -f --file checking as it depends on patch
5635# context providing the function name or a single line form for in-file
5636# function declarations
5637 if ($line =~ /^\+.*$String/ &&
5638 defined($context_function) &&
5639 get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5640 length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
5641 WARN("EMBEDDED_FUNCTION_NAME",
5642 "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
5643 }
5644
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005645# check for spaces before a quoted newline
5646 if ($rawline =~ /^.*\".*\s\\n/) {
5647 if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
5648 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
5649 $fix) {
5650 $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
5651 }
5652
5653 }
5654
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005655# concatenated string without spaces between elements
Peter Bigot5b10fac2020-03-26 11:16:33 -05005656 if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
5657 if (CHK("CONCATENATED_STRING",
5658 "Concatenated strings should use spaces between elements\n" . $herecurr) &&
5659 $fix) {
5660 while ($line =~ /($String)/g) {
5661 my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
5662 $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
5663 $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
5664 }
5665 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005666 }
5667
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005668# uncoalesced string fragments
5669 if ($line =~ /$String\s*"/) {
Peter Bigot5b10fac2020-03-26 11:16:33 -05005670 if (WARN("STRING_FRAGMENTS",
5671 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
5672 $fix) {
5673 while ($line =~ /($String)(?=\s*")/g) {
5674 my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
5675 $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
5676 }
5677 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005678 }
5679
Anas Nashif1eb244c2017-10-01 17:06:36 -04005680# check for non-standard and hex prefixed decimal printf formats
5681 my $show_L = 1; #don't show the same defect twice
5682 my $show_Z = 1;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005683 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04005684 my $string = substr($rawline, $-[1], $+[1] - $-[1]);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005685 $string =~ s/%%/__/g;
Anas Nashif1eb244c2017-10-01 17:06:36 -04005686 # check for %L
5687 if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005688 WARN("PRINTF_L",
Anas Nashif1eb244c2017-10-01 17:06:36 -04005689 "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5690 $show_L = 0;
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005691 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04005692 # check for %Z
5693 if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5694 WARN("PRINTF_Z",
5695 "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5696 $show_Z = 0;
5697 }
5698 # check for 0x<decimal>
5699 if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5700 ERROR("PRINTF_0XDECIMAL",
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005701 "Prefixing 0x with decimal output is defective\n" . $herecurr);
5702 }
5703 }
5704
5705# check for line continuations in quoted strings with odd counts of "
Peter Bigot5b10fac2020-03-26 11:16:33 -05005706 if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005707 WARN("LINE_CONTINUATIONS",
5708 "Avoid line continuations in quoted strings\n" . $herecurr);
5709 }
5710
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005711# warn about #if 0
5712 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
Peter Bigot5b10fac2020-03-26 11:16:33 -05005713 WARN("IF_0",
5714 "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
5715 }
5716
5717# warn about #if 1
5718 if ($line =~ /^.\s*\#\s*if\s+1\b/) {
5719 WARN("IF_1",
5720 "Consider removing the #if 1 and its #endif\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005721 }
5722
5723# check for needless "if (<foo>) fn(<foo>)" uses
5724 if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005725 my $tested = quotemeta($1);
5726 my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5727 if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5728 my $func = $1;
5729 if (WARN('NEEDLESS_IF',
5730 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5731 $fix) {
5732 my $do_fix = 1;
5733 my $leading_tabs = "";
5734 my $new_leading_tabs = "";
5735 if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5736 $leading_tabs = $1;
5737 } else {
5738 $do_fix = 0;
5739 }
5740 if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5741 $new_leading_tabs = $1;
5742 if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5743 $do_fix = 0;
5744 }
5745 } else {
5746 $do_fix = 0;
5747 }
5748 if ($do_fix) {
5749 fix_delete_line($fixlinenr - 1, $prevrawline);
5750 $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5751 }
5752 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005753 }
5754 }
5755
5756# check for unnecessary "Out of Memory" messages
5757 if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5758 $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5759 (defined $1 || defined $3) &&
5760 $linenr > 3) {
5761 my $testval = $2;
5762 my $testline = $lines[$linenr - 3];
5763
5764 my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5765# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5766
Peter Bigot5b10fac2020-03-26 11:16:33 -05005767 if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
5768 $s !~ /\b__GFP_NOWARN\b/ ) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005769 WARN("OOM_MESSAGE",
5770 "Possible unnecessary 'out of memory' message\n" . $hereprev);
5771 }
5772 }
5773
5774# check for logging functions with KERN_<LEVEL>
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005775 if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005776 $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5777 my $level = $1;
5778 if (WARN("UNNECESSARY_KERN_LEVEL",
5779 "Possible unnecessary $level\n" . $herecurr) &&
5780 $fix) {
5781 $fixed[$fixlinenr] =~ s/\s*$level\s*//;
5782 }
5783 }
5784
Anas Nashif1eb244c2017-10-01 17:06:36 -04005785# check for logging continuations
5786 if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
5787 WARN("LOGGING_CONTINUATION",
5788 "Avoid logging continuation uses where feasible\n" . $herecurr);
5789 }
5790
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005791# check for mask then right shift without a parentheses
Peter Bigot5b10fac2020-03-26 11:16:33 -05005792 if ($perl_version_ok &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005793 $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5794 $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5795 WARN("MASK_THEN_SHIFT",
5796 "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5797 }
5798
5799# check for pointer comparisons to NULL
Peter Bigot5b10fac2020-03-26 11:16:33 -05005800 if ($perl_version_ok) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005801 while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5802 my $val = $1;
5803 my $equal = "!";
5804 $equal = "" if ($4 eq "!=");
5805 if (CHK("COMPARISON_TO_NULL",
5806 "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5807 $fix) {
5808 $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5809 }
5810 }
5811 }
5812
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005813# check for bad placement of section $InitAttribute (e.g.: __initdata)
5814 if ($line =~ /(\b$InitAttribute\b)/) {
5815 my $attr = $1;
5816 if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
5817 my $ptr = $1;
5818 my $var = $2;
5819 if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
5820 ERROR("MISPLACED_INIT",
5821 "$attr should be placed after $var\n" . $herecurr)) ||
5822 ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
5823 WARN("MISPLACED_INIT",
5824 "$attr should be placed after $var\n" . $herecurr))) &&
5825 $fix) {
5826 $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;
5827 }
5828 }
5829 }
5830
5831# check for $InitAttributeData (ie: __initdata) with const
5832 if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5833 my $attr = $1;
5834 $attr =~ /($InitAttributePrefix)(.*)/;
5835 my $attr_prefix = $1;
5836 my $attr_type = $2;
5837 if (ERROR("INIT_ATTRIBUTE",
5838 "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5839 $fix) {
5840 $fixed[$fixlinenr] =~
5841 s/$InitAttributeData/${attr_prefix}initconst/;
5842 }
5843 }
5844
5845# check for $InitAttributeConst (ie: __initconst) without const
5846 if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5847 my $attr = $1;
5848 if (ERROR("INIT_ATTRIBUTE",
5849 "Use of $attr requires a separate use of const\n" . $herecurr) &&
5850 $fix) {
5851 my $lead = $fixed[$fixlinenr] =~
5852 /(^\+\s*(?:static\s+))/;
5853 $lead = rtrim($1);
5854 $lead = "$lead " if ($lead !~ /^\+$/);
5855 $lead = "${lead}const ";
5856 $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5857 }
5858 }
5859
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005860# check for __read_mostly with const non-pointer (should just be const)
5861 if ($line =~ /\b__read_mostly\b/ &&
5862 $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5863 if (ERROR("CONST_READ_MOSTLY",
5864 "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5865 $fix) {
5866 $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5867 }
5868 }
5869
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005870# don't use __constant_<foo> functions outside of include/uapi/
5871 if ($realfile !~ m@^include/uapi/@ &&
5872 $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5873 my $constant_func = $1;
5874 my $func = $constant_func;
5875 $func =~ s/^__constant_//;
5876 if (WARN("CONSTANT_CONVERSION",
5877 "$constant_func should be $func\n" . $herecurr) &&
5878 $fix) {
5879 $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5880 }
5881 }
5882
5883# prefer usleep_range over udelay
5884 if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
5885 my $delay = $1;
5886 # ignore udelay's < 10, however
5887 if (! ($delay < 10) ) {
5888 CHK("USLEEP_RANGE",
Peter Bigot5b10fac2020-03-26 11:16:33 -05005889 "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005890 }
5891 if ($delay > 2000) {
5892 WARN("LONG_UDELAY",
5893 "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
5894 }
5895 }
5896
5897# warn about unexpectedly long msleep's
5898 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
5899 if ($1 < 20) {
5900 WARN("MSLEEP",
Peter Bigot5b10fac2020-03-26 11:16:33 -05005901 "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005902 }
5903 }
5904
5905# check for comparisons of jiffies
5906 if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
5907 WARN("JIFFIES_COMPARISON",
5908 "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
5909 }
5910
5911# check for comparisons of get_jiffies_64()
5912 if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
5913 WARN("JIFFIES_COMPARISON",
5914 "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
5915 }
5916
5917# warn about #ifdefs in C files
5918# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
5919# print "#ifdef in C files should be avoided\n";
5920# print "$herecurr";
5921# $clean = 0;
5922# }
5923
5924# warn about spacing in #ifdefs
5925 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
5926 if (ERROR("SPACING",
5927 "exactly one space required after that #$1\n" . $herecurr) &&
5928 $fix) {
5929 $fixed[$fixlinenr] =~
5930 s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
5931 }
5932
5933 }
5934
5935# check for spinlock_t definitions without a comment.
5936 if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5937 $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
5938 my $which = $1;
5939 if (!ctx_has_comment($first_line, $linenr)) {
5940 CHK("UNCOMMENTED_DEFINITION",
5941 "$1 definition without comment\n" . $herecurr);
5942 }
5943 }
5944# check for memory barriers without a comment.
Anas Nashif76b09132016-02-20 13:53:35 -05005945
5946 my $barriers = qr{
5947 mb|
5948 rmb|
Peter A. Bigote49e3c82020-08-10 10:37:32 -05005949 wmb
Anas Nashif76b09132016-02-20 13:53:35 -05005950 }x;
5951 my $barrier_stems = qr{
5952 mb__before_atomic|
5953 mb__after_atomic|
5954 store_release|
5955 load_acquire|
5956 store_mb|
5957 (?:$barriers)
5958 }x;
5959 my $all_barriers = qr{
5960 (?:$barriers)|
5961 smp_(?:$barrier_stems)|
5962 virt_(?:$barrier_stems)
5963 }x;
5964
5965 if ($line =~ /\b(?:$all_barriers)\s*\(/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005966 if (!ctx_has_comment($first_line, $linenr)) {
5967 WARN("MEMORY_BARRIER",
5968 "memory barrier without comment\n" . $herecurr);
5969 }
5970 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005971
Anas Nashif76b09132016-02-20 13:53:35 -05005972 my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5973
5974 if ($realfile !~ m@^include/asm-generic/@ &&
5975 $realfile !~ m@/barrier\.h$@ &&
5976 $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5977 $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5978 WARN("MEMORY_BARRIER",
5979 "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5980 }
5981
Anas Nashifcbfb62c2015-10-14 06:08:54 -04005982# check for waitqueue_active without a comment.
5983 if ($line =~ /\bwaitqueue_active\s*\(/) {
5984 if (!ctx_has_comment($first_line, $linenr)) {
5985 WARN("WAITQUEUE_ACTIVE",
5986 "waitqueue_active without comment\n" . $herecurr);
5987 }
5988 }
5989
Peter A. Bigote49e3c82020-08-10 10:37:32 -05005990# check for data_race without a comment.
5991 if ($line =~ /\bdata_race\s*\(/) {
5992 if (!ctx_has_comment($first_line, $linenr)) {
5993 WARN("DATA_RACE",
5994 "data_race without comment\n" . $herecurr);
5995 }
Peter Bigot5b10fac2020-03-26 11:16:33 -05005996 }
5997
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005998# check of hardware specific defines
5999 if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6000 CHK("ARCH_DEFINES",
6001 "architecture specific defines should be avoided\n" . $herecurr);
6002 }
6003
Anas Nashif1eb244c2017-10-01 17:06:36 -04006004# check that the storage class is not after a type
6005 if ($line =~ /\b($Type)\s+($Storage)\b/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006006 WARN("STORAGE_CLASS",
Anas Nashif1eb244c2017-10-01 17:06:36 -04006007 "storage class '$2' should be located before type '$1'\n" . $herecurr);
6008 }
6009# Check that the storage class is at the beginning of a declaration
6010 if ($line =~ /\b$Storage\b/ &&
6011 $line !~ /^.\s*$Storage/ &&
6012 $line =~ /^.\s*(.+?)\$Storage\s/ &&
6013 $1 !~ /[\,\)]\s*$/) {
6014 WARN("STORAGE_CLASS",
6015 "storage class should be at the beginning of the declaration\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006016 }
6017
6018# check the location of the inline attribute, that it is between
6019# storage class and type.
6020 if ($line =~ /\b$Type\s+$Inline\b/ ||
6021 $line =~ /\b$Inline\s+$Storage\b/) {
6022 ERROR("INLINE_LOCATION",
6023 "inline keyword should sit between storage class and type\n" . $herecurr);
6024 }
6025
6026# Check for __inline__ and __inline, prefer inline
6027 if ($realfile !~ m@\binclude/uapi/@ &&
6028 $line =~ /\b(__inline__|__inline)\b/) {
6029 if (WARN("INLINE",
6030 "plain inline is preferred over $1\n" . $herecurr) &&
6031 $fix) {
6032 $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6033
6034 }
6035 }
6036
6037# Check for __attribute__ packed, prefer __packed
6038 if ($realfile !~ m@\binclude/uapi/@ &&
6039 $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
6040 WARN("PREFER_PACKED",
6041 "__packed is preferred over __attribute__((packed))\n" . $herecurr);
6042 }
6043
6044# Check for __attribute__ aligned, prefer __aligned
6045 if ($realfile !~ m@\binclude/uapi/@ &&
6046 $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
6047 WARN("PREFER_ALIGNED",
6048 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
6049 }
6050
Peter Bigot5b10fac2020-03-26 11:16:33 -05006051# Check for __attribute__ section, prefer __section
6052 if ($realfile !~ m@\binclude/uapi/@ &&
6053 $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
6054 my $old = substr($rawline, $-[1], $+[1] - $-[1]);
6055 my $new = substr($old, 1, -1);
6056 if (WARN("PREFER_SECTION",
6057 "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
6058 $fix) {
6059 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
6060 }
6061 }
6062
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006063# Check for __attribute__ format(printf, prefer __printf
6064 if ($realfile !~ m@\binclude/uapi/@ &&
6065 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
6066 if (WARN("PREFER_PRINTF",
6067 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
6068 $fix) {
6069 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
6070
6071 }
6072 }
6073
6074# Check for __attribute__ format(scanf, prefer __scanf
6075 if ($realfile !~ m@\binclude/uapi/@ &&
6076 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
6077 if (WARN("PREFER_SCANF",
6078 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
6079 $fix) {
6080 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
6081 }
6082 }
6083
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006084# Check for __attribute__ weak, or __weak declarations (may have link issues)
Peter Bigot5b10fac2020-03-26 11:16:33 -05006085 if ($perl_version_ok &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006086 $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6087 ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6088 $line =~ /\b__weak\b/)) {
6089 ERROR("WEAK_DECLARATION",
6090 "Using weak declarations can have unintended link defects\n" . $herecurr);
6091 }
6092
Kumar Gala93da8dc2020-06-02 12:38:11 -05006093# check for c99 types like uint8_t used outside of uapi/
6094 if ($realfile !~ m@\binclude/uapi/@ &&
6095 $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006096 my $type = $1;
6097 if ($type =~ /\b($typeC99Typedefs)\b/) {
6098 $type = $1;
6099 my $kernel_type = 'u';
6100 $kernel_type = 's' if ($type =~ /^_*[si]/);
6101 $type =~ /(\d+)/;
Kumar Gala93da8dc2020-06-02 12:38:11 -05006102 $kernel_type .= $1;
6103 if (CHK("PREFER_KERNEL_TYPES",
6104 "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6105 $fix) {
6106 $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6107 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006108 }
6109 }
6110
Anas Nashif76b09132016-02-20 13:53:35 -05006111# check for cast of C90 native int or longer types constants
6112 if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6113 my $cast = $1;
6114 my $const = $2;
6115 if (WARN("TYPECAST_INT_CONSTANT",
6116 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
6117 $fix) {
6118 my $suffix = "";
6119 my $newconst = $const;
6120 $newconst =~ s/${Int_type}$//;
6121 $suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6122 if ($cast =~ /\blong\s+long\b/) {
6123 $suffix .= 'LL';
6124 } elsif ($cast =~ /\blong\b/) {
6125 $suffix .= 'L';
6126 }
6127 $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6128 }
6129 }
6130
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006131# check for sizeof(&)
6132 if ($line =~ /\bsizeof\s*\(\s*\&/) {
6133 WARN("SIZEOF_ADDRESS",
6134 "sizeof(& should be avoided\n" . $herecurr);
6135 }
6136
6137# check for sizeof without parenthesis
6138 if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6139 if (WARN("SIZEOF_PARENTHESIS",
6140 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6141 $fix) {
6142 $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6143 }
6144 }
6145
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006146# check for struct spinlock declarations
6147 if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
6148 WARN("USE_SPINLOCK_T",
6149 "struct spinlock should be spinlock_t\n" . $herecurr);
6150 }
6151
6152# check for seq_printf uses that could be seq_puts
6153 if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6154 my $fmt = get_quoted_string($line, $rawline);
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006155 $fmt =~ s/%%//g;
6156 if ($fmt !~ /%/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006157 if (WARN("PREFER_SEQ_PUTS",
6158 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6159 $fix) {
6160 $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6161 }
6162 }
6163 }
6164
Peter Bigot5b10fac2020-03-26 11:16:33 -05006165# check for vsprintf extension %p<foo> misuses
6166 if ($perl_version_ok &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04006167 defined $stat &&
6168 $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
6169 $1 !~ /^_*volatile_*$/) {
Peter Bigot5b10fac2020-03-26 11:16:33 -05006170 my $stat_real;
6171
Anas Nashif1eb244c2017-10-01 17:06:36 -04006172 my $lc = $stat =~ tr@\n@@;
6173 $lc = $lc + $linenr;
6174 for (my $count = $linenr; $count <= $lc; $count++) {
Peter Bigot5b10fac2020-03-26 11:16:33 -05006175 my $specifier;
6176 my $extension;
6177 my $qualifier;
6178 my $bad_specifier = "";
Anas Nashif1eb244c2017-10-01 17:06:36 -04006179 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
6180 $fmt =~ s/%%//g;
Peter Bigot5b10fac2020-03-26 11:16:33 -05006181
6182 while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6183 $specifier = $1;
6184 $extension = $2;
6185 $qualifier = $3;
6186 if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
6187 ($extension eq "f" &&
6188 defined $qualifier && $qualifier !~ /^w/)) {
6189 $bad_specifier = $specifier;
6190 last;
6191 }
6192 if ($extension eq "x" && !defined($stat_real)) {
6193 if (!defined($stat_real)) {
6194 $stat_real = get_stat_real($linenr, $lc);
6195 }
6196 WARN("VSPRINTF_SPECIFIER_PX",
6197 "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");
6198 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04006199 }
Peter Bigot5b10fac2020-03-26 11:16:33 -05006200 if ($bad_specifier ne "") {
6201 my $stat_real = get_stat_real($linenr, $lc);
6202 my $ext_type = "Invalid";
6203 my $use = "";
6204 if ($bad_specifier =~ /p[Ff]/) {
6205 $use = " - use %pS instead";
6206 $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
6207 }
6208
6209 WARN("VSPRINTF_POINTER_EXTENSION",
6210 "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
Anas Nashif1eb244c2017-10-01 17:06:36 -04006211 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04006212 }
6213 }
6214
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006215# Check for misused memsets
Peter Bigot5b10fac2020-03-26 11:16:33 -05006216 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006217 defined $stat &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006218 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006219
6220 my $ms_addr = $2;
6221 my $ms_val = $7;
6222 my $ms_size = $12;
6223
6224 if ($ms_size =~ /^(0x|)0$/i) {
6225 ERROR("MEMSET",
6226 "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6227 } elsif ($ms_size =~ /^(0x|)1$/i) {
6228 WARN("MEMSET",
6229 "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6230 }
6231 }
6232
6233# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
Peter Bigot5b10fac2020-03-26 11:16:33 -05006234# if ($perl_version_ok &&
Anas Nashif0f3d5472016-11-07 15:57:57 -05006235# defined $stat &&
6236# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6237# if (WARN("PREFER_ETHER_ADDR_COPY",
6238# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6239# $fix) {
6240# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6241# }
6242# }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006243
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006244# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
Peter Bigot5b10fac2020-03-26 11:16:33 -05006245# if ($perl_version_ok &&
Anas Nashif0f3d5472016-11-07 15:57:57 -05006246# defined $stat &&
6247# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6248# WARN("PREFER_ETHER_ADDR_EQUAL",
6249# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6250# }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006251
6252# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
6253# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
Peter Bigot5b10fac2020-03-26 11:16:33 -05006254# if ($perl_version_ok &&
Anas Nashif0f3d5472016-11-07 15:57:57 -05006255# defined $stat &&
6256# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6257#
6258# my $ms_val = $7;
6259#
6260# if ($ms_val =~ /^(?:0x|)0+$/i) {
6261# if (WARN("PREFER_ETH_ZERO_ADDR",
6262# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6263# $fix) {
6264# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6265# }
6266# } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6267# if (WARN("PREFER_ETH_BROADCAST_ADDR",
6268# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6269# $fix) {
6270# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6271# }
6272# }
6273# }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006274
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006275# typecasts on min/max could be min_t/max_t
Peter Bigot5b10fac2020-03-26 11:16:33 -05006276 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006277 defined $stat &&
6278 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6279 if (defined $2 || defined $7) {
6280 my $call = $1;
6281 my $cast1 = deparenthesize($2);
6282 my $arg1 = $3;
6283 my $cast2 = deparenthesize($7);
6284 my $arg2 = $8;
6285 my $cast;
6286
6287 if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6288 $cast = "$cast1 or $cast2";
6289 } elsif ($cast1 ne "") {
6290 $cast = $cast1;
6291 } else {
6292 $cast = $cast2;
6293 }
6294 WARN("MINMAX",
6295 "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6296 }
6297 }
6298
6299# check usleep_range arguments
Peter Bigot5b10fac2020-03-26 11:16:33 -05006300 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006301 defined $stat &&
6302 $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
6303 my $min = $1;
6304 my $max = $7;
6305 if ($min eq $max) {
6306 WARN("USLEEP_RANGE",
Peter Bigot5b10fac2020-03-26 11:16:33 -05006307 "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006308 } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
6309 $min > $max) {
6310 WARN("USLEEP_RANGE",
Peter Bigot5b10fac2020-03-26 11:16:33 -05006311 "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006312 }
6313 }
6314
6315# check for naked sscanf
Peter Bigot5b10fac2020-03-26 11:16:33 -05006316 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006317 defined $stat &&
6318 $line =~ /\bsscanf\b/ &&
6319 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6320 $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6321 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6322 my $lc = $stat =~ tr@\n@@;
6323 $lc = $lc + $linenr;
Peter Bigot5b10fac2020-03-26 11:16:33 -05006324 my $stat_real = get_stat_real($linenr, $lc);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006325 WARN("NAKED_SSCANF",
6326 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6327 }
6328
6329# check for simple sscanf that should be kstrto<foo>
Peter Bigot5b10fac2020-03-26 11:16:33 -05006330 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006331 defined $stat &&
6332 $line =~ /\bsscanf\b/) {
6333 my $lc = $stat =~ tr@\n@@;
6334 $lc = $lc + $linenr;
Peter Bigot5b10fac2020-03-26 11:16:33 -05006335 my $stat_real = get_stat_real($linenr, $lc);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006336 if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6337 my $format = $6;
6338 my $count = $format =~ tr@%@%@;
6339 if ($count == 1 &&
6340 $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6341 WARN("SSCANF_TO_KSTRTO",
6342 "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6343 }
6344 }
6345 }
6346
6347# check for new externs in .h files.
6348 if ($realfile =~ /\.h$/ &&
6349 $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6350 if (CHK("AVOID_EXTERNS",
6351 "extern prototypes should be avoided in .h files\n" . $herecurr) &&
6352 $fix) {
6353 $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
6354 }
6355 }
6356
6357# check for new externs in .c files.
6358 if ($realfile =~ /\.c$/ && defined $stat &&
6359 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6360 {
6361 my $function_name = $1;
6362 my $paren_space = $2;
6363
6364 my $s = $stat;
6365 if (defined $cond) {
6366 substr($s, 0, length($cond), '');
6367 }
Peter A. Bigote49e3c82020-08-10 10:37:32 -05006368 if ($s =~ /^\s*;/)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006369 {
6370 WARN("AVOID_EXTERNS",
6371 "externs should be avoided in .c files\n" . $herecurr);
6372 }
6373
6374 if ($paren_space =~ /\n/) {
6375 WARN("FUNCTION_ARGUMENTS",
6376 "arguments for function declarations should follow identifier\n" . $herecurr);
6377 }
6378
6379 } elsif ($realfile =~ /\.c$/ && defined $stat &&
6380 $stat =~ /^.\s*extern\s+/)
6381 {
6382 WARN("AVOID_EXTERNS",
6383 "externs should be avoided in .c files\n" . $herecurr);
6384 }
6385
Anas Nashif1eb244c2017-10-01 17:06:36 -04006386# check for function declarations that have arguments without identifier names
6387 if (defined $stat &&
Peter Bigot5b10fac2020-03-26 11:16:33 -05006388 $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
Anas Nashif0f3d5472016-11-07 15:57:57 -05006389 $1 ne "void") {
6390 my $args = trim($1);
6391 while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6392 my $arg = trim($1);
6393 if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
6394 WARN("FUNCTION_ARGUMENTS",
6395 "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6396 }
6397 }
6398 }
6399
Anas Nashif1eb244c2017-10-01 17:06:36 -04006400# check for function definitions
Peter Bigot5b10fac2020-03-26 11:16:33 -05006401 if ($perl_version_ok &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04006402 defined $stat &&
6403 $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6404 $context_function = $1;
6405
6406# check for multiline function definition with misplaced open brace
6407 my $ok = 0;
6408 my $cnt = statement_rawlines($stat);
6409 my $herectx = $here . "\n";
6410 for (my $n = 0; $n < $cnt; $n++) {
6411 my $rl = raw_line($linenr, $n);
6412 $herectx .= $rl . "\n";
6413 $ok = 1 if ($rl =~ /^[ \+]\{/);
6414 $ok = 1 if ($rl =~ /\{/ && $n == 0);
6415 last if $rl =~ /^[ \+].*\{/;
6416 }
6417 if (!$ok) {
6418 ERROR("OPEN_BRACE",
6419 "open brace '{' following function definitions go on the next line\n" . $herectx);
6420 }
6421 }
6422
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006423# checks for new __setup's
6424 if ($rawline =~ /\b__setup\("([^"]*)"/) {
6425 my $name = $1;
6426
6427 if (!grep(/$name/, @setup_docs)) {
6428 CHK("UNDOCUMENTED_SETUP",
Peter A. Bigote49e3c82020-08-10 10:37:32 -05006429 "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006430 }
6431 }
6432
Peter Bigot5b10fac2020-03-26 11:16:33 -05006433# check for pointless casting of alloc functions
6434 if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006435 WARN("UNNECESSARY_CASTS",
6436 "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
6437 }
6438
6439# alloc style
6440# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
Peter Bigot5b10fac2020-03-26 11:16:33 -05006441 if ($perl_version_ok &&
6442 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006443 CHK("ALLOC_SIZEOF_STRUCT",
6444 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6445 }
6446
6447# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
Peter Bigot5b10fac2020-03-26 11:16:33 -05006448 if ($perl_version_ok &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04006449 defined $stat &&
6450 $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006451 my $oldfunc = $3;
6452 my $a1 = $4;
6453 my $a2 = $10;
6454 my $newfunc = "kmalloc_array";
6455 $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
6456 my $r1 = $a1;
6457 my $r2 = $a2;
6458 if ($a1 =~ /^sizeof\s*\S/) {
6459 $r1 = $a2;
6460 $r2 = $a1;
6461 }
6462 if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6463 !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
Anas Nashif1eb244c2017-10-01 17:06:36 -04006464 my $cnt = statement_rawlines($stat);
Peter Bigot5b10fac2020-03-26 11:16:33 -05006465 my $herectx = get_stat_here($linenr, $cnt, $here);
6466
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006467 if (WARN("ALLOC_WITH_MULTIPLY",
Anas Nashif1eb244c2017-10-01 17:06:36 -04006468 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
6469 $cnt == 1 &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006470 $fix) {
6471 $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006472 }
6473 }
6474 }
6475
6476# check for krealloc arg reuse
Peter Bigot5b10fac2020-03-26 11:16:33 -05006477 if ($perl_version_ok &&
6478 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
6479 $1 eq $3) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006480 WARN("KREALLOC_ARG_REUSE",
6481 "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6482 }
6483
6484# check for alloc argument mismatch
6485 if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
6486 WARN("ALLOC_ARRAY_ARGS",
6487 "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
6488 }
6489
6490# check for multiple semicolons
6491 if ($line =~ /;\s*;\s*$/) {
6492 if (WARN("ONE_SEMICOLON",
6493 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6494 $fix) {
6495 $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6496 }
6497 }
6498
Anas Nashif0f3d5472016-11-07 15:57:57 -05006499# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6500 if ($realfile !~ m@^include/uapi/@ &&
6501 $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006502 my $ull = "";
6503 $ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
6504 if (CHK("BIT_MACRO",
6505 "Prefer using the BIT$ull macro\n" . $herecurr) &&
6506 $fix) {
6507 $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
6508 }
6509 }
6510
Peter A. Bigote49e3c82020-08-10 10:37:32 -05006511# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
6512 if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^CONFIG_/) {
6513 WARN("IS_ENABLED_CONFIG",
6514 "IS_ENABLED($1) is normally used as IS_ENABLED(CONFIG_$1)\n" . $herecurr);
6515 }
6516
Anas Nashif0f3d5472016-11-07 15:57:57 -05006517# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
6518 if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
6519 my $config = $1;
6520 if (WARN("PREFER_IS_ENABLED",
6521 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
6522 $fix) {
6523 $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
6524 }
6525 }
6526
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006527# check for switch/default statements without a break;
Peter Bigot5b10fac2020-03-26 11:16:33 -05006528 if ($perl_version_ok &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006529 defined $stat &&
6530 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006531 my $cnt = statement_rawlines($stat);
Peter Bigot5b10fac2020-03-26 11:16:33 -05006532 my $herectx = get_stat_here($linenr, $cnt, $here);
6533
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006534 WARN("DEFAULT_NO_BREAK",
6535 "switch default: should use break\n" . $herectx);
6536 }
6537
6538# check for gcc specific __FUNCTION__
6539 if ($line =~ /\b__FUNCTION__\b/) {
6540 if (WARN("USE_FUNC",
6541 "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
6542 $fix) {
6543 $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6544 }
6545 }
6546
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006547# check for uses of __DATE__, __TIME__, __TIMESTAMP__
6548 while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
6549 ERROR("DATE_TIME",
6550 "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
6551 }
6552
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006553# check for use of yield()
6554 if ($line =~ /\byield\s*\(\s*\)/) {
6555 WARN("YIELD",
6556 "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr);
6557 }
6558
6559# check for comparisons against true and false
6560 if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6561 my $lead = $1;
6562 my $arg = $2;
6563 my $test = $3;
6564 my $otype = $4;
6565 my $trail = $5;
6566 my $op = "!";
6567
6568 ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6569
6570 my $type = lc($otype);
6571 if ($type =~ /^(?:true|false)$/) {
6572 if (("$test" eq "==" && "$type" eq "true") ||
6573 ("$test" eq "!=" && "$type" eq "false")) {
6574 $op = "";
6575 }
6576
6577 CHK("BOOL_COMPARISON",
6578 "Using comparison to $otype is error prone\n" . $herecurr);
6579
6580## maybe suggesting a correct construct would better
6581## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6582
6583 }
6584 }
6585
6586# check for semaphores initialized locked
6587 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6588 WARN("CONSIDER_COMPLETION",
6589 "consider using a completion\n" . $herecurr);
6590 }
6591
6592# recommend kstrto* over simple_strto* and strict_strto*
6593 if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6594 WARN("CONSIDER_KSTRTO",
6595 "$1 is obsolete, use k$3 instead\n" . $herecurr);
6596 }
6597
6598# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6599 if ($line =~ /^.\s*__initcall\s*\(/) {
6600 WARN("USE_DEVICE_INITCALL",
6601 "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6602 }
6603
Peter Bigot5b10fac2020-03-26 11:16:33 -05006604# check for spin_is_locked(), suggest lockdep instead
6605 if ($line =~ /\bspin_is_locked\(/) {
6606 WARN("USE_LOCKDEP",
6607 "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
6608 }
6609
6610# check for deprecated apis
6611 if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
6612 my $deprecated_api = $1;
6613 my $new_api = $deprecated_apis{$deprecated_api};
6614 WARN("DEPRECATED_API",
6615 "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
6616 }
6617
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006618# check for various structs that are normally const (ops, kgdb, device_tree)
Anas Nashif1eb244c2017-10-01 17:06:36 -04006619# and avoid what seem like struct definitions 'struct foo {'
Peter A. Bigote49e3c82020-08-10 10:37:32 -05006620 if (defined($const_structs) &&
6621 $line !~ /\bconst\b/ &&
Anas Nashif1eb244c2017-10-01 17:06:36 -04006622 $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006623 WARN("CONST_STRUCT",
Anas Nashif1eb244c2017-10-01 17:06:36 -04006624 "struct $1 should normally be const\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006625 }
6626
6627# use of NR_CPUS is usually wrong
6628# ignore definitions of NR_CPUS and usage to define arrays as likely right
6629 if ($line =~ /\bNR_CPUS\b/ &&
6630 $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6631 $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6632 $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6633 $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6634 $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6635 {
6636 WARN("NR_CPUS",
6637 "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6638 }
6639
6640# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
6641 if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
6642 ERROR("DEFINE_ARCH_HAS",
6643 "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
6644 }
6645
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006646# likely/unlikely comparisons similar to "(likely(foo) > 0)"
Peter Bigot5b10fac2020-03-26 11:16:33 -05006647 if ($perl_version_ok &&
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006648 $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6649 WARN("LIKELY_MISUSE",
6650 "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006651 }
6652
Peter Bigot5b10fac2020-03-26 11:16:33 -05006653# nested likely/unlikely calls
6654 if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
6655 WARN("LIKELY_MISUSE",
6656 "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
6657 }
6658
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006659# whine mightly about in_atomic
6660 if ($line =~ /\bin_atomic\s*\(/) {
6661 if ($realfile =~ m@^drivers/@) {
6662 ERROR("IN_ATOMIC",
6663 "do not use in_atomic in drivers\n" . $herecurr);
6664 } elsif ($realfile !~ m@^kernel/@) {
6665 WARN("IN_ATOMIC",
6666 "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6667 }
6668 }
6669
Anas Nashif1eb244c2017-10-01 17:06:36 -04006670# check for mutex_trylock_recursive usage
6671 if ($line =~ /mutex_trylock_recursive/) {
6672 ERROR("LOCKING",
6673 "recursive locking is bad, do not use this ever.\n" . $herecurr);
6674 }
6675
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006676# check for lockdep_set_novalidate_class
6677 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
6678 $line =~ /__lockdep_no_validate__\s*\)/ ) {
6679 if ($realfile !~ m@^kernel/lockdep@ &&
6680 $realfile !~ m@^include/linux/lockdep@ &&
6681 $realfile !~ m@^drivers/base/core@) {
6682 ERROR("LOCKDEP",
6683 "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
6684 }
6685 }
6686
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006687 if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6688 $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006689 WARN("EXPORTED_WORLD_WRITABLE",
6690 "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
6691 }
6692
Peter Bigot5b10fac2020-03-26 11:16:33 -05006693# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
6694# and whether or not function naming is typical and if
6695# DEVICE_ATTR permissions uses are unusual too
6696 if ($perl_version_ok &&
6697 defined $stat &&
6698 $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*\)/) {
6699 my $var = $1;
6700 my $perms = $2;
6701 my $show = $3;
6702 my $store = $4;
6703 my $octal_perms = perms_to_octal($perms);
6704 if ($show =~ /^${var}_show$/ &&
6705 $store =~ /^${var}_store$/ &&
6706 $octal_perms eq "0644") {
6707 if (WARN("DEVICE_ATTR_RW",
6708 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
6709 $fix) {
6710 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
6711 }
6712 } elsif ($show =~ /^${var}_show$/ &&
6713 $store =~ /^NULL$/ &&
6714 $octal_perms eq "0444") {
6715 if (WARN("DEVICE_ATTR_RO",
6716 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
6717 $fix) {
6718 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
6719 }
6720 } elsif ($show =~ /^NULL$/ &&
6721 $store =~ /^${var}_store$/ &&
6722 $octal_perms eq "0200") {
6723 if (WARN("DEVICE_ATTR_WO",
6724 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
6725 $fix) {
6726 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
6727 }
6728 } elsif ($octal_perms eq "0644" ||
6729 $octal_perms eq "0444" ||
6730 $octal_perms eq "0200") {
6731 my $newshow = "$show";
6732 $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
6733 my $newstore = $store;
6734 $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
6735 my $rename = "";
6736 if ($show ne $newshow) {
6737 $rename .= " '$show' to '$newshow'";
6738 }
6739 if ($store ne $newstore) {
6740 $rename .= " '$store' to '$newstore'";
6741 }
6742 WARN("DEVICE_ATTR_FUNCTIONS",
6743 "Consider renaming function(s)$rename\n" . $herecurr);
6744 } else {
6745 WARN("DEVICE_ATTR_PERMS",
6746 "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
6747 }
6748 }
6749
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006750# Mode permission misuses where it seems decimal should be octal
6751# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
Peter Bigot5b10fac2020-03-26 11:16:33 -05006752# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
6753# specific definition of not visible in sysfs.
6754# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
6755# use the default permissions
6756 if ($perl_version_ok &&
Anas Nashif0f3d5472016-11-07 15:57:57 -05006757 defined $stat &&
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006758 $line =~ /$mode_perms_search/) {
6759 foreach my $entry (@mode_permission_funcs) {
6760 my $func = $entry->[0];
6761 my $arg_pos = $entry->[1];
6762
Anas Nashif0f3d5472016-11-07 15:57:57 -05006763 my $lc = $stat =~ tr@\n@@;
6764 $lc = $lc + $linenr;
Peter Bigot5b10fac2020-03-26 11:16:33 -05006765 my $stat_real = get_stat_real($linenr, $lc);
Anas Nashif0f3d5472016-11-07 15:57:57 -05006766
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006767 my $skip_args = "";
6768 if ($arg_pos > 1) {
6769 $arg_pos--;
6770 $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
6771 }
Anas Nashif0f3d5472016-11-07 15:57:57 -05006772 my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6773 if ($stat =~ /$test/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006774 my $val = $1;
6775 $val = $6 if ($skip_args ne "");
Peter Bigot5b10fac2020-03-26 11:16:33 -05006776 if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
6777 (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
6778 ($val =~ /^$Octal$/ && length($val) ne 4))) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006779 ERROR("NON_OCTAL_PERMISSIONS",
Anas Nashif0f3d5472016-11-07 15:57:57 -05006780 "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6781 }
6782 if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006783 ERROR("EXPORTED_WORLD_WRITABLE",
Anas Nashif0f3d5472016-11-07 15:57:57 -05006784 "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006785 }
6786 }
6787 }
6788 }
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006789
Anas Nashif0f3d5472016-11-07 15:57:57 -05006790# check for uses of S_<PERMS> that could be octal for readability
Peter Bigot5b10fac2020-03-26 11:16:33 -05006791 while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
6792 my $oval = $1;
6793 my $octal = perms_to_octal($oval);
Anas Nashif0f3d5472016-11-07 15:57:57 -05006794 if (WARN("SYMBOLIC_PERMS",
6795 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6796 $fix) {
Peter Bigot5b10fac2020-03-26 11:16:33 -05006797 $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
Anas Nashif0f3d5472016-11-07 15:57:57 -05006798 }
6799 }
6800
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006801# validate content of MODULE_LICENSE against list from include/linux/module.h
6802 if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
6803 my $extracted_string = get_quoted_string($line, $rawline);
6804 my $valid_licenses = qr{
6805 GPL|
6806 GPL\ v2|
6807 GPL\ and\ additional\ rights|
6808 Dual\ BSD/GPL|
6809 Dual\ MIT/GPL|
6810 Dual\ MPL/GPL|
6811 Proprietary
6812 }x;
6813 if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
6814 WARN("MODULE_LICENSE",
6815 "unknown module license " . $extracted_string . "\n" . $herecurr);
6816 }
6817 }
Peter Bigot5b10fac2020-03-26 11:16:33 -05006818
6819# check for sysctl duplicate constants
6820 if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
6821 WARN("DUPLICATED_SYSCTL_CONST",
6822 "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
6823 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006824 }
6825
6826 # If we have no input at all, then there is nothing to report on
6827 # so just keep quiet.
6828 if ($#rawlines == -1) {
6829 exit(0);
6830 }
6831
6832 # In mailback mode only produce a report in the negative, for
6833 # things that appear to be patches.
6834 if ($mailback && ($clean == 1 || !$is_patch)) {
6835 exit(0);
6836 }
6837
6838 # This is not a patch, and we are are in 'no-patch' mode so
6839 # just keep quiet.
6840 if (!$chk_patch && !$is_patch) {
6841 exit(0);
6842 }
6843
Peter Bigot5b10fac2020-03-26 11:16:33 -05006844 if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006845 ERROR("NOT_UNIFIED_DIFF",
6846 "Does not appear to be a unified-diff format patch\n");
6847 }
Peter Bigot5b10fac2020-03-26 11:16:33 -05006848 if ($is_patch && $has_commit_log && $chk_signoff) {
6849 if ($signoff == 0) {
6850 ERROR("MISSING_SIGN_OFF",
6851 "Missing Signed-off-by: line(s)\n");
6852 } elsif (!$authorsignoff) {
6853 WARN("NO_AUTHOR_SIGN_OFF",
6854 "Missing Signed-off-by: line by nominal patch author '$author'\n");
6855 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006856 }
6857
6858 print report_dump();
6859 if ($summary && !($clean == 1 && $quiet == 1)) {
6860 print "$filename " if ($summary_file);
6861 print "total: $cnt_error errors, $cnt_warn warnings, " .
6862 (($check)? "$cnt_chk checks, " : "") .
6863 "$cnt_lines lines checked\n";
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006864 }
6865
6866 if ($quiet == 0) {
Anas Nashif0f3d5472016-11-07 15:57:57 -05006867 # If there were any defects found and not already fixing them
6868 if (!$clean and !$fix) {
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006869 print << "EOM"
6870
Anas Nashif0f3d5472016-11-07 15:57:57 -05006871NOTE: For some of the reported defects, checkpatch may be able to
6872 mechanically convert to the typical style using --fix or --fix-inplace.
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006873EOM
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006874 }
Anas Nashif1eb244c2017-10-01 17:06:36 -04006875 # If there were whitespace errors which cleanpatch can fix
6876 # then suggest that.
6877 if ($rpt_cleaners) {
6878 $rpt_cleaners = 0;
6879 print << "EOM"
6880
6881NOTE: Whitespace errors detected.
6882 You may wish to use scripts/cleanpatch or scripts/cleanfile
6883EOM
6884 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006885 }
6886
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006887 if ($clean == 0 && $fix &&
6888 ("@rawlines" ne "@fixed" ||
6889 $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
6890 my $newfile = $filename;
6891 $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
6892 my $linecount = 0;
6893 my $f;
6894
6895 @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6896
6897 open($f, '>', $newfile)
6898 or die "$P: Can't open $newfile for write\n";
6899 foreach my $fixed_line (@fixed) {
6900 $linecount++;
6901 if ($file) {
6902 if ($linecount > 3) {
6903 $fixed_line =~ s/^\+//;
6904 print $f $fixed_line . "\n";
6905 }
6906 } else {
6907 print $f $fixed_line . "\n";
6908 }
6909 }
6910 close($f);
6911
6912 if (!$quiet) {
6913 print << "EOM";
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006914
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006915Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
6916
6917Do _NOT_ trust the results written to this file.
6918Do _NOT_ submit these changes without inspecting them for correctness.
6919
6920This EXPERIMENTAL file is simply a convenience to help rewrite patches.
6921No warranties, expressed or implied...
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006922EOM
6923 }
6924 }
6925
Anas Nashifcbfb62c2015-10-14 06:08:54 -04006926 if ($quiet == 0) {
6927 print "\n";
6928 if ($clean == 1) {
6929 print "$vname has no obvious style problems and is ready for submission.\n";
6930 } else {
6931 print "$vname has style problems, please review.\n";
6932 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006933 }
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07006934 return $clean;
6935}