blob: c27d2312cfc307f4469ce7322b06e5025e2fb017 [file] [log] [blame]
Kamil Rytarowskicb77f0d2017-05-07 23:25:26 +02001#!/usr/bin/env perl
Joe Perches882ea1d2018-06-07 17:04:33 -07002# SPDX-License-Identifier: GPL-2.0
3#
Dave Jonesdbf004d2010-01-12 16:59:52 -05004# (c) 2001, Dave Jones. (the file handling bit)
Andy Whitcroft00df3442007-06-08 13:47:06 -07005# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
Andy Whitcroft2a5a2c22009-01-06 14:41:23 -08006# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
Andy Whitcroft015830be2010-10-26 14:23:17 -07007# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
Joe Perches882ea1d2018-06-07 17:04:33 -07008# (c) 2010-2018 Joe Perches <joe@perches.com>
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07009
10use strict;
Kamil Rytarowskicb77f0d2017-05-07 23:25:26 +020011use warnings;
Joe Perchesc707a812013-07-08 16:00:43 -070012use POSIX;
Joe Perches36061e32014-12-10 15:51:43 -080013use File::Basename;
14use Cwd 'abs_path';
Joe Perches57230292015-06-25 15:03:03 -070015use Term::ANSIColor qw(:constants);
Geert Uytterhoevencd261492018-08-21 21:57:40 -070016use Encode qw(decode encode);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -070017
18my $P = $0;
Joe Perches36061e32014-12-10 15:51:43 -080019my $D = dirname(abs_path($P));
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -070020
Joe Perches000d1cc12011-07-25 17:13:25 -070021my $V = '0.32';
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -070022
23use Getopt::Long qw(:config no_auto_abbrev);
24
25my $quiet = 0;
Dwaipayan Ray52178ce2021-02-26 15:08:26 +053026my $verbose = 0;
27my %verbose_messages = ();
28my %verbose_emitted = ();
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -070029my $tree = 1;
30my $chk_signoff = 1;
31my $chk_patch = 1;
Andy Whitcroft773647a2008-03-28 14:15:58 -070032my $tst_only;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070033my $emacs = 0;
Andy Whitcroft8905a672007-11-28 16:21:06 -080034my $terse = 0;
Joe Perches34d88152015-06-25 15:03:05 -070035my $showfile = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070036my $file = 0;
Du, Changbin4a593c32016-05-20 17:04:16 -070037my $git = 0;
Joe Perches0dea9f1e2016-05-20 17:04:19 -070038my %git_commits = ();
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070039my $check = 0;
Joe Perches2ac73b42014-06-04 16:12:05 -070040my $check_orig = 0;
Andy Whitcroft8905a672007-11-28 16:21:06 -080041my $summary = 1;
42my $mailback = 0;
Andy Whitcroft13214ad2008-02-08 04:22:03 -080043my $summary_file = 0;
Joe Perches000d1cc12011-07-25 17:13:25 -070044my $show_types = 0;
Joe Perches3beb42e2016-05-20 17:04:14 -070045my $list_types = 0;
Joe Perches3705ce52013-07-03 15:05:31 -070046my $fix = 0;
Joe Perches9624b8d2014-01-23 15:54:44 -080047my $fix_inplace = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070048my $root;
Joe Perches0f7f6352020-10-24 16:59:04 -070049my $gitroot = $ENV{'GIT_DIR'};
50$gitroot = ".git" if !defined($gitroot);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -080051my %debug;
Joe Perches34456862013-07-03 15:05:34 -070052my %camelcase = ();
Joe Perches91bfe482013-09-11 14:23:59 -070053my %use_type = ();
54my @use = ();
55my %ignore_type = ();
Joe Perches000d1cc12011-07-25 17:13:25 -070056my @ignore = ();
Hannes Eder77f5b102009-09-21 17:04:37 -070057my $help = 0;
Joe Perches000d1cc12011-07-25 17:13:25 -070058my $configuration_file = ".checkpatch.conf";
Joe Perchesbdc48fa2020-05-29 16:12:21 -070059my $max_line_length = 100;
Dave Hansend62a2012013-09-11 14:23:56 -070060my $ignore_perl_version = 0;
61my $minimum_perl_version = 5.10.0;
Vadim Bendebury56193272014-10-13 15:51:48 -070062my $min_conf_desc_length = 4;
Kees Cook66b47b42014-10-13 15:51:57 -070063my $spelling_file = "$D/spelling.txt";
Joe Perchesebfd7d62015-04-16 12:44:14 -070064my $codespell = 0;
Maxim Uvarovf1a63672015-06-25 15:03:08 -070065my $codespellfile = "/usr/share/codespell/dictionary.txt";
Joe Perchesbf1fa1d2016-10-11 13:51:56 -070066my $conststructsfile = "$D/const_structs.checkpatch";
Dwaipayan Ray52178ce2021-02-26 15:08:26 +053067my $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst";
Quentin Monnetced69da12020-08-11 18:35:13 -070068my $typedefsfile;
John Brooks737c0762017-07-10 15:52:24 -070069my $color = "auto";
Vadim Bendebury98005e82019-03-07 16:28:38 -080070my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
Joe Perchesdbbf8692019-09-25 16:46:52 -070071# git output parsing needs US English output, so first set backtick child process LANGUAGE
72my $git_command ='export LANGUAGE=en_US.UTF-8; git';
Antonio Borneo713a09d2020-04-06 20:11:07 -070073my $tabsize = 8;
Jerome Forissier3e89ad82020-10-15 20:11:49 -070074my ${CONFIG_} = "CONFIG_";
Hannes Eder77f5b102009-09-21 17:04:37 -070075
76sub help {
77 my ($exitcode) = @_;
78
79 print << "EOM";
80Usage: $P [OPTION]... [FILE]...
81Version: $V
82
83Options:
84 -q, --quiet quiet
Dwaipayan Ray52178ce2021-02-26 15:08:26 +053085 -v, --verbose verbose mode
Hannes Eder77f5b102009-09-21 17:04:37 -070086 --no-tree run without a kernel tree
87 --no-signoff do not check for 'Signed-off-by' line
88 --patch treat FILE as patchfile (default)
89 --emacs emacs compile window format
90 --terse one line per report
Joe Perches34d88152015-06-25 15:03:05 -070091 --showfile emit diffed file position, not input file position
Du, Changbin4a593c32016-05-20 17:04:16 -070092 -g, --git treat FILE as a single commit or git revision range
93 single git commit with:
94 <rev>
95 <rev>^
96 <rev>~n
97 multiple git commits with:
98 <rev1>..<rev2>
99 <rev1>...<rev2>
100 <rev>-<count>
101 git merges are ignored
Hannes Eder77f5b102009-09-21 17:04:37 -0700102 -f, --file treat FILE as regular source file
103 --subjective, --strict enable more subjective tests
Joe Perches3beb42e2016-05-20 17:04:14 -0700104 --list-types list the possible message types
Joe Perches91bfe482013-09-11 14:23:59 -0700105 --types TYPE(,TYPE2...) show only these comma separated message types
Joe Perches000d1cc12011-07-25 17:13:25 -0700106 --ignore TYPE(,TYPE2...) ignore various comma separated message types
Joe Perches3beb42e2016-05-20 17:04:14 -0700107 --show-types show the specific message type in the output
Joe Perchesbdc48fa2020-05-29 16:12:21 -0700108 --max-line-length=n set the maximum line length, (default $max_line_length)
109 if exceeded, warn on patches
110 requires --strict for use with --file
Vadim Bendebury56193272014-10-13 15:51:48 -0700111 --min-conf-desc-length=n set the min description length, if shorter, warn
Joe Perchesbdc48fa2020-05-29 16:12:21 -0700112 --tab-size=n set the number of spaces for tab (default $tabsize)
Hannes Eder77f5b102009-09-21 17:04:37 -0700113 --root=PATH PATH to the kernel tree root
114 --no-summary suppress the per-file summary
115 --mailback only produce a report in case of warnings/errors
116 --summary-file include the filename in summary
117 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
118 'values', 'possible', 'type', and 'attr' (default
119 is all off)
120 --test-only=WORD report only warnings/errors containing WORD
121 literally
Joe Perches3705ce52013-07-03 15:05:31 -0700122 --fix EXPERIMENTAL - may create horrible results
123 If correctable single-line errors exist, create
124 "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
125 with potential errors corrected to the preferred
126 checkpatch style
Joe Perches9624b8d2014-01-23 15:54:44 -0800127 --fix-inplace EXPERIMENTAL - may create horrible results
128 Is the same as --fix, but overwrites the input
129 file. It's your fault if there's no backup or git
Dave Hansend62a2012013-09-11 14:23:56 -0700130 --ignore-perl-version override checking of perl version. expect
131 runtime errors.
Joe Perchesebfd7d62015-04-16 12:44:14 -0700132 --codespell Use the codespell dictionary for spelling/typos
Maxim Uvarovf1a63672015-06-25 15:03:08 -0700133 (default:/usr/share/codespell/dictionary.txt)
Joe Perchesebfd7d62015-04-16 12:44:14 -0700134 --codespellfile Use this codespell dictionary
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700135 --typedefsfile Read additional types from this file
John Brooks737c0762017-07-10 15:52:24 -0700136 --color[=WHEN] Use colors 'always', 'never', or only when output
137 is a terminal ('auto'). Default is 'auto'.
Jerome Forissier3e89ad82020-10-15 20:11:49 -0700138 --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default
139 ${CONFIG_})
Hannes Eder77f5b102009-09-21 17:04:37 -0700140 -h, --help, --version display this help and exit
141
142When FILE is - read standard input.
143EOM
144
145 exit($exitcode);
146}
147
Joe Perches3beb42e2016-05-20 17:04:14 -0700148sub uniq {
149 my %seen;
150 return grep { !$seen{$_}++ } @_;
151}
152
153sub list_types {
154 my ($exitcode) = @_;
155
156 my $count = 0;
157
158 local $/ = undef;
159
160 open(my $script, '<', abs_path($P)) or
161 die "$P: Can't read '$P' $!\n";
162
163 my $text = <$script>;
164 close($script);
165
Dwaipayan Ray52178ce2021-02-26 15:08:26 +0530166 my %types = ();
Jean Delvare0547fa52017-09-08 16:16:11 -0700167 # Also catch when type or level is passed through a variable
Dwaipayan Ray52178ce2021-02-26 15:08:26 +0530168 while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
169 if (defined($1)) {
170 if (exists($types{$2})) {
171 $types{$2} .= ",$1" if ($types{$2} ne $1);
172 } else {
173 $types{$2} = $1;
174 }
175 } else {
176 $types{$2} = "UNDETERMINED";
177 }
Joe Perches3beb42e2016-05-20 17:04:14 -0700178 }
Dwaipayan Ray52178ce2021-02-26 15:08:26 +0530179
Joe Perches3beb42e2016-05-20 17:04:14 -0700180 print("#\tMessage type\n\n");
Dwaipayan Ray52178ce2021-02-26 15:08:26 +0530181 if ($color) {
182 print(" ( Color coding: ");
183 print(RED . "ERROR" . RESET);
184 print(" | ");
185 print(YELLOW . "WARNING" . RESET);
186 print(" | ");
187 print(GREEN . "CHECK" . RESET);
188 print(" | ");
189 print("Multiple levels / Undetermined");
190 print(" )\n\n");
191 }
192
193 foreach my $type (sort keys %types) {
194 my $orig_type = $type;
195 if ($color) {
196 my $level = $types{$type};
197 if ($level eq "ERROR") {
198 $type = RED . $type . RESET;
199 } elsif ($level eq "WARN") {
200 $type = YELLOW . $type . RESET;
201 } elsif ($level eq "CHK") {
202 $type = GREEN . $type . RESET;
203 }
204 }
Joe Perches3beb42e2016-05-20 17:04:14 -0700205 print(++$count . "\t" . $type . "\n");
Dwaipayan Ray52178ce2021-02-26 15:08:26 +0530206 if ($verbose && exists($verbose_messages{$orig_type})) {
207 my $message = $verbose_messages{$orig_type};
208 $message =~ s/\n/\n\t/g;
209 print("\t" . $message . "\n\n");
210 }
Joe Perches3beb42e2016-05-20 17:04:14 -0700211 }
212
213 exit($exitcode);
214}
215
Joe Perches000d1cc12011-07-25 17:13:25 -0700216my $conf = which_conf($configuration_file);
217if (-f $conf) {
218 my @conf_args;
219 open(my $conffile, '<', "$conf")
220 or warn "$P: Can't find a readable $configuration_file file $!\n";
221
222 while (<$conffile>) {
223 my $line = $_;
224
225 $line =~ s/\s*\n?$//g;
226 $line =~ s/^\s*//g;
227 $line =~ s/\s+/ /g;
228
229 next if ($line =~ m/^\s*#/);
230 next if ($line =~ m/^\s*$/);
231
232 my @words = split(" ", $line);
233 foreach my $word (@words) {
234 last if ($word =~ m/^#/);
235 push (@conf_args, $word);
236 }
237 }
238 close($conffile);
239 unshift(@ARGV, @conf_args) if @conf_args;
240}
241
Dwaipayan Ray52178ce2021-02-26 15:08:26 +0530242sub load_docs {
243 open(my $docs, '<', "$docsfile")
244 or warn "$P: Can't read the documentation file $docsfile $!\n";
245
246 my $type = '';
247 my $desc = '';
248 my $in_desc = 0;
249
250 while (<$docs>) {
251 chomp;
252 my $line = $_;
253 $line =~ s/\s+$//;
254
255 if ($line =~ /^\s*\*\*(.+)\*\*$/) {
256 if ($desc ne '') {
257 $verbose_messages{$type} = trim($desc);
258 }
259 $type = $1;
260 $desc = '';
261 $in_desc = 1;
262 } elsif ($in_desc) {
263 if ($line =~ /^(?:\s{4,}|$)/) {
264 $line =~ s/^\s{4}//;
265 $desc .= $line;
266 $desc .= "\n";
267 } else {
268 $verbose_messages{$type} = trim($desc);
269 $type = '';
270 $desc = '';
271 $in_desc = 0;
272 }
273 }
274 }
275
276 if ($desc ne '') {
277 $verbose_messages{$type} = trim($desc);
278 }
279 close($docs);
280}
281
John Brooks737c0762017-07-10 15:52:24 -0700282# Perl's Getopt::Long allows options to take optional arguments after a space.
283# Prevent --color by itself from consuming other arguments
284foreach (@ARGV) {
285 if ($_ eq "--color" || $_ eq "-color") {
286 $_ = "--color=$color";
287 }
288}
289
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -0700290GetOptions(
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700291 'q|quiet+' => \$quiet,
Dwaipayan Ray52178ce2021-02-26 15:08:26 +0530292 'v|verbose!' => \$verbose,
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -0700293 'tree!' => \$tree,
294 'signoff!' => \$chk_signoff,
295 'patch!' => \$chk_patch,
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700296 'emacs!' => \$emacs,
Andy Whitcroft8905a672007-11-28 16:21:06 -0800297 'terse!' => \$terse,
Joe Perches34d88152015-06-25 15:03:05 -0700298 'showfile!' => \$showfile,
Hannes Eder77f5b102009-09-21 17:04:37 -0700299 'f|file!' => \$file,
Du, Changbin4a593c32016-05-20 17:04:16 -0700300 'g|git!' => \$git,
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700301 'subjective!' => \$check,
302 'strict!' => \$check,
Joe Perches000d1cc12011-07-25 17:13:25 -0700303 'ignore=s' => \@ignore,
Joe Perches91bfe482013-09-11 14:23:59 -0700304 'types=s' => \@use,
Joe Perches000d1cc12011-07-25 17:13:25 -0700305 'show-types!' => \$show_types,
Joe Perches3beb42e2016-05-20 17:04:14 -0700306 'list-types!' => \$list_types,
Joe Perches6cd7f382012-12-17 16:01:54 -0800307 'max-line-length=i' => \$max_line_length,
Vadim Bendebury56193272014-10-13 15:51:48 -0700308 'min-conf-desc-length=i' => \$min_conf_desc_length,
Antonio Borneo713a09d2020-04-06 20:11:07 -0700309 'tab-size=i' => \$tabsize,
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700310 'root=s' => \$root,
Andy Whitcroft8905a672007-11-28 16:21:06 -0800311 'summary!' => \$summary,
312 'mailback!' => \$mailback,
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800313 'summary-file!' => \$summary_file,
Joe Perches3705ce52013-07-03 15:05:31 -0700314 'fix!' => \$fix,
Joe Perches9624b8d2014-01-23 15:54:44 -0800315 'fix-inplace!' => \$fix_inplace,
Dave Hansend62a2012013-09-11 14:23:56 -0700316 'ignore-perl-version!' => \$ignore_perl_version,
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800317 'debug=s' => \%debug,
Andy Whitcroft773647a2008-03-28 14:15:58 -0700318 'test-only=s' => \$tst_only,
Joe Perchesebfd7d62015-04-16 12:44:14 -0700319 'codespell!' => \$codespell,
320 'codespellfile=s' => \$codespellfile,
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700321 'typedefsfile=s' => \$typedefsfile,
John Brooks737c0762017-07-10 15:52:24 -0700322 'color=s' => \$color,
323 'no-color' => \$color, #keep old behaviors of -nocolor
324 'nocolor' => \$color, #keep old behaviors of -nocolor
Jerome Forissier3e89ad82020-10-15 20:11:49 -0700325 'kconfig-prefix=s' => \${CONFIG_},
Hannes Eder77f5b102009-09-21 17:04:37 -0700326 'h|help' => \$help,
327 'version' => \$help
328) or help(1);
329
330help(0) if ($help);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -0700331
Dwaipayan Ray52178ce2021-02-26 15:08:26 +0530332die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
333die "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse);
334
335if ($color =~ /^[01]$/) {
336 $color = !$color;
337} elsif ($color =~ /^always$/i) {
338 $color = 1;
339} elsif ($color =~ /^never$/i) {
340 $color = 0;
341} elsif ($color =~ /^auto$/i) {
342 $color = (-t STDOUT);
343} else {
344 die "$P: Invalid color mode: $color\n";
345}
346
347load_docs() if ($verbose);
Joe Perches3beb42e2016-05-20 17:04:14 -0700348list_types(0) if ($list_types);
349
Joe Perches9624b8d2014-01-23 15:54:44 -0800350$fix = 1 if ($fix_inplace);
Joe Perches2ac73b42014-06-04 16:12:05 -0700351$check_orig = $check;
Joe Perches9624b8d2014-01-23 15:54:44 -0800352
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -0700353my $exit = 0;
354
Joe Perches5b579802018-08-21 21:57:33 -0700355my $perl_version_ok = 1;
Dave Hansend62a2012013-09-11 14:23:56 -0700356if ($^V && $^V lt $minimum_perl_version) {
Joe Perches5b579802018-08-21 21:57:33 -0700357 $perl_version_ok = 0;
Dave Hansend62a2012013-09-11 14:23:56 -0700358 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
Joe Perches5b579802018-08-21 21:57:33 -0700359 exit(1) if (!$ignore_perl_version);
Dave Hansend62a2012013-09-11 14:23:56 -0700360}
361
Allen Hubbe45107ff2016-08-02 14:04:47 -0700362#if no filenames are given, push '-' to read patch from stdin
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -0700363if ($#ARGV < 0) {
Allen Hubbe45107ff2016-08-02 14:04:47 -0700364 push(@ARGV, '-');
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -0700365}
366
Antonio Borneo713a09d2020-04-06 20:11:07 -0700367# skip TAB size 1 to avoid additional checks on $tabsize - 1
Joe Perches32f30ca2020-06-04 16:50:40 -0700368die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
Antonio Borneo713a09d2020-04-06 20:11:07 -0700369
Joe Perches91bfe482013-09-11 14:23:59 -0700370sub hash_save_array_words {
371 my ($hashRef, $arrayRef) = @_;
Joe Perches000d1cc12011-07-25 17:13:25 -0700372
Joe Perches91bfe482013-09-11 14:23:59 -0700373 my @array = split(/,/, join(',', @$arrayRef));
374 foreach my $word (@array) {
375 $word =~ s/\s*\n?$//g;
376 $word =~ s/^\s*//g;
377 $word =~ s/\s+/ /g;
378 $word =~ tr/[a-z]/[A-Z]/;
Joe Perches000d1cc12011-07-25 17:13:25 -0700379
Joe Perches91bfe482013-09-11 14:23:59 -0700380 next if ($word =~ m/^\s*#/);
381 next if ($word =~ m/^\s*$/);
382
383 $hashRef->{$word}++;
384 }
Joe Perches000d1cc12011-07-25 17:13:25 -0700385}
386
Joe Perches91bfe482013-09-11 14:23:59 -0700387sub hash_show_words {
388 my ($hashRef, $prefix) = @_;
389
Joe Perches3c816e42015-06-25 15:03:29 -0700390 if (keys %$hashRef) {
Joe Perchesd8469f12015-06-25 15:03:00 -0700391 print "\nNOTE: $prefix message types:";
Joe Perches58cb3cf2013-09-11 14:24:04 -0700392 foreach my $word (sort keys %$hashRef) {
Joe Perches91bfe482013-09-11 14:23:59 -0700393 print " $word";
394 }
Joe Perchesd8469f12015-06-25 15:03:00 -0700395 print "\n";
Joe Perches91bfe482013-09-11 14:23:59 -0700396 }
397}
398
399hash_save_array_words(\%ignore_type, \@ignore);
400hash_save_array_words(\%use_type, \@use);
401
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800402my $dbg_values = 0;
403my $dbg_possible = 0;
Andy Whitcroft7429c692008-07-23 21:29:06 -0700404my $dbg_type = 0;
Andy Whitcrofta1ef2772008-10-15 22:02:17 -0700405my $dbg_attr = 0;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800406for my $key (keys %debug) {
Andy Whitcroft21caa132009-01-06 14:41:30 -0800407 ## no critic
408 eval "\${dbg_$key} = '$debug{$key}';";
409 die "$@" if ($@);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800410}
411
Andy Whitcroftd2c0a232010-10-26 14:23:12 -0700412my $rpt_cleaners = 0;
413
Andy Whitcroft8905a672007-11-28 16:21:06 -0800414if ($terse) {
415 $emacs = 1;
416 $quiet++;
417}
418
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700419if ($tree) {
420 if (defined $root) {
421 if (!top_of_kernel_tree($root)) {
422 die "$P: $root: --root does not point at a valid tree\n";
423 }
424 } else {
425 if (top_of_kernel_tree('.')) {
426 $root = '.';
427 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
428 top_of_kernel_tree($1)) {
429 $root = $1;
430 }
431 }
432
433 if (!defined $root) {
434 print "Must be run from the top-level dir. of a kernel tree\n";
435 exit(2);
436 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -0700437}
438
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700439my $emitted_corrupt = 0;
440
Andy Whitcroft2ceb5322009-10-26 16:50:14 -0700441our $Ident = qr{
442 [A-Za-z_][A-Za-z\d_]*
443 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
444 }x;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700445our $Storage = qr{extern|static|asmlinkage};
446our $Sparse = qr{
447 __user|
448 __kernel|
449 __force|
450 __iomem|
451 __must_check|
Andy Whitcroft417495e2009-02-27 14:03:08 -0800452 __kprobes|
Sven Eckelmann165e72a2011-07-25 17:13:23 -0700453 __ref|
Geert Uytterhoeven33aa4592018-08-21 21:57:36 -0700454 __refconst|
455 __refdata|
Boqun Fengad315452015-12-29 12:18:46 +0800456 __rcu|
457 __private
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700458 }x;
Joe Perchese970b8842013-11-12 15:10:10 -0800459our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
460our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
461our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
462our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
463our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
Joe Perches8716de32013-09-11 14:24:05 -0700464
Wolfram Sang52131292010-03-05 13:43:51 -0800465# Notes to $Attribute:
466# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700467our $Attribute = qr{
468 const|
Joe Perchesb5e87362021-02-25 17:21:40 -0800469 volatile|
Joe Perches03f1df72010-10-26 14:23:16 -0700470 __percpu|
471 __nocast|
472 __safe|
Michael S. Tsirkin46d832f2016-12-11 06:29:58 +0200473 __bitwise|
Joe Perches03f1df72010-10-26 14:23:16 -0700474 __packed__|
475 __packed2__|
476 __naked|
477 __maybe_unused|
478 __always_unused|
479 __noreturn|
480 __used|
481 __cold|
Joe Perchese23ef1f2015-02-13 14:38:24 -0800482 __pure|
Joe Perches03f1df72010-10-26 14:23:16 -0700483 __noclone|
484 __deprecated|
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700485 __read_mostly|
Joe Perchesc5967e92018-09-04 15:46:20 -0700486 __ro_after_init|
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700487 __kprobes|
Joe Perches8716de32013-09-11 14:24:05 -0700488 $InitAttribute|
Andy Whitcroft24e1d812008-10-15 22:02:18 -0700489 ____cacheline_aligned|
490 ____cacheline_aligned_in_smp|
Andy Whitcroft5fe3af12009-01-06 14:41:18 -0800491 ____cacheline_internodealigned_in_smp|
492 __weak
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700493 }x;
Andy Whitcroftc45dcab2008-06-05 22:46:01 -0700494our $Modifier;
Joe Perches91cb5192014-04-03 14:49:32 -0700495our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700496our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
497our $Lval = qr{$Ident(?:$Member)*};
498
Joe Perches95e2c602013-07-03 15:05:20 -0700499our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
500our $Binary = qr{(?i)0b[01]+$Int_type?};
501our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
502our $Int = qr{[0-9]+$Int_type?};
Joe Perches24358802014-04-03 14:49:13 -0700503our $Octal = qr{0[0-7]+$Int_type?};
Joe Perchesd2af5aa2021-09-07 19:59:51 -0700504our $String = qr{(?:\b[Lu])?"[X\t]*"};
Joe Perches326b1ff2013-02-04 14:28:51 -0800505our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
506our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
507our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
Joe Perches74349bc2012-12-17 16:02:05 -0800508our $Float = qr{$Float_hex|$Float_dec|$Float_int};
Joe Perches24358802014-04-03 14:49:13 -0700509our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
Joe Perches326b1ff2013-02-04 14:28:51 -0800510our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
Joe Perches447432f2014-04-03 14:49:17 -0700511our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
Joe Perches23f780c2013-07-03 15:05:31 -0700512our $Arithmetic = qr{\+|-|\*|\/|%};
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700513our $Operators = qr{
514 <=|>=|==|!=|
515 =>|->|<<|>>|<|>|!|~|
Joe Perches23f780c2013-07-03 15:05:31 -0700516 &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700517 }x;
518
Joe Perches91cb5192014-04-03 14:49:32 -0700519our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
520
Joe Perchesab7e23f2015-04-16 12:44:22 -0700521our $BasicType;
Andy Whitcroft8905a672007-11-28 16:21:06 -0800522our $NonptrType;
Joe Perches18130872014-08-06 16:11:22 -0700523our $NonptrTypeMisordered;
Joe Perches8716de32013-09-11 14:24:05 -0700524our $NonptrTypeWithAttr;
Andy Whitcroft8905a672007-11-28 16:21:06 -0800525our $Type;
Joe Perches18130872014-08-06 16:11:22 -0700526our $TypeMisordered;
Andy Whitcroft8905a672007-11-28 16:21:06 -0800527our $Declare;
Joe Perches18130872014-08-06 16:11:22 -0700528our $DeclareMisordered;
Andy Whitcroft8905a672007-11-28 16:21:06 -0800529
Joe Perches15662b32011-10-31 17:13:12 -0700530our $NON_ASCII_UTF8 = qr{
531 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
Andy Whitcroft171ae1a2008-04-29 00:59:32 -0700532 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
533 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
534 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
535 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
536 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
537 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
538}x;
539
Joe Perches15662b32011-10-31 17:13:12 -0700540our $UTF8 = qr{
541 [\x09\x0A\x0D\x20-\x7E] # ASCII
542 | $NON_ASCII_UTF8
543}x;
544
Joe Perchese6176fa2015-06-25 15:02:49 -0700545our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
Joe Perches021158b2015-02-13 14:38:43 -0800546our $typeOtherOSTypedefs = qr{(?x:
547 u_(?:char|short|int|long) | # bsd
548 u(?:nchar|short|int|long) # sysv
549)};
Joe Perchese6176fa2015-06-25 15:02:49 -0700550our $typeKernelTypedefs = qr{(?x:
Andy Whitcroftfb9e9092009-09-21 17:04:38 -0700551 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
Andy Whitcroft8ed22ca2008-10-15 22:02:32 -0700552 atomic_t
553)};
Joe Perchese6176fa2015-06-25 15:02:49 -0700554our $typeTypedefs = qr{(?x:
555 $typeC99Typedefs\b|
556 $typeOtherOSTypedefs\b|
557 $typeKernelTypedefs\b
558)};
Andy Whitcroft8ed22ca2008-10-15 22:02:32 -0700559
Joe Perches6d32f7a2015-11-06 16:31:37 -0800560our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
561
Joe Perches691e6692010-03-05 13:43:51 -0800562our $logFunctions = qr{(?x:
Miles Chen758d7aa2017-02-24 15:01:34 -0800563 printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
Jacob Keller7d0b6592013-07-03 15:05:35 -0700564 (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
Joe Perches87bd4992017-11-17 15:28:48 -0800565 TP_printk|
Joe Perches6e60c022011-07-25 17:13:27 -0700566 WARN(?:_RATELIMIT|_ONCE|)|
Joe Perchesb0531722011-05-24 17:13:40 -0700567 panic|
Joe Perches06668722013-11-12 15:10:07 -0800568 MODULE_[A-Z_]+|
569 seq_vprintf|seq_printf|seq_puts
Joe Perches691e6692010-03-05 13:43:51 -0800570)};
571
Joe Perchese29a70f2019-03-07 16:28:35 -0800572our $allocFunctions = qr{(?x:
573 (?:(?:devm_)?
Joe Perches58f02262021-02-25 17:22:01 -0800574 (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |
Joe Perchese29a70f2019-03-07 16:28:35 -0800575 kstrdup(?:_const)? |
576 kmemdup(?:_nul)?) |
Christophe JAILLET461e1562020-04-20 18:13:58 -0700577 (?:\w+)?alloc_skb(?:_ip_align)? |
Joe Perchese29a70f2019-03-07 16:28:35 -0800578 # dev_alloc_skb/netdev_alloc_skb, et al
579 dma_alloc_coherent
580)};
581
Joe Perches20112472011-07-25 17:13:23 -0700582our $signature_tags = qr{(?xi:
583 Signed-off-by:|
Jorge Ramirez-Ortizd4994802019-01-03 15:29:12 -0800584 Co-developed-by:|
Joe Perches20112472011-07-25 17:13:23 -0700585 Acked-by:|
586 Tested-by:|
587 Reviewed-by:|
588 Reported-by:|
Mugunthan V N8543ae12013-04-29 16:18:17 -0700589 Suggested-by:|
Joe Perches20112472011-07-25 17:13:23 -0700590 To:|
591 Cc:
592)};
593
Joe Perchesadb2da82021-02-25 17:21:50 -0800594our $tracing_logging_tags = qr{(?xi:
595 [=-]*> |
596 <[=-]* |
597 \[ |
598 \] |
599 start |
600 called |
601 entered |
602 entry |
603 enter |
604 in |
605 inside |
606 here |
607 begin |
608 exit |
609 end |
610 done |
611 leave |
612 completed |
613 out |
614 return |
615 [\.\!:\s]*
616)};
617
Aditya Srivastava831242a2020-12-15 20:45:12 -0800618sub edit_distance_min {
619 my (@arr) = @_;
620 my $len = scalar @arr;
621 if ((scalar @arr) < 1) {
622 # if underflow, return
623 return;
624 }
625 my $min = $arr[0];
626 for my $i (0 .. ($len-1)) {
627 if ($arr[$i] < $min) {
628 $min = $arr[$i];
629 }
630 }
631 return $min;
632}
633
634sub get_edit_distance {
635 my ($str1, $str2) = @_;
636 $str1 = lc($str1);
637 $str2 = lc($str2);
638 $str1 =~ s/-//g;
639 $str2 =~ s/-//g;
640 my $len1 = length($str1);
641 my $len2 = length($str2);
642 # two dimensional array storing minimum edit distance
643 my @distance;
644 for my $i (0 .. $len1) {
645 for my $j (0 .. $len2) {
646 if ($i == 0) {
647 $distance[$i][$j] = $j;
648 } elsif ($j == 0) {
649 $distance[$i][$j] = $i;
650 } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {
651 $distance[$i][$j] = $distance[$i - 1][$j - 1];
652 } else {
653 my $dist1 = $distance[$i][$j - 1]; #insert distance
654 my $dist2 = $distance[$i - 1][$j]; # remove
655 my $dist3 = $distance[$i - 1][$j - 1]; #replace
656 $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);
657 }
658 }
659 }
660 return $distance[$len1][$len2];
661}
662
663sub find_standard_signature {
664 my ($sign_off) = @_;
665 my @standard_signature_tags = (
666 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',
667 'Reviewed-by:', 'Reported-by:', 'Suggested-by:'
668 );
669 foreach my $signature (@standard_signature_tags) {
670 return $signature if (get_edit_distance($sign_off, $signature) <= 2);
671 }
672
673 return "";
674}
675
Joe Perches18130872014-08-06 16:11:22 -0700676our @typeListMisordered = (
677 qr{char\s+(?:un)?signed},
678 qr{int\s+(?:(?:un)?signed\s+)?short\s},
679 qr{int\s+short(?:\s+(?:un)?signed)},
680 qr{short\s+int(?:\s+(?:un)?signed)},
681 qr{(?:un)?signed\s+int\s+short},
682 qr{short\s+(?:un)?signed},
683 qr{long\s+int\s+(?:un)?signed},
684 qr{int\s+long\s+(?:un)?signed},
685 qr{long\s+(?:un)?signed\s+int},
686 qr{int\s+(?:un)?signed\s+long},
687 qr{int\s+(?:un)?signed},
688 qr{int\s+long\s+long\s+(?:un)?signed},
689 qr{long\s+long\s+int\s+(?:un)?signed},
690 qr{long\s+long\s+(?:un)?signed\s+int},
691 qr{long\s+long\s+(?:un)?signed},
692 qr{long\s+(?:un)?signed},
693);
694
Andy Whitcroft8905a672007-11-28 16:21:06 -0800695our @typeList = (
696 qr{void},
Joe Perches0c773d92014-08-06 16:11:20 -0700697 qr{(?:(?:un)?signed\s+)?char},
698 qr{(?:(?:un)?signed\s+)?short\s+int},
699 qr{(?:(?:un)?signed\s+)?short},
700 qr{(?:(?:un)?signed\s+)?int},
701 qr{(?:(?:un)?signed\s+)?long\s+int},
702 qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
703 qr{(?:(?:un)?signed\s+)?long\s+long},
704 qr{(?:(?:un)?signed\s+)?long},
705 qr{(?:un)?signed},
Andy Whitcroft8905a672007-11-28 16:21:06 -0800706 qr{float},
707 qr{double},
708 qr{bool},
Andy Whitcroft8905a672007-11-28 16:21:06 -0800709 qr{struct\s+$Ident},
710 qr{union\s+$Ident},
711 qr{enum\s+$Ident},
712 qr{${Ident}_t},
713 qr{${Ident}_handler},
714 qr{${Ident}_handler_fn},
Joe Perches18130872014-08-06 16:11:22 -0700715 @typeListMisordered,
Andy Whitcroft8905a672007-11-28 16:21:06 -0800716);
Joe Perches938224b2016-01-20 14:59:15 -0800717
718our $C90_int_types = qr{(?x:
719 long\s+long\s+int\s+(?:un)?signed|
720 long\s+long\s+(?:un)?signed\s+int|
721 long\s+long\s+(?:un)?signed|
722 (?:(?:un)?signed\s+)?long\s+long\s+int|
723 (?:(?:un)?signed\s+)?long\s+long|
724 int\s+long\s+long\s+(?:un)?signed|
725 int\s+(?:(?:un)?signed\s+)?long\s+long|
726
727 long\s+int\s+(?:un)?signed|
728 long\s+(?:un)?signed\s+int|
729 long\s+(?:un)?signed|
730 (?:(?:un)?signed\s+)?long\s+int|
731 (?:(?:un)?signed\s+)?long|
732 int\s+long\s+(?:un)?signed|
733 int\s+(?:(?:un)?signed\s+)?long|
734
735 int\s+(?:un)?signed|
736 (?:(?:un)?signed\s+)?int
737)};
738
Alex Dowad485ff232015-06-25 15:02:52 -0700739our @typeListFile = ();
Joe Perches8716de32013-09-11 14:24:05 -0700740our @typeListWithAttr = (
741 @typeList,
742 qr{struct\s+$InitAttribute\s+$Ident},
743 qr{union\s+$InitAttribute\s+$Ident},
744);
745
Andy Whitcroftc45dcab2008-06-05 22:46:01 -0700746our @modifierList = (
747 qr{fastcall},
748);
Alex Dowad485ff232015-06-25 15:02:52 -0700749our @modifierListFile = ();
Andy Whitcroft8905a672007-11-28 16:21:06 -0800750
Joe Perches24358802014-04-03 14:49:13 -0700751our @mode_permission_funcs = (
752 ["module_param", 3],
753 ["module_param_(?:array|named|string)", 4],
754 ["module_param_array_named", 5],
755 ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
756 ["proc_create(?:_data|)", 2],
Joe Perches459cf0a2016-10-11 13:52:19 -0700757 ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
758 ["IIO_DEV_ATTR_[A-Z_]+", 1],
759 ["SENSOR_(?:DEVICE_|)ATTR_2", 2],
760 ["SENSOR_TEMPLATE(?:_2|)", 3],
761 ["__ATTR", 2],
Joe Perches24358802014-04-03 14:49:13 -0700762);
763
Joe Perches1a3dcf22020-08-11 18:35:16 -0700764my $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
765
Joe Perches515a2352014-04-03 14:49:24 -0700766#Create a search pattern for all these functions to speed up a loop below
767our $mode_perms_search = "";
768foreach my $entry (@mode_permission_funcs) {
769 $mode_perms_search .= '|' if ($mode_perms_search ne "");
770 $mode_perms_search .= $entry->[0];
771}
Joe Perches00180462018-02-06 15:38:55 -0800772$mode_perms_search = "(?:${mode_perms_search})";
Joe Perches515a2352014-04-03 14:49:24 -0700773
Joe Perches9189c7e2018-09-07 15:26:18 -0700774our %deprecated_apis = (
775 "synchronize_rcu_bh" => "synchronize_rcu",
776 "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited",
777 "call_rcu_bh" => "call_rcu",
778 "rcu_barrier_bh" => "rcu_barrier",
779 "synchronize_sched" => "synchronize_rcu",
780 "synchronize_sched_expedited" => "synchronize_rcu_expedited",
781 "call_rcu_sched" => "call_rcu",
782 "rcu_barrier_sched" => "rcu_barrier",
783 "get_state_synchronize_sched" => "get_state_synchronize_rcu",
784 "cond_synchronize_sched" => "cond_synchronize_rcu",
785);
786
787#Create a search pattern for all these strings to speed up a loop below
788our $deprecated_apis_search = "";
789foreach my $entry (keys %deprecated_apis) {
790 $deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
791 $deprecated_apis_search .= $entry;
792}
793$deprecated_apis_search = "(?:${deprecated_apis_search})";
794
Joe Perchesb392c642015-04-16 12:44:16 -0700795our $mode_perms_world_writable = qr{
796 S_IWUGO |
797 S_IWOTH |
798 S_IRWXUGO |
799 S_IALLUGO |
800 0[0-7][0-7][2367]
801}x;
802
Joe Perchesf90774e2016-10-11 13:51:47 -0700803our %mode_permission_string_types = (
804 "S_IRWXU" => 0700,
805 "S_IRUSR" => 0400,
806 "S_IWUSR" => 0200,
807 "S_IXUSR" => 0100,
808 "S_IRWXG" => 0070,
809 "S_IRGRP" => 0040,
810 "S_IWGRP" => 0020,
811 "S_IXGRP" => 0010,
812 "S_IRWXO" => 0007,
813 "S_IROTH" => 0004,
814 "S_IWOTH" => 0002,
815 "S_IXOTH" => 0001,
816 "S_IRWXUGO" => 0777,
817 "S_IRUGO" => 0444,
818 "S_IWUGO" => 0222,
819 "S_IXUGO" => 0111,
820);
821
822#Create a search pattern for all these strings to speed up a loop below
823our $mode_perms_string_search = "";
824foreach my $entry (keys %mode_permission_string_types) {
825 $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
826 $mode_perms_string_search .= $entry;
827}
Joe Perches00180462018-02-06 15:38:55 -0800828our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
829our $multi_mode_perms_string_search = qr{
830 ${single_mode_perms_string_search}
831 (?:\s*\|\s*${single_mode_perms_string_search})*
832}x;
833
834sub perms_to_octal {
835 my ($string) = @_;
836
837 return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
838
839 my $val = "";
840 my $oval = "";
841 my $to = 0;
842 my $curpos = 0;
843 my $lastpos = 0;
844 while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
845 $curpos = pos($string);
846 my $match = $2;
847 my $omatch = $1;
848 last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
849 $lastpos = $curpos;
850 $to |= $mode_permission_string_types{$match};
851 $val .= '\s*\|\s*' if ($val ne "");
852 $val .= $match;
853 $oval .= $omatch;
854 }
855 $oval =~ s/^\s*\|\s*//;
856 $oval =~ s/\s*\|\s*$//;
857 return sprintf("%04o", $to);
858}
Joe Perchesf90774e2016-10-11 13:51:47 -0700859
Wolfram Sang7840a942010-08-09 17:20:57 -0700860our $allowed_asm_includes = qr{(?x:
861 irq|
Sergey Ryazanovcdcee682014-10-13 15:51:44 -0700862 memory|
863 time|
864 reboot
Wolfram Sang7840a942010-08-09 17:20:57 -0700865)};
866# memory.h: ARM has a custom one
867
Kees Cook66b47b42014-10-13 15:51:57 -0700868# Load common spelling mistakes and build regular expression list.
869my $misspellings;
Kees Cook66b47b42014-10-13 15:51:57 -0700870my %spelling_fix;
Kees Cook66b47b42014-10-13 15:51:57 -0700871
Joe Perches36061e32014-12-10 15:51:43 -0800872if (open(my $spelling, '<', $spelling_file)) {
Joe Perches36061e32014-12-10 15:51:43 -0800873 while (<$spelling>) {
874 my $line = $_;
Kees Cook66b47b42014-10-13 15:51:57 -0700875
Joe Perches36061e32014-12-10 15:51:43 -0800876 $line =~ s/\s*\n?$//g;
877 $line =~ s/^\s*//g;
Kees Cook66b47b42014-10-13 15:51:57 -0700878
Joe Perches36061e32014-12-10 15:51:43 -0800879 next if ($line =~ m/^\s*#/);
880 next if ($line =~ m/^\s*$/);
Kees Cook66b47b42014-10-13 15:51:57 -0700881
Joe Perches36061e32014-12-10 15:51:43 -0800882 my ($suspect, $fix) = split(/\|\|/, $line);
883
Joe Perches36061e32014-12-10 15:51:43 -0800884 $spelling_fix{$suspect} = $fix;
885 }
886 close($spelling);
Joe Perches36061e32014-12-10 15:51:43 -0800887} else {
888 warn "No typos will be found - file '$spelling_file': $!\n";
Kees Cook66b47b42014-10-13 15:51:57 -0700889}
Kees Cook66b47b42014-10-13 15:51:57 -0700890
Joe Perchesebfd7d62015-04-16 12:44:14 -0700891if ($codespell) {
892 if (open(my $spelling, '<', $codespellfile)) {
893 while (<$spelling>) {
894 my $line = $_;
895
896 $line =~ s/\s*\n?$//g;
897 $line =~ s/^\s*//g;
898
899 next if ($line =~ m/^\s*#/);
900 next if ($line =~ m/^\s*$/);
901 next if ($line =~ m/, disabled/i);
902
903 $line =~ s/,.*$//;
904
905 my ($suspect, $fix) = split(/->/, $line);
906
907 $spelling_fix{$suspect} = $fix;
908 }
909 close($spelling);
910 } else {
911 warn "No codespell typos will be found - file '$codespellfile': $!\n";
912 }
913}
914
915$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
916
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700917sub read_words {
918 my ($wordsRef, $file) = @_;
Joe Perchesbf1fa1d2016-10-11 13:51:56 -0700919
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700920 if (open(my $words, '<', $file)) {
921 while (<$words>) {
922 my $line = $_;
Joe Perchesbf1fa1d2016-10-11 13:51:56 -0700923
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700924 $line =~ s/\s*\n?$//g;
925 $line =~ s/^\s*//g;
926
927 next if ($line =~ m/^\s*#/);
928 next if ($line =~ m/^\s*$/);
929 if ($line =~ /\s/) {
930 print("$file: '$line' invalid - ignored\n");
931 next;
932 }
933
Quentin Monnetced69da12020-08-11 18:35:13 -0700934 $$wordsRef .= '|' if (defined $$wordsRef);
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700935 $$wordsRef .= $line;
Joe Perchesbf1fa1d2016-10-11 13:51:56 -0700936 }
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700937 close($file);
938 return 1;
Joe Perchesbf1fa1d2016-10-11 13:51:56 -0700939 }
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700940
941 return 0;
Joe Perchesbf1fa1d2016-10-11 13:51:56 -0700942}
943
Quentin Monnetced69da12020-08-11 18:35:13 -0700944my $const_structs;
945if (show_type("CONST_STRUCT")) {
946 read_words(\$const_structs, $conststructsfile)
947 or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
948}
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700949
Quentin Monnetced69da12020-08-11 18:35:13 -0700950if (defined($typedefsfile)) {
951 my $typeOtherTypedefs;
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700952 read_words(\$typeOtherTypedefs, $typedefsfile)
953 or warn "No additional types will be considered - file '$typedefsfile': $!\n";
Quentin Monnetced69da12020-08-11 18:35:13 -0700954 $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700955}
Jerome Forissier75ad8c52017-05-08 15:56:00 -0700956
Andy Whitcroft8905a672007-11-28 16:21:06 -0800957sub build_types {
Alex Dowad485ff232015-06-25 15:02:52 -0700958 my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
959 my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
Joe Perches18130872014-08-06 16:11:22 -0700960 my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
Joe Perches8716de32013-09-11 14:24:05 -0700961 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
Andy Whitcroftc8cb2ca2008-07-23 21:28:57 -0700962 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
Joe Perchesab7e23f2015-04-16 12:44:22 -0700963 $BasicType = qr{
Joe Perchesab7e23f2015-04-16 12:44:22 -0700964 (?:$typeTypedefs\b)|
965 (?:${all}\b)
966 }x;
Andy Whitcroft8905a672007-11-28 16:21:06 -0800967 $NonptrType = qr{
Andy Whitcroftd2172eb2008-07-23 21:29:07 -0700968 (?:$Modifier\s+|const\s+)*
Andy Whitcroftcf655042008-03-04 14:28:20 -0800969 (?:
Andy Whitcroft6b48db22012-01-10 15:10:13 -0800970 (?:typeof|__typeof__)\s*\([^\)]*\)|
Andy Whitcroft8ed22ca2008-10-15 22:02:32 -0700971 (?:$typeTypedefs\b)|
Andy Whitcroftc45dcab2008-06-05 22:46:01 -0700972 (?:${all}\b)
Andy Whitcroftcf655042008-03-04 14:28:20 -0800973 )
Andy Whitcroftc8cb2ca2008-07-23 21:28:57 -0700974 (?:\s+$Modifier|\s+const)*
Andy Whitcroft8905a672007-11-28 16:21:06 -0800975 }x;
Joe Perches18130872014-08-06 16:11:22 -0700976 $NonptrTypeMisordered = qr{
977 (?:$Modifier\s+|const\s+)*
978 (?:
979 (?:${Misordered}\b)
980 )
981 (?:\s+$Modifier|\s+const)*
982 }x;
Joe Perches8716de32013-09-11 14:24:05 -0700983 $NonptrTypeWithAttr = qr{
984 (?:$Modifier\s+|const\s+)*
985 (?:
986 (?:typeof|__typeof__)\s*\([^\)]*\)|
987 (?:$typeTypedefs\b)|
988 (?:${allWithAttr}\b)
989 )
990 (?:\s+$Modifier|\s+const)*
991 }x;
Andy Whitcroft8905a672007-11-28 16:21:06 -0800992 $Type = qr{
Andy Whitcroftc45dcab2008-06-05 22:46:01 -0700993 $NonptrType
Antonio Borneo7b184962020-04-06 20:11:04 -0700994 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
Andy Whitcroftc8cb2ca2008-07-23 21:28:57 -0700995 (?:\s+$Inline|\s+$Modifier)*
Andy Whitcroft8905a672007-11-28 16:21:06 -0800996 }x;
Joe Perches18130872014-08-06 16:11:22 -0700997 $TypeMisordered = qr{
998 $NonptrTypeMisordered
Antonio Borneo7b184962020-04-06 20:11:04 -0700999 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
Joe Perches18130872014-08-06 16:11:22 -07001000 (?:\s+$Inline|\s+$Modifier)*
1001 }x;
Joe Perches91cb5192014-04-03 14:49:32 -07001002 $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
Joe Perches18130872014-08-06 16:11:22 -07001003 $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
Andy Whitcroft8905a672007-11-28 16:21:06 -08001004}
1005build_types();
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001006
Joe Perches7d2367a2011-07-25 17:13:22 -07001007our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
Joe Perchesd1fe9c02012-03-23 15:02:16 -07001008
1009# Using $balanced_parens, $LvalOrFunc, or $FuncArg
1010# requires at least perl version v5.10.0
1011# Any use must be runtime checked with $^V
1012
1013our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
Joe Perches24358802014-04-03 14:49:13 -07001014our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
Joe Perchesc0a5c892015-02-13 14:38:21 -08001015our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
Joe Perches7d2367a2011-07-25 17:13:22 -07001016
Joe Perchesf8422302014-08-06 16:11:31 -07001017our $declaration_macros = qr{(?x:
Joe Perches3e838b62015-09-09 15:37:33 -07001018 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
Steffen Maierfe658f92017-07-10 15:52:10 -07001019 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
Gilad Ben-Yossef3d102fc2018-04-10 16:33:17 -07001020 (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
Joe Perchesf8422302014-08-06 16:11:31 -07001021)};
1022
Aditya Srivastava8d0325c2020-12-15 20:44:24 -08001023our %allow_repeated_words = (
1024 add => '',
1025 added => '',
1026 bad => '',
1027 be => '',
1028);
1029
Joe Perches7d2367a2011-07-25 17:13:22 -07001030sub deparenthesize {
1031 my ($string) = @_;
1032 return "" if (!defined($string));
Joe Perches5b9553a2014-04-03 14:49:21 -07001033
1034 while ($string =~ /^\s*\(.*\)\s*$/) {
1035 $string =~ s@^\s*\(\s*@@;
1036 $string =~ s@\s*\)\s*$@@;
1037 }
1038
Joe Perches7d2367a2011-07-25 17:13:22 -07001039 $string =~ s@\s+@ @g;
Joe Perches5b9553a2014-04-03 14:49:21 -07001040
Joe Perches7d2367a2011-07-25 17:13:22 -07001041 return $string;
1042}
1043
Joe Perches34456862013-07-03 15:05:34 -07001044sub seed_camelcase_file {
1045 my ($file) = @_;
1046
1047 return if (!(-f $file));
1048
1049 local $/;
1050
1051 open(my $include_file, '<', "$file")
1052 or warn "$P: Can't read '$file' $!\n";
1053 my $text = <$include_file>;
1054 close($include_file);
1055
1056 my @lines = split('\n', $text);
1057
1058 foreach my $line (@lines) {
1059 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
1060 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
1061 $camelcase{$1} = 1;
Joe Perches11ea5162013-11-12 15:10:08 -08001062 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
1063 $camelcase{$1} = 1;
1064 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
Joe Perches34456862013-07-03 15:05:34 -07001065 $camelcase{$1} = 1;
1066 }
1067 }
1068}
1069
Joe Perchescd28b112019-12-04 16:52:09 -08001070our %maintained_status = ();
1071
Joe Perches85b0ee12016-10-11 13:51:44 -07001072sub is_maintained_obsolete {
1073 my ($filename) = @_;
1074
Jerome Forissierf2c19c22016-12-12 16:46:23 -08001075 return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
Joe Perches85b0ee12016-10-11 13:51:44 -07001076
Joe Perchescd28b112019-12-04 16:52:09 -08001077 if (!exists($maintained_status{$filename})) {
1078 $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
1079 }
Joe Perches85b0ee12016-10-11 13:51:44 -07001080
Joe Perchescd28b112019-12-04 16:52:09 -08001081 return $maintained_status{$filename} =~ /obsolete/i;
Joe Perches85b0ee12016-10-11 13:51:44 -07001082}
1083
Joe Perches3b6e8ac2018-08-21 21:57:47 -07001084sub is_SPDX_License_valid {
1085 my ($license) = @_;
1086
Guenter Roeckf9363b32021-06-30 18:56:19 -07001087 return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
Joe Perches3b6e8ac2018-08-21 21:57:47 -07001088
Joe Perches56294112018-08-21 21:58:04 -07001089 my $root_path = abs_path($root);
Guenter Roeckf9363b32021-06-30 18:56:19 -07001090 my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`;
Joe Perches3b6e8ac2018-08-21 21:57:47 -07001091 return 0 if ($status ne "");
1092 return 1;
1093}
1094
Joe Perches34456862013-07-03 15:05:34 -07001095my $camelcase_seeded = 0;
1096sub seed_camelcase_includes {
1097 return if ($camelcase_seeded);
1098
1099 my $files;
Joe Perchesc707a812013-07-08 16:00:43 -07001100 my $camelcase_cache = "";
1101 my @include_files = ();
1102
1103 $camelcase_seeded = 1;
Joe Perches351b2a12013-07-03 15:05:36 -07001104
Joe Perches0f7f6352020-10-24 16:59:04 -07001105 if (-e "$gitroot") {
Joe Perchesdbbf8692019-09-25 16:46:52 -07001106 my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
Joe Perches351b2a12013-07-03 15:05:36 -07001107 chomp $git_last_include_commit;
Joe Perchesc707a812013-07-08 16:00:43 -07001108 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
Joe Perches34456862013-07-03 15:05:34 -07001109 } else {
Joe Perchesc707a812013-07-08 16:00:43 -07001110 my $last_mod_date = 0;
Joe Perches34456862013-07-03 15:05:34 -07001111 $files = `find $root/include -name "*.h"`;
Joe Perchesc707a812013-07-08 16:00:43 -07001112 @include_files = split('\n', $files);
1113 foreach my $file (@include_files) {
1114 my $date = POSIX::strftime("%Y%m%d%H%M",
1115 localtime((stat $file)[9]));
1116 $last_mod_date = $date if ($last_mod_date < $date);
1117 }
1118 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
Joe Perches34456862013-07-03 15:05:34 -07001119 }
Joe Perchesc707a812013-07-08 16:00:43 -07001120
1121 if ($camelcase_cache ne "" && -f $camelcase_cache) {
1122 open(my $camelcase_file, '<', "$camelcase_cache")
1123 or warn "$P: Can't read '$camelcase_cache' $!\n";
1124 while (<$camelcase_file>) {
1125 chomp;
1126 $camelcase{$_} = 1;
1127 }
1128 close($camelcase_file);
1129
1130 return;
1131 }
1132
Joe Perches0f7f6352020-10-24 16:59:04 -07001133 if (-e "$gitroot") {
Joe Perchesdbbf8692019-09-25 16:46:52 -07001134 $files = `${git_command} ls-files "include/*.h"`;
Joe Perchesc707a812013-07-08 16:00:43 -07001135 @include_files = split('\n', $files);
1136 }
1137
Joe Perches34456862013-07-03 15:05:34 -07001138 foreach my $file (@include_files) {
1139 seed_camelcase_file($file);
1140 }
Joe Perches351b2a12013-07-03 15:05:36 -07001141
Joe Perchesc707a812013-07-08 16:00:43 -07001142 if ($camelcase_cache ne "") {
Joe Perches351b2a12013-07-03 15:05:36 -07001143 unlink glob ".checkpatch-camelcase.*";
Joe Perchesc707a812013-07-08 16:00:43 -07001144 open(my $camelcase_file, '>', "$camelcase_cache")
1145 or warn "$P: Can't write '$camelcase_cache' $!\n";
Joe Perches351b2a12013-07-03 15:05:36 -07001146 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
1147 print $camelcase_file ("$_\n");
1148 }
1149 close($camelcase_file);
1150 }
Joe Perches34456862013-07-03 15:05:34 -07001151}
1152
Joe Perchesf5f61322020-10-15 20:12:12 -07001153sub git_is_single_file {
1154 my ($filename) = @_;
1155
1156 return 0 if ((which("git") eq "") || !(-e "$gitroot"));
1157
1158 my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
1159 my $count = $output =~ tr/\n//;
1160 return $count eq 1 && $output =~ m{^${filename}$};
1161}
1162
Joe Perchesd311cd42014-08-06 16:10:57 -07001163sub git_commit_info {
1164 my ($commit, $id, $desc) = @_;
1165
Joe Perches0f7f6352020-10-24 16:59:04 -07001166 return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
Joe Perchesd311cd42014-08-06 16:10:57 -07001167
Joe Perchesdbbf8692019-09-25 16:46:52 -07001168 my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
Joe Perchesd311cd42014-08-06 16:10:57 -07001169 $output =~ s/^\s*//gm;
1170 my @lines = split("\n", $output);
1171
Joe Perches0d7835f2015-02-13 14:38:35 -08001172 return ($id, $desc) if ($#lines < 0);
1173
Sean Christopherson5a7f4452019-09-25 16:46:49 -07001174 if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
Joe Perchesd311cd42014-08-06 16:10:57 -07001175# Maybe one day convert this block of bash into something that returns
1176# all matching commit ids, but it's very slow...
1177#
1178# echo "checking commits $1..."
1179# git rev-list --remotes | grep -i "^$1" |
1180# while read line ; do
1181# git log --format='%H %s' -1 $line |
1182# echo "commit $(cut -c 1-12,41-)"
1183# done
Joe Perches4ce9f972021-09-07 19:59:57 -07001184 } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ ||
1185 $lines[0] =~ /^fatal: bad object $commit/) {
Heinrich Schuchardt948b1332017-07-10 15:52:16 -07001186 $id = undef;
Joe Perchesd311cd42014-08-06 16:10:57 -07001187 } else {
1188 $id = substr($lines[0], 0, 12);
1189 $desc = substr($lines[0], 41);
1190 }
1191
1192 return ($id, $desc);
1193}
1194
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001195$chk_signoff = 0 if ($file);
1196
Andy Whitcroft00df3442007-06-08 13:47:06 -07001197my @rawlines = ();
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001198my @lines = ();
Joe Perches3705ce52013-07-03 15:05:31 -07001199my @fixed = ();
Joe Perchesd752fcc2014-08-06 16:11:05 -07001200my @fixed_inserted = ();
1201my @fixed_deleted = ();
Joe Perches194f66f2014-08-06 16:11:03 -07001202my $fixlinenr = -1;
1203
Du, Changbin4a593c32016-05-20 17:04:16 -07001204# If input is git commits, extract all commits from the commit expressions.
1205# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
Joe Perches0f7f6352020-10-24 16:59:04 -07001206die "$P: No git repository found\n" if ($git && !-e "$gitroot");
Du, Changbin4a593c32016-05-20 17:04:16 -07001207
1208if ($git) {
1209 my @commits = ();
Joe Perches0dea9f1e2016-05-20 17:04:19 -07001210 foreach my $commit_expr (@ARGV) {
Du, Changbin4a593c32016-05-20 17:04:16 -07001211 my $git_range;
Joe Perches28898fd2016-05-20 17:04:22 -07001212 if ($commit_expr =~ m/^(.*)-(\d+)$/) {
1213 $git_range = "-$2 $1";
Du, Changbin4a593c32016-05-20 17:04:16 -07001214 } elsif ($commit_expr =~ m/\.\./) {
1215 $git_range = "$commit_expr";
Du, Changbin4a593c32016-05-20 17:04:16 -07001216 } else {
Joe Perches0dea9f1e2016-05-20 17:04:19 -07001217 $git_range = "-1 $commit_expr";
1218 }
Joe Perchesdbbf8692019-09-25 16:46:52 -07001219 my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
Joe Perches0dea9f1e2016-05-20 17:04:19 -07001220 foreach my $line (split(/\n/, $lines)) {
Joe Perches28898fd2016-05-20 17:04:22 -07001221 $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
1222 next if (!defined($1) || !defined($2));
Joe Perches0dea9f1e2016-05-20 17:04:19 -07001223 my $sha1 = $1;
1224 my $subject = $2;
1225 unshift(@commits, $sha1);
1226 $git_commits{$sha1} = $subject;
Du, Changbin4a593c32016-05-20 17:04:16 -07001227 }
1228 }
1229 die "$P: no git commits after extraction!\n" if (@commits == 0);
1230 @ARGV = @commits;
1231}
1232
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001233my $vname;
Vadim Bendebury98005e82019-03-07 16:28:38 -08001234$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001235for my $filename (@ARGV) {
Andy Whitcroft21caa132009-01-06 14:41:30 -08001236 my $FILE;
Joe Perchesf5f61322020-10-15 20:12:12 -07001237 my $is_git_file = git_is_single_file($filename);
1238 my $oldfile = $file;
1239 $file = 1 if ($is_git_file);
Du, Changbin4a593c32016-05-20 17:04:16 -07001240 if ($git) {
1241 open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
1242 die "$P: $filename: git format-patch failed - $!\n";
1243 } elsif ($file) {
Andy Whitcroft21caa132009-01-06 14:41:30 -08001244 open($FILE, '-|', "diff -u /dev/null $filename") ||
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001245 die "$P: $filename: diff failed - $!\n";
Andy Whitcroft21caa132009-01-06 14:41:30 -08001246 } elsif ($filename eq '-') {
1247 open($FILE, '<&STDIN');
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001248 } else {
Andy Whitcroft21caa132009-01-06 14:41:30 -08001249 open($FILE, '<', "$filename") ||
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001250 die "$P: $filename: open failed - $!\n";
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001251 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001252 if ($filename eq '-') {
1253 $vname = 'Your patch';
Du, Changbin4a593c32016-05-20 17:04:16 -07001254 } elsif ($git) {
Joe Perches0dea9f1e2016-05-20 17:04:19 -07001255 $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001256 } else {
1257 $vname = $filename;
1258 }
Andy Whitcroft21caa132009-01-06 14:41:30 -08001259 while (<$FILE>) {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001260 chomp;
1261 push(@rawlines, $_);
Geert Uytterhoevenc7f574d2020-06-04 16:50:43 -07001262 $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001263 }
Andy Whitcroft21caa132009-01-06 14:41:30 -08001264 close($FILE);
Joe Perchesd8469f12015-06-25 15:03:00 -07001265
1266 if ($#ARGV > 0 && $quiet == 0) {
1267 print '-' x length($vname) . "\n";
1268 print "$vname\n";
1269 print '-' x length($vname) . "\n";
1270 }
1271
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001272 if (!process($filename)) {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001273 $exit = 1;
1274 }
1275 @rawlines = ();
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001276 @lines = ();
Joe Perches3705ce52013-07-03 15:05:31 -07001277 @fixed = ();
Joe Perchesd752fcc2014-08-06 16:11:05 -07001278 @fixed_inserted = ();
1279 @fixed_deleted = ();
Joe Perches194f66f2014-08-06 16:11:03 -07001280 $fixlinenr = -1;
Alex Dowad485ff232015-06-25 15:02:52 -07001281 @modifierListFile = ();
1282 @typeListFile = ();
1283 build_types();
Joe Perchesf5f61322020-10-15 20:12:12 -07001284 $file = $oldfile if ($is_git_file);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001285}
1286
Joe Perchesd8469f12015-06-25 15:03:00 -07001287if (!$quiet) {
Joe Perches3c816e42015-06-25 15:03:29 -07001288 hash_show_words(\%use_type, "Used");
1289 hash_show_words(\%ignore_type, "Ignored");
1290
Joe Perches5b579802018-08-21 21:57:33 -07001291 if (!$perl_version_ok) {
Joe Perchesd8469f12015-06-25 15:03:00 -07001292 print << "EOM"
1293
1294NOTE: perl $^V is not modern enough to detect all possible issues.
Joe Perches5b579802018-08-21 21:57:33 -07001295 An upgrade to at least perl $minimum_perl_version is suggested.
Joe Perchesd8469f12015-06-25 15:03:00 -07001296EOM
1297 }
1298 if ($exit) {
1299 print << "EOM"
1300
1301NOTE: If any of the errors are false positives, please report
1302 them to the maintainer, see CHECKPATCH in MAINTAINERS.
1303EOM
1304 }
1305}
1306
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001307exit($exit);
1308
1309sub top_of_kernel_tree {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001310 my ($root) = @_;
1311
1312 my @tree_check = (
1313 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
1314 "README", "Documentation", "arch", "include", "drivers",
1315 "fs", "init", "ipc", "kernel", "lib", "scripts",
1316 );
1317
1318 foreach my $check (@tree_check) {
1319 if (! -e $root . '/' . $check) {
1320 return 0;
1321 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001322 }
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001323 return 1;
Joe Perches8f26b832012-10-04 17:13:32 -07001324}
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001325
Joe Perches20112472011-07-25 17:13:23 -07001326sub parse_email {
1327 my ($formatted_email) = @_;
1328
1329 my $name = "";
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08001330 my $quoted = "";
Joe Perchesdfa05c22020-04-06 20:10:48 -07001331 my $name_comment = "";
Joe Perches20112472011-07-25 17:13:23 -07001332 my $address = "";
1333 my $comment = "";
1334
1335 if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
1336 $name = $1;
1337 $address = $2;
1338 $comment = $3 if defined $3;
1339 } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
1340 $address = $1;
1341 $comment = $2 if defined $2;
1342 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1343 $address = $1;
1344 $comment = $2 if defined $2;
Joe Perches85e12062018-04-10 16:33:09 -07001345 $formatted_email =~ s/\Q$address\E.*$//;
Joe Perches20112472011-07-25 17:13:23 -07001346 $name = $formatted_email;
Joe Perches3705ce52013-07-03 15:05:31 -07001347 $name = trim($name);
Joe Perches20112472011-07-25 17:13:23 -07001348 $name =~ s/^\"|\"$//g;
1349 # If there's a name left after stripping spaces and
1350 # leading quotes, and the address doesn't have both
1351 # leading and trailing angle brackets, the address
1352 # is invalid. ie:
1353 # "joe smith joe@smith.com" bad
1354 # "joe smith <joe@smith.com" bad
1355 if ($name ne "" && $address !~ /^<[^>]+>$/) {
1356 $name = "";
1357 $address = "";
1358 $comment = "";
1359 }
1360 }
1361
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08001362 # Extract comments from names excluding quoted parts
1363 # "John D. (Doe)" - Do not extract
1364 if ($name =~ s/\"(.+)\"//) {
1365 $quoted = $1;
Joe Perchesdfa05c22020-04-06 20:10:48 -07001366 }
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08001367 while ($name =~ s/\s*($balanced_parens)\s*/ /) {
1368 $name_comment .= trim($1);
1369 }
1370 $name =~ s/^[ \"]+|[ \"]+$//g;
1371 $name = trim("$quoted $name");
1372
Joe Perches3705ce52013-07-03 15:05:31 -07001373 $address = trim($address);
Joe Perches20112472011-07-25 17:13:23 -07001374 $address =~ s/^\<|\>$//g;
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08001375 $comment = trim($comment);
Joe Perches20112472011-07-25 17:13:23 -07001376
1377 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1378 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1379 $name = "\"$name\"";
1380 }
1381
Joe Perchesdfa05c22020-04-06 20:10:48 -07001382 return ($name, $name_comment, $address, $comment);
Joe Perches20112472011-07-25 17:13:23 -07001383}
1384
1385sub format_email {
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07001386 my ($name, $name_comment, $address, $comment) = @_;
Joe Perches20112472011-07-25 17:13:23 -07001387
1388 my $formatted_email;
1389
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08001390 $name =~ s/^[ \"]+|[ \"]+$//g;
Joe Perches3705ce52013-07-03 15:05:31 -07001391 $address = trim($address);
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08001392 $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
Joe Perches20112472011-07-25 17:13:23 -07001393
1394 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1395 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1396 $name = "\"$name\"";
1397 }
1398
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08001399 $name_comment = trim($name_comment);
1400 $name_comment = " $name_comment" if ($name_comment ne "");
1401 $comment = trim($comment);
1402 $comment = " $comment" if ($comment ne "");
1403
Joe Perches20112472011-07-25 17:13:23 -07001404 if ("$name" eq "") {
1405 $formatted_email = "$address";
1406 } else {
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07001407 $formatted_email = "$name$name_comment <$address>";
Joe Perches20112472011-07-25 17:13:23 -07001408 }
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07001409 $formatted_email .= "$comment";
Joe Perches20112472011-07-25 17:13:23 -07001410 return $formatted_email;
1411}
1412
Joe Perchesdfa05c22020-04-06 20:10:48 -07001413sub reformat_email {
1414 my ($email) = @_;
1415
1416 my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07001417 return format_email($email_name, $name_comment, $email_address, $comment);
Joe Perchesdfa05c22020-04-06 20:10:48 -07001418}
1419
1420sub same_email_addresses {
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08001421 my ($email1, $email2) = @_;
Joe Perchesdfa05c22020-04-06 20:10:48 -07001422
1423 my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1424 my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1425
1426 return $email1_name eq $email2_name &&
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07001427 $email1_address eq $email2_address &&
1428 $name1_comment eq $name2_comment &&
1429 $comment1 eq $comment2;
Joe Perchesdfa05c22020-04-06 20:10:48 -07001430}
1431
Joe Perchesd311cd42014-08-06 16:10:57 -07001432sub which {
Joe Perchesbd474ca2014-08-06 16:11:10 -07001433 my ($bin) = @_;
Joe Perchesd311cd42014-08-06 16:10:57 -07001434
Joe Perchesbd474ca2014-08-06 16:11:10 -07001435 foreach my $path (split(/:/, $ENV{PATH})) {
1436 if (-e "$path/$bin") {
1437 return "$path/$bin";
1438 }
Joe Perchesd311cd42014-08-06 16:10:57 -07001439 }
Joe Perchesd311cd42014-08-06 16:10:57 -07001440
Joe Perchesbd474ca2014-08-06 16:11:10 -07001441 return "";
Joe Perchesd311cd42014-08-06 16:10:57 -07001442}
1443
Joe Perches000d1cc12011-07-25 17:13:25 -07001444sub which_conf {
1445 my ($conf) = @_;
1446
1447 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1448 if (-e "$path/$conf") {
1449 return "$path/$conf";
1450 }
1451 }
1452
1453 return "";
1454}
1455
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001456sub expand_tabs {
1457 my ($str) = @_;
1458
1459 my $res = '';
1460 my $n = 0;
1461 for my $c (split(//, $str)) {
1462 if ($c eq "\t") {
1463 $res .= ' ';
1464 $n++;
Antonio Borneo713a09d2020-04-06 20:11:07 -07001465 for (; ($n % $tabsize) != 0; $n++) {
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001466 $res .= ' ';
1467 }
1468 next;
1469 }
1470 $res .= $c;
1471 $n++;
1472 }
1473
1474 return $res;
1475}
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001476sub copy_spacing {
Andy Whitcroft773647a2008-03-28 14:15:58 -07001477 (my $res = shift) =~ tr/\t/ /c;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001478 return $res;
1479}
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001480
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001481sub line_stats {
1482 my ($line) = @_;
1483
1484 # Drop the diff line leader and expand tabs
1485 $line =~ s/^.//;
1486 $line = expand_tabs($line);
1487
1488 # Pick the indent from the front of the line.
1489 my ($white) = ($line =~ /^(\s*)/);
1490
1491 return (length($line), length($white));
1492}
1493
Andy Whitcroft773647a2008-03-28 14:15:58 -07001494my $sanitise_quote = '';
1495
1496sub sanitise_line_reset {
1497 my ($in_comment) = @_;
1498
1499 if ($in_comment) {
1500 $sanitise_quote = '*/';
1501 } else {
1502 $sanitise_quote = '';
1503 }
1504}
Andy Whitcroft00df3442007-06-08 13:47:06 -07001505sub sanitise_line {
1506 my ($line) = @_;
1507
1508 my $res = '';
1509 my $l = '';
1510
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001511 my $qlen = 0;
Andy Whitcroft773647a2008-03-28 14:15:58 -07001512 my $off = 0;
1513 my $c;
Andy Whitcroft00df3442007-06-08 13:47:06 -07001514
Andy Whitcroft773647a2008-03-28 14:15:58 -07001515 # Always copy over the diff marker.
1516 $res = substr($line, 0, 1);
1517
1518 for ($off = 1; $off < length($line); $off++) {
1519 $c = substr($line, $off, 1);
1520
Claudio Fontana8d2e11b2018-04-10 16:33:42 -07001521 # Comments we are whacking completely including the begin
Andy Whitcroft773647a2008-03-28 14:15:58 -07001522 # and end, all to $;.
1523 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1524 $sanitise_quote = '*/';
1525
1526 substr($res, $off, 2, "$;$;");
1527 $off++;
1528 next;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001529 }
Andy Whitcroft81bc0e02008-10-15 22:02:26 -07001530 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
Andy Whitcroft773647a2008-03-28 14:15:58 -07001531 $sanitise_quote = '';
1532 substr($res, $off, 2, "$;$;");
1533 $off++;
1534 next;
1535 }
Daniel Walker113f04a2009-09-21 17:04:35 -07001536 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1537 $sanitise_quote = '//';
1538
1539 substr($res, $off, 2, $sanitise_quote);
1540 $off++;
1541 next;
1542 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07001543
1544 # A \ in a string means ignore the next character.
1545 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1546 $c eq "\\") {
1547 substr($res, $off, 2, 'XX');
1548 $off++;
1549 next;
1550 }
1551 # Regular quotes.
1552 if ($c eq "'" || $c eq '"') {
1553 if ($sanitise_quote eq '') {
1554 $sanitise_quote = $c;
1555
1556 substr($res, $off, 1, $c);
Andy Whitcroft00df3442007-06-08 13:47:06 -07001557 next;
Andy Whitcroft773647a2008-03-28 14:15:58 -07001558 } elsif ($sanitise_quote eq $c) {
1559 $sanitise_quote = '';
Andy Whitcroft00df3442007-06-08 13:47:06 -07001560 }
1561 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07001562
Andy Whitcroftfae17da2009-01-06 14:41:20 -08001563 #print "c<$c> SQ<$sanitise_quote>\n";
Andy Whitcroft773647a2008-03-28 14:15:58 -07001564 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1565 substr($res, $off, 1, $;);
Daniel Walker113f04a2009-09-21 17:04:35 -07001566 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1567 substr($res, $off, 1, $;);
Andy Whitcroft773647a2008-03-28 14:15:58 -07001568 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1569 substr($res, $off, 1, 'X');
Andy Whitcroft00df3442007-06-08 13:47:06 -07001570 } else {
Andy Whitcroft773647a2008-03-28 14:15:58 -07001571 substr($res, $off, 1, $c);
Andy Whitcroft00df3442007-06-08 13:47:06 -07001572 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001573 }
1574
Daniel Walker113f04a2009-09-21 17:04:35 -07001575 if ($sanitise_quote eq '//') {
1576 $sanitise_quote = '';
1577 }
1578
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001579 # The pathname on a #include may be surrounded by '<' and '>'.
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07001580 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001581 my $clean = 'X' x length($1);
1582 $res =~ s@\<.*\>@<$clean>@;
1583
1584 # The whole of a #error is a string.
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07001585 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001586 my $clean = 'X' x length($1);
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07001587 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001588 }
1589
Joe Perchesdadf6802016-08-02 14:04:33 -07001590 if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1591 my $match = $1;
1592 $res =~ s/\Q$match\E/"$;" x length($match)/e;
1593 }
1594
Andy Whitcroft00df3442007-06-08 13:47:06 -07001595 return $res;
1596}
1597
Joe Perchesa6962d72013-04-29 16:18:13 -07001598sub get_quoted_string {
1599 my ($line, $rawline) = @_;
1600
Joe Perches478b1792018-04-10 16:33:34 -07001601 return "" if (!defined($line) || !defined($rawline));
Joe Perches33acb542015-06-25 15:02:54 -07001602 return "" if ($line !~ m/($String)/g);
Joe Perchesa6962d72013-04-29 16:18:13 -07001603 return substr($rawline, $-[0], $+[0] - $-[0]);
1604}
1605
Andy Whitcroft8905a672007-11-28 16:21:06 -08001606sub ctx_statement_block {
1607 my ($linenr, $remain, $off) = @_;
1608 my $line = $linenr - 1;
1609 my $blk = '';
1610 my $soff = $off;
1611 my $coff = $off - 1;
Andy Whitcroft773647a2008-03-28 14:15:58 -07001612 my $coff_set = 0;
Andy Whitcroft8905a672007-11-28 16:21:06 -08001613
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001614 my $loff = 0;
1615
Andy Whitcroft8905a672007-11-28 16:21:06 -08001616 my $type = '';
1617 my $level = 0;
Andy Whitcrofta2750642009-01-15 13:51:04 -08001618 my @stack = ();
Andy Whitcroftcf655042008-03-04 14:28:20 -08001619 my $p;
Andy Whitcroft8905a672007-11-28 16:21:06 -08001620 my $c;
1621 my $len = 0;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001622
1623 my $remainder;
Andy Whitcroft8905a672007-11-28 16:21:06 -08001624 while (1) {
Andy Whitcrofta2750642009-01-15 13:51:04 -08001625 @stack = (['', 0]) if ($#stack == -1);
1626
Andy Whitcroft773647a2008-03-28 14:15:58 -07001627 #warn "CSB: blk<$blk> remain<$remain>\n";
Andy Whitcroft8905a672007-11-28 16:21:06 -08001628 # If we are about to drop off the end, pull in more
1629 # context.
1630 if ($off >= $len) {
1631 for (; $remain > 0; $line++) {
Andy Whitcroftdea33492008-10-15 22:02:25 -07001632 last if (!defined $lines[$line]);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001633 next if ($lines[$line] =~ /^-/);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001634 $remain--;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001635 $loff = $len;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001636 $blk .= $lines[$line] . "\n";
Andy Whitcroft8905a672007-11-28 16:21:06 -08001637 $len = length($blk);
1638 $line++;
1639 last;
1640 }
1641 # Bail if there is no further context.
1642 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001643 if ($off >= $len) {
Andy Whitcroft8905a672007-11-28 16:21:06 -08001644 last;
1645 }
Andy Whitcroftf74bd192012-01-10 15:09:54 -08001646 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1647 $level++;
1648 $type = '#';
1649 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08001650 }
Andy Whitcroftcf655042008-03-04 14:28:20 -08001651 $p = $c;
Andy Whitcroft8905a672007-11-28 16:21:06 -08001652 $c = substr($blk, $off, 1);
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001653 $remainder = substr($blk, $off);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001654
Andy Whitcroft773647a2008-03-28 14:15:58 -07001655 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
Andy Whitcroft4635f4f2009-01-06 14:41:27 -08001656
1657 # Handle nested #if/#else.
1658 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
1659 push(@stack, [ $type, $level ]);
1660 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
1661 ($type, $level) = @{$stack[$#stack - 1]};
1662 } elsif ($remainder =~ /^#\s*endif\b/) {
1663 ($type, $level) = @{pop(@stack)};
1664 }
1665
Andy Whitcroft8905a672007-11-28 16:21:06 -08001666 # Statement ends at the ';' or a close '}' at the
1667 # outermost level.
1668 if ($level == 0 && $c eq ';') {
1669 last;
1670 }
1671
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001672 # An else is really a conditional as long as its not else if
Andy Whitcroft773647a2008-03-28 14:15:58 -07001673 if ($level == 0 && $coff_set == 0 &&
1674 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1675 $remainder =~ /^(else)(?:\s|{)/ &&
1676 $remainder !~ /^else\s+if\b/) {
1677 $coff = $off + length($1) - 1;
1678 $coff_set = 1;
1679 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1680 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001681 }
1682
Andy Whitcroft8905a672007-11-28 16:21:06 -08001683 if (($type eq '' || $type eq '(') && $c eq '(') {
1684 $level++;
1685 $type = '(';
1686 }
1687 if ($type eq '(' && $c eq ')') {
1688 $level--;
1689 $type = ($level != 0)? '(' : '';
1690
1691 if ($level == 0 && $coff < $soff) {
1692 $coff = $off;
Andy Whitcroft773647a2008-03-28 14:15:58 -07001693 $coff_set = 1;
1694 #warn "CSB: mark coff<$coff>\n";
Andy Whitcroft8905a672007-11-28 16:21:06 -08001695 }
1696 }
1697 if (($type eq '' || $type eq '{') && $c eq '{') {
1698 $level++;
1699 $type = '{';
1700 }
1701 if ($type eq '{' && $c eq '}') {
1702 $level--;
1703 $type = ($level != 0)? '{' : '';
1704
1705 if ($level == 0) {
Patrick Pannutob998e002010-08-09 17:21:03 -07001706 if (substr($blk, $off + 1, 1) eq ';') {
1707 $off++;
1708 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08001709 last;
1710 }
1711 }
Andy Whitcroftf74bd192012-01-10 15:09:54 -08001712 # Preprocessor commands end at the newline unless escaped.
1713 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1714 $level--;
1715 $type = '';
1716 $off++;
1717 last;
1718 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08001719 $off++;
1720 }
Andy Whitcrofta3bb97a2008-07-23 21:29:00 -07001721 # We are truly at the end, so shuffle to the next line.
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001722 if ($off == $len) {
Andy Whitcrofta3bb97a2008-07-23 21:29:00 -07001723 $loff = $len + 1;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001724 $line++;
1725 $remain--;
1726 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08001727
1728 my $statement = substr($blk, $soff, $off - $soff + 1);
1729 my $condition = substr($blk, $soff, $coff - $soff + 1);
1730
1731 #warn "STATEMENT<$statement>\n";
1732 #warn "CONDITION<$condition>\n";
1733
Andy Whitcroft773647a2008-03-28 14:15:58 -07001734 #print "coff<$coff> soff<$off> loff<$loff>\n";
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001735
1736 return ($statement, $condition,
1737 $line, $remain + 1, $off - $loff + 1, $level);
1738}
1739
Andy Whitcroftcf655042008-03-04 14:28:20 -08001740sub statement_lines {
1741 my ($stmt) = @_;
1742
1743 # Strip the diff line prefixes and rip blank lines at start and end.
1744 $stmt =~ s/(^|\n)./$1/g;
1745 $stmt =~ s/^\s*//;
1746 $stmt =~ s/\s*$//;
1747
1748 my @stmt_lines = ($stmt =~ /\n/g);
1749
1750 return $#stmt_lines + 2;
1751}
1752
1753sub statement_rawlines {
1754 my ($stmt) = @_;
1755
1756 my @stmt_lines = ($stmt =~ /\n/g);
1757
1758 return $#stmt_lines + 2;
1759}
1760
1761sub statement_block_size {
1762 my ($stmt) = @_;
1763
1764 $stmt =~ s/(^|\n)./$1/g;
1765 $stmt =~ s/^\s*{//;
1766 $stmt =~ s/}\s*$//;
1767 $stmt =~ s/^\s*//;
1768 $stmt =~ s/\s*$//;
1769
1770 my @stmt_lines = ($stmt =~ /\n/g);
1771 my @stmt_statements = ($stmt =~ /;/g);
1772
1773 my $stmt_lines = $#stmt_lines + 2;
1774 my $stmt_statements = $#stmt_statements + 1;
1775
1776 if ($stmt_lines > $stmt_statements) {
1777 return $stmt_lines;
1778 } else {
1779 return $stmt_statements;
1780 }
1781}
1782
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001783sub ctx_statement_full {
1784 my ($linenr, $remain, $off) = @_;
1785 my ($statement, $condition, $level);
1786
1787 my (@chunks);
1788
Andy Whitcroftcf655042008-03-04 14:28:20 -08001789 # Grab the first conditional/block pair.
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001790 ($statement, $condition, $linenr, $remain, $off, $level) =
1791 ctx_statement_block($linenr, $remain, $off);
Andy Whitcroft773647a2008-03-28 14:15:58 -07001792 #print "F: c<$condition> s<$statement> remain<$remain>\n";
Andy Whitcroftcf655042008-03-04 14:28:20 -08001793 push(@chunks, [ $condition, $statement ]);
1794 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1795 return ($level, $linenr, @chunks);
1796 }
1797
1798 # Pull in the following conditional/block pairs and see if they
1799 # could continue the statement.
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001800 for (;;) {
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001801 ($statement, $condition, $linenr, $remain, $off, $level) =
1802 ctx_statement_block($linenr, $remain, $off);
Andy Whitcroftcf655042008-03-04 14:28:20 -08001803 #print "C: c<$condition> s<$statement> remain<$remain>\n";
Andy Whitcroft773647a2008-03-28 14:15:58 -07001804 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
Andy Whitcroftcf655042008-03-04 14:28:20 -08001805 #print "C: push\n";
1806 push(@chunks, [ $condition, $statement ]);
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001807 }
1808
1809 return ($level, $linenr, @chunks);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001810}
1811
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001812sub ctx_block_get {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001813 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001814 my $line;
1815 my $start = $linenr - 1;
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001816 my $blk = '';
1817 my @o;
1818 my @c;
1819 my @res = ();
1820
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001821 my $level = 0;
Andy Whitcroft4635f4f2009-01-06 14:41:27 -08001822 my @stack = ($level);
Andy Whitcroft00df3442007-06-08 13:47:06 -07001823 for ($line = $start; $remain > 0; $line++) {
1824 next if ($rawlines[$line] =~ /^-/);
1825 $remain--;
1826
1827 $blk .= $rawlines[$line];
Andy Whitcroft4635f4f2009-01-06 14:41:27 -08001828
1829 # Handle nested #if/#else.
Andy Whitcroft01464f32010-10-26 14:23:19 -07001830 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
Andy Whitcroft4635f4f2009-01-06 14:41:27 -08001831 push(@stack, $level);
Andy Whitcroft01464f32010-10-26 14:23:19 -07001832 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
Andy Whitcroft4635f4f2009-01-06 14:41:27 -08001833 $level = $stack[$#stack - 1];
Andy Whitcroft01464f32010-10-26 14:23:19 -07001834 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
Andy Whitcroft4635f4f2009-01-06 14:41:27 -08001835 $level = pop(@stack);
1836 }
1837
Andy Whitcroft01464f32010-10-26 14:23:19 -07001838 foreach my $c (split(//, $lines[$line])) {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001839 ##print "C<$c>L<$level><$open$close>O<$off>\n";
1840 if ($off > 0) {
1841 $off--;
1842 next;
1843 }
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001844
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001845 if ($c eq $close && $level > 0) {
1846 $level--;
1847 last if ($level == 0);
1848 } elsif ($c eq $open) {
1849 $level++;
1850 }
1851 }
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001852
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001853 if (!$outer || $level <= 1) {
Andy Whitcroft00df3442007-06-08 13:47:06 -07001854 push(@res, $rawlines[$line]);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001855 }
1856
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001857 last if ($level == 0);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001858 }
1859
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001860 return ($level, @res);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001861}
1862sub ctx_block_outer {
1863 my ($linenr, $remain) = @_;
1864
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001865 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1866 return @r;
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001867}
1868sub ctx_block {
1869 my ($linenr, $remain) = @_;
1870
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001871 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1872 return @r;
Andy Whitcroft653d4872007-06-23 17:16:34 -07001873}
1874sub ctx_statement {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001875 my ($linenr, $remain, $off) = @_;
1876
1877 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1878 return @r;
1879}
1880sub ctx_block_level {
Andy Whitcroft653d4872007-06-23 17:16:34 -07001881 my ($linenr, $remain) = @_;
1882
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001883 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001884}
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001885sub ctx_statement_level {
1886 my ($linenr, $remain, $off) = @_;
1887
1888 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1889}
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001890
1891sub ctx_locate_comment {
1892 my ($first_line, $end_line) = @_;
1893
Joe Perchesa55ee0c2020-06-04 16:50:36 -07001894 # If c99 comment on the current line, or the line before or after
1895 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1896 return $current_comment if (defined $current_comment);
1897 ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1898 return $current_comment if (defined $current_comment);
1899 ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1900 return $current_comment if (defined $current_comment);
1901
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001902 # Catch a comment on the end of the line itself.
Joe Perchesa55ee0c2020-06-04 16:50:36 -07001903 ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001904 return $current_comment if (defined $current_comment);
1905
1906 # Look through the context and try and figure out if there is a
1907 # comment.
1908 my $in_comment = 0;
1909 $current_comment = '';
1910 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
Andy Whitcroft00df3442007-06-08 13:47:06 -07001911 my $line = $rawlines[$linenr - 1];
1912 #warn " $line\n";
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001913 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1914 $in_comment = 1;
1915 }
1916 if ($line =~ m@/\*@) {
1917 $in_comment = 1;
1918 }
1919 if (!$in_comment && $current_comment ne '') {
1920 $current_comment = '';
1921 }
1922 $current_comment .= $line . "\n" if ($in_comment);
1923 if ($line =~ m@\*/@) {
1924 $in_comment = 0;
1925 }
1926 }
1927
1928 chomp($current_comment);
1929 return($current_comment);
1930}
1931sub ctx_has_comment {
1932 my ($first_line, $end_line) = @_;
1933 my $cmt = ctx_locate_comment($first_line, $end_line);
1934
Andy Whitcroft00df3442007-06-08 13:47:06 -07001935 ##print "LINE: $rawlines[$end_line - 1 ]\n";
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001936 ##print "CMMT: $cmt\n";
1937
1938 return ($cmt ne '');
1939}
1940
Andy Whitcroft4d001e42008-10-15 22:02:21 -07001941sub raw_line {
1942 my ($linenr, $cnt) = @_;
1943
1944 my $offset = $linenr - 1;
1945 $cnt++;
1946
1947 my $line;
1948 while ($cnt) {
1949 $line = $rawlines[$offset++];
1950 next if (defined($line) && $line =~ /^-/);
1951 $cnt--;
1952 }
1953
1954 return $line;
1955}
1956
Tobin C. Harding2a9f9d82018-04-10 16:33:20 -07001957sub get_stat_real {
1958 my ($linenr, $lc) = @_;
1959
1960 my $stat_real = raw_line($linenr, 0);
1961 for (my $count = $linenr + 1; $count <= $lc; $count++) {
1962 $stat_real = $stat_real . "\n" . raw_line($count, 0);
1963 }
1964
1965 return $stat_real;
1966}
1967
Tobin C. Hardinge3d95a22018-04-10 16:33:27 -07001968sub get_stat_here {
1969 my ($linenr, $cnt, $here) = @_;
1970
1971 my $herectx = $here . "\n";
1972 for (my $n = 0; $n < $cnt; $n++) {
1973 $herectx .= raw_line($linenr, $n) . "\n";
1974 }
1975
1976 return $herectx;
1977}
1978
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001979sub cat_vet {
1980 my ($vet) = @_;
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001981 my ($res, $coded);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001982
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001983 $res = '';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001984 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1985 $res .= $1;
1986 if ($2 ne '') {
1987 $coded = sprintf("^%c", unpack('C', $2) + 64);
1988 $res .= $coded;
1989 }
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001990 }
1991 $res =~ s/$/\$/;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001992
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001993 return $res;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07001994}
1995
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001996my $av_preprocessor = 0;
Andy Whitcroftcf655042008-03-04 14:28:20 -08001997my $av_pending;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001998my @av_paren_type;
Andy Whitcroft1f65f942008-07-23 21:29:10 -07001999my $av_pend_colon;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002000
2001sub annotate_reset {
2002 $av_preprocessor = 0;
Andy Whitcroftcf655042008-03-04 14:28:20 -08002003 $av_pending = '_';
2004 @av_paren_type = ('E');
Andy Whitcroft1f65f942008-07-23 21:29:10 -07002005 $av_pend_colon = 'O';
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002006}
2007
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002008sub annotate_values {
2009 my ($stream, $type) = @_;
2010
2011 my $res;
Andy Whitcroft1f65f942008-07-23 21:29:10 -07002012 my $var = '_' x length($stream);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002013 my $cur = $stream;
2014
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002015 print "$stream\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002016
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002017 while (length($cur)) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07002018 @av_paren_type = ('E') if ($#av_paren_type < 0);
Andy Whitcroftcf655042008-03-04 14:28:20 -08002019 print " <" . join('', @av_paren_type) .
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002020 "> <$type> <$av_pending>" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002021 if ($cur =~ /^(\s+)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002022 print "WS($1)\n" if ($dbg_values > 1);
2023 if ($1 =~ /\n/ && $av_preprocessor) {
Andy Whitcroftcf655042008-03-04 14:28:20 -08002024 $type = pop(@av_paren_type);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002025 $av_preprocessor = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002026 }
2027
Florian Micklerc023e4732011-01-12 16:59:58 -08002028 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
Andy Whitcroft9446ef52010-10-26 14:23:13 -07002029 print "CAST($1)\n" if ($dbg_values > 1);
2030 push(@av_paren_type, $type);
Andy Whitcroftaddcdce2012-01-10 15:10:11 -08002031 $type = 'c';
Andy Whitcroft9446ef52010-10-26 14:23:13 -07002032
Andy Whitcrofte91b6e22010-10-26 14:23:11 -07002033 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002034 print "DECLARE($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002035 $type = 'T';
2036
Andy Whitcroft389a2fe2008-07-23 21:29:05 -07002037 } elsif ($cur =~ /^($Modifier)\s*/) {
2038 print "MODIFIER($1)\n" if ($dbg_values > 1);
2039 $type = 'T';
2040
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002041 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002042 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002043 $av_preprocessor = 1;
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002044 push(@av_paren_type, $type);
2045 if ($2 ne '') {
2046 $av_pending = 'N';
2047 }
2048 $type = 'E';
2049
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002050 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002051 print "UNDEF($1)\n" if ($dbg_values > 1);
2052 $av_preprocessor = 1;
2053 push(@av_paren_type, $type);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002054
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002055 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
Andy Whitcroftcf655042008-03-04 14:28:20 -08002056 print "PRE_START($1)\n" if ($dbg_values > 1);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002057 $av_preprocessor = 1;
Andy Whitcroftcf655042008-03-04 14:28:20 -08002058
2059 push(@av_paren_type, $type);
2060 push(@av_paren_type, $type);
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002061 $type = 'E';
Andy Whitcroftcf655042008-03-04 14:28:20 -08002062
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002063 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
Andy Whitcroftcf655042008-03-04 14:28:20 -08002064 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
2065 $av_preprocessor = 1;
2066
2067 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
2068
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002069 $type = 'E';
Andy Whitcroftcf655042008-03-04 14:28:20 -08002070
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002071 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
Andy Whitcroftcf655042008-03-04 14:28:20 -08002072 print "PRE_END($1)\n" if ($dbg_values > 1);
2073
2074 $av_preprocessor = 1;
2075
2076 # Assume all arms of the conditional end as this
2077 # one does, and continue as if the #endif was not here.
2078 pop(@av_paren_type);
2079 push(@av_paren_type, $type);
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002080 $type = 'E';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002081
2082 } elsif ($cur =~ /^(\\\n)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002083 print "PRECONT($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002084
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002085 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
2086 print "ATTR($1)\n" if ($dbg_values > 1);
2087 $av_pending = $type;
2088 $type = 'N';
2089
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002090 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002091 print "SIZEOF($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002092 if (defined $2) {
Andy Whitcroftcf655042008-03-04 14:28:20 -08002093 $av_pending = 'V';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002094 }
2095 $type = 'N';
2096
Andy Whitcroft14b111c2008-10-15 22:02:16 -07002097 } elsif ($cur =~ /^(if|while|for)\b/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002098 print "COND($1)\n" if ($dbg_values > 1);
Andy Whitcroft14b111c2008-10-15 22:02:16 -07002099 $av_pending = 'E';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002100 $type = 'N';
2101
Andy Whitcroft1f65f942008-07-23 21:29:10 -07002102 } elsif ($cur =~/^(case)/o) {
2103 print "CASE($1)\n" if ($dbg_values > 1);
2104 $av_pend_colon = 'C';
2105 $type = 'N';
2106
Andy Whitcroft14b111c2008-10-15 22:02:16 -07002107 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002108 print "KEYWORD($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002109 $type = 'N';
2110
2111 } elsif ($cur =~ /^(\()/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002112 print "PAREN('$1')\n" if ($dbg_values > 1);
Andy Whitcroftcf655042008-03-04 14:28:20 -08002113 push(@av_paren_type, $av_pending);
2114 $av_pending = '_';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002115 $type = 'N';
2116
2117 } elsif ($cur =~ /^(\))/o) {
Andy Whitcroftcf655042008-03-04 14:28:20 -08002118 my $new_type = pop(@av_paren_type);
2119 if ($new_type ne '_') {
2120 $type = $new_type;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002121 print "PAREN('$1') -> $type\n"
2122 if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002123 } else {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002124 print "PAREN('$1')\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002125 }
2126
Andy Whitcroftc8cb2ca2008-07-23 21:28:57 -07002127 } elsif ($cur =~ /^($Ident)\s*\(/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002128 print "FUNC($1)\n" if ($dbg_values > 1);
Andy Whitcroftc8cb2ca2008-07-23 21:28:57 -07002129 $type = 'V';
Andy Whitcroftcf655042008-03-04 14:28:20 -08002130 $av_pending = 'V';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002131
Andy Whitcroft8e761b02009-01-06 14:41:19 -08002132 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
2133 if (defined $2 && $type eq 'C' || $type eq 'T') {
Andy Whitcroft1f65f942008-07-23 21:29:10 -07002134 $av_pend_colon = 'B';
Andy Whitcroft8e761b02009-01-06 14:41:19 -08002135 } elsif ($type eq 'E') {
2136 $av_pend_colon = 'L';
Andy Whitcroft1f65f942008-07-23 21:29:10 -07002137 }
2138 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
2139 $type = 'V';
2140
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002141 } elsif ($cur =~ /^($Ident|$Constant)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002142 print "IDENT($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002143 $type = 'V';
2144
2145 } elsif ($cur =~ /^($Assignment)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002146 print "ASSIGN($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002147 $type = 'N';
2148
Andy Whitcroftcf655042008-03-04 14:28:20 -08002149 } elsif ($cur =~/^(;|{|})/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002150 print "END($1)\n" if ($dbg_values > 1);
Andy Whitcroft13214ad2008-02-08 04:22:03 -08002151 $type = 'E';
Andy Whitcroft1f65f942008-07-23 21:29:10 -07002152 $av_pend_colon = 'O';
Andy Whitcroft13214ad2008-02-08 04:22:03 -08002153
Andy Whitcroft8e761b02009-01-06 14:41:19 -08002154 } elsif ($cur =~/^(,)/) {
2155 print "COMMA($1)\n" if ($dbg_values > 1);
2156 $type = 'C';
2157
Andy Whitcroft1f65f942008-07-23 21:29:10 -07002158 } elsif ($cur =~ /^(\?)/o) {
2159 print "QUESTION($1)\n" if ($dbg_values > 1);
2160 $type = 'N';
2161
2162 } elsif ($cur =~ /^(:)/o) {
2163 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
2164
2165 substr($var, length($res), 1, $av_pend_colon);
2166 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
2167 $type = 'E';
2168 } else {
2169 $type = 'N';
2170 }
2171 $av_pend_colon = 'O';
2172
Andy Whitcroft8e761b02009-01-06 14:41:19 -08002173 } elsif ($cur =~ /^(\[)/o) {
Andy Whitcroft13214ad2008-02-08 04:22:03 -08002174 print "CLOSE($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002175 $type = 'N';
2176
Andy Whitcroft0d413862008-10-15 22:02:16 -07002177 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
Andy Whitcroft74048ed2008-07-23 21:29:10 -07002178 my $variant;
2179
2180 print "OPV($1)\n" if ($dbg_values > 1);
2181 if ($type eq 'V') {
2182 $variant = 'B';
2183 } else {
2184 $variant = 'U';
2185 }
2186
2187 substr($var, length($res), 1, $variant);
2188 $type = 'N';
2189
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002190 } elsif ($cur =~ /^($Operators)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002191 print "OP($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002192 if ($1 ne '++' && $1 ne '--') {
2193 $type = 'N';
2194 }
2195
2196 } elsif ($cur =~ /(^.)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002197 print "C($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002198 }
2199 if (defined $1) {
2200 $cur = substr($cur, length($1));
2201 $res .= $type x length($1);
2202 }
2203 }
2204
Andy Whitcroft1f65f942008-07-23 21:29:10 -07002205 return ($res, $var);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002206}
2207
Andy Whitcroft8905a672007-11-28 16:21:06 -08002208sub possible {
Andy Whitcroft13214ad2008-02-08 04:22:03 -08002209 my ($possible, $line) = @_;
Andy Whitcroft9a974fd2009-10-26 16:50:12 -07002210 my $notPermitted = qr{(?:
Andy Whitcroft0776e592008-10-15 22:02:29 -07002211 ^(?:
2212 $Modifier|
2213 $Storage|
2214 $Type|
Andy Whitcroft9a974fd2009-10-26 16:50:12 -07002215 DEFINE_\S+
2216 )$|
2217 ^(?:
Andy Whitcroft0776e592008-10-15 22:02:29 -07002218 goto|
2219 return|
2220 case|
2221 else|
2222 asm|__asm__|
Andy Whitcroft89a88352012-01-10 15:10:00 -08002223 do|
2224 \#|
2225 \#\#|
Andy Whitcroft9a974fd2009-10-26 16:50:12 -07002226 )(?:\s|$)|
Andy Whitcroft0776e592008-10-15 22:02:29 -07002227 ^(?:typedef|struct|enum)\b
Andy Whitcroft9a974fd2009-10-26 16:50:12 -07002228 )}x;
2229 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
2230 if ($possible !~ $notPermitted) {
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002231 # Check for modifiers.
2232 $possible =~ s/\s*$Storage\s*//g;
2233 $possible =~ s/\s*$Sparse\s*//g;
2234 if ($possible =~ /^\s*$/) {
2235
2236 } elsif ($possible =~ /\s/) {
2237 $possible =~ s/\s*$Type\s*//g;
Andy Whitcroftd2506582008-07-23 21:29:09 -07002238 for my $modifier (split(' ', $possible)) {
Andy Whitcroft9a974fd2009-10-26 16:50:12 -07002239 if ($modifier !~ $notPermitted) {
2240 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
Alex Dowad485ff232015-06-25 15:02:52 -07002241 push(@modifierListFile, $modifier);
Andy Whitcroft9a974fd2009-10-26 16:50:12 -07002242 }
Andy Whitcroftd2506582008-07-23 21:29:09 -07002243 }
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002244
2245 } else {
2246 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
Alex Dowad485ff232015-06-25 15:02:52 -07002247 push(@typeListFile, $possible);
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002248 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08002249 build_types();
Andy Whitcroft0776e592008-10-15 22:02:29 -07002250 } else {
2251 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
Andy Whitcroft8905a672007-11-28 16:21:06 -08002252 }
2253}
2254
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002255my $prefix = '';
2256
Joe Perches000d1cc12011-07-25 17:13:25 -07002257sub show_type {
Joe Perchescbec18a2014-04-03 14:49:19 -07002258 my ($type) = @_;
Joe Perches91bfe482013-09-11 14:23:59 -07002259
Alexey Dobriyan522b8372017-02-27 14:30:05 -08002260 $type =~ tr/[a-z]/[A-Z]/;
2261
Joe Perchescbec18a2014-04-03 14:49:19 -07002262 return defined $use_type{$type} if (scalar keys %use_type > 0);
2263
2264 return !defined $ignore_type{$type};
Joe Perches000d1cc12011-07-25 17:13:25 -07002265}
2266
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07002267sub report {
Joe Perchescbec18a2014-04-03 14:49:19 -07002268 my ($level, $type, $msg) = @_;
2269
2270 if (!show_type($type) ||
2271 (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07002272 return 0;
2273 }
Joe Perches57230292015-06-25 15:03:03 -07002274 my $output = '';
John Brooks737c0762017-07-10 15:52:24 -07002275 if ($color) {
Joe Perches57230292015-06-25 15:03:03 -07002276 if ($level eq 'ERROR') {
2277 $output .= RED;
2278 } elsif ($level eq 'WARNING') {
2279 $output .= YELLOW;
2280 } else {
2281 $output .= GREEN;
2282 }
Joe Perches000d1cc12011-07-25 17:13:25 -07002283 }
Joe Perches57230292015-06-25 15:03:03 -07002284 $output .= $prefix . $level . ':';
2285 if ($show_types) {
John Brooks737c0762017-07-10 15:52:24 -07002286 $output .= BLUE if ($color);
Joe Perches57230292015-06-25 15:03:03 -07002287 $output .= "$type:";
2288 }
John Brooks737c0762017-07-10 15:52:24 -07002289 $output .= RESET if ($color);
Joe Perches57230292015-06-25 15:03:03 -07002290 $output .= ' ' . $msg . "\n";
Joe Perches34d88152015-06-25 15:03:05 -07002291
2292 if ($showfile) {
2293 my @lines = split("\n", $output, -1);
2294 splice(@lines, 1, 1);
2295 $output = join("\n", @lines);
2296 }
Dwaipayan Ray52178ce2021-02-26 15:08:26 +05302297
2298 if ($terse) {
2299 $output = (split('\n', $output))[0] . "\n";
2300 }
2301
2302 if ($verbose && exists($verbose_messages{$type}) &&
2303 !exists($verbose_emitted{$type})) {
2304 $output .= $verbose_messages{$type} . "\n\n";
2305 $verbose_emitted{$type} = 1;
2306 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08002307
Joe Perches57230292015-06-25 15:03:03 -07002308 push(our @report, $output);
Andy Whitcroft773647a2008-03-28 14:15:58 -07002309
2310 return 1;
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07002311}
Joe Perchescbec18a2014-04-03 14:49:19 -07002312
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07002313sub report_dump {
Andy Whitcroft13214ad2008-02-08 04:22:03 -08002314 our @report;
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07002315}
Joe Perches000d1cc12011-07-25 17:13:25 -07002316
Joe Perchesd752fcc2014-08-06 16:11:05 -07002317sub fixup_current_range {
2318 my ($lineRef, $offset, $length) = @_;
2319
2320 if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2321 my $o = $1;
2322 my $l = $2;
2323 my $no = $o + $offset;
2324 my $nl = $l + $length;
2325 $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2326 }
2327}
2328
2329sub fix_inserted_deleted_lines {
2330 my ($linesRef, $insertedRef, $deletedRef) = @_;
2331
2332 my $range_last_linenr = 0;
2333 my $delta_offset = 0;
2334
2335 my $old_linenr = 0;
2336 my $new_linenr = 0;
2337
2338 my $next_insert = 0;
2339 my $next_delete = 0;
2340
2341 my @lines = ();
2342
2343 my $inserted = @{$insertedRef}[$next_insert++];
2344 my $deleted = @{$deletedRef}[$next_delete++];
2345
2346 foreach my $old_line (@{$linesRef}) {
2347 my $save_line = 1;
2348 my $line = $old_line; #don't modify the array
Joe Perches323b2672015-04-16 12:44:50 -07002349 if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename
Joe Perchesd752fcc2014-08-06 16:11:05 -07002350 $delta_offset = 0;
2351 } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
2352 $range_last_linenr = $new_linenr;
2353 fixup_current_range(\$line, $delta_offset, 0);
2354 }
2355
2356 while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2357 $deleted = @{$deletedRef}[$next_delete++];
2358 $save_line = 0;
2359 fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2360 }
2361
2362 while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2363 push(@lines, ${$inserted}{'LINE'});
2364 $inserted = @{$insertedRef}[$next_insert++];
2365 $new_linenr++;
2366 fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2367 }
2368
2369 if ($save_line) {
2370 push(@lines, $line);
2371 $new_linenr++;
2372 }
2373
2374 $old_linenr++;
2375 }
2376
2377 return @lines;
2378}
2379
Joe Perchesf2d7e4d2014-08-06 16:11:07 -07002380sub fix_insert_line {
2381 my ($linenr, $line) = @_;
2382
2383 my $inserted = {
2384 LINENR => $linenr,
2385 LINE => $line,
2386 };
2387 push(@fixed_inserted, $inserted);
2388}
2389
2390sub fix_delete_line {
2391 my ($linenr, $line) = @_;
2392
2393 my $deleted = {
2394 LINENR => $linenr,
2395 LINE => $line,
2396 };
2397
2398 push(@fixed_deleted, $deleted);
2399}
2400
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002401sub ERROR {
Joe Perchescbec18a2014-04-03 14:49:19 -07002402 my ($type, $msg) = @_;
2403
2404 if (report("ERROR", $type, $msg)) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07002405 our $clean = 0;
2406 our $cnt_error++;
Joe Perches3705ce52013-07-03 15:05:31 -07002407 return 1;
Andy Whitcroft773647a2008-03-28 14:15:58 -07002408 }
Joe Perches3705ce52013-07-03 15:05:31 -07002409 return 0;
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002410}
2411sub WARN {
Joe Perchescbec18a2014-04-03 14:49:19 -07002412 my ($type, $msg) = @_;
2413
2414 if (report("WARNING", $type, $msg)) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07002415 our $clean = 0;
2416 our $cnt_warn++;
Joe Perches3705ce52013-07-03 15:05:31 -07002417 return 1;
Andy Whitcroft773647a2008-03-28 14:15:58 -07002418 }
Joe Perches3705ce52013-07-03 15:05:31 -07002419 return 0;
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002420}
2421sub CHK {
Joe Perchescbec18a2014-04-03 14:49:19 -07002422 my ($type, $msg) = @_;
2423
2424 if ($check && report("CHECK", $type, $msg)) {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002425 our $clean = 0;
2426 our $cnt_chk++;
Joe Perches3705ce52013-07-03 15:05:31 -07002427 return 1;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002428 }
Joe Perches3705ce52013-07-03 15:05:31 -07002429 return 0;
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002430}
2431
Andy Whitcroft6ecd9672008-10-15 22:02:21 -07002432sub check_absolute_file {
2433 my ($absolute, $herecurr) = @_;
2434 my $file = $absolute;
2435
2436 ##print "absolute<$absolute>\n";
2437
2438 # See if any suffix of this path is a path within the tree.
2439 while ($file =~ s@^[^/]*/@@) {
2440 if (-f "$root/$file") {
2441 ##print "file<$file>\n";
2442 last;
2443 }
2444 }
2445 if (! -f _) {
2446 return 0;
2447 }
2448
2449 # It is, so see if the prefix is acceptable.
2450 my $prefix = $absolute;
2451 substr($prefix, -length($file)) = '';
2452
2453 ##print "prefix<$prefix>\n";
2454 if ($prefix ne ".../") {
Joe Perches000d1cc12011-07-25 17:13:25 -07002455 WARN("USE_RELATIVE_PATH",
2456 "use relative pathname instead of absolute in changelog text\n" . $herecurr);
Andy Whitcroft6ecd9672008-10-15 22:02:21 -07002457 }
2458}
2459
Joe Perches3705ce52013-07-03 15:05:31 -07002460sub trim {
2461 my ($string) = @_;
2462
Joe Perchesb34c6482013-09-11 14:24:01 -07002463 $string =~ s/^\s+|\s+$//g;
2464
2465 return $string;
2466}
2467
2468sub ltrim {
2469 my ($string) = @_;
2470
2471 $string =~ s/^\s+//;
2472
2473 return $string;
2474}
2475
2476sub rtrim {
2477 my ($string) = @_;
2478
2479 $string =~ s/\s+$//;
Joe Perches3705ce52013-07-03 15:05:31 -07002480
2481 return $string;
2482}
2483
Joe Perches52ea8502013-11-12 15:10:09 -08002484sub string_find_replace {
2485 my ($string, $find, $replace) = @_;
2486
2487 $string =~ s/$find/$replace/g;
2488
2489 return $string;
2490}
2491
Joe Perches3705ce52013-07-03 15:05:31 -07002492sub tabify {
2493 my ($leading) = @_;
2494
Antonio Borneo713a09d2020-04-06 20:11:07 -07002495 my $source_indent = $tabsize;
Joe Perches3705ce52013-07-03 15:05:31 -07002496 my $max_spaces_before_tab = $source_indent - 1;
2497 my $spaces_to_tab = " " x $source_indent;
2498
2499 #convert leading spaces to tabs
2500 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
2501 #Remove spaces before a tab
2502 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
2503
2504 return "$leading";
2505}
2506
Joe Perchesd1fe9c02012-03-23 15:02:16 -07002507sub pos_last_openparen {
2508 my ($line) = @_;
2509
2510 my $pos = 0;
2511
2512 my $opens = $line =~ tr/\(/\(/;
2513 my $closes = $line =~ tr/\)/\)/;
2514
2515 my $last_openparen = 0;
2516
2517 if (($opens == 0) || ($closes >= $opens)) {
2518 return -1;
2519 }
2520
2521 my $len = length($line);
2522
2523 for ($pos = 0; $pos < $len; $pos++) {
2524 my $string = substr($line, $pos);
2525 if ($string =~ /^($FuncArg|$balanced_parens)/) {
2526 $pos += length($1) - 1;
2527 } elsif (substr($line, $pos, 1) eq '(') {
2528 $last_openparen = $pos;
2529 } elsif (index($string, '(') == -1) {
2530 last;
2531 }
2532 }
2533
Joe Perches91cb5192014-04-03 14:49:32 -07002534 return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
Joe Perchesd1fe9c02012-03-23 15:02:16 -07002535}
2536
Joe Perchesf36d3eb2020-04-06 20:10:58 -07002537sub get_raw_comment {
2538 my ($line, $rawline) = @_;
2539 my $comment = '';
2540
2541 for my $i (0 .. (length($line) - 1)) {
2542 if (substr($line, $i, 1) eq "$;") {
2543 $comment .= substr($rawline, $i, 1);
2544 }
2545 }
2546
2547 return $comment;
2548}
2549
Song Liu5b8f82e2021-02-25 17:22:08 -08002550sub exclude_global_initialisers {
2551 my ($realfile) = @_;
2552
2553 # Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
2554 return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
2555 $realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
2556 $realfile =~ m@/bpf/.*\.bpf\.c$@;
2557}
2558
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002559sub process {
2560 my $filename = shift;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002561
2562 my $linenr=0;
2563 my $prevline="";
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002564 my $prevrawline="";
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002565 my $stashline="";
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002566 my $stashrawline="";
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002567
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07002568 my $length;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002569 my $indent;
2570 my $previndent=0;
2571 my $stashindent=0;
2572
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002573 our $clean = 1;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002574 my $signoff = 0;
Geert Uytterhoevencd261492018-08-21 21:57:40 -07002575 my $author = '';
2576 my $authorsignoff = 0;
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07002577 my $author_sob = '';
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002578 my $is_patch = 0;
Rob Herring133712a2018-08-21 21:58:16 -07002579 my $is_binding_patch = -1;
Joe Perches29ee1b02014-08-06 16:10:35 -07002580 my $in_header_lines = $file ? 0 : 1;
Joe Perches15662b32011-10-31 17:13:12 -07002581 my $in_commit_log = 0; #Scanning lines before patch
Joe Perches44d303e2020-04-06 20:11:10 -07002582 my $has_patch_separator = 0; #Found a --- line
Allen Hubbeed43c4e2016-08-02 14:04:45 -07002583 my $has_commit_log = 0; #Encountered lines before patch
Joe Perches490b2922018-08-21 21:58:01 -07002584 my $commit_log_lines = 0; #Number of commit log lines
Joe Perches77cb8542017-02-24 15:01:28 -08002585 my $commit_log_possible_stack_dump = 0;
Joe Perches2a076f42015-04-16 12:44:28 -07002586 my $commit_log_long_line = 0;
Joe Perchese518e9a2015-06-25 15:03:27 -07002587 my $commit_log_has_diff = 0;
Joe Perches13f19372014-08-06 16:10:59 -07002588 my $reported_maintainer_file = 0;
Pasi Savanainenfa64205d2012-10-04 17:13:29 -07002589 my $non_utf8_charset = 0;
2590
Joe Perches4ce9f972021-09-07 19:59:57 -07002591 my $last_git_commit_id_linenr = -1;
2592
Joe Perches365dd4e2014-08-06 16:10:42 -07002593 my $last_blank_line = 0;
Joe Perches5e4f6ba2014-12-10 15:52:05 -08002594 my $last_coalesced_string_linenr = -1;
Joe Perches365dd4e2014-08-06 16:10:42 -07002595
Andy Whitcroft13214ad2008-02-08 04:22:03 -08002596 our @report = ();
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002597 our $cnt_lines = 0;
2598 our $cnt_error = 0;
2599 our $cnt_warn = 0;
2600 our $cnt_chk = 0;
2601
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002602 # Trace the real file/line as we go.
2603 my $realfile = '';
2604 my $realline = 0;
2605 my $realcnt = 0;
2606 my $here = '';
Joe Perches77cb8542017-02-24 15:01:28 -08002607 my $context_function; #undef'd unless there's a known function
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002608 my $in_comment = 0;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002609 my $comment_edge = 0;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002610 my $first_line = 0;
Wolfram Sang1e855722009-01-06 14:41:24 -08002611 my $p1_prefix = '';
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002612
Andy Whitcroft13214ad2008-02-08 04:22:03 -08002613 my $prev_values = 'E';
2614
2615 # suppression flags
Andy Whitcroft773647a2008-03-28 14:15:58 -07002616 my %suppress_ifbraces;
Andy Whitcroft170d3a22008-10-15 22:02:30 -07002617 my %suppress_whiletrailers;
Andy Whitcroft2b474a12009-10-26 16:50:16 -07002618 my %suppress_export;
Andy Whitcroft3e469cd2012-01-10 15:10:01 -08002619 my $suppress_statement = 0;
Andy Whitcroft653d4872007-06-23 17:16:34 -07002620
Joe Perches7e51f192013-09-11 14:23:57 -07002621 my %signatures = ();
Joe Perches323c1262012-12-17 16:02:07 -08002622
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002623 # Pre-scan the patch sanitizing the lines.
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002624 # Pre-scan the patch looking for any __setup documentation.
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002625 #
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002626 my @setup_docs = ();
2627 my $setup_docs = 0;
Andy Whitcroft773647a2008-03-28 14:15:58 -07002628
Joe Perchesd8b07712013-11-12 15:10:06 -08002629 my $camelcase_file_seeded = 0;
2630
Rob Herring9f3a8992018-04-10 16:33:13 -07002631 my $checklicenseline = 1;
2632
Andy Whitcroft773647a2008-03-28 14:15:58 -07002633 sanitise_line_reset();
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002634 my $line;
2635 foreach my $rawline (@rawlines) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07002636 $linenr++;
2637 $line = $rawline;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002638
Joe Perches3705ce52013-07-03 15:05:31 -07002639 push(@fixed, $rawline) if ($fix);
2640
Andy Whitcroft773647a2008-03-28 14:15:58 -07002641 if ($rawline=~/^\+\+\+\s+(\S+)/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002642 $setup_docs = 0;
Tim Froidcoeur2581ac72020-06-10 18:41:38 -07002643 if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002644 $setup_docs = 1;
2645 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07002646 #next;
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002647 }
Joe Perches74fd4f32017-05-08 15:56:02 -07002648 if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07002649 $realline=$1-1;
2650 if (defined $2) {
2651 $realcnt=$3+1;
2652 } else {
2653 $realcnt=1+1;
2654 }
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07002655 $in_comment = 0;
Andy Whitcroft773647a2008-03-28 14:15:58 -07002656
2657 # Guestimate if this is a continuing comment. Run
2658 # the context looking for a comment "edge". If this
2659 # edge is a close comment then we must be in a comment
2660 # at context start.
2661 my $edge;
Andy Whitcroft01fa9142008-10-15 22:02:19 -07002662 my $cnt = $realcnt;
2663 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
2664 next if (defined $rawlines[$ln - 1] &&
2665 $rawlines[$ln - 1] =~ /^-/);
2666 $cnt--;
2667 #print "RAW<$rawlines[$ln - 1]>\n";
Andy Whitcroft721c1cb2009-01-06 14:41:16 -08002668 last if (!defined $rawlines[$ln - 1]);
Andy Whitcroftfae17da2009-01-06 14:41:20 -08002669 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2670 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2671 ($edge) = $1;
2672 last;
2673 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07002674 }
2675 if (defined $edge && $edge eq '*/') {
2676 $in_comment = 1;
2677 }
2678
2679 # Guestimate if this is a continuing comment. If this
2680 # is the start of a diff block and this line starts
2681 # ' *' then it is very likely a comment.
2682 if (!defined $edge &&
Andy Whitcroft83242e02009-01-06 14:41:17 -08002683 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
Andy Whitcroft773647a2008-03-28 14:15:58 -07002684 {
2685 $in_comment = 1;
2686 }
2687
2688 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2689 sanitise_line_reset($in_comment);
2690
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002691 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07002692 # Standardise the strings and chars within the input to
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07002693 # simplify matching -- only bother with positive lines.
Andy Whitcroft773647a2008-03-28 14:15:58 -07002694 $line = sanitise_line($rawline);
2695 }
2696 push(@lines, $line);
2697
2698 if ($realcnt > 1) {
2699 $realcnt-- if ($line =~ /^(?:\+| |$)/);
2700 } else {
2701 $realcnt = 0;
2702 }
2703
2704 #print "==>$rawline\n";
2705 #print "-->$line\n";
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07002706
2707 if ($setup_docs && $line =~ /^\+/) {
2708 push(@setup_docs, $line);
2709 }
2710 }
2711
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002712 $prefix = '';
2713
Andy Whitcroft773647a2008-03-28 14:15:58 -07002714 $realcnt = 0;
2715 $linenr = 0;
Joe Perches194f66f2014-08-06 16:11:03 -07002716 $fixlinenr = -1;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002717 foreach my $line (@lines) {
2718 $linenr++;
Joe Perches194f66f2014-08-06 16:11:03 -07002719 $fixlinenr++;
Joe Perches1b5539b2013-09-11 14:24:03 -07002720 my $sline = $line; #copy of $line
2721 $sline =~ s/$;/ /g; #with comments as spaces
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002722
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002723 my $rawline = $rawlines[$linenr - 1];
Joe Perchesf36d3eb2020-04-06 20:10:58 -07002724 my $raw_comment = get_raw_comment($line, $rawline);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002725
Joe Perches12c253a2018-06-07 17:10:58 -07002726# check if it's a mode change, rename or start of a patch
2727 if (!$in_commit_log &&
2728 ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
2729 ($line =~ /^rename (?:from|to) \S+\s*$/ ||
2730 $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
2731 $is_patch = 1;
2732 }
2733
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002734#extract the line range in the file after the patch is applied
Joe Perchese518e9a2015-06-25 15:03:27 -07002735 if (!$in_commit_log &&
Joe Perches74fd4f32017-05-08 15:56:02 -07002736 $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2737 my $context = $4;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002738 $is_patch = 1;
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07002739 $first_line = $linenr + 1;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002740 $realline=$1-1;
2741 if (defined $2) {
2742 $realcnt=$3+1;
2743 } else {
2744 $realcnt=1+1;
2745 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002746 annotate_reset();
Andy Whitcroft13214ad2008-02-08 04:22:03 -08002747 $prev_values = 'E';
2748
Andy Whitcroft773647a2008-03-28 14:15:58 -07002749 %suppress_ifbraces = ();
Andy Whitcroft170d3a22008-10-15 22:02:30 -07002750 %suppress_whiletrailers = ();
Andy Whitcroft2b474a12009-10-26 16:50:16 -07002751 %suppress_export = ();
Andy Whitcroft3e469cd2012-01-10 15:10:01 -08002752 $suppress_statement = 0;
Joe Perches74fd4f32017-05-08 15:56:02 -07002753 if ($context =~ /\b(\w+)\s*\(/) {
2754 $context_function = $1;
2755 } else {
2756 undef $context_function;
2757 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002758 next;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002759
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07002760# track the line number as we move through the hunk, note that
2761# new versions of GNU diff omit the leading space on completely
2762# blank context lines so we need to count that too.
Andy Whitcroft773647a2008-03-28 14:15:58 -07002763 } elsif ($line =~ /^( |\+|$)/) {
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002764 $realline++;
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07002765 $realcnt-- if ($realcnt != 0);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002766
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07002767 # Measure the line length and indent.
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002768 ($length, $indent) = line_stats($rawline);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002769
2770 # Track the previous line.
2771 ($prevline, $stashline) = ($stashline, $line);
2772 ($previndent, $stashindent) = ($stashindent, $indent);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002773 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2774
Andy Whitcroft773647a2008-03-28 14:15:58 -07002775 #warn "line<$line>\n";
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002776
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07002777 } elsif ($realcnt == 1) {
2778 $realcnt--;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002779 }
2780
Andy Whitcroftcc77cdc2009-10-26 16:50:13 -07002781 my $hunk_line = ($realcnt != 0);
2782
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002783 $here = "#$linenr: " if (!$file);
2784 $here = "#$realline: " if ($file);
Andy Whitcroft773647a2008-03-28 14:15:58 -07002785
Joe Perches2ac73b42014-06-04 16:12:05 -07002786 my $found_file = 0;
Andy Whitcroft773647a2008-03-28 14:15:58 -07002787 # extract the filename as it passes
Rabin Vincent3bf9a002010-10-26 14:23:16 -07002788 if ($line =~ /^diff --git.*?(\S+)$/) {
2789 $realfile = $1;
Joe Perches2b7ab452013-11-12 15:10:14 -08002790 $realfile =~ s@^([^/]*)/@@ if (!$file);
Joe Perches270c49a2012-01-10 15:09:50 -08002791 $in_commit_log = 0;
Joe Perches2ac73b42014-06-04 16:12:05 -07002792 $found_file = 1;
Rabin Vincent3bf9a002010-10-26 14:23:16 -07002793 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07002794 $realfile = $1;
Joe Perches2b7ab452013-11-12 15:10:14 -08002795 $realfile =~ s@^([^/]*)/@@ if (!$file);
Joe Perches270c49a2012-01-10 15:09:50 -08002796 $in_commit_log = 0;
Wolfram Sang1e855722009-01-06 14:41:24 -08002797
2798 $p1_prefix = $1;
Andy Whitcrofte2f7aa42009-02-27 14:03:06 -08002799 if (!$file && $tree && $p1_prefix ne '' &&
2800 -e "$root/$p1_prefix") {
Joe Perches000d1cc12011-07-25 17:13:25 -07002801 WARN("PATCH_PREFIX",
2802 "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
Wolfram Sang1e855722009-01-06 14:41:24 -08002803 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07002804
Andy Whitcroftc1ab3322008-10-15 22:02:20 -07002805 if ($realfile =~ m@^include/asm/@) {
Joe Perches000d1cc12011-07-25 17:13:25 -07002806 ERROR("MODIFIED_INCLUDE_ASM",
2807 "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
Andy Whitcroft773647a2008-03-28 14:15:58 -07002808 }
Joe Perches2ac73b42014-06-04 16:12:05 -07002809 $found_file = 1;
2810 }
2811
Joe Perches34d88152015-06-25 15:03:05 -07002812#make up the handle for any error we report on this line
2813 if ($showfile) {
2814 $prefix = "$realfile:$realline: "
2815 } elsif ($emacs) {
Joe Perches7d3a9f62015-09-09 15:37:39 -07002816 if ($file) {
2817 $prefix = "$filename:$realline: ";
2818 } else {
2819 $prefix = "$filename:$linenr: ";
2820 }
Joe Perches34d88152015-06-25 15:03:05 -07002821 }
2822
Joe Perches2ac73b42014-06-04 16:12:05 -07002823 if ($found_file) {
Joe Perches85b0ee12016-10-11 13:51:44 -07002824 if (is_maintained_obsolete($realfile)) {
2825 WARN("OBSOLETE",
2826 "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
2827 }
Joe Perches7bd7e482015-09-09 15:37:44 -07002828 if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
Joe Perches2ac73b42014-06-04 16:12:05 -07002829 $check = 1;
2830 } else {
2831 $check = $check_orig;
2832 }
Rob Herring9f3a8992018-04-10 16:33:13 -07002833 $checklicenseline = 1;
Rob Herring133712a2018-08-21 21:58:16 -07002834
2835 if ($realfile !~ /^MAINTAINERS/) {
2836 my $last_binding_patch = $is_binding_patch;
2837
2838 $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2839
2840 if (($last_binding_patch != -1) &&
2841 ($last_binding_patch ^ $is_binding_patch)) {
2842 WARN("DT_SPLIT_BINDING_PATCH",
Mauro Carvalho Chehab858e6842020-04-15 16:45:25 +02002843 "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
Rob Herring133712a2018-08-21 21:58:16 -07002844 }
2845 }
2846
Andy Whitcroft773647a2008-03-28 14:15:58 -07002847 next;
2848 }
2849
Randy Dunlap389834b2007-06-08 13:47:03 -07002850 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002851
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08002852 my $hereline = "$here\n$rawline\n";
2853 my $herecurr = "$here\n$rawline\n";
2854 my $hereprev = "$here\n$prevrawline\n$rawline\n";
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002855
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07002856 $cnt_lines++ if ($realcnt != 0);
2857
Joe Perches490b2922018-08-21 21:58:01 -07002858# Verify the existence of a commit log if appropriate
2859# 2 is used because a $signature is counted in $commit_log_lines
2860 if ($in_commit_log) {
2861 if ($line !~ /^\s*$/) {
2862 $commit_log_lines++; #could be a $signature
2863 }
2864 } elsif ($has_commit_log && $commit_log_lines < 2) {
2865 WARN("COMMIT_MESSAGE",
2866 "Missing commit description - Add an appropriate one\n");
2867 $commit_log_lines = 2; #warn only once
2868 }
2869
Joe Perchese518e9a2015-06-25 15:03:27 -07002870# Check if the commit log has what seems like a diff which can confuse patch
2871 if ($in_commit_log && !$commit_log_has_diff &&
Mrinal Pandey13e45412020-09-04 16:35:52 -07002872 (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
2873 $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
Joe Perchese518e9a2015-06-25 15:03:27 -07002874 $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2875 $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2876 ERROR("DIFF_IN_COMMIT_MSG",
2877 "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2878 $commit_log_has_diff = 1;
2879 }
2880
Rabin Vincent3bf9a002010-10-26 14:23:16 -07002881# Check for incorrect file permissions
2882 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
2883 my $permhere = $here . "FILE: $realfile\n";
Joe Perches04db4d22013-04-29 16:18:14 -07002884 if ($realfile !~ m@scripts/@ &&
2885 $realfile !~ /\.(py|pl|awk|sh)$/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07002886 ERROR("EXECUTE_PERMISSIONS",
2887 "do not set execute permissions for source files\n" . $permhere);
Rabin Vincent3bf9a002010-10-26 14:23:16 -07002888 }
2889 }
2890
Geert Uytterhoevencd261492018-08-21 21:57:40 -07002891# Check the patch for a From:
2892 if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2893 $author = $1;
Dwaipayan Raye7f929f2020-10-15 20:12:15 -07002894 my $curline = $linenr;
2895 while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2896 $author .= $1;
2897 }
Geert Uytterhoevencd261492018-08-21 21:57:40 -07002898 $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2899 $author =~ s/"//g;
Joe Perchesdfa05c22020-04-06 20:10:48 -07002900 $author = reformat_email($author);
Geert Uytterhoevencd261492018-08-21 21:57:40 -07002901 }
2902
Joe Perches20112472011-07-25 17:13:23 -07002903# Check the patch for a signoff:
Joe Perchesdfa05c22020-04-06 20:10:48 -07002904 if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07002905 $signoff++;
Joe Perches15662b32011-10-31 17:13:12 -07002906 $in_commit_log = 0;
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07002907 if ($author ne '' && $authorsignoff != 1) {
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08002908 if (same_email_addresses($1, $author)) {
Joe Perchesdfa05c22020-04-06 20:10:48 -07002909 $authorsignoff = 1;
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07002910 } else {
2911 my $ctx = $1;
2912 my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
2913 my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
2914
Mimi Zohar046fc742021-09-07 19:59:54 -07002915 if (lc $email_address eq lc $author_address && $email_name eq $author_name) {
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07002916 $author_sob = $ctx;
2917 $authorsignoff = 2;
Mimi Zohar046fc742021-09-07 19:59:54 -07002918 } elsif (lc $email_address eq lc $author_address) {
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07002919 $author_sob = $ctx;
2920 $authorsignoff = 3;
2921 } elsif ($email_name eq $author_name) {
2922 $author_sob = $ctx;
2923 $authorsignoff = 4;
2924
2925 my $address1 = $email_address;
2926 my $address2 = $author_address;
2927
2928 if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
2929 $address1 = "$1$2";
2930 }
2931 if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
2932 $address2 = "$1$2";
2933 }
2934 if ($address1 eq $address2) {
2935 $authorsignoff = 5;
2936 }
2937 }
Geert Uytterhoevencd261492018-08-21 21:57:40 -07002938 }
2939 }
Joe Perches20112472011-07-25 17:13:23 -07002940 }
2941
Joe Perches44d303e2020-04-06 20:11:10 -07002942# Check for patch separator
2943 if ($line =~ /^---$/) {
2944 $has_patch_separator = 1;
2945 $in_commit_log = 0;
2946 }
2947
Joe Perchese0d975b2014-12-10 15:51:49 -08002948# Check if MAINTAINERS is being updated. If so, there's probably no need to
2949# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2950 if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2951 $reported_maintainer_file = 1;
2952 }
2953
Joe Perches20112472011-07-25 17:13:23 -07002954# Check signature styles
Joe Perches270c49a2012-01-10 15:09:50 -08002955 if (!$in_header_lines &&
Joe Perchesce0338df3c2012-07-30 14:41:18 -07002956 $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
Joe Perches20112472011-07-25 17:13:23 -07002957 my $space_before = $1;
2958 my $sign_off = $2;
2959 my $space_after = $3;
2960 my $email = $4;
2961 my $ucfirst_sign_off = ucfirst(lc($sign_off));
2962
Joe Perchesce0338df3c2012-07-30 14:41:18 -07002963 if ($sign_off !~ /$signature_tags/) {
Aditya Srivastava831242a2020-12-15 20:45:12 -08002964 my $suggested_signature = find_standard_signature($sign_off);
2965 if ($suggested_signature eq "") {
2966 WARN("BAD_SIGN_OFF",
2967 "Non-standard signature: $sign_off\n" . $herecurr);
2968 } else {
2969 if (WARN("BAD_SIGN_OFF",
2970 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
2971 $fix) {
2972 $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
2973 }
2974 }
Joe Perchesce0338df3c2012-07-30 14:41:18 -07002975 }
Joe Perches20112472011-07-25 17:13:23 -07002976 if (defined $space_before && $space_before ne "") {
Joe Perches3705ce52013-07-03 15:05:31 -07002977 if (WARN("BAD_SIGN_OFF",
2978 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
2979 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07002980 $fixed[$fixlinenr] =
Joe Perches3705ce52013-07-03 15:05:31 -07002981 "$ucfirst_sign_off $email";
2982 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07002983 }
Joe Perches20112472011-07-25 17:13:23 -07002984 if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
Joe Perches3705ce52013-07-03 15:05:31 -07002985 if (WARN("BAD_SIGN_OFF",
2986 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
2987 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07002988 $fixed[$fixlinenr] =
Joe Perches3705ce52013-07-03 15:05:31 -07002989 "$ucfirst_sign_off $email";
2990 }
2991
Joe Perches20112472011-07-25 17:13:23 -07002992 }
2993 if (!defined $space_after || $space_after ne " ") {
Joe Perches3705ce52013-07-03 15:05:31 -07002994 if (WARN("BAD_SIGN_OFF",
2995 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
2996 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07002997 $fixed[$fixlinenr] =
Joe Perches3705ce52013-07-03 15:05:31 -07002998 "$ucfirst_sign_off $email";
2999 }
Joe Perches20112472011-07-25 17:13:23 -07003000 }
3001
Joe Perchesdfa05c22020-04-06 20:10:48 -07003002 my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07003003 my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
Joe Perches20112472011-07-25 17:13:23 -07003004 if ($suggested_email eq "") {
Joe Perches000d1cc12011-07-25 17:13:25 -07003005 ERROR("BAD_SIGN_OFF",
3006 "Unrecognized email address: '$email'\n" . $herecurr);
Joe Perches20112472011-07-25 17:13:23 -07003007 } else {
3008 my $dequoted = $suggested_email;
3009 $dequoted =~ s/^"//;
3010 $dequoted =~ s/" </ </;
3011 # Don't force email to have quotes
3012 # Allow just an angle bracketed address
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08003013 if (!same_email_addresses($email, $suggested_email)) {
3014 if (WARN("BAD_SIGN_OFF",
3015 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
3016 $fix) {
3017 $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
3018 }
3019 }
3020
3021 # Address part shouldn't have comments
3022 my $stripped_address = $email_address;
3023 $stripped_address =~ s/\([^\(\)]*\)//g;
3024 if ($email_address ne $stripped_address) {
3025 if (WARN("BAD_SIGN_OFF",
3026 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
3027 $fix) {
3028 $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
3029 }
3030 }
3031
3032 # Only one name comment should be allowed
3033 my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
3034 if ($comment_count > 1) {
Joe Perches000d1cc12011-07-25 17:13:25 -07003035 WARN("BAD_SIGN_OFF",
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08003036 "Use a single name comment in email: '$email'\n" . $herecurr);
3037 }
3038
3039
3040 # stable@vger.kernel.org or stable@kernel.org shouldn't
Dwaipayan Raye73d2712020-12-15 20:44:56 -08003041 # have an email name. In addition comments should strictly
Dwaipayan Rayfccaebf2020-12-15 20:44:53 -08003042 # begin with a #
3043 if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
3044 if (($comment ne "" && $comment !~ /^#.+/) ||
3045 ($email_name ne "")) {
3046 my $cur_name = $email_name;
3047 my $new_comment = $comment;
3048 $cur_name =~ s/[a-zA-Z\s\-\"]+//g;
3049
3050 # Remove brackets enclosing comment text
3051 # and # from start of comments to get comment text
3052 $new_comment =~ s/^\((.*)\)$/$1/;
3053 $new_comment =~ s/^\[(.*)\]$/$1/;
3054 $new_comment =~ s/^[\s\#]+|\s+$//g;
3055
3056 $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
3057 $new_comment = " # $new_comment" if ($new_comment ne "");
3058 my $new_email = "$email_address$new_comment";
3059
3060 if (WARN("BAD_STABLE_ADDRESS_STYLE",
3061 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
3062 $fix) {
3063 $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3064 }
3065 }
3066 } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
3067 my $new_comment = $comment;
3068
3069 # Extract comment text from within brackets or
3070 # c89 style /*...*/ comments
3071 $new_comment =~ s/^\[(.*)\]$/$1/;
3072 $new_comment =~ s/^\/\*(.*)\*\/$/$1/;
3073
3074 $new_comment = trim($new_comment);
3075 $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
3076 $new_comment = "($new_comment)" if ($new_comment ne "");
3077 my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
3078
3079 if (WARN("BAD_SIGN_OFF",
3080 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
3081 $fix) {
3082 $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3083 }
Joe Perches20112472011-07-25 17:13:23 -07003084 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07003085 }
Joe Perches7e51f192013-09-11 14:23:57 -07003086
3087# Check for duplicate signatures
3088 my $sig_nospace = $line;
3089 $sig_nospace =~ s/\s//g;
3090 $sig_nospace = lc($sig_nospace);
3091 if (defined $signatures{$sig_nospace}) {
3092 WARN("BAD_SIGN_OFF",
3093 "Duplicate signature\n" . $herecurr);
3094 } else {
3095 $signatures{$sig_nospace} = 1;
3096 }
Sean Christopherson6c5d24e2019-03-22 14:11:37 -07003097
3098# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
3099 if ($sign_off =~ /^co-developed-by:$/i) {
3100 if ($email eq $author) {
3101 WARN("BAD_SIGN_OFF",
3102 "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
3103 }
3104 if (!defined $lines[$linenr]) {
3105 WARN("BAD_SIGN_OFF",
Dwaipayan Rayea7dbab2021-02-25 17:21:47 -08003106 "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
Sean Christopherson6c5d24e2019-03-22 14:11:37 -07003107 } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
3108 WARN("BAD_SIGN_OFF",
3109 "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
3110 } elsif ($1 ne $email) {
3111 WARN("BAD_SIGN_OFF",
3112 "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
3113 }
3114 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07003115 }
3116
Joe Perchesa2fe16b2015-02-13 14:39:02 -08003117# Check email subject for common tools that don't need to be mentioned
3118 if ($in_header_lines &&
3119 $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3120 WARN("EMAIL_SUBJECT",
3121 "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3122 }
3123
Joe Perches44d303e2020-04-06 20:11:10 -07003124# Check for Gerrit Change-Ids not in any patch context
3125 if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
Aditya Srivastava7580c5b2020-12-15 20:44:47 -08003126 if (ERROR("GERRIT_CHANGE_ID",
3127 "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
3128 $fix) {
Dwaipayan Rayea7dbab2021-02-25 17:21:47 -08003129 fix_delete_line($fixlinenr, $rawline);
3130 }
Christopher Covington7ebd05e2014-04-03 14:49:31 -07003131 }
3132
Joe Perches369c8dd2015-11-06 16:31:34 -08003133# Check if the commit log is in a possible stack dump
3134 if ($in_commit_log && !$commit_log_possible_stack_dump &&
3135 ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3136 $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3137 # timestamp
Joe Perches634cffc2019-09-25 16:46:32 -07003138 $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3139 $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3140 $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3141 # stack dump address styles
Joe Perches369c8dd2015-11-06 16:31:34 -08003142 $commit_log_possible_stack_dump = 1;
3143 }
3144
Joe Perches2a076f42015-04-16 12:44:28 -07003145# Check for line lengths > 75 in commit log, warn once
3146 if ($in_commit_log && !$commit_log_long_line &&
Joe Perches369c8dd2015-11-06 16:31:34 -08003147 length($line) > 75 &&
3148 !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3149 # file delta changes
3150 $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
3151 # filename then :
Aditya Srivastava27b379a2020-12-15 20:44:59 -08003152 $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
3153 # A Fixes: or Link: line or signature tag line
Joe Perches369c8dd2015-11-06 16:31:34 -08003154 $commit_log_possible_stack_dump)) {
Joe Perches2a076f42015-04-16 12:44:28 -07003155 WARN("COMMIT_LOG_LONG_LINE",
3156 "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
3157 $commit_log_long_line = 1;
3158 }
3159
Joe Perchesbf4daf12015-09-09 15:37:50 -07003160# Reset possible stack dump if a blank line is found
Joe Perches369c8dd2015-11-06 16:31:34 -08003161 if ($in_commit_log && $commit_log_possible_stack_dump &&
3162 $line =~ /^\s*$/) {
3163 $commit_log_possible_stack_dump = 0;
3164 }
Joe Perchesbf4daf12015-09-09 15:37:50 -07003165
Dwaipayan Ray084a6172020-12-15 20:45:18 -08003166# Check for lines starting with a #
3167 if ($in_commit_log && $line =~ /^#/) {
3168 if (WARN("COMMIT_COMMENT_SYMBOL",
3169 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
3170 $fix) {
3171 $fixed[$fixlinenr] =~ s/^/ /;
3172 }
3173 }
3174
Joe Perches0d7835f2015-02-13 14:38:35 -08003175# Check for git id commit length and improperly formed commit descriptions
Joe Perches4ce9f972021-09-07 19:59:57 -07003176# A correctly formed commit description is:
3177# commit <SHA-1 hash length 12+ chars> ("Complete commit subject")
3178# with the commit subject '("' prefix and '")' suffix
3179# This is a fairly compilicated block as it tests for what appears to be
3180# bare SHA-1 hash with minimum length of 5. It also avoids several types of
3181# possible SHA-1 matches.
3182# A commit match can span multiple lines so this block attempts to find a
3183# complete typical commit on a maximum of 3 lines
3184 if ($perl_version_ok &&
3185 $in_commit_log && !$commit_log_possible_stack_dump &&
John Hubbarda8972572020-04-06 20:10:55 -07003186 $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
Wei Wange882dbf2017-05-08 15:55:54 -07003187 $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
Joe Perches4ce9f972021-09-07 19:59:57 -07003188 (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
3189 ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||
Joe Perchesaab38f52016-08-02 14:04:36 -07003190 ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
Joe Perches369c8dd2015-11-06 16:31:34 -08003191 $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
3192 $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
Joe Perchesfe043ea2015-09-09 15:37:25 -07003193 my $init_char = "c";
3194 my $orig_commit = "";
Joe Perches0d7835f2015-02-13 14:38:35 -08003195 my $short = 1;
3196 my $long = 0;
3197 my $case = 1;
3198 my $space = 1;
Joe Perches0d7835f2015-02-13 14:38:35 -08003199 my $id = '0123456789ab';
3200 my $orig_desc = "commit description";
3201 my $description = "";
Joe Perches4ce9f972021-09-07 19:59:57 -07003202 my $herectx = $herecurr;
3203 my $has_parens = 0;
3204 my $has_quotes = 0;
Joe Perches0d7835f2015-02-13 14:38:35 -08003205
Joe Perches4ce9f972021-09-07 19:59:57 -07003206 my $input = $line;
3207 if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {
3208 for (my $n = 0; $n < 2; $n++) {
3209 if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {
3210 $orig_desc = $1;
3211 $has_parens = 1;
3212 # Always strip leading/trailing parens then double quotes if existing
3213 $orig_desc = substr($orig_desc, 1, -1);
3214 if ($orig_desc =~ /^".*"$/) {
3215 $orig_desc = substr($orig_desc, 1, -1);
3216 $has_quotes = 1;
3217 }
3218 last;
3219 }
3220 last if ($#lines < $linenr + $n);
3221 $input .= " " . trim($rawlines[$linenr + $n]);
3222 $herectx .= "$rawlines[$linenr + $n]\n";
3223 }
3224 $herectx = $herecurr if (!$has_parens);
Joe Perchesfe043ea2015-09-09 15:37:25 -07003225 }
3226
Joe Perches4ce9f972021-09-07 19:59:57 -07003227 if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
3228 $init_char = $1;
3229 $orig_commit = lc($2);
3230 $short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);
3231 $long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);
3232 $space = 0 if ($input =~ /\bcommit [0-9a-f]/i);
3233 $case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
3234 } elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {
3235 $orig_commit = lc($1);
Joe Perches0d7835f2015-02-13 14:38:35 -08003236 }
3237
3238 ($id, $description) = git_commit_info($orig_commit,
3239 $id, $orig_desc);
3240
Heinrich Schuchardt948b1332017-07-10 15:52:16 -07003241 if (defined($id) &&
Joe Perches4ce9f972021-09-07 19:59:57 -07003242 ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&
3243 $last_git_commit_id_linenr != $linenr - 1) {
Joe Perches0d7835f2015-02-13 14:38:35 -08003244 ERROR("GIT_COMMIT_ID",
Joe Perches4ce9f972021-09-07 19:59:57 -07003245 "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);
Joe Perches0d7835f2015-02-13 14:38:35 -08003246 }
Joe Perches4ce9f972021-09-07 19:59:57 -07003247 #don't report the next line if this line ends in commit and the sha1 hash is the next line
3248 $last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);
Joe Perchesd311cd42014-08-06 16:10:57 -07003249 }
3250
Joe Perches13f19372014-08-06 16:10:59 -07003251# Check for added, moved or deleted files
3252 if (!$reported_maintainer_file && !$in_commit_log &&
3253 ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
3254 $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
3255 ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
3256 (defined($1) || defined($2))))) {
Andrew Jefferya82603a2016-12-12 16:46:37 -08003257 $is_patch = 1;
Joe Perches13f19372014-08-06 16:10:59 -07003258 $reported_maintainer_file = 1;
3259 WARN("FILE_PATH_CHANGES",
3260 "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
3261 }
3262
Rob Herringe400edb2019-09-12 15:18:20 +01003263# Check for adding new DT bindings not in schema format
3264 if (!$in_commit_log &&
3265 ($line =~ /^new file mode\s*\d+\s*$/) &&
3266 ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3267 WARN("DT_SCHEMA_BINDING_PATCH",
Mauro Carvalho Chehab56ddc4c2021-04-01 14:17:49 +02003268 "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
Rob Herringe400edb2019-09-12 15:18:20 +01003269 }
3270
Andy Whitcroft00df3442007-06-08 13:47:06 -07003271# Check for wrappage within a valid hunk of the file
Andy Whitcroft8905a672007-11-28 16:21:06 -08003272 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
Joe Perches000d1cc12011-07-25 17:13:25 -07003273 ERROR("CORRUPTED_PATCH",
3274 "patch seems to be corrupt (line wrapped?)\n" .
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07003275 $herecurr) if (!$emitted_corrupt++);
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07003276 }
3277
3278# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
3279 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07003280 $rawline !~ m/^$UTF8*$/) {
3281 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3282
3283 my $blank = copy_spacing($rawline);
3284 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
3285 my $hereptr = "$hereline$ptr\n";
3286
Joe Perches34d99212011-07-25 17:13:26 -07003287 CHK("INVALID_UTF8",
3288 "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
Andy Whitcroft00df3442007-06-08 13:47:06 -07003289 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07003290
Joe Perches15662b32011-10-31 17:13:12 -07003291# Check if it's the start of a commit log
3292# (not a header line and we haven't seen the patch filename)
3293 if ($in_header_lines && $realfile =~ /^$/ &&
Joe Percheseb3a58d2017-05-08 15:55:42 -07003294 !($rawline =~ /^\s+(?:\S|$)/ ||
3295 $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
Joe Perches15662b32011-10-31 17:13:12 -07003296 $in_header_lines = 0;
3297 $in_commit_log = 1;
Allen Hubbeed43c4e2016-08-02 14:04:45 -07003298 $has_commit_log = 1;
Joe Perches15662b32011-10-31 17:13:12 -07003299 }
3300
Pasi Savanainenfa64205d2012-10-04 17:13:29 -07003301# Check if there is UTF-8 in a commit log when a mail header has explicitly
3302# declined it, i.e defined some charset where it is missing.
3303 if ($in_header_lines &&
3304 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3305 $1 !~ /utf-8/i) {
3306 $non_utf8_charset = 1;
3307 }
3308
3309 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
Joe Perches15662b32011-10-31 17:13:12 -07003310 $rawline =~ /$NON_ASCII_UTF8/) {
Pasi Savanainenfa64205d2012-10-04 17:13:29 -07003311 WARN("UTF8_BEFORE_PATCH",
Joe Perches15662b32011-10-31 17:13:12 -07003312 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
3313 }
3314
Joe Perchesd6430f72016-12-12 16:46:28 -08003315# Check for absolute kernel paths in commit message
3316 if ($tree && $in_commit_log) {
3317 while ($line =~ m{(?:^|\s)(/\S*)}g) {
3318 my $file = $1;
3319
3320 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
3321 check_absolute_file($1, $herecurr)) {
3322 #
3323 } else {
3324 check_absolute_file($file, $herecurr);
3325 }
3326 }
3327 }
3328
Kees Cook66b47b42014-10-13 15:51:57 -07003329# Check for various typo / spelling mistakes
Joe Perches66d7a382015-04-16 12:44:08 -07003330 if (defined($misspellings) &&
3331 ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
Dwaipayan Ray7da07c32020-12-15 20:45:21 -08003332 while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
Kees Cook66b47b42014-10-13 15:51:57 -07003333 my $typo = $1;
Dwaipayan Ray7da07c32020-12-15 20:45:21 -08003334 my $blank = copy_spacing($rawline);
3335 my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
3336 my $hereptr = "$hereline$ptr\n";
Kees Cook66b47b42014-10-13 15:51:57 -07003337 my $typo_fix = $spelling_fix{lc($typo)};
3338 $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
3339 $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
Jean Delvare0675a8f2017-09-08 16:16:07 -07003340 my $msg_level = \&WARN;
3341 $msg_level = \&CHK if ($file);
3342 if (&{$msg_level}("TYPO_SPELLING",
Dwaipayan Ray7da07c32020-12-15 20:45:21 -08003343 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
Kees Cook66b47b42014-10-13 15:51:57 -07003344 $fix) {
3345 $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
3346 }
3347 }
3348 }
3349
Matteo Crocea8dd86b2019-09-25 16:46:38 -07003350# check for invalid commit id
3351 if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3352 my $id;
3353 my $description;
3354 ($id, $description) = git_commit_info($2, undef, undef);
3355 if (!defined($id)) {
3356 WARN("UNKNOWN_COMMIT_ID",
3357 "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3358 }
3359 }
3360
Joe Perches310cd062020-10-15 20:11:52 -07003361# check for repeated words separated by a single space
Aditya Srivastava8d0325c2020-12-15 20:44:24 -08003362# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
3363 if (($rawline =~ /^\+/ || $in_commit_log) &&
3364 $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
Dwaipayan Ray1db81a62020-12-15 20:44:20 -08003365 pos($rawline) = 1 if (!$in_commit_log);
Joe Perches310cd062020-10-15 20:11:52 -07003366 while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3367
3368 my $first = $1;
3369 my $second = $2;
Dwaipayan Ray1db81a62020-12-15 20:44:20 -08003370 my $start_pos = $-[1];
3371 my $end_pos = $+[2];
Joe Perches310cd062020-10-15 20:11:52 -07003372 if ($first =~ /(?:struct|union|enum)/) {
3373 pos($rawline) += length($first) + length($second) + 1;
3374 next;
3375 }
3376
Dwaipayan Ray1db81a62020-12-15 20:44:20 -08003377 next if (lc($first) ne lc($second));
Joe Perches310cd062020-10-15 20:11:52 -07003378 next if ($first eq 'long');
3379
Dwaipayan Ray1db81a62020-12-15 20:44:20 -08003380 # check for character before and after the word matches
3381 my $start_char = '';
3382 my $end_char = '';
3383 $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
3384 $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
3385
3386 next if ($start_char =~ /^\S$/);
3387 next if (index(" \t.,;?!", $end_char) == -1);
3388
Dwaipayan Rayea7dbab2021-02-25 17:21:47 -08003389 # avoid repeating hex occurrences like 'ff ff fe 09 ...'
3390 if ($first =~ /\b[0-9a-f]{2,}\b/i) {
3391 next if (!exists($allow_repeated_words{lc($first)}));
3392 }
Aditya Srivastava8d0325c2020-12-15 20:44:24 -08003393
Joe Perches310cd062020-10-15 20:11:52 -07003394 if (WARN("REPEATED_WORD",
3395 "Possible repeated word: '$first'\n" . $herecurr) &&
3396 $fix) {
3397 $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3398 }
3399 }
3400
3401 # if it's a repeated word on consecutive lines in a comment block
3402 if ($prevline =~ /$;+\s*$/ &&
3403 $prevrawline =~ /($word_pattern)\s*$/) {
3404 my $last_word = $1;
3405 if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3406 if (WARN("REPEATED_WORD",
3407 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3408 $fix) {
3409 $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3410 }
3411 }
3412 }
3413 }
3414
Andy Whitcroft306708542008-10-15 22:02:28 -07003415# ignore non-hunk lines and lines being removed
3416 next if (!$hunk_line || $line =~ /^-/);
Andy Whitcroft00df3442007-06-08 13:47:06 -07003417
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07003418#trailing whitespace
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07003419 if ($line =~ /^\+.*\015/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08003420 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Joe Perchesd5e616f2013-09-11 14:23:54 -07003421 if (ERROR("DOS_LINE_ENDINGS",
3422 "DOS line endings\n" . $herevet) &&
3423 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07003424 $fixed[$fixlinenr] =~ s/[\s\015]+$//;
Joe Perchesd5e616f2013-09-11 14:23:54 -07003425 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08003426 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
3427 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Joe Perches3705ce52013-07-03 15:05:31 -07003428 if (ERROR("TRAILING_WHITESPACE",
3429 "trailing whitespace\n" . $herevet) &&
3430 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07003431 $fixed[$fixlinenr] =~ s/\s+$//;
Joe Perches3705ce52013-07-03 15:05:31 -07003432 }
3433
Andy Whitcroftd2c0a232010-10-26 14:23:12 -07003434 $rpt_cleaners = 1;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07003435 }
Andy Whitcroft5368df202008-10-15 22:02:27 -07003436
Josh Triplett4783f892013-11-12 15:10:12 -08003437# Check for FSF mailing addresses.
Alexander Duyck109d8cb2014-01-23 15:54:50 -08003438 if ($rawline =~ /\bwrite to the Free/i ||
Matthew Wilcox1bde5612017-02-24 15:01:38 -08003439 $rawline =~ /\b675\s+Mass\s+Ave/i ||
Joe Perches3e2232f2014-01-23 15:54:48 -08003440 $rawline =~ /\b59\s+Temple\s+Pl/i ||
3441 $rawline =~ /\b51\s+Franklin\s+St/i) {
Josh Triplett4783f892013-11-12 15:10:12 -08003442 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Jean Delvare0675a8f2017-09-08 16:16:07 -07003443 my $msg_level = \&ERROR;
3444 $msg_level = \&CHK if ($file);
3445 &{$msg_level}("FSF_MAILING_ADDRESS",
3446 "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)
Josh Triplett4783f892013-11-12 15:10:12 -08003447 }
3448
Andi Kleen33549572010-05-24 14:33:29 -07003449# check for Kconfig help text having a real description
Andy Whitcroft9fe287d72010-10-26 14:23:15 -07003450# Only applies when adding the entry originally, after that we do not have
3451# sufficient context to determine whether it is indeed long enough.
Andi Kleen33549572010-05-24 14:33:29 -07003452 if ($realfile =~ /Kconfig/ &&
Ulf Magnusson678ae162018-02-16 21:22:54 +01003453 # 'choice' is usually the last thing on the line (though
3454 # Kconfig supports named choices), so use a word boundary
3455 # (\b) rather than a whitespace character (\s)
3456 $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
Andi Kleen33549572010-05-24 14:33:29 -07003457 my $length = 0;
Andy Whitcroft9fe287d72010-10-26 14:23:15 -07003458 my $cnt = $realcnt;
3459 my $ln = $linenr + 1;
3460 my $f;
Andy Whitcrofta1385802012-01-10 15:10:03 -08003461 my $is_start = 0;
Andy Whitcroft9fe287d72010-10-26 14:23:15 -07003462 my $is_end = 0;
Andy Whitcrofta1385802012-01-10 15:10:03 -08003463 for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
Andy Whitcroft9fe287d72010-10-26 14:23:15 -07003464 $f = $lines[$ln - 1];
3465 $cnt-- if ($lines[$ln - 1] !~ /^-/);
3466 $is_end = $lines[$ln - 1] =~ /^\+/;
Andy Whitcroft9fe287d72010-10-26 14:23:15 -07003467
3468 next if ($f =~ /^-/);
Joe Perches8d73e0e2014-08-06 16:10:46 -07003469 last if (!$file && $f =~ /^\@\@/);
Andy Whitcrofta1385802012-01-10 15:10:03 -08003470
Ulf Magnusson86adf1a2018-02-16 21:22:53 +01003471 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
Andy Whitcrofta1385802012-01-10 15:10:03 -08003472 $is_start = 1;
Masahiro Yamada22a4ac02020-06-17 12:02:20 +09003473 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
Andy Whitcrofta1385802012-01-10 15:10:03 -08003474 $length = -1;
3475 }
3476
Andy Whitcroft9fe287d72010-10-26 14:23:15 -07003477 $f =~ s/^.//;
Andi Kleen33549572010-05-24 14:33:29 -07003478 $f =~ s/#.*//;
3479 $f =~ s/^\s+//;
3480 next if ($f =~ /^$/);
Ulf Magnusson678ae162018-02-16 21:22:54 +01003481
3482 # This only checks context lines in the patch
3483 # and so hopefully shouldn't trigger false
3484 # positives, even though some of these are
3485 # common words in help texts
3486 if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3487 if|endif|menu|endmenu|source)\b/x) {
Andy Whitcroft9fe287d72010-10-26 14:23:15 -07003488 $is_end = 1;
3489 last;
3490 }
Andi Kleen33549572010-05-24 14:33:29 -07003491 $length++;
3492 }
Vadim Bendebury56193272014-10-13 15:51:48 -07003493 if ($is_start && $is_end && $length < $min_conf_desc_length) {
3494 WARN("CONFIG_DESCRIPTION",
3495 "please write a paragraph that describes the config symbol fully\n" . $herecurr);
3496 }
Andy Whitcrofta1385802012-01-10 15:10:03 -08003497 #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
Andi Kleen33549572010-05-24 14:33:29 -07003498 }
3499
Joe Perches7ccf41a2020-06-04 16:50:33 -07003500# check MAINTAINERS entries
3501 if ($realfile =~ /^MAINTAINERS$/) {
3502# check MAINTAINERS entries for the right form
3503 if ($rawline =~ /^\+[A-Z]:/ &&
3504 $rawline !~ /^\+[A-Z]:\t\S/) {
3505 if (WARN("MAINTAINERS_STYLE",
3506 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3507 $fix) {
3508 $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3509 }
3510 }
3511# check MAINTAINERS entries for the right ordering too
3512 my $preferred_order = 'MRLSWQBCPTFXNK';
3513 if ($rawline =~ /^\+[A-Z]:/ &&
3514 $prevrawline =~ /^[\+ ][A-Z]:/) {
3515 $rawline =~ /^\+([A-Z]):\s*(.*)/;
3516 my $cur = $1;
3517 my $curval = $2;
3518 $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
3519 my $prev = $1;
3520 my $prevval = $2;
3521 my $curindex = index($preferred_order, $cur);
3522 my $previndex = index($preferred_order, $prev);
3523 if ($curindex < 0) {
3524 WARN("MAINTAINERS_STYLE",
3525 "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
3526 } else {
3527 if ($previndex >= 0 && $curindex < $previndex) {
3528 WARN("MAINTAINERS_STYLE",
3529 "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
3530 } elsif ((($prev eq 'F' && $cur eq 'F') ||
3531 ($prev eq 'X' && $cur eq 'X')) &&
3532 ($prevval cmp $curval) > 0) {
3533 WARN("MAINTAINERS_STYLE",
3534 "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
3535 }
3536 }
Joe Perches628f91a2017-07-10 15:52:07 -07003537 }
3538 }
3539
Arnaud Lacombec68e5872011-08-15 01:07:14 -04003540 if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3541 ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3542 my $flag = $1;
3543 my $replacement = {
3544 'EXTRA_AFLAGS' => 'asflags-y',
3545 'EXTRA_CFLAGS' => 'ccflags-y',
3546 'EXTRA_CPPFLAGS' => 'cppflags-y',
3547 'EXTRA_LDFLAGS' => 'ldflags-y',
3548 };
3549
3550 WARN("DEPRECATED_VARIABLE",
3551 "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3552 }
3553
Rob Herringbff5da42014-01-23 15:54:51 -08003554# check for DT compatible documentation
Florian Vaussard7dd05b32014-04-03 14:49:26 -07003555 if (defined $root &&
3556 (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
3557 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
3558
Rob Herringbff5da42014-01-23 15:54:51 -08003559 my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3560
Florian Vaussardcc933192014-04-03 14:49:27 -07003561 my $dt_path = $root . "/Documentation/devicetree/bindings/";
Rob Herring852d0952019-05-22 09:55:34 -05003562 my $vp_file = $dt_path . "vendor-prefixes.yaml";
Florian Vaussardcc933192014-04-03 14:49:27 -07003563
Rob Herringbff5da42014-01-23 15:54:51 -08003564 foreach my $compat (@compats) {
3565 my $compat2 = $compat;
Rob Herring185d5662014-06-04 16:12:03 -07003566 $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3567 my $compat3 = $compat;
3568 $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3569 `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
Rob Herringbff5da42014-01-23 15:54:51 -08003570 if ( $? >> 8 ) {
3571 WARN("UNDOCUMENTED_DT_STRING",
3572 "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3573 }
3574
Florian Vaussard4fbf32a2014-04-03 14:49:25 -07003575 next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
3576 my $vendor = $1;
Rob Herring852d0952019-05-22 09:55:34 -05003577 `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
Rob Herringbff5da42014-01-23 15:54:51 -08003578 if ( $? >> 8 ) {
3579 WARN("UNDOCUMENTED_DT_STRING",
Florian Vaussardcc933192014-04-03 14:49:27 -07003580 "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
Rob Herringbff5da42014-01-23 15:54:51 -08003581 }
3582 }
3583 }
3584
Rob Herring9f3a8992018-04-10 16:33:13 -07003585# check for using SPDX license tag at beginning of files
3586 if ($realline == $checklicenseline) {
3587 if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
3588 $checklicenseline = 2;
3589 } elsif ($rawline =~ /^\+/) {
3590 my $comment = "";
3591 if ($realfile =~ /\.(h|s|S)$/) {
3592 $comment = '/*';
3593 } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
3594 $comment = '//';
Lubomir Rintelc8df0ab2020-04-06 20:10:51 -07003595 } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
Rob Herring9f3a8992018-04-10 16:33:13 -07003596 $comment = '#';
3597 } elsif ($realfile =~ /\.rst$/) {
3598 $comment = '..';
3599 }
3600
Joe Perchesfdf13692019-03-07 16:28:32 -08003601# check SPDX comment style for .[chsS] files
3602 if ($realfile =~ /\.[chsS]$/ &&
3603 $rawline =~ /SPDX-License-Identifier:/ &&
Joe Perchesffbce892019-09-25 16:46:35 -07003604 $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
Joe Perchesfdf13692019-03-07 16:28:32 -08003605 WARN("SPDX_LICENSE_TAG",
3606 "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3607 }
3608
Rob Herring9f3a8992018-04-10 16:33:13 -07003609 if ($comment !~ /^$/ &&
Joe Perchesffbce892019-09-25 16:46:35 -07003610 $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
3611 WARN("SPDX_LICENSE_TAG",
3612 "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
Joe Perches3b6e8ac2018-08-21 21:57:47 -07003613 } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
Joe Perchesffbce892019-09-25 16:46:35 -07003614 my $spdx_license = $1;
3615 if (!is_SPDX_License_valid($spdx_license)) {
3616 WARN("SPDX_LICENSE_TAG",
3617 "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3618 }
Lubomir Rintel50c92902020-04-06 20:11:13 -07003619 if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
3620 not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
3621 my $msg_level = \&WARN;
3622 $msg_level = \&CHK if ($file);
3623 if (&{$msg_level}("SPDX_LICENSE_TAG",
3624
3625 "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
3626 $fix) {
3627 $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
3628 }
3629 }
Rob Herring9f3a8992018-04-10 16:33:13 -07003630 }
3631 }
3632 }
3633
Joe Perchesa0154cd2020-10-15 20:12:19 -07003634# check for embedded filenames
3635 if ($rawline =~ /^\+.*\Q$realfile\E/) {
3636 WARN("EMBEDDED_FILENAME",
3637 "It's generally not useful to have the filename in the file\n" . $herecurr);
3638 }
3639
Andy Whitcroft5368df202008-10-15 22:02:27 -07003640# check we are in a valid source file if not then ignore this hunk
Joe Perchesd6430f72016-12-12 16:46:28 -08003641 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
Andy Whitcroft5368df202008-10-15 22:02:27 -07003642
Joe Perchesa8da38a2019-03-07 16:28:42 -08003643# check for using SPDX-License-Identifier on the wrong line number
3644 if ($realline != $checklicenseline &&
3645 $rawline =~ /\bSPDX-License-Identifier:/ &&
3646 substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3647 WARN("SPDX_LICENSE_TAG",
3648 "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3649 }
3650
Joe Perches47e0c882015-06-25 15:02:57 -07003651# line length limit (with some exclusions)
3652#
3653# There are a few types of lines that may extend beyond $max_line_length:
3654# logging functions like pr_info that end in a string
3655# lines with a single string
3656# #defines that are a single string
Andreas Brauchli2e4bbbc2018-02-06 15:38:45 -08003657# lines with an RFC3986 like URL
Joe Perches47e0c882015-06-25 15:02:57 -07003658#
3659# There are 3 different line length message types:
Jean Delvareab1ecab2017-09-08 16:16:04 -07003660# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
Joe Perches47e0c882015-06-25 15:02:57 -07003661# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
3662# LONG_LINE all other lines longer than $max_line_length
3663#
3664# if LONG_LINE is ignored, the other 2 types are also ignored
3665#
3666
Joe Perchesb4749e92015-07-17 16:24:01 -07003667 if ($line =~ /^\+/ && $length > $max_line_length) {
Joe Perches47e0c882015-06-25 15:02:57 -07003668 my $msg_type = "LONG_LINE";
3669
3670 # Check the allowed long line types first
3671
3672 # logging functions that end in a string that starts
3673 # before $max_line_length
3674 if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
3675 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3676 $msg_type = "";
3677
3678 # lines with only strings (w/ possible termination)
3679 # #defines with only strings
3680 } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
3681 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
3682 $msg_type = "";
3683
Joe Perchescc147502017-11-17 15:28:44 -08003684 # More special cases
3685 } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3686 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
Joe Perchesd560a5f2016-08-02 14:04:31 -07003687 $msg_type = "";
3688
Andreas Brauchli2e4bbbc2018-02-06 15:38:45 -08003689 # URL ($rawline is used in case the URL is in a comment)
3690 } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
3691 $msg_type = "";
3692
Joe Perches47e0c882015-06-25 15:02:57 -07003693 # Otherwise set the alternate message types
3694
3695 # a comment starts before $max_line_length
3696 } elsif ($line =~ /($;[\s$;]*)$/ &&
3697 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3698 $msg_type = "LONG_LINE_COMMENT"
3699
3700 # a quoted string starts before $max_line_length
3701 } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
3702 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3703 $msg_type = "LONG_LINE_STRING"
3704 }
3705
3706 if ($msg_type ne "" &&
3707 (show_type("LONG_LINE") || show_type($msg_type))) {
Joe Perchesbdc48fa2020-05-29 16:12:21 -07003708 my $msg_level = \&WARN;
3709 $msg_level = \&CHK if ($file);
3710 &{$msg_level}($msg_type,
3711 "line length of $length exceeds $max_line_length columns\n" . $herecurr);
Joe Perches47e0c882015-06-25 15:02:57 -07003712 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07003713 }
3714
Andy Whitcroft8905a672007-11-28 16:21:06 -08003715# check for adding lines without a newline.
3716 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
Tom Rix47ca69b2020-12-15 20:44:40 -08003717 if (WARN("MISSING_EOF_NEWLINE",
3718 "adding a line without newline at end of file\n" . $herecurr) &&
3719 $fix) {
3720 fix_delete_line($fixlinenr+1, "No newline at end of file");
3721 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08003722 }
3723
Aditya Srivastavade932452021-02-25 17:21:57 -08003724# check for .L prefix local symbols in .S files
3725 if ($realfile =~ /\.S$/ &&
3726 $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
3727 WARN("AVOID_L_PREFIX",
3728 "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\n" . $herecurr);
3729 }
3730
Andy Whitcroftb9ea10d2008-10-15 22:02:24 -07003731# check we are in a valid source file C or perl if not then ignore this hunk
Geert Uytterhoevende4c9242014-10-13 15:51:46 -07003732 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07003733
3734# at the beginning of a line any tabs must come first and anything
Antonio Borneo713a09d2020-04-06 20:11:07 -07003735# more than $tabsize must use tabs.
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08003736 if ($rawline =~ /^\+\s* \t\s*\S/ ||
3737 $rawline =~ /^\+\s* \s*/) {
3738 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Andy Whitcroftd2c0a232010-10-26 14:23:12 -07003739 $rpt_cleaners = 1;
Joe Perches3705ce52013-07-03 15:05:31 -07003740 if (ERROR("CODE_INDENT",
3741 "code indent should use tabs where possible\n" . $herevet) &&
3742 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07003743 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
Joe Perches3705ce52013-07-03 15:05:31 -07003744 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07003745 }
3746
Alberto Panizzo08e44362010-03-05 13:43:54 -08003747# check for space before tabs.
3748 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
3749 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Joe Perches3705ce52013-07-03 15:05:31 -07003750 if (WARN("SPACE_BEFORE_TAB",
3751 "please, no space before tabs\n" . $herevet) &&
3752 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07003753 while ($fixed[$fixlinenr] =~
Antonio Borneo713a09d2020-04-06 20:11:07 -07003754 s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
Joe Perches194f66f2014-08-06 16:11:03 -07003755 while ($fixed[$fixlinenr] =~
Joe Perchesc76f4cb2014-01-23 15:54:46 -08003756 s/(^\+.*) +\t/$1\t/) {}
Joe Perches3705ce52013-07-03 15:05:31 -07003757 }
Alberto Panizzo08e44362010-03-05 13:43:54 -08003758 }
3759
Joe Perches6a487212018-04-10 16:34:04 -07003760# check for assignments on the start of a line
3761 if ($sline =~ /^\+\s+($Assignment)[^=]/) {
Aditya Srivastavada7355a2020-12-15 20:45:06 -08003762 my $operator = $1;
3763 if (CHK("ASSIGNMENT_CONTINUATIONS",
3764 "Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
3765 $fix && $prevrawline =~ /^\+/) {
3766 # add assignment operator to the previous line, remove from current line
3767 $fixed[$fixlinenr - 1] .= " $operator";
3768 $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3769 }
Joe Perches6a487212018-04-10 16:34:04 -07003770 }
3771
Joe Perchesd1fe9c02012-03-23 15:02:16 -07003772# check for && or || at the start of a line
3773 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
Aditya Srivastava8e08f072020-12-15 20:45:09 -08003774 my $operator = $1;
3775 if (CHK("LOGICAL_CONTINUATIONS",
3776 "Logical continuations should be on the previous line\n" . $hereprev) &&
3777 $fix && $prevrawline =~ /^\+/) {
3778 # insert logical operator at last non-comment, non-whitepsace char on previous line
3779 $prevline =~ /[\s$;]*$/;
3780 my $line_end = substr($prevrawline, $-[0]);
3781 $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
3782 $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3783 }
Joe Perchesd1fe9c02012-03-23 15:02:16 -07003784 }
3785
Joe Perchesa91e8992016-05-20 17:04:05 -07003786# check indentation starts on a tab stop
Joe Perches5b579802018-08-21 21:57:33 -07003787 if ($perl_version_ok &&
Joe Perchesbd491112018-02-06 15:39:06 -08003788 $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
Joe Perchesa91e8992016-05-20 17:04:05 -07003789 my $indent = length($1);
Antonio Borneo713a09d2020-04-06 20:11:07 -07003790 if ($indent % $tabsize) {
Joe Perchesa91e8992016-05-20 17:04:05 -07003791 if (WARN("TABSTOP",
3792 "Statements should start on a tabstop\n" . $herecurr) &&
3793 $fix) {
Antonio Borneo713a09d2020-04-06 20:11:07 -07003794 $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
Joe Perchesa91e8992016-05-20 17:04:05 -07003795 }
3796 }
3797 }
3798
Joe Perchesd1fe9c02012-03-23 15:02:16 -07003799# check multi-line statement indentation matches previous line
Joe Perches5b579802018-08-21 21:57:33 -07003800 if ($perl_version_ok &&
Joe Perchesfd71f632017-07-10 15:52:30 -07003801 $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
Joe Perchesd1fe9c02012-03-23 15:02:16 -07003802 $prevline =~ /^\+(\t*)(.*)$/;
3803 my $oldindent = $1;
3804 my $rest = $2;
3805
3806 my $pos = pos_last_openparen($rest);
3807 if ($pos >= 0) {
Joe Perchesb34a26f2012-07-30 14:41:16 -07003808 $line =~ /^(\+| )([ \t]*)/;
3809 my $newindent = $2;
Joe Perchesd1fe9c02012-03-23 15:02:16 -07003810
3811 my $goodtabindent = $oldindent .
Antonio Borneo713a09d2020-04-06 20:11:07 -07003812 "\t" x ($pos / $tabsize) .
3813 " " x ($pos % $tabsize);
Joe Perchesd1fe9c02012-03-23 15:02:16 -07003814 my $goodspaceindent = $oldindent . " " x $pos;
3815
3816 if ($newindent ne $goodtabindent &&
3817 $newindent ne $goodspaceindent) {
Joe Perches3705ce52013-07-03 15:05:31 -07003818
3819 if (CHK("PARENTHESIS_ALIGNMENT",
3820 "Alignment should match open parenthesis\n" . $hereprev) &&
3821 $fix && $line =~ /^\+/) {
Joe Perches194f66f2014-08-06 16:11:03 -07003822 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07003823 s/^\+[ \t]*/\+$goodtabindent/;
3824 }
Joe Perchesd1fe9c02012-03-23 15:02:16 -07003825 }
3826 }
3827 }
3828
Joe Perches6ab3a972015-04-16 12:44:05 -07003829# check for space after cast like "(int) foo" or "(struct foo) bar"
3830# avoid checking a few false positives:
3831# "sizeof(<type>)" or "__alignof__(<type>)"
3832# function pointer declarations like "(*foo)(int) = bar;"
3833# structure definitions like "(struct foo) { 0 };"
3834# multiline macros that define functions
3835# known attributes or the __attribute__ keyword
3836 if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
3837 (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
Joe Perches3705ce52013-07-03 15:05:31 -07003838 if (CHK("SPACING",
Joe Perchesf27c95d2014-08-06 16:10:52 -07003839 "No space is necessary after a cast\n" . $herecurr) &&
Joe Perches3705ce52013-07-03 15:05:31 -07003840 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07003841 $fixed[$fixlinenr] =~
Joe Perchesf27c95d2014-08-06 16:10:52 -07003842 s/(\(\s*$Type\s*\))[ \t]+/$1/;
Joe Perches3705ce52013-07-03 15:05:31 -07003843 }
Joe Perchesaad4f612012-03-23 15:02:19 -07003844 }
3845
Joe Perches86406b12015-09-09 15:37:41 -07003846# Block comment styles
3847# Networking with an initial /*
Joe Perches05880602012-10-04 17:13:35 -07003848 if ($realfile =~ m@^(drivers/net/|net/)@ &&
Joe Perchesfdb4bcd2013-07-03 15:05:23 -07003849 $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
Joe Perches85ad9782014-04-03 14:49:20 -07003850 $rawline =~ /^\+[ \t]*\*/ &&
Łukasz Stelmachc70735c2020-10-15 20:12:25 -07003851 $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
Joe Perches05880602012-10-04 17:13:35 -07003852 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
3853 "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
3854 }
3855
Joe Perches86406b12015-09-09 15:37:41 -07003856# Block comments use * on subsequent lines
3857 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
3858 $prevrawline =~ /^\+.*?\/\*/ && #starting /*
Joe Perchesa605e322013-07-03 15:05:24 -07003859 $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
Joe Perches61135e92013-09-11 14:23:59 -07003860 $rawline =~ /^\+/ && #line is new
Joe Perchesa605e322013-07-03 15:05:24 -07003861 $rawline !~ /^\+[ \t]*\*/) { #no leading *
Joe Perches86406b12015-09-09 15:37:41 -07003862 WARN("BLOCK_COMMENT_STYLE",
3863 "Block comments use * on subsequent lines\n" . $hereprev);
Joe Perchesa605e322013-07-03 15:05:24 -07003864 }
3865
Joe Perches86406b12015-09-09 15:37:41 -07003866# Block comments use */ on trailing lines
3867 if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
Joe Perchesc24f9f12012-11-08 15:53:29 -08003868 $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
3869 $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/
3870 $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */
Joe Perches86406b12015-09-09 15:37:41 -07003871 WARN("BLOCK_COMMENT_STYLE",
3872 "Block comments use a trailing */ on a separate line\n" . $herecurr);
Joe Perches05880602012-10-04 17:13:35 -07003873 }
3874
Joe Perches08eb9b82016-10-11 13:51:50 -07003875# Block comment * alignment
3876 if ($prevline =~ /$;[ \t]*$/ && #ends in comment
Joe Perchesaf207522016-10-11 13:52:05 -07003877 $line =~ /^\+[ \t]*$;/ && #leading comment
3878 $rawline =~ /^\+[ \t]*\*/ && #leading *
3879 (($prevrawline =~ /^\+.*?\/\*/ && #leading /*
Joe Perches08eb9b82016-10-11 13:51:50 -07003880 $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */
Joe Perchesaf207522016-10-11 13:52:05 -07003881 $prevrawline =~ /^\+[ \t]*\*/)) { #leading *
3882 my $oldindent;
Joe Perches08eb9b82016-10-11 13:51:50 -07003883 $prevrawline =~ m@^\+([ \t]*/?)\*@;
Joe Perchesaf207522016-10-11 13:52:05 -07003884 if (defined($1)) {
3885 $oldindent = expand_tabs($1);
3886 } else {
3887 $prevrawline =~ m@^\+(.*/?)\*@;
3888 $oldindent = expand_tabs($1);
3889 }
Joe Perches08eb9b82016-10-11 13:51:50 -07003890 $rawline =~ m@^\+([ \t]*)\*@;
3891 my $newindent = $1;
Joe Perches08eb9b82016-10-11 13:51:50 -07003892 $newindent = expand_tabs($newindent);
Joe Perchesaf207522016-10-11 13:52:05 -07003893 if (length($oldindent) ne length($newindent)) {
Joe Perches08eb9b82016-10-11 13:51:50 -07003894 WARN("BLOCK_COMMENT_STYLE",
3895 "Block comments should align the * on each line\n" . $hereprev);
3896 }
3897 }
3898
Joe Perches7f619192014-08-06 16:10:39 -07003899# check for missing blank lines after struct/union declarations
3900# with exceptions for various attributes and macros
3901 if ($prevline =~ /^[\+ ]};?\s*$/ &&
3902 $line =~ /^\+/ &&
3903 !($line =~ /^\+\s*$/ ||
3904 $line =~ /^\+\s*EXPORT_SYMBOL/ ||
3905 $line =~ /^\+\s*MODULE_/i ||
3906 $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
3907 $line =~ /^\+[a-z_]*init/ ||
3908 $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
3909 $line =~ /^\+\s*DECLARE/ ||
Masahiro Yamada0bc989f2017-11-17 15:28:55 -08003910 $line =~ /^\+\s*builtin_[\w_]*driver/ ||
Joe Perches7f619192014-08-06 16:10:39 -07003911 $line =~ /^\+\s*__setup/)) {
Joe Perchesd752fcc2014-08-06 16:11:05 -07003912 if (CHK("LINE_SPACING",
3913 "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3914 $fix) {
Joe Perchesf2d7e4d2014-08-06 16:11:07 -07003915 fix_insert_line($fixlinenr, "\+");
Joe Perchesd752fcc2014-08-06 16:11:05 -07003916 }
Joe Perches7f619192014-08-06 16:10:39 -07003917 }
3918
Joe Perches365dd4e2014-08-06 16:10:42 -07003919# check for multiple consecutive blank lines
3920 if ($prevline =~ /^[\+ ]\s*$/ &&
3921 $line =~ /^\+\s*$/ &&
3922 $last_blank_line != ($linenr - 1)) {
Joe Perchesd752fcc2014-08-06 16:11:05 -07003923 if (CHK("LINE_SPACING",
3924 "Please don't use multiple blank lines\n" . $hereprev) &&
3925 $fix) {
Joe Perchesf2d7e4d2014-08-06 16:11:07 -07003926 fix_delete_line($fixlinenr, $rawline);
Joe Perchesd752fcc2014-08-06 16:11:05 -07003927 }
3928
Joe Perches365dd4e2014-08-06 16:10:42 -07003929 $last_blank_line = $linenr;
3930 }
3931
Joe Perches3b617e32014-04-03 14:49:28 -07003932# check for missing blank lines after declarations
Joe Perchesb5e87362021-02-25 17:21:40 -08003933# (declarations must have the same indentation and not be at the start of line)
3934 if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
3935 # use temporaries
3936 my $sl = $sline;
3937 my $pl = $prevline;
3938 # remove $Attribute/$Sparse uses to simplify comparisons
3939 $sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3940 $pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3941 if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
Joe Perches5a4e1fd2014-08-06 16:10:33 -07003942 # function pointer declarations
Joe Perchesb5e87362021-02-25 17:21:40 -08003943 $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003944 # foo bar; where foo is some local typedef or #define
Joe Perchesb5e87362021-02-25 17:21:40 -08003945 $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003946 # known declaration macros
Joe Perchesb5e87362021-02-25 17:21:40 -08003947 $pl =~ /^\+\s+$declaration_macros/) &&
Joe Perches3f7bac02014-06-04 16:12:04 -07003948 # for "else if" which can look like "$Ident $Ident"
Joe Perchesb5e87362021-02-25 17:21:40 -08003949 !($pl =~ /^\+\s+$c90_Keywords\b/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003950 # other possible extensions of declaration lines
Joe Perchesb5e87362021-02-25 17:21:40 -08003951 $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003952 # not starting a section or a macro "\" extended line
Joe Perchesb5e87362021-02-25 17:21:40 -08003953 $pl =~ /(?:\{\s*|\\)$/) &&
Joe Perches3f7bac02014-06-04 16:12:04 -07003954 # looks like a declaration
Joe Perchesb5e87362021-02-25 17:21:40 -08003955 !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
Joe Perches5a4e1fd2014-08-06 16:10:33 -07003956 # function pointer declarations
Joe Perchesb5e87362021-02-25 17:21:40 -08003957 $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003958 # foo bar; where foo is some local typedef or #define
Joe Perchesb5e87362021-02-25 17:21:40 -08003959 $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003960 # known declaration macros
Joe Perchesb5e87362021-02-25 17:21:40 -08003961 $sl =~ /^\+\s+$declaration_macros/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003962 # start of struct or union or enum
Joe Perchesb5e87362021-02-25 17:21:40 -08003963 $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003964 # start or end of block or continuation of declaration
Joe Perchesb5e87362021-02-25 17:21:40 -08003965 $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003966 # bitfield continuation
Joe Perchesb5e87362021-02-25 17:21:40 -08003967 $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
Joe Perches3f7bac02014-06-04 16:12:04 -07003968 # other possible extensions of declaration lines
Joe Perchesb5e87362021-02-25 17:21:40 -08003969 $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
3970 if (WARN("LINE_SPACING",
3971 "Missing a blank line after declarations\n" . $hereprev) &&
3972 $fix) {
3973 fix_insert_line($fixlinenr, "\+");
3974 }
Joe Perchesd752fcc2014-08-06 16:11:05 -07003975 }
Joe Perches3b617e32014-04-03 14:49:28 -07003976 }
3977
Raffaele Recalcati5f7ddae2010-08-09 17:20:59 -07003978# check for spaces at the beginning of a line.
Andy Whitcroft6b4c5be2010-10-26 14:23:11 -07003979# Exceptions:
3980# 1) within comments
3981# 2) indented preprocessor commands
3982# 3) hanging labels
Joe Perches3705ce52013-07-03 15:05:31 -07003983 if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
Raffaele Recalcati5f7ddae2010-08-09 17:20:59 -07003984 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Joe Perches3705ce52013-07-03 15:05:31 -07003985 if (WARN("LEADING_SPACE",
3986 "please, no spaces at the start of a line\n" . $herevet) &&
3987 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07003988 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
Joe Perches3705ce52013-07-03 15:05:31 -07003989 }
Raffaele Recalcati5f7ddae2010-08-09 17:20:59 -07003990 }
3991
Andy Whitcroftb9ea10d2008-10-15 22:02:24 -07003992# check we are in a valid C source file if not then ignore this hunk
3993 next if ($realfile !~ /\.(h|c)$/);
3994
Joe Perches5751a242017-11-17 15:28:52 -08003995# check for unusual line ending [ or (
3996 if ($line =~ /^\+.*([\[\(])\s*$/) {
3997 CHK("OPEN_ENDED_LINE",
3998 "Lines should not end with a '$1'\n" . $herecurr);
3999 }
4000
Joe Perches4dbed762017-05-08 15:55:39 -07004001# check if this appears to be the start function declaration, save the name
4002 if ($sline =~ /^\+\{\s*$/ &&
4003 $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
4004 $context_function = $1;
4005 }
4006
4007# check if this appears to be the end of function declaration
4008 if ($sline =~ /^\+\}\s*$/) {
4009 undef $context_function;
4010 }
4011
Joe Perches032a4c02014-08-06 16:10:29 -07004012# check indentation of any line with a bare else
Joe Perches840080a2014-10-13 15:51:59 -07004013# (but not if it is a multiple line "if (foo) return bar; else return baz;")
Joe Perches032a4c02014-08-06 16:10:29 -07004014# if the previous line is a break or return and is indented 1 tab more...
4015 if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
4016 my $tabs = length($1) + 1;
Joe Perches840080a2014-10-13 15:51:59 -07004017 if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
4018 ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
4019 defined $lines[$linenr] &&
4020 $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
Joe Perches032a4c02014-08-06 16:10:29 -07004021 WARN("UNNECESSARY_ELSE",
4022 "else is not generally useful after a break or return\n" . $hereprev);
4023 }
4024 }
4025
Joe Perchesc00df192014-08-06 16:11:01 -07004026# check indentation of a line with a break;
Joe Perchesdc58bc52020-12-15 20:44:33 -08004027# if the previous line is a goto, return or break
4028# and is indented the same # of tabs
Joe Perchesc00df192014-08-06 16:11:01 -07004029 if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
4030 my $tabs = $1;
Joe Perchesdc58bc52020-12-15 20:44:33 -08004031 if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
4032 if (WARN("UNNECESSARY_BREAK",
4033 "break is not useful after a $1\n" . $hereprev) &&
4034 $fix) {
4035 fix_delete_line($fixlinenr, $rawline);
4036 }
Joe Perchesc00df192014-08-06 16:11:01 -07004037 }
4038 }
4039
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004040# check for RCS/CVS revision markers
Andy Whitcroftcf655042008-03-04 14:28:20 -08004041 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004042 WARN("CVS_KEYWORD",
4043 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004044 }
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07004045
Joe Perches56e77d72013-02-21 16:44:14 -08004046# check for old HOTPLUG __dev<foo> section markings
4047 if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
4048 WARN("HOTPLUG_SECTION",
4049 "Using $1 is unnecessary\n" . $herecurr);
4050 }
4051
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07004052# Check for potential 'bare' types
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004053 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
4054 $realline_next);
Andy Whitcroft3e469cd2012-01-10 15:10:01 -08004055#print "LINE<$line>\n";
Joe Perchesca819862017-07-10 15:52:13 -07004056 if ($linenr > $suppress_statement &&
Joe Perches1b5539b2013-09-11 14:24:03 -07004057 $realcnt && $sline =~ /.\s*\S/) {
Andy Whitcroft170d3a22008-10-15 22:02:30 -07004058 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
Andy Whitcroftf5fe35d2008-07-23 21:29:03 -07004059 ctx_statement_block($linenr, $realcnt, 0);
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07004060 $stat =~ s/\n./\n /g;
4061 $cond =~ s/\n./\n /g;
4062
Andy Whitcroft3e469cd2012-01-10 15:10:01 -08004063#print "linenr<$linenr> <$stat>\n";
4064 # If this statement has no statement boundaries within
4065 # it there is no point in retrying a statement scan
4066 # until we hit end of it.
4067 my $frag = $stat; $frag =~ s/;+\s*$//;
4068 if ($frag !~ /(?:{|;)/) {
4069#print "skip<$line_nr_next>\n";
4070 $suppress_statement = $line_nr_next;
4071 }
Andy Whitcroftf74bd192012-01-10 15:09:54 -08004072
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004073 # Find the real next line.
4074 $realline_next = $line_nr_next;
4075 if (defined $realline_next &&
4076 (!defined $lines[$realline_next - 1] ||
4077 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
4078 $realline_next++;
4079 }
4080
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07004081 my $s = $stat;
4082 $s =~ s/{.*$//s;
Andy Whitcroftcf655042008-03-04 14:28:20 -08004083
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004084 # Ignore goto labels.
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07004085 if ($s =~ /$Ident:\*$/s) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004086
4087 # Ignore functions being called
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07004088 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004089
Andy Whitcroft463f2862009-09-21 17:04:34 -07004090 } elsif ($s =~ /^.\s*else\b/s) {
4091
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004092 # declarations always start with types
Andy Whitcroftd2506582008-07-23 21:29:09 -07004093 } 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) {
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004094 my $type = $1;
4095 $type =~ s/\s+/ /g;
4096 possible($type, "A:" . $s);
4097
Andy Whitcroft8905a672007-11-28 16:21:06 -08004098 # definitions in global scope can only start with types
Andy Whitcrofta6a840622008-10-15 22:02:30 -07004099 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004100 possible($1, "B:" . $s);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004101 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08004102
4103 # any (foo ... *) is a pointer cast, and foo is a type
Andy Whitcroft65863862009-01-06 14:41:21 -08004104 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004105 possible($1, "C:" . $s);
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07004106 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08004107
4108 # Check for any sort of function declaration.
4109 # int foo(something bar, other baz);
4110 # void (*store_gdt)(x86_descr_ptr *);
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07004111 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
Andy Whitcroft8905a672007-11-28 16:21:06 -08004112 my ($name_len) = length($1);
Andy Whitcroft8905a672007-11-28 16:21:06 -08004113
Andy Whitcroftcf655042008-03-04 14:28:20 -08004114 my $ctx = $s;
Andy Whitcroft773647a2008-03-28 14:15:58 -07004115 substr($ctx, 0, $name_len + 1, '');
Andy Whitcroft8905a672007-11-28 16:21:06 -08004116 $ctx =~ s/\)[^\)]*$//;
Andy Whitcroftcf655042008-03-04 14:28:20 -08004117
Andy Whitcroft8905a672007-11-28 16:21:06 -08004118 for my $arg (split(/\s*,\s*/, $ctx)) {
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004119 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
Andy Whitcroft8905a672007-11-28 16:21:06 -08004120
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004121 possible($1, "D:" . $s);
Andy Whitcroft8905a672007-11-28 16:21:06 -08004122 }
4123 }
4124 }
4125
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07004126 }
4127
Andy Whitcroft653d4872007-06-23 17:16:34 -07004128#
4129# Checks which may be anchored in the context.
4130#
4131
4132# Check for switch () and associated case and default
4133# statements should be at the same indent.
Andy Whitcroft00df3442007-06-08 13:47:06 -07004134 if ($line=~/\bswitch\s*\(.*\)/) {
4135 my $err = '';
4136 my $sep = '';
4137 my @ctx = ctx_block_outer($linenr, $realcnt);
4138 shift(@ctx);
4139 for my $ctx (@ctx) {
4140 my ($clen, $cindent) = line_stats($ctx);
4141 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
4142 $indent != $cindent) {
4143 $err .= "$sep$ctx\n";
4144 $sep = '';
4145 } else {
4146 $sep = "[...]\n";
4147 }
4148 }
4149 if ($err ne '') {
Joe Perches000d1cc12011-07-25 17:13:25 -07004150 ERROR("SWITCH_CASE_INDENT_LEVEL",
4151 "switch and case should be at the same indent\n$hereline$err");
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07004152 }
4153 }
4154
4155# if/while/etc brace do not go on next line, unless defining a do while loop,
4156# or if that brace on the next line is for something else
Joe Perches0fe3dc22014-08-06 16:11:16 -07004157 if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07004158 my $pre_ctx = "$1$2";
4159
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07004160 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
Joe Perches8eef05d2012-02-03 15:20:39 -08004161
4162 if ($line =~ /^\+\t{6,}/) {
4163 WARN("DEEP_INDENTATION",
4164 "Too many leading tabs - consider code refactoring\n" . $herecurr);
4165 }
4166
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07004167 my $ctx_cnt = $realcnt - $#ctx - 1;
4168 my $ctx = join("\n", @ctx);
4169
Andy Whitcroft548596d2008-07-23 21:29:01 -07004170 my $ctx_ln = $linenr;
4171 my $ctx_skip = $realcnt;
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07004172
Andy Whitcroft548596d2008-07-23 21:29:01 -07004173 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
4174 defined $lines[$ctx_ln - 1] &&
4175 $lines[$ctx_ln - 1] =~ /^-/)) {
4176 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
4177 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
Andy Whitcroft773647a2008-03-28 14:15:58 -07004178 $ctx_ln++;
4179 }
Andy Whitcroft548596d2008-07-23 21:29:01 -07004180
Andy Whitcroft53210162008-07-23 21:29:03 -07004181 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
4182 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
Andy Whitcroft773647a2008-03-28 14:15:58 -07004183
Joe Perchesd752fcc2014-08-06 16:11:05 -07004184 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004185 ERROR("OPEN_BRACE",
4186 "that open brace { should be on the previous line\n" .
Andy Whitcroft01464f32010-10-26 14:23:19 -07004187 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
Andy Whitcroft00df3442007-06-08 13:47:06 -07004188 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07004189 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4190 $ctx =~ /\)\s*\;\s*$/ &&
4191 defined $lines[$ctx_ln - 1])
4192 {
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07004193 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
4194 if ($nindent > $indent) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004195 WARN("TRAILING_SEMICOLON",
4196 "trailing semicolon indicates no statements, indent implies otherwise\n" .
Andy Whitcroft01464f32010-10-26 14:23:19 -07004197 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07004198 }
4199 }
Andy Whitcroft00df3442007-06-08 13:47:06 -07004200 }
4201
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004202# Check relative indent for conditionals and blocks.
Joe Perchesf6950a72017-05-08 15:56:05 -07004203 if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
Andy Whitcroft3e469cd2012-01-10 15:10:01 -08004204 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4205 ctx_statement_block($linenr, $realcnt, 0)
4206 if (!defined $stat);
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004207 my ($s, $c) = ($stat, $cond);
4208
4209 substr($s, 0, length($c), '');
4210
Joe Perches9f5af482015-09-09 15:37:30 -07004211 # remove inline comments
4212 $s =~ s/$;/ /g;
4213 $c =~ s/$;/ /g;
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004214
4215 # Find out how long the conditional actually is.
Andy Whitcroft6f779c12008-10-15 22:02:27 -07004216 my @newlines = ($c =~ /\n/gs);
4217 my $cond_lines = 1 + $#newlines;
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004218
Joe Perches9f5af482015-09-09 15:37:30 -07004219 # Make sure we remove the line prefixes as we have
4220 # none on the first line, and are going to readd them
4221 # where necessary.
4222 $s =~ s/\n./\n/gs;
4223 while ($s =~ /\n\s+\\\n/) {
4224 $cond_lines += $s =~ s/\n\s+\\\n/\n/g;
4225 }
4226
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004227 # We want to check the first line inside the block
4228 # starting at the end of the conditional, so remove:
4229 # 1) any blank line termination
4230 # 2) any opening brace { on end of the line
4231 # 3) any do (...) {
4232 my $continuation = 0;
4233 my $check = 0;
4234 $s =~ s/^.*\bdo\b//;
4235 $s =~ s/^\s*{//;
4236 if ($s =~ s/^\s*\\//) {
4237 $continuation = 1;
4238 }
Andy Whitcroft9bd49ef2008-10-15 22:02:22 -07004239 if ($s =~ s/^\s*?\n//) {
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004240 $check = 1;
4241 $cond_lines++;
4242 }
4243
4244 # Also ignore a loop construct at the end of a
4245 # preprocessor statement.
4246 if (($prevline =~ /^.\s*#\s*define\s/ ||
4247 $prevline =~ /\\\s*$/) && $continuation == 0) {
4248 $check = 0;
4249 }
4250
Andy Whitcroft9bd49ef2008-10-15 22:02:22 -07004251 my $cond_ptr = -1;
Andy Whitcroft740504c2008-10-15 22:02:35 -07004252 $continuation = 0;
Andy Whitcroft9bd49ef2008-10-15 22:02:22 -07004253 while ($cond_ptr != $cond_lines) {
4254 $cond_ptr = $cond_lines;
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004255
Andy Whitcroftf16fa282008-10-15 22:02:32 -07004256 # If we see an #else/#elif then the code
4257 # is not linear.
4258 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
4259 $check = 0;
4260 }
4261
Andy Whitcroft9bd49ef2008-10-15 22:02:22 -07004262 # Ignore:
4263 # 1) blank lines, they should be at 0,
4264 # 2) preprocessor lines, and
4265 # 3) labels.
Andy Whitcroft740504c2008-10-15 22:02:35 -07004266 if ($continuation ||
4267 $s =~ /^\s*?\n/ ||
Andy Whitcroft9bd49ef2008-10-15 22:02:22 -07004268 $s =~ /^\s*#\s*?/ ||
4269 $s =~ /^\s*$Ident\s*:/) {
Andy Whitcroft740504c2008-10-15 22:02:35 -07004270 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
Andy Whitcroft30dad6e2009-09-21 17:04:36 -07004271 if ($s =~ s/^.*?\n//) {
4272 $cond_lines++;
4273 }
Andy Whitcroft9bd49ef2008-10-15 22:02:22 -07004274 }
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004275 }
4276
4277 my (undef, $sindent) = line_stats("+" . $s);
4278 my $stat_real = raw_line($linenr, $cond_lines);
4279
4280 # Check if either of these lines are modified, else
4281 # this is not this patch's fault.
4282 if (!defined($stat_real) ||
4283 $stat !~ /^\+/ && $stat_real !~ /^\+/) {
4284 $check = 0;
4285 }
4286 if (defined($stat_real) && $cond_lines > 1) {
4287 $stat_real = "[...]\n$stat_real";
4288 }
4289
Andy Whitcroft9bd49ef2008-10-15 22:02:22 -07004290 #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";
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004291
Joe Perches9f5af482015-09-09 15:37:30 -07004292 if ($check && $s ne '' &&
Antonio Borneo713a09d2020-04-06 20:11:07 -07004293 (($sindent % $tabsize) != 0 ||
Joe Perches9f5af482015-09-09 15:37:30 -07004294 ($sindent < $indent) ||
Joe Perchesf6950a72017-05-08 15:56:05 -07004295 ($sindent == $indent &&
4296 ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
Antonio Borneo713a09d2020-04-06 20:11:07 -07004297 ($sindent > $indent + $tabsize))) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004298 WARN("SUSPECT_CODE_INDENT",
4299 "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
Andy Whitcroft4d001e42008-10-15 22:02:21 -07004300 }
4301 }
4302
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004303 # Track the 'values' across context and added lines.
4304 my $opline = $line; $opline =~ s/^./ /;
Andy Whitcroft1f65f942008-07-23 21:29:10 -07004305 my ($curr_values, $curr_vars) =
4306 annotate_values($opline . "\n", $prev_values);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004307 $curr_values = $prev_values . $curr_values;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004308 if ($dbg_values) {
4309 my $outline = $opline; $outline =~ s/\t/ /g;
Andy Whitcroftcf655042008-03-04 14:28:20 -08004310 print "$linenr > .$outline\n";
4311 print "$linenr > $curr_values\n";
Andy Whitcroft1f65f942008-07-23 21:29:10 -07004312 print "$linenr > $curr_vars\n";
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004313 }
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004314 $prev_values = substr($curr_values, -1);
4315
Andy Whitcroft00df3442007-06-08 13:47:06 -07004316#ignore lines not being added
Joe Perches3705ce52013-07-03 15:05:31 -07004317 next if ($line =~ /^[^\+]/);
Andy Whitcroft00df3442007-06-08 13:47:06 -07004318
Joe Perches99ca38c2020-10-15 20:12:09 -07004319# check for self assignments used to avoid compiler warnings
4320# e.g.: int foo = foo, *bar = NULL;
4321# struct foo bar = *(&(bar));
4322 if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
4323 my $var = $1;
4324 if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
4325 WARN("SELF_ASSIGNMENT",
4326 "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
4327 }
4328 }
4329
Joe Perches11ca40a2016-12-12 16:46:31 -08004330# check for dereferences that span multiple lines
4331 if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
4332 $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
4333 $prevline =~ /($Lval\s*(?:\.|->))\s*$/;
4334 my $ref = $1;
4335 $line =~ /^.\s*($Lval)/;
4336 $ref .= $1;
4337 $ref =~ s/\s//g;
4338 WARN("MULTILINE_DEREFERENCE",
4339 "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
4340 }
4341
Joe Perchesa1ce18e2016-03-15 14:58:03 -07004342# check for declarations of signed or unsigned without int
Joe Perchesc8447112016-08-02 14:04:42 -07004343 while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
Joe Perchesa1ce18e2016-03-15 14:58:03 -07004344 my $type = $1;
4345 my $var = $2;
Joe Perches207a8e82016-03-15 14:58:06 -07004346 $var = "" if (!defined $var);
4347 if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
Joe Perchesa1ce18e2016-03-15 14:58:03 -07004348 my $sign = $1;
4349 my $pointer = $2;
4350
4351 $pointer = "" if (!defined $pointer);
4352
4353 if (WARN("UNSPECIFIED_INT",
4354 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
4355 $fix) {
4356 my $decl = trim($sign) . " int ";
Joe Perches207a8e82016-03-15 14:58:06 -07004357 my $comp_pointer = $pointer;
4358 $comp_pointer =~ s/\s//g;
4359 $decl .= $comp_pointer;
4360 $decl = rtrim($decl) if ($var eq "");
4361 $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
Joe Perchesa1ce18e2016-03-15 14:58:03 -07004362 }
4363 }
4364 }
4365
Andy Whitcroft653d4872007-06-23 17:16:34 -07004366# TEST: allow direct testing of the type matcher.
Andy Whitcroft7429c692008-07-23 21:29:06 -07004367 if ($dbg_type) {
4368 if ($line =~ /^.\s*$Declare\s*$/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004369 ERROR("TEST_TYPE",
4370 "TEST: is type\n" . $herecurr);
Andy Whitcroft7429c692008-07-23 21:29:06 -07004371 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004372 ERROR("TEST_NOT_TYPE",
4373 "TEST: is not type ($1 is)\n". $herecurr);
Andy Whitcroft7429c692008-07-23 21:29:06 -07004374 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07004375 next;
4376 }
Andy Whitcrofta1ef2772008-10-15 22:02:17 -07004377# TEST: allow direct testing of the attribute matcher.
4378 if ($dbg_attr) {
Andy Whitcroft9360b0e2009-02-27 14:03:08 -08004379 if ($line =~ /^.\s*$Modifier\s*$/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004380 ERROR("TEST_ATTR",
4381 "TEST: is attr\n" . $herecurr);
Andy Whitcroft9360b0e2009-02-27 14:03:08 -08004382 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004383 ERROR("TEST_NOT_ATTR",
4384 "TEST: is not attr ($1 is)\n". $herecurr);
Andy Whitcrofta1ef2772008-10-15 22:02:17 -07004385 }
4386 next;
4387 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07004388
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07004389# check for initialisation to aggregates open brace on the next line
Andy Whitcroft99423c22009-10-26 16:50:15 -07004390 if ($line =~ /^.\s*{/ &&
4391 $prevline =~ /(?:^|[^=])=\s*$/) {
Joe Perchesd752fcc2014-08-06 16:11:05 -07004392 if (ERROR("OPEN_BRACE",
4393 "that open brace { should be on the previous line\n" . $hereprev) &&
Joe Perchesf2d7e4d2014-08-06 16:11:07 -07004394 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4395 fix_delete_line($fixlinenr - 1, $prevrawline);
4396 fix_delete_line($fixlinenr, $rawline);
Joe Perchesd752fcc2014-08-06 16:11:05 -07004397 my $fixedline = $prevrawline;
4398 $fixedline =~ s/\s*=\s*$/ = {/;
Joe Perchesf2d7e4d2014-08-06 16:11:07 -07004399 fix_insert_line($fixlinenr, $fixedline);
Joe Perchesd752fcc2014-08-06 16:11:05 -07004400 $fixedline = $line;
Cyril Bur8d81ae02017-07-10 15:52:21 -07004401 $fixedline =~ s/^(.\s*)\{\s*/$1/;
Joe Perchesf2d7e4d2014-08-06 16:11:07 -07004402 fix_insert_line($fixlinenr, $fixedline);
Joe Perchesd752fcc2014-08-06 16:11:05 -07004403 }
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07004404 }
4405
Andy Whitcroft653d4872007-06-23 17:16:34 -07004406#
4407# Checks which are anchored on the added line.
4408#
4409
4410# check for malformed paths in #include statements (uses RAW line)
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004411 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
Andy Whitcroft653d4872007-06-23 17:16:34 -07004412 my $path = $1;
4413 if ($path =~ m{//}) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004414 ERROR("MALFORMED_INCLUDE",
Joe Perches495e9d82012-12-20 15:05:37 -08004415 "malformed #include filename\n" . $herecurr);
4416 }
4417 if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4418 ERROR("UAPI_INCLUDE",
4419 "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
Andy Whitcroft653d4872007-06-23 17:16:34 -07004420 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07004421 }
Andy Whitcroft00df3442007-06-08 13:47:06 -07004422
4423# no C99 // comments
4424 if ($line =~ m{//}) {
Joe Perches3705ce52013-07-03 15:05:31 -07004425 if (ERROR("C99_COMMENTS",
4426 "do not use C99 // comments\n" . $herecurr) &&
4427 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07004428 my $line = $fixed[$fixlinenr];
Joe Perches3705ce52013-07-03 15:05:31 -07004429 if ($line =~ /\/\/(.*)$/) {
4430 my $comment = trim($1);
Joe Perches194f66f2014-08-06 16:11:03 -07004431 $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
Joe Perches3705ce52013-07-03 15:05:31 -07004432 }
4433 }
Andy Whitcroft00df3442007-06-08 13:47:06 -07004434 }
4435 # Remove C99 comments.
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004436 $line =~ s@//.*@@;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004437 $opline =~ s@//.*@@;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004438
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004439# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
4440# the whole statement.
4441#print "APW <$lines[$realline_next - 1]>\n";
4442 if (defined $realline_next &&
4443 exists $lines[$realline_next - 1] &&
4444 !defined $suppress_export{$realline_next} &&
Christoph Hellwig36794822021-02-02 13:13:34 +01004445 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
Andy Whitcroft3cbf62d2010-10-26 14:23:18 -07004446 # Handle definitions which produce identifiers with
4447 # a prefix:
4448 # XXX(foo);
4449 # EXPORT_SYMBOL(something_foo);
Andy Whitcroft653d4872007-06-23 17:16:34 -07004450 my $name = $1;
Andy Whitcroft87a53872012-01-10 15:10:04 -08004451 if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
Andy Whitcroft3cbf62d2010-10-26 14:23:18 -07004452 $name =~ /^${Ident}_$2/) {
4453#print "FOO C name<$name>\n";
4454 $suppress_export{$realline_next} = 1;
4455
4456 } elsif ($stat !~ /(?:
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004457 \n.}\s*$|
Andy Whitcroft48012052008-10-15 22:02:34 -07004458 ^.DEFINE_$Ident\(\Q$name\E\)|
4459 ^.DECLARE_$Ident\(\Q$name\E\)|
4460 ^.LIST_HEAD\(\Q$name\E\)|
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004461 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
4462 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
Andy Whitcroft48012052008-10-15 22:02:34 -07004463 )/x) {
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004464#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
4465 $suppress_export{$realline_next} = 2;
4466 } else {
4467 $suppress_export{$realline_next} = 1;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004468 }
4469 }
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004470 if (!defined $suppress_export{$linenr} &&
4471 $prevline =~ /^.\s*$/ &&
Christoph Hellwig36794822021-02-02 13:13:34 +01004472 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004473#print "FOO B <$lines[$linenr - 1]>\n";
4474 $suppress_export{$linenr} = 2;
4475 }
4476 if (defined $suppress_export{$linenr} &&
4477 $suppress_export{$linenr} == 2) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004478 WARN("EXPORT_SYMBOL",
4479 "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
Andy Whitcroft2b474a12009-10-26 16:50:16 -07004480 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004481
Joe Eloff5150bda2010-08-09 17:21:00 -07004482# check for global initialisers.
Song Liu5b8f82e2021-02-25 17:22:08 -08004483 if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
4484 !exclude_global_initialisers($realfile)) {
Joe Perchesd5e616f2013-09-11 14:23:54 -07004485 if (ERROR("GLOBAL_INITIALISERS",
Joe Perches6d32f7a2015-11-06 16:31:37 -08004486 "do not initialise globals to $1\n" . $herecurr) &&
Joe Perchesd5e616f2013-09-11 14:23:54 -07004487 $fix) {
Joe Perches6d32f7a2015-11-06 16:31:37 -08004488 $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
Joe Perchesd5e616f2013-09-11 14:23:54 -07004489 }
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07004490 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07004491# check for static initialisers.
Joe Perches6d32f7a2015-11-06 16:31:37 -08004492 if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
Joe Perchesd5e616f2013-09-11 14:23:54 -07004493 if (ERROR("INITIALISED_STATIC",
Joe Perches6d32f7a2015-11-06 16:31:37 -08004494 "do not initialise statics to $1\n" .
Joe Perchesd5e616f2013-09-11 14:23:54 -07004495 $herecurr) &&
4496 $fix) {
Joe Perches6d32f7a2015-11-06 16:31:37 -08004497 $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
Joe Perchesd5e616f2013-09-11 14:23:54 -07004498 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004499 }
4500
Joe Perches18130872014-08-06 16:11:22 -07004501# check for misordered declarations of char/short/int/long with signed/unsigned
4502 while ($sline =~ m{(\b$TypeMisordered\b)}g) {
4503 my $tmp = trim($1);
4504 WARN("MISORDERED_TYPE",
4505 "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
4506 }
4507
Joe Perches809e0822018-08-21 21:58:12 -07004508# check for unnecessary <signed> int declarations of short/long/long long
4509 while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4510 my $type = trim($1);
4511 next if ($type !~ /\bint\b/);
4512 next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4513 my $new_type = $type;
4514 $new_type =~ s/\b\s*int\s*\b/ /;
4515 $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4516 $new_type =~ s/^const\s+//;
4517 $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4518 $new_type = "const $new_type" if ($type =~ /^const\b/);
4519 $new_type =~ s/\s+/ /g;
4520 $new_type = trim($new_type);
4521 if (WARN("UNNECESSARY_INT",
4522 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4523 $fix) {
4524 $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4525 }
4526 }
4527
Joe Perchescb710ec2010-10-26 14:23:20 -07004528# check for static const char * arrays.
4529 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004530 WARN("STATIC_CONST_CHAR_ARRAY",
4531 "static const char * array should probably be static const char * const\n" .
Joe Perchescb710ec2010-10-26 14:23:20 -07004532 $herecurr);
Joe Perches77b8c0a2019-01-03 15:26:59 -08004533 }
4534
4535# check for initialized const char arrays that should be static const
4536 if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
4537 if (WARN("STATIC_CONST_CHAR_ARRAY",
4538 "const array should probably be static const\n" . $herecurr) &&
4539 $fix) {
4540 $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
4541 }
4542 }
Joe Perchescb710ec2010-10-26 14:23:20 -07004543
4544# check for static char foo[] = "bar" declarations.
4545 if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004546 WARN("STATIC_CONST_CHAR_ARRAY",
4547 "static char array declaration should probably be static const char\n" .
Joe Perchescb710ec2010-10-26 14:23:20 -07004548 $herecurr);
Joe Perches77b8c0a2019-01-03 15:26:59 -08004549 }
Joe Perchescb710ec2010-10-26 14:23:20 -07004550
Joe Perchesab7e23f2015-04-16 12:44:22 -07004551# check for const <foo> const where <foo> is not a pointer or array type
4552 if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4553 my $found = $1;
4554 if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4555 WARN("CONST_CONST",
4556 "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4557 } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4558 WARN("CONST_CONST",
4559 "'const $found const' should probably be 'const $found'\n" . $herecurr);
4560 }
4561 }
4562
Joe Perches73169762020-12-15 20:44:30 -08004563# check for const static or static <non ptr type> const declarations
4564# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
4565 if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
4566 $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
4567 if (WARN("STATIC_CONST",
4568 "Move const after static - use 'static const $1'\n" . $herecurr) &&
4569 $fix) {
4570 $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
4571 $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
4572 }
4573 }
4574
Joe Perches9b0fa602014-04-03 14:49:18 -07004575# check for non-global char *foo[] = {"bar", ...} declarations.
4576 if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
4577 WARN("STATIC_CONST_CHAR_ARRAY",
4578 "char * array declaration might be better as static const\n" .
4579 $herecurr);
Dwaipayan Rayea7dbab2021-02-25 17:21:47 -08004580 }
Joe Perches9b0fa602014-04-03 14:49:18 -07004581
Joe Perchesb598b672015-04-16 12:44:36 -07004582# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4583 if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4584 my $array = $1;
4585 if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
4586 my $array_div = $1;
4587 if (WARN("ARRAY_SIZE",
4588 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4589 $fix) {
4590 $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4591 }
4592 }
4593 }
4594
Joe Perchesb36190c2014-01-27 17:07:18 -08004595# check for function declarations without arguments like "int foo()"
Joe Perches16b7f3c2020-04-06 20:11:17 -07004596 if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
Joe Perchesb36190c2014-01-27 17:07:18 -08004597 if (ERROR("FUNCTION_WITHOUT_ARGS",
4598 "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4599 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07004600 $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
Joe Perchesb36190c2014-01-27 17:07:18 -08004601 }
4602 }
4603
Andy Whitcroft653d4872007-06-23 17:16:34 -07004604# check for new typedefs, only function parameters and sparse annotations
4605# make sense.
4606 if ($line =~ /\btypedef\s/ &&
Andy Whitcroft80545762009-01-06 14:41:26 -08004607 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004608 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
Andy Whitcroft8ed22ca2008-10-15 22:02:32 -07004609 $line !~ /\b$typeTypedefs\b/ &&
Michael S. Tsirkin46d832f2016-12-11 06:29:58 +02004610 $line !~ /\b__bitwise\b/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004611 WARN("NEW_TYPEDEFS",
4612 "do not add new typedefs\n" . $herecurr);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004613 }
4614
4615# * goes on variable not on type
Andy Whitcroft65863862009-01-06 14:41:21 -08004616 # (char*[ const])
Andy Whitcroftbfcb2cc2012-01-10 15:10:15 -08004617 while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4618 #print "AA<$1>\n";
Joe Perches3705ce52013-07-03 15:05:31 -07004619 my ($ident, $from, $to) = ($1, $2, $2);
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07004620
Andy Whitcroft65863862009-01-06 14:41:21 -08004621 # Should start with a space.
4622 $to =~ s/^(\S)/ $1/;
4623 # Should not end with a space.
4624 $to =~ s/\s+$//;
4625 # '*'s should not have spaces between.
Andy Whitcroftf9a0b3d2009-01-15 13:51:05 -08004626 while ($to =~ s/\*\s+\*/\*\*/) {
Andy Whitcroft65863862009-01-06 14:41:21 -08004627 }
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07004628
Joe Perches3705ce52013-07-03 15:05:31 -07004629## print "1: from<$from> to<$to> ident<$ident>\n";
Andy Whitcroft65863862009-01-06 14:41:21 -08004630 if ($from ne $to) {
Joe Perches3705ce52013-07-03 15:05:31 -07004631 if (ERROR("POINTER_LOCATION",
4632 "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
4633 $fix) {
4634 my $sub_from = $ident;
4635 my $sub_to = $ident;
4636 $sub_to =~ s/\Q$from\E/$to/;
Joe Perches194f66f2014-08-06 16:11:03 -07004637 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07004638 s@\Q$sub_from\E@$sub_to@;
4639 }
Andy Whitcroft65863862009-01-06 14:41:21 -08004640 }
Andy Whitcroftbfcb2cc2012-01-10 15:10:15 -08004641 }
4642 while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4643 #print "BB<$1>\n";
Joe Perches3705ce52013-07-03 15:05:31 -07004644 my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07004645
Andy Whitcroft65863862009-01-06 14:41:21 -08004646 # Should start with a space.
4647 $to =~ s/^(\S)/ $1/;
4648 # Should not end with a space.
4649 $to =~ s/\s+$//;
4650 # '*'s should not have spaces between.
Andy Whitcroftf9a0b3d2009-01-15 13:51:05 -08004651 while ($to =~ s/\*\s+\*/\*\*/) {
Andy Whitcroft65863862009-01-06 14:41:21 -08004652 }
4653 # Modifiers should have spaces.
4654 $to =~ s/(\b$Modifier$)/$1 /;
4655
Joe Perches3705ce52013-07-03 15:05:31 -07004656## print "2: from<$from> to<$to> ident<$ident>\n";
Andy Whitcroft667026e2009-02-27 14:03:08 -08004657 if ($from ne $to && $ident !~ /^$Modifier$/) {
Joe Perches3705ce52013-07-03 15:05:31 -07004658 if (ERROR("POINTER_LOCATION",
4659 "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
4660 $fix) {
4661
4662 my $sub_from = $match;
4663 my $sub_to = $match;
4664 $sub_to =~ s/\Q$from\E/$to/;
Joe Perches194f66f2014-08-06 16:11:03 -07004665 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07004666 s@\Q$sub_from\E@$sub_to@;
4667 }
Andy Whitcroft65863862009-01-06 14:41:21 -08004668 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004669 }
4670
Joe Perches9d3e3c72015-09-09 15:37:27 -07004671# avoid BUG() or BUG_ON()
4672 if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
Jean Delvare0675a8f2017-09-08 16:16:07 -07004673 my $msg_level = \&WARN;
4674 $msg_level = \&CHK if ($file);
4675 &{$msg_level}("AVOID_BUG",
4676 "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
Joe Perches9d3e3c72015-09-09 15:37:27 -07004677 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004678
Joe Perches9d3e3c72015-09-09 15:37:27 -07004679# avoid LINUX_VERSION_CODE
Andy Whitcroft8905a672007-11-28 16:21:06 -08004680 if ($line =~ /\bLINUX_VERSION_CODE\b/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004681 WARN("LINUX_VERSION_CODE",
4682 "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
Andy Whitcroft8905a672007-11-28 16:21:06 -08004683 }
4684
Joe Perches17441222011-06-15 15:08:17 -07004685# check for uses of printk_ratelimit
4686 if ($line =~ /\bprintk_ratelimit\s*\(/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07004687 WARN("PRINTK_RATELIMITED",
Joe Perches101ee682015-02-13 14:38:54 -08004688 "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
Joe Perches17441222011-06-15 15:08:17 -07004689 }
4690
Joe Percheseeef5732017-11-17 15:28:41 -08004691# printk should use KERN_* levels
4692 if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4693 WARN("PRINTK_WITHOUT_KERN_LEVEL",
4694 "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004695 }
4696
Joe Perchesf5eea3b2020-12-15 20:45:24 -08004697# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
4698 if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
4699 my $printk = $1;
4700 my $modifier = $2;
4701 my $orig = $3;
4702 $modifier = "" if (!defined($modifier));
Joe Perches243f3802012-05-31 16:26:09 -07004703 my $level = lc($orig);
4704 $level = "warn" if ($level eq "warning");
Joe Perches8f26b832012-10-04 17:13:32 -07004705 my $level2 = $level;
4706 $level2 = "dbg" if ($level eq "debug");
Joe Perchesf5eea3b2020-12-15 20:45:24 -08004707 $level .= $modifier;
4708 $level2 .= $modifier;
Joe Perches243f3802012-05-31 16:26:09 -07004709 WARN("PREFER_PR_LEVEL",
Joe Perchesf5eea3b2020-12-15 20:45:24 -08004710 "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr);
Joe Perches243f3802012-05-31 16:26:09 -07004711 }
4712
Joe Perchesf5eea3b2020-12-15 20:45:24 -08004713# prefer dev_<level> to dev_printk(KERN_<LEVEL>
Joe Perchesdc139312013-02-21 16:44:13 -08004714 if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4715 my $orig = $1;
4716 my $level = lc($orig);
4717 $level = "warn" if ($level eq "warning");
4718 $level = "dbg" if ($level eq "debug");
4719 WARN("PREFER_DEV_LEVEL",
4720 "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4721 }
4722
Nicolas Boichat8020b252020-10-15 20:12:02 -07004723# trace_printk should not be used in production code.
4724 if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
4725 WARN("TRACE_PRINTK",
4726 "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
4727 }
4728
Andy Lutomirski91c9afa2015-04-16 12:44:44 -07004729# ENOSYS means "bad syscall nr" and nothing else. This will have a small
4730# number of false positives, but assembly files are not checked, so at
4731# least the arch entry code will not trigger this warning.
4732 if ($line =~ /\bENOSYS\b/) {
4733 WARN("ENOSYS",
4734 "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
4735 }
4736
Jakub Kicinski6b9ea5f2020-05-11 10:08:07 -07004737# ENOTSUPP is not a standard error code and should be avoided in new patches.
4738# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
4739# Similarly to ENOSYS warning a small number of false positives is expected.
4740 if (!$file && $line =~ /\bENOTSUPP\b/) {
4741 if (WARN("ENOTSUPP",
4742 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
4743 $fix) {
4744 $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
4745 }
4746 }
4747
Andy Whitcroft653d4872007-06-23 17:16:34 -07004748# function brace can't be on same line, except for #defines of do while,
4749# or if closed on same line
Joe Perches5b579802018-08-21 21:57:33 -07004750 if ($perl_version_ok &&
Joe Perches2d453e32018-02-06 15:39:09 -08004751 $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
4752 $sline !~ /\#\s*define\b.*do\s*\{/ &&
4753 $sline !~ /}/) {
Joe Perches8d182472014-08-06 16:11:12 -07004754 if (ERROR("OPEN_BRACE",
Joe Perches2d453e32018-02-06 15:39:09 -08004755 "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
Joe Perches8d182472014-08-06 16:11:12 -07004756 $fix) {
4757 fix_delete_line($fixlinenr, $rawline);
4758 my $fixed_line = $rawline;
Dwaipayan Ray03f49352020-12-15 20:45:02 -08004759 $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
Joe Perches8d182472014-08-06 16:11:12 -07004760 my $line1 = $1;
4761 my $line2 = $2;
4762 fix_insert_line($fixlinenr, ltrim($line1));
4763 fix_insert_line($fixlinenr, "\+{");
4764 if ($line2 !~ /^\s*$/) {
4765 fix_insert_line($fixlinenr, "\+\t" . trim($line2));
4766 }
4767 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004768 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07004769
Andy Whitcroft8905a672007-11-28 16:21:06 -08004770# open braces for enum, union and struct go on the same line.
4771 if ($line =~ /^.\s*{/ &&
4772 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
Joe Perches8d182472014-08-06 16:11:12 -07004773 if (ERROR("OPEN_BRACE",
4774 "open brace '{' following $1 go on the same line\n" . $hereprev) &&
4775 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4776 fix_delete_line($fixlinenr - 1, $prevrawline);
4777 fix_delete_line($fixlinenr, $rawline);
4778 my $fixedline = rtrim($prevrawline) . " {";
4779 fix_insert_line($fixlinenr, $fixedline);
4780 $fixedline = $rawline;
Cyril Bur8d81ae02017-07-10 15:52:21 -07004781 $fixedline =~ s/^(.\s*)\{\s*/$1\t/;
Joe Perches8d182472014-08-06 16:11:12 -07004782 if ($fixedline !~ /^\+\s*$/) {
4783 fix_insert_line($fixlinenr, $fixedline);
4784 }
4785 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08004786 }
4787
Andy Whitcroft0c73b4e2010-10-26 14:23:15 -07004788# missing space after union, struct or enum definition
Joe Perches3705ce52013-07-03 15:05:31 -07004789 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
4790 if (WARN("SPACING",
4791 "missing space after $1 definition\n" . $herecurr) &&
4792 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07004793 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07004794 s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
4795 }
Andy Whitcroft0c73b4e2010-10-26 14:23:15 -07004796 }
4797
Joe Perches31070b52014-01-23 15:54:49 -08004798# Function pointer declarations
4799# check spacing between type, funcptr, and args
4800# canonical declaration is "type (*funcptr)(args...)"
Joe Perches91f72e92014-04-03 14:49:12 -07004801 if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
Joe Perches31070b52014-01-23 15:54:49 -08004802 my $declare = $1;
4803 my $pre_pointer_space = $2;
4804 my $post_pointer_space = $3;
4805 my $funcname = $4;
4806 my $post_funcname_space = $5;
4807 my $pre_args_space = $6;
4808
Joe Perches91f72e92014-04-03 14:49:12 -07004809# the $Declare variable will capture all spaces after the type
4810# so check it for a missing trailing missing space but pointer return types
4811# don't need a space so don't warn for those.
4812 my $post_declare_space = "";
4813 if ($declare =~ /(\s+)$/) {
4814 $post_declare_space = $1;
4815 $declare = rtrim($declare);
4816 }
4817 if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
Joe Perches31070b52014-01-23 15:54:49 -08004818 WARN("SPACING",
4819 "missing space after return type\n" . $herecurr);
Joe Perches91f72e92014-04-03 14:49:12 -07004820 $post_declare_space = " ";
Joe Perches31070b52014-01-23 15:54:49 -08004821 }
4822
4823# unnecessary space "type (*funcptr)(args...)"
Joe Perches91f72e92014-04-03 14:49:12 -07004824# This test is not currently implemented because these declarations are
4825# equivalent to
4826# int foo(int bar, ...)
4827# and this is form shouldn't/doesn't generate a checkpatch warning.
4828#
4829# elsif ($declare =~ /\s{2,}$/) {
4830# WARN("SPACING",
4831# "Multiple spaces after return type\n" . $herecurr);
4832# }
Joe Perches31070b52014-01-23 15:54:49 -08004833
4834# unnecessary space "type ( *funcptr)(args...)"
4835 if (defined $pre_pointer_space &&
4836 $pre_pointer_space =~ /^\s/) {
4837 WARN("SPACING",
4838 "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
4839 }
4840
4841# unnecessary space "type (* funcptr)(args...)"
4842 if (defined $post_pointer_space &&
4843 $post_pointer_space =~ /^\s/) {
4844 WARN("SPACING",
4845 "Unnecessary space before function pointer name\n" . $herecurr);
4846 }
4847
4848# unnecessary space "type (*funcptr )(args...)"
4849 if (defined $post_funcname_space &&
4850 $post_funcname_space =~ /^\s/) {
4851 WARN("SPACING",
4852 "Unnecessary space after function pointer name\n" . $herecurr);
4853 }
4854
4855# unnecessary space "type (*funcptr) (args...)"
4856 if (defined $pre_args_space &&
4857 $pre_args_space =~ /^\s/) {
4858 WARN("SPACING",
4859 "Unnecessary space before function pointer arguments\n" . $herecurr);
4860 }
4861
4862 if (show_type("SPACING") && $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07004863 $fixed[$fixlinenr] =~
Joe Perches91f72e92014-04-03 14:49:12 -07004864 s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
Joe Perches31070b52014-01-23 15:54:49 -08004865 }
4866 }
4867
Andy Whitcroft8d31cfc2008-07-23 21:29:02 -07004868# check for spacing round square brackets; allowed:
4869# 1. with a type on the left -- int [] a;
Andy Whitcroftfe2a7db2008-10-15 22:02:15 -07004870# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4871# 3. inside a curly brace -- = { [0...10] = 5 }
Andy Whitcroft8d31cfc2008-07-23 21:29:02 -07004872 while ($line =~ /(.*?\s)\[/g) {
4873 my ($where, $prefix) = ($-[1], $1);
4874 if ($prefix !~ /$Type\s+$/ &&
Andy Whitcroftfe2a7db2008-10-15 22:02:15 -07004875 ($where != 0 || $prefix !~ /^.\s+$/) &&
Heinrich Schuchardt38dca982018-04-10 16:34:14 -07004876 $prefix !~ /[{,:]\s+$/) {
Joe Perches3705ce52013-07-03 15:05:31 -07004877 if (ERROR("BRACKET_SPACE",
4878 "space prohibited before open square bracket '['\n" . $herecurr) &&
4879 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07004880 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07004881 s/^(\+.*?)\s+\[/$1\[/;
4882 }
Andy Whitcroft8d31cfc2008-07-23 21:29:02 -07004883 }
4884 }
4885
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07004886# check for spaces between functions and their parentheses.
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004887 while ($line =~ /($Ident)\s+\(/g) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004888 my $name = $1;
Andy Whitcroft773647a2008-03-28 14:15:58 -07004889 my $ctx_before = substr($line, 0, $-[1]);
4890 my $ctx = "$ctx_before$name";
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004891
4892 # Ignore those directives where spaces _are_ permitted.
Andy Whitcroft773647a2008-03-28 14:15:58 -07004893 if ($name =~ /^(?:
4894 if|for|while|switch|return|case|
4895 volatile|__volatile__|
4896 __attribute__|format|__extension__|
4897 asm|__asm__)$/x)
4898 {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004899 # cpp #define statements have non-optional spaces, ie
4900 # if there is a space between the name and the open
4901 # parenthesis it is simply not a parameter group.
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004902 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07004903
4904 # cpp #elif statement condition may start with a (
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07004905 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004906
4907 # If this whole things ends with a type its most
4908 # likely a typedef for a function.
Andy Whitcroft773647a2008-03-28 14:15:58 -07004909 } elsif ($ctx =~ /$Type$/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08004910
4911 } else {
Joe Perches3705ce52013-07-03 15:05:31 -07004912 if (WARN("SPACING",
4913 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
4914 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07004915 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07004916 s/\b$name\s+\(/$name\(/;
4917 }
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004918 }
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07004919 }
Eric Nelson9a4cad42012-05-31 16:26:09 -07004920
Andy Whitcroft653d4872007-06-23 17:16:34 -07004921# Check operator spacing.
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004922 if (!($line=~/\#\s*include/)) {
Joe Perches3705ce52013-07-03 15:05:31 -07004923 my $fixed_line = "";
4924 my $line_fixed = 0;
4925
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07004926 my $ops = qr{
4927 <<=|>>=|<=|>=|==|!=|
4928 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
4929 =>|->|<<|>>|<|>|=|!|~|
Andy Whitcroft1f65f942008-07-23 21:29:10 -07004930 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
Joe Perches84731622013-11-12 15:10:05 -08004931 \?:|\?|:
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07004932 }x;
Andy Whitcroftcf655042008-03-04 14:28:20 -08004933 my @elements = split(/($ops|;)/, $opline);
Joe Perches3705ce52013-07-03 15:05:31 -07004934
4935## print("element count: <" . $#elements . ">\n");
4936## foreach my $el (@elements) {
4937## print("el: <$el>\n");
4938## }
4939
4940 my @fix_elements = ();
Andy Whitcroft00df3442007-06-08 13:47:06 -07004941 my $off = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004942
Joe Perches3705ce52013-07-03 15:05:31 -07004943 foreach my $el (@elements) {
4944 push(@fix_elements, substr($rawline, $off, length($el)));
4945 $off += length($el);
4946 }
4947
4948 $off = 0;
4949
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004950 my $blank = copy_spacing($opline);
Joe Perchesb34c6482013-09-11 14:24:01 -07004951 my $last_after = -1;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004952
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004953 for (my $n = 0; $n < $#elements; $n += 2) {
Joe Perches3705ce52013-07-03 15:05:31 -07004954
4955 my $good = $fix_elements[$n] . $fix_elements[$n + 1];
4956
4957## print("n: <$n> good: <$good>\n");
4958
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004959 $off += length($elements[$n]);
4960
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004961 # Pick up the preceding and succeeding characters.
Andy Whitcroft773647a2008-03-28 14:15:58 -07004962 my $ca = substr($opline, 0, $off);
4963 my $cc = '';
4964 if (length($opline) >= ($off + length($elements[$n + 1]))) {
4965 $cc = substr($opline, $off + length($elements[$n + 1]));
4966 }
4967 my $cb = "$ca$;$cc";
4968
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004969 my $a = '';
4970 $a = 'V' if ($elements[$n] ne '');
4971 $a = 'W' if ($elements[$n] =~ /\s$/);
Andy Whitcroftcf655042008-03-04 14:28:20 -08004972 $a = 'C' if ($elements[$n] =~ /$;$/);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004973 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
4974 $a = 'O' if ($elements[$n] eq '');
Andy Whitcroft773647a2008-03-28 14:15:58 -07004975 $a = 'E' if ($ca =~ /^\s*$/);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004976
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004977 my $op = $elements[$n + 1];
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004978
4979 my $c = '';
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004980 if (defined $elements[$n + 2]) {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004981 $c = 'V' if ($elements[$n + 2] ne '');
4982 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
Andy Whitcroftcf655042008-03-04 14:28:20 -08004983 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004984 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
4985 $c = 'O' if ($elements[$n + 2] eq '');
Andy Whitcroft8b1b3372009-01-06 14:41:27 -08004986 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004987 } else {
4988 $c = 'E';
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004989 }
4990
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07004991 my $ctx = "${a}x${c}";
4992
4993 my $at = "(ctx:$ctx)";
4994
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004995 my $ptr = substr($blank, 0, $off) . "^";
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07004996 my $hereptr = "$hereline$ptr\n";
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07004997
Andy Whitcroft74048ed2008-07-23 21:29:10 -07004998 # Pull out the value of this operator.
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07004999 my $op_type = substr($curr_values, $off + 1, 1);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005000
Andy Whitcroft1f65f942008-07-23 21:29:10 -07005001 # Get the full operator variant.
5002 my $opv = $op . substr($curr_vars, $off, 1);
5003
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005004 # Ignore operators passed as parameters.
5005 if ($op_type ne 'V' &&
Sam Bobroffd7fe8062015-04-16 12:44:39 -07005006 $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005007
Andy Whitcroftcf655042008-03-04 14:28:20 -08005008# # Ignore comments
5009# } elsif ($op =~ /^$;+$/) {
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005010
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07005011 # ; should have either the end of line or a space or \ after it
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005012 } elsif ($op eq ';') {
Andy Whitcroftcf655042008-03-04 14:28:20 -08005013 if ($ctx !~ /.x[WEBC]/ &&
5014 $cc !~ /^\\/ && $cc !~ /^;/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005015 if (ERROR("SPACING",
5016 "space required after that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005017 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
Joe Perches3705ce52013-07-03 15:05:31 -07005018 $line_fixed = 1;
5019 }
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07005020 }
5021
5022 # // is a comment
5023 } elsif ($op eq '//') {
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005024
Joe Perchesb00e4812014-04-03 14:49:33 -07005025 # : when part of a bitfield
5026 } elsif ($opv eq ':B') {
5027 # skip the bitfield test for now
5028
Andy Whitcroft1f65f942008-07-23 21:29:10 -07005029 # No spaces for:
5030 # ->
Joe Perchesb00e4812014-04-03 14:49:33 -07005031 } elsif ($op eq '->') {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07005032 if ($ctx =~ /Wx.|.xW/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005033 if (ERROR("SPACING",
5034 "spaces prohibited around that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005035 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
Joe Perches3705ce52013-07-03 15:05:31 -07005036 if (defined $fix_elements[$n + 2]) {
5037 $fix_elements[$n + 2] =~ s/^\s+//;
5038 }
Joe Perchesb34c6482013-09-11 14:24:01 -07005039 $line_fixed = 1;
Joe Perches3705ce52013-07-03 15:05:31 -07005040 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005041 }
5042
Joe Perches23810972014-12-10 15:51:32 -08005043 # , must not have a space before and must have a space on the right.
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005044 } elsif ($op eq ',') {
Joe Perches23810972014-12-10 15:51:32 -08005045 my $rtrim_before = 0;
5046 my $space_after = 0;
5047 if ($ctx =~ /Wx./) {
5048 if (ERROR("SPACING",
5049 "space prohibited before that '$op' $at\n" . $hereptr)) {
5050 $line_fixed = 1;
5051 $rtrim_before = 1;
5052 }
5053 }
Andy Whitcroftcf655042008-03-04 14:28:20 -08005054 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005055 if (ERROR("SPACING",
5056 "space required after that '$op' $at\n" . $hereptr)) {
Joe Perches3705ce52013-07-03 15:05:31 -07005057 $line_fixed = 1;
Joe Perchesb34c6482013-09-11 14:24:01 -07005058 $last_after = $n;
Joe Perches23810972014-12-10 15:51:32 -08005059 $space_after = 1;
5060 }
5061 }
5062 if ($rtrim_before || $space_after) {
5063 if ($rtrim_before) {
5064 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
5065 } else {
5066 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
5067 }
5068 if ($space_after) {
5069 $good .= " ";
Joe Perches3705ce52013-07-03 15:05:31 -07005070 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005071 }
5072
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07005073 # '*' as part of a type definition -- reported already.
Andy Whitcroft74048ed2008-07-23 21:29:10 -07005074 } elsif ($opv eq '*_') {
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07005075 #warn "'*' is part of type\n";
5076
5077 # unary operators should have a space before and
5078 # none after. May be left adjacent to another
5079 # unary operator, or a cast
5080 } elsif ($op eq '!' || $op eq '~' ||
Andy Whitcroft74048ed2008-07-23 21:29:10 -07005081 $opv eq '*U' || $opv eq '-U' ||
Andy Whitcroft0d413862008-10-15 22:02:16 -07005082 $opv eq '&U' || $opv eq '&&U') {
Andy Whitcroftcf655042008-03-04 14:28:20 -08005083 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005084 if (ERROR("SPACING",
5085 "space required before that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005086 if ($n != $last_after + 2) {
5087 $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
5088 $line_fixed = 1;
5089 }
Joe Perches3705ce52013-07-03 15:05:31 -07005090 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005091 }
Andy Whitcrofta3340b32009-02-27 14:03:07 -08005092 if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07005093 # A unary '*' may be const
5094
5095 } elsif ($ctx =~ /.xW/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005096 if (ERROR("SPACING",
5097 "space prohibited after that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005098 $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
Joe Perches3705ce52013-07-03 15:05:31 -07005099 if (defined $fix_elements[$n + 2]) {
5100 $fix_elements[$n + 2] =~ s/^\s+//;
5101 }
Joe Perchesb34c6482013-09-11 14:24:01 -07005102 $line_fixed = 1;
Joe Perches3705ce52013-07-03 15:05:31 -07005103 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005104 }
5105
5106 # unary ++ and unary -- are allowed no space on one side.
5107 } elsif ($op eq '++' or $op eq '--') {
Andy Whitcroft773647a2008-03-28 14:15:58 -07005108 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005109 if (ERROR("SPACING",
5110 "space required one side of that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005111 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
Joe Perches3705ce52013-07-03 15:05:31 -07005112 $line_fixed = 1;
5113 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005114 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07005115 if ($ctx =~ /Wx[BE]/ ||
5116 ($ctx =~ /Wx./ && $cc =~ /^;/)) {
Joe Perches3705ce52013-07-03 15:05:31 -07005117 if (ERROR("SPACING",
5118 "space prohibited before that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005119 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
Joe Perches3705ce52013-07-03 15:05:31 -07005120 $line_fixed = 1;
5121 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07005122 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07005123 if ($ctx =~ /ExW/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005124 if (ERROR("SPACING",
5125 "space prohibited after that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005126 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
Joe Perches3705ce52013-07-03 15:05:31 -07005127 if (defined $fix_elements[$n + 2]) {
5128 $fix_elements[$n + 2] =~ s/^\s+//;
5129 }
Joe Perchesb34c6482013-09-11 14:24:01 -07005130 $line_fixed = 1;
Joe Perches3705ce52013-07-03 15:05:31 -07005131 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07005132 }
5133
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005134 # << and >> may either have or not have spaces both sides
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07005135 } elsif ($op eq '<<' or $op eq '>>' or
5136 $op eq '&' or $op eq '^' or $op eq '|' or
5137 $op eq '+' or $op eq '-' or
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08005138 $op eq '*' or $op eq '/' or
5139 $op eq '%')
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005140 {
Joe Perchesd2e025f2015-02-13 14:38:57 -08005141 if ($check) {
5142 if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5143 if (CHK("SPACING",
5144 "spaces preferred around that '$op' $at\n" . $hereptr)) {
5145 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5146 $fix_elements[$n + 2] =~ s/^\s+//;
5147 $line_fixed = 1;
5148 }
5149 } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
5150 if (CHK("SPACING",
5151 "space preferred before that '$op' $at\n" . $hereptr)) {
5152 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5153 $line_fixed = 1;
5154 }
5155 }
5156 } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005157 if (ERROR("SPACING",
5158 "need consistent spacing around '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005159 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5160 if (defined $fix_elements[$n + 2]) {
5161 $fix_elements[$n + 2] =~ s/^\s+//;
5162 }
Joe Perches3705ce52013-07-03 15:05:31 -07005163 $line_fixed = 1;
5164 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005165 }
5166
Andy Whitcroft1f65f942008-07-23 21:29:10 -07005167 # A colon needs no spaces before when it is
5168 # terminating a case value or a label.
5169 } elsif ($opv eq ':C' || $opv eq ':L') {
Chris Down263afd32021-02-25 17:22:04 -08005170 if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
Joe Perches3705ce52013-07-03 15:05:31 -07005171 if (ERROR("SPACING",
5172 "space prohibited before that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005173 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
Joe Perches3705ce52013-07-03 15:05:31 -07005174 $line_fixed = 1;
5175 }
Andy Whitcroft1f65f942008-07-23 21:29:10 -07005176 }
5177
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005178 # All the others need spaces both sides.
Andy Whitcroftcf655042008-03-04 14:28:20 -08005179 } elsif ($ctx !~ /[EWC]x[CWE]/) {
Andy Whitcroft1f65f942008-07-23 21:29:10 -07005180 my $ok = 0;
5181
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005182 # Ignore email addresses <foo@bar>
Andy Whitcroft1f65f942008-07-23 21:29:10 -07005183 if (($op eq '<' &&
5184 $cc =~ /^\S+\@\S+>/) ||
5185 ($op eq '>' &&
5186 $ca =~ /<\S+\@\S+$/))
5187 {
Antonio Borneo342d3d22020-04-06 20:11:01 -07005188 $ok = 1;
Andy Whitcroft1f65f942008-07-23 21:29:10 -07005189 }
5190
Joe Perchese0df7e12015-04-16 12:44:53 -07005191 # for asm volatile statements
5192 # ignore a colon with another
5193 # colon immediately before or after
5194 if (($op eq ':') &&
5195 ($ca =~ /:$/ || $cc =~ /^:/)) {
5196 $ok = 1;
5197 }
5198
Joe Perches84731622013-11-12 15:10:05 -08005199 # messages are ERROR, but ?: are CHK
Andy Whitcroft1f65f942008-07-23 21:29:10 -07005200 if ($ok == 0) {
Jean Delvare0675a8f2017-09-08 16:16:07 -07005201 my $msg_level = \&ERROR;
5202 $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
Joe Perches84731622013-11-12 15:10:05 -08005203
Jean Delvare0675a8f2017-09-08 16:16:07 -07005204 if (&{$msg_level}("SPACING",
5205 "spaces required around that '$op' $at\n" . $hereptr)) {
Joe Perchesb34c6482013-09-11 14:24:01 -07005206 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5207 if (defined $fix_elements[$n + 2]) {
5208 $fix_elements[$n + 2] =~ s/^\s+//;
5209 }
Joe Perches3705ce52013-07-03 15:05:31 -07005210 $line_fixed = 1;
5211 }
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005212 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005213 }
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07005214 $off += length($elements[$n + 1]);
Joe Perches3705ce52013-07-03 15:05:31 -07005215
5216## print("n: <$n> GOOD: <$good>\n");
5217
5218 $fixed_line = $fixed_line . $good;
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005219 }
Joe Perches3705ce52013-07-03 15:05:31 -07005220
5221 if (($#elements % 2) == 0) {
5222 $fixed_line = $fixed_line . $fix_elements[$#elements];
5223 }
5224
Joe Perches194f66f2014-08-06 16:11:03 -07005225 if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
5226 $fixed[$fixlinenr] = $fixed_line;
Joe Perches3705ce52013-07-03 15:05:31 -07005227 }
5228
5229
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005230 }
5231
Joe Perches786b6322013-07-03 15:05:32 -07005232# check for whitespace before a non-naked semicolon
Joe Perchesd2e248e2014-01-23 15:54:41 -08005233 if ($line =~ /^\+.*\S\s+;\s*$/) {
Joe Perches786b6322013-07-03 15:05:32 -07005234 if (WARN("SPACING",
5235 "space prohibited before semicolon\n" . $herecurr) &&
5236 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005237 1 while $fixed[$fixlinenr] =~
Joe Perches786b6322013-07-03 15:05:32 -07005238 s/^(\+.*\S)\s+;/$1;/;
5239 }
5240 }
5241
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07005242# check for multiple assignments
5243 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07005244 CHK("MULTIPLE_ASSIGNMENTS",
5245 "multiple assignments should be avoided\n" . $herecurr);
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07005246 }
5247
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005248## # check for multiple declarations, allowing for a function declaration
5249## # continuation.
5250## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
5251## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
5252##
5253## # Remove any bracketed sections to ensure we do not
Dwaipayan Raye73d2712020-12-15 20:44:56 -08005254## # falsely report the parameters of functions.
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005255## my $ln = $line;
5256## while ($ln =~ s/\([^\(\)]*\)//g) {
5257## }
5258## if ($ln =~ /,/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07005259## WARN("MULTIPLE_DECLARATION",
5260## "declaring multiple variables together should be avoided\n" . $herecurr);
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005261## }
5262## }
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07005263
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005264#need space before brace following if, while, etc
Geyslan G. Bem6b8c69e2016-03-15 14:58:09 -07005265 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
Michal Zylowski6ad724e2018-08-21 21:58:08 -07005266 $line =~ /\b(?:else|do)\{/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005267 if (ERROR("SPACING",
5268 "space required before the open brace '{'\n" . $herecurr) &&
5269 $fix) {
Michal Zylowski6ad724e2018-08-21 21:58:08 -07005270 $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
Joe Perches3705ce52013-07-03 15:05:31 -07005271 }
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07005272 }
5273
Joe Perchesc4a62ef2013-07-03 15:05:28 -07005274## # check for blank lines before declarations
5275## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
5276## $prevrawline =~ /^.\s*$/) {
5277## WARN("SPACING",
5278## "No blank lines before declarations\n" . $hereprev);
5279## }
5280##
5281
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07005282# closing brace should have a space following it when it has anything
5283# on the line
Joe Perches94fb9842019-09-25 16:46:47 -07005284 if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
Joe Perchesd5e616f2013-09-11 14:23:54 -07005285 if (ERROR("SPACING",
5286 "space required after that close brace '}'\n" . $herecurr) &&
5287 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005288 $fixed[$fixlinenr] =~
Joe Perchesd5e616f2013-09-11 14:23:54 -07005289 s/}((?!(?:,|;|\)))\S)/} $1/;
5290 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005291 }
5292
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005293# check spacing on square brackets
5294 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005295 if (ERROR("SPACING",
5296 "space prohibited after that open square bracket '['\n" . $herecurr) &&
5297 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005298 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07005299 s/\[\s+/\[/;
5300 }
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005301 }
5302 if ($line =~ /\s\]/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005303 if (ERROR("SPACING",
5304 "space prohibited before that close square bracket ']'\n" . $herecurr) &&
5305 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005306 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07005307 s/\s+\]/\]/;
5308 }
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005309 }
5310
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005311# check spacing on parentheses
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07005312 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
5313 $line !~ /for\s*\(\s+;/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005314 if (ERROR("SPACING",
5315 "space prohibited after that open parenthesis '('\n" . $herecurr) &&
5316 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005317 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07005318 s/\(\s+/\(/;
5319 }
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005320 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005321 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005322 $line !~ /for\s*\(.*;\s+\)/ &&
5323 $line !~ /:\s+\)/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005324 if (ERROR("SPACING",
5325 "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
5326 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005327 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07005328 s/\s+\)/\)/;
5329 }
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07005330 }
5331
Joe Perchese2826fd2014-08-06 16:10:48 -07005332# check unnecessary parentheses around addressof/dereference single $Lvals
5333# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
5334
5335 while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
Joe Perchesea4acbb2014-12-10 15:51:51 -08005336 my $var = $1;
5337 if (CHK("UNNECESSARY_PARENTHESES",
5338 "Unnecessary parentheses around $var\n" . $herecurr) &&
5339 $fix) {
5340 $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5341 }
5342 }
5343
5344# check for unnecessary parentheses around function pointer uses
5345# ie: (foo->bar)(); should be foo->bar();
5346# but not "if (foo->bar) (" to avoid some false positives
5347 if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5348 my $var = $2;
5349 if (CHK("UNNECESSARY_PARENTHESES",
5350 "Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5351 $fix) {
5352 my $var2 = deparenthesize($var);
5353 $var2 =~ s/\s//g;
5354 $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5355 }
5356 }
Joe Perchese2826fd2014-08-06 16:10:48 -07005357
Joe Perches63b7c732017-09-08 16:16:01 -07005358# check for unnecessary parentheses around comparisons in if uses
Joe Perchesa032aa42018-02-06 15:39:03 -08005359# when !drivers/staging or command-line uses --strict
5360 if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
Joe Perches5b579802018-08-21 21:57:33 -07005361 $perl_version_ok && defined($stat) &&
Joe Perches63b7c732017-09-08 16:16:01 -07005362 $stat =~ /(^.\s*if\s*($balanced_parens))/) {
5363 my $if_stat = $1;
5364 my $test = substr($2, 1, -1);
5365 my $herectx;
5366 while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
5367 my $match = $1;
5368 # avoid parentheses around potential macro args
5369 next if ($match =~ /^\s*\w+\s*$/);
5370 if (!defined($herectx)) {
5371 $herectx = $here . "\n";
5372 my $cnt = statement_rawlines($if_stat);
5373 for (my $n = 0; $n < $cnt; $n++) {
5374 my $rl = raw_line($linenr, $n);
5375 $herectx .= $rl . "\n";
5376 last if $rl =~ /^[ \+].*\{/;
5377 }
5378 }
5379 CHK("UNNECESSARY_PARENTHESES",
5380 "Unnecessary parentheses around '$match'\n" . $herectx);
5381 }
5382 }
5383
Joe Perches69078652021-06-30 18:56:22 -07005384# check that goto labels aren't indented (allow a single space indentation)
5385# and ignore bitfield definitions like foo:1
5386# Strictly, labels can have whitespace after the identifier and before the :
5387# but this is not allowed here as many ?: uses would appear to be labels
5388 if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
5389 $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
5390 $sline !~ /^.\s+default:/) {
Joe Perches3705ce52013-07-03 15:05:31 -07005391 if (WARN("INDENTED_LABEL",
5392 "labels should not be indented\n" . $herecurr) &&
5393 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005394 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07005395 s/^(.)\s+/$1/;
5396 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005397 }
5398
Joe Perches40873ab2020-10-15 20:11:56 -07005399# check if a statement with a comma should be two statements like:
5400# foo = bar(), /* comma should be semicolon */
5401# bar = baz();
5402 if (defined($stat) &&
5403 $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
5404 my $cnt = statement_rawlines($stat);
5405 my $herectx = get_stat_here($linenr, $cnt, $here);
5406 WARN("SUSPECT_COMMA_SEMICOLON",
5407 "Possible comma where semicolon could be used\n" . $herectx);
5408 }
5409
Joe Perches5b9553a2014-04-03 14:49:21 -07005410# return is not a function
Joe Perches507e5142013-11-12 15:10:13 -08005411 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005412 my $spacing = $1;
Joe Perches5b579802018-08-21 21:57:33 -07005413 if ($perl_version_ok &&
Joe Perches5b9553a2014-04-03 14:49:21 -07005414 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
5415 my $value = $1;
5416 $value = deparenthesize($value);
5417 if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
5418 ERROR("RETURN_PARENTHESES",
5419 "return is not a function, parentheses are not required\n" . $herecurr);
5420 }
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005421 } elsif ($spacing !~ /\s+/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07005422 ERROR("SPACING",
5423 "space required before the open parenthesis '('\n" . $herecurr);
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005424 }
5425 }
Joe Perches507e5142013-11-12 15:10:13 -08005426
Joe Perchesb43ae212014-06-23 13:22:07 -07005427# unnecessary return in a void function
5428# at end-of-function, with the previous line a single leading tab, then return;
5429# and the line before that not a goto label target like "out:"
5430 if ($sline =~ /^[ \+]}\s*$/ &&
5431 $prevline =~ /^\+\treturn\s*;\s*$/ &&
5432 $linenr >= 3 &&
5433 $lines[$linenr - 3] =~ /^[ +]/ &&
5434 $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
Joe Perches9819cf22014-06-04 16:12:09 -07005435 WARN("RETURN_VOID",
Joe Perchesb43ae212014-06-23 13:22:07 -07005436 "void function return statements are not generally useful\n" . $hereprev);
Dwaipayan Rayea7dbab2021-02-25 17:21:47 -08005437 }
Joe Perches9819cf22014-06-04 16:12:09 -07005438
Joe Perches189248d2014-01-23 15:54:47 -08005439# if statements using unnecessary parentheses - ie: if ((foo == bar))
Joe Perches5b579802018-08-21 21:57:33 -07005440 if ($perl_version_ok &&
Joe Perches189248d2014-01-23 15:54:47 -08005441 $line =~ /\bif\s*((?:\(\s*){2,})/) {
5442 my $openparens = $1;
5443 my $count = $openparens =~ tr@\(@\(@;
5444 my $msg = "";
5445 if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5446 my $comp = $4; #Not $1 because of $LvalOrFunc
5447 $msg = " - maybe == should be = ?" if ($comp eq "==");
5448 WARN("UNNECESSARY_PARENTHESES",
5449 "Unnecessary parentheses$msg\n" . $herecurr);
5450 }
5451 }
5452
Joe Perchesc5595fa2015-09-09 15:37:58 -07005453# comparisons with a constant or upper case identifier on the left
5454# avoid cases like "foo + BAR < baz"
5455# only fix matches surrounded by parentheses to avoid incorrect
5456# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
Joe Perches5b579802018-08-21 21:57:33 -07005457 if ($perl_version_ok &&
Joe Perchesc5595fa2015-09-09 15:37:58 -07005458 $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5459 my $lead = $1;
5460 my $const = $2;
5461 my $comp = $3;
5462 my $to = $4;
5463 my $newcomp = $comp;
Joe Perchesf39e1762016-05-20 17:04:02 -07005464 if ($lead !~ /(?:$Operators|\.)\s*$/ &&
Joe Perchesc5595fa2015-09-09 15:37:58 -07005465 $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5466 WARN("CONSTANT_COMPARISON",
5467 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5468 $fix) {
5469 if ($comp eq "<") {
5470 $newcomp = ">";
5471 } elsif ($comp eq "<=") {
5472 $newcomp = ">=";
5473 } elsif ($comp eq ">") {
5474 $newcomp = "<";
5475 } elsif ($comp eq ">=") {
5476 $newcomp = "<=";
5477 }
5478 $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5479 }
5480 }
5481
Joe Perchesf34e4a42015-04-16 12:44:19 -07005482# Return of what appears to be an errno should normally be negative
5483 if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
Andy Whitcroft53a3c442010-10-26 14:23:14 -07005484 my $name = $1;
Guenter Roeck46b85bf2021-06-30 18:56:25 -07005485 if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07005486 WARN("USE_NEGATIVE_ERRNO",
Joe Perchesf34e4a42015-04-16 12:44:19 -07005487 "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
Andy Whitcroft53a3c442010-10-26 14:23:14 -07005488 }
5489 }
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005490
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005491# Need a space before open parenthesis after if, while etc
Joe Perches3705ce52013-07-03 15:05:31 -07005492 if ($line =~ /\b(if|while|for|switch)\(/) {
5493 if (ERROR("SPACING",
5494 "space required before the open parenthesis '('\n" . $herecurr) &&
5495 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005496 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07005497 s/\b(if|while|for|switch)\(/$1 \(/;
5498 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005499 }
5500
Andy Whitcroftf5fe35d2008-07-23 21:29:03 -07005501# Check for illegal assignment in if conditional -- and check for trailing
5502# statements after the conditional.
Andy Whitcroft170d3a22008-10-15 22:02:30 -07005503 if ($line =~ /do\s*(?!{)/) {
Andy Whitcroft3e469cd2012-01-10 15:10:01 -08005504 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
5505 ctx_statement_block($linenr, $realcnt, 0)
5506 if (!defined $stat);
Andy Whitcroft170d3a22008-10-15 22:02:30 -07005507 my ($stat_next) = ctx_statement_block($line_nr_next,
5508 $remain_next, $off_next);
5509 $stat_next =~ s/\n./\n /g;
5510 ##print "stat<$stat> stat_next<$stat_next>\n";
5511
5512 if ($stat_next =~ /^\s*while\b/) {
5513 # If the statement carries leading newlines,
5514 # then count those as offsets.
5515 my ($whitespace) =
5516 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5517 my $offset =
5518 statement_rawlines($whitespace) - 1;
5519
5520 $suppress_whiletrailers{$line_nr_next +
5521 $offset} = 1;
5522 }
5523 }
5524 if (!defined $suppress_whiletrailers{$linenr} &&
Joe Perchesc11230f2013-11-21 14:31:57 -08005525 defined($stat) && defined($cond) &&
Andy Whitcroft170d3a22008-10-15 22:02:30 -07005526 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07005527 my ($s, $c) = ($stat, $cond);
Andy Whitcroft8905a672007-11-28 16:21:06 -08005528
Andy Whitcroftb53c8e12009-01-06 14:41:29 -08005529 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
Joe Perches65b64b32020-08-11 18:35:10 -07005530 if (ERROR("ASSIGN_IN_IF",
5531 "do not use assignment in if condition\n" . $herecurr) &&
5532 $fix && $perl_version_ok) {
5533 if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
5534 my $space = $1;
5535 my $not = $2;
5536 my $statement = $3;
5537 my $assigned = $4;
5538 my $test = $8;
5539 my $against = $9;
5540 my $brace = $15;
5541 fix_delete_line($fixlinenr, $rawline);
5542 fix_insert_line($fixlinenr, "$space$statement;");
5543 my $newline = "${space}if (";
5544 $newline .= '!' if defined($not);
5545 $newline .= '(' if (defined $not && defined($test) && defined($against));
5546 $newline .= "$assigned";
5547 $newline .= " $test $against" if (defined($test) && defined($against));
5548 $newline .= ')' if (defined $not && defined($test) && defined($against));
5549 $newline .= ')';
5550 $newline .= " {" if (defined($brace));
5551 fix_insert_line($fixlinenr + 1, $newline);
5552 }
5553 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08005554 }
5555
5556 # Find out what is on the end of the line after the
5557 # conditional.
Andy Whitcroft773647a2008-03-28 14:15:58 -07005558 substr($s, 0, length($c), '');
Andy Whitcroft8905a672007-11-28 16:21:06 -08005559 $s =~ s/\n.*//g;
Antonio Borneo342d3d22020-04-06 20:11:01 -07005560 $s =~ s/$;//g; # Remove any comments
Andy Whitcroft53210162008-07-23 21:29:03 -07005561 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
5562 $c !~ /}\s*while\s*/)
Andy Whitcroft773647a2008-03-28 14:15:58 -07005563 {
Andy Whitcroftbb44ad32008-10-15 22:02:34 -07005564 # Find out how long the conditional actually is.
5565 my @newlines = ($c =~ /\n/gs);
5566 my $cond_lines = 1 + $#newlines;
Hidetoshi Seto42bdf742010-03-05 13:43:50 -08005567 my $stat_real = '';
Andy Whitcroftbb44ad32008-10-15 22:02:34 -07005568
Hidetoshi Seto42bdf742010-03-05 13:43:50 -08005569 $stat_real = raw_line($linenr, $cond_lines)
5570 . "\n" if ($cond_lines);
Andy Whitcroftbb44ad32008-10-15 22:02:34 -07005571 if (defined($stat_real) && $cond_lines > 1) {
5572 $stat_real = "[...]\n$stat_real";
5573 }
5574
Joe Perches000d1cc12011-07-25 17:13:25 -07005575 ERROR("TRAILING_STATEMENTS",
5576 "trailing statements should be on next line\n" . $herecurr . $stat_real);
Andy Whitcroft8905a672007-11-28 16:21:06 -08005577 }
5578 }
5579
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005580# Check for bitwise tests written as boolean
5581 if ($line =~ /
5582 (?:
5583 (?:\[|\(|\&\&|\|\|)
5584 \s*0[xX][0-9]+\s*
5585 (?:\&\&|\|\|)
5586 |
5587 (?:\&\&|\|\|)
5588 \s*0[xX][0-9]+\s*
5589 (?:\&\&|\|\||\)|\])
5590 )/x)
5591 {
Joe Perches000d1cc12011-07-25 17:13:25 -07005592 WARN("HEXADECIMAL_BOOLEAN_TEST",
5593 "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005594 }
5595
Andy Whitcroft8905a672007-11-28 16:21:06 -08005596# if and else should not have general statements after it
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005597 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
5598 my $s = $1;
Antonio Borneo342d3d22020-04-06 20:11:01 -07005599 $s =~ s/$;//g; # Remove any comments
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005600 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07005601 ERROR("TRAILING_STATEMENTS",
5602 "trailing statements should be on next line\n" . $herecurr);
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005603 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005604 }
Andy Whitcroft39667782009-01-15 13:51:06 -08005605# if should not continue a brace
5606 if ($line =~ /}\s*if\b/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07005607 ERROR("TRAILING_STATEMENTS",
Rasmus Villemoes048b1232014-08-06 16:10:37 -07005608 "trailing statements should be on next line (or did you mean 'else if'?)\n" .
Andy Whitcroft39667782009-01-15 13:51:06 -08005609 $herecurr);
5610 }
Andy Whitcrofta1080bf2008-10-15 22:02:25 -07005611# case and default should not have general statements after them
5612 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5613 $line !~ /\G(?:
Andy Whitcroft3fef12d2008-10-15 22:02:36 -07005614 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
Andy Whitcrofta1080bf2008-10-15 22:02:25 -07005615 \s*return\s+
5616 )/xg)
5617 {
Joe Perches000d1cc12011-07-25 17:13:25 -07005618 ERROR("TRAILING_STATEMENTS",
5619 "trailing statements should be on next line\n" . $herecurr);
Andy Whitcrofta1080bf2008-10-15 22:02:25 -07005620 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005621
5622 # Check for }<nl>else {, these must be at the same
5623 # indent level to be relevant to each other.
Joe Perches8b8856f2014-08-06 16:11:14 -07005624 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
5625 $previndent == $indent) {
5626 if (ERROR("ELSE_AFTER_BRACE",
5627 "else should follow close brace '}'\n" . $hereprev) &&
5628 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5629 fix_delete_line($fixlinenr - 1, $prevrawline);
5630 fix_delete_line($fixlinenr, $rawline);
5631 my $fixedline = $prevrawline;
5632 $fixedline =~ s/}\s*$//;
5633 if ($fixedline !~ /^\+\s*$/) {
5634 fix_insert_line($fixlinenr, $fixedline);
5635 }
5636 $fixedline = $rawline;
5637 $fixedline =~ s/^(.\s*)else/$1} else/;
5638 fix_insert_line($fixlinenr, $fixedline);
5639 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005640 }
5641
Joe Perches8b8856f2014-08-06 16:11:14 -07005642 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5643 $previndent == $indent) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08005644 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5645
5646 # Find out what is on the end of the line after the
5647 # conditional.
Andy Whitcroft773647a2008-03-28 14:15:58 -07005648 substr($s, 0, length($c), '');
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08005649 $s =~ s/\n.*//g;
5650
5651 if ($s =~ /^\s*;/) {
Joe Perches8b8856f2014-08-06 16:11:14 -07005652 if (ERROR("WHILE_AFTER_BRACE",
5653 "while should follow close brace '}'\n" . $hereprev) &&
5654 $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5655 fix_delete_line($fixlinenr - 1, $prevrawline);
5656 fix_delete_line($fixlinenr, $rawline);
5657 my $fixedline = $prevrawline;
5658 my $trailing = $rawline;
5659 $trailing =~ s/^\+//;
5660 $trailing = trim($trailing);
5661 $fixedline =~ s/}\s*$/} $trailing/;
5662 fix_insert_line($fixlinenr, $fixedline);
5663 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08005664 }
5665 }
5666
Joe Perches95e2c602013-07-03 15:05:20 -07005667#Specific variable tests
Joe Perches323c1262012-12-17 16:02:07 -08005668 while ($line =~ m{($Constant|$Lval)}g) {
5669 my $var = $1;
Joe Perches95e2c602013-07-03 15:05:20 -07005670
Joe Perches95e2c602013-07-03 15:05:20 -07005671#CamelCase
Joe Perches807bd262013-07-03 15:05:22 -07005672 if ($var !~ /^$Constant$/ &&
Joe Perchesbe797942013-07-03 15:05:20 -07005673 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
Łukasz Stelmach4104a202020-12-15 20:44:27 -08005674#Ignore some autogenerated defines and enum values
5675 $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
Joe Perches22735ce2013-07-03 15:05:33 -07005676#Ignore Page<foo> variants
Joe Perches807bd262013-07-03 15:05:22 -07005677 $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
Joe Perchesd439e6a2019-12-04 16:52:06 -08005678#Ignore SI style variants like nS, mV and dB
5679#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5680 $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
Julius Wernerf5123572014-12-10 15:51:54 -08005681#Ignore some three character SI units explicitly, like MiB and KHz
5682 $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
Joe Perches7e781f62013-09-11 14:23:55 -07005683 while ($var =~ m{($Ident)}g) {
5684 my $word = $1;
5685 next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
Joe Perchesd8b07712013-11-12 15:10:06 -08005686 if ($check) {
5687 seed_camelcase_includes();
5688 if (!$file && !$camelcase_file_seeded) {
5689 seed_camelcase_file($realfile);
5690 $camelcase_file_seeded = 1;
5691 }
5692 }
Joe Perches7e781f62013-09-11 14:23:55 -07005693 if (!defined $camelcase{$word}) {
5694 $camelcase{$word} = 1;
5695 CHK("CAMELCASE",
5696 "Avoid CamelCase: <$word>\n" . $herecurr);
5697 }
Joe Perches34456862013-07-03 15:05:34 -07005698 }
Joe Perches323c1262012-12-17 16:02:07 -08005699 }
5700 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005701
5702#no spaces allowed after \ in define
Joe Perchesd5e616f2013-09-11 14:23:54 -07005703 if ($line =~ /\#\s*define.*\\\s+$/) {
5704 if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5705 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5706 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07005707 $fixed[$fixlinenr] =~ s/\s+$//;
Joe Perchesd5e616f2013-09-11 14:23:54 -07005708 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005709 }
5710
Fabian Frederick0e212e02015-04-16 12:44:25 -07005711# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
5712# itself <asm/foo.h> (uses RAW line)
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005713 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
Andy Whitcrofte09dec42008-10-15 22:02:20 -07005714 my $file = "$1.h";
5715 my $checkfile = "include/linux/$file";
5716 if (-f "$root/$checkfile" &&
5717 $realfile ne $checkfile &&
Wolfram Sang7840a942010-08-09 17:20:57 -07005718 $1 !~ /$allowed_asm_includes/)
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005719 {
Fabian Frederick0e212e02015-04-16 12:44:25 -07005720 my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
5721 if ($asminclude > 0) {
5722 if ($realfile =~ m{^arch/}) {
5723 CHK("ARCH_INCLUDE_LINUX",
5724 "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5725 } else {
5726 WARN("INCLUDE_LINUX",
5727 "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5728 }
Andy Whitcrofte09dec42008-10-15 22:02:20 -07005729 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005730 }
5731 }
5732
Andy Whitcroft653d4872007-06-23 17:16:34 -07005733# multi-statement macros should be enclosed in a do while loop, grab the
5734# first statement and ensure its the whole macro if its not enclosed
Andy Whitcroftcf655042008-03-04 14:28:20 -08005735# in a known good container
Andy Whitcroftb8f96a312008-07-23 21:29:07 -07005736 if ($realfile !~ m@/vmlinux.lds.h$@ &&
5737 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07005738 my $ln = $linenr;
5739 my $cnt = $realcnt;
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005740 my ($off, $dstat, $dcond, $rest);
5741 my $ctx = '';
Joe Perches08a28432014-10-13 15:51:55 -07005742 my $has_flow_statement = 0;
5743 my $has_arg_concat = 0;
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005744 ($dstat, $dcond, $ln, $cnt, $off) =
Andy Whitcroftf74bd192012-01-10 15:09:54 -08005745 ctx_statement_block($linenr, $realcnt, 0);
5746 $ctx = $dstat;
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005747 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
Andy Whitcrofta3bb97a2008-07-23 21:29:00 -07005748 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005749
Joe Perches08a28432014-10-13 15:51:55 -07005750 $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
Joe Perches62e15a62016-01-20 14:59:18 -08005751 $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
Joe Perches08a28432014-10-13 15:51:55 -07005752
Joe Perchesf59b64b2016-10-11 13:52:08 -07005753 $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5754 my $define_args = $1;
5755 my $define_stmt = $dstat;
5756 my @def_args = ();
5757
5758 if (defined $define_args && $define_args ne "") {
5759 $define_args = substr($define_args, 1, length($define_args) - 2);
5760 $define_args =~ s/\s*//g;
Joe Perches8c8c45c2018-08-21 21:57:43 -07005761 $define_args =~ s/\\\+?//g;
Joe Perchesf59b64b2016-10-11 13:52:08 -07005762 @def_args = split(",", $define_args);
5763 }
5764
Andy Whitcroft292f1a92008-07-23 21:29:11 -07005765 $dstat =~ s/$;//g;
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005766 $dstat =~ s/\\\n.//g;
5767 $dstat =~ s/^\s*//s;
5768 $dstat =~ s/\s*$//s;
5769
5770 # Flatten any parentheses and braces
Dwaipayan Ray2e44e802020-10-15 20:12:22 -07005771 while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
5772 $dstat =~ s/\{[^\{\}]*\}/1u/ ||
5773 $dstat =~ s/.\[[^\[\]]*\]/1u/)
Andy Whitcroftbf30d6e2008-10-15 22:02:33 -07005774 {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07005775 }
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07005776
Antonio Borneo342d3d22020-04-06 20:11:01 -07005777 # Flatten any obvious string concatenation.
Joe Perches33acb542015-06-25 15:02:54 -07005778 while ($dstat =~ s/($String)\s*$Ident/$1/ ||
5779 $dstat =~ s/$Ident\s*($String)/$1/)
Andy Whitcrofte45bab82012-03-23 15:02:18 -07005780 {
5781 }
5782
Joe Perches42e15292016-03-15 14:58:01 -07005783 # Make asm volatile uses seem like a generic function
5784 $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
5785
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005786 my $exceptions = qr{
5787 $Declare|
5788 module_param_named|
Kees Cooka0a0a7a2012-10-04 17:13:38 -07005789 MODULE_PARM_DESC|
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005790 DECLARE_PER_CPU|
5791 DEFINE_PER_CPU|
Andy Whitcroft383099f2009-01-06 14:41:18 -08005792 __typeof__\(|
Stefani Seibold22fd2d32010-03-05 13:43:52 -08005793 union|
5794 struct|
Andy Whitcroftea71a0a2009-09-21 17:04:38 -07005795 \.$Ident\s*=\s*|
Vladimir Zapolskiy6b10df42016-01-20 14:59:21 -08005796 ^\"|\"$|
5797 ^\[
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07005798 }x;
Andy Whitcroft5eaa20b2010-10-26 14:23:18 -07005799 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
Joe Perchesf59b64b2016-10-11 13:52:08 -07005800
5801 $ctx =~ s/\n*$//;
Joe Perchesf59b64b2016-10-11 13:52:08 -07005802 my $stmt_cnt = statement_rawlines($ctx);
Tobin C. Hardinge3d95a22018-04-10 16:33:27 -07005803 my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
Joe Perchesf59b64b2016-10-11 13:52:08 -07005804
Andy Whitcroftf74bd192012-01-10 15:09:54 -08005805 if ($dstat ne '' &&
5806 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
5807 $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
Joe Perches3cc4b1c2013-07-03 15:05:27 -07005808 $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
Joe Perches356fd392014-08-06 16:10:31 -07005809 $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants
Andy Whitcroftf74bd192012-01-10 15:09:54 -08005810 $dstat !~ /$exceptions/ &&
5811 $dstat !~ /^\.$Ident\s*=/ && # .foo =
Joe Perchese942e2c2013-04-17 15:58:26 -07005812 $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
Andy Whitcroft72f115f2012-01-10 15:10:06 -08005813 $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
Dwaipayan Ray2e44e802020-10-15 20:12:22 -07005814 $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...}
Andy Whitcroftf74bd192012-01-10 15:09:54 -08005815 $dstat !~ /^for\s*$Constant$/ && # for (...)
5816 $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
5817 $dstat !~ /^do\s*{/ && # do {...
Eddie Kovsky4e5d56b2015-09-09 15:37:52 -07005818 $dstat !~ /^\(\{/ && # ({...
Joe Perchesf95a7e62013-09-11 14:24:00 -07005819 $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
Andy Whitcroftf74bd192012-01-10 15:09:54 -08005820 {
Joe Perchese7955562017-05-08 15:55:48 -07005821 if ($dstat =~ /^\s*if\b/) {
5822 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5823 "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5824 } elsif ($dstat =~ /;/) {
Andy Whitcroftf74bd192012-01-10 15:09:54 -08005825 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5826 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5827 } else {
Joe Perches000d1cc12011-07-25 17:13:25 -07005828 ERROR("COMPLEX_MACRO",
Andrew Morton388982b2014-10-13 15:51:40 -07005829 "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07005830 }
Joe Perchesf59b64b2016-10-11 13:52:08 -07005831
5832 }
Joe Perches52076492016-10-11 13:52:14 -07005833
5834 # Make $define_stmt single line, comment-free, etc
5835 my @stmt_array = split('\n', $define_stmt);
5836 my $first = 1;
5837 $define_stmt = "";
5838 foreach my $l (@stmt_array) {
5839 $l =~ s/\\$//;
5840 if ($first) {
5841 $define_stmt = $l;
5842 $first = 0;
5843 } elsif ($l =~ /^[\+ ]/) {
5844 $define_stmt .= substr($l, 1);
5845 }
5846 }
5847 $define_stmt =~ s/$;//g;
5848 $define_stmt =~ s/\s+/ /g;
5849 $define_stmt = trim($define_stmt);
5850
Joe Perchesf59b64b2016-10-11 13:52:08 -07005851# check if any macro arguments are reused (ignore '...' and 'type')
5852 foreach my $arg (@def_args) {
5853 next if ($arg =~ /\.\.\./);
Joe Perches9192d412016-10-11 13:52:11 -07005854 next if ($arg =~ /^type$/i);
Joe Perches7fe528a22017-07-10 15:52:27 -07005855 my $tmp_stmt = $define_stmt;
Vincent Mailhol7b844342021-05-06 18:03:58 -07005856 $tmp_stmt =~ s/\b(__must_be_array|offsetof|sizeof|sizeof_field|__stringify|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
Joe Perches7fe528a22017-07-10 15:52:27 -07005857 $tmp_stmt =~ s/\#+\s*$arg\b//g;
5858 $tmp_stmt =~ s/\b$arg\s*\#\#//g;
Joe Perchesd41362e2018-05-25 14:48:04 -07005859 my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
Joe Perchesf59b64b2016-10-11 13:52:08 -07005860 if ($use_cnt > 1) {
5861 CHK("MACRO_ARG_REUSE",
5862 "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
Joe Perches9192d412016-10-11 13:52:11 -07005863 }
5864# check if any macro arguments may have other precedence issues
Joe Perches7fe528a22017-07-10 15:52:27 -07005865 if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
Joe Perches9192d412016-10-11 13:52:11 -07005866 ((defined($1) && $1 ne ',') ||
5867 (defined($2) && $2 ne ','))) {
5868 CHK("MACRO_ARG_PRECEDENCE",
5869 "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
Joe Perchesf59b64b2016-10-11 13:52:08 -07005870 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07005871 }
Joe Perches5023d342012-12-17 16:01:47 -08005872
Joe Perches08a28432014-10-13 15:51:55 -07005873# check for macros with flow control, but without ## concatenation
5874# ## concatenation is commonly a macro that defines a function so ignore those
5875 if ($has_flow_statement && !$has_arg_concat) {
Joe Perches08a28432014-10-13 15:51:55 -07005876 my $cnt = statement_rawlines($ctx);
Tobin C. Hardinge3d95a22018-04-10 16:33:27 -07005877 my $herectx = get_stat_here($linenr, $cnt, $here);
Joe Perches08a28432014-10-13 15:51:55 -07005878
Joe Perches08a28432014-10-13 15:51:55 -07005879 WARN("MACRO_WITH_FLOW_CONTROL",
5880 "Macros with flow control statements should be avoided\n" . "$herectx");
5881 }
5882
Joe Perches481eb482012-12-17 16:01:56 -08005883# check for line continuations outside of #defines, preprocessor #, and asm
Joe Perches5023d342012-12-17 16:01:47 -08005884
5885 } else {
5886 if ($prevline !~ /^..*\\$/ &&
Joe Perches481eb482012-12-17 16:01:56 -08005887 $line !~ /^\+\s*\#.*\\$/ && # preprocessor
5888 $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
Joe Perches5023d342012-12-17 16:01:47 -08005889 $line =~ /^\+.*\\$/) {
5890 WARN("LINE_CONTINUATIONS",
5891 "Avoid unnecessary line continuations\n" . $herecurr);
5892 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07005893 }
5894
Joe Perchesb13edf72012-07-30 14:41:24 -07005895# do {} while (0) macro tests:
5896# single-statement macros do not need to be enclosed in do while (0) loop,
5897# macro should not end with a semicolon
Joe Perches5b579802018-08-21 21:57:33 -07005898 if ($perl_version_ok &&
Joe Perchesb13edf72012-07-30 14:41:24 -07005899 $realfile !~ m@/vmlinux.lds.h$@ &&
5900 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5901 my $ln = $linenr;
5902 my $cnt = $realcnt;
5903 my ($off, $dstat, $dcond, $rest);
5904 my $ctx = '';
5905 ($dstat, $dcond, $ln, $cnt, $off) =
5906 ctx_statement_block($linenr, $realcnt, 0);
5907 $ctx = $dstat;
5908
5909 $dstat =~ s/\\\n.//g;
Joe Perches1b36b202015-02-13 14:38:32 -08005910 $dstat =~ s/$;/ /g;
Joe Perchesb13edf72012-07-30 14:41:24 -07005911
5912 if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5913 my $stmts = $2;
5914 my $semis = $3;
5915
5916 $ctx =~ s/\n*$//;
5917 my $cnt = statement_rawlines($ctx);
Tobin C. Hardinge3d95a22018-04-10 16:33:27 -07005918 my $herectx = get_stat_here($linenr, $cnt, $here);
Joe Perchesb13edf72012-07-30 14:41:24 -07005919
Joe Perchesac8e97f2012-08-21 16:15:53 -07005920 if (($stmts =~ tr/;/;/) == 1 &&
5921 $stmts !~ /^\s*(if|while|for|switch)\b/) {
Joe Perchesb13edf72012-07-30 14:41:24 -07005922 WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5923 "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5924 }
5925 if (defined $semis && $semis ne "") {
5926 WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5927 "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5928 }
Joe Perchesf5ef95b2014-06-04 16:12:06 -07005929 } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5930 $ctx =~ s/\n*$//;
5931 my $cnt = statement_rawlines($ctx);
Tobin C. Hardinge3d95a22018-04-10 16:33:27 -07005932 my $herectx = get_stat_here($linenr, $cnt, $here);
Joe Perchesf5ef95b2014-06-04 16:12:06 -07005933
5934 WARN("TRAILING_SEMICOLON",
5935 "macros should not use a trailing semicolon\n" . "$herectx");
Joe Perchesb13edf72012-07-30 14:41:24 -07005936 }
5937 }
5938
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07005939# check for redundant bracing round if etc
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005940 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
5941 my ($level, $endln, @chunks) =
Andy Whitcroftcf655042008-03-04 14:28:20 -08005942 ctx_statement_full($linenr, $realcnt, 1);
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005943 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
Andy Whitcroftcf655042008-03-04 14:28:20 -08005944 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5945 if ($#chunks > 0 && $level == 0) {
Joe Perchesaad4f612012-03-23 15:02:19 -07005946 my @allowed = ();
5947 my $allow = 0;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005948 my $seen = 0;
Andy Whitcroft773647a2008-03-28 14:15:58 -07005949 my $herectx = $here . "\n";
Andy Whitcroftcf655042008-03-04 14:28:20 -08005950 my $ln = $linenr - 1;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005951 for my $chunk (@chunks) {
5952 my ($cond, $block) = @{$chunk};
5953
Andy Whitcroft773647a2008-03-28 14:15:58 -07005954 # If the condition carries leading newlines, then count those as offsets.
5955 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5956 my $offset = statement_rawlines($whitespace) - 1;
5957
Joe Perchesaad4f612012-03-23 15:02:19 -07005958 $allowed[$allow] = 0;
Andy Whitcroft773647a2008-03-28 14:15:58 -07005959 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5960
5961 # We have looked at and allowed this specific line.
5962 $suppress_ifbraces{$ln + $offset} = 1;
5963
5964 $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
Andy Whitcroftcf655042008-03-04 14:28:20 -08005965 $ln += statement_rawlines($block) - 1;
5966
Andy Whitcroft773647a2008-03-28 14:15:58 -07005967 substr($block, 0, length($cond), '');
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005968
5969 $seen++ if ($block =~ /^\s*{/);
5970
Joe Perchesaad4f612012-03-23 15:02:19 -07005971 #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
Andy Whitcroftcf655042008-03-04 14:28:20 -08005972 if (statement_lines($cond) > 1) {
5973 #print "APW: ALLOWED: cond<$cond>\n";
Joe Perchesaad4f612012-03-23 15:02:19 -07005974 $allowed[$allow] = 1;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005975 }
5976 if ($block =~/\b(?:if|for|while)\b/) {
Andy Whitcroftcf655042008-03-04 14:28:20 -08005977 #print "APW: ALLOWED: block<$block>\n";
Joe Perchesaad4f612012-03-23 15:02:19 -07005978 $allowed[$allow] = 1;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005979 }
Andy Whitcroftcf655042008-03-04 14:28:20 -08005980 if (statement_block_size($block) > 1) {
5981 #print "APW: ALLOWED: lines block<$block>\n";
Joe Perchesaad4f612012-03-23 15:02:19 -07005982 $allowed[$allow] = 1;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005983 }
Joe Perchesaad4f612012-03-23 15:02:19 -07005984 $allow++;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005985 }
Joe Perchesaad4f612012-03-23 15:02:19 -07005986 if ($seen) {
5987 my $sum_allowed = 0;
5988 foreach (@allowed) {
5989 $sum_allowed += $_;
5990 }
5991 if ($sum_allowed == 0) {
5992 WARN("BRACES",
5993 "braces {} are not necessary for any arm of this statement\n" . $herectx);
5994 } elsif ($sum_allowed != $allow &&
5995 $seen != $allow) {
5996 CHK("BRACES",
5997 "braces {} should be used on all arms of this statement\n" . $herectx);
5998 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08005999 }
6000 }
6001 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07006002 if (!defined $suppress_ifbraces{$linenr - 1} &&
Andy Whitcroft13214ad2008-02-08 04:22:03 -08006003 $line =~ /\b(if|while|for|else)\b/) {
Andy Whitcroftcf655042008-03-04 14:28:20 -08006004 my $allowed = 0;
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07006005
Andy Whitcroftcf655042008-03-04 14:28:20 -08006006 # Check the pre-context.
6007 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
6008 #print "APW: ALLOWED: pre<$1>\n";
6009 $allowed = 1;
6010 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07006011
6012 my ($level, $endln, @chunks) =
6013 ctx_statement_full($linenr, $realcnt, $-[0]);
6014
Andy Whitcroftcf655042008-03-04 14:28:20 -08006015 # Check the condition.
6016 my ($cond, $block) = @{$chunks[0]};
Andy Whitcroft773647a2008-03-28 14:15:58 -07006017 #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
Andy Whitcroftcf655042008-03-04 14:28:20 -08006018 if (defined $cond) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07006019 substr($block, 0, length($cond), '');
Andy Whitcroftcf655042008-03-04 14:28:20 -08006020 }
6021 if (statement_lines($cond) > 1) {
6022 #print "APW: ALLOWED: cond<$cond>\n";
6023 $allowed = 1;
6024 }
6025 if ($block =~/\b(?:if|for|while)\b/) {
6026 #print "APW: ALLOWED: block<$block>\n";
6027 $allowed = 1;
6028 }
6029 if (statement_block_size($block) > 1) {
6030 #print "APW: ALLOWED: lines block<$block>\n";
6031 $allowed = 1;
6032 }
6033 # Check the post-context.
6034 if (defined $chunks[1]) {
6035 my ($cond, $block) = @{$chunks[1]};
6036 if (defined $cond) {
Andy Whitcroft773647a2008-03-28 14:15:58 -07006037 substr($block, 0, length($cond), '');
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07006038 }
Andy Whitcroftcf655042008-03-04 14:28:20 -08006039 if ($block =~ /^\s*\{/) {
6040 #print "APW: ALLOWED: chunk-1 block<$block>\n";
6041 $allowed = 1;
6042 }
6043 }
6044 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
Andy Whitcroftf0556632008-10-15 22:02:23 -07006045 my $cnt = statement_rawlines($block);
Tobin C. Hardinge3d95a22018-04-10 16:33:27 -07006046 my $herectx = get_stat_here($linenr, $cnt, $here);
Andy Whitcroftcf655042008-03-04 14:28:20 -08006047
Joe Perches000d1cc12011-07-25 17:13:25 -07006048 WARN("BRACES",
6049 "braces {} are not necessary for single statement blocks\n" . $herectx);
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07006050 }
6051 }
6052
Joe Perchese4c5bab2017-02-24 15:01:41 -08006053# check for single line unbalanced braces
Sven Eckelmann95330472017-02-24 15:01:43 -08006054 if ($sline =~ /^.\s*\}\s*else\s*$/ ||
6055 $sline =~ /^.\s*else\s*\{\s*$/) {
Joe Perchese4c5bab2017-02-24 15:01:41 -08006056 CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
6057 }
6058
Joe Perches0979ae62012-12-17 16:01:59 -08006059# check for unnecessary blank lines around braces
Joe Perches77b9a532013-07-03 15:05:29 -07006060 if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
Joe Perchesf8e58212015-02-13 14:38:46 -08006061 if (CHK("BRACES",
6062 "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
6063 $fix && $prevrawline =~ /^\+/) {
6064 fix_delete_line($fixlinenr - 1, $prevrawline);
6065 }
Joe Perches0979ae62012-12-17 16:01:59 -08006066 }
Joe Perches77b9a532013-07-03 15:05:29 -07006067 if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
Joe Perchesf8e58212015-02-13 14:38:46 -08006068 if (CHK("BRACES",
6069 "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
6070 $fix) {
6071 fix_delete_line($fixlinenr, $rawline);
6072 }
Joe Perches0979ae62012-12-17 16:01:59 -08006073 }
6074
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006075# no volatiles please
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07006076 my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
6077 if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006078 WARN("VOLATILE",
Mauro Carvalho Chehab8c27ceff32016-10-18 10:12:27 -02006079 "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006080 }
6081
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006082# Check for user-visible strings broken across lines, which breaks the ability
6083# to grep for the string. Make exceptions when the previous string ends in a
6084# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
6085# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
Joe Perches33acb542015-06-25 15:02:54 -07006086 if ($line =~ /^\+\s*$String/ &&
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006087 $prevline =~ /"\s*$/ &&
6088 $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
6089 if (WARN("SPLIT_STRING",
6090 "quoted string split across lines\n" . $hereprev) &&
6091 $fix &&
6092 $prevrawline =~ /^\+.*"\s*$/ &&
6093 $last_coalesced_string_linenr != $linenr - 1) {
6094 my $extracted_string = get_quoted_string($line, $rawline);
6095 my $comma_close = "";
6096 if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
6097 $comma_close = $1;
6098 }
6099
6100 fix_delete_line($fixlinenr - 1, $prevrawline);
6101 fix_delete_line($fixlinenr, $rawline);
6102 my $fixedline = $prevrawline;
6103 $fixedline =~ s/"\s*$//;
6104 $fixedline .= substr($extracted_string, 1) . trim($comma_close);
6105 fix_insert_line($fixlinenr - 1, $fixedline);
6106 $fixedline = $rawline;
6107 $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
6108 if ($fixedline !~ /\+\s*$/) {
6109 fix_insert_line($fixlinenr, $fixedline);
6110 }
6111 $last_coalesced_string_linenr = $linenr;
6112 }
6113 }
6114
6115# check for missing a space in a string concatenation
6116 if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
6117 WARN('MISSING_SPACE',
6118 "break quoted strings at a space character\n" . $hereprev);
6119 }
6120
Joe Perchese4b7d302017-05-08 15:55:51 -07006121# check for an embedded function name in a string when the function is known
6122# This does not work very well for -f --file checking as it depends on patch
6123# context providing the function name or a single line form for in-file
6124# function declarations
Joe Perches77cb8542017-02-24 15:01:28 -08006125 if ($line =~ /^\+.*$String/ &&
6126 defined($context_function) &&
Joe Perchese4b7d302017-05-08 15:55:51 -07006127 get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
6128 length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
Joe Perches77cb8542017-02-24 15:01:28 -08006129 WARN("EMBEDDED_FUNCTION_NAME",
Joe Perchese4b7d302017-05-08 15:55:51 -07006130 "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
Joe Perches77cb8542017-02-24 15:01:28 -08006131 }
6132
Joe Perchesadb2da82021-02-25 17:21:50 -08006133# check for unnecessary function tracing like uses
6134# This does not use $logFunctions because there are many instances like
6135# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6136 if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6137 if (WARN("TRACING_LOGGING",
6138 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
6139 $fix) {
6140 fix_delete_line($fixlinenr, $rawline);
6141 }
6142 }
6143
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006144# check for spaces before a quoted newline
6145 if ($rawline =~ /^.*\".*\s\\n/) {
6146 if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
6147 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
6148 $fix) {
6149 $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
6150 }
6151
6152 }
6153
Joe Perchesf17dba42014-10-13 15:51:51 -07006154# concatenated string without spaces between elements
Joe Perchesd2af5aa2021-09-07 19:59:51 -07006155 if ($line =~ /$String[A-Z_]/ ||
6156 ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
Joe Perches79682c02018-08-21 21:57:29 -07006157 if (CHK("CONCATENATED_STRING",
6158 "Concatenated strings should use spaces between elements\n" . $herecurr) &&
6159 $fix) {
6160 while ($line =~ /($String)/g) {
6161 my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
6162 $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
6163 $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
6164 }
6165 }
Joe Perchesf17dba42014-10-13 15:51:51 -07006166 }
6167
Joe Perches90ad30e2014-12-10 15:51:59 -08006168# uncoalesced string fragments
Joe Perchesd2af5aa2021-09-07 19:59:51 -07006169 if ($line =~ /$String\s*[Lu]?"/) {
Joe Perches79682c02018-08-21 21:57:29 -07006170 if (WARN("STRING_FRAGMENTS",
6171 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
6172 $fix) {
6173 while ($line =~ /($String)(?=\s*")/g) {
6174 my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
6175 $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
6176 }
6177 }
Joe Perches90ad30e2014-12-10 15:51:59 -08006178 }
6179
Alexey Dobriyan522b8372017-02-27 14:30:05 -08006180# check for non-standard and hex prefixed decimal printf formats
6181 my $show_L = 1; #don't show the same defect twice
6182 my $show_Z = 1;
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006183 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
Alexey Dobriyan522b8372017-02-27 14:30:05 -08006184 my $string = substr($rawline, $-[1], $+[1] - $-[1]);
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006185 $string =~ s/%%/__/g;
Alexey Dobriyan522b8372017-02-27 14:30:05 -08006186 # check for %L
6187 if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006188 WARN("PRINTF_L",
Alexey Dobriyan522b8372017-02-27 14:30:05 -08006189 "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
6190 $show_L = 0;
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006191 }
Alexey Dobriyan522b8372017-02-27 14:30:05 -08006192 # check for %Z
6193 if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6194 WARN("PRINTF_Z",
6195 "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6196 $show_Z = 0;
6197 }
6198 # check for 0x<decimal>
6199 if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6200 ERROR("PRINTF_0XDECIMAL",
Joe Perches6e300752015-09-09 15:37:47 -07006201 "Prefixing 0x with decimal output is defective\n" . $herecurr);
6202 }
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006203 }
6204
6205# check for line continuations in quoted strings with odd counts of "
Joe Perches3f7f3352018-02-06 15:38:52 -08006206 if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
Joe Perches5e4f6ba2014-12-10 15:52:05 -08006207 WARN("LINE_CONTINUATIONS",
6208 "Avoid line continuations in quoted strings\n" . $herecurr);
6209 }
6210
Andy Whitcroft00df3442007-06-08 13:47:06 -07006211# warn about #if 0
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07006212 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
Prakruthi Deepak Heragu60f89012018-08-21 21:57:57 -07006213 WARN("IF_0",
6214 "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
6215 }
6216
6217# warn about #if 1
6218 if ($line =~ /^.\s*\#\s*if\s+1\b/) {
6219 WARN("IF_1",
6220 "Consider removing the #if 1 and its #endif\n" . $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006221 }
6222
Andy Whitcroft03df4b52012-12-17 16:01:52 -08006223# check for needless "if (<foo>) fn(<foo>)" uses
6224 if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
Joe Perches100425d2015-09-09 15:37:36 -07006225 my $tested = quotemeta($1);
6226 my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
6227 if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
6228 my $func = $1;
6229 if (WARN('NEEDLESS_IF',
6230 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
6231 $fix) {
6232 my $do_fix = 1;
6233 my $leading_tabs = "";
6234 my $new_leading_tabs = "";
6235 if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
6236 $leading_tabs = $1;
6237 } else {
6238 $do_fix = 0;
6239 }
6240 if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6241 $new_leading_tabs = $1;
6242 if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6243 $do_fix = 0;
6244 }
6245 } else {
6246 $do_fix = 0;
6247 }
6248 if ($do_fix) {
6249 fix_delete_line($fixlinenr - 1, $prevrawline);
6250 $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6251 }
6252 }
Greg Kroah-Hartman4c432a82008-07-23 21:29:04 -07006253 }
6254 }
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07006255
Joe Perchesebfdc402014-08-06 16:10:27 -07006256# check for unnecessary "Out of Memory" messages
6257 if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6258 $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6259 (defined $1 || defined $3) &&
6260 $linenr > 3) {
6261 my $testval = $2;
6262 my $testline = $lines[$linenr - 3];
6263
6264 my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6265# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6266
Joe Perchese29a70f2019-03-07 16:28:35 -08006267 if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
6268 $s !~ /\b__GFP_NOWARN\b/ ) {
Joe Perchesebfdc402014-08-06 16:10:27 -07006269 WARN("OOM_MESSAGE",
6270 "Possible unnecessary 'out of memory' message\n" . $hereprev);
6271 }
6272 }
6273
Joe Perchesf78d98f2014-10-13 15:52:01 -07006274# check for logging functions with KERN_<LEVEL>
Paolo Bonzinidcaf1122015-02-13 14:38:26 -08006275 if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
Joe Perchesf78d98f2014-10-13 15:52:01 -07006276 $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6277 my $level = $1;
6278 if (WARN("UNNECESSARY_KERN_LEVEL",
6279 "Possible unnecessary $level\n" . $herecurr) &&
6280 $fix) {
6281 $fixed[$fixlinenr] =~ s/\s*$level\s*//;
6282 }
6283 }
6284
Joe Perches45c55e92017-02-24 15:01:31 -08006285# check for logging continuations
6286 if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
6287 WARN("LOGGING_CONTINUATION",
6288 "Avoid logging continuation uses where feasible\n" . $herecurr);
6289 }
6290
Dwaipayan Ray70eb2272020-12-15 20:45:15 -08006291# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
6292 if (defined $stat &&
6293 $line =~ /\b$logFunctions\s*\(/ &&
6294 index($stat, '"') >= 0) {
6295 my $lc = $stat =~ tr@\n@@;
6296 $lc = $lc + $linenr;
6297 my $stat_real = get_stat_real($linenr, $lc);
6298 pos($stat_real) = index($stat_real, '"');
6299 while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
6300 my $pspec = $1;
6301 my $h = $2;
6302 my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
6303 if (WARN("UNNECESSARY_MODIFIER",
6304 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
6305 $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
6306 my $nspec = $pspec;
6307 $nspec =~ s/h//g;
6308 $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
6309 }
6310 }
6311 }
6312
Joe Perchesabb08a52014-12-10 15:51:46 -08006313# check for mask then right shift without a parentheses
Joe Perches5b579802018-08-21 21:57:33 -07006314 if ($perl_version_ok &&
Joe Perchesabb08a52014-12-10 15:51:46 -08006315 $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
6316 $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
6317 WARN("MASK_THEN_SHIFT",
6318 "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
6319 }
6320
Joe Perchesb75ac612014-12-10 15:52:02 -08006321# check for pointer comparisons to NULL
Joe Perches5b579802018-08-21 21:57:33 -07006322 if ($perl_version_ok) {
Joe Perchesb75ac612014-12-10 15:52:02 -08006323 while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
6324 my $val = $1;
6325 my $equal = "!";
6326 $equal = "" if ($4 eq "!=");
6327 if (CHK("COMPARISON_TO_NULL",
6328 "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6329 $fix) {
6330 $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6331 }
6332 }
6333 }
6334
Joe Perches8716de32013-09-11 14:24:05 -07006335# check for bad placement of section $InitAttribute (e.g.: __initdata)
6336 if ($line =~ /(\b$InitAttribute\b)/) {
6337 my $attr = $1;
6338 if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
6339 my $ptr = $1;
6340 my $var = $2;
6341 if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
6342 ERROR("MISPLACED_INIT",
6343 "$attr should be placed after $var\n" . $herecurr)) ||
6344 ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
6345 WARN("MISPLACED_INIT",
6346 "$attr should be placed after $var\n" . $herecurr))) &&
6347 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006348 $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;
Joe Perches8716de32013-09-11 14:24:05 -07006349 }
6350 }
6351 }
6352
Joe Perchese970b8842013-11-12 15:10:10 -08006353# check for $InitAttributeData (ie: __initdata) with const
6354 if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
6355 my $attr = $1;
6356 $attr =~ /($InitAttributePrefix)(.*)/;
6357 my $attr_prefix = $1;
6358 my $attr_type = $2;
6359 if (ERROR("INIT_ATTRIBUTE",
6360 "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
6361 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006362 $fixed[$fixlinenr] =~
Joe Perchese970b8842013-11-12 15:10:10 -08006363 s/$InitAttributeData/${attr_prefix}initconst/;
6364 }
6365 }
6366
6367# check for $InitAttributeConst (ie: __initconst) without const
6368 if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6369 my $attr = $1;
6370 if (ERROR("INIT_ATTRIBUTE",
6371 "Use of $attr requires a separate use of const\n" . $herecurr) &&
6372 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006373 my $lead = $fixed[$fixlinenr] =~
Joe Perchese970b8842013-11-12 15:10:10 -08006374 /(^\+\s*(?:static\s+))/;
6375 $lead = rtrim($1);
6376 $lead = "$lead " if ($lead !~ /^\+$/);
6377 $lead = "${lead}const ";
Joe Perches194f66f2014-08-06 16:11:03 -07006378 $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
Joe Perchese970b8842013-11-12 15:10:10 -08006379 }
6380 }
6381
Joe Perchesc17893c2015-04-16 12:44:42 -07006382# check for __read_mostly with const non-pointer (should just be const)
6383 if ($line =~ /\b__read_mostly\b/ &&
6384 $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6385 if (ERROR("CONST_READ_MOSTLY",
6386 "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6387 $fix) {
6388 $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6389 }
6390 }
6391
Joe Perchesfbdb8132014-04-03 14:49:14 -07006392# don't use __constant_<foo> functions outside of include/uapi/
6393 if ($realfile !~ m@^include/uapi/@ &&
6394 $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6395 my $constant_func = $1;
6396 my $func = $constant_func;
6397 $func =~ s/^__constant_//;
6398 if (WARN("CONSTANT_CONVERSION",
6399 "$constant_func should be $func\n" . $herecurr) &&
6400 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006401 $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
Joe Perchesfbdb8132014-04-03 14:49:14 -07006402 }
6403 }
6404
Patrick Pannuto1a15a252010-08-09 17:21:01 -07006405# prefer usleep_range over udelay
Bruce Allan37581c22013-02-21 16:44:19 -08006406 if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
Joe Perches43c1d772014-04-03 14:49:11 -07006407 my $delay = $1;
Patrick Pannuto1a15a252010-08-09 17:21:01 -07006408 # ignore udelay's < 10, however
Joe Perches43c1d772014-04-03 14:49:11 -07006409 if (! ($delay < 10) ) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006410 CHK("USLEEP_RANGE",
Mauro Carvalho Chehab458f69e2019-06-12 14:53:00 -03006411 "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
Joe Perches43c1d772014-04-03 14:49:11 -07006412 }
6413 if ($delay > 2000) {
6414 WARN("LONG_UDELAY",
6415 "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
Patrick Pannuto1a15a252010-08-09 17:21:01 -07006416 }
6417 }
6418
Patrick Pannuto09ef8722010-08-09 17:21:02 -07006419# warn about unexpectedly long msleep's
6420 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
6421 if ($1 < 20) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006422 WARN("MSLEEP",
Mauro Carvalho Chehab458f69e2019-06-12 14:53:00 -03006423 "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
Patrick Pannuto09ef8722010-08-09 17:21:02 -07006424 }
6425 }
6426
Joe Perches36ec1932013-07-03 15:05:25 -07006427# check for comparisons of jiffies
6428 if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
6429 WARN("JIFFIES_COMPARISON",
6430 "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
6431 }
6432
Joe Perches9d7a34a2013-07-03 15:05:26 -07006433# check for comparisons of get_jiffies_64()
6434 if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
6435 WARN("JIFFIES_COMPARISON",
6436 "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
6437 }
6438
Andy Whitcroft00df3442007-06-08 13:47:06 -07006439# warn about #ifdefs in C files
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07006440# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
Andy Whitcroft00df3442007-06-08 13:47:06 -07006441# print "#ifdef in C files should be avoided\n";
6442# print "$herecurr";
6443# $clean = 0;
6444# }
6445
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07006446# warn about spacing in #ifdefs
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07006447 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
Joe Perches3705ce52013-07-03 15:05:31 -07006448 if (ERROR("SPACING",
6449 "exactly one space required after that #$1\n" . $herecurr) &&
6450 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006451 $fixed[$fixlinenr] =~
Joe Perches3705ce52013-07-03 15:05:31 -07006452 s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
6453 }
6454
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07006455 }
6456
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006457# check for spinlock_t definitions without a comment.
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07006458 if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
6459 $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006460 my $which = $1;
6461 if (!ctx_has_comment($first_line, $linenr)) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006462 CHK("UNCOMMENTED_DEFINITION",
6463 "$1 definition without comment\n" . $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006464 }
6465 }
6466# check for memory barriers without a comment.
Michael S. Tsirkin402c2552016-01-04 09:39:01 +02006467
6468 my $barriers = qr{
6469 mb|
6470 rmb|
Will Deaconad83ec62019-11-07 14:49:00 +00006471 wmb
Michael S. Tsirkin402c2552016-01-04 09:39:01 +02006472 }x;
6473 my $barrier_stems = qr{
6474 mb__before_atomic|
6475 mb__after_atomic|
6476 store_release|
6477 load_acquire|
6478 store_mb|
6479 (?:$barriers)
6480 }x;
6481 my $all_barriers = qr{
6482 (?:$barriers)|
Michael S. Tsirkin43e361f2016-01-04 10:00:10 +02006483 smp_(?:$barrier_stems)|
6484 virt_(?:$barrier_stems)
Michael S. Tsirkin402c2552016-01-04 09:39:01 +02006485 }x;
6486
6487 if ($line =~ /\b(?:$all_barriers)\s*\(/) {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006488 if (!ctx_has_comment($first_line, $linenr)) {
Joe Perchesc1fd7bb2013-11-12 15:10:11 -08006489 WARN("MEMORY_BARRIER",
6490 "memory barrier without comment\n" . $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006491 }
6492 }
Paul E. McKenney3ad81772015-07-02 11:55:40 -07006493
Michael S. Tsirkinf4073b02016-01-04 09:54:51 +02006494 my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6495
6496 if ($realfile !~ m@^include/asm-generic/@ &&
6497 $realfile !~ m@/barrier\.h$@ &&
6498 $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6499 $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6500 WARN("MEMORY_BARRIER",
6501 "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
6502 }
6503
Joe Perchescb426e92015-06-25 15:02:46 -07006504# check for waitqueue_active without a comment.
6505 if ($line =~ /\bwaitqueue_active\s*\(/) {
6506 if (!ctx_has_comment($first_line, $linenr)) {
6507 WARN("WAITQUEUE_ACTIVE",
6508 "waitqueue_active without comment\n" . $herecurr);
6509 }
6510 }
Paul E. McKenney3ad81772015-07-02 11:55:40 -07006511
Marco Elver5099a722020-04-01 12:17:14 +02006512# check for data_race without a comment.
6513 if ($line =~ /\bdata_race\s*\(/) {
6514 if (!ctx_has_comment($first_line, $linenr)) {
6515 WARN("DATA_RACE",
6516 "data_race without comment\n" . $herecurr);
6517 }
6518 }
6519
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07006520# check of hardware specific defines
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07006521 if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006522 CHK("ARCH_DEFINES",
6523 "architecture specific defines should be avoided\n" . $herecurr);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07006524 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07006525
Joe Perches596ed452017-07-12 14:37:02 -07006526# check that the storage class is not after a type
6527 if ($line =~ /\b($Type)\s+($Storage)\b/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006528 WARN("STORAGE_CLASS",
Joe Perches596ed452017-07-12 14:37:02 -07006529 "storage class '$2' should be located before type '$1'\n" . $herecurr);
6530 }
6531# Check that the storage class is at the beginning of a declaration
6532 if ($line =~ /\b$Storage\b/ &&
6533 $line !~ /^.\s*$Storage/ &&
6534 $line =~ /^.\s*(.+?)\$Storage\s/ &&
6535 $1 !~ /[\,\)]\s*$/) {
6536 WARN("STORAGE_CLASS",
6537 "storage class should be at the beginning of the declaration\n" . $herecurr);
Tobias Klauserd4977c72010-05-24 14:33:30 -07006538 }
6539
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07006540# check the location of the inline attribute, that it is between
6541# storage class and type.
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07006542 if ($line =~ /\b$Type\s+$Inline\b/ ||
6543 $line =~ /\b$Inline\s+$Storage\b/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006544 ERROR("INLINE_LOCATION",
6545 "inline keyword should sit between storage class and type\n" . $herecurr);
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07006546 }
6547
Andy Whitcroft8905a672007-11-28 16:21:06 -08006548# Check for __inline__ and __inline, prefer inline
Joe Perches2b7ab452013-11-12 15:10:14 -08006549 if ($realfile !~ m@\binclude/uapi/@ &&
6550 $line =~ /\b(__inline__|__inline)\b/) {
Joe Perchesd5e616f2013-09-11 14:23:54 -07006551 if (WARN("INLINE",
6552 "plain inline is preferred over $1\n" . $herecurr) &&
6553 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006554 $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
Joe Perchesd5e616f2013-09-11 14:23:54 -07006555
6556 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08006557 }
6558
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006559# Check for compiler attributes
Joe Perches2b7ab452013-11-12 15:10:14 -08006560 if ($realfile !~ m@\binclude/uapi/@ &&
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006561 $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
6562 my $attr = $1;
6563 $attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
Joe Perches3d130fd2011-01-12 17:00:00 -08006564
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006565 my %attr_list = (
Joe Perches0830aab2020-12-15 20:44:50 -08006566 "alias" => "__alias",
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006567 "aligned" => "__aligned",
6568 "always_inline" => "__always_inline",
6569 "assume_aligned" => "__assume_aligned",
6570 "cold" => "__cold",
6571 "const" => "__attribute_const__",
6572 "copy" => "__copy",
6573 "designated_init" => "__designated_init",
6574 "externally_visible" => "__visible",
6575 "format" => "printf|scanf",
6576 "gnu_inline" => "__gnu_inline",
6577 "malloc" => "__malloc",
6578 "mode" => "__mode",
6579 "no_caller_saved_registers" => "__no_caller_saved_registers",
6580 "noclone" => "__noclone",
6581 "noinline" => "noinline",
6582 "nonstring" => "__nonstring",
6583 "noreturn" => "__noreturn",
6584 "packed" => "__packed",
6585 "pure" => "__pure",
Joe Perches339f29d2020-12-15 20:44:43 -08006586 "section" => "__section",
Joe Perches0830aab2020-12-15 20:44:50 -08006587 "used" => "__used",
6588 "weak" => "__weak"
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006589 );
Joe Perches39b7e282011-07-25 17:13:24 -07006590
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006591 while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
Joe Perches339f29d2020-12-15 20:44:43 -08006592 my $orig_attr = $1;
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006593 my $params = '';
6594 $params = $2 if defined($2);
Joe Perches339f29d2020-12-15 20:44:43 -08006595 my $curr_attr = $orig_attr;
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006596 $curr_attr =~ s/^[\s_]+|[\s_]+$//g;
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006597 if (exists($attr_list{$curr_attr})) {
Joe Perches339f29d2020-12-15 20:44:43 -08006598 my $new = $attr_list{$curr_attr};
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006599 if ($curr_attr eq "format" && $params) {
6600 $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
Joe Perches339f29d2020-12-15 20:44:43 -08006601 $new = "__$1\($2";
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006602 } else {
Joe Perches339f29d2020-12-15 20:44:43 -08006603 $new = "$new$params";
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006604 }
Joe Perches339f29d2020-12-15 20:44:43 -08006605 if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6606 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
6607 $fix) {
6608 my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6609 $fixed[$fixlinenr] =~ s/$remove//;
6610 $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
6611 $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6612 $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
6613 }
Dwaipayan Ray7ebe1d12020-12-15 20:44:36 -08006614 }
6615 }
6616
6617 # Check for __attribute__ unused, prefer __always_unused or __maybe_unused
6618 if ($attr =~ /^_*unused/) {
6619 WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6620 "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
Joe Perchesd5e616f2013-09-11 14:23:54 -07006621 }
Joe Perches6061d942012-03-23 15:02:16 -07006622 }
6623
Joe Perches619a9082014-12-10 15:51:35 -08006624# Check for __attribute__ weak, or __weak declarations (may have link issues)
Joe Perches5b579802018-08-21 21:57:33 -07006625 if ($perl_version_ok &&
Joe Perches619a9082014-12-10 15:51:35 -08006626 $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6627 ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6628 $line =~ /\b__weak\b/)) {
6629 ERROR("WEAK_DECLARATION",
6630 "Using weak declarations can have unintended link defects\n" . $herecurr);
6631 }
6632
Tomas Winklerfd39f902016-12-12 16:46:34 -08006633# check for c99 types like uint8_t used outside of uapi/ and tools/
Joe Perchese6176fa2015-06-25 15:02:49 -07006634 if ($realfile !~ m@\binclude/uapi/@ &&
Tomas Winklerfd39f902016-12-12 16:46:34 -08006635 $realfile !~ m@\btools/@ &&
Joe Perchese6176fa2015-06-25 15:02:49 -07006636 $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6637 my $type = $1;
6638 if ($type =~ /\b($typeC99Typedefs)\b/) {
6639 $type = $1;
6640 my $kernel_type = 'u';
6641 $kernel_type = 's' if ($type =~ /^_*[si]/);
6642 $type =~ /(\d+)/;
6643 $kernel_type .= $1;
6644 if (CHK("PREFER_KERNEL_TYPES",
6645 "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6646 $fix) {
6647 $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6648 }
6649 }
6650 }
6651
Joe Perches938224b2016-01-20 14:59:15 -08006652# check for cast of C90 native int or longer types constants
6653 if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6654 my $cast = $1;
6655 my $const = $2;
Joe Perches0972b8b2021-02-25 17:21:54 -08006656 my $suffix = "";
6657 my $newconst = $const;
6658 $newconst =~ s/${Int_type}$//;
6659 $suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6660 if ($cast =~ /\blong\s+long\b/) {
6661 $suffix .= 'LL';
6662 } elsif ($cast =~ /\blong\b/) {
6663 $suffix .= 'L';
6664 }
Joe Perches938224b2016-01-20 14:59:15 -08006665 if (WARN("TYPECAST_INT_CONSTANT",
Joe Perches0972b8b2021-02-25 17:21:54 -08006666 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
Joe Perches938224b2016-01-20 14:59:15 -08006667 $fix) {
Joe Perches938224b2016-01-20 14:59:15 -08006668 $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6669 }
6670 }
6671
Joe Perches8f53a9b2010-03-05 13:43:48 -08006672# check for sizeof(&)
6673 if ($line =~ /\bsizeof\s*\(\s*\&/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006674 WARN("SIZEOF_ADDRESS",
6675 "sizeof(& should be avoided\n" . $herecurr);
Joe Perches8f53a9b2010-03-05 13:43:48 -08006676 }
6677
Joe Perches66c80b62012-07-30 14:41:22 -07006678# check for sizeof without parenthesis
6679 if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
Joe Perchesd5e616f2013-09-11 14:23:54 -07006680 if (WARN("SIZEOF_PARENTHESIS",
6681 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6682 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006683 $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
Joe Perchesd5e616f2013-09-11 14:23:54 -07006684 }
Joe Perches66c80b62012-07-30 14:41:22 -07006685 }
6686
Joe Perches88982fe2012-12-17 16:02:00 -08006687# check for struct spinlock declarations
6688 if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
6689 WARN("USE_SPINLOCK_T",
6690 "struct spinlock should be spinlock_t\n" . $herecurr);
6691 }
6692
Joe Perchesa6962d72013-04-29 16:18:13 -07006693# check for seq_printf uses that could be seq_puts
Joe Perches06668722013-11-12 15:10:07 -08006694 if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
Joe Perchesa6962d72013-04-29 16:18:13 -07006695 my $fmt = get_quoted_string($line, $rawline);
Heba Aamercaac1d52015-02-13 14:38:49 -08006696 $fmt =~ s/%%//g;
6697 if ($fmt !~ /%/) {
Joe Perchesd5e616f2013-09-11 14:23:54 -07006698 if (WARN("PREFER_SEQ_PUTS",
6699 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6700 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006701 $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
Joe Perchesd5e616f2013-09-11 14:23:54 -07006702 }
Joe Perchesa6962d72013-04-29 16:18:13 -07006703 }
6704 }
6705
Joe Perches478b1792018-04-10 16:33:34 -07006706# check for vsprintf extension %p<foo> misuses
Joe Perches5b579802018-08-21 21:57:33 -07006707 if ($perl_version_ok &&
Joe Perches0b523762017-05-08 15:55:36 -07006708 defined $stat &&
6709 $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
6710 $1 !~ /^_*volatile_*$/) {
Tobin C. Hardinge3c6bc92018-04-10 16:33:31 -07006711 my $stat_real;
6712
Joe Perches0b523762017-05-08 15:55:36 -07006713 my $lc = $stat =~ tr@\n@@;
6714 $lc = $lc + $linenr;
6715 for (my $count = $linenr; $count <= $lc; $count++) {
Joe Perchesffe07512018-07-13 16:59:23 -07006716 my $specifier;
6717 my $extension;
Sakari Ailus3bd32d62019-10-03 15:32:18 +03006718 my $qualifier;
Joe Perchesffe07512018-07-13 16:59:23 -07006719 my $bad_specifier = "";
Joe Perches0b523762017-05-08 15:55:36 -07006720 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
6721 $fmt =~ s/%%//g;
Tobin C. Harding2a9f9d82018-04-10 16:33:20 -07006722
Sakari Ailus3bd32d62019-10-03 15:32:18 +03006723 while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
Tobin C. Hardinge3c6bc92018-04-10 16:33:31 -07006724 $specifier = $1;
6725 $extension = $2;
Sakari Ailus3bd32d62019-10-03 15:32:18 +03006726 $qualifier = $3;
Sakari Ailusaf612e42021-02-16 17:57:20 +02006727 if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
Sakari Ailus3bd32d62019-10-03 15:32:18 +03006728 ($extension eq "f" &&
Sakari Ailusaf612e42021-02-16 17:57:20 +02006729 defined $qualifier && $qualifier !~ /^w/) ||
6730 ($extension eq "4" &&
6731 defined $qualifier && $qualifier !~ /^cc/)) {
Tobin C. Hardinge3c6bc92018-04-10 16:33:31 -07006732 $bad_specifier = $specifier;
6733 last;
6734 }
6735 if ($extension eq "x" && !defined($stat_real)) {
6736 if (!defined($stat_real)) {
6737 $stat_real = get_stat_real($linenr, $lc);
6738 }
6739 WARN("VSPRINTF_SPECIFIER_PX",
6740 "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");
6741 }
6742 }
6743 if ($bad_specifier ne "") {
6744 my $stat_real = get_stat_real($linenr, $lc);
6745 my $ext_type = "Invalid";
6746 my $use = "";
6747 if ($bad_specifier =~ /p[Ff]/) {
Tobin C. Hardinge3c6bc92018-04-10 16:33:31 -07006748 $use = " - use %pS instead";
6749 $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
6750 }
6751
6752 WARN("VSPRINTF_POINTER_EXTENSION",
6753 "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6754 }
Joe Perches0b523762017-05-08 15:55:36 -07006755 }
6756 }
6757
Andy Whitcroft554e1652012-01-10 15:09:57 -08006758# Check for misused memsets
Joe Perches5b579802018-08-21 21:57:33 -07006759 if ($perl_version_ok &&
Joe Perchesd1fe9c02012-03-23 15:02:16 -07006760 defined $stat &&
Mateusz Kulikowski9e20a852015-06-25 15:03:16 -07006761 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
Andy Whitcroft554e1652012-01-10 15:09:57 -08006762
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006763 my $ms_addr = $2;
Joe Perchesd1fe9c02012-03-23 15:02:16 -07006764 my $ms_val = $7;
6765 my $ms_size = $12;
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006766
Andy Whitcroft554e1652012-01-10 15:09:57 -08006767 if ($ms_size =~ /^(0x|)0$/i) {
6768 ERROR("MEMSET",
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006769 "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
Andy Whitcroft554e1652012-01-10 15:09:57 -08006770 } elsif ($ms_size =~ /^(0x|)1$/i) {
6771 WARN("MEMSET",
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006772 "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6773 }
6774 }
6775
Joe Perches98a9bba2014-01-23 15:54:52 -08006776# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
Joe Perches5b579802018-08-21 21:57:33 -07006777# if ($perl_version_ok &&
Joe Perchesf3331952016-10-11 13:51:53 -07006778# defined $stat &&
6779# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6780# if (WARN("PREFER_ETHER_ADDR_COPY",
6781# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6782# $fix) {
6783# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6784# }
6785# }
Joe Perches98a9bba2014-01-23 15:54:52 -08006786
Mateusz Kulikowskib6117d12015-06-25 15:03:13 -07006787# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
Joe Perches5b579802018-08-21 21:57:33 -07006788# if ($perl_version_ok &&
Joe Perchesf3331952016-10-11 13:51:53 -07006789# defined $stat &&
6790# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6791# WARN("PREFER_ETHER_ADDR_EQUAL",
6792# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6793# }
Mateusz Kulikowskib6117d12015-06-25 15:03:13 -07006794
Mateusz Kulikowski8617cd02015-06-25 15:03:19 -07006795# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
6796# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
Joe Perches5b579802018-08-21 21:57:33 -07006797# if ($perl_version_ok &&
Joe Perchesf3331952016-10-11 13:51:53 -07006798# defined $stat &&
6799# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6800#
6801# my $ms_val = $7;
6802#
6803# if ($ms_val =~ /^(?:0x|)0+$/i) {
6804# if (WARN("PREFER_ETH_ZERO_ADDR",
6805# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6806# $fix) {
6807# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6808# }
6809# } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6810# if (WARN("PREFER_ETH_BROADCAST_ADDR",
6811# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6812# $fix) {
6813# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6814# }
6815# }
6816# }
Mateusz Kulikowski8617cd02015-06-25 15:03:19 -07006817
Joe Perches5dbdb2d2020-12-29 15:14:31 -08006818# strlcpy uses that should likely be strscpy
6819 if ($line =~ /\bstrlcpy\s*\(/) {
6820 WARN("STRLCPY",
6821 "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr);
6822 }
6823
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006824# typecasts on min/max could be min_t/max_t
Joe Perches5b579802018-08-21 21:57:33 -07006825 if ($perl_version_ok &&
Joe Perchesd1fe9c02012-03-23 15:02:16 -07006826 defined $stat &&
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006827 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
Joe Perchesd1fe9c02012-03-23 15:02:16 -07006828 if (defined $2 || defined $7) {
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006829 my $call = $1;
6830 my $cast1 = deparenthesize($2);
6831 my $arg1 = $3;
Joe Perchesd1fe9c02012-03-23 15:02:16 -07006832 my $cast2 = deparenthesize($7);
6833 my $arg2 = $8;
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006834 my $cast;
6835
Joe Perchesd1fe9c02012-03-23 15:02:16 -07006836 if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
Joe Perchesd7c76ba2012-01-10 15:09:58 -08006837 $cast = "$cast1 or $cast2";
6838 } elsif ($cast1 ne "") {
6839 $cast = $cast1;
6840 } else {
6841 $cast = $cast2;
6842 }
6843 WARN("MINMAX",
6844 "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
Andy Whitcroft554e1652012-01-10 15:09:57 -08006845 }
6846 }
6847
Joe Perches4a273192012-07-30 14:41:20 -07006848# check usleep_range arguments
Joe Perches5b579802018-08-21 21:57:33 -07006849 if ($perl_version_ok &&
Joe Perches4a273192012-07-30 14:41:20 -07006850 defined $stat &&
6851 $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
6852 my $min = $1;
6853 my $max = $7;
6854 if ($min eq $max) {
6855 WARN("USLEEP_RANGE",
Mauro Carvalho Chehab458f69e2019-06-12 14:53:00 -03006856 "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
Joe Perches4a273192012-07-30 14:41:20 -07006857 } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
6858 $min > $max) {
6859 WARN("USLEEP_RANGE",
Mauro Carvalho Chehab458f69e2019-06-12 14:53:00 -03006860 "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
Joe Perches4a273192012-07-30 14:41:20 -07006861 }
6862 }
6863
Joe Perches823b7942013-11-12 15:10:15 -08006864# check for naked sscanf
Joe Perches5b579802018-08-21 21:57:33 -07006865 if ($perl_version_ok &&
Joe Perches823b7942013-11-12 15:10:15 -08006866 defined $stat &&
Joe Perches6c8bd702014-04-03 14:49:16 -07006867 $line =~ /\bsscanf\b/ &&
Joe Perches823b7942013-11-12 15:10:15 -08006868 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6869 $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6870 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6871 my $lc = $stat =~ tr@\n@@;
6872 $lc = $lc + $linenr;
Tobin C. Harding2a9f9d82018-04-10 16:33:20 -07006873 my $stat_real = get_stat_real($linenr, $lc);
Joe Perches823b7942013-11-12 15:10:15 -08006874 WARN("NAKED_SSCANF",
6875 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6876 }
6877
Joe Perchesafc819a2014-06-04 16:12:08 -07006878# check for simple sscanf that should be kstrto<foo>
Joe Perches5b579802018-08-21 21:57:33 -07006879 if ($perl_version_ok &&
Joe Perchesafc819a2014-06-04 16:12:08 -07006880 defined $stat &&
6881 $line =~ /\bsscanf\b/) {
6882 my $lc = $stat =~ tr@\n@@;
6883 $lc = $lc + $linenr;
Tobin C. Harding2a9f9d82018-04-10 16:33:20 -07006884 my $stat_real = get_stat_real($linenr, $lc);
Joe Perchesafc819a2014-06-04 16:12:08 -07006885 if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6886 my $format = $6;
6887 my $count = $format =~ tr@%@%@;
6888 if ($count == 1 &&
6889 $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6890 WARN("SSCANF_TO_KSTRTO",
6891 "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6892 }
6893 }
6894 }
6895
Joe Perches70dc8a42013-09-11 14:23:58 -07006896# check for new externs in .h files.
6897 if ($realfile =~ /\.h$/ &&
6898 $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
Joe Perchesd1d85782013-09-24 15:27:46 -07006899 if (CHK("AVOID_EXTERNS",
6900 "extern prototypes should be avoided in .h files\n" . $herecurr) &&
Joe Perches70dc8a42013-09-11 14:23:58 -07006901 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07006902 $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
Joe Perches70dc8a42013-09-11 14:23:58 -07006903 }
6904 }
6905
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07006906# check for new externs in .c files.
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07006907 if ($realfile =~ /\.c$/ && defined $stat &&
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07006908 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07006909 {
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07006910 my $function_name = $1;
6911 my $paren_space = $2;
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07006912
6913 my $s = $stat;
6914 if (defined $cond) {
6915 substr($s, 0, length($cond), '');
6916 }
Kees Cookd8b44b52020-06-03 14:18:09 -07006917 if ($s =~ /^\s*;/)
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07006918 {
Joe Perches000d1cc12011-07-25 17:13:25 -07006919 WARN("AVOID_EXTERNS",
6920 "externs should be avoided in .c files\n" . $herecurr);
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07006921 }
6922
6923 if ($paren_space =~ /\n/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006924 WARN("FUNCTION_ARGUMENTS",
6925 "arguments for function declarations should follow identifier\n" . $herecurr);
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07006926 }
Andy Whitcroft9c9ba342008-04-29 00:59:33 -07006927
6928 } elsif ($realfile =~ /\.c$/ && defined $stat &&
6929 $stat =~ /^.\s*extern\s+/)
6930 {
Joe Perches000d1cc12011-07-25 17:13:25 -07006931 WARN("AVOID_EXTERNS",
6932 "externs should be avoided in .c files\n" . $herecurr);
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07006933 }
6934
Joe Perchesa0ad7592017-07-10 15:52:19 -07006935# check for function declarations that have arguments without identifier names
6936 if (defined $stat &&
Kees Cookd8b44b52020-06-03 14:18:09 -07006937 $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6938 $1 ne "void") {
6939 my $args = trim($1);
Joe Perchesca0d8922016-10-11 13:52:16 -07006940 while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6941 my $arg = trim($1);
Kees Cookd8b44b52020-06-03 14:18:09 -07006942 if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
Joe Perchesca0d8922016-10-11 13:52:16 -07006943 WARN("FUNCTION_ARGUMENTS",
6944 "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6945 }
6946 }
6947 }
6948
Joe Perchesa0ad7592017-07-10 15:52:19 -07006949# check for function definitions
Joe Perches5b579802018-08-21 21:57:33 -07006950 if ($perl_version_ok &&
Joe Perchesa0ad7592017-07-10 15:52:19 -07006951 defined $stat &&
6952 $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6953 $context_function = $1;
6954
6955# check for multiline function definition with misplaced open brace
6956 my $ok = 0;
6957 my $cnt = statement_rawlines($stat);
6958 my $herectx = $here . "\n";
6959 for (my $n = 0; $n < $cnt; $n++) {
6960 my $rl = raw_line($linenr, $n);
6961 $herectx .= $rl . "\n";
6962 $ok = 1 if ($rl =~ /^[ \+]\{/);
6963 $ok = 1 if ($rl =~ /\{/ && $n == 0);
6964 last if $rl =~ /^[ \+].*\{/;
6965 }
6966 if (!$ok) {
6967 ERROR("OPEN_BRACE",
6968 "open brace '{' following function definitions go on the next line\n" . $herectx);
6969 }
6970 }
6971
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07006972# checks for new __setup's
6973 if ($rawline =~ /\b__setup\("([^"]*)"/) {
6974 my $name = $1;
6975
6976 if (!grep(/$name/, @setup_docs)) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006977 CHK("UNDOCUMENTED_SETUP",
Tim Froidcoeur2581ac72020-06-10 18:41:38 -07006978 "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07006979 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07006980 }
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07006981
Joe Perchese29a70f2019-03-07 16:28:35 -08006982# check for pointless casting of alloc functions
6983 if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07006984 WARN("UNNECESSARY_CASTS",
6985 "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07006986 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08006987
Joe Perchesa640d252013-07-03 15:05:21 -07006988# alloc style
6989# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
Joe Perches5b579802018-08-21 21:57:33 -07006990 if ($perl_version_ok &&
Joe Perchese29a70f2019-03-07 16:28:35 -08006991 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
Joe Perchesa640d252013-07-03 15:05:21 -07006992 CHK("ALLOC_SIZEOF_STRUCT",
6993 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6994 }
6995
Joe Perches60a55362014-06-04 16:12:07 -07006996# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
Joe Perches5b579802018-08-21 21:57:33 -07006997 if ($perl_version_ok &&
Joe Perches1b4a2ed2017-05-08 15:55:57 -07006998 defined $stat &&
6999 $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
Joe Perches60a55362014-06-04 16:12:07 -07007000 my $oldfunc = $3;
7001 my $a1 = $4;
7002 my $a2 = $10;
7003 my $newfunc = "kmalloc_array";
7004 $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
Joe Perchese3674552014-08-06 16:10:55 -07007005 my $r1 = $a1;
7006 my $r2 = $a2;
7007 if ($a1 =~ /^sizeof\s*\S/) {
7008 $r1 = $a2;
7009 $r2 = $a1;
7010 }
7011 if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
7012 !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
Joe Perches1b4a2ed2017-05-08 15:55:57 -07007013 my $cnt = statement_rawlines($stat);
Tobin C. Hardinge3d95a22018-04-10 16:33:27 -07007014 my $herectx = get_stat_here($linenr, $cnt, $here);
7015
Joe Perches60a55362014-06-04 16:12:07 -07007016 if (WARN("ALLOC_WITH_MULTIPLY",
Joe Perches1b4a2ed2017-05-08 15:55:57 -07007017 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
7018 $cnt == 1 &&
Joe Perches60a55362014-06-04 16:12:07 -07007019 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07007020 $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;
Joe Perches60a55362014-06-04 16:12:07 -07007021 }
7022 }
7023 }
7024
Joe Perches972fdea2013-04-29 16:18:12 -07007025# check for krealloc arg reuse
Joe Perches5b579802018-08-21 21:57:33 -07007026 if ($perl_version_ok &&
Joe Perches4cab63c2018-08-21 21:57:50 -07007027 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
7028 $1 eq $3) {
Joe Perches972fdea2013-04-29 16:18:12 -07007029 WARN("KREALLOC_ARG_REUSE",
7030 "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
7031 }
7032
Joe Perches5ce59ae2013-02-21 16:44:18 -08007033# check for alloc argument mismatch
Christophe JAILLET7e6cdd72021-05-06 18:04:01 -07007034 if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) {
Joe Perches5ce59ae2013-02-21 16:44:18 -08007035 WARN("ALLOC_ARRAY_ARGS",
7036 "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
7037 }
7038
Joe Perchescaf2a542011-01-12 16:59:56 -08007039# check for multiple semicolons
7040 if ($line =~ /;\s*;\s*$/) {
Joe Perchesd5e616f2013-09-11 14:23:54 -07007041 if (WARN("ONE_SEMICOLON",
7042 "Statements terminations use 1 semicolon\n" . $herecurr) &&
7043 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07007044 $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
Joe Perchesd5e616f2013-09-11 14:23:54 -07007045 }
Joe Perchesd1e2ad02012-12-17 16:02:01 -08007046 }
7047
Tomas Winklercec3aaa2016-08-02 14:04:39 -07007048# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
7049 if ($realfile !~ m@^include/uapi/@ &&
7050 $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
Joe Perches0ab90192014-12-10 15:51:57 -08007051 my $ull = "";
7052 $ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
7053 if (CHK("BIT_MACRO",
7054 "Prefer using the BIT$ull macro\n" . $herecurr) &&
7055 $fix) {
7056 $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
7057 }
7058 }
7059
Joe Perches50161262020-08-11 18:35:07 -07007060# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
Jerome Forissier3e89ad82020-10-15 20:11:49 -07007061 if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
Joe Perches50161262020-08-11 18:35:07 -07007062 WARN("IS_ENABLED_CONFIG",
Jerome Forissier3e89ad82020-10-15 20:11:49 -07007063 "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
Joe Perches50161262020-08-11 18:35:07 -07007064 }
7065
Joe Perches2d632742016-05-20 17:04:00 -07007066# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
Jerome Forissier3e89ad82020-10-15 20:11:49 -07007067 if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
Joe Perches2d632742016-05-20 17:04:00 -07007068 my $config = $1;
7069 if (WARN("PREFER_IS_ENABLED",
Jerome Forissier3e89ad82020-10-15 20:11:49 -07007070 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
Joe Perches2d632742016-05-20 17:04:00 -07007071 $fix) {
7072 $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
7073 }
7074 }
7075
Joe Perchesf36d3eb2020-04-06 20:10:58 -07007076# check for /* fallthrough */ like comment, prefer fallthrough;
7077 my @fallthroughs = (
7078 'fallthrough',
7079 '@fallthrough@',
7080 'lint -fallthrough[ \t]*',
7081 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
7082 '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
7083 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7084 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7085 );
7086 if ($raw_comment ne '') {
7087 foreach my $ft (@fallthroughs) {
7088 if ($raw_comment =~ /$ft/) {
7089 my $msg_level = \&WARN;
7090 $msg_level = \&CHK if ($file);
7091 &{$msg_level}("PREFER_FALLTHROUGH",
7092 "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
7093 last;
7094 }
7095 }
7096 }
7097
Joe Perchesd1e2ad02012-12-17 16:02:01 -08007098# check for switch/default statements without a break;
Joe Perches5b579802018-08-21 21:57:33 -07007099 if ($perl_version_ok &&
Joe Perchesd1e2ad02012-12-17 16:02:01 -08007100 defined $stat &&
7101 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
Joe Perchesd1e2ad02012-12-17 16:02:01 -08007102 my $cnt = statement_rawlines($stat);
Tobin C. Hardinge3d95a22018-04-10 16:33:27 -07007103 my $herectx = get_stat_here($linenr, $cnt, $here);
7104
Joe Perchesd1e2ad02012-12-17 16:02:01 -08007105 WARN("DEFAULT_NO_BREAK",
7106 "switch default: should use break\n" . $herectx);
Joe Perchescaf2a542011-01-12 16:59:56 -08007107 }
7108
Andy Whitcroft13214ad2008-02-08 04:22:03 -08007109# check for gcc specific __FUNCTION__
Joe Perchesd5e616f2013-09-11 14:23:54 -07007110 if ($line =~ /\b__FUNCTION__\b/) {
7111 if (WARN("USE_FUNC",
7112 "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
7113 $fix) {
Joe Perches194f66f2014-08-06 16:11:03 -07007114 $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
Joe Perchesd5e616f2013-09-11 14:23:54 -07007115 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08007116 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07007117
Joe Perches62ec8182015-02-13 14:38:18 -08007118# check for uses of __DATE__, __TIME__, __TIMESTAMP__
7119 while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
7120 ERROR("DATE_TIME",
7121 "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
7122 }
7123
Joe Perches2c924882012-03-23 15:02:20 -07007124# check for use of yield()
7125 if ($line =~ /\byield\s*\(\s*\)/) {
7126 WARN("YIELD",
7127 "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr);
7128 }
7129
Joe Perches179f8f42013-07-03 15:05:30 -07007130# check for comparisons against true and false
7131 if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
7132 my $lead = $1;
7133 my $arg = $2;
7134 my $test = $3;
7135 my $otype = $4;
7136 my $trail = $5;
7137 my $op = "!";
7138
7139 ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
7140
7141 my $type = lc($otype);
7142 if ($type =~ /^(?:true|false)$/) {
7143 if (("$test" eq "==" && "$type" eq "true") ||
7144 ("$test" eq "!=" && "$type" eq "false")) {
7145 $op = "";
7146 }
7147
7148 CHK("BOOL_COMPARISON",
7149 "Using comparison to $otype is error prone\n" . $herecurr);
7150
7151## maybe suggesting a correct construct would better
7152## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7153
7154 }
7155 }
7156
Thomas Gleixner4882720b2010-09-07 14:34:01 +00007157# check for semaphores initialized locked
7158 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007159 WARN("CONSIDER_COMPLETION",
7160 "consider using a completion\n" . $herecurr);
Andy Whitcroft773647a2008-03-28 14:15:58 -07007161 }
Joe Perches6712d852012-03-23 15:02:20 -07007162
Joe Perches67d0a072011-10-31 17:13:10 -07007163# recommend kstrto* over simple_strto* and strict_strto*
7164 if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007165 WARN("CONSIDER_KSTRTO",
Joe Perches67d0a072011-10-31 17:13:10 -07007166 "$1 is obsolete, use k$3 instead\n" . $herecurr);
Andy Whitcroft773647a2008-03-28 14:15:58 -07007167 }
Joe Perches6712d852012-03-23 15:02:20 -07007168
Fabian Frederickae3ccc42014-06-04 16:12:10 -07007169# check for __initcall(), use device_initcall() explicitly or more appropriate function please
Michael Ellermanf3db6632008-07-23 21:28:57 -07007170 if ($line =~ /^.\s*__initcall\s*\(/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007171 WARN("USE_DEVICE_INITCALL",
Fabian Frederickae3ccc42014-06-04 16:12:10 -07007172 "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
Michael Ellermanf3db6632008-07-23 21:28:57 -07007173 }
Joe Perches6712d852012-03-23 15:02:20 -07007174
Paul E. McKenney3d709ab2018-11-11 10:49:10 -08007175# check for spin_is_locked(), suggest lockdep instead
7176 if ($line =~ /\bspin_is_locked\(/) {
7177 WARN("USE_LOCKDEP",
7178 "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
7179 }
7180
Joe Perches9189c7e2018-09-07 15:26:18 -07007181# check for deprecated apis
7182 if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
7183 my $deprecated_api = $1;
7184 my $new_api = $deprecated_apis{$deprecated_api};
7185 WARN("DEPRECATED_API",
7186 "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
7187 }
7188
Joe Perches0f3c5aa2015-02-13 14:39:05 -08007189# check for various structs that are normally const (ops, kgdb, device_tree)
Joe Perchesd9190e42017-05-08 15:55:45 -07007190# and avoid what seem like struct definitions 'struct foo {'
Quentin Monnetced69da12020-08-11 18:35:13 -07007191 if (defined($const_structs) &&
7192 $line !~ /\bconst\b/ &&
Joe Perchesd9190e42017-05-08 15:55:45 -07007193 $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007194 WARN("CONST_STRUCT",
Joe Perchesd9190e42017-05-08 15:55:45 -07007195 "struct $1 should normally be const\n" . $herecurr);
Andy Whitcroft2b6db5c2009-01-06 14:41:29 -08007196 }
Andy Whitcroft773647a2008-03-28 14:15:58 -07007197
7198# use of NR_CPUS is usually wrong
7199# ignore definitions of NR_CPUS and usage to define arrays as likely right
Peng Wang35cdcbf2021-02-25 17:21:44 -08007200# ignore designated initializers using NR_CPUS
Andy Whitcroft773647a2008-03-28 14:15:58 -07007201 if ($line =~ /\bNR_CPUS\b/ &&
Andy Whitcroftc45dcab2008-06-05 22:46:01 -07007202 $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
7203 $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
Andy Whitcroft171ae1a2008-04-29 00:59:32 -07007204 $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7205 $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
Peng Wang35cdcbf2021-02-25 17:21:44 -08007206 $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
7207 $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
Andy Whitcroft773647a2008-03-28 14:15:58 -07007208 {
Joe Perches000d1cc12011-07-25 17:13:25 -07007209 WARN("NR_CPUS",
7210 "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
Andy Whitcroft773647a2008-03-28 14:15:58 -07007211 }
Andy Whitcroft9c9ba342008-04-29 00:59:33 -07007212
Joe Perches52ea8502013-11-12 15:10:09 -08007213# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
7214 if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
7215 ERROR("DEFINE_ARCH_HAS",
7216 "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
7217 }
7218
Joe Perchesacd93622015-02-13 14:38:38 -08007219# likely/unlikely comparisons similar to "(likely(foo) > 0)"
Joe Perches5b579802018-08-21 21:57:33 -07007220 if ($perl_version_ok &&
Joe Perchesacd93622015-02-13 14:38:38 -08007221 $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7222 WARN("LIKELY_MISUSE",
7223 "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7224 }
7225
Joe Perchesfbe74542021-05-06 18:03:55 -07007226# return sysfs_emit(foo, fmt, ...) fmt without newline
7227 if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
7228 substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
7229 my $offset = $+[6] - 1;
7230 if (WARN("SYSFS_EMIT",
7231 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
7232 $fix) {
7233 substr($fixed[$fixlinenr], $offset, 0) = '\\n';
7234 }
7235 }
7236
Denis Efremovde3f1862019-09-25 16:49:25 -07007237# nested likely/unlikely calls
7238 if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7239 WARN("LIKELY_MISUSE",
7240 "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
7241 }
7242
Andy Whitcroft691d77b2009-01-06 14:41:16 -08007243# whine mightly about in_atomic
7244 if ($line =~ /\bin_atomic\s*\(/) {
7245 if ($realfile =~ m@^drivers/@) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007246 ERROR("IN_ATOMIC",
7247 "do not use in_atomic in drivers\n" . $herecurr);
Andy Whitcroftf4a87732009-02-27 14:03:05 -08007248 } elsif ($realfile !~ m@^kernel/@) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007249 WARN("IN_ATOMIC",
7250 "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
Andy Whitcroft691d77b2009-01-06 14:41:16 -08007251 }
7252 }
Peter Zijlstra1704f472010-03-19 01:37:42 +01007253
7254# check for lockdep_set_novalidate_class
7255 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
7256 $line =~ /__lockdep_no_validate__\s*\)/ ) {
7257 if ($realfile !~ m@^kernel/lockdep@ &&
7258 $realfile !~ m@^include/linux/lockdep@ &&
7259 $realfile !~ m@^drivers/base/core@) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007260 ERROR("LOCKDEP",
7261 "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
Peter Zijlstra1704f472010-03-19 01:37:42 +01007262 }
7263 }
Dave Jones88f88312011-01-12 16:59:59 -08007264
Joe Perchesb392c642015-04-16 12:44:16 -07007265 if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
7266 $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007267 WARN("EXPORTED_WORLD_WRITABLE",
7268 "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
Dave Jones88f88312011-01-12 16:59:59 -08007269 }
Joe Perches24358802014-04-03 14:49:13 -07007270
Joe Perches00180462018-02-06 15:38:55 -08007271# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
7272# and whether or not function naming is typical and if
7273# DEVICE_ATTR permissions uses are unusual too
Joe Perches5b579802018-08-21 21:57:33 -07007274 if ($perl_version_ok &&
Joe Perches00180462018-02-06 15:38:55 -08007275 defined $stat &&
7276 $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*\)/) {
7277 my $var = $1;
7278 my $perms = $2;
7279 my $show = $3;
7280 my $store = $4;
7281 my $octal_perms = perms_to_octal($perms);
7282 if ($show =~ /^${var}_show$/ &&
7283 $store =~ /^${var}_store$/ &&
7284 $octal_perms eq "0644") {
7285 if (WARN("DEVICE_ATTR_RW",
7286 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
7287 $fix) {
7288 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
7289 }
7290 } elsif ($show =~ /^${var}_show$/ &&
7291 $store =~ /^NULL$/ &&
7292 $octal_perms eq "0444") {
7293 if (WARN("DEVICE_ATTR_RO",
7294 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
7295 $fix) {
7296 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
7297 }
7298 } elsif ($show =~ /^NULL$/ &&
7299 $store =~ /^${var}_store$/ &&
7300 $octal_perms eq "0200") {
7301 if (WARN("DEVICE_ATTR_WO",
7302 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
7303 $fix) {
7304 $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
7305 }
7306 } elsif ($octal_perms eq "0644" ||
7307 $octal_perms eq "0444" ||
7308 $octal_perms eq "0200") {
7309 my $newshow = "$show";
7310 $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
7311 my $newstore = $store;
7312 $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
7313 my $rename = "";
7314 if ($show ne $newshow) {
7315 $rename .= " '$show' to '$newshow'";
7316 }
7317 if ($store ne $newstore) {
7318 $rename .= " '$store' to '$newstore'";
7319 }
7320 WARN("DEVICE_ATTR_FUNCTIONS",
7321 "Consider renaming function(s)$rename\n" . $herecurr);
7322 } else {
7323 WARN("DEVICE_ATTR_PERMS",
7324 "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
7325 }
7326 }
7327
Joe Perches515a2352014-04-03 14:49:24 -07007328# Mode permission misuses where it seems decimal should be octal
7329# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
Joe Perches73121532018-02-06 15:38:49 -08007330# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
7331# specific definition of not visible in sysfs.
7332# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
7333# use the default permissions
Joe Perches5b579802018-08-21 21:57:33 -07007334 if ($perl_version_ok &&
Joe Perches459cf0a2016-10-11 13:52:19 -07007335 defined $stat &&
Joe Perches515a2352014-04-03 14:49:24 -07007336 $line =~ /$mode_perms_search/) {
7337 foreach my $entry (@mode_permission_funcs) {
7338 my $func = $entry->[0];
7339 my $arg_pos = $entry->[1];
Joe Perches24358802014-04-03 14:49:13 -07007340
Joe Perches459cf0a2016-10-11 13:52:19 -07007341 my $lc = $stat =~ tr@\n@@;
7342 $lc = $lc + $linenr;
Tobin C. Harding2a9f9d82018-04-10 16:33:20 -07007343 my $stat_real = get_stat_real($linenr, $lc);
Joe Perches459cf0a2016-10-11 13:52:19 -07007344
Joe Perches515a2352014-04-03 14:49:24 -07007345 my $skip_args = "";
7346 if ($arg_pos > 1) {
7347 $arg_pos--;
7348 $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
7349 }
Joe Perchesf90774e2016-10-11 13:51:47 -07007350 my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
Joe Perches459cf0a2016-10-11 13:52:19 -07007351 if ($stat =~ /$test/) {
Joe Perches515a2352014-04-03 14:49:24 -07007352 my $val = $1;
7353 $val = $6 if ($skip_args ne "");
Joe Perches73121532018-02-06 15:38:49 -08007354 if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
7355 (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
7356 ($val =~ /^$Octal$/ && length($val) ne 4))) {
Joe Perches515a2352014-04-03 14:49:24 -07007357 ERROR("NON_OCTAL_PERMISSIONS",
Joe Perches459cf0a2016-10-11 13:52:19 -07007358 "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
Joe Perchesf90774e2016-10-11 13:51:47 -07007359 }
7360 if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
Joe Perchesc0a5c892015-02-13 14:38:21 -08007361 ERROR("EXPORTED_WORLD_WRITABLE",
Joe Perches459cf0a2016-10-11 13:52:19 -07007362 "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
Joe Perchesf90774e2016-10-11 13:51:47 -07007363 }
Joe Perches24358802014-04-03 14:49:13 -07007364 }
7365 }
7366 }
Bjorn Andersson5a6d20c2015-06-25 15:03:24 -07007367
Joe Perches459cf0a2016-10-11 13:52:19 -07007368# check for uses of S_<PERMS> that could be octal for readability
Joe Perchesbc22d9a2018-04-10 16:33:53 -07007369 while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
Joe Perches00180462018-02-06 15:38:55 -08007370 my $oval = $1;
7371 my $octal = perms_to_octal($oval);
Joe Perches459cf0a2016-10-11 13:52:19 -07007372 if (WARN("SYMBOLIC_PERMS",
7373 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7374 $fix) {
Joe Perches00180462018-02-06 15:38:55 -08007375 $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
Joe Perches459cf0a2016-10-11 13:52:19 -07007376 }
7377 }
7378
Bjorn Andersson5a6d20c2015-06-25 15:03:24 -07007379# validate content of MODULE_LICENSE against list from include/linux/module.h
7380 if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
7381 my $extracted_string = get_quoted_string($line, $rawline);
7382 my $valid_licenses = qr{
7383 GPL|
7384 GPL\ v2|
7385 GPL\ and\ additional\ rights|
7386 Dual\ BSD/GPL|
7387 Dual\ MIT/GPL|
7388 Dual\ MPL/GPL|
7389 Proprietary
7390 }x;
7391 if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
7392 WARN("MODULE_LICENSE",
7393 "unknown module license " . $extracted_string . "\n" . $herecurr);
7394 }
7395 }
Matteo Croce6a8d76c2019-07-16 16:27:48 -07007396
7397# check for sysctl duplicate constants
7398 if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
7399 WARN("DUPLICATED_SYSCTL_CONST",
7400 "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
7401 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08007402 }
7403
7404 # If we have no input at all, then there is nothing to report on
7405 # so just keep quiet.
7406 if ($#rawlines == -1) {
7407 exit(0);
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07007408 }
7409
Andy Whitcroft8905a672007-11-28 16:21:06 -08007410 # In mailback mode only produce a report in the negative, for
7411 # things that appear to be patches.
7412 if ($mailback && ($clean == 1 || !$is_patch)) {
7413 exit(0);
7414 }
7415
Dwaipayan Raye73d2712020-12-15 20:44:56 -08007416 # This is not a patch, and we are in 'no-patch' mode so
Andy Whitcroft8905a672007-11-28 16:21:06 -08007417 # just keep quiet.
7418 if (!$chk_patch && !$is_patch) {
7419 exit(0);
7420 }
7421
Stafford Hornea08ffbe2017-10-03 16:16:51 -07007422 if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
Joe Perches000d1cc12011-07-25 17:13:25 -07007423 ERROR("NOT_UNIFIED_DIFF",
7424 "Does not appear to be a unified-diff format patch\n");
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07007425 }
Geert Uytterhoevencd261492018-08-21 21:57:40 -07007426 if ($is_patch && $has_commit_log && $chk_signoff) {
7427 if ($signoff == 0) {
7428 ERROR("MISSING_SIGN_OFF",
7429 "Missing Signed-off-by: line(s)\n");
Dwaipayan Ray48ca2d82020-10-15 20:12:28 -07007430 } elsif ($authorsignoff != 1) {
7431 # authorsignoff values:
7432 # 0 -> missing sign off
7433 # 1 -> sign off identical
7434 # 2 -> names and addresses match, comments mismatch
7435 # 3 -> addresses match, names different
7436 # 4 -> names match, addresses different
7437 # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
7438
7439 my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
7440
7441 if ($authorsignoff == 0) {
7442 ERROR("NO_AUTHOR_SIGN_OFF",
7443 "Missing Signed-off-by: line by nominal patch author '$author'\n");
7444 } elsif ($authorsignoff == 2) {
7445 CHK("FROM_SIGN_OFF_MISMATCH",
7446 "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
7447 } elsif ($authorsignoff == 3) {
7448 WARN("FROM_SIGN_OFF_MISMATCH",
7449 "From:/Signed-off-by: email name mismatch: $sob_msg\n");
7450 } elsif ($authorsignoff == 4) {
7451 WARN("FROM_SIGN_OFF_MISMATCH",
7452 "From:/Signed-off-by: email address mismatch: $sob_msg\n");
7453 } elsif ($authorsignoff == 5) {
7454 WARN("FROM_SIGN_OFF_MISMATCH",
7455 "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
7456 }
Geert Uytterhoevencd261492018-08-21 21:57:40 -07007457 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07007458 }
7459
Andy Whitcroft8905a672007-11-28 16:21:06 -08007460 print report_dump();
Andy Whitcroft13214ad2008-02-08 04:22:03 -08007461 if ($summary && !($clean == 1 && $quiet == 1)) {
7462 print "$filename " if ($summary_file);
Andy Whitcroft8905a672007-11-28 16:21:06 -08007463 print "total: $cnt_error errors, $cnt_warn warnings, " .
7464 (($check)? "$cnt_chk checks, " : "") .
7465 "$cnt_lines lines checked\n";
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07007466 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08007467
Andy Whitcroftd2c0a232010-10-26 14:23:12 -07007468 if ($quiet == 0) {
Joe Perchesef212192016-05-20 17:04:11 -07007469 # If there were any defects found and not already fixing them
7470 if (!$clean and !$fix) {
7471 print << "EOM"
7472
7473NOTE: For some of the reported defects, checkpatch may be able to
7474 mechanically convert to the typical style using --fix or --fix-inplace.
7475EOM
7476 }
Andy Whitcroftd2c0a232010-10-26 14:23:12 -07007477 # If there were whitespace errors which cleanpatch can fix
7478 # then suggest that.
7479 if ($rpt_cleaners) {
Mike Frysingerb0781212011-03-22 16:34:43 -07007480 $rpt_cleaners = 0;
Joe Perchesd8469f12015-06-25 15:03:00 -07007481 print << "EOM"
7482
7483NOTE: Whitespace errors detected.
7484 You may wish to use scripts/cleanpatch or scripts/cleanfile
7485EOM
Andy Whitcroftd2c0a232010-10-26 14:23:12 -07007486 }
7487 }
7488
Joe Perchesd752fcc2014-08-06 16:11:05 -07007489 if ($clean == 0 && $fix &&
7490 ("@rawlines" ne "@fixed" ||
7491 $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
Joe Perches9624b8d2014-01-23 15:54:44 -08007492 my $newfile = $filename;
7493 $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
Joe Perches3705ce52013-07-03 15:05:31 -07007494 my $linecount = 0;
7495 my $f;
7496
Joe Perchesd752fcc2014-08-06 16:11:05 -07007497 @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7498
Joe Perches3705ce52013-07-03 15:05:31 -07007499 open($f, '>', $newfile)
7500 or die "$P: Can't open $newfile for write\n";
7501 foreach my $fixed_line (@fixed) {
7502 $linecount++;
7503 if ($file) {
7504 if ($linecount > 3) {
7505 $fixed_line =~ s/^\+//;
Joe Perchesd752fcc2014-08-06 16:11:05 -07007506 print $f $fixed_line . "\n";
Joe Perches3705ce52013-07-03 15:05:31 -07007507 }
7508 } else {
7509 print $f $fixed_line . "\n";
7510 }
7511 }
7512 close($f);
7513
7514 if (!$quiet) {
7515 print << "EOM";
Joe Perchesd8469f12015-06-25 15:03:00 -07007516
Joe Perches3705ce52013-07-03 15:05:31 -07007517Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
7518
7519Do _NOT_ trust the results written to this file.
7520Do _NOT_ submit these changes without inspecting them for correctness.
7521
7522This EXPERIMENTAL file is simply a convenience to help rewrite patches.
7523No warranties, expressed or implied...
Joe Perches3705ce52013-07-03 15:05:31 -07007524EOM
7525 }
7526 }
7527
Joe Perchesd8469f12015-06-25 15:03:00 -07007528 if ($quiet == 0) {
7529 print "\n";
7530 if ($clean == 1) {
7531 print "$vname has no obvious style problems and is ready for submission.\n";
7532 } else {
7533 print "$vname has style problems, please review.\n";
7534 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07007535 }
Andy Whitcroft0a920b5b2007-06-01 00:46:48 -07007536 return $clean;
7537}