Kamil Rytarowski | cb77f0d | 2017-05-07 23:25:26 +0200 | [diff] [blame] | 1 | #!/usr/bin/env perl |
Joe Perches | 882ea1d | 2018-06-07 17:04:33 -0700 | [diff] [blame] | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | # |
Dave Jones | dbf004d | 2010-01-12 16:59:52 -0500 | [diff] [blame] | 4 | # (c) 2001, Dave Jones. (the file handling bit) |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 5 | # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) |
Andy Whitcroft | 2a5a2c2 | 2009-01-06 14:41:23 -0800 | [diff] [blame] | 6 | # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) |
Andy Whitcroft | 015830be | 2010-10-26 14:23:17 -0700 | [diff] [blame] | 7 | # (c) 2008-2010 Andy Whitcroft <apw@canonical.com> |
Joe Perches | 882ea1d | 2018-06-07 17:04:33 -0700 | [diff] [blame] | 8 | # (c) 2010-2018 Joe Perches <joe@perches.com> |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 9 | |
| 10 | use strict; |
Kamil Rytarowski | cb77f0d | 2017-05-07 23:25:26 +0200 | [diff] [blame] | 11 | use warnings; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 12 | use POSIX; |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 13 | use File::Basename; |
| 14 | use Cwd 'abs_path'; |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 15 | use Term::ANSIColor qw(:constants); |
Geert Uytterhoeven | cd26149 | 2018-08-21 21:57:40 -0700 | [diff] [blame] | 16 | use Encode qw(decode encode); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 17 | |
| 18 | my $P = $0; |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 19 | my $D = dirname(abs_path($P)); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 20 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 21 | my $V = '0.32'; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 22 | |
| 23 | use Getopt::Long qw(:config no_auto_abbrev); |
| 24 | |
| 25 | my $quiet = 0; |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 26 | my $verbose = 0; |
| 27 | my %verbose_messages = (); |
| 28 | my %verbose_emitted = (); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 29 | my $tree = 1; |
| 30 | my $chk_signoff = 1; |
| 31 | my $chk_patch = 1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 32 | my $tst_only; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 33 | my $emacs = 0; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 34 | my $terse = 0; |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 35 | my $showfile = 0; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 36 | my $file = 0; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 37 | my $git = 0; |
Joe Perches | 0dea9f1e | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 38 | my %git_commits = (); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 39 | my $check = 0; |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 40 | my $check_orig = 0; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 41 | my $summary = 1; |
| 42 | my $mailback = 0; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 43 | my $summary_file = 0; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 44 | my $show_types = 0; |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 45 | my $list_types = 0; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 46 | my $fix = 0; |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 47 | my $fix_inplace = 0; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 48 | my $root; |
Joe Perches | 0f7f635 | 2020-10-24 16:59:04 -0700 | [diff] [blame] | 49 | my $gitroot = $ENV{'GIT_DIR'}; |
| 50 | $gitroot = ".git" if !defined($gitroot); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 51 | my %debug; |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 52 | my %camelcase = (); |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 53 | my %use_type = (); |
| 54 | my @use = (); |
| 55 | my %ignore_type = (); |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 56 | my @ignore = (); |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 57 | my $help = 0; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 58 | my $configuration_file = ".checkpatch.conf"; |
Joe Perches | bdc48fa | 2020-05-29 16:12:21 -0700 | [diff] [blame] | 59 | my $max_line_length = 100; |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 60 | my $ignore_perl_version = 0; |
| 61 | my $minimum_perl_version = 5.10.0; |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 62 | my $min_conf_desc_length = 4; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 63 | my $spelling_file = "$D/spelling.txt"; |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 64 | my $codespell = 0; |
Maxim Uvarov | f1a6367 | 2015-06-25 15:03:08 -0700 | [diff] [blame] | 65 | my $codespellfile = "/usr/share/codespell/dictionary.txt"; |
Peter Ujfalusi | 0ee3e7b | 2021-11-08 18:33:34 -0800 | [diff] [blame] | 66 | my $user_codespellfile = ""; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 67 | my $conststructsfile = "$D/const_structs.checkpatch"; |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 68 | my $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst"; |
Quentin Monnet | ced69da1 | 2020-08-11 18:35:13 -0700 | [diff] [blame] | 69 | my $typedefsfile; |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 70 | my $color = "auto"; |
Vadim Bendebury | 98005e8 | 2019-03-07 16:28:38 -0800 | [diff] [blame] | 71 | my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE |
Joe Perches | dbbf869 | 2019-09-25 16:46:52 -0700 | [diff] [blame] | 72 | # git output parsing needs US English output, so first set backtick child process LANGUAGE |
| 73 | my $git_command ='export LANGUAGE=en_US.UTF-8; git'; |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 74 | my $tabsize = 8; |
Jerome Forissier | 3e89ad8 | 2020-10-15 20:11:49 -0700 | [diff] [blame] | 75 | my ${CONFIG_} = "CONFIG_"; |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 76 | |
| 77 | sub help { |
| 78 | my ($exitcode) = @_; |
| 79 | |
| 80 | print << "EOM"; |
| 81 | Usage: $P [OPTION]... [FILE]... |
| 82 | Version: $V |
| 83 | |
| 84 | Options: |
| 85 | -q, --quiet quiet |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 86 | -v, --verbose verbose mode |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 87 | --no-tree run without a kernel tree |
| 88 | --no-signoff do not check for 'Signed-off-by' line |
| 89 | --patch treat FILE as patchfile (default) |
| 90 | --emacs emacs compile window format |
| 91 | --terse one line per report |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 92 | --showfile emit diffed file position, not input file position |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 93 | -g, --git treat FILE as a single commit or git revision range |
| 94 | single git commit with: |
| 95 | <rev> |
| 96 | <rev>^ |
| 97 | <rev>~n |
| 98 | multiple git commits with: |
| 99 | <rev1>..<rev2> |
| 100 | <rev1>...<rev2> |
| 101 | <rev>-<count> |
| 102 | git merges are ignored |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 103 | -f, --file treat FILE as regular source file |
| 104 | --subjective, --strict enable more subjective tests |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 105 | --list-types list the possible message types |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 106 | --types TYPE(,TYPE2...) show only these comma separated message types |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 107 | --ignore TYPE(,TYPE2...) ignore various comma separated message types |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 108 | --show-types show the specific message type in the output |
Joe Perches | bdc48fa | 2020-05-29 16:12:21 -0700 | [diff] [blame] | 109 | --max-line-length=n set the maximum line length, (default $max_line_length) |
| 110 | if exceeded, warn on patches |
| 111 | requires --strict for use with --file |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 112 | --min-conf-desc-length=n set the min description length, if shorter, warn |
Joe Perches | bdc48fa | 2020-05-29 16:12:21 -0700 | [diff] [blame] | 113 | --tab-size=n set the number of spaces for tab (default $tabsize) |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 114 | --root=PATH PATH to the kernel tree root |
| 115 | --no-summary suppress the per-file summary |
| 116 | --mailback only produce a report in case of warnings/errors |
| 117 | --summary-file include the filename in summary |
| 118 | --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of |
| 119 | 'values', 'possible', 'type', and 'attr' (default |
| 120 | is all off) |
| 121 | --test-only=WORD report only warnings/errors containing WORD |
| 122 | literally |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 123 | --fix EXPERIMENTAL - may create horrible results |
| 124 | If correctable single-line errors exist, create |
| 125 | "<inputfile>.EXPERIMENTAL-checkpatch-fixes" |
| 126 | with potential errors corrected to the preferred |
| 127 | checkpatch style |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 128 | --fix-inplace EXPERIMENTAL - may create horrible results |
| 129 | Is the same as --fix, but overwrites the input |
| 130 | file. It's your fault if there's no backup or git |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 131 | --ignore-perl-version override checking of perl version. expect |
| 132 | runtime errors. |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 133 | --codespell Use the codespell dictionary for spelling/typos |
Peter Ujfalusi | 0ee3e7b | 2021-11-08 18:33:34 -0800 | [diff] [blame] | 134 | (default:$codespellfile) |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 135 | --codespellfile Use this codespell dictionary |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 136 | --typedefsfile Read additional types from this file |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 137 | --color[=WHEN] Use colors 'always', 'never', or only when output |
| 138 | is a terminal ('auto'). Default is 'auto'. |
Jerome Forissier | 3e89ad8 | 2020-10-15 20:11:49 -0700 | [diff] [blame] | 139 | --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default |
| 140 | ${CONFIG_}) |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 141 | -h, --help, --version display this help and exit |
| 142 | |
| 143 | When FILE is - read standard input. |
| 144 | EOM |
| 145 | |
| 146 | exit($exitcode); |
| 147 | } |
| 148 | |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 149 | sub uniq { |
| 150 | my %seen; |
| 151 | return grep { !$seen{$_}++ } @_; |
| 152 | } |
| 153 | |
| 154 | sub list_types { |
| 155 | my ($exitcode) = @_; |
| 156 | |
| 157 | my $count = 0; |
| 158 | |
| 159 | local $/ = undef; |
| 160 | |
| 161 | open(my $script, '<', abs_path($P)) or |
| 162 | die "$P: Can't read '$P' $!\n"; |
| 163 | |
| 164 | my $text = <$script>; |
| 165 | close($script); |
| 166 | |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 167 | my %types = (); |
Jean Delvare | 0547fa5 | 2017-09-08 16:16:11 -0700 | [diff] [blame] | 168 | # Also catch when type or level is passed through a variable |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 169 | while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { |
| 170 | if (defined($1)) { |
| 171 | if (exists($types{$2})) { |
| 172 | $types{$2} .= ",$1" if ($types{$2} ne $1); |
| 173 | } else { |
| 174 | $types{$2} = $1; |
| 175 | } |
| 176 | } else { |
| 177 | $types{$2} = "UNDETERMINED"; |
| 178 | } |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 179 | } |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 180 | |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 181 | print("#\tMessage type\n\n"); |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 182 | if ($color) { |
| 183 | print(" ( Color coding: "); |
| 184 | print(RED . "ERROR" . RESET); |
| 185 | print(" | "); |
| 186 | print(YELLOW . "WARNING" . RESET); |
| 187 | print(" | "); |
| 188 | print(GREEN . "CHECK" . RESET); |
| 189 | print(" | "); |
| 190 | print("Multiple levels / Undetermined"); |
| 191 | print(" )\n\n"); |
| 192 | } |
| 193 | |
| 194 | foreach my $type (sort keys %types) { |
| 195 | my $orig_type = $type; |
| 196 | if ($color) { |
| 197 | my $level = $types{$type}; |
| 198 | if ($level eq "ERROR") { |
| 199 | $type = RED . $type . RESET; |
| 200 | } elsif ($level eq "WARN") { |
| 201 | $type = YELLOW . $type . RESET; |
| 202 | } elsif ($level eq "CHK") { |
| 203 | $type = GREEN . $type . RESET; |
| 204 | } |
| 205 | } |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 206 | print(++$count . "\t" . $type . "\n"); |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 207 | if ($verbose && exists($verbose_messages{$orig_type})) { |
| 208 | my $message = $verbose_messages{$orig_type}; |
| 209 | $message =~ s/\n/\n\t/g; |
| 210 | print("\t" . $message . "\n\n"); |
| 211 | } |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 212 | } |
| 213 | |
| 214 | exit($exitcode); |
| 215 | } |
| 216 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 217 | my $conf = which_conf($configuration_file); |
| 218 | if (-f $conf) { |
| 219 | my @conf_args; |
| 220 | open(my $conffile, '<', "$conf") |
| 221 | or warn "$P: Can't find a readable $configuration_file file $!\n"; |
| 222 | |
| 223 | while (<$conffile>) { |
| 224 | my $line = $_; |
| 225 | |
| 226 | $line =~ s/\s*\n?$//g; |
| 227 | $line =~ s/^\s*//g; |
| 228 | $line =~ s/\s+/ /g; |
| 229 | |
| 230 | next if ($line =~ m/^\s*#/); |
| 231 | next if ($line =~ m/^\s*$/); |
| 232 | |
| 233 | my @words = split(" ", $line); |
| 234 | foreach my $word (@words) { |
| 235 | last if ($word =~ m/^#/); |
| 236 | push (@conf_args, $word); |
| 237 | } |
| 238 | } |
| 239 | close($conffile); |
| 240 | unshift(@ARGV, @conf_args) if @conf_args; |
| 241 | } |
| 242 | |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 243 | sub load_docs { |
| 244 | open(my $docs, '<', "$docsfile") |
| 245 | or warn "$P: Can't read the documentation file $docsfile $!\n"; |
| 246 | |
| 247 | my $type = ''; |
| 248 | my $desc = ''; |
| 249 | my $in_desc = 0; |
| 250 | |
| 251 | while (<$docs>) { |
| 252 | chomp; |
| 253 | my $line = $_; |
| 254 | $line =~ s/\s+$//; |
| 255 | |
| 256 | if ($line =~ /^\s*\*\*(.+)\*\*$/) { |
| 257 | if ($desc ne '') { |
| 258 | $verbose_messages{$type} = trim($desc); |
| 259 | } |
| 260 | $type = $1; |
| 261 | $desc = ''; |
| 262 | $in_desc = 1; |
| 263 | } elsif ($in_desc) { |
| 264 | if ($line =~ /^(?:\s{4,}|$)/) { |
| 265 | $line =~ s/^\s{4}//; |
| 266 | $desc .= $line; |
| 267 | $desc .= "\n"; |
| 268 | } else { |
| 269 | $verbose_messages{$type} = trim($desc); |
| 270 | $type = ''; |
| 271 | $desc = ''; |
| 272 | $in_desc = 0; |
| 273 | } |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | if ($desc ne '') { |
| 278 | $verbose_messages{$type} = trim($desc); |
| 279 | } |
| 280 | close($docs); |
| 281 | } |
| 282 | |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 283 | # Perl's Getopt::Long allows options to take optional arguments after a space. |
| 284 | # Prevent --color by itself from consuming other arguments |
| 285 | foreach (@ARGV) { |
| 286 | if ($_ eq "--color" || $_ eq "-color") { |
| 287 | $_ = "--color=$color"; |
| 288 | } |
| 289 | } |
| 290 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 291 | GetOptions( |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 292 | 'q|quiet+' => \$quiet, |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 293 | 'v|verbose!' => \$verbose, |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 294 | 'tree!' => \$tree, |
| 295 | 'signoff!' => \$chk_signoff, |
| 296 | 'patch!' => \$chk_patch, |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 297 | 'emacs!' => \$emacs, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 298 | 'terse!' => \$terse, |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 299 | 'showfile!' => \$showfile, |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 300 | 'f|file!' => \$file, |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 301 | 'g|git!' => \$git, |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 302 | 'subjective!' => \$check, |
| 303 | 'strict!' => \$check, |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 304 | 'ignore=s' => \@ignore, |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 305 | 'types=s' => \@use, |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 306 | 'show-types!' => \$show_types, |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 307 | 'list-types!' => \$list_types, |
Joe Perches | 6cd7f38 | 2012-12-17 16:01:54 -0800 | [diff] [blame] | 308 | 'max-line-length=i' => \$max_line_length, |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 309 | 'min-conf-desc-length=i' => \$min_conf_desc_length, |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 310 | 'tab-size=i' => \$tabsize, |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 311 | 'root=s' => \$root, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 312 | 'summary!' => \$summary, |
| 313 | 'mailback!' => \$mailback, |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 314 | 'summary-file!' => \$summary_file, |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 315 | 'fix!' => \$fix, |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 316 | 'fix-inplace!' => \$fix_inplace, |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 317 | 'ignore-perl-version!' => \$ignore_perl_version, |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 318 | 'debug=s' => \%debug, |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 319 | 'test-only=s' => \$tst_only, |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 320 | 'codespell!' => \$codespell, |
Peter Ujfalusi | 0ee3e7b | 2021-11-08 18:33:34 -0800 | [diff] [blame] | 321 | 'codespellfile=s' => \$user_codespellfile, |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 322 | 'typedefsfile=s' => \$typedefsfile, |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 323 | 'color=s' => \$color, |
| 324 | 'no-color' => \$color, #keep old behaviors of -nocolor |
| 325 | 'nocolor' => \$color, #keep old behaviors of -nocolor |
Jerome Forissier | 3e89ad8 | 2020-10-15 20:11:49 -0700 | [diff] [blame] | 326 | 'kconfig-prefix=s' => \${CONFIG_}, |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 327 | 'h|help' => \$help, |
| 328 | 'version' => \$help |
Peter Ujfalusi | 0ee3e7b | 2021-11-08 18:33:34 -0800 | [diff] [blame] | 329 | ) or $help = 2; |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 330 | |
Peter Ujfalusi | 0ee3e7b | 2021-11-08 18:33:34 -0800 | [diff] [blame] | 331 | if ($user_codespellfile) { |
| 332 | # Use the user provided codespell file unconditionally |
| 333 | $codespellfile = $user_codespellfile; |
| 334 | } elsif (!(-f $codespellfile)) { |
| 335 | # If /usr/share/codespell/dictionary.txt is not present, try to find it |
| 336 | # under codespell's install directory: <codespell_root>/data/dictionary.txt |
| 337 | if (($codespell || $help) && which("codespell") ne "" && which("python") ne "") { |
| 338 | my $python_codespell_dict = << "EOF"; |
| 339 | |
| 340 | import os.path as op |
| 341 | import codespell_lib |
| 342 | codespell_dir = op.dirname(codespell_lib.__file__) |
| 343 | codespell_file = op.join(codespell_dir, 'data', 'dictionary.txt') |
| 344 | print(codespell_file, end='') |
| 345 | EOF |
| 346 | |
| 347 | my $codespell_dict = `python -c "$python_codespell_dict" 2> /dev/null`; |
| 348 | $codespellfile = $codespell_dict if (-f $codespell_dict); |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | # $help is 1 if either -h, --help or --version is passed as option - exitcode: 0 |
| 353 | # $help is 2 if invalid option is passed - exitcode: 1 |
| 354 | help($help - 1) if ($help); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 355 | |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 356 | die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); |
| 357 | die "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse); |
| 358 | |
| 359 | if ($color =~ /^[01]$/) { |
| 360 | $color = !$color; |
| 361 | } elsif ($color =~ /^always$/i) { |
| 362 | $color = 1; |
| 363 | } elsif ($color =~ /^never$/i) { |
| 364 | $color = 0; |
| 365 | } elsif ($color =~ /^auto$/i) { |
| 366 | $color = (-t STDOUT); |
| 367 | } else { |
| 368 | die "$P: Invalid color mode: $color\n"; |
| 369 | } |
| 370 | |
| 371 | load_docs() if ($verbose); |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 372 | list_types(0) if ($list_types); |
| 373 | |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 374 | $fix = 1 if ($fix_inplace); |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 375 | $check_orig = $check; |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 376 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 377 | my $exit = 0; |
| 378 | |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 379 | my $perl_version_ok = 1; |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 380 | if ($^V && $^V lt $minimum_perl_version) { |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 381 | $perl_version_ok = 0; |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 382 | printf "$P: requires at least perl version %vd\n", $minimum_perl_version; |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 383 | exit(1) if (!$ignore_perl_version); |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 384 | } |
| 385 | |
Allen Hubbe | 45107ff | 2016-08-02 14:04:47 -0700 | [diff] [blame] | 386 | #if no filenames are given, push '-' to read patch from stdin |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 387 | if ($#ARGV < 0) { |
Allen Hubbe | 45107ff | 2016-08-02 14:04:47 -0700 | [diff] [blame] | 388 | push(@ARGV, '-'); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 389 | } |
| 390 | |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 391 | # skip TAB size 1 to avoid additional checks on $tabsize - 1 |
Joe Perches | 32f30ca | 2020-06-04 16:50:40 -0700 | [diff] [blame] | 392 | die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 393 | |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 394 | sub hash_save_array_words { |
| 395 | my ($hashRef, $arrayRef) = @_; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 396 | |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 397 | my @array = split(/,/, join(',', @$arrayRef)); |
| 398 | foreach my $word (@array) { |
| 399 | $word =~ s/\s*\n?$//g; |
| 400 | $word =~ s/^\s*//g; |
| 401 | $word =~ s/\s+/ /g; |
| 402 | $word =~ tr/[a-z]/[A-Z]/; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 403 | |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 404 | next if ($word =~ m/^\s*#/); |
| 405 | next if ($word =~ m/^\s*$/); |
| 406 | |
| 407 | $hashRef->{$word}++; |
| 408 | } |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 409 | } |
| 410 | |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 411 | sub hash_show_words { |
| 412 | my ($hashRef, $prefix) = @_; |
| 413 | |
Joe Perches | 3c816e4 | 2015-06-25 15:03:29 -0700 | [diff] [blame] | 414 | if (keys %$hashRef) { |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 415 | print "\nNOTE: $prefix message types:"; |
Joe Perches | 58cb3cf | 2013-09-11 14:24:04 -0700 | [diff] [blame] | 416 | foreach my $word (sort keys %$hashRef) { |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 417 | print " $word"; |
| 418 | } |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 419 | print "\n"; |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 420 | } |
| 421 | } |
| 422 | |
| 423 | hash_save_array_words(\%ignore_type, \@ignore); |
| 424 | hash_save_array_words(\%use_type, \@use); |
| 425 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 426 | my $dbg_values = 0; |
| 427 | my $dbg_possible = 0; |
Andy Whitcroft | 7429c69 | 2008-07-23 21:29:06 -0700 | [diff] [blame] | 428 | my $dbg_type = 0; |
Andy Whitcroft | a1ef277 | 2008-10-15 22:02:17 -0700 | [diff] [blame] | 429 | my $dbg_attr = 0; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 430 | for my $key (keys %debug) { |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 431 | ## no critic |
| 432 | eval "\${dbg_$key} = '$debug{$key}';"; |
| 433 | die "$@" if ($@); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 434 | } |
| 435 | |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 436 | my $rpt_cleaners = 0; |
| 437 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 438 | if ($terse) { |
| 439 | $emacs = 1; |
| 440 | $quiet++; |
| 441 | } |
| 442 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 443 | if ($tree) { |
| 444 | if (defined $root) { |
| 445 | if (!top_of_kernel_tree($root)) { |
| 446 | die "$P: $root: --root does not point at a valid tree\n"; |
| 447 | } |
| 448 | } else { |
| 449 | if (top_of_kernel_tree('.')) { |
| 450 | $root = '.'; |
| 451 | } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && |
| 452 | top_of_kernel_tree($1)) { |
| 453 | $root = $1; |
| 454 | } |
| 455 | } |
| 456 | |
| 457 | if (!defined $root) { |
| 458 | print "Must be run from the top-level dir. of a kernel tree\n"; |
| 459 | exit(2); |
| 460 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 461 | } |
| 462 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 463 | my $emitted_corrupt = 0; |
| 464 | |
Andy Whitcroft | 2ceb532 | 2009-10-26 16:50:14 -0700 | [diff] [blame] | 465 | our $Ident = qr{ |
| 466 | [A-Za-z_][A-Za-z\d_]* |
| 467 | (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* |
| 468 | }x; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 469 | our $Storage = qr{extern|static|asmlinkage}; |
| 470 | our $Sparse = qr{ |
| 471 | __user| |
| 472 | __kernel| |
| 473 | __force| |
| 474 | __iomem| |
| 475 | __must_check| |
Andy Whitcroft | 417495e | 2009-02-27 14:03:08 -0800 | [diff] [blame] | 476 | __kprobes| |
Sven Eckelmann | 165e72a | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 477 | __ref| |
Geert Uytterhoeven | 33aa459 | 2018-08-21 21:57:36 -0700 | [diff] [blame] | 478 | __refconst| |
| 479 | __refdata| |
Boqun Feng | ad31545 | 2015-12-29 12:18:46 +0800 | [diff] [blame] | 480 | __rcu| |
| 481 | __private |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 482 | }x; |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 483 | our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; |
| 484 | our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; |
| 485 | our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; |
| 486 | our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; |
| 487 | our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 488 | |
Wolfram Sang | 5213129 | 2010-03-05 13:43:51 -0800 | [diff] [blame] | 489 | # Notes to $Attribute: |
| 490 | # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 491 | our $Attribute = qr{ |
| 492 | const| |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 493 | volatile| |
Joe Perches | 03f1df7 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 494 | __percpu| |
| 495 | __nocast| |
| 496 | __safe| |
Michael S. Tsirkin | 46d832f | 2016-12-11 06:29:58 +0200 | [diff] [blame] | 497 | __bitwise| |
Joe Perches | 03f1df7 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 498 | __packed__| |
| 499 | __packed2__| |
| 500 | __naked| |
| 501 | __maybe_unused| |
| 502 | __always_unused| |
| 503 | __noreturn| |
| 504 | __used| |
| 505 | __cold| |
Joe Perches | e23ef1f | 2015-02-13 14:38:24 -0800 | [diff] [blame] | 506 | __pure| |
Joe Perches | 03f1df7 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 507 | __noclone| |
| 508 | __deprecated| |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 509 | __read_mostly| |
Joe Perches | c5967e9 | 2018-09-04 15:46:20 -0700 | [diff] [blame] | 510 | __ro_after_init| |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 511 | __kprobes| |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 512 | $InitAttribute| |
Andy Whitcroft | 24e1d81 | 2008-10-15 22:02:18 -0700 | [diff] [blame] | 513 | ____cacheline_aligned| |
| 514 | ____cacheline_aligned_in_smp| |
Andy Whitcroft | 5fe3af1 | 2009-01-06 14:41:18 -0800 | [diff] [blame] | 515 | ____cacheline_internodealigned_in_smp| |
Kees Cook | 86cffec | 2021-11-05 13:36:19 -0700 | [diff] [blame] | 516 | __weak| |
| 517 | __alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 518 | }x; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 519 | our $Modifier; |
Joe Perches | 91cb519 | 2014-04-03 14:49:32 -0700 | [diff] [blame] | 520 | our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 521 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; |
| 522 | our $Lval = qr{$Ident(?:$Member)*}; |
| 523 | |
Joe Perches | 95e2c60 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 524 | our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; |
| 525 | our $Binary = qr{(?i)0b[01]+$Int_type?}; |
| 526 | our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; |
| 527 | our $Int = qr{[0-9]+$Int_type?}; |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 528 | our $Octal = qr{0[0-7]+$Int_type?}; |
Joe Perches | d2af5aa | 2021-09-07 19:59:51 -0700 | [diff] [blame] | 529 | our $String = qr{(?:\b[Lu])?"[X\t]*"}; |
Joe Perches | 326b1ff | 2013-02-04 14:28:51 -0800 | [diff] [blame] | 530 | our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; |
| 531 | our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; |
| 532 | our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; |
Joe Perches | 74349bc | 2012-12-17 16:02:05 -0800 | [diff] [blame] | 533 | our $Float = qr{$Float_hex|$Float_dec|$Float_int}; |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 534 | our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; |
Joe Perches | 326b1ff | 2013-02-04 14:28:51 -0800 | [diff] [blame] | 535 | our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; |
Joe Perches | 447432f | 2014-04-03 14:49:17 -0700 | [diff] [blame] | 536 | our $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; |
Joe Perches | 23f780c | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 537 | our $Arithmetic = qr{\+|-|\*|\/|%}; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 538 | our $Operators = qr{ |
| 539 | <=|>=|==|!=| |
| 540 | =>|->|<<|>>|<|>|!|~| |
Joe Perches | 23f780c | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 541 | &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 542 | }x; |
| 543 | |
Joe Perches | 91cb519 | 2014-04-03 14:49:32 -0700 | [diff] [blame] | 544 | our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; |
| 545 | |
Joe Perches | ab7e23f | 2015-04-16 12:44:22 -0700 | [diff] [blame] | 546 | our $BasicType; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 547 | our $NonptrType; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 548 | our $NonptrTypeMisordered; |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 549 | our $NonptrTypeWithAttr; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 550 | our $Type; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 551 | our $TypeMisordered; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 552 | our $Declare; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 553 | our $DeclareMisordered; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 554 | |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 555 | our $NON_ASCII_UTF8 = qr{ |
| 556 | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 557 | | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs |
| 558 | | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte |
| 559 | | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates |
| 560 | | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 |
| 561 | | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 |
| 562 | | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 |
| 563 | }x; |
| 564 | |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 565 | our $UTF8 = qr{ |
| 566 | [\x09\x0A\x0D\x20-\x7E] # ASCII |
| 567 | | $NON_ASCII_UTF8 |
| 568 | }x; |
| 569 | |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 570 | our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; |
Joe Perches | 021158b | 2015-02-13 14:38:43 -0800 | [diff] [blame] | 571 | our $typeOtherOSTypedefs = qr{(?x: |
| 572 | u_(?:char|short|int|long) | # bsd |
| 573 | u(?:nchar|short|int|long) # sysv |
| 574 | )}; |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 575 | our $typeKernelTypedefs = qr{(?x: |
Andy Whitcroft | fb9e909 | 2009-09-21 17:04:38 -0700 | [diff] [blame] | 576 | (?:__)?(?:u|s|be|le)(?:8|16|32|64)| |
Andy Whitcroft | 8ed22ca | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 577 | atomic_t |
| 578 | )}; |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 579 | our $typeTypedefs = qr{(?x: |
| 580 | $typeC99Typedefs\b| |
| 581 | $typeOtherOSTypedefs\b| |
| 582 | $typeKernelTypedefs\b |
| 583 | )}; |
Andy Whitcroft | 8ed22ca | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 584 | |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 585 | our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; |
| 586 | |
Joe Perches | 691e669 | 2010-03-05 13:43:51 -0800 | [diff] [blame] | 587 | our $logFunctions = qr{(?x: |
Miles Chen | 758d7aa | 2017-02-24 15:01:34 -0800 | [diff] [blame] | 588 | printk(?:_ratelimited|_once|_deferred_once|_deferred|)| |
Jacob Keller | 7d0b659 | 2013-07-03 15:05:35 -0700 | [diff] [blame] | 589 | (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| |
Joe Perches | 87bd499 | 2017-11-17 15:28:48 -0800 | [diff] [blame] | 590 | TP_printk| |
Joe Perches | 6e60c02 | 2011-07-25 17:13:27 -0700 | [diff] [blame] | 591 | WARN(?:_RATELIMIT|_ONCE|)| |
Joe Perches | b053172 | 2011-05-24 17:13:40 -0700 | [diff] [blame] | 592 | panic| |
Joe Perches | 0666872 | 2013-11-12 15:10:07 -0800 | [diff] [blame] | 593 | MODULE_[A-Z_]+| |
| 594 | seq_vprintf|seq_printf|seq_puts |
Joe Perches | 691e669 | 2010-03-05 13:43:51 -0800 | [diff] [blame] | 595 | )}; |
| 596 | |
Joe Perches | e29a70f | 2019-03-07 16:28:35 -0800 | [diff] [blame] | 597 | our $allocFunctions = qr{(?x: |
| 598 | (?:(?:devm_)? |
Joe Perches | 58f0226 | 2021-02-25 17:22:01 -0800 | [diff] [blame] | 599 | (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? | |
Joe Perches | e29a70f | 2019-03-07 16:28:35 -0800 | [diff] [blame] | 600 | kstrdup(?:_const)? | |
| 601 | kmemdup(?:_nul)?) | |
Christophe JAILLET | 461e156 | 2020-04-20 18:13:58 -0700 | [diff] [blame] | 602 | (?:\w+)?alloc_skb(?:_ip_align)? | |
Joe Perches | e29a70f | 2019-03-07 16:28:35 -0800 | [diff] [blame] | 603 | # dev_alloc_skb/netdev_alloc_skb, et al |
| 604 | dma_alloc_coherent |
| 605 | )}; |
| 606 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 607 | our $signature_tags = qr{(?xi: |
| 608 | Signed-off-by:| |
Jorge Ramirez-Ortiz | d499480 | 2019-01-03 15:29:12 -0800 | [diff] [blame] | 609 | Co-developed-by:| |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 610 | Acked-by:| |
| 611 | Tested-by:| |
| 612 | Reviewed-by:| |
| 613 | Reported-by:| |
Mugunthan V N | 8543ae1 | 2013-04-29 16:18:17 -0700 | [diff] [blame] | 614 | Suggested-by:| |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 615 | To:| |
| 616 | Cc: |
| 617 | )}; |
| 618 | |
Joe Perches | adb2da8 | 2021-02-25 17:21:50 -0800 | [diff] [blame] | 619 | our $tracing_logging_tags = qr{(?xi: |
| 620 | [=-]*> | |
| 621 | <[=-]* | |
| 622 | \[ | |
| 623 | \] | |
| 624 | start | |
| 625 | called | |
| 626 | entered | |
| 627 | entry | |
| 628 | enter | |
| 629 | in | |
| 630 | inside | |
| 631 | here | |
| 632 | begin | |
| 633 | exit | |
| 634 | end | |
| 635 | done | |
| 636 | leave | |
| 637 | completed | |
| 638 | out | |
| 639 | return | |
| 640 | [\.\!:\s]* |
| 641 | )}; |
| 642 | |
Aditya Srivastava | 831242a | 2020-12-15 20:45:12 -0800 | [diff] [blame] | 643 | sub edit_distance_min { |
| 644 | my (@arr) = @_; |
| 645 | my $len = scalar @arr; |
| 646 | if ((scalar @arr) < 1) { |
| 647 | # if underflow, return |
| 648 | return; |
| 649 | } |
| 650 | my $min = $arr[0]; |
| 651 | for my $i (0 .. ($len-1)) { |
| 652 | if ($arr[$i] < $min) { |
| 653 | $min = $arr[$i]; |
| 654 | } |
| 655 | } |
| 656 | return $min; |
| 657 | } |
| 658 | |
| 659 | sub get_edit_distance { |
| 660 | my ($str1, $str2) = @_; |
| 661 | $str1 = lc($str1); |
| 662 | $str2 = lc($str2); |
| 663 | $str1 =~ s/-//g; |
| 664 | $str2 =~ s/-//g; |
| 665 | my $len1 = length($str1); |
| 666 | my $len2 = length($str2); |
| 667 | # two dimensional array storing minimum edit distance |
| 668 | my @distance; |
| 669 | for my $i (0 .. $len1) { |
| 670 | for my $j (0 .. $len2) { |
| 671 | if ($i == 0) { |
| 672 | $distance[$i][$j] = $j; |
| 673 | } elsif ($j == 0) { |
| 674 | $distance[$i][$j] = $i; |
| 675 | } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { |
| 676 | $distance[$i][$j] = $distance[$i - 1][$j - 1]; |
| 677 | } else { |
| 678 | my $dist1 = $distance[$i][$j - 1]; #insert distance |
| 679 | my $dist2 = $distance[$i - 1][$j]; # remove |
| 680 | my $dist3 = $distance[$i - 1][$j - 1]; #replace |
| 681 | $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); |
| 682 | } |
| 683 | } |
| 684 | } |
| 685 | return $distance[$len1][$len2]; |
| 686 | } |
| 687 | |
| 688 | sub find_standard_signature { |
| 689 | my ($sign_off) = @_; |
| 690 | my @standard_signature_tags = ( |
| 691 | 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', |
| 692 | 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' |
| 693 | ); |
| 694 | foreach my $signature (@standard_signature_tags) { |
| 695 | return $signature if (get_edit_distance($sign_off, $signature) <= 2); |
| 696 | } |
| 697 | |
| 698 | return ""; |
| 699 | } |
| 700 | |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 701 | our @typeListMisordered = ( |
| 702 | qr{char\s+(?:un)?signed}, |
| 703 | qr{int\s+(?:(?:un)?signed\s+)?short\s}, |
| 704 | qr{int\s+short(?:\s+(?:un)?signed)}, |
| 705 | qr{short\s+int(?:\s+(?:un)?signed)}, |
| 706 | qr{(?:un)?signed\s+int\s+short}, |
| 707 | qr{short\s+(?:un)?signed}, |
| 708 | qr{long\s+int\s+(?:un)?signed}, |
| 709 | qr{int\s+long\s+(?:un)?signed}, |
| 710 | qr{long\s+(?:un)?signed\s+int}, |
| 711 | qr{int\s+(?:un)?signed\s+long}, |
| 712 | qr{int\s+(?:un)?signed}, |
| 713 | qr{int\s+long\s+long\s+(?:un)?signed}, |
| 714 | qr{long\s+long\s+int\s+(?:un)?signed}, |
| 715 | qr{long\s+long\s+(?:un)?signed\s+int}, |
| 716 | qr{long\s+long\s+(?:un)?signed}, |
| 717 | qr{long\s+(?:un)?signed}, |
| 718 | ); |
| 719 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 720 | our @typeList = ( |
| 721 | qr{void}, |
Joe Perches | 0c773d9 | 2014-08-06 16:11:20 -0700 | [diff] [blame] | 722 | qr{(?:(?:un)?signed\s+)?char}, |
| 723 | qr{(?:(?:un)?signed\s+)?short\s+int}, |
| 724 | qr{(?:(?:un)?signed\s+)?short}, |
| 725 | qr{(?:(?:un)?signed\s+)?int}, |
| 726 | qr{(?:(?:un)?signed\s+)?long\s+int}, |
| 727 | qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, |
| 728 | qr{(?:(?:un)?signed\s+)?long\s+long}, |
| 729 | qr{(?:(?:un)?signed\s+)?long}, |
| 730 | qr{(?:un)?signed}, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 731 | qr{float}, |
| 732 | qr{double}, |
| 733 | qr{bool}, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 734 | qr{struct\s+$Ident}, |
| 735 | qr{union\s+$Ident}, |
| 736 | qr{enum\s+$Ident}, |
| 737 | qr{${Ident}_t}, |
| 738 | qr{${Ident}_handler}, |
| 739 | qr{${Ident}_handler_fn}, |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 740 | @typeListMisordered, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 741 | ); |
Joe Perches | 938224b | 2016-01-20 14:59:15 -0800 | [diff] [blame] | 742 | |
| 743 | our $C90_int_types = qr{(?x: |
| 744 | long\s+long\s+int\s+(?:un)?signed| |
| 745 | long\s+long\s+(?:un)?signed\s+int| |
| 746 | long\s+long\s+(?:un)?signed| |
| 747 | (?:(?:un)?signed\s+)?long\s+long\s+int| |
| 748 | (?:(?:un)?signed\s+)?long\s+long| |
| 749 | int\s+long\s+long\s+(?:un)?signed| |
| 750 | int\s+(?:(?:un)?signed\s+)?long\s+long| |
| 751 | |
| 752 | long\s+int\s+(?:un)?signed| |
| 753 | long\s+(?:un)?signed\s+int| |
| 754 | long\s+(?:un)?signed| |
| 755 | (?:(?:un)?signed\s+)?long\s+int| |
| 756 | (?:(?:un)?signed\s+)?long| |
| 757 | int\s+long\s+(?:un)?signed| |
| 758 | int\s+(?:(?:un)?signed\s+)?long| |
| 759 | |
| 760 | int\s+(?:un)?signed| |
| 761 | (?:(?:un)?signed\s+)?int |
| 762 | )}; |
| 763 | |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 764 | our @typeListFile = (); |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 765 | our @typeListWithAttr = ( |
| 766 | @typeList, |
| 767 | qr{struct\s+$InitAttribute\s+$Ident}, |
| 768 | qr{union\s+$InitAttribute\s+$Ident}, |
| 769 | ); |
| 770 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 771 | our @modifierList = ( |
| 772 | qr{fastcall}, |
| 773 | ); |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 774 | our @modifierListFile = (); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 775 | |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 776 | our @mode_permission_funcs = ( |
| 777 | ["module_param", 3], |
| 778 | ["module_param_(?:array|named|string)", 4], |
| 779 | ["module_param_array_named", 5], |
| 780 | ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], |
| 781 | ["proc_create(?:_data|)", 2], |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 782 | ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], |
| 783 | ["IIO_DEV_ATTR_[A-Z_]+", 1], |
| 784 | ["SENSOR_(?:DEVICE_|)ATTR_2", 2], |
| 785 | ["SENSOR_TEMPLATE(?:_2|)", 3], |
| 786 | ["__ATTR", 2], |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 787 | ); |
| 788 | |
Joe Perches | 1a3dcf2 | 2020-08-11 18:35:16 -0700 | [diff] [blame] | 789 | my $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; |
| 790 | |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 791 | #Create a search pattern for all these functions to speed up a loop below |
| 792 | our $mode_perms_search = ""; |
| 793 | foreach my $entry (@mode_permission_funcs) { |
| 794 | $mode_perms_search .= '|' if ($mode_perms_search ne ""); |
| 795 | $mode_perms_search .= $entry->[0]; |
| 796 | } |
Joe Perches | 0018046 | 2018-02-06 15:38:55 -0800 | [diff] [blame] | 797 | $mode_perms_search = "(?:${mode_perms_search})"; |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 798 | |
Joe Perches | 9189c7e | 2018-09-07 15:26:18 -0700 | [diff] [blame] | 799 | our %deprecated_apis = ( |
| 800 | "synchronize_rcu_bh" => "synchronize_rcu", |
| 801 | "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", |
| 802 | "call_rcu_bh" => "call_rcu", |
| 803 | "rcu_barrier_bh" => "rcu_barrier", |
| 804 | "synchronize_sched" => "synchronize_rcu", |
| 805 | "synchronize_sched_expedited" => "synchronize_rcu_expedited", |
| 806 | "call_rcu_sched" => "call_rcu", |
| 807 | "rcu_barrier_sched" => "rcu_barrier", |
| 808 | "get_state_synchronize_sched" => "get_state_synchronize_rcu", |
| 809 | "cond_synchronize_sched" => "cond_synchronize_rcu", |
| 810 | ); |
| 811 | |
| 812 | #Create a search pattern for all these strings to speed up a loop below |
| 813 | our $deprecated_apis_search = ""; |
| 814 | foreach my $entry (keys %deprecated_apis) { |
| 815 | $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); |
| 816 | $deprecated_apis_search .= $entry; |
| 817 | } |
| 818 | $deprecated_apis_search = "(?:${deprecated_apis_search})"; |
| 819 | |
Joe Perches | b392c64 | 2015-04-16 12:44:16 -0700 | [diff] [blame] | 820 | our $mode_perms_world_writable = qr{ |
| 821 | S_IWUGO | |
| 822 | S_IWOTH | |
| 823 | S_IRWXUGO | |
| 824 | S_IALLUGO | |
| 825 | 0[0-7][0-7][2367] |
| 826 | }x; |
| 827 | |
Joe Perches | f90774e | 2016-10-11 13:51:47 -0700 | [diff] [blame] | 828 | our %mode_permission_string_types = ( |
| 829 | "S_IRWXU" => 0700, |
| 830 | "S_IRUSR" => 0400, |
| 831 | "S_IWUSR" => 0200, |
| 832 | "S_IXUSR" => 0100, |
| 833 | "S_IRWXG" => 0070, |
| 834 | "S_IRGRP" => 0040, |
| 835 | "S_IWGRP" => 0020, |
| 836 | "S_IXGRP" => 0010, |
| 837 | "S_IRWXO" => 0007, |
| 838 | "S_IROTH" => 0004, |
| 839 | "S_IWOTH" => 0002, |
| 840 | "S_IXOTH" => 0001, |
| 841 | "S_IRWXUGO" => 0777, |
| 842 | "S_IRUGO" => 0444, |
| 843 | "S_IWUGO" => 0222, |
| 844 | "S_IXUGO" => 0111, |
| 845 | ); |
| 846 | |
| 847 | #Create a search pattern for all these strings to speed up a loop below |
| 848 | our $mode_perms_string_search = ""; |
| 849 | foreach my $entry (keys %mode_permission_string_types) { |
| 850 | $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); |
| 851 | $mode_perms_string_search .= $entry; |
| 852 | } |
Joe Perches | 0018046 | 2018-02-06 15:38:55 -0800 | [diff] [blame] | 853 | our $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; |
| 854 | our $multi_mode_perms_string_search = qr{ |
| 855 | ${single_mode_perms_string_search} |
| 856 | (?:\s*\|\s*${single_mode_perms_string_search})* |
| 857 | }x; |
| 858 | |
| 859 | sub perms_to_octal { |
| 860 | my ($string) = @_; |
| 861 | |
| 862 | return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); |
| 863 | |
| 864 | my $val = ""; |
| 865 | my $oval = ""; |
| 866 | my $to = 0; |
| 867 | my $curpos = 0; |
| 868 | my $lastpos = 0; |
| 869 | while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { |
| 870 | $curpos = pos($string); |
| 871 | my $match = $2; |
| 872 | my $omatch = $1; |
| 873 | last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); |
| 874 | $lastpos = $curpos; |
| 875 | $to |= $mode_permission_string_types{$match}; |
| 876 | $val .= '\s*\|\s*' if ($val ne ""); |
| 877 | $val .= $match; |
| 878 | $oval .= $omatch; |
| 879 | } |
| 880 | $oval =~ s/^\s*\|\s*//; |
| 881 | $oval =~ s/\s*\|\s*$//; |
| 882 | return sprintf("%04o", $to); |
| 883 | } |
Joe Perches | f90774e | 2016-10-11 13:51:47 -0700 | [diff] [blame] | 884 | |
Wolfram Sang | 7840a94 | 2010-08-09 17:20:57 -0700 | [diff] [blame] | 885 | our $allowed_asm_includes = qr{(?x: |
| 886 | irq| |
Sergey Ryazanov | cdcee68 | 2014-10-13 15:51:44 -0700 | [diff] [blame] | 887 | memory| |
| 888 | time| |
| 889 | reboot |
Wolfram Sang | 7840a94 | 2010-08-09 17:20:57 -0700 | [diff] [blame] | 890 | )}; |
| 891 | # memory.h: ARM has a custom one |
| 892 | |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 893 | # Load common spelling mistakes and build regular expression list. |
| 894 | my $misspellings; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 895 | my %spelling_fix; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 896 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 897 | if (open(my $spelling, '<', $spelling_file)) { |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 898 | while (<$spelling>) { |
| 899 | my $line = $_; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 900 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 901 | $line =~ s/\s*\n?$//g; |
| 902 | $line =~ s/^\s*//g; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 903 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 904 | next if ($line =~ m/^\s*#/); |
| 905 | next if ($line =~ m/^\s*$/); |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 906 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 907 | my ($suspect, $fix) = split(/\|\|/, $line); |
| 908 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 909 | $spelling_fix{$suspect} = $fix; |
| 910 | } |
| 911 | close($spelling); |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 912 | } else { |
| 913 | warn "No typos will be found - file '$spelling_file': $!\n"; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 914 | } |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 915 | |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 916 | if ($codespell) { |
| 917 | if (open(my $spelling, '<', $codespellfile)) { |
| 918 | while (<$spelling>) { |
| 919 | my $line = $_; |
| 920 | |
| 921 | $line =~ s/\s*\n?$//g; |
| 922 | $line =~ s/^\s*//g; |
| 923 | |
| 924 | next if ($line =~ m/^\s*#/); |
| 925 | next if ($line =~ m/^\s*$/); |
| 926 | next if ($line =~ m/, disabled/i); |
| 927 | |
| 928 | $line =~ s/,.*$//; |
| 929 | |
| 930 | my ($suspect, $fix) = split(/->/, $line); |
| 931 | |
| 932 | $spelling_fix{$suspect} = $fix; |
| 933 | } |
| 934 | close($spelling); |
| 935 | } else { |
| 936 | warn "No codespell typos will be found - file '$codespellfile': $!\n"; |
| 937 | } |
| 938 | } |
| 939 | |
| 940 | $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; |
| 941 | |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 942 | sub read_words { |
| 943 | my ($wordsRef, $file) = @_; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 944 | |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 945 | if (open(my $words, '<', $file)) { |
| 946 | while (<$words>) { |
| 947 | my $line = $_; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 948 | |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 949 | $line =~ s/\s*\n?$//g; |
| 950 | $line =~ s/^\s*//g; |
| 951 | |
| 952 | next if ($line =~ m/^\s*#/); |
| 953 | next if ($line =~ m/^\s*$/); |
| 954 | if ($line =~ /\s/) { |
| 955 | print("$file: '$line' invalid - ignored\n"); |
| 956 | next; |
| 957 | } |
| 958 | |
Quentin Monnet | ced69da1 | 2020-08-11 18:35:13 -0700 | [diff] [blame] | 959 | $$wordsRef .= '|' if (defined $$wordsRef); |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 960 | $$wordsRef .= $line; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 961 | } |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 962 | close($file); |
| 963 | return 1; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 964 | } |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 965 | |
| 966 | return 0; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 967 | } |
| 968 | |
Quentin Monnet | ced69da1 | 2020-08-11 18:35:13 -0700 | [diff] [blame] | 969 | my $const_structs; |
| 970 | if (show_type("CONST_STRUCT")) { |
| 971 | read_words(\$const_structs, $conststructsfile) |
| 972 | or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; |
| 973 | } |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 974 | |
Quentin Monnet | ced69da1 | 2020-08-11 18:35:13 -0700 | [diff] [blame] | 975 | if (defined($typedefsfile)) { |
| 976 | my $typeOtherTypedefs; |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 977 | read_words(\$typeOtherTypedefs, $typedefsfile) |
| 978 | or warn "No additional types will be considered - file '$typedefsfile': $!\n"; |
Quentin Monnet | ced69da1 | 2020-08-11 18:35:13 -0700 | [diff] [blame] | 979 | $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 980 | } |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 981 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 982 | sub build_types { |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 983 | my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; |
| 984 | my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 985 | my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 986 | my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 987 | $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; |
Joe Perches | ab7e23f | 2015-04-16 12:44:22 -0700 | [diff] [blame] | 988 | $BasicType = qr{ |
Joe Perches | ab7e23f | 2015-04-16 12:44:22 -0700 | [diff] [blame] | 989 | (?:$typeTypedefs\b)| |
| 990 | (?:${all}\b) |
| 991 | }x; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 992 | $NonptrType = qr{ |
Andy Whitcroft | d2172eb | 2008-07-23 21:29:07 -0700 | [diff] [blame] | 993 | (?:$Modifier\s+|const\s+)* |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 994 | (?: |
Andy Whitcroft | 6b48db2 | 2012-01-10 15:10:13 -0800 | [diff] [blame] | 995 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
Andy Whitcroft | 8ed22ca | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 996 | (?:$typeTypedefs\b)| |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 997 | (?:${all}\b) |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 998 | ) |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 999 | (?:\s+$Modifier|\s+const)* |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1000 | }x; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 1001 | $NonptrTypeMisordered = qr{ |
| 1002 | (?:$Modifier\s+|const\s+)* |
| 1003 | (?: |
| 1004 | (?:${Misordered}\b) |
| 1005 | ) |
| 1006 | (?:\s+$Modifier|\s+const)* |
| 1007 | }x; |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 1008 | $NonptrTypeWithAttr = qr{ |
| 1009 | (?:$Modifier\s+|const\s+)* |
| 1010 | (?: |
| 1011 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
| 1012 | (?:$typeTypedefs\b)| |
| 1013 | (?:${allWithAttr}\b) |
| 1014 | ) |
| 1015 | (?:\s+$Modifier|\s+const)* |
| 1016 | }x; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1017 | $Type = qr{ |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1018 | $NonptrType |
Antonio Borneo | 7b18496 | 2020-04-06 20:11:04 -0700 | [diff] [blame] | 1019 | (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 1020 | (?:\s+$Inline|\s+$Modifier)* |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1021 | }x; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 1022 | $TypeMisordered = qr{ |
| 1023 | $NonptrTypeMisordered |
Antonio Borneo | 7b18496 | 2020-04-06 20:11:04 -0700 | [diff] [blame] | 1024 | (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 1025 | (?:\s+$Inline|\s+$Modifier)* |
| 1026 | }x; |
Joe Perches | 91cb519 | 2014-04-03 14:49:32 -0700 | [diff] [blame] | 1027 | $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 1028 | $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1029 | } |
| 1030 | build_types(); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1031 | |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 1032 | our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 1033 | |
| 1034 | # Using $balanced_parens, $LvalOrFunc, or $FuncArg |
| 1035 | # requires at least perl version v5.10.0 |
| 1036 | # Any use must be runtime checked with $^V |
| 1037 | |
| 1038 | our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 1039 | our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; |
Joe Perches | c0a5c89 | 2015-02-13 14:38:21 -0800 | [diff] [blame] | 1040 | our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 1041 | |
Joe Perches | f842230 | 2014-08-06 16:11:31 -0700 | [diff] [blame] | 1042 | our $declaration_macros = qr{(?x: |
Joe Perches | 3e838b6 | 2015-09-09 15:37:33 -0700 | [diff] [blame] | 1043 | (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| |
Steffen Maier | fe658f9 | 2017-07-10 15:52:10 -0700 | [diff] [blame] | 1044 | (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| |
Gilad Ben-Yossef | 3d102fc | 2018-04-10 16:33:17 -0700 | [diff] [blame] | 1045 | (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( |
Joe Perches | f842230 | 2014-08-06 16:11:31 -0700 | [diff] [blame] | 1046 | )}; |
| 1047 | |
Aditya Srivastava | 8d0325c | 2020-12-15 20:44:24 -0800 | [diff] [blame] | 1048 | our %allow_repeated_words = ( |
| 1049 | add => '', |
| 1050 | added => '', |
| 1051 | bad => '', |
| 1052 | be => '', |
| 1053 | ); |
| 1054 | |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 1055 | sub deparenthesize { |
| 1056 | my ($string) = @_; |
| 1057 | return "" if (!defined($string)); |
Joe Perches | 5b9553a | 2014-04-03 14:49:21 -0700 | [diff] [blame] | 1058 | |
| 1059 | while ($string =~ /^\s*\(.*\)\s*$/) { |
| 1060 | $string =~ s@^\s*\(\s*@@; |
| 1061 | $string =~ s@\s*\)\s*$@@; |
| 1062 | } |
| 1063 | |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 1064 | $string =~ s@\s+@ @g; |
Joe Perches | 5b9553a | 2014-04-03 14:49:21 -0700 | [diff] [blame] | 1065 | |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 1066 | return $string; |
| 1067 | } |
| 1068 | |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 1069 | sub seed_camelcase_file { |
| 1070 | my ($file) = @_; |
| 1071 | |
| 1072 | return if (!(-f $file)); |
| 1073 | |
| 1074 | local $/; |
| 1075 | |
| 1076 | open(my $include_file, '<', "$file") |
| 1077 | or warn "$P: Can't read '$file' $!\n"; |
| 1078 | my $text = <$include_file>; |
| 1079 | close($include_file); |
| 1080 | |
| 1081 | my @lines = split('\n', $text); |
| 1082 | |
| 1083 | foreach my $line (@lines) { |
| 1084 | next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); |
| 1085 | if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { |
| 1086 | $camelcase{$1} = 1; |
Joe Perches | 11ea516 | 2013-11-12 15:10:08 -0800 | [diff] [blame] | 1087 | } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { |
| 1088 | $camelcase{$1} = 1; |
| 1089 | } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 1090 | $camelcase{$1} = 1; |
| 1091 | } |
| 1092 | } |
| 1093 | } |
| 1094 | |
Joe Perches | cd28b11 | 2019-12-04 16:52:09 -0800 | [diff] [blame] | 1095 | our %maintained_status = (); |
| 1096 | |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 1097 | sub is_maintained_obsolete { |
| 1098 | my ($filename) = @_; |
| 1099 | |
Jerome Forissier | f2c19c2 | 2016-12-12 16:46:23 -0800 | [diff] [blame] | 1100 | return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 1101 | |
Joe Perches | cd28b11 | 2019-12-04 16:52:09 -0800 | [diff] [blame] | 1102 | if (!exists($maintained_status{$filename})) { |
| 1103 | $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; |
| 1104 | } |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 1105 | |
Joe Perches | cd28b11 | 2019-12-04 16:52:09 -0800 | [diff] [blame] | 1106 | return $maintained_status{$filename} =~ /obsolete/i; |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 1107 | } |
| 1108 | |
Joe Perches | 3b6e8ac | 2018-08-21 21:57:47 -0700 | [diff] [blame] | 1109 | sub is_SPDX_License_valid { |
| 1110 | my ($license) = @_; |
| 1111 | |
Guenter Roeck | f9363b3 | 2021-06-30 18:56:19 -0700 | [diff] [blame] | 1112 | return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); |
Joe Perches | 3b6e8ac | 2018-08-21 21:57:47 -0700 | [diff] [blame] | 1113 | |
Joe Perches | 5629411 | 2018-08-21 21:58:04 -0700 | [diff] [blame] | 1114 | my $root_path = abs_path($root); |
Guenter Roeck | f9363b3 | 2021-06-30 18:56:19 -0700 | [diff] [blame] | 1115 | my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`; |
Joe Perches | 3b6e8ac | 2018-08-21 21:57:47 -0700 | [diff] [blame] | 1116 | return 0 if ($status ne ""); |
| 1117 | return 1; |
| 1118 | } |
| 1119 | |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 1120 | my $camelcase_seeded = 0; |
| 1121 | sub seed_camelcase_includes { |
| 1122 | return if ($camelcase_seeded); |
| 1123 | |
| 1124 | my $files; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 1125 | my $camelcase_cache = ""; |
| 1126 | my @include_files = (); |
| 1127 | |
| 1128 | $camelcase_seeded = 1; |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 1129 | |
Joe Perches | 0f7f635 | 2020-10-24 16:59:04 -0700 | [diff] [blame] | 1130 | if (-e "$gitroot") { |
Joe Perches | dbbf869 | 2019-09-25 16:46:52 -0700 | [diff] [blame] | 1131 | my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 1132 | chomp $git_last_include_commit; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 1133 | $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 1134 | } else { |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 1135 | my $last_mod_date = 0; |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 1136 | $files = `find $root/include -name "*.h"`; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 1137 | @include_files = split('\n', $files); |
| 1138 | foreach my $file (@include_files) { |
| 1139 | my $date = POSIX::strftime("%Y%m%d%H%M", |
| 1140 | localtime((stat $file)[9])); |
| 1141 | $last_mod_date = $date if ($last_mod_date < $date); |
| 1142 | } |
| 1143 | $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 1144 | } |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 1145 | |
| 1146 | if ($camelcase_cache ne "" && -f $camelcase_cache) { |
| 1147 | open(my $camelcase_file, '<', "$camelcase_cache") |
| 1148 | or warn "$P: Can't read '$camelcase_cache' $!\n"; |
| 1149 | while (<$camelcase_file>) { |
| 1150 | chomp; |
| 1151 | $camelcase{$_} = 1; |
| 1152 | } |
| 1153 | close($camelcase_file); |
| 1154 | |
| 1155 | return; |
| 1156 | } |
| 1157 | |
Joe Perches | 0f7f635 | 2020-10-24 16:59:04 -0700 | [diff] [blame] | 1158 | if (-e "$gitroot") { |
Joe Perches | dbbf869 | 2019-09-25 16:46:52 -0700 | [diff] [blame] | 1159 | $files = `${git_command} ls-files "include/*.h"`; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 1160 | @include_files = split('\n', $files); |
| 1161 | } |
| 1162 | |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 1163 | foreach my $file (@include_files) { |
| 1164 | seed_camelcase_file($file); |
| 1165 | } |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 1166 | |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 1167 | if ($camelcase_cache ne "") { |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 1168 | unlink glob ".checkpatch-camelcase.*"; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 1169 | open(my $camelcase_file, '>', "$camelcase_cache") |
| 1170 | or warn "$P: Can't write '$camelcase_cache' $!\n"; |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 1171 | foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { |
| 1172 | print $camelcase_file ("$_\n"); |
| 1173 | } |
| 1174 | close($camelcase_file); |
| 1175 | } |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 1176 | } |
| 1177 | |
Joe Perches | f5f6132 | 2020-10-15 20:12:12 -0700 | [diff] [blame] | 1178 | sub git_is_single_file { |
| 1179 | my ($filename) = @_; |
| 1180 | |
| 1181 | return 0 if ((which("git") eq "") || !(-e "$gitroot")); |
| 1182 | |
| 1183 | my $output = `${git_command} ls-files -- $filename 2>/dev/null`; |
| 1184 | my $count = $output =~ tr/\n//; |
| 1185 | return $count eq 1 && $output =~ m{^${filename}$}; |
| 1186 | } |
| 1187 | |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1188 | sub git_commit_info { |
| 1189 | my ($commit, $id, $desc) = @_; |
| 1190 | |
Joe Perches | 0f7f635 | 2020-10-24 16:59:04 -0700 | [diff] [blame] | 1191 | return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1192 | |
Joe Perches | dbbf869 | 2019-09-25 16:46:52 -0700 | [diff] [blame] | 1193 | my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1194 | $output =~ s/^\s*//gm; |
| 1195 | my @lines = split("\n", $output); |
| 1196 | |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 1197 | return ($id, $desc) if ($#lines < 0); |
| 1198 | |
Sean Christopherson | 5a7f445 | 2019-09-25 16:46:49 -0700 | [diff] [blame] | 1199 | if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1200 | # Maybe one day convert this block of bash into something that returns |
| 1201 | # all matching commit ids, but it's very slow... |
| 1202 | # |
| 1203 | # echo "checking commits $1..." |
| 1204 | # git rev-list --remotes | grep -i "^$1" | |
| 1205 | # while read line ; do |
| 1206 | # git log --format='%H %s' -1 $line | |
| 1207 | # echo "commit $(cut -c 1-12,41-)" |
| 1208 | # done |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 1209 | } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ || |
| 1210 | $lines[0] =~ /^fatal: bad object $commit/) { |
Heinrich Schuchardt | 948b133 | 2017-07-10 15:52:16 -0700 | [diff] [blame] | 1211 | $id = undef; |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1212 | } else { |
| 1213 | $id = substr($lines[0], 0, 12); |
| 1214 | $desc = substr($lines[0], 41); |
| 1215 | } |
| 1216 | |
| 1217 | return ($id, $desc); |
| 1218 | } |
| 1219 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1220 | $chk_signoff = 0 if ($file); |
| 1221 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1222 | my @rawlines = (); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1223 | my @lines = (); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1224 | my @fixed = (); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 1225 | my @fixed_inserted = (); |
| 1226 | my @fixed_deleted = (); |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 1227 | my $fixlinenr = -1; |
| 1228 | |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 1229 | # If input is git commits, extract all commits from the commit expressions. |
| 1230 | # For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. |
Joe Perches | 0f7f635 | 2020-10-24 16:59:04 -0700 | [diff] [blame] | 1231 | die "$P: No git repository found\n" if ($git && !-e "$gitroot"); |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 1232 | |
| 1233 | if ($git) { |
| 1234 | my @commits = (); |
Joe Perches | 0dea9f1e | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 1235 | foreach my $commit_expr (@ARGV) { |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 1236 | my $git_range; |
Joe Perches | 28898fd | 2016-05-20 17:04:22 -0700 | [diff] [blame] | 1237 | if ($commit_expr =~ m/^(.*)-(\d+)$/) { |
| 1238 | $git_range = "-$2 $1"; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 1239 | } elsif ($commit_expr =~ m/\.\./) { |
| 1240 | $git_range = "$commit_expr"; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 1241 | } else { |
Joe Perches | 0dea9f1e | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 1242 | $git_range = "-1 $commit_expr"; |
| 1243 | } |
Joe Perches | dbbf869 | 2019-09-25 16:46:52 -0700 | [diff] [blame] | 1244 | my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; |
Joe Perches | 0dea9f1e | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 1245 | foreach my $line (split(/\n/, $lines)) { |
Joe Perches | 28898fd | 2016-05-20 17:04:22 -0700 | [diff] [blame] | 1246 | $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; |
| 1247 | next if (!defined($1) || !defined($2)); |
Joe Perches | 0dea9f1e | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 1248 | my $sha1 = $1; |
| 1249 | my $subject = $2; |
| 1250 | unshift(@commits, $sha1); |
| 1251 | $git_commits{$sha1} = $subject; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 1252 | } |
| 1253 | } |
| 1254 | die "$P: no git commits after extraction!\n" if (@commits == 0); |
| 1255 | @ARGV = @commits; |
| 1256 | } |
| 1257 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1258 | my $vname; |
Vadim Bendebury | 98005e8 | 2019-03-07 16:28:38 -0800 | [diff] [blame] | 1259 | $allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1260 | for my $filename (@ARGV) { |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 1261 | my $FILE; |
Joe Perches | f5f6132 | 2020-10-15 20:12:12 -0700 | [diff] [blame] | 1262 | my $is_git_file = git_is_single_file($filename); |
| 1263 | my $oldfile = $file; |
| 1264 | $file = 1 if ($is_git_file); |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 1265 | if ($git) { |
| 1266 | open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || |
| 1267 | die "$P: $filename: git format-patch failed - $!\n"; |
| 1268 | } elsif ($file) { |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 1269 | open($FILE, '-|', "diff -u /dev/null $filename") || |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1270 | die "$P: $filename: diff failed - $!\n"; |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 1271 | } elsif ($filename eq '-') { |
| 1272 | open($FILE, '<&STDIN'); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1273 | } else { |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 1274 | open($FILE, '<', "$filename") || |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1275 | die "$P: $filename: open failed - $!\n"; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1276 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1277 | if ($filename eq '-') { |
| 1278 | $vname = 'Your patch'; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 1279 | } elsif ($git) { |
Joe Perches | 0dea9f1e | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 1280 | $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1281 | } else { |
| 1282 | $vname = $filename; |
| 1283 | } |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 1284 | while (<$FILE>) { |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1285 | chomp; |
| 1286 | push(@rawlines, $_); |
Geert Uytterhoeven | c7f574d | 2020-06-04 16:50:43 -0700 | [diff] [blame] | 1287 | $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1288 | } |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 1289 | close($FILE); |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 1290 | |
| 1291 | if ($#ARGV > 0 && $quiet == 0) { |
| 1292 | print '-' x length($vname) . "\n"; |
| 1293 | print "$vname\n"; |
| 1294 | print '-' x length($vname) . "\n"; |
| 1295 | } |
| 1296 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1297 | if (!process($filename)) { |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1298 | $exit = 1; |
| 1299 | } |
| 1300 | @rawlines = (); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1301 | @lines = (); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1302 | @fixed = (); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 1303 | @fixed_inserted = (); |
| 1304 | @fixed_deleted = (); |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 1305 | $fixlinenr = -1; |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 1306 | @modifierListFile = (); |
| 1307 | @typeListFile = (); |
| 1308 | build_types(); |
Joe Perches | f5f6132 | 2020-10-15 20:12:12 -0700 | [diff] [blame] | 1309 | $file = $oldfile if ($is_git_file); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1310 | } |
| 1311 | |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 1312 | if (!$quiet) { |
Joe Perches | 3c816e4 | 2015-06-25 15:03:29 -0700 | [diff] [blame] | 1313 | hash_show_words(\%use_type, "Used"); |
| 1314 | hash_show_words(\%ignore_type, "Ignored"); |
| 1315 | |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 1316 | if (!$perl_version_ok) { |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 1317 | print << "EOM" |
| 1318 | |
| 1319 | NOTE: perl $^V is not modern enough to detect all possible issues. |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 1320 | An upgrade to at least perl $minimum_perl_version is suggested. |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 1321 | EOM |
| 1322 | } |
| 1323 | if ($exit) { |
| 1324 | print << "EOM" |
| 1325 | |
| 1326 | NOTE: If any of the errors are false positives, please report |
| 1327 | them to the maintainer, see CHECKPATCH in MAINTAINERS. |
| 1328 | EOM |
| 1329 | } |
| 1330 | } |
| 1331 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1332 | exit($exit); |
| 1333 | |
| 1334 | sub top_of_kernel_tree { |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1335 | my ($root) = @_; |
| 1336 | |
| 1337 | my @tree_check = ( |
| 1338 | "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", |
| 1339 | "README", "Documentation", "arch", "include", "drivers", |
| 1340 | "fs", "init", "ipc", "kernel", "lib", "scripts", |
| 1341 | ); |
| 1342 | |
| 1343 | foreach my $check (@tree_check) { |
| 1344 | if (! -e $root . '/' . $check) { |
| 1345 | return 0; |
| 1346 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1347 | } |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1348 | return 1; |
Joe Perches | 8f26b83 | 2012-10-04 17:13:32 -0700 | [diff] [blame] | 1349 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1350 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1351 | sub parse_email { |
| 1352 | my ($formatted_email) = @_; |
| 1353 | |
| 1354 | my $name = ""; |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 1355 | my $quoted = ""; |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 1356 | my $name_comment = ""; |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1357 | my $address = ""; |
| 1358 | my $comment = ""; |
| 1359 | |
| 1360 | if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { |
| 1361 | $name = $1; |
| 1362 | $address = $2; |
| 1363 | $comment = $3 if defined $3; |
| 1364 | } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { |
| 1365 | $address = $1; |
| 1366 | $comment = $2 if defined $2; |
| 1367 | } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { |
| 1368 | $address = $1; |
| 1369 | $comment = $2 if defined $2; |
Joe Perches | 85e1206 | 2018-04-10 16:33:09 -0700 | [diff] [blame] | 1370 | $formatted_email =~ s/\Q$address\E.*$//; |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1371 | $name = $formatted_email; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1372 | $name = trim($name); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1373 | $name =~ s/^\"|\"$//g; |
| 1374 | # If there's a name left after stripping spaces and |
| 1375 | # leading quotes, and the address doesn't have both |
| 1376 | # leading and trailing angle brackets, the address |
| 1377 | # is invalid. ie: |
| 1378 | # "joe smith joe@smith.com" bad |
| 1379 | # "joe smith <joe@smith.com" bad |
| 1380 | if ($name ne "" && $address !~ /^<[^>]+>$/) { |
| 1381 | $name = ""; |
| 1382 | $address = ""; |
| 1383 | $comment = ""; |
| 1384 | } |
| 1385 | } |
| 1386 | |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 1387 | # Extract comments from names excluding quoted parts |
| 1388 | # "John D. (Doe)" - Do not extract |
| 1389 | if ($name =~ s/\"(.+)\"//) { |
| 1390 | $quoted = $1; |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 1391 | } |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 1392 | while ($name =~ s/\s*($balanced_parens)\s*/ /) { |
| 1393 | $name_comment .= trim($1); |
| 1394 | } |
| 1395 | $name =~ s/^[ \"]+|[ \"]+$//g; |
| 1396 | $name = trim("$quoted $name"); |
| 1397 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1398 | $address = trim($address); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1399 | $address =~ s/^\<|\>$//g; |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 1400 | $comment = trim($comment); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1401 | |
| 1402 | if ($name =~ /[^\w \-]/i) { ##has "must quote" chars |
| 1403 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes |
| 1404 | $name = "\"$name\""; |
| 1405 | } |
| 1406 | |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 1407 | return ($name, $name_comment, $address, $comment); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1408 | } |
| 1409 | |
| 1410 | sub format_email { |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 1411 | my ($name, $name_comment, $address, $comment) = @_; |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1412 | |
| 1413 | my $formatted_email; |
| 1414 | |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 1415 | $name =~ s/^[ \"]+|[ \"]+$//g; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1416 | $address = trim($address); |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 1417 | $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1418 | |
| 1419 | if ($name =~ /[^\w \-]/i) { ##has "must quote" chars |
| 1420 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes |
| 1421 | $name = "\"$name\""; |
| 1422 | } |
| 1423 | |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 1424 | $name_comment = trim($name_comment); |
| 1425 | $name_comment = " $name_comment" if ($name_comment ne ""); |
| 1426 | $comment = trim($comment); |
| 1427 | $comment = " $comment" if ($comment ne ""); |
| 1428 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1429 | if ("$name" eq "") { |
| 1430 | $formatted_email = "$address"; |
| 1431 | } else { |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 1432 | $formatted_email = "$name$name_comment <$address>"; |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1433 | } |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 1434 | $formatted_email .= "$comment"; |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1435 | return $formatted_email; |
| 1436 | } |
| 1437 | |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 1438 | sub reformat_email { |
| 1439 | my ($email) = @_; |
| 1440 | |
| 1441 | my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 1442 | return format_email($email_name, $name_comment, $email_address, $comment); |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 1443 | } |
| 1444 | |
| 1445 | sub same_email_addresses { |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 1446 | my ($email1, $email2) = @_; |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 1447 | |
| 1448 | my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); |
| 1449 | my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); |
| 1450 | |
| 1451 | return $email1_name eq $email2_name && |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 1452 | $email1_address eq $email2_address && |
| 1453 | $name1_comment eq $name2_comment && |
| 1454 | $comment1 eq $comment2; |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 1455 | } |
| 1456 | |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1457 | sub which { |
Joe Perches | bd474ca | 2014-08-06 16:11:10 -0700 | [diff] [blame] | 1458 | my ($bin) = @_; |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1459 | |
Joe Perches | bd474ca | 2014-08-06 16:11:10 -0700 | [diff] [blame] | 1460 | foreach my $path (split(/:/, $ENV{PATH})) { |
| 1461 | if (-e "$path/$bin") { |
| 1462 | return "$path/$bin"; |
| 1463 | } |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1464 | } |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1465 | |
Joe Perches | bd474ca | 2014-08-06 16:11:10 -0700 | [diff] [blame] | 1466 | return ""; |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1467 | } |
| 1468 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 1469 | sub which_conf { |
| 1470 | my ($conf) = @_; |
| 1471 | |
| 1472 | foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { |
| 1473 | if (-e "$path/$conf") { |
| 1474 | return "$path/$conf"; |
| 1475 | } |
| 1476 | } |
| 1477 | |
| 1478 | return ""; |
| 1479 | } |
| 1480 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1481 | sub expand_tabs { |
| 1482 | my ($str) = @_; |
| 1483 | |
| 1484 | my $res = ''; |
| 1485 | my $n = 0; |
| 1486 | for my $c (split(//, $str)) { |
| 1487 | if ($c eq "\t") { |
| 1488 | $res .= ' '; |
| 1489 | $n++; |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 1490 | for (; ($n % $tabsize) != 0; $n++) { |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1491 | $res .= ' '; |
| 1492 | } |
| 1493 | next; |
| 1494 | } |
| 1495 | $res .= $c; |
| 1496 | $n++; |
| 1497 | } |
| 1498 | |
| 1499 | return $res; |
| 1500 | } |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1501 | sub copy_spacing { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1502 | (my $res = shift) =~ tr/\t/ /c; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1503 | return $res; |
| 1504 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1505 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1506 | sub line_stats { |
| 1507 | my ($line) = @_; |
| 1508 | |
| 1509 | # Drop the diff line leader and expand tabs |
| 1510 | $line =~ s/^.//; |
| 1511 | $line = expand_tabs($line); |
| 1512 | |
| 1513 | # Pick the indent from the front of the line. |
| 1514 | my ($white) = ($line =~ /^(\s*)/); |
| 1515 | |
| 1516 | return (length($line), length($white)); |
| 1517 | } |
| 1518 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1519 | my $sanitise_quote = ''; |
| 1520 | |
| 1521 | sub sanitise_line_reset { |
| 1522 | my ($in_comment) = @_; |
| 1523 | |
| 1524 | if ($in_comment) { |
| 1525 | $sanitise_quote = '*/'; |
| 1526 | } else { |
| 1527 | $sanitise_quote = ''; |
| 1528 | } |
| 1529 | } |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1530 | sub sanitise_line { |
| 1531 | my ($line) = @_; |
| 1532 | |
| 1533 | my $res = ''; |
| 1534 | my $l = ''; |
| 1535 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1536 | my $qlen = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1537 | my $off = 0; |
| 1538 | my $c; |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1539 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1540 | # Always copy over the diff marker. |
| 1541 | $res = substr($line, 0, 1); |
| 1542 | |
| 1543 | for ($off = 1; $off < length($line); $off++) { |
| 1544 | $c = substr($line, $off, 1); |
| 1545 | |
Claudio Fontana | 8d2e11b | 2018-04-10 16:33:42 -0700 | [diff] [blame] | 1546 | # Comments we are whacking completely including the begin |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1547 | # and end, all to $;. |
| 1548 | if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { |
| 1549 | $sanitise_quote = '*/'; |
| 1550 | |
| 1551 | substr($res, $off, 2, "$;$;"); |
| 1552 | $off++; |
| 1553 | next; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1554 | } |
Andy Whitcroft | 81bc0e0 | 2008-10-15 22:02:26 -0700 | [diff] [blame] | 1555 | if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1556 | $sanitise_quote = ''; |
| 1557 | substr($res, $off, 2, "$;$;"); |
| 1558 | $off++; |
| 1559 | next; |
| 1560 | } |
Daniel Walker | 113f04a | 2009-09-21 17:04:35 -0700 | [diff] [blame] | 1561 | if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { |
| 1562 | $sanitise_quote = '//'; |
| 1563 | |
| 1564 | substr($res, $off, 2, $sanitise_quote); |
| 1565 | $off++; |
| 1566 | next; |
| 1567 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1568 | |
| 1569 | # A \ in a string means ignore the next character. |
| 1570 | if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && |
| 1571 | $c eq "\\") { |
| 1572 | substr($res, $off, 2, 'XX'); |
| 1573 | $off++; |
| 1574 | next; |
| 1575 | } |
| 1576 | # Regular quotes. |
| 1577 | if ($c eq "'" || $c eq '"') { |
| 1578 | if ($sanitise_quote eq '') { |
| 1579 | $sanitise_quote = $c; |
| 1580 | |
| 1581 | substr($res, $off, 1, $c); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1582 | next; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1583 | } elsif ($sanitise_quote eq $c) { |
| 1584 | $sanitise_quote = ''; |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1585 | } |
| 1586 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1587 | |
Andy Whitcroft | fae17da | 2009-01-06 14:41:20 -0800 | [diff] [blame] | 1588 | #print "c<$c> SQ<$sanitise_quote>\n"; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1589 | if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { |
| 1590 | substr($res, $off, 1, $;); |
Daniel Walker | 113f04a | 2009-09-21 17:04:35 -0700 | [diff] [blame] | 1591 | } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { |
| 1592 | substr($res, $off, 1, $;); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1593 | } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { |
| 1594 | substr($res, $off, 1, 'X'); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1595 | } else { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1596 | substr($res, $off, 1, $c); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1597 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1598 | } |
| 1599 | |
Daniel Walker | 113f04a | 2009-09-21 17:04:35 -0700 | [diff] [blame] | 1600 | if ($sanitise_quote eq '//') { |
| 1601 | $sanitise_quote = ''; |
| 1602 | } |
| 1603 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1604 | # The pathname on a #include may be surrounded by '<' and '>'. |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1605 | if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1606 | my $clean = 'X' x length($1); |
| 1607 | $res =~ s@\<.*\>@<$clean>@; |
| 1608 | |
| 1609 | # The whole of a #error is a string. |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1610 | } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1611 | my $clean = 'X' x length($1); |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1612 | $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1613 | } |
| 1614 | |
Joe Perches | dadf680 | 2016-08-02 14:04:33 -0700 | [diff] [blame] | 1615 | if ($allow_c99_comments && $res =~ m@(//.*$)@) { |
| 1616 | my $match = $1; |
| 1617 | $res =~ s/\Q$match\E/"$;" x length($match)/e; |
| 1618 | } |
| 1619 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1620 | return $res; |
| 1621 | } |
| 1622 | |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 1623 | sub get_quoted_string { |
| 1624 | my ($line, $rawline) = @_; |
| 1625 | |
Joe Perches | 478b179 | 2018-04-10 16:33:34 -0700 | [diff] [blame] | 1626 | return "" if (!defined($line) || !defined($rawline)); |
Joe Perches | 33acb54 | 2015-06-25 15:02:54 -0700 | [diff] [blame] | 1627 | return "" if ($line !~ m/($String)/g); |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 1628 | return substr($rawline, $-[0], $+[0] - $-[0]); |
| 1629 | } |
| 1630 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1631 | sub ctx_statement_block { |
| 1632 | my ($linenr, $remain, $off) = @_; |
| 1633 | my $line = $linenr - 1; |
| 1634 | my $blk = ''; |
| 1635 | my $soff = $off; |
| 1636 | my $coff = $off - 1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1637 | my $coff_set = 0; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1638 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1639 | my $loff = 0; |
| 1640 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1641 | my $type = ''; |
| 1642 | my $level = 0; |
Andy Whitcroft | a275064 | 2009-01-15 13:51:04 -0800 | [diff] [blame] | 1643 | my @stack = (); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1644 | my $p; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1645 | my $c; |
| 1646 | my $len = 0; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1647 | |
| 1648 | my $remainder; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1649 | while (1) { |
Andy Whitcroft | a275064 | 2009-01-15 13:51:04 -0800 | [diff] [blame] | 1650 | @stack = (['', 0]) if ($#stack == -1); |
| 1651 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1652 | #warn "CSB: blk<$blk> remain<$remain>\n"; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1653 | # If we are about to drop off the end, pull in more |
| 1654 | # context. |
| 1655 | if ($off >= $len) { |
| 1656 | for (; $remain > 0; $line++) { |
Andy Whitcroft | dea3349 | 2008-10-15 22:02:25 -0700 | [diff] [blame] | 1657 | last if (!defined $lines[$line]); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1658 | next if ($lines[$line] =~ /^-/); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1659 | $remain--; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1660 | $loff = $len; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1661 | $blk .= $lines[$line] . "\n"; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1662 | $len = length($blk); |
| 1663 | $line++; |
| 1664 | last; |
| 1665 | } |
| 1666 | # Bail if there is no further context. |
| 1667 | #warn "CSB: blk<$blk> off<$off> len<$len>\n"; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1668 | if ($off >= $len) { |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1669 | last; |
| 1670 | } |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 1671 | if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { |
| 1672 | $level++; |
| 1673 | $type = '#'; |
| 1674 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1675 | } |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1676 | $p = $c; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1677 | $c = substr($blk, $off, 1); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1678 | $remainder = substr($blk, $off); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1679 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1680 | #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1681 | |
| 1682 | # Handle nested #if/#else. |
| 1683 | if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { |
| 1684 | push(@stack, [ $type, $level ]); |
| 1685 | } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { |
| 1686 | ($type, $level) = @{$stack[$#stack - 1]}; |
| 1687 | } elsif ($remainder =~ /^#\s*endif\b/) { |
| 1688 | ($type, $level) = @{pop(@stack)}; |
| 1689 | } |
| 1690 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1691 | # Statement ends at the ';' or a close '}' at the |
| 1692 | # outermost level. |
| 1693 | if ($level == 0 && $c eq ';') { |
| 1694 | last; |
| 1695 | } |
| 1696 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1697 | # An else is really a conditional as long as its not else if |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1698 | if ($level == 0 && $coff_set == 0 && |
| 1699 | (!defined($p) || $p =~ /(?:\s|\}|\+)/) && |
| 1700 | $remainder =~ /^(else)(?:\s|{)/ && |
| 1701 | $remainder !~ /^else\s+if\b/) { |
| 1702 | $coff = $off + length($1) - 1; |
| 1703 | $coff_set = 1; |
| 1704 | #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; |
| 1705 | #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1706 | } |
| 1707 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1708 | if (($type eq '' || $type eq '(') && $c eq '(') { |
| 1709 | $level++; |
| 1710 | $type = '('; |
| 1711 | } |
| 1712 | if ($type eq '(' && $c eq ')') { |
| 1713 | $level--; |
| 1714 | $type = ($level != 0)? '(' : ''; |
| 1715 | |
| 1716 | if ($level == 0 && $coff < $soff) { |
| 1717 | $coff = $off; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1718 | $coff_set = 1; |
| 1719 | #warn "CSB: mark coff<$coff>\n"; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1720 | } |
| 1721 | } |
| 1722 | if (($type eq '' || $type eq '{') && $c eq '{') { |
| 1723 | $level++; |
| 1724 | $type = '{'; |
| 1725 | } |
| 1726 | if ($type eq '{' && $c eq '}') { |
| 1727 | $level--; |
| 1728 | $type = ($level != 0)? '{' : ''; |
| 1729 | |
| 1730 | if ($level == 0) { |
Patrick Pannuto | b998e00 | 2010-08-09 17:21:03 -0700 | [diff] [blame] | 1731 | if (substr($blk, $off + 1, 1) eq ';') { |
| 1732 | $off++; |
| 1733 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1734 | last; |
| 1735 | } |
| 1736 | } |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 1737 | # Preprocessor commands end at the newline unless escaped. |
| 1738 | if ($type eq '#' && $c eq "\n" && $p ne "\\") { |
| 1739 | $level--; |
| 1740 | $type = ''; |
| 1741 | $off++; |
| 1742 | last; |
| 1743 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1744 | $off++; |
| 1745 | } |
Andy Whitcroft | a3bb97a | 2008-07-23 21:29:00 -0700 | [diff] [blame] | 1746 | # We are truly at the end, so shuffle to the next line. |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1747 | if ($off == $len) { |
Andy Whitcroft | a3bb97a | 2008-07-23 21:29:00 -0700 | [diff] [blame] | 1748 | $loff = $len + 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1749 | $line++; |
| 1750 | $remain--; |
| 1751 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1752 | |
| 1753 | my $statement = substr($blk, $soff, $off - $soff + 1); |
| 1754 | my $condition = substr($blk, $soff, $coff - $soff + 1); |
| 1755 | |
| 1756 | #warn "STATEMENT<$statement>\n"; |
| 1757 | #warn "CONDITION<$condition>\n"; |
| 1758 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1759 | #print "coff<$coff> soff<$off> loff<$loff>\n"; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1760 | |
| 1761 | return ($statement, $condition, |
| 1762 | $line, $remain + 1, $off - $loff + 1, $level); |
| 1763 | } |
| 1764 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1765 | sub statement_lines { |
| 1766 | my ($stmt) = @_; |
| 1767 | |
| 1768 | # Strip the diff line prefixes and rip blank lines at start and end. |
| 1769 | $stmt =~ s/(^|\n)./$1/g; |
| 1770 | $stmt =~ s/^\s*//; |
| 1771 | $stmt =~ s/\s*$//; |
| 1772 | |
| 1773 | my @stmt_lines = ($stmt =~ /\n/g); |
| 1774 | |
| 1775 | return $#stmt_lines + 2; |
| 1776 | } |
| 1777 | |
| 1778 | sub statement_rawlines { |
| 1779 | my ($stmt) = @_; |
| 1780 | |
| 1781 | my @stmt_lines = ($stmt =~ /\n/g); |
| 1782 | |
| 1783 | return $#stmt_lines + 2; |
| 1784 | } |
| 1785 | |
| 1786 | sub statement_block_size { |
| 1787 | my ($stmt) = @_; |
| 1788 | |
| 1789 | $stmt =~ s/(^|\n)./$1/g; |
| 1790 | $stmt =~ s/^\s*{//; |
| 1791 | $stmt =~ s/}\s*$//; |
| 1792 | $stmt =~ s/^\s*//; |
| 1793 | $stmt =~ s/\s*$//; |
| 1794 | |
| 1795 | my @stmt_lines = ($stmt =~ /\n/g); |
| 1796 | my @stmt_statements = ($stmt =~ /;/g); |
| 1797 | |
| 1798 | my $stmt_lines = $#stmt_lines + 2; |
| 1799 | my $stmt_statements = $#stmt_statements + 1; |
| 1800 | |
| 1801 | if ($stmt_lines > $stmt_statements) { |
| 1802 | return $stmt_lines; |
| 1803 | } else { |
| 1804 | return $stmt_statements; |
| 1805 | } |
| 1806 | } |
| 1807 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1808 | sub ctx_statement_full { |
| 1809 | my ($linenr, $remain, $off) = @_; |
| 1810 | my ($statement, $condition, $level); |
| 1811 | |
| 1812 | my (@chunks); |
| 1813 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1814 | # Grab the first conditional/block pair. |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1815 | ($statement, $condition, $linenr, $remain, $off, $level) = |
| 1816 | ctx_statement_block($linenr, $remain, $off); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1817 | #print "F: c<$condition> s<$statement> remain<$remain>\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1818 | push(@chunks, [ $condition, $statement ]); |
| 1819 | if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { |
| 1820 | return ($level, $linenr, @chunks); |
| 1821 | } |
| 1822 | |
| 1823 | # Pull in the following conditional/block pairs and see if they |
| 1824 | # could continue the statement. |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1825 | for (;;) { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1826 | ($statement, $condition, $linenr, $remain, $off, $level) = |
| 1827 | ctx_statement_block($linenr, $remain, $off); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1828 | #print "C: c<$condition> s<$statement> remain<$remain>\n"; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1829 | last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1830 | #print "C: push\n"; |
| 1831 | push(@chunks, [ $condition, $statement ]); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1832 | } |
| 1833 | |
| 1834 | return ($level, $linenr, @chunks); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1835 | } |
| 1836 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1837 | sub ctx_block_get { |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1838 | my ($linenr, $remain, $outer, $open, $close, $off) = @_; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1839 | my $line; |
| 1840 | my $start = $linenr - 1; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1841 | my $blk = ''; |
| 1842 | my @o; |
| 1843 | my @c; |
| 1844 | my @res = (); |
| 1845 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1846 | my $level = 0; |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1847 | my @stack = ($level); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1848 | for ($line = $start; $remain > 0; $line++) { |
| 1849 | next if ($rawlines[$line] =~ /^-/); |
| 1850 | $remain--; |
| 1851 | |
| 1852 | $blk .= $rawlines[$line]; |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1853 | |
| 1854 | # Handle nested #if/#else. |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 1855 | if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1856 | push(@stack, $level); |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 1857 | } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1858 | $level = $stack[$#stack - 1]; |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 1859 | } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1860 | $level = pop(@stack); |
| 1861 | } |
| 1862 | |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 1863 | foreach my $c (split(//, $lines[$line])) { |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1864 | ##print "C<$c>L<$level><$open$close>O<$off>\n"; |
| 1865 | if ($off > 0) { |
| 1866 | $off--; |
| 1867 | next; |
| 1868 | } |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1869 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1870 | if ($c eq $close && $level > 0) { |
| 1871 | $level--; |
| 1872 | last if ($level == 0); |
| 1873 | } elsif ($c eq $open) { |
| 1874 | $level++; |
| 1875 | } |
| 1876 | } |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1877 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1878 | if (!$outer || $level <= 1) { |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1879 | push(@res, $rawlines[$line]); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1880 | } |
| 1881 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1882 | last if ($level == 0); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1883 | } |
| 1884 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1885 | return ($level, @res); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1886 | } |
| 1887 | sub ctx_block_outer { |
| 1888 | my ($linenr, $remain) = @_; |
| 1889 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1890 | my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); |
| 1891 | return @r; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1892 | } |
| 1893 | sub ctx_block { |
| 1894 | my ($linenr, $remain) = @_; |
| 1895 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1896 | my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); |
| 1897 | return @r; |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 1898 | } |
| 1899 | sub ctx_statement { |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1900 | my ($linenr, $remain, $off) = @_; |
| 1901 | |
| 1902 | my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); |
| 1903 | return @r; |
| 1904 | } |
| 1905 | sub ctx_block_level { |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 1906 | my ($linenr, $remain) = @_; |
| 1907 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1908 | return ctx_block_get($linenr, $remain, 0, '{', '}', 0); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1909 | } |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 1910 | sub ctx_statement_level { |
| 1911 | my ($linenr, $remain, $off) = @_; |
| 1912 | |
| 1913 | return ctx_block_get($linenr, $remain, 0, '(', ')', $off); |
| 1914 | } |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1915 | |
| 1916 | sub ctx_locate_comment { |
| 1917 | my ($first_line, $end_line) = @_; |
| 1918 | |
Joe Perches | a55ee0c | 2020-06-04 16:50:36 -0700 | [diff] [blame] | 1919 | # If c99 comment on the current line, or the line before or after |
| 1920 | my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); |
| 1921 | return $current_comment if (defined $current_comment); |
| 1922 | ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); |
| 1923 | return $current_comment if (defined $current_comment); |
| 1924 | ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); |
| 1925 | return $current_comment if (defined $current_comment); |
| 1926 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1927 | # Catch a comment on the end of the line itself. |
Joe Perches | a55ee0c | 2020-06-04 16:50:36 -0700 | [diff] [blame] | 1928 | ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1929 | return $current_comment if (defined $current_comment); |
| 1930 | |
| 1931 | # Look through the context and try and figure out if there is a |
| 1932 | # comment. |
| 1933 | my $in_comment = 0; |
| 1934 | $current_comment = ''; |
| 1935 | for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1936 | my $line = $rawlines[$linenr - 1]; |
| 1937 | #warn " $line\n"; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1938 | if ($linenr == $first_line and $line =~ m@^.\s*\*@) { |
| 1939 | $in_comment = 1; |
| 1940 | } |
| 1941 | if ($line =~ m@/\*@) { |
| 1942 | $in_comment = 1; |
| 1943 | } |
| 1944 | if (!$in_comment && $current_comment ne '') { |
| 1945 | $current_comment = ''; |
| 1946 | } |
| 1947 | $current_comment .= $line . "\n" if ($in_comment); |
| 1948 | if ($line =~ m@\*/@) { |
| 1949 | $in_comment = 0; |
| 1950 | } |
| 1951 | } |
| 1952 | |
| 1953 | chomp($current_comment); |
| 1954 | return($current_comment); |
| 1955 | } |
| 1956 | sub ctx_has_comment { |
| 1957 | my ($first_line, $end_line) = @_; |
| 1958 | my $cmt = ctx_locate_comment($first_line, $end_line); |
| 1959 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1960 | ##print "LINE: $rawlines[$end_line - 1 ]\n"; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1961 | ##print "CMMT: $cmt\n"; |
| 1962 | |
| 1963 | return ($cmt ne ''); |
| 1964 | } |
| 1965 | |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 1966 | sub raw_line { |
| 1967 | my ($linenr, $cnt) = @_; |
| 1968 | |
| 1969 | my $offset = $linenr - 1; |
| 1970 | $cnt++; |
| 1971 | |
| 1972 | my $line; |
| 1973 | while ($cnt) { |
| 1974 | $line = $rawlines[$offset++]; |
| 1975 | next if (defined($line) && $line =~ /^-/); |
| 1976 | $cnt--; |
| 1977 | } |
| 1978 | |
| 1979 | return $line; |
| 1980 | } |
| 1981 | |
Tobin C. Harding | 2a9f9d8 | 2018-04-10 16:33:20 -0700 | [diff] [blame] | 1982 | sub get_stat_real { |
| 1983 | my ($linenr, $lc) = @_; |
| 1984 | |
| 1985 | my $stat_real = raw_line($linenr, 0); |
| 1986 | for (my $count = $linenr + 1; $count <= $lc; $count++) { |
| 1987 | $stat_real = $stat_real . "\n" . raw_line($count, 0); |
| 1988 | } |
| 1989 | |
| 1990 | return $stat_real; |
| 1991 | } |
| 1992 | |
Tobin C. Harding | e3d95a2 | 2018-04-10 16:33:27 -0700 | [diff] [blame] | 1993 | sub get_stat_here { |
| 1994 | my ($linenr, $cnt, $here) = @_; |
| 1995 | |
| 1996 | my $herectx = $here . "\n"; |
| 1997 | for (my $n = 0; $n < $cnt; $n++) { |
| 1998 | $herectx .= raw_line($linenr, $n) . "\n"; |
| 1999 | } |
| 2000 | |
| 2001 | return $herectx; |
| 2002 | } |
| 2003 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2004 | sub cat_vet { |
| 2005 | my ($vet) = @_; |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 2006 | my ($res, $coded); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2007 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 2008 | $res = ''; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2009 | while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { |
| 2010 | $res .= $1; |
| 2011 | if ($2 ne '') { |
| 2012 | $coded = sprintf("^%c", unpack('C', $2) + 64); |
| 2013 | $res .= $coded; |
| 2014 | } |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 2015 | } |
| 2016 | $res =~ s/$/\$/; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2017 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 2018 | return $res; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2019 | } |
| 2020 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2021 | my $av_preprocessor = 0; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2022 | my $av_pending; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2023 | my @av_paren_type; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2024 | my $av_pend_colon; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2025 | |
| 2026 | sub annotate_reset { |
| 2027 | $av_preprocessor = 0; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2028 | $av_pending = '_'; |
| 2029 | @av_paren_type = ('E'); |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2030 | $av_pend_colon = 'O'; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2031 | } |
| 2032 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2033 | sub annotate_values { |
| 2034 | my ($stream, $type) = @_; |
| 2035 | |
| 2036 | my $res; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2037 | my $var = '_' x length($stream); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2038 | my $cur = $stream; |
| 2039 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2040 | print "$stream\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2041 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2042 | while (length($cur)) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2043 | @av_paren_type = ('E') if ($#av_paren_type < 0); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2044 | print " <" . join('', @av_paren_type) . |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2045 | "> <$type> <$av_pending>" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2046 | if ($cur =~ /^(\s+)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2047 | print "WS($1)\n" if ($dbg_values > 1); |
| 2048 | if ($1 =~ /\n/ && $av_preprocessor) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2049 | $type = pop(@av_paren_type); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2050 | $av_preprocessor = 0; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2051 | } |
| 2052 | |
Florian Mickler | c023e473 | 2011-01-12 16:59:58 -0800 | [diff] [blame] | 2053 | } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { |
Andy Whitcroft | 9446ef5 | 2010-10-26 14:23:13 -0700 | [diff] [blame] | 2054 | print "CAST($1)\n" if ($dbg_values > 1); |
| 2055 | push(@av_paren_type, $type); |
Andy Whitcroft | addcdce | 2012-01-10 15:10:11 -0800 | [diff] [blame] | 2056 | $type = 'c'; |
Andy Whitcroft | 9446ef5 | 2010-10-26 14:23:13 -0700 | [diff] [blame] | 2057 | |
Andy Whitcroft | e91b6e2 | 2010-10-26 14:23:11 -0700 | [diff] [blame] | 2058 | } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2059 | print "DECLARE($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2060 | $type = 'T'; |
| 2061 | |
Andy Whitcroft | 389a2fe | 2008-07-23 21:29:05 -0700 | [diff] [blame] | 2062 | } elsif ($cur =~ /^($Modifier)\s*/) { |
| 2063 | print "MODIFIER($1)\n" if ($dbg_values > 1); |
| 2064 | $type = 'T'; |
| 2065 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2066 | } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2067 | print "DEFINE($1,$2)\n" if ($dbg_values > 1); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2068 | $av_preprocessor = 1; |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2069 | push(@av_paren_type, $type); |
| 2070 | if ($2 ne '') { |
| 2071 | $av_pending = 'N'; |
| 2072 | } |
| 2073 | $type = 'E'; |
| 2074 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2075 | } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2076 | print "UNDEF($1)\n" if ($dbg_values > 1); |
| 2077 | $av_preprocessor = 1; |
| 2078 | push(@av_paren_type, $type); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2079 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2080 | } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2081 | print "PRE_START($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2082 | $av_preprocessor = 1; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2083 | |
| 2084 | push(@av_paren_type, $type); |
| 2085 | push(@av_paren_type, $type); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2086 | $type = 'E'; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2087 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2088 | } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2089 | print "PRE_RESTART($1)\n" if ($dbg_values > 1); |
| 2090 | $av_preprocessor = 1; |
| 2091 | |
| 2092 | push(@av_paren_type, $av_paren_type[$#av_paren_type]); |
| 2093 | |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2094 | $type = 'E'; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2095 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2096 | } elsif ($cur =~ /^(\#\s*(?:endif))/o) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2097 | print "PRE_END($1)\n" if ($dbg_values > 1); |
| 2098 | |
| 2099 | $av_preprocessor = 1; |
| 2100 | |
| 2101 | # Assume all arms of the conditional end as this |
| 2102 | # one does, and continue as if the #endif was not here. |
| 2103 | pop(@av_paren_type); |
| 2104 | push(@av_paren_type, $type); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2105 | $type = 'E'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2106 | |
| 2107 | } elsif ($cur =~ /^(\\\n)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2108 | print "PRECONT($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2109 | |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2110 | } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { |
| 2111 | print "ATTR($1)\n" if ($dbg_values > 1); |
| 2112 | $av_pending = $type; |
| 2113 | $type = 'N'; |
| 2114 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2115 | } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2116 | print "SIZEOF($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2117 | if (defined $2) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2118 | $av_pending = 'V'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2119 | } |
| 2120 | $type = 'N'; |
| 2121 | |
Andy Whitcroft | 14b111c | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 2122 | } elsif ($cur =~ /^(if|while|for)\b/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2123 | print "COND($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 14b111c | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 2124 | $av_pending = 'E'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2125 | $type = 'N'; |
| 2126 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2127 | } elsif ($cur =~/^(case)/o) { |
| 2128 | print "CASE($1)\n" if ($dbg_values > 1); |
| 2129 | $av_pend_colon = 'C'; |
| 2130 | $type = 'N'; |
| 2131 | |
Andy Whitcroft | 14b111c | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 2132 | } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2133 | print "KEYWORD($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2134 | $type = 'N'; |
| 2135 | |
| 2136 | } elsif ($cur =~ /^(\()/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2137 | print "PAREN('$1')\n" if ($dbg_values > 1); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2138 | push(@av_paren_type, $av_pending); |
| 2139 | $av_pending = '_'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2140 | $type = 'N'; |
| 2141 | |
| 2142 | } elsif ($cur =~ /^(\))/o) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2143 | my $new_type = pop(@av_paren_type); |
| 2144 | if ($new_type ne '_') { |
| 2145 | $type = $new_type; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2146 | print "PAREN('$1') -> $type\n" |
| 2147 | if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2148 | } else { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2149 | print "PAREN('$1')\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2150 | } |
| 2151 | |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 2152 | } elsif ($cur =~ /^($Ident)\s*\(/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2153 | print "FUNC($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 2154 | $type = 'V'; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2155 | $av_pending = 'V'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2156 | |
Andy Whitcroft | 8e761b0 | 2009-01-06 14:41:19 -0800 | [diff] [blame] | 2157 | } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { |
| 2158 | if (defined $2 && $type eq 'C' || $type eq 'T') { |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2159 | $av_pend_colon = 'B'; |
Andy Whitcroft | 8e761b0 | 2009-01-06 14:41:19 -0800 | [diff] [blame] | 2160 | } elsif ($type eq 'E') { |
| 2161 | $av_pend_colon = 'L'; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2162 | } |
| 2163 | print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); |
| 2164 | $type = 'V'; |
| 2165 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2166 | } elsif ($cur =~ /^($Ident|$Constant)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2167 | print "IDENT($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2168 | $type = 'V'; |
| 2169 | |
| 2170 | } elsif ($cur =~ /^($Assignment)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2171 | print "ASSIGN($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2172 | $type = 'N'; |
| 2173 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 2174 | } elsif ($cur =~/^(;|{|})/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2175 | print "END($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2176 | $type = 'E'; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2177 | $av_pend_colon = 'O'; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2178 | |
Andy Whitcroft | 8e761b0 | 2009-01-06 14:41:19 -0800 | [diff] [blame] | 2179 | } elsif ($cur =~/^(,)/) { |
| 2180 | print "COMMA($1)\n" if ($dbg_values > 1); |
| 2181 | $type = 'C'; |
| 2182 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2183 | } elsif ($cur =~ /^(\?)/o) { |
| 2184 | print "QUESTION($1)\n" if ($dbg_values > 1); |
| 2185 | $type = 'N'; |
| 2186 | |
| 2187 | } elsif ($cur =~ /^(:)/o) { |
| 2188 | print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); |
| 2189 | |
| 2190 | substr($var, length($res), 1, $av_pend_colon); |
| 2191 | if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { |
| 2192 | $type = 'E'; |
| 2193 | } else { |
| 2194 | $type = 'N'; |
| 2195 | } |
| 2196 | $av_pend_colon = 'O'; |
| 2197 | |
Andy Whitcroft | 8e761b0 | 2009-01-06 14:41:19 -0800 | [diff] [blame] | 2198 | } elsif ($cur =~ /^(\[)/o) { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2199 | print "CLOSE($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2200 | $type = 'N'; |
| 2201 | |
Andy Whitcroft | 0d41386 | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 2202 | } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { |
Andy Whitcroft | 74048ed | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2203 | my $variant; |
| 2204 | |
| 2205 | print "OPV($1)\n" if ($dbg_values > 1); |
| 2206 | if ($type eq 'V') { |
| 2207 | $variant = 'B'; |
| 2208 | } else { |
| 2209 | $variant = 'U'; |
| 2210 | } |
| 2211 | |
| 2212 | substr($var, length($res), 1, $variant); |
| 2213 | $type = 'N'; |
| 2214 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2215 | } elsif ($cur =~ /^($Operators)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2216 | print "OP($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2217 | if ($1 ne '++' && $1 ne '--') { |
| 2218 | $type = 'N'; |
| 2219 | } |
| 2220 | |
| 2221 | } elsif ($cur =~ /(^.)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2222 | print "C($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2223 | } |
| 2224 | if (defined $1) { |
| 2225 | $cur = substr($cur, length($1)); |
| 2226 | $res .= $type x length($1); |
| 2227 | } |
| 2228 | } |
| 2229 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 2230 | return ($res, $var); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2231 | } |
| 2232 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 2233 | sub possible { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2234 | my ($possible, $line) = @_; |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 2235 | my $notPermitted = qr{(?: |
Andy Whitcroft | 0776e59 | 2008-10-15 22:02:29 -0700 | [diff] [blame] | 2236 | ^(?: |
| 2237 | $Modifier| |
| 2238 | $Storage| |
| 2239 | $Type| |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 2240 | DEFINE_\S+ |
| 2241 | )$| |
| 2242 | ^(?: |
Andy Whitcroft | 0776e59 | 2008-10-15 22:02:29 -0700 | [diff] [blame] | 2243 | goto| |
| 2244 | return| |
| 2245 | case| |
| 2246 | else| |
| 2247 | asm|__asm__| |
Andy Whitcroft | 89a8835 | 2012-01-10 15:10:00 -0800 | [diff] [blame] | 2248 | do| |
| 2249 | \#| |
| 2250 | \#\#| |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 2251 | )(?:\s|$)| |
Andy Whitcroft | 0776e59 | 2008-10-15 22:02:29 -0700 | [diff] [blame] | 2252 | ^(?:typedef|struct|enum)\b |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 2253 | )}x; |
| 2254 | warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); |
| 2255 | if ($possible !~ $notPermitted) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2256 | # Check for modifiers. |
| 2257 | $possible =~ s/\s*$Storage\s*//g; |
| 2258 | $possible =~ s/\s*$Sparse\s*//g; |
| 2259 | if ($possible =~ /^\s*$/) { |
| 2260 | |
| 2261 | } elsif ($possible =~ /\s/) { |
| 2262 | $possible =~ s/\s*$Type\s*//g; |
Andy Whitcroft | d250658 | 2008-07-23 21:29:09 -0700 | [diff] [blame] | 2263 | for my $modifier (split(' ', $possible)) { |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 2264 | if ($modifier !~ $notPermitted) { |
| 2265 | warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 2266 | push(@modifierListFile, $modifier); |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 2267 | } |
Andy Whitcroft | d250658 | 2008-07-23 21:29:09 -0700 | [diff] [blame] | 2268 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2269 | |
| 2270 | } else { |
| 2271 | warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 2272 | push(@typeListFile, $possible); |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2273 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 2274 | build_types(); |
Andy Whitcroft | 0776e59 | 2008-10-15 22:02:29 -0700 | [diff] [blame] | 2275 | } else { |
| 2276 | warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 2277 | } |
| 2278 | } |
| 2279 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2280 | my $prefix = ''; |
| 2281 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2282 | sub show_type { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2283 | my ($type) = @_; |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 2284 | |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 2285 | $type =~ tr/[a-z]/[A-Z]/; |
| 2286 | |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2287 | return defined $use_type{$type} if (scalar keys %use_type > 0); |
| 2288 | |
| 2289 | return !defined $ignore_type{$type}; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2290 | } |
| 2291 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 2292 | sub report { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2293 | my ($level, $type, $msg) = @_; |
| 2294 | |
| 2295 | if (!show_type($type) || |
| 2296 | (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2297 | return 0; |
| 2298 | } |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 2299 | my $output = ''; |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 2300 | if ($color) { |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 2301 | if ($level eq 'ERROR') { |
| 2302 | $output .= RED; |
| 2303 | } elsif ($level eq 'WARNING') { |
| 2304 | $output .= YELLOW; |
| 2305 | } else { |
| 2306 | $output .= GREEN; |
| 2307 | } |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2308 | } |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 2309 | $output .= $prefix . $level . ':'; |
| 2310 | if ($show_types) { |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 2311 | $output .= BLUE if ($color); |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 2312 | $output .= "$type:"; |
| 2313 | } |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 2314 | $output .= RESET if ($color); |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 2315 | $output .= ' ' . $msg . "\n"; |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 2316 | |
| 2317 | if ($showfile) { |
| 2318 | my @lines = split("\n", $output, -1); |
| 2319 | splice(@lines, 1, 1); |
| 2320 | $output = join("\n", @lines); |
| 2321 | } |
Dwaipayan Ray | 52178ce | 2021-02-26 15:08:26 +0530 | [diff] [blame] | 2322 | |
| 2323 | if ($terse) { |
| 2324 | $output = (split('\n', $output))[0] . "\n"; |
| 2325 | } |
| 2326 | |
| 2327 | if ($verbose && exists($verbose_messages{$type}) && |
| 2328 | !exists($verbose_emitted{$type})) { |
| 2329 | $output .= $verbose_messages{$type} . "\n\n"; |
| 2330 | $verbose_emitted{$type} = 1; |
| 2331 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 2332 | |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 2333 | push(our @report, $output); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2334 | |
| 2335 | return 1; |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 2336 | } |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2337 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 2338 | sub report_dump { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2339 | our @report; |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 2340 | } |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2341 | |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 2342 | sub fixup_current_range { |
| 2343 | my ($lineRef, $offset, $length) = @_; |
| 2344 | |
| 2345 | if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { |
| 2346 | my $o = $1; |
| 2347 | my $l = $2; |
| 2348 | my $no = $o + $offset; |
| 2349 | my $nl = $l + $length; |
| 2350 | $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; |
| 2351 | } |
| 2352 | } |
| 2353 | |
| 2354 | sub fix_inserted_deleted_lines { |
| 2355 | my ($linesRef, $insertedRef, $deletedRef) = @_; |
| 2356 | |
| 2357 | my $range_last_linenr = 0; |
| 2358 | my $delta_offset = 0; |
| 2359 | |
| 2360 | my $old_linenr = 0; |
| 2361 | my $new_linenr = 0; |
| 2362 | |
| 2363 | my $next_insert = 0; |
| 2364 | my $next_delete = 0; |
| 2365 | |
| 2366 | my @lines = (); |
| 2367 | |
| 2368 | my $inserted = @{$insertedRef}[$next_insert++]; |
| 2369 | my $deleted = @{$deletedRef}[$next_delete++]; |
| 2370 | |
| 2371 | foreach my $old_line (@{$linesRef}) { |
| 2372 | my $save_line = 1; |
| 2373 | my $line = $old_line; #don't modify the array |
Joe Perches | 323b267 | 2015-04-16 12:44:50 -0700 | [diff] [blame] | 2374 | if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 2375 | $delta_offset = 0; |
| 2376 | } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk |
| 2377 | $range_last_linenr = $new_linenr; |
| 2378 | fixup_current_range(\$line, $delta_offset, 0); |
| 2379 | } |
| 2380 | |
| 2381 | while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { |
| 2382 | $deleted = @{$deletedRef}[$next_delete++]; |
| 2383 | $save_line = 0; |
| 2384 | fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); |
| 2385 | } |
| 2386 | |
| 2387 | while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { |
| 2388 | push(@lines, ${$inserted}{'LINE'}); |
| 2389 | $inserted = @{$insertedRef}[$next_insert++]; |
| 2390 | $new_linenr++; |
| 2391 | fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); |
| 2392 | } |
| 2393 | |
| 2394 | if ($save_line) { |
| 2395 | push(@lines, $line); |
| 2396 | $new_linenr++; |
| 2397 | } |
| 2398 | |
| 2399 | $old_linenr++; |
| 2400 | } |
| 2401 | |
| 2402 | return @lines; |
| 2403 | } |
| 2404 | |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 2405 | sub fix_insert_line { |
| 2406 | my ($linenr, $line) = @_; |
| 2407 | |
| 2408 | my $inserted = { |
| 2409 | LINENR => $linenr, |
| 2410 | LINE => $line, |
| 2411 | }; |
| 2412 | push(@fixed_inserted, $inserted); |
| 2413 | } |
| 2414 | |
| 2415 | sub fix_delete_line { |
| 2416 | my ($linenr, $line) = @_; |
| 2417 | |
| 2418 | my $deleted = { |
| 2419 | LINENR => $linenr, |
| 2420 | LINE => $line, |
| 2421 | }; |
| 2422 | |
| 2423 | push(@fixed_deleted, $deleted); |
| 2424 | } |
| 2425 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2426 | sub ERROR { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2427 | my ($type, $msg) = @_; |
| 2428 | |
| 2429 | if (report("ERROR", $type, $msg)) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2430 | our $clean = 0; |
| 2431 | our $cnt_error++; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2432 | return 1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2433 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2434 | return 0; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2435 | } |
| 2436 | sub WARN { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2437 | my ($type, $msg) = @_; |
| 2438 | |
| 2439 | if (report("WARNING", $type, $msg)) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2440 | our $clean = 0; |
| 2441 | our $cnt_warn++; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2442 | return 1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2443 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2444 | return 0; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2445 | } |
| 2446 | sub CHK { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2447 | my ($type, $msg) = @_; |
| 2448 | |
| 2449 | if ($check && report("CHECK", $type, $msg)) { |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2450 | our $clean = 0; |
| 2451 | our $cnt_chk++; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2452 | return 1; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2453 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2454 | return 0; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2455 | } |
| 2456 | |
Andy Whitcroft | 6ecd967 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 2457 | sub check_absolute_file { |
| 2458 | my ($absolute, $herecurr) = @_; |
| 2459 | my $file = $absolute; |
| 2460 | |
| 2461 | ##print "absolute<$absolute>\n"; |
| 2462 | |
| 2463 | # See if any suffix of this path is a path within the tree. |
| 2464 | while ($file =~ s@^[^/]*/@@) { |
| 2465 | if (-f "$root/$file") { |
| 2466 | ##print "file<$file>\n"; |
| 2467 | last; |
| 2468 | } |
| 2469 | } |
| 2470 | if (! -f _) { |
| 2471 | return 0; |
| 2472 | } |
| 2473 | |
| 2474 | # It is, so see if the prefix is acceptable. |
| 2475 | my $prefix = $absolute; |
| 2476 | substr($prefix, -length($file)) = ''; |
| 2477 | |
| 2478 | ##print "prefix<$prefix>\n"; |
| 2479 | if ($prefix ne ".../") { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2480 | WARN("USE_RELATIVE_PATH", |
| 2481 | "use relative pathname instead of absolute in changelog text\n" . $herecurr); |
Andy Whitcroft | 6ecd967 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 2482 | } |
| 2483 | } |
| 2484 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2485 | sub trim { |
| 2486 | my ($string) = @_; |
| 2487 | |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 2488 | $string =~ s/^\s+|\s+$//g; |
| 2489 | |
| 2490 | return $string; |
| 2491 | } |
| 2492 | |
| 2493 | sub ltrim { |
| 2494 | my ($string) = @_; |
| 2495 | |
| 2496 | $string =~ s/^\s+//; |
| 2497 | |
| 2498 | return $string; |
| 2499 | } |
| 2500 | |
| 2501 | sub rtrim { |
| 2502 | my ($string) = @_; |
| 2503 | |
| 2504 | $string =~ s/\s+$//; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2505 | |
| 2506 | return $string; |
| 2507 | } |
| 2508 | |
Joe Perches | 52ea850 | 2013-11-12 15:10:09 -0800 | [diff] [blame] | 2509 | sub string_find_replace { |
| 2510 | my ($string, $find, $replace) = @_; |
| 2511 | |
| 2512 | $string =~ s/$find/$replace/g; |
| 2513 | |
| 2514 | return $string; |
| 2515 | } |
| 2516 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2517 | sub tabify { |
| 2518 | my ($leading) = @_; |
| 2519 | |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 2520 | my $source_indent = $tabsize; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2521 | my $max_spaces_before_tab = $source_indent - 1; |
| 2522 | my $spaces_to_tab = " " x $source_indent; |
| 2523 | |
| 2524 | #convert leading spaces to tabs |
| 2525 | 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; |
| 2526 | #Remove spaces before a tab |
| 2527 | 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; |
| 2528 | |
| 2529 | return "$leading"; |
| 2530 | } |
| 2531 | |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 2532 | sub pos_last_openparen { |
| 2533 | my ($line) = @_; |
| 2534 | |
| 2535 | my $pos = 0; |
| 2536 | |
| 2537 | my $opens = $line =~ tr/\(/\(/; |
| 2538 | my $closes = $line =~ tr/\)/\)/; |
| 2539 | |
| 2540 | my $last_openparen = 0; |
| 2541 | |
| 2542 | if (($opens == 0) || ($closes >= $opens)) { |
| 2543 | return -1; |
| 2544 | } |
| 2545 | |
| 2546 | my $len = length($line); |
| 2547 | |
| 2548 | for ($pos = 0; $pos < $len; $pos++) { |
| 2549 | my $string = substr($line, $pos); |
| 2550 | if ($string =~ /^($FuncArg|$balanced_parens)/) { |
| 2551 | $pos += length($1) - 1; |
| 2552 | } elsif (substr($line, $pos, 1) eq '(') { |
| 2553 | $last_openparen = $pos; |
| 2554 | } elsif (index($string, '(') == -1) { |
| 2555 | last; |
| 2556 | } |
| 2557 | } |
| 2558 | |
Joe Perches | 91cb519 | 2014-04-03 14:49:32 -0700 | [diff] [blame] | 2559 | return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 2560 | } |
| 2561 | |
Joe Perches | f36d3eb | 2020-04-06 20:10:58 -0700 | [diff] [blame] | 2562 | sub get_raw_comment { |
| 2563 | my ($line, $rawline) = @_; |
| 2564 | my $comment = ''; |
| 2565 | |
| 2566 | for my $i (0 .. (length($line) - 1)) { |
| 2567 | if (substr($line, $i, 1) eq "$;") { |
| 2568 | $comment .= substr($rawline, $i, 1); |
| 2569 | } |
| 2570 | } |
| 2571 | |
| 2572 | return $comment; |
| 2573 | } |
| 2574 | |
Song Liu | 5b8f82e | 2021-02-25 17:22:08 -0800 | [diff] [blame] | 2575 | sub exclude_global_initialisers { |
| 2576 | my ($realfile) = @_; |
| 2577 | |
| 2578 | # Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c). |
| 2579 | return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ || |
| 2580 | $realfile =~ m@^samples/bpf/.*_kern\.c$@ || |
| 2581 | $realfile =~ m@/bpf/.*\.bpf\.c$@; |
| 2582 | } |
| 2583 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2584 | sub process { |
| 2585 | my $filename = shift; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2586 | |
| 2587 | my $linenr=0; |
| 2588 | my $prevline=""; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2589 | my $prevrawline=""; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2590 | my $stashline=""; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2591 | my $stashrawline=""; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2592 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2593 | my $length; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2594 | my $indent; |
| 2595 | my $previndent=0; |
| 2596 | my $stashindent=0; |
| 2597 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2598 | our $clean = 1; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2599 | my $signoff = 0; |
Geert Uytterhoeven | cd26149 | 2018-08-21 21:57:40 -0700 | [diff] [blame] | 2600 | my $author = ''; |
| 2601 | my $authorsignoff = 0; |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 2602 | my $author_sob = ''; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2603 | my $is_patch = 0; |
Rob Herring | 133712a | 2018-08-21 21:58:16 -0700 | [diff] [blame] | 2604 | my $is_binding_patch = -1; |
Joe Perches | 29ee1b0 | 2014-08-06 16:10:35 -0700 | [diff] [blame] | 2605 | my $in_header_lines = $file ? 0 : 1; |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2606 | my $in_commit_log = 0; #Scanning lines before patch |
Joe Perches | 44d303e | 2020-04-06 20:11:10 -0700 | [diff] [blame] | 2607 | my $has_patch_separator = 0; #Found a --- line |
Allen Hubbe | ed43c4e | 2016-08-02 14:04:45 -0700 | [diff] [blame] | 2608 | my $has_commit_log = 0; #Encountered lines before patch |
Joe Perches | 490b292 | 2018-08-21 21:58:01 -0700 | [diff] [blame] | 2609 | my $commit_log_lines = 0; #Number of commit log lines |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 2610 | my $commit_log_possible_stack_dump = 0; |
Joe Perches | 2a076f4 | 2015-04-16 12:44:28 -0700 | [diff] [blame] | 2611 | my $commit_log_long_line = 0; |
Joe Perches | e518e9a | 2015-06-25 15:03:27 -0700 | [diff] [blame] | 2612 | my $commit_log_has_diff = 0; |
Joe Perches | 13f1937 | 2014-08-06 16:10:59 -0700 | [diff] [blame] | 2613 | my $reported_maintainer_file = 0; |
Pasi Savanainen | fa64205d | 2012-10-04 17:13:29 -0700 | [diff] [blame] | 2614 | my $non_utf8_charset = 0; |
| 2615 | |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 2616 | my $last_git_commit_id_linenr = -1; |
| 2617 | |
Joe Perches | 365dd4e | 2014-08-06 16:10:42 -0700 | [diff] [blame] | 2618 | my $last_blank_line = 0; |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 2619 | my $last_coalesced_string_linenr = -1; |
Joe Perches | 365dd4e | 2014-08-06 16:10:42 -0700 | [diff] [blame] | 2620 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2621 | our @report = (); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2622 | our $cnt_lines = 0; |
| 2623 | our $cnt_error = 0; |
| 2624 | our $cnt_warn = 0; |
| 2625 | our $cnt_chk = 0; |
| 2626 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2627 | # Trace the real file/line as we go. |
| 2628 | my $realfile = ''; |
| 2629 | my $realline = 0; |
| 2630 | my $realcnt = 0; |
| 2631 | my $here = ''; |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 2632 | my $context_function; #undef'd unless there's a known function |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2633 | my $in_comment = 0; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2634 | my $comment_edge = 0; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2635 | my $first_line = 0; |
Wolfram Sang | 1e85572 | 2009-01-06 14:41:24 -0800 | [diff] [blame] | 2636 | my $p1_prefix = ''; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2637 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2638 | my $prev_values = 'E'; |
| 2639 | |
| 2640 | # suppression flags |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2641 | my %suppress_ifbraces; |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 2642 | my %suppress_whiletrailers; |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 2643 | my %suppress_export; |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 2644 | my $suppress_statement = 0; |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 2645 | |
Joe Perches | 7e51f19 | 2013-09-11 14:23:57 -0700 | [diff] [blame] | 2646 | my %signatures = (); |
Joe Perches | 323c126 | 2012-12-17 16:02:07 -0800 | [diff] [blame] | 2647 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2648 | # Pre-scan the patch sanitizing the lines. |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2649 | # Pre-scan the patch looking for any __setup documentation. |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2650 | # |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2651 | my @setup_docs = (); |
| 2652 | my $setup_docs = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2653 | |
Joe Perches | d8b0771 | 2013-11-12 15:10:06 -0800 | [diff] [blame] | 2654 | my $camelcase_file_seeded = 0; |
| 2655 | |
Rob Herring | 9f3a899 | 2018-04-10 16:33:13 -0700 | [diff] [blame] | 2656 | my $checklicenseline = 1; |
| 2657 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2658 | sanitise_line_reset(); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2659 | my $line; |
| 2660 | foreach my $rawline (@rawlines) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2661 | $linenr++; |
| 2662 | $line = $rawline; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2663 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2664 | push(@fixed, $rawline) if ($fix); |
| 2665 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2666 | if ($rawline=~/^\+\+\+\s+(\S+)/) { |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2667 | $setup_docs = 0; |
Tim Froidcoeur | 2581ac7 | 2020-06-10 18:41:38 -0700 | [diff] [blame] | 2668 | if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2669 | $setup_docs = 1; |
| 2670 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2671 | #next; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2672 | } |
Joe Perches | 74fd4f3 | 2017-05-08 15:56:02 -0700 | [diff] [blame] | 2673 | if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2674 | $realline=$1-1; |
| 2675 | if (defined $2) { |
| 2676 | $realcnt=$3+1; |
| 2677 | } else { |
| 2678 | $realcnt=1+1; |
| 2679 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2680 | $in_comment = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2681 | |
| 2682 | # Guestimate if this is a continuing comment. Run |
| 2683 | # the context looking for a comment "edge". If this |
| 2684 | # edge is a close comment then we must be in a comment |
| 2685 | # at context start. |
| 2686 | my $edge; |
Andy Whitcroft | 01fa914 | 2008-10-15 22:02:19 -0700 | [diff] [blame] | 2687 | my $cnt = $realcnt; |
| 2688 | for (my $ln = $linenr + 1; $cnt > 0; $ln++) { |
| 2689 | next if (defined $rawlines[$ln - 1] && |
| 2690 | $rawlines[$ln - 1] =~ /^-/); |
| 2691 | $cnt--; |
| 2692 | #print "RAW<$rawlines[$ln - 1]>\n"; |
Andy Whitcroft | 721c1cb | 2009-01-06 14:41:16 -0800 | [diff] [blame] | 2693 | last if (!defined $rawlines[$ln - 1]); |
Andy Whitcroft | fae17da | 2009-01-06 14:41:20 -0800 | [diff] [blame] | 2694 | if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && |
| 2695 | $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { |
| 2696 | ($edge) = $1; |
| 2697 | last; |
| 2698 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2699 | } |
| 2700 | if (defined $edge && $edge eq '*/') { |
| 2701 | $in_comment = 1; |
| 2702 | } |
| 2703 | |
| 2704 | # Guestimate if this is a continuing comment. If this |
| 2705 | # is the start of a diff block and this line starts |
| 2706 | # ' *' then it is very likely a comment. |
| 2707 | if (!defined $edge && |
Andy Whitcroft | 83242e0 | 2009-01-06 14:41:17 -0800 | [diff] [blame] | 2708 | $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2709 | { |
| 2710 | $in_comment = 1; |
| 2711 | } |
| 2712 | |
| 2713 | ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; |
| 2714 | sanitise_line_reset($in_comment); |
| 2715 | |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2716 | } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2717 | # Standardise the strings and chars within the input to |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2718 | # simplify matching -- only bother with positive lines. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2719 | $line = sanitise_line($rawline); |
| 2720 | } |
| 2721 | push(@lines, $line); |
| 2722 | |
| 2723 | if ($realcnt > 1) { |
| 2724 | $realcnt-- if ($line =~ /^(?:\+| |$)/); |
| 2725 | } else { |
| 2726 | $realcnt = 0; |
| 2727 | } |
| 2728 | |
| 2729 | #print "==>$rawline\n"; |
| 2730 | #print "-->$line\n"; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2731 | |
| 2732 | if ($setup_docs && $line =~ /^\+/) { |
| 2733 | push(@setup_docs, $line); |
| 2734 | } |
| 2735 | } |
| 2736 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2737 | $prefix = ''; |
| 2738 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2739 | $realcnt = 0; |
| 2740 | $linenr = 0; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2741 | $fixlinenr = -1; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2742 | foreach my $line (@lines) { |
| 2743 | $linenr++; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2744 | $fixlinenr++; |
Joe Perches | 1b5539b | 2013-09-11 14:24:03 -0700 | [diff] [blame] | 2745 | my $sline = $line; #copy of $line |
| 2746 | $sline =~ s/$;/ /g; #with comments as spaces |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2747 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2748 | my $rawline = $rawlines[$linenr - 1]; |
Joe Perches | f36d3eb | 2020-04-06 20:10:58 -0700 | [diff] [blame] | 2749 | my $raw_comment = get_raw_comment($line, $rawline); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2750 | |
Joe Perches | 12c253a | 2018-06-07 17:10:58 -0700 | [diff] [blame] | 2751 | # check if it's a mode change, rename or start of a patch |
| 2752 | if (!$in_commit_log && |
| 2753 | ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || |
| 2754 | ($line =~ /^rename (?:from|to) \S+\s*$/ || |
| 2755 | $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { |
| 2756 | $is_patch = 1; |
| 2757 | } |
| 2758 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2759 | #extract the line range in the file after the patch is applied |
Joe Perches | e518e9a | 2015-06-25 15:03:27 -0700 | [diff] [blame] | 2760 | if (!$in_commit_log && |
Joe Perches | 74fd4f3 | 2017-05-08 15:56:02 -0700 | [diff] [blame] | 2761 | $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { |
| 2762 | my $context = $4; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2763 | $is_patch = 1; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2764 | $first_line = $linenr + 1; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2765 | $realline=$1-1; |
| 2766 | if (defined $2) { |
| 2767 | $realcnt=$3+1; |
| 2768 | } else { |
| 2769 | $realcnt=1+1; |
| 2770 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2771 | annotate_reset(); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2772 | $prev_values = 'E'; |
| 2773 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2774 | %suppress_ifbraces = (); |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 2775 | %suppress_whiletrailers = (); |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 2776 | %suppress_export = (); |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 2777 | $suppress_statement = 0; |
Joe Perches | 74fd4f3 | 2017-05-08 15:56:02 -0700 | [diff] [blame] | 2778 | if ($context =~ /\b(\w+)\s*\(/) { |
| 2779 | $context_function = $1; |
| 2780 | } else { |
| 2781 | undef $context_function; |
| 2782 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2783 | next; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2784 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2785 | # track the line number as we move through the hunk, note that |
| 2786 | # new versions of GNU diff omit the leading space on completely |
| 2787 | # blank context lines so we need to count that too. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2788 | } elsif ($line =~ /^( |\+|$)/) { |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2789 | $realline++; |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 2790 | $realcnt-- if ($realcnt != 0); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2791 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2792 | # Measure the line length and indent. |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2793 | ($length, $indent) = line_stats($rawline); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2794 | |
| 2795 | # Track the previous line. |
| 2796 | ($prevline, $stashline) = ($stashline, $line); |
| 2797 | ($previndent, $stashindent) = ($stashindent, $indent); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2798 | ($prevrawline, $stashrawline) = ($stashrawline, $rawline); |
| 2799 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2800 | #warn "line<$line>\n"; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2801 | |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 2802 | } elsif ($realcnt == 1) { |
| 2803 | $realcnt--; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2804 | } |
| 2805 | |
Andy Whitcroft | cc77cdc | 2009-10-26 16:50:13 -0700 | [diff] [blame] | 2806 | my $hunk_line = ($realcnt != 0); |
| 2807 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2808 | $here = "#$linenr: " if (!$file); |
| 2809 | $here = "#$realline: " if ($file); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2810 | |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2811 | my $found_file = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2812 | # extract the filename as it passes |
Rabin Vincent | 3bf9a00 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 2813 | if ($line =~ /^diff --git.*?(\S+)$/) { |
| 2814 | $realfile = $1; |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 2815 | $realfile =~ s@^([^/]*)/@@ if (!$file); |
Joe Perches | 270c49a | 2012-01-10 15:09:50 -0800 | [diff] [blame] | 2816 | $in_commit_log = 0; |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2817 | $found_file = 1; |
Rabin Vincent | 3bf9a00 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 2818 | } elsif ($line =~ /^\+\+\+\s+(\S+)/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2819 | $realfile = $1; |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 2820 | $realfile =~ s@^([^/]*)/@@ if (!$file); |
Joe Perches | 270c49a | 2012-01-10 15:09:50 -0800 | [diff] [blame] | 2821 | $in_commit_log = 0; |
Wolfram Sang | 1e85572 | 2009-01-06 14:41:24 -0800 | [diff] [blame] | 2822 | |
| 2823 | $p1_prefix = $1; |
Andy Whitcroft | e2f7aa4 | 2009-02-27 14:03:06 -0800 | [diff] [blame] | 2824 | if (!$file && $tree && $p1_prefix ne '' && |
| 2825 | -e "$root/$p1_prefix") { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2826 | WARN("PATCH_PREFIX", |
| 2827 | "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); |
Wolfram Sang | 1e85572 | 2009-01-06 14:41:24 -0800 | [diff] [blame] | 2828 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2829 | |
Andy Whitcroft | c1ab332 | 2008-10-15 22:02:20 -0700 | [diff] [blame] | 2830 | if ($realfile =~ m@^include/asm/@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2831 | ERROR("MODIFIED_INCLUDE_ASM", |
| 2832 | "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2833 | } |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2834 | $found_file = 1; |
| 2835 | } |
| 2836 | |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 2837 | #make up the handle for any error we report on this line |
| 2838 | if ($showfile) { |
| 2839 | $prefix = "$realfile:$realline: " |
| 2840 | } elsif ($emacs) { |
Joe Perches | 7d3a9f6 | 2015-09-09 15:37:39 -0700 | [diff] [blame] | 2841 | if ($file) { |
| 2842 | $prefix = "$filename:$realline: "; |
| 2843 | } else { |
| 2844 | $prefix = "$filename:$linenr: "; |
| 2845 | } |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 2846 | } |
| 2847 | |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2848 | if ($found_file) { |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 2849 | if (is_maintained_obsolete($realfile)) { |
| 2850 | WARN("OBSOLETE", |
| 2851 | "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); |
| 2852 | } |
Joe Perches | 7bd7e48 | 2015-09-09 15:37:44 -0700 | [diff] [blame] | 2853 | if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2854 | $check = 1; |
| 2855 | } else { |
| 2856 | $check = $check_orig; |
| 2857 | } |
Rob Herring | 9f3a899 | 2018-04-10 16:33:13 -0700 | [diff] [blame] | 2858 | $checklicenseline = 1; |
Rob Herring | 133712a | 2018-08-21 21:58:16 -0700 | [diff] [blame] | 2859 | |
| 2860 | if ($realfile !~ /^MAINTAINERS/) { |
| 2861 | my $last_binding_patch = $is_binding_patch; |
| 2862 | |
| 2863 | $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; |
| 2864 | |
| 2865 | if (($last_binding_patch != -1) && |
| 2866 | ($last_binding_patch ^ $is_binding_patch)) { |
| 2867 | WARN("DT_SPLIT_BINDING_PATCH", |
Mauro Carvalho Chehab | 858e684 | 2020-04-15 16:45:25 +0200 | [diff] [blame] | 2868 | "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); |
Rob Herring | 133712a | 2018-08-21 21:58:16 -0700 | [diff] [blame] | 2869 | } |
| 2870 | } |
| 2871 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2872 | next; |
| 2873 | } |
| 2874 | |
Randy Dunlap | 389834b | 2007-06-08 13:47:03 -0700 | [diff] [blame] | 2875 | $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2876 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2877 | my $hereline = "$here\n$rawline\n"; |
| 2878 | my $herecurr = "$here\n$rawline\n"; |
| 2879 | my $hereprev = "$here\n$prevrawline\n$rawline\n"; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2880 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2881 | $cnt_lines++ if ($realcnt != 0); |
| 2882 | |
Joe Perches | 490b292 | 2018-08-21 21:58:01 -0700 | [diff] [blame] | 2883 | # Verify the existence of a commit log if appropriate |
| 2884 | # 2 is used because a $signature is counted in $commit_log_lines |
| 2885 | if ($in_commit_log) { |
| 2886 | if ($line !~ /^\s*$/) { |
| 2887 | $commit_log_lines++; #could be a $signature |
| 2888 | } |
| 2889 | } elsif ($has_commit_log && $commit_log_lines < 2) { |
| 2890 | WARN("COMMIT_MESSAGE", |
| 2891 | "Missing commit description - Add an appropriate one\n"); |
| 2892 | $commit_log_lines = 2; #warn only once |
| 2893 | } |
| 2894 | |
Joe Perches | e518e9a | 2015-06-25 15:03:27 -0700 | [diff] [blame] | 2895 | # Check if the commit log has what seems like a diff which can confuse patch |
| 2896 | if ($in_commit_log && !$commit_log_has_diff && |
Mrinal Pandey | 13e4541 | 2020-09-04 16:35:52 -0700 | [diff] [blame] | 2897 | (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && |
| 2898 | $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || |
Joe Perches | e518e9a | 2015-06-25 15:03:27 -0700 | [diff] [blame] | 2899 | $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || |
| 2900 | $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { |
| 2901 | ERROR("DIFF_IN_COMMIT_MSG", |
| 2902 | "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); |
| 2903 | $commit_log_has_diff = 1; |
| 2904 | } |
| 2905 | |
Rabin Vincent | 3bf9a00 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 2906 | # Check for incorrect file permissions |
| 2907 | if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { |
| 2908 | my $permhere = $here . "FILE: $realfile\n"; |
Joe Perches | 04db4d2 | 2013-04-29 16:18:14 -0700 | [diff] [blame] | 2909 | if ($realfile !~ m@scripts/@ && |
| 2910 | $realfile !~ /\.(py|pl|awk|sh)$/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2911 | ERROR("EXECUTE_PERMISSIONS", |
| 2912 | "do not set execute permissions for source files\n" . $permhere); |
Rabin Vincent | 3bf9a00 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 2913 | } |
| 2914 | } |
| 2915 | |
Geert Uytterhoeven | cd26149 | 2018-08-21 21:57:40 -0700 | [diff] [blame] | 2916 | # Check the patch for a From: |
| 2917 | if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { |
| 2918 | $author = $1; |
Dwaipayan Ray | e7f929f | 2020-10-15 20:12:15 -0700 | [diff] [blame] | 2919 | my $curline = $linenr; |
| 2920 | while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { |
| 2921 | $author .= $1; |
| 2922 | } |
Geert Uytterhoeven | cd26149 | 2018-08-21 21:57:40 -0700 | [diff] [blame] | 2923 | $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); |
| 2924 | $author =~ s/"//g; |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 2925 | $author = reformat_email($author); |
Geert Uytterhoeven | cd26149 | 2018-08-21 21:57:40 -0700 | [diff] [blame] | 2926 | } |
| 2927 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2928 | # Check the patch for a signoff: |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 2929 | if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2930 | $signoff++; |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2931 | $in_commit_log = 0; |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 2932 | if ($author ne '' && $authorsignoff != 1) { |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 2933 | if (same_email_addresses($1, $author)) { |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 2934 | $authorsignoff = 1; |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 2935 | } else { |
| 2936 | my $ctx = $1; |
| 2937 | my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); |
| 2938 | my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); |
| 2939 | |
Mimi Zohar | 046fc74 | 2021-09-07 19:59:54 -0700 | [diff] [blame] | 2940 | if (lc $email_address eq lc $author_address && $email_name eq $author_name) { |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 2941 | $author_sob = $ctx; |
| 2942 | $authorsignoff = 2; |
Mimi Zohar | 046fc74 | 2021-09-07 19:59:54 -0700 | [diff] [blame] | 2943 | } elsif (lc $email_address eq lc $author_address) { |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 2944 | $author_sob = $ctx; |
| 2945 | $authorsignoff = 3; |
| 2946 | } elsif ($email_name eq $author_name) { |
| 2947 | $author_sob = $ctx; |
| 2948 | $authorsignoff = 4; |
| 2949 | |
| 2950 | my $address1 = $email_address; |
| 2951 | my $address2 = $author_address; |
| 2952 | |
| 2953 | if ($address1 =~ /(\S+)\+\S+(\@.*)/) { |
| 2954 | $address1 = "$1$2"; |
| 2955 | } |
| 2956 | if ($address2 =~ /(\S+)\+\S+(\@.*)/) { |
| 2957 | $address2 = "$1$2"; |
| 2958 | } |
| 2959 | if ($address1 eq $address2) { |
| 2960 | $authorsignoff = 5; |
| 2961 | } |
| 2962 | } |
Geert Uytterhoeven | cd26149 | 2018-08-21 21:57:40 -0700 | [diff] [blame] | 2963 | } |
| 2964 | } |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2965 | } |
| 2966 | |
Joe Perches | 44d303e | 2020-04-06 20:11:10 -0700 | [diff] [blame] | 2967 | # Check for patch separator |
| 2968 | if ($line =~ /^---$/) { |
| 2969 | $has_patch_separator = 1; |
| 2970 | $in_commit_log = 0; |
| 2971 | } |
| 2972 | |
Joe Perches | e0d975b | 2014-12-10 15:51:49 -0800 | [diff] [blame] | 2973 | # Check if MAINTAINERS is being updated. If so, there's probably no need to |
| 2974 | # emit the "does MAINTAINERS need updating?" message on file add/move/delete |
| 2975 | if ($line =~ /^\s*MAINTAINERS\s*\|/) { |
| 2976 | $reported_maintainer_file = 1; |
| 2977 | } |
| 2978 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2979 | # Check signature styles |
Joe Perches | 270c49a | 2012-01-10 15:09:50 -0800 | [diff] [blame] | 2980 | if (!$in_header_lines && |
Joe Perches | ce0338df3c | 2012-07-30 14:41:18 -0700 | [diff] [blame] | 2981 | $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2982 | my $space_before = $1; |
| 2983 | my $sign_off = $2; |
| 2984 | my $space_after = $3; |
| 2985 | my $email = $4; |
| 2986 | my $ucfirst_sign_off = ucfirst(lc($sign_off)); |
| 2987 | |
Joe Perches | ce0338df3c | 2012-07-30 14:41:18 -0700 | [diff] [blame] | 2988 | if ($sign_off !~ /$signature_tags/) { |
Aditya Srivastava | 831242a | 2020-12-15 20:45:12 -0800 | [diff] [blame] | 2989 | my $suggested_signature = find_standard_signature($sign_off); |
| 2990 | if ($suggested_signature eq "") { |
| 2991 | WARN("BAD_SIGN_OFF", |
| 2992 | "Non-standard signature: $sign_off\n" . $herecurr); |
| 2993 | } else { |
| 2994 | if (WARN("BAD_SIGN_OFF", |
| 2995 | "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && |
| 2996 | $fix) { |
| 2997 | $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; |
| 2998 | } |
| 2999 | } |
Joe Perches | ce0338df3c | 2012-07-30 14:41:18 -0700 | [diff] [blame] | 3000 | } |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 3001 | if (defined $space_before && $space_before ne "") { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3002 | if (WARN("BAD_SIGN_OFF", |
| 3003 | "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && |
| 3004 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3005 | $fixed[$fixlinenr] = |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3006 | "$ucfirst_sign_off $email"; |
| 3007 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3008 | } |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 3009 | if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3010 | if (WARN("BAD_SIGN_OFF", |
| 3011 | "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && |
| 3012 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3013 | $fixed[$fixlinenr] = |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3014 | "$ucfirst_sign_off $email"; |
| 3015 | } |
| 3016 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 3017 | } |
| 3018 | if (!defined $space_after || $space_after ne " ") { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3019 | if (WARN("BAD_SIGN_OFF", |
| 3020 | "Use a single space after $ucfirst_sign_off\n" . $herecurr) && |
| 3021 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3022 | $fixed[$fixlinenr] = |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3023 | "$ucfirst_sign_off $email"; |
| 3024 | } |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 3025 | } |
| 3026 | |
Joe Perches | dfa05c2 | 2020-04-06 20:10:48 -0700 | [diff] [blame] | 3027 | my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 3028 | my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 3029 | if ($suggested_email eq "") { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3030 | ERROR("BAD_SIGN_OFF", |
| 3031 | "Unrecognized email address: '$email'\n" . $herecurr); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 3032 | } else { |
| 3033 | my $dequoted = $suggested_email; |
| 3034 | $dequoted =~ s/^"//; |
| 3035 | $dequoted =~ s/" </ </; |
| 3036 | # Don't force email to have quotes |
| 3037 | # Allow just an angle bracketed address |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 3038 | if (!same_email_addresses($email, $suggested_email)) { |
| 3039 | if (WARN("BAD_SIGN_OFF", |
| 3040 | "email address '$email' might be better as '$suggested_email'\n" . $herecurr) && |
| 3041 | $fix) { |
| 3042 | $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/; |
| 3043 | } |
| 3044 | } |
| 3045 | |
| 3046 | # Address part shouldn't have comments |
| 3047 | my $stripped_address = $email_address; |
| 3048 | $stripped_address =~ s/\([^\(\)]*\)//g; |
| 3049 | if ($email_address ne $stripped_address) { |
| 3050 | if (WARN("BAD_SIGN_OFF", |
| 3051 | "address part of email should not have comments: '$email_address'\n" . $herecurr) && |
| 3052 | $fix) { |
| 3053 | $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/; |
| 3054 | } |
| 3055 | } |
| 3056 | |
| 3057 | # Only one name comment should be allowed |
| 3058 | my $comment_count = () = $name_comment =~ /\([^\)]+\)/g; |
| 3059 | if ($comment_count > 1) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3060 | WARN("BAD_SIGN_OFF", |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 3061 | "Use a single name comment in email: '$email'\n" . $herecurr); |
| 3062 | } |
| 3063 | |
| 3064 | |
| 3065 | # stable@vger.kernel.org or stable@kernel.org shouldn't |
Dwaipayan Ray | e73d271 | 2020-12-15 20:44:56 -0800 | [diff] [blame] | 3066 | # have an email name. In addition comments should strictly |
Dwaipayan Ray | fccaebf | 2020-12-15 20:44:53 -0800 | [diff] [blame] | 3067 | # begin with a # |
| 3068 | if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { |
| 3069 | if (($comment ne "" && $comment !~ /^#.+/) || |
| 3070 | ($email_name ne "")) { |
| 3071 | my $cur_name = $email_name; |
| 3072 | my $new_comment = $comment; |
| 3073 | $cur_name =~ s/[a-zA-Z\s\-\"]+//g; |
| 3074 | |
| 3075 | # Remove brackets enclosing comment text |
| 3076 | # and # from start of comments to get comment text |
| 3077 | $new_comment =~ s/^\((.*)\)$/$1/; |
| 3078 | $new_comment =~ s/^\[(.*)\]$/$1/; |
| 3079 | $new_comment =~ s/^[\s\#]+|\s+$//g; |
| 3080 | |
| 3081 | $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); |
| 3082 | $new_comment = " # $new_comment" if ($new_comment ne ""); |
| 3083 | my $new_email = "$email_address$new_comment"; |
| 3084 | |
| 3085 | if (WARN("BAD_STABLE_ADDRESS_STYLE", |
| 3086 | "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && |
| 3087 | $fix) { |
| 3088 | $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; |
| 3089 | } |
| 3090 | } |
| 3091 | } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { |
| 3092 | my $new_comment = $comment; |
| 3093 | |
| 3094 | # Extract comment text from within brackets or |
| 3095 | # c89 style /*...*/ comments |
| 3096 | $new_comment =~ s/^\[(.*)\]$/$1/; |
| 3097 | $new_comment =~ s/^\/\*(.*)\*\/$/$1/; |
| 3098 | |
| 3099 | $new_comment = trim($new_comment); |
| 3100 | $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo |
| 3101 | $new_comment = "($new_comment)" if ($new_comment ne ""); |
| 3102 | my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); |
| 3103 | |
| 3104 | if (WARN("BAD_SIGN_OFF", |
| 3105 | "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && |
| 3106 | $fix) { |
| 3107 | $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; |
| 3108 | } |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 3109 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3110 | } |
Joe Perches | 7e51f19 | 2013-09-11 14:23:57 -0700 | [diff] [blame] | 3111 | |
| 3112 | # Check for duplicate signatures |
| 3113 | my $sig_nospace = $line; |
| 3114 | $sig_nospace =~ s/\s//g; |
| 3115 | $sig_nospace = lc($sig_nospace); |
| 3116 | if (defined $signatures{$sig_nospace}) { |
| 3117 | WARN("BAD_SIGN_OFF", |
| 3118 | "Duplicate signature\n" . $herecurr); |
| 3119 | } else { |
| 3120 | $signatures{$sig_nospace} = 1; |
| 3121 | } |
Sean Christopherson | 6c5d24e | 2019-03-22 14:11:37 -0700 | [diff] [blame] | 3122 | |
| 3123 | # Check Co-developed-by: immediately followed by Signed-off-by: with same name and email |
| 3124 | if ($sign_off =~ /^co-developed-by:$/i) { |
| 3125 | if ($email eq $author) { |
| 3126 | WARN("BAD_SIGN_OFF", |
| 3127 | "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); |
| 3128 | } |
| 3129 | if (!defined $lines[$linenr]) { |
| 3130 | WARN("BAD_SIGN_OFF", |
Dwaipayan Ray | ea7dbab | 2021-02-25 17:21:47 -0800 | [diff] [blame] | 3131 | "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); |
Sean Christopherson | 6c5d24e | 2019-03-22 14:11:37 -0700 | [diff] [blame] | 3132 | } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { |
| 3133 | WARN("BAD_SIGN_OFF", |
| 3134 | "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); |
| 3135 | } elsif ($1 ne $email) { |
| 3136 | WARN("BAD_SIGN_OFF", |
| 3137 | "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); |
| 3138 | } |
| 3139 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3140 | } |
| 3141 | |
Joe Perches | a2fe16b | 2015-02-13 14:39:02 -0800 | [diff] [blame] | 3142 | # Check email subject for common tools that don't need to be mentioned |
| 3143 | if ($in_header_lines && |
| 3144 | $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { |
| 3145 | WARN("EMAIL_SUBJECT", |
| 3146 | "A patch subject line should describe the change not the tool that found it\n" . $herecurr); |
| 3147 | } |
| 3148 | |
Joe Perches | 44d303e | 2020-04-06 20:11:10 -0700 | [diff] [blame] | 3149 | # Check for Gerrit Change-Ids not in any patch context |
| 3150 | if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { |
Aditya Srivastava | 7580c5b | 2020-12-15 20:44:47 -0800 | [diff] [blame] | 3151 | if (ERROR("GERRIT_CHANGE_ID", |
| 3152 | "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && |
| 3153 | $fix) { |
Dwaipayan Ray | ea7dbab | 2021-02-25 17:21:47 -0800 | [diff] [blame] | 3154 | fix_delete_line($fixlinenr, $rawline); |
| 3155 | } |
Christopher Covington | 7ebd05e | 2014-04-03 14:49:31 -0700 | [diff] [blame] | 3156 | } |
| 3157 | |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 3158 | # Check if the commit log is in a possible stack dump |
| 3159 | if ($in_commit_log && !$commit_log_possible_stack_dump && |
| 3160 | ($line =~ /^\s*(?:WARNING:|BUG:)/ || |
| 3161 | $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || |
| 3162 | # timestamp |
Joe Perches | 634cffc | 2019-09-25 16:46:32 -0700 | [diff] [blame] | 3163 | $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || |
| 3164 | $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || |
| 3165 | $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { |
| 3166 | # stack dump address styles |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 3167 | $commit_log_possible_stack_dump = 1; |
| 3168 | } |
| 3169 | |
Joe Perches | 2a076f4 | 2015-04-16 12:44:28 -0700 | [diff] [blame] | 3170 | # Check for line lengths > 75 in commit log, warn once |
| 3171 | if ($in_commit_log && !$commit_log_long_line && |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 3172 | length($line) > 75 && |
| 3173 | !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || |
| 3174 | # file delta changes |
Jerome Forissier | 36f8b34 | 2022-01-19 18:09:31 -0800 | [diff] [blame] | 3175 | $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ || |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 3176 | # filename then : |
Aditya Srivastava | 27b379a | 2020-12-15 20:44:59 -0800 | [diff] [blame] | 3177 | $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i || |
| 3178 | # A Fixes: or Link: line or signature tag line |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 3179 | $commit_log_possible_stack_dump)) { |
Joe Perches | 2a076f4 | 2015-04-16 12:44:28 -0700 | [diff] [blame] | 3180 | WARN("COMMIT_LOG_LONG_LINE", |
| 3181 | "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); |
| 3182 | $commit_log_long_line = 1; |
| 3183 | } |
| 3184 | |
Joe Perches | bf4daf1 | 2015-09-09 15:37:50 -0700 | [diff] [blame] | 3185 | # Reset possible stack dump if a blank line is found |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 3186 | if ($in_commit_log && $commit_log_possible_stack_dump && |
| 3187 | $line =~ /^\s*$/) { |
| 3188 | $commit_log_possible_stack_dump = 0; |
| 3189 | } |
Joe Perches | bf4daf1 | 2015-09-09 15:37:50 -0700 | [diff] [blame] | 3190 | |
Dwaipayan Ray | 084a617 | 2020-12-15 20:45:18 -0800 | [diff] [blame] | 3191 | # Check for lines starting with a # |
| 3192 | if ($in_commit_log && $line =~ /^#/) { |
| 3193 | if (WARN("COMMIT_COMMENT_SYMBOL", |
| 3194 | "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && |
| 3195 | $fix) { |
| 3196 | $fixed[$fixlinenr] =~ s/^/ /; |
| 3197 | } |
| 3198 | } |
| 3199 | |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 3200 | # Check for git id commit length and improperly formed commit descriptions |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 3201 | # A correctly formed commit description is: |
| 3202 | # commit <SHA-1 hash length 12+ chars> ("Complete commit subject") |
| 3203 | # with the commit subject '("' prefix and '")' suffix |
| 3204 | # This is a fairly compilicated block as it tests for what appears to be |
| 3205 | # bare SHA-1 hash with minimum length of 5. It also avoids several types of |
| 3206 | # possible SHA-1 matches. |
| 3207 | # A commit match can span multiple lines so this block attempts to find a |
| 3208 | # complete typical commit on a maximum of 3 lines |
| 3209 | if ($perl_version_ok && |
| 3210 | $in_commit_log && !$commit_log_possible_stack_dump && |
John Hubbard | a897257 | 2020-04-06 20:10:55 -0700 | [diff] [blame] | 3211 | $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && |
Wei Wang | e882dbf | 2017-05-08 15:55:54 -0700 | [diff] [blame] | 3212 | $line !~ /^This reverts commit [0-9a-f]{7,40}/ && |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 3213 | (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || |
| 3214 | ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) || |
Joe Perches | aab38f5 | 2016-08-02 14:04:36 -0700 | [diff] [blame] | 3215 | ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 3216 | $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && |
| 3217 | $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { |
Joe Perches | fe043ea | 2015-09-09 15:37:25 -0700 | [diff] [blame] | 3218 | my $init_char = "c"; |
| 3219 | my $orig_commit = ""; |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 3220 | my $short = 1; |
| 3221 | my $long = 0; |
| 3222 | my $case = 1; |
| 3223 | my $space = 1; |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 3224 | my $id = '0123456789ab'; |
| 3225 | my $orig_desc = "commit description"; |
| 3226 | my $description = ""; |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 3227 | my $herectx = $herecurr; |
| 3228 | my $has_parens = 0; |
| 3229 | my $has_quotes = 0; |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 3230 | |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 3231 | my $input = $line; |
| 3232 | if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) { |
| 3233 | for (my $n = 0; $n < 2; $n++) { |
| 3234 | if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) { |
| 3235 | $orig_desc = $1; |
| 3236 | $has_parens = 1; |
| 3237 | # Always strip leading/trailing parens then double quotes if existing |
| 3238 | $orig_desc = substr($orig_desc, 1, -1); |
| 3239 | if ($orig_desc =~ /^".*"$/) { |
| 3240 | $orig_desc = substr($orig_desc, 1, -1); |
| 3241 | $has_quotes = 1; |
| 3242 | } |
| 3243 | last; |
| 3244 | } |
| 3245 | last if ($#lines < $linenr + $n); |
| 3246 | $input .= " " . trim($rawlines[$linenr + $n]); |
| 3247 | $herectx .= "$rawlines[$linenr + $n]\n"; |
| 3248 | } |
| 3249 | $herectx = $herecurr if (!$has_parens); |
Joe Perches | fe043ea | 2015-09-09 15:37:25 -0700 | [diff] [blame] | 3250 | } |
| 3251 | |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 3252 | if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { |
| 3253 | $init_char = $1; |
| 3254 | $orig_commit = lc($2); |
| 3255 | $short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i); |
| 3256 | $long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i); |
| 3257 | $space = 0 if ($input =~ /\bcommit [0-9a-f]/i); |
| 3258 | $case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); |
| 3259 | } elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) { |
| 3260 | $orig_commit = lc($1); |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 3261 | } |
| 3262 | |
| 3263 | ($id, $description) = git_commit_info($orig_commit, |
| 3264 | $id, $orig_desc); |
| 3265 | |
Heinrich Schuchardt | 948b133 | 2017-07-10 15:52:16 -0700 | [diff] [blame] | 3266 | if (defined($id) && |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 3267 | ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) && |
| 3268 | $last_git_commit_id_linenr != $linenr - 1) { |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 3269 | ERROR("GIT_COMMIT_ID", |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 3270 | "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx); |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 3271 | } |
Joe Perches | 4ce9f97 | 2021-09-07 19:59:57 -0700 | [diff] [blame] | 3272 | #don't report the next line if this line ends in commit and the sha1 hash is the next line |
| 3273 | $last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i); |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 3274 | } |
| 3275 | |
Joe Perches | 13f1937 | 2014-08-06 16:10:59 -0700 | [diff] [blame] | 3276 | # Check for added, moved or deleted files |
| 3277 | if (!$reported_maintainer_file && !$in_commit_log && |
| 3278 | ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || |
| 3279 | $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || |
| 3280 | ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && |
| 3281 | (defined($1) || defined($2))))) { |
Andrew Jeffery | a82603a | 2016-12-12 16:46:37 -0800 | [diff] [blame] | 3282 | $is_patch = 1; |
Joe Perches | 13f1937 | 2014-08-06 16:10:59 -0700 | [diff] [blame] | 3283 | $reported_maintainer_file = 1; |
| 3284 | WARN("FILE_PATH_CHANGES", |
| 3285 | "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); |
| 3286 | } |
| 3287 | |
Rob Herring | e400edb | 2019-09-12 15:18:20 +0100 | [diff] [blame] | 3288 | # Check for adding new DT bindings not in schema format |
| 3289 | if (!$in_commit_log && |
| 3290 | ($line =~ /^new file mode\s*\d+\s*$/) && |
| 3291 | ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { |
| 3292 | WARN("DT_SCHEMA_BINDING_PATCH", |
Mauro Carvalho Chehab | 56ddc4c | 2021-04-01 14:17:49 +0200 | [diff] [blame] | 3293 | "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n"); |
Rob Herring | e400edb | 2019-09-12 15:18:20 +0100 | [diff] [blame] | 3294 | } |
| 3295 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3296 | # Check for wrappage within a valid hunk of the file |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3297 | if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3298 | ERROR("CORRUPTED_PATCH", |
| 3299 | "patch seems to be corrupt (line wrapped?)\n" . |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 3300 | $herecurr) if (!$emitted_corrupt++); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 3301 | } |
| 3302 | |
| 3303 | # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php |
| 3304 | if (($realfile =~ /^$/ || $line =~ /^\+/) && |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 3305 | $rawline !~ m/^$UTF8*$/) { |
| 3306 | my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); |
| 3307 | |
| 3308 | my $blank = copy_spacing($rawline); |
| 3309 | my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; |
| 3310 | my $hereptr = "$hereline$ptr\n"; |
| 3311 | |
Joe Perches | 34d9921 | 2011-07-25 17:13:26 -0700 | [diff] [blame] | 3312 | CHK("INVALID_UTF8", |
| 3313 | "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3314 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3315 | |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 3316 | # Check if it's the start of a commit log |
| 3317 | # (not a header line and we haven't seen the patch filename) |
| 3318 | if ($in_header_lines && $realfile =~ /^$/ && |
Joe Perches | eb3a58d | 2017-05-08 15:55:42 -0700 | [diff] [blame] | 3319 | !($rawline =~ /^\s+(?:\S|$)/ || |
| 3320 | $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 3321 | $in_header_lines = 0; |
| 3322 | $in_commit_log = 1; |
Allen Hubbe | ed43c4e | 2016-08-02 14:04:45 -0700 | [diff] [blame] | 3323 | $has_commit_log = 1; |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 3324 | } |
| 3325 | |
Pasi Savanainen | fa64205d | 2012-10-04 17:13:29 -0700 | [diff] [blame] | 3326 | # Check if there is UTF-8 in a commit log when a mail header has explicitly |
| 3327 | # declined it, i.e defined some charset where it is missing. |
| 3328 | if ($in_header_lines && |
| 3329 | $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && |
| 3330 | $1 !~ /utf-8/i) { |
| 3331 | $non_utf8_charset = 1; |
| 3332 | } |
| 3333 | |
| 3334 | if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 3335 | $rawline =~ /$NON_ASCII_UTF8/) { |
Pasi Savanainen | fa64205d | 2012-10-04 17:13:29 -0700 | [diff] [blame] | 3336 | WARN("UTF8_BEFORE_PATCH", |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 3337 | "8-bit UTF-8 used in possible commit log\n" . $herecurr); |
| 3338 | } |
| 3339 | |
Joe Perches | d6430f7 | 2016-12-12 16:46:28 -0800 | [diff] [blame] | 3340 | # Check for absolute kernel paths in commit message |
| 3341 | if ($tree && $in_commit_log) { |
| 3342 | while ($line =~ m{(?:^|\s)(/\S*)}g) { |
| 3343 | my $file = $1; |
| 3344 | |
| 3345 | if ($file =~ m{^(.*?)(?::\d+)+:?$} && |
| 3346 | check_absolute_file($1, $herecurr)) { |
| 3347 | # |
| 3348 | } else { |
| 3349 | check_absolute_file($file, $herecurr); |
| 3350 | } |
| 3351 | } |
| 3352 | } |
| 3353 | |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 3354 | # Check for various typo / spelling mistakes |
Joe Perches | 66d7a38 | 2015-04-16 12:44:08 -0700 | [diff] [blame] | 3355 | if (defined($misspellings) && |
| 3356 | ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { |
Dwaipayan Ray | 7da07c3 | 2020-12-15 20:45:21 -0800 | [diff] [blame] | 3357 | while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 3358 | my $typo = $1; |
Dwaipayan Ray | 7da07c3 | 2020-12-15 20:45:21 -0800 | [diff] [blame] | 3359 | my $blank = copy_spacing($rawline); |
| 3360 | my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); |
| 3361 | my $hereptr = "$hereline$ptr\n"; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 3362 | my $typo_fix = $spelling_fix{lc($typo)}; |
| 3363 | $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); |
| 3364 | $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); |
Jean Delvare | 0675a8f | 2017-09-08 16:16:07 -0700 | [diff] [blame] | 3365 | my $msg_level = \&WARN; |
| 3366 | $msg_level = \&CHK if ($file); |
| 3367 | if (&{$msg_level}("TYPO_SPELLING", |
Dwaipayan Ray | 7da07c3 | 2020-12-15 20:45:21 -0800 | [diff] [blame] | 3368 | "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 3369 | $fix) { |
| 3370 | $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; |
| 3371 | } |
| 3372 | } |
| 3373 | } |
| 3374 | |
Matteo Croce | a8dd86b | 2019-09-25 16:46:38 -0700 | [diff] [blame] | 3375 | # check for invalid commit id |
| 3376 | if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { |
| 3377 | my $id; |
| 3378 | my $description; |
| 3379 | ($id, $description) = git_commit_info($2, undef, undef); |
| 3380 | if (!defined($id)) { |
| 3381 | WARN("UNKNOWN_COMMIT_ID", |
| 3382 | "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); |
| 3383 | } |
| 3384 | } |
| 3385 | |
Joe Perches | 310cd06 | 2020-10-15 20:11:52 -0700 | [diff] [blame] | 3386 | # check for repeated words separated by a single space |
Aditya Srivastava | 8d0325c | 2020-12-15 20:44:24 -0800 | [diff] [blame] | 3387 | # avoid false positive from list command eg, '-rw-r--r-- 1 root root' |
| 3388 | if (($rawline =~ /^\+/ || $in_commit_log) && |
| 3389 | $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { |
Dwaipayan Ray | 1db81a6 | 2020-12-15 20:44:20 -0800 | [diff] [blame] | 3390 | pos($rawline) = 1 if (!$in_commit_log); |
Joe Perches | 310cd06 | 2020-10-15 20:11:52 -0700 | [diff] [blame] | 3391 | while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { |
| 3392 | |
| 3393 | my $first = $1; |
| 3394 | my $second = $2; |
Dwaipayan Ray | 1db81a6 | 2020-12-15 20:44:20 -0800 | [diff] [blame] | 3395 | my $start_pos = $-[1]; |
| 3396 | my $end_pos = $+[2]; |
Joe Perches | 310cd06 | 2020-10-15 20:11:52 -0700 | [diff] [blame] | 3397 | if ($first =~ /(?:struct|union|enum)/) { |
| 3398 | pos($rawline) += length($first) + length($second) + 1; |
| 3399 | next; |
| 3400 | } |
| 3401 | |
Dwaipayan Ray | 1db81a6 | 2020-12-15 20:44:20 -0800 | [diff] [blame] | 3402 | next if (lc($first) ne lc($second)); |
Joe Perches | 310cd06 | 2020-10-15 20:11:52 -0700 | [diff] [blame] | 3403 | next if ($first eq 'long'); |
| 3404 | |
Dwaipayan Ray | 1db81a6 | 2020-12-15 20:44:20 -0800 | [diff] [blame] | 3405 | # check for character before and after the word matches |
| 3406 | my $start_char = ''; |
| 3407 | my $end_char = ''; |
| 3408 | $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); |
| 3409 | $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); |
| 3410 | |
| 3411 | next if ($start_char =~ /^\S$/); |
| 3412 | next if (index(" \t.,;?!", $end_char) == -1); |
| 3413 | |
Dwaipayan Ray | ea7dbab | 2021-02-25 17:21:47 -0800 | [diff] [blame] | 3414 | # avoid repeating hex occurrences like 'ff ff fe 09 ...' |
| 3415 | if ($first =~ /\b[0-9a-f]{2,}\b/i) { |
| 3416 | next if (!exists($allow_repeated_words{lc($first)})); |
| 3417 | } |
Aditya Srivastava | 8d0325c | 2020-12-15 20:44:24 -0800 | [diff] [blame] | 3418 | |
Joe Perches | 310cd06 | 2020-10-15 20:11:52 -0700 | [diff] [blame] | 3419 | if (WARN("REPEATED_WORD", |
| 3420 | "Possible repeated word: '$first'\n" . $herecurr) && |
| 3421 | $fix) { |
| 3422 | $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; |
| 3423 | } |
| 3424 | } |
| 3425 | |
| 3426 | # if it's a repeated word on consecutive lines in a comment block |
| 3427 | if ($prevline =~ /$;+\s*$/ && |
| 3428 | $prevrawline =~ /($word_pattern)\s*$/) { |
| 3429 | my $last_word = $1; |
| 3430 | if ($rawline =~ /^\+\s*\*\s*$last_word /) { |
| 3431 | if (WARN("REPEATED_WORD", |
| 3432 | "Possible repeated word: '$last_word'\n" . $hereprev) && |
| 3433 | $fix) { |
| 3434 | $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; |
| 3435 | } |
| 3436 | } |
| 3437 | } |
| 3438 | } |
| 3439 | |
Andy Whitcroft | 30670854 | 2008-10-15 22:02:28 -0700 | [diff] [blame] | 3440 | # ignore non-hunk lines and lines being removed |
| 3441 | next if (!$hunk_line || $line =~ /^-/); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3442 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3443 | #trailing whitespace |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 3444 | if ($line =~ /^\+.*\015/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3445 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3446 | if (ERROR("DOS_LINE_ENDINGS", |
| 3447 | "DOS line endings\n" . $herevet) && |
| 3448 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3449 | $fixed[$fixlinenr] =~ s/[\s\015]+$//; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3450 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3451 | } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { |
| 3452 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3453 | if (ERROR("TRAILING_WHITESPACE", |
| 3454 | "trailing whitespace\n" . $herevet) && |
| 3455 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3456 | $fixed[$fixlinenr] =~ s/\s+$//; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3457 | } |
| 3458 | |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 3459 | $rpt_cleaners = 1; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3460 | } |
Andy Whitcroft | 5368df20 | 2008-10-15 22:02:27 -0700 | [diff] [blame] | 3461 | |
Josh Triplett | 4783f89 | 2013-11-12 15:10:12 -0800 | [diff] [blame] | 3462 | # Check for FSF mailing addresses. |
Alexander Duyck | 109d8cb | 2014-01-23 15:54:50 -0800 | [diff] [blame] | 3463 | if ($rawline =~ /\bwrite to the Free/i || |
Matthew Wilcox | 1bde561 | 2017-02-24 15:01:38 -0800 | [diff] [blame] | 3464 | $rawline =~ /\b675\s+Mass\s+Ave/i || |
Joe Perches | 3e2232f | 2014-01-23 15:54:48 -0800 | [diff] [blame] | 3465 | $rawline =~ /\b59\s+Temple\s+Pl/i || |
| 3466 | $rawline =~ /\b51\s+Franklin\s+St/i) { |
Josh Triplett | 4783f89 | 2013-11-12 15:10:12 -0800 | [diff] [blame] | 3467 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Jean Delvare | 0675a8f | 2017-09-08 16:16:07 -0700 | [diff] [blame] | 3468 | my $msg_level = \&ERROR; |
| 3469 | $msg_level = \&CHK if ($file); |
| 3470 | &{$msg_level}("FSF_MAILING_ADDRESS", |
| 3471 | "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 Triplett | 4783f89 | 2013-11-12 15:10:12 -0800 | [diff] [blame] | 3472 | } |
| 3473 | |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 3474 | # check for Kconfig help text having a real description |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 3475 | # Only applies when adding the entry originally, after that we do not have |
| 3476 | # sufficient context to determine whether it is indeed long enough. |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 3477 | if ($realfile =~ /Kconfig/ && |
Ulf Magnusson | 678ae16 | 2018-02-16 21:22:54 +0100 | [diff] [blame] | 3478 | # 'choice' is usually the last thing on the line (though |
| 3479 | # Kconfig supports named choices), so use a word boundary |
| 3480 | # (\b) rather than a whitespace character (\s) |
| 3481 | $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3482 | my $ln = $linenr; |
| 3483 | my $needs_help = 0; |
| 3484 | my $has_help = 0; |
| 3485 | my $help_length = 0; |
| 3486 | while (defined $lines[$ln]) { |
| 3487 | my $f = $lines[$ln++]; |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 3488 | |
| 3489 | next if ($f =~ /^-/); |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3490 | last if ($f !~ /^[\+ ]/); # !patch context |
Andy Whitcroft | a138580 | 2012-01-10 15:10:03 -0800 | [diff] [blame] | 3491 | |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3492 | if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { |
| 3493 | $needs_help = 1; |
| 3494 | next; |
| 3495 | } |
| 3496 | if ($f =~ /^\+\s*help\s*$/) { |
| 3497 | $has_help = 1; |
| 3498 | next; |
Andy Whitcroft | a138580 | 2012-01-10 15:10:03 -0800 | [diff] [blame] | 3499 | } |
| 3500 | |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3501 | $f =~ s/^.//; # strip patch context [+ ] |
| 3502 | $f =~ s/#.*//; # strip # directives |
| 3503 | $f =~ s/^\s+//; # strip leading blanks |
| 3504 | next if ($f =~ /^$/); # skip blank lines |
Ulf Magnusson | 678ae16 | 2018-02-16 21:22:54 +0100 | [diff] [blame] | 3505 | |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3506 | # At the end of this Kconfig block: |
Ulf Magnusson | 678ae16 | 2018-02-16 21:22:54 +0100 | [diff] [blame] | 3507 | # This only checks context lines in the patch |
| 3508 | # and so hopefully shouldn't trigger false |
| 3509 | # positives, even though some of these are |
| 3510 | # common words in help texts |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3511 | if ($f =~ /^(?:config|menuconfig|choice|endchoice| |
| 3512 | if|endif|menu|endmenu|source)\b/x) { |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 3513 | last; |
| 3514 | } |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3515 | $help_length++ if ($has_help); |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 3516 | } |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3517 | if ($needs_help && |
| 3518 | $help_length < $min_conf_desc_length) { |
| 3519 | my $stat_real = get_stat_real($linenr, $ln - 1); |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 3520 | WARN("CONFIG_DESCRIPTION", |
Joe Perches | b8709bc | 2022-01-19 18:09:34 -0800 | [diff] [blame] | 3521 | "please write a help paragraph that fully describes the config symbol\n" . "$here\n$stat_real\n"); |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 3522 | } |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 3523 | } |
| 3524 | |
Joe Perches | 7ccf41a | 2020-06-04 16:50:33 -0700 | [diff] [blame] | 3525 | # check MAINTAINERS entries |
| 3526 | if ($realfile =~ /^MAINTAINERS$/) { |
| 3527 | # check MAINTAINERS entries for the right form |
| 3528 | if ($rawline =~ /^\+[A-Z]:/ && |
| 3529 | $rawline !~ /^\+[A-Z]:\t\S/) { |
| 3530 | if (WARN("MAINTAINERS_STYLE", |
| 3531 | "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && |
| 3532 | $fix) { |
| 3533 | $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; |
| 3534 | } |
| 3535 | } |
| 3536 | # check MAINTAINERS entries for the right ordering too |
| 3537 | my $preferred_order = 'MRLSWQBCPTFXNK'; |
| 3538 | if ($rawline =~ /^\+[A-Z]:/ && |
| 3539 | $prevrawline =~ /^[\+ ][A-Z]:/) { |
| 3540 | $rawline =~ /^\+([A-Z]):\s*(.*)/; |
| 3541 | my $cur = $1; |
| 3542 | my $curval = $2; |
| 3543 | $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; |
| 3544 | my $prev = $1; |
| 3545 | my $prevval = $2; |
| 3546 | my $curindex = index($preferred_order, $cur); |
| 3547 | my $previndex = index($preferred_order, $prev); |
| 3548 | if ($curindex < 0) { |
| 3549 | WARN("MAINTAINERS_STYLE", |
| 3550 | "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); |
| 3551 | } else { |
| 3552 | if ($previndex >= 0 && $curindex < $previndex) { |
| 3553 | WARN("MAINTAINERS_STYLE", |
| 3554 | "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); |
| 3555 | } elsif ((($prev eq 'F' && $cur eq 'F') || |
| 3556 | ($prev eq 'X' && $cur eq 'X')) && |
| 3557 | ($prevval cmp $curval) > 0) { |
| 3558 | WARN("MAINTAINERS_STYLE", |
| 3559 | "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); |
| 3560 | } |
| 3561 | } |
Joe Perches | 628f91a | 2017-07-10 15:52:07 -0700 | [diff] [blame] | 3562 | } |
| 3563 | } |
| 3564 | |
Arnaud Lacombe | c68e587 | 2011-08-15 01:07:14 -0400 | [diff] [blame] | 3565 | if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && |
| 3566 | ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { |
| 3567 | my $flag = $1; |
| 3568 | my $replacement = { |
| 3569 | 'EXTRA_AFLAGS' => 'asflags-y', |
| 3570 | 'EXTRA_CFLAGS' => 'ccflags-y', |
| 3571 | 'EXTRA_CPPFLAGS' => 'cppflags-y', |
| 3572 | 'EXTRA_LDFLAGS' => 'ldflags-y', |
| 3573 | }; |
| 3574 | |
| 3575 | WARN("DEPRECATED_VARIABLE", |
| 3576 | "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); |
| 3577 | } |
| 3578 | |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 3579 | # check for DT compatible documentation |
Florian Vaussard | 7dd05b3 | 2014-04-03 14:49:26 -0700 | [diff] [blame] | 3580 | if (defined $root && |
| 3581 | (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || |
| 3582 | ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { |
| 3583 | |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 3584 | my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; |
| 3585 | |
Florian Vaussard | cc93319 | 2014-04-03 14:49:27 -0700 | [diff] [blame] | 3586 | my $dt_path = $root . "/Documentation/devicetree/bindings/"; |
Rob Herring | 852d095 | 2019-05-22 09:55:34 -0500 | [diff] [blame] | 3587 | my $vp_file = $dt_path . "vendor-prefixes.yaml"; |
Florian Vaussard | cc93319 | 2014-04-03 14:49:27 -0700 | [diff] [blame] | 3588 | |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 3589 | foreach my $compat (@compats) { |
| 3590 | my $compat2 = $compat; |
Rob Herring | 185d566 | 2014-06-04 16:12:03 -0700 | [diff] [blame] | 3591 | $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; |
| 3592 | my $compat3 = $compat; |
| 3593 | $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; |
| 3594 | `grep -Erq "$compat|$compat2|$compat3" $dt_path`; |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 3595 | if ( $? >> 8 ) { |
| 3596 | WARN("UNDOCUMENTED_DT_STRING", |
| 3597 | "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); |
| 3598 | } |
| 3599 | |
Florian Vaussard | 4fbf32a | 2014-04-03 14:49:25 -0700 | [diff] [blame] | 3600 | next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; |
| 3601 | my $vendor = $1; |
Rob Herring | 852d095 | 2019-05-22 09:55:34 -0500 | [diff] [blame] | 3602 | `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 3603 | if ( $? >> 8 ) { |
| 3604 | WARN("UNDOCUMENTED_DT_STRING", |
Florian Vaussard | cc93319 | 2014-04-03 14:49:27 -0700 | [diff] [blame] | 3605 | "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 3606 | } |
| 3607 | } |
| 3608 | } |
| 3609 | |
Rob Herring | 9f3a899 | 2018-04-10 16:33:13 -0700 | [diff] [blame] | 3610 | # check for using SPDX license tag at beginning of files |
| 3611 | if ($realline == $checklicenseline) { |
| 3612 | if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { |
| 3613 | $checklicenseline = 2; |
| 3614 | } elsif ($rawline =~ /^\+/) { |
| 3615 | my $comment = ""; |
| 3616 | if ($realfile =~ /\.(h|s|S)$/) { |
| 3617 | $comment = '/*'; |
| 3618 | } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { |
| 3619 | $comment = '//'; |
Lubomir Rintel | c8df0ab | 2020-04-06 20:10:51 -0700 | [diff] [blame] | 3620 | } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { |
Rob Herring | 9f3a899 | 2018-04-10 16:33:13 -0700 | [diff] [blame] | 3621 | $comment = '#'; |
| 3622 | } elsif ($realfile =~ /\.rst$/) { |
| 3623 | $comment = '..'; |
| 3624 | } |
| 3625 | |
Joe Perches | fdf1369 | 2019-03-07 16:28:32 -0800 | [diff] [blame] | 3626 | # check SPDX comment style for .[chsS] files |
| 3627 | if ($realfile =~ /\.[chsS]$/ && |
| 3628 | $rawline =~ /SPDX-License-Identifier:/ && |
Joe Perches | ffbce89 | 2019-09-25 16:46:35 -0700 | [diff] [blame] | 3629 | $rawline !~ m@^\+\s*\Q$comment\E\s*@) { |
Joe Perches | fdf1369 | 2019-03-07 16:28:32 -0800 | [diff] [blame] | 3630 | WARN("SPDX_LICENSE_TAG", |
| 3631 | "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); |
| 3632 | } |
| 3633 | |
Rob Herring | 9f3a899 | 2018-04-10 16:33:13 -0700 | [diff] [blame] | 3634 | if ($comment !~ /^$/ && |
Joe Perches | ffbce89 | 2019-09-25 16:46:35 -0700 | [diff] [blame] | 3635 | $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { |
| 3636 | WARN("SPDX_LICENSE_TAG", |
| 3637 | "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); |
Joe Perches | 3b6e8ac | 2018-08-21 21:57:47 -0700 | [diff] [blame] | 3638 | } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { |
Joe Perches | ffbce89 | 2019-09-25 16:46:35 -0700 | [diff] [blame] | 3639 | my $spdx_license = $1; |
| 3640 | if (!is_SPDX_License_valid($spdx_license)) { |
| 3641 | WARN("SPDX_LICENSE_TAG", |
| 3642 | "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); |
| 3643 | } |
Lubomir Rintel | 50c9290 | 2020-04-06 20:11:13 -0700 | [diff] [blame] | 3644 | if ($realfile =~ m@^Documentation/devicetree/bindings/@ && |
| 3645 | not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { |
| 3646 | my $msg_level = \&WARN; |
| 3647 | $msg_level = \&CHK if ($file); |
| 3648 | if (&{$msg_level}("SPDX_LICENSE_TAG", |
| 3649 | |
| 3650 | "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && |
| 3651 | $fix) { |
| 3652 | $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; |
| 3653 | } |
| 3654 | } |
Rob Herring | 9f3a899 | 2018-04-10 16:33:13 -0700 | [diff] [blame] | 3655 | } |
| 3656 | } |
| 3657 | } |
| 3658 | |
Joe Perches | a0154cd | 2020-10-15 20:12:19 -0700 | [diff] [blame] | 3659 | # check for embedded filenames |
| 3660 | if ($rawline =~ /^\+.*\Q$realfile\E/) { |
| 3661 | WARN("EMBEDDED_FILENAME", |
| 3662 | "It's generally not useful to have the filename in the file\n" . $herecurr); |
| 3663 | } |
| 3664 | |
Andy Whitcroft | 5368df20 | 2008-10-15 22:02:27 -0700 | [diff] [blame] | 3665 | # check we are in a valid source file if not then ignore this hunk |
Joe Perches | d6430f7 | 2016-12-12 16:46:28 -0800 | [diff] [blame] | 3666 | next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); |
Andy Whitcroft | 5368df20 | 2008-10-15 22:02:27 -0700 | [diff] [blame] | 3667 | |
Joe Perches | a8da38a | 2019-03-07 16:28:42 -0800 | [diff] [blame] | 3668 | # check for using SPDX-License-Identifier on the wrong line number |
| 3669 | if ($realline != $checklicenseline && |
| 3670 | $rawline =~ /\bSPDX-License-Identifier:/ && |
| 3671 | substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { |
| 3672 | WARN("SPDX_LICENSE_TAG", |
| 3673 | "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); |
| 3674 | } |
| 3675 | |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 3676 | # line length limit (with some exclusions) |
| 3677 | # |
| 3678 | # There are a few types of lines that may extend beyond $max_line_length: |
| 3679 | # logging functions like pr_info that end in a string |
| 3680 | # lines with a single string |
| 3681 | # #defines that are a single string |
Andreas Brauchli | 2e4bbbc | 2018-02-06 15:38:45 -0800 | [diff] [blame] | 3682 | # lines with an RFC3986 like URL |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 3683 | # |
| 3684 | # There are 3 different line length message types: |
Jean Delvare | ab1ecab | 2017-09-08 16:16:04 -0700 | [diff] [blame] | 3685 | # LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 3686 | # LONG_LINE_STRING a string starts before but extends beyond $max_line_length |
| 3687 | # LONG_LINE all other lines longer than $max_line_length |
| 3688 | # |
| 3689 | # if LONG_LINE is ignored, the other 2 types are also ignored |
| 3690 | # |
| 3691 | |
Joe Perches | b4749e9 | 2015-07-17 16:24:01 -0700 | [diff] [blame] | 3692 | if ($line =~ /^\+/ && $length > $max_line_length) { |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 3693 | my $msg_type = "LONG_LINE"; |
| 3694 | |
| 3695 | # Check the allowed long line types first |
| 3696 | |
| 3697 | # logging functions that end in a string that starts |
| 3698 | # before $max_line_length |
| 3699 | if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && |
| 3700 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { |
| 3701 | $msg_type = ""; |
| 3702 | |
| 3703 | # lines with only strings (w/ possible termination) |
| 3704 | # #defines with only strings |
| 3705 | } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || |
| 3706 | $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { |
| 3707 | $msg_type = ""; |
| 3708 | |
Joe Perches | cc14750 | 2017-11-17 15:28:44 -0800 | [diff] [blame] | 3709 | # More special cases |
| 3710 | } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || |
| 3711 | $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { |
Joe Perches | d560a5f | 2016-08-02 14:04:31 -0700 | [diff] [blame] | 3712 | $msg_type = ""; |
| 3713 | |
Andreas Brauchli | 2e4bbbc | 2018-02-06 15:38:45 -0800 | [diff] [blame] | 3714 | # URL ($rawline is used in case the URL is in a comment) |
| 3715 | } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { |
| 3716 | $msg_type = ""; |
| 3717 | |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 3718 | # Otherwise set the alternate message types |
| 3719 | |
| 3720 | # a comment starts before $max_line_length |
| 3721 | } elsif ($line =~ /($;[\s$;]*)$/ && |
| 3722 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { |
| 3723 | $msg_type = "LONG_LINE_COMMENT" |
| 3724 | |
| 3725 | # a quoted string starts before $max_line_length |
| 3726 | } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && |
| 3727 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { |
| 3728 | $msg_type = "LONG_LINE_STRING" |
| 3729 | } |
| 3730 | |
| 3731 | if ($msg_type ne "" && |
| 3732 | (show_type("LONG_LINE") || show_type($msg_type))) { |
Joe Perches | bdc48fa | 2020-05-29 16:12:21 -0700 | [diff] [blame] | 3733 | my $msg_level = \&WARN; |
| 3734 | $msg_level = \&CHK if ($file); |
| 3735 | &{$msg_level}($msg_type, |
| 3736 | "line length of $length exceeds $max_line_length columns\n" . $herecurr); |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 3737 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3738 | } |
| 3739 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3740 | # check for adding lines without a newline. |
| 3741 | if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { |
Tom Rix | 47ca69b | 2020-12-15 20:44:40 -0800 | [diff] [blame] | 3742 | if (WARN("MISSING_EOF_NEWLINE", |
| 3743 | "adding a line without newline at end of file\n" . $herecurr) && |
| 3744 | $fix) { |
| 3745 | fix_delete_line($fixlinenr+1, "No newline at end of file"); |
| 3746 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3747 | } |
| 3748 | |
Aditya Srivastava | de93245 | 2021-02-25 17:21:57 -0800 | [diff] [blame] | 3749 | # check for .L prefix local symbols in .S files |
| 3750 | if ($realfile =~ /\.S$/ && |
| 3751 | $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { |
| 3752 | WARN("AVOID_L_PREFIX", |
| 3753 | "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); |
| 3754 | } |
| 3755 | |
Andy Whitcroft | b9ea10d | 2008-10-15 22:02:24 -0700 | [diff] [blame] | 3756 | # check we are in a valid source file C or perl if not then ignore this hunk |
Geert Uytterhoeven | de4c924 | 2014-10-13 15:51:46 -0700 | [diff] [blame] | 3757 | next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3758 | |
| 3759 | # at the beginning of a line any tabs must come first and anything |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 3760 | # more than $tabsize must use tabs. |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3761 | if ($rawline =~ /^\+\s* \t\s*\S/ || |
| 3762 | $rawline =~ /^\+\s* \s*/) { |
| 3763 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 3764 | $rpt_cleaners = 1; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3765 | if (ERROR("CODE_INDENT", |
| 3766 | "code indent should use tabs where possible\n" . $herevet) && |
| 3767 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3768 | $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3769 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3770 | } |
| 3771 | |
Alberto Panizzo | 08e4436 | 2010-03-05 13:43:54 -0800 | [diff] [blame] | 3772 | # check for space before tabs. |
| 3773 | if ($rawline =~ /^\+/ && $rawline =~ / \t/) { |
| 3774 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3775 | if (WARN("SPACE_BEFORE_TAB", |
| 3776 | "please, no space before tabs\n" . $herevet) && |
| 3777 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3778 | while ($fixed[$fixlinenr] =~ |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 3779 | s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3780 | while ($fixed[$fixlinenr] =~ |
Joe Perches | c76f4cb | 2014-01-23 15:54:46 -0800 | [diff] [blame] | 3781 | s/(^\+.*) +\t/$1\t/) {} |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3782 | } |
Alberto Panizzo | 08e4436 | 2010-03-05 13:43:54 -0800 | [diff] [blame] | 3783 | } |
| 3784 | |
Joe Perches | 6a48721 | 2018-04-10 16:34:04 -0700 | [diff] [blame] | 3785 | # check for assignments on the start of a line |
| 3786 | if ($sline =~ /^\+\s+($Assignment)[^=]/) { |
Aditya Srivastava | da7355a | 2020-12-15 20:45:06 -0800 | [diff] [blame] | 3787 | my $operator = $1; |
| 3788 | if (CHK("ASSIGNMENT_CONTINUATIONS", |
| 3789 | "Assignment operator '$1' should be on the previous line\n" . $hereprev) && |
| 3790 | $fix && $prevrawline =~ /^\+/) { |
| 3791 | # add assignment operator to the previous line, remove from current line |
| 3792 | $fixed[$fixlinenr - 1] .= " $operator"; |
| 3793 | $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; |
| 3794 | } |
Joe Perches | 6a48721 | 2018-04-10 16:34:04 -0700 | [diff] [blame] | 3795 | } |
| 3796 | |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3797 | # check for && or || at the start of a line |
| 3798 | if ($rawline =~ /^\+\s*(&&|\|\|)/) { |
Aditya Srivastava | 8e08f07 | 2020-12-15 20:45:09 -0800 | [diff] [blame] | 3799 | my $operator = $1; |
| 3800 | if (CHK("LOGICAL_CONTINUATIONS", |
| 3801 | "Logical continuations should be on the previous line\n" . $hereprev) && |
| 3802 | $fix && $prevrawline =~ /^\+/) { |
| 3803 | # insert logical operator at last non-comment, non-whitepsace char on previous line |
| 3804 | $prevline =~ /[\s$;]*$/; |
| 3805 | my $line_end = substr($prevrawline, $-[0]); |
| 3806 | $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; |
| 3807 | $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; |
| 3808 | } |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3809 | } |
| 3810 | |
Joe Perches | a91e899 | 2016-05-20 17:04:05 -0700 | [diff] [blame] | 3811 | # check indentation starts on a tab stop |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 3812 | if ($perl_version_ok && |
Joe Perches | bd49111 | 2018-02-06 15:39:06 -0800 | [diff] [blame] | 3813 | $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { |
Joe Perches | a91e899 | 2016-05-20 17:04:05 -0700 | [diff] [blame] | 3814 | my $indent = length($1); |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 3815 | if ($indent % $tabsize) { |
Joe Perches | a91e899 | 2016-05-20 17:04:05 -0700 | [diff] [blame] | 3816 | if (WARN("TABSTOP", |
| 3817 | "Statements should start on a tabstop\n" . $herecurr) && |
| 3818 | $fix) { |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 3819 | $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; |
Joe Perches | a91e899 | 2016-05-20 17:04:05 -0700 | [diff] [blame] | 3820 | } |
| 3821 | } |
| 3822 | } |
| 3823 | |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3824 | # check multi-line statement indentation matches previous line |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 3825 | if ($perl_version_ok && |
Joe Perches | fd71f63 | 2017-07-10 15:52:30 -0700 | [diff] [blame] | 3826 | $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3827 | $prevline =~ /^\+(\t*)(.*)$/; |
| 3828 | my $oldindent = $1; |
| 3829 | my $rest = $2; |
| 3830 | |
| 3831 | my $pos = pos_last_openparen($rest); |
| 3832 | if ($pos >= 0) { |
Joe Perches | b34a26f | 2012-07-30 14:41:16 -0700 | [diff] [blame] | 3833 | $line =~ /^(\+| )([ \t]*)/; |
| 3834 | my $newindent = $2; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3835 | |
| 3836 | my $goodtabindent = $oldindent . |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 3837 | "\t" x ($pos / $tabsize) . |
| 3838 | " " x ($pos % $tabsize); |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3839 | my $goodspaceindent = $oldindent . " " x $pos; |
| 3840 | |
| 3841 | if ($newindent ne $goodtabindent && |
| 3842 | $newindent ne $goodspaceindent) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3843 | |
| 3844 | if (CHK("PARENTHESIS_ALIGNMENT", |
| 3845 | "Alignment should match open parenthesis\n" . $hereprev) && |
| 3846 | $fix && $line =~ /^\+/) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3847 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3848 | s/^\+[ \t]*/\+$goodtabindent/; |
| 3849 | } |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3850 | } |
| 3851 | } |
| 3852 | } |
| 3853 | |
Joe Perches | 6ab3a97 | 2015-04-16 12:44:05 -0700 | [diff] [blame] | 3854 | # check for space after cast like "(int) foo" or "(struct foo) bar" |
| 3855 | # avoid checking a few false positives: |
| 3856 | # "sizeof(<type>)" or "__alignof__(<type>)" |
| 3857 | # function pointer declarations like "(*foo)(int) = bar;" |
| 3858 | # structure definitions like "(struct foo) { 0 };" |
| 3859 | # multiline macros that define functions |
| 3860 | # known attributes or the __attribute__ keyword |
| 3861 | if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && |
| 3862 | (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3863 | if (CHK("SPACING", |
Joe Perches | f27c95d | 2014-08-06 16:10:52 -0700 | [diff] [blame] | 3864 | "No space is necessary after a cast\n" . $herecurr) && |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3865 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3866 | $fixed[$fixlinenr] =~ |
Joe Perches | f27c95d | 2014-08-06 16:10:52 -0700 | [diff] [blame] | 3867 | s/(\(\s*$Type\s*\))[ \t]+/$1/; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3868 | } |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 3869 | } |
| 3870 | |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3871 | # Block comment styles |
| 3872 | # Networking with an initial /* |
Joe Perches | 0588060 | 2012-10-04 17:13:35 -0700 | [diff] [blame] | 3873 | if ($realfile =~ m@^(drivers/net/|net/)@ && |
Joe Perches | fdb4bcd | 2013-07-03 15:05:23 -0700 | [diff] [blame] | 3874 | $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && |
Joe Perches | 85ad978 | 2014-04-03 14:49:20 -0700 | [diff] [blame] | 3875 | $rawline =~ /^\+[ \t]*\*/ && |
Łukasz Stelmach | c70735c | 2020-10-15 20:12:25 -0700 | [diff] [blame] | 3876 | $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier |
Joe Perches | 0588060 | 2012-10-04 17:13:35 -0700 | [diff] [blame] | 3877 | WARN("NETWORKING_BLOCK_COMMENT_STYLE", |
| 3878 | "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); |
| 3879 | } |
| 3880 | |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3881 | # Block comments use * on subsequent lines |
| 3882 | if ($prevline =~ /$;[ \t]*$/ && #ends in comment |
| 3883 | $prevrawline =~ /^\+.*?\/\*/ && #starting /* |
Joe Perches | a605e32 | 2013-07-03 15:05:24 -0700 | [diff] [blame] | 3884 | $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ |
Joe Perches | 61135e9 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 3885 | $rawline =~ /^\+/ && #line is new |
Joe Perches | a605e32 | 2013-07-03 15:05:24 -0700 | [diff] [blame] | 3886 | $rawline !~ /^\+[ \t]*\*/) { #no leading * |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3887 | WARN("BLOCK_COMMENT_STYLE", |
| 3888 | "Block comments use * on subsequent lines\n" . $hereprev); |
Joe Perches | a605e32 | 2013-07-03 15:05:24 -0700 | [diff] [blame] | 3889 | } |
| 3890 | |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3891 | # Block comments use */ on trailing lines |
| 3892 | if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ |
Joe Perches | c24f9f1 | 2012-11-08 15:53:29 -0800 | [diff] [blame] | 3893 | $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ |
| 3894 | $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ |
| 3895 | $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3896 | WARN("BLOCK_COMMENT_STYLE", |
| 3897 | "Block comments use a trailing */ on a separate line\n" . $herecurr); |
Joe Perches | 0588060 | 2012-10-04 17:13:35 -0700 | [diff] [blame] | 3898 | } |
| 3899 | |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3900 | # Block comment * alignment |
| 3901 | if ($prevline =~ /$;[ \t]*$/ && #ends in comment |
Joe Perches | af20752 | 2016-10-11 13:52:05 -0700 | [diff] [blame] | 3902 | $line =~ /^\+[ \t]*$;/ && #leading comment |
| 3903 | $rawline =~ /^\+[ \t]*\*/ && #leading * |
| 3904 | (($prevrawline =~ /^\+.*?\/\*/ && #leading /* |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3905 | $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ |
Joe Perches | af20752 | 2016-10-11 13:52:05 -0700 | [diff] [blame] | 3906 | $prevrawline =~ /^\+[ \t]*\*/)) { #leading * |
| 3907 | my $oldindent; |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3908 | $prevrawline =~ m@^\+([ \t]*/?)\*@; |
Joe Perches | af20752 | 2016-10-11 13:52:05 -0700 | [diff] [blame] | 3909 | if (defined($1)) { |
| 3910 | $oldindent = expand_tabs($1); |
| 3911 | } else { |
| 3912 | $prevrawline =~ m@^\+(.*/?)\*@; |
| 3913 | $oldindent = expand_tabs($1); |
| 3914 | } |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3915 | $rawline =~ m@^\+([ \t]*)\*@; |
| 3916 | my $newindent = $1; |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3917 | $newindent = expand_tabs($newindent); |
Joe Perches | af20752 | 2016-10-11 13:52:05 -0700 | [diff] [blame] | 3918 | if (length($oldindent) ne length($newindent)) { |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3919 | WARN("BLOCK_COMMENT_STYLE", |
| 3920 | "Block comments should align the * on each line\n" . $hereprev); |
| 3921 | } |
| 3922 | } |
| 3923 | |
Joe Perches | 7f61919 | 2014-08-06 16:10:39 -0700 | [diff] [blame] | 3924 | # check for missing blank lines after struct/union declarations |
| 3925 | # with exceptions for various attributes and macros |
| 3926 | if ($prevline =~ /^[\+ ]};?\s*$/ && |
| 3927 | $line =~ /^\+/ && |
| 3928 | !($line =~ /^\+\s*$/ || |
| 3929 | $line =~ /^\+\s*EXPORT_SYMBOL/ || |
| 3930 | $line =~ /^\+\s*MODULE_/i || |
| 3931 | $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || |
| 3932 | $line =~ /^\+[a-z_]*init/ || |
| 3933 | $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || |
| 3934 | $line =~ /^\+\s*DECLARE/ || |
Masahiro Yamada | 0bc989f | 2017-11-17 15:28:55 -0800 | [diff] [blame] | 3935 | $line =~ /^\+\s*builtin_[\w_]*driver/ || |
Joe Perches | 7f61919 | 2014-08-06 16:10:39 -0700 | [diff] [blame] | 3936 | $line =~ /^\+\s*__setup/)) { |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3937 | if (CHK("LINE_SPACING", |
| 3938 | "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && |
| 3939 | $fix) { |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 3940 | fix_insert_line($fixlinenr, "\+"); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3941 | } |
Joe Perches | 7f61919 | 2014-08-06 16:10:39 -0700 | [diff] [blame] | 3942 | } |
| 3943 | |
Joe Perches | 365dd4e | 2014-08-06 16:10:42 -0700 | [diff] [blame] | 3944 | # check for multiple consecutive blank lines |
| 3945 | if ($prevline =~ /^[\+ ]\s*$/ && |
| 3946 | $line =~ /^\+\s*$/ && |
| 3947 | $last_blank_line != ($linenr - 1)) { |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3948 | if (CHK("LINE_SPACING", |
| 3949 | "Please don't use multiple blank lines\n" . $hereprev) && |
| 3950 | $fix) { |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 3951 | fix_delete_line($fixlinenr, $rawline); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3952 | } |
| 3953 | |
Joe Perches | 365dd4e | 2014-08-06 16:10:42 -0700 | [diff] [blame] | 3954 | $last_blank_line = $linenr; |
| 3955 | } |
| 3956 | |
Joe Perches | 3b617e3 | 2014-04-03 14:49:28 -0700 | [diff] [blame] | 3957 | # check for missing blank lines after declarations |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3958 | # (declarations must have the same indentation and not be at the start of line) |
| 3959 | if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) { |
| 3960 | # use temporaries |
| 3961 | my $sl = $sline; |
| 3962 | my $pl = $prevline; |
| 3963 | # remove $Attribute/$Sparse uses to simplify comparisons |
| 3964 | $sl =~ s/\b(?:$Attribute|$Sparse)\b//g; |
| 3965 | $pl =~ s/\b(?:$Attribute|$Sparse)\b//g; |
| 3966 | if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || |
Joe Perches | 5a4e1fd | 2014-08-06 16:10:33 -0700 | [diff] [blame] | 3967 | # function pointer declarations |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3968 | $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3969 | # foo bar; where foo is some local typedef or #define |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3970 | $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3971 | # known declaration macros |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3972 | $pl =~ /^\+\s+$declaration_macros/) && |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3973 | # for "else if" which can look like "$Ident $Ident" |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3974 | !($pl =~ /^\+\s+$c90_Keywords\b/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3975 | # other possible extensions of declaration lines |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3976 | $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3977 | # not starting a section or a macro "\" extended line |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3978 | $pl =~ /(?:\{\s*|\\)$/) && |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3979 | # looks like a declaration |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3980 | !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || |
Joe Perches | 5a4e1fd | 2014-08-06 16:10:33 -0700 | [diff] [blame] | 3981 | # function pointer declarations |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3982 | $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3983 | # foo bar; where foo is some local typedef or #define |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3984 | $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3985 | # known declaration macros |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3986 | $sl =~ /^\+\s+$declaration_macros/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3987 | # start of struct or union or enum |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3988 | $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3989 | # start or end of block or continuation of declaration |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3990 | $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3991 | # bitfield continuation |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3992 | $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3993 | # other possible extensions of declaration lines |
Joe Perches | b5e8736 | 2021-02-25 17:21:40 -0800 | [diff] [blame] | 3994 | $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) { |
| 3995 | if (WARN("LINE_SPACING", |
| 3996 | "Missing a blank line after declarations\n" . $hereprev) && |
| 3997 | $fix) { |
| 3998 | fix_insert_line($fixlinenr, "\+"); |
| 3999 | } |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 4000 | } |
Joe Perches | 3b617e3 | 2014-04-03 14:49:28 -0700 | [diff] [blame] | 4001 | } |
| 4002 | |
Raffaele Recalcati | 5f7ddae | 2010-08-09 17:20:59 -0700 | [diff] [blame] | 4003 | # check for spaces at the beginning of a line. |
Andy Whitcroft | 6b4c5be | 2010-10-26 14:23:11 -0700 | [diff] [blame] | 4004 | # Exceptions: |
| 4005 | # 1) within comments |
| 4006 | # 2) indented preprocessor commands |
| 4007 | # 3) hanging labels |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4008 | if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { |
Raffaele Recalcati | 5f7ddae | 2010-08-09 17:20:59 -0700 | [diff] [blame] | 4009 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4010 | if (WARN("LEADING_SPACE", |
| 4011 | "please, no spaces at the start of a line\n" . $herevet) && |
| 4012 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4013 | $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4014 | } |
Raffaele Recalcati | 5f7ddae | 2010-08-09 17:20:59 -0700 | [diff] [blame] | 4015 | } |
| 4016 | |
Andy Whitcroft | b9ea10d | 2008-10-15 22:02:24 -0700 | [diff] [blame] | 4017 | # check we are in a valid C source file if not then ignore this hunk |
| 4018 | next if ($realfile !~ /\.(h|c)$/); |
| 4019 | |
Joe Perches | 5751a24 | 2017-11-17 15:28:52 -0800 | [diff] [blame] | 4020 | # check for unusual line ending [ or ( |
| 4021 | if ($line =~ /^\+.*([\[\(])\s*$/) { |
| 4022 | CHK("OPEN_ENDED_LINE", |
| 4023 | "Lines should not end with a '$1'\n" . $herecurr); |
| 4024 | } |
| 4025 | |
Joe Perches | 4dbed76 | 2017-05-08 15:55:39 -0700 | [diff] [blame] | 4026 | # check if this appears to be the start function declaration, save the name |
| 4027 | if ($sline =~ /^\+\{\s*$/ && |
| 4028 | $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { |
| 4029 | $context_function = $1; |
| 4030 | } |
| 4031 | |
| 4032 | # check if this appears to be the end of function declaration |
| 4033 | if ($sline =~ /^\+\}\s*$/) { |
| 4034 | undef $context_function; |
| 4035 | } |
| 4036 | |
Joe Perches | 032a4c0 | 2014-08-06 16:10:29 -0700 | [diff] [blame] | 4037 | # check indentation of any line with a bare else |
Joe Perches | 840080a | 2014-10-13 15:51:59 -0700 | [diff] [blame] | 4038 | # (but not if it is a multiple line "if (foo) return bar; else return baz;") |
Joe Perches | 032a4c0 | 2014-08-06 16:10:29 -0700 | [diff] [blame] | 4039 | # if the previous line is a break or return and is indented 1 tab more... |
| 4040 | if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { |
| 4041 | my $tabs = length($1) + 1; |
Joe Perches | 840080a | 2014-10-13 15:51:59 -0700 | [diff] [blame] | 4042 | if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || |
| 4043 | ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && |
| 4044 | defined $lines[$linenr] && |
| 4045 | $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { |
Joe Perches | 032a4c0 | 2014-08-06 16:10:29 -0700 | [diff] [blame] | 4046 | WARN("UNNECESSARY_ELSE", |
| 4047 | "else is not generally useful after a break or return\n" . $hereprev); |
| 4048 | } |
| 4049 | } |
| 4050 | |
Joe Perches | c00df19 | 2014-08-06 16:11:01 -0700 | [diff] [blame] | 4051 | # check indentation of a line with a break; |
Joe Perches | dc58bc5 | 2020-12-15 20:44:33 -0800 | [diff] [blame] | 4052 | # if the previous line is a goto, return or break |
| 4053 | # and is indented the same # of tabs |
Joe Perches | c00df19 | 2014-08-06 16:11:01 -0700 | [diff] [blame] | 4054 | if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { |
| 4055 | my $tabs = $1; |
Joe Perches | dc58bc5 | 2020-12-15 20:44:33 -0800 | [diff] [blame] | 4056 | if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { |
| 4057 | if (WARN("UNNECESSARY_BREAK", |
| 4058 | "break is not useful after a $1\n" . $hereprev) && |
| 4059 | $fix) { |
| 4060 | fix_delete_line($fixlinenr, $rawline); |
| 4061 | } |
Joe Perches | c00df19 | 2014-08-06 16:11:01 -0700 | [diff] [blame] | 4062 | } |
| 4063 | } |
| 4064 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4065 | # check for RCS/CVS revision markers |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4066 | if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4067 | WARN("CVS_KEYWORD", |
| 4068 | "CVS style keyword markers, these will _not_ be updated\n". $herecurr); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4069 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4070 | |
Joe Perches | 56e77d7 | 2013-02-21 16:44:14 -0800 | [diff] [blame] | 4071 | # check for old HOTPLUG __dev<foo> section markings |
| 4072 | if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { |
| 4073 | WARN("HOTPLUG_SECTION", |
| 4074 | "Using $1 is unnecessary\n" . $herecurr); |
| 4075 | } |
| 4076 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4077 | # Check for potential 'bare' types |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4078 | my ($stat, $cond, $line_nr_next, $remain_next, $off_next, |
| 4079 | $realline_next); |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 4080 | #print "LINE<$line>\n"; |
Joe Perches | ca81986 | 2017-07-10 15:52:13 -0700 | [diff] [blame] | 4081 | if ($linenr > $suppress_statement && |
Joe Perches | 1b5539b | 2013-09-11 14:24:03 -0700 | [diff] [blame] | 4082 | $realcnt && $sline =~ /.\s*\S/) { |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 4083 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
Andy Whitcroft | f5fe35d | 2008-07-23 21:29:03 -0700 | [diff] [blame] | 4084 | ctx_statement_block($linenr, $realcnt, 0); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 4085 | $stat =~ s/\n./\n /g; |
| 4086 | $cond =~ s/\n./\n /g; |
| 4087 | |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 4088 | #print "linenr<$linenr> <$stat>\n"; |
| 4089 | # If this statement has no statement boundaries within |
| 4090 | # it there is no point in retrying a statement scan |
| 4091 | # until we hit end of it. |
| 4092 | my $frag = $stat; $frag =~ s/;+\s*$//; |
| 4093 | if ($frag !~ /(?:{|;)/) { |
| 4094 | #print "skip<$line_nr_next>\n"; |
| 4095 | $suppress_statement = $line_nr_next; |
| 4096 | } |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 4097 | |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4098 | # Find the real next line. |
| 4099 | $realline_next = $line_nr_next; |
| 4100 | if (defined $realline_next && |
| 4101 | (!defined $lines[$realline_next - 1] || |
| 4102 | substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { |
| 4103 | $realline_next++; |
| 4104 | } |
| 4105 | |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 4106 | my $s = $stat; |
| 4107 | $s =~ s/{.*$//s; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4108 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4109 | # Ignore goto labels. |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 4110 | if ($s =~ /$Ident:\*$/s) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4111 | |
| 4112 | # Ignore functions being called |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 4113 | } elsif ($s =~ /^.\s*$Ident\s*\(/s) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4114 | |
Andy Whitcroft | 463f286 | 2009-09-21 17:04:34 -0700 | [diff] [blame] | 4115 | } elsif ($s =~ /^.\s*else\b/s) { |
| 4116 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4117 | # declarations always start with types |
Andy Whitcroft | d250658 | 2008-07-23 21:29:09 -0700 | [diff] [blame] | 4118 | } 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 Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4119 | my $type = $1; |
| 4120 | $type =~ s/\s+/ /g; |
| 4121 | possible($type, "A:" . $s); |
| 4122 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4123 | # definitions in global scope can only start with types |
Andy Whitcroft | a6a84062 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 4124 | } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4125 | possible($1, "B:" . $s); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4126 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4127 | |
| 4128 | # any (foo ... *) is a pointer cast, and foo is a type |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4129 | while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4130 | possible($1, "C:" . $s); |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4131 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4132 | |
| 4133 | # Check for any sort of function declaration. |
| 4134 | # int foo(something bar, other baz); |
| 4135 | # void (*store_gdt)(x86_descr_ptr *); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 4136 | if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4137 | my ($name_len) = length($1); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4138 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4139 | my $ctx = $s; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4140 | substr($ctx, 0, $name_len + 1, ''); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4141 | $ctx =~ s/\)[^\)]*$//; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4142 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4143 | for my $arg (split(/\s*,\s*/, $ctx)) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4144 | if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4145 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4146 | possible($1, "D:" . $s); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4147 | } |
| 4148 | } |
| 4149 | } |
| 4150 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4151 | } |
| 4152 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4153 | # |
| 4154 | # Checks which may be anchored in the context. |
| 4155 | # |
| 4156 | |
| 4157 | # Check for switch () and associated case and default |
| 4158 | # statements should be at the same indent. |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4159 | if ($line=~/\bswitch\s*\(.*\)/) { |
| 4160 | my $err = ''; |
| 4161 | my $sep = ''; |
| 4162 | my @ctx = ctx_block_outer($linenr, $realcnt); |
| 4163 | shift(@ctx); |
| 4164 | for my $ctx (@ctx) { |
| 4165 | my ($clen, $cindent) = line_stats($ctx); |
| 4166 | if ($ctx =~ /^\+\s*(case\s+|default:)/ && |
| 4167 | $indent != $cindent) { |
| 4168 | $err .= "$sep$ctx\n"; |
| 4169 | $sep = ''; |
| 4170 | } else { |
| 4171 | $sep = "[...]\n"; |
| 4172 | } |
| 4173 | } |
| 4174 | if ($err ne '') { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4175 | ERROR("SWITCH_CASE_INDENT_LEVEL", |
| 4176 | "switch and case should be at the same indent\n$hereline$err"); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 4177 | } |
| 4178 | } |
| 4179 | |
| 4180 | # if/while/etc brace do not go on next line, unless defining a do while loop, |
| 4181 | # or if that brace on the next line is for something else |
Joe Perches | 0fe3dc2 | 2014-08-06 16:11:16 -0700 | [diff] [blame] | 4182 | if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4183 | my $pre_ctx = "$1$2"; |
| 4184 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4185 | my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); |
Joe Perches | 8eef05d | 2012-02-03 15:20:39 -0800 | [diff] [blame] | 4186 | |
| 4187 | if ($line =~ /^\+\t{6,}/) { |
| 4188 | WARN("DEEP_INDENTATION", |
| 4189 | "Too many leading tabs - consider code refactoring\n" . $herecurr); |
| 4190 | } |
| 4191 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 4192 | my $ctx_cnt = $realcnt - $#ctx - 1; |
| 4193 | my $ctx = join("\n", @ctx); |
| 4194 | |
Andy Whitcroft | 548596d | 2008-07-23 21:29:01 -0700 | [diff] [blame] | 4195 | my $ctx_ln = $linenr; |
| 4196 | my $ctx_skip = $realcnt; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 4197 | |
Andy Whitcroft | 548596d | 2008-07-23 21:29:01 -0700 | [diff] [blame] | 4198 | while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && |
| 4199 | defined $lines[$ctx_ln - 1] && |
| 4200 | $lines[$ctx_ln - 1] =~ /^-/)) { |
| 4201 | ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; |
| 4202 | $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4203 | $ctx_ln++; |
| 4204 | } |
Andy Whitcroft | 548596d | 2008-07-23 21:29:01 -0700 | [diff] [blame] | 4205 | |
Andy Whitcroft | 5321016 | 2008-07-23 21:29:03 -0700 | [diff] [blame] | 4206 | #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; |
| 4207 | #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4208 | |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 4209 | if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4210 | ERROR("OPEN_BRACE", |
| 4211 | "that open brace { should be on the previous line\n" . |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 4212 | "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4213 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4214 | if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && |
| 4215 | $ctx =~ /\)\s*\;\s*$/ && |
| 4216 | defined $lines[$ctx_ln - 1]) |
| 4217 | { |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4218 | my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); |
| 4219 | if ($nindent > $indent) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4220 | WARN("TRAILING_SEMICOLON", |
| 4221 | "trailing semicolon indicates no statements, indent implies otherwise\n" . |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 4222 | "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4223 | } |
| 4224 | } |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4225 | } |
| 4226 | |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4227 | # Check relative indent for conditionals and blocks. |
Joe Perches | f6950a7 | 2017-05-08 15:56:05 -0700 | [diff] [blame] | 4228 | if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 4229 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
| 4230 | ctx_statement_block($linenr, $realcnt, 0) |
| 4231 | if (!defined $stat); |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4232 | my ($s, $c) = ($stat, $cond); |
| 4233 | |
| 4234 | substr($s, 0, length($c), ''); |
| 4235 | |
Joe Perches | 9f5af48 | 2015-09-09 15:37:30 -0700 | [diff] [blame] | 4236 | # remove inline comments |
| 4237 | $s =~ s/$;/ /g; |
| 4238 | $c =~ s/$;/ /g; |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4239 | |
| 4240 | # Find out how long the conditional actually is. |
Andy Whitcroft | 6f779c1 | 2008-10-15 22:02:27 -0700 | [diff] [blame] | 4241 | my @newlines = ($c =~ /\n/gs); |
| 4242 | my $cond_lines = 1 + $#newlines; |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4243 | |
Joe Perches | 9f5af48 | 2015-09-09 15:37:30 -0700 | [diff] [blame] | 4244 | # Make sure we remove the line prefixes as we have |
| 4245 | # none on the first line, and are going to readd them |
| 4246 | # where necessary. |
| 4247 | $s =~ s/\n./\n/gs; |
| 4248 | while ($s =~ /\n\s+\\\n/) { |
| 4249 | $cond_lines += $s =~ s/\n\s+\\\n/\n/g; |
| 4250 | } |
| 4251 | |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4252 | # We want to check the first line inside the block |
| 4253 | # starting at the end of the conditional, so remove: |
| 4254 | # 1) any blank line termination |
| 4255 | # 2) any opening brace { on end of the line |
| 4256 | # 3) any do (...) { |
| 4257 | my $continuation = 0; |
| 4258 | my $check = 0; |
| 4259 | $s =~ s/^.*\bdo\b//; |
| 4260 | $s =~ s/^\s*{//; |
| 4261 | if ($s =~ s/^\s*\\//) { |
| 4262 | $continuation = 1; |
| 4263 | } |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 4264 | if ($s =~ s/^\s*?\n//) { |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4265 | $check = 1; |
| 4266 | $cond_lines++; |
| 4267 | } |
| 4268 | |
| 4269 | # Also ignore a loop construct at the end of a |
| 4270 | # preprocessor statement. |
| 4271 | if (($prevline =~ /^.\s*#\s*define\s/ || |
| 4272 | $prevline =~ /\\\s*$/) && $continuation == 0) { |
| 4273 | $check = 0; |
| 4274 | } |
| 4275 | |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 4276 | my $cond_ptr = -1; |
Andy Whitcroft | 740504c | 2008-10-15 22:02:35 -0700 | [diff] [blame] | 4277 | $continuation = 0; |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 4278 | while ($cond_ptr != $cond_lines) { |
| 4279 | $cond_ptr = $cond_lines; |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4280 | |
Andy Whitcroft | f16fa28 | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 4281 | # If we see an #else/#elif then the code |
| 4282 | # is not linear. |
| 4283 | if ($s =~ /^\s*\#\s*(?:else|elif)/) { |
| 4284 | $check = 0; |
| 4285 | } |
| 4286 | |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 4287 | # Ignore: |
| 4288 | # 1) blank lines, they should be at 0, |
| 4289 | # 2) preprocessor lines, and |
| 4290 | # 3) labels. |
Andy Whitcroft | 740504c | 2008-10-15 22:02:35 -0700 | [diff] [blame] | 4291 | if ($continuation || |
| 4292 | $s =~ /^\s*?\n/ || |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 4293 | $s =~ /^\s*#\s*?/ || |
| 4294 | $s =~ /^\s*$Ident\s*:/) { |
Andy Whitcroft | 740504c | 2008-10-15 22:02:35 -0700 | [diff] [blame] | 4295 | $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; |
Andy Whitcroft | 30dad6e | 2009-09-21 17:04:36 -0700 | [diff] [blame] | 4296 | if ($s =~ s/^.*?\n//) { |
| 4297 | $cond_lines++; |
| 4298 | } |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 4299 | } |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4300 | } |
| 4301 | |
| 4302 | my (undef, $sindent) = line_stats("+" . $s); |
| 4303 | my $stat_real = raw_line($linenr, $cond_lines); |
| 4304 | |
| 4305 | # Check if either of these lines are modified, else |
| 4306 | # this is not this patch's fault. |
| 4307 | if (!defined($stat_real) || |
| 4308 | $stat !~ /^\+/ && $stat_real !~ /^\+/) { |
| 4309 | $check = 0; |
| 4310 | } |
| 4311 | if (defined($stat_real) && $cond_lines > 1) { |
| 4312 | $stat_real = "[...]\n$stat_real"; |
| 4313 | } |
| 4314 | |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 4315 | #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 Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4316 | |
Joe Perches | 9f5af48 | 2015-09-09 15:37:30 -0700 | [diff] [blame] | 4317 | if ($check && $s ne '' && |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 4318 | (($sindent % $tabsize) != 0 || |
Joe Perches | 9f5af48 | 2015-09-09 15:37:30 -0700 | [diff] [blame] | 4319 | ($sindent < $indent) || |
Joe Perches | f6950a7 | 2017-05-08 15:56:05 -0700 | [diff] [blame] | 4320 | ($sindent == $indent && |
| 4321 | ($s !~ /^\s*(?:\}|\{|else\b)/)) || |
Antonio Borneo | 713a09d | 2020-04-06 20:11:07 -0700 | [diff] [blame] | 4322 | ($sindent > $indent + $tabsize))) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4323 | WARN("SUSPECT_CODE_INDENT", |
| 4324 | "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 4325 | } |
| 4326 | } |
| 4327 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4328 | # Track the 'values' across context and added lines. |
| 4329 | my $opline = $line; $opline =~ s/^./ /; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4330 | my ($curr_values, $curr_vars) = |
| 4331 | annotate_values($opline . "\n", $prev_values); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4332 | $curr_values = $prev_values . $curr_values; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4333 | if ($dbg_values) { |
| 4334 | my $outline = $opline; $outline =~ s/\t/ /g; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4335 | print "$linenr > .$outline\n"; |
| 4336 | print "$linenr > $curr_values\n"; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4337 | print "$linenr > $curr_vars\n"; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4338 | } |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4339 | $prev_values = substr($curr_values, -1); |
| 4340 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4341 | #ignore lines not being added |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4342 | next if ($line =~ /^[^\+]/); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4343 | |
Joe Perches | 99ca38c | 2020-10-15 20:12:09 -0700 | [diff] [blame] | 4344 | # check for self assignments used to avoid compiler warnings |
| 4345 | # e.g.: int foo = foo, *bar = NULL; |
| 4346 | # struct foo bar = *(&(bar)); |
| 4347 | if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { |
| 4348 | my $var = $1; |
| 4349 | if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { |
| 4350 | WARN("SELF_ASSIGNMENT", |
| 4351 | "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); |
| 4352 | } |
| 4353 | } |
| 4354 | |
Joe Perches | 11ca40a | 2016-12-12 16:46:31 -0800 | [diff] [blame] | 4355 | # check for dereferences that span multiple lines |
| 4356 | if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && |
| 4357 | $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { |
| 4358 | $prevline =~ /($Lval\s*(?:\.|->))\s*$/; |
| 4359 | my $ref = $1; |
| 4360 | $line =~ /^.\s*($Lval)/; |
| 4361 | $ref .= $1; |
| 4362 | $ref =~ s/\s//g; |
| 4363 | WARN("MULTILINE_DEREFERENCE", |
| 4364 | "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); |
| 4365 | } |
| 4366 | |
Joe Perches | a1ce18e | 2016-03-15 14:58:03 -0700 | [diff] [blame] | 4367 | # check for declarations of signed or unsigned without int |
Joe Perches | c844711 | 2016-08-02 14:04:42 -0700 | [diff] [blame] | 4368 | while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { |
Joe Perches | a1ce18e | 2016-03-15 14:58:03 -0700 | [diff] [blame] | 4369 | my $type = $1; |
| 4370 | my $var = $2; |
Joe Perches | 207a8e8 | 2016-03-15 14:58:06 -0700 | [diff] [blame] | 4371 | $var = "" if (!defined $var); |
| 4372 | if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { |
Joe Perches | a1ce18e | 2016-03-15 14:58:03 -0700 | [diff] [blame] | 4373 | my $sign = $1; |
| 4374 | my $pointer = $2; |
| 4375 | |
| 4376 | $pointer = "" if (!defined $pointer); |
| 4377 | |
| 4378 | if (WARN("UNSPECIFIED_INT", |
| 4379 | "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && |
| 4380 | $fix) { |
| 4381 | my $decl = trim($sign) . " int "; |
Joe Perches | 207a8e8 | 2016-03-15 14:58:06 -0700 | [diff] [blame] | 4382 | my $comp_pointer = $pointer; |
| 4383 | $comp_pointer =~ s/\s//g; |
| 4384 | $decl .= $comp_pointer; |
| 4385 | $decl = rtrim($decl) if ($var eq ""); |
| 4386 | $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; |
Joe Perches | a1ce18e | 2016-03-15 14:58:03 -0700 | [diff] [blame] | 4387 | } |
| 4388 | } |
| 4389 | } |
| 4390 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4391 | # TEST: allow direct testing of the type matcher. |
Andy Whitcroft | 7429c69 | 2008-07-23 21:29:06 -0700 | [diff] [blame] | 4392 | if ($dbg_type) { |
| 4393 | if ($line =~ /^.\s*$Declare\s*$/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4394 | ERROR("TEST_TYPE", |
| 4395 | "TEST: is type\n" . $herecurr); |
Andy Whitcroft | 7429c69 | 2008-07-23 21:29:06 -0700 | [diff] [blame] | 4396 | } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4397 | ERROR("TEST_NOT_TYPE", |
| 4398 | "TEST: is not type ($1 is)\n". $herecurr); |
Andy Whitcroft | 7429c69 | 2008-07-23 21:29:06 -0700 | [diff] [blame] | 4399 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4400 | next; |
| 4401 | } |
Andy Whitcroft | a1ef277 | 2008-10-15 22:02:17 -0700 | [diff] [blame] | 4402 | # TEST: allow direct testing of the attribute matcher. |
| 4403 | if ($dbg_attr) { |
Andy Whitcroft | 9360b0e | 2009-02-27 14:03:08 -0800 | [diff] [blame] | 4404 | if ($line =~ /^.\s*$Modifier\s*$/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4405 | ERROR("TEST_ATTR", |
| 4406 | "TEST: is attr\n" . $herecurr); |
Andy Whitcroft | 9360b0e | 2009-02-27 14:03:08 -0800 | [diff] [blame] | 4407 | } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4408 | ERROR("TEST_NOT_ATTR", |
| 4409 | "TEST: is not attr ($1 is)\n". $herecurr); |
Andy Whitcroft | a1ef277 | 2008-10-15 22:02:17 -0700 | [diff] [blame] | 4410 | } |
| 4411 | next; |
| 4412 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4413 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4414 | # check for initialisation to aggregates open brace on the next line |
Andy Whitcroft | 99423c2 | 2009-10-26 16:50:15 -0700 | [diff] [blame] | 4415 | if ($line =~ /^.\s*{/ && |
| 4416 | $prevline =~ /(?:^|[^=])=\s*$/) { |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 4417 | if (ERROR("OPEN_BRACE", |
| 4418 | "that open brace { should be on the previous line\n" . $hereprev) && |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 4419 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { |
| 4420 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 4421 | fix_delete_line($fixlinenr, $rawline); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 4422 | my $fixedline = $prevrawline; |
| 4423 | $fixedline =~ s/\s*=\s*$/ = {/; |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 4424 | fix_insert_line($fixlinenr, $fixedline); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 4425 | $fixedline = $line; |
Cyril Bur | 8d81ae0 | 2017-07-10 15:52:21 -0700 | [diff] [blame] | 4426 | $fixedline =~ s/^(.\s*)\{\s*/$1/; |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 4427 | fix_insert_line($fixlinenr, $fixedline); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 4428 | } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4429 | } |
| 4430 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4431 | # |
| 4432 | # Checks which are anchored on the added line. |
| 4433 | # |
| 4434 | |
| 4435 | # check for malformed paths in #include statements (uses RAW line) |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4436 | if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4437 | my $path = $1; |
| 4438 | if ($path =~ m{//}) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4439 | ERROR("MALFORMED_INCLUDE", |
Joe Perches | 495e9d8 | 2012-12-20 15:05:37 -0800 | [diff] [blame] | 4440 | "malformed #include filename\n" . $herecurr); |
| 4441 | } |
| 4442 | if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { |
| 4443 | ERROR("UAPI_INCLUDE", |
| 4444 | "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4445 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4446 | } |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4447 | |
| 4448 | # no C99 // comments |
| 4449 | if ($line =~ m{//}) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4450 | if (ERROR("C99_COMMENTS", |
| 4451 | "do not use C99 // comments\n" . $herecurr) && |
| 4452 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4453 | my $line = $fixed[$fixlinenr]; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4454 | if ($line =~ /\/\/(.*)$/) { |
| 4455 | my $comment = trim($1); |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4456 | $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4457 | } |
| 4458 | } |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4459 | } |
| 4460 | # Remove C99 comments. |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4461 | $line =~ s@//.*@@; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4462 | $opline =~ s@//.*@@; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4463 | |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4464 | # EXPORT_SYMBOL should immediately follow the thing it is exporting, consider |
| 4465 | # the whole statement. |
| 4466 | #print "APW <$lines[$realline_next - 1]>\n"; |
| 4467 | if (defined $realline_next && |
| 4468 | exists $lines[$realline_next - 1] && |
| 4469 | !defined $suppress_export{$realline_next} && |
Christoph Hellwig | 3679482 | 2021-02-02 13:13:34 +0100 | [diff] [blame] | 4470 | ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { |
Andy Whitcroft | 3cbf62d | 2010-10-26 14:23:18 -0700 | [diff] [blame] | 4471 | # Handle definitions which produce identifiers with |
| 4472 | # a prefix: |
| 4473 | # XXX(foo); |
| 4474 | # EXPORT_SYMBOL(something_foo); |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4475 | my $name = $1; |
Joe Perches | 70a1165 | 2021-11-08 18:33:31 -0800 | [diff] [blame] | 4476 | $name =~ s/^\s*($Ident).*/$1/; |
Andy Whitcroft | 87a5387 | 2012-01-10 15:10:04 -0800 | [diff] [blame] | 4477 | if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && |
Andy Whitcroft | 3cbf62d | 2010-10-26 14:23:18 -0700 | [diff] [blame] | 4478 | $name =~ /^${Ident}_$2/) { |
| 4479 | #print "FOO C name<$name>\n"; |
| 4480 | $suppress_export{$realline_next} = 1; |
| 4481 | |
| 4482 | } elsif ($stat !~ /(?: |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4483 | \n.}\s*$| |
Andy Whitcroft | 4801205 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 4484 | ^.DEFINE_$Ident\(\Q$name\E\)| |
| 4485 | ^.DECLARE_$Ident\(\Q$name\E\)| |
| 4486 | ^.LIST_HEAD\(\Q$name\E\)| |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4487 | ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| |
| 4488 | \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() |
Andy Whitcroft | 4801205 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 4489 | )/x) { |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4490 | #print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; |
| 4491 | $suppress_export{$realline_next} = 2; |
| 4492 | } else { |
| 4493 | $suppress_export{$realline_next} = 1; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4494 | } |
| 4495 | } |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4496 | if (!defined $suppress_export{$linenr} && |
| 4497 | $prevline =~ /^.\s*$/ && |
Christoph Hellwig | 3679482 | 2021-02-02 13:13:34 +0100 | [diff] [blame] | 4498 | ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4499 | #print "FOO B <$lines[$linenr - 1]>\n"; |
| 4500 | $suppress_export{$linenr} = 2; |
| 4501 | } |
| 4502 | if (defined $suppress_export{$linenr} && |
| 4503 | $suppress_export{$linenr} == 2) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4504 | WARN("EXPORT_SYMBOL", |
| 4505 | "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 4506 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4507 | |
Joe Eloff | 5150bda | 2010-08-09 17:21:00 -0700 | [diff] [blame] | 4508 | # check for global initialisers. |
Song Liu | 5b8f82e | 2021-02-25 17:22:08 -0800 | [diff] [blame] | 4509 | if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ && |
| 4510 | !exclude_global_initialisers($realfile)) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4511 | if (ERROR("GLOBAL_INITIALISERS", |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 4512 | "do not initialise globals to $1\n" . $herecurr) && |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4513 | $fix) { |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 4514 | $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4515 | } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4516 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4517 | # check for static initialisers. |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 4518 | if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4519 | if (ERROR("INITIALISED_STATIC", |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 4520 | "do not initialise statics to $1\n" . |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4521 | $herecurr) && |
| 4522 | $fix) { |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 4523 | $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4524 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4525 | } |
| 4526 | |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 4527 | # check for misordered declarations of char/short/int/long with signed/unsigned |
| 4528 | while ($sline =~ m{(\b$TypeMisordered\b)}g) { |
| 4529 | my $tmp = trim($1); |
| 4530 | WARN("MISORDERED_TYPE", |
| 4531 | "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); |
| 4532 | } |
| 4533 | |
Joe Perches | 809e082 | 2018-08-21 21:58:12 -0700 | [diff] [blame] | 4534 | # check for unnecessary <signed> int declarations of short/long/long long |
| 4535 | while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { |
| 4536 | my $type = trim($1); |
| 4537 | next if ($type !~ /\bint\b/); |
| 4538 | next if ($type !~ /\b(?:short|long\s+long|long)\b/); |
| 4539 | my $new_type = $type; |
| 4540 | $new_type =~ s/\b\s*int\s*\b/ /; |
| 4541 | $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; |
| 4542 | $new_type =~ s/^const\s+//; |
| 4543 | $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); |
| 4544 | $new_type = "const $new_type" if ($type =~ /^const\b/); |
| 4545 | $new_type =~ s/\s+/ /g; |
| 4546 | $new_type = trim($new_type); |
| 4547 | if (WARN("UNNECESSARY_INT", |
| 4548 | "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && |
| 4549 | $fix) { |
| 4550 | $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; |
| 4551 | } |
| 4552 | } |
| 4553 | |
Joe Perches | cb710ec | 2010-10-26 14:23:20 -0700 | [diff] [blame] | 4554 | # check for static const char * arrays. |
| 4555 | if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4556 | WARN("STATIC_CONST_CHAR_ARRAY", |
| 4557 | "static const char * array should probably be static const char * const\n" . |
Joe Perches | cb710ec | 2010-10-26 14:23:20 -0700 | [diff] [blame] | 4558 | $herecurr); |
Joe Perches | 77b8c0a | 2019-01-03 15:26:59 -0800 | [diff] [blame] | 4559 | } |
| 4560 | |
| 4561 | # check for initialized const char arrays that should be static const |
| 4562 | if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { |
| 4563 | if (WARN("STATIC_CONST_CHAR_ARRAY", |
| 4564 | "const array should probably be static const\n" . $herecurr) && |
| 4565 | $fix) { |
| 4566 | $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; |
| 4567 | } |
| 4568 | } |
Joe Perches | cb710ec | 2010-10-26 14:23:20 -0700 | [diff] [blame] | 4569 | |
| 4570 | # check for static char foo[] = "bar" declarations. |
| 4571 | if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4572 | WARN("STATIC_CONST_CHAR_ARRAY", |
| 4573 | "static char array declaration should probably be static const char\n" . |
Joe Perches | cb710ec | 2010-10-26 14:23:20 -0700 | [diff] [blame] | 4574 | $herecurr); |
Joe Perches | 77b8c0a | 2019-01-03 15:26:59 -0800 | [diff] [blame] | 4575 | } |
Joe Perches | cb710ec | 2010-10-26 14:23:20 -0700 | [diff] [blame] | 4576 | |
Joe Perches | ab7e23f | 2015-04-16 12:44:22 -0700 | [diff] [blame] | 4577 | # check for const <foo> const where <foo> is not a pointer or array type |
| 4578 | if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { |
| 4579 | my $found = $1; |
| 4580 | if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { |
| 4581 | WARN("CONST_CONST", |
| 4582 | "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); |
| 4583 | } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { |
| 4584 | WARN("CONST_CONST", |
| 4585 | "'const $found const' should probably be 'const $found'\n" . $herecurr); |
| 4586 | } |
| 4587 | } |
| 4588 | |
Joe Perches | 7316976 | 2020-12-15 20:44:30 -0800 | [diff] [blame] | 4589 | # check for const static or static <non ptr type> const declarations |
| 4590 | # prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const' |
| 4591 | if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || |
| 4592 | $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { |
| 4593 | if (WARN("STATIC_CONST", |
| 4594 | "Move const after static - use 'static const $1'\n" . $herecurr) && |
| 4595 | $fix) { |
| 4596 | $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; |
| 4597 | $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; |
| 4598 | } |
| 4599 | } |
| 4600 | |
Joe Perches | 9b0fa60 | 2014-04-03 14:49:18 -0700 | [diff] [blame] | 4601 | # check for non-global char *foo[] = {"bar", ...} declarations. |
| 4602 | if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { |
| 4603 | WARN("STATIC_CONST_CHAR_ARRAY", |
| 4604 | "char * array declaration might be better as static const\n" . |
| 4605 | $herecurr); |
Dwaipayan Ray | ea7dbab | 2021-02-25 17:21:47 -0800 | [diff] [blame] | 4606 | } |
Joe Perches | 9b0fa60 | 2014-04-03 14:49:18 -0700 | [diff] [blame] | 4607 | |
Joe Perches | b598b67 | 2015-04-16 12:44:36 -0700 | [diff] [blame] | 4608 | # check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) |
| 4609 | if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { |
| 4610 | my $array = $1; |
| 4611 | if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { |
| 4612 | my $array_div = $1; |
| 4613 | if (WARN("ARRAY_SIZE", |
| 4614 | "Prefer ARRAY_SIZE($array)\n" . $herecurr) && |
| 4615 | $fix) { |
| 4616 | $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; |
| 4617 | } |
| 4618 | } |
| 4619 | } |
| 4620 | |
Joe Perches | b36190c | 2014-01-27 17:07:18 -0800 | [diff] [blame] | 4621 | # check for function declarations without arguments like "int foo()" |
Joe Perches | 16b7f3c | 2020-04-06 20:11:17 -0700 | [diff] [blame] | 4622 | if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { |
Joe Perches | b36190c | 2014-01-27 17:07:18 -0800 | [diff] [blame] | 4623 | if (ERROR("FUNCTION_WITHOUT_ARGS", |
| 4624 | "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && |
| 4625 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4626 | $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; |
Joe Perches | b36190c | 2014-01-27 17:07:18 -0800 | [diff] [blame] | 4627 | } |
| 4628 | } |
| 4629 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4630 | # check for new typedefs, only function parameters and sparse annotations |
| 4631 | # make sense. |
| 4632 | if ($line =~ /\btypedef\s/ && |
Andy Whitcroft | 8054576 | 2009-01-06 14:41:26 -0800 | [diff] [blame] | 4633 | $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4634 | $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && |
Andy Whitcroft | 8ed22ca | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 4635 | $line !~ /\b$typeTypedefs\b/ && |
Michael S. Tsirkin | 46d832f | 2016-12-11 06:29:58 +0200 | [diff] [blame] | 4636 | $line !~ /\b__bitwise\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4637 | WARN("NEW_TYPEDEFS", |
| 4638 | "do not add new typedefs\n" . $herecurr); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4639 | } |
| 4640 | |
| 4641 | # * goes on variable not on type |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4642 | # (char*[ const]) |
Andy Whitcroft | bfcb2cc | 2012-01-10 15:10:15 -0800 | [diff] [blame] | 4643 | while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { |
| 4644 | #print "AA<$1>\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4645 | my ($ident, $from, $to) = ($1, $2, $2); |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 4646 | |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4647 | # Should start with a space. |
| 4648 | $to =~ s/^(\S)/ $1/; |
| 4649 | # Should not end with a space. |
| 4650 | $to =~ s/\s+$//; |
| 4651 | # '*'s should not have spaces between. |
Andy Whitcroft | f9a0b3d | 2009-01-15 13:51:05 -0800 | [diff] [blame] | 4652 | while ($to =~ s/\*\s+\*/\*\*/) { |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4653 | } |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 4654 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4655 | ## print "1: from<$from> to<$to> ident<$ident>\n"; |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4656 | if ($from ne $to) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4657 | if (ERROR("POINTER_LOCATION", |
| 4658 | "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && |
| 4659 | $fix) { |
| 4660 | my $sub_from = $ident; |
| 4661 | my $sub_to = $ident; |
| 4662 | $sub_to =~ s/\Q$from\E/$to/; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4663 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4664 | s@\Q$sub_from\E@$sub_to@; |
| 4665 | } |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4666 | } |
Andy Whitcroft | bfcb2cc | 2012-01-10 15:10:15 -0800 | [diff] [blame] | 4667 | } |
| 4668 | while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { |
| 4669 | #print "BB<$1>\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4670 | my ($match, $from, $to, $ident) = ($1, $2, $2, $3); |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 4671 | |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4672 | # Should start with a space. |
| 4673 | $to =~ s/^(\S)/ $1/; |
| 4674 | # Should not end with a space. |
| 4675 | $to =~ s/\s+$//; |
| 4676 | # '*'s should not have spaces between. |
Andy Whitcroft | f9a0b3d | 2009-01-15 13:51:05 -0800 | [diff] [blame] | 4677 | while ($to =~ s/\*\s+\*/\*\*/) { |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4678 | } |
| 4679 | # Modifiers should have spaces. |
| 4680 | $to =~ s/(\b$Modifier$)/$1 /; |
| 4681 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4682 | ## print "2: from<$from> to<$to> ident<$ident>\n"; |
Andy Whitcroft | 667026e | 2009-02-27 14:03:08 -0800 | [diff] [blame] | 4683 | if ($from ne $to && $ident !~ /^$Modifier$/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4684 | if (ERROR("POINTER_LOCATION", |
| 4685 | "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && |
| 4686 | $fix) { |
| 4687 | |
| 4688 | my $sub_from = $match; |
| 4689 | my $sub_to = $match; |
| 4690 | $sub_to =~ s/\Q$from\E/$to/; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4691 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4692 | s@\Q$sub_from\E@$sub_to@; |
| 4693 | } |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 4694 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4695 | } |
| 4696 | |
Joe Perches | 9d3e3c7 | 2015-09-09 15:37:27 -0700 | [diff] [blame] | 4697 | # avoid BUG() or BUG_ON() |
| 4698 | if ($line =~ /\b(?:BUG|BUG_ON)\b/) { |
Jean Delvare | 0675a8f | 2017-09-08 16:16:07 -0700 | [diff] [blame] | 4699 | my $msg_level = \&WARN; |
| 4700 | $msg_level = \&CHK if ($file); |
| 4701 | &{$msg_level}("AVOID_BUG", |
| 4702 | "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); |
Joe Perches | 9d3e3c7 | 2015-09-09 15:37:27 -0700 | [diff] [blame] | 4703 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4704 | |
Joe Perches | 9d3e3c7 | 2015-09-09 15:37:27 -0700 | [diff] [blame] | 4705 | # avoid LINUX_VERSION_CODE |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4706 | if ($line =~ /\bLINUX_VERSION_CODE\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4707 | WARN("LINUX_VERSION_CODE", |
| 4708 | "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4709 | } |
| 4710 | |
Joe Perches | 1744122 | 2011-06-15 15:08:17 -0700 | [diff] [blame] | 4711 | # check for uses of printk_ratelimit |
| 4712 | if ($line =~ /\bprintk_ratelimit\s*\(/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4713 | WARN("PRINTK_RATELIMITED", |
Joe Perches | 101ee68 | 2015-02-13 14:38:54 -0800 | [diff] [blame] | 4714 | "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); |
Joe Perches | 1744122 | 2011-06-15 15:08:17 -0700 | [diff] [blame] | 4715 | } |
| 4716 | |
Joe Perches | eeef573 | 2017-11-17 15:28:41 -0800 | [diff] [blame] | 4717 | # printk should use KERN_* levels |
| 4718 | if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { |
| 4719 | WARN("PRINTK_WITHOUT_KERN_LEVEL", |
| 4720 | "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4721 | } |
| 4722 | |
Joe Perches | f5eea3b | 2020-12-15 20:45:24 -0800 | [diff] [blame] | 4723 | # prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL> |
| 4724 | if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { |
| 4725 | my $printk = $1; |
| 4726 | my $modifier = $2; |
| 4727 | my $orig = $3; |
| 4728 | $modifier = "" if (!defined($modifier)); |
Joe Perches | 243f380 | 2012-05-31 16:26:09 -0700 | [diff] [blame] | 4729 | my $level = lc($orig); |
| 4730 | $level = "warn" if ($level eq "warning"); |
Joe Perches | 8f26b83 | 2012-10-04 17:13:32 -0700 | [diff] [blame] | 4731 | my $level2 = $level; |
| 4732 | $level2 = "dbg" if ($level eq "debug"); |
Joe Perches | f5eea3b | 2020-12-15 20:45:24 -0800 | [diff] [blame] | 4733 | $level .= $modifier; |
| 4734 | $level2 .= $modifier; |
Joe Perches | 243f380 | 2012-05-31 16:26:09 -0700 | [diff] [blame] | 4735 | WARN("PREFER_PR_LEVEL", |
Joe Perches | f5eea3b | 2020-12-15 20:45:24 -0800 | [diff] [blame] | 4736 | "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); |
Joe Perches | 243f380 | 2012-05-31 16:26:09 -0700 | [diff] [blame] | 4737 | } |
| 4738 | |
Joe Perches | f5eea3b | 2020-12-15 20:45:24 -0800 | [diff] [blame] | 4739 | # prefer dev_<level> to dev_printk(KERN_<LEVEL> |
Joe Perches | dc13931 | 2013-02-21 16:44:13 -0800 | [diff] [blame] | 4740 | if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { |
| 4741 | my $orig = $1; |
| 4742 | my $level = lc($orig); |
| 4743 | $level = "warn" if ($level eq "warning"); |
| 4744 | $level = "dbg" if ($level eq "debug"); |
| 4745 | WARN("PREFER_DEV_LEVEL", |
| 4746 | "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); |
| 4747 | } |
| 4748 | |
Nicolas Boichat | 8020b25 | 2020-10-15 20:12:02 -0700 | [diff] [blame] | 4749 | # trace_printk should not be used in production code. |
| 4750 | if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { |
| 4751 | WARN("TRACE_PRINTK", |
| 4752 | "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); |
| 4753 | } |
| 4754 | |
Andy Lutomirski | 91c9afa | 2015-04-16 12:44:44 -0700 | [diff] [blame] | 4755 | # ENOSYS means "bad syscall nr" and nothing else. This will have a small |
| 4756 | # number of false positives, but assembly files are not checked, so at |
| 4757 | # least the arch entry code will not trigger this warning. |
| 4758 | if ($line =~ /\bENOSYS\b/) { |
| 4759 | WARN("ENOSYS", |
| 4760 | "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); |
| 4761 | } |
| 4762 | |
Jakub Kicinski | 6b9ea5f | 2020-05-11 10:08:07 -0700 | [diff] [blame] | 4763 | # ENOTSUPP is not a standard error code and should be avoided in new patches. |
| 4764 | # Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. |
| 4765 | # Similarly to ENOSYS warning a small number of false positives is expected. |
| 4766 | if (!$file && $line =~ /\bENOTSUPP\b/) { |
| 4767 | if (WARN("ENOTSUPP", |
| 4768 | "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && |
| 4769 | $fix) { |
| 4770 | $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; |
| 4771 | } |
| 4772 | } |
| 4773 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4774 | # function brace can't be on same line, except for #defines of do while, |
| 4775 | # or if closed on same line |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 4776 | if ($perl_version_ok && |
Joe Perches | 2d453e3 | 2018-02-06 15:39:09 -0800 | [diff] [blame] | 4777 | $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && |
| 4778 | $sline !~ /\#\s*define\b.*do\s*\{/ && |
| 4779 | $sline !~ /}/) { |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 4780 | if (ERROR("OPEN_BRACE", |
Joe Perches | 2d453e3 | 2018-02-06 15:39:09 -0800 | [diff] [blame] | 4781 | "open brace '{' following function definitions go on the next line\n" . $herecurr) && |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 4782 | $fix) { |
| 4783 | fix_delete_line($fixlinenr, $rawline); |
| 4784 | my $fixed_line = $rawline; |
Dwaipayan Ray | 03f4935 | 2020-12-15 20:45:02 -0800 | [diff] [blame] | 4785 | $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 4786 | my $line1 = $1; |
| 4787 | my $line2 = $2; |
| 4788 | fix_insert_line($fixlinenr, ltrim($line1)); |
| 4789 | fix_insert_line($fixlinenr, "\+{"); |
| 4790 | if ($line2 !~ /^\s*$/) { |
| 4791 | fix_insert_line($fixlinenr, "\+\t" . trim($line2)); |
| 4792 | } |
| 4793 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4794 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4795 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4796 | # open braces for enum, union and struct go on the same line. |
| 4797 | if ($line =~ /^.\s*{/ && |
| 4798 | $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 4799 | if (ERROR("OPEN_BRACE", |
| 4800 | "open brace '{' following $1 go on the same line\n" . $hereprev) && |
| 4801 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { |
| 4802 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 4803 | fix_delete_line($fixlinenr, $rawline); |
| 4804 | my $fixedline = rtrim($prevrawline) . " {"; |
| 4805 | fix_insert_line($fixlinenr, $fixedline); |
| 4806 | $fixedline = $rawline; |
Cyril Bur | 8d81ae0 | 2017-07-10 15:52:21 -0700 | [diff] [blame] | 4807 | $fixedline =~ s/^(.\s*)\{\s*/$1\t/; |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 4808 | if ($fixedline !~ /^\+\s*$/) { |
| 4809 | fix_insert_line($fixlinenr, $fixedline); |
| 4810 | } |
| 4811 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4812 | } |
| 4813 | |
Andy Whitcroft | 0c73b4e | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 4814 | # missing space after union, struct or enum definition |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4815 | if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { |
| 4816 | if (WARN("SPACING", |
| 4817 | "missing space after $1 definition\n" . $herecurr) && |
| 4818 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4819 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4820 | s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; |
| 4821 | } |
Andy Whitcroft | 0c73b4e | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 4822 | } |
| 4823 | |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 4824 | # Function pointer declarations |
| 4825 | # check spacing between type, funcptr, and args |
| 4826 | # canonical declaration is "type (*funcptr)(args...)" |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 4827 | if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 4828 | my $declare = $1; |
| 4829 | my $pre_pointer_space = $2; |
| 4830 | my $post_pointer_space = $3; |
| 4831 | my $funcname = $4; |
| 4832 | my $post_funcname_space = $5; |
| 4833 | my $pre_args_space = $6; |
| 4834 | |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 4835 | # the $Declare variable will capture all spaces after the type |
| 4836 | # so check it for a missing trailing missing space but pointer return types |
| 4837 | # don't need a space so don't warn for those. |
| 4838 | my $post_declare_space = ""; |
| 4839 | if ($declare =~ /(\s+)$/) { |
| 4840 | $post_declare_space = $1; |
| 4841 | $declare = rtrim($declare); |
| 4842 | } |
| 4843 | if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 4844 | WARN("SPACING", |
| 4845 | "missing space after return type\n" . $herecurr); |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 4846 | $post_declare_space = " "; |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 4847 | } |
| 4848 | |
| 4849 | # unnecessary space "type (*funcptr)(args...)" |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 4850 | # This test is not currently implemented because these declarations are |
| 4851 | # equivalent to |
| 4852 | # int foo(int bar, ...) |
| 4853 | # and this is form shouldn't/doesn't generate a checkpatch warning. |
| 4854 | # |
| 4855 | # elsif ($declare =~ /\s{2,}$/) { |
| 4856 | # WARN("SPACING", |
| 4857 | # "Multiple spaces after return type\n" . $herecurr); |
| 4858 | # } |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 4859 | |
| 4860 | # unnecessary space "type ( *funcptr)(args...)" |
| 4861 | if (defined $pre_pointer_space && |
| 4862 | $pre_pointer_space =~ /^\s/) { |
| 4863 | WARN("SPACING", |
| 4864 | "Unnecessary space after function pointer open parenthesis\n" . $herecurr); |
| 4865 | } |
| 4866 | |
| 4867 | # unnecessary space "type (* funcptr)(args...)" |
| 4868 | if (defined $post_pointer_space && |
| 4869 | $post_pointer_space =~ /^\s/) { |
| 4870 | WARN("SPACING", |
| 4871 | "Unnecessary space before function pointer name\n" . $herecurr); |
| 4872 | } |
| 4873 | |
| 4874 | # unnecessary space "type (*funcptr )(args...)" |
| 4875 | if (defined $post_funcname_space && |
| 4876 | $post_funcname_space =~ /^\s/) { |
| 4877 | WARN("SPACING", |
| 4878 | "Unnecessary space after function pointer name\n" . $herecurr); |
| 4879 | } |
| 4880 | |
| 4881 | # unnecessary space "type (*funcptr) (args...)" |
| 4882 | if (defined $pre_args_space && |
| 4883 | $pre_args_space =~ /^\s/) { |
| 4884 | WARN("SPACING", |
| 4885 | "Unnecessary space before function pointer arguments\n" . $herecurr); |
| 4886 | } |
| 4887 | |
| 4888 | if (show_type("SPACING") && $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4889 | $fixed[$fixlinenr] =~ |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 4890 | s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 4891 | } |
| 4892 | } |
| 4893 | |
Andy Whitcroft | 8d31cfc | 2008-07-23 21:29:02 -0700 | [diff] [blame] | 4894 | # check for spacing round square brackets; allowed: |
| 4895 | # 1. with a type on the left -- int [] a; |
Andy Whitcroft | fe2a7db | 2008-10-15 22:02:15 -0700 | [diff] [blame] | 4896 | # 2. at the beginning of a line for slice initialisers -- [0...10] = 5, |
| 4897 | # 3. inside a curly brace -- = { [0...10] = 5 } |
Andy Whitcroft | 8d31cfc | 2008-07-23 21:29:02 -0700 | [diff] [blame] | 4898 | while ($line =~ /(.*?\s)\[/g) { |
| 4899 | my ($where, $prefix) = ($-[1], $1); |
| 4900 | if ($prefix !~ /$Type\s+$/ && |
Andy Whitcroft | fe2a7db | 2008-10-15 22:02:15 -0700 | [diff] [blame] | 4901 | ($where != 0 || $prefix !~ /^.\s+$/) && |
Heinrich Schuchardt | 38dca98 | 2018-04-10 16:34:14 -0700 | [diff] [blame] | 4902 | $prefix !~ /[{,:]\s+$/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4903 | if (ERROR("BRACKET_SPACE", |
| 4904 | "space prohibited before open square bracket '['\n" . $herecurr) && |
| 4905 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4906 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4907 | s/^(\+.*?)\s+\[/$1\[/; |
| 4908 | } |
Andy Whitcroft | 8d31cfc | 2008-07-23 21:29:02 -0700 | [diff] [blame] | 4909 | } |
| 4910 | } |
| 4911 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4912 | # check for spaces between functions and their parentheses. |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4913 | while ($line =~ /($Ident)\s+\(/g) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4914 | my $name = $1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4915 | my $ctx_before = substr($line, 0, $-[1]); |
| 4916 | my $ctx = "$ctx_before$name"; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4917 | |
| 4918 | # Ignore those directives where spaces _are_ permitted. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4919 | if ($name =~ /^(?: |
| 4920 | if|for|while|switch|return|case| |
| 4921 | volatile|__volatile__| |
| 4922 | __attribute__|format|__extension__| |
| 4923 | asm|__asm__)$/x) |
| 4924 | { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4925 | # cpp #define statements have non-optional spaces, ie |
| 4926 | # if there is a space between the name and the open |
| 4927 | # parenthesis it is simply not a parameter group. |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4928 | } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4929 | |
| 4930 | # cpp #elif statement condition may start with a ( |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4931 | } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4932 | |
| 4933 | # If this whole things ends with a type its most |
| 4934 | # likely a typedef for a function. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4935 | } elsif ($ctx =~ /$Type$/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4936 | |
| 4937 | } else { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4938 | if (WARN("SPACING", |
| 4939 | "space prohibited between function name and open parenthesis '('\n" . $herecurr) && |
| 4940 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4941 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4942 | s/\b$name\s+\(/$name\(/; |
| 4943 | } |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4944 | } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4945 | } |
Eric Nelson | 9a4cad4 | 2012-05-31 16:26:09 -0700 | [diff] [blame] | 4946 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4947 | # Check operator spacing. |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4948 | if (!($line=~/\#\s*include/)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4949 | my $fixed_line = ""; |
| 4950 | my $line_fixed = 0; |
| 4951 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4952 | my $ops = qr{ |
| 4953 | <<=|>>=|<=|>=|==|!=| |
| 4954 | \+=|-=|\*=|\/=|%=|\^=|\|=|&=| |
| 4955 | =>|->|<<|>>|<|>|=|!|~| |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4956 | &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| |
Joe Perches | 8473162 | 2013-11-12 15:10:05 -0800 | [diff] [blame] | 4957 | \?:|\?|: |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4958 | }x; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4959 | my @elements = split(/($ops|;)/, $opline); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4960 | |
| 4961 | ## print("element count: <" . $#elements . ">\n"); |
| 4962 | ## foreach my $el (@elements) { |
| 4963 | ## print("el: <$el>\n"); |
| 4964 | ## } |
| 4965 | |
| 4966 | my @fix_elements = (); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4967 | my $off = 0; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4968 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4969 | foreach my $el (@elements) { |
| 4970 | push(@fix_elements, substr($rawline, $off, length($el))); |
| 4971 | $off += length($el); |
| 4972 | } |
| 4973 | |
| 4974 | $off = 0; |
| 4975 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4976 | my $blank = copy_spacing($opline); |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4977 | my $last_after = -1; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4978 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4979 | for (my $n = 0; $n < $#elements; $n += 2) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4980 | |
| 4981 | my $good = $fix_elements[$n] . $fix_elements[$n + 1]; |
| 4982 | |
| 4983 | ## print("n: <$n> good: <$good>\n"); |
| 4984 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4985 | $off += length($elements[$n]); |
| 4986 | |
Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 4987 | # Pick up the preceding and succeeding characters. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4988 | my $ca = substr($opline, 0, $off); |
| 4989 | my $cc = ''; |
| 4990 | if (length($opline) >= ($off + length($elements[$n + 1]))) { |
| 4991 | $cc = substr($opline, $off + length($elements[$n + 1])); |
| 4992 | } |
| 4993 | my $cb = "$ca$;$cc"; |
| 4994 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4995 | my $a = ''; |
| 4996 | $a = 'V' if ($elements[$n] ne ''); |
| 4997 | $a = 'W' if ($elements[$n] =~ /\s$/); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4998 | $a = 'C' if ($elements[$n] =~ /$;$/); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4999 | $a = 'B' if ($elements[$n] =~ /(\[|\()$/); |
| 5000 | $a = 'O' if ($elements[$n] eq ''); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5001 | $a = 'E' if ($ca =~ /^\s*$/); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5002 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5003 | my $op = $elements[$n + 1]; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5004 | |
| 5005 | my $c = ''; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5006 | if (defined $elements[$n + 2]) { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5007 | $c = 'V' if ($elements[$n + 2] ne ''); |
| 5008 | $c = 'W' if ($elements[$n + 2] =~ /^\s/); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5009 | $c = 'C' if ($elements[$n + 2] =~ /^$;/); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5010 | $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); |
| 5011 | $c = 'O' if ($elements[$n + 2] eq ''); |
Andy Whitcroft | 8b1b337 | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 5012 | $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5013 | } else { |
| 5014 | $c = 'E'; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5015 | } |
| 5016 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5017 | my $ctx = "${a}x${c}"; |
| 5018 | |
| 5019 | my $at = "(ctx:$ctx)"; |
| 5020 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 5021 | my $ptr = substr($blank, 0, $off) . "^"; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5022 | my $hereptr = "$hereline$ptr\n"; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5023 | |
Andy Whitcroft | 74048ed | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5024 | # Pull out the value of this operator. |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 5025 | my $op_type = substr($curr_values, $off + 1, 1); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5026 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5027 | # Get the full operator variant. |
| 5028 | my $opv = $op . substr($curr_vars, $off, 1); |
| 5029 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5030 | # Ignore operators passed as parameters. |
| 5031 | if ($op_type ne 'V' && |
Sam Bobroff | d7fe806 | 2015-04-16 12:44:39 -0700 | [diff] [blame] | 5032 | $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5033 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5034 | # # Ignore comments |
| 5035 | # } elsif ($op =~ /^$;+$/) { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5036 | |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 5037 | # ; should have either the end of line or a space or \ after it |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5038 | } elsif ($op eq ';') { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5039 | if ($ctx !~ /.x[WEBC]/ && |
| 5040 | $cc !~ /^\\/ && $cc !~ /^;/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5041 | if (ERROR("SPACING", |
| 5042 | "space required after that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5043 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5044 | $line_fixed = 1; |
| 5045 | } |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 5046 | } |
| 5047 | |
| 5048 | # // is a comment |
| 5049 | } elsif ($op eq '//') { |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5050 | |
Joe Perches | b00e481 | 2014-04-03 14:49:33 -0700 | [diff] [blame] | 5051 | # : when part of a bitfield |
| 5052 | } elsif ($opv eq ':B') { |
| 5053 | # skip the bitfield test for now |
| 5054 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5055 | # No spaces for: |
| 5056 | # -> |
Joe Perches | b00e481 | 2014-04-03 14:49:33 -0700 | [diff] [blame] | 5057 | } elsif ($op eq '->') { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5058 | if ($ctx =~ /Wx.|.xW/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5059 | if (ERROR("SPACING", |
| 5060 | "spaces prohibited around that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5061 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5062 | if (defined $fix_elements[$n + 2]) { |
| 5063 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 5064 | } |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5065 | $line_fixed = 1; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5066 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5067 | } |
| 5068 | |
Joe Perches | 2381097 | 2014-12-10 15:51:32 -0800 | [diff] [blame] | 5069 | # , must not have a space before and must have a space on the right. |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5070 | } elsif ($op eq ',') { |
Joe Perches | 2381097 | 2014-12-10 15:51:32 -0800 | [diff] [blame] | 5071 | my $rtrim_before = 0; |
| 5072 | my $space_after = 0; |
| 5073 | if ($ctx =~ /Wx./) { |
| 5074 | if (ERROR("SPACING", |
| 5075 | "space prohibited before that '$op' $at\n" . $hereptr)) { |
| 5076 | $line_fixed = 1; |
| 5077 | $rtrim_before = 1; |
| 5078 | } |
| 5079 | } |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5080 | if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5081 | if (ERROR("SPACING", |
| 5082 | "space required after that '$op' $at\n" . $hereptr)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5083 | $line_fixed = 1; |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5084 | $last_after = $n; |
Joe Perches | 2381097 | 2014-12-10 15:51:32 -0800 | [diff] [blame] | 5085 | $space_after = 1; |
| 5086 | } |
| 5087 | } |
| 5088 | if ($rtrim_before || $space_after) { |
| 5089 | if ($rtrim_before) { |
| 5090 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
| 5091 | } else { |
| 5092 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); |
| 5093 | } |
| 5094 | if ($space_after) { |
| 5095 | $good .= " "; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5096 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5097 | } |
| 5098 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 5099 | # '*' as part of a type definition -- reported already. |
Andy Whitcroft | 74048ed | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5100 | } elsif ($opv eq '*_') { |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 5101 | #warn "'*' is part of type\n"; |
| 5102 | |
| 5103 | # unary operators should have a space before and |
| 5104 | # none after. May be left adjacent to another |
| 5105 | # unary operator, or a cast |
| 5106 | } elsif ($op eq '!' || $op eq '~' || |
Andy Whitcroft | 74048ed | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5107 | $opv eq '*U' || $opv eq '-U' || |
Andy Whitcroft | 0d41386 | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 5108 | $opv eq '&U' || $opv eq '&&U') { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5109 | if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5110 | if (ERROR("SPACING", |
| 5111 | "space required before that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5112 | if ($n != $last_after + 2) { |
| 5113 | $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); |
| 5114 | $line_fixed = 1; |
| 5115 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5116 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5117 | } |
Andy Whitcroft | a3340b3 | 2009-02-27 14:03:07 -0800 | [diff] [blame] | 5118 | if ($op eq '*' && $cc =~/\s*$Modifier\b/) { |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 5119 | # A unary '*' may be const |
| 5120 | |
| 5121 | } elsif ($ctx =~ /.xW/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5122 | if (ERROR("SPACING", |
| 5123 | "space prohibited after that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5124 | $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5125 | if (defined $fix_elements[$n + 2]) { |
| 5126 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 5127 | } |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5128 | $line_fixed = 1; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5129 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5130 | } |
| 5131 | |
| 5132 | # unary ++ and unary -- are allowed no space on one side. |
| 5133 | } elsif ($op eq '++' or $op eq '--') { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5134 | if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5135 | if (ERROR("SPACING", |
| 5136 | "space required one side of that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5137 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5138 | $line_fixed = 1; |
| 5139 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5140 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5141 | if ($ctx =~ /Wx[BE]/ || |
| 5142 | ($ctx =~ /Wx./ && $cc =~ /^;/)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5143 | if (ERROR("SPACING", |
| 5144 | "space prohibited before that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5145 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5146 | $line_fixed = 1; |
| 5147 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 5148 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5149 | if ($ctx =~ /ExW/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5150 | if (ERROR("SPACING", |
| 5151 | "space prohibited after that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5152 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5153 | if (defined $fix_elements[$n + 2]) { |
| 5154 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 5155 | } |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5156 | $line_fixed = 1; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5157 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5158 | } |
| 5159 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5160 | # << and >> may either have or not have spaces both sides |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 5161 | } elsif ($op eq '<<' or $op eq '>>' or |
| 5162 | $op eq '&' or $op eq '^' or $op eq '|' or |
| 5163 | $op eq '+' or $op eq '-' or |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 5164 | $op eq '*' or $op eq '/' or |
| 5165 | $op eq '%') |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5166 | { |
Joe Perches | d2e025f | 2015-02-13 14:38:57 -0800 | [diff] [blame] | 5167 | if ($check) { |
| 5168 | if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { |
| 5169 | if (CHK("SPACING", |
| 5170 | "spaces preferred around that '$op' $at\n" . $hereptr)) { |
| 5171 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
| 5172 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 5173 | $line_fixed = 1; |
| 5174 | } |
| 5175 | } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { |
| 5176 | if (CHK("SPACING", |
| 5177 | "space preferred before that '$op' $at\n" . $hereptr)) { |
| 5178 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); |
| 5179 | $line_fixed = 1; |
| 5180 | } |
| 5181 | } |
| 5182 | } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5183 | if (ERROR("SPACING", |
| 5184 | "need consistent spacing around '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5185 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
| 5186 | if (defined $fix_elements[$n + 2]) { |
| 5187 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 5188 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5189 | $line_fixed = 1; |
| 5190 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5191 | } |
| 5192 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5193 | # A colon needs no spaces before when it is |
| 5194 | # terminating a case value or a label. |
| 5195 | } elsif ($opv eq ':C' || $opv eq ':L') { |
Chris Down | 263afd3 | 2021-02-25 17:22:04 -0800 | [diff] [blame] | 5196 | if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5197 | if (ERROR("SPACING", |
| 5198 | "space prohibited before that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5199 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5200 | $line_fixed = 1; |
| 5201 | } |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5202 | } |
| 5203 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5204 | # All the others need spaces both sides. |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5205 | } elsif ($ctx !~ /[EWC]x[CWE]/) { |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5206 | my $ok = 0; |
| 5207 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5208 | # Ignore email addresses <foo@bar> |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5209 | if (($op eq '<' && |
| 5210 | $cc =~ /^\S+\@\S+>/) || |
| 5211 | ($op eq '>' && |
| 5212 | $ca =~ /<\S+\@\S+$/)) |
| 5213 | { |
Antonio Borneo | 342d3d2 | 2020-04-06 20:11:01 -0700 | [diff] [blame] | 5214 | $ok = 1; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5215 | } |
| 5216 | |
Joe Perches | e0df7e1 | 2015-04-16 12:44:53 -0700 | [diff] [blame] | 5217 | # for asm volatile statements |
| 5218 | # ignore a colon with another |
| 5219 | # colon immediately before or after |
| 5220 | if (($op eq ':') && |
| 5221 | ($ca =~ /:$/ || $cc =~ /^:/)) { |
| 5222 | $ok = 1; |
| 5223 | } |
| 5224 | |
Joe Perches | 8473162 | 2013-11-12 15:10:05 -0800 | [diff] [blame] | 5225 | # messages are ERROR, but ?: are CHK |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 5226 | if ($ok == 0) { |
Jean Delvare | 0675a8f | 2017-09-08 16:16:07 -0700 | [diff] [blame] | 5227 | my $msg_level = \&ERROR; |
| 5228 | $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); |
Joe Perches | 8473162 | 2013-11-12 15:10:05 -0800 | [diff] [blame] | 5229 | |
Jean Delvare | 0675a8f | 2017-09-08 16:16:07 -0700 | [diff] [blame] | 5230 | if (&{$msg_level}("SPACING", |
| 5231 | "spaces required around that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 5232 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
| 5233 | if (defined $fix_elements[$n + 2]) { |
| 5234 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 5235 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5236 | $line_fixed = 1; |
| 5237 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5238 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5239 | } |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5240 | $off += length($elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5241 | |
| 5242 | ## print("n: <$n> GOOD: <$good>\n"); |
| 5243 | |
| 5244 | $fixed_line = $fixed_line . $good; |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5245 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5246 | |
| 5247 | if (($#elements % 2) == 0) { |
| 5248 | $fixed_line = $fixed_line . $fix_elements[$#elements]; |
| 5249 | } |
| 5250 | |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5251 | if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { |
| 5252 | $fixed[$fixlinenr] = $fixed_line; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5253 | } |
| 5254 | |
| 5255 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5256 | } |
| 5257 | |
Joe Perches | 786b632 | 2013-07-03 15:05:32 -0700 | [diff] [blame] | 5258 | # check for whitespace before a non-naked semicolon |
Joe Perches | d2e248e | 2014-01-23 15:54:41 -0800 | [diff] [blame] | 5259 | if ($line =~ /^\+.*\S\s+;\s*$/) { |
Joe Perches | 786b632 | 2013-07-03 15:05:32 -0700 | [diff] [blame] | 5260 | if (WARN("SPACING", |
| 5261 | "space prohibited before semicolon\n" . $herecurr) && |
| 5262 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5263 | 1 while $fixed[$fixlinenr] =~ |
Joe Perches | 786b632 | 2013-07-03 15:05:32 -0700 | [diff] [blame] | 5264 | s/^(\+.*\S)\s+;/$1;/; |
| 5265 | } |
| 5266 | } |
| 5267 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5268 | # check for multiple assignments |
| 5269 | if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5270 | CHK("MULTIPLE_ASSIGNMENTS", |
| 5271 | "multiple assignments should be avoided\n" . $herecurr); |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5272 | } |
| 5273 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5274 | ## # check for multiple declarations, allowing for a function declaration |
| 5275 | ## # continuation. |
| 5276 | ## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && |
| 5277 | ## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { |
| 5278 | ## |
| 5279 | ## # Remove any bracketed sections to ensure we do not |
Dwaipayan Ray | e73d271 | 2020-12-15 20:44:56 -0800 | [diff] [blame] | 5280 | ## # falsely report the parameters of functions. |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5281 | ## my $ln = $line; |
| 5282 | ## while ($ln =~ s/\([^\(\)]*\)//g) { |
| 5283 | ## } |
| 5284 | ## if ($ln =~ /,/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5285 | ## WARN("MULTIPLE_DECLARATION", |
| 5286 | ## "declaring multiple variables together should be avoided\n" . $herecurr); |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5287 | ## } |
| 5288 | ## } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5289 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5290 | #need space before brace following if, while, etc |
Geyslan G. Bem | 6b8c69e | 2016-03-15 14:58:09 -0700 | [diff] [blame] | 5291 | if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || |
Michal Zylowski | 6ad724e | 2018-08-21 21:58:08 -0700 | [diff] [blame] | 5292 | $line =~ /\b(?:else|do)\{/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5293 | if (ERROR("SPACING", |
| 5294 | "space required before the open brace '{'\n" . $herecurr) && |
| 5295 | $fix) { |
Michal Zylowski | 6ad724e | 2018-08-21 21:58:08 -0700 | [diff] [blame] | 5296 | $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5297 | } |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5298 | } |
| 5299 | |
Joe Perches | c4a62ef | 2013-07-03 15:05:28 -0700 | [diff] [blame] | 5300 | ## # check for blank lines before declarations |
| 5301 | ## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && |
| 5302 | ## $prevrawline =~ /^.\s*$/) { |
| 5303 | ## WARN("SPACING", |
| 5304 | ## "No blank lines before declarations\n" . $hereprev); |
| 5305 | ## } |
| 5306 | ## |
| 5307 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5308 | # closing brace should have a space following it when it has anything |
| 5309 | # on the line |
Joe Perches | 94fb984 | 2019-09-25 16:46:47 -0700 | [diff] [blame] | 5310 | if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5311 | if (ERROR("SPACING", |
| 5312 | "space required after that close brace '}'\n" . $herecurr) && |
| 5313 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5314 | $fixed[$fixlinenr] =~ |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5315 | s/}((?!(?:,|;|\)))\S)/} $1/; |
| 5316 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5317 | } |
| 5318 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5319 | # check spacing on square brackets |
| 5320 | if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5321 | if (ERROR("SPACING", |
| 5322 | "space prohibited after that open square bracket '['\n" . $herecurr) && |
| 5323 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5324 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5325 | s/\[\s+/\[/; |
| 5326 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5327 | } |
| 5328 | if ($line =~ /\s\]/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5329 | if (ERROR("SPACING", |
| 5330 | "space prohibited before that close square bracket ']'\n" . $herecurr) && |
| 5331 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5332 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5333 | s/\s+\]/\]/; |
| 5334 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5335 | } |
| 5336 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5337 | # check spacing on parentheses |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 5338 | if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && |
| 5339 | $line !~ /for\s*\(\s+;/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5340 | if (ERROR("SPACING", |
| 5341 | "space prohibited after that open parenthesis '('\n" . $herecurr) && |
| 5342 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5343 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5344 | s/\(\s+/\(/; |
| 5345 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5346 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5347 | if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5348 | $line !~ /for\s*\(.*;\s+\)/ && |
| 5349 | $line !~ /:\s+\)/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5350 | if (ERROR("SPACING", |
| 5351 | "space prohibited before that close parenthesis ')'\n" . $herecurr) && |
| 5352 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5353 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5354 | s/\s+\)/\)/; |
| 5355 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5356 | } |
| 5357 | |
Joe Perches | e2826fd | 2014-08-06 16:10:48 -0700 | [diff] [blame] | 5358 | # check unnecessary parentheses around addressof/dereference single $Lvals |
| 5359 | # ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar |
| 5360 | |
| 5361 | while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { |
Joe Perches | ea4acbb | 2014-12-10 15:51:51 -0800 | [diff] [blame] | 5362 | my $var = $1; |
| 5363 | if (CHK("UNNECESSARY_PARENTHESES", |
| 5364 | "Unnecessary parentheses around $var\n" . $herecurr) && |
| 5365 | $fix) { |
| 5366 | $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; |
| 5367 | } |
| 5368 | } |
| 5369 | |
| 5370 | # check for unnecessary parentheses around function pointer uses |
| 5371 | # ie: (foo->bar)(); should be foo->bar(); |
| 5372 | # but not "if (foo->bar) (" to avoid some false positives |
| 5373 | if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { |
| 5374 | my $var = $2; |
| 5375 | if (CHK("UNNECESSARY_PARENTHESES", |
| 5376 | "Unnecessary parentheses around function pointer $var\n" . $herecurr) && |
| 5377 | $fix) { |
| 5378 | my $var2 = deparenthesize($var); |
| 5379 | $var2 =~ s/\s//g; |
| 5380 | $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; |
| 5381 | } |
| 5382 | } |
Joe Perches | e2826fd | 2014-08-06 16:10:48 -0700 | [diff] [blame] | 5383 | |
Joe Perches | 63b7c73 | 2017-09-08 16:16:01 -0700 | [diff] [blame] | 5384 | # check for unnecessary parentheses around comparisons in if uses |
Joe Perches | a032aa4 | 2018-02-06 15:39:03 -0800 | [diff] [blame] | 5385 | # when !drivers/staging or command-line uses --strict |
| 5386 | if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 5387 | $perl_version_ok && defined($stat) && |
Joe Perches | 63b7c73 | 2017-09-08 16:16:01 -0700 | [diff] [blame] | 5388 | $stat =~ /(^.\s*if\s*($balanced_parens))/) { |
| 5389 | my $if_stat = $1; |
| 5390 | my $test = substr($2, 1, -1); |
| 5391 | my $herectx; |
| 5392 | while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { |
| 5393 | my $match = $1; |
| 5394 | # avoid parentheses around potential macro args |
| 5395 | next if ($match =~ /^\s*\w+\s*$/); |
| 5396 | if (!defined($herectx)) { |
| 5397 | $herectx = $here . "\n"; |
| 5398 | my $cnt = statement_rawlines($if_stat); |
| 5399 | for (my $n = 0; $n < $cnt; $n++) { |
| 5400 | my $rl = raw_line($linenr, $n); |
| 5401 | $herectx .= $rl . "\n"; |
| 5402 | last if $rl =~ /^[ \+].*\{/; |
| 5403 | } |
| 5404 | } |
| 5405 | CHK("UNNECESSARY_PARENTHESES", |
| 5406 | "Unnecessary parentheses around '$match'\n" . $herectx); |
| 5407 | } |
| 5408 | } |
| 5409 | |
Joe Perches | 6907865 | 2021-06-30 18:56:22 -0700 | [diff] [blame] | 5410 | # check that goto labels aren't indented (allow a single space indentation) |
| 5411 | # and ignore bitfield definitions like foo:1 |
| 5412 | # Strictly, labels can have whitespace after the identifier and before the : |
| 5413 | # but this is not allowed here as many ?: uses would appear to be labels |
| 5414 | if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ && |
| 5415 | $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ && |
| 5416 | $sline !~ /^.\s+default:/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5417 | if (WARN("INDENTED_LABEL", |
| 5418 | "labels should not be indented\n" . $herecurr) && |
| 5419 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5420 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5421 | s/^(.)\s+/$1/; |
| 5422 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5423 | } |
| 5424 | |
Joe Perches | 40873ab | 2020-10-15 20:11:56 -0700 | [diff] [blame] | 5425 | # check if a statement with a comma should be two statements like: |
| 5426 | # foo = bar(), /* comma should be semicolon */ |
| 5427 | # bar = baz(); |
| 5428 | if (defined($stat) && |
| 5429 | $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { |
| 5430 | my $cnt = statement_rawlines($stat); |
| 5431 | my $herectx = get_stat_here($linenr, $cnt, $here); |
| 5432 | WARN("SUSPECT_COMMA_SEMICOLON", |
| 5433 | "Possible comma where semicolon could be used\n" . $herectx); |
| 5434 | } |
| 5435 | |
Joe Perches | 5b9553a | 2014-04-03 14:49:21 -0700 | [diff] [blame] | 5436 | # return is not a function |
Joe Perches | 507e514 | 2013-11-12 15:10:13 -0800 | [diff] [blame] | 5437 | if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5438 | my $spacing = $1; |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 5439 | if ($perl_version_ok && |
Joe Perches | 5b9553a | 2014-04-03 14:49:21 -0700 | [diff] [blame] | 5440 | $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { |
| 5441 | my $value = $1; |
| 5442 | $value = deparenthesize($value); |
| 5443 | if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { |
| 5444 | ERROR("RETURN_PARENTHESES", |
| 5445 | "return is not a function, parentheses are not required\n" . $herecurr); |
| 5446 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5447 | } elsif ($spacing !~ /\s+/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5448 | ERROR("SPACING", |
| 5449 | "space required before the open parenthesis '('\n" . $herecurr); |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5450 | } |
| 5451 | } |
Joe Perches | 507e514 | 2013-11-12 15:10:13 -0800 | [diff] [blame] | 5452 | |
Joe Perches | b43ae21 | 2014-06-23 13:22:07 -0700 | [diff] [blame] | 5453 | # unnecessary return in a void function |
| 5454 | # at end-of-function, with the previous line a single leading tab, then return; |
| 5455 | # and the line before that not a goto label target like "out:" |
| 5456 | if ($sline =~ /^[ \+]}\s*$/ && |
| 5457 | $prevline =~ /^\+\treturn\s*;\s*$/ && |
| 5458 | $linenr >= 3 && |
| 5459 | $lines[$linenr - 3] =~ /^[ +]/ && |
| 5460 | $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { |
Joe Perches | 9819cf2 | 2014-06-04 16:12:09 -0700 | [diff] [blame] | 5461 | WARN("RETURN_VOID", |
Joe Perches | b43ae21 | 2014-06-23 13:22:07 -0700 | [diff] [blame] | 5462 | "void function return statements are not generally useful\n" . $hereprev); |
Dwaipayan Ray | ea7dbab | 2021-02-25 17:21:47 -0800 | [diff] [blame] | 5463 | } |
Joe Perches | 9819cf2 | 2014-06-04 16:12:09 -0700 | [diff] [blame] | 5464 | |
Joe Perches | 189248d | 2014-01-23 15:54:47 -0800 | [diff] [blame] | 5465 | # if statements using unnecessary parentheses - ie: if ((foo == bar)) |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 5466 | if ($perl_version_ok && |
Joe Perches | 189248d | 2014-01-23 15:54:47 -0800 | [diff] [blame] | 5467 | $line =~ /\bif\s*((?:\(\s*){2,})/) { |
| 5468 | my $openparens = $1; |
| 5469 | my $count = $openparens =~ tr@\(@\(@; |
| 5470 | my $msg = ""; |
| 5471 | if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { |
| 5472 | my $comp = $4; #Not $1 because of $LvalOrFunc |
| 5473 | $msg = " - maybe == should be = ?" if ($comp eq "=="); |
| 5474 | WARN("UNNECESSARY_PARENTHESES", |
| 5475 | "Unnecessary parentheses$msg\n" . $herecurr); |
| 5476 | } |
| 5477 | } |
| 5478 | |
Joe Perches | c5595fa | 2015-09-09 15:37:58 -0700 | [diff] [blame] | 5479 | # comparisons with a constant or upper case identifier on the left |
| 5480 | # avoid cases like "foo + BAR < baz" |
| 5481 | # only fix matches surrounded by parentheses to avoid incorrect |
| 5482 | # conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 5483 | if ($perl_version_ok && |
Joe Perches | c5595fa | 2015-09-09 15:37:58 -0700 | [diff] [blame] | 5484 | $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { |
| 5485 | my $lead = $1; |
| 5486 | my $const = $2; |
| 5487 | my $comp = $3; |
| 5488 | my $to = $4; |
| 5489 | my $newcomp = $comp; |
Joe Perches | f39e176 | 2016-05-20 17:04:02 -0700 | [diff] [blame] | 5490 | if ($lead !~ /(?:$Operators|\.)\s*$/ && |
Joe Perches | c5595fa | 2015-09-09 15:37:58 -0700 | [diff] [blame] | 5491 | $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && |
| 5492 | WARN("CONSTANT_COMPARISON", |
| 5493 | "Comparisons should place the constant on the right side of the test\n" . $herecurr) && |
| 5494 | $fix) { |
| 5495 | if ($comp eq "<") { |
| 5496 | $newcomp = ">"; |
| 5497 | } elsif ($comp eq "<=") { |
| 5498 | $newcomp = ">="; |
| 5499 | } elsif ($comp eq ">") { |
| 5500 | $newcomp = "<"; |
| 5501 | } elsif ($comp eq ">=") { |
| 5502 | $newcomp = "<="; |
| 5503 | } |
| 5504 | $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; |
| 5505 | } |
| 5506 | } |
| 5507 | |
Joe Perches | f34e4a4 | 2015-04-16 12:44:19 -0700 | [diff] [blame] | 5508 | # Return of what appears to be an errno should normally be negative |
| 5509 | if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { |
Andy Whitcroft | 53a3c44 | 2010-10-26 14:23:14 -0700 | [diff] [blame] | 5510 | my $name = $1; |
Guenter Roeck | 46b85bf | 2021-06-30 18:56:25 -0700 | [diff] [blame] | 5511 | if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5512 | WARN("USE_NEGATIVE_ERRNO", |
Joe Perches | f34e4a4 | 2015-04-16 12:44:19 -0700 | [diff] [blame] | 5513 | "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); |
Andy Whitcroft | 53a3c44 | 2010-10-26 14:23:14 -0700 | [diff] [blame] | 5514 | } |
| 5515 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5516 | |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5517 | # Need a space before open parenthesis after if, while etc |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5518 | if ($line =~ /\b(if|while|for|switch)\(/) { |
| 5519 | if (ERROR("SPACING", |
| 5520 | "space required before the open parenthesis '('\n" . $herecurr) && |
| 5521 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5522 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5523 | s/\b(if|while|for|switch)\(/$1 \(/; |
| 5524 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5525 | } |
| 5526 | |
Andy Whitcroft | f5fe35d | 2008-07-23 21:29:03 -0700 | [diff] [blame] | 5527 | # Check for illegal assignment in if conditional -- and check for trailing |
| 5528 | # statements after the conditional. |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 5529 | if ($line =~ /do\s*(?!{)/) { |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 5530 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
| 5531 | ctx_statement_block($linenr, $realcnt, 0) |
| 5532 | if (!defined $stat); |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 5533 | my ($stat_next) = ctx_statement_block($line_nr_next, |
| 5534 | $remain_next, $off_next); |
| 5535 | $stat_next =~ s/\n./\n /g; |
| 5536 | ##print "stat<$stat> stat_next<$stat_next>\n"; |
| 5537 | |
| 5538 | if ($stat_next =~ /^\s*while\b/) { |
| 5539 | # If the statement carries leading newlines, |
| 5540 | # then count those as offsets. |
| 5541 | my ($whitespace) = |
| 5542 | ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); |
| 5543 | my $offset = |
| 5544 | statement_rawlines($whitespace) - 1; |
| 5545 | |
| 5546 | $suppress_whiletrailers{$line_nr_next + |
| 5547 | $offset} = 1; |
| 5548 | } |
| 5549 | } |
| 5550 | if (!defined $suppress_whiletrailers{$linenr} && |
Joe Perches | c11230f | 2013-11-21 14:31:57 -0800 | [diff] [blame] | 5551 | defined($stat) && defined($cond) && |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 5552 | $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 5553 | my ($s, $c) = ($stat, $cond); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 5554 | |
Andy Whitcroft | b53c8e1 | 2009-01-06 14:41:29 -0800 | [diff] [blame] | 5555 | if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { |
Joe Perches | 65b64b3 | 2020-08-11 18:35:10 -0700 | [diff] [blame] | 5556 | if (ERROR("ASSIGN_IN_IF", |
| 5557 | "do not use assignment in if condition\n" . $herecurr) && |
| 5558 | $fix && $perl_version_ok) { |
| 5559 | if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { |
| 5560 | my $space = $1; |
| 5561 | my $not = $2; |
| 5562 | my $statement = $3; |
| 5563 | my $assigned = $4; |
| 5564 | my $test = $8; |
| 5565 | my $against = $9; |
| 5566 | my $brace = $15; |
| 5567 | fix_delete_line($fixlinenr, $rawline); |
| 5568 | fix_insert_line($fixlinenr, "$space$statement;"); |
| 5569 | my $newline = "${space}if ("; |
| 5570 | $newline .= '!' if defined($not); |
| 5571 | $newline .= '(' if (defined $not && defined($test) && defined($against)); |
| 5572 | $newline .= "$assigned"; |
| 5573 | $newline .= " $test $against" if (defined($test) && defined($against)); |
| 5574 | $newline .= ')' if (defined $not && defined($test) && defined($against)); |
| 5575 | $newline .= ')'; |
| 5576 | $newline .= " {" if (defined($brace)); |
| 5577 | fix_insert_line($fixlinenr + 1, $newline); |
| 5578 | } |
| 5579 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 5580 | } |
| 5581 | |
| 5582 | # Find out what is on the end of the line after the |
| 5583 | # conditional. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5584 | substr($s, 0, length($c), ''); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 5585 | $s =~ s/\n.*//g; |
Antonio Borneo | 342d3d2 | 2020-04-06 20:11:01 -0700 | [diff] [blame] | 5586 | $s =~ s/$;//g; # Remove any comments |
Andy Whitcroft | 5321016 | 2008-07-23 21:29:03 -0700 | [diff] [blame] | 5587 | if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && |
| 5588 | $c !~ /}\s*while\s*/) |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5589 | { |
Andy Whitcroft | bb44ad3 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 5590 | # Find out how long the conditional actually is. |
| 5591 | my @newlines = ($c =~ /\n/gs); |
| 5592 | my $cond_lines = 1 + $#newlines; |
Hidetoshi Seto | 42bdf74 | 2010-03-05 13:43:50 -0800 | [diff] [blame] | 5593 | my $stat_real = ''; |
Andy Whitcroft | bb44ad3 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 5594 | |
Hidetoshi Seto | 42bdf74 | 2010-03-05 13:43:50 -0800 | [diff] [blame] | 5595 | $stat_real = raw_line($linenr, $cond_lines) |
| 5596 | . "\n" if ($cond_lines); |
Andy Whitcroft | bb44ad3 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 5597 | if (defined($stat_real) && $cond_lines > 1) { |
| 5598 | $stat_real = "[...]\n$stat_real"; |
| 5599 | } |
| 5600 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5601 | ERROR("TRAILING_STATEMENTS", |
| 5602 | "trailing statements should be on next line\n" . $herecurr . $stat_real); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 5603 | } |
| 5604 | } |
| 5605 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5606 | # Check for bitwise tests written as boolean |
| 5607 | if ($line =~ / |
| 5608 | (?: |
| 5609 | (?:\[|\(|\&\&|\|\|) |
| 5610 | \s*0[xX][0-9]+\s* |
| 5611 | (?:\&\&|\|\|) |
| 5612 | | |
| 5613 | (?:\&\&|\|\|) |
| 5614 | \s*0[xX][0-9]+\s* |
| 5615 | (?:\&\&|\|\||\)|\]) |
| 5616 | )/x) |
| 5617 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5618 | WARN("HEXADECIMAL_BOOLEAN_TEST", |
| 5619 | "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5620 | } |
| 5621 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 5622 | # if and else should not have general statements after it |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5623 | if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { |
| 5624 | my $s = $1; |
Antonio Borneo | 342d3d2 | 2020-04-06 20:11:01 -0700 | [diff] [blame] | 5625 | $s =~ s/$;//g; # Remove any comments |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5626 | if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5627 | ERROR("TRAILING_STATEMENTS", |
| 5628 | "trailing statements should be on next line\n" . $herecurr); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5629 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5630 | } |
Andy Whitcroft | 3966778 | 2009-01-15 13:51:06 -0800 | [diff] [blame] | 5631 | # if should not continue a brace |
| 5632 | if ($line =~ /}\s*if\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5633 | ERROR("TRAILING_STATEMENTS", |
Rasmus Villemoes | 048b123 | 2014-08-06 16:10:37 -0700 | [diff] [blame] | 5634 | "trailing statements should be on next line (or did you mean 'else if'?)\n" . |
Andy Whitcroft | 3966778 | 2009-01-15 13:51:06 -0800 | [diff] [blame] | 5635 | $herecurr); |
| 5636 | } |
Andy Whitcroft | a1080bf | 2008-10-15 22:02:25 -0700 | [diff] [blame] | 5637 | # case and default should not have general statements after them |
| 5638 | if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && |
| 5639 | $line !~ /\G(?: |
Andy Whitcroft | 3fef12d | 2008-10-15 22:02:36 -0700 | [diff] [blame] | 5640 | (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| |
Andy Whitcroft | a1080bf | 2008-10-15 22:02:25 -0700 | [diff] [blame] | 5641 | \s*return\s+ |
| 5642 | )/xg) |
| 5643 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5644 | ERROR("TRAILING_STATEMENTS", |
| 5645 | "trailing statements should be on next line\n" . $herecurr); |
Andy Whitcroft | a1080bf | 2008-10-15 22:02:25 -0700 | [diff] [blame] | 5646 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5647 | |
| 5648 | # Check for }<nl>else {, these must be at the same |
| 5649 | # indent level to be relevant to each other. |
Joe Perches | 8b8856f | 2014-08-06 16:11:14 -0700 | [diff] [blame] | 5650 | if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && |
| 5651 | $previndent == $indent) { |
| 5652 | if (ERROR("ELSE_AFTER_BRACE", |
| 5653 | "else 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 | $fixedline =~ s/}\s*$//; |
| 5659 | if ($fixedline !~ /^\+\s*$/) { |
| 5660 | fix_insert_line($fixlinenr, $fixedline); |
| 5661 | } |
| 5662 | $fixedline = $rawline; |
| 5663 | $fixedline =~ s/^(.\s*)else/$1} else/; |
| 5664 | fix_insert_line($fixlinenr, $fixedline); |
| 5665 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5666 | } |
| 5667 | |
Joe Perches | 8b8856f | 2014-08-06 16:11:14 -0700 | [diff] [blame] | 5668 | if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && |
| 5669 | $previndent == $indent) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 5670 | my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); |
| 5671 | |
| 5672 | # Find out what is on the end of the line after the |
| 5673 | # conditional. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5674 | substr($s, 0, length($c), ''); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 5675 | $s =~ s/\n.*//g; |
| 5676 | |
| 5677 | if ($s =~ /^\s*;/) { |
Joe Perches | 8b8856f | 2014-08-06 16:11:14 -0700 | [diff] [blame] | 5678 | if (ERROR("WHILE_AFTER_BRACE", |
| 5679 | "while should follow close brace '}'\n" . $hereprev) && |
| 5680 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { |
| 5681 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 5682 | fix_delete_line($fixlinenr, $rawline); |
| 5683 | my $fixedline = $prevrawline; |
| 5684 | my $trailing = $rawline; |
| 5685 | $trailing =~ s/^\+//; |
| 5686 | $trailing = trim($trailing); |
| 5687 | $fixedline =~ s/}\s*$/} $trailing/; |
| 5688 | fix_insert_line($fixlinenr, $fixedline); |
| 5689 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 5690 | } |
| 5691 | } |
| 5692 | |
Joe Perches | 95e2c60 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 5693 | #Specific variable tests |
Joe Perches | 323c126 | 2012-12-17 16:02:07 -0800 | [diff] [blame] | 5694 | while ($line =~ m{($Constant|$Lval)}g) { |
| 5695 | my $var = $1; |
Joe Perches | 95e2c60 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 5696 | |
Joe Perches | 95e2c60 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 5697 | #CamelCase |
Joe Perches | 807bd26 | 2013-07-03 15:05:22 -0700 | [diff] [blame] | 5698 | if ($var !~ /^$Constant$/ && |
Joe Perches | be79794 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 5699 | $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && |
Łukasz Stelmach | 4104a20 | 2020-12-15 20:44:27 -0800 | [diff] [blame] | 5700 | #Ignore some autogenerated defines and enum values |
| 5701 | $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && |
Joe Perches | 22735ce | 2013-07-03 15:05:33 -0700 | [diff] [blame] | 5702 | #Ignore Page<foo> variants |
Joe Perches | 807bd26 | 2013-07-03 15:05:22 -0700 | [diff] [blame] | 5703 | $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && |
Joe Perches | d439e6a | 2019-12-04 16:52:06 -0800 | [diff] [blame] | 5704 | #Ignore SI style variants like nS, mV and dB |
| 5705 | #(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) |
| 5706 | $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && |
Julius Werner | f512357 | 2014-12-10 15:51:54 -0800 | [diff] [blame] | 5707 | #Ignore some three character SI units explicitly, like MiB and KHz |
| 5708 | $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { |
Joe Perches | 7e781f6 | 2013-09-11 14:23:55 -0700 | [diff] [blame] | 5709 | while ($var =~ m{($Ident)}g) { |
| 5710 | my $word = $1; |
| 5711 | next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); |
Joe Perches | d8b0771 | 2013-11-12 15:10:06 -0800 | [diff] [blame] | 5712 | if ($check) { |
| 5713 | seed_camelcase_includes(); |
| 5714 | if (!$file && !$camelcase_file_seeded) { |
| 5715 | seed_camelcase_file($realfile); |
| 5716 | $camelcase_file_seeded = 1; |
| 5717 | } |
| 5718 | } |
Joe Perches | 7e781f6 | 2013-09-11 14:23:55 -0700 | [diff] [blame] | 5719 | if (!defined $camelcase{$word}) { |
| 5720 | $camelcase{$word} = 1; |
| 5721 | CHK("CAMELCASE", |
| 5722 | "Avoid CamelCase: <$word>\n" . $herecurr); |
| 5723 | } |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 5724 | } |
Joe Perches | 323c126 | 2012-12-17 16:02:07 -0800 | [diff] [blame] | 5725 | } |
| 5726 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5727 | |
| 5728 | #no spaces allowed after \ in define |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5729 | if ($line =~ /\#\s*define.*\\\s+$/) { |
| 5730 | if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", |
| 5731 | "Whitespace after \\ makes next lines useless\n" . $herecurr) && |
| 5732 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5733 | $fixed[$fixlinenr] =~ s/\s+$//; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5734 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5735 | } |
| 5736 | |
Fabian Frederick | 0e212e0 | 2015-04-16 12:44:25 -0700 | [diff] [blame] | 5737 | # warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes |
| 5738 | # itself <asm/foo.h> (uses RAW line) |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5739 | if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { |
Andy Whitcroft | e09dec4 | 2008-10-15 22:02:20 -0700 | [diff] [blame] | 5740 | my $file = "$1.h"; |
| 5741 | my $checkfile = "include/linux/$file"; |
| 5742 | if (-f "$root/$checkfile" && |
| 5743 | $realfile ne $checkfile && |
Wolfram Sang | 7840a94 | 2010-08-09 17:20:57 -0700 | [diff] [blame] | 5744 | $1 !~ /$allowed_asm_includes/) |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5745 | { |
Fabian Frederick | 0e212e0 | 2015-04-16 12:44:25 -0700 | [diff] [blame] | 5746 | my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; |
| 5747 | if ($asminclude > 0) { |
| 5748 | if ($realfile =~ m{^arch/}) { |
| 5749 | CHK("ARCH_INCLUDE_LINUX", |
| 5750 | "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); |
| 5751 | } else { |
| 5752 | WARN("INCLUDE_LINUX", |
| 5753 | "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); |
| 5754 | } |
Andy Whitcroft | e09dec4 | 2008-10-15 22:02:20 -0700 | [diff] [blame] | 5755 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5756 | } |
| 5757 | } |
| 5758 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 5759 | # multi-statement macros should be enclosed in a do while loop, grab the |
| 5760 | # first statement and ensure its the whole macro if its not enclosed |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5761 | # in a known good container |
Andy Whitcroft | b8f96a31 | 2008-07-23 21:29:07 -0700 | [diff] [blame] | 5762 | if ($realfile !~ m@/vmlinux.lds.h$@ && |
| 5763 | $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 5764 | my $ln = $linenr; |
| 5765 | my $cnt = $realcnt; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5766 | my ($off, $dstat, $dcond, $rest); |
| 5767 | my $ctx = ''; |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 5768 | my $has_flow_statement = 0; |
| 5769 | my $has_arg_concat = 0; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5770 | ($dstat, $dcond, $ln, $cnt, $off) = |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 5771 | ctx_statement_block($linenr, $realcnt, 0); |
| 5772 | $ctx = $dstat; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5773 | #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; |
Andy Whitcroft | a3bb97a | 2008-07-23 21:29:00 -0700 | [diff] [blame] | 5774 | #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5775 | |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 5776 | $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); |
Joe Perches | 62e15a6 | 2016-01-20 14:59:18 -0800 | [diff] [blame] | 5777 | $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 5778 | |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5779 | $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; |
| 5780 | my $define_args = $1; |
| 5781 | my $define_stmt = $dstat; |
| 5782 | my @def_args = (); |
| 5783 | |
| 5784 | if (defined $define_args && $define_args ne "") { |
| 5785 | $define_args = substr($define_args, 1, length($define_args) - 2); |
| 5786 | $define_args =~ s/\s*//g; |
Joe Perches | 8c8c45c | 2018-08-21 21:57:43 -0700 | [diff] [blame] | 5787 | $define_args =~ s/\\\+?//g; |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5788 | @def_args = split(",", $define_args); |
| 5789 | } |
| 5790 | |
Andy Whitcroft | 292f1a9 | 2008-07-23 21:29:11 -0700 | [diff] [blame] | 5791 | $dstat =~ s/$;//g; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5792 | $dstat =~ s/\\\n.//g; |
| 5793 | $dstat =~ s/^\s*//s; |
| 5794 | $dstat =~ s/\s*$//s; |
| 5795 | |
| 5796 | # Flatten any parentheses and braces |
Dwaipayan Ray | 2e44e80 | 2020-10-15 20:12:22 -0700 | [diff] [blame] | 5797 | while ($dstat =~ s/\([^\(\)]*\)/1u/ || |
| 5798 | $dstat =~ s/\{[^\{\}]*\}/1u/ || |
| 5799 | $dstat =~ s/.\[[^\[\]]*\]/1u/) |
Andy Whitcroft | bf30d6e | 2008-10-15 22:02:33 -0700 | [diff] [blame] | 5800 | { |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5801 | } |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 5802 | |
Antonio Borneo | 342d3d2 | 2020-04-06 20:11:01 -0700 | [diff] [blame] | 5803 | # Flatten any obvious string concatenation. |
Joe Perches | 33acb54 | 2015-06-25 15:02:54 -0700 | [diff] [blame] | 5804 | while ($dstat =~ s/($String)\s*$Ident/$1/ || |
| 5805 | $dstat =~ s/$Ident\s*($String)/$1/) |
Andy Whitcroft | e45bab8 | 2012-03-23 15:02:18 -0700 | [diff] [blame] | 5806 | { |
| 5807 | } |
| 5808 | |
Joe Perches | 42e1529 | 2016-03-15 14:58:01 -0700 | [diff] [blame] | 5809 | # Make asm volatile uses seem like a generic function |
| 5810 | $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; |
| 5811 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5812 | my $exceptions = qr{ |
| 5813 | $Declare| |
| 5814 | module_param_named| |
Kees Cook | a0a0a7a | 2012-10-04 17:13:38 -0700 | [diff] [blame] | 5815 | MODULE_PARM_DESC| |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5816 | DECLARE_PER_CPU| |
| 5817 | DEFINE_PER_CPU| |
Andy Whitcroft | 383099f | 2009-01-06 14:41:18 -0800 | [diff] [blame] | 5818 | __typeof__\(| |
Stefani Seibold | 22fd2d3 | 2010-03-05 13:43:52 -0800 | [diff] [blame] | 5819 | union| |
| 5820 | struct| |
Andy Whitcroft | ea71a0a | 2009-09-21 17:04:38 -0700 | [diff] [blame] | 5821 | \.$Ident\s*=\s*| |
Vladimir Zapolskiy | 6b10df4 | 2016-01-20 14:59:21 -0800 | [diff] [blame] | 5822 | ^\"|\"$| |
| 5823 | ^\[ |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5824 | }x; |
Andy Whitcroft | 5eaa20b | 2010-10-26 14:23:18 -0700 | [diff] [blame] | 5825 | #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5826 | |
| 5827 | $ctx =~ s/\n*$//; |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5828 | my $stmt_cnt = statement_rawlines($ctx); |
Tobin C. Harding | e3d95a2 | 2018-04-10 16:33:27 -0700 | [diff] [blame] | 5829 | my $herectx = get_stat_here($linenr, $stmt_cnt, $here); |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5830 | |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 5831 | if ($dstat ne '' && |
| 5832 | $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), |
| 5833 | $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); |
Joe Perches | 3cc4b1c | 2013-07-03 15:05:27 -0700 | [diff] [blame] | 5834 | $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz |
Joe Perches | 356fd39 | 2014-08-06 16:10:31 -0700 | [diff] [blame] | 5835 | $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 5836 | $dstat !~ /$exceptions/ && |
| 5837 | $dstat !~ /^\.$Ident\s*=/ && # .foo = |
Joe Perches | e942e2c | 2013-04-17 15:58:26 -0700 | [diff] [blame] | 5838 | $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo |
Andy Whitcroft | 72f115f | 2012-01-10 15:10:06 -0800 | [diff] [blame] | 5839 | $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) |
Dwaipayan Ray | 2e44e80 | 2020-10-15 20:12:22 -0700 | [diff] [blame] | 5840 | $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 5841 | $dstat !~ /^for\s*$Constant$/ && # for (...) |
| 5842 | $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() |
| 5843 | $dstat !~ /^do\s*{/ && # do {... |
Eddie Kovsky | 4e5d56b | 2015-09-09 15:37:52 -0700 | [diff] [blame] | 5844 | $dstat !~ /^\(\{/ && # ({... |
Joe Perches | f95a7e6 | 2013-09-11 14:24:00 -0700 | [diff] [blame] | 5845 | $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 5846 | { |
Joe Perches | e795556 | 2017-05-08 15:55:48 -0700 | [diff] [blame] | 5847 | if ($dstat =~ /^\s*if\b/) { |
| 5848 | ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", |
| 5849 | "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); |
| 5850 | } elsif ($dstat =~ /;/) { |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 5851 | ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", |
| 5852 | "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); |
| 5853 | } else { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5854 | ERROR("COMPLEX_MACRO", |
Andrew Morton | 388982b | 2014-10-13 15:51:40 -0700 | [diff] [blame] | 5855 | "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 5856 | } |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5857 | |
| 5858 | } |
Joe Perches | 5207649 | 2016-10-11 13:52:14 -0700 | [diff] [blame] | 5859 | |
| 5860 | # Make $define_stmt single line, comment-free, etc |
| 5861 | my @stmt_array = split('\n', $define_stmt); |
| 5862 | my $first = 1; |
| 5863 | $define_stmt = ""; |
| 5864 | foreach my $l (@stmt_array) { |
| 5865 | $l =~ s/\\$//; |
| 5866 | if ($first) { |
| 5867 | $define_stmt = $l; |
| 5868 | $first = 0; |
| 5869 | } elsif ($l =~ /^[\+ ]/) { |
| 5870 | $define_stmt .= substr($l, 1); |
| 5871 | } |
| 5872 | } |
| 5873 | $define_stmt =~ s/$;//g; |
| 5874 | $define_stmt =~ s/\s+/ /g; |
| 5875 | $define_stmt = trim($define_stmt); |
| 5876 | |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5877 | # check if any macro arguments are reused (ignore '...' and 'type') |
| 5878 | foreach my $arg (@def_args) { |
| 5879 | next if ($arg =~ /\.\.\./); |
Joe Perches | 9192d41 | 2016-10-11 13:52:11 -0700 | [diff] [blame] | 5880 | next if ($arg =~ /^type$/i); |
Joe Perches | 7fe528a2 | 2017-07-10 15:52:27 -0700 | [diff] [blame] | 5881 | my $tmp_stmt = $define_stmt; |
Vincent Mailhol | 7b84434 | 2021-05-06 18:03:58 -0700 | [diff] [blame] | 5882 | $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 Perches | 7fe528a2 | 2017-07-10 15:52:27 -0700 | [diff] [blame] | 5883 | $tmp_stmt =~ s/\#+\s*$arg\b//g; |
| 5884 | $tmp_stmt =~ s/\b$arg\s*\#\#//g; |
Joe Perches | d41362e | 2018-05-25 14:48:04 -0700 | [diff] [blame] | 5885 | my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5886 | if ($use_cnt > 1) { |
| 5887 | CHK("MACRO_ARG_REUSE", |
| 5888 | "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); |
Joe Perches | 9192d41 | 2016-10-11 13:52:11 -0700 | [diff] [blame] | 5889 | } |
| 5890 | # check if any macro arguments may have other precedence issues |
Joe Perches | 7fe528a2 | 2017-07-10 15:52:27 -0700 | [diff] [blame] | 5891 | if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && |
Joe Perches | 9192d41 | 2016-10-11 13:52:11 -0700 | [diff] [blame] | 5892 | ((defined($1) && $1 ne ',') || |
| 5893 | (defined($2) && $2 ne ','))) { |
| 5894 | CHK("MACRO_ARG_PRECEDENCE", |
| 5895 | "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 5896 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 5897 | } |
Joe Perches | 5023d34 | 2012-12-17 16:01:47 -0800 | [diff] [blame] | 5898 | |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 5899 | # check for macros with flow control, but without ## concatenation |
| 5900 | # ## concatenation is commonly a macro that defines a function so ignore those |
| 5901 | if ($has_flow_statement && !$has_arg_concat) { |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 5902 | my $cnt = statement_rawlines($ctx); |
Tobin C. Harding | e3d95a2 | 2018-04-10 16:33:27 -0700 | [diff] [blame] | 5903 | my $herectx = get_stat_here($linenr, $cnt, $here); |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 5904 | |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 5905 | WARN("MACRO_WITH_FLOW_CONTROL", |
| 5906 | "Macros with flow control statements should be avoided\n" . "$herectx"); |
| 5907 | } |
| 5908 | |
Joe Perches | 481eb48 | 2012-12-17 16:01:56 -0800 | [diff] [blame] | 5909 | # check for line continuations outside of #defines, preprocessor #, and asm |
Joe Perches | 5023d34 | 2012-12-17 16:01:47 -0800 | [diff] [blame] | 5910 | |
| 5911 | } else { |
| 5912 | if ($prevline !~ /^..*\\$/ && |
Joe Perches | 481eb48 | 2012-12-17 16:01:56 -0800 | [diff] [blame] | 5913 | $line !~ /^\+\s*\#.*\\$/ && # preprocessor |
| 5914 | $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm |
Joe Perches | 5023d34 | 2012-12-17 16:01:47 -0800 | [diff] [blame] | 5915 | $line =~ /^\+.*\\$/) { |
| 5916 | WARN("LINE_CONTINUATIONS", |
| 5917 | "Avoid unnecessary line continuations\n" . $herecurr); |
| 5918 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5919 | } |
| 5920 | |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5921 | # do {} while (0) macro tests: |
| 5922 | # single-statement macros do not need to be enclosed in do while (0) loop, |
| 5923 | # macro should not end with a semicolon |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 5924 | if ($perl_version_ok && |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5925 | $realfile !~ m@/vmlinux.lds.h$@ && |
| 5926 | $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { |
| 5927 | my $ln = $linenr; |
| 5928 | my $cnt = $realcnt; |
| 5929 | my ($off, $dstat, $dcond, $rest); |
| 5930 | my $ctx = ''; |
| 5931 | ($dstat, $dcond, $ln, $cnt, $off) = |
| 5932 | ctx_statement_block($linenr, $realcnt, 0); |
| 5933 | $ctx = $dstat; |
| 5934 | |
| 5935 | $dstat =~ s/\\\n.//g; |
Joe Perches | 1b36b20 | 2015-02-13 14:38:32 -0800 | [diff] [blame] | 5936 | $dstat =~ s/$;/ /g; |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5937 | |
| 5938 | if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { |
| 5939 | my $stmts = $2; |
| 5940 | my $semis = $3; |
| 5941 | |
| 5942 | $ctx =~ s/\n*$//; |
| 5943 | my $cnt = statement_rawlines($ctx); |
Tobin C. Harding | e3d95a2 | 2018-04-10 16:33:27 -0700 | [diff] [blame] | 5944 | my $herectx = get_stat_here($linenr, $cnt, $here); |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5945 | |
Joe Perches | ac8e97f | 2012-08-21 16:15:53 -0700 | [diff] [blame] | 5946 | if (($stmts =~ tr/;/;/) == 1 && |
| 5947 | $stmts !~ /^\s*(if|while|for|switch)\b/) { |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5948 | WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", |
| 5949 | "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); |
| 5950 | } |
| 5951 | if (defined $semis && $semis ne "") { |
| 5952 | WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", |
| 5953 | "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); |
| 5954 | } |
Joe Perches | f5ef95b | 2014-06-04 16:12:06 -0700 | [diff] [blame] | 5955 | } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { |
| 5956 | $ctx =~ s/\n*$//; |
| 5957 | my $cnt = statement_rawlines($ctx); |
Tobin C. Harding | e3d95a2 | 2018-04-10 16:33:27 -0700 | [diff] [blame] | 5958 | my $herectx = get_stat_here($linenr, $cnt, $here); |
Joe Perches | f5ef95b | 2014-06-04 16:12:06 -0700 | [diff] [blame] | 5959 | |
| 5960 | WARN("TRAILING_SEMICOLON", |
| 5961 | "macros should not use a trailing semicolon\n" . "$herectx"); |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5962 | } |
| 5963 | } |
| 5964 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5965 | # check for redundant bracing round if etc |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5966 | if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { |
| 5967 | my ($level, $endln, @chunks) = |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5968 | ctx_statement_full($linenr, $realcnt, 1); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5969 | #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5970 | #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; |
| 5971 | if ($#chunks > 0 && $level == 0) { |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5972 | my @allowed = (); |
| 5973 | my $allow = 0; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5974 | my $seen = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5975 | my $herectx = $here . "\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5976 | my $ln = $linenr - 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5977 | for my $chunk (@chunks) { |
| 5978 | my ($cond, $block) = @{$chunk}; |
| 5979 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5980 | # If the condition carries leading newlines, then count those as offsets. |
| 5981 | my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); |
| 5982 | my $offset = statement_rawlines($whitespace) - 1; |
| 5983 | |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5984 | $allowed[$allow] = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5985 | #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; |
| 5986 | |
| 5987 | # We have looked at and allowed this specific line. |
| 5988 | $suppress_ifbraces{$ln + $offset} = 1; |
| 5989 | |
| 5990 | $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5991 | $ln += statement_rawlines($block) - 1; |
| 5992 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5993 | substr($block, 0, length($cond), ''); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5994 | |
| 5995 | $seen++ if ($block =~ /^\s*{/); |
| 5996 | |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5997 | #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5998 | if (statement_lines($cond) > 1) { |
| 5999 | #print "APW: ALLOWED: cond<$cond>\n"; |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 6000 | $allowed[$allow] = 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6001 | } |
| 6002 | if ($block =~/\b(?:if|for|while)\b/) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6003 | #print "APW: ALLOWED: block<$block>\n"; |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 6004 | $allowed[$allow] = 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6005 | } |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6006 | if (statement_block_size($block) > 1) { |
| 6007 | #print "APW: ALLOWED: lines block<$block>\n"; |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 6008 | $allowed[$allow] = 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6009 | } |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 6010 | $allow++; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6011 | } |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 6012 | if ($seen) { |
| 6013 | my $sum_allowed = 0; |
| 6014 | foreach (@allowed) { |
| 6015 | $sum_allowed += $_; |
| 6016 | } |
| 6017 | if ($sum_allowed == 0) { |
| 6018 | WARN("BRACES", |
| 6019 | "braces {} are not necessary for any arm of this statement\n" . $herectx); |
| 6020 | } elsif ($sum_allowed != $allow && |
| 6021 | $seen != $allow) { |
| 6022 | CHK("BRACES", |
| 6023 | "braces {} should be used on all arms of this statement\n" . $herectx); |
| 6024 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6025 | } |
| 6026 | } |
| 6027 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6028 | if (!defined $suppress_ifbraces{$linenr - 1} && |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6029 | $line =~ /\b(if|while|for|else)\b/) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6030 | my $allowed = 0; |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 6031 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6032 | # Check the pre-context. |
| 6033 | if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { |
| 6034 | #print "APW: ALLOWED: pre<$1>\n"; |
| 6035 | $allowed = 1; |
| 6036 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6037 | |
| 6038 | my ($level, $endln, @chunks) = |
| 6039 | ctx_statement_full($linenr, $realcnt, $-[0]); |
| 6040 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6041 | # Check the condition. |
| 6042 | my ($cond, $block) = @{$chunks[0]}; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6043 | #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6044 | if (defined $cond) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6045 | substr($block, 0, length($cond), ''); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6046 | } |
| 6047 | if (statement_lines($cond) > 1) { |
| 6048 | #print "APW: ALLOWED: cond<$cond>\n"; |
| 6049 | $allowed = 1; |
| 6050 | } |
| 6051 | if ($block =~/\b(?:if|for|while)\b/) { |
| 6052 | #print "APW: ALLOWED: block<$block>\n"; |
| 6053 | $allowed = 1; |
| 6054 | } |
| 6055 | if (statement_block_size($block) > 1) { |
| 6056 | #print "APW: ALLOWED: lines block<$block>\n"; |
| 6057 | $allowed = 1; |
| 6058 | } |
| 6059 | # Check the post-context. |
| 6060 | if (defined $chunks[1]) { |
| 6061 | my ($cond, $block) = @{$chunks[1]}; |
| 6062 | if (defined $cond) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6063 | substr($block, 0, length($cond), ''); |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 6064 | } |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6065 | if ($block =~ /^\s*\{/) { |
| 6066 | #print "APW: ALLOWED: chunk-1 block<$block>\n"; |
| 6067 | $allowed = 1; |
| 6068 | } |
| 6069 | } |
| 6070 | if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { |
Andy Whitcroft | f055663 | 2008-10-15 22:02:23 -0700 | [diff] [blame] | 6071 | my $cnt = statement_rawlines($block); |
Tobin C. Harding | e3d95a2 | 2018-04-10 16:33:27 -0700 | [diff] [blame] | 6072 | my $herectx = get_stat_here($linenr, $cnt, $here); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 6073 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6074 | WARN("BRACES", |
| 6075 | "braces {} are not necessary for single statement blocks\n" . $herectx); |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 6076 | } |
| 6077 | } |
| 6078 | |
Joe Perches | e4c5bab | 2017-02-24 15:01:41 -0800 | [diff] [blame] | 6079 | # check for single line unbalanced braces |
Sven Eckelmann | 9533047 | 2017-02-24 15:01:43 -0800 | [diff] [blame] | 6080 | if ($sline =~ /^.\s*\}\s*else\s*$/ || |
| 6081 | $sline =~ /^.\s*else\s*\{\s*$/) { |
Joe Perches | e4c5bab | 2017-02-24 15:01:41 -0800 | [diff] [blame] | 6082 | CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); |
| 6083 | } |
| 6084 | |
Joe Perches | 0979ae6 | 2012-12-17 16:01:59 -0800 | [diff] [blame] | 6085 | # check for unnecessary blank lines around braces |
Joe Perches | 77b9a53 | 2013-07-03 15:05:29 -0700 | [diff] [blame] | 6086 | if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { |
Joe Perches | f8e5821 | 2015-02-13 14:38:46 -0800 | [diff] [blame] | 6087 | if (CHK("BRACES", |
| 6088 | "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && |
| 6089 | $fix && $prevrawline =~ /^\+/) { |
| 6090 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 6091 | } |
Joe Perches | 0979ae6 | 2012-12-17 16:01:59 -0800 | [diff] [blame] | 6092 | } |
Joe Perches | 77b9a53 | 2013-07-03 15:05:29 -0700 | [diff] [blame] | 6093 | if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { |
Joe Perches | f8e5821 | 2015-02-13 14:38:46 -0800 | [diff] [blame] | 6094 | if (CHK("BRACES", |
| 6095 | "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && |
| 6096 | $fix) { |
| 6097 | fix_delete_line($fixlinenr, $rawline); |
| 6098 | } |
Joe Perches | 0979ae6 | 2012-12-17 16:01:59 -0800 | [diff] [blame] | 6099 | } |
| 6100 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6101 | # no volatiles please |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 6102 | my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; |
| 6103 | if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6104 | WARN("VOLATILE", |
Mauro Carvalho Chehab | 8c27ceff3 | 2016-10-18 10:12:27 -0200 | [diff] [blame] | 6105 | "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6106 | } |
| 6107 | |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6108 | # Check for user-visible strings broken across lines, which breaks the ability |
| 6109 | # to grep for the string. Make exceptions when the previous string ends in a |
| 6110 | # newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' |
| 6111 | # (common in inline assembly) or is a octal \123 or hexadecimal \xaf value |
Joe Perches | 33acb54 | 2015-06-25 15:02:54 -0700 | [diff] [blame] | 6112 | if ($line =~ /^\+\s*$String/ && |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6113 | $prevline =~ /"\s*$/ && |
| 6114 | $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { |
| 6115 | if (WARN("SPLIT_STRING", |
| 6116 | "quoted string split across lines\n" . $hereprev) && |
| 6117 | $fix && |
| 6118 | $prevrawline =~ /^\+.*"\s*$/ && |
| 6119 | $last_coalesced_string_linenr != $linenr - 1) { |
| 6120 | my $extracted_string = get_quoted_string($line, $rawline); |
| 6121 | my $comma_close = ""; |
| 6122 | if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { |
| 6123 | $comma_close = $1; |
| 6124 | } |
| 6125 | |
| 6126 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 6127 | fix_delete_line($fixlinenr, $rawline); |
| 6128 | my $fixedline = $prevrawline; |
| 6129 | $fixedline =~ s/"\s*$//; |
| 6130 | $fixedline .= substr($extracted_string, 1) . trim($comma_close); |
| 6131 | fix_insert_line($fixlinenr - 1, $fixedline); |
| 6132 | $fixedline = $rawline; |
| 6133 | $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; |
| 6134 | if ($fixedline !~ /\+\s*$/) { |
| 6135 | fix_insert_line($fixlinenr, $fixedline); |
| 6136 | } |
| 6137 | $last_coalesced_string_linenr = $linenr; |
| 6138 | } |
| 6139 | } |
| 6140 | |
| 6141 | # check for missing a space in a string concatenation |
| 6142 | if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { |
| 6143 | WARN('MISSING_SPACE', |
| 6144 | "break quoted strings at a space character\n" . $hereprev); |
| 6145 | } |
| 6146 | |
Joe Perches | e4b7d30 | 2017-05-08 15:55:51 -0700 | [diff] [blame] | 6147 | # check for an embedded function name in a string when the function is known |
| 6148 | # This does not work very well for -f --file checking as it depends on patch |
| 6149 | # context providing the function name or a single line form for in-file |
| 6150 | # function declarations |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 6151 | if ($line =~ /^\+.*$String/ && |
| 6152 | defined($context_function) && |
Joe Perches | e4b7d30 | 2017-05-08 15:55:51 -0700 | [diff] [blame] | 6153 | get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && |
| 6154 | length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 6155 | WARN("EMBEDDED_FUNCTION_NAME", |
Joe Perches | e4b7d30 | 2017-05-08 15:55:51 -0700 | [diff] [blame] | 6156 | "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 6157 | } |
| 6158 | |
Joe Perches | adb2da8 | 2021-02-25 17:21:50 -0800 | [diff] [blame] | 6159 | # check for unnecessary function tracing like uses |
| 6160 | # This does not use $logFunctions because there are many instances like |
| 6161 | # 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions |
| 6162 | if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) { |
| 6163 | if (WARN("TRACING_LOGGING", |
| 6164 | "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) && |
| 6165 | $fix) { |
| 6166 | fix_delete_line($fixlinenr, $rawline); |
| 6167 | } |
| 6168 | } |
| 6169 | |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6170 | # check for spaces before a quoted newline |
| 6171 | if ($rawline =~ /^.*\".*\s\\n/) { |
| 6172 | if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", |
| 6173 | "unnecessary whitespace before a quoted newline\n" . $herecurr) && |
| 6174 | $fix) { |
| 6175 | $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; |
| 6176 | } |
| 6177 | |
| 6178 | } |
| 6179 | |
Joe Perches | f17dba4 | 2014-10-13 15:51:51 -0700 | [diff] [blame] | 6180 | # concatenated string without spaces between elements |
Joe Perches | d2af5aa | 2021-09-07 19:59:51 -0700 | [diff] [blame] | 6181 | if ($line =~ /$String[A-Z_]/ || |
| 6182 | ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) { |
Joe Perches | 79682c0 | 2018-08-21 21:57:29 -0700 | [diff] [blame] | 6183 | if (CHK("CONCATENATED_STRING", |
| 6184 | "Concatenated strings should use spaces between elements\n" . $herecurr) && |
| 6185 | $fix) { |
| 6186 | while ($line =~ /($String)/g) { |
| 6187 | my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); |
| 6188 | $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; |
| 6189 | $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; |
| 6190 | } |
| 6191 | } |
Joe Perches | f17dba4 | 2014-10-13 15:51:51 -0700 | [diff] [blame] | 6192 | } |
| 6193 | |
Joe Perches | 90ad30e | 2014-12-10 15:51:59 -0800 | [diff] [blame] | 6194 | # uncoalesced string fragments |
Joe Perches | d2af5aa | 2021-09-07 19:59:51 -0700 | [diff] [blame] | 6195 | if ($line =~ /$String\s*[Lu]?"/) { |
Joe Perches | 79682c0 | 2018-08-21 21:57:29 -0700 | [diff] [blame] | 6196 | if (WARN("STRING_FRAGMENTS", |
| 6197 | "Consecutive strings are generally better as a single string\n" . $herecurr) && |
| 6198 | $fix) { |
| 6199 | while ($line =~ /($String)(?=\s*")/g) { |
| 6200 | my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); |
| 6201 | $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; |
| 6202 | } |
| 6203 | } |
Joe Perches | 90ad30e | 2014-12-10 15:51:59 -0800 | [diff] [blame] | 6204 | } |
| 6205 | |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 6206 | # check for non-standard and hex prefixed decimal printf formats |
| 6207 | my $show_L = 1; #don't show the same defect twice |
| 6208 | my $show_Z = 1; |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6209 | while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 6210 | my $string = substr($rawline, $-[1], $+[1] - $-[1]); |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6211 | $string =~ s/%%/__/g; |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 6212 | # check for %L |
| 6213 | if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6214 | WARN("PRINTF_L", |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 6215 | "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); |
| 6216 | $show_L = 0; |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6217 | } |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 6218 | # check for %Z |
| 6219 | if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { |
| 6220 | WARN("PRINTF_Z", |
| 6221 | "%Z$1 is non-standard C, use %z$1\n" . $herecurr); |
| 6222 | $show_Z = 0; |
| 6223 | } |
| 6224 | # check for 0x<decimal> |
| 6225 | if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { |
| 6226 | ERROR("PRINTF_0XDECIMAL", |
Joe Perches | 6e30075 | 2015-09-09 15:37:47 -0700 | [diff] [blame] | 6227 | "Prefixing 0x with decimal output is defective\n" . $herecurr); |
| 6228 | } |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6229 | } |
| 6230 | |
| 6231 | # check for line continuations in quoted strings with odd counts of " |
Joe Perches | 3f7f335 | 2018-02-06 15:38:52 -0800 | [diff] [blame] | 6232 | if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 6233 | WARN("LINE_CONTINUATIONS", |
| 6234 | "Avoid line continuations in quoted strings\n" . $herecurr); |
| 6235 | } |
| 6236 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 6237 | # warn about #if 0 |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 6238 | if ($line =~ /^.\s*\#\s*if\s+0\b/) { |
Prakruthi Deepak Heragu | 60f8901 | 2018-08-21 21:57:57 -0700 | [diff] [blame] | 6239 | WARN("IF_0", |
| 6240 | "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); |
| 6241 | } |
| 6242 | |
| 6243 | # warn about #if 1 |
| 6244 | if ($line =~ /^.\s*\#\s*if\s+1\b/) { |
| 6245 | WARN("IF_1", |
| 6246 | "Consider removing the #if 1 and its #endif\n" . $herecurr); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6247 | } |
| 6248 | |
Andy Whitcroft | 03df4b5 | 2012-12-17 16:01:52 -0800 | [diff] [blame] | 6249 | # check for needless "if (<foo>) fn(<foo>)" uses |
| 6250 | if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { |
Joe Perches | 100425d | 2015-09-09 15:37:36 -0700 | [diff] [blame] | 6251 | my $tested = quotemeta($1); |
| 6252 | my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; |
| 6253 | if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { |
| 6254 | my $func = $1; |
| 6255 | if (WARN('NEEDLESS_IF', |
| 6256 | "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && |
| 6257 | $fix) { |
| 6258 | my $do_fix = 1; |
| 6259 | my $leading_tabs = ""; |
| 6260 | my $new_leading_tabs = ""; |
| 6261 | if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { |
| 6262 | $leading_tabs = $1; |
| 6263 | } else { |
| 6264 | $do_fix = 0; |
| 6265 | } |
| 6266 | if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { |
| 6267 | $new_leading_tabs = $1; |
| 6268 | if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { |
| 6269 | $do_fix = 0; |
| 6270 | } |
| 6271 | } else { |
| 6272 | $do_fix = 0; |
| 6273 | } |
| 6274 | if ($do_fix) { |
| 6275 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 6276 | $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; |
| 6277 | } |
| 6278 | } |
Greg Kroah-Hartman | 4c432a8 | 2008-07-23 21:29:04 -0700 | [diff] [blame] | 6279 | } |
| 6280 | } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 6281 | |
Joe Perches | ebfdc40 | 2014-08-06 16:10:27 -0700 | [diff] [blame] | 6282 | # check for unnecessary "Out of Memory" messages |
| 6283 | if ($line =~ /^\+.*\b$logFunctions\s*\(/ && |
| 6284 | $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && |
| 6285 | (defined $1 || defined $3) && |
| 6286 | $linenr > 3) { |
| 6287 | my $testval = $2; |
| 6288 | my $testline = $lines[$linenr - 3]; |
| 6289 | |
| 6290 | my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); |
| 6291 | # print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); |
| 6292 | |
Joe Perches | e29a70f | 2019-03-07 16:28:35 -0800 | [diff] [blame] | 6293 | if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && |
| 6294 | $s !~ /\b__GFP_NOWARN\b/ ) { |
Joe Perches | ebfdc40 | 2014-08-06 16:10:27 -0700 | [diff] [blame] | 6295 | WARN("OOM_MESSAGE", |
| 6296 | "Possible unnecessary 'out of memory' message\n" . $hereprev); |
| 6297 | } |
| 6298 | } |
| 6299 | |
Joe Perches | f78d98f | 2014-10-13 15:52:01 -0700 | [diff] [blame] | 6300 | # check for logging functions with KERN_<LEVEL> |
Paolo Bonzini | dcaf112 | 2015-02-13 14:38:26 -0800 | [diff] [blame] | 6301 | if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && |
Joe Perches | f78d98f | 2014-10-13 15:52:01 -0700 | [diff] [blame] | 6302 | $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { |
| 6303 | my $level = $1; |
| 6304 | if (WARN("UNNECESSARY_KERN_LEVEL", |
| 6305 | "Possible unnecessary $level\n" . $herecurr) && |
| 6306 | $fix) { |
| 6307 | $fixed[$fixlinenr] =~ s/\s*$level\s*//; |
| 6308 | } |
| 6309 | } |
| 6310 | |
Joe Perches | 45c55e9 | 2017-02-24 15:01:31 -0800 | [diff] [blame] | 6311 | # check for logging continuations |
| 6312 | if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { |
| 6313 | WARN("LOGGING_CONTINUATION", |
| 6314 | "Avoid logging continuation uses where feasible\n" . $herecurr); |
| 6315 | } |
| 6316 | |
Dwaipayan Ray | 70eb227 | 2020-12-15 20:45:15 -0800 | [diff] [blame] | 6317 | # check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions |
| 6318 | if (defined $stat && |
| 6319 | $line =~ /\b$logFunctions\s*\(/ && |
| 6320 | index($stat, '"') >= 0) { |
| 6321 | my $lc = $stat =~ tr@\n@@; |
| 6322 | $lc = $lc + $linenr; |
| 6323 | my $stat_real = get_stat_real($linenr, $lc); |
| 6324 | pos($stat_real) = index($stat_real, '"'); |
| 6325 | while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { |
| 6326 | my $pspec = $1; |
| 6327 | my $h = $2; |
| 6328 | my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; |
| 6329 | if (WARN("UNNECESSARY_MODIFIER", |
| 6330 | "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && |
| 6331 | $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { |
| 6332 | my $nspec = $pspec; |
| 6333 | $nspec =~ s/h//g; |
| 6334 | $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; |
| 6335 | } |
| 6336 | } |
| 6337 | } |
| 6338 | |
Joe Perches | abb08a5 | 2014-12-10 15:51:46 -0800 | [diff] [blame] | 6339 | # check for mask then right shift without a parentheses |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6340 | if ($perl_version_ok && |
Joe Perches | abb08a5 | 2014-12-10 15:51:46 -0800 | [diff] [blame] | 6341 | $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && |
| 6342 | $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so |
| 6343 | WARN("MASK_THEN_SHIFT", |
| 6344 | "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); |
| 6345 | } |
| 6346 | |
Joe Perches | b75ac61 | 2014-12-10 15:52:02 -0800 | [diff] [blame] | 6347 | # check for pointer comparisons to NULL |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6348 | if ($perl_version_ok) { |
Joe Perches | b75ac61 | 2014-12-10 15:52:02 -0800 | [diff] [blame] | 6349 | while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { |
| 6350 | my $val = $1; |
| 6351 | my $equal = "!"; |
| 6352 | $equal = "" if ($4 eq "!="); |
| 6353 | if (CHK("COMPARISON_TO_NULL", |
| 6354 | "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && |
| 6355 | $fix) { |
| 6356 | $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; |
| 6357 | } |
| 6358 | } |
| 6359 | } |
| 6360 | |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 6361 | # check for bad placement of section $InitAttribute (e.g.: __initdata) |
| 6362 | if ($line =~ /(\b$InitAttribute\b)/) { |
| 6363 | my $attr = $1; |
| 6364 | if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { |
| 6365 | my $ptr = $1; |
| 6366 | my $var = $2; |
| 6367 | if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && |
| 6368 | ERROR("MISPLACED_INIT", |
| 6369 | "$attr should be placed after $var\n" . $herecurr)) || |
| 6370 | ($ptr !~ /\b(union|struct)\s+$attr\b/ && |
| 6371 | WARN("MISPLACED_INIT", |
| 6372 | "$attr should be placed after $var\n" . $herecurr))) && |
| 6373 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6374 | $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 Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 6375 | } |
| 6376 | } |
| 6377 | } |
| 6378 | |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 6379 | # check for $InitAttributeData (ie: __initdata) with const |
| 6380 | if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { |
| 6381 | my $attr = $1; |
| 6382 | $attr =~ /($InitAttributePrefix)(.*)/; |
| 6383 | my $attr_prefix = $1; |
| 6384 | my $attr_type = $2; |
| 6385 | if (ERROR("INIT_ATTRIBUTE", |
| 6386 | "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && |
| 6387 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6388 | $fixed[$fixlinenr] =~ |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 6389 | s/$InitAttributeData/${attr_prefix}initconst/; |
| 6390 | } |
| 6391 | } |
| 6392 | |
| 6393 | # check for $InitAttributeConst (ie: __initconst) without const |
| 6394 | if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { |
| 6395 | my $attr = $1; |
| 6396 | if (ERROR("INIT_ATTRIBUTE", |
| 6397 | "Use of $attr requires a separate use of const\n" . $herecurr) && |
| 6398 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6399 | my $lead = $fixed[$fixlinenr] =~ |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 6400 | /(^\+\s*(?:static\s+))/; |
| 6401 | $lead = rtrim($1); |
| 6402 | $lead = "$lead " if ($lead !~ /^\+$/); |
| 6403 | $lead = "${lead}const "; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6404 | $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 6405 | } |
| 6406 | } |
| 6407 | |
Joe Perches | c17893c | 2015-04-16 12:44:42 -0700 | [diff] [blame] | 6408 | # check for __read_mostly with const non-pointer (should just be const) |
| 6409 | if ($line =~ /\b__read_mostly\b/ && |
| 6410 | $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { |
| 6411 | if (ERROR("CONST_READ_MOSTLY", |
| 6412 | "Invalid use of __read_mostly with const type\n" . $herecurr) && |
| 6413 | $fix) { |
| 6414 | $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; |
| 6415 | } |
| 6416 | } |
| 6417 | |
Joe Perches | fbdb813 | 2014-04-03 14:49:14 -0700 | [diff] [blame] | 6418 | # don't use __constant_<foo> functions outside of include/uapi/ |
| 6419 | if ($realfile !~ m@^include/uapi/@ && |
| 6420 | $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { |
| 6421 | my $constant_func = $1; |
| 6422 | my $func = $constant_func; |
| 6423 | $func =~ s/^__constant_//; |
| 6424 | if (WARN("CONSTANT_CONVERSION", |
| 6425 | "$constant_func should be $func\n" . $herecurr) && |
| 6426 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6427 | $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; |
Joe Perches | fbdb813 | 2014-04-03 14:49:14 -0700 | [diff] [blame] | 6428 | } |
| 6429 | } |
| 6430 | |
Patrick Pannuto | 1a15a25 | 2010-08-09 17:21:01 -0700 | [diff] [blame] | 6431 | # prefer usleep_range over udelay |
Bruce Allan | 37581c2 | 2013-02-21 16:44:19 -0800 | [diff] [blame] | 6432 | if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { |
Joe Perches | 43c1d77 | 2014-04-03 14:49:11 -0700 | [diff] [blame] | 6433 | my $delay = $1; |
Patrick Pannuto | 1a15a25 | 2010-08-09 17:21:01 -0700 | [diff] [blame] | 6434 | # ignore udelay's < 10, however |
Joe Perches | 43c1d77 | 2014-04-03 14:49:11 -0700 | [diff] [blame] | 6435 | if (! ($delay < 10) ) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6436 | CHK("USLEEP_RANGE", |
Mauro Carvalho Chehab | 458f69e | 2019-06-12 14:53:00 -0300 | [diff] [blame] | 6437 | "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); |
Joe Perches | 43c1d77 | 2014-04-03 14:49:11 -0700 | [diff] [blame] | 6438 | } |
| 6439 | if ($delay > 2000) { |
| 6440 | WARN("LONG_UDELAY", |
| 6441 | "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); |
Patrick Pannuto | 1a15a25 | 2010-08-09 17:21:01 -0700 | [diff] [blame] | 6442 | } |
| 6443 | } |
| 6444 | |
Patrick Pannuto | 09ef872 | 2010-08-09 17:21:02 -0700 | [diff] [blame] | 6445 | # warn about unexpectedly long msleep's |
| 6446 | if ($line =~ /\bmsleep\s*\((\d+)\);/) { |
| 6447 | if ($1 < 20) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6448 | WARN("MSLEEP", |
Mauro Carvalho Chehab | 458f69e | 2019-06-12 14:53:00 -0300 | [diff] [blame] | 6449 | "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); |
Patrick Pannuto | 09ef872 | 2010-08-09 17:21:02 -0700 | [diff] [blame] | 6450 | } |
| 6451 | } |
| 6452 | |
Joe Perches | 36ec193 | 2013-07-03 15:05:25 -0700 | [diff] [blame] | 6453 | # check for comparisons of jiffies |
| 6454 | if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { |
| 6455 | WARN("JIFFIES_COMPARISON", |
| 6456 | "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); |
| 6457 | } |
| 6458 | |
Joe Perches | 9d7a34a | 2013-07-03 15:05:26 -0700 | [diff] [blame] | 6459 | # check for comparisons of get_jiffies_64() |
| 6460 | if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { |
| 6461 | WARN("JIFFIES_COMPARISON", |
| 6462 | "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); |
| 6463 | } |
| 6464 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 6465 | # warn about #ifdefs in C files |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 6466 | # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 6467 | # print "#ifdef in C files should be avoided\n"; |
| 6468 | # print "$herecurr"; |
| 6469 | # $clean = 0; |
| 6470 | # } |
| 6471 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 6472 | # warn about spacing in #ifdefs |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 6473 | if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 6474 | if (ERROR("SPACING", |
| 6475 | "exactly one space required after that #$1\n" . $herecurr) && |
| 6476 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6477 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 6478 | s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; |
| 6479 | } |
| 6480 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 6481 | } |
| 6482 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6483 | # check for spinlock_t definitions without a comment. |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 6484 | if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || |
| 6485 | $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6486 | my $which = $1; |
| 6487 | if (!ctx_has_comment($first_line, $linenr)) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6488 | CHK("UNCOMMENTED_DEFINITION", |
| 6489 | "$1 definition without comment\n" . $herecurr); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6490 | } |
| 6491 | } |
| 6492 | # check for memory barriers without a comment. |
Michael S. Tsirkin | 402c255 | 2016-01-04 09:39:01 +0200 | [diff] [blame] | 6493 | |
| 6494 | my $barriers = qr{ |
| 6495 | mb| |
| 6496 | rmb| |
Will Deacon | ad83ec6 | 2019-11-07 14:49:00 +0000 | [diff] [blame] | 6497 | wmb |
Michael S. Tsirkin | 402c255 | 2016-01-04 09:39:01 +0200 | [diff] [blame] | 6498 | }x; |
| 6499 | my $barrier_stems = qr{ |
| 6500 | mb__before_atomic| |
| 6501 | mb__after_atomic| |
| 6502 | store_release| |
| 6503 | load_acquire| |
| 6504 | store_mb| |
| 6505 | (?:$barriers) |
| 6506 | }x; |
| 6507 | my $all_barriers = qr{ |
| 6508 | (?:$barriers)| |
Michael S. Tsirkin | 43e361f | 2016-01-04 10:00:10 +0200 | [diff] [blame] | 6509 | smp_(?:$barrier_stems)| |
| 6510 | virt_(?:$barrier_stems) |
Michael S. Tsirkin | 402c255 | 2016-01-04 09:39:01 +0200 | [diff] [blame] | 6511 | }x; |
| 6512 | |
| 6513 | if ($line =~ /\b(?:$all_barriers)\s*\(/) { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6514 | if (!ctx_has_comment($first_line, $linenr)) { |
Joe Perches | c1fd7bb | 2013-11-12 15:10:11 -0800 | [diff] [blame] | 6515 | WARN("MEMORY_BARRIER", |
| 6516 | "memory barrier without comment\n" . $herecurr); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6517 | } |
| 6518 | } |
Paul E. McKenney | 3ad8177 | 2015-07-02 11:55:40 -0700 | [diff] [blame] | 6519 | |
Michael S. Tsirkin | f4073b0 | 2016-01-04 09:54:51 +0200 | [diff] [blame] | 6520 | my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; |
| 6521 | |
| 6522 | if ($realfile !~ m@^include/asm-generic/@ && |
| 6523 | $realfile !~ m@/barrier\.h$@ && |
| 6524 | $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && |
| 6525 | $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { |
| 6526 | WARN("MEMORY_BARRIER", |
| 6527 | "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); |
| 6528 | } |
| 6529 | |
Joe Perches | cb426e9 | 2015-06-25 15:02:46 -0700 | [diff] [blame] | 6530 | # check for waitqueue_active without a comment. |
| 6531 | if ($line =~ /\bwaitqueue_active\s*\(/) { |
| 6532 | if (!ctx_has_comment($first_line, $linenr)) { |
| 6533 | WARN("WAITQUEUE_ACTIVE", |
| 6534 | "waitqueue_active without comment\n" . $herecurr); |
| 6535 | } |
| 6536 | } |
Paul E. McKenney | 3ad8177 | 2015-07-02 11:55:40 -0700 | [diff] [blame] | 6537 | |
Marco Elver | 5099a72 | 2020-04-01 12:17:14 +0200 | [diff] [blame] | 6538 | # check for data_race without a comment. |
| 6539 | if ($line =~ /\bdata_race\s*\(/) { |
| 6540 | if (!ctx_has_comment($first_line, $linenr)) { |
| 6541 | WARN("DATA_RACE", |
| 6542 | "data_race without comment\n" . $herecurr); |
| 6543 | } |
| 6544 | } |
| 6545 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 6546 | # check of hardware specific defines |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 6547 | if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6548 | CHK("ARCH_DEFINES", |
| 6549 | "architecture specific defines should be avoided\n" . $herecurr); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 6550 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 6551 | |
Joe Perches | 596ed45 | 2017-07-12 14:37:02 -0700 | [diff] [blame] | 6552 | # check that the storage class is not after a type |
| 6553 | if ($line =~ /\b($Type)\s+($Storage)\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6554 | WARN("STORAGE_CLASS", |
Joe Perches | 596ed45 | 2017-07-12 14:37:02 -0700 | [diff] [blame] | 6555 | "storage class '$2' should be located before type '$1'\n" . $herecurr); |
| 6556 | } |
| 6557 | # Check that the storage class is at the beginning of a declaration |
| 6558 | if ($line =~ /\b$Storage\b/ && |
| 6559 | $line !~ /^.\s*$Storage/ && |
| 6560 | $line =~ /^.\s*(.+?)\$Storage\s/ && |
| 6561 | $1 !~ /[\,\)]\s*$/) { |
| 6562 | WARN("STORAGE_CLASS", |
| 6563 | "storage class should be at the beginning of the declaration\n" . $herecurr); |
Tobias Klauser | d4977c7 | 2010-05-24 14:33:30 -0700 | [diff] [blame] | 6564 | } |
| 6565 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 6566 | # check the location of the inline attribute, that it is between |
| 6567 | # storage class and type. |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 6568 | if ($line =~ /\b$Type\s+$Inline\b/ || |
| 6569 | $line =~ /\b$Inline\s+$Storage\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6570 | ERROR("INLINE_LOCATION", |
| 6571 | "inline keyword should sit between storage class and type\n" . $herecurr); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 6572 | } |
| 6573 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 6574 | # Check for __inline__ and __inline, prefer inline |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 6575 | if ($realfile !~ m@\binclude/uapi/@ && |
| 6576 | $line =~ /\b(__inline__|__inline)\b/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6577 | if (WARN("INLINE", |
| 6578 | "plain inline is preferred over $1\n" . $herecurr) && |
| 6579 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6580 | $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6581 | |
| 6582 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 6583 | } |
| 6584 | |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6585 | # Check for compiler attributes |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 6586 | if ($realfile !~ m@\binclude/uapi/@ && |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6587 | $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { |
| 6588 | my $attr = $1; |
| 6589 | $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; |
Joe Perches | 3d130fd | 2011-01-12 17:00:00 -0800 | [diff] [blame] | 6590 | |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6591 | my %attr_list = ( |
Joe Perches | 0830aab | 2020-12-15 20:44:50 -0800 | [diff] [blame] | 6592 | "alias" => "__alias", |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6593 | "aligned" => "__aligned", |
| 6594 | "always_inline" => "__always_inline", |
| 6595 | "assume_aligned" => "__assume_aligned", |
| 6596 | "cold" => "__cold", |
| 6597 | "const" => "__attribute_const__", |
| 6598 | "copy" => "__copy", |
| 6599 | "designated_init" => "__designated_init", |
| 6600 | "externally_visible" => "__visible", |
| 6601 | "format" => "printf|scanf", |
| 6602 | "gnu_inline" => "__gnu_inline", |
| 6603 | "malloc" => "__malloc", |
| 6604 | "mode" => "__mode", |
| 6605 | "no_caller_saved_registers" => "__no_caller_saved_registers", |
| 6606 | "noclone" => "__noclone", |
| 6607 | "noinline" => "noinline", |
| 6608 | "nonstring" => "__nonstring", |
| 6609 | "noreturn" => "__noreturn", |
| 6610 | "packed" => "__packed", |
| 6611 | "pure" => "__pure", |
Joe Perches | 339f29d | 2020-12-15 20:44:43 -0800 | [diff] [blame] | 6612 | "section" => "__section", |
Joe Perches | 0830aab | 2020-12-15 20:44:50 -0800 | [diff] [blame] | 6613 | "used" => "__used", |
| 6614 | "weak" => "__weak" |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6615 | ); |
Joe Perches | 39b7e28 | 2011-07-25 17:13:24 -0700 | [diff] [blame] | 6616 | |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6617 | while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { |
Joe Perches | 339f29d | 2020-12-15 20:44:43 -0800 | [diff] [blame] | 6618 | my $orig_attr = $1; |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6619 | my $params = ''; |
| 6620 | $params = $2 if defined($2); |
Joe Perches | 339f29d | 2020-12-15 20:44:43 -0800 | [diff] [blame] | 6621 | my $curr_attr = $orig_attr; |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6622 | $curr_attr =~ s/^[\s_]+|[\s_]+$//g; |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6623 | if (exists($attr_list{$curr_attr})) { |
Joe Perches | 339f29d | 2020-12-15 20:44:43 -0800 | [diff] [blame] | 6624 | my $new = $attr_list{$curr_attr}; |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6625 | if ($curr_attr eq "format" && $params) { |
| 6626 | $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; |
Joe Perches | 339f29d | 2020-12-15 20:44:43 -0800 | [diff] [blame] | 6627 | $new = "__$1\($2"; |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6628 | } else { |
Joe Perches | 339f29d | 2020-12-15 20:44:43 -0800 | [diff] [blame] | 6629 | $new = "$new$params"; |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6630 | } |
Joe Perches | 339f29d | 2020-12-15 20:44:43 -0800 | [diff] [blame] | 6631 | if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", |
| 6632 | "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && |
| 6633 | $fix) { |
| 6634 | my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; |
| 6635 | $fixed[$fixlinenr] =~ s/$remove//; |
| 6636 | $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; |
| 6637 | $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; |
| 6638 | $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; |
| 6639 | } |
Dwaipayan Ray | 7ebe1d1 | 2020-12-15 20:44:36 -0800 | [diff] [blame] | 6640 | } |
| 6641 | } |
| 6642 | |
| 6643 | # Check for __attribute__ unused, prefer __always_unused or __maybe_unused |
| 6644 | if ($attr =~ /^_*unused/) { |
| 6645 | WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", |
| 6646 | "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6647 | } |
Joe Perches | 6061d94 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 6648 | } |
| 6649 | |
Joe Perches | 619a908 | 2014-12-10 15:51:35 -0800 | [diff] [blame] | 6650 | # Check for __attribute__ weak, or __weak declarations (may have link issues) |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6651 | if ($perl_version_ok && |
Joe Perches | 619a908 | 2014-12-10 15:51:35 -0800 | [diff] [blame] | 6652 | $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && |
| 6653 | ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || |
| 6654 | $line =~ /\b__weak\b/)) { |
| 6655 | ERROR("WEAK_DECLARATION", |
| 6656 | "Using weak declarations can have unintended link defects\n" . $herecurr); |
| 6657 | } |
| 6658 | |
Tomas Winkler | fd39f90 | 2016-12-12 16:46:34 -0800 | [diff] [blame] | 6659 | # check for c99 types like uint8_t used outside of uapi/ and tools/ |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 6660 | if ($realfile !~ m@\binclude/uapi/@ && |
Tomas Winkler | fd39f90 | 2016-12-12 16:46:34 -0800 | [diff] [blame] | 6661 | $realfile !~ m@\btools/@ && |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 6662 | $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { |
| 6663 | my $type = $1; |
| 6664 | if ($type =~ /\b($typeC99Typedefs)\b/) { |
| 6665 | $type = $1; |
| 6666 | my $kernel_type = 'u'; |
| 6667 | $kernel_type = 's' if ($type =~ /^_*[si]/); |
| 6668 | $type =~ /(\d+)/; |
| 6669 | $kernel_type .= $1; |
| 6670 | if (CHK("PREFER_KERNEL_TYPES", |
| 6671 | "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && |
| 6672 | $fix) { |
| 6673 | $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; |
| 6674 | } |
| 6675 | } |
| 6676 | } |
| 6677 | |
Joe Perches | 938224b | 2016-01-20 14:59:15 -0800 | [diff] [blame] | 6678 | # check for cast of C90 native int or longer types constants |
| 6679 | if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { |
| 6680 | my $cast = $1; |
| 6681 | my $const = $2; |
Joe Perches | 0972b8b | 2021-02-25 17:21:54 -0800 | [diff] [blame] | 6682 | my $suffix = ""; |
| 6683 | my $newconst = $const; |
| 6684 | $newconst =~ s/${Int_type}$//; |
| 6685 | $suffix .= 'U' if ($cast =~ /\bunsigned\b/); |
| 6686 | if ($cast =~ /\blong\s+long\b/) { |
| 6687 | $suffix .= 'LL'; |
| 6688 | } elsif ($cast =~ /\blong\b/) { |
| 6689 | $suffix .= 'L'; |
| 6690 | } |
Joe Perches | 938224b | 2016-01-20 14:59:15 -0800 | [diff] [blame] | 6691 | if (WARN("TYPECAST_INT_CONSTANT", |
Joe Perches | 0972b8b | 2021-02-25 17:21:54 -0800 | [diff] [blame] | 6692 | "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) && |
Joe Perches | 938224b | 2016-01-20 14:59:15 -0800 | [diff] [blame] | 6693 | $fix) { |
Joe Perches | 938224b | 2016-01-20 14:59:15 -0800 | [diff] [blame] | 6694 | $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; |
| 6695 | } |
| 6696 | } |
| 6697 | |
Joe Perches | 8f53a9b | 2010-03-05 13:43:48 -0800 | [diff] [blame] | 6698 | # check for sizeof(&) |
| 6699 | if ($line =~ /\bsizeof\s*\(\s*\&/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6700 | WARN("SIZEOF_ADDRESS", |
| 6701 | "sizeof(& should be avoided\n" . $herecurr); |
Joe Perches | 8f53a9b | 2010-03-05 13:43:48 -0800 | [diff] [blame] | 6702 | } |
| 6703 | |
Joe Perches | 66c80b6 | 2012-07-30 14:41:22 -0700 | [diff] [blame] | 6704 | # check for sizeof without parenthesis |
| 6705 | if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6706 | if (WARN("SIZEOF_PARENTHESIS", |
| 6707 | "sizeof $1 should be sizeof($1)\n" . $herecurr) && |
| 6708 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6709 | $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6710 | } |
Joe Perches | 66c80b6 | 2012-07-30 14:41:22 -0700 | [diff] [blame] | 6711 | } |
| 6712 | |
Joe Perches | 88982fe | 2012-12-17 16:02:00 -0800 | [diff] [blame] | 6713 | # check for struct spinlock declarations |
| 6714 | if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { |
| 6715 | WARN("USE_SPINLOCK_T", |
| 6716 | "struct spinlock should be spinlock_t\n" . $herecurr); |
| 6717 | } |
| 6718 | |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 6719 | # check for seq_printf uses that could be seq_puts |
Joe Perches | 0666872 | 2013-11-12 15:10:07 -0800 | [diff] [blame] | 6720 | if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 6721 | my $fmt = get_quoted_string($line, $rawline); |
Heba Aamer | caac1d5 | 2015-02-13 14:38:49 -0800 | [diff] [blame] | 6722 | $fmt =~ s/%%//g; |
| 6723 | if ($fmt !~ /%/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6724 | if (WARN("PREFER_SEQ_PUTS", |
| 6725 | "Prefer seq_puts to seq_printf\n" . $herecurr) && |
| 6726 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6727 | $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6728 | } |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 6729 | } |
| 6730 | } |
| 6731 | |
Joe Perches | 478b179 | 2018-04-10 16:33:34 -0700 | [diff] [blame] | 6732 | # check for vsprintf extension %p<foo> misuses |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6733 | if ($perl_version_ok && |
Joe Perches | 0b52376 | 2017-05-08 15:55:36 -0700 | [diff] [blame] | 6734 | defined $stat && |
| 6735 | $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && |
| 6736 | $1 !~ /^_*volatile_*$/) { |
Tobin C. Harding | e3c6bc9 | 2018-04-10 16:33:31 -0700 | [diff] [blame] | 6737 | my $stat_real; |
| 6738 | |
Joe Perches | 0b52376 | 2017-05-08 15:55:36 -0700 | [diff] [blame] | 6739 | my $lc = $stat =~ tr@\n@@; |
| 6740 | $lc = $lc + $linenr; |
| 6741 | for (my $count = $linenr; $count <= $lc; $count++) { |
Joe Perches | ffe0751 | 2018-07-13 16:59:23 -0700 | [diff] [blame] | 6742 | my $specifier; |
| 6743 | my $extension; |
Sakari Ailus | 3bd32d6 | 2019-10-03 15:32:18 +0300 | [diff] [blame] | 6744 | my $qualifier; |
Joe Perches | ffe0751 | 2018-07-13 16:59:23 -0700 | [diff] [blame] | 6745 | my $bad_specifier = ""; |
Joe Perches | 0b52376 | 2017-05-08 15:55:36 -0700 | [diff] [blame] | 6746 | my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); |
| 6747 | $fmt =~ s/%%//g; |
Tobin C. Harding | 2a9f9d8 | 2018-04-10 16:33:20 -0700 | [diff] [blame] | 6748 | |
Sakari Ailus | 3bd32d6 | 2019-10-03 15:32:18 +0300 | [diff] [blame] | 6749 | while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { |
Tobin C. Harding | e3c6bc9 | 2018-04-10 16:33:31 -0700 | [diff] [blame] | 6750 | $specifier = $1; |
| 6751 | $extension = $2; |
Sakari Ailus | 3bd32d6 | 2019-10-03 15:32:18 +0300 | [diff] [blame] | 6752 | $qualifier = $3; |
Sakari Ailus | af612e4 | 2021-02-16 17:57:20 +0200 | [diff] [blame] | 6753 | if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ || |
Sakari Ailus | 3bd32d6 | 2019-10-03 15:32:18 +0300 | [diff] [blame] | 6754 | ($extension eq "f" && |
Sakari Ailus | af612e4 | 2021-02-16 17:57:20 +0200 | [diff] [blame] | 6755 | defined $qualifier && $qualifier !~ /^w/) || |
| 6756 | ($extension eq "4" && |
| 6757 | defined $qualifier && $qualifier !~ /^cc/)) { |
Tobin C. Harding | e3c6bc9 | 2018-04-10 16:33:31 -0700 | [diff] [blame] | 6758 | $bad_specifier = $specifier; |
| 6759 | last; |
| 6760 | } |
| 6761 | if ($extension eq "x" && !defined($stat_real)) { |
| 6762 | if (!defined($stat_real)) { |
| 6763 | $stat_real = get_stat_real($linenr, $lc); |
| 6764 | } |
| 6765 | WARN("VSPRINTF_SPECIFIER_PX", |
| 6766 | "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"); |
| 6767 | } |
| 6768 | } |
| 6769 | if ($bad_specifier ne "") { |
| 6770 | my $stat_real = get_stat_real($linenr, $lc); |
| 6771 | my $ext_type = "Invalid"; |
| 6772 | my $use = ""; |
| 6773 | if ($bad_specifier =~ /p[Ff]/) { |
Tobin C. Harding | e3c6bc9 | 2018-04-10 16:33:31 -0700 | [diff] [blame] | 6774 | $use = " - use %pS instead"; |
| 6775 | $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); |
| 6776 | } |
| 6777 | |
| 6778 | WARN("VSPRINTF_POINTER_EXTENSION", |
| 6779 | "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); |
| 6780 | } |
Joe Perches | 0b52376 | 2017-05-08 15:55:36 -0700 | [diff] [blame] | 6781 | } |
| 6782 | } |
| 6783 | |
Andy Whitcroft | 554e165 | 2012-01-10 15:09:57 -0800 | [diff] [blame] | 6784 | # Check for misused memsets |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6785 | if ($perl_version_ok && |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 6786 | defined $stat && |
Mateusz Kulikowski | 9e20a85 | 2015-06-25 15:03:16 -0700 | [diff] [blame] | 6787 | $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { |
Andy Whitcroft | 554e165 | 2012-01-10 15:09:57 -0800 | [diff] [blame] | 6788 | |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6789 | my $ms_addr = $2; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 6790 | my $ms_val = $7; |
| 6791 | my $ms_size = $12; |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6792 | |
Andy Whitcroft | 554e165 | 2012-01-10 15:09:57 -0800 | [diff] [blame] | 6793 | if ($ms_size =~ /^(0x|)0$/i) { |
| 6794 | ERROR("MEMSET", |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6795 | "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); |
Andy Whitcroft | 554e165 | 2012-01-10 15:09:57 -0800 | [diff] [blame] | 6796 | } elsif ($ms_size =~ /^(0x|)1$/i) { |
| 6797 | WARN("MEMSET", |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6798 | "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); |
| 6799 | } |
| 6800 | } |
| 6801 | |
Joe Perches | 98a9bba | 2014-01-23 15:54:52 -0800 | [diff] [blame] | 6802 | # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6803 | # if ($perl_version_ok && |
Joe Perches | f333195 | 2016-10-11 13:51:53 -0700 | [diff] [blame] | 6804 | # defined $stat && |
| 6805 | # $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { |
| 6806 | # if (WARN("PREFER_ETHER_ADDR_COPY", |
| 6807 | # "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && |
| 6808 | # $fix) { |
| 6809 | # $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; |
| 6810 | # } |
| 6811 | # } |
Joe Perches | 98a9bba | 2014-01-23 15:54:52 -0800 | [diff] [blame] | 6812 | |
Mateusz Kulikowski | b6117d1 | 2015-06-25 15:03:13 -0700 | [diff] [blame] | 6813 | # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6814 | # if ($perl_version_ok && |
Joe Perches | f333195 | 2016-10-11 13:51:53 -0700 | [diff] [blame] | 6815 | # defined $stat && |
| 6816 | # $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { |
| 6817 | # WARN("PREFER_ETHER_ADDR_EQUAL", |
| 6818 | # "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") |
| 6819 | # } |
Mateusz Kulikowski | b6117d1 | 2015-06-25 15:03:13 -0700 | [diff] [blame] | 6820 | |
Mateusz Kulikowski | 8617cd0 | 2015-06-25 15:03:19 -0700 | [diff] [blame] | 6821 | # check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr |
| 6822 | # check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6823 | # if ($perl_version_ok && |
Joe Perches | f333195 | 2016-10-11 13:51:53 -0700 | [diff] [blame] | 6824 | # defined $stat && |
| 6825 | # $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { |
| 6826 | # |
| 6827 | # my $ms_val = $7; |
| 6828 | # |
| 6829 | # if ($ms_val =~ /^(?:0x|)0+$/i) { |
| 6830 | # if (WARN("PREFER_ETH_ZERO_ADDR", |
| 6831 | # "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && |
| 6832 | # $fix) { |
| 6833 | # $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; |
| 6834 | # } |
| 6835 | # } elsif ($ms_val =~ /^(?:0xff|255)$/i) { |
| 6836 | # if (WARN("PREFER_ETH_BROADCAST_ADDR", |
| 6837 | # "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && |
| 6838 | # $fix) { |
| 6839 | # $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; |
| 6840 | # } |
| 6841 | # } |
| 6842 | # } |
Mateusz Kulikowski | 8617cd0 | 2015-06-25 15:03:19 -0700 | [diff] [blame] | 6843 | |
Joe Perches | 5dbdb2d | 2020-12-29 15:14:31 -0800 | [diff] [blame] | 6844 | # strlcpy uses that should likely be strscpy |
| 6845 | if ($line =~ /\bstrlcpy\s*\(/) { |
| 6846 | WARN("STRLCPY", |
| 6847 | "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr); |
| 6848 | } |
| 6849 | |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6850 | # typecasts on min/max could be min_t/max_t |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6851 | if ($perl_version_ok && |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 6852 | defined $stat && |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6853 | $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 6854 | if (defined $2 || defined $7) { |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6855 | my $call = $1; |
| 6856 | my $cast1 = deparenthesize($2); |
| 6857 | my $arg1 = $3; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 6858 | my $cast2 = deparenthesize($7); |
| 6859 | my $arg2 = $8; |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6860 | my $cast; |
| 6861 | |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 6862 | if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 6863 | $cast = "$cast1 or $cast2"; |
| 6864 | } elsif ($cast1 ne "") { |
| 6865 | $cast = $cast1; |
| 6866 | } else { |
| 6867 | $cast = $cast2; |
| 6868 | } |
| 6869 | WARN("MINMAX", |
| 6870 | "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); |
Andy Whitcroft | 554e165 | 2012-01-10 15:09:57 -0800 | [diff] [blame] | 6871 | } |
| 6872 | } |
| 6873 | |
Joe Perches | 4a27319 | 2012-07-30 14:41:20 -0700 | [diff] [blame] | 6874 | # check usleep_range arguments |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6875 | if ($perl_version_ok && |
Joe Perches | 4a27319 | 2012-07-30 14:41:20 -0700 | [diff] [blame] | 6876 | defined $stat && |
| 6877 | $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { |
| 6878 | my $min = $1; |
| 6879 | my $max = $7; |
| 6880 | if ($min eq $max) { |
| 6881 | WARN("USLEEP_RANGE", |
Mauro Carvalho Chehab | 458f69e | 2019-06-12 14:53:00 -0300 | [diff] [blame] | 6882 | "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); |
Joe Perches | 4a27319 | 2012-07-30 14:41:20 -0700 | [diff] [blame] | 6883 | } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && |
| 6884 | $min > $max) { |
| 6885 | WARN("USLEEP_RANGE", |
Mauro Carvalho Chehab | 458f69e | 2019-06-12 14:53:00 -0300 | [diff] [blame] | 6886 | "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); |
Joe Perches | 4a27319 | 2012-07-30 14:41:20 -0700 | [diff] [blame] | 6887 | } |
| 6888 | } |
| 6889 | |
Joe Perches | 823b794 | 2013-11-12 15:10:15 -0800 | [diff] [blame] | 6890 | # check for naked sscanf |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6891 | if ($perl_version_ok && |
Joe Perches | 823b794 | 2013-11-12 15:10:15 -0800 | [diff] [blame] | 6892 | defined $stat && |
Joe Perches | 6c8bd70 | 2014-04-03 14:49:16 -0700 | [diff] [blame] | 6893 | $line =~ /\bsscanf\b/ && |
Joe Perches | 823b794 | 2013-11-12 15:10:15 -0800 | [diff] [blame] | 6894 | ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && |
| 6895 | $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && |
| 6896 | $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { |
| 6897 | my $lc = $stat =~ tr@\n@@; |
| 6898 | $lc = $lc + $linenr; |
Tobin C. Harding | 2a9f9d8 | 2018-04-10 16:33:20 -0700 | [diff] [blame] | 6899 | my $stat_real = get_stat_real($linenr, $lc); |
Joe Perches | 823b794 | 2013-11-12 15:10:15 -0800 | [diff] [blame] | 6900 | WARN("NAKED_SSCANF", |
| 6901 | "unchecked sscanf return value\n" . "$here\n$stat_real\n"); |
| 6902 | } |
| 6903 | |
Joe Perches | afc819a | 2014-06-04 16:12:08 -0700 | [diff] [blame] | 6904 | # check for simple sscanf that should be kstrto<foo> |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6905 | if ($perl_version_ok && |
Joe Perches | afc819a | 2014-06-04 16:12:08 -0700 | [diff] [blame] | 6906 | defined $stat && |
| 6907 | $line =~ /\bsscanf\b/) { |
| 6908 | my $lc = $stat =~ tr@\n@@; |
| 6909 | $lc = $lc + $linenr; |
Tobin C. Harding | 2a9f9d8 | 2018-04-10 16:33:20 -0700 | [diff] [blame] | 6910 | my $stat_real = get_stat_real($linenr, $lc); |
Joe Perches | afc819a | 2014-06-04 16:12:08 -0700 | [diff] [blame] | 6911 | if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { |
| 6912 | my $format = $6; |
| 6913 | my $count = $format =~ tr@%@%@; |
| 6914 | if ($count == 1 && |
| 6915 | $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { |
| 6916 | WARN("SSCANF_TO_KSTRTO", |
| 6917 | "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); |
| 6918 | } |
| 6919 | } |
| 6920 | } |
| 6921 | |
Joe Perches | 70dc8a4 | 2013-09-11 14:23:58 -0700 | [diff] [blame] | 6922 | # check for new externs in .h files. |
| 6923 | if ($realfile =~ /\.h$/ && |
| 6924 | $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { |
Joe Perches | d1d8578 | 2013-09-24 15:27:46 -0700 | [diff] [blame] | 6925 | if (CHK("AVOID_EXTERNS", |
| 6926 | "extern prototypes should be avoided in .h files\n" . $herecurr) && |
Joe Perches | 70dc8a4 | 2013-09-11 14:23:58 -0700 | [diff] [blame] | 6927 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6928 | $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; |
Joe Perches | 70dc8a4 | 2013-09-11 14:23:58 -0700 | [diff] [blame] | 6929 | } |
| 6930 | } |
| 6931 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 6932 | # check for new externs in .c files. |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 6933 | if ($realfile =~ /\.c$/ && defined $stat && |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 6934 | $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 6935 | { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 6936 | my $function_name = $1; |
| 6937 | my $paren_space = $2; |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 6938 | |
| 6939 | my $s = $stat; |
| 6940 | if (defined $cond) { |
| 6941 | substr($s, 0, length($cond), ''); |
| 6942 | } |
Kees Cook | d8b44b5 | 2020-06-03 14:18:09 -0700 | [diff] [blame] | 6943 | if ($s =~ /^\s*;/) |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 6944 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6945 | WARN("AVOID_EXTERNS", |
| 6946 | "externs should be avoided in .c files\n" . $herecurr); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 6947 | } |
| 6948 | |
| 6949 | if ($paren_space =~ /\n/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6950 | WARN("FUNCTION_ARGUMENTS", |
| 6951 | "arguments for function declarations should follow identifier\n" . $herecurr); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 6952 | } |
Andy Whitcroft | 9c9ba34 | 2008-04-29 00:59:33 -0700 | [diff] [blame] | 6953 | |
| 6954 | } elsif ($realfile =~ /\.c$/ && defined $stat && |
| 6955 | $stat =~ /^.\s*extern\s+/) |
| 6956 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6957 | WARN("AVOID_EXTERNS", |
| 6958 | "externs should be avoided in .c files\n" . $herecurr); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 6959 | } |
| 6960 | |
Joe Perches | a0ad759 | 2017-07-10 15:52:19 -0700 | [diff] [blame] | 6961 | # check for function declarations that have arguments without identifier names |
| 6962 | if (defined $stat && |
Kees Cook | d8b44b5 | 2020-06-03 14:18:09 -0700 | [diff] [blame] | 6963 | $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && |
| 6964 | $1 ne "void") { |
| 6965 | my $args = trim($1); |
Joe Perches | ca0d892 | 2016-10-11 13:52:16 -0700 | [diff] [blame] | 6966 | while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { |
| 6967 | my $arg = trim($1); |
Kees Cook | d8b44b5 | 2020-06-03 14:18:09 -0700 | [diff] [blame] | 6968 | if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { |
Joe Perches | ca0d892 | 2016-10-11 13:52:16 -0700 | [diff] [blame] | 6969 | WARN("FUNCTION_ARGUMENTS", |
| 6970 | "function definition argument '$arg' should also have an identifier name\n" . $herecurr); |
| 6971 | } |
| 6972 | } |
| 6973 | } |
| 6974 | |
Joe Perches | a0ad759 | 2017-07-10 15:52:19 -0700 | [diff] [blame] | 6975 | # check for function definitions |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 6976 | if ($perl_version_ok && |
Joe Perches | a0ad759 | 2017-07-10 15:52:19 -0700 | [diff] [blame] | 6977 | defined $stat && |
| 6978 | $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { |
| 6979 | $context_function = $1; |
| 6980 | |
| 6981 | # check for multiline function definition with misplaced open brace |
| 6982 | my $ok = 0; |
| 6983 | my $cnt = statement_rawlines($stat); |
| 6984 | my $herectx = $here . "\n"; |
| 6985 | for (my $n = 0; $n < $cnt; $n++) { |
| 6986 | my $rl = raw_line($linenr, $n); |
| 6987 | $herectx .= $rl . "\n"; |
| 6988 | $ok = 1 if ($rl =~ /^[ \+]\{/); |
| 6989 | $ok = 1 if ($rl =~ /\{/ && $n == 0); |
| 6990 | last if $rl =~ /^[ \+].*\{/; |
| 6991 | } |
| 6992 | if (!$ok) { |
| 6993 | ERROR("OPEN_BRACE", |
| 6994 | "open brace '{' following function definitions go on the next line\n" . $herectx); |
| 6995 | } |
| 6996 | } |
| 6997 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 6998 | # checks for new __setup's |
| 6999 | if ($rawline =~ /\b__setup\("([^"]*)"/) { |
| 7000 | my $name = $1; |
| 7001 | |
| 7002 | if (!grep(/$name/, @setup_docs)) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7003 | CHK("UNDOCUMENTED_SETUP", |
Tim Froidcoeur | 2581ac7 | 2020-06-10 18:41:38 -0700 | [diff] [blame] | 7004 | "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 7005 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 7006 | } |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 7007 | |
Joe Perches | e29a70f | 2019-03-07 16:28:35 -0800 | [diff] [blame] | 7008 | # check for pointless casting of alloc functions |
| 7009 | if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7010 | WARN("UNNECESSARY_CASTS", |
| 7011 | "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 7012 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 7013 | |
Joe Perches | a640d25 | 2013-07-03 15:05:21 -0700 | [diff] [blame] | 7014 | # alloc style |
| 7015 | # p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 7016 | if ($perl_version_ok && |
Joe Perches | e29a70f | 2019-03-07 16:28:35 -0800 | [diff] [blame] | 7017 | $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { |
Joe Perches | a640d25 | 2013-07-03 15:05:21 -0700 | [diff] [blame] | 7018 | CHK("ALLOC_SIZEOF_STRUCT", |
| 7019 | "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); |
| 7020 | } |
| 7021 | |
Joe Perches | 60a5536 | 2014-06-04 16:12:07 -0700 | [diff] [blame] | 7022 | # check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 7023 | if ($perl_version_ok && |
Joe Perches | 1b4a2ed | 2017-05-08 15:55:57 -0700 | [diff] [blame] | 7024 | defined $stat && |
| 7025 | $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { |
Joe Perches | 60a5536 | 2014-06-04 16:12:07 -0700 | [diff] [blame] | 7026 | my $oldfunc = $3; |
| 7027 | my $a1 = $4; |
| 7028 | my $a2 = $10; |
| 7029 | my $newfunc = "kmalloc_array"; |
| 7030 | $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); |
Joe Perches | e367455 | 2014-08-06 16:10:55 -0700 | [diff] [blame] | 7031 | my $r1 = $a1; |
| 7032 | my $r2 = $a2; |
| 7033 | if ($a1 =~ /^sizeof\s*\S/) { |
| 7034 | $r1 = $a2; |
| 7035 | $r2 = $a1; |
| 7036 | } |
| 7037 | if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && |
| 7038 | !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { |
Joe Perches | 1b4a2ed | 2017-05-08 15:55:57 -0700 | [diff] [blame] | 7039 | my $cnt = statement_rawlines($stat); |
Tobin C. Harding | e3d95a2 | 2018-04-10 16:33:27 -0700 | [diff] [blame] | 7040 | my $herectx = get_stat_here($linenr, $cnt, $here); |
| 7041 | |
Joe Perches | 60a5536 | 2014-06-04 16:12:07 -0700 | [diff] [blame] | 7042 | if (WARN("ALLOC_WITH_MULTIPLY", |
Joe Perches | 1b4a2ed | 2017-05-08 15:55:57 -0700 | [diff] [blame] | 7043 | "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && |
| 7044 | $cnt == 1 && |
Joe Perches | 60a5536 | 2014-06-04 16:12:07 -0700 | [diff] [blame] | 7045 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 7046 | $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 Perches | 60a5536 | 2014-06-04 16:12:07 -0700 | [diff] [blame] | 7047 | } |
| 7048 | } |
| 7049 | } |
| 7050 | |
Joe Perches | 972fdea | 2013-04-29 16:18:12 -0700 | [diff] [blame] | 7051 | # check for krealloc arg reuse |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 7052 | if ($perl_version_ok && |
Joe Perches | 4cab63c | 2018-08-21 21:57:50 -0700 | [diff] [blame] | 7053 | $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && |
| 7054 | $1 eq $3) { |
Joe Perches | 972fdea | 2013-04-29 16:18:12 -0700 | [diff] [blame] | 7055 | WARN("KREALLOC_ARG_REUSE", |
| 7056 | "Reusing the krealloc arg is almost always a bug\n" . $herecurr); |
| 7057 | } |
| 7058 | |
Joe Perches | 5ce59ae | 2013-02-21 16:44:18 -0800 | [diff] [blame] | 7059 | # check for alloc argument mismatch |
Christophe JAILLET | 7e6cdd7 | 2021-05-06 18:04:01 -0700 | [diff] [blame] | 7060 | if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) { |
Joe Perches | 5ce59ae | 2013-02-21 16:44:18 -0800 | [diff] [blame] | 7061 | WARN("ALLOC_ARRAY_ARGS", |
| 7062 | "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); |
| 7063 | } |
| 7064 | |
Joe Perches | caf2a54 | 2011-01-12 16:59:56 -0800 | [diff] [blame] | 7065 | # check for multiple semicolons |
| 7066 | if ($line =~ /;\s*;\s*$/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 7067 | if (WARN("ONE_SEMICOLON", |
| 7068 | "Statements terminations use 1 semicolon\n" . $herecurr) && |
| 7069 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 7070 | $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 7071 | } |
Joe Perches | d1e2ad0 | 2012-12-17 16:02:01 -0800 | [diff] [blame] | 7072 | } |
| 7073 | |
Tomas Winkler | cec3aaa | 2016-08-02 14:04:39 -0700 | [diff] [blame] | 7074 | # check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi |
| 7075 | if ($realfile !~ m@^include/uapi/@ && |
| 7076 | $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { |
Joe Perches | 0ab9019 | 2014-12-10 15:51:57 -0800 | [diff] [blame] | 7077 | my $ull = ""; |
| 7078 | $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); |
| 7079 | if (CHK("BIT_MACRO", |
| 7080 | "Prefer using the BIT$ull macro\n" . $herecurr) && |
| 7081 | $fix) { |
| 7082 | $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; |
| 7083 | } |
| 7084 | } |
| 7085 | |
Joe Perches | 5016126 | 2020-08-11 18:35:07 -0700 | [diff] [blame] | 7086 | # check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) |
Jerome Forissier | 3e89ad8 | 2020-10-15 20:11:49 -0700 | [diff] [blame] | 7087 | if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { |
Joe Perches | 5016126 | 2020-08-11 18:35:07 -0700 | [diff] [blame] | 7088 | WARN("IS_ENABLED_CONFIG", |
Jerome Forissier | 3e89ad8 | 2020-10-15 20:11:49 -0700 | [diff] [blame] | 7089 | "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); |
Joe Perches | 5016126 | 2020-08-11 18:35:07 -0700 | [diff] [blame] | 7090 | } |
| 7091 | |
Joe Perches | 2d63274 | 2016-05-20 17:04:00 -0700 | [diff] [blame] | 7092 | # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE |
Jerome Forissier | 3e89ad8 | 2020-10-15 20:11:49 -0700 | [diff] [blame] | 7093 | 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 Perches | 2d63274 | 2016-05-20 17:04:00 -0700 | [diff] [blame] | 7094 | my $config = $1; |
| 7095 | if (WARN("PREFER_IS_ENABLED", |
Jerome Forissier | 3e89ad8 | 2020-10-15 20:11:49 -0700 | [diff] [blame] | 7096 | "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && |
Joe Perches | 2d63274 | 2016-05-20 17:04:00 -0700 | [diff] [blame] | 7097 | $fix) { |
| 7098 | $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; |
| 7099 | } |
| 7100 | } |
| 7101 | |
Joe Perches | f36d3eb | 2020-04-06 20:10:58 -0700 | [diff] [blame] | 7102 | # check for /* fallthrough */ like comment, prefer fallthrough; |
| 7103 | my @fallthroughs = ( |
| 7104 | 'fallthrough', |
| 7105 | '@fallthrough@', |
| 7106 | 'lint -fallthrough[ \t]*', |
| 7107 | 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', |
| 7108 | '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', |
| 7109 | 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', |
| 7110 | 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', |
| 7111 | ); |
| 7112 | if ($raw_comment ne '') { |
| 7113 | foreach my $ft (@fallthroughs) { |
| 7114 | if ($raw_comment =~ /$ft/) { |
| 7115 | my $msg_level = \&WARN; |
| 7116 | $msg_level = \&CHK if ($file); |
| 7117 | &{$msg_level}("PREFER_FALLTHROUGH", |
| 7118 | "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); |
| 7119 | last; |
| 7120 | } |
| 7121 | } |
| 7122 | } |
| 7123 | |
Joe Perches | d1e2ad0 | 2012-12-17 16:02:01 -0800 | [diff] [blame] | 7124 | # check for switch/default statements without a break; |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 7125 | if ($perl_version_ok && |
Joe Perches | d1e2ad0 | 2012-12-17 16:02:01 -0800 | [diff] [blame] | 7126 | defined $stat && |
| 7127 | $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { |
Joe Perches | d1e2ad0 | 2012-12-17 16:02:01 -0800 | [diff] [blame] | 7128 | my $cnt = statement_rawlines($stat); |
Tobin C. Harding | e3d95a2 | 2018-04-10 16:33:27 -0700 | [diff] [blame] | 7129 | my $herectx = get_stat_here($linenr, $cnt, $here); |
| 7130 | |
Joe Perches | d1e2ad0 | 2012-12-17 16:02:01 -0800 | [diff] [blame] | 7131 | WARN("DEFAULT_NO_BREAK", |
| 7132 | "switch default: should use break\n" . $herectx); |
Joe Perches | caf2a54 | 2011-01-12 16:59:56 -0800 | [diff] [blame] | 7133 | } |
| 7134 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 7135 | # check for gcc specific __FUNCTION__ |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 7136 | if ($line =~ /\b__FUNCTION__\b/) { |
| 7137 | if (WARN("USE_FUNC", |
| 7138 | "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && |
| 7139 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 7140 | $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 7141 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 7142 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 7143 | |
Joe Perches | 62ec818 | 2015-02-13 14:38:18 -0800 | [diff] [blame] | 7144 | # check for uses of __DATE__, __TIME__, __TIMESTAMP__ |
| 7145 | while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { |
| 7146 | ERROR("DATE_TIME", |
| 7147 | "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); |
| 7148 | } |
| 7149 | |
Joe Perches | 2c92488 | 2012-03-23 15:02:20 -0700 | [diff] [blame] | 7150 | # check for use of yield() |
| 7151 | if ($line =~ /\byield\s*\(\s*\)/) { |
| 7152 | WARN("YIELD", |
| 7153 | "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); |
| 7154 | } |
| 7155 | |
Joe Perches | 179f8f4 | 2013-07-03 15:05:30 -0700 | [diff] [blame] | 7156 | # check for comparisons against true and false |
| 7157 | if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { |
| 7158 | my $lead = $1; |
| 7159 | my $arg = $2; |
| 7160 | my $test = $3; |
| 7161 | my $otype = $4; |
| 7162 | my $trail = $5; |
| 7163 | my $op = "!"; |
| 7164 | |
| 7165 | ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); |
| 7166 | |
| 7167 | my $type = lc($otype); |
| 7168 | if ($type =~ /^(?:true|false)$/) { |
| 7169 | if (("$test" eq "==" && "$type" eq "true") || |
| 7170 | ("$test" eq "!=" && "$type" eq "false")) { |
| 7171 | $op = ""; |
| 7172 | } |
| 7173 | |
| 7174 | CHK("BOOL_COMPARISON", |
| 7175 | "Using comparison to $otype is error prone\n" . $herecurr); |
| 7176 | |
| 7177 | ## maybe suggesting a correct construct would better |
| 7178 | ## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); |
| 7179 | |
| 7180 | } |
| 7181 | } |
| 7182 | |
Thomas Gleixner | 4882720b | 2010-09-07 14:34:01 +0000 | [diff] [blame] | 7183 | # check for semaphores initialized locked |
| 7184 | if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7185 | WARN("CONSIDER_COMPLETION", |
| 7186 | "consider using a completion\n" . $herecurr); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 7187 | } |
Joe Perches | 6712d85 | 2012-03-23 15:02:20 -0700 | [diff] [blame] | 7188 | |
Joe Perches | 67d0a07 | 2011-10-31 17:13:10 -0700 | [diff] [blame] | 7189 | # recommend kstrto* over simple_strto* and strict_strto* |
| 7190 | if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7191 | WARN("CONSIDER_KSTRTO", |
Joe Perches | 67d0a07 | 2011-10-31 17:13:10 -0700 | [diff] [blame] | 7192 | "$1 is obsolete, use k$3 instead\n" . $herecurr); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 7193 | } |
Joe Perches | 6712d85 | 2012-03-23 15:02:20 -0700 | [diff] [blame] | 7194 | |
Fabian Frederick | ae3ccc4 | 2014-06-04 16:12:10 -0700 | [diff] [blame] | 7195 | # check for __initcall(), use device_initcall() explicitly or more appropriate function please |
Michael Ellerman | f3db663 | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 7196 | if ($line =~ /^.\s*__initcall\s*\(/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7197 | WARN("USE_DEVICE_INITCALL", |
Fabian Frederick | ae3ccc4 | 2014-06-04 16:12:10 -0700 | [diff] [blame] | 7198 | "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); |
Michael Ellerman | f3db663 | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 7199 | } |
Joe Perches | 6712d85 | 2012-03-23 15:02:20 -0700 | [diff] [blame] | 7200 | |
Paul E. McKenney | 3d709ab | 2018-11-11 10:49:10 -0800 | [diff] [blame] | 7201 | # check for spin_is_locked(), suggest lockdep instead |
| 7202 | if ($line =~ /\bspin_is_locked\(/) { |
| 7203 | WARN("USE_LOCKDEP", |
| 7204 | "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); |
| 7205 | } |
| 7206 | |
Joe Perches | 9189c7e | 2018-09-07 15:26:18 -0700 | [diff] [blame] | 7207 | # check for deprecated apis |
| 7208 | if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { |
| 7209 | my $deprecated_api = $1; |
| 7210 | my $new_api = $deprecated_apis{$deprecated_api}; |
| 7211 | WARN("DEPRECATED_API", |
| 7212 | "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); |
| 7213 | } |
| 7214 | |
Joe Perches | 0f3c5aa | 2015-02-13 14:39:05 -0800 | [diff] [blame] | 7215 | # check for various structs that are normally const (ops, kgdb, device_tree) |
Joe Perches | d9190e4 | 2017-05-08 15:55:45 -0700 | [diff] [blame] | 7216 | # and avoid what seem like struct definitions 'struct foo {' |
Quentin Monnet | ced69da1 | 2020-08-11 18:35:13 -0700 | [diff] [blame] | 7217 | if (defined($const_structs) && |
| 7218 | $line !~ /\bconst\b/ && |
Joe Perches | d9190e4 | 2017-05-08 15:55:45 -0700 | [diff] [blame] | 7219 | $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7220 | WARN("CONST_STRUCT", |
Joe Perches | d9190e4 | 2017-05-08 15:55:45 -0700 | [diff] [blame] | 7221 | "struct $1 should normally be const\n" . $herecurr); |
Andy Whitcroft | 2b6db5c | 2009-01-06 14:41:29 -0800 | [diff] [blame] | 7222 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 7223 | |
| 7224 | # use of NR_CPUS is usually wrong |
| 7225 | # ignore definitions of NR_CPUS and usage to define arrays as likely right |
Peng Wang | 35cdcbf | 2021-02-25 17:21:44 -0800 | [diff] [blame] | 7226 | # ignore designated initializers using NR_CPUS |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 7227 | if ($line =~ /\bNR_CPUS\b/ && |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 7228 | $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && |
| 7229 | $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 7230 | $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && |
| 7231 | $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && |
Peng Wang | 35cdcbf | 2021-02-25 17:21:44 -0800 | [diff] [blame] | 7232 | $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ && |
| 7233 | $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/) |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 7234 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7235 | WARN("NR_CPUS", |
| 7236 | "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 7237 | } |
Andy Whitcroft | 9c9ba34 | 2008-04-29 00:59:33 -0700 | [diff] [blame] | 7238 | |
Joe Perches | 52ea850 | 2013-11-12 15:10:09 -0800 | [diff] [blame] | 7239 | # Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. |
| 7240 | if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { |
| 7241 | ERROR("DEFINE_ARCH_HAS", |
| 7242 | "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); |
| 7243 | } |
| 7244 | |
Joe Perches | acd9362 | 2015-02-13 14:38:38 -0800 | [diff] [blame] | 7245 | # likely/unlikely comparisons similar to "(likely(foo) > 0)" |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 7246 | if ($perl_version_ok && |
Joe Perches | acd9362 | 2015-02-13 14:38:38 -0800 | [diff] [blame] | 7247 | $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { |
| 7248 | WARN("LIKELY_MISUSE", |
| 7249 | "Using $1 should generally have parentheses around the comparison\n" . $herecurr); |
| 7250 | } |
| 7251 | |
Joe Perches | fbe7454 | 2021-05-06 18:03:55 -0700 | [diff] [blame] | 7252 | # return sysfs_emit(foo, fmt, ...) fmt without newline |
| 7253 | if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ && |
| 7254 | substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) { |
| 7255 | my $offset = $+[6] - 1; |
| 7256 | if (WARN("SYSFS_EMIT", |
| 7257 | "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) && |
| 7258 | $fix) { |
| 7259 | substr($fixed[$fixlinenr], $offset, 0) = '\\n'; |
| 7260 | } |
| 7261 | } |
| 7262 | |
Denis Efremov | de3f186 | 2019-09-25 16:49:25 -0700 | [diff] [blame] | 7263 | # nested likely/unlikely calls |
| 7264 | if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { |
| 7265 | WARN("LIKELY_MISUSE", |
| 7266 | "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); |
| 7267 | } |
| 7268 | |
Andy Whitcroft | 691d77b | 2009-01-06 14:41:16 -0800 | [diff] [blame] | 7269 | # whine mightly about in_atomic |
| 7270 | if ($line =~ /\bin_atomic\s*\(/) { |
| 7271 | if ($realfile =~ m@^drivers/@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7272 | ERROR("IN_ATOMIC", |
| 7273 | "do not use in_atomic in drivers\n" . $herecurr); |
Andy Whitcroft | f4a8773 | 2009-02-27 14:03:05 -0800 | [diff] [blame] | 7274 | } elsif ($realfile !~ m@^kernel/@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7275 | WARN("IN_ATOMIC", |
| 7276 | "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); |
Andy Whitcroft | 691d77b | 2009-01-06 14:41:16 -0800 | [diff] [blame] | 7277 | } |
| 7278 | } |
Peter Zijlstra | 1704f47 | 2010-03-19 01:37:42 +0100 | [diff] [blame] | 7279 | |
| 7280 | # check for lockdep_set_novalidate_class |
| 7281 | if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || |
| 7282 | $line =~ /__lockdep_no_validate__\s*\)/ ) { |
| 7283 | if ($realfile !~ m@^kernel/lockdep@ && |
| 7284 | $realfile !~ m@^include/linux/lockdep@ && |
| 7285 | $realfile !~ m@^drivers/base/core@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7286 | ERROR("LOCKDEP", |
| 7287 | "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); |
Peter Zijlstra | 1704f47 | 2010-03-19 01:37:42 +0100 | [diff] [blame] | 7288 | } |
| 7289 | } |
Dave Jones | 88f8831 | 2011-01-12 16:59:59 -0800 | [diff] [blame] | 7290 | |
Joe Perches | b392c64 | 2015-04-16 12:44:16 -0700 | [diff] [blame] | 7291 | if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || |
| 7292 | $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7293 | WARN("EXPORTED_WORLD_WRITABLE", |
| 7294 | "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); |
Dave Jones | 88f8831 | 2011-01-12 16:59:59 -0800 | [diff] [blame] | 7295 | } |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 7296 | |
Joe Perches | 0018046 | 2018-02-06 15:38:55 -0800 | [diff] [blame] | 7297 | # check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> |
| 7298 | # and whether or not function naming is typical and if |
| 7299 | # DEVICE_ATTR permissions uses are unusual too |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 7300 | if ($perl_version_ok && |
Joe Perches | 0018046 | 2018-02-06 15:38:55 -0800 | [diff] [blame] | 7301 | defined $stat && |
| 7302 | $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*\)/) { |
| 7303 | my $var = $1; |
| 7304 | my $perms = $2; |
| 7305 | my $show = $3; |
| 7306 | my $store = $4; |
| 7307 | my $octal_perms = perms_to_octal($perms); |
| 7308 | if ($show =~ /^${var}_show$/ && |
| 7309 | $store =~ /^${var}_store$/ && |
| 7310 | $octal_perms eq "0644") { |
| 7311 | if (WARN("DEVICE_ATTR_RW", |
| 7312 | "Use DEVICE_ATTR_RW\n" . $herecurr) && |
| 7313 | $fix) { |
| 7314 | $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/; |
| 7315 | } |
| 7316 | } elsif ($show =~ /^${var}_show$/ && |
| 7317 | $store =~ /^NULL$/ && |
| 7318 | $octal_perms eq "0444") { |
| 7319 | if (WARN("DEVICE_ATTR_RO", |
| 7320 | "Use DEVICE_ATTR_RO\n" . $herecurr) && |
| 7321 | $fix) { |
| 7322 | $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/; |
| 7323 | } |
| 7324 | } elsif ($show =~ /^NULL$/ && |
| 7325 | $store =~ /^${var}_store$/ && |
| 7326 | $octal_perms eq "0200") { |
| 7327 | if (WARN("DEVICE_ATTR_WO", |
| 7328 | "Use DEVICE_ATTR_WO\n" . $herecurr) && |
| 7329 | $fix) { |
| 7330 | $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/; |
| 7331 | } |
| 7332 | } elsif ($octal_perms eq "0644" || |
| 7333 | $octal_perms eq "0444" || |
| 7334 | $octal_perms eq "0200") { |
| 7335 | my $newshow = "$show"; |
| 7336 | $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); |
| 7337 | my $newstore = $store; |
| 7338 | $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); |
| 7339 | my $rename = ""; |
| 7340 | if ($show ne $newshow) { |
| 7341 | $rename .= " '$show' to '$newshow'"; |
| 7342 | } |
| 7343 | if ($store ne $newstore) { |
| 7344 | $rename .= " '$store' to '$newstore'"; |
| 7345 | } |
| 7346 | WARN("DEVICE_ATTR_FUNCTIONS", |
| 7347 | "Consider renaming function(s)$rename\n" . $herecurr); |
| 7348 | } else { |
| 7349 | WARN("DEVICE_ATTR_PERMS", |
| 7350 | "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); |
| 7351 | } |
| 7352 | } |
| 7353 | |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 7354 | # Mode permission misuses where it seems decimal should be octal |
| 7355 | # This uses a shortcut match to avoid unnecessary uses of a slow foreach loop |
Joe Perches | 7312153 | 2018-02-06 15:38:49 -0800 | [diff] [blame] | 7356 | # o Ignore module_param*(...) uses with a decimal 0 permission as that has a |
| 7357 | # specific definition of not visible in sysfs. |
| 7358 | # o Ignore proc_create*(...) uses with a decimal 0 permission as that means |
| 7359 | # use the default permissions |
Joe Perches | 5b57980 | 2018-08-21 21:57:33 -0700 | [diff] [blame] | 7360 | if ($perl_version_ok && |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7361 | defined $stat && |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 7362 | $line =~ /$mode_perms_search/) { |
| 7363 | foreach my $entry (@mode_permission_funcs) { |
| 7364 | my $func = $entry->[0]; |
| 7365 | my $arg_pos = $entry->[1]; |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 7366 | |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7367 | my $lc = $stat =~ tr@\n@@; |
| 7368 | $lc = $lc + $linenr; |
Tobin C. Harding | 2a9f9d8 | 2018-04-10 16:33:20 -0700 | [diff] [blame] | 7369 | my $stat_real = get_stat_real($linenr, $lc); |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7370 | |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 7371 | my $skip_args = ""; |
| 7372 | if ($arg_pos > 1) { |
| 7373 | $arg_pos--; |
| 7374 | $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; |
| 7375 | } |
Joe Perches | f90774e | 2016-10-11 13:51:47 -0700 | [diff] [blame] | 7376 | my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7377 | if ($stat =~ /$test/) { |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 7378 | my $val = $1; |
| 7379 | $val = $6 if ($skip_args ne ""); |
Joe Perches | 7312153 | 2018-02-06 15:38:49 -0800 | [diff] [blame] | 7380 | if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && |
| 7381 | (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || |
| 7382 | ($val =~ /^$Octal$/ && length($val) ne 4))) { |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 7383 | ERROR("NON_OCTAL_PERMISSIONS", |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7384 | "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); |
Joe Perches | f90774e | 2016-10-11 13:51:47 -0700 | [diff] [blame] | 7385 | } |
| 7386 | if ($val =~ /^$Octal$/ && (oct($val) & 02)) { |
Joe Perches | c0a5c89 | 2015-02-13 14:38:21 -0800 | [diff] [blame] | 7387 | ERROR("EXPORTED_WORLD_WRITABLE", |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7388 | "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); |
Joe Perches | f90774e | 2016-10-11 13:51:47 -0700 | [diff] [blame] | 7389 | } |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 7390 | } |
| 7391 | } |
| 7392 | } |
Bjorn Andersson | 5a6d20c | 2015-06-25 15:03:24 -0700 | [diff] [blame] | 7393 | |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7394 | # check for uses of S_<PERMS> that could be octal for readability |
Joe Perches | bc22d9a | 2018-04-10 16:33:53 -0700 | [diff] [blame] | 7395 | while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { |
Joe Perches | 0018046 | 2018-02-06 15:38:55 -0800 | [diff] [blame] | 7396 | my $oval = $1; |
| 7397 | my $octal = perms_to_octal($oval); |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7398 | if (WARN("SYMBOLIC_PERMS", |
| 7399 | "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && |
| 7400 | $fix) { |
Joe Perches | 0018046 | 2018-02-06 15:38:55 -0800 | [diff] [blame] | 7401 | $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 7402 | } |
| 7403 | } |
| 7404 | |
Bjorn Andersson | 5a6d20c | 2015-06-25 15:03:24 -0700 | [diff] [blame] | 7405 | # validate content of MODULE_LICENSE against list from include/linux/module.h |
| 7406 | if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { |
| 7407 | my $extracted_string = get_quoted_string($line, $rawline); |
| 7408 | my $valid_licenses = qr{ |
| 7409 | GPL| |
| 7410 | GPL\ v2| |
| 7411 | GPL\ and\ additional\ rights| |
| 7412 | Dual\ BSD/GPL| |
| 7413 | Dual\ MIT/GPL| |
| 7414 | Dual\ MPL/GPL| |
| 7415 | Proprietary |
| 7416 | }x; |
| 7417 | if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { |
| 7418 | WARN("MODULE_LICENSE", |
| 7419 | "unknown module license " . $extracted_string . "\n" . $herecurr); |
| 7420 | } |
| 7421 | } |
Matteo Croce | 6a8d76c | 2019-07-16 16:27:48 -0700 | [diff] [blame] | 7422 | |
| 7423 | # check for sysctl duplicate constants |
| 7424 | if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { |
| 7425 | WARN("DUPLICATED_SYSCTL_CONST", |
| 7426 | "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); |
| 7427 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 7428 | } |
| 7429 | |
| 7430 | # If we have no input at all, then there is nothing to report on |
| 7431 | # so just keep quiet. |
| 7432 | if ($#rawlines == -1) { |
| 7433 | exit(0); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 7434 | } |
| 7435 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 7436 | # In mailback mode only produce a report in the negative, for |
| 7437 | # things that appear to be patches. |
| 7438 | if ($mailback && ($clean == 1 || !$is_patch)) { |
| 7439 | exit(0); |
| 7440 | } |
| 7441 | |
Dwaipayan Ray | e73d271 | 2020-12-15 20:44:56 -0800 | [diff] [blame] | 7442 | # This is not a patch, and we are in 'no-patch' mode so |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 7443 | # just keep quiet. |
| 7444 | if (!$chk_patch && !$is_patch) { |
| 7445 | exit(0); |
| 7446 | } |
| 7447 | |
Stafford Horne | a08ffbe | 2017-10-03 16:16:51 -0700 | [diff] [blame] | 7448 | if (!$is_patch && $filename !~ /cover-letter\.patch$/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 7449 | ERROR("NOT_UNIFIED_DIFF", |
| 7450 | "Does not appear to be a unified-diff format patch\n"); |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 7451 | } |
Geert Uytterhoeven | cd26149 | 2018-08-21 21:57:40 -0700 | [diff] [blame] | 7452 | if ($is_patch && $has_commit_log && $chk_signoff) { |
| 7453 | if ($signoff == 0) { |
| 7454 | ERROR("MISSING_SIGN_OFF", |
| 7455 | "Missing Signed-off-by: line(s)\n"); |
Dwaipayan Ray | 48ca2d8 | 2020-10-15 20:12:28 -0700 | [diff] [blame] | 7456 | } elsif ($authorsignoff != 1) { |
| 7457 | # authorsignoff values: |
| 7458 | # 0 -> missing sign off |
| 7459 | # 1 -> sign off identical |
| 7460 | # 2 -> names and addresses match, comments mismatch |
| 7461 | # 3 -> addresses match, names different |
| 7462 | # 4 -> names match, addresses different |
| 7463 | # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match |
| 7464 | |
| 7465 | my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; |
| 7466 | |
| 7467 | if ($authorsignoff == 0) { |
| 7468 | ERROR("NO_AUTHOR_SIGN_OFF", |
| 7469 | "Missing Signed-off-by: line by nominal patch author '$author'\n"); |
| 7470 | } elsif ($authorsignoff == 2) { |
| 7471 | CHK("FROM_SIGN_OFF_MISMATCH", |
| 7472 | "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); |
| 7473 | } elsif ($authorsignoff == 3) { |
| 7474 | WARN("FROM_SIGN_OFF_MISMATCH", |
| 7475 | "From:/Signed-off-by: email name mismatch: $sob_msg\n"); |
| 7476 | } elsif ($authorsignoff == 4) { |
| 7477 | WARN("FROM_SIGN_OFF_MISMATCH", |
| 7478 | "From:/Signed-off-by: email address mismatch: $sob_msg\n"); |
| 7479 | } elsif ($authorsignoff == 5) { |
| 7480 | WARN("FROM_SIGN_OFF_MISMATCH", |
| 7481 | "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); |
| 7482 | } |
Geert Uytterhoeven | cd26149 | 2018-08-21 21:57:40 -0700 | [diff] [blame] | 7483 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 7484 | } |
| 7485 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 7486 | print report_dump(); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 7487 | if ($summary && !($clean == 1 && $quiet == 1)) { |
| 7488 | print "$filename " if ($summary_file); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 7489 | print "total: $cnt_error errors, $cnt_warn warnings, " . |
| 7490 | (($check)? "$cnt_chk checks, " : "") . |
| 7491 | "$cnt_lines lines checked\n"; |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 7492 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 7493 | |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 7494 | if ($quiet == 0) { |
Joe Perches | ef21219 | 2016-05-20 17:04:11 -0700 | [diff] [blame] | 7495 | # If there were any defects found and not already fixing them |
| 7496 | if (!$clean and !$fix) { |
| 7497 | print << "EOM" |
| 7498 | |
| 7499 | NOTE: For some of the reported defects, checkpatch may be able to |
| 7500 | mechanically convert to the typical style using --fix or --fix-inplace. |
| 7501 | EOM |
| 7502 | } |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 7503 | # If there were whitespace errors which cleanpatch can fix |
| 7504 | # then suggest that. |
| 7505 | if ($rpt_cleaners) { |
Mike Frysinger | b078121 | 2011-03-22 16:34:43 -0700 | [diff] [blame] | 7506 | $rpt_cleaners = 0; |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 7507 | print << "EOM" |
| 7508 | |
| 7509 | NOTE: Whitespace errors detected. |
| 7510 | You may wish to use scripts/cleanpatch or scripts/cleanfile |
| 7511 | EOM |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 7512 | } |
| 7513 | } |
| 7514 | |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 7515 | if ($clean == 0 && $fix && |
| 7516 | ("@rawlines" ne "@fixed" || |
| 7517 | $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 7518 | my $newfile = $filename; |
| 7519 | $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 7520 | my $linecount = 0; |
| 7521 | my $f; |
| 7522 | |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 7523 | @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); |
| 7524 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 7525 | open($f, '>', $newfile) |
| 7526 | or die "$P: Can't open $newfile for write\n"; |
| 7527 | foreach my $fixed_line (@fixed) { |
| 7528 | $linecount++; |
| 7529 | if ($file) { |
| 7530 | if ($linecount > 3) { |
| 7531 | $fixed_line =~ s/^\+//; |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 7532 | print $f $fixed_line . "\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 7533 | } |
| 7534 | } else { |
| 7535 | print $f $fixed_line . "\n"; |
| 7536 | } |
| 7537 | } |
| 7538 | close($f); |
| 7539 | |
| 7540 | if (!$quiet) { |
| 7541 | print << "EOM"; |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 7542 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 7543 | Wrote EXPERIMENTAL --fix correction(s) to '$newfile' |
| 7544 | |
| 7545 | Do _NOT_ trust the results written to this file. |
| 7546 | Do _NOT_ submit these changes without inspecting them for correctness. |
| 7547 | |
| 7548 | This EXPERIMENTAL file is simply a convenience to help rewrite patches. |
| 7549 | No warranties, expressed or implied... |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 7550 | EOM |
| 7551 | } |
| 7552 | } |
| 7553 | |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 7554 | if ($quiet == 0) { |
| 7555 | print "\n"; |
| 7556 | if ($clean == 1) { |
| 7557 | print "$vname has no obvious style problems and is ready for submission.\n"; |
| 7558 | } else { |
| 7559 | print "$vname has style problems, please review.\n"; |
| 7560 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 7561 | } |
Andy Whitcroft | 0a920b5b | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 7562 | return $clean; |
| 7563 | } |