Kamil Rytarowski | cb77f0d | 2017-05-07 23:25:26 +0200 | [diff] [blame] | 1 | #!/usr/bin/env perl |
Dave Jones | dbf004d | 2010-01-12 16:59:52 -0500 | [diff] [blame] | 2 | # (c) 2001, Dave Jones. (the file handling bit) |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3 | # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) |
Andy Whitcroft | 2a5a2c2 | 2009-01-06 14:41:23 -0800 | [diff] [blame] | 4 | # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) |
Andy Whitcroft | 015830b | 2010-10-26 14:23:17 -0700 | [diff] [blame] | 5 | # (c) 2008-2010 Andy Whitcroft <apw@canonical.com> |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 6 | # Licensed under the terms of the GNU GPL License version 2 |
| 7 | |
| 8 | use strict; |
Kamil Rytarowski | cb77f0d | 2017-05-07 23:25:26 +0200 | [diff] [blame] | 9 | use warnings; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 10 | use POSIX; |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 11 | use File::Basename; |
| 12 | use Cwd 'abs_path'; |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 13 | use Term::ANSIColor qw(:constants); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 14 | |
| 15 | my $P = $0; |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 16 | my $D = dirname(abs_path($P)); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 17 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 18 | my $V = '0.32'; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 19 | |
| 20 | use Getopt::Long qw(:config no_auto_abbrev); |
| 21 | |
| 22 | my $quiet = 0; |
| 23 | my $tree = 1; |
| 24 | my $chk_signoff = 1; |
| 25 | my $chk_patch = 1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 26 | my $tst_only; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 27 | my $emacs = 0; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 28 | my $terse = 0; |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 29 | my $showfile = 0; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 30 | my $file = 0; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 31 | my $git = 0; |
Joe Perches | 0dea9f1 | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 32 | my %git_commits = (); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 33 | my $check = 0; |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 34 | my $check_orig = 0; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 35 | my $summary = 1; |
| 36 | my $mailback = 0; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 37 | my $summary_file = 0; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 38 | my $show_types = 0; |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 39 | my $list_types = 0; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 40 | my $fix = 0; |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 41 | my $fix_inplace = 0; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 42 | my $root; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 43 | my %debug; |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 44 | my %camelcase = (); |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 45 | my %use_type = (); |
| 46 | my @use = (); |
| 47 | my %ignore_type = (); |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 48 | my @ignore = (); |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 49 | my $help = 0; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 50 | my $configuration_file = ".checkpatch.conf"; |
Joe Perches | 6cd7f38 | 2012-12-17 16:01:54 -0800 | [diff] [blame] | 51 | my $max_line_length = 80; |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 52 | my $ignore_perl_version = 0; |
| 53 | my $minimum_perl_version = 5.10.0; |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 54 | my $min_conf_desc_length = 4; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 55 | my $spelling_file = "$D/spelling.txt"; |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 56 | my $codespell = 0; |
Maxim Uvarov | f1a6367 | 2015-06-25 15:03:08 -0700 | [diff] [blame] | 57 | my $codespellfile = "/usr/share/codespell/dictionary.txt"; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 58 | my $conststructsfile = "$D/const_structs.checkpatch"; |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 59 | my $typedefsfile = ""; |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 60 | my $color = "auto"; |
Joe Perches | dadf680 | 2016-08-02 14:04:33 -0700 | [diff] [blame] | 61 | my $allow_c99_comments = 1; |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 62 | |
| 63 | sub help { |
| 64 | my ($exitcode) = @_; |
| 65 | |
| 66 | print << "EOM"; |
| 67 | Usage: $P [OPTION]... [FILE]... |
| 68 | Version: $V |
| 69 | |
| 70 | Options: |
| 71 | -q, --quiet quiet |
| 72 | --no-tree run without a kernel tree |
| 73 | --no-signoff do not check for 'Signed-off-by' line |
| 74 | --patch treat FILE as patchfile (default) |
| 75 | --emacs emacs compile window format |
| 76 | --terse one line per report |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 77 | --showfile emit diffed file position, not input file position |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 78 | -g, --git treat FILE as a single commit or git revision range |
| 79 | single git commit with: |
| 80 | <rev> |
| 81 | <rev>^ |
| 82 | <rev>~n |
| 83 | multiple git commits with: |
| 84 | <rev1>..<rev2> |
| 85 | <rev1>...<rev2> |
| 86 | <rev>-<count> |
| 87 | git merges are ignored |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 88 | -f, --file treat FILE as regular source file |
| 89 | --subjective, --strict enable more subjective tests |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 90 | --list-types list the possible message types |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 91 | --types TYPE(,TYPE2...) show only these comma separated message types |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 92 | --ignore TYPE(,TYPE2...) ignore various comma separated message types |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 93 | --show-types show the specific message type in the output |
Joe Perches | 6cd7f38 | 2012-12-17 16:01:54 -0800 | [diff] [blame] | 94 | --max-line-length=n set the maximum line length, if exceeded, warn |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 95 | --min-conf-desc-length=n set the min description length, if shorter, warn |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 96 | --root=PATH PATH to the kernel tree root |
| 97 | --no-summary suppress the per-file summary |
| 98 | --mailback only produce a report in case of warnings/errors |
| 99 | --summary-file include the filename in summary |
| 100 | --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of |
| 101 | 'values', 'possible', 'type', and 'attr' (default |
| 102 | is all off) |
| 103 | --test-only=WORD report only warnings/errors containing WORD |
| 104 | literally |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 105 | --fix EXPERIMENTAL - may create horrible results |
| 106 | If correctable single-line errors exist, create |
| 107 | "<inputfile>.EXPERIMENTAL-checkpatch-fixes" |
| 108 | with potential errors corrected to the preferred |
| 109 | checkpatch style |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 110 | --fix-inplace EXPERIMENTAL - may create horrible results |
| 111 | Is the same as --fix, but overwrites the input |
| 112 | file. It's your fault if there's no backup or git |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 113 | --ignore-perl-version override checking of perl version. expect |
| 114 | runtime errors. |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 115 | --codespell Use the codespell dictionary for spelling/typos |
Maxim Uvarov | f1a6367 | 2015-06-25 15:03:08 -0700 | [diff] [blame] | 116 | (default:/usr/share/codespell/dictionary.txt) |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 117 | --codespellfile Use this codespell dictionary |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 118 | --typedefsfile Read additional types from this file |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 119 | --color[=WHEN] Use colors 'always', 'never', or only when output |
| 120 | is a terminal ('auto'). Default is 'auto'. |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 121 | -h, --help, --version display this help and exit |
| 122 | |
| 123 | When FILE is - read standard input. |
| 124 | EOM |
| 125 | |
| 126 | exit($exitcode); |
| 127 | } |
| 128 | |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 129 | sub uniq { |
| 130 | my %seen; |
| 131 | return grep { !$seen{$_}++ } @_; |
| 132 | } |
| 133 | |
| 134 | sub list_types { |
| 135 | my ($exitcode) = @_; |
| 136 | |
| 137 | my $count = 0; |
| 138 | |
| 139 | local $/ = undef; |
| 140 | |
| 141 | open(my $script, '<', abs_path($P)) or |
| 142 | die "$P: Can't read '$P' $!\n"; |
| 143 | |
| 144 | my $text = <$script>; |
| 145 | close($script); |
| 146 | |
| 147 | my @types = (); |
| 148 | for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) { |
| 149 | push (@types, $_); |
| 150 | } |
| 151 | @types = sort(uniq(@types)); |
| 152 | print("#\tMessage type\n\n"); |
| 153 | foreach my $type (@types) { |
| 154 | print(++$count . "\t" . $type . "\n"); |
| 155 | } |
| 156 | |
| 157 | exit($exitcode); |
| 158 | } |
| 159 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 160 | my $conf = which_conf($configuration_file); |
| 161 | if (-f $conf) { |
| 162 | my @conf_args; |
| 163 | open(my $conffile, '<', "$conf") |
| 164 | or warn "$P: Can't find a readable $configuration_file file $!\n"; |
| 165 | |
| 166 | while (<$conffile>) { |
| 167 | my $line = $_; |
| 168 | |
| 169 | $line =~ s/\s*\n?$//g; |
| 170 | $line =~ s/^\s*//g; |
| 171 | $line =~ s/\s+/ /g; |
| 172 | |
| 173 | next if ($line =~ m/^\s*#/); |
| 174 | next if ($line =~ m/^\s*$/); |
| 175 | |
| 176 | my @words = split(" ", $line); |
| 177 | foreach my $word (@words) { |
| 178 | last if ($word =~ m/^#/); |
| 179 | push (@conf_args, $word); |
| 180 | } |
| 181 | } |
| 182 | close($conffile); |
| 183 | unshift(@ARGV, @conf_args) if @conf_args; |
| 184 | } |
| 185 | |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 186 | # Perl's Getopt::Long allows options to take optional arguments after a space. |
| 187 | # Prevent --color by itself from consuming other arguments |
| 188 | foreach (@ARGV) { |
| 189 | if ($_ eq "--color" || $_ eq "-color") { |
| 190 | $_ = "--color=$color"; |
| 191 | } |
| 192 | } |
| 193 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 194 | GetOptions( |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 195 | 'q|quiet+' => \$quiet, |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 196 | 'tree!' => \$tree, |
| 197 | 'signoff!' => \$chk_signoff, |
| 198 | 'patch!' => \$chk_patch, |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 199 | 'emacs!' => \$emacs, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 200 | 'terse!' => \$terse, |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 201 | 'showfile!' => \$showfile, |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 202 | 'f|file!' => \$file, |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 203 | 'g|git!' => \$git, |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 204 | 'subjective!' => \$check, |
| 205 | 'strict!' => \$check, |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 206 | 'ignore=s' => \@ignore, |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 207 | 'types=s' => \@use, |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 208 | 'show-types!' => \$show_types, |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 209 | 'list-types!' => \$list_types, |
Joe Perches | 6cd7f38 | 2012-12-17 16:01:54 -0800 | [diff] [blame] | 210 | 'max-line-length=i' => \$max_line_length, |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 211 | 'min-conf-desc-length=i' => \$min_conf_desc_length, |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 212 | 'root=s' => \$root, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 213 | 'summary!' => \$summary, |
| 214 | 'mailback!' => \$mailback, |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 215 | 'summary-file!' => \$summary_file, |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 216 | 'fix!' => \$fix, |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 217 | 'fix-inplace!' => \$fix_inplace, |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 218 | 'ignore-perl-version!' => \$ignore_perl_version, |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 219 | 'debug=s' => \%debug, |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 220 | 'test-only=s' => \$tst_only, |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 221 | 'codespell!' => \$codespell, |
| 222 | 'codespellfile=s' => \$codespellfile, |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 223 | 'typedefsfile=s' => \$typedefsfile, |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 224 | 'color=s' => \$color, |
| 225 | 'no-color' => \$color, #keep old behaviors of -nocolor |
| 226 | 'nocolor' => \$color, #keep old behaviors of -nocolor |
Hannes Eder | 77f5b10 | 2009-09-21 17:04:37 -0700 | [diff] [blame] | 227 | 'h|help' => \$help, |
| 228 | 'version' => \$help |
| 229 | ) or help(1); |
| 230 | |
| 231 | help(0) if ($help); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 232 | |
Joe Perches | 3beb42e | 2016-05-20 17:04:14 -0700 | [diff] [blame] | 233 | list_types(0) if ($list_types); |
| 234 | |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 235 | $fix = 1 if ($fix_inplace); |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 236 | $check_orig = $check; |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 237 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 238 | my $exit = 0; |
| 239 | |
Dave Hansen | d62a201 | 2013-09-11 14:23:56 -0700 | [diff] [blame] | 240 | if ($^V && $^V lt $minimum_perl_version) { |
| 241 | printf "$P: requires at least perl version %vd\n", $minimum_perl_version; |
| 242 | if (!$ignore_perl_version) { |
| 243 | exit(1); |
| 244 | } |
| 245 | } |
| 246 | |
Allen Hubbe | 45107ff | 2016-08-02 14:04:47 -0700 | [diff] [blame] | 247 | #if no filenames are given, push '-' to read patch from stdin |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 248 | if ($#ARGV < 0) { |
Allen Hubbe | 45107ff | 2016-08-02 14:04:47 -0700 | [diff] [blame] | 249 | push(@ARGV, '-'); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 250 | } |
| 251 | |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 252 | if ($color =~ /^[01]$/) { |
| 253 | $color = !$color; |
| 254 | } elsif ($color =~ /^always$/i) { |
| 255 | $color = 1; |
| 256 | } elsif ($color =~ /^never$/i) { |
| 257 | $color = 0; |
| 258 | } elsif ($color =~ /^auto$/i) { |
| 259 | $color = (-t STDOUT); |
| 260 | } else { |
| 261 | die "Invalid color mode: $color\n"; |
| 262 | } |
| 263 | |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 264 | sub hash_save_array_words { |
| 265 | my ($hashRef, $arrayRef) = @_; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 266 | |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 267 | my @array = split(/,/, join(',', @$arrayRef)); |
| 268 | foreach my $word (@array) { |
| 269 | $word =~ s/\s*\n?$//g; |
| 270 | $word =~ s/^\s*//g; |
| 271 | $word =~ s/\s+/ /g; |
| 272 | $word =~ tr/[a-z]/[A-Z]/; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 273 | |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 274 | next if ($word =~ m/^\s*#/); |
| 275 | next if ($word =~ m/^\s*$/); |
| 276 | |
| 277 | $hashRef->{$word}++; |
| 278 | } |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 279 | } |
| 280 | |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 281 | sub hash_show_words { |
| 282 | my ($hashRef, $prefix) = @_; |
| 283 | |
Joe Perches | 3c816e4 | 2015-06-25 15:03:29 -0700 | [diff] [blame] | 284 | if (keys %$hashRef) { |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 285 | print "\nNOTE: $prefix message types:"; |
Joe Perches | 58cb3cf | 2013-09-11 14:24:04 -0700 | [diff] [blame] | 286 | foreach my $word (sort keys %$hashRef) { |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 287 | print " $word"; |
| 288 | } |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 289 | print "\n"; |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 290 | } |
| 291 | } |
| 292 | |
| 293 | hash_save_array_words(\%ignore_type, \@ignore); |
| 294 | hash_save_array_words(\%use_type, \@use); |
| 295 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 296 | my $dbg_values = 0; |
| 297 | my $dbg_possible = 0; |
Andy Whitcroft | 7429c69 | 2008-07-23 21:29:06 -0700 | [diff] [blame] | 298 | my $dbg_type = 0; |
Andy Whitcroft | a1ef277 | 2008-10-15 22:02:17 -0700 | [diff] [blame] | 299 | my $dbg_attr = 0; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 300 | for my $key (keys %debug) { |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 301 | ## no critic |
| 302 | eval "\${dbg_$key} = '$debug{$key}';"; |
| 303 | die "$@" if ($@); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 304 | } |
| 305 | |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 306 | my $rpt_cleaners = 0; |
| 307 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 308 | if ($terse) { |
| 309 | $emacs = 1; |
| 310 | $quiet++; |
| 311 | } |
| 312 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 313 | if ($tree) { |
| 314 | if (defined $root) { |
| 315 | if (!top_of_kernel_tree($root)) { |
| 316 | die "$P: $root: --root does not point at a valid tree\n"; |
| 317 | } |
| 318 | } else { |
| 319 | if (top_of_kernel_tree('.')) { |
| 320 | $root = '.'; |
| 321 | } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && |
| 322 | top_of_kernel_tree($1)) { |
| 323 | $root = $1; |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | if (!defined $root) { |
| 328 | print "Must be run from the top-level dir. of a kernel tree\n"; |
| 329 | exit(2); |
| 330 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 331 | } |
| 332 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 333 | my $emitted_corrupt = 0; |
| 334 | |
Andy Whitcroft | 2ceb532 | 2009-10-26 16:50:14 -0700 | [diff] [blame] | 335 | our $Ident = qr{ |
| 336 | [A-Za-z_][A-Za-z\d_]* |
| 337 | (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* |
| 338 | }x; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 339 | our $Storage = qr{extern|static|asmlinkage}; |
| 340 | our $Sparse = qr{ |
| 341 | __user| |
| 342 | __kernel| |
| 343 | __force| |
| 344 | __iomem| |
| 345 | __must_check| |
| 346 | __init_refok| |
Andy Whitcroft | 417495e | 2009-02-27 14:03:08 -0800 | [diff] [blame] | 347 | __kprobes| |
Sven Eckelmann | 165e72a | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 348 | __ref| |
Boqun Feng | ad31545 | 2015-12-29 12:18:46 +0800 | [diff] [blame] | 349 | __rcu| |
| 350 | __private |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 351 | }x; |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 352 | our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; |
| 353 | our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; |
| 354 | our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; |
| 355 | our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; |
| 356 | our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 357 | |
Wolfram Sang | 5213129 | 2010-03-05 13:43:51 -0800 | [diff] [blame] | 358 | # Notes to $Attribute: |
| 359 | # 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] | 360 | our $Attribute = qr{ |
| 361 | const| |
Joe Perches | 03f1df7 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 362 | __percpu| |
| 363 | __nocast| |
| 364 | __safe| |
Michael S. Tsirkin | 46d832f | 2016-12-11 06:29:58 +0200 | [diff] [blame] | 365 | __bitwise| |
Joe Perches | 03f1df7 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 366 | __packed__| |
| 367 | __packed2__| |
| 368 | __naked| |
| 369 | __maybe_unused| |
| 370 | __always_unused| |
| 371 | __noreturn| |
| 372 | __used| |
| 373 | __cold| |
Joe Perches | e23ef1f | 2015-02-13 14:38:24 -0800 | [diff] [blame] | 374 | __pure| |
Joe Perches | 03f1df7 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 375 | __noclone| |
| 376 | __deprecated| |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 377 | __read_mostly| |
| 378 | __kprobes| |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 379 | $InitAttribute| |
Andy Whitcroft | 24e1d81 | 2008-10-15 22:02:18 -0700 | [diff] [blame] | 380 | ____cacheline_aligned| |
| 381 | ____cacheline_aligned_in_smp| |
Andy Whitcroft | 5fe3af1 | 2009-01-06 14:41:18 -0800 | [diff] [blame] | 382 | ____cacheline_internodealigned_in_smp| |
| 383 | __weak |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 384 | }x; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 385 | our $Modifier; |
Joe Perches | 91cb519 | 2014-04-03 14:49:32 -0700 | [diff] [blame] | 386 | our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 387 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; |
| 388 | our $Lval = qr{$Ident(?:$Member)*}; |
| 389 | |
Joe Perches | 95e2c60 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 390 | our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; |
| 391 | our $Binary = qr{(?i)0b[01]+$Int_type?}; |
| 392 | our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; |
| 393 | our $Int = qr{[0-9]+$Int_type?}; |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 394 | our $Octal = qr{0[0-7]+$Int_type?}; |
Joe Perches | c0a5c89 | 2015-02-13 14:38:21 -0800 | [diff] [blame] | 395 | our $String = qr{"[X\t]*"}; |
Joe Perches | 326b1ff | 2013-02-04 14:28:51 -0800 | [diff] [blame] | 396 | our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; |
| 397 | our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; |
| 398 | our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; |
Joe Perches | 74349bc | 2012-12-17 16:02:05 -0800 | [diff] [blame] | 399 | our $Float = qr{$Float_hex|$Float_dec|$Float_int}; |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 400 | our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; |
Joe Perches | 326b1ff | 2013-02-04 14:28:51 -0800 | [diff] [blame] | 401 | our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; |
Joe Perches | 447432f | 2014-04-03 14:49:17 -0700 | [diff] [blame] | 402 | our $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; |
Joe Perches | 23f780c | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 403 | our $Arithmetic = qr{\+|-|\*|\/|%}; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 404 | our $Operators = qr{ |
| 405 | <=|>=|==|!=| |
| 406 | =>|->|<<|>>|<|>|!|~| |
Joe Perches | 23f780c | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 407 | &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 408 | }x; |
| 409 | |
Joe Perches | 91cb519 | 2014-04-03 14:49:32 -0700 | [diff] [blame] | 410 | our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; |
| 411 | |
Joe Perches | ab7e23f | 2015-04-16 12:44:22 -0700 | [diff] [blame] | 412 | our $BasicType; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 413 | our $NonptrType; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 414 | our $NonptrTypeMisordered; |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 415 | our $NonptrTypeWithAttr; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 416 | our $Type; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 417 | our $TypeMisordered; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 418 | our $Declare; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 419 | our $DeclareMisordered; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 420 | |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 421 | our $NON_ASCII_UTF8 = qr{ |
| 422 | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 423 | | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs |
| 424 | | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte |
| 425 | | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates |
| 426 | | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 |
| 427 | | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 |
| 428 | | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 |
| 429 | }x; |
| 430 | |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 431 | our $UTF8 = qr{ |
| 432 | [\x09\x0A\x0D\x20-\x7E] # ASCII |
| 433 | | $NON_ASCII_UTF8 |
| 434 | }x; |
| 435 | |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 436 | our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; |
Joe Perches | 021158b | 2015-02-13 14:38:43 -0800 | [diff] [blame] | 437 | our $typeOtherOSTypedefs = qr{(?x: |
| 438 | u_(?:char|short|int|long) | # bsd |
| 439 | u(?:nchar|short|int|long) # sysv |
| 440 | )}; |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 441 | our $typeKernelTypedefs = qr{(?x: |
Andy Whitcroft | fb9e909 | 2009-09-21 17:04:38 -0700 | [diff] [blame] | 442 | (?:__)?(?:u|s|be|le)(?:8|16|32|64)| |
Andy Whitcroft | 8ed22ca | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 443 | atomic_t |
| 444 | )}; |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 445 | our $typeTypedefs = qr{(?x: |
| 446 | $typeC99Typedefs\b| |
| 447 | $typeOtherOSTypedefs\b| |
| 448 | $typeKernelTypedefs\b |
| 449 | )}; |
Andy Whitcroft | 8ed22ca | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 450 | |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 451 | our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; |
| 452 | |
Joe Perches | 691e669 | 2010-03-05 13:43:51 -0800 | [diff] [blame] | 453 | our $logFunctions = qr{(?x: |
Miles Chen | 758d7aa | 2017-02-24 15:01:34 -0800 | [diff] [blame] | 454 | printk(?:_ratelimited|_once|_deferred_once|_deferred|)| |
Jacob Keller | 7d0b659 | 2013-07-03 15:05:35 -0700 | [diff] [blame] | 455 | (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| |
Joe Perches | 6e60c02 | 2011-07-25 17:13:27 -0700 | [diff] [blame] | 456 | WARN(?:_RATELIMIT|_ONCE|)| |
Joe Perches | b053172 | 2011-05-24 17:13:40 -0700 | [diff] [blame] | 457 | panic| |
Joe Perches | 0666872 | 2013-11-12 15:10:07 -0800 | [diff] [blame] | 458 | MODULE_[A-Z_]+| |
| 459 | seq_vprintf|seq_printf|seq_puts |
Joe Perches | 691e669 | 2010-03-05 13:43:51 -0800 | [diff] [blame] | 460 | )}; |
| 461 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 462 | our $signature_tags = qr{(?xi: |
| 463 | Signed-off-by:| |
| 464 | Acked-by:| |
| 465 | Tested-by:| |
| 466 | Reviewed-by:| |
| 467 | Reported-by:| |
Mugunthan V N | 8543ae1 | 2013-04-29 16:18:17 -0700 | [diff] [blame] | 468 | Suggested-by:| |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 469 | To:| |
| 470 | Cc: |
| 471 | )}; |
| 472 | |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 473 | our @typeListMisordered = ( |
| 474 | qr{char\s+(?:un)?signed}, |
| 475 | qr{int\s+(?:(?:un)?signed\s+)?short\s}, |
| 476 | qr{int\s+short(?:\s+(?:un)?signed)}, |
| 477 | qr{short\s+int(?:\s+(?:un)?signed)}, |
| 478 | qr{(?:un)?signed\s+int\s+short}, |
| 479 | qr{short\s+(?:un)?signed}, |
| 480 | qr{long\s+int\s+(?:un)?signed}, |
| 481 | qr{int\s+long\s+(?:un)?signed}, |
| 482 | qr{long\s+(?:un)?signed\s+int}, |
| 483 | qr{int\s+(?:un)?signed\s+long}, |
| 484 | qr{int\s+(?:un)?signed}, |
| 485 | qr{int\s+long\s+long\s+(?:un)?signed}, |
| 486 | qr{long\s+long\s+int\s+(?:un)?signed}, |
| 487 | qr{long\s+long\s+(?:un)?signed\s+int}, |
| 488 | qr{long\s+long\s+(?:un)?signed}, |
| 489 | qr{long\s+(?:un)?signed}, |
| 490 | ); |
| 491 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 492 | our @typeList = ( |
| 493 | qr{void}, |
Joe Perches | 0c773d9 | 2014-08-06 16:11:20 -0700 | [diff] [blame] | 494 | qr{(?:(?:un)?signed\s+)?char}, |
| 495 | qr{(?:(?:un)?signed\s+)?short\s+int}, |
| 496 | qr{(?:(?:un)?signed\s+)?short}, |
| 497 | qr{(?:(?:un)?signed\s+)?int}, |
| 498 | qr{(?:(?:un)?signed\s+)?long\s+int}, |
| 499 | qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, |
| 500 | qr{(?:(?:un)?signed\s+)?long\s+long}, |
| 501 | qr{(?:(?:un)?signed\s+)?long}, |
| 502 | qr{(?:un)?signed}, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 503 | qr{float}, |
| 504 | qr{double}, |
| 505 | qr{bool}, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 506 | qr{struct\s+$Ident}, |
| 507 | qr{union\s+$Ident}, |
| 508 | qr{enum\s+$Ident}, |
| 509 | qr{${Ident}_t}, |
| 510 | qr{${Ident}_handler}, |
| 511 | qr{${Ident}_handler_fn}, |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 512 | @typeListMisordered, |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 513 | ); |
Joe Perches | 938224b | 2016-01-20 14:59:15 -0800 | [diff] [blame] | 514 | |
| 515 | our $C90_int_types = qr{(?x: |
| 516 | long\s+long\s+int\s+(?:un)?signed| |
| 517 | long\s+long\s+(?:un)?signed\s+int| |
| 518 | long\s+long\s+(?:un)?signed| |
| 519 | (?:(?:un)?signed\s+)?long\s+long\s+int| |
| 520 | (?:(?:un)?signed\s+)?long\s+long| |
| 521 | int\s+long\s+long\s+(?:un)?signed| |
| 522 | int\s+(?:(?:un)?signed\s+)?long\s+long| |
| 523 | |
| 524 | long\s+int\s+(?:un)?signed| |
| 525 | long\s+(?:un)?signed\s+int| |
| 526 | long\s+(?:un)?signed| |
| 527 | (?:(?:un)?signed\s+)?long\s+int| |
| 528 | (?:(?:un)?signed\s+)?long| |
| 529 | int\s+long\s+(?:un)?signed| |
| 530 | int\s+(?:(?:un)?signed\s+)?long| |
| 531 | |
| 532 | int\s+(?:un)?signed| |
| 533 | (?:(?:un)?signed\s+)?int |
| 534 | )}; |
| 535 | |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 536 | our @typeListFile = (); |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 537 | our @typeListWithAttr = ( |
| 538 | @typeList, |
| 539 | qr{struct\s+$InitAttribute\s+$Ident}, |
| 540 | qr{union\s+$InitAttribute\s+$Ident}, |
| 541 | ); |
| 542 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 543 | our @modifierList = ( |
| 544 | qr{fastcall}, |
| 545 | ); |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 546 | our @modifierListFile = (); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 547 | |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 548 | our @mode_permission_funcs = ( |
| 549 | ["module_param", 3], |
| 550 | ["module_param_(?:array|named|string)", 4], |
| 551 | ["module_param_array_named", 5], |
| 552 | ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], |
| 553 | ["proc_create(?:_data|)", 2], |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 554 | ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], |
| 555 | ["IIO_DEV_ATTR_[A-Z_]+", 1], |
| 556 | ["SENSOR_(?:DEVICE_|)ATTR_2", 2], |
| 557 | ["SENSOR_TEMPLATE(?:_2|)", 3], |
| 558 | ["__ATTR", 2], |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 559 | ); |
| 560 | |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 561 | #Create a search pattern for all these functions to speed up a loop below |
| 562 | our $mode_perms_search = ""; |
| 563 | foreach my $entry (@mode_permission_funcs) { |
| 564 | $mode_perms_search .= '|' if ($mode_perms_search ne ""); |
| 565 | $mode_perms_search .= $entry->[0]; |
| 566 | } |
| 567 | |
Joe Perches | b392c64 | 2015-04-16 12:44:16 -0700 | [diff] [blame] | 568 | our $mode_perms_world_writable = qr{ |
| 569 | S_IWUGO | |
| 570 | S_IWOTH | |
| 571 | S_IRWXUGO | |
| 572 | S_IALLUGO | |
| 573 | 0[0-7][0-7][2367] |
| 574 | }x; |
| 575 | |
Joe Perches | f90774e | 2016-10-11 13:51:47 -0700 | [diff] [blame] | 576 | our %mode_permission_string_types = ( |
| 577 | "S_IRWXU" => 0700, |
| 578 | "S_IRUSR" => 0400, |
| 579 | "S_IWUSR" => 0200, |
| 580 | "S_IXUSR" => 0100, |
| 581 | "S_IRWXG" => 0070, |
| 582 | "S_IRGRP" => 0040, |
| 583 | "S_IWGRP" => 0020, |
| 584 | "S_IXGRP" => 0010, |
| 585 | "S_IRWXO" => 0007, |
| 586 | "S_IROTH" => 0004, |
| 587 | "S_IWOTH" => 0002, |
| 588 | "S_IXOTH" => 0001, |
| 589 | "S_IRWXUGO" => 0777, |
| 590 | "S_IRUGO" => 0444, |
| 591 | "S_IWUGO" => 0222, |
| 592 | "S_IXUGO" => 0111, |
| 593 | ); |
| 594 | |
| 595 | #Create a search pattern for all these strings to speed up a loop below |
| 596 | our $mode_perms_string_search = ""; |
| 597 | foreach my $entry (keys %mode_permission_string_types) { |
| 598 | $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); |
| 599 | $mode_perms_string_search .= $entry; |
| 600 | } |
| 601 | |
Wolfram Sang | 7840a94 | 2010-08-09 17:20:57 -0700 | [diff] [blame] | 602 | our $allowed_asm_includes = qr{(?x: |
| 603 | irq| |
Sergey Ryazanov | cdcee68 | 2014-10-13 15:51:44 -0700 | [diff] [blame] | 604 | memory| |
| 605 | time| |
| 606 | reboot |
Wolfram Sang | 7840a94 | 2010-08-09 17:20:57 -0700 | [diff] [blame] | 607 | )}; |
| 608 | # memory.h: ARM has a custom one |
| 609 | |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 610 | # Load common spelling mistakes and build regular expression list. |
| 611 | my $misspellings; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 612 | my %spelling_fix; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 613 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 614 | if (open(my $spelling, '<', $spelling_file)) { |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 615 | while (<$spelling>) { |
| 616 | my $line = $_; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 617 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 618 | $line =~ s/\s*\n?$//g; |
| 619 | $line =~ s/^\s*//g; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 620 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 621 | next if ($line =~ m/^\s*#/); |
| 622 | next if ($line =~ m/^\s*$/); |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 623 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 624 | my ($suspect, $fix) = split(/\|\|/, $line); |
| 625 | |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 626 | $spelling_fix{$suspect} = $fix; |
| 627 | } |
| 628 | close($spelling); |
Joe Perches | 36061e3 | 2014-12-10 15:51:43 -0800 | [diff] [blame] | 629 | } else { |
| 630 | warn "No typos will be found - file '$spelling_file': $!\n"; |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 631 | } |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 632 | |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 633 | if ($codespell) { |
| 634 | if (open(my $spelling, '<', $codespellfile)) { |
| 635 | while (<$spelling>) { |
| 636 | my $line = $_; |
| 637 | |
| 638 | $line =~ s/\s*\n?$//g; |
| 639 | $line =~ s/^\s*//g; |
| 640 | |
| 641 | next if ($line =~ m/^\s*#/); |
| 642 | next if ($line =~ m/^\s*$/); |
| 643 | next if ($line =~ m/, disabled/i); |
| 644 | |
| 645 | $line =~ s/,.*$//; |
| 646 | |
| 647 | my ($suspect, $fix) = split(/->/, $line); |
| 648 | |
| 649 | $spelling_fix{$suspect} = $fix; |
| 650 | } |
| 651 | close($spelling); |
| 652 | } else { |
| 653 | warn "No codespell typos will be found - file '$codespellfile': $!\n"; |
| 654 | } |
| 655 | } |
| 656 | |
| 657 | $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; |
| 658 | |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 659 | sub read_words { |
| 660 | my ($wordsRef, $file) = @_; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 661 | |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 662 | if (open(my $words, '<', $file)) { |
| 663 | while (<$words>) { |
| 664 | my $line = $_; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 665 | |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 666 | $line =~ s/\s*\n?$//g; |
| 667 | $line =~ s/^\s*//g; |
| 668 | |
| 669 | next if ($line =~ m/^\s*#/); |
| 670 | next if ($line =~ m/^\s*$/); |
| 671 | if ($line =~ /\s/) { |
| 672 | print("$file: '$line' invalid - ignored\n"); |
| 673 | next; |
| 674 | } |
| 675 | |
| 676 | $$wordsRef .= '|' if ($$wordsRef ne ""); |
| 677 | $$wordsRef .= $line; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 678 | } |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 679 | close($file); |
| 680 | return 1; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 681 | } |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 682 | |
| 683 | return 0; |
Joe Perches | bf1fa1d | 2016-10-11 13:51:56 -0700 | [diff] [blame] | 684 | } |
| 685 | |
Jerome Forissier | 75ad8c5 | 2017-05-08 15:56:00 -0700 | [diff] [blame] | 686 | my $const_structs = ""; |
| 687 | read_words(\$const_structs, $conststructsfile) |
| 688 | or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; |
| 689 | |
| 690 | my $typeOtherTypedefs = ""; |
| 691 | if (length($typedefsfile)) { |
| 692 | read_words(\$typeOtherTypedefs, $typedefsfile) |
| 693 | or warn "No additional types will be considered - file '$typedefsfile': $!\n"; |
| 694 | } |
| 695 | $typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); |
| 696 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 697 | sub build_types { |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 698 | my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; |
| 699 | my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 700 | my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 701 | my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 702 | $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; |
Joe Perches | ab7e23f | 2015-04-16 12:44:22 -0700 | [diff] [blame] | 703 | $BasicType = qr{ |
Joe Perches | ab7e23f | 2015-04-16 12:44:22 -0700 | [diff] [blame] | 704 | (?:$typeTypedefs\b)| |
| 705 | (?:${all}\b) |
| 706 | }x; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 707 | $NonptrType = qr{ |
Andy Whitcroft | d2172eb | 2008-07-23 21:29:07 -0700 | [diff] [blame] | 708 | (?:$Modifier\s+|const\s+)* |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 709 | (?: |
Andy Whitcroft | 6b48db2 | 2012-01-10 15:10:13 -0800 | [diff] [blame] | 710 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
Andy Whitcroft | 8ed22ca | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 711 | (?:$typeTypedefs\b)| |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 712 | (?:${all}\b) |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 713 | ) |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 714 | (?:\s+$Modifier|\s+const)* |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 715 | }x; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 716 | $NonptrTypeMisordered = qr{ |
| 717 | (?:$Modifier\s+|const\s+)* |
| 718 | (?: |
| 719 | (?:${Misordered}\b) |
| 720 | ) |
| 721 | (?:\s+$Modifier|\s+const)* |
| 722 | }x; |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 723 | $NonptrTypeWithAttr = qr{ |
| 724 | (?:$Modifier\s+|const\s+)* |
| 725 | (?: |
| 726 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
| 727 | (?:$typeTypedefs\b)| |
| 728 | (?:${allWithAttr}\b) |
| 729 | ) |
| 730 | (?:\s+$Modifier|\s+const)* |
| 731 | }x; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 732 | $Type = qr{ |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 733 | $NonptrType |
Joe Perches | 1574a29 | 2014-08-06 16:10:50 -0700 | [diff] [blame] | 734 | (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 735 | (?:\s+$Inline|\s+$Modifier)* |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 736 | }x; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 737 | $TypeMisordered = qr{ |
| 738 | $NonptrTypeMisordered |
| 739 | (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? |
| 740 | (?:\s+$Inline|\s+$Modifier)* |
| 741 | }x; |
Joe Perches | 91cb519 | 2014-04-03 14:49:32 -0700 | [diff] [blame] | 742 | $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 743 | $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 744 | } |
| 745 | build_types(); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 746 | |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 747 | our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 748 | |
| 749 | # Using $balanced_parens, $LvalOrFunc, or $FuncArg |
| 750 | # requires at least perl version v5.10.0 |
| 751 | # Any use must be runtime checked with $^V |
| 752 | |
| 753 | our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 754 | our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; |
Joe Perches | c0a5c89 | 2015-02-13 14:38:21 -0800 | [diff] [blame] | 755 | our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 756 | |
Joe Perches | f842230 | 2014-08-06 16:11:31 -0700 | [diff] [blame] | 757 | our $declaration_macros = qr{(?x: |
Joe Perches | 3e838b6 | 2015-09-09 15:37:33 -0700 | [diff] [blame] | 758 | (?:$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] | 759 | (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| |
Joe Perches | f842230 | 2014-08-06 16:11:31 -0700 | [diff] [blame] | 760 | (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( |
| 761 | )}; |
| 762 | |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 763 | sub deparenthesize { |
| 764 | my ($string) = @_; |
| 765 | return "" if (!defined($string)); |
Joe Perches | 5b9553a | 2014-04-03 14:49:21 -0700 | [diff] [blame] | 766 | |
| 767 | while ($string =~ /^\s*\(.*\)\s*$/) { |
| 768 | $string =~ s@^\s*\(\s*@@; |
| 769 | $string =~ s@\s*\)\s*$@@; |
| 770 | } |
| 771 | |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 772 | $string =~ s@\s+@ @g; |
Joe Perches | 5b9553a | 2014-04-03 14:49:21 -0700 | [diff] [blame] | 773 | |
Joe Perches | 7d2367a | 2011-07-25 17:13:22 -0700 | [diff] [blame] | 774 | return $string; |
| 775 | } |
| 776 | |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 777 | sub seed_camelcase_file { |
| 778 | my ($file) = @_; |
| 779 | |
| 780 | return if (!(-f $file)); |
| 781 | |
| 782 | local $/; |
| 783 | |
| 784 | open(my $include_file, '<', "$file") |
| 785 | or warn "$P: Can't read '$file' $!\n"; |
| 786 | my $text = <$include_file>; |
| 787 | close($include_file); |
| 788 | |
| 789 | my @lines = split('\n', $text); |
| 790 | |
| 791 | foreach my $line (@lines) { |
| 792 | next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); |
| 793 | if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { |
| 794 | $camelcase{$1} = 1; |
Joe Perches | 11ea516 | 2013-11-12 15:10:08 -0800 | [diff] [blame] | 795 | } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { |
| 796 | $camelcase{$1} = 1; |
| 797 | } 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] | 798 | $camelcase{$1} = 1; |
| 799 | } |
| 800 | } |
| 801 | } |
| 802 | |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 803 | sub is_maintained_obsolete { |
| 804 | my ($filename) = @_; |
| 805 | |
Jerome Forissier | f2c19c2 | 2016-12-12 16:46:23 -0800 | [diff] [blame] | 806 | return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 807 | |
Joe Perches | 0616efa | 2016-10-11 13:52:02 -0700 | [diff] [blame] | 808 | my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 809 | |
| 810 | return $status =~ /obsolete/i; |
| 811 | } |
| 812 | |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 813 | my $camelcase_seeded = 0; |
| 814 | sub seed_camelcase_includes { |
| 815 | return if ($camelcase_seeded); |
| 816 | |
| 817 | my $files; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 818 | my $camelcase_cache = ""; |
| 819 | my @include_files = (); |
| 820 | |
| 821 | $camelcase_seeded = 1; |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 822 | |
Richard Genoud | 3645e32 | 2014-02-10 14:25:32 -0800 | [diff] [blame] | 823 | if (-e ".git") { |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 824 | my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; |
| 825 | chomp $git_last_include_commit; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 826 | $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 827 | } else { |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 828 | my $last_mod_date = 0; |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 829 | $files = `find $root/include -name "*.h"`; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 830 | @include_files = split('\n', $files); |
| 831 | foreach my $file (@include_files) { |
| 832 | my $date = POSIX::strftime("%Y%m%d%H%M", |
| 833 | localtime((stat $file)[9])); |
| 834 | $last_mod_date = $date if ($last_mod_date < $date); |
| 835 | } |
| 836 | $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 837 | } |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 838 | |
| 839 | if ($camelcase_cache ne "" && -f $camelcase_cache) { |
| 840 | open(my $camelcase_file, '<', "$camelcase_cache") |
| 841 | or warn "$P: Can't read '$camelcase_cache' $!\n"; |
| 842 | while (<$camelcase_file>) { |
| 843 | chomp; |
| 844 | $camelcase{$_} = 1; |
| 845 | } |
| 846 | close($camelcase_file); |
| 847 | |
| 848 | return; |
| 849 | } |
| 850 | |
Richard Genoud | 3645e32 | 2014-02-10 14:25:32 -0800 | [diff] [blame] | 851 | if (-e ".git") { |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 852 | $files = `git ls-files "include/*.h"`; |
| 853 | @include_files = split('\n', $files); |
| 854 | } |
| 855 | |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 856 | foreach my $file (@include_files) { |
| 857 | seed_camelcase_file($file); |
| 858 | } |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 859 | |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 860 | if ($camelcase_cache ne "") { |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 861 | unlink glob ".checkpatch-camelcase.*"; |
Joe Perches | c707a81 | 2013-07-08 16:00:43 -0700 | [diff] [blame] | 862 | open(my $camelcase_file, '>', "$camelcase_cache") |
| 863 | or warn "$P: Can't write '$camelcase_cache' $!\n"; |
Joe Perches | 351b2a1 | 2013-07-03 15:05:36 -0700 | [diff] [blame] | 864 | foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { |
| 865 | print $camelcase_file ("$_\n"); |
| 866 | } |
| 867 | close($camelcase_file); |
| 868 | } |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 869 | } |
| 870 | |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 871 | sub git_commit_info { |
| 872 | my ($commit, $id, $desc) = @_; |
| 873 | |
| 874 | return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); |
| 875 | |
| 876 | my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; |
| 877 | $output =~ s/^\s*//gm; |
| 878 | my @lines = split("\n", $output); |
| 879 | |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 880 | return ($id, $desc) if ($#lines < 0); |
| 881 | |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 882 | if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { |
| 883 | # Maybe one day convert this block of bash into something that returns |
| 884 | # all matching commit ids, but it's very slow... |
| 885 | # |
| 886 | # echo "checking commits $1..." |
| 887 | # git rev-list --remotes | grep -i "^$1" | |
| 888 | # while read line ; do |
| 889 | # git log --format='%H %s' -1 $line | |
| 890 | # echo "commit $(cut -c 1-12,41-)" |
| 891 | # done |
| 892 | } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { |
Heinrich Schuchardt | 948b133 | 2017-07-10 15:52:16 -0700 | [diff] [blame] | 893 | $id = undef; |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 894 | } else { |
| 895 | $id = substr($lines[0], 0, 12); |
| 896 | $desc = substr($lines[0], 41); |
| 897 | } |
| 898 | |
| 899 | return ($id, $desc); |
| 900 | } |
| 901 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 902 | $chk_signoff = 0 if ($file); |
| 903 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 904 | my @rawlines = (); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 905 | my @lines = (); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 906 | my @fixed = (); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 907 | my @fixed_inserted = (); |
| 908 | my @fixed_deleted = (); |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 909 | my $fixlinenr = -1; |
| 910 | |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 911 | # If input is git commits, extract all commits from the commit expressions. |
| 912 | # For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. |
| 913 | die "$P: No git repository found\n" if ($git && !-e ".git"); |
| 914 | |
| 915 | if ($git) { |
| 916 | my @commits = (); |
Joe Perches | 0dea9f1 | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 917 | foreach my $commit_expr (@ARGV) { |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 918 | my $git_range; |
Joe Perches | 28898fd | 2016-05-20 17:04:22 -0700 | [diff] [blame] | 919 | if ($commit_expr =~ m/^(.*)-(\d+)$/) { |
| 920 | $git_range = "-$2 $1"; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 921 | } elsif ($commit_expr =~ m/\.\./) { |
| 922 | $git_range = "$commit_expr"; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 923 | } else { |
Joe Perches | 0dea9f1 | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 924 | $git_range = "-1 $commit_expr"; |
| 925 | } |
| 926 | my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; |
| 927 | foreach my $line (split(/\n/, $lines)) { |
Joe Perches | 28898fd | 2016-05-20 17:04:22 -0700 | [diff] [blame] | 928 | $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; |
| 929 | next if (!defined($1) || !defined($2)); |
Joe Perches | 0dea9f1 | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 930 | my $sha1 = $1; |
| 931 | my $subject = $2; |
| 932 | unshift(@commits, $sha1); |
| 933 | $git_commits{$sha1} = $subject; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 934 | } |
| 935 | } |
| 936 | die "$P: no git commits after extraction!\n" if (@commits == 0); |
| 937 | @ARGV = @commits; |
| 938 | } |
| 939 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 940 | my $vname; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 941 | for my $filename (@ARGV) { |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 942 | my $FILE; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 943 | if ($git) { |
| 944 | open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || |
| 945 | die "$P: $filename: git format-patch failed - $!\n"; |
| 946 | } elsif ($file) { |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 947 | open($FILE, '-|', "diff -u /dev/null $filename") || |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 948 | die "$P: $filename: diff failed - $!\n"; |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 949 | } elsif ($filename eq '-') { |
| 950 | open($FILE, '<&STDIN'); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 951 | } else { |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 952 | open($FILE, '<', "$filename") || |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 953 | die "$P: $filename: open failed - $!\n"; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 954 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 955 | if ($filename eq '-') { |
| 956 | $vname = 'Your patch'; |
Du, Changbin | 4a593c3 | 2016-05-20 17:04:16 -0700 | [diff] [blame] | 957 | } elsif ($git) { |
Joe Perches | 0dea9f1 | 2016-05-20 17:04:19 -0700 | [diff] [blame] | 958 | $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 959 | } else { |
| 960 | $vname = $filename; |
| 961 | } |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 962 | while (<$FILE>) { |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 963 | chomp; |
| 964 | push(@rawlines, $_); |
| 965 | } |
Andy Whitcroft | 21caa13 | 2009-01-06 14:41:30 -0800 | [diff] [blame] | 966 | close($FILE); |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 967 | |
| 968 | if ($#ARGV > 0 && $quiet == 0) { |
| 969 | print '-' x length($vname) . "\n"; |
| 970 | print "$vname\n"; |
| 971 | print '-' x length($vname) . "\n"; |
| 972 | } |
| 973 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 974 | if (!process($filename)) { |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 975 | $exit = 1; |
| 976 | } |
| 977 | @rawlines = (); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 978 | @lines = (); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 979 | @fixed = (); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 980 | @fixed_inserted = (); |
| 981 | @fixed_deleted = (); |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 982 | $fixlinenr = -1; |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 983 | @modifierListFile = (); |
| 984 | @typeListFile = (); |
| 985 | build_types(); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 986 | } |
| 987 | |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 988 | if (!$quiet) { |
Joe Perches | 3c816e4 | 2015-06-25 15:03:29 -0700 | [diff] [blame] | 989 | hash_show_words(\%use_type, "Used"); |
| 990 | hash_show_words(\%ignore_type, "Ignored"); |
| 991 | |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 992 | if ($^V lt 5.10.0) { |
| 993 | print << "EOM" |
| 994 | |
| 995 | NOTE: perl $^V is not modern enough to detect all possible issues. |
| 996 | An upgrade to at least perl v5.10.0 is suggested. |
| 997 | EOM |
| 998 | } |
| 999 | if ($exit) { |
| 1000 | print << "EOM" |
| 1001 | |
| 1002 | NOTE: If any of the errors are false positives, please report |
| 1003 | them to the maintainer, see CHECKPATCH in MAINTAINERS. |
| 1004 | EOM |
| 1005 | } |
| 1006 | } |
| 1007 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1008 | exit($exit); |
| 1009 | |
| 1010 | sub top_of_kernel_tree { |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1011 | my ($root) = @_; |
| 1012 | |
| 1013 | my @tree_check = ( |
| 1014 | "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", |
| 1015 | "README", "Documentation", "arch", "include", "drivers", |
| 1016 | "fs", "init", "ipc", "kernel", "lib", "scripts", |
| 1017 | ); |
| 1018 | |
| 1019 | foreach my $check (@tree_check) { |
| 1020 | if (! -e $root . '/' . $check) { |
| 1021 | return 0; |
| 1022 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1023 | } |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1024 | return 1; |
Joe Perches | 8f26b83 | 2012-10-04 17:13:32 -0700 | [diff] [blame] | 1025 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1026 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1027 | sub parse_email { |
| 1028 | my ($formatted_email) = @_; |
| 1029 | |
| 1030 | my $name = ""; |
| 1031 | my $address = ""; |
| 1032 | my $comment = ""; |
| 1033 | |
| 1034 | if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { |
| 1035 | $name = $1; |
| 1036 | $address = $2; |
| 1037 | $comment = $3 if defined $3; |
| 1038 | } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { |
| 1039 | $address = $1; |
| 1040 | $comment = $2 if defined $2; |
| 1041 | } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { |
| 1042 | $address = $1; |
| 1043 | $comment = $2 if defined $2; |
| 1044 | $formatted_email =~ s/$address.*$//; |
| 1045 | $name = $formatted_email; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1046 | $name = trim($name); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1047 | $name =~ s/^\"|\"$//g; |
| 1048 | # If there's a name left after stripping spaces and |
| 1049 | # leading quotes, and the address doesn't have both |
| 1050 | # leading and trailing angle brackets, the address |
| 1051 | # is invalid. ie: |
| 1052 | # "joe smith joe@smith.com" bad |
| 1053 | # "joe smith <joe@smith.com" bad |
| 1054 | if ($name ne "" && $address !~ /^<[^>]+>$/) { |
| 1055 | $name = ""; |
| 1056 | $address = ""; |
| 1057 | $comment = ""; |
| 1058 | } |
| 1059 | } |
| 1060 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1061 | $name = trim($name); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1062 | $name =~ s/^\"|\"$//g; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1063 | $address = trim($address); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1064 | $address =~ s/^\<|\>$//g; |
| 1065 | |
| 1066 | if ($name =~ /[^\w \-]/i) { ##has "must quote" chars |
| 1067 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes |
| 1068 | $name = "\"$name\""; |
| 1069 | } |
| 1070 | |
| 1071 | return ($name, $address, $comment); |
| 1072 | } |
| 1073 | |
| 1074 | sub format_email { |
| 1075 | my ($name, $address) = @_; |
| 1076 | |
| 1077 | my $formatted_email; |
| 1078 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1079 | $name = trim($name); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1080 | $name =~ s/^\"|\"$//g; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 1081 | $address = trim($address); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 1082 | |
| 1083 | if ($name =~ /[^\w \-]/i) { ##has "must quote" chars |
| 1084 | $name =~ s/(?<!\\)"/\\"/g; ##escape quotes |
| 1085 | $name = "\"$name\""; |
| 1086 | } |
| 1087 | |
| 1088 | if ("$name" eq "") { |
| 1089 | $formatted_email = "$address"; |
| 1090 | } else { |
| 1091 | $formatted_email = "$name <$address>"; |
| 1092 | } |
| 1093 | |
| 1094 | return $formatted_email; |
| 1095 | } |
| 1096 | |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1097 | sub which { |
Joe Perches | bd474ca | 2014-08-06 16:11:10 -0700 | [diff] [blame] | 1098 | my ($bin) = @_; |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1099 | |
Joe Perches | bd474ca | 2014-08-06 16:11:10 -0700 | [diff] [blame] | 1100 | foreach my $path (split(/:/, $ENV{PATH})) { |
| 1101 | if (-e "$path/$bin") { |
| 1102 | return "$path/$bin"; |
| 1103 | } |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1104 | } |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1105 | |
Joe Perches | bd474ca | 2014-08-06 16:11:10 -0700 | [diff] [blame] | 1106 | return ""; |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 1107 | } |
| 1108 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 1109 | sub which_conf { |
| 1110 | my ($conf) = @_; |
| 1111 | |
| 1112 | foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { |
| 1113 | if (-e "$path/$conf") { |
| 1114 | return "$path/$conf"; |
| 1115 | } |
| 1116 | } |
| 1117 | |
| 1118 | return ""; |
| 1119 | } |
| 1120 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1121 | sub expand_tabs { |
| 1122 | my ($str) = @_; |
| 1123 | |
| 1124 | my $res = ''; |
| 1125 | my $n = 0; |
| 1126 | for my $c (split(//, $str)) { |
| 1127 | if ($c eq "\t") { |
| 1128 | $res .= ' '; |
| 1129 | $n++; |
| 1130 | for (; ($n % 8) != 0; $n++) { |
| 1131 | $res .= ' '; |
| 1132 | } |
| 1133 | next; |
| 1134 | } |
| 1135 | $res .= $c; |
| 1136 | $n++; |
| 1137 | } |
| 1138 | |
| 1139 | return $res; |
| 1140 | } |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1141 | sub copy_spacing { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1142 | (my $res = shift) =~ tr/\t/ /c; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1143 | return $res; |
| 1144 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1145 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1146 | sub line_stats { |
| 1147 | my ($line) = @_; |
| 1148 | |
| 1149 | # Drop the diff line leader and expand tabs |
| 1150 | $line =~ s/^.//; |
| 1151 | $line = expand_tabs($line); |
| 1152 | |
| 1153 | # Pick the indent from the front of the line. |
| 1154 | my ($white) = ($line =~ /^(\s*)/); |
| 1155 | |
| 1156 | return (length($line), length($white)); |
| 1157 | } |
| 1158 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1159 | my $sanitise_quote = ''; |
| 1160 | |
| 1161 | sub sanitise_line_reset { |
| 1162 | my ($in_comment) = @_; |
| 1163 | |
| 1164 | if ($in_comment) { |
| 1165 | $sanitise_quote = '*/'; |
| 1166 | } else { |
| 1167 | $sanitise_quote = ''; |
| 1168 | } |
| 1169 | } |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1170 | sub sanitise_line { |
| 1171 | my ($line) = @_; |
| 1172 | |
| 1173 | my $res = ''; |
| 1174 | my $l = ''; |
| 1175 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1176 | my $qlen = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1177 | my $off = 0; |
| 1178 | my $c; |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1179 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1180 | # Always copy over the diff marker. |
| 1181 | $res = substr($line, 0, 1); |
| 1182 | |
| 1183 | for ($off = 1; $off < length($line); $off++) { |
| 1184 | $c = substr($line, $off, 1); |
| 1185 | |
| 1186 | # Comments we are wacking completly including the begin |
| 1187 | # and end, all to $;. |
| 1188 | if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { |
| 1189 | $sanitise_quote = '*/'; |
| 1190 | |
| 1191 | substr($res, $off, 2, "$;$;"); |
| 1192 | $off++; |
| 1193 | next; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1194 | } |
Andy Whitcroft | 81bc0e0 | 2008-10-15 22:02:26 -0700 | [diff] [blame] | 1195 | if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1196 | $sanitise_quote = ''; |
| 1197 | substr($res, $off, 2, "$;$;"); |
| 1198 | $off++; |
| 1199 | next; |
| 1200 | } |
Daniel Walker | 113f04a | 2009-09-21 17:04:35 -0700 | [diff] [blame] | 1201 | if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { |
| 1202 | $sanitise_quote = '//'; |
| 1203 | |
| 1204 | substr($res, $off, 2, $sanitise_quote); |
| 1205 | $off++; |
| 1206 | next; |
| 1207 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1208 | |
| 1209 | # A \ in a string means ignore the next character. |
| 1210 | if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && |
| 1211 | $c eq "\\") { |
| 1212 | substr($res, $off, 2, 'XX'); |
| 1213 | $off++; |
| 1214 | next; |
| 1215 | } |
| 1216 | # Regular quotes. |
| 1217 | if ($c eq "'" || $c eq '"') { |
| 1218 | if ($sanitise_quote eq '') { |
| 1219 | $sanitise_quote = $c; |
| 1220 | |
| 1221 | substr($res, $off, 1, $c); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1222 | next; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1223 | } elsif ($sanitise_quote eq $c) { |
| 1224 | $sanitise_quote = ''; |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1225 | } |
| 1226 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1227 | |
Andy Whitcroft | fae17da | 2009-01-06 14:41:20 -0800 | [diff] [blame] | 1228 | #print "c<$c> SQ<$sanitise_quote>\n"; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1229 | if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { |
| 1230 | substr($res, $off, 1, $;); |
Daniel Walker | 113f04a | 2009-09-21 17:04:35 -0700 | [diff] [blame] | 1231 | } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { |
| 1232 | substr($res, $off, 1, $;); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1233 | } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { |
| 1234 | substr($res, $off, 1, 'X'); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1235 | } else { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1236 | substr($res, $off, 1, $c); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1237 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1238 | } |
| 1239 | |
Daniel Walker | 113f04a | 2009-09-21 17:04:35 -0700 | [diff] [blame] | 1240 | if ($sanitise_quote eq '//') { |
| 1241 | $sanitise_quote = ''; |
| 1242 | } |
| 1243 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1244 | # The pathname on a #include may be surrounded by '<' and '>'. |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1245 | if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1246 | my $clean = 'X' x length($1); |
| 1247 | $res =~ s@\<.*\>@<$clean>@; |
| 1248 | |
| 1249 | # The whole of a #error is a string. |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1250 | } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1251 | my $clean = 'X' x length($1); |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1252 | $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1253 | } |
| 1254 | |
Joe Perches | dadf680 | 2016-08-02 14:04:33 -0700 | [diff] [blame] | 1255 | if ($allow_c99_comments && $res =~ m@(//.*$)@) { |
| 1256 | my $match = $1; |
| 1257 | $res =~ s/\Q$match\E/"$;" x length($match)/e; |
| 1258 | } |
| 1259 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1260 | return $res; |
| 1261 | } |
| 1262 | |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 1263 | sub get_quoted_string { |
| 1264 | my ($line, $rawline) = @_; |
| 1265 | |
Joe Perches | 33acb54 | 2015-06-25 15:02:54 -0700 | [diff] [blame] | 1266 | return "" if ($line !~ m/($String)/g); |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 1267 | return substr($rawline, $-[0], $+[0] - $-[0]); |
| 1268 | } |
| 1269 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1270 | sub ctx_statement_block { |
| 1271 | my ($linenr, $remain, $off) = @_; |
| 1272 | my $line = $linenr - 1; |
| 1273 | my $blk = ''; |
| 1274 | my $soff = $off; |
| 1275 | my $coff = $off - 1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1276 | my $coff_set = 0; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1277 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1278 | my $loff = 0; |
| 1279 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1280 | my $type = ''; |
| 1281 | my $level = 0; |
Andy Whitcroft | a275064 | 2009-01-15 13:51:04 -0800 | [diff] [blame] | 1282 | my @stack = (); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1283 | my $p; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1284 | my $c; |
| 1285 | my $len = 0; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1286 | |
| 1287 | my $remainder; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1288 | while (1) { |
Andy Whitcroft | a275064 | 2009-01-15 13:51:04 -0800 | [diff] [blame] | 1289 | @stack = (['', 0]) if ($#stack == -1); |
| 1290 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1291 | #warn "CSB: blk<$blk> remain<$remain>\n"; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1292 | # If we are about to drop off the end, pull in more |
| 1293 | # context. |
| 1294 | if ($off >= $len) { |
| 1295 | for (; $remain > 0; $line++) { |
Andy Whitcroft | dea3349 | 2008-10-15 22:02:25 -0700 | [diff] [blame] | 1296 | last if (!defined $lines[$line]); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1297 | next if ($lines[$line] =~ /^-/); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1298 | $remain--; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1299 | $loff = $len; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1300 | $blk .= $lines[$line] . "\n"; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1301 | $len = length($blk); |
| 1302 | $line++; |
| 1303 | last; |
| 1304 | } |
| 1305 | # Bail if there is no further context. |
| 1306 | #warn "CSB: blk<$blk> off<$off> len<$len>\n"; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1307 | if ($off >= $len) { |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1308 | last; |
| 1309 | } |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 1310 | if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { |
| 1311 | $level++; |
| 1312 | $type = '#'; |
| 1313 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1314 | } |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1315 | $p = $c; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1316 | $c = substr($blk, $off, 1); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1317 | $remainder = substr($blk, $off); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1318 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1319 | #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] | 1320 | |
| 1321 | # Handle nested #if/#else. |
| 1322 | if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { |
| 1323 | push(@stack, [ $type, $level ]); |
| 1324 | } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { |
| 1325 | ($type, $level) = @{$stack[$#stack - 1]}; |
| 1326 | } elsif ($remainder =~ /^#\s*endif\b/) { |
| 1327 | ($type, $level) = @{pop(@stack)}; |
| 1328 | } |
| 1329 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1330 | # Statement ends at the ';' or a close '}' at the |
| 1331 | # outermost level. |
| 1332 | if ($level == 0 && $c eq ';') { |
| 1333 | last; |
| 1334 | } |
| 1335 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1336 | # 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] | 1337 | if ($level == 0 && $coff_set == 0 && |
| 1338 | (!defined($p) || $p =~ /(?:\s|\}|\+)/) && |
| 1339 | $remainder =~ /^(else)(?:\s|{)/ && |
| 1340 | $remainder !~ /^else\s+if\b/) { |
| 1341 | $coff = $off + length($1) - 1; |
| 1342 | $coff_set = 1; |
| 1343 | #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; |
| 1344 | #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1345 | } |
| 1346 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1347 | if (($type eq '' || $type eq '(') && $c eq '(') { |
| 1348 | $level++; |
| 1349 | $type = '('; |
| 1350 | } |
| 1351 | if ($type eq '(' && $c eq ')') { |
| 1352 | $level--; |
| 1353 | $type = ($level != 0)? '(' : ''; |
| 1354 | |
| 1355 | if ($level == 0 && $coff < $soff) { |
| 1356 | $coff = $off; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1357 | $coff_set = 1; |
| 1358 | #warn "CSB: mark coff<$coff>\n"; |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1359 | } |
| 1360 | } |
| 1361 | if (($type eq '' || $type eq '{') && $c eq '{') { |
| 1362 | $level++; |
| 1363 | $type = '{'; |
| 1364 | } |
| 1365 | if ($type eq '{' && $c eq '}') { |
| 1366 | $level--; |
| 1367 | $type = ($level != 0)? '{' : ''; |
| 1368 | |
| 1369 | if ($level == 0) { |
Patrick Pannuto | b998e00 | 2010-08-09 17:21:03 -0700 | [diff] [blame] | 1370 | if (substr($blk, $off + 1, 1) eq ';') { |
| 1371 | $off++; |
| 1372 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1373 | last; |
| 1374 | } |
| 1375 | } |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 1376 | # Preprocessor commands end at the newline unless escaped. |
| 1377 | if ($type eq '#' && $c eq "\n" && $p ne "\\") { |
| 1378 | $level--; |
| 1379 | $type = ''; |
| 1380 | $off++; |
| 1381 | last; |
| 1382 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1383 | $off++; |
| 1384 | } |
Andy Whitcroft | a3bb97a | 2008-07-23 21:29:00 -0700 | [diff] [blame] | 1385 | # We are truly at the end, so shuffle to the next line. |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1386 | if ($off == $len) { |
Andy Whitcroft | a3bb97a | 2008-07-23 21:29:00 -0700 | [diff] [blame] | 1387 | $loff = $len + 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1388 | $line++; |
| 1389 | $remain--; |
| 1390 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1391 | |
| 1392 | my $statement = substr($blk, $soff, $off - $soff + 1); |
| 1393 | my $condition = substr($blk, $soff, $coff - $soff + 1); |
| 1394 | |
| 1395 | #warn "STATEMENT<$statement>\n"; |
| 1396 | #warn "CONDITION<$condition>\n"; |
| 1397 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1398 | #print "coff<$coff> soff<$off> loff<$loff>\n"; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1399 | |
| 1400 | return ($statement, $condition, |
| 1401 | $line, $remain + 1, $off - $loff + 1, $level); |
| 1402 | } |
| 1403 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1404 | sub statement_lines { |
| 1405 | my ($stmt) = @_; |
| 1406 | |
| 1407 | # Strip the diff line prefixes and rip blank lines at start and end. |
| 1408 | $stmt =~ s/(^|\n)./$1/g; |
| 1409 | $stmt =~ s/^\s*//; |
| 1410 | $stmt =~ s/\s*$//; |
| 1411 | |
| 1412 | my @stmt_lines = ($stmt =~ /\n/g); |
| 1413 | |
| 1414 | return $#stmt_lines + 2; |
| 1415 | } |
| 1416 | |
| 1417 | sub statement_rawlines { |
| 1418 | my ($stmt) = @_; |
| 1419 | |
| 1420 | my @stmt_lines = ($stmt =~ /\n/g); |
| 1421 | |
| 1422 | return $#stmt_lines + 2; |
| 1423 | } |
| 1424 | |
| 1425 | sub statement_block_size { |
| 1426 | my ($stmt) = @_; |
| 1427 | |
| 1428 | $stmt =~ s/(^|\n)./$1/g; |
| 1429 | $stmt =~ s/^\s*{//; |
| 1430 | $stmt =~ s/}\s*$//; |
| 1431 | $stmt =~ s/^\s*//; |
| 1432 | $stmt =~ s/\s*$//; |
| 1433 | |
| 1434 | my @stmt_lines = ($stmt =~ /\n/g); |
| 1435 | my @stmt_statements = ($stmt =~ /;/g); |
| 1436 | |
| 1437 | my $stmt_lines = $#stmt_lines + 2; |
| 1438 | my $stmt_statements = $#stmt_statements + 1; |
| 1439 | |
| 1440 | if ($stmt_lines > $stmt_statements) { |
| 1441 | return $stmt_lines; |
| 1442 | } else { |
| 1443 | return $stmt_statements; |
| 1444 | } |
| 1445 | } |
| 1446 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1447 | sub ctx_statement_full { |
| 1448 | my ($linenr, $remain, $off) = @_; |
| 1449 | my ($statement, $condition, $level); |
| 1450 | |
| 1451 | my (@chunks); |
| 1452 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1453 | # Grab the first conditional/block pair. |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1454 | ($statement, $condition, $linenr, $remain, $off, $level) = |
| 1455 | ctx_statement_block($linenr, $remain, $off); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1456 | #print "F: c<$condition> s<$statement> remain<$remain>\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1457 | push(@chunks, [ $condition, $statement ]); |
| 1458 | if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { |
| 1459 | return ($level, $linenr, @chunks); |
| 1460 | } |
| 1461 | |
| 1462 | # Pull in the following conditional/block pairs and see if they |
| 1463 | # could continue the statement. |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1464 | for (;;) { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1465 | ($statement, $condition, $linenr, $remain, $off, $level) = |
| 1466 | ctx_statement_block($linenr, $remain, $off); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1467 | #print "C: c<$condition> s<$statement> remain<$remain>\n"; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1468 | last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1469 | #print "C: push\n"; |
| 1470 | push(@chunks, [ $condition, $statement ]); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1471 | } |
| 1472 | |
| 1473 | return ($level, $linenr, @chunks); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1474 | } |
| 1475 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1476 | sub ctx_block_get { |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1477 | my ($linenr, $remain, $outer, $open, $close, $off) = @_; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1478 | my $line; |
| 1479 | my $start = $linenr - 1; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1480 | my $blk = ''; |
| 1481 | my @o; |
| 1482 | my @c; |
| 1483 | my @res = (); |
| 1484 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1485 | my $level = 0; |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1486 | my @stack = ($level); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1487 | for ($line = $start; $remain > 0; $line++) { |
| 1488 | next if ($rawlines[$line] =~ /^-/); |
| 1489 | $remain--; |
| 1490 | |
| 1491 | $blk .= $rawlines[$line]; |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1492 | |
| 1493 | # Handle nested #if/#else. |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 1494 | if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1495 | push(@stack, $level); |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 1496 | } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1497 | $level = $stack[$#stack - 1]; |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 1498 | } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { |
Andy Whitcroft | 4635f4f | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 1499 | $level = pop(@stack); |
| 1500 | } |
| 1501 | |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 1502 | foreach my $c (split(//, $lines[$line])) { |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1503 | ##print "C<$c>L<$level><$open$close>O<$off>\n"; |
| 1504 | if ($off > 0) { |
| 1505 | $off--; |
| 1506 | next; |
| 1507 | } |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1508 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1509 | if ($c eq $close && $level > 0) { |
| 1510 | $level--; |
| 1511 | last if ($level == 0); |
| 1512 | } elsif ($c eq $open) { |
| 1513 | $level++; |
| 1514 | } |
| 1515 | } |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1516 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1517 | if (!$outer || $level <= 1) { |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1518 | push(@res, $rawlines[$line]); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1519 | } |
| 1520 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1521 | last if ($level == 0); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1522 | } |
| 1523 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1524 | return ($level, @res); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1525 | } |
| 1526 | sub ctx_block_outer { |
| 1527 | my ($linenr, $remain) = @_; |
| 1528 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1529 | my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); |
| 1530 | return @r; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1531 | } |
| 1532 | sub ctx_block { |
| 1533 | my ($linenr, $remain) = @_; |
| 1534 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1535 | my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); |
| 1536 | return @r; |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 1537 | } |
| 1538 | sub ctx_statement { |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1539 | my ($linenr, $remain, $off) = @_; |
| 1540 | |
| 1541 | my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); |
| 1542 | return @r; |
| 1543 | } |
| 1544 | sub ctx_block_level { |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 1545 | my ($linenr, $remain) = @_; |
| 1546 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1547 | return ctx_block_get($linenr, $remain, 0, '{', '}', 0); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1548 | } |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 1549 | sub ctx_statement_level { |
| 1550 | my ($linenr, $remain, $off) = @_; |
| 1551 | |
| 1552 | return ctx_block_get($linenr, $remain, 0, '(', ')', $off); |
| 1553 | } |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1554 | |
| 1555 | sub ctx_locate_comment { |
| 1556 | my ($first_line, $end_line) = @_; |
| 1557 | |
| 1558 | # Catch a comment on the end of the line itself. |
Andy Whitcroft | beae633 | 2008-07-23 21:28:59 -0700 | [diff] [blame] | 1559 | my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1560 | return $current_comment if (defined $current_comment); |
| 1561 | |
| 1562 | # Look through the context and try and figure out if there is a |
| 1563 | # comment. |
| 1564 | my $in_comment = 0; |
| 1565 | $current_comment = ''; |
| 1566 | for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1567 | my $line = $rawlines[$linenr - 1]; |
| 1568 | #warn " $line\n"; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1569 | if ($linenr == $first_line and $line =~ m@^.\s*\*@) { |
| 1570 | $in_comment = 1; |
| 1571 | } |
| 1572 | if ($line =~ m@/\*@) { |
| 1573 | $in_comment = 1; |
| 1574 | } |
| 1575 | if (!$in_comment && $current_comment ne '') { |
| 1576 | $current_comment = ''; |
| 1577 | } |
| 1578 | $current_comment .= $line . "\n" if ($in_comment); |
| 1579 | if ($line =~ m@\*/@) { |
| 1580 | $in_comment = 0; |
| 1581 | } |
| 1582 | } |
| 1583 | |
| 1584 | chomp($current_comment); |
| 1585 | return($current_comment); |
| 1586 | } |
| 1587 | sub ctx_has_comment { |
| 1588 | my ($first_line, $end_line) = @_; |
| 1589 | my $cmt = ctx_locate_comment($first_line, $end_line); |
| 1590 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 1591 | ##print "LINE: $rawlines[$end_line - 1 ]\n"; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 1592 | ##print "CMMT: $cmt\n"; |
| 1593 | |
| 1594 | return ($cmt ne ''); |
| 1595 | } |
| 1596 | |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 1597 | sub raw_line { |
| 1598 | my ($linenr, $cnt) = @_; |
| 1599 | |
| 1600 | my $offset = $linenr - 1; |
| 1601 | $cnt++; |
| 1602 | |
| 1603 | my $line; |
| 1604 | while ($cnt) { |
| 1605 | $line = $rawlines[$offset++]; |
| 1606 | next if (defined($line) && $line =~ /^-/); |
| 1607 | $cnt--; |
| 1608 | } |
| 1609 | |
| 1610 | return $line; |
| 1611 | } |
| 1612 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1613 | sub cat_vet { |
| 1614 | my ($vet) = @_; |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 1615 | my ($res, $coded); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1616 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 1617 | $res = ''; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1618 | while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { |
| 1619 | $res .= $1; |
| 1620 | if ($2 ne '') { |
| 1621 | $coded = sprintf("^%c", unpack('C', $2) + 64); |
| 1622 | $res .= $coded; |
| 1623 | } |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 1624 | } |
| 1625 | $res =~ s/$/\$/; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1626 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 1627 | return $res; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 1628 | } |
| 1629 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1630 | my $av_preprocessor = 0; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1631 | my $av_pending; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1632 | my @av_paren_type; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1633 | my $av_pend_colon; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1634 | |
| 1635 | sub annotate_reset { |
| 1636 | $av_preprocessor = 0; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1637 | $av_pending = '_'; |
| 1638 | @av_paren_type = ('E'); |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1639 | $av_pend_colon = 'O'; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1640 | } |
| 1641 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1642 | sub annotate_values { |
| 1643 | my ($stream, $type) = @_; |
| 1644 | |
| 1645 | my $res; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1646 | my $var = '_' x length($stream); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1647 | my $cur = $stream; |
| 1648 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1649 | print "$stream\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1650 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1651 | while (length($cur)) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1652 | @av_paren_type = ('E') if ($#av_paren_type < 0); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1653 | print " <" . join('', @av_paren_type) . |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 1654 | "> <$type> <$av_pending>" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1655 | if ($cur =~ /^(\s+)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1656 | print "WS($1)\n" if ($dbg_values > 1); |
| 1657 | if ($1 =~ /\n/ && $av_preprocessor) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1658 | $type = pop(@av_paren_type); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1659 | $av_preprocessor = 0; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1660 | } |
| 1661 | |
Florian Mickler | c023e473 | 2011-01-12 16:59:58 -0800 | [diff] [blame] | 1662 | } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { |
Andy Whitcroft | 9446ef5 | 2010-10-26 14:23:13 -0700 | [diff] [blame] | 1663 | print "CAST($1)\n" if ($dbg_values > 1); |
| 1664 | push(@av_paren_type, $type); |
Andy Whitcroft | addcdce | 2012-01-10 15:10:11 -0800 | [diff] [blame] | 1665 | $type = 'c'; |
Andy Whitcroft | 9446ef5 | 2010-10-26 14:23:13 -0700 | [diff] [blame] | 1666 | |
Andy Whitcroft | e91b6e2 | 2010-10-26 14:23:11 -0700 | [diff] [blame] | 1667 | } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1668 | print "DECLARE($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1669 | $type = 'T'; |
| 1670 | |
Andy Whitcroft | 389a2fe | 2008-07-23 21:29:05 -0700 | [diff] [blame] | 1671 | } elsif ($cur =~ /^($Modifier)\s*/) { |
| 1672 | print "MODIFIER($1)\n" if ($dbg_values > 1); |
| 1673 | $type = 'T'; |
| 1674 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1675 | } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 1676 | print "DEFINE($1,$2)\n" if ($dbg_values > 1); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1677 | $av_preprocessor = 1; |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 1678 | push(@av_paren_type, $type); |
| 1679 | if ($2 ne '') { |
| 1680 | $av_pending = 'N'; |
| 1681 | } |
| 1682 | $type = 'E'; |
| 1683 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1684 | } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 1685 | print "UNDEF($1)\n" if ($dbg_values > 1); |
| 1686 | $av_preprocessor = 1; |
| 1687 | push(@av_paren_type, $type); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1688 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1689 | } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1690 | print "PRE_START($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1691 | $av_preprocessor = 1; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1692 | |
| 1693 | push(@av_paren_type, $type); |
| 1694 | push(@av_paren_type, $type); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 1695 | $type = 'E'; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1696 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1697 | } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1698 | print "PRE_RESTART($1)\n" if ($dbg_values > 1); |
| 1699 | $av_preprocessor = 1; |
| 1700 | |
| 1701 | push(@av_paren_type, $av_paren_type[$#av_paren_type]); |
| 1702 | |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 1703 | $type = 'E'; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1704 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1705 | } elsif ($cur =~ /^(\#\s*(?:endif))/o) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1706 | print "PRE_END($1)\n" if ($dbg_values > 1); |
| 1707 | |
| 1708 | $av_preprocessor = 1; |
| 1709 | |
| 1710 | # Assume all arms of the conditional end as this |
| 1711 | # one does, and continue as if the #endif was not here. |
| 1712 | pop(@av_paren_type); |
| 1713 | push(@av_paren_type, $type); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 1714 | $type = 'E'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1715 | |
| 1716 | } elsif ($cur =~ /^(\\\n)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1717 | print "PRECONT($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1718 | |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 1719 | } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { |
| 1720 | print "ATTR($1)\n" if ($dbg_values > 1); |
| 1721 | $av_pending = $type; |
| 1722 | $type = 'N'; |
| 1723 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1724 | } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1725 | print "SIZEOF($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1726 | if (defined $2) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1727 | $av_pending = 'V'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1728 | } |
| 1729 | $type = 'N'; |
| 1730 | |
Andy Whitcroft | 14b111c | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 1731 | } elsif ($cur =~ /^(if|while|for)\b/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1732 | print "COND($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 14b111c | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 1733 | $av_pending = 'E'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1734 | $type = 'N'; |
| 1735 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1736 | } elsif ($cur =~/^(case)/o) { |
| 1737 | print "CASE($1)\n" if ($dbg_values > 1); |
| 1738 | $av_pend_colon = 'C'; |
| 1739 | $type = 'N'; |
| 1740 | |
Andy Whitcroft | 14b111c | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 1741 | } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1742 | print "KEYWORD($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1743 | $type = 'N'; |
| 1744 | |
| 1745 | } elsif ($cur =~ /^(\()/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1746 | print "PAREN('$1')\n" if ($dbg_values > 1); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1747 | push(@av_paren_type, $av_pending); |
| 1748 | $av_pending = '_'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1749 | $type = 'N'; |
| 1750 | |
| 1751 | } elsif ($cur =~ /^(\))/o) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1752 | my $new_type = pop(@av_paren_type); |
| 1753 | if ($new_type ne '_') { |
| 1754 | $type = $new_type; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1755 | print "PAREN('$1') -> $type\n" |
| 1756 | if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1757 | } else { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1758 | print "PAREN('$1')\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1759 | } |
| 1760 | |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 1761 | } elsif ($cur =~ /^($Ident)\s*\(/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1762 | print "FUNC($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | c8cb2ca | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 1763 | $type = 'V'; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1764 | $av_pending = 'V'; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1765 | |
Andy Whitcroft | 8e761b0 | 2009-01-06 14:41:19 -0800 | [diff] [blame] | 1766 | } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { |
| 1767 | if (defined $2 && $type eq 'C' || $type eq 'T') { |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1768 | $av_pend_colon = 'B'; |
Andy Whitcroft | 8e761b0 | 2009-01-06 14:41:19 -0800 | [diff] [blame] | 1769 | } elsif ($type eq 'E') { |
| 1770 | $av_pend_colon = 'L'; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1771 | } |
| 1772 | print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); |
| 1773 | $type = 'V'; |
| 1774 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1775 | } elsif ($cur =~ /^($Ident|$Constant)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1776 | print "IDENT($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1777 | $type = 'V'; |
| 1778 | |
| 1779 | } elsif ($cur =~ /^($Assignment)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1780 | print "ASSIGN($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1781 | $type = 'N'; |
| 1782 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 1783 | } elsif ($cur =~/^(;|{|})/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1784 | print "END($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1785 | $type = 'E'; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1786 | $av_pend_colon = 'O'; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1787 | |
Andy Whitcroft | 8e761b0 | 2009-01-06 14:41:19 -0800 | [diff] [blame] | 1788 | } elsif ($cur =~/^(,)/) { |
| 1789 | print "COMMA($1)\n" if ($dbg_values > 1); |
| 1790 | $type = 'C'; |
| 1791 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1792 | } elsif ($cur =~ /^(\?)/o) { |
| 1793 | print "QUESTION($1)\n" if ($dbg_values > 1); |
| 1794 | $type = 'N'; |
| 1795 | |
| 1796 | } elsif ($cur =~ /^(:)/o) { |
| 1797 | print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); |
| 1798 | |
| 1799 | substr($var, length($res), 1, $av_pend_colon); |
| 1800 | if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { |
| 1801 | $type = 'E'; |
| 1802 | } else { |
| 1803 | $type = 'N'; |
| 1804 | } |
| 1805 | $av_pend_colon = 'O'; |
| 1806 | |
Andy Whitcroft | 8e761b0 | 2009-01-06 14:41:19 -0800 | [diff] [blame] | 1807 | } elsif ($cur =~ /^(\[)/o) { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1808 | print "CLOSE($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1809 | $type = 'N'; |
| 1810 | |
Andy Whitcroft | 0d41386 | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 1811 | } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { |
Andy Whitcroft | 74048ed | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1812 | my $variant; |
| 1813 | |
| 1814 | print "OPV($1)\n" if ($dbg_values > 1); |
| 1815 | if ($type eq 'V') { |
| 1816 | $variant = 'B'; |
| 1817 | } else { |
| 1818 | $variant = 'U'; |
| 1819 | } |
| 1820 | |
| 1821 | substr($var, length($res), 1, $variant); |
| 1822 | $type = 'N'; |
| 1823 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1824 | } elsif ($cur =~ /^($Operators)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1825 | print "OP($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1826 | if ($1 ne '++' && $1 ne '--') { |
| 1827 | $type = 'N'; |
| 1828 | } |
| 1829 | |
| 1830 | } elsif ($cur =~ /(^.)/o) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 1831 | print "C($1)\n" if ($dbg_values > 1); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1832 | } |
| 1833 | if (defined $1) { |
| 1834 | $cur = substr($cur, length($1)); |
| 1835 | $res .= $type x length($1); |
| 1836 | } |
| 1837 | } |
| 1838 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 1839 | return ($res, $var); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1840 | } |
| 1841 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1842 | sub possible { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1843 | my ($possible, $line) = @_; |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 1844 | my $notPermitted = qr{(?: |
Andy Whitcroft | 0776e59 | 2008-10-15 22:02:29 -0700 | [diff] [blame] | 1845 | ^(?: |
| 1846 | $Modifier| |
| 1847 | $Storage| |
| 1848 | $Type| |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 1849 | DEFINE_\S+ |
| 1850 | )$| |
| 1851 | ^(?: |
Andy Whitcroft | 0776e59 | 2008-10-15 22:02:29 -0700 | [diff] [blame] | 1852 | goto| |
| 1853 | return| |
| 1854 | case| |
| 1855 | else| |
| 1856 | asm|__asm__| |
Andy Whitcroft | 89a8835 | 2012-01-10 15:10:00 -0800 | [diff] [blame] | 1857 | do| |
| 1858 | \#| |
| 1859 | \#\#| |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 1860 | )(?:\s|$)| |
Andy Whitcroft | 0776e59 | 2008-10-15 22:02:29 -0700 | [diff] [blame] | 1861 | ^(?:typedef|struct|enum)\b |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 1862 | )}x; |
| 1863 | warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); |
| 1864 | if ($possible !~ $notPermitted) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1865 | # Check for modifiers. |
| 1866 | $possible =~ s/\s*$Storage\s*//g; |
| 1867 | $possible =~ s/\s*$Sparse\s*//g; |
| 1868 | if ($possible =~ /^\s*$/) { |
| 1869 | |
| 1870 | } elsif ($possible =~ /\s/) { |
| 1871 | $possible =~ s/\s*$Type\s*//g; |
Andy Whitcroft | d250658 | 2008-07-23 21:29:09 -0700 | [diff] [blame] | 1872 | for my $modifier (split(' ', $possible)) { |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 1873 | if ($modifier !~ $notPermitted) { |
| 1874 | warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 1875 | push(@modifierListFile, $modifier); |
Andy Whitcroft | 9a974fd | 2009-10-26 16:50:12 -0700 | [diff] [blame] | 1876 | } |
Andy Whitcroft | d250658 | 2008-07-23 21:29:09 -0700 | [diff] [blame] | 1877 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1878 | |
| 1879 | } else { |
| 1880 | warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); |
Alex Dowad | 485ff23 | 2015-06-25 15:02:52 -0700 | [diff] [blame] | 1881 | push(@typeListFile, $possible); |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 1882 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1883 | build_types(); |
Andy Whitcroft | 0776e59 | 2008-10-15 22:02:29 -0700 | [diff] [blame] | 1884 | } else { |
| 1885 | warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1886 | } |
| 1887 | } |
| 1888 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 1889 | my $prefix = ''; |
| 1890 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 1891 | sub show_type { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 1892 | my ($type) = @_; |
Joe Perches | 91bfe48 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 1893 | |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 1894 | $type =~ tr/[a-z]/[A-Z]/; |
| 1895 | |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 1896 | return defined $use_type{$type} if (scalar keys %use_type > 0); |
| 1897 | |
| 1898 | return !defined $ignore_type{$type}; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 1899 | } |
| 1900 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1901 | sub report { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 1902 | my ($level, $type, $msg) = @_; |
| 1903 | |
| 1904 | if (!show_type($type) || |
| 1905 | (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1906 | return 0; |
| 1907 | } |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 1908 | my $output = ''; |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 1909 | if ($color) { |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 1910 | if ($level eq 'ERROR') { |
| 1911 | $output .= RED; |
| 1912 | } elsif ($level eq 'WARNING') { |
| 1913 | $output .= YELLOW; |
| 1914 | } else { |
| 1915 | $output .= GREEN; |
| 1916 | } |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 1917 | } |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 1918 | $output .= $prefix . $level . ':'; |
| 1919 | if ($show_types) { |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 1920 | $output .= BLUE if ($color); |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 1921 | $output .= "$type:"; |
| 1922 | } |
John Brooks | 737c076 | 2017-07-10 15:52:24 -0700 | [diff] [blame] | 1923 | $output .= RESET if ($color); |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 1924 | $output .= ' ' . $msg . "\n"; |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 1925 | |
| 1926 | if ($showfile) { |
| 1927 | my @lines = split("\n", $output, -1); |
| 1928 | splice(@lines, 1, 1); |
| 1929 | $output = join("\n", @lines); |
| 1930 | } |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 1931 | $output = (split('\n', $output))[0] . "\n" if ($terse); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 1932 | |
Joe Perches | 5723029 | 2015-06-25 15:03:03 -0700 | [diff] [blame] | 1933 | push(our @report, $output); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 1934 | |
| 1935 | return 1; |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1936 | } |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 1937 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1938 | sub report_dump { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 1939 | our @report; |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 1940 | } |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 1941 | |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 1942 | sub fixup_current_range { |
| 1943 | my ($lineRef, $offset, $length) = @_; |
| 1944 | |
| 1945 | if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { |
| 1946 | my $o = $1; |
| 1947 | my $l = $2; |
| 1948 | my $no = $o + $offset; |
| 1949 | my $nl = $l + $length; |
| 1950 | $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; |
| 1951 | } |
| 1952 | } |
| 1953 | |
| 1954 | sub fix_inserted_deleted_lines { |
| 1955 | my ($linesRef, $insertedRef, $deletedRef) = @_; |
| 1956 | |
| 1957 | my $range_last_linenr = 0; |
| 1958 | my $delta_offset = 0; |
| 1959 | |
| 1960 | my $old_linenr = 0; |
| 1961 | my $new_linenr = 0; |
| 1962 | |
| 1963 | my $next_insert = 0; |
| 1964 | my $next_delete = 0; |
| 1965 | |
| 1966 | my @lines = (); |
| 1967 | |
| 1968 | my $inserted = @{$insertedRef}[$next_insert++]; |
| 1969 | my $deleted = @{$deletedRef}[$next_delete++]; |
| 1970 | |
| 1971 | foreach my $old_line (@{$linesRef}) { |
| 1972 | my $save_line = 1; |
| 1973 | my $line = $old_line; #don't modify the array |
Joe Perches | 323b267 | 2015-04-16 12:44:50 -0700 | [diff] [blame] | 1974 | if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 1975 | $delta_offset = 0; |
| 1976 | } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk |
| 1977 | $range_last_linenr = $new_linenr; |
| 1978 | fixup_current_range(\$line, $delta_offset, 0); |
| 1979 | } |
| 1980 | |
| 1981 | while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { |
| 1982 | $deleted = @{$deletedRef}[$next_delete++]; |
| 1983 | $save_line = 0; |
| 1984 | fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); |
| 1985 | } |
| 1986 | |
| 1987 | while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { |
| 1988 | push(@lines, ${$inserted}{'LINE'}); |
| 1989 | $inserted = @{$insertedRef}[$next_insert++]; |
| 1990 | $new_linenr++; |
| 1991 | fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); |
| 1992 | } |
| 1993 | |
| 1994 | if ($save_line) { |
| 1995 | push(@lines, $line); |
| 1996 | $new_linenr++; |
| 1997 | } |
| 1998 | |
| 1999 | $old_linenr++; |
| 2000 | } |
| 2001 | |
| 2002 | return @lines; |
| 2003 | } |
| 2004 | |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 2005 | sub fix_insert_line { |
| 2006 | my ($linenr, $line) = @_; |
| 2007 | |
| 2008 | my $inserted = { |
| 2009 | LINENR => $linenr, |
| 2010 | LINE => $line, |
| 2011 | }; |
| 2012 | push(@fixed_inserted, $inserted); |
| 2013 | } |
| 2014 | |
| 2015 | sub fix_delete_line { |
| 2016 | my ($linenr, $line) = @_; |
| 2017 | |
| 2018 | my $deleted = { |
| 2019 | LINENR => $linenr, |
| 2020 | LINE => $line, |
| 2021 | }; |
| 2022 | |
| 2023 | push(@fixed_deleted, $deleted); |
| 2024 | } |
| 2025 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2026 | sub ERROR { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2027 | my ($type, $msg) = @_; |
| 2028 | |
| 2029 | if (report("ERROR", $type, $msg)) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2030 | our $clean = 0; |
| 2031 | our $cnt_error++; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2032 | return 1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2033 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2034 | return 0; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2035 | } |
| 2036 | sub WARN { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2037 | my ($type, $msg) = @_; |
| 2038 | |
| 2039 | if (report("WARNING", $type, $msg)) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2040 | our $clean = 0; |
| 2041 | our $cnt_warn++; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2042 | return 1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2043 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2044 | return 0; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2045 | } |
| 2046 | sub CHK { |
Joe Perches | cbec18a | 2014-04-03 14:49:19 -0700 | [diff] [blame] | 2047 | my ($type, $msg) = @_; |
| 2048 | |
| 2049 | if ($check && report("CHECK", $type, $msg)) { |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2050 | our $clean = 0; |
| 2051 | our $cnt_chk++; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2052 | return 1; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2053 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2054 | return 0; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2055 | } |
| 2056 | |
Andy Whitcroft | 6ecd967 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 2057 | sub check_absolute_file { |
| 2058 | my ($absolute, $herecurr) = @_; |
| 2059 | my $file = $absolute; |
| 2060 | |
| 2061 | ##print "absolute<$absolute>\n"; |
| 2062 | |
| 2063 | # See if any suffix of this path is a path within the tree. |
| 2064 | while ($file =~ s@^[^/]*/@@) { |
| 2065 | if (-f "$root/$file") { |
| 2066 | ##print "file<$file>\n"; |
| 2067 | last; |
| 2068 | } |
| 2069 | } |
| 2070 | if (! -f _) { |
| 2071 | return 0; |
| 2072 | } |
| 2073 | |
| 2074 | # It is, so see if the prefix is acceptable. |
| 2075 | my $prefix = $absolute; |
| 2076 | substr($prefix, -length($file)) = ''; |
| 2077 | |
| 2078 | ##print "prefix<$prefix>\n"; |
| 2079 | if ($prefix ne ".../") { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2080 | WARN("USE_RELATIVE_PATH", |
| 2081 | "use relative pathname instead of absolute in changelog text\n" . $herecurr); |
Andy Whitcroft | 6ecd967 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 2082 | } |
| 2083 | } |
| 2084 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2085 | sub trim { |
| 2086 | my ($string) = @_; |
| 2087 | |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 2088 | $string =~ s/^\s+|\s+$//g; |
| 2089 | |
| 2090 | return $string; |
| 2091 | } |
| 2092 | |
| 2093 | sub ltrim { |
| 2094 | my ($string) = @_; |
| 2095 | |
| 2096 | $string =~ s/^\s+//; |
| 2097 | |
| 2098 | return $string; |
| 2099 | } |
| 2100 | |
| 2101 | sub rtrim { |
| 2102 | my ($string) = @_; |
| 2103 | |
| 2104 | $string =~ s/\s+$//; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2105 | |
| 2106 | return $string; |
| 2107 | } |
| 2108 | |
Joe Perches | 52ea850 | 2013-11-12 15:10:09 -0800 | [diff] [blame] | 2109 | sub string_find_replace { |
| 2110 | my ($string, $find, $replace) = @_; |
| 2111 | |
| 2112 | $string =~ s/$find/$replace/g; |
| 2113 | |
| 2114 | return $string; |
| 2115 | } |
| 2116 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2117 | sub tabify { |
| 2118 | my ($leading) = @_; |
| 2119 | |
| 2120 | my $source_indent = 8; |
| 2121 | my $max_spaces_before_tab = $source_indent - 1; |
| 2122 | my $spaces_to_tab = " " x $source_indent; |
| 2123 | |
| 2124 | #convert leading spaces to tabs |
| 2125 | 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; |
| 2126 | #Remove spaces before a tab |
| 2127 | 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; |
| 2128 | |
| 2129 | return "$leading"; |
| 2130 | } |
| 2131 | |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 2132 | sub pos_last_openparen { |
| 2133 | my ($line) = @_; |
| 2134 | |
| 2135 | my $pos = 0; |
| 2136 | |
| 2137 | my $opens = $line =~ tr/\(/\(/; |
| 2138 | my $closes = $line =~ tr/\)/\)/; |
| 2139 | |
| 2140 | my $last_openparen = 0; |
| 2141 | |
| 2142 | if (($opens == 0) || ($closes >= $opens)) { |
| 2143 | return -1; |
| 2144 | } |
| 2145 | |
| 2146 | my $len = length($line); |
| 2147 | |
| 2148 | for ($pos = 0; $pos < $len; $pos++) { |
| 2149 | my $string = substr($line, $pos); |
| 2150 | if ($string =~ /^($FuncArg|$balanced_parens)/) { |
| 2151 | $pos += length($1) - 1; |
| 2152 | } elsif (substr($line, $pos, 1) eq '(') { |
| 2153 | $last_openparen = $pos; |
| 2154 | } elsif (index($string, '(') == -1) { |
| 2155 | last; |
| 2156 | } |
| 2157 | } |
| 2158 | |
Joe Perches | 91cb519 | 2014-04-03 14:49:32 -0700 | [diff] [blame] | 2159 | return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 2160 | } |
| 2161 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2162 | sub process { |
| 2163 | my $filename = shift; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2164 | |
| 2165 | my $linenr=0; |
| 2166 | my $prevline=""; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2167 | my $prevrawline=""; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2168 | my $stashline=""; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2169 | my $stashrawline=""; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2170 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2171 | my $length; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2172 | my $indent; |
| 2173 | my $previndent=0; |
| 2174 | my $stashindent=0; |
| 2175 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2176 | our $clean = 1; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2177 | my $signoff = 0; |
| 2178 | my $is_patch = 0; |
Joe Perches | 29ee1b0 | 2014-08-06 16:10:35 -0700 | [diff] [blame] | 2179 | my $in_header_lines = $file ? 0 : 1; |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2180 | my $in_commit_log = 0; #Scanning lines before patch |
Allen Hubbe | ed43c4e | 2016-08-02 14:04:45 -0700 | [diff] [blame] | 2181 | my $has_commit_log = 0; #Encountered lines before patch |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 2182 | my $commit_log_possible_stack_dump = 0; |
Joe Perches | 2a076f4 | 2015-04-16 12:44:28 -0700 | [diff] [blame] | 2183 | my $commit_log_long_line = 0; |
Joe Perches | e518e9a | 2015-06-25 15:03:27 -0700 | [diff] [blame] | 2184 | my $commit_log_has_diff = 0; |
Joe Perches | 13f1937 | 2014-08-06 16:10:59 -0700 | [diff] [blame] | 2185 | my $reported_maintainer_file = 0; |
Pasi Savanainen | fa64205d | 2012-10-04 17:13:29 -0700 | [diff] [blame] | 2186 | my $non_utf8_charset = 0; |
| 2187 | |
Joe Perches | 365dd4e | 2014-08-06 16:10:42 -0700 | [diff] [blame] | 2188 | my $last_blank_line = 0; |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 2189 | my $last_coalesced_string_linenr = -1; |
Joe Perches | 365dd4e | 2014-08-06 16:10:42 -0700 | [diff] [blame] | 2190 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2191 | our @report = (); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2192 | our $cnt_lines = 0; |
| 2193 | our $cnt_error = 0; |
| 2194 | our $cnt_warn = 0; |
| 2195 | our $cnt_chk = 0; |
| 2196 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2197 | # Trace the real file/line as we go. |
| 2198 | my $realfile = ''; |
| 2199 | my $realline = 0; |
| 2200 | my $realcnt = 0; |
| 2201 | my $here = ''; |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 2202 | my $context_function; #undef'd unless there's a known function |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2203 | my $in_comment = 0; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2204 | my $comment_edge = 0; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2205 | my $first_line = 0; |
Wolfram Sang | 1e85572 | 2009-01-06 14:41:24 -0800 | [diff] [blame] | 2206 | my $p1_prefix = ''; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2207 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2208 | my $prev_values = 'E'; |
| 2209 | |
| 2210 | # suppression flags |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2211 | my %suppress_ifbraces; |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 2212 | my %suppress_whiletrailers; |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 2213 | my %suppress_export; |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 2214 | my $suppress_statement = 0; |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 2215 | |
Joe Perches | 7e51f19 | 2013-09-11 14:23:57 -0700 | [diff] [blame] | 2216 | my %signatures = (); |
Joe Perches | 323c126 | 2012-12-17 16:02:07 -0800 | [diff] [blame] | 2217 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2218 | # Pre-scan the patch sanitizing the lines. |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2219 | # Pre-scan the patch looking for any __setup documentation. |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2220 | # |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2221 | my @setup_docs = (); |
| 2222 | my $setup_docs = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2223 | |
Joe Perches | d8b0771 | 2013-11-12 15:10:06 -0800 | [diff] [blame] | 2224 | my $camelcase_file_seeded = 0; |
| 2225 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2226 | sanitise_line_reset(); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2227 | my $line; |
| 2228 | foreach my $rawline (@rawlines) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2229 | $linenr++; |
| 2230 | $line = $rawline; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2231 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2232 | push(@fixed, $rawline) if ($fix); |
| 2233 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2234 | if ($rawline=~/^\+\+\+\s+(\S+)/) { |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2235 | $setup_docs = 0; |
Mauro Carvalho Chehab | 8c27ceff3 | 2016-10-18 10:12:27 -0200 | [diff] [blame] | 2236 | if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2237 | $setup_docs = 1; |
| 2238 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2239 | #next; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2240 | } |
Joe Perches | 74fd4f3 | 2017-05-08 15:56:02 -0700 | [diff] [blame] | 2241 | if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2242 | $realline=$1-1; |
| 2243 | if (defined $2) { |
| 2244 | $realcnt=$3+1; |
| 2245 | } else { |
| 2246 | $realcnt=1+1; |
| 2247 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 2248 | $in_comment = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2249 | |
| 2250 | # Guestimate if this is a continuing comment. Run |
| 2251 | # the context looking for a comment "edge". If this |
| 2252 | # edge is a close comment then we must be in a comment |
| 2253 | # at context start. |
| 2254 | my $edge; |
Andy Whitcroft | 01fa914 | 2008-10-15 22:02:19 -0700 | [diff] [blame] | 2255 | my $cnt = $realcnt; |
| 2256 | for (my $ln = $linenr + 1; $cnt > 0; $ln++) { |
| 2257 | next if (defined $rawlines[$ln - 1] && |
| 2258 | $rawlines[$ln - 1] =~ /^-/); |
| 2259 | $cnt--; |
| 2260 | #print "RAW<$rawlines[$ln - 1]>\n"; |
Andy Whitcroft | 721c1cb | 2009-01-06 14:41:16 -0800 | [diff] [blame] | 2261 | last if (!defined $rawlines[$ln - 1]); |
Andy Whitcroft | fae17da | 2009-01-06 14:41:20 -0800 | [diff] [blame] | 2262 | if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && |
| 2263 | $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { |
| 2264 | ($edge) = $1; |
| 2265 | last; |
| 2266 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2267 | } |
| 2268 | if (defined $edge && $edge eq '*/') { |
| 2269 | $in_comment = 1; |
| 2270 | } |
| 2271 | |
| 2272 | # Guestimate if this is a continuing comment. If this |
| 2273 | # is the start of a diff block and this line starts |
| 2274 | # ' *' then it is very likely a comment. |
| 2275 | if (!defined $edge && |
Andy Whitcroft | 83242e0 | 2009-01-06 14:41:17 -0800 | [diff] [blame] | 2276 | $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2277 | { |
| 2278 | $in_comment = 1; |
| 2279 | } |
| 2280 | |
| 2281 | ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; |
| 2282 | sanitise_line_reset($in_comment); |
| 2283 | |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2284 | } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2285 | # Standardise the strings and chars within the input to |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2286 | # simplify matching -- only bother with positive lines. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2287 | $line = sanitise_line($rawline); |
| 2288 | } |
| 2289 | push(@lines, $line); |
| 2290 | |
| 2291 | if ($realcnt > 1) { |
| 2292 | $realcnt-- if ($line =~ /^(?:\+| |$)/); |
| 2293 | } else { |
| 2294 | $realcnt = 0; |
| 2295 | } |
| 2296 | |
| 2297 | #print "==>$rawline\n"; |
| 2298 | #print "-->$line\n"; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2299 | |
| 2300 | if ($setup_docs && $line =~ /^\+/) { |
| 2301 | push(@setup_docs, $line); |
| 2302 | } |
| 2303 | } |
| 2304 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2305 | $prefix = ''; |
| 2306 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2307 | $realcnt = 0; |
| 2308 | $linenr = 0; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2309 | $fixlinenr = -1; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2310 | foreach my $line (@lines) { |
| 2311 | $linenr++; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2312 | $fixlinenr++; |
Joe Perches | 1b5539b | 2013-09-11 14:24:03 -0700 | [diff] [blame] | 2313 | my $sline = $line; #copy of $line |
| 2314 | $sline =~ s/$;/ /g; #with comments as spaces |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2315 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2316 | my $rawline = $rawlines[$linenr - 1]; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2317 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2318 | #extract the line range in the file after the patch is applied |
Joe Perches | e518e9a | 2015-06-25 15:03:27 -0700 | [diff] [blame] | 2319 | if (!$in_commit_log && |
Joe Perches | 74fd4f3 | 2017-05-08 15:56:02 -0700 | [diff] [blame] | 2320 | $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { |
| 2321 | my $context = $4; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2322 | $is_patch = 1; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2323 | $first_line = $linenr + 1; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2324 | $realline=$1-1; |
| 2325 | if (defined $2) { |
| 2326 | $realcnt=$3+1; |
| 2327 | } else { |
| 2328 | $realcnt=1+1; |
| 2329 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2330 | annotate_reset(); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 2331 | $prev_values = 'E'; |
| 2332 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2333 | %suppress_ifbraces = (); |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 2334 | %suppress_whiletrailers = (); |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 2335 | %suppress_export = (); |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 2336 | $suppress_statement = 0; |
Joe Perches | 74fd4f3 | 2017-05-08 15:56:02 -0700 | [diff] [blame] | 2337 | if ($context =~ /\b(\w+)\s*\(/) { |
| 2338 | $context_function = $1; |
| 2339 | } else { |
| 2340 | undef $context_function; |
| 2341 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2342 | next; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2343 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2344 | # track the line number as we move through the hunk, note that |
| 2345 | # new versions of GNU diff omit the leading space on completely |
| 2346 | # blank context lines so we need to count that too. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2347 | } elsif ($line =~ /^( |\+|$)/) { |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2348 | $realline++; |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 2349 | $realcnt-- if ($realcnt != 0); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2350 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2351 | # Measure the line length and indent. |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2352 | ($length, $indent) = line_stats($rawline); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2353 | |
| 2354 | # Track the previous line. |
| 2355 | ($prevline, $stashline) = ($stashline, $line); |
| 2356 | ($previndent, $stashindent) = ($stashindent, $indent); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2357 | ($prevrawline, $stashrawline) = ($stashrawline, $rawline); |
| 2358 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2359 | #warn "line<$line>\n"; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2360 | |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 2361 | } elsif ($realcnt == 1) { |
| 2362 | $realcnt--; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2363 | } |
| 2364 | |
Andy Whitcroft | cc77cdc | 2009-10-26 16:50:13 -0700 | [diff] [blame] | 2365 | my $hunk_line = ($realcnt != 0); |
| 2366 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2367 | $here = "#$linenr: " if (!$file); |
| 2368 | $here = "#$realline: " if ($file); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2369 | |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2370 | my $found_file = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2371 | # extract the filename as it passes |
Rabin Vincent | 3bf9a00 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 2372 | if ($line =~ /^diff --git.*?(\S+)$/) { |
| 2373 | $realfile = $1; |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 2374 | $realfile =~ s@^([^/]*)/@@ if (!$file); |
Joe Perches | 270c49a | 2012-01-10 15:09:50 -0800 | [diff] [blame] | 2375 | $in_commit_log = 0; |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2376 | $found_file = 1; |
Rabin Vincent | 3bf9a00 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 2377 | } elsif ($line =~ /^\+\+\+\s+(\S+)/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2378 | $realfile = $1; |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 2379 | $realfile =~ s@^([^/]*)/@@ if (!$file); |
Joe Perches | 270c49a | 2012-01-10 15:09:50 -0800 | [diff] [blame] | 2380 | $in_commit_log = 0; |
Wolfram Sang | 1e85572 | 2009-01-06 14:41:24 -0800 | [diff] [blame] | 2381 | |
| 2382 | $p1_prefix = $1; |
Andy Whitcroft | e2f7aa4 | 2009-02-27 14:03:06 -0800 | [diff] [blame] | 2383 | if (!$file && $tree && $p1_prefix ne '' && |
| 2384 | -e "$root/$p1_prefix") { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2385 | WARN("PATCH_PREFIX", |
| 2386 | "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); |
Wolfram Sang | 1e85572 | 2009-01-06 14:41:24 -0800 | [diff] [blame] | 2387 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2388 | |
Andy Whitcroft | c1ab332 | 2008-10-15 22:02:20 -0700 | [diff] [blame] | 2389 | if ($realfile =~ m@^include/asm/@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2390 | ERROR("MODIFIED_INCLUDE_ASM", |
| 2391 | "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] | 2392 | } |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2393 | $found_file = 1; |
| 2394 | } |
| 2395 | |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 2396 | #make up the handle for any error we report on this line |
| 2397 | if ($showfile) { |
| 2398 | $prefix = "$realfile:$realline: " |
| 2399 | } elsif ($emacs) { |
Joe Perches | 7d3a9f6 | 2015-09-09 15:37:39 -0700 | [diff] [blame] | 2400 | if ($file) { |
| 2401 | $prefix = "$filename:$realline: "; |
| 2402 | } else { |
| 2403 | $prefix = "$filename:$linenr: "; |
| 2404 | } |
Joe Perches | 34d8815 | 2015-06-25 15:03:05 -0700 | [diff] [blame] | 2405 | } |
| 2406 | |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2407 | if ($found_file) { |
Joe Perches | 85b0ee1 | 2016-10-11 13:51:44 -0700 | [diff] [blame] | 2408 | if (is_maintained_obsolete($realfile)) { |
| 2409 | WARN("OBSOLETE", |
| 2410 | "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); |
| 2411 | } |
Joe Perches | 7bd7e48 | 2015-09-09 15:37:44 -0700 | [diff] [blame] | 2412 | if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { |
Joe Perches | 2ac73b4 | 2014-06-04 16:12:05 -0700 | [diff] [blame] | 2413 | $check = 1; |
| 2414 | } else { |
| 2415 | $check = $check_orig; |
| 2416 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 2417 | next; |
| 2418 | } |
| 2419 | |
Randy Dunlap | 389834b | 2007-06-08 13:47:03 -0700 | [diff] [blame] | 2420 | $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2421 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2422 | my $hereline = "$here\n$rawline\n"; |
| 2423 | my $herecurr = "$here\n$rawline\n"; |
| 2424 | my $hereprev = "$here\n$prevrawline\n$rawline\n"; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2425 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2426 | $cnt_lines++ if ($realcnt != 0); |
| 2427 | |
Joe Perches | e518e9a | 2015-06-25 15:03:27 -0700 | [diff] [blame] | 2428 | # Check if the commit log has what seems like a diff which can confuse patch |
| 2429 | if ($in_commit_log && !$commit_log_has_diff && |
| 2430 | (($line =~ m@^\s+diff\b.*a/[\w/]+@ && |
| 2431 | $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || |
| 2432 | $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || |
| 2433 | $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { |
| 2434 | ERROR("DIFF_IN_COMMIT_MSG", |
| 2435 | "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); |
| 2436 | $commit_log_has_diff = 1; |
| 2437 | } |
| 2438 | |
Rabin Vincent | 3bf9a00 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 2439 | # Check for incorrect file permissions |
| 2440 | if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { |
| 2441 | my $permhere = $here . "FILE: $realfile\n"; |
Joe Perches | 04db4d2 | 2013-04-29 16:18:14 -0700 | [diff] [blame] | 2442 | if ($realfile !~ m@scripts/@ && |
| 2443 | $realfile !~ /\.(py|pl|awk|sh)$/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2444 | ERROR("EXECUTE_PERMISSIONS", |
| 2445 | "do not set execute permissions for source files\n" . $permhere); |
Rabin Vincent | 3bf9a00 | 2010-10-26 14:23:16 -0700 | [diff] [blame] | 2446 | } |
| 2447 | } |
| 2448 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2449 | # Check the patch for a signoff: |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 2450 | if ($line =~ /^\s*signed-off-by:/i) { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 2451 | $signoff++; |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2452 | $in_commit_log = 0; |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2453 | } |
| 2454 | |
Joe Perches | e0d975b | 2014-12-10 15:51:49 -0800 | [diff] [blame] | 2455 | # Check if MAINTAINERS is being updated. If so, there's probably no need to |
| 2456 | # emit the "does MAINTAINERS need updating?" message on file add/move/delete |
| 2457 | if ($line =~ /^\s*MAINTAINERS\s*\|/) { |
| 2458 | $reported_maintainer_file = 1; |
| 2459 | } |
| 2460 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2461 | # Check signature styles |
Joe Perches | 270c49a | 2012-01-10 15:09:50 -0800 | [diff] [blame] | 2462 | if (!$in_header_lines && |
Joe Perches | ce0338df3c | 2012-07-30 14:41:18 -0700 | [diff] [blame] | 2463 | $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2464 | my $space_before = $1; |
| 2465 | my $sign_off = $2; |
| 2466 | my $space_after = $3; |
| 2467 | my $email = $4; |
| 2468 | my $ucfirst_sign_off = ucfirst(lc($sign_off)); |
| 2469 | |
Joe Perches | ce0338df3c | 2012-07-30 14:41:18 -0700 | [diff] [blame] | 2470 | if ($sign_off !~ /$signature_tags/) { |
| 2471 | WARN("BAD_SIGN_OFF", |
| 2472 | "Non-standard signature: $sign_off\n" . $herecurr); |
| 2473 | } |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2474 | if (defined $space_before && $space_before ne "") { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2475 | if (WARN("BAD_SIGN_OFF", |
| 2476 | "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && |
| 2477 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2478 | $fixed[$fixlinenr] = |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2479 | "$ucfirst_sign_off $email"; |
| 2480 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2481 | } |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2482 | if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2483 | if (WARN("BAD_SIGN_OFF", |
| 2484 | "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && |
| 2485 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2486 | $fixed[$fixlinenr] = |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2487 | "$ucfirst_sign_off $email"; |
| 2488 | } |
| 2489 | |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2490 | } |
| 2491 | if (!defined $space_after || $space_after ne " ") { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2492 | if (WARN("BAD_SIGN_OFF", |
| 2493 | "Use a single space after $ucfirst_sign_off\n" . $herecurr) && |
| 2494 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2495 | $fixed[$fixlinenr] = |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2496 | "$ucfirst_sign_off $email"; |
| 2497 | } |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2498 | } |
| 2499 | |
| 2500 | my ($email_name, $email_address, $comment) = parse_email($email); |
| 2501 | my $suggested_email = format_email(($email_name, $email_address)); |
| 2502 | if ($suggested_email eq "") { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2503 | ERROR("BAD_SIGN_OFF", |
| 2504 | "Unrecognized email address: '$email'\n" . $herecurr); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2505 | } else { |
| 2506 | my $dequoted = $suggested_email; |
| 2507 | $dequoted =~ s/^"//; |
| 2508 | $dequoted =~ s/" </ </; |
| 2509 | # Don't force email to have quotes |
| 2510 | # Allow just an angle bracketed address |
| 2511 | if ("$dequoted$comment" ne $email && |
| 2512 | "<$email_address>$comment" ne $email && |
| 2513 | "$suggested_email$comment" ne $email) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2514 | WARN("BAD_SIGN_OFF", |
| 2515 | "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); |
Joe Perches | 2011247 | 2011-07-25 17:13:23 -0700 | [diff] [blame] | 2516 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2517 | } |
Joe Perches | 7e51f19 | 2013-09-11 14:23:57 -0700 | [diff] [blame] | 2518 | |
| 2519 | # Check for duplicate signatures |
| 2520 | my $sig_nospace = $line; |
| 2521 | $sig_nospace =~ s/\s//g; |
| 2522 | $sig_nospace = lc($sig_nospace); |
| 2523 | if (defined $signatures{$sig_nospace}) { |
| 2524 | WARN("BAD_SIGN_OFF", |
| 2525 | "Duplicate signature\n" . $herecurr); |
| 2526 | } else { |
| 2527 | $signatures{$sig_nospace} = 1; |
| 2528 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2529 | } |
| 2530 | |
Joe Perches | a2fe16b | 2015-02-13 14:39:02 -0800 | [diff] [blame] | 2531 | # Check email subject for common tools that don't need to be mentioned |
| 2532 | if ($in_header_lines && |
| 2533 | $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { |
| 2534 | WARN("EMAIL_SUBJECT", |
| 2535 | "A patch subject line should describe the change not the tool that found it\n" . $herecurr); |
| 2536 | } |
| 2537 | |
Joe Perches | 9b3189e | 2014-06-04 16:12:10 -0700 | [diff] [blame] | 2538 | # Check for old stable address |
| 2539 | if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { |
| 2540 | ERROR("STABLE_ADDRESS", |
| 2541 | "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); |
| 2542 | } |
| 2543 | |
Christopher Covington | 7ebd05e | 2014-04-03 14:49:31 -0700 | [diff] [blame] | 2544 | # Check for unwanted Gerrit info |
| 2545 | if ($in_commit_log && $line =~ /^\s*change-id:/i) { |
| 2546 | ERROR("GERRIT_CHANGE_ID", |
| 2547 | "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); |
| 2548 | } |
| 2549 | |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 2550 | # Check if the commit log is in a possible stack dump |
| 2551 | if ($in_commit_log && !$commit_log_possible_stack_dump && |
| 2552 | ($line =~ /^\s*(?:WARNING:|BUG:)/ || |
| 2553 | $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || |
| 2554 | # timestamp |
| 2555 | $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { |
| 2556 | # stack dump address |
| 2557 | $commit_log_possible_stack_dump = 1; |
| 2558 | } |
| 2559 | |
Joe Perches | 2a076f4 | 2015-04-16 12:44:28 -0700 | [diff] [blame] | 2560 | # Check for line lengths > 75 in commit log, warn once |
| 2561 | if ($in_commit_log && !$commit_log_long_line && |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 2562 | length($line) > 75 && |
| 2563 | !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || |
| 2564 | # file delta changes |
| 2565 | $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || |
| 2566 | # filename then : |
| 2567 | $line =~ /^\s*(?:Fixes:|Link:)/i || |
| 2568 | # A Fixes: or Link: line |
| 2569 | $commit_log_possible_stack_dump)) { |
Joe Perches | 2a076f4 | 2015-04-16 12:44:28 -0700 | [diff] [blame] | 2570 | WARN("COMMIT_LOG_LONG_LINE", |
| 2571 | "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); |
| 2572 | $commit_log_long_line = 1; |
| 2573 | } |
| 2574 | |
Joe Perches | bf4daf1 | 2015-09-09 15:37:50 -0700 | [diff] [blame] | 2575 | # Reset possible stack dump if a blank line is found |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 2576 | if ($in_commit_log && $commit_log_possible_stack_dump && |
| 2577 | $line =~ /^\s*$/) { |
| 2578 | $commit_log_possible_stack_dump = 0; |
| 2579 | } |
Joe Perches | bf4daf1 | 2015-09-09 15:37:50 -0700 | [diff] [blame] | 2580 | |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 2581 | # Check for git id commit length and improperly formed commit descriptions |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 2582 | if ($in_commit_log && !$commit_log_possible_stack_dump && |
Joe Perches | aab38f5 | 2016-08-02 14:04:36 -0700 | [diff] [blame] | 2583 | $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i && |
Wei Wang | e882dbf | 2017-05-08 15:55:54 -0700 | [diff] [blame] | 2584 | $line !~ /^This reverts commit [0-9a-f]{7,40}/ && |
Joe Perches | fe043ea | 2015-09-09 15:37:25 -0700 | [diff] [blame] | 2585 | ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || |
Joe Perches | aab38f5 | 2016-08-02 14:04:36 -0700 | [diff] [blame] | 2586 | ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && |
Joe Perches | 369c8dd | 2015-11-06 16:31:34 -0800 | [diff] [blame] | 2587 | $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && |
| 2588 | $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { |
Joe Perches | fe043ea | 2015-09-09 15:37:25 -0700 | [diff] [blame] | 2589 | my $init_char = "c"; |
| 2590 | my $orig_commit = ""; |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 2591 | my $short = 1; |
| 2592 | my $long = 0; |
| 2593 | my $case = 1; |
| 2594 | my $space = 1; |
| 2595 | my $hasdesc = 0; |
Joe Perches | 19c146a | 2015-02-13 14:39:00 -0800 | [diff] [blame] | 2596 | my $hasparens = 0; |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 2597 | my $id = '0123456789ab'; |
| 2598 | my $orig_desc = "commit description"; |
| 2599 | my $description = ""; |
| 2600 | |
Joe Perches | fe043ea | 2015-09-09 15:37:25 -0700 | [diff] [blame] | 2601 | if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { |
| 2602 | $init_char = $1; |
| 2603 | $orig_commit = lc($2); |
| 2604 | } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { |
| 2605 | $orig_commit = lc($1); |
| 2606 | } |
| 2607 | |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 2608 | $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); |
| 2609 | $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); |
| 2610 | $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); |
| 2611 | $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); |
| 2612 | if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { |
| 2613 | $orig_desc = $1; |
Joe Perches | 19c146a | 2015-02-13 14:39:00 -0800 | [diff] [blame] | 2614 | $hasparens = 1; |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 2615 | } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && |
| 2616 | defined $rawlines[$linenr] && |
| 2617 | $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { |
| 2618 | $orig_desc = $1; |
Joe Perches | 19c146a | 2015-02-13 14:39:00 -0800 | [diff] [blame] | 2619 | $hasparens = 1; |
Joe Perches | b671fde | 2015-02-13 14:38:41 -0800 | [diff] [blame] | 2620 | } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && |
| 2621 | defined $rawlines[$linenr] && |
| 2622 | $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { |
| 2623 | $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; |
| 2624 | $orig_desc = $1; |
| 2625 | $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; |
| 2626 | $orig_desc .= " " . $1; |
Joe Perches | 19c146a | 2015-02-13 14:39:00 -0800 | [diff] [blame] | 2627 | $hasparens = 1; |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 2628 | } |
| 2629 | |
| 2630 | ($id, $description) = git_commit_info($orig_commit, |
| 2631 | $id, $orig_desc); |
| 2632 | |
Heinrich Schuchardt | 948b133 | 2017-07-10 15:52:16 -0700 | [diff] [blame] | 2633 | if (defined($id) && |
| 2634 | ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { |
Joe Perches | 0d7835f | 2015-02-13 14:38:35 -0800 | [diff] [blame] | 2635 | ERROR("GIT_COMMIT_ID", |
| 2636 | "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); |
| 2637 | } |
Joe Perches | d311cd4 | 2014-08-06 16:10:57 -0700 | [diff] [blame] | 2638 | } |
| 2639 | |
Joe Perches | 13f1937 | 2014-08-06 16:10:59 -0700 | [diff] [blame] | 2640 | # Check for added, moved or deleted files |
| 2641 | if (!$reported_maintainer_file && !$in_commit_log && |
| 2642 | ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || |
| 2643 | $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || |
| 2644 | ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && |
| 2645 | (defined($1) || defined($2))))) { |
Andrew Jeffery | a82603a | 2016-12-12 16:46:37 -0800 | [diff] [blame] | 2646 | $is_patch = 1; |
Joe Perches | 13f1937 | 2014-08-06 16:10:59 -0700 | [diff] [blame] | 2647 | $reported_maintainer_file = 1; |
| 2648 | WARN("FILE_PATH_CHANGES", |
| 2649 | "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); |
| 2650 | } |
| 2651 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 2652 | # Check for wrappage within a valid hunk of the file |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 2653 | if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2654 | ERROR("CORRUPTED_PATCH", |
| 2655 | "patch seems to be corrupt (line wrapped?)\n" . |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 2656 | $herecurr) if (!$emitted_corrupt++); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 2657 | } |
| 2658 | |
| 2659 | # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php |
| 2660 | if (($realfile =~ /^$/ || $line =~ /^\+/) && |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 2661 | $rawline !~ m/^$UTF8*$/) { |
| 2662 | my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); |
| 2663 | |
| 2664 | my $blank = copy_spacing($rawline); |
| 2665 | my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; |
| 2666 | my $hereptr = "$hereline$ptr\n"; |
| 2667 | |
Joe Perches | 34d9921 | 2011-07-25 17:13:26 -0700 | [diff] [blame] | 2668 | CHK("INVALID_UTF8", |
| 2669 | "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] | 2670 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2671 | |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2672 | # Check if it's the start of a commit log |
| 2673 | # (not a header line and we haven't seen the patch filename) |
| 2674 | if ($in_header_lines && $realfile =~ /^$/ && |
Joe Perches | eb3a58d | 2017-05-08 15:55:42 -0700 | [diff] [blame] | 2675 | !($rawline =~ /^\s+(?:\S|$)/ || |
| 2676 | $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2677 | $in_header_lines = 0; |
| 2678 | $in_commit_log = 1; |
Allen Hubbe | ed43c4e | 2016-08-02 14:04:45 -0700 | [diff] [blame] | 2679 | $has_commit_log = 1; |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2680 | } |
| 2681 | |
Pasi Savanainen | fa64205d | 2012-10-04 17:13:29 -0700 | [diff] [blame] | 2682 | # Check if there is UTF-8 in a commit log when a mail header has explicitly |
| 2683 | # declined it, i.e defined some charset where it is missing. |
| 2684 | if ($in_header_lines && |
| 2685 | $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && |
| 2686 | $1 !~ /utf-8/i) { |
| 2687 | $non_utf8_charset = 1; |
| 2688 | } |
| 2689 | |
| 2690 | if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2691 | $rawline =~ /$NON_ASCII_UTF8/) { |
Pasi Savanainen | fa64205d | 2012-10-04 17:13:29 -0700 | [diff] [blame] | 2692 | WARN("UTF8_BEFORE_PATCH", |
Joe Perches | 15662b3 | 2011-10-31 17:13:12 -0700 | [diff] [blame] | 2693 | "8-bit UTF-8 used in possible commit log\n" . $herecurr); |
| 2694 | } |
| 2695 | |
Joe Perches | d6430f7 | 2016-12-12 16:46:28 -0800 | [diff] [blame] | 2696 | # Check for absolute kernel paths in commit message |
| 2697 | if ($tree && $in_commit_log) { |
| 2698 | while ($line =~ m{(?:^|\s)(/\S*)}g) { |
| 2699 | my $file = $1; |
| 2700 | |
| 2701 | if ($file =~ m{^(.*?)(?::\d+)+:?$} && |
| 2702 | check_absolute_file($1, $herecurr)) { |
| 2703 | # |
| 2704 | } else { |
| 2705 | check_absolute_file($file, $herecurr); |
| 2706 | } |
| 2707 | } |
| 2708 | } |
| 2709 | |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 2710 | # Check for various typo / spelling mistakes |
Joe Perches | 66d7a38 | 2015-04-16 12:44:08 -0700 | [diff] [blame] | 2711 | if (defined($misspellings) && |
| 2712 | ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { |
Joe Perches | ebfd7d6 | 2015-04-16 12:44:14 -0700 | [diff] [blame] | 2713 | while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { |
Kees Cook | 66b47b4 | 2014-10-13 15:51:57 -0700 | [diff] [blame] | 2714 | my $typo = $1; |
| 2715 | my $typo_fix = $spelling_fix{lc($typo)}; |
| 2716 | $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); |
| 2717 | $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); |
| 2718 | my $msg_type = \&WARN; |
| 2719 | $msg_type = \&CHK if ($file); |
| 2720 | if (&{$msg_type}("TYPO_SPELLING", |
| 2721 | "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && |
| 2722 | $fix) { |
| 2723 | $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; |
| 2724 | } |
| 2725 | } |
| 2726 | } |
| 2727 | |
Andy Whitcroft | 30670854 | 2008-10-15 22:02:28 -0700 | [diff] [blame] | 2728 | # ignore non-hunk lines and lines being removed |
| 2729 | next if (!$hunk_line || $line =~ /^-/); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 2730 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2731 | #trailing whitespace |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 2732 | if ($line =~ /^\+.*\015/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2733 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 2734 | if (ERROR("DOS_LINE_ENDINGS", |
| 2735 | "DOS line endings\n" . $herevet) && |
| 2736 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2737 | $fixed[$fixlinenr] =~ s/[\s\015]+$//; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 2738 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2739 | } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { |
| 2740 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2741 | if (ERROR("TRAILING_WHITESPACE", |
| 2742 | "trailing whitespace\n" . $herevet) && |
| 2743 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2744 | $fixed[$fixlinenr] =~ s/\s+$//; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2745 | } |
| 2746 | |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 2747 | $rpt_cleaners = 1; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2748 | } |
Andy Whitcroft | 5368df2 | 2008-10-15 22:02:27 -0700 | [diff] [blame] | 2749 | |
Josh Triplett | 4783f89 | 2013-11-12 15:10:12 -0800 | [diff] [blame] | 2750 | # Check for FSF mailing addresses. |
Alexander Duyck | 109d8cb | 2014-01-23 15:54:50 -0800 | [diff] [blame] | 2751 | if ($rawline =~ /\bwrite to the Free/i || |
Matthew Wilcox | 1bde561 | 2017-02-24 15:01:38 -0800 | [diff] [blame] | 2752 | $rawline =~ /\b675\s+Mass\s+Ave/i || |
Joe Perches | 3e2232f | 2014-01-23 15:54:48 -0800 | [diff] [blame] | 2753 | $rawline =~ /\b59\s+Temple\s+Pl/i || |
| 2754 | $rawline =~ /\b51\s+Franklin\s+St/i) { |
Josh Triplett | 4783f89 | 2013-11-12 15:10:12 -0800 | [diff] [blame] | 2755 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
| 2756 | my $msg_type = \&ERROR; |
| 2757 | $msg_type = \&CHK if ($file); |
| 2758 | &{$msg_type}("FSF_MAILING_ADDRESS", |
Joe Perches | 3e2232f | 2014-01-23 15:54:48 -0800 | [diff] [blame] | 2759 | "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] | 2760 | } |
| 2761 | |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 2762 | # check for Kconfig help text having a real description |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 2763 | # Only applies when adding the entry originally, after that we do not have |
| 2764 | # sufficient context to determine whether it is indeed long enough. |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 2765 | if ($realfile =~ /Kconfig/ && |
Joe Perches | 8d73e0e | 2014-08-06 16:10:46 -0700 | [diff] [blame] | 2766 | $line =~ /^\+\s*config\s+/) { |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 2767 | my $length = 0; |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 2768 | my $cnt = $realcnt; |
| 2769 | my $ln = $linenr + 1; |
| 2770 | my $f; |
Andy Whitcroft | a138580 | 2012-01-10 15:10:03 -0800 | [diff] [blame] | 2771 | my $is_start = 0; |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 2772 | my $is_end = 0; |
Andy Whitcroft | a138580 | 2012-01-10 15:10:03 -0800 | [diff] [blame] | 2773 | for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 2774 | $f = $lines[$ln - 1]; |
| 2775 | $cnt-- if ($lines[$ln - 1] !~ /^-/); |
| 2776 | $is_end = $lines[$ln - 1] =~ /^\+/; |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 2777 | |
| 2778 | next if ($f =~ /^-/); |
Joe Perches | 8d73e0e | 2014-08-06 16:10:46 -0700 | [diff] [blame] | 2779 | last if (!$file && $f =~ /^\@\@/); |
Andy Whitcroft | a138580 | 2012-01-10 15:10:03 -0800 | [diff] [blame] | 2780 | |
Joe Perches | 8d73e0e | 2014-08-06 16:10:46 -0700 | [diff] [blame] | 2781 | if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { |
Andy Whitcroft | a138580 | 2012-01-10 15:10:03 -0800 | [diff] [blame] | 2782 | $is_start = 1; |
Joe Perches | 8d73e0e | 2014-08-06 16:10:46 -0700 | [diff] [blame] | 2783 | } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { |
Andy Whitcroft | a138580 | 2012-01-10 15:10:03 -0800 | [diff] [blame] | 2784 | $length = -1; |
| 2785 | } |
| 2786 | |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 2787 | $f =~ s/^.//; |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 2788 | $f =~ s/#.*//; |
| 2789 | $f =~ s/^\s+//; |
| 2790 | next if ($f =~ /^$/); |
Andy Whitcroft | 9fe287d7 | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 2791 | if ($f =~ /^\s*config\s/) { |
| 2792 | $is_end = 1; |
| 2793 | last; |
| 2794 | } |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 2795 | $length++; |
| 2796 | } |
Vadim Bendebury | 5619327 | 2014-10-13 15:51:48 -0700 | [diff] [blame] | 2797 | if ($is_start && $is_end && $length < $min_conf_desc_length) { |
| 2798 | WARN("CONFIG_DESCRIPTION", |
| 2799 | "please write a paragraph that describes the config symbol fully\n" . $herecurr); |
| 2800 | } |
Andy Whitcroft | a138580 | 2012-01-10 15:10:03 -0800 | [diff] [blame] | 2801 | #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; |
Andi Kleen | 3354957 | 2010-05-24 14:33:29 -0700 | [diff] [blame] | 2802 | } |
| 2803 | |
Joe Perches | 628f91a | 2017-07-10 15:52:07 -0700 | [diff] [blame] | 2804 | # check for MAINTAINERS entries that don't have the right form |
| 2805 | if ($realfile =~ /^MAINTAINERS$/ && |
| 2806 | $rawline =~ /^\+[A-Z]:/ && |
| 2807 | $rawline !~ /^\+[A-Z]:\t\S/) { |
| 2808 | if (WARN("MAINTAINERS_STYLE", |
| 2809 | "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && |
| 2810 | $fix) { |
| 2811 | $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; |
| 2812 | } |
| 2813 | } |
| 2814 | |
Christoph Jaeger | 327953e | 2015-02-13 14:38:29 -0800 | [diff] [blame] | 2815 | # discourage the use of boolean for type definition attributes of Kconfig options |
| 2816 | if ($realfile =~ /Kconfig/ && |
| 2817 | $line =~ /^\+\s*\bboolean\b/) { |
| 2818 | WARN("CONFIG_TYPE_BOOLEAN", |
| 2819 | "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); |
| 2820 | } |
| 2821 | |
Arnaud Lacombe | c68e587 | 2011-08-15 01:07:14 -0400 | [diff] [blame] | 2822 | if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && |
| 2823 | ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { |
| 2824 | my $flag = $1; |
| 2825 | my $replacement = { |
| 2826 | 'EXTRA_AFLAGS' => 'asflags-y', |
| 2827 | 'EXTRA_CFLAGS' => 'ccflags-y', |
| 2828 | 'EXTRA_CPPFLAGS' => 'cppflags-y', |
| 2829 | 'EXTRA_LDFLAGS' => 'ldflags-y', |
| 2830 | }; |
| 2831 | |
| 2832 | WARN("DEPRECATED_VARIABLE", |
| 2833 | "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); |
| 2834 | } |
| 2835 | |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 2836 | # check for DT compatible documentation |
Florian Vaussard | 7dd05b3 | 2014-04-03 14:49:26 -0700 | [diff] [blame] | 2837 | if (defined $root && |
| 2838 | (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || |
| 2839 | ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { |
| 2840 | |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 2841 | my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; |
| 2842 | |
Florian Vaussard | cc93319 | 2014-04-03 14:49:27 -0700 | [diff] [blame] | 2843 | my $dt_path = $root . "/Documentation/devicetree/bindings/"; |
| 2844 | my $vp_file = $dt_path . "vendor-prefixes.txt"; |
| 2845 | |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 2846 | foreach my $compat (@compats) { |
| 2847 | my $compat2 = $compat; |
Rob Herring | 185d566 | 2014-06-04 16:12:03 -0700 | [diff] [blame] | 2848 | $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; |
| 2849 | my $compat3 = $compat; |
| 2850 | $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; |
| 2851 | `grep -Erq "$compat|$compat2|$compat3" $dt_path`; |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 2852 | if ( $? >> 8 ) { |
| 2853 | WARN("UNDOCUMENTED_DT_STRING", |
| 2854 | "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); |
| 2855 | } |
| 2856 | |
Florian Vaussard | 4fbf32a | 2014-04-03 14:49:25 -0700 | [diff] [blame] | 2857 | next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; |
| 2858 | my $vendor = $1; |
Florian Vaussard | cc93319 | 2014-04-03 14:49:27 -0700 | [diff] [blame] | 2859 | `grep -Eq "^$vendor\\b" $vp_file`; |
Rob Herring | bff5da4 | 2014-01-23 15:54:51 -0800 | [diff] [blame] | 2860 | if ( $? >> 8 ) { |
| 2861 | WARN("UNDOCUMENTED_DT_STRING", |
Florian Vaussard | cc93319 | 2014-04-03 14:49:27 -0700 | [diff] [blame] | 2862 | "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] | 2863 | } |
| 2864 | } |
| 2865 | } |
| 2866 | |
Andy Whitcroft | 5368df2 | 2008-10-15 22:02:27 -0700 | [diff] [blame] | 2867 | # 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] | 2868 | next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); |
Andy Whitcroft | 5368df2 | 2008-10-15 22:02:27 -0700 | [diff] [blame] | 2869 | |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 2870 | # line length limit (with some exclusions) |
| 2871 | # |
| 2872 | # There are a few types of lines that may extend beyond $max_line_length: |
| 2873 | # logging functions like pr_info that end in a string |
| 2874 | # lines with a single string |
| 2875 | # #defines that are a single string |
| 2876 | # |
| 2877 | # There are 3 different line length message types: |
| 2878 | # LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength |
| 2879 | # LONG_LINE_STRING a string starts before but extends beyond $max_line_length |
| 2880 | # LONG_LINE all other lines longer than $max_line_length |
| 2881 | # |
| 2882 | # if LONG_LINE is ignored, the other 2 types are also ignored |
| 2883 | # |
| 2884 | |
Joe Perches | b4749e9 | 2015-07-17 16:24:01 -0700 | [diff] [blame] | 2885 | if ($line =~ /^\+/ && $length > $max_line_length) { |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 2886 | my $msg_type = "LONG_LINE"; |
| 2887 | |
| 2888 | # Check the allowed long line types first |
| 2889 | |
| 2890 | # logging functions that end in a string that starts |
| 2891 | # before $max_line_length |
| 2892 | if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && |
| 2893 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { |
| 2894 | $msg_type = ""; |
| 2895 | |
| 2896 | # lines with only strings (w/ possible termination) |
| 2897 | # #defines with only strings |
| 2898 | } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || |
| 2899 | $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { |
| 2900 | $msg_type = ""; |
| 2901 | |
Joe Perches | d560a5f | 2016-08-02 14:04:31 -0700 | [diff] [blame] | 2902 | # EFI_GUID is another special case |
| 2903 | } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { |
| 2904 | $msg_type = ""; |
| 2905 | |
Joe Perches | 47e0c88 | 2015-06-25 15:02:57 -0700 | [diff] [blame] | 2906 | # Otherwise set the alternate message types |
| 2907 | |
| 2908 | # a comment starts before $max_line_length |
| 2909 | } elsif ($line =~ /($;[\s$;]*)$/ && |
| 2910 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { |
| 2911 | $msg_type = "LONG_LINE_COMMENT" |
| 2912 | |
| 2913 | # a quoted string starts before $max_line_length |
| 2914 | } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && |
| 2915 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { |
| 2916 | $msg_type = "LONG_LINE_STRING" |
| 2917 | } |
| 2918 | |
| 2919 | if ($msg_type ne "" && |
| 2920 | (show_type("LONG_LINE") || show_type($msg_type))) { |
| 2921 | WARN($msg_type, |
| 2922 | "line over $max_line_length characters\n" . $herecurr); |
| 2923 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2924 | } |
| 2925 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 2926 | # check for adding lines without a newline. |
| 2927 | if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2928 | WARN("MISSING_EOF_NEWLINE", |
| 2929 | "adding a line without newline at end of file\n" . $herecurr); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 2930 | } |
| 2931 | |
Mike Frysinger | 42e41c5 | 2009-09-21 17:04:40 -0700 | [diff] [blame] | 2932 | # Blackfin: use hi/lo macros |
| 2933 | if ($realfile =~ m@arch/blackfin/.*\.S$@) { |
| 2934 | if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { |
| 2935 | my $herevet = "$here\n" . cat_vet($line) . "\n"; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2936 | ERROR("LO_MACRO", |
| 2937 | "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); |
Mike Frysinger | 42e41c5 | 2009-09-21 17:04:40 -0700 | [diff] [blame] | 2938 | } |
| 2939 | if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { |
| 2940 | my $herevet = "$here\n" . cat_vet($line) . "\n"; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 2941 | ERROR("HI_MACRO", |
| 2942 | "use the HI() macro, not (... >> 16)\n" . $herevet); |
Mike Frysinger | 42e41c5 | 2009-09-21 17:04:40 -0700 | [diff] [blame] | 2943 | } |
| 2944 | } |
| 2945 | |
Andy Whitcroft | b9ea10d | 2008-10-15 22:02:24 -0700 | [diff] [blame] | 2946 | # 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] | 2947 | next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2948 | |
| 2949 | # at the beginning of a line any tabs must come first and anything |
| 2950 | # more than 8 must use tabs. |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 2951 | if ($rawline =~ /^\+\s* \t\s*\S/ || |
| 2952 | $rawline =~ /^\+\s* \s*/) { |
| 2953 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 2954 | $rpt_cleaners = 1; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2955 | if (ERROR("CODE_INDENT", |
| 2956 | "code indent should use tabs where possible\n" . $herevet) && |
| 2957 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2958 | $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2959 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 2960 | } |
| 2961 | |
Alberto Panizzo | 08e4436 | 2010-03-05 13:43:54 -0800 | [diff] [blame] | 2962 | # check for space before tabs. |
| 2963 | if ($rawline =~ /^\+/ && $rawline =~ / \t/) { |
| 2964 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2965 | if (WARN("SPACE_BEFORE_TAB", |
| 2966 | "please, no space before tabs\n" . $herevet) && |
| 2967 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2968 | while ($fixed[$fixlinenr] =~ |
Joe Perches | d2207cc | 2014-10-13 15:51:53 -0700 | [diff] [blame] | 2969 | s/(^\+.*) {8,8}\t/$1\t\t/) {} |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 2970 | while ($fixed[$fixlinenr] =~ |
Joe Perches | c76f4cb | 2014-01-23 15:54:46 -0800 | [diff] [blame] | 2971 | s/(^\+.*) +\t/$1\t/) {} |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 2972 | } |
Alberto Panizzo | 08e4436 | 2010-03-05 13:43:54 -0800 | [diff] [blame] | 2973 | } |
| 2974 | |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 2975 | # check for && or || at the start of a line |
| 2976 | if ($rawline =~ /^\+\s*(&&|\|\|)/) { |
| 2977 | CHK("LOGICAL_CONTINUATIONS", |
| 2978 | "Logical continuations should be on the previous line\n" . $hereprev); |
| 2979 | } |
| 2980 | |
Joe Perches | a91e899 | 2016-05-20 17:04:05 -0700 | [diff] [blame] | 2981 | # check indentation starts on a tab stop |
| 2982 | if ($^V && $^V ge 5.10.0 && |
| 2983 | $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { |
| 2984 | my $indent = length($1); |
| 2985 | if ($indent % 8) { |
| 2986 | if (WARN("TABSTOP", |
| 2987 | "Statements should start on a tabstop\n" . $herecurr) && |
| 2988 | $fix) { |
| 2989 | $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; |
| 2990 | } |
| 2991 | } |
| 2992 | } |
| 2993 | |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 2994 | # check multi-line statement indentation matches previous line |
| 2995 | if ($^V && $^V ge 5.10.0 && |
Joe Perches | fd71f63 | 2017-07-10 15:52:30 -0700 | [diff] [blame] | 2996 | $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] | 2997 | $prevline =~ /^\+(\t*)(.*)$/; |
| 2998 | my $oldindent = $1; |
| 2999 | my $rest = $2; |
| 3000 | |
| 3001 | my $pos = pos_last_openparen($rest); |
| 3002 | if ($pos >= 0) { |
Joe Perches | b34a26f | 2012-07-30 14:41:16 -0700 | [diff] [blame] | 3003 | $line =~ /^(\+| )([ \t]*)/; |
| 3004 | my $newindent = $2; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3005 | |
| 3006 | my $goodtabindent = $oldindent . |
| 3007 | "\t" x ($pos / 8) . |
| 3008 | " " x ($pos % 8); |
| 3009 | my $goodspaceindent = $oldindent . " " x $pos; |
| 3010 | |
| 3011 | if ($newindent ne $goodtabindent && |
| 3012 | $newindent ne $goodspaceindent) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3013 | |
| 3014 | if (CHK("PARENTHESIS_ALIGNMENT", |
| 3015 | "Alignment should match open parenthesis\n" . $hereprev) && |
| 3016 | $fix && $line =~ /^\+/) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3017 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3018 | s/^\+[ \t]*/\+$goodtabindent/; |
| 3019 | } |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 3020 | } |
| 3021 | } |
| 3022 | } |
| 3023 | |
Joe Perches | 6ab3a97 | 2015-04-16 12:44:05 -0700 | [diff] [blame] | 3024 | # check for space after cast like "(int) foo" or "(struct foo) bar" |
| 3025 | # avoid checking a few false positives: |
| 3026 | # "sizeof(<type>)" or "__alignof__(<type>)" |
| 3027 | # function pointer declarations like "(*foo)(int) = bar;" |
| 3028 | # structure definitions like "(struct foo) { 0 };" |
| 3029 | # multiline macros that define functions |
| 3030 | # known attributes or the __attribute__ keyword |
| 3031 | if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && |
| 3032 | (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3033 | if (CHK("SPACING", |
Joe Perches | f27c95d | 2014-08-06 16:10:52 -0700 | [diff] [blame] | 3034 | "No space is necessary after a cast\n" . $herecurr) && |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3035 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3036 | $fixed[$fixlinenr] =~ |
Joe Perches | f27c95d | 2014-08-06 16:10:52 -0700 | [diff] [blame] | 3037 | s/(\(\s*$Type\s*\))[ \t]+/$1/; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3038 | } |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 3039 | } |
| 3040 | |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3041 | # Block comment styles |
| 3042 | # Networking with an initial /* |
Joe Perches | 0588060 | 2012-10-04 17:13:35 -0700 | [diff] [blame] | 3043 | if ($realfile =~ m@^(drivers/net/|net/)@ && |
Joe Perches | fdb4bcd | 2013-07-03 15:05:23 -0700 | [diff] [blame] | 3044 | $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && |
Joe Perches | 85ad978 | 2014-04-03 14:49:20 -0700 | [diff] [blame] | 3045 | $rawline =~ /^\+[ \t]*\*/ && |
| 3046 | $realline > 2) { |
Joe Perches | 0588060 | 2012-10-04 17:13:35 -0700 | [diff] [blame] | 3047 | WARN("NETWORKING_BLOCK_COMMENT_STYLE", |
| 3048 | "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); |
| 3049 | } |
| 3050 | |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3051 | # Block comments use * on subsequent lines |
| 3052 | if ($prevline =~ /$;[ \t]*$/ && #ends in comment |
| 3053 | $prevrawline =~ /^\+.*?\/\*/ && #starting /* |
Joe Perches | a605e32 | 2013-07-03 15:05:24 -0700 | [diff] [blame] | 3054 | $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ |
Joe Perches | 61135e9 | 2013-09-11 14:23:59 -0700 | [diff] [blame] | 3055 | $rawline =~ /^\+/ && #line is new |
Joe Perches | a605e32 | 2013-07-03 15:05:24 -0700 | [diff] [blame] | 3056 | $rawline !~ /^\+[ \t]*\*/) { #no leading * |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3057 | WARN("BLOCK_COMMENT_STYLE", |
| 3058 | "Block comments use * on subsequent lines\n" . $hereprev); |
Joe Perches | a605e32 | 2013-07-03 15:05:24 -0700 | [diff] [blame] | 3059 | } |
| 3060 | |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3061 | # Block comments use */ on trailing lines |
| 3062 | if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ |
Joe Perches | c24f9f1 | 2012-11-08 15:53:29 -0800 | [diff] [blame] | 3063 | $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ |
| 3064 | $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ |
| 3065 | $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ |
Joe Perches | 86406b1 | 2015-09-09 15:37:41 -0700 | [diff] [blame] | 3066 | WARN("BLOCK_COMMENT_STYLE", |
| 3067 | "Block comments use a trailing */ on a separate line\n" . $herecurr); |
Joe Perches | 0588060 | 2012-10-04 17:13:35 -0700 | [diff] [blame] | 3068 | } |
| 3069 | |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3070 | # Block comment * alignment |
| 3071 | if ($prevline =~ /$;[ \t]*$/ && #ends in comment |
Joe Perches | af20752 | 2016-10-11 13:52:05 -0700 | [diff] [blame] | 3072 | $line =~ /^\+[ \t]*$;/ && #leading comment |
| 3073 | $rawline =~ /^\+[ \t]*\*/ && #leading * |
| 3074 | (($prevrawline =~ /^\+.*?\/\*/ && #leading /* |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3075 | $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ |
Joe Perches | af20752 | 2016-10-11 13:52:05 -0700 | [diff] [blame] | 3076 | $prevrawline =~ /^\+[ \t]*\*/)) { #leading * |
| 3077 | my $oldindent; |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3078 | $prevrawline =~ m@^\+([ \t]*/?)\*@; |
Joe Perches | af20752 | 2016-10-11 13:52:05 -0700 | [diff] [blame] | 3079 | if (defined($1)) { |
| 3080 | $oldindent = expand_tabs($1); |
| 3081 | } else { |
| 3082 | $prevrawline =~ m@^\+(.*/?)\*@; |
| 3083 | $oldindent = expand_tabs($1); |
| 3084 | } |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3085 | $rawline =~ m@^\+([ \t]*)\*@; |
| 3086 | my $newindent = $1; |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3087 | $newindent = expand_tabs($newindent); |
Joe Perches | af20752 | 2016-10-11 13:52:05 -0700 | [diff] [blame] | 3088 | if (length($oldindent) ne length($newindent)) { |
Joe Perches | 08eb9b8 | 2016-10-11 13:51:50 -0700 | [diff] [blame] | 3089 | WARN("BLOCK_COMMENT_STYLE", |
| 3090 | "Block comments should align the * on each line\n" . $hereprev); |
| 3091 | } |
| 3092 | } |
| 3093 | |
Joe Perches | 7f61919 | 2014-08-06 16:10:39 -0700 | [diff] [blame] | 3094 | # check for missing blank lines after struct/union declarations |
| 3095 | # with exceptions for various attributes and macros |
| 3096 | if ($prevline =~ /^[\+ ]};?\s*$/ && |
| 3097 | $line =~ /^\+/ && |
| 3098 | !($line =~ /^\+\s*$/ || |
| 3099 | $line =~ /^\+\s*EXPORT_SYMBOL/ || |
| 3100 | $line =~ /^\+\s*MODULE_/i || |
| 3101 | $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || |
| 3102 | $line =~ /^\+[a-z_]*init/ || |
| 3103 | $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || |
| 3104 | $line =~ /^\+\s*DECLARE/ || |
| 3105 | $line =~ /^\+\s*__setup/)) { |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3106 | if (CHK("LINE_SPACING", |
| 3107 | "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && |
| 3108 | $fix) { |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 3109 | fix_insert_line($fixlinenr, "\+"); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3110 | } |
Joe Perches | 7f61919 | 2014-08-06 16:10:39 -0700 | [diff] [blame] | 3111 | } |
| 3112 | |
Joe Perches | 365dd4e | 2014-08-06 16:10:42 -0700 | [diff] [blame] | 3113 | # check for multiple consecutive blank lines |
| 3114 | if ($prevline =~ /^[\+ ]\s*$/ && |
| 3115 | $line =~ /^\+\s*$/ && |
| 3116 | $last_blank_line != ($linenr - 1)) { |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3117 | if (CHK("LINE_SPACING", |
| 3118 | "Please don't use multiple blank lines\n" . $hereprev) && |
| 3119 | $fix) { |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 3120 | fix_delete_line($fixlinenr, $rawline); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3121 | } |
| 3122 | |
Joe Perches | 365dd4e | 2014-08-06 16:10:42 -0700 | [diff] [blame] | 3123 | $last_blank_line = $linenr; |
| 3124 | } |
| 3125 | |
Joe Perches | 3b617e3 | 2014-04-03 14:49:28 -0700 | [diff] [blame] | 3126 | # check for missing blank lines after declarations |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3127 | if ($sline =~ /^\+\s+\S/ && #Not at char 1 |
| 3128 | # actual declarations |
| 3129 | ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || |
Joe Perches | 5a4e1fd | 2014-08-06 16:10:33 -0700 | [diff] [blame] | 3130 | # function pointer declarations |
| 3131 | $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3132 | # foo bar; where foo is some local typedef or #define |
| 3133 | $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || |
| 3134 | # known declaration macros |
| 3135 | $prevline =~ /^\+\s+$declaration_macros/) && |
| 3136 | # for "else if" which can look like "$Ident $Ident" |
| 3137 | !($prevline =~ /^\+\s+$c90_Keywords\b/ || |
| 3138 | # other possible extensions of declaration lines |
| 3139 | $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || |
| 3140 | # not starting a section or a macro "\" extended line |
| 3141 | $prevline =~ /(?:\{\s*|\\)$/) && |
| 3142 | # looks like a declaration |
| 3143 | !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || |
Joe Perches | 5a4e1fd | 2014-08-06 16:10:33 -0700 | [diff] [blame] | 3144 | # function pointer declarations |
| 3145 | $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3146 | # foo bar; where foo is some local typedef or #define |
| 3147 | $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || |
| 3148 | # known declaration macros |
| 3149 | $sline =~ /^\+\s+$declaration_macros/ || |
| 3150 | # start of struct or union or enum |
Joe Perches | 3b617e3 | 2014-04-03 14:49:28 -0700 | [diff] [blame] | 3151 | $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || |
Joe Perches | 3f7bac0 | 2014-06-04 16:12:04 -0700 | [diff] [blame] | 3152 | # start or end of block or continuation of declaration |
| 3153 | $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || |
| 3154 | # bitfield continuation |
| 3155 | $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || |
| 3156 | # other possible extensions of declaration lines |
| 3157 | $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && |
| 3158 | # indentation of previous and current line are the same |
| 3159 | (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3160 | if (WARN("LINE_SPACING", |
| 3161 | "Missing a blank line after declarations\n" . $hereprev) && |
| 3162 | $fix) { |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 3163 | fix_insert_line($fixlinenr, "\+"); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3164 | } |
Joe Perches | 3b617e3 | 2014-04-03 14:49:28 -0700 | [diff] [blame] | 3165 | } |
| 3166 | |
Raffaele Recalcati | 5f7ddae | 2010-08-09 17:20:59 -0700 | [diff] [blame] | 3167 | # check for spaces at the beginning of a line. |
Andy Whitcroft | 6b4c5be | 2010-10-26 14:23:11 -0700 | [diff] [blame] | 3168 | # Exceptions: |
| 3169 | # 1) within comments |
| 3170 | # 2) indented preprocessor commands |
| 3171 | # 3) hanging labels |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3172 | if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { |
Raffaele Recalcati | 5f7ddae | 2010-08-09 17:20:59 -0700 | [diff] [blame] | 3173 | my $herevet = "$here\n" . cat_vet($rawline) . "\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3174 | if (WARN("LEADING_SPACE", |
| 3175 | "please, no spaces at the start of a line\n" . $herevet) && |
| 3176 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3177 | $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3178 | } |
Raffaele Recalcati | 5f7ddae | 2010-08-09 17:20:59 -0700 | [diff] [blame] | 3179 | } |
| 3180 | |
Andy Whitcroft | b9ea10d | 2008-10-15 22:02:24 -0700 | [diff] [blame] | 3181 | # check we are in a valid C source file if not then ignore this hunk |
| 3182 | next if ($realfile !~ /\.(h|c)$/); |
| 3183 | |
Joe Perches | 4dbed76 | 2017-05-08 15:55:39 -0700 | [diff] [blame] | 3184 | # check if this appears to be the start function declaration, save the name |
| 3185 | if ($sline =~ /^\+\{\s*$/ && |
| 3186 | $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { |
| 3187 | $context_function = $1; |
| 3188 | } |
| 3189 | |
| 3190 | # check if this appears to be the end of function declaration |
| 3191 | if ($sline =~ /^\+\}\s*$/) { |
| 3192 | undef $context_function; |
| 3193 | } |
| 3194 | |
Joe Perches | 032a4c0 | 2014-08-06 16:10:29 -0700 | [diff] [blame] | 3195 | # check indentation of any line with a bare else |
Joe Perches | 840080a | 2014-10-13 15:51:59 -0700 | [diff] [blame] | 3196 | # (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] | 3197 | # if the previous line is a break or return and is indented 1 tab more... |
| 3198 | if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { |
| 3199 | my $tabs = length($1) + 1; |
Joe Perches | 840080a | 2014-10-13 15:51:59 -0700 | [diff] [blame] | 3200 | if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || |
| 3201 | ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && |
| 3202 | defined $lines[$linenr] && |
| 3203 | $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { |
Joe Perches | 032a4c0 | 2014-08-06 16:10:29 -0700 | [diff] [blame] | 3204 | WARN("UNNECESSARY_ELSE", |
| 3205 | "else is not generally useful after a break or return\n" . $hereprev); |
| 3206 | } |
| 3207 | } |
| 3208 | |
Joe Perches | c00df19 | 2014-08-06 16:11:01 -0700 | [diff] [blame] | 3209 | # check indentation of a line with a break; |
| 3210 | # if the previous line is a goto or return and is indented the same # of tabs |
| 3211 | if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { |
| 3212 | my $tabs = $1; |
| 3213 | if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { |
| 3214 | WARN("UNNECESSARY_BREAK", |
| 3215 | "break is not useful after a goto or return\n" . $hereprev); |
| 3216 | } |
| 3217 | } |
| 3218 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3219 | # check for RCS/CVS revision markers |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 3220 | if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3221 | WARN("CVS_KEYWORD", |
| 3222 | "CVS style keyword markers, these will _not_ be updated\n". $herecurr); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3223 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 3224 | |
Mike Frysinger | 42e41c5 | 2009-09-21 17:04:40 -0700 | [diff] [blame] | 3225 | # Blackfin: don't use __builtin_bfin_[cs]sync |
| 3226 | if ($line =~ /__builtin_bfin_csync/) { |
| 3227 | my $herevet = "$here\n" . cat_vet($line) . "\n"; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3228 | ERROR("CSYNC", |
| 3229 | "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); |
Mike Frysinger | 42e41c5 | 2009-09-21 17:04:40 -0700 | [diff] [blame] | 3230 | } |
| 3231 | if ($line =~ /__builtin_bfin_ssync/) { |
| 3232 | my $herevet = "$here\n" . cat_vet($line) . "\n"; |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3233 | ERROR("SSYNC", |
| 3234 | "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); |
Mike Frysinger | 42e41c5 | 2009-09-21 17:04:40 -0700 | [diff] [blame] | 3235 | } |
| 3236 | |
Joe Perches | 56e77d7 | 2013-02-21 16:44:14 -0800 | [diff] [blame] | 3237 | # check for old HOTPLUG __dev<foo> section markings |
| 3238 | if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { |
| 3239 | WARN("HOTPLUG_SECTION", |
| 3240 | "Using $1 is unnecessary\n" . $herecurr); |
| 3241 | } |
| 3242 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 3243 | # Check for potential 'bare' types |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 3244 | my ($stat, $cond, $line_nr_next, $remain_next, $off_next, |
| 3245 | $realline_next); |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 3246 | #print "LINE<$line>\n"; |
Joe Perches | ca81986 | 2017-07-10 15:52:13 -0700 | [diff] [blame] | 3247 | if ($linenr > $suppress_statement && |
Joe Perches | 1b5539b | 2013-09-11 14:24:03 -0700 | [diff] [blame] | 3248 | $realcnt && $sline =~ /.\s*\S/) { |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 3249 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
Andy Whitcroft | f5fe35d | 2008-07-23 21:29:03 -0700 | [diff] [blame] | 3250 | ctx_statement_block($linenr, $realcnt, 0); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 3251 | $stat =~ s/\n./\n /g; |
| 3252 | $cond =~ s/\n./\n /g; |
| 3253 | |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 3254 | #print "linenr<$linenr> <$stat>\n"; |
| 3255 | # If this statement has no statement boundaries within |
| 3256 | # it there is no point in retrying a statement scan |
| 3257 | # until we hit end of it. |
| 3258 | my $frag = $stat; $frag =~ s/;+\s*$//; |
| 3259 | if ($frag !~ /(?:{|;)/) { |
| 3260 | #print "skip<$line_nr_next>\n"; |
| 3261 | $suppress_statement = $line_nr_next; |
| 3262 | } |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 3263 | |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 3264 | # Find the real next line. |
| 3265 | $realline_next = $line_nr_next; |
| 3266 | if (defined $realline_next && |
| 3267 | (!defined $lines[$realline_next - 1] || |
| 3268 | substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { |
| 3269 | $realline_next++; |
| 3270 | } |
| 3271 | |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 3272 | my $s = $stat; |
| 3273 | $s =~ s/{.*$//s; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 3274 | |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3275 | # Ignore goto labels. |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 3276 | if ($s =~ /$Ident:\*$/s) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3277 | |
| 3278 | # Ignore functions being called |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 3279 | } elsif ($s =~ /^.\s*$Ident\s*\(/s) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3280 | |
Andy Whitcroft | 463f286 | 2009-09-21 17:04:34 -0700 | [diff] [blame] | 3281 | } elsif ($s =~ /^.\s*else\b/s) { |
| 3282 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 3283 | # declarations always start with types |
Andy Whitcroft | d250658 | 2008-07-23 21:29:09 -0700 | [diff] [blame] | 3284 | } 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] | 3285 | my $type = $1; |
| 3286 | $type =~ s/\s+/ /g; |
| 3287 | possible($type, "A:" . $s); |
| 3288 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3289 | # definitions in global scope can only start with types |
Andy Whitcroft | a6a84062 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 3290 | } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 3291 | possible($1, "B:" . $s); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3292 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3293 | |
| 3294 | # any (foo ... *) is a pointer cast, and foo is a type |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3295 | while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 3296 | possible($1, "C:" . $s); |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 3297 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3298 | |
| 3299 | # Check for any sort of function declaration. |
| 3300 | # int foo(something bar, other baz); |
| 3301 | # void (*store_gdt)(x86_descr_ptr *); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 3302 | 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] | 3303 | my ($name_len) = length($1); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3304 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 3305 | my $ctx = $s; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 3306 | substr($ctx, 0, $name_len + 1, ''); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3307 | $ctx =~ s/\)[^\)]*$//; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 3308 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3309 | for my $arg (split(/\s*,\s*/, $ctx)) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 3310 | 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] | 3311 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 3312 | possible($1, "D:" . $s); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3313 | } |
| 3314 | } |
| 3315 | } |
| 3316 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 3317 | } |
| 3318 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3319 | # |
| 3320 | # Checks which may be anchored in the context. |
| 3321 | # |
| 3322 | |
| 3323 | # Check for switch () and associated case and default |
| 3324 | # statements should be at the same indent. |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3325 | if ($line=~/\bswitch\s*\(.*\)/) { |
| 3326 | my $err = ''; |
| 3327 | my $sep = ''; |
| 3328 | my @ctx = ctx_block_outer($linenr, $realcnt); |
| 3329 | shift(@ctx); |
| 3330 | for my $ctx (@ctx) { |
| 3331 | my ($clen, $cindent) = line_stats($ctx); |
| 3332 | if ($ctx =~ /^\+\s*(case\s+|default:)/ && |
| 3333 | $indent != $cindent) { |
| 3334 | $err .= "$sep$ctx\n"; |
| 3335 | $sep = ''; |
| 3336 | } else { |
| 3337 | $sep = "[...]\n"; |
| 3338 | } |
| 3339 | } |
| 3340 | if ($err ne '') { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3341 | ERROR("SWITCH_CASE_INDENT_LEVEL", |
| 3342 | "switch and case should be at the same indent\n$hereline$err"); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 3343 | } |
| 3344 | } |
| 3345 | |
| 3346 | # if/while/etc brace do not go on next line, unless defining a do while loop, |
| 3347 | # or if that brace on the next line is for something else |
Joe Perches | 0fe3dc2 | 2014-08-06 16:11:16 -0700 | [diff] [blame] | 3348 | 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] | 3349 | my $pre_ctx = "$1$2"; |
| 3350 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 3351 | my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); |
Joe Perches | 8eef05d | 2012-02-03 15:20:39 -0800 | [diff] [blame] | 3352 | |
| 3353 | if ($line =~ /^\+\t{6,}/) { |
| 3354 | WARN("DEEP_INDENTATION", |
| 3355 | "Too many leading tabs - consider code refactoring\n" . $herecurr); |
| 3356 | } |
| 3357 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 3358 | my $ctx_cnt = $realcnt - $#ctx - 1; |
| 3359 | my $ctx = join("\n", @ctx); |
| 3360 | |
Andy Whitcroft | 548596d | 2008-07-23 21:29:01 -0700 | [diff] [blame] | 3361 | my $ctx_ln = $linenr; |
| 3362 | my $ctx_skip = $realcnt; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 3363 | |
Andy Whitcroft | 548596d | 2008-07-23 21:29:01 -0700 | [diff] [blame] | 3364 | while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && |
| 3365 | defined $lines[$ctx_ln - 1] && |
| 3366 | $lines[$ctx_ln - 1] =~ /^-/)) { |
| 3367 | ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; |
| 3368 | $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 3369 | $ctx_ln++; |
| 3370 | } |
Andy Whitcroft | 548596d | 2008-07-23 21:29:01 -0700 | [diff] [blame] | 3371 | |
Andy Whitcroft | 5321016 | 2008-07-23 21:29:03 -0700 | [diff] [blame] | 3372 | #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; |
| 3373 | #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] | 3374 | |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3375 | 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] | 3376 | ERROR("OPEN_BRACE", |
| 3377 | "that open brace { should be on the previous line\n" . |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 3378 | "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3379 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 3380 | if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && |
| 3381 | $ctx =~ /\)\s*\;\s*$/ && |
| 3382 | defined $lines[$ctx_ln - 1]) |
| 3383 | { |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 3384 | my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); |
| 3385 | if ($nindent > $indent) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3386 | WARN("TRAILING_SEMICOLON", |
| 3387 | "trailing semicolon indicates no statements, indent implies otherwise\n" . |
Andy Whitcroft | 01464f3 | 2010-10-26 14:23:19 -0700 | [diff] [blame] | 3388 | "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 3389 | } |
| 3390 | } |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3391 | } |
| 3392 | |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 3393 | # Check relative indent for conditionals and blocks. |
Joe Perches | f6950a7 | 2017-05-08 15:56:05 -0700 | [diff] [blame] | 3394 | 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] | 3395 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
| 3396 | ctx_statement_block($linenr, $realcnt, 0) |
| 3397 | if (!defined $stat); |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 3398 | my ($s, $c) = ($stat, $cond); |
| 3399 | |
| 3400 | substr($s, 0, length($c), ''); |
| 3401 | |
Joe Perches | 9f5af48 | 2015-09-09 15:37:30 -0700 | [diff] [blame] | 3402 | # remove inline comments |
| 3403 | $s =~ s/$;/ /g; |
| 3404 | $c =~ s/$;/ /g; |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 3405 | |
| 3406 | # Find out how long the conditional actually is. |
Andy Whitcroft | 6f779c1 | 2008-10-15 22:02:27 -0700 | [diff] [blame] | 3407 | my @newlines = ($c =~ /\n/gs); |
| 3408 | my $cond_lines = 1 + $#newlines; |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 3409 | |
Joe Perches | 9f5af48 | 2015-09-09 15:37:30 -0700 | [diff] [blame] | 3410 | # Make sure we remove the line prefixes as we have |
| 3411 | # none on the first line, and are going to readd them |
| 3412 | # where necessary. |
| 3413 | $s =~ s/\n./\n/gs; |
| 3414 | while ($s =~ /\n\s+\\\n/) { |
| 3415 | $cond_lines += $s =~ s/\n\s+\\\n/\n/g; |
| 3416 | } |
| 3417 | |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 3418 | # We want to check the first line inside the block |
| 3419 | # starting at the end of the conditional, so remove: |
| 3420 | # 1) any blank line termination |
| 3421 | # 2) any opening brace { on end of the line |
| 3422 | # 3) any do (...) { |
| 3423 | my $continuation = 0; |
| 3424 | my $check = 0; |
| 3425 | $s =~ s/^.*\bdo\b//; |
| 3426 | $s =~ s/^\s*{//; |
| 3427 | if ($s =~ s/^\s*\\//) { |
| 3428 | $continuation = 1; |
| 3429 | } |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 3430 | if ($s =~ s/^\s*?\n//) { |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 3431 | $check = 1; |
| 3432 | $cond_lines++; |
| 3433 | } |
| 3434 | |
| 3435 | # Also ignore a loop construct at the end of a |
| 3436 | # preprocessor statement. |
| 3437 | if (($prevline =~ /^.\s*#\s*define\s/ || |
| 3438 | $prevline =~ /\\\s*$/) && $continuation == 0) { |
| 3439 | $check = 0; |
| 3440 | } |
| 3441 | |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 3442 | my $cond_ptr = -1; |
Andy Whitcroft | 740504c | 2008-10-15 22:02:35 -0700 | [diff] [blame] | 3443 | $continuation = 0; |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 3444 | while ($cond_ptr != $cond_lines) { |
| 3445 | $cond_ptr = $cond_lines; |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 3446 | |
Andy Whitcroft | f16fa28 | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 3447 | # If we see an #else/#elif then the code |
| 3448 | # is not linear. |
| 3449 | if ($s =~ /^\s*\#\s*(?:else|elif)/) { |
| 3450 | $check = 0; |
| 3451 | } |
| 3452 | |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 3453 | # Ignore: |
| 3454 | # 1) blank lines, they should be at 0, |
| 3455 | # 2) preprocessor lines, and |
| 3456 | # 3) labels. |
Andy Whitcroft | 740504c | 2008-10-15 22:02:35 -0700 | [diff] [blame] | 3457 | if ($continuation || |
| 3458 | $s =~ /^\s*?\n/ || |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 3459 | $s =~ /^\s*#\s*?/ || |
| 3460 | $s =~ /^\s*$Ident\s*:/) { |
Andy Whitcroft | 740504c | 2008-10-15 22:02:35 -0700 | [diff] [blame] | 3461 | $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; |
Andy Whitcroft | 30dad6e | 2009-09-21 17:04:36 -0700 | [diff] [blame] | 3462 | if ($s =~ s/^.*?\n//) { |
| 3463 | $cond_lines++; |
| 3464 | } |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 3465 | } |
Andy Whitcroft | 4d001e4 | 2008-10-15 22:02:21 -0700 | [diff] [blame] | 3466 | } |
| 3467 | |
| 3468 | my (undef, $sindent) = line_stats("+" . $s); |
| 3469 | my $stat_real = raw_line($linenr, $cond_lines); |
| 3470 | |
| 3471 | # Check if either of these lines are modified, else |
| 3472 | # this is not this patch's fault. |
| 3473 | if (!defined($stat_real) || |
| 3474 | $stat !~ /^\+/ && $stat_real !~ /^\+/) { |
| 3475 | $check = 0; |
| 3476 | } |
| 3477 | if (defined($stat_real) && $cond_lines > 1) { |
| 3478 | $stat_real = "[...]\n$stat_real"; |
| 3479 | } |
| 3480 | |
Andy Whitcroft | 9bd49ef | 2008-10-15 22:02:22 -0700 | [diff] [blame] | 3481 | #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] | 3482 | |
Joe Perches | 9f5af48 | 2015-09-09 15:37:30 -0700 | [diff] [blame] | 3483 | if ($check && $s ne '' && |
| 3484 | (($sindent % 8) != 0 || |
| 3485 | ($sindent < $indent) || |
Joe Perches | f6950a7 | 2017-05-08 15:56:05 -0700 | [diff] [blame] | 3486 | ($sindent == $indent && |
| 3487 | ($s !~ /^\s*(?:\}|\{|else\b)/)) || |
Joe Perches | 9f5af48 | 2015-09-09 15:37:30 -0700 | [diff] [blame] | 3488 | ($sindent > $indent + 8))) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3489 | WARN("SUSPECT_CODE_INDENT", |
| 3490 | "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] | 3491 | } |
| 3492 | } |
| 3493 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 3494 | # Track the 'values' across context and added lines. |
| 3495 | my $opline = $line; $opline =~ s/^./ /; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 3496 | my ($curr_values, $curr_vars) = |
| 3497 | annotate_values($opline . "\n", $prev_values); |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 3498 | $curr_values = $prev_values . $curr_values; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3499 | if ($dbg_values) { |
| 3500 | my $outline = $opline; $outline =~ s/\t/ /g; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 3501 | print "$linenr > .$outline\n"; |
| 3502 | print "$linenr > $curr_values\n"; |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 3503 | print "$linenr > $curr_vars\n"; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 3504 | } |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 3505 | $prev_values = substr($curr_values, -1); |
| 3506 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3507 | #ignore lines not being added |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3508 | next if ($line =~ /^[^\+]/); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3509 | |
Joe Perches | 11ca40a | 2016-12-12 16:46:31 -0800 | [diff] [blame] | 3510 | # check for dereferences that span multiple lines |
| 3511 | if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && |
| 3512 | $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { |
| 3513 | $prevline =~ /($Lval\s*(?:\.|->))\s*$/; |
| 3514 | my $ref = $1; |
| 3515 | $line =~ /^.\s*($Lval)/; |
| 3516 | $ref .= $1; |
| 3517 | $ref =~ s/\s//g; |
| 3518 | WARN("MULTILINE_DEREFERENCE", |
| 3519 | "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); |
| 3520 | } |
| 3521 | |
Joe Perches | a1ce18e | 2016-03-15 14:58:03 -0700 | [diff] [blame] | 3522 | # check for declarations of signed or unsigned without int |
Joe Perches | c844711 | 2016-08-02 14:04:42 -0700 | [diff] [blame] | 3523 | 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] | 3524 | my $type = $1; |
| 3525 | my $var = $2; |
Joe Perches | 207a8e8 | 2016-03-15 14:58:06 -0700 | [diff] [blame] | 3526 | $var = "" if (!defined $var); |
| 3527 | if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { |
Joe Perches | a1ce18e | 2016-03-15 14:58:03 -0700 | [diff] [blame] | 3528 | my $sign = $1; |
| 3529 | my $pointer = $2; |
| 3530 | |
| 3531 | $pointer = "" if (!defined $pointer); |
| 3532 | |
| 3533 | if (WARN("UNSPECIFIED_INT", |
| 3534 | "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && |
| 3535 | $fix) { |
| 3536 | my $decl = trim($sign) . " int "; |
Joe Perches | 207a8e8 | 2016-03-15 14:58:06 -0700 | [diff] [blame] | 3537 | my $comp_pointer = $pointer; |
| 3538 | $comp_pointer =~ s/\s//g; |
| 3539 | $decl .= $comp_pointer; |
| 3540 | $decl = rtrim($decl) if ($var eq ""); |
| 3541 | $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] | 3542 | } |
| 3543 | } |
| 3544 | } |
| 3545 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3546 | # TEST: allow direct testing of the type matcher. |
Andy Whitcroft | 7429c69 | 2008-07-23 21:29:06 -0700 | [diff] [blame] | 3547 | if ($dbg_type) { |
| 3548 | if ($line =~ /^.\s*$Declare\s*$/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3549 | ERROR("TEST_TYPE", |
| 3550 | "TEST: is type\n" . $herecurr); |
Andy Whitcroft | 7429c69 | 2008-07-23 21:29:06 -0700 | [diff] [blame] | 3551 | } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3552 | ERROR("TEST_NOT_TYPE", |
| 3553 | "TEST: is not type ($1 is)\n". $herecurr); |
Andy Whitcroft | 7429c69 | 2008-07-23 21:29:06 -0700 | [diff] [blame] | 3554 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3555 | next; |
| 3556 | } |
Andy Whitcroft | a1ef277 | 2008-10-15 22:02:17 -0700 | [diff] [blame] | 3557 | # TEST: allow direct testing of the attribute matcher. |
| 3558 | if ($dbg_attr) { |
Andy Whitcroft | 9360b0e | 2009-02-27 14:03:08 -0800 | [diff] [blame] | 3559 | if ($line =~ /^.\s*$Modifier\s*$/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3560 | ERROR("TEST_ATTR", |
| 3561 | "TEST: is attr\n" . $herecurr); |
Andy Whitcroft | 9360b0e | 2009-02-27 14:03:08 -0800 | [diff] [blame] | 3562 | } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3563 | ERROR("TEST_NOT_ATTR", |
| 3564 | "TEST: is not attr ($1 is)\n". $herecurr); |
Andy Whitcroft | a1ef277 | 2008-10-15 22:02:17 -0700 | [diff] [blame] | 3565 | } |
| 3566 | next; |
| 3567 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3568 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 3569 | # check for initialisation to aggregates open brace on the next line |
Andy Whitcroft | 99423c2 | 2009-10-26 16:50:15 -0700 | [diff] [blame] | 3570 | if ($line =~ /^.\s*{/ && |
| 3571 | $prevline =~ /(?:^|[^=])=\s*$/) { |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3572 | if (ERROR("OPEN_BRACE", |
| 3573 | "that open brace { should be on the previous line\n" . $hereprev) && |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 3574 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { |
| 3575 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 3576 | fix_delete_line($fixlinenr, $rawline); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3577 | my $fixedline = $prevrawline; |
| 3578 | $fixedline =~ s/\s*=\s*$/ = {/; |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 3579 | fix_insert_line($fixlinenr, $fixedline); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3580 | $fixedline = $line; |
Cyril Bur | 8d81ae0 | 2017-07-10 15:52:21 -0700 | [diff] [blame] | 3581 | $fixedline =~ s/^(.\s*)\{\s*/$1/; |
Joe Perches | f2d7e4d | 2014-08-06 16:11:07 -0700 | [diff] [blame] | 3582 | fix_insert_line($fixlinenr, $fixedline); |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 3583 | } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 3584 | } |
| 3585 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3586 | # |
| 3587 | # Checks which are anchored on the added line. |
| 3588 | # |
| 3589 | |
| 3590 | # check for malformed paths in #include statements (uses RAW line) |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 3591 | if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3592 | my $path = $1; |
| 3593 | if ($path =~ m{//}) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3594 | ERROR("MALFORMED_INCLUDE", |
Joe Perches | 495e9d8 | 2012-12-20 15:05:37 -0800 | [diff] [blame] | 3595 | "malformed #include filename\n" . $herecurr); |
| 3596 | } |
| 3597 | if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { |
| 3598 | ERROR("UAPI_INCLUDE", |
| 3599 | "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] | 3600 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3601 | } |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3602 | |
| 3603 | # no C99 // comments |
| 3604 | if ($line =~ m{//}) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3605 | if (ERROR("C99_COMMENTS", |
| 3606 | "do not use C99 // comments\n" . $herecurr) && |
| 3607 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3608 | my $line = $fixed[$fixlinenr]; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3609 | if ($line =~ /\/\/(.*)$/) { |
| 3610 | my $comment = trim($1); |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3611 | $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3612 | } |
| 3613 | } |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3614 | } |
| 3615 | # Remove C99 comments. |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3616 | $line =~ s@//.*@@; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 3617 | $opline =~ s@//.*@@; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3618 | |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 3619 | # EXPORT_SYMBOL should immediately follow the thing it is exporting, consider |
| 3620 | # the whole statement. |
| 3621 | #print "APW <$lines[$realline_next - 1]>\n"; |
| 3622 | if (defined $realline_next && |
| 3623 | exists $lines[$realline_next - 1] && |
| 3624 | !defined $suppress_export{$realline_next} && |
| 3625 | ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || |
| 3626 | $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { |
Andy Whitcroft | 3cbf62d | 2010-10-26 14:23:18 -0700 | [diff] [blame] | 3627 | # Handle definitions which produce identifiers with |
| 3628 | # a prefix: |
| 3629 | # XXX(foo); |
| 3630 | # EXPORT_SYMBOL(something_foo); |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3631 | my $name = $1; |
Andy Whitcroft | 87a5387 | 2012-01-10 15:10:04 -0800 | [diff] [blame] | 3632 | if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && |
Andy Whitcroft | 3cbf62d | 2010-10-26 14:23:18 -0700 | [diff] [blame] | 3633 | $name =~ /^${Ident}_$2/) { |
| 3634 | #print "FOO C name<$name>\n"; |
| 3635 | $suppress_export{$realline_next} = 1; |
| 3636 | |
| 3637 | } elsif ($stat !~ /(?: |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 3638 | \n.}\s*$| |
Andy Whitcroft | 4801205 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 3639 | ^.DEFINE_$Ident\(\Q$name\E\)| |
| 3640 | ^.DECLARE_$Ident\(\Q$name\E\)| |
| 3641 | ^.LIST_HEAD\(\Q$name\E\)| |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 3642 | ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| |
| 3643 | \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() |
Andy Whitcroft | 4801205 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 3644 | )/x) { |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 3645 | #print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; |
| 3646 | $suppress_export{$realline_next} = 2; |
| 3647 | } else { |
| 3648 | $suppress_export{$realline_next} = 1; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3649 | } |
| 3650 | } |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 3651 | if (!defined $suppress_export{$linenr} && |
| 3652 | $prevline =~ /^.\s*$/ && |
| 3653 | ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || |
| 3654 | $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { |
| 3655 | #print "FOO B <$lines[$linenr - 1]>\n"; |
| 3656 | $suppress_export{$linenr} = 2; |
| 3657 | } |
| 3658 | if (defined $suppress_export{$linenr} && |
| 3659 | $suppress_export{$linenr} == 2) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3660 | WARN("EXPORT_SYMBOL", |
| 3661 | "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); |
Andy Whitcroft | 2b474a1 | 2009-10-26 16:50:16 -0700 | [diff] [blame] | 3662 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3663 | |
Joe Eloff | 5150bda | 2010-08-09 17:21:00 -0700 | [diff] [blame] | 3664 | # check for global initialisers. |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 3665 | if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3666 | if (ERROR("GLOBAL_INITIALISERS", |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 3667 | "do not initialise globals to $1\n" . $herecurr) && |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3668 | $fix) { |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 3669 | $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] | 3670 | } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 3671 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3672 | # check for static initialisers. |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 3673 | if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3674 | if (ERROR("INITIALISED_STATIC", |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 3675 | "do not initialise statics to $1\n" . |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3676 | $herecurr) && |
| 3677 | $fix) { |
Joe Perches | 6d32f7a | 2015-11-06 16:31:37 -0800 | [diff] [blame] | 3678 | $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3679 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3680 | } |
| 3681 | |
Joe Perches | 1813087 | 2014-08-06 16:11:22 -0700 | [diff] [blame] | 3682 | # check for misordered declarations of char/short/int/long with signed/unsigned |
| 3683 | while ($sline =~ m{(\b$TypeMisordered\b)}g) { |
| 3684 | my $tmp = trim($1); |
| 3685 | WARN("MISORDERED_TYPE", |
| 3686 | "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); |
| 3687 | } |
| 3688 | |
Joe Perches | cb710ec | 2010-10-26 14:23:20 -0700 | [diff] [blame] | 3689 | # check for static const char * arrays. |
| 3690 | 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] | 3691 | WARN("STATIC_CONST_CHAR_ARRAY", |
| 3692 | "static const char * array should probably be static const char * const\n" . |
Joe Perches | cb710ec | 2010-10-26 14:23:20 -0700 | [diff] [blame] | 3693 | $herecurr); |
| 3694 | } |
| 3695 | |
| 3696 | # check for static char foo[] = "bar" declarations. |
| 3697 | if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3698 | WARN("STATIC_CONST_CHAR_ARRAY", |
| 3699 | "static char array declaration should probably be static const char\n" . |
Joe Perches | cb710ec | 2010-10-26 14:23:20 -0700 | [diff] [blame] | 3700 | $herecurr); |
| 3701 | } |
| 3702 | |
Joe Perches | ab7e23f | 2015-04-16 12:44:22 -0700 | [diff] [blame] | 3703 | # check for const <foo> const where <foo> is not a pointer or array type |
| 3704 | if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { |
| 3705 | my $found = $1; |
| 3706 | if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { |
| 3707 | WARN("CONST_CONST", |
| 3708 | "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); |
| 3709 | } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { |
| 3710 | WARN("CONST_CONST", |
| 3711 | "'const $found const' should probably be 'const $found'\n" . $herecurr); |
| 3712 | } |
| 3713 | } |
| 3714 | |
Joe Perches | 9b0fa60 | 2014-04-03 14:49:18 -0700 | [diff] [blame] | 3715 | # check for non-global char *foo[] = {"bar", ...} declarations. |
| 3716 | if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { |
| 3717 | WARN("STATIC_CONST_CHAR_ARRAY", |
| 3718 | "char * array declaration might be better as static const\n" . |
| 3719 | $herecurr); |
| 3720 | } |
| 3721 | |
Joe Perches | b598b67 | 2015-04-16 12:44:36 -0700 | [diff] [blame] | 3722 | # check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) |
| 3723 | if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { |
| 3724 | my $array = $1; |
| 3725 | if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { |
| 3726 | my $array_div = $1; |
| 3727 | if (WARN("ARRAY_SIZE", |
| 3728 | "Prefer ARRAY_SIZE($array)\n" . $herecurr) && |
| 3729 | $fix) { |
| 3730 | $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; |
| 3731 | } |
| 3732 | } |
| 3733 | } |
| 3734 | |
Joe Perches | b36190c | 2014-01-27 17:07:18 -0800 | [diff] [blame] | 3735 | # check for function declarations without arguments like "int foo()" |
| 3736 | if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { |
| 3737 | if (ERROR("FUNCTION_WITHOUT_ARGS", |
| 3738 | "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && |
| 3739 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3740 | $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; |
Joe Perches | b36190c | 2014-01-27 17:07:18 -0800 | [diff] [blame] | 3741 | } |
| 3742 | } |
| 3743 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3744 | # check for new typedefs, only function parameters and sparse annotations |
| 3745 | # make sense. |
| 3746 | if ($line =~ /\btypedef\s/ && |
Andy Whitcroft | 8054576 | 2009-01-06 14:41:26 -0800 | [diff] [blame] | 3747 | $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 3748 | $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && |
Andy Whitcroft | 8ed22ca | 2008-10-15 22:02:32 -0700 | [diff] [blame] | 3749 | $line !~ /\b$typeTypedefs\b/ && |
Michael S. Tsirkin | 46d832f | 2016-12-11 06:29:58 +0200 | [diff] [blame] | 3750 | $line !~ /\b__bitwise\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3751 | WARN("NEW_TYPEDEFS", |
| 3752 | "do not add new typedefs\n" . $herecurr); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3753 | } |
| 3754 | |
| 3755 | # * goes on variable not on type |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3756 | # (char*[ const]) |
Andy Whitcroft | bfcb2cc | 2012-01-10 15:10:15 -0800 | [diff] [blame] | 3757 | while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { |
| 3758 | #print "AA<$1>\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3759 | my ($ident, $from, $to) = ($1, $2, $2); |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 3760 | |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3761 | # Should start with a space. |
| 3762 | $to =~ s/^(\S)/ $1/; |
| 3763 | # Should not end with a space. |
| 3764 | $to =~ s/\s+$//; |
| 3765 | # '*'s should not have spaces between. |
Andy Whitcroft | f9a0b3d | 2009-01-15 13:51:05 -0800 | [diff] [blame] | 3766 | while ($to =~ s/\*\s+\*/\*\*/) { |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3767 | } |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 3768 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3769 | ## print "1: from<$from> to<$to> ident<$ident>\n"; |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3770 | if ($from ne $to) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3771 | if (ERROR("POINTER_LOCATION", |
| 3772 | "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && |
| 3773 | $fix) { |
| 3774 | my $sub_from = $ident; |
| 3775 | my $sub_to = $ident; |
| 3776 | $sub_to =~ s/\Q$from\E/$to/; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3777 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3778 | s@\Q$sub_from\E@$sub_to@; |
| 3779 | } |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3780 | } |
Andy Whitcroft | bfcb2cc | 2012-01-10 15:10:15 -0800 | [diff] [blame] | 3781 | } |
| 3782 | while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { |
| 3783 | #print "BB<$1>\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3784 | my ($match, $from, $to, $ident) = ($1, $2, $2, $3); |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 3785 | |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3786 | # Should start with a space. |
| 3787 | $to =~ s/^(\S)/ $1/; |
| 3788 | # Should not end with a space. |
| 3789 | $to =~ s/\s+$//; |
| 3790 | # '*'s should not have spaces between. |
Andy Whitcroft | f9a0b3d | 2009-01-15 13:51:05 -0800 | [diff] [blame] | 3791 | while ($to =~ s/\*\s+\*/\*\*/) { |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3792 | } |
| 3793 | # Modifiers should have spaces. |
| 3794 | $to =~ s/(\b$Modifier$)/$1 /; |
| 3795 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3796 | ## print "2: from<$from> to<$to> ident<$ident>\n"; |
Andy Whitcroft | 667026e | 2009-02-27 14:03:08 -0800 | [diff] [blame] | 3797 | if ($from ne $to && $ident !~ /^$Modifier$/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3798 | if (ERROR("POINTER_LOCATION", |
| 3799 | "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && |
| 3800 | $fix) { |
| 3801 | |
| 3802 | my $sub_from = $match; |
| 3803 | my $sub_to = $match; |
| 3804 | $sub_to =~ s/\Q$from\E/$to/; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3805 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3806 | s@\Q$sub_from\E@$sub_to@; |
| 3807 | } |
Andy Whitcroft | 6586386 | 2009-01-06 14:41:21 -0800 | [diff] [blame] | 3808 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3809 | } |
| 3810 | |
Joe Perches | 9d3e3c7 | 2015-09-09 15:37:27 -0700 | [diff] [blame] | 3811 | # avoid BUG() or BUG_ON() |
| 3812 | if ($line =~ /\b(?:BUG|BUG_ON)\b/) { |
| 3813 | my $msg_type = \&WARN; |
| 3814 | $msg_type = \&CHK if ($file); |
| 3815 | &{$msg_type}("AVOID_BUG", |
| 3816 | "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); |
| 3817 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3818 | |
Joe Perches | 9d3e3c7 | 2015-09-09 15:37:27 -0700 | [diff] [blame] | 3819 | # avoid LINUX_VERSION_CODE |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3820 | if ($line =~ /\bLINUX_VERSION_CODE\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3821 | WARN("LINUX_VERSION_CODE", |
| 3822 | "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] | 3823 | } |
| 3824 | |
Joe Perches | 1744122 | 2011-06-15 15:08:17 -0700 | [diff] [blame] | 3825 | # check for uses of printk_ratelimit |
| 3826 | if ($line =~ /\bprintk_ratelimit\s*\(/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3827 | WARN("PRINTK_RATELIMITED", |
Joe Perches | 101ee68 | 2015-02-13 14:38:54 -0800 | [diff] [blame] | 3828 | "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); |
Joe Perches | 1744122 | 2011-06-15 15:08:17 -0700 | [diff] [blame] | 3829 | } |
| 3830 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3831 | # printk should use KERN_* levels. Note that follow on printk's on the |
| 3832 | # same line do not need a level, so we use the current block context |
| 3833 | # to try and find and validate the current printk. In summary the current |
Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 3834 | # printk includes all preceding printk's which have no newline on the end. |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3835 | # we assume the first bad printk is the one to report. |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 3836 | if ($line =~ /\bprintk\((?!KERN_)\s*"/) { |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3837 | my $ok = 0; |
| 3838 | for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { |
| 3839 | #print "CHECK<$lines[$ln - 1]\n"; |
Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 3840 | # we have a preceding printk if it ends |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3841 | # with "\n" ignore it, else it is to blame |
| 3842 | if ($lines[$ln - 1] =~ m{\bprintk\(}) { |
| 3843 | if ($rawlines[$ln - 1] !~ m{\\n"}) { |
| 3844 | $ok = 1; |
| 3845 | } |
| 3846 | last; |
| 3847 | } |
| 3848 | } |
| 3849 | if ($ok == 0) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 3850 | WARN("PRINTK_WITHOUT_KERN_LEVEL", |
| 3851 | "printk() should include KERN_ facility level\n" . $herecurr); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 3852 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3853 | } |
| 3854 | |
Joe Perches | 243f380 | 2012-05-31 16:26:09 -0700 | [diff] [blame] | 3855 | if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { |
| 3856 | my $orig = $1; |
| 3857 | my $level = lc($orig); |
| 3858 | $level = "warn" if ($level eq "warning"); |
Joe Perches | 8f26b83 | 2012-10-04 17:13:32 -0700 | [diff] [blame] | 3859 | my $level2 = $level; |
| 3860 | $level2 = "dbg" if ($level eq "debug"); |
Joe Perches | 243f380 | 2012-05-31 16:26:09 -0700 | [diff] [blame] | 3861 | WARN("PREFER_PR_LEVEL", |
Yogesh Chaudhari | daa8b05 | 2014-04-03 14:49:23 -0700 | [diff] [blame] | 3862 | "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] | 3863 | } |
| 3864 | |
| 3865 | if ($line =~ /\bpr_warning\s*\(/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3866 | if (WARN("PREFER_PR_LEVEL", |
| 3867 | "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && |
| 3868 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3869 | $fixed[$fixlinenr] =~ |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 3870 | s/\bpr_warning\b/pr_warn/; |
| 3871 | } |
Joe Perches | 243f380 | 2012-05-31 16:26:09 -0700 | [diff] [blame] | 3872 | } |
| 3873 | |
Joe Perches | dc13931 | 2013-02-21 16:44:13 -0800 | [diff] [blame] | 3874 | if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { |
| 3875 | my $orig = $1; |
| 3876 | my $level = lc($orig); |
| 3877 | $level = "warn" if ($level eq "warning"); |
| 3878 | $level = "dbg" if ($level eq "debug"); |
| 3879 | WARN("PREFER_DEV_LEVEL", |
| 3880 | "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); |
| 3881 | } |
| 3882 | |
Andy Lutomirski | 91c9afa | 2015-04-16 12:44:44 -0700 | [diff] [blame] | 3883 | # ENOSYS means "bad syscall nr" and nothing else. This will have a small |
| 3884 | # number of false positives, but assembly files are not checked, so at |
| 3885 | # least the arch entry code will not trigger this warning. |
| 3886 | if ($line =~ /\bENOSYS\b/) { |
| 3887 | WARN("ENOSYS", |
| 3888 | "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); |
| 3889 | } |
| 3890 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3891 | # function brace can't be on same line, except for #defines of do while, |
| 3892 | # or if closed on same line |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 3893 | if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and |
Eddie Kovsky | 4e5d56b | 2015-09-09 15:37:52 -0700 | [diff] [blame] | 3894 | !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 3895 | if (ERROR("OPEN_BRACE", |
| 3896 | "open brace '{' following function declarations go on the next line\n" . $herecurr) && |
| 3897 | $fix) { |
| 3898 | fix_delete_line($fixlinenr, $rawline); |
| 3899 | my $fixed_line = $rawline; |
| 3900 | $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; |
| 3901 | my $line1 = $1; |
| 3902 | my $line2 = $2; |
| 3903 | fix_insert_line($fixlinenr, ltrim($line1)); |
| 3904 | fix_insert_line($fixlinenr, "\+{"); |
| 3905 | if ($line2 !~ /^\s*$/) { |
| 3906 | fix_insert_line($fixlinenr, "\+\t" . trim($line2)); |
| 3907 | } |
| 3908 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 3909 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 3910 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3911 | # open braces for enum, union and struct go on the same line. |
| 3912 | if ($line =~ /^.\s*{/ && |
| 3913 | $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 3914 | if (ERROR("OPEN_BRACE", |
| 3915 | "open brace '{' following $1 go on the same line\n" . $hereprev) && |
| 3916 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { |
| 3917 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 3918 | fix_delete_line($fixlinenr, $rawline); |
| 3919 | my $fixedline = rtrim($prevrawline) . " {"; |
| 3920 | fix_insert_line($fixlinenr, $fixedline); |
| 3921 | $fixedline = $rawline; |
Cyril Bur | 8d81ae0 | 2017-07-10 15:52:21 -0700 | [diff] [blame] | 3922 | $fixedline =~ s/^(.\s*)\{\s*/$1\t/; |
Joe Perches | 8d18247 | 2014-08-06 16:11:12 -0700 | [diff] [blame] | 3923 | if ($fixedline !~ /^\+\s*$/) { |
| 3924 | fix_insert_line($fixlinenr, $fixedline); |
| 3925 | } |
| 3926 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 3927 | } |
| 3928 | |
Andy Whitcroft | 0c73b4e | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 3929 | # missing space after union, struct or enum definition |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3930 | if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { |
| 3931 | if (WARN("SPACING", |
| 3932 | "missing space after $1 definition\n" . $herecurr) && |
| 3933 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 3934 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 3935 | s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; |
| 3936 | } |
Andy Whitcroft | 0c73b4e | 2010-10-26 14:23:15 -0700 | [diff] [blame] | 3937 | } |
| 3938 | |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 3939 | # Function pointer declarations |
| 3940 | # check spacing between type, funcptr, and args |
| 3941 | # canonical declaration is "type (*funcptr)(args...)" |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 3942 | if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 3943 | my $declare = $1; |
| 3944 | my $pre_pointer_space = $2; |
| 3945 | my $post_pointer_space = $3; |
| 3946 | my $funcname = $4; |
| 3947 | my $post_funcname_space = $5; |
| 3948 | my $pre_args_space = $6; |
| 3949 | |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 3950 | # the $Declare variable will capture all spaces after the type |
| 3951 | # so check it for a missing trailing missing space but pointer return types |
| 3952 | # don't need a space so don't warn for those. |
| 3953 | my $post_declare_space = ""; |
| 3954 | if ($declare =~ /(\s+)$/) { |
| 3955 | $post_declare_space = $1; |
| 3956 | $declare = rtrim($declare); |
| 3957 | } |
| 3958 | if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 3959 | WARN("SPACING", |
| 3960 | "missing space after return type\n" . $herecurr); |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 3961 | $post_declare_space = " "; |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 3962 | } |
| 3963 | |
| 3964 | # unnecessary space "type (*funcptr)(args...)" |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 3965 | # This test is not currently implemented because these declarations are |
| 3966 | # equivalent to |
| 3967 | # int foo(int bar, ...) |
| 3968 | # and this is form shouldn't/doesn't generate a checkpatch warning. |
| 3969 | # |
| 3970 | # elsif ($declare =~ /\s{2,}$/) { |
| 3971 | # WARN("SPACING", |
| 3972 | # "Multiple spaces after return type\n" . $herecurr); |
| 3973 | # } |
Joe Perches | 31070b5 | 2014-01-23 15:54:49 -0800 | [diff] [blame] | 3974 | |
| 3975 | # unnecessary space "type ( *funcptr)(args...)" |
| 3976 | if (defined $pre_pointer_space && |
| 3977 | $pre_pointer_space =~ /^\s/) { |
| 3978 | WARN("SPACING", |
| 3979 | "Unnecessary space after function pointer open parenthesis\n" . $herecurr); |
| 3980 | } |
| 3981 | |
| 3982 | # unnecessary space "type (* funcptr)(args...)" |
| 3983 | if (defined $post_pointer_space && |
| 3984 | $post_pointer_space =~ /^\s/) { |
| 3985 | WARN("SPACING", |
| 3986 | "Unnecessary space before function pointer name\n" . $herecurr); |
| 3987 | } |
| 3988 | |
| 3989 | # unnecessary space "type (*funcptr )(args...)" |
| 3990 | if (defined $post_funcname_space && |
| 3991 | $post_funcname_space =~ /^\s/) { |
| 3992 | WARN("SPACING", |
| 3993 | "Unnecessary space after function pointer name\n" . $herecurr); |
| 3994 | } |
| 3995 | |
| 3996 | # unnecessary space "type (*funcptr) (args...)" |
| 3997 | if (defined $pre_args_space && |
| 3998 | $pre_args_space =~ /^\s/) { |
| 3999 | WARN("SPACING", |
| 4000 | "Unnecessary space before function pointer arguments\n" . $herecurr); |
| 4001 | } |
| 4002 | |
| 4003 | if (show_type("SPACING") && $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4004 | $fixed[$fixlinenr] =~ |
Joe Perches | 91f72e9 | 2014-04-03 14:49:12 -0700 | [diff] [blame] | 4005 | 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] | 4006 | } |
| 4007 | } |
| 4008 | |
Andy Whitcroft | 8d31cfc | 2008-07-23 21:29:02 -0700 | [diff] [blame] | 4009 | # check for spacing round square brackets; allowed: |
| 4010 | # 1. with a type on the left -- int [] a; |
Andy Whitcroft | fe2a7db | 2008-10-15 22:02:15 -0700 | [diff] [blame] | 4011 | # 2. at the beginning of a line for slice initialisers -- [0...10] = 5, |
| 4012 | # 3. inside a curly brace -- = { [0...10] = 5 } |
Andy Whitcroft | 8d31cfc | 2008-07-23 21:29:02 -0700 | [diff] [blame] | 4013 | while ($line =~ /(.*?\s)\[/g) { |
| 4014 | my ($where, $prefix) = ($-[1], $1); |
| 4015 | if ($prefix !~ /$Type\s+$/ && |
Andy Whitcroft | fe2a7db | 2008-10-15 22:02:15 -0700 | [diff] [blame] | 4016 | ($where != 0 || $prefix !~ /^.\s+$/) && |
Andy Whitcroft | daebc53 | 2012-03-23 15:02:17 -0700 | [diff] [blame] | 4017 | $prefix !~ /[{,]\s+$/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4018 | if (ERROR("BRACKET_SPACE", |
| 4019 | "space prohibited before open square bracket '['\n" . $herecurr) && |
| 4020 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4021 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4022 | s/^(\+.*?)\s+\[/$1\[/; |
| 4023 | } |
Andy Whitcroft | 8d31cfc | 2008-07-23 21:29:02 -0700 | [diff] [blame] | 4024 | } |
| 4025 | } |
| 4026 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4027 | # check for spaces between functions and their parentheses. |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4028 | while ($line =~ /($Ident)\s+\(/g) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4029 | my $name = $1; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4030 | my $ctx_before = substr($line, 0, $-[1]); |
| 4031 | my $ctx = "$ctx_before$name"; |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4032 | |
| 4033 | # Ignore those directives where spaces _are_ permitted. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4034 | if ($name =~ /^(?: |
| 4035 | if|for|while|switch|return|case| |
| 4036 | volatile|__volatile__| |
| 4037 | __attribute__|format|__extension__| |
| 4038 | asm|__asm__)$/x) |
| 4039 | { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4040 | # cpp #define statements have non-optional spaces, ie |
| 4041 | # if there is a space between the name and the open |
| 4042 | # parenthesis it is simply not a parameter group. |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4043 | } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4044 | |
| 4045 | # cpp #elif statement condition may start with a ( |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4046 | } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4047 | |
| 4048 | # If this whole things ends with a type its most |
| 4049 | # likely a typedef for a function. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4050 | } elsif ($ctx =~ /$Type$/) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4051 | |
| 4052 | } else { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4053 | if (WARN("SPACING", |
| 4054 | "space prohibited between function name and open parenthesis '('\n" . $herecurr) && |
| 4055 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4056 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4057 | s/\b$name\s+\(/$name\(/; |
| 4058 | } |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4059 | } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4060 | } |
Eric Nelson | 9a4cad4 | 2012-05-31 16:26:09 -0700 | [diff] [blame] | 4061 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4062 | # Check operator spacing. |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4063 | if (!($line=~/\#\s*include/)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4064 | my $fixed_line = ""; |
| 4065 | my $line_fixed = 0; |
| 4066 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4067 | my $ops = qr{ |
| 4068 | <<=|>>=|<=|>=|==|!=| |
| 4069 | \+=|-=|\*=|\/=|%=|\^=|\|=|&=| |
| 4070 | =>|->|<<|>>|<|>|=|!|~| |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4071 | &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| |
Joe Perches | 8473162 | 2013-11-12 15:10:05 -0800 | [diff] [blame] | 4072 | \?:|\?|: |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4073 | }x; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4074 | my @elements = split(/($ops|;)/, $opline); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4075 | |
| 4076 | ## print("element count: <" . $#elements . ">\n"); |
| 4077 | ## foreach my $el (@elements) { |
| 4078 | ## print("el: <$el>\n"); |
| 4079 | ## } |
| 4080 | |
| 4081 | my @fix_elements = (); |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 4082 | my $off = 0; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4083 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4084 | foreach my $el (@elements) { |
| 4085 | push(@fix_elements, substr($rawline, $off, length($el))); |
| 4086 | $off += length($el); |
| 4087 | } |
| 4088 | |
| 4089 | $off = 0; |
| 4090 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4091 | my $blank = copy_spacing($opline); |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4092 | my $last_after = -1; |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4093 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4094 | for (my $n = 0; $n < $#elements; $n += 2) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4095 | |
| 4096 | my $good = $fix_elements[$n] . $fix_elements[$n + 1]; |
| 4097 | |
| 4098 | ## print("n: <$n> good: <$good>\n"); |
| 4099 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4100 | $off += length($elements[$n]); |
| 4101 | |
Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 4102 | # Pick up the preceding and succeeding characters. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4103 | my $ca = substr($opline, 0, $off); |
| 4104 | my $cc = ''; |
| 4105 | if (length($opline) >= ($off + length($elements[$n + 1]))) { |
| 4106 | $cc = substr($opline, $off + length($elements[$n + 1])); |
| 4107 | } |
| 4108 | my $cb = "$ca$;$cc"; |
| 4109 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4110 | my $a = ''; |
| 4111 | $a = 'V' if ($elements[$n] ne ''); |
| 4112 | $a = 'W' if ($elements[$n] =~ /\s$/); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4113 | $a = 'C' if ($elements[$n] =~ /$;$/); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4114 | $a = 'B' if ($elements[$n] =~ /(\[|\()$/); |
| 4115 | $a = 'O' if ($elements[$n] eq ''); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4116 | $a = 'E' if ($ca =~ /^\s*$/); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4117 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4118 | my $op = $elements[$n + 1]; |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4119 | |
| 4120 | my $c = ''; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4121 | if (defined $elements[$n + 2]) { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4122 | $c = 'V' if ($elements[$n + 2] ne ''); |
| 4123 | $c = 'W' if ($elements[$n + 2] =~ /^\s/); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4124 | $c = 'C' if ($elements[$n + 2] =~ /^$;/); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4125 | $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); |
| 4126 | $c = 'O' if ($elements[$n + 2] eq ''); |
Andy Whitcroft | 8b1b337 | 2009-01-06 14:41:27 -0800 | [diff] [blame] | 4127 | $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4128 | } else { |
| 4129 | $c = 'E'; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4130 | } |
| 4131 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4132 | my $ctx = "${a}x${c}"; |
| 4133 | |
| 4134 | my $at = "(ctx:$ctx)"; |
| 4135 | |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4136 | my $ptr = substr($blank, 0, $off) . "^"; |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 4137 | my $hereptr = "$hereline$ptr\n"; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4138 | |
Andy Whitcroft | 74048ed | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4139 | # Pull out the value of this operator. |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 4140 | my $op_type = substr($curr_values, $off + 1, 1); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4141 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4142 | # Get the full operator variant. |
| 4143 | my $opv = $op . substr($curr_vars, $off, 1); |
| 4144 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4145 | # Ignore operators passed as parameters. |
| 4146 | if ($op_type ne 'V' && |
Sam Bobroff | d7fe806 | 2015-04-16 12:44:39 -0700 | [diff] [blame] | 4147 | $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4148 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4149 | # # Ignore comments |
| 4150 | # } elsif ($op =~ /^$;+$/) { |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4151 | |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 4152 | # ; 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] | 4153 | } elsif ($op eq ';') { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4154 | if ($ctx !~ /.x[WEBC]/ && |
| 4155 | $cc !~ /^\\/ && $cc !~ /^;/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4156 | if (ERROR("SPACING", |
| 4157 | "space required after that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4158 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4159 | $line_fixed = 1; |
| 4160 | } |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 4161 | } |
| 4162 | |
| 4163 | # // is a comment |
| 4164 | } elsif ($op eq '//') { |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4165 | |
Joe Perches | b00e481 | 2014-04-03 14:49:33 -0700 | [diff] [blame] | 4166 | # : when part of a bitfield |
| 4167 | } elsif ($opv eq ':B') { |
| 4168 | # skip the bitfield test for now |
| 4169 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4170 | # No spaces for: |
| 4171 | # -> |
Joe Perches | b00e481 | 2014-04-03 14:49:33 -0700 | [diff] [blame] | 4172 | } elsif ($op eq '->') { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4173 | if ($ctx =~ /Wx.|.xW/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4174 | if (ERROR("SPACING", |
| 4175 | "spaces prohibited around that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4176 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4177 | if (defined $fix_elements[$n + 2]) { |
| 4178 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 4179 | } |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4180 | $line_fixed = 1; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4181 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4182 | } |
| 4183 | |
Joe Perches | 2381097 | 2014-12-10 15:51:32 -0800 | [diff] [blame] | 4184 | # , must not have a space before and must have a space on the right. |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4185 | } elsif ($op eq ',') { |
Joe Perches | 2381097 | 2014-12-10 15:51:32 -0800 | [diff] [blame] | 4186 | my $rtrim_before = 0; |
| 4187 | my $space_after = 0; |
| 4188 | if ($ctx =~ /Wx./) { |
| 4189 | if (ERROR("SPACING", |
| 4190 | "space prohibited before that '$op' $at\n" . $hereptr)) { |
| 4191 | $line_fixed = 1; |
| 4192 | $rtrim_before = 1; |
| 4193 | } |
| 4194 | } |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4195 | if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4196 | if (ERROR("SPACING", |
| 4197 | "space required after that '$op' $at\n" . $hereptr)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4198 | $line_fixed = 1; |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4199 | $last_after = $n; |
Joe Perches | 2381097 | 2014-12-10 15:51:32 -0800 | [diff] [blame] | 4200 | $space_after = 1; |
| 4201 | } |
| 4202 | } |
| 4203 | if ($rtrim_before || $space_after) { |
| 4204 | if ($rtrim_before) { |
| 4205 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
| 4206 | } else { |
| 4207 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); |
| 4208 | } |
| 4209 | if ($space_after) { |
| 4210 | $good .= " "; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4211 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4212 | } |
| 4213 | |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4214 | # '*' as part of a type definition -- reported already. |
Andy Whitcroft | 74048ed | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4215 | } elsif ($opv eq '*_') { |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4216 | #warn "'*' is part of type\n"; |
| 4217 | |
| 4218 | # unary operators should have a space before and |
| 4219 | # none after. May be left adjacent to another |
| 4220 | # unary operator, or a cast |
| 4221 | } elsif ($op eq '!' || $op eq '~' || |
Andy Whitcroft | 74048ed | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4222 | $opv eq '*U' || $opv eq '-U' || |
Andy Whitcroft | 0d41386 | 2008-10-15 22:02:16 -0700 | [diff] [blame] | 4223 | $opv eq '&U' || $opv eq '&&U') { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4224 | if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4225 | if (ERROR("SPACING", |
| 4226 | "space required before that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4227 | if ($n != $last_after + 2) { |
| 4228 | $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); |
| 4229 | $line_fixed = 1; |
| 4230 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4231 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4232 | } |
Andy Whitcroft | a3340b3 | 2009-02-27 14:03:07 -0800 | [diff] [blame] | 4233 | if ($op eq '*' && $cc =~/\s*$Modifier\b/) { |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 4234 | # A unary '*' may be const |
| 4235 | |
| 4236 | } elsif ($ctx =~ /.xW/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4237 | if (ERROR("SPACING", |
| 4238 | "space prohibited after that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4239 | $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4240 | if (defined $fix_elements[$n + 2]) { |
| 4241 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 4242 | } |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4243 | $line_fixed = 1; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4244 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4245 | } |
| 4246 | |
| 4247 | # unary ++ and unary -- are allowed no space on one side. |
| 4248 | } elsif ($op eq '++' or $op eq '--') { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4249 | if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4250 | if (ERROR("SPACING", |
| 4251 | "space required one side of that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4252 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4253 | $line_fixed = 1; |
| 4254 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4255 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4256 | if ($ctx =~ /Wx[BE]/ || |
| 4257 | ($ctx =~ /Wx./ && $cc =~ /^;/)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4258 | if (ERROR("SPACING", |
| 4259 | "space prohibited before that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4260 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4261 | $line_fixed = 1; |
| 4262 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4263 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4264 | if ($ctx =~ /ExW/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4265 | if (ERROR("SPACING", |
| 4266 | "space prohibited after that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4267 | $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4268 | if (defined $fix_elements[$n + 2]) { |
| 4269 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 4270 | } |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4271 | $line_fixed = 1; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4272 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4273 | } |
| 4274 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4275 | # << and >> may either have or not have spaces both sides |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4276 | } elsif ($op eq '<<' or $op eq '>>' or |
| 4277 | $op eq '&' or $op eq '^' or $op eq '|' or |
| 4278 | $op eq '+' or $op eq '-' or |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4279 | $op eq '*' or $op eq '/' or |
| 4280 | $op eq '%') |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4281 | { |
Joe Perches | d2e025f | 2015-02-13 14:38:57 -0800 | [diff] [blame] | 4282 | if ($check) { |
| 4283 | if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { |
| 4284 | if (CHK("SPACING", |
| 4285 | "spaces preferred around that '$op' $at\n" . $hereptr)) { |
| 4286 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
| 4287 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 4288 | $line_fixed = 1; |
| 4289 | } |
| 4290 | } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { |
| 4291 | if (CHK("SPACING", |
| 4292 | "space preferred before that '$op' $at\n" . $hereptr)) { |
| 4293 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); |
| 4294 | $line_fixed = 1; |
| 4295 | } |
| 4296 | } |
| 4297 | } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4298 | if (ERROR("SPACING", |
| 4299 | "need consistent spacing around '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4300 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
| 4301 | if (defined $fix_elements[$n + 2]) { |
| 4302 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 4303 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4304 | $line_fixed = 1; |
| 4305 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4306 | } |
| 4307 | |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4308 | # A colon needs no spaces before when it is |
| 4309 | # terminating a case value or a label. |
| 4310 | } elsif ($opv eq ':C' || $opv eq ':L') { |
| 4311 | if ($ctx =~ /Wx./) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4312 | if (ERROR("SPACING", |
| 4313 | "space prohibited before that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4314 | $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4315 | $line_fixed = 1; |
| 4316 | } |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4317 | } |
| 4318 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4319 | # All the others need spaces both sides. |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4320 | } elsif ($ctx !~ /[EWC]x[CWE]/) { |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4321 | my $ok = 0; |
| 4322 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4323 | # Ignore email addresses <foo@bar> |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4324 | if (($op eq '<' && |
| 4325 | $cc =~ /^\S+\@\S+>/) || |
| 4326 | ($op eq '>' && |
| 4327 | $ca =~ /<\S+\@\S+$/)) |
| 4328 | { |
| 4329 | $ok = 1; |
| 4330 | } |
| 4331 | |
Joe Perches | e0df7e1 | 2015-04-16 12:44:53 -0700 | [diff] [blame] | 4332 | # for asm volatile statements |
| 4333 | # ignore a colon with another |
| 4334 | # colon immediately before or after |
| 4335 | if (($op eq ':') && |
| 4336 | ($ca =~ /:$/ || $cc =~ /^:/)) { |
| 4337 | $ok = 1; |
| 4338 | } |
| 4339 | |
Joe Perches | 8473162 | 2013-11-12 15:10:05 -0800 | [diff] [blame] | 4340 | # messages are ERROR, but ?: are CHK |
Andy Whitcroft | 1f65f94 | 2008-07-23 21:29:10 -0700 | [diff] [blame] | 4341 | if ($ok == 0) { |
Joe Perches | 8473162 | 2013-11-12 15:10:05 -0800 | [diff] [blame] | 4342 | my $msg_type = \&ERROR; |
| 4343 | $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); |
| 4344 | |
| 4345 | if (&{$msg_type}("SPACING", |
| 4346 | "spaces required around that '$op' $at\n" . $hereptr)) { |
Joe Perches | b34c648 | 2013-09-11 14:24:01 -0700 | [diff] [blame] | 4347 | $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; |
| 4348 | if (defined $fix_elements[$n + 2]) { |
| 4349 | $fix_elements[$n + 2] =~ s/^\s+//; |
| 4350 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4351 | $line_fixed = 1; |
| 4352 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4353 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4354 | } |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4355 | $off += length($elements[$n + 1]); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4356 | |
| 4357 | ## print("n: <$n> GOOD: <$good>\n"); |
| 4358 | |
| 4359 | $fixed_line = $fixed_line . $good; |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4360 | } |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4361 | |
| 4362 | if (($#elements % 2) == 0) { |
| 4363 | $fixed_line = $fixed_line . $fix_elements[$#elements]; |
| 4364 | } |
| 4365 | |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4366 | if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { |
| 4367 | $fixed[$fixlinenr] = $fixed_line; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4368 | } |
| 4369 | |
| 4370 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4371 | } |
| 4372 | |
Joe Perches | 786b632 | 2013-07-03 15:05:32 -0700 | [diff] [blame] | 4373 | # check for whitespace before a non-naked semicolon |
Joe Perches | d2e248e | 2014-01-23 15:54:41 -0800 | [diff] [blame] | 4374 | if ($line =~ /^\+.*\S\s+;\s*$/) { |
Joe Perches | 786b632 | 2013-07-03 15:05:32 -0700 | [diff] [blame] | 4375 | if (WARN("SPACING", |
| 4376 | "space prohibited before semicolon\n" . $herecurr) && |
| 4377 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4378 | 1 while $fixed[$fixlinenr] =~ |
Joe Perches | 786b632 | 2013-07-03 15:05:32 -0700 | [diff] [blame] | 4379 | s/^(\+.*\S)\s+;/$1;/; |
| 4380 | } |
| 4381 | } |
| 4382 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4383 | # check for multiple assignments |
| 4384 | if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4385 | CHK("MULTIPLE_ASSIGNMENTS", |
| 4386 | "multiple assignments should be avoided\n" . $herecurr); |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4387 | } |
| 4388 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4389 | ## # check for multiple declarations, allowing for a function declaration |
| 4390 | ## # continuation. |
| 4391 | ## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && |
| 4392 | ## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { |
| 4393 | ## |
| 4394 | ## # Remove any bracketed sections to ensure we do not |
| 4395 | ## # falsly report the parameters of functions. |
| 4396 | ## my $ln = $line; |
| 4397 | ## while ($ln =~ s/\([^\(\)]*\)//g) { |
| 4398 | ## } |
| 4399 | ## if ($ln =~ /,/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4400 | ## WARN("MULTIPLE_DECLARATION", |
| 4401 | ## "declaring multiple variables together should be avoided\n" . $herecurr); |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4402 | ## } |
| 4403 | ## } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 4404 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4405 | #need space before brace following if, while, etc |
Geyslan G. Bem | 6b8c69e | 2016-03-15 14:58:09 -0700 | [diff] [blame] | 4406 | if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || |
Eddie Kovsky | 4e5d56b | 2015-09-09 15:37:52 -0700 | [diff] [blame] | 4407 | $line =~ /do\{/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4408 | if (ERROR("SPACING", |
| 4409 | "space required before the open brace '{'\n" . $herecurr) && |
| 4410 | $fix) { |
Cyril Bur | 8d81ae0 | 2017-07-10 15:52:21 -0700 | [diff] [blame] | 4411 | $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4412 | } |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 4413 | } |
| 4414 | |
Joe Perches | c4a62ef | 2013-07-03 15:05:28 -0700 | [diff] [blame] | 4415 | ## # check for blank lines before declarations |
| 4416 | ## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && |
| 4417 | ## $prevrawline =~ /^.\s*$/) { |
| 4418 | ## WARN("SPACING", |
| 4419 | ## "No blank lines before declarations\n" . $hereprev); |
| 4420 | ## } |
| 4421 | ## |
| 4422 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 4423 | # closing brace should have a space following it when it has anything |
| 4424 | # on the line |
| 4425 | if ($line =~ /}(?!(?:,|;|\)))\S/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4426 | if (ERROR("SPACING", |
| 4427 | "space required after that close brace '}'\n" . $herecurr) && |
| 4428 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4429 | $fixed[$fixlinenr] =~ |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4430 | s/}((?!(?:,|;|\)))\S)/} $1/; |
| 4431 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4432 | } |
| 4433 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4434 | # check spacing on square brackets |
| 4435 | if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4436 | if (ERROR("SPACING", |
| 4437 | "space prohibited after that open square bracket '['\n" . $herecurr) && |
| 4438 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4439 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4440 | s/\[\s+/\[/; |
| 4441 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4442 | } |
| 4443 | if ($line =~ /\s\]/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4444 | if (ERROR("SPACING", |
| 4445 | "space prohibited before that close square bracket ']'\n" . $herecurr) && |
| 4446 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4447 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4448 | s/\s+\]/\]/; |
| 4449 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4450 | } |
| 4451 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4452 | # check spacing on parentheses |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 4453 | if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && |
| 4454 | $line !~ /for\s*\(\s+;/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4455 | if (ERROR("SPACING", |
| 4456 | "space prohibited after that open parenthesis '('\n" . $herecurr) && |
| 4457 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4458 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4459 | s/\(\s+/\(/; |
| 4460 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4461 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4462 | if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4463 | $line !~ /for\s*\(.*;\s+\)/ && |
| 4464 | $line !~ /:\s+\)/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4465 | if (ERROR("SPACING", |
| 4466 | "space prohibited before that close parenthesis ')'\n" . $herecurr) && |
| 4467 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4468 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4469 | s/\s+\)/\)/; |
| 4470 | } |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 4471 | } |
| 4472 | |
Joe Perches | e2826fd | 2014-08-06 16:10:48 -0700 | [diff] [blame] | 4473 | # check unnecessary parentheses around addressof/dereference single $Lvals |
| 4474 | # ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar |
| 4475 | |
| 4476 | while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { |
Joe Perches | ea4acbb | 2014-12-10 15:51:51 -0800 | [diff] [blame] | 4477 | my $var = $1; |
| 4478 | if (CHK("UNNECESSARY_PARENTHESES", |
| 4479 | "Unnecessary parentheses around $var\n" . $herecurr) && |
| 4480 | $fix) { |
| 4481 | $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; |
| 4482 | } |
| 4483 | } |
| 4484 | |
| 4485 | # check for unnecessary parentheses around function pointer uses |
| 4486 | # ie: (foo->bar)(); should be foo->bar(); |
| 4487 | # but not "if (foo->bar) (" to avoid some false positives |
| 4488 | if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { |
| 4489 | my $var = $2; |
| 4490 | if (CHK("UNNECESSARY_PARENTHESES", |
| 4491 | "Unnecessary parentheses around function pointer $var\n" . $herecurr) && |
| 4492 | $fix) { |
| 4493 | my $var2 = deparenthesize($var); |
| 4494 | $var2 =~ s/\s//g; |
| 4495 | $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; |
| 4496 | } |
| 4497 | } |
Joe Perches | e2826fd | 2014-08-06 16:10:48 -0700 | [diff] [blame] | 4498 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4499 | #goto labels aren't indented, allow a single space however |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 4500 | if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4501 | !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4502 | if (WARN("INDENTED_LABEL", |
| 4503 | "labels should not be indented\n" . $herecurr) && |
| 4504 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4505 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4506 | s/^(.)\s+/$1/; |
| 4507 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4508 | } |
| 4509 | |
Joe Perches | 5b9553a | 2014-04-03 14:49:21 -0700 | [diff] [blame] | 4510 | # return is not a function |
Joe Perches | 507e514 | 2013-11-12 15:10:13 -0800 | [diff] [blame] | 4511 | if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4512 | my $spacing = $1; |
Joe Perches | 507e514 | 2013-11-12 15:10:13 -0800 | [diff] [blame] | 4513 | if ($^V && $^V ge 5.10.0 && |
Joe Perches | 5b9553a | 2014-04-03 14:49:21 -0700 | [diff] [blame] | 4514 | $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { |
| 4515 | my $value = $1; |
| 4516 | $value = deparenthesize($value); |
| 4517 | if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { |
| 4518 | ERROR("RETURN_PARENTHESES", |
| 4519 | "return is not a function, parentheses are not required\n" . $herecurr); |
| 4520 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4521 | } elsif ($spacing !~ /\s+/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4522 | ERROR("SPACING", |
| 4523 | "space required before the open parenthesis '('\n" . $herecurr); |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4524 | } |
| 4525 | } |
Joe Perches | 507e514 | 2013-11-12 15:10:13 -0800 | [diff] [blame] | 4526 | |
Joe Perches | b43ae21 | 2014-06-23 13:22:07 -0700 | [diff] [blame] | 4527 | # unnecessary return in a void function |
| 4528 | # at end-of-function, with the previous line a single leading tab, then return; |
| 4529 | # and the line before that not a goto label target like "out:" |
| 4530 | if ($sline =~ /^[ \+]}\s*$/ && |
| 4531 | $prevline =~ /^\+\treturn\s*;\s*$/ && |
| 4532 | $linenr >= 3 && |
| 4533 | $lines[$linenr - 3] =~ /^[ +]/ && |
| 4534 | $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { |
Joe Perches | 9819cf2 | 2014-06-04 16:12:09 -0700 | [diff] [blame] | 4535 | WARN("RETURN_VOID", |
Joe Perches | b43ae21 | 2014-06-23 13:22:07 -0700 | [diff] [blame] | 4536 | "void function return statements are not generally useful\n" . $hereprev); |
| 4537 | } |
Joe Perches | 9819cf2 | 2014-06-04 16:12:09 -0700 | [diff] [blame] | 4538 | |
Joe Perches | 189248d | 2014-01-23 15:54:47 -0800 | [diff] [blame] | 4539 | # if statements using unnecessary parentheses - ie: if ((foo == bar)) |
| 4540 | if ($^V && $^V ge 5.10.0 && |
| 4541 | $line =~ /\bif\s*((?:\(\s*){2,})/) { |
| 4542 | my $openparens = $1; |
| 4543 | my $count = $openparens =~ tr@\(@\(@; |
| 4544 | my $msg = ""; |
| 4545 | if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { |
| 4546 | my $comp = $4; #Not $1 because of $LvalOrFunc |
| 4547 | $msg = " - maybe == should be = ?" if ($comp eq "=="); |
| 4548 | WARN("UNNECESSARY_PARENTHESES", |
| 4549 | "Unnecessary parentheses$msg\n" . $herecurr); |
| 4550 | } |
| 4551 | } |
| 4552 | |
Joe Perches | c5595fa | 2015-09-09 15:37:58 -0700 | [diff] [blame] | 4553 | # comparisons with a constant or upper case identifier on the left |
| 4554 | # avoid cases like "foo + BAR < baz" |
| 4555 | # only fix matches surrounded by parentheses to avoid incorrect |
| 4556 | # conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" |
| 4557 | if ($^V && $^V ge 5.10.0 && |
| 4558 | $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { |
| 4559 | my $lead = $1; |
| 4560 | my $const = $2; |
| 4561 | my $comp = $3; |
| 4562 | my $to = $4; |
| 4563 | my $newcomp = $comp; |
Joe Perches | f39e176 | 2016-05-20 17:04:02 -0700 | [diff] [blame] | 4564 | if ($lead !~ /(?:$Operators|\.)\s*$/ && |
Joe Perches | c5595fa | 2015-09-09 15:37:58 -0700 | [diff] [blame] | 4565 | $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && |
| 4566 | WARN("CONSTANT_COMPARISON", |
| 4567 | "Comparisons should place the constant on the right side of the test\n" . $herecurr) && |
| 4568 | $fix) { |
| 4569 | if ($comp eq "<") { |
| 4570 | $newcomp = ">"; |
| 4571 | } elsif ($comp eq "<=") { |
| 4572 | $newcomp = ">="; |
| 4573 | } elsif ($comp eq ">") { |
| 4574 | $newcomp = "<"; |
| 4575 | } elsif ($comp eq ">=") { |
| 4576 | $newcomp = "<="; |
| 4577 | } |
| 4578 | $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; |
| 4579 | } |
| 4580 | } |
| 4581 | |
Joe Perches | f34e4a4 | 2015-04-16 12:44:19 -0700 | [diff] [blame] | 4582 | # Return of what appears to be an errno should normally be negative |
| 4583 | if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { |
Andy Whitcroft | 53a3c44 | 2010-10-26 14:23:14 -0700 | [diff] [blame] | 4584 | my $name = $1; |
| 4585 | if ($name ne 'EOF' && $name ne 'ERROR') { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4586 | WARN("USE_NEGATIVE_ERRNO", |
Joe Perches | f34e4a4 | 2015-04-16 12:44:19 -0700 | [diff] [blame] | 4587 | "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] | 4588 | } |
| 4589 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4590 | |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4591 | # Need a space before open parenthesis after if, while etc |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4592 | if ($line =~ /\b(if|while|for|switch)\(/) { |
| 4593 | if (ERROR("SPACING", |
| 4594 | "space required before the open parenthesis '('\n" . $herecurr) && |
| 4595 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4596 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 4597 | s/\b(if|while|for|switch)\(/$1 \(/; |
| 4598 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4599 | } |
| 4600 | |
Andy Whitcroft | f5fe35d | 2008-07-23 21:29:03 -0700 | [diff] [blame] | 4601 | # Check for illegal assignment in if conditional -- and check for trailing |
| 4602 | # statements after the conditional. |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 4603 | if ($line =~ /do\s*(?!{)/) { |
Andy Whitcroft | 3e469cd | 2012-01-10 15:10:01 -0800 | [diff] [blame] | 4604 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
| 4605 | ctx_statement_block($linenr, $realcnt, 0) |
| 4606 | if (!defined $stat); |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 4607 | my ($stat_next) = ctx_statement_block($line_nr_next, |
| 4608 | $remain_next, $off_next); |
| 4609 | $stat_next =~ s/\n./\n /g; |
| 4610 | ##print "stat<$stat> stat_next<$stat_next>\n"; |
| 4611 | |
| 4612 | if ($stat_next =~ /^\s*while\b/) { |
| 4613 | # If the statement carries leading newlines, |
| 4614 | # then count those as offsets. |
| 4615 | my ($whitespace) = |
| 4616 | ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); |
| 4617 | my $offset = |
| 4618 | statement_rawlines($whitespace) - 1; |
| 4619 | |
| 4620 | $suppress_whiletrailers{$line_nr_next + |
| 4621 | $offset} = 1; |
| 4622 | } |
| 4623 | } |
| 4624 | if (!defined $suppress_whiletrailers{$linenr} && |
Joe Perches | c11230f | 2013-11-21 14:31:57 -0800 | [diff] [blame] | 4625 | defined($stat) && defined($cond) && |
Andy Whitcroft | 170d3a2 | 2008-10-15 22:02:30 -0700 | [diff] [blame] | 4626 | $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 4627 | my ($s, $c) = ($stat, $cond); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4628 | |
Andy Whitcroft | b53c8e1 | 2009-01-06 14:41:29 -0800 | [diff] [blame] | 4629 | if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4630 | ERROR("ASSIGN_IN_IF", |
| 4631 | "do not use assignment in if condition\n" . $herecurr); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4632 | } |
| 4633 | |
| 4634 | # Find out what is on the end of the line after the |
| 4635 | # conditional. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4636 | substr($s, 0, length($c), ''); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4637 | $s =~ s/\n.*//g; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4638 | $s =~ s/$;//g; # Remove any comments |
Andy Whitcroft | 5321016 | 2008-07-23 21:29:03 -0700 | [diff] [blame] | 4639 | if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && |
| 4640 | $c !~ /}\s*while\s*/) |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4641 | { |
Andy Whitcroft | bb44ad3 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 4642 | # Find out how long the conditional actually is. |
| 4643 | my @newlines = ($c =~ /\n/gs); |
| 4644 | my $cond_lines = 1 + $#newlines; |
Hidetoshi Seto | 42bdf74 | 2010-03-05 13:43:50 -0800 | [diff] [blame] | 4645 | my $stat_real = ''; |
Andy Whitcroft | bb44ad3 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 4646 | |
Hidetoshi Seto | 42bdf74 | 2010-03-05 13:43:50 -0800 | [diff] [blame] | 4647 | $stat_real = raw_line($linenr, $cond_lines) |
| 4648 | . "\n" if ($cond_lines); |
Andy Whitcroft | bb44ad3 | 2008-10-15 22:02:34 -0700 | [diff] [blame] | 4649 | if (defined($stat_real) && $cond_lines > 1) { |
| 4650 | $stat_real = "[...]\n$stat_real"; |
| 4651 | } |
| 4652 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4653 | ERROR("TRAILING_STATEMENTS", |
| 4654 | "trailing statements should be on next line\n" . $herecurr . $stat_real); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4655 | } |
| 4656 | } |
| 4657 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4658 | # Check for bitwise tests written as boolean |
| 4659 | if ($line =~ / |
| 4660 | (?: |
| 4661 | (?:\[|\(|\&\&|\|\|) |
| 4662 | \s*0[xX][0-9]+\s* |
| 4663 | (?:\&\&|\|\|) |
| 4664 | | |
| 4665 | (?:\&\&|\|\|) |
| 4666 | \s*0[xX][0-9]+\s* |
| 4667 | (?:\&\&|\|\||\)|\]) |
| 4668 | )/x) |
| 4669 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4670 | WARN("HEXADECIMAL_BOOLEAN_TEST", |
| 4671 | "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4672 | } |
| 4673 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 4674 | # if and else should not have general statements after it |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4675 | if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { |
| 4676 | my $s = $1; |
| 4677 | $s =~ s/$;//g; # Remove any comments |
| 4678 | if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4679 | ERROR("TRAILING_STATEMENTS", |
| 4680 | "trailing statements should be on next line\n" . $herecurr); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 4681 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4682 | } |
Andy Whitcroft | 3966778 | 2009-01-15 13:51:06 -0800 | [diff] [blame] | 4683 | # if should not continue a brace |
| 4684 | if ($line =~ /}\s*if\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4685 | ERROR("TRAILING_STATEMENTS", |
Rasmus Villemoes | 048b123 | 2014-08-06 16:10:37 -0700 | [diff] [blame] | 4686 | "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] | 4687 | $herecurr); |
| 4688 | } |
Andy Whitcroft | a1080bf | 2008-10-15 22:02:25 -0700 | [diff] [blame] | 4689 | # case and default should not have general statements after them |
| 4690 | if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && |
| 4691 | $line !~ /\G(?: |
Andy Whitcroft | 3fef12d | 2008-10-15 22:02:36 -0700 | [diff] [blame] | 4692 | (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| |
Andy Whitcroft | a1080bf | 2008-10-15 22:02:25 -0700 | [diff] [blame] | 4693 | \s*return\s+ |
| 4694 | )/xg) |
| 4695 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4696 | ERROR("TRAILING_STATEMENTS", |
| 4697 | "trailing statements should be on next line\n" . $herecurr); |
Andy Whitcroft | a1080bf | 2008-10-15 22:02:25 -0700 | [diff] [blame] | 4698 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4699 | |
| 4700 | # Check for }<nl>else {, these must be at the same |
| 4701 | # indent level to be relevant to each other. |
Joe Perches | 8b8856f | 2014-08-06 16:11:14 -0700 | [diff] [blame] | 4702 | if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && |
| 4703 | $previndent == $indent) { |
| 4704 | if (ERROR("ELSE_AFTER_BRACE", |
| 4705 | "else should follow close brace '}'\n" . $hereprev) && |
| 4706 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { |
| 4707 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 4708 | fix_delete_line($fixlinenr, $rawline); |
| 4709 | my $fixedline = $prevrawline; |
| 4710 | $fixedline =~ s/}\s*$//; |
| 4711 | if ($fixedline !~ /^\+\s*$/) { |
| 4712 | fix_insert_line($fixlinenr, $fixedline); |
| 4713 | } |
| 4714 | $fixedline = $rawline; |
| 4715 | $fixedline =~ s/^(.\s*)else/$1} else/; |
| 4716 | fix_insert_line($fixlinenr, $fixedline); |
| 4717 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4718 | } |
| 4719 | |
Joe Perches | 8b8856f | 2014-08-06 16:11:14 -0700 | [diff] [blame] | 4720 | if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && |
| 4721 | $previndent == $indent) { |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4722 | my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); |
| 4723 | |
| 4724 | # Find out what is on the end of the line after the |
| 4725 | # conditional. |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 4726 | substr($s, 0, length($c), ''); |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4727 | $s =~ s/\n.*//g; |
| 4728 | |
| 4729 | if ($s =~ /^\s*;/) { |
Joe Perches | 8b8856f | 2014-08-06 16:11:14 -0700 | [diff] [blame] | 4730 | if (ERROR("WHILE_AFTER_BRACE", |
| 4731 | "while should follow close brace '}'\n" . $hereprev) && |
| 4732 | $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { |
| 4733 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 4734 | fix_delete_line($fixlinenr, $rawline); |
| 4735 | my $fixedline = $prevrawline; |
| 4736 | my $trailing = $rawline; |
| 4737 | $trailing =~ s/^\+//; |
| 4738 | $trailing = trim($trailing); |
| 4739 | $fixedline =~ s/}\s*$/} $trailing/; |
| 4740 | fix_insert_line($fixlinenr, $fixedline); |
| 4741 | } |
Andy Whitcroft | c2fdda0 | 2008-02-08 04:20:54 -0800 | [diff] [blame] | 4742 | } |
| 4743 | } |
| 4744 | |
Joe Perches | 95e2c60 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 4745 | #Specific variable tests |
Joe Perches | 323c126 | 2012-12-17 16:02:07 -0800 | [diff] [blame] | 4746 | while ($line =~ m{($Constant|$Lval)}g) { |
| 4747 | my $var = $1; |
Joe Perches | 95e2c60 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 4748 | |
| 4749 | #gcc binary extension |
| 4750 | if ($var =~ /^$Binary$/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4751 | if (WARN("GCC_BINARY_CONSTANT", |
| 4752 | "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && |
| 4753 | $fix) { |
| 4754 | my $hexval = sprintf("0x%x", oct($var)); |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4755 | $fixed[$fixlinenr] =~ |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4756 | s/\b$var\b/$hexval/; |
| 4757 | } |
Joe Perches | 95e2c60 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 4758 | } |
| 4759 | |
| 4760 | #CamelCase |
Joe Perches | 807bd26 | 2013-07-03 15:05:22 -0700 | [diff] [blame] | 4761 | if ($var !~ /^$Constant$/ && |
Joe Perches | be79794 | 2013-07-03 15:05:20 -0700 | [diff] [blame] | 4762 | $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && |
Joe Perches | 22735ce | 2013-07-03 15:05:33 -0700 | [diff] [blame] | 4763 | #Ignore Page<foo> variants |
Joe Perches | 807bd26 | 2013-07-03 15:05:22 -0700 | [diff] [blame] | 4764 | $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && |
Joe Perches | 22735ce | 2013-07-03 15:05:33 -0700 | [diff] [blame] | 4765 | #Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) |
Julius Werner | f512357 | 2014-12-10 15:51:54 -0800 | [diff] [blame] | 4766 | $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && |
| 4767 | #Ignore some three character SI units explicitly, like MiB and KHz |
| 4768 | $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { |
Joe Perches | 7e781f6 | 2013-09-11 14:23:55 -0700 | [diff] [blame] | 4769 | while ($var =~ m{($Ident)}g) { |
| 4770 | my $word = $1; |
| 4771 | next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); |
Joe Perches | d8b0771 | 2013-11-12 15:10:06 -0800 | [diff] [blame] | 4772 | if ($check) { |
| 4773 | seed_camelcase_includes(); |
| 4774 | if (!$file && !$camelcase_file_seeded) { |
| 4775 | seed_camelcase_file($realfile); |
| 4776 | $camelcase_file_seeded = 1; |
| 4777 | } |
| 4778 | } |
Joe Perches | 7e781f6 | 2013-09-11 14:23:55 -0700 | [diff] [blame] | 4779 | if (!defined $camelcase{$word}) { |
| 4780 | $camelcase{$word} = 1; |
| 4781 | CHK("CAMELCASE", |
| 4782 | "Avoid CamelCase: <$word>\n" . $herecurr); |
| 4783 | } |
Joe Perches | 3445686 | 2013-07-03 15:05:34 -0700 | [diff] [blame] | 4784 | } |
Joe Perches | 323c126 | 2012-12-17 16:02:07 -0800 | [diff] [blame] | 4785 | } |
| 4786 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4787 | |
| 4788 | #no spaces allowed after \ in define |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4789 | if ($line =~ /\#\s*define.*\\\s+$/) { |
| 4790 | if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", |
| 4791 | "Whitespace after \\ makes next lines useless\n" . $herecurr) && |
| 4792 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 4793 | $fixed[$fixlinenr] =~ s/\s+$//; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 4794 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4795 | } |
| 4796 | |
Fabian Frederick | 0e212e0 | 2015-04-16 12:44:25 -0700 | [diff] [blame] | 4797 | # warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes |
| 4798 | # itself <asm/foo.h> (uses RAW line) |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4799 | if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { |
Andy Whitcroft | e09dec4 | 2008-10-15 22:02:20 -0700 | [diff] [blame] | 4800 | my $file = "$1.h"; |
| 4801 | my $checkfile = "include/linux/$file"; |
| 4802 | if (-f "$root/$checkfile" && |
| 4803 | $realfile ne $checkfile && |
Wolfram Sang | 7840a94 | 2010-08-09 17:20:57 -0700 | [diff] [blame] | 4804 | $1 !~ /$allowed_asm_includes/) |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4805 | { |
Fabian Frederick | 0e212e0 | 2015-04-16 12:44:25 -0700 | [diff] [blame] | 4806 | my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; |
| 4807 | if ($asminclude > 0) { |
| 4808 | if ($realfile =~ m{^arch/}) { |
| 4809 | CHK("ARCH_INCLUDE_LINUX", |
| 4810 | "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); |
| 4811 | } else { |
| 4812 | WARN("INCLUDE_LINUX", |
| 4813 | "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); |
| 4814 | } |
Andy Whitcroft | e09dec4 | 2008-10-15 22:02:20 -0700 | [diff] [blame] | 4815 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4816 | } |
| 4817 | } |
| 4818 | |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4819 | # multi-statement macros should be enclosed in a do while loop, grab the |
| 4820 | # first statement and ensure its the whole macro if its not enclosed |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 4821 | # in a known good container |
Andy Whitcroft | b8f96a3 | 2008-07-23 21:29:07 -0700 | [diff] [blame] | 4822 | if ($realfile !~ m@/vmlinux.lds.h$@ && |
| 4823 | $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 4824 | my $ln = $linenr; |
| 4825 | my $cnt = $realcnt; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4826 | my ($off, $dstat, $dcond, $rest); |
| 4827 | my $ctx = ''; |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 4828 | my $has_flow_statement = 0; |
| 4829 | my $has_arg_concat = 0; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4830 | ($dstat, $dcond, $ln, $cnt, $off) = |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 4831 | ctx_statement_block($linenr, $realcnt, 0); |
| 4832 | $ctx = $dstat; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4833 | #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; |
Andy Whitcroft | a3bb97a | 2008-07-23 21:29:00 -0700 | [diff] [blame] | 4834 | #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4835 | |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 4836 | $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); |
Joe Perches | 62e15a6 | 2016-01-20 14:59:18 -0800 | [diff] [blame] | 4837 | $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 4838 | |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 4839 | $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; |
| 4840 | my $define_args = $1; |
| 4841 | my $define_stmt = $dstat; |
| 4842 | my @def_args = (); |
| 4843 | |
| 4844 | if (defined $define_args && $define_args ne "") { |
| 4845 | $define_args = substr($define_args, 1, length($define_args) - 2); |
| 4846 | $define_args =~ s/\s*//g; |
| 4847 | @def_args = split(",", $define_args); |
| 4848 | } |
| 4849 | |
Andy Whitcroft | 292f1a9 | 2008-07-23 21:29:11 -0700 | [diff] [blame] | 4850 | $dstat =~ s/$;//g; |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4851 | $dstat =~ s/\\\n.//g; |
| 4852 | $dstat =~ s/^\s*//s; |
| 4853 | $dstat =~ s/\s*$//s; |
| 4854 | |
| 4855 | # Flatten any parentheses and braces |
Andy Whitcroft | bf30d6e | 2008-10-15 22:02:33 -0700 | [diff] [blame] | 4856 | while ($dstat =~ s/\([^\(\)]*\)/1/ || |
| 4857 | $dstat =~ s/\{[^\{\}]*\}/1/ || |
Vladimir Zapolskiy | 6b10df4 | 2016-01-20 14:59:21 -0800 | [diff] [blame] | 4858 | $dstat =~ s/.\[[^\[\]]*\]/1/) |
Andy Whitcroft | bf30d6e | 2008-10-15 22:02:33 -0700 | [diff] [blame] | 4859 | { |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 4860 | } |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 4861 | |
Andy Whitcroft | e45bab8 | 2012-03-23 15:02:18 -0700 | [diff] [blame] | 4862 | # Flatten any obvious string concatentation. |
Joe Perches | 33acb54 | 2015-06-25 15:02:54 -0700 | [diff] [blame] | 4863 | while ($dstat =~ s/($String)\s*$Ident/$1/ || |
| 4864 | $dstat =~ s/$Ident\s*($String)/$1/) |
Andy Whitcroft | e45bab8 | 2012-03-23 15:02:18 -0700 | [diff] [blame] | 4865 | { |
| 4866 | } |
| 4867 | |
Joe Perches | 42e1529 | 2016-03-15 14:58:01 -0700 | [diff] [blame] | 4868 | # Make asm volatile uses seem like a generic function |
| 4869 | $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; |
| 4870 | |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4871 | my $exceptions = qr{ |
| 4872 | $Declare| |
| 4873 | module_param_named| |
Kees Cook | a0a0a7a | 2012-10-04 17:13:38 -0700 | [diff] [blame] | 4874 | MODULE_PARM_DESC| |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4875 | DECLARE_PER_CPU| |
| 4876 | DEFINE_PER_CPU| |
Andy Whitcroft | 383099f | 2009-01-06 14:41:18 -0800 | [diff] [blame] | 4877 | __typeof__\(| |
Stefani Seibold | 22fd2d3 | 2010-03-05 13:43:52 -0800 | [diff] [blame] | 4878 | union| |
| 4879 | struct| |
Andy Whitcroft | ea71a0a | 2009-09-21 17:04:38 -0700 | [diff] [blame] | 4880 | \.$Ident\s*=\s*| |
Vladimir Zapolskiy | 6b10df4 | 2016-01-20 14:59:21 -0800 | [diff] [blame] | 4881 | ^\"|\"$| |
| 4882 | ^\[ |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 4883 | }x; |
Andy Whitcroft | 5eaa20b | 2010-10-26 14:23:18 -0700 | [diff] [blame] | 4884 | #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 4885 | |
| 4886 | $ctx =~ s/\n*$//; |
| 4887 | my $herectx = $here . "\n"; |
| 4888 | my $stmt_cnt = statement_rawlines($ctx); |
| 4889 | |
| 4890 | for (my $n = 0; $n < $stmt_cnt; $n++) { |
| 4891 | $herectx .= raw_line($linenr, $n) . "\n"; |
| 4892 | } |
| 4893 | |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 4894 | if ($dstat ne '' && |
| 4895 | $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), |
| 4896 | $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); |
Joe Perches | 3cc4b1c | 2013-07-03 15:05:27 -0700 | [diff] [blame] | 4897 | $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] | 4898 | $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 4899 | $dstat !~ /$exceptions/ && |
| 4900 | $dstat !~ /^\.$Ident\s*=/ && # .foo = |
Joe Perches | e942e2c | 2013-04-17 15:58:26 -0700 | [diff] [blame] | 4901 | $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo |
Andy Whitcroft | 72f115f | 2012-01-10 15:10:06 -0800 | [diff] [blame] | 4902 | $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 4903 | $dstat !~ /^for\s*$Constant$/ && # for (...) |
| 4904 | $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() |
| 4905 | $dstat !~ /^do\s*{/ && # do {... |
Eddie Kovsky | 4e5d56b | 2015-09-09 15:37:52 -0700 | [diff] [blame] | 4906 | $dstat !~ /^\(\{/ && # ({... |
Joe Perches | f95a7e6 | 2013-09-11 14:24:00 -0700 | [diff] [blame] | 4907 | $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 4908 | { |
Joe Perches | e795556 | 2017-05-08 15:55:48 -0700 | [diff] [blame] | 4909 | if ($dstat =~ /^\s*if\b/) { |
| 4910 | ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", |
| 4911 | "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); |
| 4912 | } elsif ($dstat =~ /;/) { |
Andy Whitcroft | f74bd19 | 2012-01-10 15:09:54 -0800 | [diff] [blame] | 4913 | ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", |
| 4914 | "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); |
| 4915 | } else { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 4916 | ERROR("COMPLEX_MACRO", |
Andrew Morton | 388982b | 2014-10-13 15:51:40 -0700 | [diff] [blame] | 4917 | "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); |
Andy Whitcroft | d8aaf12 | 2007-06-23 17:16:44 -0700 | [diff] [blame] | 4918 | } |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 4919 | |
| 4920 | } |
Joe Perches | 5207649 | 2016-10-11 13:52:14 -0700 | [diff] [blame] | 4921 | |
| 4922 | # Make $define_stmt single line, comment-free, etc |
| 4923 | my @stmt_array = split('\n', $define_stmt); |
| 4924 | my $first = 1; |
| 4925 | $define_stmt = ""; |
| 4926 | foreach my $l (@stmt_array) { |
| 4927 | $l =~ s/\\$//; |
| 4928 | if ($first) { |
| 4929 | $define_stmt = $l; |
| 4930 | $first = 0; |
| 4931 | } elsif ($l =~ /^[\+ ]/) { |
| 4932 | $define_stmt .= substr($l, 1); |
| 4933 | } |
| 4934 | } |
| 4935 | $define_stmt =~ s/$;//g; |
| 4936 | $define_stmt =~ s/\s+/ /g; |
| 4937 | $define_stmt = trim($define_stmt); |
| 4938 | |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 4939 | # check if any macro arguments are reused (ignore '...' and 'type') |
| 4940 | foreach my $arg (@def_args) { |
| 4941 | next if ($arg =~ /\.\.\./); |
Joe Perches | 9192d41 | 2016-10-11 13:52:11 -0700 | [diff] [blame] | 4942 | next if ($arg =~ /^type$/i); |
Joe Perches | 7fe528a2 | 2017-07-10 15:52:27 -0700 | [diff] [blame] | 4943 | my $tmp_stmt = $define_stmt; |
| 4944 | $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; |
| 4945 | $tmp_stmt =~ s/\#+\s*$arg\b//g; |
| 4946 | $tmp_stmt =~ s/\b$arg\s*\#\#//g; |
| 4947 | my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g; |
Joe Perches | f59b64b | 2016-10-11 13:52:08 -0700 | [diff] [blame] | 4948 | if ($use_cnt > 1) { |
| 4949 | CHK("MACRO_ARG_REUSE", |
| 4950 | "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); |
Joe Perches | 9192d41 | 2016-10-11 13:52:11 -0700 | [diff] [blame] | 4951 | } |
| 4952 | # check if any macro arguments may have other precedence issues |
Joe Perches | 7fe528a2 | 2017-07-10 15:52:27 -0700 | [diff] [blame] | 4953 | if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && |
Joe Perches | 9192d41 | 2016-10-11 13:52:11 -0700 | [diff] [blame] | 4954 | ((defined($1) && $1 ne ',') || |
| 4955 | (defined($2) && $2 ne ','))) { |
| 4956 | CHK("MACRO_ARG_PRECEDENCE", |
| 4957 | "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] | 4958 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 4959 | } |
Joe Perches | 5023d34 | 2012-12-17 16:01:47 -0800 | [diff] [blame] | 4960 | |
Joe Perches | 08a2843 | 2014-10-13 15:51:55 -0700 | [diff] [blame] | 4961 | # check for macros with flow control, but without ## concatenation |
| 4962 | # ## concatenation is commonly a macro that defines a function so ignore those |
| 4963 | if ($has_flow_statement && !$has_arg_concat) { |
| 4964 | my $herectx = $here . "\n"; |
| 4965 | my $cnt = statement_rawlines($ctx); |
| 4966 | |
| 4967 | for (my $n = 0; $n < $cnt; $n++) { |
| 4968 | $herectx .= raw_line($linenr, $n) . "\n"; |
| 4969 | } |
| 4970 | WARN("MACRO_WITH_FLOW_CONTROL", |
| 4971 | "Macros with flow control statements should be avoided\n" . "$herectx"); |
| 4972 | } |
| 4973 | |
Joe Perches | 481eb48 | 2012-12-17 16:01:56 -0800 | [diff] [blame] | 4974 | # check for line continuations outside of #defines, preprocessor #, and asm |
Joe Perches | 5023d34 | 2012-12-17 16:01:47 -0800 | [diff] [blame] | 4975 | |
| 4976 | } else { |
| 4977 | if ($prevline !~ /^..*\\$/ && |
Joe Perches | 481eb48 | 2012-12-17 16:01:56 -0800 | [diff] [blame] | 4978 | $line !~ /^\+\s*\#.*\\$/ && # preprocessor |
| 4979 | $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm |
Joe Perches | 5023d34 | 2012-12-17 16:01:47 -0800 | [diff] [blame] | 4980 | $line =~ /^\+.*\\$/) { |
| 4981 | WARN("LINE_CONTINUATIONS", |
| 4982 | "Avoid unnecessary line continuations\n" . $herecurr); |
| 4983 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 4984 | } |
| 4985 | |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 4986 | # do {} while (0) macro tests: |
| 4987 | # single-statement macros do not need to be enclosed in do while (0) loop, |
| 4988 | # macro should not end with a semicolon |
| 4989 | if ($^V && $^V ge 5.10.0 && |
| 4990 | $realfile !~ m@/vmlinux.lds.h$@ && |
| 4991 | $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { |
| 4992 | my $ln = $linenr; |
| 4993 | my $cnt = $realcnt; |
| 4994 | my ($off, $dstat, $dcond, $rest); |
| 4995 | my $ctx = ''; |
| 4996 | ($dstat, $dcond, $ln, $cnt, $off) = |
| 4997 | ctx_statement_block($linenr, $realcnt, 0); |
| 4998 | $ctx = $dstat; |
| 4999 | |
| 5000 | $dstat =~ s/\\\n.//g; |
Joe Perches | 1b36b20 | 2015-02-13 14:38:32 -0800 | [diff] [blame] | 5001 | $dstat =~ s/$;/ /g; |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5002 | |
| 5003 | if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { |
| 5004 | my $stmts = $2; |
| 5005 | my $semis = $3; |
| 5006 | |
| 5007 | $ctx =~ s/\n*$//; |
| 5008 | my $cnt = statement_rawlines($ctx); |
| 5009 | my $herectx = $here . "\n"; |
| 5010 | |
| 5011 | for (my $n = 0; $n < $cnt; $n++) { |
| 5012 | $herectx .= raw_line($linenr, $n) . "\n"; |
| 5013 | } |
| 5014 | |
Joe Perches | ac8e97f | 2012-08-21 16:15:53 -0700 | [diff] [blame] | 5015 | if (($stmts =~ tr/;/;/) == 1 && |
| 5016 | $stmts !~ /^\s*(if|while|for|switch)\b/) { |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5017 | WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", |
| 5018 | "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); |
| 5019 | } |
| 5020 | if (defined $semis && $semis ne "") { |
| 5021 | WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", |
| 5022 | "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); |
| 5023 | } |
Joe Perches | f5ef95b | 2014-06-04 16:12:06 -0700 | [diff] [blame] | 5024 | } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { |
| 5025 | $ctx =~ s/\n*$//; |
| 5026 | my $cnt = statement_rawlines($ctx); |
| 5027 | my $herectx = $here . "\n"; |
| 5028 | |
| 5029 | for (my $n = 0; $n < $cnt; $n++) { |
| 5030 | $herectx .= raw_line($linenr, $n) . "\n"; |
| 5031 | } |
| 5032 | |
| 5033 | WARN("TRAILING_SEMICOLON", |
| 5034 | "macros should not use a trailing semicolon\n" . "$herectx"); |
Joe Perches | b13edf7 | 2012-07-30 14:41:24 -0700 | [diff] [blame] | 5035 | } |
| 5036 | } |
| 5037 | |
Mike Frysinger | 080ba92 | 2009-01-06 14:41:25 -0800 | [diff] [blame] | 5038 | # make sure symbols are always wrapped with VMLINUX_SYMBOL() ... |
| 5039 | # all assignments may have only one of the following with an assignment: |
| 5040 | # . |
| 5041 | # ALIGN(...) |
| 5042 | # VMLINUX_SYMBOL(...) |
| 5043 | if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5044 | WARN("MISSING_VMLINUX_SYMBOL", |
| 5045 | "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); |
Mike Frysinger | 080ba92 | 2009-01-06 14:41:25 -0800 | [diff] [blame] | 5046 | } |
| 5047 | |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5048 | # check for redundant bracing round if etc |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5049 | if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { |
| 5050 | my ($level, $endln, @chunks) = |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5051 | ctx_statement_full($linenr, $realcnt, 1); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5052 | #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5053 | #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; |
| 5054 | if ($#chunks > 0 && $level == 0) { |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5055 | my @allowed = (); |
| 5056 | my $allow = 0; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5057 | my $seen = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5058 | my $herectx = $here . "\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5059 | my $ln = $linenr - 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5060 | for my $chunk (@chunks) { |
| 5061 | my ($cond, $block) = @{$chunk}; |
| 5062 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5063 | # If the condition carries leading newlines, then count those as offsets. |
| 5064 | my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); |
| 5065 | my $offset = statement_rawlines($whitespace) - 1; |
| 5066 | |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5067 | $allowed[$allow] = 0; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5068 | #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; |
| 5069 | |
| 5070 | # We have looked at and allowed this specific line. |
| 5071 | $suppress_ifbraces{$ln + $offset} = 1; |
| 5072 | |
| 5073 | $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5074 | $ln += statement_rawlines($block) - 1; |
| 5075 | |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5076 | substr($block, 0, length($cond), ''); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5077 | |
| 5078 | $seen++ if ($block =~ /^\s*{/); |
| 5079 | |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5080 | #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5081 | if (statement_lines($cond) > 1) { |
| 5082 | #print "APW: ALLOWED: cond<$cond>\n"; |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5083 | $allowed[$allow] = 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5084 | } |
| 5085 | if ($block =~/\b(?:if|for|while)\b/) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5086 | #print "APW: ALLOWED: block<$block>\n"; |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5087 | $allowed[$allow] = 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5088 | } |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5089 | if (statement_block_size($block) > 1) { |
| 5090 | #print "APW: ALLOWED: lines block<$block>\n"; |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5091 | $allowed[$allow] = 1; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5092 | } |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5093 | $allow++; |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5094 | } |
Joe Perches | aad4f61 | 2012-03-23 15:02:19 -0700 | [diff] [blame] | 5095 | if ($seen) { |
| 5096 | my $sum_allowed = 0; |
| 5097 | foreach (@allowed) { |
| 5098 | $sum_allowed += $_; |
| 5099 | } |
| 5100 | if ($sum_allowed == 0) { |
| 5101 | WARN("BRACES", |
| 5102 | "braces {} are not necessary for any arm of this statement\n" . $herectx); |
| 5103 | } elsif ($sum_allowed != $allow && |
| 5104 | $seen != $allow) { |
| 5105 | CHK("BRACES", |
| 5106 | "braces {} should be used on all arms of this statement\n" . $herectx); |
| 5107 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5108 | } |
| 5109 | } |
| 5110 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5111 | if (!defined $suppress_ifbraces{$linenr - 1} && |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5112 | $line =~ /\b(if|while|for|else)\b/) { |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5113 | my $allowed = 0; |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5114 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5115 | # Check the pre-context. |
| 5116 | if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { |
| 5117 | #print "APW: ALLOWED: pre<$1>\n"; |
| 5118 | $allowed = 1; |
| 5119 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5120 | |
| 5121 | my ($level, $endln, @chunks) = |
| 5122 | ctx_statement_full($linenr, $realcnt, $-[0]); |
| 5123 | |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5124 | # Check the condition. |
| 5125 | my ($cond, $block) = @{$chunks[0]}; |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5126 | #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5127 | if (defined $cond) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5128 | substr($block, 0, length($cond), ''); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5129 | } |
| 5130 | if (statement_lines($cond) > 1) { |
| 5131 | #print "APW: ALLOWED: cond<$cond>\n"; |
| 5132 | $allowed = 1; |
| 5133 | } |
| 5134 | if ($block =~/\b(?:if|for|while)\b/) { |
| 5135 | #print "APW: ALLOWED: block<$block>\n"; |
| 5136 | $allowed = 1; |
| 5137 | } |
| 5138 | if (statement_block_size($block) > 1) { |
| 5139 | #print "APW: ALLOWED: lines block<$block>\n"; |
| 5140 | $allowed = 1; |
| 5141 | } |
| 5142 | # Check the post-context. |
| 5143 | if (defined $chunks[1]) { |
| 5144 | my ($cond, $block) = @{$chunks[1]}; |
| 5145 | if (defined $cond) { |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 5146 | substr($block, 0, length($cond), ''); |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5147 | } |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5148 | if ($block =~ /^\s*\{/) { |
| 5149 | #print "APW: ALLOWED: chunk-1 block<$block>\n"; |
| 5150 | $allowed = 1; |
| 5151 | } |
| 5152 | } |
| 5153 | if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { |
Justin P. Mattock | 6993248 | 2011-07-26 23:06:29 -0700 | [diff] [blame] | 5154 | my $herectx = $here . "\n"; |
Andy Whitcroft | f055663 | 2008-10-15 22:02:23 -0700 | [diff] [blame] | 5155 | my $cnt = statement_rawlines($block); |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5156 | |
Andy Whitcroft | f055663 | 2008-10-15 22:02:23 -0700 | [diff] [blame] | 5157 | for (my $n = 0; $n < $cnt; $n++) { |
Justin P. Mattock | 6993248 | 2011-07-26 23:06:29 -0700 | [diff] [blame] | 5158 | $herectx .= raw_line($linenr, $n) . "\n"; |
Andy Whitcroft | cf65504 | 2008-03-04 14:28:20 -0800 | [diff] [blame] | 5159 | } |
| 5160 | |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5161 | WARN("BRACES", |
| 5162 | "braces {} are not necessary for single statement blocks\n" . $herectx); |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5163 | } |
| 5164 | } |
| 5165 | |
Joe Perches | e4c5bab | 2017-02-24 15:01:41 -0800 | [diff] [blame] | 5166 | # check for single line unbalanced braces |
Sven Eckelmann | 9533047 | 2017-02-24 15:01:43 -0800 | [diff] [blame] | 5167 | if ($sline =~ /^.\s*\}\s*else\s*$/ || |
| 5168 | $sline =~ /^.\s*else\s*\{\s*$/) { |
Joe Perches | e4c5bab | 2017-02-24 15:01:41 -0800 | [diff] [blame] | 5169 | CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); |
| 5170 | } |
| 5171 | |
Joe Perches | 0979ae6 | 2012-12-17 16:01:59 -0800 | [diff] [blame] | 5172 | # check for unnecessary blank lines around braces |
Joe Perches | 77b9a53 | 2013-07-03 15:05:29 -0700 | [diff] [blame] | 5173 | if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { |
Joe Perches | f8e5821 | 2015-02-13 14:38:46 -0800 | [diff] [blame] | 5174 | if (CHK("BRACES", |
| 5175 | "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && |
| 5176 | $fix && $prevrawline =~ /^\+/) { |
| 5177 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 5178 | } |
Joe Perches | 0979ae6 | 2012-12-17 16:01:59 -0800 | [diff] [blame] | 5179 | } |
Joe Perches | 77b9a53 | 2013-07-03 15:05:29 -0700 | [diff] [blame] | 5180 | if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { |
Joe Perches | f8e5821 | 2015-02-13 14:38:46 -0800 | [diff] [blame] | 5181 | if (CHK("BRACES", |
| 5182 | "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && |
| 5183 | $fix) { |
| 5184 | fix_delete_line($fixlinenr, $rawline); |
| 5185 | } |
Joe Perches | 0979ae6 | 2012-12-17 16:01:59 -0800 | [diff] [blame] | 5186 | } |
| 5187 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5188 | # no volatiles please |
Andy Whitcroft | 6c72ffa | 2007-10-18 03:05:08 -0700 | [diff] [blame] | 5189 | my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; |
| 5190 | if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5191 | WARN("VOLATILE", |
Mauro Carvalho Chehab | 8c27ceff3 | 2016-10-18 10:12:27 -0200 | [diff] [blame] | 5192 | "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] | 5193 | } |
| 5194 | |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 5195 | # Check for user-visible strings broken across lines, which breaks the ability |
| 5196 | # to grep for the string. Make exceptions when the previous string ends in a |
| 5197 | # newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' |
| 5198 | # (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] | 5199 | if ($line =~ /^\+\s*$String/ && |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 5200 | $prevline =~ /"\s*$/ && |
| 5201 | $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { |
| 5202 | if (WARN("SPLIT_STRING", |
| 5203 | "quoted string split across lines\n" . $hereprev) && |
| 5204 | $fix && |
| 5205 | $prevrawline =~ /^\+.*"\s*$/ && |
| 5206 | $last_coalesced_string_linenr != $linenr - 1) { |
| 5207 | my $extracted_string = get_quoted_string($line, $rawline); |
| 5208 | my $comma_close = ""; |
| 5209 | if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { |
| 5210 | $comma_close = $1; |
| 5211 | } |
| 5212 | |
| 5213 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 5214 | fix_delete_line($fixlinenr, $rawline); |
| 5215 | my $fixedline = $prevrawline; |
| 5216 | $fixedline =~ s/"\s*$//; |
| 5217 | $fixedline .= substr($extracted_string, 1) . trim($comma_close); |
| 5218 | fix_insert_line($fixlinenr - 1, $fixedline); |
| 5219 | $fixedline = $rawline; |
| 5220 | $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; |
| 5221 | if ($fixedline !~ /\+\s*$/) { |
| 5222 | fix_insert_line($fixlinenr, $fixedline); |
| 5223 | } |
| 5224 | $last_coalesced_string_linenr = $linenr; |
| 5225 | } |
| 5226 | } |
| 5227 | |
| 5228 | # check for missing a space in a string concatenation |
| 5229 | if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { |
| 5230 | WARN('MISSING_SPACE', |
| 5231 | "break quoted strings at a space character\n" . $hereprev); |
| 5232 | } |
| 5233 | |
Joe Perches | e4b7d30 | 2017-05-08 15:55:51 -0700 | [diff] [blame] | 5234 | # check for an embedded function name in a string when the function is known |
| 5235 | # This does not work very well for -f --file checking as it depends on patch |
| 5236 | # context providing the function name or a single line form for in-file |
| 5237 | # function declarations |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 5238 | if ($line =~ /^\+.*$String/ && |
| 5239 | defined($context_function) && |
Joe Perches | e4b7d30 | 2017-05-08 15:55:51 -0700 | [diff] [blame] | 5240 | get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && |
| 5241 | length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { |
Joe Perches | 77cb854 | 2017-02-24 15:01:28 -0800 | [diff] [blame] | 5242 | WARN("EMBEDDED_FUNCTION_NAME", |
Joe Perches | e4b7d30 | 2017-05-08 15:55:51 -0700 | [diff] [blame] | 5243 | "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] | 5244 | } |
| 5245 | |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 5246 | # check for spaces before a quoted newline |
| 5247 | if ($rawline =~ /^.*\".*\s\\n/) { |
| 5248 | if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", |
| 5249 | "unnecessary whitespace before a quoted newline\n" . $herecurr) && |
| 5250 | $fix) { |
| 5251 | $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; |
| 5252 | } |
| 5253 | |
| 5254 | } |
| 5255 | |
Joe Perches | f17dba4 | 2014-10-13 15:51:51 -0700 | [diff] [blame] | 5256 | # concatenated string without spaces between elements |
Joe Perches | 33acb54 | 2015-06-25 15:02:54 -0700 | [diff] [blame] | 5257 | if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { |
Joe Perches | f17dba4 | 2014-10-13 15:51:51 -0700 | [diff] [blame] | 5258 | CHK("CONCATENATED_STRING", |
| 5259 | "Concatenated strings should use spaces between elements\n" . $herecurr); |
| 5260 | } |
| 5261 | |
Joe Perches | 90ad30e | 2014-12-10 15:51:59 -0800 | [diff] [blame] | 5262 | # uncoalesced string fragments |
Joe Perches | 33acb54 | 2015-06-25 15:02:54 -0700 | [diff] [blame] | 5263 | if ($line =~ /$String\s*"/) { |
Joe Perches | 90ad30e | 2014-12-10 15:51:59 -0800 | [diff] [blame] | 5264 | WARN("STRING_FRAGMENTS", |
| 5265 | "Consecutive strings are generally better as a single string\n" . $herecurr); |
| 5266 | } |
| 5267 | |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 5268 | # check for non-standard and hex prefixed decimal printf formats |
| 5269 | my $show_L = 1; #don't show the same defect twice |
| 5270 | my $show_Z = 1; |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 5271 | while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 5272 | my $string = substr($rawline, $-[1], $+[1] - $-[1]); |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 5273 | $string =~ s/%%/__/g; |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 5274 | # check for %L |
| 5275 | if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 5276 | WARN("PRINTF_L", |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 5277 | "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); |
| 5278 | $show_L = 0; |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 5279 | } |
Alexey Dobriyan | 522b837 | 2017-02-27 14:30:05 -0800 | [diff] [blame] | 5280 | # check for %Z |
| 5281 | if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { |
| 5282 | WARN("PRINTF_Z", |
| 5283 | "%Z$1 is non-standard C, use %z$1\n" . $herecurr); |
| 5284 | $show_Z = 0; |
| 5285 | } |
| 5286 | # check for 0x<decimal> |
| 5287 | if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { |
| 5288 | ERROR("PRINTF_0XDECIMAL", |
Joe Perches | 6e30075 | 2015-09-09 15:37:47 -0700 | [diff] [blame] | 5289 | "Prefixing 0x with decimal output is defective\n" . $herecurr); |
| 5290 | } |
Joe Perches | 5e4f6ba | 2014-12-10 15:52:05 -0800 | [diff] [blame] | 5291 | } |
| 5292 | |
| 5293 | # check for line continuations in quoted strings with odd counts of " |
| 5294 | if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { |
| 5295 | WARN("LINE_CONTINUATIONS", |
| 5296 | "Avoid line continuations in quoted strings\n" . $herecurr); |
| 5297 | } |
| 5298 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 5299 | # warn about #if 0 |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5300 | if ($line =~ /^.\s*\#\s*if\s+0\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5301 | CHK("REDUNDANT_CODE", |
| 5302 | "if this code is redundant consider removing it\n" . |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5303 | $herecurr); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5304 | } |
| 5305 | |
Andy Whitcroft | 03df4b5 | 2012-12-17 16:01:52 -0800 | [diff] [blame] | 5306 | # check for needless "if (<foo>) fn(<foo>)" uses |
| 5307 | if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { |
Joe Perches | 100425d | 2015-09-09 15:37:36 -0700 | [diff] [blame] | 5308 | my $tested = quotemeta($1); |
| 5309 | my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; |
| 5310 | if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { |
| 5311 | my $func = $1; |
| 5312 | if (WARN('NEEDLESS_IF', |
| 5313 | "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && |
| 5314 | $fix) { |
| 5315 | my $do_fix = 1; |
| 5316 | my $leading_tabs = ""; |
| 5317 | my $new_leading_tabs = ""; |
| 5318 | if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { |
| 5319 | $leading_tabs = $1; |
| 5320 | } else { |
| 5321 | $do_fix = 0; |
| 5322 | } |
| 5323 | if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { |
| 5324 | $new_leading_tabs = $1; |
| 5325 | if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { |
| 5326 | $do_fix = 0; |
| 5327 | } |
| 5328 | } else { |
| 5329 | $do_fix = 0; |
| 5330 | } |
| 5331 | if ($do_fix) { |
| 5332 | fix_delete_line($fixlinenr - 1, $prevrawline); |
| 5333 | $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; |
| 5334 | } |
| 5335 | } |
Greg Kroah-Hartman | 4c432a8 | 2008-07-23 21:29:04 -0700 | [diff] [blame] | 5336 | } |
| 5337 | } |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 5338 | |
Joe Perches | ebfdc40 | 2014-08-06 16:10:27 -0700 | [diff] [blame] | 5339 | # check for unnecessary "Out of Memory" messages |
| 5340 | if ($line =~ /^\+.*\b$logFunctions\s*\(/ && |
| 5341 | $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && |
| 5342 | (defined $1 || defined $3) && |
| 5343 | $linenr > 3) { |
| 5344 | my $testval = $2; |
| 5345 | my $testline = $lines[$linenr - 3]; |
| 5346 | |
| 5347 | my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); |
| 5348 | # print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); |
| 5349 | |
Joe Perches | fb0d0e0 | 2017-07-10 15:52:04 -0700 | [diff] [blame] | 5350 | if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) { |
Joe Perches | ebfdc40 | 2014-08-06 16:10:27 -0700 | [diff] [blame] | 5351 | WARN("OOM_MESSAGE", |
| 5352 | "Possible unnecessary 'out of memory' message\n" . $hereprev); |
| 5353 | } |
| 5354 | } |
| 5355 | |
Joe Perches | f78d98f | 2014-10-13 15:52:01 -0700 | [diff] [blame] | 5356 | # check for logging functions with KERN_<LEVEL> |
Paolo Bonzini | dcaf112 | 2015-02-13 14:38:26 -0800 | [diff] [blame] | 5357 | if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && |
Joe Perches | f78d98f | 2014-10-13 15:52:01 -0700 | [diff] [blame] | 5358 | $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { |
| 5359 | my $level = $1; |
| 5360 | if (WARN("UNNECESSARY_KERN_LEVEL", |
| 5361 | "Possible unnecessary $level\n" . $herecurr) && |
| 5362 | $fix) { |
| 5363 | $fixed[$fixlinenr] =~ s/\s*$level\s*//; |
| 5364 | } |
| 5365 | } |
| 5366 | |
Joe Perches | 45c55e9 | 2017-02-24 15:01:31 -0800 | [diff] [blame] | 5367 | # check for logging continuations |
| 5368 | if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { |
| 5369 | WARN("LOGGING_CONTINUATION", |
| 5370 | "Avoid logging continuation uses where feasible\n" . $herecurr); |
| 5371 | } |
| 5372 | |
Joe Perches | abb08a5 | 2014-12-10 15:51:46 -0800 | [diff] [blame] | 5373 | # check for mask then right shift without a parentheses |
| 5374 | if ($^V && $^V ge 5.10.0 && |
| 5375 | $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && |
| 5376 | $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so |
| 5377 | WARN("MASK_THEN_SHIFT", |
| 5378 | "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); |
| 5379 | } |
| 5380 | |
Joe Perches | b75ac61 | 2014-12-10 15:52:02 -0800 | [diff] [blame] | 5381 | # check for pointer comparisons to NULL |
| 5382 | if ($^V && $^V ge 5.10.0) { |
| 5383 | while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { |
| 5384 | my $val = $1; |
| 5385 | my $equal = "!"; |
| 5386 | $equal = "" if ($4 eq "!="); |
| 5387 | if (CHK("COMPARISON_TO_NULL", |
| 5388 | "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && |
| 5389 | $fix) { |
| 5390 | $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; |
| 5391 | } |
| 5392 | } |
| 5393 | } |
| 5394 | |
Joe Perches | 8716de3 | 2013-09-11 14:24:05 -0700 | [diff] [blame] | 5395 | # check for bad placement of section $InitAttribute (e.g.: __initdata) |
| 5396 | if ($line =~ /(\b$InitAttribute\b)/) { |
| 5397 | my $attr = $1; |
| 5398 | if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { |
| 5399 | my $ptr = $1; |
| 5400 | my $var = $2; |
| 5401 | if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && |
| 5402 | ERROR("MISPLACED_INIT", |
| 5403 | "$attr should be placed after $var\n" . $herecurr)) || |
| 5404 | ($ptr !~ /\b(union|struct)\s+$attr\b/ && |
| 5405 | WARN("MISPLACED_INIT", |
| 5406 | "$attr should be placed after $var\n" . $herecurr))) && |
| 5407 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5408 | $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] | 5409 | } |
| 5410 | } |
| 5411 | } |
| 5412 | |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 5413 | # check for $InitAttributeData (ie: __initdata) with const |
| 5414 | if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { |
| 5415 | my $attr = $1; |
| 5416 | $attr =~ /($InitAttributePrefix)(.*)/; |
| 5417 | my $attr_prefix = $1; |
| 5418 | my $attr_type = $2; |
| 5419 | if (ERROR("INIT_ATTRIBUTE", |
| 5420 | "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && |
| 5421 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5422 | $fixed[$fixlinenr] =~ |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 5423 | s/$InitAttributeData/${attr_prefix}initconst/; |
| 5424 | } |
| 5425 | } |
| 5426 | |
| 5427 | # check for $InitAttributeConst (ie: __initconst) without const |
| 5428 | if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { |
| 5429 | my $attr = $1; |
| 5430 | if (ERROR("INIT_ATTRIBUTE", |
| 5431 | "Use of $attr requires a separate use of const\n" . $herecurr) && |
| 5432 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5433 | my $lead = $fixed[$fixlinenr] =~ |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 5434 | /(^\+\s*(?:static\s+))/; |
| 5435 | $lead = rtrim($1); |
| 5436 | $lead = "$lead " if ($lead !~ /^\+$/); |
| 5437 | $lead = "${lead}const "; |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5438 | $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; |
Joe Perches | e970b884 | 2013-11-12 15:10:10 -0800 | [diff] [blame] | 5439 | } |
| 5440 | } |
| 5441 | |
Joe Perches | c17893c | 2015-04-16 12:44:42 -0700 | [diff] [blame] | 5442 | # check for __read_mostly with const non-pointer (should just be const) |
| 5443 | if ($line =~ /\b__read_mostly\b/ && |
| 5444 | $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { |
| 5445 | if (ERROR("CONST_READ_MOSTLY", |
| 5446 | "Invalid use of __read_mostly with const type\n" . $herecurr) && |
| 5447 | $fix) { |
| 5448 | $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; |
| 5449 | } |
| 5450 | } |
| 5451 | |
Joe Perches | fbdb813 | 2014-04-03 14:49:14 -0700 | [diff] [blame] | 5452 | # don't use __constant_<foo> functions outside of include/uapi/ |
| 5453 | if ($realfile !~ m@^include/uapi/@ && |
| 5454 | $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { |
| 5455 | my $constant_func = $1; |
| 5456 | my $func = $constant_func; |
| 5457 | $func =~ s/^__constant_//; |
| 5458 | if (WARN("CONSTANT_CONVERSION", |
| 5459 | "$constant_func should be $func\n" . $herecurr) && |
| 5460 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5461 | $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; |
Joe Perches | fbdb813 | 2014-04-03 14:49:14 -0700 | [diff] [blame] | 5462 | } |
| 5463 | } |
| 5464 | |
Patrick Pannuto | 1a15a25 | 2010-08-09 17:21:01 -0700 | [diff] [blame] | 5465 | # prefer usleep_range over udelay |
Bruce Allan | 37581c2 | 2013-02-21 16:44:19 -0800 | [diff] [blame] | 5466 | if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { |
Joe Perches | 43c1d77 | 2014-04-03 14:49:11 -0700 | [diff] [blame] | 5467 | my $delay = $1; |
Patrick Pannuto | 1a15a25 | 2010-08-09 17:21:01 -0700 | [diff] [blame] | 5468 | # ignore udelay's < 10, however |
Joe Perches | 43c1d77 | 2014-04-03 14:49:11 -0700 | [diff] [blame] | 5469 | if (! ($delay < 10) ) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5470 | CHK("USLEEP_RANGE", |
Joe Perches | 43c1d77 | 2014-04-03 14:49:11 -0700 | [diff] [blame] | 5471 | "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); |
| 5472 | } |
| 5473 | if ($delay > 2000) { |
| 5474 | WARN("LONG_UDELAY", |
| 5475 | "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] | 5476 | } |
| 5477 | } |
| 5478 | |
Patrick Pannuto | 09ef872 | 2010-08-09 17:21:02 -0700 | [diff] [blame] | 5479 | # warn about unexpectedly long msleep's |
| 5480 | if ($line =~ /\bmsleep\s*\((\d+)\);/) { |
| 5481 | if ($1 < 20) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5482 | WARN("MSLEEP", |
Joe Perches | 43c1d77 | 2014-04-03 14:49:11 -0700 | [diff] [blame] | 5483 | "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); |
Patrick Pannuto | 09ef872 | 2010-08-09 17:21:02 -0700 | [diff] [blame] | 5484 | } |
| 5485 | } |
| 5486 | |
Joe Perches | 36ec193 | 2013-07-03 15:05:25 -0700 | [diff] [blame] | 5487 | # check for comparisons of jiffies |
| 5488 | if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { |
| 5489 | WARN("JIFFIES_COMPARISON", |
| 5490 | "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); |
| 5491 | } |
| 5492 | |
Joe Perches | 9d7a34a | 2013-07-03 15:05:26 -0700 | [diff] [blame] | 5493 | # check for comparisons of get_jiffies_64() |
| 5494 | if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { |
| 5495 | WARN("JIFFIES_COMPARISON", |
| 5496 | "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); |
| 5497 | } |
| 5498 | |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 5499 | # warn about #ifdefs in C files |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5500 | # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { |
Andy Whitcroft | 00df344 | 2007-06-08 13:47:06 -0700 | [diff] [blame] | 5501 | # print "#ifdef in C files should be avoided\n"; |
| 5502 | # print "$herecurr"; |
| 5503 | # $clean = 0; |
| 5504 | # } |
| 5505 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5506 | # warn about spacing in #ifdefs |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5507 | if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5508 | if (ERROR("SPACING", |
| 5509 | "exactly one space required after that #$1\n" . $herecurr) && |
| 5510 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5511 | $fixed[$fixlinenr] =~ |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 5512 | s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; |
| 5513 | } |
| 5514 | |
Andy Whitcroft | 22f2a2e | 2007-08-10 13:01:03 -0700 | [diff] [blame] | 5515 | } |
| 5516 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5517 | # check for spinlock_t definitions without a comment. |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 5518 | if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || |
| 5519 | $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5520 | my $which = $1; |
| 5521 | if (!ctx_has_comment($first_line, $linenr)) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5522 | CHK("UNCOMMENTED_DEFINITION", |
| 5523 | "$1 definition without comment\n" . $herecurr); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5524 | } |
| 5525 | } |
| 5526 | # check for memory barriers without a comment. |
Michael S. Tsirkin | 402c255 | 2016-01-04 09:39:01 +0200 | [diff] [blame] | 5527 | |
| 5528 | my $barriers = qr{ |
| 5529 | mb| |
| 5530 | rmb| |
| 5531 | wmb| |
| 5532 | read_barrier_depends |
| 5533 | }x; |
| 5534 | my $barrier_stems = qr{ |
| 5535 | mb__before_atomic| |
| 5536 | mb__after_atomic| |
| 5537 | store_release| |
| 5538 | load_acquire| |
| 5539 | store_mb| |
| 5540 | (?:$barriers) |
| 5541 | }x; |
| 5542 | my $all_barriers = qr{ |
| 5543 | (?:$barriers)| |
Michael S. Tsirkin | 43e361f | 2016-01-04 10:00:10 +0200 | [diff] [blame] | 5544 | smp_(?:$barrier_stems)| |
| 5545 | virt_(?:$barrier_stems) |
Michael S. Tsirkin | 402c255 | 2016-01-04 09:39:01 +0200 | [diff] [blame] | 5546 | }x; |
| 5547 | |
| 5548 | if ($line =~ /\b(?:$all_barriers)\s*\(/) { |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5549 | if (!ctx_has_comment($first_line, $linenr)) { |
Joe Perches | c1fd7bb | 2013-11-12 15:10:11 -0800 | [diff] [blame] | 5550 | WARN("MEMORY_BARRIER", |
| 5551 | "memory barrier without comment\n" . $herecurr); |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5552 | } |
| 5553 | } |
Paul E. McKenney | 3ad8177 | 2015-07-02 11:55:40 -0700 | [diff] [blame] | 5554 | |
Michael S. Tsirkin | f4073b0 | 2016-01-04 09:54:51 +0200 | [diff] [blame] | 5555 | my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; |
| 5556 | |
| 5557 | if ($realfile !~ m@^include/asm-generic/@ && |
| 5558 | $realfile !~ m@/barrier\.h$@ && |
| 5559 | $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && |
| 5560 | $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { |
| 5561 | WARN("MEMORY_BARRIER", |
| 5562 | "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); |
| 5563 | } |
| 5564 | |
Joe Perches | cb426e9 | 2015-06-25 15:02:46 -0700 | [diff] [blame] | 5565 | # check for waitqueue_active without a comment. |
| 5566 | if ($line =~ /\bwaitqueue_active\s*\(/) { |
| 5567 | if (!ctx_has_comment($first_line, $linenr)) { |
| 5568 | WARN("WAITQUEUE_ACTIVE", |
| 5569 | "waitqueue_active without comment\n" . $herecurr); |
| 5570 | } |
| 5571 | } |
Paul E. McKenney | 3ad8177 | 2015-07-02 11:55:40 -0700 | [diff] [blame] | 5572 | |
Andy Whitcroft | 4a0df2e | 2007-06-08 13:46:39 -0700 | [diff] [blame] | 5573 | # check of hardware specific defines |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5574 | 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] | 5575 | CHK("ARCH_DEFINES", |
| 5576 | "architecture specific defines should be avoided\n" . $herecurr); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 5577 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 5578 | |
Joe Perches | 596ed45 | 2017-07-12 14:37:02 -0700 | [diff] [blame] | 5579 | # check that the storage class is not after a type |
| 5580 | if ($line =~ /\b($Type)\s+($Storage)\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5581 | WARN("STORAGE_CLASS", |
Joe Perches | 596ed45 | 2017-07-12 14:37:02 -0700 | [diff] [blame] | 5582 | "storage class '$2' should be located before type '$1'\n" . $herecurr); |
| 5583 | } |
| 5584 | # Check that the storage class is at the beginning of a declaration |
| 5585 | if ($line =~ /\b$Storage\b/ && |
| 5586 | $line !~ /^.\s*$Storage/ && |
| 5587 | $line =~ /^.\s*(.+?)\$Storage\s/ && |
| 5588 | $1 !~ /[\,\)]\s*$/) { |
| 5589 | WARN("STORAGE_CLASS", |
| 5590 | "storage class should be at the beginning of the declaration\n" . $herecurr); |
Tobias Klauser | d4977c7 | 2010-05-24 14:33:30 -0700 | [diff] [blame] | 5591 | } |
| 5592 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5593 | # check the location of the inline attribute, that it is between |
| 5594 | # storage class and type. |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 5595 | if ($line =~ /\b$Type\s+$Inline\b/ || |
| 5596 | $line =~ /\b$Inline\s+$Storage\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5597 | ERROR("INLINE_LOCATION", |
| 5598 | "inline keyword should sit between storage class and type\n" . $herecurr); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5599 | } |
| 5600 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 5601 | # Check for __inline__ and __inline, prefer inline |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 5602 | if ($realfile !~ m@\binclude/uapi/@ && |
| 5603 | $line =~ /\b(__inline__|__inline)\b/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5604 | if (WARN("INLINE", |
| 5605 | "plain inline is preferred over $1\n" . $herecurr) && |
| 5606 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5607 | $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5608 | |
| 5609 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 5610 | } |
| 5611 | |
Joe Perches | 3d130fd | 2011-01-12 17:00:00 -0800 | [diff] [blame] | 5612 | # Check for __attribute__ packed, prefer __packed |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 5613 | if ($realfile !~ m@\binclude/uapi/@ && |
| 5614 | $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5615 | WARN("PREFER_PACKED", |
| 5616 | "__packed is preferred over __attribute__((packed))\n" . $herecurr); |
Joe Perches | 3d130fd | 2011-01-12 17:00:00 -0800 | [diff] [blame] | 5617 | } |
| 5618 | |
Joe Perches | 39b7e28 | 2011-07-25 17:13:24 -0700 | [diff] [blame] | 5619 | # Check for __attribute__ aligned, prefer __aligned |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 5620 | if ($realfile !~ m@\binclude/uapi/@ && |
| 5621 | $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5622 | WARN("PREFER_ALIGNED", |
| 5623 | "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); |
Joe Perches | 39b7e28 | 2011-07-25 17:13:24 -0700 | [diff] [blame] | 5624 | } |
| 5625 | |
Joe Perches | 5f14d3b | 2012-01-10 15:09:52 -0800 | [diff] [blame] | 5626 | # Check for __attribute__ format(printf, prefer __printf |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 5627 | if ($realfile !~ m@\binclude/uapi/@ && |
| 5628 | $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5629 | if (WARN("PREFER_PRINTF", |
| 5630 | "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && |
| 5631 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5632 | $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5633 | |
| 5634 | } |
Joe Perches | 5f14d3b | 2012-01-10 15:09:52 -0800 | [diff] [blame] | 5635 | } |
| 5636 | |
Joe Perches | 6061d94 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 5637 | # Check for __attribute__ format(scanf, prefer __scanf |
Joe Perches | 2b7ab45 | 2013-11-12 15:10:14 -0800 | [diff] [blame] | 5638 | if ($realfile !~ m@\binclude/uapi/@ && |
| 5639 | $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5640 | if (WARN("PREFER_SCANF", |
| 5641 | "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && |
| 5642 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5643 | $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5644 | } |
Joe Perches | 6061d94 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 5645 | } |
| 5646 | |
Joe Perches | 619a908 | 2014-12-10 15:51:35 -0800 | [diff] [blame] | 5647 | # Check for __attribute__ weak, or __weak declarations (may have link issues) |
| 5648 | if ($^V && $^V ge 5.10.0 && |
| 5649 | $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && |
| 5650 | ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || |
| 5651 | $line =~ /\b__weak\b/)) { |
| 5652 | ERROR("WEAK_DECLARATION", |
| 5653 | "Using weak declarations can have unintended link defects\n" . $herecurr); |
| 5654 | } |
| 5655 | |
Tomas Winkler | fd39f90 | 2016-12-12 16:46:34 -0800 | [diff] [blame] | 5656 | # 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] | 5657 | if ($realfile !~ m@\binclude/uapi/@ && |
Tomas Winkler | fd39f90 | 2016-12-12 16:46:34 -0800 | [diff] [blame] | 5658 | $realfile !~ m@\btools/@ && |
Joe Perches | e6176fa | 2015-06-25 15:02:49 -0700 | [diff] [blame] | 5659 | $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { |
| 5660 | my $type = $1; |
| 5661 | if ($type =~ /\b($typeC99Typedefs)\b/) { |
| 5662 | $type = $1; |
| 5663 | my $kernel_type = 'u'; |
| 5664 | $kernel_type = 's' if ($type =~ /^_*[si]/); |
| 5665 | $type =~ /(\d+)/; |
| 5666 | $kernel_type .= $1; |
| 5667 | if (CHK("PREFER_KERNEL_TYPES", |
| 5668 | "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && |
| 5669 | $fix) { |
| 5670 | $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; |
| 5671 | } |
| 5672 | } |
| 5673 | } |
| 5674 | |
Joe Perches | 938224b | 2016-01-20 14:59:15 -0800 | [diff] [blame] | 5675 | # check for cast of C90 native int or longer types constants |
| 5676 | if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { |
| 5677 | my $cast = $1; |
| 5678 | my $const = $2; |
| 5679 | if (WARN("TYPECAST_INT_CONSTANT", |
| 5680 | "Unnecessary typecast of c90 int constant\n" . $herecurr) && |
| 5681 | $fix) { |
| 5682 | my $suffix = ""; |
| 5683 | my $newconst = $const; |
| 5684 | $newconst =~ s/${Int_type}$//; |
| 5685 | $suffix .= 'U' if ($cast =~ /\bunsigned\b/); |
| 5686 | if ($cast =~ /\blong\s+long\b/) { |
| 5687 | $suffix .= 'LL'; |
| 5688 | } elsif ($cast =~ /\blong\b/) { |
| 5689 | $suffix .= 'L'; |
| 5690 | } |
| 5691 | $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; |
| 5692 | } |
| 5693 | } |
| 5694 | |
Joe Perches | 8f53a9b | 2010-03-05 13:43:48 -0800 | [diff] [blame] | 5695 | # check for sizeof(&) |
| 5696 | if ($line =~ /\bsizeof\s*\(\s*\&/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5697 | WARN("SIZEOF_ADDRESS", |
| 5698 | "sizeof(& should be avoided\n" . $herecurr); |
Joe Perches | 8f53a9b | 2010-03-05 13:43:48 -0800 | [diff] [blame] | 5699 | } |
| 5700 | |
Joe Perches | 66c80b6 | 2012-07-30 14:41:22 -0700 | [diff] [blame] | 5701 | # check for sizeof without parenthesis |
| 5702 | if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5703 | if (WARN("SIZEOF_PARENTHESIS", |
| 5704 | "sizeof $1 should be sizeof($1)\n" . $herecurr) && |
| 5705 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5706 | $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] | 5707 | } |
Joe Perches | 66c80b6 | 2012-07-30 14:41:22 -0700 | [diff] [blame] | 5708 | } |
| 5709 | |
Joe Perches | 88982fe | 2012-12-17 16:02:00 -0800 | [diff] [blame] | 5710 | # check for struct spinlock declarations |
| 5711 | if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { |
| 5712 | WARN("USE_SPINLOCK_T", |
| 5713 | "struct spinlock should be spinlock_t\n" . $herecurr); |
| 5714 | } |
| 5715 | |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 5716 | # check for seq_printf uses that could be seq_puts |
Joe Perches | 0666872 | 2013-11-12 15:10:07 -0800 | [diff] [blame] | 5717 | if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 5718 | my $fmt = get_quoted_string($line, $rawline); |
Heba Aamer | caac1d5 | 2015-02-13 14:38:49 -0800 | [diff] [blame] | 5719 | $fmt =~ s/%%//g; |
| 5720 | if ($fmt !~ /%/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5721 | if (WARN("PREFER_SEQ_PUTS", |
| 5722 | "Prefer seq_puts to seq_printf\n" . $herecurr) && |
| 5723 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5724 | $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 5725 | } |
Joe Perches | a6962d7 | 2013-04-29 16:18:13 -0700 | [diff] [blame] | 5726 | } |
| 5727 | } |
| 5728 | |
Joe Perches | 0b52376 | 2017-05-08 15:55:36 -0700 | [diff] [blame] | 5729 | # check for vsprintf extension %p<foo> misuses |
| 5730 | if ($^V && $^V ge 5.10.0 && |
| 5731 | defined $stat && |
| 5732 | $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && |
| 5733 | $1 !~ /^_*volatile_*$/) { |
| 5734 | my $bad_extension = ""; |
| 5735 | my $lc = $stat =~ tr@\n@@; |
| 5736 | $lc = $lc + $linenr; |
| 5737 | for (my $count = $linenr; $count <= $lc; $count++) { |
| 5738 | my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); |
| 5739 | $fmt =~ s/%%//g; |
Pantelis Antoniou | ce4fecf | 2015-01-21 19:06:14 +0200 | [diff] [blame] | 5740 | if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { |
Joe Perches | 0b52376 | 2017-05-08 15:55:36 -0700 | [diff] [blame] | 5741 | $bad_extension = $1; |
| 5742 | last; |
| 5743 | } |
| 5744 | } |
| 5745 | if ($bad_extension ne "") { |
| 5746 | my $stat_real = raw_line($linenr, 0); |
| 5747 | for (my $count = $linenr + 1; $count <= $lc; $count++) { |
| 5748 | $stat_real = $stat_real . "\n" . raw_line($count, 0); |
| 5749 | } |
| 5750 | WARN("VSPRINTF_POINTER_EXTENSION", |
| 5751 | "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); |
| 5752 | } |
| 5753 | } |
| 5754 | |
Andy Whitcroft | 554e165 | 2012-01-10 15:09:57 -0800 | [diff] [blame] | 5755 | # Check for misused memsets |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 5756 | if ($^V && $^V ge 5.10.0 && |
| 5757 | defined $stat && |
Mateusz Kulikowski | 9e20a85 | 2015-06-25 15:03:16 -0700 | [diff] [blame] | 5758 | $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { |
Andy Whitcroft | 554e165 | 2012-01-10 15:09:57 -0800 | [diff] [blame] | 5759 | |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5760 | my $ms_addr = $2; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 5761 | my $ms_val = $7; |
| 5762 | my $ms_size = $12; |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5763 | |
Andy Whitcroft | 554e165 | 2012-01-10 15:09:57 -0800 | [diff] [blame] | 5764 | if ($ms_size =~ /^(0x|)0$/i) { |
| 5765 | ERROR("MEMSET", |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5766 | "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] | 5767 | } elsif ($ms_size =~ /^(0x|)1$/i) { |
| 5768 | WARN("MEMSET", |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5769 | "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); |
| 5770 | } |
| 5771 | } |
| 5772 | |
Joe Perches | 98a9bba | 2014-01-23 15:54:52 -0800 | [diff] [blame] | 5773 | # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) |
Joe Perches | f333195 | 2016-10-11 13:51:53 -0700 | [diff] [blame] | 5774 | # if ($^V && $^V ge 5.10.0 && |
| 5775 | # defined $stat && |
| 5776 | # $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { |
| 5777 | # if (WARN("PREFER_ETHER_ADDR_COPY", |
| 5778 | # "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && |
| 5779 | # $fix) { |
| 5780 | # $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; |
| 5781 | # } |
| 5782 | # } |
Joe Perches | 98a9bba | 2014-01-23 15:54:52 -0800 | [diff] [blame] | 5783 | |
Mateusz Kulikowski | b6117d1 | 2015-06-25 15:03:13 -0700 | [diff] [blame] | 5784 | # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) |
Joe Perches | f333195 | 2016-10-11 13:51:53 -0700 | [diff] [blame] | 5785 | # if ($^V && $^V ge 5.10.0 && |
| 5786 | # defined $stat && |
| 5787 | # $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { |
| 5788 | # WARN("PREFER_ETHER_ADDR_EQUAL", |
| 5789 | # "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") |
| 5790 | # } |
Mateusz Kulikowski | b6117d1 | 2015-06-25 15:03:13 -0700 | [diff] [blame] | 5791 | |
Mateusz Kulikowski | 8617cd0 | 2015-06-25 15:03:19 -0700 | [diff] [blame] | 5792 | # check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr |
| 5793 | # check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr |
Joe Perches | f333195 | 2016-10-11 13:51:53 -0700 | [diff] [blame] | 5794 | # if ($^V && $^V ge 5.10.0 && |
| 5795 | # defined $stat && |
| 5796 | # $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { |
| 5797 | # |
| 5798 | # my $ms_val = $7; |
| 5799 | # |
| 5800 | # if ($ms_val =~ /^(?:0x|)0+$/i) { |
| 5801 | # if (WARN("PREFER_ETH_ZERO_ADDR", |
| 5802 | # "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && |
| 5803 | # $fix) { |
| 5804 | # $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; |
| 5805 | # } |
| 5806 | # } elsif ($ms_val =~ /^(?:0xff|255)$/i) { |
| 5807 | # if (WARN("PREFER_ETH_BROADCAST_ADDR", |
| 5808 | # "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && |
| 5809 | # $fix) { |
| 5810 | # $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; |
| 5811 | # } |
| 5812 | # } |
| 5813 | # } |
Mateusz Kulikowski | 8617cd0 | 2015-06-25 15:03:19 -0700 | [diff] [blame] | 5814 | |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5815 | # typecasts on min/max could be min_t/max_t |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 5816 | if ($^V && $^V ge 5.10.0 && |
| 5817 | defined $stat && |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5818 | $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 5819 | if (defined $2 || defined $7) { |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5820 | my $call = $1; |
| 5821 | my $cast1 = deparenthesize($2); |
| 5822 | my $arg1 = $3; |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 5823 | my $cast2 = deparenthesize($7); |
| 5824 | my $arg2 = $8; |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5825 | my $cast; |
| 5826 | |
Joe Perches | d1fe9c0 | 2012-03-23 15:02:16 -0700 | [diff] [blame] | 5827 | if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { |
Joe Perches | d7c76ba | 2012-01-10 15:09:58 -0800 | [diff] [blame] | 5828 | $cast = "$cast1 or $cast2"; |
| 5829 | } elsif ($cast1 ne "") { |
| 5830 | $cast = $cast1; |
| 5831 | } else { |
| 5832 | $cast = $cast2; |
| 5833 | } |
| 5834 | WARN("MINMAX", |
| 5835 | "$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] | 5836 | } |
| 5837 | } |
| 5838 | |
Joe Perches | 4a27319 | 2012-07-30 14:41:20 -0700 | [diff] [blame] | 5839 | # check usleep_range arguments |
| 5840 | if ($^V && $^V ge 5.10.0 && |
| 5841 | defined $stat && |
| 5842 | $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { |
| 5843 | my $min = $1; |
| 5844 | my $max = $7; |
| 5845 | if ($min eq $max) { |
| 5846 | WARN("USLEEP_RANGE", |
| 5847 | "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); |
| 5848 | } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && |
| 5849 | $min > $max) { |
| 5850 | WARN("USLEEP_RANGE", |
| 5851 | "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); |
| 5852 | } |
| 5853 | } |
| 5854 | |
Joe Perches | 823b794 | 2013-11-12 15:10:15 -0800 | [diff] [blame] | 5855 | # check for naked sscanf |
| 5856 | if ($^V && $^V ge 5.10.0 && |
| 5857 | defined $stat && |
Joe Perches | 6c8bd70 | 2014-04-03 14:49:16 -0700 | [diff] [blame] | 5858 | $line =~ /\bsscanf\b/ && |
Joe Perches | 823b794 | 2013-11-12 15:10:15 -0800 | [diff] [blame] | 5859 | ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && |
| 5860 | $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && |
| 5861 | $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { |
| 5862 | my $lc = $stat =~ tr@\n@@; |
| 5863 | $lc = $lc + $linenr; |
| 5864 | my $stat_real = raw_line($linenr, 0); |
| 5865 | for (my $count = $linenr + 1; $count <= $lc; $count++) { |
| 5866 | $stat_real = $stat_real . "\n" . raw_line($count, 0); |
| 5867 | } |
| 5868 | WARN("NAKED_SSCANF", |
| 5869 | "unchecked sscanf return value\n" . "$here\n$stat_real\n"); |
| 5870 | } |
| 5871 | |
Joe Perches | afc819a | 2014-06-04 16:12:08 -0700 | [diff] [blame] | 5872 | # check for simple sscanf that should be kstrto<foo> |
| 5873 | if ($^V && $^V ge 5.10.0 && |
| 5874 | defined $stat && |
| 5875 | $line =~ /\bsscanf\b/) { |
| 5876 | my $lc = $stat =~ tr@\n@@; |
| 5877 | $lc = $lc + $linenr; |
| 5878 | my $stat_real = raw_line($linenr, 0); |
| 5879 | for (my $count = $linenr + 1; $count <= $lc; $count++) { |
| 5880 | $stat_real = $stat_real . "\n" . raw_line($count, 0); |
| 5881 | } |
| 5882 | if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { |
| 5883 | my $format = $6; |
| 5884 | my $count = $format =~ tr@%@%@; |
| 5885 | if ($count == 1 && |
| 5886 | $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { |
| 5887 | WARN("SSCANF_TO_KSTRTO", |
| 5888 | "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); |
| 5889 | } |
| 5890 | } |
| 5891 | } |
| 5892 | |
Joe Perches | 70dc8a4 | 2013-09-11 14:23:58 -0700 | [diff] [blame] | 5893 | # check for new externs in .h files. |
| 5894 | if ($realfile =~ /\.h$/ && |
| 5895 | $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { |
Joe Perches | d1d8578 | 2013-09-24 15:27:46 -0700 | [diff] [blame] | 5896 | if (CHK("AVOID_EXTERNS", |
| 5897 | "extern prototypes should be avoided in .h files\n" . $herecurr) && |
Joe Perches | 70dc8a4 | 2013-09-11 14:23:58 -0700 | [diff] [blame] | 5898 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 5899 | $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; |
Joe Perches | 70dc8a4 | 2013-09-11 14:23:58 -0700 | [diff] [blame] | 5900 | } |
| 5901 | } |
| 5902 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5903 | # check for new externs in .c files. |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 5904 | if ($realfile =~ /\.c$/ && defined $stat && |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5905 | $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 5906 | { |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5907 | my $function_name = $1; |
| 5908 | my $paren_space = $2; |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 5909 | |
| 5910 | my $s = $stat; |
| 5911 | if (defined $cond) { |
| 5912 | substr($s, 0, length($cond), ''); |
| 5913 | } |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 5914 | if ($s =~ /^\s*;/ && |
| 5915 | $function_name ne 'uninitialized_var') |
| 5916 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5917 | WARN("AVOID_EXTERNS", |
| 5918 | "externs should be avoided in .c files\n" . $herecurr); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 5919 | } |
| 5920 | |
| 5921 | if ($paren_space =~ /\n/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5922 | WARN("FUNCTION_ARGUMENTS", |
| 5923 | "arguments for function declarations should follow identifier\n" . $herecurr); |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 5924 | } |
Andy Whitcroft | 9c9ba34 | 2008-04-29 00:59:33 -0700 | [diff] [blame] | 5925 | |
| 5926 | } elsif ($realfile =~ /\.c$/ && defined $stat && |
| 5927 | $stat =~ /^.\s*extern\s+/) |
| 5928 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5929 | WARN("AVOID_EXTERNS", |
| 5930 | "externs should be avoided in .c files\n" . $herecurr); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5931 | } |
| 5932 | |
Joe Perches | a0ad759 | 2017-07-10 15:52:19 -0700 | [diff] [blame] | 5933 | # check for function declarations that have arguments without identifier names |
| 5934 | if (defined $stat && |
Joe Perches | ca0d892 | 2016-10-11 13:52:16 -0700 | [diff] [blame] | 5935 | $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && |
| 5936 | $1 ne "void") { |
| 5937 | my $args = trim($1); |
| 5938 | while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { |
| 5939 | my $arg = trim($1); |
| 5940 | if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { |
| 5941 | WARN("FUNCTION_ARGUMENTS", |
| 5942 | "function definition argument '$arg' should also have an identifier name\n" . $herecurr); |
| 5943 | } |
| 5944 | } |
| 5945 | } |
| 5946 | |
Joe Perches | a0ad759 | 2017-07-10 15:52:19 -0700 | [diff] [blame] | 5947 | # check for function definitions |
| 5948 | if ($^V && $^V ge 5.10.0 && |
| 5949 | defined $stat && |
| 5950 | $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { |
| 5951 | $context_function = $1; |
| 5952 | |
| 5953 | # check for multiline function definition with misplaced open brace |
| 5954 | my $ok = 0; |
| 5955 | my $cnt = statement_rawlines($stat); |
| 5956 | my $herectx = $here . "\n"; |
| 5957 | for (my $n = 0; $n < $cnt; $n++) { |
| 5958 | my $rl = raw_line($linenr, $n); |
| 5959 | $herectx .= $rl . "\n"; |
| 5960 | $ok = 1 if ($rl =~ /^[ \+]\{/); |
| 5961 | $ok = 1 if ($rl =~ /\{/ && $n == 0); |
| 5962 | last if $rl =~ /^[ \+].*\{/; |
| 5963 | } |
| 5964 | if (!$ok) { |
| 5965 | ERROR("OPEN_BRACE", |
| 5966 | "open brace '{' following function definitions go on the next line\n" . $herectx); |
| 5967 | } |
| 5968 | } |
| 5969 | |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5970 | # checks for new __setup's |
| 5971 | if ($rawline =~ /\b__setup\("([^"]*)"/) { |
| 5972 | my $name = $1; |
| 5973 | |
| 5974 | if (!grep(/$name/, @setup_docs)) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5975 | CHK("UNDOCUMENTED_SETUP", |
Mauro Carvalho Chehab | 8c27ceff3 | 2016-10-18 10:12:27 -0200 | [diff] [blame] | 5976 | "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); |
Andy Whitcroft | de7d4f0 | 2007-07-15 23:37:22 -0700 | [diff] [blame] | 5977 | } |
Andy Whitcroft | 653d487 | 2007-06-23 17:16:34 -0700 | [diff] [blame] | 5978 | } |
Andy Whitcroft | 9c0ca6f | 2007-10-16 23:29:38 -0700 | [diff] [blame] | 5979 | |
| 5980 | # check for pointless casting of kmalloc return |
Joe Perches | caf2a54 | 2011-01-12 16:59:56 -0800 | [diff] [blame] | 5981 | if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 5982 | WARN("UNNECESSARY_CASTS", |
| 5983 | "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] | 5984 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 5985 | |
Joe Perches | a640d25 | 2013-07-03 15:05:21 -0700 | [diff] [blame] | 5986 | # alloc style |
| 5987 | # p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) |
| 5988 | if ($^V && $^V ge 5.10.0 && |
| 5989 | $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { |
| 5990 | CHK("ALLOC_SIZEOF_STRUCT", |
| 5991 | "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); |
| 5992 | } |
| 5993 | |
Joe Perches | 60a5536 | 2014-06-04 16:12:07 -0700 | [diff] [blame] | 5994 | # check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc |
| 5995 | if ($^V && $^V ge 5.10.0 && |
Joe Perches | 1b4a2ed | 2017-05-08 15:55:57 -0700 | [diff] [blame] | 5996 | defined $stat && |
| 5997 | $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] | 5998 | my $oldfunc = $3; |
| 5999 | my $a1 = $4; |
| 6000 | my $a2 = $10; |
| 6001 | my $newfunc = "kmalloc_array"; |
| 6002 | $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); |
Joe Perches | e367455 | 2014-08-06 16:10:55 -0700 | [diff] [blame] | 6003 | my $r1 = $a1; |
| 6004 | my $r2 = $a2; |
| 6005 | if ($a1 =~ /^sizeof\s*\S/) { |
| 6006 | $r1 = $a2; |
| 6007 | $r2 = $a1; |
| 6008 | } |
| 6009 | if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && |
| 6010 | !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { |
Joe Perches | 1b4a2ed | 2017-05-08 15:55:57 -0700 | [diff] [blame] | 6011 | my $ctx = ''; |
| 6012 | my $herectx = $here . "\n"; |
| 6013 | my $cnt = statement_rawlines($stat); |
| 6014 | for (my $n = 0; $n < $cnt; $n++) { |
| 6015 | $herectx .= raw_line($linenr, $n) . "\n"; |
| 6016 | } |
Joe Perches | 60a5536 | 2014-06-04 16:12:07 -0700 | [diff] [blame] | 6017 | if (WARN("ALLOC_WITH_MULTIPLY", |
Joe Perches | 1b4a2ed | 2017-05-08 15:55:57 -0700 | [diff] [blame] | 6018 | "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && |
| 6019 | $cnt == 1 && |
Joe Perches | 60a5536 | 2014-06-04 16:12:07 -0700 | [diff] [blame] | 6020 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6021 | $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] | 6022 | } |
| 6023 | } |
| 6024 | } |
| 6025 | |
Joe Perches | 972fdea | 2013-04-29 16:18:12 -0700 | [diff] [blame] | 6026 | # check for krealloc arg reuse |
| 6027 | if ($^V && $^V ge 5.10.0 && |
| 6028 | $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { |
| 6029 | WARN("KREALLOC_ARG_REUSE", |
| 6030 | "Reusing the krealloc arg is almost always a bug\n" . $herecurr); |
| 6031 | } |
| 6032 | |
Joe Perches | 5ce59ae | 2013-02-21 16:44:18 -0800 | [diff] [blame] | 6033 | # check for alloc argument mismatch |
| 6034 | if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { |
| 6035 | WARN("ALLOC_ARRAY_ARGS", |
| 6036 | "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); |
| 6037 | } |
| 6038 | |
Joe Perches | caf2a54 | 2011-01-12 16:59:56 -0800 | [diff] [blame] | 6039 | # check for multiple semicolons |
| 6040 | if ($line =~ /;\s*;\s*$/) { |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6041 | if (WARN("ONE_SEMICOLON", |
| 6042 | "Statements terminations use 1 semicolon\n" . $herecurr) && |
| 6043 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6044 | $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6045 | } |
Joe Perches | d1e2ad0 | 2012-12-17 16:02:01 -0800 | [diff] [blame] | 6046 | } |
| 6047 | |
Tomas Winkler | cec3aaa | 2016-08-02 14:04:39 -0700 | [diff] [blame] | 6048 | # check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi |
| 6049 | if ($realfile !~ m@^include/uapi/@ && |
| 6050 | $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] | 6051 | my $ull = ""; |
| 6052 | $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); |
| 6053 | if (CHK("BIT_MACRO", |
| 6054 | "Prefer using the BIT$ull macro\n" . $herecurr) && |
| 6055 | $fix) { |
| 6056 | $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; |
| 6057 | } |
| 6058 | } |
| 6059 | |
Joe Perches | 2d63274 | 2016-05-20 17:04:00 -0700 | [diff] [blame] | 6060 | # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE |
| 6061 | if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { |
| 6062 | my $config = $1; |
| 6063 | if (WARN("PREFER_IS_ENABLED", |
| 6064 | "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && |
| 6065 | $fix) { |
| 6066 | $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; |
| 6067 | } |
| 6068 | } |
| 6069 | |
Joe Perches | e81f239 | 2014-08-06 16:11:25 -0700 | [diff] [blame] | 6070 | # check for case / default statements not preceded by break/fallthrough/switch |
Joe Perches | c34c09a | 2014-01-23 15:54:43 -0800 | [diff] [blame] | 6071 | if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { |
| 6072 | my $has_break = 0; |
| 6073 | my $has_statement = 0; |
| 6074 | my $count = 0; |
| 6075 | my $prevline = $linenr; |
Joe Perches | e81f239 | 2014-08-06 16:11:25 -0700 | [diff] [blame] | 6076 | while ($prevline > 1 && ($file || $count < 3) && !$has_break) { |
Joe Perches | c34c09a | 2014-01-23 15:54:43 -0800 | [diff] [blame] | 6077 | $prevline--; |
| 6078 | my $rline = $rawlines[$prevline - 1]; |
| 6079 | my $fline = $lines[$prevline - 1]; |
| 6080 | last if ($fline =~ /^\@\@/); |
| 6081 | next if ($fline =~ /^\-/); |
| 6082 | next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); |
| 6083 | $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); |
| 6084 | next if ($fline =~ /^.[\s$;]*$/); |
| 6085 | $has_statement = 1; |
| 6086 | $count++; |
| 6087 | $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); |
| 6088 | } |
| 6089 | if (!$has_break && $has_statement) { |
| 6090 | WARN("MISSING_BREAK", |
Andrew Morton | 224236d | 2016-12-12 16:46:26 -0800 | [diff] [blame] | 6091 | "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); |
Joe Perches | c34c09a | 2014-01-23 15:54:43 -0800 | [diff] [blame] | 6092 | } |
| 6093 | } |
| 6094 | |
Joe Perches | d1e2ad0 | 2012-12-17 16:02:01 -0800 | [diff] [blame] | 6095 | # check for switch/default statements without a break; |
| 6096 | if ($^V && $^V ge 5.10.0 && |
| 6097 | defined $stat && |
| 6098 | $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { |
| 6099 | my $ctx = ''; |
| 6100 | my $herectx = $here . "\n"; |
| 6101 | my $cnt = statement_rawlines($stat); |
| 6102 | for (my $n = 0; $n < $cnt; $n++) { |
| 6103 | $herectx .= raw_line($linenr, $n) . "\n"; |
| 6104 | } |
| 6105 | WARN("DEFAULT_NO_BREAK", |
| 6106 | "switch default: should use break\n" . $herectx); |
Joe Perches | caf2a54 | 2011-01-12 16:59:56 -0800 | [diff] [blame] | 6107 | } |
| 6108 | |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6109 | # check for gcc specific __FUNCTION__ |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6110 | if ($line =~ /\b__FUNCTION__\b/) { |
| 6111 | if (WARN("USE_FUNC", |
| 6112 | "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && |
| 6113 | $fix) { |
Joe Perches | 194f66f | 2014-08-06 16:11:03 -0700 | [diff] [blame] | 6114 | $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; |
Joe Perches | d5e616f | 2013-09-11 14:23:54 -0700 | [diff] [blame] | 6115 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6116 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6117 | |
Joe Perches | 62ec818 | 2015-02-13 14:38:18 -0800 | [diff] [blame] | 6118 | # check for uses of __DATE__, __TIME__, __TIMESTAMP__ |
| 6119 | while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { |
| 6120 | ERROR("DATE_TIME", |
| 6121 | "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); |
| 6122 | } |
| 6123 | |
Joe Perches | 2c92488 | 2012-03-23 15:02:20 -0700 | [diff] [blame] | 6124 | # check for use of yield() |
| 6125 | if ($line =~ /\byield\s*\(\s*\)/) { |
| 6126 | WARN("YIELD", |
| 6127 | "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); |
| 6128 | } |
| 6129 | |
Joe Perches | 179f8f4 | 2013-07-03 15:05:30 -0700 | [diff] [blame] | 6130 | # check for comparisons against true and false |
| 6131 | if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { |
| 6132 | my $lead = $1; |
| 6133 | my $arg = $2; |
| 6134 | my $test = $3; |
| 6135 | my $otype = $4; |
| 6136 | my $trail = $5; |
| 6137 | my $op = "!"; |
| 6138 | |
| 6139 | ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); |
| 6140 | |
| 6141 | my $type = lc($otype); |
| 6142 | if ($type =~ /^(?:true|false)$/) { |
| 6143 | if (("$test" eq "==" && "$type" eq "true") || |
| 6144 | ("$test" eq "!=" && "$type" eq "false")) { |
| 6145 | $op = ""; |
| 6146 | } |
| 6147 | |
| 6148 | CHK("BOOL_COMPARISON", |
| 6149 | "Using comparison to $otype is error prone\n" . $herecurr); |
| 6150 | |
| 6151 | ## maybe suggesting a correct construct would better |
| 6152 | ## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); |
| 6153 | |
| 6154 | } |
| 6155 | } |
| 6156 | |
Thomas Gleixner | 4882720b | 2010-09-07 14:34:01 +0000 | [diff] [blame] | 6157 | # check for semaphores initialized locked |
| 6158 | if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6159 | WARN("CONSIDER_COMPLETION", |
| 6160 | "consider using a completion\n" . $herecurr); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6161 | } |
Joe Perches | 6712d85 | 2012-03-23 15:02:20 -0700 | [diff] [blame] | 6162 | |
Joe Perches | 67d0a07 | 2011-10-31 17:13:10 -0700 | [diff] [blame] | 6163 | # recommend kstrto* over simple_strto* and strict_strto* |
| 6164 | if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6165 | WARN("CONSIDER_KSTRTO", |
Joe Perches | 67d0a07 | 2011-10-31 17:13:10 -0700 | [diff] [blame] | 6166 | "$1 is obsolete, use k$3 instead\n" . $herecurr); |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6167 | } |
Joe Perches | 6712d85 | 2012-03-23 15:02:20 -0700 | [diff] [blame] | 6168 | |
Fabian Frederick | ae3ccc4 | 2014-06-04 16:12:10 -0700 | [diff] [blame] | 6169 | # check for __initcall(), use device_initcall() explicitly or more appropriate function please |
Michael Ellerman | f3db663 | 2008-07-23 21:28:57 -0700 | [diff] [blame] | 6170 | if ($line =~ /^.\s*__initcall\s*\(/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6171 | WARN("USE_DEVICE_INITCALL", |
Fabian Frederick | ae3ccc4 | 2014-06-04 16:12:10 -0700 | [diff] [blame] | 6172 | "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] | 6173 | } |
Joe Perches | 6712d85 | 2012-03-23 15:02:20 -0700 | [diff] [blame] | 6174 | |
Joe Perches | 0f3c5aa | 2015-02-13 14:39:05 -0800 | [diff] [blame] | 6175 | # check for various structs that are normally const (ops, kgdb, device_tree) |
Joe Perches | d9190e4 | 2017-05-08 15:55:45 -0700 | [diff] [blame] | 6176 | # and avoid what seem like struct definitions 'struct foo {' |
Andy Whitcroft | 6903ffb | 2009-01-15 13:51:07 -0800 | [diff] [blame] | 6177 | if ($line !~ /\bconst\b/ && |
Joe Perches | d9190e4 | 2017-05-08 15:55:45 -0700 | [diff] [blame] | 6178 | $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6179 | WARN("CONST_STRUCT", |
Joe Perches | d9190e4 | 2017-05-08 15:55:45 -0700 | [diff] [blame] | 6180 | "struct $1 should normally be const\n" . $herecurr); |
Andy Whitcroft | 2b6db5c | 2009-01-06 14:41:29 -0800 | [diff] [blame] | 6181 | } |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6182 | |
| 6183 | # use of NR_CPUS is usually wrong |
| 6184 | # ignore definitions of NR_CPUS and usage to define arrays as likely right |
| 6185 | if ($line =~ /\bNR_CPUS\b/ && |
Andy Whitcroft | c45dcab | 2008-06-05 22:46:01 -0700 | [diff] [blame] | 6186 | $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && |
| 6187 | $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && |
Andy Whitcroft | 171ae1a | 2008-04-29 00:59:32 -0700 | [diff] [blame] | 6188 | $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && |
| 6189 | $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && |
| 6190 | $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) |
Andy Whitcroft | 773647a | 2008-03-28 14:15:58 -0700 | [diff] [blame] | 6191 | { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6192 | WARN("NR_CPUS", |
| 6193 | "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] | 6194 | } |
Andy Whitcroft | 9c9ba34 | 2008-04-29 00:59:33 -0700 | [diff] [blame] | 6195 | |
Joe Perches | 52ea850 | 2013-11-12 15:10:09 -0800 | [diff] [blame] | 6196 | # Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. |
| 6197 | if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { |
| 6198 | ERROR("DEFINE_ARCH_HAS", |
| 6199 | "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); |
| 6200 | } |
| 6201 | |
Joe Perches | acd9362 | 2015-02-13 14:38:38 -0800 | [diff] [blame] | 6202 | # likely/unlikely comparisons similar to "(likely(foo) > 0)" |
| 6203 | if ($^V && $^V ge 5.10.0 && |
| 6204 | $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { |
| 6205 | WARN("LIKELY_MISUSE", |
| 6206 | "Using $1 should generally have parentheses around the comparison\n" . $herecurr); |
| 6207 | } |
| 6208 | |
Andy Whitcroft | 691d77b | 2009-01-06 14:41:16 -0800 | [diff] [blame] | 6209 | # whine mightly about in_atomic |
| 6210 | if ($line =~ /\bin_atomic\s*\(/) { |
| 6211 | if ($realfile =~ m@^drivers/@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6212 | ERROR("IN_ATOMIC", |
| 6213 | "do not use in_atomic in drivers\n" . $herecurr); |
Andy Whitcroft | f4a8773 | 2009-02-27 14:03:05 -0800 | [diff] [blame] | 6214 | } elsif ($realfile !~ m@^kernel/@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6215 | WARN("IN_ATOMIC", |
| 6216 | "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); |
Andy Whitcroft | 691d77b | 2009-01-06 14:41:16 -0800 | [diff] [blame] | 6217 | } |
| 6218 | } |
Peter Zijlstra | 1704f47 | 2010-03-19 01:37:42 +0100 | [diff] [blame] | 6219 | |
Joe Perches | 481aea5 | 2016-05-20 17:04:08 -0700 | [diff] [blame] | 6220 | # whine about ACCESS_ONCE |
| 6221 | if ($^V && $^V ge 5.10.0 && |
| 6222 | $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { |
| 6223 | my $par = $1; |
| 6224 | my $eq = $2; |
| 6225 | my $fun = $3; |
| 6226 | $par =~ s/^\(\s*(.*)\s*\)$/$1/; |
| 6227 | if (defined($eq)) { |
| 6228 | if (WARN("PREFER_WRITE_ONCE", |
| 6229 | "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && |
| 6230 | $fix) { |
| 6231 | $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; |
| 6232 | } |
| 6233 | } else { |
| 6234 | if (WARN("PREFER_READ_ONCE", |
| 6235 | "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && |
| 6236 | $fix) { |
| 6237 | $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; |
| 6238 | } |
| 6239 | } |
| 6240 | } |
| 6241 | |
Peter Zijlstra | 0f5225b | 2016-10-07 17:43:51 +0200 | [diff] [blame] | 6242 | # check for mutex_trylock_recursive usage |
| 6243 | if ($line =~ /mutex_trylock_recursive/) { |
| 6244 | ERROR("LOCKING", |
| 6245 | "recursive locking is bad, do not use this ever.\n" . $herecurr); |
| 6246 | } |
| 6247 | |
Peter Zijlstra | 1704f47 | 2010-03-19 01:37:42 +0100 | [diff] [blame] | 6248 | # check for lockdep_set_novalidate_class |
| 6249 | if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || |
| 6250 | $line =~ /__lockdep_no_validate__\s*\)/ ) { |
| 6251 | if ($realfile !~ m@^kernel/lockdep@ && |
| 6252 | $realfile !~ m@^include/linux/lockdep@ && |
| 6253 | $realfile !~ m@^drivers/base/core@) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6254 | ERROR("LOCKDEP", |
| 6255 | "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); |
Peter Zijlstra | 1704f47 | 2010-03-19 01:37:42 +0100 | [diff] [blame] | 6256 | } |
| 6257 | } |
Dave Jones | 88f8831 | 2011-01-12 16:59:59 -0800 | [diff] [blame] | 6258 | |
Joe Perches | b392c64 | 2015-04-16 12:44:16 -0700 | [diff] [blame] | 6259 | if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || |
| 6260 | $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6261 | WARN("EXPORTED_WORLD_WRITABLE", |
| 6262 | "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] | 6263 | } |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 6264 | |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 6265 | # Mode permission misuses where it seems decimal should be octal |
| 6266 | # This uses a shortcut match to avoid unnecessary uses of a slow foreach loop |
| 6267 | if ($^V && $^V ge 5.10.0 && |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 6268 | defined $stat && |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 6269 | $line =~ /$mode_perms_search/) { |
| 6270 | foreach my $entry (@mode_permission_funcs) { |
| 6271 | my $func = $entry->[0]; |
| 6272 | my $arg_pos = $entry->[1]; |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 6273 | |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 6274 | my $lc = $stat =~ tr@\n@@; |
| 6275 | $lc = $lc + $linenr; |
| 6276 | my $stat_real = raw_line($linenr, 0); |
| 6277 | for (my $count = $linenr + 1; $count <= $lc; $count++) { |
| 6278 | $stat_real = $stat_real . "\n" . raw_line($count, 0); |
| 6279 | } |
| 6280 | |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 6281 | my $skip_args = ""; |
| 6282 | if ($arg_pos > 1) { |
| 6283 | $arg_pos--; |
| 6284 | $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; |
| 6285 | } |
Joe Perches | f90774e | 2016-10-11 13:51:47 -0700 | [diff] [blame] | 6286 | my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 6287 | if ($stat =~ /$test/) { |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 6288 | my $val = $1; |
| 6289 | $val = $6 if ($skip_args ne ""); |
Joe Perches | f90774e | 2016-10-11 13:51:47 -0700 | [diff] [blame] | 6290 | if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || |
| 6291 | ($val =~ /^$Octal$/ && length($val) ne 4)) { |
Joe Perches | 515a235 | 2014-04-03 14:49:24 -0700 | [diff] [blame] | 6292 | ERROR("NON_OCTAL_PERMISSIONS", |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 6293 | "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] | 6294 | } |
| 6295 | if ($val =~ /^$Octal$/ && (oct($val) & 02)) { |
Joe Perches | c0a5c89 | 2015-02-13 14:38:21 -0800 | [diff] [blame] | 6296 | ERROR("EXPORTED_WORLD_WRITABLE", |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 6297 | "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] | 6298 | } |
Joe Perches | 2435880 | 2014-04-03 14:49:13 -0700 | [diff] [blame] | 6299 | } |
| 6300 | } |
| 6301 | } |
Bjorn Andersson | 5a6d20c | 2015-06-25 15:03:24 -0700 | [diff] [blame] | 6302 | |
Joe Perches | 459cf0a | 2016-10-11 13:52:19 -0700 | [diff] [blame] | 6303 | # check for uses of S_<PERMS> that could be octal for readability |
| 6304 | if ($line =~ /\b$mode_perms_string_search\b/) { |
| 6305 | my $val = ""; |
| 6306 | my $oval = ""; |
| 6307 | my $to = 0; |
| 6308 | my $curpos = 0; |
| 6309 | my $lastpos = 0; |
| 6310 | while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { |
| 6311 | $curpos = pos($line); |
| 6312 | my $match = $2; |
| 6313 | my $omatch = $1; |
| 6314 | last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); |
| 6315 | $lastpos = $curpos; |
| 6316 | $to |= $mode_permission_string_types{$match}; |
| 6317 | $val .= '\s*\|\s*' if ($val ne ""); |
| 6318 | $val .= $match; |
| 6319 | $oval .= $omatch; |
| 6320 | } |
| 6321 | $oval =~ s/^\s*\|\s*//; |
| 6322 | $oval =~ s/\s*\|\s*$//; |
| 6323 | my $octal = sprintf("%04o", $to); |
| 6324 | if (WARN("SYMBOLIC_PERMS", |
| 6325 | "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && |
| 6326 | $fix) { |
| 6327 | $fixed[$fixlinenr] =~ s/$val/$octal/; |
| 6328 | } |
| 6329 | } |
| 6330 | |
Bjorn Andersson | 5a6d20c | 2015-06-25 15:03:24 -0700 | [diff] [blame] | 6331 | # validate content of MODULE_LICENSE against list from include/linux/module.h |
| 6332 | if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { |
| 6333 | my $extracted_string = get_quoted_string($line, $rawline); |
| 6334 | my $valid_licenses = qr{ |
| 6335 | GPL| |
| 6336 | GPL\ v2| |
| 6337 | GPL\ and\ additional\ rights| |
| 6338 | Dual\ BSD/GPL| |
| 6339 | Dual\ MIT/GPL| |
| 6340 | Dual\ MPL/GPL| |
| 6341 | Proprietary |
| 6342 | }x; |
| 6343 | if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { |
| 6344 | WARN("MODULE_LICENSE", |
| 6345 | "unknown module license " . $extracted_string . "\n" . $herecurr); |
| 6346 | } |
| 6347 | } |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6348 | } |
| 6349 | |
| 6350 | # If we have no input at all, then there is nothing to report on |
| 6351 | # so just keep quiet. |
| 6352 | if ($#rawlines == -1) { |
| 6353 | exit(0); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 6354 | } |
| 6355 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 6356 | # In mailback mode only produce a report in the negative, for |
| 6357 | # things that appear to be patches. |
| 6358 | if ($mailback && ($clean == 1 || !$is_patch)) { |
| 6359 | exit(0); |
| 6360 | } |
| 6361 | |
| 6362 | # This is not a patch, and we are are in 'no-patch' mode so |
| 6363 | # just keep quiet. |
| 6364 | if (!$chk_patch && !$is_patch) { |
| 6365 | exit(0); |
| 6366 | } |
| 6367 | |
Joe Perches | 06330fc | 2015-06-25 15:03:11 -0700 | [diff] [blame] | 6368 | if (!$is_patch && $file !~ /cover-letter\.patch$/) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6369 | ERROR("NOT_UNIFIED_DIFF", |
| 6370 | "Does not appear to be a unified-diff format patch\n"); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 6371 | } |
Allen Hubbe | ed43c4e | 2016-08-02 14:04:45 -0700 | [diff] [blame] | 6372 | if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { |
Joe Perches | 000d1cc1 | 2011-07-25 17:13:25 -0700 | [diff] [blame] | 6373 | ERROR("MISSING_SIGN_OFF", |
| 6374 | "Missing Signed-off-by: line(s)\n"); |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 6375 | } |
| 6376 | |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 6377 | print report_dump(); |
Andy Whitcroft | 13214ad | 2008-02-08 04:22:03 -0800 | [diff] [blame] | 6378 | if ($summary && !($clean == 1 && $quiet == 1)) { |
| 6379 | print "$filename " if ($summary_file); |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 6380 | print "total: $cnt_error errors, $cnt_warn warnings, " . |
| 6381 | (($check)? "$cnt_chk checks, " : "") . |
| 6382 | "$cnt_lines lines checked\n"; |
Andy Whitcroft | f0a594c | 2007-07-19 01:48:34 -0700 | [diff] [blame] | 6383 | } |
Andy Whitcroft | 8905a67 | 2007-11-28 16:21:06 -0800 | [diff] [blame] | 6384 | |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 6385 | if ($quiet == 0) { |
Joe Perches | ef21219 | 2016-05-20 17:04:11 -0700 | [diff] [blame] | 6386 | # If there were any defects found and not already fixing them |
| 6387 | if (!$clean and !$fix) { |
| 6388 | print << "EOM" |
| 6389 | |
| 6390 | NOTE: For some of the reported defects, checkpatch may be able to |
| 6391 | mechanically convert to the typical style using --fix or --fix-inplace. |
| 6392 | EOM |
| 6393 | } |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 6394 | # If there were whitespace errors which cleanpatch can fix |
| 6395 | # then suggest that. |
| 6396 | if ($rpt_cleaners) { |
Mike Frysinger | b078121 | 2011-03-22 16:34:43 -0700 | [diff] [blame] | 6397 | $rpt_cleaners = 0; |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 6398 | print << "EOM" |
| 6399 | |
| 6400 | NOTE: Whitespace errors detected. |
| 6401 | You may wish to use scripts/cleanpatch or scripts/cleanfile |
| 6402 | EOM |
Andy Whitcroft | d2c0a23 | 2010-10-26 14:23:12 -0700 | [diff] [blame] | 6403 | } |
| 6404 | } |
| 6405 | |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 6406 | if ($clean == 0 && $fix && |
| 6407 | ("@rawlines" ne "@fixed" || |
| 6408 | $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { |
Joe Perches | 9624b8d | 2014-01-23 15:54:44 -0800 | [diff] [blame] | 6409 | my $newfile = $filename; |
| 6410 | $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 6411 | my $linecount = 0; |
| 6412 | my $f; |
| 6413 | |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 6414 | @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); |
| 6415 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 6416 | open($f, '>', $newfile) |
| 6417 | or die "$P: Can't open $newfile for write\n"; |
| 6418 | foreach my $fixed_line (@fixed) { |
| 6419 | $linecount++; |
| 6420 | if ($file) { |
| 6421 | if ($linecount > 3) { |
| 6422 | $fixed_line =~ s/^\+//; |
Joe Perches | d752fcc | 2014-08-06 16:11:05 -0700 | [diff] [blame] | 6423 | print $f $fixed_line . "\n"; |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 6424 | } |
| 6425 | } else { |
| 6426 | print $f $fixed_line . "\n"; |
| 6427 | } |
| 6428 | } |
| 6429 | close($f); |
| 6430 | |
| 6431 | if (!$quiet) { |
| 6432 | print << "EOM"; |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 6433 | |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 6434 | Wrote EXPERIMENTAL --fix correction(s) to '$newfile' |
| 6435 | |
| 6436 | Do _NOT_ trust the results written to this file. |
| 6437 | Do _NOT_ submit these changes without inspecting them for correctness. |
| 6438 | |
| 6439 | This EXPERIMENTAL file is simply a convenience to help rewrite patches. |
| 6440 | No warranties, expressed or implied... |
Joe Perches | 3705ce5 | 2013-07-03 15:05:31 -0700 | [diff] [blame] | 6441 | EOM |
| 6442 | } |
| 6443 | } |
| 6444 | |
Joe Perches | d8469f1 | 2015-06-25 15:03:00 -0700 | [diff] [blame] | 6445 | if ($quiet == 0) { |
| 6446 | print "\n"; |
| 6447 | if ($clean == 1) { |
| 6448 | print "$vname has no obvious style problems and is ready for submission.\n"; |
| 6449 | } else { |
| 6450 | print "$vname has style problems, please review.\n"; |
| 6451 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 6452 | } |
Andy Whitcroft | 0a920b5 | 2007-06-01 00:46:48 -0700 | [diff] [blame] | 6453 | return $clean; |
| 6454 | } |