blob: 4bed2b0cdc7c2a59c7b620e89cd602933e8685b1 [file] [log] [blame]
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001#!/usr/bin/env perl
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002# SPDX-License-Identifier: GPL-2.0
3#
Joe Hershberger05622192011-10-18 10:06:59 +00004# (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>
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02008# (c) 2010-2018 Joe Perches <joe@perches.com>
Joe Hershberger05622192011-10-18 10:06:59 +00009
10use strict;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020011use warnings;
Tom Rini6b9709d2014-02-27 08:27:28 -050012use POSIX;
Dan Murphyc10e0f52017-01-31 14:15:53 -060013use File::Basename;
14use Cwd 'abs_path';
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020015use Term::ANSIColor qw(:constants);
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +020016use Encode qw(decode encode);
Joe Hershberger05622192011-10-18 10:06:59 +000017
18my $P = $0;
Dan Murphyc10e0f52017-01-31 14:15:53 -060019my $D = dirname(abs_path($P));
Joe Hershberger05622192011-10-18 10:06:59 +000020
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;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020032my $showfile = 0;
Joe Hershberger05622192011-10-18 10:06:59 +000033my $file = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020034my $git = 0;
35my %git_commits = ();
Joe Hershberger05622192011-10-18 10:06:59 +000036my $check = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020037my $check_orig = 0;
Joe Hershberger05622192011-10-18 10:06:59 +000038my $summary = 1;
39my $mailback = 0;
40my $summary_file = 0;
41my $show_types = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020042my $list_types = 0;
Tom Rini6b9709d2014-02-27 08:27:28 -050043my $fix = 0;
44my $fix_inplace = 0;
Joe Hershberger05622192011-10-18 10:06:59 +000045my $root;
46my %debug;
Tom Rini6b9709d2014-02-27 08:27:28 -050047my %camelcase = ();
48my %use_type = ();
49my @use = ();
Joe Hershberger05622192011-10-18 10:06:59 +000050my %ignore_type = ();
51my @ignore = ();
52my $help = 0;
53my $configuration_file = ".checkpatch.conf";
Simon Glass048a6482020-05-22 16:32:35 -060054my $max_line_length = 100;
Tom Rini6b9709d2014-02-27 08:27:28 -050055my $ignore_perl_version = 0;
56my $minimum_perl_version = 5.10.0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020057my $min_conf_desc_length = 4;
Dan Murphyc10e0f52017-01-31 14:15:53 -060058my $spelling_file = "$D/spelling.txt";
59my $codespell = 0;
60my $codespellfile = "/usr/share/codespell/dictionary.txt";
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020061my $conststructsfile = "$D/const_structs.checkpatch";
62my $typedefsfile = "";
Simon Glassb77df592020-05-22 16:32:36 -060063my $u_boot = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020064my $color = "auto";
Tom Rinic57383b2020-06-16 10:29:46 -040065my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
66# git output parsing needs US English output, so first set backtick child process LANGUAGE
67my $git_command ='export LANGUAGE=en_US.UTF-8; git';
68my $tabsize = 8;
Joe Hershberger05622192011-10-18 10:06:59 +000069
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
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020084 --showfile emit diffed file position, not input file position
85 -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
Joe Hershberger05622192011-10-18 10:06:59 +000095 -f, --file treat FILE as regular source file
96 --subjective, --strict enable more subjective tests
Heinrich Schuchardt6305db92017-09-12 09:57:45 +020097 --list-types list the possible message types
Tom Rini6b9709d2014-02-27 08:27:28 -050098 --types TYPE(,TYPE2...) show only these comma separated message types
Joe Hershberger05622192011-10-18 10:06:59 +000099 --ignore TYPE(,TYPE2...) ignore various comma separated message types
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200100 --show-types show the specific message type in the output
Simon Glass048a6482020-05-22 16:32:35 -0600101 --max-line-length=n set the maximum line length, (default $max_line_length)
102 if exceeded, warn on patches
103 requires --strict for use with --file
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200104 --min-conf-desc-length=n set the min description length, if shorter, warn
Tom Rinic57383b2020-06-16 10:29:46 -0400105 --tab-size=n set the number of spaces for tab (default $tabsize)
Joe Hershberger05622192011-10-18 10:06:59 +0000106 --root=PATH PATH to the kernel tree root
107 --no-summary suppress the per-file summary
108 --mailback only produce a report in case of warnings/errors
109 --summary-file include the filename in summary
110 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
111 'values', 'possible', 'type', and 'attr' (default
112 is all off)
113 --test-only=WORD report only warnings/errors containing WORD
114 literally
Tom Rini6b9709d2014-02-27 08:27:28 -0500115 --fix EXPERIMENTAL - may create horrible results
116 If correctable single-line errors exist, create
117 "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
118 with potential errors corrected to the preferred
119 checkpatch style
120 --fix-inplace EXPERIMENTAL - may create horrible results
121 Is the same as --fix, but overwrites the input
122 file. It's your fault if there's no backup or git
123 --ignore-perl-version override checking of perl version. expect
124 runtime errors.
Dan Murphyc10e0f52017-01-31 14:15:53 -0600125 --codespell Use the codespell dictionary for spelling/typos
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200126 (default:/usr/share/codespell/dictionary.txt)
Dan Murphyc10e0f52017-01-31 14:15:53 -0600127 --codespellfile Use this codespell dictionary
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200128 --typedefsfile Read additional types from this file
129 --color[=WHEN] Use colors 'always', 'never', or only when output
130 is a terminal ('auto'). Default is 'auto'.
Simon Glassb77df592020-05-22 16:32:36 -0600131 --u-boot Run additional checks for U-Boot
Joe Hershberger05622192011-10-18 10:06:59 +0000132 -h, --help, --version display this help and exit
133
134When FILE is - read standard input.
135EOM
136
137 exit($exitcode);
138}
139
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200140sub 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 = ();
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +0200159 # 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) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200161 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
Joe Hershberger05622192011-10-18 10:06:59 +0000172my $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
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200198# 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
Joe Hershberger05622192011-10-18 10:06:59 +0000206GetOptions(
207 'q|quiet+' => \$quiet,
208 'tree!' => \$tree,
209 'signoff!' => \$chk_signoff,
210 'patch!' => \$chk_patch,
211 'emacs!' => \$emacs,
212 'terse!' => \$terse,
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200213 'showfile!' => \$showfile,
Joe Hershberger05622192011-10-18 10:06:59 +0000214 'f|file!' => \$file,
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200215 'g|git!' => \$git,
Joe Hershberger05622192011-10-18 10:06:59 +0000216 'subjective!' => \$check,
217 'strict!' => \$check,
218 'ignore=s' => \@ignore,
Tom Rini6b9709d2014-02-27 08:27:28 -0500219 'types=s' => \@use,
Joe Hershberger05622192011-10-18 10:06:59 +0000220 'show-types!' => \$show_types,
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200221 'list-types!' => \$list_types,
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000222 'max-line-length=i' => \$max_line_length,
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200223 'min-conf-desc-length=i' => \$min_conf_desc_length,
Tom Rinic57383b2020-06-16 10:29:46 -0400224 'tab-size=i' => \$tabsize,
Joe Hershberger05622192011-10-18 10:06:59 +0000225 'root=s' => \$root,
226 'summary!' => \$summary,
227 'mailback!' => \$mailback,
228 'summary-file!' => \$summary_file,
Tom Rini6b9709d2014-02-27 08:27:28 -0500229 'fix!' => \$fix,
230 'fix-inplace!' => \$fix_inplace,
231 'ignore-perl-version!' => \$ignore_perl_version,
Joe Hershberger05622192011-10-18 10:06:59 +0000232 'debug=s' => \%debug,
233 'test-only=s' => \$tst_only,
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200234 'codespell!' => \$codespell,
235 'codespellfile=s' => \$codespellfile,
236 'typedefsfile=s' => \$typedefsfile,
Simon Glassb77df592020-05-22 16:32:36 -0600237 'u-boot' => \$u_boot,
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200238 'color=s' => \$color,
239 'no-color' => \$color, #keep old behaviors of -nocolor
240 'nocolor' => \$color, #keep old behaviors of -nocolor
Joe Hershberger05622192011-10-18 10:06:59 +0000241 'h|help' => \$help,
242 'version' => \$help
243) or help(1);
244
245help(0) if ($help);
246
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200247list_types(0) if ($list_types);
248
Tom Rini6b9709d2014-02-27 08:27:28 -0500249$fix = 1 if ($fix_inplace);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200250$check_orig = $check;
Tom Rini6b9709d2014-02-27 08:27:28 -0500251
Joe Hershberger05622192011-10-18 10:06:59 +0000252my $exit = 0;
253
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +0200254my $perl_version_ok = 1;
Tom Rini6b9709d2014-02-27 08:27:28 -0500255if ($^V && $^V lt $minimum_perl_version) {
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +0200256 $perl_version_ok = 0;
Tom Rini6b9709d2014-02-27 08:27:28 -0500257 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +0200258 exit(1) if (!$ignore_perl_version);
Tom Rini6b9709d2014-02-27 08:27:28 -0500259}
260
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200261#if no filenames are given, push '-' to read patch from stdin
Joe Hershberger05622192011-10-18 10:06:59 +0000262if ($#ARGV < 0) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200263 push(@ARGV, '-');
264}
265
266if ($color =~ /^[01]$/) {
267 $color = !$color;
268} elsif ($color =~ /^always$/i) {
269 $color = 1;
270} elsif ($color =~ /^never$/i) {
271 $color = 0;
272} elsif ($color =~ /^auto$/i) {
273 $color = (-t STDOUT);
274} else {
275 die "Invalid color mode: $color\n";
Joe Hershberger05622192011-10-18 10:06:59 +0000276}
277
Tom Rinic57383b2020-06-16 10:29:46 -0400278# skip TAB size 1 to avoid additional checks on $tabsize - 1
279die "Invalid TAB size: $tabsize\n" if ($tabsize < 2);
280
Tom Rini6b9709d2014-02-27 08:27:28 -0500281sub hash_save_array_words {
282 my ($hashRef, $arrayRef) = @_;
Joe Hershberger05622192011-10-18 10:06:59 +0000283
Tom Rini6b9709d2014-02-27 08:27:28 -0500284 my @array = split(/,/, join(',', @$arrayRef));
285 foreach my $word (@array) {
286 $word =~ s/\s*\n?$//g;
287 $word =~ s/^\s*//g;
288 $word =~ s/\s+/ /g;
289 $word =~ tr/[a-z]/[A-Z]/;
Joe Hershberger05622192011-10-18 10:06:59 +0000290
Tom Rini6b9709d2014-02-27 08:27:28 -0500291 next if ($word =~ m/^\s*#/);
292 next if ($word =~ m/^\s*$/);
293
294 $hashRef->{$word}++;
295 }
Joe Hershberger05622192011-10-18 10:06:59 +0000296}
297
Tom Rini6b9709d2014-02-27 08:27:28 -0500298sub hash_show_words {
299 my ($hashRef, $prefix) = @_;
300
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200301 if (keys %$hashRef) {
302 print "\nNOTE: $prefix message types:";
Tom Rini6b9709d2014-02-27 08:27:28 -0500303 foreach my $word (sort keys %$hashRef) {
304 print " $word";
305 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200306 print "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -0500307 }
308}
309
310hash_save_array_words(\%ignore_type, \@ignore);
311hash_save_array_words(\%use_type, \@use);
312
Joe Hershberger05622192011-10-18 10:06:59 +0000313my $dbg_values = 0;
314my $dbg_possible = 0;
315my $dbg_type = 0;
316my $dbg_attr = 0;
317for my $key (keys %debug) {
318 ## no critic
319 eval "\${dbg_$key} = '$debug{$key}';";
320 die "$@" if ($@);
321}
322
323my $rpt_cleaners = 0;
324
325if ($terse) {
326 $emacs = 1;
327 $quiet++;
328}
329
330if ($tree) {
331 if (defined $root) {
332 if (!top_of_kernel_tree($root)) {
333 die "$P: $root: --root does not point at a valid tree\n";
334 }
335 } else {
336 if (top_of_kernel_tree('.')) {
337 $root = '.';
338 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
339 top_of_kernel_tree($1)) {
340 $root = $1;
341 }
342 }
343
344 if (!defined $root) {
345 print "Must be run from the top-level dir. of a kernel tree\n";
346 exit(2);
347 }
348}
349
350my $emitted_corrupt = 0;
351
352our $Ident = qr{
353 [A-Za-z_][A-Za-z\d_]*
354 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
355 }x;
356our $Storage = qr{extern|static|asmlinkage};
357our $Sparse = qr{
358 __user|
359 __kernel|
360 __force|
361 __iomem|
362 __must_check|
Joe Hershberger05622192011-10-18 10:06:59 +0000363 __kprobes|
364 __ref|
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +0200365 __refconst|
366 __refdata|
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200367 __rcu|
368 __private
Joe Hershberger05622192011-10-18 10:06:59 +0000369 }x;
Tom Rini6b9709d2014-02-27 08:27:28 -0500370our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
371our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
372our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
373our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
374our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
Joe Hershberger05622192011-10-18 10:06:59 +0000375
376# Notes to $Attribute:
377# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
378our $Attribute = qr{
379 const|
380 __percpu|
381 __nocast|
382 __safe|
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200383 __bitwise|
Joe Hershberger05622192011-10-18 10:06:59 +0000384 __packed__|
385 __packed2__|
386 __naked|
387 __maybe_unused|
388 __always_unused|
389 __noreturn|
390 __used|
391 __cold|
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200392 __pure|
Joe Hershberger05622192011-10-18 10:06:59 +0000393 __noclone|
394 __deprecated|
395 __read_mostly|
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +0200396 __ro_after_init|
Joe Hershberger05622192011-10-18 10:06:59 +0000397 __kprobes|
Tom Rini6b9709d2014-02-27 08:27:28 -0500398 $InitAttribute|
Joe Hershberger05622192011-10-18 10:06:59 +0000399 ____cacheline_aligned|
400 ____cacheline_aligned_in_smp|
401 ____cacheline_internodealigned_in_smp|
402 __weak
403 }x;
404our $Modifier;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200405our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
Joe Hershberger05622192011-10-18 10:06:59 +0000406our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
407our $Lval = qr{$Ident(?:$Member)*};
408
Tom Rini6b9709d2014-02-27 08:27:28 -0500409our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
410our $Binary = qr{(?i)0b[01]+$Int_type?};
411our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
412our $Int = qr{[0-9]+$Int_type?};
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200413our $Octal = qr{0[0-7]+$Int_type?};
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +0200414our $String = qr{"[X\t]*"};
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000415our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
416our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
417our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
418our $Float = qr{$Float_hex|$Float_dec|$Float_int};
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200419our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000420our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200421our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
Tom Rini6b9709d2014-02-27 08:27:28 -0500422our $Arithmetic = qr{\+|-|\*|\/|%};
Joe Hershberger05622192011-10-18 10:06:59 +0000423our $Operators = qr{
424 <=|>=|==|!=|
425 =>|->|<<|>>|<|>|!|~|
Tom Rini6b9709d2014-02-27 08:27:28 -0500426 &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
Joe Hershberger05622192011-10-18 10:06:59 +0000427 }x;
428
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200429our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
430
431our $BasicType;
Joe Hershberger05622192011-10-18 10:06:59 +0000432our $NonptrType;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200433our $NonptrTypeMisordered;
Tom Rini6b9709d2014-02-27 08:27:28 -0500434our $NonptrTypeWithAttr;
Joe Hershberger05622192011-10-18 10:06:59 +0000435our $Type;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200436our $TypeMisordered;
Joe Hershberger05622192011-10-18 10:06:59 +0000437our $Declare;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200438our $DeclareMisordered;
Joe Hershberger05622192011-10-18 10:06:59 +0000439
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000440our $NON_ASCII_UTF8 = qr{
441 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
Joe Hershberger05622192011-10-18 10:06:59 +0000442 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
443 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
444 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
445 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
446 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
447 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
448}x;
449
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000450our $UTF8 = qr{
451 [\x09\x0A\x0D\x20-\x7E] # ASCII
452 | $NON_ASCII_UTF8
453}x;
454
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200455our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
456our $typeOtherOSTypedefs = qr{(?x:
457 u_(?:char|short|int|long) | # bsd
458 u(?:nchar|short|int|long) # sysv
459)};
460our $typeKernelTypedefs = qr{(?x:
Joe Hershberger05622192011-10-18 10:06:59 +0000461 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
462 atomic_t
463)};
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200464our $typeTypedefs = qr{(?x:
465 $typeC99Typedefs\b|
466 $typeOtherOSTypedefs\b|
467 $typeKernelTypedefs\b
468)};
469
470our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
Joe Hershberger05622192011-10-18 10:06:59 +0000471
472our $logFunctions = qr{(?x:
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200473 printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
Tom Rini6b9709d2014-02-27 08:27:28 -0500474 (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +0200475 TP_printk|
Joe Hershberger05622192011-10-18 10:06:59 +0000476 WARN(?:_RATELIMIT|_ONCE|)|
477 panic|
James Byrne66b3ccc2019-11-21 14:32:46 +0000478 debug|
479 printf|
Tom Rini6b9709d2014-02-27 08:27:28 -0500480 MODULE_[A-Z_]+|
481 seq_vprintf|seq_printf|seq_puts
Joe Hershberger05622192011-10-18 10:06:59 +0000482)};
483
Tom Rinic57383b2020-06-16 10:29:46 -0400484our $allocFunctions = qr{(?x:
485 (?:(?:devm_)?
486 (?:kv|k|v)[czm]alloc(?:_node|_array)? |
487 kstrdup(?:_const)? |
488 kmemdup(?:_nul)?) |
489 (?:\w+)?alloc_skb(?:_ip_align)? |
490 # dev_alloc_skb/netdev_alloc_skb, et al
491 dma_alloc_coherent
492)};
493
Joe Hershberger05622192011-10-18 10:06:59 +0000494our $signature_tags = qr{(?xi:
495 Signed-off-by:|
Tom Rinic57383b2020-06-16 10:29:46 -0400496 Co-developed-by:|
Joe Hershberger05622192011-10-18 10:06:59 +0000497 Acked-by:|
498 Tested-by:|
499 Reviewed-by:|
500 Reported-by:|
Tom Rini6b9709d2014-02-27 08:27:28 -0500501 Suggested-by:|
Joe Hershberger05622192011-10-18 10:06:59 +0000502 To:|
503 Cc:
504)};
505
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200506our @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
Joe Hershberger05622192011-10-18 10:06:59 +0000525our @typeList = (
526 qr{void},
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200527 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},
Joe Hershberger05622192011-10-18 10:06:59 +0000536 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},
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200545 @typeListMisordered,
Joe Hershberger05622192011-10-18 10:06:59 +0000546);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200547
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
569our @typeListFile = ();
Tom Rini6b9709d2014-02-27 08:27:28 -0500570our @typeListWithAttr = (
571 @typeList,
572 qr{struct\s+$InitAttribute\s+$Ident},
573 qr{union\s+$InitAttribute\s+$Ident},
574);
575
Joe Hershberger05622192011-10-18 10:06:59 +0000576our @modifierList = (
577 qr{fastcall},
578);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200579our @modifierListFile = ();
580
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],
587 ["(?: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],
592);
593
594#Create a search pattern for all these functions to speed up a loop below
595our $mode_perms_search = "";
596foreach my $entry (@mode_permission_funcs) {
597 $mode_perms_search .= '|' if ($mode_perms_search ne "");
598 $mode_perms_search .= $entry->[0];
599}
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +0200600$mode_perms_search = "(?:${mode_perms_search})";
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200601
Tom Rinic57383b2020-06-16 10:29:46 -0400602our %deprecated_apis = (
603 "synchronize_rcu_bh" => "synchronize_rcu",
604 "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited",
605 "call_rcu_bh" => "call_rcu",
606 "rcu_barrier_bh" => "rcu_barrier",
607 "synchronize_sched" => "synchronize_rcu",
608 "synchronize_sched_expedited" => "synchronize_rcu_expedited",
609 "call_rcu_sched" => "call_rcu",
610 "rcu_barrier_sched" => "rcu_barrier",
611 "get_state_synchronize_sched" => "get_state_synchronize_rcu",
612 "cond_synchronize_sched" => "cond_synchronize_rcu",
613);
614
615#Create a search pattern for all these strings to speed up a loop below
616our $deprecated_apis_search = "";
617foreach my $entry (keys %deprecated_apis) {
618 $deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
619 $deprecated_apis_search .= $entry;
620}
621$deprecated_apis_search = "(?:${deprecated_apis_search})";
622
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200623our $mode_perms_world_writable = qr{
624 S_IWUGO |
625 S_IWOTH |
626 S_IRWXUGO |
627 S_IALLUGO |
628 0[0-7][0-7][2367]
629}x;
630
631our %mode_permission_string_types = (
632 "S_IRWXU" => 0700,
633 "S_IRUSR" => 0400,
634 "S_IWUSR" => 0200,
635 "S_IXUSR" => 0100,
636 "S_IRWXG" => 0070,
637 "S_IRGRP" => 0040,
638 "S_IWGRP" => 0020,
639 "S_IXGRP" => 0010,
640 "S_IRWXO" => 0007,
641 "S_IROTH" => 0004,
642 "S_IWOTH" => 0002,
643 "S_IXOTH" => 0001,
644 "S_IRWXUGO" => 0777,
645 "S_IRUGO" => 0444,
646 "S_IWUGO" => 0222,
647 "S_IXUGO" => 0111,
648);
649
650#Create a search pattern for all these strings to speed up a loop below
651our $mode_perms_string_search = "";
652foreach my $entry (keys %mode_permission_string_types) {
653 $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
654 $mode_perms_string_search .= $entry;
655}
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +0200656our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
657our $multi_mode_perms_string_search = qr{
658 ${single_mode_perms_string_search}
659 (?:\s*\|\s*${single_mode_perms_string_search})*
660}x;
661
662sub perms_to_octal {
663 my ($string) = @_;
664
665 return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
666
667 my $val = "";
668 my $oval = "";
669 my $to = 0;
670 my $curpos = 0;
671 my $lastpos = 0;
672 while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
673 $curpos = pos($string);
674 my $match = $2;
675 my $omatch = $1;
676 last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
677 $lastpos = $curpos;
678 $to |= $mode_permission_string_types{$match};
679 $val .= '\s*\|\s*' if ($val ne "");
680 $val .= $match;
681 $oval .= $omatch;
682 }
683 $oval =~ s/^\s*\|\s*//;
684 $oval =~ s/\s*\|\s*$//;
685 return sprintf("%04o", $to);
686}
Joe Hershberger05622192011-10-18 10:06:59 +0000687
688our $allowed_asm_includes = qr{(?x:
689 irq|
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200690 memory|
691 time|
692 reboot
Joe Hershberger05622192011-10-18 10:06:59 +0000693)};
694# memory.h: ARM has a custom one
695
Dan Murphyc10e0f52017-01-31 14:15:53 -0600696# Load common spelling mistakes and build regular expression list.
697my $misspellings;
698my %spelling_fix;
699
700if (open(my $spelling, '<', $spelling_file)) {
701 while (<$spelling>) {
702 my $line = $_;
703
704 $line =~ s/\s*\n?$//g;
705 $line =~ s/^\s*//g;
706
707 next if ($line =~ m/^\s*#/);
708 next if ($line =~ m/^\s*$/);
709
710 my ($suspect, $fix) = split(/\|\|/, $line);
711
712 $spelling_fix{$suspect} = $fix;
713 }
714 close($spelling);
715} else {
716 warn "No typos will be found - file '$spelling_file': $!\n";
717}
718
719if ($codespell) {
720 if (open(my $spelling, '<', $codespellfile)) {
721 while (<$spelling>) {
722 my $line = $_;
723
724 $line =~ s/\s*\n?$//g;
725 $line =~ s/^\s*//g;
726
727 next if ($line =~ m/^\s*#/);
728 next if ($line =~ m/^\s*$/);
729 next if ($line =~ m/, disabled/i);
730
731 $line =~ s/,.*$//;
732
733 my ($suspect, $fix) = split(/->/, $line);
734
735 $spelling_fix{$suspect} = $fix;
736 }
737 close($spelling);
738 } else {
739 warn "No codespell typos will be found - file '$codespellfile': $!\n";
740 }
741}
742
743$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
744
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200745sub read_words {
746 my ($wordsRef, $file) = @_;
747
748 if (open(my $words, '<', $file)) {
749 while (<$words>) {
750 my $line = $_;
751
752 $line =~ s/\s*\n?$//g;
753 $line =~ s/^\s*//g;
754
755 next if ($line =~ m/^\s*#/);
756 next if ($line =~ m/^\s*$/);
757 if ($line =~ /\s/) {
758 print("$file: '$line' invalid - ignored\n");
759 next;
760 }
761
762 $$wordsRef .= '|' if ($$wordsRef ne "");
763 $$wordsRef .= $line;
764 }
765 close($file);
766 return 1;
767 }
768
769 return 0;
770}
771
772my $const_structs = "";
773read_words(\$const_structs, $conststructsfile)
774 or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
775
776my $typeOtherTypedefs = "";
777if (length($typedefsfile)) {
778 read_words(\$typeOtherTypedefs, $typedefsfile)
779 or warn "No additional types will be considered - file '$typedefsfile': $!\n";
780}
781$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
Dan Murphyc10e0f52017-01-31 14:15:53 -0600782
Joe Hershberger05622192011-10-18 10:06:59 +0000783sub build_types {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200784 my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
785 my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
786 my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
Tom Rini6b9709d2014-02-27 08:27:28 -0500787 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
Joe Hershberger05622192011-10-18 10:06:59 +0000788 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200789 $BasicType = qr{
790 (?:$typeTypedefs\b)|
791 (?:${all}\b)
792 }x;
Joe Hershberger05622192011-10-18 10:06:59 +0000793 $NonptrType = qr{
794 (?:$Modifier\s+|const\s+)*
795 (?:
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000796 (?:typeof|__typeof__)\s*\([^\)]*\)|
Joe Hershberger05622192011-10-18 10:06:59 +0000797 (?:$typeTypedefs\b)|
798 (?:${all}\b)
799 )
800 (?:\s+$Modifier|\s+const)*
801 }x;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200802 $NonptrTypeMisordered = qr{
803 (?:$Modifier\s+|const\s+)*
804 (?:
805 (?:${Misordered}\b)
806 )
807 (?:\s+$Modifier|\s+const)*
808 }x;
Tom Rini6b9709d2014-02-27 08:27:28 -0500809 $NonptrTypeWithAttr = qr{
810 (?:$Modifier\s+|const\s+)*
811 (?:
812 (?:typeof|__typeof__)\s*\([^\)]*\)|
813 (?:$typeTypedefs\b)|
814 (?:${allWithAttr}\b)
815 )
816 (?:\s+$Modifier|\s+const)*
817 }x;
Joe Hershberger05622192011-10-18 10:06:59 +0000818 $Type = qr{
819 $NonptrType
Tom Rinic57383b2020-06-16 10:29:46 -0400820 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
Joe Hershberger05622192011-10-18 10:06:59 +0000821 (?:\s+$Inline|\s+$Modifier)*
822 }x;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200823 $TypeMisordered = qr{
824 $NonptrTypeMisordered
Tom Rinic57383b2020-06-16 10:29:46 -0400825 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200826 (?:\s+$Inline|\s+$Modifier)*
827 }x;
828 $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
829 $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
Joe Hershberger05622192011-10-18 10:06:59 +0000830}
831build_types();
832
Joe Hershberger05622192011-10-18 10:06:59 +0000833our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000834
835# Using $balanced_parens, $LvalOrFunc, or $FuncArg
836# requires at least perl version v5.10.0
837# Any use must be runtime checked with $^V
838
839our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200840our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
841our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
842
843our $declaration_macros = qr{(?x:
844 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
845 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +0200846 (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
847 (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200848)};
Joe Hershberger05622192011-10-18 10:06:59 +0000849
850sub deparenthesize {
851 my ($string) = @_;
852 return "" if (!defined($string));
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200853
854 while ($string =~ /^\s*\(.*\)\s*$/) {
855 $string =~ s@^\s*\(\s*@@;
856 $string =~ s@\s*\)\s*$@@;
857 }
858
Joe Hershberger05622192011-10-18 10:06:59 +0000859 $string =~ s@\s+@ @g;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200860
Joe Hershberger05622192011-10-18 10:06:59 +0000861 return $string;
862}
863
Tom Rini6b9709d2014-02-27 08:27:28 -0500864sub seed_camelcase_file {
865 my ($file) = @_;
866
867 return if (!(-f $file));
868
869 local $/;
870
871 open(my $include_file, '<', "$file")
872 or warn "$P: Can't read '$file' $!\n";
873 my $text = <$include_file>;
874 close($include_file);
875
876 my @lines = split('\n', $text);
877
878 foreach my $line (@lines) {
879 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
880 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
881 $camelcase{$1} = 1;
882 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
883 $camelcase{$1} = 1;
884 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
885 $camelcase{$1} = 1;
886 }
887 }
888}
889
Tom Rinic57383b2020-06-16 10:29:46 -0400890our %maintained_status = ();
891
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200892sub is_maintained_obsolete {
893 my ($filename) = @_;
894
895 return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
896
Tom Rinic57383b2020-06-16 10:29:46 -0400897 if (!exists($maintained_status{$filename})) {
898 $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
899 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200900
Tom Rinic57383b2020-06-16 10:29:46 -0400901 return $maintained_status{$filename} =~ /obsolete/i;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200902}
903
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +0200904sub is_SPDX_License_valid {
905 my ($license) = @_;
906
907 return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
908
909 my $root_path = abs_path($root);
910 my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
911 return 0 if ($status ne "");
912 return 1;
913}
914
Tom Rini6b9709d2014-02-27 08:27:28 -0500915my $camelcase_seeded = 0;
916sub seed_camelcase_includes {
917 return if ($camelcase_seeded);
918
919 my $files;
920 my $camelcase_cache = "";
921 my @include_files = ();
922
923 $camelcase_seeded = 1;
924
925 if (-e ".git") {
Tom Rinic57383b2020-06-16 10:29:46 -0400926 my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
Tom Rini6b9709d2014-02-27 08:27:28 -0500927 chomp $git_last_include_commit;
928 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
929 } else {
930 my $last_mod_date = 0;
931 $files = `find $root/include -name "*.h"`;
932 @include_files = split('\n', $files);
933 foreach my $file (@include_files) {
934 my $date = POSIX::strftime("%Y%m%d%H%M",
935 localtime((stat $file)[9]));
936 $last_mod_date = $date if ($last_mod_date < $date);
937 }
938 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
939 }
940
941 if ($camelcase_cache ne "" && -f $camelcase_cache) {
942 open(my $camelcase_file, '<', "$camelcase_cache")
943 or warn "$P: Can't read '$camelcase_cache' $!\n";
944 while (<$camelcase_file>) {
945 chomp;
946 $camelcase{$_} = 1;
947 }
948 close($camelcase_file);
949
950 return;
951 }
952
953 if (-e ".git") {
Tom Rinic57383b2020-06-16 10:29:46 -0400954 $files = `${git_command} ls-files "include/*.h"`;
Tom Rini6b9709d2014-02-27 08:27:28 -0500955 @include_files = split('\n', $files);
956 }
957
958 foreach my $file (@include_files) {
959 seed_camelcase_file($file);
960 }
961
962 if ($camelcase_cache ne "") {
963 unlink glob ".checkpatch-camelcase.*";
964 open(my $camelcase_file, '>', "$camelcase_cache")
965 or warn "$P: Can't write '$camelcase_cache' $!\n";
966 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
967 print $camelcase_file ("$_\n");
968 }
969 close($camelcase_file);
970 }
971}
972
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200973sub git_commit_info {
974 my ($commit, $id, $desc) = @_;
975
976 return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
977
Tom Rinic57383b2020-06-16 10:29:46 -0400978 my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200979 $output =~ s/^\s*//gm;
980 my @lines = split("\n", $output);
981
982 return ($id, $desc) if ($#lines < 0);
983
Tom Rinic57383b2020-06-16 10:29:46 -0400984 if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +0200985# Maybe one day convert this block of bash into something that returns
986# all matching commit ids, but it's very slow...
987#
988# echo "checking commits $1..."
989# git rev-list --remotes | grep -i "^$1" |
990# while read line ; do
991# git log --format='%H %s' -1 $line |
992# echo "commit $(cut -c 1-12,41-)"
993# done
994 } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
995 $id = undef;
996 } else {
997 $id = substr($lines[0], 0, 12);
998 $desc = substr($lines[0], 41);
999 }
1000
1001 return ($id, $desc);
1002}
1003
Joe Hershberger05622192011-10-18 10:06:59 +00001004$chk_signoff = 0 if ($file);
1005
Joe Hershberger05622192011-10-18 10:06:59 +00001006my @rawlines = ();
1007my @lines = ();
Tom Rini6b9709d2014-02-27 08:27:28 -05001008my @fixed = ();
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001009my @fixed_inserted = ();
1010my @fixed_deleted = ();
Dan Murphyc10e0f52017-01-31 14:15:53 -06001011my $fixlinenr = -1;
1012
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001013# If input is git commits, extract all commits from the commit expressions.
1014# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
1015die "$P: No git repository found\n" if ($git && !-e ".git");
1016
1017if ($git) {
1018 my @commits = ();
1019 foreach my $commit_expr (@ARGV) {
1020 my $git_range;
1021 if ($commit_expr =~ m/^(.*)-(\d+)$/) {
1022 $git_range = "-$2 $1";
1023 } elsif ($commit_expr =~ m/\.\./) {
1024 $git_range = "$commit_expr";
1025 } else {
1026 $git_range = "-1 $commit_expr";
1027 }
Tom Rinic57383b2020-06-16 10:29:46 -04001028 my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001029 foreach my $line (split(/\n/, $lines)) {
1030 $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
1031 next if (!defined($1) || !defined($2));
1032 my $sha1 = $1;
1033 my $subject = $2;
1034 unshift(@commits, $sha1);
1035 $git_commits{$sha1} = $subject;
1036 }
1037 }
1038 die "$P: no git commits after extraction!\n" if (@commits == 0);
1039 @ARGV = @commits;
1040}
1041
1042my $vname;
Tom Rinic57383b2020-06-16 10:29:46 -04001043$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
Joe Hershberger05622192011-10-18 10:06:59 +00001044for my $filename (@ARGV) {
1045 my $FILE;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001046 if ($git) {
1047 open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
1048 die "$P: $filename: git format-patch failed - $!\n";
1049 } elsif ($file) {
Joe Hershberger05622192011-10-18 10:06:59 +00001050 open($FILE, '-|', "diff -u /dev/null $filename") ||
1051 die "$P: $filename: diff failed - $!\n";
1052 } elsif ($filename eq '-') {
1053 open($FILE, '<&STDIN');
1054 } else {
1055 open($FILE, '<', "$filename") ||
1056 die "$P: $filename: open failed - $!\n";
1057 }
1058 if ($filename eq '-') {
1059 $vname = 'Your patch';
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001060 } elsif ($git) {
1061 $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
Joe Hershberger05622192011-10-18 10:06:59 +00001062 } else {
1063 $vname = $filename;
1064 }
1065 while (<$FILE>) {
1066 chomp;
1067 push(@rawlines, $_);
1068 }
1069 close($FILE);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001070
1071 if ($#ARGV > 0 && $quiet == 0) {
1072 print '-' x length($vname) . "\n";
1073 print "$vname\n";
1074 print '-' x length($vname) . "\n";
1075 }
1076
Joe Hershberger05622192011-10-18 10:06:59 +00001077 if (!process($filename)) {
1078 $exit = 1;
1079 }
1080 @rawlines = ();
1081 @lines = ();
Tom Rini6b9709d2014-02-27 08:27:28 -05001082 @fixed = ();
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001083 @fixed_inserted = ();
1084 @fixed_deleted = ();
1085 $fixlinenr = -1;
1086 @modifierListFile = ();
1087 @typeListFile = ();
1088 build_types();
1089}
1090
1091if (!$quiet) {
1092 hash_show_words(\%use_type, "Used");
1093 hash_show_words(\%ignore_type, "Ignored");
1094
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02001095 if (!$perl_version_ok) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001096 print << "EOM"
1097
1098NOTE: perl $^V is not modern enough to detect all possible issues.
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02001099 An upgrade to at least perl $minimum_perl_version is suggested.
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001100EOM
1101 }
1102 if ($exit) {
1103 print << "EOM"
1104
1105NOTE: If any of the errors are false positives, please report
1106 them to the maintainer, see CHECKPATCH in MAINTAINERS.
1107EOM
1108 }
Joe Hershberger05622192011-10-18 10:06:59 +00001109}
1110
1111exit($exit);
1112
1113sub top_of_kernel_tree {
1114 my ($root) = @_;
1115
1116 my @tree_check = (
Tom Rini6b9709d2014-02-27 08:27:28 -05001117 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
Joe Hershberger05622192011-10-18 10:06:59 +00001118 "README", "Documentation", "arch", "include", "drivers",
1119 "fs", "init", "ipc", "kernel", "lib", "scripts",
1120 );
1121
1122 foreach my $check (@tree_check) {
1123 if (! -e $root . '/' . $check) {
1124 return 0;
1125 }
1126 }
1127 return 1;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001128}
Joe Hershberger05622192011-10-18 10:06:59 +00001129
1130sub parse_email {
1131 my ($formatted_email) = @_;
1132
1133 my $name = "";
Tom Rinic57383b2020-06-16 10:29:46 -04001134 my $name_comment = "";
Joe Hershberger05622192011-10-18 10:06:59 +00001135 my $address = "";
1136 my $comment = "";
1137
1138 if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
1139 $name = $1;
1140 $address = $2;
1141 $comment = $3 if defined $3;
1142 } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
1143 $address = $1;
1144 $comment = $2 if defined $2;
1145 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1146 $address = $1;
1147 $comment = $2 if defined $2;
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02001148 $formatted_email =~ s/\Q$address\E.*$//;
Joe Hershberger05622192011-10-18 10:06:59 +00001149 $name = $formatted_email;
Tom Rini6b9709d2014-02-27 08:27:28 -05001150 $name = trim($name);
Joe Hershberger05622192011-10-18 10:06:59 +00001151 $name =~ s/^\"|\"$//g;
1152 # If there's a name left after stripping spaces and
1153 # leading quotes, and the address doesn't have both
1154 # leading and trailing angle brackets, the address
1155 # is invalid. ie:
1156 # "joe smith joe@smith.com" bad
1157 # "joe smith <joe@smith.com" bad
1158 if ($name ne "" && $address !~ /^<[^>]+>$/) {
1159 $name = "";
1160 $address = "";
1161 $comment = "";
1162 }
1163 }
1164
Tom Rini6b9709d2014-02-27 08:27:28 -05001165 $name = trim($name);
Joe Hershberger05622192011-10-18 10:06:59 +00001166 $name =~ s/^\"|\"$//g;
Tom Rinic57383b2020-06-16 10:29:46 -04001167 $name =~ s/(\s*\([^\)]+\))\s*//;
1168 if (defined($1)) {
1169 $name_comment = trim($1);
1170 }
Tom Rini6b9709d2014-02-27 08:27:28 -05001171 $address = trim($address);
Joe Hershberger05622192011-10-18 10:06:59 +00001172 $address =~ s/^\<|\>$//g;
1173
1174 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1175 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1176 $name = "\"$name\"";
1177 }
1178
Tom Rinic57383b2020-06-16 10:29:46 -04001179 return ($name, $name_comment, $address, $comment);
Joe Hershberger05622192011-10-18 10:06:59 +00001180}
1181
1182sub format_email {
1183 my ($name, $address) = @_;
1184
1185 my $formatted_email;
1186
Tom Rini6b9709d2014-02-27 08:27:28 -05001187 $name = trim($name);
Joe Hershberger05622192011-10-18 10:06:59 +00001188 $name =~ s/^\"|\"$//g;
Tom Rini6b9709d2014-02-27 08:27:28 -05001189 $address = trim($address);
Joe Hershberger05622192011-10-18 10:06:59 +00001190
1191 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1192 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1193 $name = "\"$name\"";
1194 }
1195
1196 if ("$name" eq "") {
1197 $formatted_email = "$address";
1198 } else {
1199 $formatted_email = "$name <$address>";
1200 }
1201
1202 return $formatted_email;
1203}
1204
Tom Rinic57383b2020-06-16 10:29:46 -04001205sub reformat_email {
1206 my ($email) = @_;
1207
1208 my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
1209 return format_email($email_name, $email_address);
1210}
1211
1212sub same_email_addresses {
1213 my ($email1, $email2) = @_;
1214
1215 my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1216 my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1217
1218 return $email1_name eq $email2_name &&
1219 $email1_address eq $email2_address;
1220}
1221
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001222sub which {
1223 my ($bin) = @_;
1224
1225 foreach my $path (split(/:/, $ENV{PATH})) {
1226 if (-e "$path/$bin") {
1227 return "$path/$bin";
1228 }
1229 }
1230
1231 return "";
1232}
1233
Joe Hershberger05622192011-10-18 10:06:59 +00001234sub which_conf {
1235 my ($conf) = @_;
1236
1237 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1238 if (-e "$path/$conf") {
1239 return "$path/$conf";
1240 }
1241 }
1242
1243 return "";
1244}
1245
1246sub expand_tabs {
1247 my ($str) = @_;
1248
1249 my $res = '';
1250 my $n = 0;
1251 for my $c (split(//, $str)) {
1252 if ($c eq "\t") {
1253 $res .= ' ';
1254 $n++;
Tom Rinic57383b2020-06-16 10:29:46 -04001255 for (; ($n % $tabsize) != 0; $n++) {
Joe Hershberger05622192011-10-18 10:06:59 +00001256 $res .= ' ';
1257 }
1258 next;
1259 }
1260 $res .= $c;
1261 $n++;
1262 }
1263
1264 return $res;
1265}
1266sub copy_spacing {
1267 (my $res = shift) =~ tr/\t/ /c;
1268 return $res;
1269}
1270
1271sub line_stats {
1272 my ($line) = @_;
1273
1274 # Drop the diff line leader and expand tabs
1275 $line =~ s/^.//;
1276 $line = expand_tabs($line);
1277
1278 # Pick the indent from the front of the line.
1279 my ($white) = ($line =~ /^(\s*)/);
1280
1281 return (length($line), length($white));
1282}
1283
1284my $sanitise_quote = '';
1285
1286sub sanitise_line_reset {
1287 my ($in_comment) = @_;
1288
1289 if ($in_comment) {
1290 $sanitise_quote = '*/';
1291 } else {
1292 $sanitise_quote = '';
1293 }
1294}
1295sub sanitise_line {
1296 my ($line) = @_;
1297
1298 my $res = '';
1299 my $l = '';
1300
1301 my $qlen = 0;
1302 my $off = 0;
1303 my $c;
1304
1305 # Always copy over the diff marker.
1306 $res = substr($line, 0, 1);
1307
1308 for ($off = 1; $off < length($line); $off++) {
1309 $c = substr($line, $off, 1);
1310
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02001311 # Comments we are whacking completely including the begin
Joe Hershberger05622192011-10-18 10:06:59 +00001312 # and end, all to $;.
1313 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1314 $sanitise_quote = '*/';
1315
1316 substr($res, $off, 2, "$;$;");
1317 $off++;
1318 next;
1319 }
1320 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1321 $sanitise_quote = '';
1322 substr($res, $off, 2, "$;$;");
1323 $off++;
1324 next;
1325 }
1326 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1327 $sanitise_quote = '//';
1328
1329 substr($res, $off, 2, $sanitise_quote);
1330 $off++;
1331 next;
1332 }
1333
1334 # A \ in a string means ignore the next character.
1335 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1336 $c eq "\\") {
1337 substr($res, $off, 2, 'XX');
1338 $off++;
1339 next;
1340 }
1341 # Regular quotes.
1342 if ($c eq "'" || $c eq '"') {
1343 if ($sanitise_quote eq '') {
1344 $sanitise_quote = $c;
1345
1346 substr($res, $off, 1, $c);
1347 next;
1348 } elsif ($sanitise_quote eq $c) {
1349 $sanitise_quote = '';
1350 }
1351 }
1352
1353 #print "c<$c> SQ<$sanitise_quote>\n";
1354 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1355 substr($res, $off, 1, $;);
1356 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1357 substr($res, $off, 1, $;);
1358 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1359 substr($res, $off, 1, 'X');
1360 } else {
1361 substr($res, $off, 1, $c);
1362 }
1363 }
1364
1365 if ($sanitise_quote eq '//') {
1366 $sanitise_quote = '';
1367 }
1368
1369 # The pathname on a #include may be surrounded by '<' and '>'.
1370 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1371 my $clean = 'X' x length($1);
1372 $res =~ s@\<.*\>@<$clean>@;
1373
1374 # The whole of a #error is a string.
1375 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1376 my $clean = 'X' x length($1);
1377 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1378 }
1379
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001380 if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1381 my $match = $1;
1382 $res =~ s/\Q$match\E/"$;" x length($match)/e;
1383 }
1384
Joe Hershberger05622192011-10-18 10:06:59 +00001385 return $res;
1386}
1387
Tom Rini6b9709d2014-02-27 08:27:28 -05001388sub get_quoted_string {
1389 my ($line, $rawline) = @_;
1390
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02001391 return "" if (!defined($line) || !defined($rawline));
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02001392 return "" if ($line !~ m/($String)/g);
Tom Rini6b9709d2014-02-27 08:27:28 -05001393 return substr($rawline, $-[0], $+[0] - $-[0]);
1394}
1395
Joe Hershberger05622192011-10-18 10:06:59 +00001396sub ctx_statement_block {
1397 my ($linenr, $remain, $off) = @_;
1398 my $line = $linenr - 1;
1399 my $blk = '';
1400 my $soff = $off;
1401 my $coff = $off - 1;
1402 my $coff_set = 0;
1403
1404 my $loff = 0;
1405
1406 my $type = '';
1407 my $level = 0;
1408 my @stack = ();
1409 my $p;
1410 my $c;
1411 my $len = 0;
1412
1413 my $remainder;
1414 while (1) {
1415 @stack = (['', 0]) if ($#stack == -1);
1416
1417 #warn "CSB: blk<$blk> remain<$remain>\n";
1418 # If we are about to drop off the end, pull in more
1419 # context.
1420 if ($off >= $len) {
1421 for (; $remain > 0; $line++) {
1422 last if (!defined $lines[$line]);
1423 next if ($lines[$line] =~ /^-/);
1424 $remain--;
1425 $loff = $len;
1426 $blk .= $lines[$line] . "\n";
1427 $len = length($blk);
1428 $line++;
1429 last;
1430 }
1431 # Bail if there is no further context.
1432 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
1433 if ($off >= $len) {
1434 last;
1435 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001436 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1437 $level++;
1438 $type = '#';
1439 }
Joe Hershberger05622192011-10-18 10:06:59 +00001440 }
1441 $p = $c;
1442 $c = substr($blk, $off, 1);
1443 $remainder = substr($blk, $off);
1444
1445 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
1446
1447 # Handle nested #if/#else.
1448 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
1449 push(@stack, [ $type, $level ]);
1450 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
1451 ($type, $level) = @{$stack[$#stack - 1]};
1452 } elsif ($remainder =~ /^#\s*endif\b/) {
1453 ($type, $level) = @{pop(@stack)};
1454 }
1455
1456 # Statement ends at the ';' or a close '}' at the
1457 # outermost level.
1458 if ($level == 0 && $c eq ';') {
1459 last;
1460 }
1461
1462 # An else is really a conditional as long as its not else if
1463 if ($level == 0 && $coff_set == 0 &&
1464 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1465 $remainder =~ /^(else)(?:\s|{)/ &&
1466 $remainder !~ /^else\s+if\b/) {
1467 $coff = $off + length($1) - 1;
1468 $coff_set = 1;
1469 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1470 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
1471 }
1472
1473 if (($type eq '' || $type eq '(') && $c eq '(') {
1474 $level++;
1475 $type = '(';
1476 }
1477 if ($type eq '(' && $c eq ')') {
1478 $level--;
1479 $type = ($level != 0)? '(' : '';
1480
1481 if ($level == 0 && $coff < $soff) {
1482 $coff = $off;
1483 $coff_set = 1;
1484 #warn "CSB: mark coff<$coff>\n";
1485 }
1486 }
1487 if (($type eq '' || $type eq '{') && $c eq '{') {
1488 $level++;
1489 $type = '{';
1490 }
1491 if ($type eq '{' && $c eq '}') {
1492 $level--;
1493 $type = ($level != 0)? '{' : '';
1494
1495 if ($level == 0) {
1496 if (substr($blk, $off + 1, 1) eq ';') {
1497 $off++;
1498 }
1499 last;
1500 }
1501 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001502 # Preprocessor commands end at the newline unless escaped.
1503 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1504 $level--;
1505 $type = '';
1506 $off++;
1507 last;
1508 }
Joe Hershberger05622192011-10-18 10:06:59 +00001509 $off++;
1510 }
1511 # We are truly at the end, so shuffle to the next line.
1512 if ($off == $len) {
1513 $loff = $len + 1;
1514 $line++;
1515 $remain--;
1516 }
1517
1518 my $statement = substr($blk, $soff, $off - $soff + 1);
1519 my $condition = substr($blk, $soff, $coff - $soff + 1);
1520
1521 #warn "STATEMENT<$statement>\n";
1522 #warn "CONDITION<$condition>\n";
1523
1524 #print "coff<$coff> soff<$off> loff<$loff>\n";
1525
1526 return ($statement, $condition,
1527 $line, $remain + 1, $off - $loff + 1, $level);
1528}
1529
1530sub statement_lines {
1531 my ($stmt) = @_;
1532
1533 # Strip the diff line prefixes and rip blank lines at start and end.
1534 $stmt =~ s/(^|\n)./$1/g;
1535 $stmt =~ s/^\s*//;
1536 $stmt =~ s/\s*$//;
1537
1538 my @stmt_lines = ($stmt =~ /\n/g);
1539
1540 return $#stmt_lines + 2;
1541}
1542
1543sub statement_rawlines {
1544 my ($stmt) = @_;
1545
1546 my @stmt_lines = ($stmt =~ /\n/g);
1547
1548 return $#stmt_lines + 2;
1549}
1550
1551sub statement_block_size {
1552 my ($stmt) = @_;
1553
1554 $stmt =~ s/(^|\n)./$1/g;
1555 $stmt =~ s/^\s*{//;
1556 $stmt =~ s/}\s*$//;
1557 $stmt =~ s/^\s*//;
1558 $stmt =~ s/\s*$//;
1559
1560 my @stmt_lines = ($stmt =~ /\n/g);
1561 my @stmt_statements = ($stmt =~ /;/g);
1562
1563 my $stmt_lines = $#stmt_lines + 2;
1564 my $stmt_statements = $#stmt_statements + 1;
1565
1566 if ($stmt_lines > $stmt_statements) {
1567 return $stmt_lines;
1568 } else {
1569 return $stmt_statements;
1570 }
1571}
1572
1573sub ctx_statement_full {
1574 my ($linenr, $remain, $off) = @_;
1575 my ($statement, $condition, $level);
1576
1577 my (@chunks);
1578
1579 # Grab the first conditional/block pair.
1580 ($statement, $condition, $linenr, $remain, $off, $level) =
1581 ctx_statement_block($linenr, $remain, $off);
1582 #print "F: c<$condition> s<$statement> remain<$remain>\n";
1583 push(@chunks, [ $condition, $statement ]);
1584 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1585 return ($level, $linenr, @chunks);
1586 }
1587
1588 # Pull in the following conditional/block pairs and see if they
1589 # could continue the statement.
1590 for (;;) {
1591 ($statement, $condition, $linenr, $remain, $off, $level) =
1592 ctx_statement_block($linenr, $remain, $off);
1593 #print "C: c<$condition> s<$statement> remain<$remain>\n";
1594 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1595 #print "C: push\n";
1596 push(@chunks, [ $condition, $statement ]);
1597 }
1598
1599 return ($level, $linenr, @chunks);
1600}
1601
1602sub ctx_block_get {
1603 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1604 my $line;
1605 my $start = $linenr - 1;
1606 my $blk = '';
1607 my @o;
1608 my @c;
1609 my @res = ();
1610
1611 my $level = 0;
1612 my @stack = ($level);
1613 for ($line = $start; $remain > 0; $line++) {
1614 next if ($rawlines[$line] =~ /^-/);
1615 $remain--;
1616
1617 $blk .= $rawlines[$line];
1618
1619 # Handle nested #if/#else.
1620 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1621 push(@stack, $level);
1622 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1623 $level = $stack[$#stack - 1];
1624 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1625 $level = pop(@stack);
1626 }
1627
1628 foreach my $c (split(//, $lines[$line])) {
1629 ##print "C<$c>L<$level><$open$close>O<$off>\n";
1630 if ($off > 0) {
1631 $off--;
1632 next;
1633 }
1634
1635 if ($c eq $close && $level > 0) {
1636 $level--;
1637 last if ($level == 0);
1638 } elsif ($c eq $open) {
1639 $level++;
1640 }
1641 }
1642
1643 if (!$outer || $level <= 1) {
1644 push(@res, $rawlines[$line]);
1645 }
1646
1647 last if ($level == 0);
1648 }
1649
1650 return ($level, @res);
1651}
1652sub ctx_block_outer {
1653 my ($linenr, $remain) = @_;
1654
1655 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1656 return @r;
1657}
1658sub ctx_block {
1659 my ($linenr, $remain) = @_;
1660
1661 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1662 return @r;
1663}
1664sub ctx_statement {
1665 my ($linenr, $remain, $off) = @_;
1666
1667 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1668 return @r;
1669}
1670sub ctx_block_level {
1671 my ($linenr, $remain) = @_;
1672
1673 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1674}
1675sub ctx_statement_level {
1676 my ($linenr, $remain, $off) = @_;
1677
1678 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1679}
1680
1681sub ctx_locate_comment {
1682 my ($first_line, $end_line) = @_;
1683
1684 # Catch a comment on the end of the line itself.
1685 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1686 return $current_comment if (defined $current_comment);
1687
1688 # Look through the context and try and figure out if there is a
1689 # comment.
1690 my $in_comment = 0;
1691 $current_comment = '';
1692 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1693 my $line = $rawlines[$linenr - 1];
1694 #warn " $line\n";
1695 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1696 $in_comment = 1;
1697 }
1698 if ($line =~ m@/\*@) {
1699 $in_comment = 1;
1700 }
1701 if (!$in_comment && $current_comment ne '') {
1702 $current_comment = '';
1703 }
1704 $current_comment .= $line . "\n" if ($in_comment);
1705 if ($line =~ m@\*/@) {
1706 $in_comment = 0;
1707 }
1708 }
1709
1710 chomp($current_comment);
1711 return($current_comment);
1712}
1713sub ctx_has_comment {
1714 my ($first_line, $end_line) = @_;
1715 my $cmt = ctx_locate_comment($first_line, $end_line);
1716
1717 ##print "LINE: $rawlines[$end_line - 1 ]\n";
1718 ##print "CMMT: $cmt\n";
1719
1720 return ($cmt ne '');
1721}
1722
1723sub raw_line {
1724 my ($linenr, $cnt) = @_;
1725
1726 my $offset = $linenr - 1;
1727 $cnt++;
1728
1729 my $line;
1730 while ($cnt) {
1731 $line = $rawlines[$offset++];
1732 next if (defined($line) && $line =~ /^-/);
1733 $cnt--;
1734 }
1735
1736 return $line;
1737}
1738
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02001739sub get_stat_real {
1740 my ($linenr, $lc) = @_;
1741
1742 my $stat_real = raw_line($linenr, 0);
1743 for (my $count = $linenr + 1; $count <= $lc; $count++) {
1744 $stat_real = $stat_real . "\n" . raw_line($count, 0);
1745 }
1746
1747 return $stat_real;
1748}
1749
1750sub get_stat_here {
1751 my ($linenr, $cnt, $here) = @_;
1752
1753 my $herectx = $here . "\n";
1754 for (my $n = 0; $n < $cnt; $n++) {
1755 $herectx .= raw_line($linenr, $n) . "\n";
1756 }
1757
1758 return $herectx;
1759}
1760
Joe Hershberger05622192011-10-18 10:06:59 +00001761sub cat_vet {
1762 my ($vet) = @_;
1763 my ($res, $coded);
1764
1765 $res = '';
1766 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1767 $res .= $1;
1768 if ($2 ne '') {
1769 $coded = sprintf("^%c", unpack('C', $2) + 64);
1770 $res .= $coded;
1771 }
1772 }
1773 $res =~ s/$/\$/;
1774
1775 return $res;
1776}
1777
1778my $av_preprocessor = 0;
1779my $av_pending;
1780my @av_paren_type;
1781my $av_pend_colon;
1782
1783sub annotate_reset {
1784 $av_preprocessor = 0;
1785 $av_pending = '_';
1786 @av_paren_type = ('E');
1787 $av_pend_colon = 'O';
1788}
1789
1790sub annotate_values {
1791 my ($stream, $type) = @_;
1792
1793 my $res;
1794 my $var = '_' x length($stream);
1795 my $cur = $stream;
1796
1797 print "$stream\n" if ($dbg_values > 1);
1798
1799 while (length($cur)) {
1800 @av_paren_type = ('E') if ($#av_paren_type < 0);
1801 print " <" . join('', @av_paren_type) .
1802 "> <$type> <$av_pending>" if ($dbg_values > 1);
1803 if ($cur =~ /^(\s+)/o) {
1804 print "WS($1)\n" if ($dbg_values > 1);
1805 if ($1 =~ /\n/ && $av_preprocessor) {
1806 $type = pop(@av_paren_type);
1807 $av_preprocessor = 0;
1808 }
1809
1810 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1811 print "CAST($1)\n" if ($dbg_values > 1);
1812 push(@av_paren_type, $type);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001813 $type = 'c';
Joe Hershberger05622192011-10-18 10:06:59 +00001814
1815 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1816 print "DECLARE($1)\n" if ($dbg_values > 1);
1817 $type = 'T';
1818
1819 } elsif ($cur =~ /^($Modifier)\s*/) {
1820 print "MODIFIER($1)\n" if ($dbg_values > 1);
1821 $type = 'T';
1822
1823 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1824 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1825 $av_preprocessor = 1;
1826 push(@av_paren_type, $type);
1827 if ($2 ne '') {
1828 $av_pending = 'N';
1829 }
1830 $type = 'E';
1831
1832 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1833 print "UNDEF($1)\n" if ($dbg_values > 1);
1834 $av_preprocessor = 1;
1835 push(@av_paren_type, $type);
1836
1837 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1838 print "PRE_START($1)\n" if ($dbg_values > 1);
1839 $av_preprocessor = 1;
1840
1841 push(@av_paren_type, $type);
1842 push(@av_paren_type, $type);
1843 $type = 'E';
1844
1845 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1846 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1847 $av_preprocessor = 1;
1848
1849 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1850
1851 $type = 'E';
1852
1853 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1854 print "PRE_END($1)\n" if ($dbg_values > 1);
1855
1856 $av_preprocessor = 1;
1857
1858 # Assume all arms of the conditional end as this
1859 # one does, and continue as if the #endif was not here.
1860 pop(@av_paren_type);
1861 push(@av_paren_type, $type);
1862 $type = 'E';
1863
1864 } elsif ($cur =~ /^(\\\n)/o) {
1865 print "PRECONT($1)\n" if ($dbg_values > 1);
1866
1867 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1868 print "ATTR($1)\n" if ($dbg_values > 1);
1869 $av_pending = $type;
1870 $type = 'N';
1871
1872 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1873 print "SIZEOF($1)\n" if ($dbg_values > 1);
1874 if (defined $2) {
1875 $av_pending = 'V';
1876 }
1877 $type = 'N';
1878
1879 } elsif ($cur =~ /^(if|while|for)\b/o) {
1880 print "COND($1)\n" if ($dbg_values > 1);
1881 $av_pending = 'E';
1882 $type = 'N';
1883
1884 } elsif ($cur =~/^(case)/o) {
1885 print "CASE($1)\n" if ($dbg_values > 1);
1886 $av_pend_colon = 'C';
1887 $type = 'N';
1888
1889 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1890 print "KEYWORD($1)\n" if ($dbg_values > 1);
1891 $type = 'N';
1892
1893 } elsif ($cur =~ /^(\()/o) {
1894 print "PAREN('$1')\n" if ($dbg_values > 1);
1895 push(@av_paren_type, $av_pending);
1896 $av_pending = '_';
1897 $type = 'N';
1898
1899 } elsif ($cur =~ /^(\))/o) {
1900 my $new_type = pop(@av_paren_type);
1901 if ($new_type ne '_') {
1902 $type = $new_type;
1903 print "PAREN('$1') -> $type\n"
1904 if ($dbg_values > 1);
1905 } else {
1906 print "PAREN('$1')\n" if ($dbg_values > 1);
1907 }
1908
1909 } elsif ($cur =~ /^($Ident)\s*\(/o) {
1910 print "FUNC($1)\n" if ($dbg_values > 1);
1911 $type = 'V';
1912 $av_pending = 'V';
1913
1914 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1915 if (defined $2 && $type eq 'C' || $type eq 'T') {
1916 $av_pend_colon = 'B';
1917 } elsif ($type eq 'E') {
1918 $av_pend_colon = 'L';
1919 }
1920 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1921 $type = 'V';
1922
1923 } elsif ($cur =~ /^($Ident|$Constant)/o) {
1924 print "IDENT($1)\n" if ($dbg_values > 1);
1925 $type = 'V';
1926
1927 } elsif ($cur =~ /^($Assignment)/o) {
1928 print "ASSIGN($1)\n" if ($dbg_values > 1);
1929 $type = 'N';
1930
1931 } elsif ($cur =~/^(;|{|})/) {
1932 print "END($1)\n" if ($dbg_values > 1);
1933 $type = 'E';
1934 $av_pend_colon = 'O';
1935
1936 } elsif ($cur =~/^(,)/) {
1937 print "COMMA($1)\n" if ($dbg_values > 1);
1938 $type = 'C';
1939
1940 } elsif ($cur =~ /^(\?)/o) {
1941 print "QUESTION($1)\n" if ($dbg_values > 1);
1942 $type = 'N';
1943
1944 } elsif ($cur =~ /^(:)/o) {
1945 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1946
1947 substr($var, length($res), 1, $av_pend_colon);
1948 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1949 $type = 'E';
1950 } else {
1951 $type = 'N';
1952 }
1953 $av_pend_colon = 'O';
1954
1955 } elsif ($cur =~ /^(\[)/o) {
1956 print "CLOSE($1)\n" if ($dbg_values > 1);
1957 $type = 'N';
1958
1959 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1960 my $variant;
1961
1962 print "OPV($1)\n" if ($dbg_values > 1);
1963 if ($type eq 'V') {
1964 $variant = 'B';
1965 } else {
1966 $variant = 'U';
1967 }
1968
1969 substr($var, length($res), 1, $variant);
1970 $type = 'N';
1971
1972 } elsif ($cur =~ /^($Operators)/o) {
1973 print "OP($1)\n" if ($dbg_values > 1);
1974 if ($1 ne '++' && $1 ne '--') {
1975 $type = 'N';
1976 }
1977
1978 } elsif ($cur =~ /(^.)/o) {
1979 print "C($1)\n" if ($dbg_values > 1);
1980 }
1981 if (defined $1) {
1982 $cur = substr($cur, length($1));
1983 $res .= $type x length($1);
1984 }
1985 }
1986
1987 return ($res, $var);
1988}
1989
1990sub possible {
1991 my ($possible, $line) = @_;
1992 my $notPermitted = qr{(?:
1993 ^(?:
1994 $Modifier|
1995 $Storage|
1996 $Type|
1997 DEFINE_\S+
1998 )$|
1999 ^(?:
2000 goto|
2001 return|
2002 case|
2003 else|
2004 asm|__asm__|
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002005 do|
2006 \#|
2007 \#\#|
Joe Hershberger05622192011-10-18 10:06:59 +00002008 )(?:\s|$)|
2009 ^(?:typedef|struct|enum)\b
2010 )}x;
2011 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
2012 if ($possible !~ $notPermitted) {
2013 # Check for modifiers.
2014 $possible =~ s/\s*$Storage\s*//g;
2015 $possible =~ s/\s*$Sparse\s*//g;
2016 if ($possible =~ /^\s*$/) {
2017
2018 } elsif ($possible =~ /\s/) {
2019 $possible =~ s/\s*$Type\s*//g;
2020 for my $modifier (split(' ', $possible)) {
2021 if ($modifier !~ $notPermitted) {
2022 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002023 push(@modifierListFile, $modifier);
Joe Hershberger05622192011-10-18 10:06:59 +00002024 }
2025 }
2026
2027 } else {
2028 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002029 push(@typeListFile, $possible);
Joe Hershberger05622192011-10-18 10:06:59 +00002030 }
2031 build_types();
2032 } else {
2033 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
2034 }
2035}
2036
2037my $prefix = '';
2038
2039sub show_type {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002040 my ($type) = @_;
Tom Rini6b9709d2014-02-27 08:27:28 -05002041
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002042 $type =~ tr/[a-z]/[A-Z]/;
2043
2044 return defined $use_type{$type} if (scalar keys %use_type > 0);
2045
2046 return !defined $ignore_type{$type};
Joe Hershberger05622192011-10-18 10:06:59 +00002047}
2048
2049sub report {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002050 my ($level, $type, $msg) = @_;
2051
2052 if (!show_type($type) ||
2053 (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
Joe Hershberger05622192011-10-18 10:06:59 +00002054 return 0;
2055 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002056 my $output = '';
2057 if ($color) {
2058 if ($level eq 'ERROR') {
2059 $output .= RED;
2060 } elsif ($level eq 'WARNING') {
2061 $output .= YELLOW;
2062 } else {
2063 $output .= GREEN;
2064 }
Joe Hershberger05622192011-10-18 10:06:59 +00002065 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002066 $output .= $prefix . $level . ':';
2067 if ($show_types) {
2068 $output .= BLUE if ($color);
2069 $output .= "$type:";
2070 }
2071 $output .= RESET if ($color);
2072 $output .= ' ' . $msg . "\n";
Joe Hershberger05622192011-10-18 10:06:59 +00002073
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002074 if ($showfile) {
2075 my @lines = split("\n", $output, -1);
2076 splice(@lines, 1, 1);
2077 $output = join("\n", @lines);
2078 }
2079 $output = (split('\n', $output))[0] . "\n" if ($terse);
2080
2081 push(our @report, $output);
Joe Hershberger05622192011-10-18 10:06:59 +00002082
2083 return 1;
2084}
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002085
Joe Hershberger05622192011-10-18 10:06:59 +00002086sub report_dump {
2087 our @report;
2088}
2089
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002090sub fixup_current_range {
2091 my ($lineRef, $offset, $length) = @_;
2092
2093 if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2094 my $o = $1;
2095 my $l = $2;
2096 my $no = $o + $offset;
2097 my $nl = $l + $length;
2098 $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2099 }
2100}
2101
2102sub fix_inserted_deleted_lines {
2103 my ($linesRef, $insertedRef, $deletedRef) = @_;
2104
2105 my $range_last_linenr = 0;
2106 my $delta_offset = 0;
2107
2108 my $old_linenr = 0;
2109 my $new_linenr = 0;
2110
2111 my $next_insert = 0;
2112 my $next_delete = 0;
2113
2114 my @lines = ();
2115
2116 my $inserted = @{$insertedRef}[$next_insert++];
2117 my $deleted = @{$deletedRef}[$next_delete++];
2118
2119 foreach my $old_line (@{$linesRef}) {
2120 my $save_line = 1;
2121 my $line = $old_line; #don't modify the array
2122 if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename
2123 $delta_offset = 0;
2124 } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
2125 $range_last_linenr = $new_linenr;
2126 fixup_current_range(\$line, $delta_offset, 0);
2127 }
2128
2129 while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2130 $deleted = @{$deletedRef}[$next_delete++];
2131 $save_line = 0;
2132 fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2133 }
2134
2135 while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2136 push(@lines, ${$inserted}{'LINE'});
2137 $inserted = @{$insertedRef}[$next_insert++];
2138 $new_linenr++;
2139 fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2140 }
2141
2142 if ($save_line) {
2143 push(@lines, $line);
2144 $new_linenr++;
2145 }
2146
2147 $old_linenr++;
2148 }
2149
2150 return @lines;
2151}
2152
2153sub fix_insert_line {
2154 my ($linenr, $line) = @_;
2155
2156 my $inserted = {
2157 LINENR => $linenr,
2158 LINE => $line,
2159 };
2160 push(@fixed_inserted, $inserted);
2161}
2162
2163sub fix_delete_line {
2164 my ($linenr, $line) = @_;
2165
2166 my $deleted = {
2167 LINENR => $linenr,
2168 LINE => $line,
2169 };
2170
2171 push(@fixed_deleted, $deleted);
2172}
2173
Joe Hershberger05622192011-10-18 10:06:59 +00002174sub ERROR {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002175 my ($type, $msg) = @_;
2176
2177 if (report("ERROR", $type, $msg)) {
Joe Hershberger05622192011-10-18 10:06:59 +00002178 our $clean = 0;
2179 our $cnt_error++;
Tom Rini6b9709d2014-02-27 08:27:28 -05002180 return 1;
Joe Hershberger05622192011-10-18 10:06:59 +00002181 }
Tom Rini6b9709d2014-02-27 08:27:28 -05002182 return 0;
Joe Hershberger05622192011-10-18 10:06:59 +00002183}
2184sub WARN {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002185 my ($type, $msg) = @_;
2186
2187 if (report("WARNING", $type, $msg)) {
Joe Hershberger05622192011-10-18 10:06:59 +00002188 our $clean = 0;
2189 our $cnt_warn++;
Tom Rini6b9709d2014-02-27 08:27:28 -05002190 return 1;
Joe Hershberger05622192011-10-18 10:06:59 +00002191 }
Tom Rini6b9709d2014-02-27 08:27:28 -05002192 return 0;
Joe Hershberger05622192011-10-18 10:06:59 +00002193}
2194sub CHK {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002195 my ($type, $msg) = @_;
2196
2197 if ($check && report("CHECK", $type, $msg)) {
Joe Hershberger05622192011-10-18 10:06:59 +00002198 our $clean = 0;
2199 our $cnt_chk++;
Tom Rini6b9709d2014-02-27 08:27:28 -05002200 return 1;
Joe Hershberger05622192011-10-18 10:06:59 +00002201 }
Tom Rini6b9709d2014-02-27 08:27:28 -05002202 return 0;
Joe Hershberger05622192011-10-18 10:06:59 +00002203}
2204
2205sub check_absolute_file {
2206 my ($absolute, $herecurr) = @_;
2207 my $file = $absolute;
2208
2209 ##print "absolute<$absolute>\n";
2210
2211 # See if any suffix of this path is a path within the tree.
2212 while ($file =~ s@^[^/]*/@@) {
2213 if (-f "$root/$file") {
2214 ##print "file<$file>\n";
2215 last;
2216 }
2217 }
2218 if (! -f _) {
2219 return 0;
2220 }
2221
2222 # It is, so see if the prefix is acceptable.
2223 my $prefix = $absolute;
2224 substr($prefix, -length($file)) = '';
2225
2226 ##print "prefix<$prefix>\n";
2227 if ($prefix ne ".../") {
2228 WARN("USE_RELATIVE_PATH",
2229 "use relative pathname instead of absolute in changelog text\n" . $herecurr);
2230 }
2231}
2232
Tom Rini6b9709d2014-02-27 08:27:28 -05002233sub trim {
2234 my ($string) = @_;
2235
2236 $string =~ s/^\s+|\s+$//g;
2237
2238 return $string;
2239}
2240
2241sub ltrim {
2242 my ($string) = @_;
2243
2244 $string =~ s/^\s+//;
2245
2246 return $string;
2247}
2248
2249sub rtrim {
2250 my ($string) = @_;
2251
2252 $string =~ s/\s+$//;
2253
2254 return $string;
2255}
2256
2257sub string_find_replace {
2258 my ($string, $find, $replace) = @_;
2259
2260 $string =~ s/$find/$replace/g;
2261
2262 return $string;
2263}
2264
2265sub tabify {
2266 my ($leading) = @_;
2267
Tom Rinic57383b2020-06-16 10:29:46 -04002268 my $source_indent = $tabsize;
Tom Rini6b9709d2014-02-27 08:27:28 -05002269 my $max_spaces_before_tab = $source_indent - 1;
2270 my $spaces_to_tab = " " x $source_indent;
2271
2272 #convert leading spaces to tabs
2273 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
2274 #Remove spaces before a tab
2275 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
2276
2277 return "$leading";
2278}
2279
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002280sub pos_last_openparen {
2281 my ($line) = @_;
2282
2283 my $pos = 0;
2284
2285 my $opens = $line =~ tr/\(/\(/;
2286 my $closes = $line =~ tr/\)/\)/;
2287
2288 my $last_openparen = 0;
2289
2290 if (($opens == 0) || ($closes >= $opens)) {
2291 return -1;
2292 }
2293
2294 my $len = length($line);
2295
2296 for ($pos = 0; $pos < $len; $pos++) {
2297 my $string = substr($line, $pos);
2298 if ($string =~ /^($FuncArg|$balanced_parens)/) {
2299 $pos += length($1) - 1;
2300 } elsif (substr($line, $pos, 1) eq '(') {
2301 $last_openparen = $pos;
2302 } elsif (index($string, '(') == -1) {
2303 last;
2304 }
2305 }
2306
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002307 return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002308}
2309
Tom Rinic57383b2020-06-16 10:29:46 -04002310sub get_raw_comment {
2311 my ($line, $rawline) = @_;
2312 my $comment = '';
2313
2314 for my $i (0 .. (length($line) - 1)) {
2315 if (substr($line, $i, 1) eq "$;") {
2316 $comment .= substr($rawline, $i, 1);
2317 }
2318 }
2319
2320 return $comment;
2321}
2322
Simon Glassb77df592020-05-22 16:32:36 -06002323# Checks specific to U-Boot
2324sub u_boot_line {
Simon Glass23552ba2020-07-19 10:16:01 -06002325 my ($realfile, $line, $rawline, $herecurr) = @_;
Simon Glass281236c2020-05-22 16:32:37 -06002326
2327 # ask for a test if a new uclass ID is added
2328 if ($realfile =~ /uclass-id.h/ && $line =~ /^\+/) {
2329 WARN("NEW_UCLASS",
2330 "Possible new uclass - make sure to add a sandbox driver, plus a test in test/dm/<name>.c\n" . $herecurr);
2331 }
Simon Glass7fc7d242020-05-22 16:32:38 -06002332
2333 # try to get people to use the livetree API
2334 if ($line =~ /^\+.*fdtdec_/) {
2335 WARN("LIVETREE",
2336 "Use the livetree API (dev_read_...)\n" . $herecurr);
2337 }
Simon Glass58978112020-05-22 16:32:39 -06002338
2339 # add tests for new commands
2340 if ($line =~ /^\+.*do_($Ident)\(struct cmd_tbl.*/) {
2341 WARN("CMD_TEST",
2342 "Possible new command - make sure you add a test\n" . $herecurr);
2343 }
Simon Glassdd5b0fa2020-05-22 16:32:40 -06002344
2345 # use if instead of #if
Simon Glass8af45b12020-06-14 10:54:08 -06002346 if ($realfile =~ /\.c$/ && $line =~ /^\+#if.*CONFIG.*/) {
Simon Glassdd5b0fa2020-05-22 16:32:40 -06002347 WARN("PREFER_IF",
2348 "Use 'if (IS_ENABLED(CONFIG...))' instead of '#if or #ifdef' where possible\n" . $herecurr);
2349 }
Tom Rinif3e2ebe2020-05-26 14:29:02 -04002350
2351 # use defconfig to manage CONFIG_CMD options
2352 if ($line =~ /\+\s*#\s*(define|undef)\s+(CONFIG_CMD\w*)\b/) {
2353 ERROR("DEFINE_CONFIG_CMD",
2354 "All commands are managed by Kconfig\n" . $herecurr);
2355 }
Simon Glass23552ba2020-07-19 10:16:01 -06002356
2357 # Don't put common.h and dm.h in header files
2358 if ($realfile =~ /\.h$/ && $rawline =~ /^\+#include\s*<(common|dm)\.h>*/) {
2359 ERROR("BARRED_INCLUDE_IN_HDR",
2360 "Avoid including common.h and dm.h in header files\n" . $herecurr);
2361 }
Tom Rini12178b52020-08-20 08:37:49 -04002362
2363 # Do not disable fdt / initrd relocation
2364 if ($rawline =~ /.*(fdt|initrd)_high=0xffffffff/) {
2365 ERROR("DISABLE_FDT_OR_INITRD_RELOC",
2366 "fdt or initrd relocation disabled at boot time\n" . $herecurr);
2367 }
Simon Glassb77df592020-05-22 16:32:36 -06002368}
2369
Joe Hershberger05622192011-10-18 10:06:59 +00002370sub process {
2371 my $filename = shift;
2372
2373 my $linenr=0;
2374 my $prevline="";
2375 my $prevrawline="";
2376 my $stashline="";
2377 my $stashrawline="";
2378
2379 my $length;
2380 my $indent;
2381 my $previndent=0;
2382 my $stashindent=0;
2383
2384 our $clean = 1;
2385 my $signoff = 0;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002386 my $author = '';
2387 my $authorsignoff = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00002388 my $is_patch = 0;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002389 my $is_binding_patch = -1;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002390 my $in_header_lines = $file ? 0 : 1;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002391 my $in_commit_log = 0; #Scanning lines before patch
Tom Rinic57383b2020-06-16 10:29:46 -04002392 my $has_patch_separator = 0; #Found a --- line
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002393 my $has_commit_log = 0; #Encountered lines before patch
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002394 my $commit_log_lines = 0; #Number of commit log lines
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002395 my $commit_log_possible_stack_dump = 0;
2396 my $commit_log_long_line = 0;
2397 my $commit_log_has_diff = 0;
2398 my $reported_maintainer_file = 0;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002399 my $non_utf8_charset = 0;
2400
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002401 my $last_blank_line = 0;
2402 my $last_coalesced_string_linenr = -1;
2403
Joe Hershberger05622192011-10-18 10:06:59 +00002404 our @report = ();
2405 our $cnt_lines = 0;
2406 our $cnt_error = 0;
2407 our $cnt_warn = 0;
2408 our $cnt_chk = 0;
2409
2410 # Trace the real file/line as we go.
2411 my $realfile = '';
2412 my $realline = 0;
2413 my $realcnt = 0;
2414 my $here = '';
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002415 my $context_function; #undef'd unless there's a known function
Joe Hershberger05622192011-10-18 10:06:59 +00002416 my $in_comment = 0;
2417 my $comment_edge = 0;
2418 my $first_line = 0;
2419 my $p1_prefix = '';
2420
2421 my $prev_values = 'E';
2422
2423 # suppression flags
2424 my %suppress_ifbraces;
2425 my %suppress_whiletrailers;
2426 my %suppress_export;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002427 my $suppress_statement = 0;
2428
Tom Rini6b9709d2014-02-27 08:27:28 -05002429 my %signatures = ();
Joe Hershberger05622192011-10-18 10:06:59 +00002430
2431 # Pre-scan the patch sanitizing the lines.
2432 # Pre-scan the patch looking for any __setup documentation.
2433 #
2434 my @setup_docs = ();
2435 my $setup_docs = 0;
2436
Tom Rini6b9709d2014-02-27 08:27:28 -05002437 my $camelcase_file_seeded = 0;
2438
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02002439 my $checklicenseline = 1;
2440
Joe Hershberger05622192011-10-18 10:06:59 +00002441 sanitise_line_reset();
2442 my $line;
2443 foreach my $rawline (@rawlines) {
2444 $linenr++;
2445 $line = $rawline;
2446
Tom Rini6b9709d2014-02-27 08:27:28 -05002447 push(@fixed, $rawline) if ($fix);
2448
Joe Hershberger05622192011-10-18 10:06:59 +00002449 if ($rawline=~/^\+\+\+\s+(\S+)/) {
2450 $setup_docs = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002451 if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
Joe Hershberger05622192011-10-18 10:06:59 +00002452 $setup_docs = 1;
2453 }
2454 #next;
2455 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002456 if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
Joe Hershberger05622192011-10-18 10:06:59 +00002457 $realline=$1-1;
2458 if (defined $2) {
2459 $realcnt=$3+1;
2460 } else {
2461 $realcnt=1+1;
2462 }
2463 $in_comment = 0;
2464
2465 # Guestimate if this is a continuing comment. Run
2466 # the context looking for a comment "edge". If this
2467 # edge is a close comment then we must be in a comment
2468 # at context start.
2469 my $edge;
2470 my $cnt = $realcnt;
2471 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
2472 next if (defined $rawlines[$ln - 1] &&
2473 $rawlines[$ln - 1] =~ /^-/);
2474 $cnt--;
2475 #print "RAW<$rawlines[$ln - 1]>\n";
2476 last if (!defined $rawlines[$ln - 1]);
2477 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2478 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2479 ($edge) = $1;
2480 last;
2481 }
2482 }
2483 if (defined $edge && $edge eq '*/') {
2484 $in_comment = 1;
2485 }
2486
2487 # Guestimate if this is a continuing comment. If this
2488 # is the start of a diff block and this line starts
2489 # ' *' then it is very likely a comment.
2490 if (!defined $edge &&
2491 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2492 {
2493 $in_comment = 1;
2494 }
2495
2496 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2497 sanitise_line_reset($in_comment);
2498
2499 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2500 # Standardise the strings and chars within the input to
2501 # simplify matching -- only bother with positive lines.
2502 $line = sanitise_line($rawline);
2503 }
2504 push(@lines, $line);
2505
2506 if ($realcnt > 1) {
2507 $realcnt-- if ($line =~ /^(?:\+| |$)/);
2508 } else {
2509 $realcnt = 0;
2510 }
2511
2512 #print "==>$rawline\n";
2513 #print "-->$line\n";
2514
2515 if ($setup_docs && $line =~ /^\+/) {
2516 push(@setup_docs, $line);
2517 }
2518 }
2519
2520 $prefix = '';
2521
2522 $realcnt = 0;
2523 $linenr = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002524 $fixlinenr = -1;
Joe Hershberger05622192011-10-18 10:06:59 +00002525 foreach my $line (@lines) {
2526 $linenr++;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002527 $fixlinenr++;
Tom Rini6b9709d2014-02-27 08:27:28 -05002528 my $sline = $line; #copy of $line
2529 $sline =~ s/$;/ /g; #with comments as spaces
Joe Hershberger05622192011-10-18 10:06:59 +00002530
2531 my $rawline = $rawlines[$linenr - 1];
Tom Rinic57383b2020-06-16 10:29:46 -04002532 my $raw_comment = get_raw_comment($line, $rawline);
Joe Hershberger05622192011-10-18 10:06:59 +00002533
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002534# check if it's a mode change, rename or start of a patch
2535 if (!$in_commit_log &&
2536 ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
2537 ($line =~ /^rename (?:from|to) \S+\s*$/ ||
2538 $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
2539 $is_patch = 1;
2540 }
2541
Joe Hershberger05622192011-10-18 10:06:59 +00002542#extract the line range in the file after the patch is applied
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002543 if (!$in_commit_log &&
2544 $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2545 my $context = $4;
Joe Hershberger05622192011-10-18 10:06:59 +00002546 $is_patch = 1;
2547 $first_line = $linenr + 1;
2548 $realline=$1-1;
2549 if (defined $2) {
2550 $realcnt=$3+1;
2551 } else {
2552 $realcnt=1+1;
2553 }
2554 annotate_reset();
2555 $prev_values = 'E';
2556
2557 %suppress_ifbraces = ();
2558 %suppress_whiletrailers = ();
2559 %suppress_export = ();
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002560 $suppress_statement = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002561 if ($context =~ /\b(\w+)\s*\(/) {
2562 $context_function = $1;
2563 } else {
2564 undef $context_function;
2565 }
Joe Hershberger05622192011-10-18 10:06:59 +00002566 next;
2567
2568# track the line number as we move through the hunk, note that
2569# new versions of GNU diff omit the leading space on completely
2570# blank context lines so we need to count that too.
2571 } elsif ($line =~ /^( |\+|$)/) {
2572 $realline++;
2573 $realcnt-- if ($realcnt != 0);
2574
2575 # Measure the line length and indent.
2576 ($length, $indent) = line_stats($rawline);
2577
2578 # Track the previous line.
2579 ($prevline, $stashline) = ($stashline, $line);
2580 ($previndent, $stashindent) = ($stashindent, $indent);
2581 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2582
2583 #warn "line<$line>\n";
2584
2585 } elsif ($realcnt == 1) {
2586 $realcnt--;
2587 }
2588
2589 my $hunk_line = ($realcnt != 0);
2590
Joe Hershberger05622192011-10-18 10:06:59 +00002591 $here = "#$linenr: " if (!$file);
2592 $here = "#$realline: " if ($file);
2593
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002594 my $found_file = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00002595 # extract the filename as it passes
2596 if ($line =~ /^diff --git.*?(\S+)$/) {
2597 $realfile = $1;
Tom Rini6b9709d2014-02-27 08:27:28 -05002598 $realfile =~ s@^([^/]*)/@@ if (!$file);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002599 $in_commit_log = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002600 $found_file = 1;
Joe Hershberger05622192011-10-18 10:06:59 +00002601 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2602 $realfile = $1;
Tom Rini6b9709d2014-02-27 08:27:28 -05002603 $realfile =~ s@^([^/]*)/@@ if (!$file);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002604 $in_commit_log = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00002605
2606 $p1_prefix = $1;
2607 if (!$file && $tree && $p1_prefix ne '' &&
2608 -e "$root/$p1_prefix") {
2609 WARN("PATCH_PREFIX",
2610 "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
2611 }
2612
2613 if ($realfile =~ m@^include/asm/@) {
2614 ERROR("MODIFIED_INCLUDE_ASM",
2615 "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2616 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002617 $found_file = 1;
2618 }
2619
2620#make up the handle for any error we report on this line
2621 if ($showfile) {
2622 $prefix = "$realfile:$realline: "
2623 } elsif ($emacs) {
2624 if ($file) {
2625 $prefix = "$filename:$realline: ";
2626 } else {
2627 $prefix = "$filename:$linenr: ";
2628 }
2629 }
2630
2631 if ($found_file) {
2632 if (is_maintained_obsolete($realfile)) {
2633 WARN("OBSOLETE",
2634 "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
2635 }
2636 if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
2637 $check = 1;
2638 } else {
2639 $check = $check_orig;
2640 }
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02002641 $checklicenseline = 1;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002642
2643 if ($realfile !~ /^MAINTAINERS/) {
2644 my $last_binding_patch = $is_binding_patch;
2645
2646 $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2647
2648 if (($last_binding_patch != -1) &&
2649 ($last_binding_patch ^ $is_binding_patch)) {
2650 WARN("DT_SPLIT_BINDING_PATCH",
2651 "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
2652 }
2653 }
2654
Joe Hershberger05622192011-10-18 10:06:59 +00002655 next;
2656 }
2657
2658 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
2659
2660 my $hereline = "$here\n$rawline\n";
2661 my $herecurr = "$here\n$rawline\n";
2662 my $hereprev = "$here\n$prevrawline\n$rawline\n";
2663
2664 $cnt_lines++ if ($realcnt != 0);
2665
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002666# Verify the existence of a commit log if appropriate
2667# 2 is used because a $signature is counted in $commit_log_lines
2668 if ($in_commit_log) {
2669 if ($line !~ /^\s*$/) {
2670 $commit_log_lines++; #could be a $signature
2671 }
2672 } elsif ($has_commit_log && $commit_log_lines < 2) {
2673 WARN("COMMIT_MESSAGE",
2674 "Missing commit description - Add an appropriate one\n");
2675 $commit_log_lines = 2; #warn only once
2676 }
2677
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002678# Check if the commit log has what seems like a diff which can confuse patch
2679 if ($in_commit_log && !$commit_log_has_diff &&
2680 (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2681 $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2682 $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2683 $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2684 ERROR("DIFF_IN_COMMIT_MSG",
2685 "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2686 $commit_log_has_diff = 1;
2687 }
2688
Joe Hershberger05622192011-10-18 10:06:59 +00002689# Check for incorrect file permissions
2690 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
2691 my $permhere = $here . "FILE: $realfile\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05002692 if ($realfile !~ m@scripts/@ &&
2693 $realfile !~ /\.(py|pl|awk|sh)$/) {
Joe Hershberger05622192011-10-18 10:06:59 +00002694 ERROR("EXECUTE_PERMISSIONS",
2695 "do not set execute permissions for source files\n" . $permhere);
2696 }
2697 }
2698
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002699# Check the patch for a From:
2700 if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2701 $author = $1;
2702 $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2703 $author =~ s/"//g;
Tom Rinic57383b2020-06-16 10:29:46 -04002704 $author = reformat_email($author);
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002705 }
2706
Joe Hershberger05622192011-10-18 10:06:59 +00002707# Check the patch for a signoff:
Tom Rinic57383b2020-06-16 10:29:46 -04002708 if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
Joe Hershberger05622192011-10-18 10:06:59 +00002709 $signoff++;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002710 $in_commit_log = 0;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002711 if ($author ne '') {
Tom Rinic57383b2020-06-16 10:29:46 -04002712 if (same_email_addresses($1, $author)) {
2713 $authorsignoff = 1;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02002714 }
2715 }
Joe Hershberger05622192011-10-18 10:06:59 +00002716 }
2717
Tom Rinic57383b2020-06-16 10:29:46 -04002718# Check for patch separator
2719 if ($line =~ /^---$/) {
2720 $has_patch_separator = 1;
2721 $in_commit_log = 0;
2722 }
2723
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002724# Check if MAINTAINERS is being updated. If so, there's probably no need to
2725# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2726 if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2727 $reported_maintainer_file = 1;
2728 }
2729
Joe Hershberger05622192011-10-18 10:06:59 +00002730# Check signature styles
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002731 if (!$in_header_lines &&
2732 $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
Joe Hershberger05622192011-10-18 10:06:59 +00002733 my $space_before = $1;
2734 my $sign_off = $2;
2735 my $space_after = $3;
2736 my $email = $4;
2737 my $ucfirst_sign_off = ucfirst(lc($sign_off));
2738
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002739 if ($sign_off !~ /$signature_tags/) {
2740 WARN("BAD_SIGN_OFF",
2741 "Non-standard signature: $sign_off\n" . $herecurr);
2742 }
Joe Hershberger05622192011-10-18 10:06:59 +00002743 if (defined $space_before && $space_before ne "") {
Tom Rini6b9709d2014-02-27 08:27:28 -05002744 if (WARN("BAD_SIGN_OFF",
2745 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
2746 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002747 $fixed[$fixlinenr] =
Tom Rini6b9709d2014-02-27 08:27:28 -05002748 "$ucfirst_sign_off $email";
2749 }
Joe Hershberger05622192011-10-18 10:06:59 +00002750 }
2751 if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
Tom Rini6b9709d2014-02-27 08:27:28 -05002752 if (WARN("BAD_SIGN_OFF",
2753 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
2754 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002755 $fixed[$fixlinenr] =
Tom Rini6b9709d2014-02-27 08:27:28 -05002756 "$ucfirst_sign_off $email";
2757 }
2758
Joe Hershberger05622192011-10-18 10:06:59 +00002759 }
2760 if (!defined $space_after || $space_after ne " ") {
Tom Rini6b9709d2014-02-27 08:27:28 -05002761 if (WARN("BAD_SIGN_OFF",
2762 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
2763 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002764 $fixed[$fixlinenr] =
Tom Rini6b9709d2014-02-27 08:27:28 -05002765 "$ucfirst_sign_off $email";
2766 }
Joe Hershberger05622192011-10-18 10:06:59 +00002767 }
2768
Tom Rinic57383b2020-06-16 10:29:46 -04002769 my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
Joe Hershberger05622192011-10-18 10:06:59 +00002770 my $suggested_email = format_email(($email_name, $email_address));
2771 if ($suggested_email eq "") {
2772 ERROR("BAD_SIGN_OFF",
2773 "Unrecognized email address: '$email'\n" . $herecurr);
2774 } else {
2775 my $dequoted = $suggested_email;
2776 $dequoted =~ s/^"//;
2777 $dequoted =~ s/" </ </;
2778 # Don't force email to have quotes
2779 # Allow just an angle bracketed address
Tom Rinic57383b2020-06-16 10:29:46 -04002780 if (!same_email_addresses($email, $suggested_email)) {
Joe Hershberger05622192011-10-18 10:06:59 +00002781 WARN("BAD_SIGN_OFF",
2782 "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
2783 }
2784 }
Tom Rini6b9709d2014-02-27 08:27:28 -05002785
2786# Check for duplicate signatures
2787 my $sig_nospace = $line;
2788 $sig_nospace =~ s/\s//g;
2789 $sig_nospace = lc($sig_nospace);
2790 if (defined $signatures{$sig_nospace}) {
2791 WARN("BAD_SIGN_OFF",
2792 "Duplicate signature\n" . $herecurr);
2793 } else {
2794 $signatures{$sig_nospace} = 1;
2795 }
Tom Rinic57383b2020-06-16 10:29:46 -04002796
2797# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
2798 if ($sign_off =~ /^co-developed-by:$/i) {
2799 if ($email eq $author) {
2800 WARN("BAD_SIGN_OFF",
2801 "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
2802 }
2803 if (!defined $lines[$linenr]) {
2804 WARN("BAD_SIGN_OFF",
2805 "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
2806 } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
2807 WARN("BAD_SIGN_OFF",
2808 "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
2809 } elsif ($1 ne $email) {
2810 WARN("BAD_SIGN_OFF",
2811 "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
2812 }
2813 }
Joe Hershberger05622192011-10-18 10:06:59 +00002814 }
2815
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002816# Check email subject for common tools that don't need to be mentioned
2817 if ($in_header_lines &&
2818 $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2819 WARN("EMAIL_SUBJECT",
2820 "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2821 }
2822
Tom Rinic57383b2020-06-16 10:29:46 -04002823# Check for Gerrit Change-Ids not in any patch context
2824 if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002825 ERROR("GERRIT_CHANGE_ID",
Tom Rinic57383b2020-06-16 10:29:46 -04002826 "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002827 }
2828
2829# Check if the commit log is in a possible stack dump
2830 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2831 ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2832 $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2833 # timestamp
Tom Rinic57383b2020-06-16 10:29:46 -04002834 $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
2835 $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
2836 $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
2837 # stack dump address styles
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002838 $commit_log_possible_stack_dump = 1;
2839 }
2840
2841# Check for line lengths > 75 in commit log, warn once
2842 if ($in_commit_log && !$commit_log_long_line &&
2843 length($line) > 75 &&
2844 !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2845 # file delta changes
2846 $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2847 # filename then :
2848 $line =~ /^\s*(?:Fixes:|Link:)/i ||
2849 # A Fixes: or Link: line
2850 $commit_log_possible_stack_dump)) {
2851 WARN("COMMIT_LOG_LONG_LINE",
2852 "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
2853 $commit_log_long_line = 1;
2854 }
2855
2856# Reset possible stack dump if a blank line is found
2857 if ($in_commit_log && $commit_log_possible_stack_dump &&
2858 $line =~ /^\s*$/) {
2859 $commit_log_possible_stack_dump = 0;
2860 }
2861
2862# Check for git id commit length and improperly formed commit descriptions
2863 if ($in_commit_log && !$commit_log_possible_stack_dump &&
Tom Rinic57383b2020-06-16 10:29:46 -04002864 $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002865 $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2866 ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2867 ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2868 $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2869 $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2870 my $init_char = "c";
2871 my $orig_commit = "";
2872 my $short = 1;
2873 my $long = 0;
2874 my $case = 1;
2875 my $space = 1;
2876 my $hasdesc = 0;
2877 my $hasparens = 0;
2878 my $id = '0123456789ab';
2879 my $orig_desc = "commit description";
2880 my $description = "";
2881
2882 if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2883 $init_char = $1;
2884 $orig_commit = lc($2);
2885 } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2886 $orig_commit = lc($1);
2887 }
2888
2889 $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
2890 $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
2891 $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
2892 $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
2893 if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
2894 $orig_desc = $1;
2895 $hasparens = 1;
2896 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
2897 defined $rawlines[$linenr] &&
2898 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
2899 $orig_desc = $1;
2900 $hasparens = 1;
2901 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2902 defined $rawlines[$linenr] &&
2903 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2904 $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2905 $orig_desc = $1;
2906 $rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2907 $orig_desc .= " " . $1;
2908 $hasparens = 1;
2909 }
2910
2911 ($id, $description) = git_commit_info($orig_commit,
2912 $id, $orig_desc);
2913
2914 if (defined($id) &&
2915 ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
2916 ERROR("GIT_COMMIT_ID",
2917 "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
2918 }
2919 }
2920
2921# Check for added, moved or deleted files
2922 if (!$reported_maintainer_file && !$in_commit_log &&
2923 ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
2924 $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
2925 ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
2926 (defined($1) || defined($2))))) {
2927 $is_patch = 1;
2928 $reported_maintainer_file = 1;
2929 WARN("FILE_PATH_CHANGES",
2930 "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
2931 }
2932
Tom Rinic57383b2020-06-16 10:29:46 -04002933# Check for adding new DT bindings not in schema format
2934 if (!$in_commit_log &&
2935 ($line =~ /^new file mode\s*\d+\s*$/) &&
2936 ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
2937 WARN("DT_SCHEMA_BINDING_PATCH",
2938 "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
2939 }
2940
Joe Hershberger05622192011-10-18 10:06:59 +00002941# Check for wrappage within a valid hunk of the file
2942 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2943 ERROR("CORRUPTED_PATCH",
2944 "patch seems to be corrupt (line wrapped?)\n" .
2945 $herecurr) if (!$emitted_corrupt++);
2946 }
2947
Joe Hershberger05622192011-10-18 10:06:59 +00002948# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2949 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2950 $rawline !~ m/^$UTF8*$/) {
2951 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2952
2953 my $blank = copy_spacing($rawline);
2954 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2955 my $hereptr = "$hereline$ptr\n";
2956
2957 CHK("INVALID_UTF8",
2958 "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
2959 }
2960
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002961# Check if it's the start of a commit log
2962# (not a header line and we haven't seen the patch filename)
2963 if ($in_header_lines && $realfile =~ /^$/ &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002964 !($rawline =~ /^\s+(?:\S|$)/ ||
2965 $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002966 $in_header_lines = 0;
2967 $in_commit_log = 1;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002968 $has_commit_log = 1;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002969 }
2970
2971# Check if there is UTF-8 in a commit log when a mail header has explicitly
2972# declined it, i.e defined some charset where it is missing.
2973 if ($in_header_lines &&
2974 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2975 $1 !~ /utf-8/i) {
2976 $non_utf8_charset = 1;
2977 }
2978
2979 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
2980 $rawline =~ /$NON_ASCII_UTF8/) {
2981 WARN("UTF8_BEFORE_PATCH",
2982 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
2983 }
2984
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02002985# Check for absolute kernel paths in commit message
2986 if ($tree && $in_commit_log) {
2987 while ($line =~ m{(?:^|\s)(/\S*)}g) {
2988 my $file = $1;
2989
2990 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2991 check_absolute_file($1, $herecurr)) {
2992 #
2993 } else {
2994 check_absolute_file($file, $herecurr);
2995 }
2996 }
2997 }
2998
Dan Murphyc10e0f52017-01-31 14:15:53 -06002999# Check for various typo / spelling mistakes
3000 if (defined($misspellings) &&
3001 ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
3002 while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
3003 my $typo = $1;
3004 my $typo_fix = $spelling_fix{lc($typo)};
3005 $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
3006 $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003007 my $msg_level = \&WARN;
3008 $msg_level = \&CHK if ($file);
3009 if (&{$msg_level}("TYPO_SPELLING",
3010 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
Dan Murphyc10e0f52017-01-31 14:15:53 -06003011 $fix) {
3012 $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
3013 }
3014 }
3015 }
3016
Tom Rinic57383b2020-06-16 10:29:46 -04003017# check for invalid commit id
3018 if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3019 my $id;
3020 my $description;
3021 ($id, $description) = git_commit_info($2, undef, undef);
3022 if (!defined($id)) {
3023 WARN("UNKNOWN_COMMIT_ID",
3024 "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3025 }
3026 }
3027
Joe Hershberger05622192011-10-18 10:06:59 +00003028# ignore non-hunk lines and lines being removed
3029 next if (!$hunk_line || $line =~ /^-/);
3030
3031#trailing whitespace
3032 if ($line =~ /^\+.*\015/) {
3033 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05003034 if (ERROR("DOS_LINE_ENDINGS",
3035 "DOS line endings\n" . $herevet) &&
3036 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003037 $fixed[$fixlinenr] =~ s/[\s\015]+$//;
Tom Rini6b9709d2014-02-27 08:27:28 -05003038 }
Joe Hershberger05622192011-10-18 10:06:59 +00003039 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
3040 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05003041 if (ERROR("TRAILING_WHITESPACE",
3042 "trailing whitespace\n" . $herevet) &&
3043 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003044 $fixed[$fixlinenr] =~ s/\s+$//;
Tom Rini6b9709d2014-02-27 08:27:28 -05003045 }
3046
Joe Hershberger05622192011-10-18 10:06:59 +00003047 $rpt_cleaners = 1;
3048 }
3049
Tom Rini6b9709d2014-02-27 08:27:28 -05003050# Check for FSF mailing addresses.
3051 if ($rawline =~ /\bwrite to the Free/i ||
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003052 $rawline =~ /\b675\s+Mass\s+Ave/i ||
Tom Rini6b9709d2014-02-27 08:27:28 -05003053 $rawline =~ /\b59\s+Temple\s+Pl/i ||
3054 $rawline =~ /\b51\s+Franklin\s+St/i) {
3055 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003056 my $msg_level = \&ERROR;
3057 $msg_level = \&CHK if ($file);
3058 &{$msg_level}("FSF_MAILING_ADDRESS",
3059 "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)
Tom Rini6b9709d2014-02-27 08:27:28 -05003060 }
3061
Joe Hershberger05622192011-10-18 10:06:59 +00003062# check for Kconfig help text having a real description
3063# Only applies when adding the entry originally, after that we do not have
3064# sufficient context to determine whether it is indeed long enough.
3065 if ($realfile =~ /Kconfig/ &&
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003066 # 'choice' is usually the last thing on the line (though
3067 # Kconfig supports named choices), so use a word boundary
3068 # (\b) rather than a whitespace character (\s)
3069 $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
Joe Hershberger05622192011-10-18 10:06:59 +00003070 my $length = 0;
3071 my $cnt = $realcnt;
3072 my $ln = $linenr + 1;
3073 my $f;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003074 my $is_start = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00003075 my $is_end = 0;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003076 for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
Joe Hershberger05622192011-10-18 10:06:59 +00003077 $f = $lines[$ln - 1];
3078 $cnt-- if ($lines[$ln - 1] !~ /^-/);
3079 $is_end = $lines[$ln - 1] =~ /^\+/;
Joe Hershberger05622192011-10-18 10:06:59 +00003080
3081 next if ($f =~ /^-/);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003082 last if (!$file && $f =~ /^\@\@/);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003083
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003084 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003085 $is_start = 1;
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003086 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
3087 if ($lines[$ln - 1] =~ "---help---") {
3088 WARN("CONFIG_DESCRIPTION",
3089 "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
3090 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003091 $length = -1;
3092 }
3093
Joe Hershberger05622192011-10-18 10:06:59 +00003094 $f =~ s/^.//;
3095 $f =~ s/#.*//;
3096 $f =~ s/^\s+//;
3097 next if ($f =~ /^$/);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003098
3099 # This only checks context lines in the patch
3100 # and so hopefully shouldn't trigger false
3101 # positives, even though some of these are
3102 # common words in help texts
3103 if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3104 if|endif|menu|endmenu|source)\b/x) {
Joe Hershberger05622192011-10-18 10:06:59 +00003105 $is_end = 1;
3106 last;
3107 }
3108 $length++;
3109 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003110 if ($is_start && $is_end && $length < $min_conf_desc_length) {
3111 WARN("CONFIG_DESCRIPTION",
3112 "please write a paragraph that describes the config symbol fully\n" . $herecurr);
3113 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003114 #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
3115 }
3116
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003117# check for MAINTAINERS entries that don't have the right form
3118 if ($realfile =~ /^MAINTAINERS$/ &&
3119 $rawline =~ /^\+[A-Z]:/ &&
3120 $rawline !~ /^\+[A-Z]:\t\S/) {
3121 if (WARN("MAINTAINERS_STYLE",
3122 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3123 $fix) {
3124 $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3125 }
3126 }
3127
3128# discourage the use of boolean for type definition attributes of Kconfig options
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003129 if ($realfile =~ /Kconfig/ &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003130 $line =~ /^\+\s*\bboolean\b/) {
3131 WARN("CONFIG_TYPE_BOOLEAN",
3132 "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003133 }
3134
3135 if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3136 ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3137 my $flag = $1;
3138 my $replacement = {
3139 'EXTRA_AFLAGS' => 'asflags-y',
3140 'EXTRA_CFLAGS' => 'ccflags-y',
3141 'EXTRA_CPPFLAGS' => 'cppflags-y',
3142 'EXTRA_LDFLAGS' => 'ldflags-y',
3143 };
3144
3145 WARN("DEPRECATED_VARIABLE",
3146 "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
Joe Hershberger05622192011-10-18 10:06:59 +00003147 }
3148
Tom Rini6b9709d2014-02-27 08:27:28 -05003149# check for DT compatible documentation
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003150 if (defined $root &&
3151 (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
3152 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
3153
Tom Rini6b9709d2014-02-27 08:27:28 -05003154 my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3155
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003156 my $dt_path = $root . "/Documentation/devicetree/bindings/";
Tom Rinic57383b2020-06-16 10:29:46 -04003157 my $vp_file = $dt_path . "vendor-prefixes.yaml";
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003158
Tom Rini6b9709d2014-02-27 08:27:28 -05003159 foreach my $compat (@compats) {
3160 my $compat2 = $compat;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003161 $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3162 my $compat3 = $compat;
3163 $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3164 `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
Tom Rini6b9709d2014-02-27 08:27:28 -05003165 if ( $? >> 8 ) {
3166 WARN("UNDOCUMENTED_DT_STRING",
3167 "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3168 }
3169
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003170 next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
3171 my $vendor = $1;
Tom Rinic57383b2020-06-16 10:29:46 -04003172 `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
Tom Rini6b9709d2014-02-27 08:27:28 -05003173 if ( $? >> 8 ) {
3174 WARN("UNDOCUMENTED_DT_STRING",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003175 "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
Tom Rini6b9709d2014-02-27 08:27:28 -05003176 }
3177 }
3178 }
3179
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003180# check for using SPDX license tag at beginning of files
3181 if ($realline == $checklicenseline) {
3182 if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
3183 $checklicenseline = 2;
3184 } elsif ($rawline =~ /^\+/) {
3185 my $comment = "";
3186 if ($realfile =~ /\.(h|s|S)$/) {
3187 $comment = '/*';
3188 } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
3189 $comment = '//';
Tom Rinic57383b2020-06-16 10:29:46 -04003190 } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003191 $comment = '#';
3192 } elsif ($realfile =~ /\.rst$/) {
3193 $comment = '..';
3194 }
3195
Tom Rinic57383b2020-06-16 10:29:46 -04003196# check SPDX comment style for .[chsS] files
3197 if ($realfile =~ /\.[chsS]$/ &&
3198 $rawline =~ /SPDX-License-Identifier:/ &&
3199 $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3200 WARN("SPDX_LICENSE_TAG",
3201 "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3202 }
3203
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003204 if ($comment !~ /^$/ &&
Tom Rinic57383b2020-06-16 10:29:46 -04003205 $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
3206 WARN("SPDX_LICENSE_TAG",
3207 "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02003208 } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
Tom Rinic57383b2020-06-16 10:29:46 -04003209 my $spdx_license = $1;
3210 if (!is_SPDX_License_valid($spdx_license)) {
3211 WARN("SPDX_LICENSE_TAG",
3212 "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3213 }
3214 if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
3215 not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
3216 my $msg_level = \&WARN;
3217 $msg_level = \&CHK if ($file);
3218 if (&{$msg_level}("SPDX_LICENSE_TAG",
3219
3220 "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
3221 $fix) {
3222 $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
3223 }
3224 }
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003225 }
3226 }
3227 }
3228
Joe Hershberger05622192011-10-18 10:06:59 +00003229# check we are in a valid source file if not then ignore this hunk
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003230 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
Joe Hershberger05622192011-10-18 10:06:59 +00003231
Tom Rinic57383b2020-06-16 10:29:46 -04003232# check for using SPDX-License-Identifier on the wrong line number
3233 if ($realline != $checklicenseline &&
3234 $rawline =~ /\bSPDX-License-Identifier:/ &&
3235 substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3236 WARN("SPDX_LICENSE_TAG",
3237 "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3238 }
3239
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003240# line length limit (with some exclusions)
3241#
3242# There are a few types of lines that may extend beyond $max_line_length:
3243# logging functions like pr_info that end in a string
3244# lines with a single string
3245# #defines that are a single string
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003246# lines with an RFC3986 like URL
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003247#
3248# There are 3 different line length message types:
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003249# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003250# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
3251# LONG_LINE all other lines longer than $max_line_length
3252#
3253# if LONG_LINE is ignored, the other 2 types are also ignored
3254#
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003255
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003256 if ($line =~ /^\+/ && $length > $max_line_length) {
3257 my $msg_type = "LONG_LINE";
Joe Hershberger05622192011-10-18 10:06:59 +00003258
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003259 # Check the allowed long line types first
3260
3261 # logging functions that end in a string that starts
3262 # before $max_line_length
3263 if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
3264 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3265 $msg_type = "";
3266
3267 # lines with only strings (w/ possible termination)
3268 # #defines with only strings
3269 } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
3270 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
3271 $msg_type = "";
3272
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003273 # More special cases
3274 } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3275 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3276 $msg_type = "";
3277
3278 # URL ($rawline is used in case the URL is in a comment)
3279 } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003280 $msg_type = "";
3281
3282 # Otherwise set the alternate message types
3283
3284 # a comment starts before $max_line_length
3285 } elsif ($line =~ /($;[\s$;]*)$/ &&
3286 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3287 $msg_type = "LONG_LINE_COMMENT"
3288
3289 # a quoted string starts before $max_line_length
3290 } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
3291 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3292 $msg_type = "LONG_LINE_STRING"
Tom Rini6b9709d2014-02-27 08:27:28 -05003293 }
3294
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003295 if ($msg_type ne "" &&
3296 (show_type("LONG_LINE") || show_type($msg_type))) {
Simon Glass048a6482020-05-22 16:32:35 -06003297 my $msg_level = \&WARN;
3298 $msg_level = \&CHK if ($file);
3299 &{$msg_level}($msg_type,
3300 "line length of $length exceeds $max_line_length columns\n" . $herecurr);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003301 }
Joe Hershberger05622192011-10-18 10:06:59 +00003302 }
3303
3304# check for adding lines without a newline.
3305 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
3306 WARN("MISSING_EOF_NEWLINE",
3307 "adding a line without newline at end of file\n" . $herecurr);
3308 }
3309
Simon Glassb77df592020-05-22 16:32:36 -06003310 if ($u_boot) {
Simon Glass23552ba2020-07-19 10:16:01 -06003311 u_boot_line($realfile, $line, $rawline, $herecurr);
Simon Glassb77df592020-05-22 16:32:36 -06003312 }
3313
Joe Hershberger05622192011-10-18 10:06:59 +00003314# check we are in a valid source file C or perl if not then ignore this hunk
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003315 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
Joe Hershberger05622192011-10-18 10:06:59 +00003316
3317# at the beginning of a line any tabs must come first and anything
Tom Rinic57383b2020-06-16 10:29:46 -04003318# more than $tabsize must use tabs.
Joe Hershberger05622192011-10-18 10:06:59 +00003319 if ($rawline =~ /^\+\s* \t\s*\S/ ||
3320 $rawline =~ /^\+\s* \s*/) {
3321 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Joe Hershberger05622192011-10-18 10:06:59 +00003322 $rpt_cleaners = 1;
Tom Rini6b9709d2014-02-27 08:27:28 -05003323 if (ERROR("CODE_INDENT",
3324 "code indent should use tabs where possible\n" . $herevet) &&
3325 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003326 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
Tom Rini6b9709d2014-02-27 08:27:28 -05003327 }
Joe Hershberger05622192011-10-18 10:06:59 +00003328 }
3329
3330# check for space before tabs.
3331 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
3332 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05003333 if (WARN("SPACE_BEFORE_TAB",
3334 "please, no space before tabs\n" . $herevet) &&
3335 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003336 while ($fixed[$fixlinenr] =~
Tom Rinic57383b2020-06-16 10:29:46 -04003337 s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003338 while ($fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05003339 s/(^\+.*) +\t/$1\t/) {}
3340 }
Joe Hershberger05622192011-10-18 10:06:59 +00003341 }
3342
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02003343# check for assignments on the start of a line
3344 if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3345 CHK("ASSIGNMENT_CONTINUATIONS",
3346 "Assignment operator '$1' should be on the previous line\n" . $hereprev);
3347 }
3348
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003349# check for && or || at the start of a line
3350 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
3351 CHK("LOGICAL_CONTINUATIONS",
3352 "Logical continuations should be on the previous line\n" . $hereprev);
3353 }
3354
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003355# check indentation starts on a tab stop
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02003356 if ($perl_version_ok &&
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003357 $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003358 my $indent = length($1);
Tom Rinic57383b2020-06-16 10:29:46 -04003359 if ($indent % $tabsize) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003360 if (WARN("TABSTOP",
3361 "Statements should start on a tabstop\n" . $herecurr) &&
3362 $fix) {
Tom Rinic57383b2020-06-16 10:29:46 -04003363 $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003364 }
3365 }
3366 }
3367
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003368# check multi-line statement indentation matches previous line
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02003369 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003370 $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003371 $prevline =~ /^\+(\t*)(.*)$/;
3372 my $oldindent = $1;
3373 my $rest = $2;
3374
3375 my $pos = pos_last_openparen($rest);
3376 if ($pos >= 0) {
3377 $line =~ /^(\+| )([ \t]*)/;
3378 my $newindent = $2;
3379
3380 my $goodtabindent = $oldindent .
Tom Rinic57383b2020-06-16 10:29:46 -04003381 "\t" x ($pos / $tabsize) .
3382 " " x ($pos % $tabsize);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003383 my $goodspaceindent = $oldindent . " " x $pos;
3384
3385 if ($newindent ne $goodtabindent &&
3386 $newindent ne $goodspaceindent) {
Tom Rini6b9709d2014-02-27 08:27:28 -05003387
3388 if (CHK("PARENTHESIS_ALIGNMENT",
3389 "Alignment should match open parenthesis\n" . $hereprev) &&
3390 $fix && $line =~ /^\+/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003391 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05003392 s/^\+[ \t]*/\+$goodtabindent/;
3393 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003394 }
3395 }
3396 }
3397
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003398# check for space after cast like "(int) foo" or "(struct foo) bar"
3399# avoid checking a few false positives:
3400# "sizeof(<type>)" or "__alignof__(<type>)"
3401# function pointer declarations like "(*foo)(int) = bar;"
3402# structure definitions like "(struct foo) { 0 };"
3403# multiline macros that define functions
3404# known attributes or the __attribute__ keyword
3405 if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
3406 (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
Tom Rini6b9709d2014-02-27 08:27:28 -05003407 if (CHK("SPACING",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003408 "No space is necessary after a cast\n" . $herecurr) &&
Tom Rini6b9709d2014-02-27 08:27:28 -05003409 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003410 $fixed[$fixlinenr] =~
3411 s/(\(\s*$Type\s*\))[ \t]+/$1/;
Tom Rini6b9709d2014-02-27 08:27:28 -05003412 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003413 }
3414
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003415# Block comment styles
3416# Networking with an initial /*
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003417 if ($realfile =~ m@^(drivers/net/|net/)@ &&
Tom Rini6b9709d2014-02-27 08:27:28 -05003418 $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003419 $rawline =~ /^\+[ \t]*\*/ &&
3420 $realline > 2) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003421 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
3422 "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
3423 }
3424
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003425# Block comments use * on subsequent lines
3426 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3427 $prevrawline =~ /^\+.*?\/\*/ && #starting /*
Tom Rini6b9709d2014-02-27 08:27:28 -05003428 $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
3429 $rawline =~ /^\+/ && #line is new
3430 $rawline !~ /^\+[ \t]*\*/) { #no leading *
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003431 WARN("BLOCK_COMMENT_STYLE",
3432 "Block comments use * on subsequent lines\n" . $hereprev);
Tom Rini6b9709d2014-02-27 08:27:28 -05003433 }
3434
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003435# Block comments use */ on trailing lines
3436 if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003437 $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
3438 $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/
3439 $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003440 WARN("BLOCK_COMMENT_STYLE",
3441 "Block comments use a trailing */ on a separate line\n" . $herecurr);
3442 }
3443
3444# Block comment * alignment
3445 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3446 $line =~ /^\+[ \t]*$;/ && #leading comment
3447 $rawline =~ /^\+[ \t]*\*/ && #leading *
3448 (($prevrawline =~ /^\+.*?\/\*/ && #leading /*
3449 $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */
3450 $prevrawline =~ /^\+[ \t]*\*/)) { #leading *
3451 my $oldindent;
3452 $prevrawline =~ m@^\+([ \t]*/?)\*@;
3453 if (defined($1)) {
3454 $oldindent = expand_tabs($1);
3455 } else {
3456 $prevrawline =~ m@^\+(.*/?)\*@;
3457 $oldindent = expand_tabs($1);
3458 }
3459 $rawline =~ m@^\+([ \t]*)\*@;
3460 my $newindent = $1;
3461 $newindent = expand_tabs($newindent);
3462 if (length($oldindent) ne length($newindent)) {
3463 WARN("BLOCK_COMMENT_STYLE",
3464 "Block comments should align the * on each line\n" . $hereprev);
3465 }
3466 }
3467
3468# check for missing blank lines after struct/union declarations
3469# with exceptions for various attributes and macros
3470 if ($prevline =~ /^[\+ ]};?\s*$/ &&
3471 $line =~ /^\+/ &&
3472 !($line =~ /^\+\s*$/ ||
3473 $line =~ /^\+\s*EXPORT_SYMBOL/ ||
3474 $line =~ /^\+\s*MODULE_/i ||
3475 $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
3476 $line =~ /^\+[a-z_]*init/ ||
3477 $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
3478 $line =~ /^\+\s*DECLARE/ ||
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003479 $line =~ /^\+\s*builtin_[\w_]*driver/ ||
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003480 $line =~ /^\+\s*__setup/)) {
3481 if (CHK("LINE_SPACING",
3482 "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3483 $fix) {
3484 fix_insert_line($fixlinenr, "\+");
3485 }
3486 }
3487
3488# check for multiple consecutive blank lines
3489 if ($prevline =~ /^[\+ ]\s*$/ &&
3490 $line =~ /^\+\s*$/ &&
3491 $last_blank_line != ($linenr - 1)) {
3492 if (CHK("LINE_SPACING",
3493 "Please don't use multiple blank lines\n" . $hereprev) &&
3494 $fix) {
3495 fix_delete_line($fixlinenr, $rawline);
3496 }
3497
3498 $last_blank_line = $linenr;
3499 }
3500
3501# check for missing blank lines after declarations
3502 if ($sline =~ /^\+\s+\S/ && #Not at char 1
3503 # actual declarations
3504 ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
3505 # function pointer declarations
3506 $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
3507 # foo bar; where foo is some local typedef or #define
3508 $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
3509 # known declaration macros
3510 $prevline =~ /^\+\s+$declaration_macros/) &&
3511 # for "else if" which can look like "$Ident $Ident"
3512 !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
3513 # other possible extensions of declaration lines
3514 $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
3515 # not starting a section or a macro "\" extended line
3516 $prevline =~ /(?:\{\s*|\\)$/) &&
3517 # looks like a declaration
3518 !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
3519 # function pointer declarations
3520 $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
3521 # foo bar; where foo is some local typedef or #define
3522 $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
3523 # known declaration macros
3524 $sline =~ /^\+\s+$declaration_macros/ ||
3525 # start of struct or union or enum
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02003526 $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003527 # start or end of block or continuation of declaration
3528 $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
3529 # bitfield continuation
3530 $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
3531 # other possible extensions of declaration lines
3532 $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
3533 # indentation of previous and current line are the same
3534 (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3535 if (WARN("LINE_SPACING",
3536 "Missing a blank line after declarations\n" . $hereprev) &&
3537 $fix) {
3538 fix_insert_line($fixlinenr, "\+");
3539 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003540 }
3541
Joe Hershberger05622192011-10-18 10:06:59 +00003542# check for spaces at the beginning of a line.
3543# Exceptions:
3544# 1) within comments
3545# 2) indented preprocessor commands
3546# 3) hanging labels
Tom Rini6b9709d2014-02-27 08:27:28 -05003547 if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
Joe Hershberger05622192011-10-18 10:06:59 +00003548 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05003549 if (WARN("LEADING_SPACE",
3550 "please, no spaces at the start of a line\n" . $herevet) &&
3551 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003552 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
Tom Rini6b9709d2014-02-27 08:27:28 -05003553 }
Joe Hershberger05622192011-10-18 10:06:59 +00003554 }
3555
3556# check we are in a valid C source file if not then ignore this hunk
3557 next if ($realfile !~ /\.(h|c)$/);
3558
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02003559# check for unusual line ending [ or (
3560 if ($line =~ /^\+.*([\[\(])\s*$/) {
3561 CHK("OPEN_ENDED_LINE",
3562 "Lines should not end with a '$1'\n" . $herecurr);
3563 }
3564
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003565# check if this appears to be the start function declaration, save the name
3566 if ($sline =~ /^\+\{\s*$/ &&
3567 $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
3568 $context_function = $1;
3569 }
3570
3571# check if this appears to be the end of function declaration
3572 if ($sline =~ /^\+\}\s*$/) {
3573 undef $context_function;
3574 }
3575
3576# check indentation of any line with a bare else
3577# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3578# if the previous line is a break or return and is indented 1 tab more...
3579 if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3580 my $tabs = length($1) + 1;
3581 if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3582 ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3583 defined $lines[$linenr] &&
3584 $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3585 WARN("UNNECESSARY_ELSE",
3586 "else is not generally useful after a break or return\n" . $hereprev);
3587 }
3588 }
3589
3590# check indentation of a line with a break;
3591# if the previous line is a goto or return and is indented the same # of tabs
3592 if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3593 my $tabs = $1;
3594 if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3595 WARN("UNNECESSARY_BREAK",
3596 "break is not useful after a goto or return\n" . $hereprev);
3597 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003598 }
3599
Joe Hershberger05622192011-10-18 10:06:59 +00003600# check for RCS/CVS revision markers
3601 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3602 WARN("CVS_KEYWORD",
3603 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3604 }
3605
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003606# check for old HOTPLUG __dev<foo> section markings
3607 if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
3608 WARN("HOTPLUG_SECTION",
3609 "Using $1 is unnecessary\n" . $herecurr);
3610 }
3611
Joe Hershberger05622192011-10-18 10:06:59 +00003612# Check for potential 'bare' types
3613 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
3614 $realline_next);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003615#print "LINE<$line>\n";
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003616 if ($linenr > $suppress_statement &&
Tom Rini6b9709d2014-02-27 08:27:28 -05003617 $realcnt && $sline =~ /.\s*\S/) {
Joe Hershberger05622192011-10-18 10:06:59 +00003618 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3619 ctx_statement_block($linenr, $realcnt, 0);
3620 $stat =~ s/\n./\n /g;
3621 $cond =~ s/\n./\n /g;
3622
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003623#print "linenr<$linenr> <$stat>\n";
3624 # If this statement has no statement boundaries within
3625 # it there is no point in retrying a statement scan
3626 # until we hit end of it.
3627 my $frag = $stat; $frag =~ s/;+\s*$//;
3628 if ($frag !~ /(?:{|;)/) {
3629#print "skip<$line_nr_next>\n";
3630 $suppress_statement = $line_nr_next;
3631 }
3632
Joe Hershberger05622192011-10-18 10:06:59 +00003633 # Find the real next line.
3634 $realline_next = $line_nr_next;
3635 if (defined $realline_next &&
3636 (!defined $lines[$realline_next - 1] ||
3637 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
3638 $realline_next++;
3639 }
3640
3641 my $s = $stat;
3642 $s =~ s/{.*$//s;
3643
3644 # Ignore goto labels.
3645 if ($s =~ /$Ident:\*$/s) {
3646
3647 # Ignore functions being called
3648 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3649
3650 } elsif ($s =~ /^.\s*else\b/s) {
3651
3652 # declarations always start with types
3653 } 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) {
3654 my $type = $1;
3655 $type =~ s/\s+/ /g;
3656 possible($type, "A:" . $s);
3657
3658 # definitions in global scope can only start with types
3659 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3660 possible($1, "B:" . $s);
3661 }
3662
3663 # any (foo ... *) is a pointer cast, and foo is a type
3664 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3665 possible($1, "C:" . $s);
3666 }
3667
3668 # Check for any sort of function declaration.
3669 # int foo(something bar, other baz);
3670 # void (*store_gdt)(x86_descr_ptr *);
3671 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
3672 my ($name_len) = length($1);
3673
3674 my $ctx = $s;
3675 substr($ctx, 0, $name_len + 1, '');
3676 $ctx =~ s/\)[^\)]*$//;
3677
3678 for my $arg (split(/\s*,\s*/, $ctx)) {
3679 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
3680
3681 possible($1, "D:" . $s);
3682 }
3683 }
3684 }
3685
3686 }
3687
3688#
3689# Checks which may be anchored in the context.
3690#
3691
3692# Check for switch () and associated case and default
3693# statements should be at the same indent.
3694 if ($line=~/\bswitch\s*\(.*\)/) {
3695 my $err = '';
3696 my $sep = '';
3697 my @ctx = ctx_block_outer($linenr, $realcnt);
3698 shift(@ctx);
3699 for my $ctx (@ctx) {
3700 my ($clen, $cindent) = line_stats($ctx);
3701 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
3702 $indent != $cindent) {
3703 $err .= "$sep$ctx\n";
3704 $sep = '';
3705 } else {
3706 $sep = "[...]\n";
3707 }
3708 }
3709 if ($err ne '') {
3710 ERROR("SWITCH_CASE_INDENT_LEVEL",
3711 "switch and case should be at the same indent\n$hereline$err");
3712 }
3713 }
3714
3715# if/while/etc brace do not go on next line, unless defining a do while loop,
3716# or if that brace on the next line is for something else
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003717 if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
Joe Hershberger05622192011-10-18 10:06:59 +00003718 my $pre_ctx = "$1$2";
3719
3720 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003721
3722 if ($line =~ /^\+\t{6,}/) {
3723 WARN("DEEP_INDENTATION",
3724 "Too many leading tabs - consider code refactoring\n" . $herecurr);
3725 }
3726
Joe Hershberger05622192011-10-18 10:06:59 +00003727 my $ctx_cnt = $realcnt - $#ctx - 1;
3728 my $ctx = join("\n", @ctx);
3729
3730 my $ctx_ln = $linenr;
3731 my $ctx_skip = $realcnt;
3732
3733 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3734 defined $lines[$ctx_ln - 1] &&
3735 $lines[$ctx_ln - 1] =~ /^-/)) {
3736 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3737 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3738 $ctx_ln++;
3739 }
3740
3741 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
3742 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3743
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003744 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
Joe Hershberger05622192011-10-18 10:06:59 +00003745 ERROR("OPEN_BRACE",
3746 "that open brace { should be on the previous line\n" .
3747 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
3748 }
3749 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3750 $ctx =~ /\)\s*\;\s*$/ &&
3751 defined $lines[$ctx_ln - 1])
3752 {
3753 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
3754 if ($nindent > $indent) {
3755 WARN("TRAILING_SEMICOLON",
3756 "trailing semicolon indicates no statements, indent implies otherwise\n" .
3757 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
3758 }
3759 }
3760 }
3761
3762# Check relative indent for conditionals and blocks.
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003763 if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003764 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3765 ctx_statement_block($linenr, $realcnt, 0)
3766 if (!defined $stat);
Joe Hershberger05622192011-10-18 10:06:59 +00003767 my ($s, $c) = ($stat, $cond);
3768
3769 substr($s, 0, length($c), '');
3770
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003771 # remove inline comments
3772 $s =~ s/$;/ /g;
3773 $c =~ s/$;/ /g;
Joe Hershberger05622192011-10-18 10:06:59 +00003774
3775 # Find out how long the conditional actually is.
3776 my @newlines = ($c =~ /\n/gs);
3777 my $cond_lines = 1 + $#newlines;
3778
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003779 # Make sure we remove the line prefixes as we have
3780 # none on the first line, and are going to readd them
3781 # where necessary.
3782 $s =~ s/\n./\n/gs;
3783 while ($s =~ /\n\s+\\\n/) {
3784 $cond_lines += $s =~ s/\n\s+\\\n/\n/g;
3785 }
3786
Joe Hershberger05622192011-10-18 10:06:59 +00003787 # We want to check the first line inside the block
3788 # starting at the end of the conditional, so remove:
3789 # 1) any blank line termination
3790 # 2) any opening brace { on end of the line
3791 # 3) any do (...) {
3792 my $continuation = 0;
3793 my $check = 0;
3794 $s =~ s/^.*\bdo\b//;
3795 $s =~ s/^\s*{//;
3796 if ($s =~ s/^\s*\\//) {
3797 $continuation = 1;
3798 }
3799 if ($s =~ s/^\s*?\n//) {
3800 $check = 1;
3801 $cond_lines++;
3802 }
3803
3804 # Also ignore a loop construct at the end of a
3805 # preprocessor statement.
3806 if (($prevline =~ /^.\s*#\s*define\s/ ||
3807 $prevline =~ /\\\s*$/) && $continuation == 0) {
3808 $check = 0;
3809 }
3810
3811 my $cond_ptr = -1;
3812 $continuation = 0;
3813 while ($cond_ptr != $cond_lines) {
3814 $cond_ptr = $cond_lines;
3815
3816 # If we see an #else/#elif then the code
3817 # is not linear.
3818 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3819 $check = 0;
3820 }
3821
3822 # Ignore:
3823 # 1) blank lines, they should be at 0,
3824 # 2) preprocessor lines, and
3825 # 3) labels.
3826 if ($continuation ||
3827 $s =~ /^\s*?\n/ ||
3828 $s =~ /^\s*#\s*?/ ||
3829 $s =~ /^\s*$Ident\s*:/) {
3830 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
3831 if ($s =~ s/^.*?\n//) {
3832 $cond_lines++;
3833 }
3834 }
3835 }
3836
3837 my (undef, $sindent) = line_stats("+" . $s);
3838 my $stat_real = raw_line($linenr, $cond_lines);
3839
3840 # Check if either of these lines are modified, else
3841 # this is not this patch's fault.
3842 if (!defined($stat_real) ||
3843 $stat !~ /^\+/ && $stat_real !~ /^\+/) {
3844 $check = 0;
3845 }
3846 if (defined($stat_real) && $cond_lines > 1) {
3847 $stat_real = "[...]\n$stat_real";
3848 }
3849
3850 #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";
3851
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003852 if ($check && $s ne '' &&
Tom Rinic57383b2020-06-16 10:29:46 -04003853 (($sindent % $tabsize) != 0 ||
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003854 ($sindent < $indent) ||
3855 ($sindent == $indent &&
3856 ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
Tom Rinic57383b2020-06-16 10:29:46 -04003857 ($sindent > $indent + $tabsize))) {
Joe Hershberger05622192011-10-18 10:06:59 +00003858 WARN("SUSPECT_CODE_INDENT",
3859 "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
3860 }
3861 }
3862
3863 # Track the 'values' across context and added lines.
3864 my $opline = $line; $opline =~ s/^./ /;
3865 my ($curr_values, $curr_vars) =
3866 annotate_values($opline . "\n", $prev_values);
3867 $curr_values = $prev_values . $curr_values;
3868 if ($dbg_values) {
3869 my $outline = $opline; $outline =~ s/\t/ /g;
3870 print "$linenr > .$outline\n";
3871 print "$linenr > $curr_values\n";
3872 print "$linenr > $curr_vars\n";
3873 }
3874 $prev_values = substr($curr_values, -1);
3875
3876#ignore lines not being added
Tom Rini6b9709d2014-02-27 08:27:28 -05003877 next if ($line =~ /^[^\+]/);
Joe Hershberger05622192011-10-18 10:06:59 +00003878
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003879# check for dereferences that span multiple lines
3880 if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
3881 $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
3882 $prevline =~ /($Lval\s*(?:\.|->))\s*$/;
3883 my $ref = $1;
3884 $line =~ /^.\s*($Lval)/;
3885 $ref .= $1;
3886 $ref =~ s/\s//g;
3887 WARN("MULTILINE_DEREFERENCE",
3888 "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
3889 }
3890
3891# check for declarations of signed or unsigned without int
3892 while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3893 my $type = $1;
3894 my $var = $2;
3895 $var = "" if (!defined $var);
3896 if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3897 my $sign = $1;
3898 my $pointer = $2;
3899
3900 $pointer = "" if (!defined $pointer);
3901
3902 if (WARN("UNSPECIFIED_INT",
3903 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3904 $fix) {
3905 my $decl = trim($sign) . " int ";
3906 my $comp_pointer = $pointer;
3907 $comp_pointer =~ s/\s//g;
3908 $decl .= $comp_pointer;
3909 $decl = rtrim($decl) if ($var eq "");
3910 $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3911 }
3912 }
3913 }
3914
Joe Hershberger05622192011-10-18 10:06:59 +00003915# TEST: allow direct testing of the type matcher.
3916 if ($dbg_type) {
3917 if ($line =~ /^.\s*$Declare\s*$/) {
3918 ERROR("TEST_TYPE",
3919 "TEST: is type\n" . $herecurr);
3920 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3921 ERROR("TEST_NOT_TYPE",
3922 "TEST: is not type ($1 is)\n". $herecurr);
3923 }
3924 next;
3925 }
3926# TEST: allow direct testing of the attribute matcher.
3927 if ($dbg_attr) {
3928 if ($line =~ /^.\s*$Modifier\s*$/) {
3929 ERROR("TEST_ATTR",
3930 "TEST: is attr\n" . $herecurr);
3931 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3932 ERROR("TEST_NOT_ATTR",
3933 "TEST: is not attr ($1 is)\n". $herecurr);
3934 }
3935 next;
3936 }
3937
3938# check for initialisation to aggregates open brace on the next line
3939 if ($line =~ /^.\s*{/ &&
3940 $prevline =~ /(?:^|[^=])=\s*$/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003941 if (ERROR("OPEN_BRACE",
3942 "that open brace { should be on the previous line\n" . $hereprev) &&
3943 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3944 fix_delete_line($fixlinenr - 1, $prevrawline);
3945 fix_delete_line($fixlinenr, $rawline);
3946 my $fixedline = $prevrawline;
3947 $fixedline =~ s/\s*=\s*$/ = {/;
3948 fix_insert_line($fixlinenr, $fixedline);
3949 $fixedline = $line;
3950 $fixedline =~ s/^(.\s*)\{\s*/$1/;
3951 fix_insert_line($fixlinenr, $fixedline);
3952 }
Joe Hershberger05622192011-10-18 10:06:59 +00003953 }
3954
3955#
3956# Checks which are anchored on the added line.
3957#
3958
3959# check for malformed paths in #include statements (uses RAW line)
3960 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3961 my $path = $1;
3962 if ($path =~ m{//}) {
3963 ERROR("MALFORMED_INCLUDE",
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00003964 "malformed #include filename\n" . $herecurr);
3965 }
3966 if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3967 ERROR("UAPI_INCLUDE",
3968 "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00003969 }
3970 }
3971
3972# no C99 // comments
3973 if ($line =~ m{//}) {
Tom Rini6b9709d2014-02-27 08:27:28 -05003974 if (ERROR("C99_COMMENTS",
3975 "do not use C99 // comments\n" . $herecurr) &&
3976 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003977 my $line = $fixed[$fixlinenr];
Tom Rini6b9709d2014-02-27 08:27:28 -05003978 if ($line =~ /\/\/(.*)$/) {
3979 my $comment = trim($1);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02003980 $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
Tom Rini6b9709d2014-02-27 08:27:28 -05003981 }
3982 }
Joe Hershberger05622192011-10-18 10:06:59 +00003983 }
3984 # Remove C99 comments.
3985 $line =~ s@//.*@@;
3986 $opline =~ s@//.*@@;
3987
3988# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
3989# the whole statement.
3990#print "APW <$lines[$realline_next - 1]>\n";
3991 if (defined $realline_next &&
3992 exists $lines[$realline_next - 1] &&
3993 !defined $suppress_export{$realline_next} &&
3994 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
3995 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
3996 # Handle definitions which produce identifiers with
3997 # a prefix:
3998 # XXX(foo);
3999 # EXPORT_SYMBOL(something_foo);
4000 my $name = $1;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00004001 if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
Joe Hershberger05622192011-10-18 10:06:59 +00004002 $name =~ /^${Ident}_$2/) {
4003#print "FOO C name<$name>\n";
4004 $suppress_export{$realline_next} = 1;
4005
4006 } elsif ($stat !~ /(?:
4007 \n.}\s*$|
4008 ^.DEFINE_$Ident\(\Q$name\E\)|
4009 ^.DECLARE_$Ident\(\Q$name\E\)|
4010 ^.LIST_HEAD\(\Q$name\E\)|
4011 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
4012 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
4013 )/x) {
4014#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
4015 $suppress_export{$realline_next} = 2;
4016 } else {
4017 $suppress_export{$realline_next} = 1;
4018 }
4019 }
4020 if (!defined $suppress_export{$linenr} &&
4021 $prevline =~ /^.\s*$/ &&
4022 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
4023 $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
4024#print "FOO B <$lines[$linenr - 1]>\n";
4025 $suppress_export{$linenr} = 2;
4026 }
4027 if (defined $suppress_export{$linenr} &&
4028 $suppress_export{$linenr} == 2) {
4029 WARN("EXPORT_SYMBOL",
4030 "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
4031 }
4032
4033# check for global initialisers.
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004034 if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004035 if (ERROR("GLOBAL_INITIALISERS",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004036 "do not initialise globals to $1\n" . $herecurr) &&
Tom Rini6b9709d2014-02-27 08:27:28 -05004037 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004038 $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
Tom Rini6b9709d2014-02-27 08:27:28 -05004039 }
Joe Hershberger05622192011-10-18 10:06:59 +00004040 }
4041# check for static initialisers.
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004042 if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004043 if (ERROR("INITIALISED_STATIC",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004044 "do not initialise statics to $1\n" .
Tom Rini6b9709d2014-02-27 08:27:28 -05004045 $herecurr) &&
4046 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004047 $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
Tom Rini6b9709d2014-02-27 08:27:28 -05004048 }
Joe Hershberger05622192011-10-18 10:06:59 +00004049 }
4050
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004051# check for misordered declarations of char/short/int/long with signed/unsigned
4052 while ($sline =~ m{(\b$TypeMisordered\b)}g) {
4053 my $tmp = trim($1);
4054 WARN("MISORDERED_TYPE",
4055 "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
4056 }
4057
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004058# check for unnecessary <signed> int declarations of short/long/long long
4059 while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4060 my $type = trim($1);
4061 next if ($type !~ /\bint\b/);
4062 next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4063 my $new_type = $type;
4064 $new_type =~ s/\b\s*int\s*\b/ /;
4065 $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4066 $new_type =~ s/^const\s+//;
4067 $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4068 $new_type = "const $new_type" if ($type =~ /^const\b/);
4069 $new_type =~ s/\s+/ /g;
4070 $new_type = trim($new_type);
4071 if (WARN("UNNECESSARY_INT",
4072 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4073 $fix) {
4074 $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4075 }
4076 }
4077
Joe Hershberger05622192011-10-18 10:06:59 +00004078# check for static const char * arrays.
4079 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4080 WARN("STATIC_CONST_CHAR_ARRAY",
4081 "static const char * array should probably be static const char * const\n" .
4082 $herecurr);
Tom Rinic57383b2020-06-16 10:29:46 -04004083 }
4084
4085# check for initialized const char arrays that should be static const
4086 if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
4087 if (WARN("STATIC_CONST_CHAR_ARRAY",
4088 "const array should probably be static const\n" . $herecurr) &&
4089 $fix) {
4090 $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
4091 }
4092 }
Joe Hershberger05622192011-10-18 10:06:59 +00004093
4094# check for static char foo[] = "bar" declarations.
4095 if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4096 WARN("STATIC_CONST_CHAR_ARRAY",
4097 "static char array declaration should probably be static const char\n" .
4098 $herecurr);
Tom Rinic57383b2020-06-16 10:29:46 -04004099 }
Joe Hershberger05622192011-10-18 10:06:59 +00004100
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004101# check for const <foo> const where <foo> is not a pointer or array type
4102 if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4103 my $found = $1;
4104 if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4105 WARN("CONST_CONST",
4106 "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4107 } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4108 WARN("CONST_CONST",
4109 "'const $found const' should probably be 'const $found'\n" . $herecurr);
4110 }
4111 }
4112
4113# check for non-global char *foo[] = {"bar", ...} declarations.
4114 if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
4115 WARN("STATIC_CONST_CHAR_ARRAY",
4116 "char * array declaration might be better as static const\n" .
4117 $herecurr);
4118 }
4119
4120# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4121 if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4122 my $array = $1;
4123 if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
4124 my $array_div = $1;
4125 if (WARN("ARRAY_SIZE",
4126 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4127 $fix) {
4128 $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4129 }
4130 }
4131 }
4132
Tom Rini6b9709d2014-02-27 08:27:28 -05004133# check for function declarations without arguments like "int foo()"
Tom Rinic57383b2020-06-16 10:29:46 -04004134 if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004135 if (ERROR("FUNCTION_WITHOUT_ARGS",
4136 "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4137 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004138 $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
Tom Rini6b9709d2014-02-27 08:27:28 -05004139 }
Joe Hershberger05622192011-10-18 10:06:59 +00004140 }
4141
4142# check for new typedefs, only function parameters and sparse annotations
4143# make sense.
4144 if ($line =~ /\btypedef\s/ &&
4145 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4146 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
4147 $line !~ /\b$typeTypedefs\b/ &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004148 $line !~ /\b__bitwise\b/) {
Joe Hershberger05622192011-10-18 10:06:59 +00004149 WARN("NEW_TYPEDEFS",
4150 "do not add new typedefs\n" . $herecurr);
4151 }
4152
4153# * goes on variable not on type
4154 # (char*[ const])
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00004155 while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4156 #print "AA<$1>\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05004157 my ($ident, $from, $to) = ($1, $2, $2);
Joe Hershberger05622192011-10-18 10:06:59 +00004158
4159 # Should start with a space.
4160 $to =~ s/^(\S)/ $1/;
4161 # Should not end with a space.
4162 $to =~ s/\s+$//;
4163 # '*'s should not have spaces between.
4164 while ($to =~ s/\*\s+\*/\*\*/) {
4165 }
4166
Tom Rini6b9709d2014-02-27 08:27:28 -05004167## print "1: from<$from> to<$to> ident<$ident>\n";
Joe Hershberger05622192011-10-18 10:06:59 +00004168 if ($from ne $to) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004169 if (ERROR("POINTER_LOCATION",
4170 "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
4171 $fix) {
4172 my $sub_from = $ident;
4173 my $sub_to = $ident;
4174 $sub_to =~ s/\Q$from\E/$to/;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004175 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004176 s@\Q$sub_from\E@$sub_to@;
4177 }
Joe Hershberger05622192011-10-18 10:06:59 +00004178 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00004179 }
4180 while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4181 #print "BB<$1>\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05004182 my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
Joe Hershberger05622192011-10-18 10:06:59 +00004183
4184 # Should start with a space.
4185 $to =~ s/^(\S)/ $1/;
4186 # Should not end with a space.
4187 $to =~ s/\s+$//;
4188 # '*'s should not have spaces between.
4189 while ($to =~ s/\*\s+\*/\*\*/) {
4190 }
4191 # Modifiers should have spaces.
4192 $to =~ s/(\b$Modifier$)/$1 /;
4193
Tom Rini6b9709d2014-02-27 08:27:28 -05004194## print "2: from<$from> to<$to> ident<$ident>\n";
Joe Hershberger05622192011-10-18 10:06:59 +00004195 if ($from ne $to && $ident !~ /^$Modifier$/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004196 if (ERROR("POINTER_LOCATION",
4197 "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
4198 $fix) {
4199
4200 my $sub_from = $match;
4201 my $sub_to = $match;
4202 $sub_to =~ s/\Q$from\E/$to/;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004203 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004204 s@\Q$sub_from\E@$sub_to@;
4205 }
Joe Hershberger05622192011-10-18 10:06:59 +00004206 }
4207 }
4208
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004209# avoid BUG() or BUG_ON()
4210 if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02004211 my $msg_level = \&WARN;
4212 $msg_level = \&CHK if ($file);
4213 &{$msg_level}("AVOID_BUG",
4214 "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004215 }
Joe Hershberger05622192011-10-18 10:06:59 +00004216
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004217# avoid LINUX_VERSION_CODE
Joe Hershberger05622192011-10-18 10:06:59 +00004218 if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4219 WARN("LINUX_VERSION_CODE",
4220 "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
4221 }
4222
4223# check for uses of printk_ratelimit
4224 if ($line =~ /\bprintk_ratelimit\s*\(/) {
4225 WARN("PRINTK_RATELIMITED",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004226 "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00004227 }
4228
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02004229# printk should use KERN_* levels
4230 if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4231 WARN("PRINTK_WITHOUT_KERN_LEVEL",
4232 "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00004233 }
4234
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00004235 if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
4236 my $orig = $1;
4237 my $level = lc($orig);
4238 $level = "warn" if ($level eq "warning");
4239 my $level2 = $level;
4240 $level2 = "dbg" if ($level eq "debug");
4241 WARN("PREFER_PR_LEVEL",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004242 "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00004243 }
4244
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00004245 if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4246 my $orig = $1;
4247 my $level = lc($orig);
4248 $level = "warn" if ($level eq "warning");
4249 $level = "dbg" if ($level eq "debug");
4250 WARN("PREFER_DEV_LEVEL",
4251 "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4252 }
4253
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004254# ENOSYS means "bad syscall nr" and nothing else. This will have a small
4255# number of false positives, but assembly files are not checked, so at
4256# least the arch entry code will not trigger this warning.
4257 if ($line =~ /\bENOSYS\b/) {
4258 WARN("ENOSYS",
4259 "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
4260 }
4261
Joe Hershberger05622192011-10-18 10:06:59 +00004262# function brace can't be on same line, except for #defines of do while,
4263# or if closed on same line
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004264 if ($perl_version_ok &&
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02004265 $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
4266 $sline !~ /\#\s*define\b.*do\s*\{/ &&
4267 $sline !~ /}/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004268 if (ERROR("OPEN_BRACE",
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02004269 "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004270 $fix) {
4271 fix_delete_line($fixlinenr, $rawline);
4272 my $fixed_line = $rawline;
4273 $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
4274 my $line1 = $1;
4275 my $line2 = $2;
4276 fix_insert_line($fixlinenr, ltrim($line1));
4277 fix_insert_line($fixlinenr, "\+{");
4278 if ($line2 !~ /^\s*$/) {
4279 fix_insert_line($fixlinenr, "\+\t" . trim($line2));
4280 }
4281 }
Joe Hershberger05622192011-10-18 10:06:59 +00004282 }
4283
4284# open braces for enum, union and struct go on the same line.
4285 if ($line =~ /^.\s*{/ &&
4286 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004287 if (ERROR("OPEN_BRACE",
4288 "open brace '{' following $1 go on the same line\n" . $hereprev) &&
4289 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4290 fix_delete_line($fixlinenr - 1, $prevrawline);
4291 fix_delete_line($fixlinenr, $rawline);
4292 my $fixedline = rtrim($prevrawline) . " {";
4293 fix_insert_line($fixlinenr, $fixedline);
4294 $fixedline = $rawline;
4295 $fixedline =~ s/^(.\s*)\{\s*/$1\t/;
4296 if ($fixedline !~ /^\+\s*$/) {
4297 fix_insert_line($fixlinenr, $fixedline);
4298 }
4299 }
Joe Hershberger05622192011-10-18 10:06:59 +00004300 }
4301
4302# missing space after union, struct or enum definition
Tom Rini6b9709d2014-02-27 08:27:28 -05004303 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
4304 if (WARN("SPACING",
4305 "missing space after $1 definition\n" . $herecurr) &&
4306 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004307 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004308 s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
4309 }
4310 }
4311
4312# Function pointer declarations
4313# check spacing between type, funcptr, and args
4314# canonical declaration is "type (*funcptr)(args...)"
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004315 if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004316 my $declare = $1;
4317 my $pre_pointer_space = $2;
4318 my $post_pointer_space = $3;
4319 my $funcname = $4;
4320 my $post_funcname_space = $5;
4321 my $pre_args_space = $6;
4322
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004323# the $Declare variable will capture all spaces after the type
4324# so check it for a missing trailing missing space but pointer return types
4325# don't need a space so don't warn for those.
4326 my $post_declare_space = "";
4327 if ($declare =~ /(\s+)$/) {
4328 $post_declare_space = $1;
4329 $declare = rtrim($declare);
4330 }
4331 if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004332 WARN("SPACING",
4333 "missing space after return type\n" . $herecurr);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004334 $post_declare_space = " ";
Tom Rini6b9709d2014-02-27 08:27:28 -05004335 }
4336
4337# unnecessary space "type (*funcptr)(args...)"
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004338# This test is not currently implemented because these declarations are
4339# equivalent to
4340# int foo(int bar, ...)
4341# and this is form shouldn't/doesn't generate a checkpatch warning.
4342#
4343# elsif ($declare =~ /\s{2,}$/) {
4344# WARN("SPACING",
4345# "Multiple spaces after return type\n" . $herecurr);
4346# }
Tom Rini6b9709d2014-02-27 08:27:28 -05004347
4348# unnecessary space "type ( *funcptr)(args...)"
4349 if (defined $pre_pointer_space &&
4350 $pre_pointer_space =~ /^\s/) {
4351 WARN("SPACING",
4352 "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
4353 }
4354
4355# unnecessary space "type (* funcptr)(args...)"
4356 if (defined $post_pointer_space &&
4357 $post_pointer_space =~ /^\s/) {
4358 WARN("SPACING",
4359 "Unnecessary space before function pointer name\n" . $herecurr);
4360 }
4361
4362# unnecessary space "type (*funcptr )(args...)"
4363 if (defined $post_funcname_space &&
4364 $post_funcname_space =~ /^\s/) {
4365 WARN("SPACING",
4366 "Unnecessary space after function pointer name\n" . $herecurr);
4367 }
4368
4369# unnecessary space "type (*funcptr) (args...)"
4370 if (defined $pre_args_space &&
4371 $pre_args_space =~ /^\s/) {
4372 WARN("SPACING",
4373 "Unnecessary space before function pointer arguments\n" . $herecurr);
4374 }
4375
4376 if (show_type("SPACING") && $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004377 $fixed[$fixlinenr] =~
4378 s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
Tom Rini6b9709d2014-02-27 08:27:28 -05004379 }
Joe Hershberger05622192011-10-18 10:06:59 +00004380 }
4381
4382# check for spacing round square brackets; allowed:
4383# 1. with a type on the left -- int [] a;
4384# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4385# 3. inside a curly brace -- = { [0...10] = 5 }
4386 while ($line =~ /(.*?\s)\[/g) {
4387 my ($where, $prefix) = ($-[1], $1);
4388 if ($prefix !~ /$Type\s+$/ &&
4389 ($where != 0 || $prefix !~ /^.\s+$/) &&
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004390 $prefix !~ /[{,:]\s+$/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004391 if (ERROR("BRACKET_SPACE",
4392 "space prohibited before open square bracket '['\n" . $herecurr) &&
4393 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004394 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004395 s/^(\+.*?)\s+\[/$1\[/;
4396 }
Joe Hershberger05622192011-10-18 10:06:59 +00004397 }
4398 }
4399
4400# check for spaces between functions and their parentheses.
4401 while ($line =~ /($Ident)\s+\(/g) {
4402 my $name = $1;
4403 my $ctx_before = substr($line, 0, $-[1]);
4404 my $ctx = "$ctx_before$name";
4405
4406 # Ignore those directives where spaces _are_ permitted.
4407 if ($name =~ /^(?:
4408 if|for|while|switch|return|case|
4409 volatile|__volatile__|
4410 __attribute__|format|__extension__|
4411 asm|__asm__)$/x)
4412 {
Joe Hershberger05622192011-10-18 10:06:59 +00004413 # cpp #define statements have non-optional spaces, ie
4414 # if there is a space between the name and the open
4415 # parenthesis it is simply not a parameter group.
4416 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4417
4418 # cpp #elif statement condition may start with a (
4419 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4420
4421 # If this whole things ends with a type its most
4422 # likely a typedef for a function.
4423 } elsif ($ctx =~ /$Type$/) {
4424
4425 } else {
Tom Rini6b9709d2014-02-27 08:27:28 -05004426 if (WARN("SPACING",
4427 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
4428 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004429 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004430 s/\b$name\s+\(/$name\(/;
4431 }
Joe Hershberger05622192011-10-18 10:06:59 +00004432 }
4433 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00004434
Joe Hershberger05622192011-10-18 10:06:59 +00004435# Check operator spacing.
4436 if (!($line=~/\#\s*include/)) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004437 my $fixed_line = "";
4438 my $line_fixed = 0;
4439
Joe Hershberger05622192011-10-18 10:06:59 +00004440 my $ops = qr{
4441 <<=|>>=|<=|>=|==|!=|
4442 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
4443 =>|->|<<|>>|<|>|=|!|~|
4444 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
Tom Rini6b9709d2014-02-27 08:27:28 -05004445 \?:|\?|:
Joe Hershberger05622192011-10-18 10:06:59 +00004446 }x;
4447 my @elements = split(/($ops|;)/, $opline);
Tom Rini6b9709d2014-02-27 08:27:28 -05004448
4449## print("element count: <" . $#elements . ">\n");
4450## foreach my $el (@elements) {
4451## print("el: <$el>\n");
4452## }
4453
4454 my @fix_elements = ();
Joe Hershberger05622192011-10-18 10:06:59 +00004455 my $off = 0;
4456
Tom Rini6b9709d2014-02-27 08:27:28 -05004457 foreach my $el (@elements) {
4458 push(@fix_elements, substr($rawline, $off, length($el)));
4459 $off += length($el);
4460 }
4461
4462 $off = 0;
4463
Joe Hershberger05622192011-10-18 10:06:59 +00004464 my $blank = copy_spacing($opline);
Tom Rini6b9709d2014-02-27 08:27:28 -05004465 my $last_after = -1;
Joe Hershberger05622192011-10-18 10:06:59 +00004466
4467 for (my $n = 0; $n < $#elements; $n += 2) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004468
4469 my $good = $fix_elements[$n] . $fix_elements[$n + 1];
4470
4471## print("n: <$n> good: <$good>\n");
4472
Joe Hershberger05622192011-10-18 10:06:59 +00004473 $off += length($elements[$n]);
4474
4475 # Pick up the preceding and succeeding characters.
4476 my $ca = substr($opline, 0, $off);
4477 my $cc = '';
4478 if (length($opline) >= ($off + length($elements[$n + 1]))) {
4479 $cc = substr($opline, $off + length($elements[$n + 1]));
4480 }
4481 my $cb = "$ca$;$cc";
4482
4483 my $a = '';
4484 $a = 'V' if ($elements[$n] ne '');
4485 $a = 'W' if ($elements[$n] =~ /\s$/);
4486 $a = 'C' if ($elements[$n] =~ /$;$/);
4487 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
4488 $a = 'O' if ($elements[$n] eq '');
4489 $a = 'E' if ($ca =~ /^\s*$/);
4490
4491 my $op = $elements[$n + 1];
4492
4493 my $c = '';
4494 if (defined $elements[$n + 2]) {
4495 $c = 'V' if ($elements[$n + 2] ne '');
4496 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
4497 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
4498 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
4499 $c = 'O' if ($elements[$n + 2] eq '');
4500 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
4501 } else {
4502 $c = 'E';
4503 }
4504
4505 my $ctx = "${a}x${c}";
4506
4507 my $at = "(ctx:$ctx)";
4508
4509 my $ptr = substr($blank, 0, $off) . "^";
4510 my $hereptr = "$hereline$ptr\n";
4511
4512 # Pull out the value of this operator.
4513 my $op_type = substr($curr_values, $off + 1, 1);
4514
4515 # Get the full operator variant.
4516 my $opv = $op . substr($curr_vars, $off, 1);
4517
4518 # Ignore operators passed as parameters.
4519 if ($op_type ne 'V' &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004520 $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
Joe Hershberger05622192011-10-18 10:06:59 +00004521
4522# # Ignore comments
4523# } elsif ($op =~ /^$;+$/) {
4524
4525 # ; should have either the end of line or a space or \ after it
4526 } elsif ($op eq ';') {
4527 if ($ctx !~ /.x[WEBC]/ &&
4528 $cc !~ /^\\/ && $cc !~ /^;/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004529 if (ERROR("SPACING",
4530 "space required after that '$op' $at\n" . $hereptr)) {
4531 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
4532 $line_fixed = 1;
4533 }
Joe Hershberger05622192011-10-18 10:06:59 +00004534 }
4535
4536 # // is a comment
4537 } elsif ($op eq '//') {
4538
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004539 # : when part of a bitfield
4540 } elsif ($opv eq ':B') {
4541 # skip the bitfield test for now
4542
Joe Hershberger05622192011-10-18 10:06:59 +00004543 # No spaces for:
4544 # ->
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004545 } elsif ($op eq '->') {
Joe Hershberger05622192011-10-18 10:06:59 +00004546 if ($ctx =~ /Wx.|.xW/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004547 if (ERROR("SPACING",
4548 "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4549 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4550 if (defined $fix_elements[$n + 2]) {
4551 $fix_elements[$n + 2] =~ s/^\s+//;
4552 }
4553 $line_fixed = 1;
4554 }
Joe Hershberger05622192011-10-18 10:06:59 +00004555 }
4556
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004557 # , must not have a space before and must have a space on the right.
Joe Hershberger05622192011-10-18 10:06:59 +00004558 } elsif ($op eq ',') {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004559 my $rtrim_before = 0;
4560 my $space_after = 0;
4561 if ($ctx =~ /Wx./) {
4562 if (ERROR("SPACING",
4563 "space prohibited before that '$op' $at\n" . $hereptr)) {
4564 $line_fixed = 1;
4565 $rtrim_before = 1;
4566 }
4567 }
Joe Hershberger05622192011-10-18 10:06:59 +00004568 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004569 if (ERROR("SPACING",
4570 "space required after that '$op' $at\n" . $hereptr)) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004571 $line_fixed = 1;
4572 $last_after = $n;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004573 $space_after = 1;
4574 }
4575 }
4576 if ($rtrim_before || $space_after) {
4577 if ($rtrim_before) {
4578 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4579 } else {
4580 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
4581 }
4582 if ($space_after) {
4583 $good .= " ";
Tom Rini6b9709d2014-02-27 08:27:28 -05004584 }
Joe Hershberger05622192011-10-18 10:06:59 +00004585 }
4586
4587 # '*' as part of a type definition -- reported already.
4588 } elsif ($opv eq '*_') {
4589 #warn "'*' is part of type\n";
4590
4591 # unary operators should have a space before and
4592 # none after. May be left adjacent to another
4593 # unary operator, or a cast
4594 } elsif ($op eq '!' || $op eq '~' ||
4595 $opv eq '*U' || $opv eq '-U' ||
4596 $opv eq '&U' || $opv eq '&&U') {
4597 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004598 if (ERROR("SPACING",
4599 "space required before that '$op' $at\n" . $hereptr)) {
4600 if ($n != $last_after + 2) {
4601 $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
4602 $line_fixed = 1;
4603 }
4604 }
Joe Hershberger05622192011-10-18 10:06:59 +00004605 }
4606 if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4607 # A unary '*' may be const
4608
4609 } elsif ($ctx =~ /.xW/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004610 if (ERROR("SPACING",
4611 "space prohibited after that '$op' $at\n" . $hereptr)) {
4612 $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
4613 if (defined $fix_elements[$n + 2]) {
4614 $fix_elements[$n + 2] =~ s/^\s+//;
4615 }
4616 $line_fixed = 1;
4617 }
Joe Hershberger05622192011-10-18 10:06:59 +00004618 }
4619
4620 # unary ++ and unary -- are allowed no space on one side.
4621 } elsif ($op eq '++' or $op eq '--') {
4622 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004623 if (ERROR("SPACING",
4624 "space required one side of that '$op' $at\n" . $hereptr)) {
4625 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
4626 $line_fixed = 1;
4627 }
Joe Hershberger05622192011-10-18 10:06:59 +00004628 }
4629 if ($ctx =~ /Wx[BE]/ ||
4630 ($ctx =~ /Wx./ && $cc =~ /^;/)) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004631 if (ERROR("SPACING",
4632 "space prohibited before that '$op' $at\n" . $hereptr)) {
4633 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4634 $line_fixed = 1;
4635 }
Joe Hershberger05622192011-10-18 10:06:59 +00004636 }
4637 if ($ctx =~ /ExW/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004638 if (ERROR("SPACING",
4639 "space prohibited after that '$op' $at\n" . $hereptr)) {
4640 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
4641 if (defined $fix_elements[$n + 2]) {
4642 $fix_elements[$n + 2] =~ s/^\s+//;
4643 }
4644 $line_fixed = 1;
4645 }
Joe Hershberger05622192011-10-18 10:06:59 +00004646 }
4647
Joe Hershberger05622192011-10-18 10:06:59 +00004648 # << and >> may either have or not have spaces both sides
4649 } elsif ($op eq '<<' or $op eq '>>' or
4650 $op eq '&' or $op eq '^' or $op eq '|' or
4651 $op eq '+' or $op eq '-' or
4652 $op eq '*' or $op eq '/' or
4653 $op eq '%')
4654 {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004655 if ($check) {
4656 if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4657 if (CHK("SPACING",
4658 "spaces preferred around that '$op' $at\n" . $hereptr)) {
4659 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4660 $fix_elements[$n + 2] =~ s/^\s+//;
4661 $line_fixed = 1;
4662 }
4663 } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4664 if (CHK("SPACING",
4665 "space preferred before that '$op' $at\n" . $hereptr)) {
4666 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4667 $line_fixed = 1;
4668 }
4669 }
4670 } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004671 if (ERROR("SPACING",
4672 "need consistent spacing around '$op' $at\n" . $hereptr)) {
4673 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4674 if (defined $fix_elements[$n + 2]) {
4675 $fix_elements[$n + 2] =~ s/^\s+//;
4676 }
4677 $line_fixed = 1;
4678 }
Joe Hershberger05622192011-10-18 10:06:59 +00004679 }
4680
4681 # A colon needs no spaces before when it is
4682 # terminating a case value or a label.
4683 } elsif ($opv eq ':C' || $opv eq ':L') {
4684 if ($ctx =~ /Wx./) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004685 if (ERROR("SPACING",
4686 "space prohibited before that '$op' $at\n" . $hereptr)) {
4687 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
4688 $line_fixed = 1;
4689 }
Joe Hershberger05622192011-10-18 10:06:59 +00004690 }
4691
4692 # All the others need spaces both sides.
4693 } elsif ($ctx !~ /[EWC]x[CWE]/) {
4694 my $ok = 0;
4695
4696 # Ignore email addresses <foo@bar>
4697 if (($op eq '<' &&
4698 $cc =~ /^\S+\@\S+>/) ||
4699 ($op eq '>' &&
4700 $ca =~ /<\S+\@\S+$/))
4701 {
Tom Rinic57383b2020-06-16 10:29:46 -04004702 $ok = 1;
Joe Hershberger05622192011-10-18 10:06:59 +00004703 }
4704
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004705 # for asm volatile statements
4706 # ignore a colon with another
4707 # colon immediately before or after
4708 if (($op eq ':') &&
4709 ($ca =~ /:$/ || $cc =~ /^:/)) {
4710 $ok = 1;
4711 }
4712
Tom Rini6b9709d2014-02-27 08:27:28 -05004713 # messages are ERROR, but ?: are CHK
Joe Hershberger05622192011-10-18 10:06:59 +00004714 if ($ok == 0) {
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02004715 my $msg_level = \&ERROR;
4716 $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
Tom Rini6b9709d2014-02-27 08:27:28 -05004717
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02004718 if (&{$msg_level}("SPACING",
4719 "spaces required around that '$op' $at\n" . $hereptr)) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004720 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4721 if (defined $fix_elements[$n + 2]) {
4722 $fix_elements[$n + 2] =~ s/^\s+//;
4723 }
4724 $line_fixed = 1;
4725 }
Joe Hershberger05622192011-10-18 10:06:59 +00004726 }
4727 }
4728 $off += length($elements[$n + 1]);
Tom Rini6b9709d2014-02-27 08:27:28 -05004729
4730## print("n: <$n> GOOD: <$good>\n");
4731
4732 $fixed_line = $fixed_line . $good;
4733 }
4734
4735 if (($#elements % 2) == 0) {
4736 $fixed_line = $fixed_line . $fix_elements[$#elements];
4737 }
4738
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004739 if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4740 $fixed[$fixlinenr] = $fixed_line;
Tom Rini6b9709d2014-02-27 08:27:28 -05004741 }
4742
4743
4744 }
4745
4746# check for whitespace before a non-naked semicolon
4747 if ($line =~ /^\+.*\S\s+;\s*$/) {
4748 if (WARN("SPACING",
4749 "space prohibited before semicolon\n" . $herecurr) &&
4750 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004751 1 while $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004752 s/^(\+.*\S)\s+;/$1;/;
Joe Hershberger05622192011-10-18 10:06:59 +00004753 }
4754 }
4755
4756# check for multiple assignments
4757 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4758 CHK("MULTIPLE_ASSIGNMENTS",
4759 "multiple assignments should be avoided\n" . $herecurr);
4760 }
4761
4762## # check for multiple declarations, allowing for a function declaration
4763## # continuation.
4764## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
4765## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
4766##
4767## # Remove any bracketed sections to ensure we do not
4768## # falsly report the parameters of functions.
4769## my $ln = $line;
4770## while ($ln =~ s/\([^\(\)]*\)//g) {
4771## }
4772## if ($ln =~ /,/) {
4773## WARN("MULTIPLE_DECLARATION",
4774## "declaring multiple variables together should be avoided\n" . $herecurr);
4775## }
4776## }
4777
4778#need space before brace following if, while, etc
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004779 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004780 $line =~ /\b(?:else|do)\{/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004781 if (ERROR("SPACING",
4782 "space required before the open brace '{'\n" . $herecurr) &&
4783 $fix) {
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004784 $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
Tom Rini6b9709d2014-02-27 08:27:28 -05004785 }
Joe Hershberger05622192011-10-18 10:06:59 +00004786 }
4787
Tom Rini6b9709d2014-02-27 08:27:28 -05004788## # check for blank lines before declarations
4789## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4790## $prevrawline =~ /^.\s*$/) {
4791## WARN("SPACING",
4792## "No blank lines before declarations\n" . $hereprev);
4793## }
4794##
4795
Joe Hershberger05622192011-10-18 10:06:59 +00004796# closing brace should have a space following it when it has anything
4797# on the line
Tom Rinic57383b2020-06-16 10:29:46 -04004798 if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004799 if (ERROR("SPACING",
4800 "space required after that close brace '}'\n" . $herecurr) &&
4801 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004802 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004803 s/}((?!(?:,|;|\)))\S)/} $1/;
4804 }
Joe Hershberger05622192011-10-18 10:06:59 +00004805 }
4806
4807# check spacing on square brackets
4808 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004809 if (ERROR("SPACING",
4810 "space prohibited after that open square bracket '['\n" . $herecurr) &&
4811 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004812 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004813 s/\[\s+/\[/;
4814 }
Joe Hershberger05622192011-10-18 10:06:59 +00004815 }
4816 if ($line =~ /\s\]/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004817 if (ERROR("SPACING",
4818 "space prohibited before that close square bracket ']'\n" . $herecurr) &&
4819 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004820 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004821 s/\s+\]/\]/;
4822 }
Joe Hershberger05622192011-10-18 10:06:59 +00004823 }
4824
4825# check spacing on parentheses
4826 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
4827 $line !~ /for\s*\(\s+;/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004828 if (ERROR("SPACING",
4829 "space prohibited after that open parenthesis '('\n" . $herecurr) &&
4830 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004831 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004832 s/\(\s+/\(/;
4833 }
Joe Hershberger05622192011-10-18 10:06:59 +00004834 }
4835 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4836 $line !~ /for\s*\(.*;\s+\)/ &&
4837 $line !~ /:\s+\)/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004838 if (ERROR("SPACING",
4839 "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
4840 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004841 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004842 s/\s+\)/\)/;
4843 }
Joe Hershberger05622192011-10-18 10:06:59 +00004844 }
4845
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004846# check unnecessary parentheses around addressof/dereference single $Lvals
4847# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4848
4849 while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4850 my $var = $1;
4851 if (CHK("UNNECESSARY_PARENTHESES",
4852 "Unnecessary parentheses around $var\n" . $herecurr) &&
4853 $fix) {
4854 $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4855 }
4856 }
4857
4858# check for unnecessary parentheses around function pointer uses
4859# ie: (foo->bar)(); should be foo->bar();
4860# but not "if (foo->bar) (" to avoid some false positives
4861 if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4862 my $var = $2;
4863 if (CHK("UNNECESSARY_PARENTHESES",
4864 "Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4865 $fix) {
4866 my $var2 = deparenthesize($var);
4867 $var2 =~ s/\s//g;
4868 $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4869 }
4870 }
4871
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02004872# check for unnecessary parentheses around comparisons in if uses
4873# when !drivers/staging or command-line uses --strict
4874 if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004875 $perl_version_ok && defined($stat) &&
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02004876 $stat =~ /(^.\s*if\s*($balanced_parens))/) {
4877 my $if_stat = $1;
4878 my $test = substr($2, 1, -1);
4879 my $herectx;
4880 while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
4881 my $match = $1;
4882 # avoid parentheses around potential macro args
4883 next if ($match =~ /^\s*\w+\s*$/);
4884 if (!defined($herectx)) {
4885 $herectx = $here . "\n";
4886 my $cnt = statement_rawlines($if_stat);
4887 for (my $n = 0; $n < $cnt; $n++) {
4888 my $rl = raw_line($linenr, $n);
4889 $herectx .= $rl . "\n";
4890 last if $rl =~ /^[ \+].*\{/;
4891 }
4892 }
4893 CHK("UNNECESSARY_PARENTHESES",
4894 "Unnecessary parentheses around '$match'\n" . $herectx);
4895 }
4896 }
4897
Joe Hershberger05622192011-10-18 10:06:59 +00004898#goto labels aren't indented, allow a single space however
4899 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
4900 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
Tom Rini6b9709d2014-02-27 08:27:28 -05004901 if (WARN("INDENTED_LABEL",
4902 "labels should not be indented\n" . $herecurr) &&
4903 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004904 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004905 s/^(.)\s+/$1/;
4906 }
Joe Hershberger05622192011-10-18 10:06:59 +00004907 }
4908
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004909# return is not a function
Tom Rini6b9709d2014-02-27 08:27:28 -05004910 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
Joe Hershberger05622192011-10-18 10:06:59 +00004911 my $spacing = $1;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004912 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004913 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
4914 my $value = $1;
4915 $value = deparenthesize($value);
4916 if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4917 ERROR("RETURN_PARENTHESES",
4918 "return is not a function, parentheses are not required\n" . $herecurr);
4919 }
Joe Hershberger05622192011-10-18 10:06:59 +00004920 } elsif ($spacing !~ /\s+/) {
4921 ERROR("SPACING",
4922 "space required before the open parenthesis '('\n" . $herecurr);
4923 }
4924 }
Tom Rini6b9709d2014-02-27 08:27:28 -05004925
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004926# unnecessary return in a void function
4927# at end-of-function, with the previous line a single leading tab, then return;
4928# and the line before that not a goto label target like "out:"
4929 if ($sline =~ /^[ \+]}\s*$/ &&
4930 $prevline =~ /^\+\treturn\s*;\s*$/ &&
4931 $linenr >= 3 &&
4932 $lines[$linenr - 3] =~ /^[ +]/ &&
4933 $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
4934 WARN("RETURN_VOID",
4935 "void function return statements are not generally useful\n" . $hereprev);
4936 }
4937
Tom Rini6b9709d2014-02-27 08:27:28 -05004938# if statements using unnecessary parentheses - ie: if ((foo == bar))
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004939 if ($perl_version_ok &&
Tom Rini6b9709d2014-02-27 08:27:28 -05004940 $line =~ /\bif\s*((?:\(\s*){2,})/) {
4941 my $openparens = $1;
4942 my $count = $openparens =~ tr@\(@\(@;
4943 my $msg = "";
4944 if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4945 my $comp = $4; #Not $1 because of $LvalOrFunc
4946 $msg = " - maybe == should be = ?" if ($comp eq "==");
4947 WARN("UNNECESSARY_PARENTHESES",
4948 "Unnecessary parentheses$msg\n" . $herecurr);
4949 }
4950 }
4951
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004952# comparisons with a constant or upper case identifier on the left
4953# avoid cases like "foo + BAR < baz"
4954# only fix matches surrounded by parentheses to avoid incorrect
4955# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02004956 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004957 $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4958 my $lead = $1;
4959 my $const = $2;
4960 my $comp = $3;
4961 my $to = $4;
4962 my $newcomp = $comp;
4963 if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4964 $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4965 WARN("CONSTANT_COMPARISON",
4966 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4967 $fix) {
4968 if ($comp eq "<") {
4969 $newcomp = ">";
4970 } elsif ($comp eq "<=") {
4971 $newcomp = ">=";
4972 } elsif ($comp eq ">") {
4973 $newcomp = "<";
4974 } elsif ($comp eq ">=") {
4975 $newcomp = "<=";
4976 }
4977 $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4978 }
4979 }
4980
4981# Return of what appears to be an errno should normally be negative
4982 if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
Joe Hershberger05622192011-10-18 10:06:59 +00004983 my $name = $1;
4984 if ($name ne 'EOF' && $name ne 'ERROR') {
4985 WARN("USE_NEGATIVE_ERRNO",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004986 "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00004987 }
4988 }
4989
Joe Hershberger05622192011-10-18 10:06:59 +00004990# Need a space before open parenthesis after if, while etc
Tom Rini6b9709d2014-02-27 08:27:28 -05004991 if ($line =~ /\b(if|while|for|switch)\(/) {
4992 if (ERROR("SPACING",
4993 "space required before the open parenthesis '('\n" . $herecurr) &&
4994 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02004995 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05004996 s/\b(if|while|for|switch)\(/$1 \(/;
4997 }
Joe Hershberger05622192011-10-18 10:06:59 +00004998 }
4999
5000# Check for illegal assignment in if conditional -- and check for trailing
5001# statements after the conditional.
5002 if ($line =~ /do\s*(?!{)/) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005003 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
5004 ctx_statement_block($linenr, $realcnt, 0)
5005 if (!defined $stat);
Joe Hershberger05622192011-10-18 10:06:59 +00005006 my ($stat_next) = ctx_statement_block($line_nr_next,
5007 $remain_next, $off_next);
5008 $stat_next =~ s/\n./\n /g;
5009 ##print "stat<$stat> stat_next<$stat_next>\n";
5010
5011 if ($stat_next =~ /^\s*while\b/) {
5012 # If the statement carries leading newlines,
5013 # then count those as offsets.
5014 my ($whitespace) =
5015 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5016 my $offset =
5017 statement_rawlines($whitespace) - 1;
5018
5019 $suppress_whiletrailers{$line_nr_next +
5020 $offset} = 1;
5021 }
5022 }
5023 if (!defined $suppress_whiletrailers{$linenr} &&
Tom Rini6b9709d2014-02-27 08:27:28 -05005024 defined($stat) && defined($cond) &&
Joe Hershberger05622192011-10-18 10:06:59 +00005025 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5026 my ($s, $c) = ($stat, $cond);
5027
5028 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
5029 ERROR("ASSIGN_IN_IF",
5030 "do not use assignment in if condition\n" . $herecurr);
5031 }
5032
5033 # Find out what is on the end of the line after the
5034 # conditional.
5035 substr($s, 0, length($c), '');
5036 $s =~ s/\n.*//g;
Tom Rinic57383b2020-06-16 10:29:46 -04005037 $s =~ s/$;//g; # Remove any comments
Joe Hershberger05622192011-10-18 10:06:59 +00005038 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
5039 $c !~ /}\s*while\s*/)
5040 {
5041 # Find out how long the conditional actually is.
5042 my @newlines = ($c =~ /\n/gs);
5043 my $cond_lines = 1 + $#newlines;
5044 my $stat_real = '';
5045
5046 $stat_real = raw_line($linenr, $cond_lines)
5047 . "\n" if ($cond_lines);
5048 if (defined($stat_real) && $cond_lines > 1) {
5049 $stat_real = "[...]\n$stat_real";
5050 }
5051
5052 ERROR("TRAILING_STATEMENTS",
5053 "trailing statements should be on next line\n" . $herecurr . $stat_real);
5054 }
5055 }
5056
5057# Check for bitwise tests written as boolean
5058 if ($line =~ /
5059 (?:
5060 (?:\[|\(|\&\&|\|\|)
5061 \s*0[xX][0-9]+\s*
5062 (?:\&\&|\|\|)
5063 |
5064 (?:\&\&|\|\|)
5065 \s*0[xX][0-9]+\s*
5066 (?:\&\&|\|\||\)|\])
5067 )/x)
5068 {
5069 WARN("HEXADECIMAL_BOOLEAN_TEST",
5070 "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
5071 }
5072
5073# if and else should not have general statements after it
5074 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
5075 my $s = $1;
Tom Rinic57383b2020-06-16 10:29:46 -04005076 $s =~ s/$;//g; # Remove any comments
Joe Hershberger05622192011-10-18 10:06:59 +00005077 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5078 ERROR("TRAILING_STATEMENTS",
5079 "trailing statements should be on next line\n" . $herecurr);
5080 }
5081 }
5082# if should not continue a brace
5083 if ($line =~ /}\s*if\b/) {
5084 ERROR("TRAILING_STATEMENTS",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005085 "trailing statements should be on next line (or did you mean 'else if'?)\n" .
Joe Hershberger05622192011-10-18 10:06:59 +00005086 $herecurr);
5087 }
5088# case and default should not have general statements after them
5089 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5090 $line !~ /\G(?:
5091 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5092 \s*return\s+
5093 )/xg)
5094 {
5095 ERROR("TRAILING_STATEMENTS",
5096 "trailing statements should be on next line\n" . $herecurr);
5097 }
5098
5099 # Check for }<nl>else {, these must be at the same
5100 # indent level to be relevant to each other.
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005101 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
5102 $previndent == $indent) {
5103 if (ERROR("ELSE_AFTER_BRACE",
5104 "else should follow close brace '}'\n" . $hereprev) &&
5105 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5106 fix_delete_line($fixlinenr - 1, $prevrawline);
5107 fix_delete_line($fixlinenr, $rawline);
5108 my $fixedline = $prevrawline;
5109 $fixedline =~ s/}\s*$//;
5110 if ($fixedline !~ /^\+\s*$/) {
5111 fix_insert_line($fixlinenr, $fixedline);
5112 }
5113 $fixedline = $rawline;
5114 $fixedline =~ s/^(.\s*)else/$1} else/;
5115 fix_insert_line($fixlinenr, $fixedline);
5116 }
Joe Hershberger05622192011-10-18 10:06:59 +00005117 }
5118
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005119 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5120 $previndent == $indent) {
Joe Hershberger05622192011-10-18 10:06:59 +00005121 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5122
5123 # Find out what is on the end of the line after the
5124 # conditional.
5125 substr($s, 0, length($c), '');
5126 $s =~ s/\n.*//g;
5127
5128 if ($s =~ /^\s*;/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005129 if (ERROR("WHILE_AFTER_BRACE",
5130 "while should follow close brace '}'\n" . $hereprev) &&
5131 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5132 fix_delete_line($fixlinenr - 1, $prevrawline);
5133 fix_delete_line($fixlinenr, $rawline);
5134 my $fixedline = $prevrawline;
5135 my $trailing = $rawline;
5136 $trailing =~ s/^\+//;
5137 $trailing = trim($trailing);
5138 $fixedline =~ s/}\s*$/} $trailing/;
5139 fix_insert_line($fixlinenr, $fixedline);
5140 }
Joe Hershberger05622192011-10-18 10:06:59 +00005141 }
5142 }
5143
Tom Rini6b9709d2014-02-27 08:27:28 -05005144#Specific variable tests
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005145 while ($line =~ m{($Constant|$Lval)}g) {
5146 my $var = $1;
Tom Rini6b9709d2014-02-27 08:27:28 -05005147
Tom Rini6b9709d2014-02-27 08:27:28 -05005148#CamelCase
5149 if ($var !~ /^$Constant$/ &&
5150 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
5151#Ignore Page<foo> variants
5152 $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
Tom Rinic57383b2020-06-16 10:29:46 -04005153#Ignore SI style variants like nS, mV and dB
5154#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5155 $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005156#Ignore some three character SI units explicitly, like MiB and KHz
5157 $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05005158 while ($var =~ m{($Ident)}g) {
5159 my $word = $1;
5160 next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5161 if ($check) {
5162 seed_camelcase_includes();
5163 if (!$file && !$camelcase_file_seeded) {
5164 seed_camelcase_file($realfile);
5165 $camelcase_file_seeded = 1;
5166 }
5167 }
5168 if (!defined $camelcase{$word}) {
5169 $camelcase{$word} = 1;
5170 CHK("CAMELCASE",
5171 "Avoid CamelCase: <$word>\n" . $herecurr);
5172 }
5173 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005174 }
5175 }
Joe Hershberger05622192011-10-18 10:06:59 +00005176
5177#no spaces allowed after \ in define
Tom Rini6b9709d2014-02-27 08:27:28 -05005178 if ($line =~ /\#\s*define.*\\\s+$/) {
5179 if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5180 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5181 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005182 $fixed[$fixlinenr] =~ s/\s+$//;
Tom Rini6b9709d2014-02-27 08:27:28 -05005183 }
Joe Hershberger05622192011-10-18 10:06:59 +00005184 }
5185
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005186# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
5187# itself <asm/foo.h> (uses RAW line)
Joe Hershberger05622192011-10-18 10:06:59 +00005188 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5189 my $file = "$1.h";
5190 my $checkfile = "include/linux/$file";
5191 if (-f "$root/$checkfile" &&
5192 $realfile ne $checkfile &&
5193 $1 !~ /$allowed_asm_includes/)
5194 {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005195 my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
5196 if ($asminclude > 0) {
5197 if ($realfile =~ m{^arch/}) {
5198 CHK("ARCH_INCLUDE_LINUX",
5199 "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5200 } else {
5201 WARN("INCLUDE_LINUX",
5202 "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5203 }
Joe Hershberger05622192011-10-18 10:06:59 +00005204 }
5205 }
5206 }
5207
5208# multi-statement macros should be enclosed in a do while loop, grab the
5209# first statement and ensure its the whole macro if its not enclosed
5210# in a known good container
5211 if ($realfile !~ m@/vmlinux.lds.h$@ &&
5212 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5213 my $ln = $linenr;
5214 my $cnt = $realcnt;
5215 my ($off, $dstat, $dcond, $rest);
5216 my $ctx = '';
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005217 my $has_flow_statement = 0;
5218 my $has_arg_concat = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00005219 ($dstat, $dcond, $ln, $cnt, $off) =
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005220 ctx_statement_block($linenr, $realcnt, 0);
5221 $ctx = $dstat;
Joe Hershberger05622192011-10-18 10:06:59 +00005222 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5223 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5224
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005225 $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
5226 $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
5227
5228 $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5229 my $define_args = $1;
5230 my $define_stmt = $dstat;
5231 my @def_args = ();
5232
5233 if (defined $define_args && $define_args ne "") {
5234 $define_args = substr($define_args, 1, length($define_args) - 2);
5235 $define_args =~ s/\s*//g;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02005236 $define_args =~ s/\\\+?//g;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005237 @def_args = split(",", $define_args);
5238 }
5239
Joe Hershberger05622192011-10-18 10:06:59 +00005240 $dstat =~ s/$;//g;
5241 $dstat =~ s/\\\n.//g;
5242 $dstat =~ s/^\s*//s;
5243 $dstat =~ s/\s*$//s;
5244
5245 # Flatten any parentheses and braces
5246 while ($dstat =~ s/\([^\(\)]*\)/1/ ||
5247 $dstat =~ s/\{[^\{\}]*\}/1/ ||
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005248 $dstat =~ s/.\[[^\[\]]*\]/1/)
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005249 {
5250 }
5251
Tom Rinic57383b2020-06-16 10:29:46 -04005252 # Flatten any obvious string concatenation.
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005253 while ($dstat =~ s/($String)\s*$Ident/$1/ ||
5254 $dstat =~ s/$Ident\s*($String)/$1/)
Joe Hershberger05622192011-10-18 10:06:59 +00005255 {
5256 }
5257
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005258 # Make asm volatile uses seem like a generic function
5259 $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
5260
Joe Hershberger05622192011-10-18 10:06:59 +00005261 my $exceptions = qr{
5262 $Declare|
5263 module_param_named|
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005264 MODULE_PARM_DESC|
Joe Hershberger05622192011-10-18 10:06:59 +00005265 DECLARE_PER_CPU|
5266 DEFINE_PER_CPU|
5267 __typeof__\(|
5268 union|
5269 struct|
5270 \.$Ident\s*=\s*|
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005271 ^\"|\"$|
5272 ^\[
Joe Hershberger05622192011-10-18 10:06:59 +00005273 }x;
5274 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005275
5276 $ctx =~ s/\n*$//;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005277 my $stmt_cnt = statement_rawlines($ctx);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02005278 my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005279
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005280 if ($dstat ne '' &&
5281 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
5282 $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
Tom Rini6b9709d2014-02-27 08:27:28 -05005283 $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005284 $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005285 $dstat !~ /$exceptions/ &&
5286 $dstat !~ /^\.$Ident\s*=/ && # .foo =
Tom Rini6b9709d2014-02-27 08:27:28 -05005287 $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005288 $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
5289 $dstat !~ /^for\s*$Constant$/ && # for (...)
5290 $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
5291 $dstat !~ /^do\s*{/ && # do {...
Heiko Schocherd8a1a302016-01-04 09:17:19 +01005292 $dstat !~ /^\(\{/ && # ({...
Tom Rini6b9709d2014-02-27 08:27:28 -05005293 $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005294 {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005295 if ($dstat =~ /^\s*if\b/) {
5296 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5297 "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5298 } elsif ($dstat =~ /;/) {
5299 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5300 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5301 } else {
5302 ERROR("COMPLEX_MACRO",
5303 "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5304 }
5305
5306 }
5307
5308 # Make $define_stmt single line, comment-free, etc
5309 my @stmt_array = split('\n', $define_stmt);
5310 my $first = 1;
5311 $define_stmt = "";
5312 foreach my $l (@stmt_array) {
5313 $l =~ s/\\$//;
5314 if ($first) {
5315 $define_stmt = $l;
5316 $first = 0;
5317 } elsif ($l =~ /^[\+ ]/) {
5318 $define_stmt .= substr($l, 1);
5319 }
5320 }
5321 $define_stmt =~ s/$;//g;
5322 $define_stmt =~ s/\s+/ /g;
5323 $define_stmt = trim($define_stmt);
5324
5325# check if any macro arguments are reused (ignore '...' and 'type')
5326 foreach my $arg (@def_args) {
5327 next if ($arg =~ /\.\.\./);
5328 next if ($arg =~ /^type$/i);
5329 my $tmp_stmt = $define_stmt;
Tom Rinic57383b2020-06-16 10:29:46 -04005330 $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005331 $tmp_stmt =~ s/\#+\s*$arg\b//g;
5332 $tmp_stmt =~ s/\b$arg\s*\#\#//g;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02005333 my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005334 if ($use_cnt > 1) {
5335 CHK("MACRO_ARG_REUSE",
5336 "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5337 }
5338# check if any macro arguments may have other precedence issues
5339 if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
5340 ((defined($1) && $1 ne ',') ||
5341 (defined($2) && $2 ne ','))) {
5342 CHK("MACRO_ARG_PRECEDENCE",
5343 "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
5344 }
5345 }
5346
5347# check for macros with flow control, but without ## concatenation
5348# ## concatenation is commonly a macro that defines a function so ignore those
5349 if ($has_flow_statement && !$has_arg_concat) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005350 my $cnt = statement_rawlines($ctx);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02005351 my $herectx = get_stat_here($linenr, $cnt, $here);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005352
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005353 WARN("MACRO_WITH_FLOW_CONTROL",
5354 "Macros with flow control statements should be avoided\n" . "$herectx");
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005355 }
5356
5357# check for line continuations outside of #defines, preprocessor #, and asm
5358
5359 } else {
5360 if ($prevline !~ /^..*\\$/ &&
5361 $line !~ /^\+\s*\#.*\\$/ && # preprocessor
5362 $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
5363 $line =~ /^\+.*\\$/) {
5364 WARN("LINE_CONTINUATIONS",
5365 "Avoid unnecessary line continuations\n" . $herecurr);
5366 }
5367 }
5368
5369# do {} while (0) macro tests:
5370# single-statement macros do not need to be enclosed in do while (0) loop,
5371# macro should not end with a semicolon
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02005372 if ($perl_version_ok &&
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005373 $realfile !~ m@/vmlinux.lds.h$@ &&
5374 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5375 my $ln = $linenr;
5376 my $cnt = $realcnt;
5377 my ($off, $dstat, $dcond, $rest);
5378 my $ctx = '';
5379 ($dstat, $dcond, $ln, $cnt, $off) =
5380 ctx_statement_block($linenr, $realcnt, 0);
5381 $ctx = $dstat;
5382
5383 $dstat =~ s/\\\n.//g;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005384 $dstat =~ s/$;/ /g;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005385
5386 if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5387 my $stmts = $2;
5388 my $semis = $3;
5389
5390 $ctx =~ s/\n*$//;
5391 my $cnt = statement_rawlines($ctx);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02005392 my $herectx = get_stat_here($linenr, $cnt, $here);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005393
5394 if (($stmts =~ tr/;/;/) == 1 &&
5395 $stmts !~ /^\s*(if|while|for|switch)\b/) {
5396 WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5397 "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5398 }
5399 if (defined $semis && $semis ne "") {
5400 WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5401 "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
Joe Hershberger05622192011-10-18 10:06:59 +00005402 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005403 } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5404 $ctx =~ s/\n*$//;
5405 my $cnt = statement_rawlines($ctx);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02005406 my $herectx = get_stat_here($linenr, $cnt, $here);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005407
5408 WARN("TRAILING_SEMICOLON",
5409 "macros should not use a trailing semicolon\n" . "$herectx");
Joe Hershberger05622192011-10-18 10:06:59 +00005410 }
5411 }
5412
Joe Hershberger05622192011-10-18 10:06:59 +00005413# check for redundant bracing round if etc
5414 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
5415 my ($level, $endln, @chunks) =
5416 ctx_statement_full($linenr, $realcnt, 1);
5417 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5418 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5419 if ($#chunks > 0 && $level == 0) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005420 my @allowed = ();
5421 my $allow = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00005422 my $seen = 0;
5423 my $herectx = $here . "\n";
5424 my $ln = $linenr - 1;
5425 for my $chunk (@chunks) {
5426 my ($cond, $block) = @{$chunk};
5427
5428 # If the condition carries leading newlines, then count those as offsets.
5429 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5430 my $offset = statement_rawlines($whitespace) - 1;
5431
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005432 $allowed[$allow] = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00005433 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5434
5435 # We have looked at and allowed this specific line.
5436 $suppress_ifbraces{$ln + $offset} = 1;
5437
5438 $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5439 $ln += statement_rawlines($block) - 1;
5440
5441 substr($block, 0, length($cond), '');
5442
5443 $seen++ if ($block =~ /^\s*{/);
5444
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005445 #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
Joe Hershberger05622192011-10-18 10:06:59 +00005446 if (statement_lines($cond) > 1) {
5447 #print "APW: ALLOWED: cond<$cond>\n";
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005448 $allowed[$allow] = 1;
Joe Hershberger05622192011-10-18 10:06:59 +00005449 }
5450 if ($block =~/\b(?:if|for|while)\b/) {
5451 #print "APW: ALLOWED: block<$block>\n";
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005452 $allowed[$allow] = 1;
Joe Hershberger05622192011-10-18 10:06:59 +00005453 }
5454 if (statement_block_size($block) > 1) {
5455 #print "APW: ALLOWED: lines block<$block>\n";
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005456 $allowed[$allow] = 1;
Joe Hershberger05622192011-10-18 10:06:59 +00005457 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005458 $allow++;
Joe Hershberger05622192011-10-18 10:06:59 +00005459 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005460 if ($seen) {
5461 my $sum_allowed = 0;
5462 foreach (@allowed) {
5463 $sum_allowed += $_;
5464 }
5465 if ($sum_allowed == 0) {
5466 WARN("BRACES",
5467 "braces {} are not necessary for any arm of this statement\n" . $herectx);
5468 } elsif ($sum_allowed != $allow &&
5469 $seen != $allow) {
5470 CHK("BRACES",
5471 "braces {} should be used on all arms of this statement\n" . $herectx);
5472 }
Joe Hershberger05622192011-10-18 10:06:59 +00005473 }
5474 }
5475 }
5476 if (!defined $suppress_ifbraces{$linenr - 1} &&
5477 $line =~ /\b(if|while|for|else)\b/) {
5478 my $allowed = 0;
5479
5480 # Check the pre-context.
5481 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5482 #print "APW: ALLOWED: pre<$1>\n";
5483 $allowed = 1;
5484 }
5485
5486 my ($level, $endln, @chunks) =
5487 ctx_statement_full($linenr, $realcnt, $-[0]);
5488
5489 # Check the condition.
5490 my ($cond, $block) = @{$chunks[0]};
5491 #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5492 if (defined $cond) {
5493 substr($block, 0, length($cond), '');
5494 }
5495 if (statement_lines($cond) > 1) {
5496 #print "APW: ALLOWED: cond<$cond>\n";
5497 $allowed = 1;
5498 }
5499 if ($block =~/\b(?:if|for|while)\b/) {
5500 #print "APW: ALLOWED: block<$block>\n";
5501 $allowed = 1;
5502 }
5503 if (statement_block_size($block) > 1) {
5504 #print "APW: ALLOWED: lines block<$block>\n";
5505 $allowed = 1;
5506 }
5507 # Check the post-context.
5508 if (defined $chunks[1]) {
5509 my ($cond, $block) = @{$chunks[1]};
5510 if (defined $cond) {
5511 substr($block, 0, length($cond), '');
5512 }
5513 if ($block =~ /^\s*\{/) {
5514 #print "APW: ALLOWED: chunk-1 block<$block>\n";
5515 $allowed = 1;
5516 }
5517 }
5518 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
Joe Hershberger05622192011-10-18 10:06:59 +00005519 my $cnt = statement_rawlines($block);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02005520 my $herectx = get_stat_here($linenr, $cnt, $here);
Joe Hershberger05622192011-10-18 10:06:59 +00005521
5522 WARN("BRACES",
5523 "braces {} are not necessary for single statement blocks\n" . $herectx);
5524 }
5525 }
5526
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005527# check for single line unbalanced braces
5528 if ($sline =~ /^.\s*\}\s*else\s*$/ ||
5529 $sline =~ /^.\s*else\s*\{\s*$/) {
5530 CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5531 }
5532
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005533# check for unnecessary blank lines around braces
Tom Rini6b9709d2014-02-27 08:27:28 -05005534 if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005535 if (CHK("BRACES",
5536 "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5537 $fix && $prevrawline =~ /^\+/) {
5538 fix_delete_line($fixlinenr - 1, $prevrawline);
5539 }
Joe Hershberger05622192011-10-18 10:06:59 +00005540 }
Tom Rini6b9709d2014-02-27 08:27:28 -05005541 if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005542 if (CHK("BRACES",
5543 "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5544 $fix) {
5545 fix_delete_line($fixlinenr, $rawline);
5546 }
Joe Hershberger05622192011-10-18 10:06:59 +00005547 }
5548
5549# no volatiles please
5550 my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
5551 if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5552 WARN("VOLATILE",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005553 "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
5554 }
5555
5556# Check for user-visible strings broken across lines, which breaks the ability
5557# to grep for the string. Make exceptions when the previous string ends in a
5558# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
5559# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
5560 if ($line =~ /^\+\s*$String/ &&
5561 $prevline =~ /"\s*$/ &&
5562 $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
5563 if (WARN("SPLIT_STRING",
5564 "quoted string split across lines\n" . $hereprev) &&
5565 $fix &&
5566 $prevrawline =~ /^\+.*"\s*$/ &&
5567 $last_coalesced_string_linenr != $linenr - 1) {
5568 my $extracted_string = get_quoted_string($line, $rawline);
5569 my $comma_close = "";
5570 if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
5571 $comma_close = $1;
5572 }
5573
5574 fix_delete_line($fixlinenr - 1, $prevrawline);
5575 fix_delete_line($fixlinenr, $rawline);
5576 my $fixedline = $prevrawline;
5577 $fixedline =~ s/"\s*$//;
5578 $fixedline .= substr($extracted_string, 1) . trim($comma_close);
5579 fix_insert_line($fixlinenr - 1, $fixedline);
5580 $fixedline = $rawline;
5581 $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
5582 if ($fixedline !~ /\+\s*$/) {
5583 fix_insert_line($fixlinenr, $fixedline);
5584 }
5585 $last_coalesced_string_linenr = $linenr;
5586 }
5587 }
5588
5589# check for missing a space in a string concatenation
5590 if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
5591 WARN('MISSING_SPACE',
5592 "break quoted strings at a space character\n" . $hereprev);
5593 }
5594
5595# check for an embedded function name in a string when the function is known
5596# This does not work very well for -f --file checking as it depends on patch
5597# context providing the function name or a single line form for in-file
5598# function declarations
5599 if ($line =~ /^\+.*$String/ &&
5600 defined($context_function) &&
5601 get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5602 length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
5603 WARN("EMBEDDED_FUNCTION_NAME",
5604 "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
5605 }
5606
5607# check for spaces before a quoted newline
5608 if ($rawline =~ /^.*\".*\s\\n/) {
5609 if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
5610 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
5611 $fix) {
5612 $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
5613 }
5614
5615 }
5616
5617# concatenated string without spaces between elements
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02005618 if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
5619 if (CHK("CONCATENATED_STRING",
5620 "Concatenated strings should use spaces between elements\n" . $herecurr) &&
5621 $fix) {
5622 while ($line =~ /($String)/g) {
5623 my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
5624 $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
5625 $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
5626 }
5627 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005628 }
5629
5630# uncoalesced string fragments
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02005631 if ($line =~ /$String\s*"/) {
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02005632 if (WARN("STRING_FRAGMENTS",
5633 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
5634 $fix) {
5635 while ($line =~ /($String)(?=\s*")/g) {
5636 my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
5637 $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
5638 }
5639 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005640 }
5641
5642# check for non-standard and hex prefixed decimal printf formats
5643 my $show_L = 1; #don't show the same defect twice
5644 my $show_Z = 1;
5645 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
5646 my $string = substr($rawline, $-[1], $+[1] - $-[1]);
5647 $string =~ s/%%/__/g;
5648 # check for %L
5649 if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
5650 WARN("PRINTF_L",
5651 "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5652 $show_L = 0;
5653 }
5654 # check for %Z
5655 if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5656 WARN("PRINTF_Z",
5657 "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5658 $show_Z = 0;
5659 }
5660 # check for 0x<decimal>
5661 if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5662 ERROR("PRINTF_0XDECIMAL",
5663 "Prefixing 0x with decimal output is defective\n" . $herecurr);
5664 }
5665 }
5666
5667# check for line continuations in quoted strings with odd counts of "
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02005668 if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005669 WARN("LINE_CONTINUATIONS",
5670 "Avoid line continuations in quoted strings\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00005671 }
5672
5673# warn about #if 0
5674 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02005675 WARN("IF_0",
5676 "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
5677 }
5678
5679# warn about #if 1
5680 if ($line =~ /^.\s*\#\s*if\s+1\b/) {
5681 WARN("IF_1",
5682 "Consider removing the #if 1 and its #endif\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00005683 }
5684
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005685# check for needless "if (<foo>) fn(<foo>)" uses
5686 if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005687 my $tested = quotemeta($1);
5688 my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5689 if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5690 my $func = $1;
5691 if (WARN('NEEDLESS_IF',
5692 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5693 $fix) {
5694 my $do_fix = 1;
5695 my $leading_tabs = "";
5696 my $new_leading_tabs = "";
5697 if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5698 $leading_tabs = $1;
5699 } else {
5700 $do_fix = 0;
5701 }
5702 if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5703 $new_leading_tabs = $1;
5704 if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5705 $do_fix = 0;
5706 }
5707 } else {
5708 $do_fix = 0;
5709 }
5710 if ($do_fix) {
5711 fix_delete_line($fixlinenr - 1, $prevrawline);
5712 $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5713 }
5714 }
5715 }
5716 }
5717
5718# check for unnecessary "Out of Memory" messages
5719 if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5720 $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5721 (defined $1 || defined $3) &&
5722 $linenr > 3) {
5723 my $testval = $2;
5724 my $testline = $lines[$linenr - 3];
5725
5726 my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5727# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5728
Tom Rinic57383b2020-06-16 10:29:46 -04005729 if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
5730 $s !~ /\b__GFP_NOWARN\b/ ) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005731 WARN("OOM_MESSAGE",
5732 "Possible unnecessary 'out of memory' message\n" . $hereprev);
5733 }
5734 }
5735
5736# check for logging functions with KERN_<LEVEL>
5737 if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
5738 $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5739 my $level = $1;
5740 if (WARN("UNNECESSARY_KERN_LEVEL",
5741 "Possible unnecessary $level\n" . $herecurr) &&
5742 $fix) {
5743 $fixed[$fixlinenr] =~ s/\s*$level\s*//;
5744 }
5745 }
5746
5747# check for logging continuations
5748 if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
5749 WARN("LOGGING_CONTINUATION",
5750 "Avoid logging continuation uses where feasible\n" . $herecurr);
5751 }
5752
5753# check for mask then right shift without a parentheses
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02005754 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005755 $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5756 $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5757 WARN("MASK_THEN_SHIFT",
5758 "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5759 }
5760
5761# check for pointer comparisons to NULL
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02005762 if ($perl_version_ok) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005763 while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5764 my $val = $1;
5765 my $equal = "!";
5766 $equal = "" if ($4 eq "!=");
5767 if (CHK("COMPARISON_TO_NULL",
5768 "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5769 $fix) {
5770 $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5771 }
Joe Hershberger05622192011-10-18 10:06:59 +00005772 }
5773 }
5774
Tom Rini6b9709d2014-02-27 08:27:28 -05005775# check for bad placement of section $InitAttribute (e.g.: __initdata)
5776 if ($line =~ /(\b$InitAttribute\b)/) {
5777 my $attr = $1;
5778 if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
5779 my $ptr = $1;
5780 my $var = $2;
5781 if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
5782 ERROR("MISPLACED_INIT",
5783 "$attr should be placed after $var\n" . $herecurr)) ||
5784 ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
5785 WARN("MISPLACED_INIT",
5786 "$attr should be placed after $var\n" . $herecurr))) &&
5787 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005788 $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;
Tom Rini6b9709d2014-02-27 08:27:28 -05005789 }
5790 }
5791 }
5792
5793# check for $InitAttributeData (ie: __initdata) with const
5794 if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5795 my $attr = $1;
5796 $attr =~ /($InitAttributePrefix)(.*)/;
5797 my $attr_prefix = $1;
5798 my $attr_type = $2;
5799 if (ERROR("INIT_ATTRIBUTE",
5800 "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5801 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005802 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05005803 s/$InitAttributeData/${attr_prefix}initconst/;
5804 }
5805 }
5806
5807# check for $InitAttributeConst (ie: __initconst) without const
5808 if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5809 my $attr = $1;
5810 if (ERROR("INIT_ATTRIBUTE",
5811 "Use of $attr requires a separate use of const\n" . $herecurr) &&
5812 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005813 my $lead = $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05005814 /(^\+\s*(?:static\s+))/;
5815 $lead = rtrim($1);
5816 $lead = "$lead " if ($lead !~ /^\+$/);
5817 $lead = "${lead}const ";
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005818 $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5819 }
5820 }
5821
5822# check for __read_mostly with const non-pointer (should just be const)
5823 if ($line =~ /\b__read_mostly\b/ &&
5824 $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5825 if (ERROR("CONST_READ_MOSTLY",
5826 "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5827 $fix) {
5828 $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5829 }
5830 }
5831
5832# don't use __constant_<foo> functions outside of include/uapi/
5833 if ($realfile !~ m@^include/uapi/@ &&
5834 $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5835 my $constant_func = $1;
5836 my $func = $constant_func;
5837 $func =~ s/^__constant_//;
5838 if (WARN("CONSTANT_CONVERSION",
5839 "$constant_func should be $func\n" . $herecurr) &&
5840 $fix) {
5841 $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
Tom Rini6b9709d2014-02-27 08:27:28 -05005842 }
5843 }
5844
Joe Hershberger05622192011-10-18 10:06:59 +00005845# prefer usleep_range over udelay
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00005846 if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005847 my $delay = $1;
Joe Hershberger05622192011-10-18 10:06:59 +00005848 # ignore udelay's < 10, however
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005849 if (! ($delay < 10) ) {
Joe Hershberger05622192011-10-18 10:06:59 +00005850 CHK("USLEEP_RANGE",
Tom Rinic57383b2020-06-16 10:29:46 -04005851 "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005852 }
5853 if ($delay > 2000) {
5854 WARN("LONG_UDELAY",
5855 "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00005856 }
5857 }
5858
5859# warn about unexpectedly long msleep's
5860 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
5861 if ($1 < 20) {
5862 WARN("MSLEEP",
Tom Rinic57383b2020-06-16 10:29:46 -04005863 "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00005864 }
5865 }
5866
Tom Rini6b9709d2014-02-27 08:27:28 -05005867# check for comparisons of jiffies
5868 if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
5869 WARN("JIFFIES_COMPARISON",
5870 "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
5871 }
5872
5873# check for comparisons of get_jiffies_64()
5874 if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
5875 WARN("JIFFIES_COMPARISON",
5876 "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
5877 }
5878
Joe Hershberger05622192011-10-18 10:06:59 +00005879# warn about #ifdefs in C files
5880# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
5881# print "#ifdef in C files should be avoided\n";
5882# print "$herecurr";
5883# $clean = 0;
5884# }
5885
5886# warn about spacing in #ifdefs
5887 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05005888 if (ERROR("SPACING",
5889 "exactly one space required after that #$1\n" . $herecurr) &&
5890 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005891 $fixed[$fixlinenr] =~
Tom Rini6b9709d2014-02-27 08:27:28 -05005892 s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
5893 }
5894
Joe Hershberger05622192011-10-18 10:06:59 +00005895 }
5896
5897# check for spinlock_t definitions without a comment.
5898 if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5899 $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
5900 my $which = $1;
5901 if (!ctx_has_comment($first_line, $linenr)) {
5902 CHK("UNCOMMENTED_DEFINITION",
5903 "$1 definition without comment\n" . $herecurr);
5904 }
5905 }
5906# check for memory barriers without a comment.
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005907
5908 my $barriers = qr{
5909 mb|
5910 rmb|
5911 wmb|
5912 read_barrier_depends
5913 }x;
5914 my $barrier_stems = qr{
5915 mb__before_atomic|
5916 mb__after_atomic|
5917 store_release|
5918 load_acquire|
5919 store_mb|
5920 (?:$barriers)
5921 }x;
5922 my $all_barriers = qr{
5923 (?:$barriers)|
5924 smp_(?:$barrier_stems)|
5925 virt_(?:$barrier_stems)
5926 }x;
5927
5928 if ($line =~ /\b(?:$all_barriers)\s*\(/) {
Joe Hershberger05622192011-10-18 10:06:59 +00005929 if (!ctx_has_comment($first_line, $linenr)) {
Tom Rini6b9709d2014-02-27 08:27:28 -05005930 WARN("MEMORY_BARRIER",
5931 "memory barrier without comment\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00005932 }
5933 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005934
5935 my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5936
5937 if ($realfile !~ m@^include/asm-generic/@ &&
5938 $realfile !~ m@/barrier\.h$@ &&
5939 $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5940 $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5941 WARN("MEMORY_BARRIER",
5942 "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5943 }
5944
5945# check for waitqueue_active without a comment.
5946 if ($line =~ /\bwaitqueue_active\s*\(/) {
5947 if (!ctx_has_comment($first_line, $linenr)) {
5948 WARN("WAITQUEUE_ACTIVE",
5949 "waitqueue_active without comment\n" . $herecurr);
5950 }
5951 }
5952
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02005953# check for smp_read_barrier_depends and read_barrier_depends
5954 if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
5955 WARN("READ_BARRIER_DEPENDS",
5956 "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
5957 }
5958
Joe Hershberger05622192011-10-18 10:06:59 +00005959# check of hardware specific defines
5960 if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5961 CHK("ARCH_DEFINES",
5962 "architecture specific defines should be avoided\n" . $herecurr);
5963 }
5964
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005965# check that the storage class is not after a type
5966 if ($line =~ /\b($Type)\s+($Storage)\b/) {
Joe Hershberger05622192011-10-18 10:06:59 +00005967 WARN("STORAGE_CLASS",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005968 "storage class '$2' should be located before type '$1'\n" . $herecurr);
5969 }
5970# Check that the storage class is at the beginning of a declaration
5971 if ($line =~ /\b$Storage\b/ &&
5972 $line !~ /^.\s*$Storage/ &&
5973 $line =~ /^.\s*(.+?)\$Storage\s/ &&
5974 $1 !~ /[\,\)]\s*$/) {
5975 WARN("STORAGE_CLASS",
5976 "storage class should be at the beginning of the declaration\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00005977 }
5978
5979# check the location of the inline attribute, that it is between
5980# storage class and type.
5981 if ($line =~ /\b$Type\s+$Inline\b/ ||
5982 $line =~ /\b$Inline\s+$Storage\b/) {
5983 ERROR("INLINE_LOCATION",
5984 "inline keyword should sit between storage class and type\n" . $herecurr);
5985 }
5986
5987# Check for __inline__ and __inline, prefer inline
Tom Rini6b9709d2014-02-27 08:27:28 -05005988 if ($realfile !~ m@\binclude/uapi/@ &&
5989 $line =~ /\b(__inline__|__inline)\b/) {
5990 if (WARN("INLINE",
5991 "plain inline is preferred over $1\n" . $herecurr) &&
5992 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02005993 $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
Tom Rini6b9709d2014-02-27 08:27:28 -05005994
5995 }
Joe Hershberger05622192011-10-18 10:06:59 +00005996 }
5997
5998# Check for __attribute__ packed, prefer __packed
Tom Rini6b9709d2014-02-27 08:27:28 -05005999 if ($realfile !~ m@\binclude/uapi/@ &&
6000 $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
Joe Hershberger05622192011-10-18 10:06:59 +00006001 WARN("PREFER_PACKED",
6002 "__packed is preferred over __attribute__((packed))\n" . $herecurr);
6003 }
6004
6005# Check for __attribute__ aligned, prefer __aligned
Tom Rini6b9709d2014-02-27 08:27:28 -05006006 if ($realfile !~ m@\binclude/uapi/@ &&
6007 $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
Joe Hershberger05622192011-10-18 10:06:59 +00006008 WARN("PREFER_ALIGNED",
6009 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
6010 }
6011
Tom Rinic57383b2020-06-16 10:29:46 -04006012# Check for __attribute__ section, prefer __section
6013 if ($realfile !~ m@\binclude/uapi/@ &&
6014 $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
6015 my $old = substr($rawline, $-[1], $+[1] - $-[1]);
6016 my $new = substr($old, 1, -1);
6017 if (WARN("PREFER_SECTION",
6018 "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
6019 $fix) {
6020 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
6021 }
6022 }
6023
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006024# Check for __attribute__ format(printf, prefer __printf
Tom Rini6b9709d2014-02-27 08:27:28 -05006025 if ($realfile !~ m@\binclude/uapi/@ &&
6026 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
6027 if (WARN("PREFER_PRINTF",
6028 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
6029 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006030 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
Tom Rini6b9709d2014-02-27 08:27:28 -05006031
6032 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006033 }
6034
6035# Check for __attribute__ format(scanf, prefer __scanf
Tom Rini6b9709d2014-02-27 08:27:28 -05006036 if ($realfile !~ m@\binclude/uapi/@ &&
6037 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
6038 if (WARN("PREFER_SCANF",
6039 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
6040 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006041 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
6042 }
6043 }
6044
6045# Check for __attribute__ weak, or __weak declarations (may have link issues)
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006046 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006047 $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6048 ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6049 $line =~ /\b__weak\b/)) {
6050 ERROR("WEAK_DECLARATION",
6051 "Using weak declarations can have unintended link defects\n" . $herecurr);
6052 }
6053
6054# check for c99 types like uint8_t used outside of uapi/ and tools/
6055 if ($realfile !~ m@\binclude/uapi/@ &&
6056 $realfile !~ m@\btools/@ &&
6057 $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6058 my $type = $1;
6059 if ($type =~ /\b($typeC99Typedefs)\b/) {
6060 $type = $1;
6061 my $kernel_type = 'u';
6062 $kernel_type = 's' if ($type =~ /^_*[si]/);
6063 $type =~ /(\d+)/;
6064 $kernel_type .= $1;
6065 if (CHK("PREFER_KERNEL_TYPES",
6066 "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6067 $fix) {
6068 $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6069 }
6070 }
6071 }
6072
6073# check for cast of C90 native int or longer types constants
6074 if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6075 my $cast = $1;
6076 my $const = $2;
6077 if (WARN("TYPECAST_INT_CONSTANT",
6078 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
6079 $fix) {
6080 my $suffix = "";
6081 my $newconst = $const;
6082 $newconst =~ s/${Int_type}$//;
6083 $suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6084 if ($cast =~ /\blong\s+long\b/) {
6085 $suffix .= 'LL';
6086 } elsif ($cast =~ /\blong\b/) {
6087 $suffix .= 'L';
6088 }
6089 $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
Tom Rini6b9709d2014-02-27 08:27:28 -05006090 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006091 }
6092
Joe Hershberger05622192011-10-18 10:06:59 +00006093# check for sizeof(&)
6094 if ($line =~ /\bsizeof\s*\(\s*\&/) {
6095 WARN("SIZEOF_ADDRESS",
6096 "sizeof(& should be avoided\n" . $herecurr);
6097 }
6098
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006099# check for sizeof without parenthesis
6100 if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05006101 if (WARN("SIZEOF_PARENTHESIS",
6102 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6103 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006104 $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
Tom Rini6b9709d2014-02-27 08:27:28 -05006105 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006106 }
6107
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006108# check for struct spinlock declarations
6109 if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
6110 WARN("USE_SPINLOCK_T",
6111 "struct spinlock should be spinlock_t\n" . $herecurr);
6112 }
6113
Tom Rini6b9709d2014-02-27 08:27:28 -05006114# check for seq_printf uses that could be seq_puts
6115 if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6116 my $fmt = get_quoted_string($line, $rawline);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006117 $fmt =~ s/%%//g;
6118 if ($fmt !~ /%/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05006119 if (WARN("PREFER_SEQ_PUTS",
6120 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6121 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006122 $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
Tom Rini6b9709d2014-02-27 08:27:28 -05006123 }
6124 }
6125 }
6126
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006127# check for vsprintf extension %p<foo> misuses
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006128 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006129 defined $stat &&
6130 $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
6131 $1 !~ /^_*volatile_*$/) {
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006132 my $stat_real;
6133
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006134 my $lc = $stat =~ tr@\n@@;
6135 $lc = $lc + $linenr;
6136 for (my $count = $linenr; $count <= $lc; $count++) {
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006137 my $specifier;
6138 my $extension;
Tom Rinic57383b2020-06-16 10:29:46 -04006139 my $qualifier;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006140 my $bad_specifier = "";
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006141 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
6142 $fmt =~ s/%%//g;
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006143
Tom Rinic57383b2020-06-16 10:29:46 -04006144 while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006145 $specifier = $1;
6146 $extension = $2;
Tom Rinic57383b2020-06-16 10:29:46 -04006147 $qualifier = $3;
6148 if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
6149 ($extension eq "f" &&
6150 defined $qualifier && $qualifier !~ /^w/)) {
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006151 $bad_specifier = $specifier;
6152 last;
6153 }
6154 if ($extension eq "x" && !defined($stat_real)) {
6155 if (!defined($stat_real)) {
6156 $stat_real = get_stat_real($linenr, $lc);
6157 }
6158 WARN("VSPRINTF_SPECIFIER_PX",
6159 "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");
6160 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006161 }
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006162 if ($bad_specifier ne "") {
6163 my $stat_real = get_stat_real($linenr, $lc);
6164 my $ext_type = "Invalid";
6165 my $use = "";
6166 if ($bad_specifier =~ /p[Ff]/) {
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006167 $use = " - use %pS instead";
6168 $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
6169 }
6170
6171 WARN("VSPRINTF_POINTER_EXTENSION",
6172 "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006173 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006174 }
6175 }
6176
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006177# Check for misused memsets
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006178 if ($perl_version_ok &&
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006179 defined $stat &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006180 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006181
6182 my $ms_addr = $2;
6183 my $ms_val = $7;
6184 my $ms_size = $12;
6185
6186 if ($ms_size =~ /^(0x|)0$/i) {
6187 ERROR("MEMSET",
6188 "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6189 } elsif ($ms_size =~ /^(0x|)1$/i) {
6190 WARN("MEMSET",
6191 "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6192 }
6193 }
6194
Tom Rini6b9709d2014-02-27 08:27:28 -05006195# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006196# if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006197# defined $stat &&
6198# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6199# if (WARN("PREFER_ETHER_ADDR_COPY",
6200# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6201# $fix) {
6202# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6203# }
6204# }
6205
6206# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006207# if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006208# defined $stat &&
6209# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6210# WARN("PREFER_ETHER_ADDR_EQUAL",
6211# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6212# }
6213
6214# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
6215# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006216# if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006217# defined $stat &&
6218# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6219#
6220# my $ms_val = $7;
6221#
6222# if ($ms_val =~ /^(?:0x|)0+$/i) {
6223# if (WARN("PREFER_ETH_ZERO_ADDR",
6224# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6225# $fix) {
6226# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6227# }
6228# } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6229# if (WARN("PREFER_ETH_BROADCAST_ADDR",
6230# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6231# $fix) {
6232# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6233# }
6234# }
6235# }
Tom Rini6b9709d2014-02-27 08:27:28 -05006236
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006237# typecasts on min/max could be min_t/max_t
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006238 if ($perl_version_ok &&
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006239 defined $stat &&
6240 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6241 if (defined $2 || defined $7) {
6242 my $call = $1;
6243 my $cast1 = deparenthesize($2);
6244 my $arg1 = $3;
6245 my $cast2 = deparenthesize($7);
6246 my $arg2 = $8;
6247 my $cast;
6248
6249 if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6250 $cast = "$cast1 or $cast2";
6251 } elsif ($cast1 ne "") {
6252 $cast = $cast1;
6253 } else {
6254 $cast = $cast2;
6255 }
6256 WARN("MINMAX",
6257 "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6258 }
6259 }
6260
6261# check usleep_range arguments
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006262 if ($perl_version_ok &&
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006263 defined $stat &&
6264 $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
6265 my $min = $1;
6266 my $max = $7;
6267 if ($min eq $max) {
6268 WARN("USLEEP_RANGE",
Tom Rinic57383b2020-06-16 10:29:46 -04006269 "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006270 } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
6271 $min > $max) {
6272 WARN("USLEEP_RANGE",
Tom Rinic57383b2020-06-16 10:29:46 -04006273 "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006274 }
6275 }
6276
Tom Rini6b9709d2014-02-27 08:27:28 -05006277# check for naked sscanf
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006278 if ($perl_version_ok &&
Tom Rini6b9709d2014-02-27 08:27:28 -05006279 defined $stat &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006280 $line =~ /\bsscanf\b/ &&
Tom Rini6b9709d2014-02-27 08:27:28 -05006281 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6282 $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6283 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6284 my $lc = $stat =~ tr@\n@@;
6285 $lc = $lc + $linenr;
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006286 my $stat_real = get_stat_real($linenr, $lc);
Tom Rini6b9709d2014-02-27 08:27:28 -05006287 WARN("NAKED_SSCANF",
6288 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6289 }
6290
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006291# check for simple sscanf that should be kstrto<foo>
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006292 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006293 defined $stat &&
6294 $line =~ /\bsscanf\b/) {
6295 my $lc = $stat =~ tr@\n@@;
6296 $lc = $lc + $linenr;
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006297 my $stat_real = get_stat_real($linenr, $lc);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006298 if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6299 my $format = $6;
6300 my $count = $format =~ tr@%@%@;
6301 if ($count == 1 &&
6302 $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6303 WARN("SSCANF_TO_KSTRTO",
6304 "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6305 }
6306 }
6307 }
6308
Tom Rini6b9709d2014-02-27 08:27:28 -05006309# check for new externs in .h files.
6310 if ($realfile =~ /\.h$/ &&
6311 $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6312 if (CHK("AVOID_EXTERNS",
6313 "extern prototypes should be avoided in .h files\n" . $herecurr) &&
6314 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006315 $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
Tom Rini6b9709d2014-02-27 08:27:28 -05006316 }
6317 }
6318
Joe Hershberger05622192011-10-18 10:06:59 +00006319# check for new externs in .c files.
6320 if ($realfile =~ /\.c$/ && defined $stat &&
6321 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6322 {
6323 my $function_name = $1;
6324 my $paren_space = $2;
6325
6326 my $s = $stat;
6327 if (defined $cond) {
6328 substr($s, 0, length($cond), '');
6329 }
6330 if ($s =~ /^\s*;/ &&
6331 $function_name ne 'uninitialized_var')
6332 {
6333 WARN("AVOID_EXTERNS",
6334 "externs should be avoided in .c files\n" . $herecurr);
6335 }
6336
6337 if ($paren_space =~ /\n/) {
6338 WARN("FUNCTION_ARGUMENTS",
6339 "arguments for function declarations should follow identifier\n" . $herecurr);
6340 }
6341
6342 } elsif ($realfile =~ /\.c$/ && defined $stat &&
6343 $stat =~ /^.\s*extern\s+/)
6344 {
6345 WARN("AVOID_EXTERNS",
6346 "externs should be avoided in .c files\n" . $herecurr);
6347 }
6348
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006349# check for function declarations that have arguments without identifier names
Tom Rinic57383b2020-06-16 10:29:46 -04006350# while avoiding uninitialized_var(x)
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006351 if (defined $stat &&
Tom Rinic57383b2020-06-16 10:29:46 -04006352 $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:($Ident)|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6353 (!defined($1) ||
6354 (defined($1) && $1 ne "uninitialized_var")) &&
6355 $2 ne "void") {
6356 my $args = trim($2);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006357 while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6358 my $arg = trim($1);
Tom Rinic57383b2020-06-16 10:29:46 -04006359 if ($arg =~ /^$Type$/ &&
6360 $arg !~ /enum\s+$Ident$/) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006361 WARN("FUNCTION_ARGUMENTS",
6362 "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6363 }
6364 }
6365 }
6366
6367# check for function definitions
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006368 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006369 defined $stat &&
6370 $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6371 $context_function = $1;
6372
6373# check for multiline function definition with misplaced open brace
6374 my $ok = 0;
6375 my $cnt = statement_rawlines($stat);
6376 my $herectx = $here . "\n";
6377 for (my $n = 0; $n < $cnt; $n++) {
6378 my $rl = raw_line($linenr, $n);
6379 $herectx .= $rl . "\n";
6380 $ok = 1 if ($rl =~ /^[ \+]\{/);
6381 $ok = 1 if ($rl =~ /\{/ && $n == 0);
6382 last if $rl =~ /^[ \+].*\{/;
6383 }
6384 if (!$ok) {
6385 ERROR("OPEN_BRACE",
6386 "open brace '{' following function definitions go on the next line\n" . $herectx);
6387 }
6388 }
6389
Joe Hershberger05622192011-10-18 10:06:59 +00006390# checks for new __setup's
6391 if ($rawline =~ /\b__setup\("([^"]*)"/) {
6392 my $name = $1;
6393
6394 if (!grep(/$name/, @setup_docs)) {
6395 CHK("UNDOCUMENTED_SETUP",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006396 "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00006397 }
6398 }
6399
Tom Rinic57383b2020-06-16 10:29:46 -04006400# check for pointless casting of alloc functions
6401 if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
Joe Hershberger05622192011-10-18 10:06:59 +00006402 WARN("UNNECESSARY_CASTS",
6403 "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
6404 }
6405
Tom Rini6b9709d2014-02-27 08:27:28 -05006406# alloc style
6407# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006408 if ($perl_version_ok &&
Tom Rinic57383b2020-06-16 10:29:46 -04006409 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05006410 CHK("ALLOC_SIZEOF_STRUCT",
6411 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6412 }
6413
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006414# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006415 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006416 defined $stat &&
6417 $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
6418 my $oldfunc = $3;
6419 my $a1 = $4;
6420 my $a2 = $10;
6421 my $newfunc = "kmalloc_array";
6422 $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
6423 my $r1 = $a1;
6424 my $r2 = $a2;
6425 if ($a1 =~ /^sizeof\s*\S/) {
6426 $r1 = $a2;
6427 $r2 = $a1;
6428 }
6429 if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6430 !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006431 my $cnt = statement_rawlines($stat);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006432 my $herectx = get_stat_here($linenr, $cnt, $here);
6433
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006434 if (WARN("ALLOC_WITH_MULTIPLY",
6435 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
6436 $cnt == 1 &&
6437 $fix) {
6438 $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;
6439 }
6440 }
6441 }
6442
Tom Rini6b9709d2014-02-27 08:27:28 -05006443# check for krealloc arg reuse
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006444 if ($perl_version_ok &&
6445 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
6446 $1 eq $3) {
Tom Rini6b9709d2014-02-27 08:27:28 -05006447 WARN("KREALLOC_ARG_REUSE",
6448 "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6449 }
6450
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006451# check for alloc argument mismatch
6452 if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
6453 WARN("ALLOC_ARRAY_ARGS",
6454 "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00006455 }
6456
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006457# check for multiple semicolons
6458 if ($line =~ /;\s*;\s*$/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05006459 if (WARN("ONE_SEMICOLON",
6460 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6461 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006462 $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6463 }
6464 }
6465
6466# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6467 if ($realfile !~ m@^include/uapi/@ &&
6468 $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
6469 my $ull = "";
6470 $ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
6471 if (CHK("BIT_MACRO",
6472 "Prefer using the BIT$ull macro\n" . $herecurr) &&
6473 $fix) {
6474 $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
6475 }
6476 }
6477
6478# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
6479 if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
6480 my $config = $1;
6481 if (WARN("PREFER_IS_ENABLED",
6482 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
6483 $fix) {
6484 $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
Tom Rini6b9709d2014-02-27 08:27:28 -05006485 }
6486 }
6487
Robert P. J. Dayfc0b5942016-09-07 14:27:59 -04006488# check for case / default statements not preceded by break/fallthrough/switch
Tom Rini6b9709d2014-02-27 08:27:28 -05006489 if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6490 my $has_break = 0;
6491 my $has_statement = 0;
6492 my $count = 0;
6493 my $prevline = $linenr;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006494 while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
Tom Rini6b9709d2014-02-27 08:27:28 -05006495 $prevline--;
6496 my $rline = $rawlines[$prevline - 1];
6497 my $fline = $lines[$prevline - 1];
6498 last if ($fline =~ /^\@\@/);
6499 next if ($fline =~ /^\-/);
6500 next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6501 $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6502 next if ($fline =~ /^.[\s$;]*$/);
6503 $has_statement = 1;
6504 $count++;
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006505 $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
Tom Rini6b9709d2014-02-27 08:27:28 -05006506 }
6507 if (!$has_break && $has_statement) {
6508 WARN("MISSING_BREAK",
Robert P. J. Dayfc0b5942016-09-07 14:27:59 -04006509 "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
Tom Rini6b9709d2014-02-27 08:27:28 -05006510 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006511 }
6512
Tom Rinic57383b2020-06-16 10:29:46 -04006513# check for /* fallthrough */ like comment, prefer fallthrough;
6514 my @fallthroughs = (
6515 'fallthrough',
6516 '@fallthrough@',
6517 'lint -fallthrough[ \t]*',
6518 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
6519 '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
6520 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6521 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6522 );
6523 if ($raw_comment ne '') {
6524 foreach my $ft (@fallthroughs) {
6525 if ($raw_comment =~ /$ft/) {
6526 my $msg_level = \&WARN;
6527 $msg_level = \&CHK if ($file);
6528 &{$msg_level}("PREFER_FALLTHROUGH",
6529 "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
6530 last;
6531 }
6532 }
6533 }
6534
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006535# check for switch/default statements without a break;
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006536 if ($perl_version_ok &&
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006537 defined $stat &&
6538 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006539 my $cnt = statement_rawlines($stat);
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006540 my $herectx = get_stat_here($linenr, $cnt, $here);
6541
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006542 WARN("DEFAULT_NO_BREAK",
6543 "switch default: should use break\n" . $herectx);
Eric Nelson172a3a82012-05-02 20:32:18 -07006544 }
6545
Joe Hershberger05622192011-10-18 10:06:59 +00006546# check for gcc specific __FUNCTION__
Tom Rini6b9709d2014-02-27 08:27:28 -05006547 if ($line =~ /\b__FUNCTION__\b/) {
6548 if (WARN("USE_FUNC",
6549 "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
6550 $fix) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006551 $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
Tom Rini6b9709d2014-02-27 08:27:28 -05006552 }
Joe Hershberger05622192011-10-18 10:06:59 +00006553 }
6554
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006555# check for uses of __DATE__, __TIME__, __TIMESTAMP__
6556 while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
6557 ERROR("DATE_TIME",
6558 "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
6559 }
6560
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006561# check for use of yield()
6562 if ($line =~ /\byield\s*\(\s*\)/) {
6563 WARN("YIELD",
6564 "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr);
6565 }
6566
Tom Rini6b9709d2014-02-27 08:27:28 -05006567# check for comparisons against true and false
6568 if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6569 my $lead = $1;
6570 my $arg = $2;
6571 my $test = $3;
6572 my $otype = $4;
6573 my $trail = $5;
6574 my $op = "!";
6575
6576 ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6577
6578 my $type = lc($otype);
6579 if ($type =~ /^(?:true|false)$/) {
6580 if (("$test" eq "==" && "$type" eq "true") ||
6581 ("$test" eq "!=" && "$type" eq "false")) {
6582 $op = "";
6583 }
6584
6585 CHK("BOOL_COMPARISON",
6586 "Using comparison to $otype is error prone\n" . $herecurr);
6587
6588## maybe suggesting a correct construct would better
6589## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6590
6591 }
6592 }
6593
Joe Hershberger05622192011-10-18 10:06:59 +00006594# check for semaphores initialized locked
6595 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6596 WARN("CONSIDER_COMPLETION",
6597 "consider using a completion\n" . $herecurr);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006598 }
Joe Hershberger05622192011-10-18 10:06:59 +00006599
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006600# recommend kstrto* over simple_strto* and strict_strto*
6601 if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
Joe Hershberger05622192011-10-18 10:06:59 +00006602 WARN("CONSIDER_KSTRTO",
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006603 "$1 is obsolete, use k$3 instead\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00006604 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006605
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006606# check for __initcall(), use device_initcall() explicitly or more appropriate function please
Joe Hershberger05622192011-10-18 10:06:59 +00006607 if ($line =~ /^.\s*__initcall\s*\(/) {
6608 WARN("USE_DEVICE_INITCALL",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006609 "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00006610 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006611
Tom Rinic57383b2020-06-16 10:29:46 -04006612# check for spin_is_locked(), suggest lockdep instead
6613 if ($line =~ /\bspin_is_locked\(/) {
6614 WARN("USE_LOCKDEP",
6615 "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
6616 }
6617
6618# check for deprecated apis
6619 if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
6620 my $deprecated_api = $1;
6621 my $new_api = $deprecated_apis{$deprecated_api};
6622 WARN("DEPRECATED_API",
6623 "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
6624 }
6625
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006626# check for various structs that are normally const (ops, kgdb, device_tree)
6627# and avoid what seem like struct definitions 'struct foo {'
Joe Hershberger05622192011-10-18 10:06:59 +00006628 if ($line !~ /\bconst\b/ &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006629 $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
Joe Hershberger05622192011-10-18 10:06:59 +00006630 WARN("CONST_STRUCT",
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006631 "struct $1 should normally be const\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00006632 }
6633
6634# use of NR_CPUS is usually wrong
6635# ignore definitions of NR_CPUS and usage to define arrays as likely right
6636 if ($line =~ /\bNR_CPUS\b/ &&
6637 $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6638 $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6639 $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6640 $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6641 $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6642 {
6643 WARN("NR_CPUS",
6644 "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6645 }
6646
Tom Rini6b9709d2014-02-27 08:27:28 -05006647# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
6648 if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
6649 ERROR("DEFINE_ARCH_HAS",
6650 "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
6651 }
6652
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006653# likely/unlikely comparisons similar to "(likely(foo) > 0)"
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006654 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006655 $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6656 WARN("LIKELY_MISUSE",
6657 "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
Joe Hershberger05622192011-10-18 10:06:59 +00006658 }
6659
Tom Rinic57383b2020-06-16 10:29:46 -04006660# nested likely/unlikely calls
6661 if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
6662 WARN("LIKELY_MISUSE",
6663 "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
6664 }
6665
Joe Hershberger05622192011-10-18 10:06:59 +00006666# whine mightly about in_atomic
6667 if ($line =~ /\bin_atomic\s*\(/) {
6668 if ($realfile =~ m@^drivers/@) {
6669 ERROR("IN_ATOMIC",
6670 "do not use in_atomic in drivers\n" . $herecurr);
6671 } elsif ($realfile !~ m@^kernel/@) {
6672 WARN("IN_ATOMIC",
6673 "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6674 }
6675 }
6676
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006677# check for mutex_trylock_recursive usage
6678 if ($line =~ /mutex_trylock_recursive/) {
6679 ERROR("LOCKING",
6680 "recursive locking is bad, do not use this ever.\n" . $herecurr);
6681 }
6682
Joe Hershberger05622192011-10-18 10:06:59 +00006683# check for lockdep_set_novalidate_class
6684 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
6685 $line =~ /__lockdep_no_validate__\s*\)/ ) {
6686 if ($realfile !~ m@^kernel/lockdep@ &&
6687 $realfile !~ m@^include/linux/lockdep@ &&
6688 $realfile !~ m@^drivers/base/core@) {
6689 ERROR("LOCKDEP",
6690 "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
6691 }
6692 }
6693
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006694 if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6695 $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
Joe Hershberger05622192011-10-18 10:06:59 +00006696 WARN("EXPORTED_WORLD_WRITABLE",
6697 "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
6698 }
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006699
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006700# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
6701# and whether or not function naming is typical and if
6702# DEVICE_ATTR permissions uses are unusual too
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006703 if ($perl_version_ok &&
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006704 defined $stat &&
6705 $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*\)/) {
6706 my $var = $1;
6707 my $perms = $2;
6708 my $show = $3;
6709 my $store = $4;
6710 my $octal_perms = perms_to_octal($perms);
6711 if ($show =~ /^${var}_show$/ &&
6712 $store =~ /^${var}_store$/ &&
6713 $octal_perms eq "0644") {
6714 if (WARN("DEVICE_ATTR_RW",
6715 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
6716 $fix) {
6717 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
6718 }
6719 } elsif ($show =~ /^${var}_show$/ &&
6720 $store =~ /^NULL$/ &&
6721 $octal_perms eq "0444") {
6722 if (WARN("DEVICE_ATTR_RO",
6723 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
6724 $fix) {
6725 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
6726 }
6727 } elsif ($show =~ /^NULL$/ &&
6728 $store =~ /^${var}_store$/ &&
6729 $octal_perms eq "0200") {
6730 if (WARN("DEVICE_ATTR_WO",
6731 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
6732 $fix) {
6733 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
6734 }
6735 } elsif ($octal_perms eq "0644" ||
6736 $octal_perms eq "0444" ||
6737 $octal_perms eq "0200") {
6738 my $newshow = "$show";
6739 $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
6740 my $newstore = $store;
6741 $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
6742 my $rename = "";
6743 if ($show ne $newshow) {
6744 $rename .= " '$show' to '$newshow'";
6745 }
6746 if ($store ne $newstore) {
6747 $rename .= " '$store' to '$newstore'";
6748 }
6749 WARN("DEVICE_ATTR_FUNCTIONS",
6750 "Consider renaming function(s)$rename\n" . $herecurr);
6751 } else {
6752 WARN("DEVICE_ATTR_PERMS",
6753 "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
6754 }
6755 }
6756
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006757# Mode permission misuses where it seems decimal should be octal
6758# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006759# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
6760# specific definition of not visible in sysfs.
6761# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
6762# use the default permissions
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006763 if ($perl_version_ok &&
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006764 defined $stat &&
6765 $line =~ /$mode_perms_search/) {
6766 foreach my $entry (@mode_permission_funcs) {
6767 my $func = $entry->[0];
6768 my $arg_pos = $entry->[1];
6769
6770 my $lc = $stat =~ tr@\n@@;
6771 $lc = $lc + $linenr;
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006772 my $stat_real = get_stat_real($linenr, $lc);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006773
6774 my $skip_args = "";
6775 if ($arg_pos > 1) {
6776 $arg_pos--;
6777 $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
6778 }
6779 my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6780 if ($stat =~ /$test/) {
6781 my $val = $1;
6782 $val = $6 if ($skip_args ne "");
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006783 if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
6784 (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
6785 ($val =~ /^$Octal$/ && length($val) ne 4))) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006786 ERROR("NON_OCTAL_PERMISSIONS",
6787 "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6788 }
6789 if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
6790 ERROR("EXPORTED_WORLD_WRITABLE",
6791 "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
6792 }
6793 }
6794 }
6795 }
6796
6797# check for uses of S_<PERMS> that could be octal for readability
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006798 while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
6799 my $oval = $1;
6800 my $octal = perms_to_octal($oval);
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006801 if (WARN("SYMBOLIC_PERMS",
6802 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6803 $fix) {
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006804 $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006805 }
6806 }
6807
6808# validate content of MODULE_LICENSE against list from include/linux/module.h
6809 if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
6810 my $extracted_string = get_quoted_string($line, $rawline);
6811 my $valid_licenses = qr{
6812 GPL|
6813 GPL\ v2|
6814 GPL\ and\ additional\ rights|
6815 Dual\ BSD/GPL|
6816 Dual\ MIT/GPL|
6817 Dual\ MPL/GPL|
6818 Proprietary
6819 }x;
6820 if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
6821 WARN("MODULE_LICENSE",
6822 "unknown module license " . $extracted_string . "\n" . $herecurr);
6823 }
6824 }
Tom Rinic57383b2020-06-16 10:29:46 -04006825
6826# check for sysctl duplicate constants
6827 if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
6828 WARN("DUPLICATED_SYSCTL_CONST",
6829 "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
6830 }
Joe Hershberger05622192011-10-18 10:06:59 +00006831 }
6832
6833 # If we have no input at all, then there is nothing to report on
6834 # so just keep quiet.
6835 if ($#rawlines == -1) {
6836 exit(0);
6837 }
6838
6839 # In mailback mode only produce a report in the negative, for
6840 # things that appear to be patches.
6841 if ($mailback && ($clean == 1 || !$is_patch)) {
6842 exit(0);
6843 }
6844
6845 # This is not a patch, and we are are in 'no-patch' mode so
6846 # just keep quiet.
6847 if (!$chk_patch && !$is_patch) {
6848 exit(0);
6849 }
6850
Heinrich Schuchardtc398f2d2018-04-04 15:39:20 +02006851 if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
Joe Hershberger05622192011-10-18 10:06:59 +00006852 ERROR("NOT_UNIFIED_DIFF",
6853 "Does not appear to be a unified-diff format patch\n");
6854 }
Heinrich Schuchardtc261fef2019-10-19 09:06:38 +02006855 if ($is_patch && $has_commit_log && $chk_signoff) {
6856 if ($signoff == 0) {
6857 ERROR("MISSING_SIGN_OFF",
6858 "Missing Signed-off-by: line(s)\n");
6859 } elsif (!$authorsignoff) {
6860 WARN("NO_AUTHOR_SIGN_OFF",
6861 "Missing Signed-off-by: line by nominal patch author '$author'\n");
6862 }
Joe Hershberger05622192011-10-18 10:06:59 +00006863 }
6864
6865 print report_dump();
6866 if ($summary && !($clean == 1 && $quiet == 1)) {
6867 print "$filename " if ($summary_file);
6868 print "total: $cnt_error errors, $cnt_warn warnings, " .
6869 (($check)? "$cnt_chk checks, " : "") .
6870 "$cnt_lines lines checked\n";
Joe Hershberger05622192011-10-18 10:06:59 +00006871 }
6872
6873 if ($quiet == 0) {
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006874 # If there were any defects found and not already fixing them
6875 if (!$clean and !$fix) {
6876 print << "EOM"
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006877
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006878NOTE: For some of the reported defects, checkpatch may be able to
6879 mechanically convert to the typical style using --fix or --fix-inplace.
6880EOM
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00006881 }
Joe Hershberger05622192011-10-18 10:06:59 +00006882 # If there were whitespace errors which cleanpatch can fix
6883 # then suggest that.
6884 if ($rpt_cleaners) {
Joe Hershberger05622192011-10-18 10:06:59 +00006885 $rpt_cleaners = 0;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006886 print << "EOM"
6887
6888NOTE: Whitespace errors detected.
6889 You may wish to use scripts/cleanpatch or scripts/cleanfile
6890EOM
Joe Hershberger05622192011-10-18 10:06:59 +00006891 }
6892 }
6893
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006894 if ($clean == 0 && $fix &&
6895 ("@rawlines" ne "@fixed" ||
6896 $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
Tom Rini6b9709d2014-02-27 08:27:28 -05006897 my $newfile = $filename;
6898 $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
6899 my $linecount = 0;
6900 my $f;
6901
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006902 @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6903
Tom Rini6b9709d2014-02-27 08:27:28 -05006904 open($f, '>', $newfile)
6905 or die "$P: Can't open $newfile for write\n";
6906 foreach my $fixed_line (@fixed) {
6907 $linecount++;
6908 if ($file) {
6909 if ($linecount > 3) {
6910 $fixed_line =~ s/^\+//;
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006911 print $f $fixed_line . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05006912 }
6913 } else {
6914 print $f $fixed_line . "\n";
6915 }
6916 }
6917 close($f);
6918
6919 if (!$quiet) {
6920 print << "EOM";
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006921
Tom Rini6b9709d2014-02-27 08:27:28 -05006922Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
6923
6924Do _NOT_ trust the results written to this file.
6925Do _NOT_ submit these changes without inspecting them for correctness.
6926
6927This EXPERIMENTAL file is simply a convenience to help rewrite patches.
6928No warranties, expressed or implied...
Tom Rini6b9709d2014-02-27 08:27:28 -05006929EOM
6930 }
Joe Hershberger05622192011-10-18 10:06:59 +00006931 }
6932
Heinrich Schuchardt6305db92017-09-12 09:57:45 +02006933 if ($quiet == 0) {
6934 print "\n";
6935 if ($clean == 1) {
6936 print "$vname has no obvious style problems and is ready for submission.\n";
6937 } else {
6938 print "$vname has style problems, please review.\n";
6939 }
Joe Hershberger05622192011-10-18 10:06:59 +00006940 }
Joe Hershberger05622192011-10-18 10:06:59 +00006941 return $clean;
6942}