1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl 2882ea1d6SJoe Perches# SPDX-License-Identifier: GPL-2.0 3882ea1d6SJoe Perches# 4dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit) 500df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 62a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite) 7015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]> 8882ea1d6SJoe Perches# (c) 2010-2018 Joe Perches <[email protected]> 90a920b5bSAndy Whitcroft 100a920b5bSAndy Whitcroftuse strict; 11cb77f0d6SKamil Rytarowskiuse warnings; 12c707a81dSJoe Perchesuse POSIX; 1336061e38SJoe Perchesuse File::Basename; 1436061e38SJoe Perchesuse Cwd 'abs_path'; 1557230297SJoe Perchesuse Term::ANSIColor qw(:constants); 16cd261496SGeert Uytterhoevenuse Encode qw(decode encode); 170a920b5bSAndy Whitcroft 180a920b5bSAndy Whitcroftmy $P = $0; 1936061e38SJoe Perchesmy $D = dirname(abs_path($P)); 200a920b5bSAndy Whitcroft 21000d1cc1SJoe Perchesmy $V = '0.32'; 220a920b5bSAndy Whitcroft 230a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 240a920b5bSAndy Whitcroft 250a920b5bSAndy Whitcroftmy $quiet = 0; 260a920b5bSAndy Whitcroftmy $tree = 1; 270a920b5bSAndy Whitcroftmy $chk_signoff = 1; 280a920b5bSAndy Whitcroftmy $chk_patch = 1; 29773647a0SAndy Whitcroftmy $tst_only; 306c72ffaaSAndy Whitcroftmy $emacs = 0; 318905a67cSAndy Whitcroftmy $terse = 0; 3234d8815fSJoe Perchesmy $showfile = 0; 336c72ffaaSAndy Whitcroftmy $file = 0; 344a593c34SDu, Changbinmy $git = 0; 350dea9f1eSJoe Perchesmy %git_commits = (); 366c72ffaaSAndy Whitcroftmy $check = 0; 372ac73b4fSJoe Perchesmy $check_orig = 0; 388905a67cSAndy Whitcroftmy $summary = 1; 398905a67cSAndy Whitcroftmy $mailback = 0; 4013214adfSAndy Whitcroftmy $summary_file = 0; 41000d1cc1SJoe Perchesmy $show_types = 0; 423beb42ecSJoe Perchesmy $list_types = 0; 433705ce5bSJoe Perchesmy $fix = 0; 449624b8d6SJoe Perchesmy $fix_inplace = 0; 456c72ffaaSAndy Whitcroftmy $root; 460f7f635bSJoe Perchesmy $gitroot = $ENV{'GIT_DIR'}; 470f7f635bSJoe Perches$gitroot = ".git" if !defined($gitroot); 48c2fdda0dSAndy Whitcroftmy %debug; 493445686aSJoe Perchesmy %camelcase = (); 5091bfe484SJoe Perchesmy %use_type = (); 5191bfe484SJoe Perchesmy @use = (); 5291bfe484SJoe Perchesmy %ignore_type = (); 53000d1cc1SJoe Perchesmy @ignore = (); 5477f5b10aSHannes Edermy $help = 0; 55000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 56bdc48fa1SJoe Perchesmy $max_line_length = 100; 57d62a201fSDave Hansenmy $ignore_perl_version = 0; 58d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 5956193274SVadim Bendeburymy $min_conf_desc_length = 4; 6066b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 61ebfd7d62SJoe Perchesmy $codespell = 0; 62f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt"; 63bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 64ced69da1SQuentin Monnetmy $typedefsfile; 65737c0767SJohn Brooksmy $color = "auto"; 6698005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE 67dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE 68dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git'; 69713a09deSAntonio Borneomy $tabsize = 8; 703e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_"; 7177f5b10aSHannes Eder 7277f5b10aSHannes Edersub help { 7377f5b10aSHannes Eder my ($exitcode) = @_; 7477f5b10aSHannes Eder 7577f5b10aSHannes Eder print << "EOM"; 7677f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 7777f5b10aSHannes EderVersion: $V 7877f5b10aSHannes Eder 7977f5b10aSHannes EderOptions: 8077f5b10aSHannes Eder -q, --quiet quiet 8177f5b10aSHannes Eder --no-tree run without a kernel tree 8277f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 8377f5b10aSHannes Eder --patch treat FILE as patchfile (default) 8477f5b10aSHannes Eder --emacs emacs compile window format 8577f5b10aSHannes Eder --terse one line per report 8634d8815fSJoe Perches --showfile emit diffed file position, not input file position 874a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 884a593c34SDu, Changbin single git commit with: 894a593c34SDu, Changbin <rev> 904a593c34SDu, Changbin <rev>^ 914a593c34SDu, Changbin <rev>~n 924a593c34SDu, Changbin multiple git commits with: 934a593c34SDu, Changbin <rev1>..<rev2> 944a593c34SDu, Changbin <rev1>...<rev2> 954a593c34SDu, Changbin <rev>-<count> 964a593c34SDu, Changbin git merges are ignored 9777f5b10aSHannes Eder -f, --file treat FILE as regular source file 9877f5b10aSHannes Eder --subjective, --strict enable more subjective tests 993beb42ecSJoe Perches --list-types list the possible message types 10091bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 101000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 1023beb42ecSJoe Perches --show-types show the specific message type in the output 103bdc48fa1SJoe Perches --max-line-length=n set the maximum line length, (default $max_line_length) 104bdc48fa1SJoe Perches if exceeded, warn on patches 105bdc48fa1SJoe Perches requires --strict for use with --file 10656193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 107bdc48fa1SJoe Perches --tab-size=n set the number of spaces for tab (default $tabsize) 10877f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 10977f5b10aSHannes Eder --no-summary suppress the per-file summary 11077f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 11177f5b10aSHannes Eder --summary-file include the filename in summary 11277f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 11377f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 11477f5b10aSHannes Eder is all off) 11577f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 11677f5b10aSHannes Eder literally 1173705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1183705ce5bSJoe Perches If correctable single-line errors exist, create 1193705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1203705ce5bSJoe Perches with potential errors corrected to the preferred 1213705ce5bSJoe Perches checkpatch style 1229624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1239624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1249624b8d6SJoe Perches file. It's your fault if there's no backup or git 125d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 126d62a201fSDave Hansen runtime errors. 127ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 128f1a63678SMaxim Uvarov (default:/usr/share/codespell/dictionary.txt) 129ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 13075ad8c57SJerome Forissier --typedefsfile Read additional types from this file 131737c0767SJohn Brooks --color[=WHEN] Use colors 'always', 'never', or only when output 132737c0767SJohn Brooks is a terminal ('auto'). Default is 'auto'. 1333e89ad85SJerome Forissier --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default 1343e89ad85SJerome Forissier ${CONFIG_}) 13577f5b10aSHannes Eder -h, --help, --version display this help and exit 13677f5b10aSHannes Eder 13777f5b10aSHannes EderWhen FILE is - read standard input. 13877f5b10aSHannes EderEOM 13977f5b10aSHannes Eder 14077f5b10aSHannes Eder exit($exitcode); 14177f5b10aSHannes Eder} 14277f5b10aSHannes Eder 1433beb42ecSJoe Perchessub uniq { 1443beb42ecSJoe Perches my %seen; 1453beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1463beb42ecSJoe Perches} 1473beb42ecSJoe Perches 1483beb42ecSJoe Perchessub list_types { 1493beb42ecSJoe Perches my ($exitcode) = @_; 1503beb42ecSJoe Perches 1513beb42ecSJoe Perches my $count = 0; 1523beb42ecSJoe Perches 1533beb42ecSJoe Perches local $/ = undef; 1543beb42ecSJoe Perches 1553beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1563beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1573beb42ecSJoe Perches 1583beb42ecSJoe Perches my $text = <$script>; 1593beb42ecSJoe Perches close($script); 1603beb42ecSJoe Perches 1613beb42ecSJoe Perches my @types = (); 1620547fa58SJean Delvare # Also catch when type or level is passed through a variable 1630547fa58SJean Delvare for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { 1643beb42ecSJoe Perches push (@types, $_); 1653beb42ecSJoe Perches } 1663beb42ecSJoe Perches @types = sort(uniq(@types)); 1673beb42ecSJoe Perches print("#\tMessage type\n\n"); 1683beb42ecSJoe Perches foreach my $type (@types) { 1693beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 1703beb42ecSJoe Perches } 1713beb42ecSJoe Perches 1723beb42ecSJoe Perches exit($exitcode); 1733beb42ecSJoe Perches} 1743beb42ecSJoe Perches 175000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 176000d1cc1SJoe Perchesif (-f $conf) { 177000d1cc1SJoe Perches my @conf_args; 178000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 179000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 180000d1cc1SJoe Perches 181000d1cc1SJoe Perches while (<$conffile>) { 182000d1cc1SJoe Perches my $line = $_; 183000d1cc1SJoe Perches 184000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 185000d1cc1SJoe Perches $line =~ s/^\s*//g; 186000d1cc1SJoe Perches $line =~ s/\s+/ /g; 187000d1cc1SJoe Perches 188000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 189000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 190000d1cc1SJoe Perches 191000d1cc1SJoe Perches my @words = split(" ", $line); 192000d1cc1SJoe Perches foreach my $word (@words) { 193000d1cc1SJoe Perches last if ($word =~ m/^#/); 194000d1cc1SJoe Perches push (@conf_args, $word); 195000d1cc1SJoe Perches } 196000d1cc1SJoe Perches } 197000d1cc1SJoe Perches close($conffile); 198000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 199000d1cc1SJoe Perches} 200000d1cc1SJoe Perches 201737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space. 202737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments 203737c0767SJohn Brooksforeach (@ARGV) { 204737c0767SJohn Brooks if ($_ eq "--color" || $_ eq "-color") { 205737c0767SJohn Brooks $_ = "--color=$color"; 206737c0767SJohn Brooks } 207737c0767SJohn Brooks} 208737c0767SJohn Brooks 2090a920b5bSAndy WhitcroftGetOptions( 2106c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 2110a920b5bSAndy Whitcroft 'tree!' => \$tree, 2120a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 2130a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 2146c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 2158905a67cSAndy Whitcroft 'terse!' => \$terse, 21634d8815fSJoe Perches 'showfile!' => \$showfile, 21777f5b10aSHannes Eder 'f|file!' => \$file, 2184a593c34SDu, Changbin 'g|git!' => \$git, 2196c72ffaaSAndy Whitcroft 'subjective!' => \$check, 2206c72ffaaSAndy Whitcroft 'strict!' => \$check, 221000d1cc1SJoe Perches 'ignore=s' => \@ignore, 22291bfe484SJoe Perches 'types=s' => \@use, 223000d1cc1SJoe Perches 'show-types!' => \$show_types, 2243beb42ecSJoe Perches 'list-types!' => \$list_types, 2256cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 22656193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 227713a09deSAntonio Borneo 'tab-size=i' => \$tabsize, 2286c72ffaaSAndy Whitcroft 'root=s' => \$root, 2298905a67cSAndy Whitcroft 'summary!' => \$summary, 2308905a67cSAndy Whitcroft 'mailback!' => \$mailback, 23113214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 2323705ce5bSJoe Perches 'fix!' => \$fix, 2339624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 234d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 235c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 236773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 237ebfd7d62SJoe Perches 'codespell!' => \$codespell, 238ebfd7d62SJoe Perches 'codespellfile=s' => \$codespellfile, 23975ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 240737c0767SJohn Brooks 'color=s' => \$color, 241737c0767SJohn Brooks 'no-color' => \$color, #keep old behaviors of -nocolor 242737c0767SJohn Brooks 'nocolor' => \$color, #keep old behaviors of -nocolor 2433e89ad85SJerome Forissier 'kconfig-prefix=s' => \${CONFIG_}, 24477f5b10aSHannes Eder 'h|help' => \$help, 24577f5b10aSHannes Eder 'version' => \$help 24677f5b10aSHannes Eder) or help(1); 24777f5b10aSHannes Eder 24877f5b10aSHannes Ederhelp(0) if ($help); 2490a920b5bSAndy Whitcroft 2503beb42ecSJoe Percheslist_types(0) if ($list_types); 2513beb42ecSJoe Perches 2529624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 2532ac73b4fSJoe Perches$check_orig = $check; 2549624b8d6SJoe Perches 25532f30ca9SJoe Perchesdie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); 25632f30ca9SJoe Perches 2570a920b5bSAndy Whitcroftmy $exit = 0; 2580a920b5bSAndy Whitcroft 2595b57980dSJoe Perchesmy $perl_version_ok = 1; 260d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 2615b57980dSJoe Perches $perl_version_ok = 0; 262d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 2635b57980dSJoe Perches exit(1) if (!$ignore_perl_version); 264d62a201fSDave Hansen} 265d62a201fSDave Hansen 26645107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 2670a920b5bSAndy Whitcroftif ($#ARGV < 0) { 26845107ff6SAllen Hubbe push(@ARGV, '-'); 2690a920b5bSAndy Whitcroft} 2700a920b5bSAndy Whitcroft 271737c0767SJohn Brooksif ($color =~ /^[01]$/) { 272737c0767SJohn Brooks $color = !$color; 273737c0767SJohn Brooks} elsif ($color =~ /^always$/i) { 274737c0767SJohn Brooks $color = 1; 275737c0767SJohn Brooks} elsif ($color =~ /^never$/i) { 276737c0767SJohn Brooks $color = 0; 277737c0767SJohn Brooks} elsif ($color =~ /^auto$/i) { 278737c0767SJohn Brooks $color = (-t STDOUT); 279737c0767SJohn Brooks} else { 28032f30ca9SJoe Perches die "$P: Invalid color mode: $color\n"; 281737c0767SJohn Brooks} 282737c0767SJohn Brooks 283713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1 28432f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); 285713a09deSAntonio Borneo 28691bfe484SJoe Perchessub hash_save_array_words { 28791bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 28891bfe484SJoe Perches 28991bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 29091bfe484SJoe Perches foreach my $word (@array) { 291000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 292000d1cc1SJoe Perches $word =~ s/^\s*//g; 293000d1cc1SJoe Perches $word =~ s/\s+/ /g; 294000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 295000d1cc1SJoe Perches 296000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 297000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 298000d1cc1SJoe Perches 29991bfe484SJoe Perches $hashRef->{$word}++; 300000d1cc1SJoe Perches } 30191bfe484SJoe Perches} 30291bfe484SJoe Perches 30391bfe484SJoe Perchessub hash_show_words { 30491bfe484SJoe Perches my ($hashRef, $prefix) = @_; 30591bfe484SJoe Perches 3063c816e49SJoe Perches if (keys %$hashRef) { 307d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 30858cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 30991bfe484SJoe Perches print " $word"; 31091bfe484SJoe Perches } 311d8469f16SJoe Perches print "\n"; 31291bfe484SJoe Perches } 31391bfe484SJoe Perches} 31491bfe484SJoe Perches 31591bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 31691bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 317000d1cc1SJoe Perches 318c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 319c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 3207429c690SAndy Whitcroftmy $dbg_type = 0; 321a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 322c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 32321caa13cSAndy Whitcroft ## no critic 32421caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 32521caa13cSAndy Whitcroft die "$@" if ($@); 326c2fdda0dSAndy Whitcroft} 327c2fdda0dSAndy Whitcroft 328d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 329d2c0a235SAndy Whitcroft 3308905a67cSAndy Whitcroftif ($terse) { 3318905a67cSAndy Whitcroft $emacs = 1; 3328905a67cSAndy Whitcroft $quiet++; 3338905a67cSAndy Whitcroft} 3348905a67cSAndy Whitcroft 3356c72ffaaSAndy Whitcroftif ($tree) { 3366c72ffaaSAndy Whitcroft if (defined $root) { 3376c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 3386c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 3396c72ffaaSAndy Whitcroft } 3406c72ffaaSAndy Whitcroft } else { 3416c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 3426c72ffaaSAndy Whitcroft $root = '.'; 3436c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 3446c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 3456c72ffaaSAndy Whitcroft $root = $1; 3466c72ffaaSAndy Whitcroft } 3476c72ffaaSAndy Whitcroft } 3486c72ffaaSAndy Whitcroft 3496c72ffaaSAndy Whitcroft if (!defined $root) { 3500a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 3510a920b5bSAndy Whitcroft exit(2); 3520a920b5bSAndy Whitcroft } 3536c72ffaaSAndy Whitcroft} 3546c72ffaaSAndy Whitcroft 3556c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 3566c72ffaaSAndy Whitcroft 3572ceb532bSAndy Whitcroftour $Ident = qr{ 3582ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 3592ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 3602ceb532bSAndy Whitcroft }x; 3616c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 3626c72ffaaSAndy Whitcroftour $Sparse = qr{ 3636c72ffaaSAndy Whitcroft __user| 3646c72ffaaSAndy Whitcroft __kernel| 3656c72ffaaSAndy Whitcroft __force| 3666c72ffaaSAndy Whitcroft __iomem| 3676c72ffaaSAndy Whitcroft __must_check| 368417495edSAndy Whitcroft __kprobes| 369165e72a6SSven Eckelmann __ref| 37033aa4597SGeert Uytterhoeven __refconst| 37133aa4597SGeert Uytterhoeven __refdata| 372ad315455SBoqun Feng __rcu| 373ad315455SBoqun Feng __private 3746c72ffaaSAndy Whitcroft }x; 375e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 376e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 377e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 378e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 379e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 3808716de38SJoe Perches 38152131292SWolfram Sang# Notes to $Attribute: 38252131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 3836c72ffaaSAndy Whitcroftour $Attribute = qr{ 3846c72ffaaSAndy Whitcroft const| 385b5e8736aSJoe Perches volatile| 38603f1df7dSJoe Perches __percpu| 38703f1df7dSJoe Perches __nocast| 38803f1df7dSJoe Perches __safe| 38946d832f5SMichael S. Tsirkin __bitwise| 39003f1df7dSJoe Perches __packed__| 39103f1df7dSJoe Perches __packed2__| 39203f1df7dSJoe Perches __naked| 39303f1df7dSJoe Perches __maybe_unused| 39403f1df7dSJoe Perches __always_unused| 39503f1df7dSJoe Perches __noreturn| 39603f1df7dSJoe Perches __used| 39703f1df7dSJoe Perches __cold| 398e23ef1f3SJoe Perches __pure| 39903f1df7dSJoe Perches __noclone| 40003f1df7dSJoe Perches __deprecated| 4016c72ffaaSAndy Whitcroft __read_mostly| 402c5967e98SJoe Perches __ro_after_init| 4036c72ffaaSAndy Whitcroft __kprobes| 4048716de38SJoe Perches $InitAttribute| 40524e1d81aSAndy Whitcroft ____cacheline_aligned| 40624e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 4075fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 4085fe3af11SAndy Whitcroft __weak 4096c72ffaaSAndy Whitcroft }x; 410c45dcabdSAndy Whitcroftour $Modifier; 41191cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 4126c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 4136c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 4146c72ffaaSAndy Whitcroft 41595e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 41695e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 41795e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 41895e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 4192435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 420c0a5c898SJoe Perchesour $String = qr{"[X\t]*"}; 421326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 422326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 423326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 42474349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 4252435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 426326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 427447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 42823f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 4296c72ffaaSAndy Whitcroftour $Operators = qr{ 4306c72ffaaSAndy Whitcroft <=|>=|==|!=| 4316c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 43223f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 4336c72ffaaSAndy Whitcroft }x; 4346c72ffaaSAndy Whitcroft 43591cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 43691cb5195SJoe Perches 437ab7e23f3SJoe Perchesour $BasicType; 4388905a67cSAndy Whitcroftour $NonptrType; 4391813087dSJoe Perchesour $NonptrTypeMisordered; 4408716de38SJoe Perchesour $NonptrTypeWithAttr; 4418905a67cSAndy Whitcroftour $Type; 4421813087dSJoe Perchesour $TypeMisordered; 4438905a67cSAndy Whitcroftour $Declare; 4441813087dSJoe Perchesour $DeclareMisordered; 4458905a67cSAndy Whitcroft 44615662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 44715662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 448171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 449171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 450171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 451171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 452171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 453171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 454171ae1a4SAndy Whitcroft}x; 455171ae1a4SAndy Whitcroft 45615662b3eSJoe Perchesour $UTF8 = qr{ 45715662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 45815662b3eSJoe Perches | $NON_ASCII_UTF8 45915662b3eSJoe Perches}x; 46015662b3eSJoe Perches 461e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 462021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 463021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 464021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 465021158b4SJoe Perches)}; 466e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 467fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 4688ed22cadSAndy Whitcroft atomic_t 4698ed22cadSAndy Whitcroft)}; 470e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 471e6176fa4SJoe Perches $typeC99Typedefs\b| 472e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 473e6176fa4SJoe Perches $typeKernelTypedefs\b 474e6176fa4SJoe Perches)}; 4758ed22cadSAndy Whitcroft 4766d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 4776d32f7a3SJoe Perches 478691e669bSJoe Perchesour $logFunctions = qr{(?x: 479758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 4807d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 48187bd499aSJoe Perches TP_printk| 4826e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 483b0531722SJoe Perches panic| 48406668727SJoe Perches MODULE_[A-Z_]+| 48506668727SJoe Perches seq_vprintf|seq_printf|seq_puts 486691e669bSJoe Perches)}; 487691e669bSJoe Perches 488e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 489e29a70f1SJoe Perches (?:(?:devm_)? 49058f02267SJoe Perches (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? | 491e29a70f1SJoe Perches kstrdup(?:_const)? | 492e29a70f1SJoe Perches kmemdup(?:_nul)?) | 493461e1565SChristophe JAILLET (?:\w+)?alloc_skb(?:_ip_align)? | 494e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 495e29a70f1SJoe Perches dma_alloc_coherent 496e29a70f1SJoe Perches)}; 497e29a70f1SJoe Perches 49820112475SJoe Perchesour $signature_tags = qr{(?xi: 49920112475SJoe Perches Signed-off-by:| 500d499480cSJorge Ramirez-Ortiz Co-developed-by:| 50120112475SJoe Perches Acked-by:| 50220112475SJoe Perches Tested-by:| 50320112475SJoe Perches Reviewed-by:| 50420112475SJoe Perches Reported-by:| 5058543ae12SMugunthan V N Suggested-by:| 50620112475SJoe Perches To:| 50720112475SJoe Perches Cc: 50820112475SJoe Perches)}; 50920112475SJoe Perches 510adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi: 511adb2da82SJoe Perches [=-]*> | 512adb2da82SJoe Perches <[=-]* | 513adb2da82SJoe Perches \[ | 514adb2da82SJoe Perches \] | 515adb2da82SJoe Perches start | 516adb2da82SJoe Perches called | 517adb2da82SJoe Perches entered | 518adb2da82SJoe Perches entry | 519adb2da82SJoe Perches enter | 520adb2da82SJoe Perches in | 521adb2da82SJoe Perches inside | 522adb2da82SJoe Perches here | 523adb2da82SJoe Perches begin | 524adb2da82SJoe Perches exit | 525adb2da82SJoe Perches end | 526adb2da82SJoe Perches done | 527adb2da82SJoe Perches leave | 528adb2da82SJoe Perches completed | 529adb2da82SJoe Perches out | 530adb2da82SJoe Perches return | 531adb2da82SJoe Perches [\.\!:\s]* 532adb2da82SJoe Perches)}; 533adb2da82SJoe Perches 534831242abSAditya Srivastavasub edit_distance_min { 535831242abSAditya Srivastava my (@arr) = @_; 536831242abSAditya Srivastava my $len = scalar @arr; 537831242abSAditya Srivastava if ((scalar @arr) < 1) { 538831242abSAditya Srivastava # if underflow, return 539831242abSAditya Srivastava return; 540831242abSAditya Srivastava } 541831242abSAditya Srivastava my $min = $arr[0]; 542831242abSAditya Srivastava for my $i (0 .. ($len-1)) { 543831242abSAditya Srivastava if ($arr[$i] < $min) { 544831242abSAditya Srivastava $min = $arr[$i]; 545831242abSAditya Srivastava } 546831242abSAditya Srivastava } 547831242abSAditya Srivastava return $min; 548831242abSAditya Srivastava} 549831242abSAditya Srivastava 550831242abSAditya Srivastavasub get_edit_distance { 551831242abSAditya Srivastava my ($str1, $str2) = @_; 552831242abSAditya Srivastava $str1 = lc($str1); 553831242abSAditya Srivastava $str2 = lc($str2); 554831242abSAditya Srivastava $str1 =~ s/-//g; 555831242abSAditya Srivastava $str2 =~ s/-//g; 556831242abSAditya Srivastava my $len1 = length($str1); 557831242abSAditya Srivastava my $len2 = length($str2); 558831242abSAditya Srivastava # two dimensional array storing minimum edit distance 559831242abSAditya Srivastava my @distance; 560831242abSAditya Srivastava for my $i (0 .. $len1) { 561831242abSAditya Srivastava for my $j (0 .. $len2) { 562831242abSAditya Srivastava if ($i == 0) { 563831242abSAditya Srivastava $distance[$i][$j] = $j; 564831242abSAditya Srivastava } elsif ($j == 0) { 565831242abSAditya Srivastava $distance[$i][$j] = $i; 566831242abSAditya Srivastava } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { 567831242abSAditya Srivastava $distance[$i][$j] = $distance[$i - 1][$j - 1]; 568831242abSAditya Srivastava } else { 569831242abSAditya Srivastava my $dist1 = $distance[$i][$j - 1]; #insert distance 570831242abSAditya Srivastava my $dist2 = $distance[$i - 1][$j]; # remove 571831242abSAditya Srivastava my $dist3 = $distance[$i - 1][$j - 1]; #replace 572831242abSAditya Srivastava $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); 573831242abSAditya Srivastava } 574831242abSAditya Srivastava } 575831242abSAditya Srivastava } 576831242abSAditya Srivastava return $distance[$len1][$len2]; 577831242abSAditya Srivastava} 578831242abSAditya Srivastava 579831242abSAditya Srivastavasub find_standard_signature { 580831242abSAditya Srivastava my ($sign_off) = @_; 581831242abSAditya Srivastava my @standard_signature_tags = ( 582831242abSAditya Srivastava 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', 583831242abSAditya Srivastava 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' 584831242abSAditya Srivastava ); 585831242abSAditya Srivastava foreach my $signature (@standard_signature_tags) { 586831242abSAditya Srivastava return $signature if (get_edit_distance($sign_off, $signature) <= 2); 587831242abSAditya Srivastava } 588831242abSAditya Srivastava 589831242abSAditya Srivastava return ""; 590831242abSAditya Srivastava} 591831242abSAditya Srivastava 5921813087dSJoe Perchesour @typeListMisordered = ( 5931813087dSJoe Perches qr{char\s+(?:un)?signed}, 5941813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 5951813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 5961813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 5971813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 5981813087dSJoe Perches qr{short\s+(?:un)?signed}, 5991813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 6001813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 6011813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 6021813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 6031813087dSJoe Perches qr{int\s+(?:un)?signed}, 6041813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 6051813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 6061813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 6071813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 6081813087dSJoe Perches qr{long\s+(?:un)?signed}, 6091813087dSJoe Perches); 6101813087dSJoe Perches 6118905a67cSAndy Whitcroftour @typeList = ( 6128905a67cSAndy Whitcroft qr{void}, 6130c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 6140c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 6150c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 6160c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 6170c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 6180c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 6190c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 6200c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 6210c773d9dSJoe Perches qr{(?:un)?signed}, 6228905a67cSAndy Whitcroft qr{float}, 6238905a67cSAndy Whitcroft qr{double}, 6248905a67cSAndy Whitcroft qr{bool}, 6258905a67cSAndy Whitcroft qr{struct\s+$Ident}, 6268905a67cSAndy Whitcroft qr{union\s+$Ident}, 6278905a67cSAndy Whitcroft qr{enum\s+$Ident}, 6288905a67cSAndy Whitcroft qr{${Ident}_t}, 6298905a67cSAndy Whitcroft qr{${Ident}_handler}, 6308905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 6311813087dSJoe Perches @typeListMisordered, 6328905a67cSAndy Whitcroft); 633938224b5SJoe Perches 634938224b5SJoe Perchesour $C90_int_types = qr{(?x: 635938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 636938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 637938224b5SJoe Perches long\s+long\s+(?:un)?signed| 638938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 639938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 640938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 641938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 642938224b5SJoe Perches 643938224b5SJoe Perches long\s+int\s+(?:un)?signed| 644938224b5SJoe Perches long\s+(?:un)?signed\s+int| 645938224b5SJoe Perches long\s+(?:un)?signed| 646938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 647938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 648938224b5SJoe Perches int\s+long\s+(?:un)?signed| 649938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 650938224b5SJoe Perches 651938224b5SJoe Perches int\s+(?:un)?signed| 652938224b5SJoe Perches (?:(?:un)?signed\s+)?int 653938224b5SJoe Perches)}; 654938224b5SJoe Perches 655485ff23eSAlex Dowadour @typeListFile = (); 6568716de38SJoe Perchesour @typeListWithAttr = ( 6578716de38SJoe Perches @typeList, 6588716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 6598716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 6608716de38SJoe Perches); 6618716de38SJoe Perches 662c45dcabdSAndy Whitcroftour @modifierList = ( 663c45dcabdSAndy Whitcroft qr{fastcall}, 664c45dcabdSAndy Whitcroft); 665485ff23eSAlex Dowadour @modifierListFile = (); 6668905a67cSAndy Whitcroft 6672435880fSJoe Perchesour @mode_permission_funcs = ( 6682435880fSJoe Perches ["module_param", 3], 6692435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 6702435880fSJoe Perches ["module_param_array_named", 5], 6712435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 6722435880fSJoe Perches ["proc_create(?:_data|)", 2], 673459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 674459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 675459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 676459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 677459cf0aeSJoe Perches ["__ATTR", 2], 6782435880fSJoe Perches); 6792435880fSJoe Perches 6801a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; 6811a3dcf2eSJoe Perches 682515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 683515a235eSJoe Perchesour $mode_perms_search = ""; 684515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 685515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 686515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 687515a235eSJoe Perches} 68800180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 689515a235eSJoe Perches 6909189c7e7SJoe Perchesour %deprecated_apis = ( 6919189c7e7SJoe Perches "synchronize_rcu_bh" => "synchronize_rcu", 6929189c7e7SJoe Perches "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 6939189c7e7SJoe Perches "call_rcu_bh" => "call_rcu", 6949189c7e7SJoe Perches "rcu_barrier_bh" => "rcu_barrier", 6959189c7e7SJoe Perches "synchronize_sched" => "synchronize_rcu", 6969189c7e7SJoe Perches "synchronize_sched_expedited" => "synchronize_rcu_expedited", 6979189c7e7SJoe Perches "call_rcu_sched" => "call_rcu", 6989189c7e7SJoe Perches "rcu_barrier_sched" => "rcu_barrier", 6999189c7e7SJoe Perches "get_state_synchronize_sched" => "get_state_synchronize_rcu", 7009189c7e7SJoe Perches "cond_synchronize_sched" => "cond_synchronize_rcu", 7019189c7e7SJoe Perches); 7029189c7e7SJoe Perches 7039189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 7049189c7e7SJoe Perchesour $deprecated_apis_search = ""; 7059189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 7069189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 7079189c7e7SJoe Perches $deprecated_apis_search .= $entry; 7089189c7e7SJoe Perches} 7099189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 7109189c7e7SJoe Perches 711b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 712b392c64fSJoe Perches S_IWUGO | 713b392c64fSJoe Perches S_IWOTH | 714b392c64fSJoe Perches S_IRWXUGO | 715b392c64fSJoe Perches S_IALLUGO | 716b392c64fSJoe Perches 0[0-7][0-7][2367] 717b392c64fSJoe Perches}x; 718b392c64fSJoe Perches 719f90774e1SJoe Perchesour %mode_permission_string_types = ( 720f90774e1SJoe Perches "S_IRWXU" => 0700, 721f90774e1SJoe Perches "S_IRUSR" => 0400, 722f90774e1SJoe Perches "S_IWUSR" => 0200, 723f90774e1SJoe Perches "S_IXUSR" => 0100, 724f90774e1SJoe Perches "S_IRWXG" => 0070, 725f90774e1SJoe Perches "S_IRGRP" => 0040, 726f90774e1SJoe Perches "S_IWGRP" => 0020, 727f90774e1SJoe Perches "S_IXGRP" => 0010, 728f90774e1SJoe Perches "S_IRWXO" => 0007, 729f90774e1SJoe Perches "S_IROTH" => 0004, 730f90774e1SJoe Perches "S_IWOTH" => 0002, 731f90774e1SJoe Perches "S_IXOTH" => 0001, 732f90774e1SJoe Perches "S_IRWXUGO" => 0777, 733f90774e1SJoe Perches "S_IRUGO" => 0444, 734f90774e1SJoe Perches "S_IWUGO" => 0222, 735f90774e1SJoe Perches "S_IXUGO" => 0111, 736f90774e1SJoe Perches); 737f90774e1SJoe Perches 738f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 739f90774e1SJoe Perchesour $mode_perms_string_search = ""; 740f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 741f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 742f90774e1SJoe Perches $mode_perms_string_search .= $entry; 743f90774e1SJoe Perches} 74400180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 74500180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 74600180468SJoe Perches ${single_mode_perms_string_search} 74700180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 74800180468SJoe Perches}x; 74900180468SJoe Perches 75000180468SJoe Perchessub perms_to_octal { 75100180468SJoe Perches my ($string) = @_; 75200180468SJoe Perches 75300180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 75400180468SJoe Perches 75500180468SJoe Perches my $val = ""; 75600180468SJoe Perches my $oval = ""; 75700180468SJoe Perches my $to = 0; 75800180468SJoe Perches my $curpos = 0; 75900180468SJoe Perches my $lastpos = 0; 76000180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 76100180468SJoe Perches $curpos = pos($string); 76200180468SJoe Perches my $match = $2; 76300180468SJoe Perches my $omatch = $1; 76400180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 76500180468SJoe Perches $lastpos = $curpos; 76600180468SJoe Perches $to |= $mode_permission_string_types{$match}; 76700180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 76800180468SJoe Perches $val .= $match; 76900180468SJoe Perches $oval .= $omatch; 77000180468SJoe Perches } 77100180468SJoe Perches $oval =~ s/^\s*\|\s*//; 77200180468SJoe Perches $oval =~ s/\s*\|\s*$//; 77300180468SJoe Perches return sprintf("%04o", $to); 77400180468SJoe Perches} 775f90774e1SJoe Perches 7767840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 7777840a94cSWolfram Sang irq| 778cdcee686SSergey Ryazanov memory| 779cdcee686SSergey Ryazanov time| 780cdcee686SSergey Ryazanov reboot 7817840a94cSWolfram Sang)}; 7827840a94cSWolfram Sang# memory.h: ARM has a custom one 7837840a94cSWolfram Sang 78466b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 78566b47b4aSKees Cookmy $misspellings; 78666b47b4aSKees Cookmy %spelling_fix; 78736061e38SJoe Perches 78836061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 78966b47b4aSKees Cook while (<$spelling>) { 79066b47b4aSKees Cook my $line = $_; 79166b47b4aSKees Cook 79266b47b4aSKees Cook $line =~ s/\s*\n?$//g; 79366b47b4aSKees Cook $line =~ s/^\s*//g; 79466b47b4aSKees Cook 79566b47b4aSKees Cook next if ($line =~ m/^\s*#/); 79666b47b4aSKees Cook next if ($line =~ m/^\s*$/); 79766b47b4aSKees Cook 79866b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 79966b47b4aSKees Cook 80066b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 80166b47b4aSKees Cook } 80266b47b4aSKees Cook close($spelling); 80336061e38SJoe Perches} else { 80436061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 80536061e38SJoe Perches} 80666b47b4aSKees Cook 807ebfd7d62SJoe Perchesif ($codespell) { 808ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 809ebfd7d62SJoe Perches while (<$spelling>) { 810ebfd7d62SJoe Perches my $line = $_; 811ebfd7d62SJoe Perches 812ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 813ebfd7d62SJoe Perches $line =~ s/^\s*//g; 814ebfd7d62SJoe Perches 815ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 816ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 817ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 818ebfd7d62SJoe Perches 819ebfd7d62SJoe Perches $line =~ s/,.*$//; 820ebfd7d62SJoe Perches 821ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 822ebfd7d62SJoe Perches 823ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 824ebfd7d62SJoe Perches } 825ebfd7d62SJoe Perches close($spelling); 826ebfd7d62SJoe Perches } else { 827ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 828ebfd7d62SJoe Perches } 829ebfd7d62SJoe Perches} 830ebfd7d62SJoe Perches 831ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 832ebfd7d62SJoe Perches 83375ad8c57SJerome Forissiersub read_words { 83475ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 83575ad8c57SJerome Forissier 83675ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 83775ad8c57SJerome Forissier while (<$words>) { 838bf1fa1daSJoe Perches my $line = $_; 839bf1fa1daSJoe Perches 840bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 841bf1fa1daSJoe Perches $line =~ s/^\s*//g; 842bf1fa1daSJoe Perches 843bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 844bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 845bf1fa1daSJoe Perches if ($line =~ /\s/) { 84675ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 847bf1fa1daSJoe Perches next; 848bf1fa1daSJoe Perches } 849bf1fa1daSJoe Perches 850ced69da1SQuentin Monnet $$wordsRef .= '|' if (defined $$wordsRef); 85175ad8c57SJerome Forissier $$wordsRef .= $line; 852bf1fa1daSJoe Perches } 85375ad8c57SJerome Forissier close($file); 85475ad8c57SJerome Forissier return 1; 855bf1fa1daSJoe Perches } 856bf1fa1daSJoe Perches 85775ad8c57SJerome Forissier return 0; 85875ad8c57SJerome Forissier} 85975ad8c57SJerome Forissier 860ced69da1SQuentin Monnetmy $const_structs; 861ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) { 86275ad8c57SJerome Forissier read_words(\$const_structs, $conststructsfile) 86375ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 864ced69da1SQuentin Monnet} 86575ad8c57SJerome Forissier 866ced69da1SQuentin Monnetif (defined($typedefsfile)) { 867ced69da1SQuentin Monnet my $typeOtherTypedefs; 86875ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 86975ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 870ced69da1SQuentin Monnet $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); 87175ad8c57SJerome Forissier} 87275ad8c57SJerome Forissier 8738905a67cSAndy Whitcroftsub build_types { 874485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 875485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 8761813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 8778716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 878c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 879ab7e23f3SJoe Perches $BasicType = qr{ 880ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 881ab7e23f3SJoe Perches (?:${all}\b) 882ab7e23f3SJoe Perches }x; 8838905a67cSAndy Whitcroft $NonptrType = qr{ 884d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 885cf655043SAndy Whitcroft (?: 8866b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 8878ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 888c45dcabdSAndy Whitcroft (?:${all}\b) 889cf655043SAndy Whitcroft ) 890c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 8918905a67cSAndy Whitcroft }x; 8921813087dSJoe Perches $NonptrTypeMisordered = qr{ 8931813087dSJoe Perches (?:$Modifier\s+|const\s+)* 8941813087dSJoe Perches (?: 8951813087dSJoe Perches (?:${Misordered}\b) 8961813087dSJoe Perches ) 8971813087dSJoe Perches (?:\s+$Modifier|\s+const)* 8981813087dSJoe Perches }x; 8998716de38SJoe Perches $NonptrTypeWithAttr = qr{ 9008716de38SJoe Perches (?:$Modifier\s+|const\s+)* 9018716de38SJoe Perches (?: 9028716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 9038716de38SJoe Perches (?:$typeTypedefs\b)| 9048716de38SJoe Perches (?:${allWithAttr}\b) 9058716de38SJoe Perches ) 9068716de38SJoe Perches (?:\s+$Modifier|\s+const)* 9078716de38SJoe Perches }x; 9088905a67cSAndy Whitcroft $Type = qr{ 909c45dcabdSAndy Whitcroft $NonptrType 9107b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 911c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 9128905a67cSAndy Whitcroft }x; 9131813087dSJoe Perches $TypeMisordered = qr{ 9141813087dSJoe Perches $NonptrTypeMisordered 9157b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 9161813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 9171813087dSJoe Perches }x; 91891cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 9191813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 9208905a67cSAndy Whitcroft} 9218905a67cSAndy Whitcroftbuild_types(); 9226c72ffaaSAndy Whitcroft 9237d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 924d1fe9c09SJoe Perches 925d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 926d1fe9c09SJoe Perches# requires at least perl version v5.10.0 927d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 928d1fe9c09SJoe Perches 929d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 9302435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 931c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 9327d2367afSJoe Perches 933f8422308SJoe Perchesour $declaration_macros = qr{(?x: 9343e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 935fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 9363d102fc0SGilad Ben-Yossef (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( 937f8422308SJoe Perches)}; 938f8422308SJoe Perches 9398d0325ccSAditya Srivastavaour %allow_repeated_words = ( 9408d0325ccSAditya Srivastava add => '', 9418d0325ccSAditya Srivastava added => '', 9428d0325ccSAditya Srivastava bad => '', 9438d0325ccSAditya Srivastava be => '', 9448d0325ccSAditya Srivastava); 9458d0325ccSAditya Srivastava 9467d2367afSJoe Perchessub deparenthesize { 9477d2367afSJoe Perches my ($string) = @_; 9487d2367afSJoe Perches return "" if (!defined($string)); 9495b9553abSJoe Perches 9505b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 9515b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 9525b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 9535b9553abSJoe Perches } 9545b9553abSJoe Perches 9557d2367afSJoe Perches $string =~ s@\s+@ @g; 9565b9553abSJoe Perches 9577d2367afSJoe Perches return $string; 9587d2367afSJoe Perches} 9597d2367afSJoe Perches 9603445686aSJoe Perchessub seed_camelcase_file { 9613445686aSJoe Perches my ($file) = @_; 9623445686aSJoe Perches 9633445686aSJoe Perches return if (!(-f $file)); 9643445686aSJoe Perches 9653445686aSJoe Perches local $/; 9663445686aSJoe Perches 9673445686aSJoe Perches open(my $include_file, '<', "$file") 9683445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 9693445686aSJoe Perches my $text = <$include_file>; 9703445686aSJoe Perches close($include_file); 9713445686aSJoe Perches 9723445686aSJoe Perches my @lines = split('\n', $text); 9733445686aSJoe Perches 9743445686aSJoe Perches foreach my $line (@lines) { 9753445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 9763445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 9773445686aSJoe Perches $camelcase{$1} = 1; 97811ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 97911ea516aSJoe Perches $camelcase{$1} = 1; 98011ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 9813445686aSJoe Perches $camelcase{$1} = 1; 9823445686aSJoe Perches } 9833445686aSJoe Perches } 9843445686aSJoe Perches} 9853445686aSJoe Perches 986cd28b119SJoe Perchesour %maintained_status = (); 987cd28b119SJoe Perches 98885b0ee18SJoe Perchessub is_maintained_obsolete { 98985b0ee18SJoe Perches my ($filename) = @_; 99085b0ee18SJoe Perches 991f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 99285b0ee18SJoe Perches 993cd28b119SJoe Perches if (!exists($maintained_status{$filename})) { 994cd28b119SJoe Perches $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 995cd28b119SJoe Perches } 99685b0ee18SJoe Perches 997cd28b119SJoe Perches return $maintained_status{$filename} =~ /obsolete/i; 99885b0ee18SJoe Perches} 99985b0ee18SJoe Perches 10003b6e8ac9SJoe Perchessub is_SPDX_License_valid { 10013b6e8ac9SJoe Perches my ($license) = @_; 10023b6e8ac9SJoe Perches 10030f7f635bSJoe Perches return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); 10043b6e8ac9SJoe Perches 100556294112SJoe Perches my $root_path = abs_path($root); 100656294112SJoe Perches my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`; 10073b6e8ac9SJoe Perches return 0 if ($status ne ""); 10083b6e8ac9SJoe Perches return 1; 10093b6e8ac9SJoe Perches} 10103b6e8ac9SJoe Perches 10113445686aSJoe Perchesmy $camelcase_seeded = 0; 10123445686aSJoe Perchessub seed_camelcase_includes { 10133445686aSJoe Perches return if ($camelcase_seeded); 10143445686aSJoe Perches 10153445686aSJoe Perches my $files; 1016c707a81dSJoe Perches my $camelcase_cache = ""; 1017c707a81dSJoe Perches my @include_files = (); 1018c707a81dSJoe Perches 1019c707a81dSJoe Perches $camelcase_seeded = 1; 1020351b2a1fSJoe Perches 10210f7f635bSJoe Perches if (-e "$gitroot") { 1022dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 1023351b2a1fSJoe Perches chomp $git_last_include_commit; 1024c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 1025c707a81dSJoe Perches } else { 1026c707a81dSJoe Perches my $last_mod_date = 0; 1027c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 1028c707a81dSJoe Perches @include_files = split('\n', $files); 1029c707a81dSJoe Perches foreach my $file (@include_files) { 1030c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 1031c707a81dSJoe Perches localtime((stat $file)[9])); 1032c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 1033c707a81dSJoe Perches } 1034c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 1035c707a81dSJoe Perches } 1036c707a81dSJoe Perches 1037c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 1038c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 1039c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 1040351b2a1fSJoe Perches while (<$camelcase_file>) { 1041351b2a1fSJoe Perches chomp; 1042351b2a1fSJoe Perches $camelcase{$_} = 1; 1043351b2a1fSJoe Perches } 1044351b2a1fSJoe Perches close($camelcase_file); 1045351b2a1fSJoe Perches 1046351b2a1fSJoe Perches return; 1047351b2a1fSJoe Perches } 1048c707a81dSJoe Perches 10490f7f635bSJoe Perches if (-e "$gitroot") { 1050dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 1051c707a81dSJoe Perches @include_files = split('\n', $files); 10523445686aSJoe Perches } 1053c707a81dSJoe Perches 10543445686aSJoe Perches foreach my $file (@include_files) { 10553445686aSJoe Perches seed_camelcase_file($file); 10563445686aSJoe Perches } 1057351b2a1fSJoe Perches 1058c707a81dSJoe Perches if ($camelcase_cache ne "") { 1059351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 1060c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 1061c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 1062351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 1063351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 1064351b2a1fSJoe Perches } 1065351b2a1fSJoe Perches close($camelcase_file); 1066351b2a1fSJoe Perches } 10673445686aSJoe Perches} 10683445686aSJoe Perches 1069f5f61325SJoe Perchessub git_is_single_file { 1070f5f61325SJoe Perches my ($filename) = @_; 1071f5f61325SJoe Perches 1072f5f61325SJoe Perches return 0 if ((which("git") eq "") || !(-e "$gitroot")); 1073f5f61325SJoe Perches 1074f5f61325SJoe Perches my $output = `${git_command} ls-files -- $filename 2>/dev/null`; 1075f5f61325SJoe Perches my $count = $output =~ tr/\n//; 1076f5f61325SJoe Perches return $count eq 1 && $output =~ m{^${filename}$}; 1077f5f61325SJoe Perches} 1078f5f61325SJoe Perches 1079d311cd44SJoe Perchessub git_commit_info { 1080d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 1081d311cd44SJoe Perches 10820f7f635bSJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); 1083d311cd44SJoe Perches 1084dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 1085d311cd44SJoe Perches $output =~ s/^\s*//gm; 1086d311cd44SJoe Perches my @lines = split("\n", $output); 1087d311cd44SJoe Perches 10880d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 10890d7835fcSJoe Perches 10905a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 1091d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 1092d311cd44SJoe Perches# all matching commit ids, but it's very slow... 1093d311cd44SJoe Perches# 1094d311cd44SJoe Perches# echo "checking commits $1..." 1095d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 1096d311cd44SJoe Perches# while read line ; do 1097d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 1098d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 1099d311cd44SJoe Perches# done 1100d311cd44SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { 1101948b133aSHeinrich Schuchardt $id = undef; 1102d311cd44SJoe Perches } else { 1103d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 1104d311cd44SJoe Perches $desc = substr($lines[0], 41); 1105d311cd44SJoe Perches } 1106d311cd44SJoe Perches 1107d311cd44SJoe Perches return ($id, $desc); 1108d311cd44SJoe Perches} 1109d311cd44SJoe Perches 11106c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 11110a920b5bSAndy Whitcroft 111200df344fSAndy Whitcroftmy @rawlines = (); 1113c2fdda0dSAndy Whitcroftmy @lines = (); 11143705ce5bSJoe Perchesmy @fixed = (); 1115d752fcc8SJoe Perchesmy @fixed_inserted = (); 1116d752fcc8SJoe Perchesmy @fixed_deleted = (); 1117194f66fcSJoe Perchesmy $fixlinenr = -1; 1118194f66fcSJoe Perches 11194a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 11204a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 11210f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot"); 11224a593c34SDu, Changbin 11234a593c34SDu, Changbinif ($git) { 11244a593c34SDu, Changbin my @commits = (); 11250dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 11264a593c34SDu, Changbin my $git_range; 112728898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 112828898fd1SJoe Perches $git_range = "-$2 $1"; 11294a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 11304a593c34SDu, Changbin $git_range = "$commit_expr"; 11314a593c34SDu, Changbin } else { 11320dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 11330dea9f1eSJoe Perches } 1134dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 11350dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 113628898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 113728898fd1SJoe Perches next if (!defined($1) || !defined($2)); 11380dea9f1eSJoe Perches my $sha1 = $1; 11390dea9f1eSJoe Perches my $subject = $2; 11400dea9f1eSJoe Perches unshift(@commits, $sha1); 11410dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 11424a593c34SDu, Changbin } 11434a593c34SDu, Changbin } 11444a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 11454a593c34SDu, Changbin @ARGV = @commits; 11464a593c34SDu, Changbin} 11474a593c34SDu, Changbin 1148c2fdda0dSAndy Whitcroftmy $vname; 114998005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 11506c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 115121caa13cSAndy Whitcroft my $FILE; 1152f5f61325SJoe Perches my $is_git_file = git_is_single_file($filename); 1153f5f61325SJoe Perches my $oldfile = $file; 1154f5f61325SJoe Perches $file = 1 if ($is_git_file); 11554a593c34SDu, Changbin if ($git) { 11564a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 11574a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 11584a593c34SDu, Changbin } elsif ($file) { 115921caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 11606c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 116121caa13cSAndy Whitcroft } elsif ($filename eq '-') { 116221caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 11636c72ffaaSAndy Whitcroft } else { 116421caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 11656c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 11666c72ffaaSAndy Whitcroft } 1167c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1168c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 11694a593c34SDu, Changbin } elsif ($git) { 11700dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1171c2fdda0dSAndy Whitcroft } else { 1172c2fdda0dSAndy Whitcroft $vname = $filename; 1173c2fdda0dSAndy Whitcroft } 117421caa13cSAndy Whitcroft while (<$FILE>) { 11750a920b5bSAndy Whitcroft chomp; 117600df344fSAndy Whitcroft push(@rawlines, $_); 1177c7f574d0SGeert Uytterhoeven $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); 11786c72ffaaSAndy Whitcroft } 117921caa13cSAndy Whitcroft close($FILE); 1180d8469f16SJoe Perches 1181d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1182d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1183d8469f16SJoe Perches print "$vname\n"; 1184d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1185d8469f16SJoe Perches } 1186d8469f16SJoe Perches 1187c2fdda0dSAndy Whitcroft if (!process($filename)) { 11880a920b5bSAndy Whitcroft $exit = 1; 11890a920b5bSAndy Whitcroft } 119000df344fSAndy Whitcroft @rawlines = (); 119113214adfSAndy Whitcroft @lines = (); 11923705ce5bSJoe Perches @fixed = (); 1193d752fcc8SJoe Perches @fixed_inserted = (); 1194d752fcc8SJoe Perches @fixed_deleted = (); 1195194f66fcSJoe Perches $fixlinenr = -1; 1196485ff23eSAlex Dowad @modifierListFile = (); 1197485ff23eSAlex Dowad @typeListFile = (); 1198485ff23eSAlex Dowad build_types(); 1199f5f61325SJoe Perches $file = $oldfile if ($is_git_file); 12000a920b5bSAndy Whitcroft} 12010a920b5bSAndy Whitcroft 1202d8469f16SJoe Perchesif (!$quiet) { 12033c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 12043c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 12053c816e49SJoe Perches 12065b57980dSJoe Perches if (!$perl_version_ok) { 1207d8469f16SJoe Perches print << "EOM" 1208d8469f16SJoe Perches 1209d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 12105b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1211d8469f16SJoe PerchesEOM 1212d8469f16SJoe Perches } 1213d8469f16SJoe Perches if ($exit) { 1214d8469f16SJoe Perches print << "EOM" 1215d8469f16SJoe Perches 1216d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1217d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1218d8469f16SJoe PerchesEOM 1219d8469f16SJoe Perches } 1220d8469f16SJoe Perches} 1221d8469f16SJoe Perches 12220a920b5bSAndy Whitcroftexit($exit); 12230a920b5bSAndy Whitcroft 12240a920b5bSAndy Whitcroftsub top_of_kernel_tree { 12256c72ffaaSAndy Whitcroft my ($root) = @_; 12266c72ffaaSAndy Whitcroft 12276c72ffaaSAndy Whitcroft my @tree_check = ( 12286c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 12296c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 12306c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 12316c72ffaaSAndy Whitcroft ); 12326c72ffaaSAndy Whitcroft 12336c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 12346c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 12350a920b5bSAndy Whitcroft return 0; 12360a920b5bSAndy Whitcroft } 12376c72ffaaSAndy Whitcroft } 12386c72ffaaSAndy Whitcroft return 1; 12396c72ffaaSAndy Whitcroft} 12400a920b5bSAndy Whitcroft 124120112475SJoe Perchessub parse_email { 124220112475SJoe Perches my ($formatted_email) = @_; 124320112475SJoe Perches 124420112475SJoe Perches my $name = ""; 1245fccaebf0SDwaipayan Ray my $quoted = ""; 1246dfa05c28SJoe Perches my $name_comment = ""; 124720112475SJoe Perches my $address = ""; 124820112475SJoe Perches my $comment = ""; 124920112475SJoe Perches 125020112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 125120112475SJoe Perches $name = $1; 125220112475SJoe Perches $address = $2; 125320112475SJoe Perches $comment = $3 if defined $3; 125420112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 125520112475SJoe Perches $address = $1; 125620112475SJoe Perches $comment = $2 if defined $2; 125720112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 125820112475SJoe Perches $address = $1; 125920112475SJoe Perches $comment = $2 if defined $2; 126085e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 126120112475SJoe Perches $name = $formatted_email; 12623705ce5bSJoe Perches $name = trim($name); 126320112475SJoe Perches $name =~ s/^\"|\"$//g; 126420112475SJoe Perches # If there's a name left after stripping spaces and 126520112475SJoe Perches # leading quotes, and the address doesn't have both 126620112475SJoe Perches # leading and trailing angle brackets, the address 126720112475SJoe Perches # is invalid. ie: 126820112475SJoe Perches # "joe smith [email protected]" bad 126920112475SJoe Perches # "joe smith <[email protected]" bad 127020112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 127120112475SJoe Perches $name = ""; 127220112475SJoe Perches $address = ""; 127320112475SJoe Perches $comment = ""; 127420112475SJoe Perches } 127520112475SJoe Perches } 127620112475SJoe Perches 1277fccaebf0SDwaipayan Ray # Extract comments from names excluding quoted parts 1278fccaebf0SDwaipayan Ray # "John D. (Doe)" - Do not extract 1279fccaebf0SDwaipayan Ray if ($name =~ s/\"(.+)\"//) { 1280fccaebf0SDwaipayan Ray $quoted = $1; 1281dfa05c28SJoe Perches } 1282fccaebf0SDwaipayan Ray while ($name =~ s/\s*($balanced_parens)\s*/ /) { 1283fccaebf0SDwaipayan Ray $name_comment .= trim($1); 1284fccaebf0SDwaipayan Ray } 1285fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 1286fccaebf0SDwaipayan Ray $name = trim("$quoted $name"); 1287fccaebf0SDwaipayan Ray 12883705ce5bSJoe Perches $address = trim($address); 128920112475SJoe Perches $address =~ s/^\<|\>$//g; 1290fccaebf0SDwaipayan Ray $comment = trim($comment); 129120112475SJoe Perches 129220112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 129320112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 129420112475SJoe Perches $name = "\"$name\""; 129520112475SJoe Perches } 129620112475SJoe Perches 1297dfa05c28SJoe Perches return ($name, $name_comment, $address, $comment); 129820112475SJoe Perches} 129920112475SJoe Perches 130020112475SJoe Perchessub format_email { 130148ca2d8aSDwaipayan Ray my ($name, $name_comment, $address, $comment) = @_; 130220112475SJoe Perches 130320112475SJoe Perches my $formatted_email; 130420112475SJoe Perches 1305fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 13063705ce5bSJoe Perches $address = trim($address); 1307fccaebf0SDwaipayan Ray $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes 130820112475SJoe Perches 130920112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 131020112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 131120112475SJoe Perches $name = "\"$name\""; 131220112475SJoe Perches } 131320112475SJoe Perches 1314fccaebf0SDwaipayan Ray $name_comment = trim($name_comment); 1315fccaebf0SDwaipayan Ray $name_comment = " $name_comment" if ($name_comment ne ""); 1316fccaebf0SDwaipayan Ray $comment = trim($comment); 1317fccaebf0SDwaipayan Ray $comment = " $comment" if ($comment ne ""); 1318fccaebf0SDwaipayan Ray 131920112475SJoe Perches if ("$name" eq "") { 132020112475SJoe Perches $formatted_email = "$address"; 132120112475SJoe Perches } else { 132248ca2d8aSDwaipayan Ray $formatted_email = "$name$name_comment <$address>"; 132320112475SJoe Perches } 132448ca2d8aSDwaipayan Ray $formatted_email .= "$comment"; 132520112475SJoe Perches return $formatted_email; 132620112475SJoe Perches} 132720112475SJoe Perches 1328dfa05c28SJoe Perchessub reformat_email { 1329dfa05c28SJoe Perches my ($email) = @_; 1330dfa05c28SJoe Perches 1331dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 133248ca2d8aSDwaipayan Ray return format_email($email_name, $name_comment, $email_address, $comment); 1333dfa05c28SJoe Perches} 1334dfa05c28SJoe Perches 1335dfa05c28SJoe Perchessub same_email_addresses { 1336fccaebf0SDwaipayan Ray my ($email1, $email2) = @_; 1337dfa05c28SJoe Perches 1338dfa05c28SJoe Perches my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); 1339dfa05c28SJoe Perches my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); 1340dfa05c28SJoe Perches 134148ca2d8aSDwaipayan Ray return $email1_name eq $email2_name && 134248ca2d8aSDwaipayan Ray $email1_address eq $email2_address && 134348ca2d8aSDwaipayan Ray $name1_comment eq $name2_comment && 134448ca2d8aSDwaipayan Ray $comment1 eq $comment2; 134548ca2d8aSDwaipayan Ray} 1346dfa05c28SJoe Perches 1347d311cd44SJoe Perchessub which { 1348d311cd44SJoe Perches my ($bin) = @_; 1349d311cd44SJoe Perches 1350d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1351d311cd44SJoe Perches if (-e "$path/$bin") { 1352d311cd44SJoe Perches return "$path/$bin"; 1353d311cd44SJoe Perches } 1354d311cd44SJoe Perches } 1355d311cd44SJoe Perches 1356d311cd44SJoe Perches return ""; 1357d311cd44SJoe Perches} 1358d311cd44SJoe Perches 1359000d1cc1SJoe Perchessub which_conf { 1360000d1cc1SJoe Perches my ($conf) = @_; 1361000d1cc1SJoe Perches 1362000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1363000d1cc1SJoe Perches if (-e "$path/$conf") { 1364000d1cc1SJoe Perches return "$path/$conf"; 1365000d1cc1SJoe Perches } 1366000d1cc1SJoe Perches } 1367000d1cc1SJoe Perches 1368000d1cc1SJoe Perches return ""; 1369000d1cc1SJoe Perches} 1370000d1cc1SJoe Perches 13710a920b5bSAndy Whitcroftsub expand_tabs { 13720a920b5bSAndy Whitcroft my ($str) = @_; 13730a920b5bSAndy Whitcroft 13740a920b5bSAndy Whitcroft my $res = ''; 13750a920b5bSAndy Whitcroft my $n = 0; 13760a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 13770a920b5bSAndy Whitcroft if ($c eq "\t") { 13780a920b5bSAndy Whitcroft $res .= ' '; 13790a920b5bSAndy Whitcroft $n++; 1380713a09deSAntonio Borneo for (; ($n % $tabsize) != 0; $n++) { 13810a920b5bSAndy Whitcroft $res .= ' '; 13820a920b5bSAndy Whitcroft } 13830a920b5bSAndy Whitcroft next; 13840a920b5bSAndy Whitcroft } 13850a920b5bSAndy Whitcroft $res .= $c; 13860a920b5bSAndy Whitcroft $n++; 13870a920b5bSAndy Whitcroft } 13880a920b5bSAndy Whitcroft 13890a920b5bSAndy Whitcroft return $res; 13900a920b5bSAndy Whitcroft} 13916c72ffaaSAndy Whitcroftsub copy_spacing { 1392773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 13936c72ffaaSAndy Whitcroft return $res; 13946c72ffaaSAndy Whitcroft} 13950a920b5bSAndy Whitcroft 13964a0df2efSAndy Whitcroftsub line_stats { 13974a0df2efSAndy Whitcroft my ($line) = @_; 13984a0df2efSAndy Whitcroft 13994a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 14004a0df2efSAndy Whitcroft $line =~ s/^.//; 14014a0df2efSAndy Whitcroft $line = expand_tabs($line); 14024a0df2efSAndy Whitcroft 14034a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 14044a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 14054a0df2efSAndy Whitcroft 14064a0df2efSAndy Whitcroft return (length($line), length($white)); 14074a0df2efSAndy Whitcroft} 14084a0df2efSAndy Whitcroft 1409773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1410773647a0SAndy Whitcroft 1411773647a0SAndy Whitcroftsub sanitise_line_reset { 1412773647a0SAndy Whitcroft my ($in_comment) = @_; 1413773647a0SAndy Whitcroft 1414773647a0SAndy Whitcroft if ($in_comment) { 1415773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1416773647a0SAndy Whitcroft } else { 1417773647a0SAndy Whitcroft $sanitise_quote = ''; 1418773647a0SAndy Whitcroft } 1419773647a0SAndy Whitcroft} 142000df344fSAndy Whitcroftsub sanitise_line { 142100df344fSAndy Whitcroft my ($line) = @_; 142200df344fSAndy Whitcroft 142300df344fSAndy Whitcroft my $res = ''; 142400df344fSAndy Whitcroft my $l = ''; 142500df344fSAndy Whitcroft 1426c2fdda0dSAndy Whitcroft my $qlen = 0; 1427773647a0SAndy Whitcroft my $off = 0; 1428773647a0SAndy Whitcroft my $c; 142900df344fSAndy Whitcroft 1430773647a0SAndy Whitcroft # Always copy over the diff marker. 1431773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1432773647a0SAndy Whitcroft 1433773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1434773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1435773647a0SAndy Whitcroft 14368d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1437773647a0SAndy Whitcroft # and end, all to $;. 1438773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1439773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1440773647a0SAndy Whitcroft 1441773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1442773647a0SAndy Whitcroft $off++; 144300df344fSAndy Whitcroft next; 1444773647a0SAndy Whitcroft } 144581bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1446773647a0SAndy Whitcroft $sanitise_quote = ''; 1447773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1448773647a0SAndy Whitcroft $off++; 1449773647a0SAndy Whitcroft next; 1450773647a0SAndy Whitcroft } 1451113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1452113f04a8SDaniel Walker $sanitise_quote = '//'; 1453113f04a8SDaniel Walker 1454113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1455113f04a8SDaniel Walker $off++; 1456113f04a8SDaniel Walker next; 1457113f04a8SDaniel Walker } 1458773647a0SAndy Whitcroft 1459773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1460773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1461773647a0SAndy Whitcroft $c eq "\\") { 1462773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1463773647a0SAndy Whitcroft $off++; 1464773647a0SAndy Whitcroft next; 1465773647a0SAndy Whitcroft } 1466773647a0SAndy Whitcroft # Regular quotes. 1467773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1468773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1469773647a0SAndy Whitcroft $sanitise_quote = $c; 1470773647a0SAndy Whitcroft 1471773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1472773647a0SAndy Whitcroft next; 1473773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1474773647a0SAndy Whitcroft $sanitise_quote = ''; 147500df344fSAndy Whitcroft } 147600df344fSAndy Whitcroft } 1477773647a0SAndy Whitcroft 1478fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1479773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1480773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1481113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1482113f04a8SDaniel Walker substr($res, $off, 1, $;); 1483773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1484773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 148500df344fSAndy Whitcroft } else { 1486773647a0SAndy Whitcroft substr($res, $off, 1, $c); 148700df344fSAndy Whitcroft } 1488c2fdda0dSAndy Whitcroft } 1489c2fdda0dSAndy Whitcroft 1490113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1491113f04a8SDaniel Walker $sanitise_quote = ''; 1492113f04a8SDaniel Walker } 1493113f04a8SDaniel Walker 1494c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1495c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1496c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1497c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1498c2fdda0dSAndy Whitcroft 1499c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1500c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1501c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1502c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1503c2fdda0dSAndy Whitcroft } 1504c2fdda0dSAndy Whitcroft 1505dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1506dadf680dSJoe Perches my $match = $1; 1507dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1508dadf680dSJoe Perches } 1509dadf680dSJoe Perches 151000df344fSAndy Whitcroft return $res; 151100df344fSAndy Whitcroft} 151200df344fSAndy Whitcroft 1513a6962d72SJoe Perchessub get_quoted_string { 1514a6962d72SJoe Perches my ($line, $rawline) = @_; 1515a6962d72SJoe Perches 1516478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 151733acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1518a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1519a6962d72SJoe Perches} 1520a6962d72SJoe Perches 15218905a67cSAndy Whitcroftsub ctx_statement_block { 15228905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 15238905a67cSAndy Whitcroft my $line = $linenr - 1; 15248905a67cSAndy Whitcroft my $blk = ''; 15258905a67cSAndy Whitcroft my $soff = $off; 15268905a67cSAndy Whitcroft my $coff = $off - 1; 1527773647a0SAndy Whitcroft my $coff_set = 0; 15288905a67cSAndy Whitcroft 152913214adfSAndy Whitcroft my $loff = 0; 153013214adfSAndy Whitcroft 15318905a67cSAndy Whitcroft my $type = ''; 15328905a67cSAndy Whitcroft my $level = 0; 1533a2750645SAndy Whitcroft my @stack = (); 1534cf655043SAndy Whitcroft my $p; 15358905a67cSAndy Whitcroft my $c; 15368905a67cSAndy Whitcroft my $len = 0; 153713214adfSAndy Whitcroft 153813214adfSAndy Whitcroft my $remainder; 15398905a67cSAndy Whitcroft while (1) { 1540a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1541a2750645SAndy Whitcroft 1542773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 15438905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 15448905a67cSAndy Whitcroft # context. 15458905a67cSAndy Whitcroft if ($off >= $len) { 15468905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1547dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1548c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 15498905a67cSAndy Whitcroft $remain--; 155013214adfSAndy Whitcroft $loff = $len; 1551c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 15528905a67cSAndy Whitcroft $len = length($blk); 15538905a67cSAndy Whitcroft $line++; 15548905a67cSAndy Whitcroft last; 15558905a67cSAndy Whitcroft } 15568905a67cSAndy Whitcroft # Bail if there is no further context. 15578905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 155813214adfSAndy Whitcroft if ($off >= $len) { 15598905a67cSAndy Whitcroft last; 15608905a67cSAndy Whitcroft } 1561f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1562f74bd194SAndy Whitcroft $level++; 1563f74bd194SAndy Whitcroft $type = '#'; 1564f74bd194SAndy Whitcroft } 15658905a67cSAndy Whitcroft } 1566cf655043SAndy Whitcroft $p = $c; 15678905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 156813214adfSAndy Whitcroft $remainder = substr($blk, $off); 15698905a67cSAndy Whitcroft 1570773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 15714635f4fbSAndy Whitcroft 15724635f4fbSAndy Whitcroft # Handle nested #if/#else. 15734635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 15744635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 15754635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 15764635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 15774635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 15784635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 15794635f4fbSAndy Whitcroft } 15804635f4fbSAndy Whitcroft 15818905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 15828905a67cSAndy Whitcroft # outermost level. 15838905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 15848905a67cSAndy Whitcroft last; 15858905a67cSAndy Whitcroft } 15868905a67cSAndy Whitcroft 158713214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1588773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1589773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1590773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1591773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1592773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1593773647a0SAndy Whitcroft $coff_set = 1; 1594773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1595773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 159613214adfSAndy Whitcroft } 159713214adfSAndy Whitcroft 15988905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 15998905a67cSAndy Whitcroft $level++; 16008905a67cSAndy Whitcroft $type = '('; 16018905a67cSAndy Whitcroft } 16028905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 16038905a67cSAndy Whitcroft $level--; 16048905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 16058905a67cSAndy Whitcroft 16068905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 16078905a67cSAndy Whitcroft $coff = $off; 1608773647a0SAndy Whitcroft $coff_set = 1; 1609773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 16108905a67cSAndy Whitcroft } 16118905a67cSAndy Whitcroft } 16128905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 16138905a67cSAndy Whitcroft $level++; 16148905a67cSAndy Whitcroft $type = '{'; 16158905a67cSAndy Whitcroft } 16168905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 16178905a67cSAndy Whitcroft $level--; 16188905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 16198905a67cSAndy Whitcroft 16208905a67cSAndy Whitcroft if ($level == 0) { 1621b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1622b998e001SPatrick Pannuto $off++; 1623b998e001SPatrick Pannuto } 16248905a67cSAndy Whitcroft last; 16258905a67cSAndy Whitcroft } 16268905a67cSAndy Whitcroft } 1627f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1628f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1629f74bd194SAndy Whitcroft $level--; 1630f74bd194SAndy Whitcroft $type = ''; 1631f74bd194SAndy Whitcroft $off++; 1632f74bd194SAndy Whitcroft last; 1633f74bd194SAndy Whitcroft } 16348905a67cSAndy Whitcroft $off++; 16358905a67cSAndy Whitcroft } 1636a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 163713214adfSAndy Whitcroft if ($off == $len) { 1638a3bb97a7SAndy Whitcroft $loff = $len + 1; 163913214adfSAndy Whitcroft $line++; 164013214adfSAndy Whitcroft $remain--; 164113214adfSAndy Whitcroft } 16428905a67cSAndy Whitcroft 16438905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 16448905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 16458905a67cSAndy Whitcroft 16468905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 16478905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 16488905a67cSAndy Whitcroft 1649773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 165013214adfSAndy Whitcroft 165113214adfSAndy Whitcroft return ($statement, $condition, 165213214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 165313214adfSAndy Whitcroft} 165413214adfSAndy Whitcroft 1655cf655043SAndy Whitcroftsub statement_lines { 1656cf655043SAndy Whitcroft my ($stmt) = @_; 1657cf655043SAndy Whitcroft 1658cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1659cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1660cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1661cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1662cf655043SAndy Whitcroft 1663cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1664cf655043SAndy Whitcroft 1665cf655043SAndy Whitcroft return $#stmt_lines + 2; 1666cf655043SAndy Whitcroft} 1667cf655043SAndy Whitcroft 1668cf655043SAndy Whitcroftsub statement_rawlines { 1669cf655043SAndy Whitcroft my ($stmt) = @_; 1670cf655043SAndy Whitcroft 1671cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1672cf655043SAndy Whitcroft 1673cf655043SAndy Whitcroft return $#stmt_lines + 2; 1674cf655043SAndy Whitcroft} 1675cf655043SAndy Whitcroft 1676cf655043SAndy Whitcroftsub statement_block_size { 1677cf655043SAndy Whitcroft my ($stmt) = @_; 1678cf655043SAndy Whitcroft 1679cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1680cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1681cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1682cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1683cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1684cf655043SAndy Whitcroft 1685cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1686cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1687cf655043SAndy Whitcroft 1688cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1689cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1690cf655043SAndy Whitcroft 1691cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1692cf655043SAndy Whitcroft return $stmt_lines; 1693cf655043SAndy Whitcroft } else { 1694cf655043SAndy Whitcroft return $stmt_statements; 1695cf655043SAndy Whitcroft } 1696cf655043SAndy Whitcroft} 1697cf655043SAndy Whitcroft 169813214adfSAndy Whitcroftsub ctx_statement_full { 169913214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 170013214adfSAndy Whitcroft my ($statement, $condition, $level); 170113214adfSAndy Whitcroft 170213214adfSAndy Whitcroft my (@chunks); 170313214adfSAndy Whitcroft 1704cf655043SAndy Whitcroft # Grab the first conditional/block pair. 170513214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 170613214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1707773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 170813214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1709cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1710cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1711cf655043SAndy Whitcroft } 1712cf655043SAndy Whitcroft 1713cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1714cf655043SAndy Whitcroft # could continue the statement. 1715cf655043SAndy Whitcroft for (;;) { 171613214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 171713214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1718cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1719773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1720cf655043SAndy Whitcroft #print "C: push\n"; 1721cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 172213214adfSAndy Whitcroft } 172313214adfSAndy Whitcroft 172413214adfSAndy Whitcroft return ($level, $linenr, @chunks); 17258905a67cSAndy Whitcroft} 17268905a67cSAndy Whitcroft 17274a0df2efSAndy Whitcroftsub ctx_block_get { 1728f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 17294a0df2efSAndy Whitcroft my $line; 17304a0df2efSAndy Whitcroft my $start = $linenr - 1; 17314a0df2efSAndy Whitcroft my $blk = ''; 17324a0df2efSAndy Whitcroft my @o; 17334a0df2efSAndy Whitcroft my @c; 17344a0df2efSAndy Whitcroft my @res = (); 17354a0df2efSAndy Whitcroft 1736f0a594c1SAndy Whitcroft my $level = 0; 17374635f4fbSAndy Whitcroft my @stack = ($level); 173800df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 173900df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 174000df344fSAndy Whitcroft $remain--; 174100df344fSAndy Whitcroft 174200df344fSAndy Whitcroft $blk .= $rawlines[$line]; 17434635f4fbSAndy Whitcroft 17444635f4fbSAndy Whitcroft # Handle nested #if/#else. 174501464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 17464635f4fbSAndy Whitcroft push(@stack, $level); 174701464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 17484635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 174901464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 17504635f4fbSAndy Whitcroft $level = pop(@stack); 17514635f4fbSAndy Whitcroft } 17524635f4fbSAndy Whitcroft 175301464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1754f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1755f0a594c1SAndy Whitcroft if ($off > 0) { 1756f0a594c1SAndy Whitcroft $off--; 1757f0a594c1SAndy Whitcroft next; 1758f0a594c1SAndy Whitcroft } 17594a0df2efSAndy Whitcroft 1760f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1761f0a594c1SAndy Whitcroft $level--; 1762f0a594c1SAndy Whitcroft last if ($level == 0); 1763f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1764f0a594c1SAndy Whitcroft $level++; 1765f0a594c1SAndy Whitcroft } 1766f0a594c1SAndy Whitcroft } 17674a0df2efSAndy Whitcroft 1768f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 176900df344fSAndy Whitcroft push(@res, $rawlines[$line]); 17704a0df2efSAndy Whitcroft } 17714a0df2efSAndy Whitcroft 1772f0a594c1SAndy Whitcroft last if ($level == 0); 17734a0df2efSAndy Whitcroft } 17744a0df2efSAndy Whitcroft 1775f0a594c1SAndy Whitcroft return ($level, @res); 17764a0df2efSAndy Whitcroft} 17774a0df2efSAndy Whitcroftsub ctx_block_outer { 17784a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 17794a0df2efSAndy Whitcroft 1780f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1781f0a594c1SAndy Whitcroft return @r; 17824a0df2efSAndy Whitcroft} 17834a0df2efSAndy Whitcroftsub ctx_block { 17844a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 17854a0df2efSAndy Whitcroft 1786f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1787f0a594c1SAndy Whitcroft return @r; 1788653d4876SAndy Whitcroft} 1789653d4876SAndy Whitcroftsub ctx_statement { 1790f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1791f0a594c1SAndy Whitcroft 1792f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1793f0a594c1SAndy Whitcroft return @r; 1794f0a594c1SAndy Whitcroft} 1795f0a594c1SAndy Whitcroftsub ctx_block_level { 1796653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1797653d4876SAndy Whitcroft 1798f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 17994a0df2efSAndy Whitcroft} 18009c0ca6f9SAndy Whitcroftsub ctx_statement_level { 18019c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 18029c0ca6f9SAndy Whitcroft 18039c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 18049c0ca6f9SAndy Whitcroft} 18054a0df2efSAndy Whitcroft 18064a0df2efSAndy Whitcroftsub ctx_locate_comment { 18074a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 18084a0df2efSAndy Whitcroft 1809a55ee0ccSJoe Perches # If c99 comment on the current line, or the line before or after 1810a55ee0ccSJoe Perches my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); 1811a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1812a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); 1813a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1814a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); 1815a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1816a55ee0ccSJoe Perches 18174a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1818a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 18194a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 18204a0df2efSAndy Whitcroft 18214a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 18224a0df2efSAndy Whitcroft # comment. 18234a0df2efSAndy Whitcroft my $in_comment = 0; 18244a0df2efSAndy Whitcroft $current_comment = ''; 18254a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 182600df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 182700df344fSAndy Whitcroft #warn " $line\n"; 18284a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 18294a0df2efSAndy Whitcroft $in_comment = 1; 18304a0df2efSAndy Whitcroft } 18314a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 18324a0df2efSAndy Whitcroft $in_comment = 1; 18334a0df2efSAndy Whitcroft } 18344a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 18354a0df2efSAndy Whitcroft $current_comment = ''; 18364a0df2efSAndy Whitcroft } 18374a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 18384a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 18394a0df2efSAndy Whitcroft $in_comment = 0; 18404a0df2efSAndy Whitcroft } 18414a0df2efSAndy Whitcroft } 18424a0df2efSAndy Whitcroft 18434a0df2efSAndy Whitcroft chomp($current_comment); 18444a0df2efSAndy Whitcroft return($current_comment); 18454a0df2efSAndy Whitcroft} 18464a0df2efSAndy Whitcroftsub ctx_has_comment { 18474a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 18484a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 18494a0df2efSAndy Whitcroft 185000df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 18514a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 18524a0df2efSAndy Whitcroft 18534a0df2efSAndy Whitcroft return ($cmt ne ''); 18544a0df2efSAndy Whitcroft} 18554a0df2efSAndy Whitcroft 18564d001e4dSAndy Whitcroftsub raw_line { 18574d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 18584d001e4dSAndy Whitcroft 18594d001e4dSAndy Whitcroft my $offset = $linenr - 1; 18604d001e4dSAndy Whitcroft $cnt++; 18614d001e4dSAndy Whitcroft 18624d001e4dSAndy Whitcroft my $line; 18634d001e4dSAndy Whitcroft while ($cnt) { 18644d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 18654d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 18664d001e4dSAndy Whitcroft $cnt--; 18674d001e4dSAndy Whitcroft } 18684d001e4dSAndy Whitcroft 18694d001e4dSAndy Whitcroft return $line; 18704d001e4dSAndy Whitcroft} 18714d001e4dSAndy Whitcroft 18722a9f9d85STobin C. Hardingsub get_stat_real { 18732a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 18742a9f9d85STobin C. Harding 18752a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 18762a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 18772a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 18782a9f9d85STobin C. Harding } 18792a9f9d85STobin C. Harding 18802a9f9d85STobin C. Harding return $stat_real; 18812a9f9d85STobin C. Harding} 18822a9f9d85STobin C. Harding 1883e3d95a2aSTobin C. Hardingsub get_stat_here { 1884e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 1885e3d95a2aSTobin C. Harding 1886e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 1887e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 1888e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 1889e3d95a2aSTobin C. Harding } 1890e3d95a2aSTobin C. Harding 1891e3d95a2aSTobin C. Harding return $herectx; 1892e3d95a2aSTobin C. Harding} 1893e3d95a2aSTobin C. Harding 18940a920b5bSAndy Whitcroftsub cat_vet { 18950a920b5bSAndy Whitcroft my ($vet) = @_; 18969c0ca6f9SAndy Whitcroft my ($res, $coded); 18970a920b5bSAndy Whitcroft 18989c0ca6f9SAndy Whitcroft $res = ''; 18996c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 19006c72ffaaSAndy Whitcroft $res .= $1; 19016c72ffaaSAndy Whitcroft if ($2 ne '') { 19029c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 19036c72ffaaSAndy Whitcroft $res .= $coded; 19046c72ffaaSAndy Whitcroft } 19059c0ca6f9SAndy Whitcroft } 19069c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 19070a920b5bSAndy Whitcroft 19089c0ca6f9SAndy Whitcroft return $res; 19090a920b5bSAndy Whitcroft} 19100a920b5bSAndy Whitcroft 1911c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1912cf655043SAndy Whitcroftmy $av_pending; 1913c2fdda0dSAndy Whitcroftmy @av_paren_type; 19141f65f947SAndy Whitcroftmy $av_pend_colon; 1915c2fdda0dSAndy Whitcroft 1916c2fdda0dSAndy Whitcroftsub annotate_reset { 1917c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1918cf655043SAndy Whitcroft $av_pending = '_'; 1919cf655043SAndy Whitcroft @av_paren_type = ('E'); 19201f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1921c2fdda0dSAndy Whitcroft} 1922c2fdda0dSAndy Whitcroft 19236c72ffaaSAndy Whitcroftsub annotate_values { 19246c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 19256c72ffaaSAndy Whitcroft 19266c72ffaaSAndy Whitcroft my $res; 19271f65f947SAndy Whitcroft my $var = '_' x length($stream); 19286c72ffaaSAndy Whitcroft my $cur = $stream; 19296c72ffaaSAndy Whitcroft 1930c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 19316c72ffaaSAndy Whitcroft 19326c72ffaaSAndy Whitcroft while (length($cur)) { 1933773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1934cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1935171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 19366c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1937c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1938c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1939cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1940c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 19416c72ffaaSAndy Whitcroft } 19426c72ffaaSAndy Whitcroft 1943c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 19449446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 19459446ef56SAndy Whitcroft push(@av_paren_type, $type); 1946addcdceaSAndy Whitcroft $type = 'c'; 19479446ef56SAndy Whitcroft 1948e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1949c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 19506c72ffaaSAndy Whitcroft $type = 'T'; 19516c72ffaaSAndy Whitcroft 1952389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1953389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1954389a2fe5SAndy Whitcroft $type = 'T'; 1955389a2fe5SAndy Whitcroft 1956c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1957171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1958c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1959171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1960171ae1a4SAndy Whitcroft if ($2 ne '') { 1961cf655043SAndy Whitcroft $av_pending = 'N'; 1962171ae1a4SAndy Whitcroft } 1963171ae1a4SAndy Whitcroft $type = 'E'; 1964171ae1a4SAndy Whitcroft 1965c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1966171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1967171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1968171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 19696c72ffaaSAndy Whitcroft 1970c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1971cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1972c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1973cf655043SAndy Whitcroft 1974cf655043SAndy Whitcroft push(@av_paren_type, $type); 1975cf655043SAndy Whitcroft push(@av_paren_type, $type); 1976171ae1a4SAndy Whitcroft $type = 'E'; 1977cf655043SAndy Whitcroft 1978c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1979cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1980cf655043SAndy Whitcroft $av_preprocessor = 1; 1981cf655043SAndy Whitcroft 1982cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1983cf655043SAndy Whitcroft 1984171ae1a4SAndy Whitcroft $type = 'E'; 1985cf655043SAndy Whitcroft 1986c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1987cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1988cf655043SAndy Whitcroft 1989cf655043SAndy Whitcroft $av_preprocessor = 1; 1990cf655043SAndy Whitcroft 1991cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1992cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1993cf655043SAndy Whitcroft pop(@av_paren_type); 1994cf655043SAndy Whitcroft push(@av_paren_type, $type); 1995171ae1a4SAndy Whitcroft $type = 'E'; 19966c72ffaaSAndy Whitcroft 19976c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1998c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 19996c72ffaaSAndy Whitcroft 2000171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 2001171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 2002171ae1a4SAndy Whitcroft $av_pending = $type; 2003171ae1a4SAndy Whitcroft $type = 'N'; 2004171ae1a4SAndy Whitcroft 20056c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 2006c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 20076c72ffaaSAndy Whitcroft if (defined $2) { 2008cf655043SAndy Whitcroft $av_pending = 'V'; 20096c72ffaaSAndy Whitcroft } 20106c72ffaaSAndy Whitcroft $type = 'N'; 20116c72ffaaSAndy Whitcroft 201214b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 2013c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 201414b111c1SAndy Whitcroft $av_pending = 'E'; 20156c72ffaaSAndy Whitcroft $type = 'N'; 20166c72ffaaSAndy Whitcroft 20171f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 20181f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 20191f65f947SAndy Whitcroft $av_pend_colon = 'C'; 20201f65f947SAndy Whitcroft $type = 'N'; 20211f65f947SAndy Whitcroft 202214b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 2023c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 20246c72ffaaSAndy Whitcroft $type = 'N'; 20256c72ffaaSAndy Whitcroft 20266c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 2027c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 2028cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 2029cf655043SAndy Whitcroft $av_pending = '_'; 20306c72ffaaSAndy Whitcroft $type = 'N'; 20316c72ffaaSAndy Whitcroft 20326c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 2033cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 2034cf655043SAndy Whitcroft if ($new_type ne '_') { 2035cf655043SAndy Whitcroft $type = $new_type; 2036c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 2037c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 20386c72ffaaSAndy Whitcroft } else { 2039c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 20406c72ffaaSAndy Whitcroft } 20416c72ffaaSAndy Whitcroft 2042c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 2043c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 2044c8cb2ca3SAndy Whitcroft $type = 'V'; 2045cf655043SAndy Whitcroft $av_pending = 'V'; 20466c72ffaaSAndy Whitcroft 20478e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 20488e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 20491f65f947SAndy Whitcroft $av_pend_colon = 'B'; 20508e761b04SAndy Whitcroft } elsif ($type eq 'E') { 20518e761b04SAndy Whitcroft $av_pend_colon = 'L'; 20521f65f947SAndy Whitcroft } 20531f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 20541f65f947SAndy Whitcroft $type = 'V'; 20551f65f947SAndy Whitcroft 20566c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 2057c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 20586c72ffaaSAndy Whitcroft $type = 'V'; 20596c72ffaaSAndy Whitcroft 20606c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 2061c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 20626c72ffaaSAndy Whitcroft $type = 'N'; 20636c72ffaaSAndy Whitcroft 2064cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 2065c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 206613214adfSAndy Whitcroft $type = 'E'; 20671f65f947SAndy Whitcroft $av_pend_colon = 'O'; 206813214adfSAndy Whitcroft 20698e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 20708e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 20718e761b04SAndy Whitcroft $type = 'C'; 20728e761b04SAndy Whitcroft 20731f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 20741f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 20751f65f947SAndy Whitcroft $type = 'N'; 20761f65f947SAndy Whitcroft 20771f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 20781f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 20791f65f947SAndy Whitcroft 20801f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 20811f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 20821f65f947SAndy Whitcroft $type = 'E'; 20831f65f947SAndy Whitcroft } else { 20841f65f947SAndy Whitcroft $type = 'N'; 20851f65f947SAndy Whitcroft } 20861f65f947SAndy Whitcroft $av_pend_colon = 'O'; 20871f65f947SAndy Whitcroft 20888e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 208913214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 20906c72ffaaSAndy Whitcroft $type = 'N'; 20916c72ffaaSAndy Whitcroft 20920d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 209374048ed8SAndy Whitcroft my $variant; 209474048ed8SAndy Whitcroft 209574048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 209674048ed8SAndy Whitcroft if ($type eq 'V') { 209774048ed8SAndy Whitcroft $variant = 'B'; 209874048ed8SAndy Whitcroft } else { 209974048ed8SAndy Whitcroft $variant = 'U'; 210074048ed8SAndy Whitcroft } 210174048ed8SAndy Whitcroft 210274048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 210374048ed8SAndy Whitcroft $type = 'N'; 210474048ed8SAndy Whitcroft 21056c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 2106c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 21076c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 21086c72ffaaSAndy Whitcroft $type = 'N'; 21096c72ffaaSAndy Whitcroft } 21106c72ffaaSAndy Whitcroft 21116c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 2112c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 21136c72ffaaSAndy Whitcroft } 21146c72ffaaSAndy Whitcroft if (defined $1) { 21156c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 21166c72ffaaSAndy Whitcroft $res .= $type x length($1); 21176c72ffaaSAndy Whitcroft } 21186c72ffaaSAndy Whitcroft } 21196c72ffaaSAndy Whitcroft 21201f65f947SAndy Whitcroft return ($res, $var); 21216c72ffaaSAndy Whitcroft} 21226c72ffaaSAndy Whitcroft 21238905a67cSAndy Whitcroftsub possible { 212413214adfSAndy Whitcroft my ($possible, $line) = @_; 21259a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 21260776e594SAndy Whitcroft ^(?: 21270776e594SAndy Whitcroft $Modifier| 21280776e594SAndy Whitcroft $Storage| 21290776e594SAndy Whitcroft $Type| 21309a974fdbSAndy Whitcroft DEFINE_\S+ 21319a974fdbSAndy Whitcroft )$| 21329a974fdbSAndy Whitcroft ^(?: 21330776e594SAndy Whitcroft goto| 21340776e594SAndy Whitcroft return| 21350776e594SAndy Whitcroft case| 21360776e594SAndy Whitcroft else| 21370776e594SAndy Whitcroft asm|__asm__| 213889a88353SAndy Whitcroft do| 213989a88353SAndy Whitcroft \#| 214089a88353SAndy Whitcroft \#\#| 21419a974fdbSAndy Whitcroft )(?:\s|$)| 21420776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 21439a974fdbSAndy Whitcroft )}x; 21449a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 21459a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 2146c45dcabdSAndy Whitcroft # Check for modifiers. 2147c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 2148c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 2149c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 2150c45dcabdSAndy Whitcroft 2151c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 2152c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 2153d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 21549a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 2155d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 2156485ff23eSAlex Dowad push(@modifierListFile, $modifier); 2157d2506586SAndy Whitcroft } 21589a974fdbSAndy Whitcroft } 2159c45dcabdSAndy Whitcroft 2160c45dcabdSAndy Whitcroft } else { 216113214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 2162485ff23eSAlex Dowad push(@typeListFile, $possible); 2163c45dcabdSAndy Whitcroft } 21648905a67cSAndy Whitcroft build_types(); 21650776e594SAndy Whitcroft } else { 21660776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 21678905a67cSAndy Whitcroft } 21688905a67cSAndy Whitcroft} 21698905a67cSAndy Whitcroft 21706c72ffaaSAndy Whitcroftmy $prefix = ''; 21716c72ffaaSAndy Whitcroft 2172000d1cc1SJoe Perchessub show_type { 2173cbec18afSJoe Perches my ($type) = @_; 217491bfe484SJoe Perches 2175522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2176522b837cSAlexey Dobriyan 2177cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2178cbec18afSJoe Perches 2179cbec18afSJoe Perches return !defined $ignore_type{$type}; 2180000d1cc1SJoe Perches} 2181000d1cc1SJoe Perches 2182f0a594c1SAndy Whitcroftsub report { 2183cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2184cbec18afSJoe Perches 2185cbec18afSJoe Perches if (!show_type($type) || 2186cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2187773647a0SAndy Whitcroft return 0; 2188773647a0SAndy Whitcroft } 218957230297SJoe Perches my $output = ''; 2190737c0767SJohn Brooks if ($color) { 219157230297SJoe Perches if ($level eq 'ERROR') { 219257230297SJoe Perches $output .= RED; 219357230297SJoe Perches } elsif ($level eq 'WARNING') { 219457230297SJoe Perches $output .= YELLOW; 2195000d1cc1SJoe Perches } else { 219657230297SJoe Perches $output .= GREEN; 2197000d1cc1SJoe Perches } 219857230297SJoe Perches } 219957230297SJoe Perches $output .= $prefix . $level . ':'; 220057230297SJoe Perches if ($show_types) { 2201737c0767SJohn Brooks $output .= BLUE if ($color); 220257230297SJoe Perches $output .= "$type:"; 220357230297SJoe Perches } 2204737c0767SJohn Brooks $output .= RESET if ($color); 220557230297SJoe Perches $output .= ' ' . $msg . "\n"; 220634d8815fSJoe Perches 220734d8815fSJoe Perches if ($showfile) { 220834d8815fSJoe Perches my @lines = split("\n", $output, -1); 220934d8815fSJoe Perches splice(@lines, 1, 1); 221034d8815fSJoe Perches $output = join("\n", @lines); 221134d8815fSJoe Perches } 221257230297SJoe Perches $output = (split('\n', $output))[0] . "\n" if ($terse); 22138905a67cSAndy Whitcroft 221457230297SJoe Perches push(our @report, $output); 2215773647a0SAndy Whitcroft 2216773647a0SAndy Whitcroft return 1; 2217f0a594c1SAndy Whitcroft} 2218cbec18afSJoe Perches 2219f0a594c1SAndy Whitcroftsub report_dump { 222013214adfSAndy Whitcroft our @report; 2221f0a594c1SAndy Whitcroft} 2222000d1cc1SJoe Perches 2223d752fcc8SJoe Perchessub fixup_current_range { 2224d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2225d752fcc8SJoe Perches 2226d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2227d752fcc8SJoe Perches my $o = $1; 2228d752fcc8SJoe Perches my $l = $2; 2229d752fcc8SJoe Perches my $no = $o + $offset; 2230d752fcc8SJoe Perches my $nl = $l + $length; 2231d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2232d752fcc8SJoe Perches } 2233d752fcc8SJoe Perches} 2234d752fcc8SJoe Perches 2235d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2236d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2237d752fcc8SJoe Perches 2238d752fcc8SJoe Perches my $range_last_linenr = 0; 2239d752fcc8SJoe Perches my $delta_offset = 0; 2240d752fcc8SJoe Perches 2241d752fcc8SJoe Perches my $old_linenr = 0; 2242d752fcc8SJoe Perches my $new_linenr = 0; 2243d752fcc8SJoe Perches 2244d752fcc8SJoe Perches my $next_insert = 0; 2245d752fcc8SJoe Perches my $next_delete = 0; 2246d752fcc8SJoe Perches 2247d752fcc8SJoe Perches my @lines = (); 2248d752fcc8SJoe Perches 2249d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2250d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2251d752fcc8SJoe Perches 2252d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2253d752fcc8SJoe Perches my $save_line = 1; 2254d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2255323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2256d752fcc8SJoe Perches $delta_offset = 0; 2257d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2258d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2259d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2260d752fcc8SJoe Perches } 2261d752fcc8SJoe Perches 2262d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2263d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2264d752fcc8SJoe Perches $save_line = 0; 2265d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2266d752fcc8SJoe Perches } 2267d752fcc8SJoe Perches 2268d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2269d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2270d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2271d752fcc8SJoe Perches $new_linenr++; 2272d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2273d752fcc8SJoe Perches } 2274d752fcc8SJoe Perches 2275d752fcc8SJoe Perches if ($save_line) { 2276d752fcc8SJoe Perches push(@lines, $line); 2277d752fcc8SJoe Perches $new_linenr++; 2278d752fcc8SJoe Perches } 2279d752fcc8SJoe Perches 2280d752fcc8SJoe Perches $old_linenr++; 2281d752fcc8SJoe Perches } 2282d752fcc8SJoe Perches 2283d752fcc8SJoe Perches return @lines; 2284d752fcc8SJoe Perches} 2285d752fcc8SJoe Perches 2286f2d7e4d4SJoe Perchessub fix_insert_line { 2287f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2288f2d7e4d4SJoe Perches 2289f2d7e4d4SJoe Perches my $inserted = { 2290f2d7e4d4SJoe Perches LINENR => $linenr, 2291f2d7e4d4SJoe Perches LINE => $line, 2292f2d7e4d4SJoe Perches }; 2293f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2294f2d7e4d4SJoe Perches} 2295f2d7e4d4SJoe Perches 2296f2d7e4d4SJoe Perchessub fix_delete_line { 2297f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2298f2d7e4d4SJoe Perches 2299f2d7e4d4SJoe Perches my $deleted = { 2300f2d7e4d4SJoe Perches LINENR => $linenr, 2301f2d7e4d4SJoe Perches LINE => $line, 2302f2d7e4d4SJoe Perches }; 2303f2d7e4d4SJoe Perches 2304f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2305f2d7e4d4SJoe Perches} 2306f2d7e4d4SJoe Perches 2307de7d4f0eSAndy Whitcroftsub ERROR { 2308cbec18afSJoe Perches my ($type, $msg) = @_; 2309cbec18afSJoe Perches 2310cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2311de7d4f0eSAndy Whitcroft our $clean = 0; 23126c72ffaaSAndy Whitcroft our $cnt_error++; 23133705ce5bSJoe Perches return 1; 2314de7d4f0eSAndy Whitcroft } 23153705ce5bSJoe Perches return 0; 2316773647a0SAndy Whitcroft} 2317de7d4f0eSAndy Whitcroftsub WARN { 2318cbec18afSJoe Perches my ($type, $msg) = @_; 2319cbec18afSJoe Perches 2320cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2321de7d4f0eSAndy Whitcroft our $clean = 0; 23226c72ffaaSAndy Whitcroft our $cnt_warn++; 23233705ce5bSJoe Perches return 1; 2324de7d4f0eSAndy Whitcroft } 23253705ce5bSJoe Perches return 0; 2326773647a0SAndy Whitcroft} 2327de7d4f0eSAndy Whitcroftsub CHK { 2328cbec18afSJoe Perches my ($type, $msg) = @_; 2329cbec18afSJoe Perches 2330cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2331de7d4f0eSAndy Whitcroft our $clean = 0; 23326c72ffaaSAndy Whitcroft our $cnt_chk++; 23333705ce5bSJoe Perches return 1; 23346c72ffaaSAndy Whitcroft } 23353705ce5bSJoe Perches return 0; 2336de7d4f0eSAndy Whitcroft} 2337de7d4f0eSAndy Whitcroft 23386ecd9674SAndy Whitcroftsub check_absolute_file { 23396ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 23406ecd9674SAndy Whitcroft my $file = $absolute; 23416ecd9674SAndy Whitcroft 23426ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 23436ecd9674SAndy Whitcroft 23446ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 23456ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 23466ecd9674SAndy Whitcroft if (-f "$root/$file") { 23476ecd9674SAndy Whitcroft ##print "file<$file>\n"; 23486ecd9674SAndy Whitcroft last; 23496ecd9674SAndy Whitcroft } 23506ecd9674SAndy Whitcroft } 23516ecd9674SAndy Whitcroft if (! -f _) { 23526ecd9674SAndy Whitcroft return 0; 23536ecd9674SAndy Whitcroft } 23546ecd9674SAndy Whitcroft 23556ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 23566ecd9674SAndy Whitcroft my $prefix = $absolute; 23576ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 23586ecd9674SAndy Whitcroft 23596ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 23606ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2361000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2362000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 23636ecd9674SAndy Whitcroft } 23646ecd9674SAndy Whitcroft} 23656ecd9674SAndy Whitcroft 23663705ce5bSJoe Perchessub trim { 23673705ce5bSJoe Perches my ($string) = @_; 23683705ce5bSJoe Perches 2369b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2370b34c648bSJoe Perches 2371b34c648bSJoe Perches return $string; 2372b34c648bSJoe Perches} 2373b34c648bSJoe Perches 2374b34c648bSJoe Perchessub ltrim { 2375b34c648bSJoe Perches my ($string) = @_; 2376b34c648bSJoe Perches 2377b34c648bSJoe Perches $string =~ s/^\s+//; 2378b34c648bSJoe Perches 2379b34c648bSJoe Perches return $string; 2380b34c648bSJoe Perches} 2381b34c648bSJoe Perches 2382b34c648bSJoe Perchessub rtrim { 2383b34c648bSJoe Perches my ($string) = @_; 2384b34c648bSJoe Perches 2385b34c648bSJoe Perches $string =~ s/\s+$//; 23863705ce5bSJoe Perches 23873705ce5bSJoe Perches return $string; 23883705ce5bSJoe Perches} 23893705ce5bSJoe Perches 239052ea8506SJoe Perchessub string_find_replace { 239152ea8506SJoe Perches my ($string, $find, $replace) = @_; 239252ea8506SJoe Perches 239352ea8506SJoe Perches $string =~ s/$find/$replace/g; 239452ea8506SJoe Perches 239552ea8506SJoe Perches return $string; 239652ea8506SJoe Perches} 239752ea8506SJoe Perches 23983705ce5bSJoe Perchessub tabify { 23993705ce5bSJoe Perches my ($leading) = @_; 24003705ce5bSJoe Perches 2401713a09deSAntonio Borneo my $source_indent = $tabsize; 24023705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 24033705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 24043705ce5bSJoe Perches 24053705ce5bSJoe Perches #convert leading spaces to tabs 24063705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 24073705ce5bSJoe Perches #Remove spaces before a tab 24083705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 24093705ce5bSJoe Perches 24103705ce5bSJoe Perches return "$leading"; 24113705ce5bSJoe Perches} 24123705ce5bSJoe Perches 2413d1fe9c09SJoe Perchessub pos_last_openparen { 2414d1fe9c09SJoe Perches my ($line) = @_; 2415d1fe9c09SJoe Perches 2416d1fe9c09SJoe Perches my $pos = 0; 2417d1fe9c09SJoe Perches 2418d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2419d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2420d1fe9c09SJoe Perches 2421d1fe9c09SJoe Perches my $last_openparen = 0; 2422d1fe9c09SJoe Perches 2423d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2424d1fe9c09SJoe Perches return -1; 2425d1fe9c09SJoe Perches } 2426d1fe9c09SJoe Perches 2427d1fe9c09SJoe Perches my $len = length($line); 2428d1fe9c09SJoe Perches 2429d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2430d1fe9c09SJoe Perches my $string = substr($line, $pos); 2431d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2432d1fe9c09SJoe Perches $pos += length($1) - 1; 2433d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2434d1fe9c09SJoe Perches $last_openparen = $pos; 2435d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2436d1fe9c09SJoe Perches last; 2437d1fe9c09SJoe Perches } 2438d1fe9c09SJoe Perches } 2439d1fe9c09SJoe Perches 244091cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2441d1fe9c09SJoe Perches} 2442d1fe9c09SJoe Perches 2443f36d3eb8SJoe Perchessub get_raw_comment { 2444f36d3eb8SJoe Perches my ($line, $rawline) = @_; 2445f36d3eb8SJoe Perches my $comment = ''; 2446f36d3eb8SJoe Perches 2447f36d3eb8SJoe Perches for my $i (0 .. (length($line) - 1)) { 2448f36d3eb8SJoe Perches if (substr($line, $i, 1) eq "$;") { 2449f36d3eb8SJoe Perches $comment .= substr($rawline, $i, 1); 2450f36d3eb8SJoe Perches } 2451f36d3eb8SJoe Perches } 2452f36d3eb8SJoe Perches 2453f36d3eb8SJoe Perches return $comment; 2454f36d3eb8SJoe Perches} 2455f36d3eb8SJoe Perches 24565b8f82e1SSong Liusub exclude_global_initialisers { 24575b8f82e1SSong Liu my ($realfile) = @_; 24585b8f82e1SSong Liu 24595b8f82e1SSong Liu # Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c). 24605b8f82e1SSong Liu return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ || 24615b8f82e1SSong Liu $realfile =~ m@^samples/bpf/.*_kern\.c$@ || 24625b8f82e1SSong Liu $realfile =~ m@/bpf/.*\.bpf\.c$@; 24635b8f82e1SSong Liu} 24645b8f82e1SSong Liu 24650a920b5bSAndy Whitcroftsub process { 24660a920b5bSAndy Whitcroft my $filename = shift; 24670a920b5bSAndy Whitcroft 24680a920b5bSAndy Whitcroft my $linenr=0; 24690a920b5bSAndy Whitcroft my $prevline=""; 2470c2fdda0dSAndy Whitcroft my $prevrawline=""; 24710a920b5bSAndy Whitcroft my $stashline=""; 2472c2fdda0dSAndy Whitcroft my $stashrawline=""; 24730a920b5bSAndy Whitcroft 24744a0df2efSAndy Whitcroft my $length; 24750a920b5bSAndy Whitcroft my $indent; 24760a920b5bSAndy Whitcroft my $previndent=0; 24770a920b5bSAndy Whitcroft my $stashindent=0; 24780a920b5bSAndy Whitcroft 2479de7d4f0eSAndy Whitcroft our $clean = 1; 24800a920b5bSAndy Whitcroft my $signoff = 0; 2481cd261496SGeert Uytterhoeven my $author = ''; 2482cd261496SGeert Uytterhoeven my $authorsignoff = 0; 248348ca2d8aSDwaipayan Ray my $author_sob = ''; 24840a920b5bSAndy Whitcroft my $is_patch = 0; 2485133712a2SRob Herring my $is_binding_patch = -1; 248629ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 248715662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 248844d303ebSJoe Perches my $has_patch_separator = 0; #Found a --- line 2489ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2490490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2491bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 24922a076f40SJoe Perches my $commit_log_long_line = 0; 2493e518e9a5SJoe Perches my $commit_log_has_diff = 0; 249413f1937eSJoe Perches my $reported_maintainer_file = 0; 2495fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2496fa64205dSPasi Savanainen 2497365dd4eaSJoe Perches my $last_blank_line = 0; 24985e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2499365dd4eaSJoe Perches 250013214adfSAndy Whitcroft our @report = (); 25016c72ffaaSAndy Whitcroft our $cnt_lines = 0; 25026c72ffaaSAndy Whitcroft our $cnt_error = 0; 25036c72ffaaSAndy Whitcroft our $cnt_warn = 0; 25046c72ffaaSAndy Whitcroft our $cnt_chk = 0; 25056c72ffaaSAndy Whitcroft 25060a920b5bSAndy Whitcroft # Trace the real file/line as we go. 25070a920b5bSAndy Whitcroft my $realfile = ''; 25080a920b5bSAndy Whitcroft my $realline = 0; 25090a920b5bSAndy Whitcroft my $realcnt = 0; 25100a920b5bSAndy Whitcroft my $here = ''; 251177cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 25120a920b5bSAndy Whitcroft my $in_comment = 0; 2513c2fdda0dSAndy Whitcroft my $comment_edge = 0; 25140a920b5bSAndy Whitcroft my $first_line = 0; 25151e855726SWolfram Sang my $p1_prefix = ''; 25160a920b5bSAndy Whitcroft 251713214adfSAndy Whitcroft my $prev_values = 'E'; 251813214adfSAndy Whitcroft 251913214adfSAndy Whitcroft # suppression flags 2520773647a0SAndy Whitcroft my %suppress_ifbraces; 2521170d3a22SAndy Whitcroft my %suppress_whiletrailers; 25222b474a1aSAndy Whitcroft my %suppress_export; 25233e469cdcSAndy Whitcroft my $suppress_statement = 0; 2524653d4876SAndy Whitcroft 25257e51f197SJoe Perches my %signatures = (); 2526323c1260SJoe Perches 2527c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2528de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2529c2fdda0dSAndy Whitcroft # 2530de7d4f0eSAndy Whitcroft my @setup_docs = (); 2531de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2532773647a0SAndy Whitcroft 2533d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2534d8b07710SJoe Perches 25359f3a8992SRob Herring my $checklicenseline = 1; 25369f3a8992SRob Herring 2537773647a0SAndy Whitcroft sanitise_line_reset(); 2538c2fdda0dSAndy Whitcroft my $line; 2539c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2540773647a0SAndy Whitcroft $linenr++; 2541773647a0SAndy Whitcroft $line = $rawline; 2542c2fdda0dSAndy Whitcroft 25433705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 25443705ce5bSJoe Perches 2545773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2546de7d4f0eSAndy Whitcroft $setup_docs = 0; 25472581ac7cSTim Froidcoeur if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { 2548de7d4f0eSAndy Whitcroft $setup_docs = 1; 2549de7d4f0eSAndy Whitcroft } 2550773647a0SAndy Whitcroft #next; 2551de7d4f0eSAndy Whitcroft } 255274fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2553773647a0SAndy Whitcroft $realline=$1-1; 2554773647a0SAndy Whitcroft if (defined $2) { 2555773647a0SAndy Whitcroft $realcnt=$3+1; 2556773647a0SAndy Whitcroft } else { 2557773647a0SAndy Whitcroft $realcnt=1+1; 2558773647a0SAndy Whitcroft } 2559c45dcabdSAndy Whitcroft $in_comment = 0; 2560773647a0SAndy Whitcroft 2561773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2562773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2563773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2564773647a0SAndy Whitcroft # at context start. 2565773647a0SAndy Whitcroft my $edge; 256601fa9147SAndy Whitcroft my $cnt = $realcnt; 256701fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 256801fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 256901fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 257001fa9147SAndy Whitcroft $cnt--; 257101fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2572721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2573fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2574fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2575fae17daeSAndy Whitcroft ($edge) = $1; 2576fae17daeSAndy Whitcroft last; 2577fae17daeSAndy Whitcroft } 2578773647a0SAndy Whitcroft } 2579773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2580773647a0SAndy Whitcroft $in_comment = 1; 2581773647a0SAndy Whitcroft } 2582773647a0SAndy Whitcroft 2583773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2584773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2585773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2586773647a0SAndy Whitcroft if (!defined $edge && 258783242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2588773647a0SAndy Whitcroft { 2589773647a0SAndy Whitcroft $in_comment = 1; 2590773647a0SAndy Whitcroft } 2591773647a0SAndy Whitcroft 2592773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2593773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2594773647a0SAndy Whitcroft 2595171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2596773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2597171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2598773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2599773647a0SAndy Whitcroft } 2600773647a0SAndy Whitcroft push(@lines, $line); 2601773647a0SAndy Whitcroft 2602773647a0SAndy Whitcroft if ($realcnt > 1) { 2603773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2604773647a0SAndy Whitcroft } else { 2605773647a0SAndy Whitcroft $realcnt = 0; 2606773647a0SAndy Whitcroft } 2607773647a0SAndy Whitcroft 2608773647a0SAndy Whitcroft #print "==>$rawline\n"; 2609773647a0SAndy Whitcroft #print "-->$line\n"; 2610de7d4f0eSAndy Whitcroft 2611de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2612de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2613de7d4f0eSAndy Whitcroft } 2614de7d4f0eSAndy Whitcroft } 2615de7d4f0eSAndy Whitcroft 26166c72ffaaSAndy Whitcroft $prefix = ''; 26176c72ffaaSAndy Whitcroft 2618773647a0SAndy Whitcroft $realcnt = 0; 2619773647a0SAndy Whitcroft $linenr = 0; 2620194f66fcSJoe Perches $fixlinenr = -1; 26210a920b5bSAndy Whitcroft foreach my $line (@lines) { 26220a920b5bSAndy Whitcroft $linenr++; 2623194f66fcSJoe Perches $fixlinenr++; 26241b5539b1SJoe Perches my $sline = $line; #copy of $line 26251b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 26260a920b5bSAndy Whitcroft 2627c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 2628f36d3eb8SJoe Perches my $raw_comment = get_raw_comment($line, $rawline); 26296c72ffaaSAndy Whitcroft 263012c253abSJoe Perches# check if it's a mode change, rename or start of a patch 263112c253abSJoe Perches if (!$in_commit_log && 263212c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 263312c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 263412c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 263512c253abSJoe Perches $is_patch = 1; 263612c253abSJoe Perches } 263712c253abSJoe Perches 26380a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2639e518e9a5SJoe Perches if (!$in_commit_log && 264074fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 264174fd4f34SJoe Perches my $context = $4; 26420a920b5bSAndy Whitcroft $is_patch = 1; 26434a0df2efSAndy Whitcroft $first_line = $linenr + 1; 26440a920b5bSAndy Whitcroft $realline=$1-1; 26450a920b5bSAndy Whitcroft if (defined $2) { 26460a920b5bSAndy Whitcroft $realcnt=$3+1; 26470a920b5bSAndy Whitcroft } else { 26480a920b5bSAndy Whitcroft $realcnt=1+1; 26490a920b5bSAndy Whitcroft } 2650c2fdda0dSAndy Whitcroft annotate_reset(); 265113214adfSAndy Whitcroft $prev_values = 'E'; 265213214adfSAndy Whitcroft 2653773647a0SAndy Whitcroft %suppress_ifbraces = (); 2654170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 26552b474a1aSAndy Whitcroft %suppress_export = (); 26563e469cdcSAndy Whitcroft $suppress_statement = 0; 265774fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 265874fd4f34SJoe Perches $context_function = $1; 265974fd4f34SJoe Perches } else { 266074fd4f34SJoe Perches undef $context_function; 266174fd4f34SJoe Perches } 26620a920b5bSAndy Whitcroft next; 26630a920b5bSAndy Whitcroft 26644a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 26654a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 26664a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2667773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 26680a920b5bSAndy Whitcroft $realline++; 2669d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 26700a920b5bSAndy Whitcroft 26714a0df2efSAndy Whitcroft # Measure the line length and indent. 2672c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 26730a920b5bSAndy Whitcroft 26740a920b5bSAndy Whitcroft # Track the previous line. 26750a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 26760a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2677c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2678c2fdda0dSAndy Whitcroft 2679773647a0SAndy Whitcroft #warn "line<$line>\n"; 26806c72ffaaSAndy Whitcroft 2681d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2682d8aaf121SAndy Whitcroft $realcnt--; 26830a920b5bSAndy Whitcroft } 26840a920b5bSAndy Whitcroft 2685cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2686cc77cdcaSAndy Whitcroft 26876c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 26886c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2689773647a0SAndy Whitcroft 26902ac73b4fSJoe Perches my $found_file = 0; 2691773647a0SAndy Whitcroft # extract the filename as it passes 26923bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 26933bf9a009SRabin Vincent $realfile = $1; 26942b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2695270c49a0SJoe Perches $in_commit_log = 0; 26962ac73b4fSJoe Perches $found_file = 1; 26973bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2698773647a0SAndy Whitcroft $realfile = $1; 26992b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2700270c49a0SJoe Perches $in_commit_log = 0; 27011e855726SWolfram Sang 27021e855726SWolfram Sang $p1_prefix = $1; 2703e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2704e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2705000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2706000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 27071e855726SWolfram Sang } 2708773647a0SAndy Whitcroft 2709c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2710000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2711000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2712773647a0SAndy Whitcroft } 27132ac73b4fSJoe Perches $found_file = 1; 27142ac73b4fSJoe Perches } 27152ac73b4fSJoe Perches 271634d8815fSJoe Perches#make up the handle for any error we report on this line 271734d8815fSJoe Perches if ($showfile) { 271834d8815fSJoe Perches $prefix = "$realfile:$realline: " 271934d8815fSJoe Perches } elsif ($emacs) { 27207d3a9f67SJoe Perches if ($file) { 27217d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 27227d3a9f67SJoe Perches } else { 272334d8815fSJoe Perches $prefix = "$filename:$linenr: "; 272434d8815fSJoe Perches } 27257d3a9f67SJoe Perches } 272634d8815fSJoe Perches 27272ac73b4fSJoe Perches if ($found_file) { 272885b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 272985b0ee18SJoe Perches WARN("OBSOLETE", 273085b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 273185b0ee18SJoe Perches } 27327bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 27332ac73b4fSJoe Perches $check = 1; 27342ac73b4fSJoe Perches } else { 27352ac73b4fSJoe Perches $check = $check_orig; 27362ac73b4fSJoe Perches } 27379f3a8992SRob Herring $checklicenseline = 1; 2738133712a2SRob Herring 2739133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2740133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2741133712a2SRob Herring 2742133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2743133712a2SRob Herring 2744133712a2SRob Herring if (($last_binding_patch != -1) && 2745133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2746133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2747858e6845SMauro Carvalho Chehab "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); 2748133712a2SRob Herring } 2749133712a2SRob Herring } 2750133712a2SRob Herring 2751773647a0SAndy Whitcroft next; 2752773647a0SAndy Whitcroft } 2753773647a0SAndy Whitcroft 2754389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 27550a920b5bSAndy Whitcroft 2756c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2757c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2758c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 27590a920b5bSAndy Whitcroft 27606c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 27616c72ffaaSAndy Whitcroft 2762490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2763490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2764490b292cSJoe Perches if ($in_commit_log) { 2765490b292cSJoe Perches if ($line !~ /^\s*$/) { 2766490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2767490b292cSJoe Perches } 2768490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2769490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2770490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2771490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2772490b292cSJoe Perches } 2773490b292cSJoe Perches 2774e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2775e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 277613e45417SMrinal Pandey (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && 277713e45417SMrinal Pandey $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || 2778e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2779e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2780e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2781e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2782e518e9a5SJoe Perches $commit_log_has_diff = 1; 2783e518e9a5SJoe Perches } 2784e518e9a5SJoe Perches 27853bf9a009SRabin Vincent# Check for incorrect file permissions 27863bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 27873bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 278804db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 278904db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2790000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2791000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 27923bf9a009SRabin Vincent } 27933bf9a009SRabin Vincent } 27943bf9a009SRabin Vincent 2795cd261496SGeert Uytterhoeven# Check the patch for a From: 2796cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2797cd261496SGeert Uytterhoeven $author = $1; 2798e7f929f3SDwaipayan Ray my $curline = $linenr; 2799e7f929f3SDwaipayan Ray while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { 2800e7f929f3SDwaipayan Ray $author .= $1; 2801e7f929f3SDwaipayan Ray } 2802cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2803cd261496SGeert Uytterhoeven $author =~ s/"//g; 2804dfa05c28SJoe Perches $author = reformat_email($author); 2805cd261496SGeert Uytterhoeven } 2806cd261496SGeert Uytterhoeven 280720112475SJoe Perches# Check the patch for a signoff: 2808dfa05c28SJoe Perches if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { 28094a0df2efSAndy Whitcroft $signoff++; 281015662b3eSJoe Perches $in_commit_log = 0; 281148ca2d8aSDwaipayan Ray if ($author ne '' && $authorsignoff != 1) { 2812fccaebf0SDwaipayan Ray if (same_email_addresses($1, $author)) { 2813cd261496SGeert Uytterhoeven $authorsignoff = 1; 281448ca2d8aSDwaipayan Ray } else { 281548ca2d8aSDwaipayan Ray my $ctx = $1; 281648ca2d8aSDwaipayan Ray my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); 281748ca2d8aSDwaipayan Ray my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); 281848ca2d8aSDwaipayan Ray 281948ca2d8aSDwaipayan Ray if ($email_address eq $author_address && $email_name eq $author_name) { 282048ca2d8aSDwaipayan Ray $author_sob = $ctx; 282148ca2d8aSDwaipayan Ray $authorsignoff = 2; 282248ca2d8aSDwaipayan Ray } elsif ($email_address eq $author_address) { 282348ca2d8aSDwaipayan Ray $author_sob = $ctx; 282448ca2d8aSDwaipayan Ray $authorsignoff = 3; 282548ca2d8aSDwaipayan Ray } elsif ($email_name eq $author_name) { 282648ca2d8aSDwaipayan Ray $author_sob = $ctx; 282748ca2d8aSDwaipayan Ray $authorsignoff = 4; 282848ca2d8aSDwaipayan Ray 282948ca2d8aSDwaipayan Ray my $address1 = $email_address; 283048ca2d8aSDwaipayan Ray my $address2 = $author_address; 283148ca2d8aSDwaipayan Ray 283248ca2d8aSDwaipayan Ray if ($address1 =~ /(\S+)\+\S+(\@.*)/) { 283348ca2d8aSDwaipayan Ray $address1 = "$1$2"; 283448ca2d8aSDwaipayan Ray } 283548ca2d8aSDwaipayan Ray if ($address2 =~ /(\S+)\+\S+(\@.*)/) { 283648ca2d8aSDwaipayan Ray $address2 = "$1$2"; 283748ca2d8aSDwaipayan Ray } 283848ca2d8aSDwaipayan Ray if ($address1 eq $address2) { 283948ca2d8aSDwaipayan Ray $authorsignoff = 5; 284048ca2d8aSDwaipayan Ray } 284148ca2d8aSDwaipayan Ray } 2842cd261496SGeert Uytterhoeven } 2843cd261496SGeert Uytterhoeven } 28440a920b5bSAndy Whitcroft } 284520112475SJoe Perches 284644d303ebSJoe Perches# Check for patch separator 284744d303ebSJoe Perches if ($line =~ /^---$/) { 284844d303ebSJoe Perches $has_patch_separator = 1; 284944d303ebSJoe Perches $in_commit_log = 0; 285044d303ebSJoe Perches } 285144d303ebSJoe Perches 2852e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2853e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2854e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2855e0d975b1SJoe Perches $reported_maintainer_file = 1; 2856e0d975b1SJoe Perches } 2857e0d975b1SJoe Perches 285820112475SJoe Perches# Check signature styles 2859270c49a0SJoe Perches if (!$in_header_lines && 2860ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 286120112475SJoe Perches my $space_before = $1; 286220112475SJoe Perches my $sign_off = $2; 286320112475SJoe Perches my $space_after = $3; 286420112475SJoe Perches my $email = $4; 286520112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 286620112475SJoe Perches 2867ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2868831242abSAditya Srivastava my $suggested_signature = find_standard_signature($sign_off); 2869831242abSAditya Srivastava if ($suggested_signature eq "") { 2870ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2871ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2872831242abSAditya Srivastava } else { 2873831242abSAditya Srivastava if (WARN("BAD_SIGN_OFF", 2874831242abSAditya Srivastava "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && 2875831242abSAditya Srivastava $fix) { 2876831242abSAditya Srivastava $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; 2877831242abSAditya Srivastava } 2878831242abSAditya Srivastava } 2879ce0338dfSJoe Perches } 288020112475SJoe Perches if (defined $space_before && $space_before ne "") { 28813705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 28823705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 28833705ce5bSJoe Perches $fix) { 2884194f66fcSJoe Perches $fixed[$fixlinenr] = 28853705ce5bSJoe Perches "$ucfirst_sign_off $email"; 28863705ce5bSJoe Perches } 288720112475SJoe Perches } 288820112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 28893705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 28903705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 28913705ce5bSJoe Perches $fix) { 2892194f66fcSJoe Perches $fixed[$fixlinenr] = 28933705ce5bSJoe Perches "$ucfirst_sign_off $email"; 28943705ce5bSJoe Perches } 28953705ce5bSJoe Perches 289620112475SJoe Perches } 289720112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 28983705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 28993705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 29003705ce5bSJoe Perches $fix) { 2901194f66fcSJoe Perches $fixed[$fixlinenr] = 29023705ce5bSJoe Perches "$ucfirst_sign_off $email"; 29033705ce5bSJoe Perches } 290420112475SJoe Perches } 290520112475SJoe Perches 2906dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 290748ca2d8aSDwaipayan Ray my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); 290820112475SJoe Perches if ($suggested_email eq "") { 2909000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 2910000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 291120112475SJoe Perches } else { 291220112475SJoe Perches my $dequoted = $suggested_email; 291320112475SJoe Perches $dequoted =~ s/^"//; 291420112475SJoe Perches $dequoted =~ s/" </ </; 291520112475SJoe Perches # Don't force email to have quotes 291620112475SJoe Perches # Allow just an angle bracketed address 2917fccaebf0SDwaipayan Ray if (!same_email_addresses($email, $suggested_email)) { 2918fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 2919fccaebf0SDwaipayan Ray "email address '$email' might be better as '$suggested_email'\n" . $herecurr) && 2920fccaebf0SDwaipayan Ray $fix) { 2921fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/; 2922fccaebf0SDwaipayan Ray } 2923fccaebf0SDwaipayan Ray } 2924fccaebf0SDwaipayan Ray 2925fccaebf0SDwaipayan Ray # Address part shouldn't have comments 2926fccaebf0SDwaipayan Ray my $stripped_address = $email_address; 2927fccaebf0SDwaipayan Ray $stripped_address =~ s/\([^\(\)]*\)//g; 2928fccaebf0SDwaipayan Ray if ($email_address ne $stripped_address) { 2929fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 2930fccaebf0SDwaipayan Ray "address part of email should not have comments: '$email_address'\n" . $herecurr) && 2931fccaebf0SDwaipayan Ray $fix) { 2932fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/; 2933fccaebf0SDwaipayan Ray } 2934fccaebf0SDwaipayan Ray } 2935fccaebf0SDwaipayan Ray 2936fccaebf0SDwaipayan Ray # Only one name comment should be allowed 2937fccaebf0SDwaipayan Ray my $comment_count = () = $name_comment =~ /\([^\)]+\)/g; 2938fccaebf0SDwaipayan Ray if ($comment_count > 1) { 2939000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 2940fccaebf0SDwaipayan Ray "Use a single name comment in email: '$email'\n" . $herecurr); 2941fccaebf0SDwaipayan Ray } 2942fccaebf0SDwaipayan Ray 2943fccaebf0SDwaipayan Ray 2944fccaebf0SDwaipayan Ray # [email protected] or [email protected] shouldn't 2945e73d2715SDwaipayan Ray # have an email name. In addition comments should strictly 2946fccaebf0SDwaipayan Ray # begin with a # 2947fccaebf0SDwaipayan Ray if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { 2948fccaebf0SDwaipayan Ray if (($comment ne "" && $comment !~ /^#.+/) || 2949fccaebf0SDwaipayan Ray ($email_name ne "")) { 2950fccaebf0SDwaipayan Ray my $cur_name = $email_name; 2951fccaebf0SDwaipayan Ray my $new_comment = $comment; 2952fccaebf0SDwaipayan Ray $cur_name =~ s/[a-zA-Z\s\-\"]+//g; 2953fccaebf0SDwaipayan Ray 2954fccaebf0SDwaipayan Ray # Remove brackets enclosing comment text 2955fccaebf0SDwaipayan Ray # and # from start of comments to get comment text 2956fccaebf0SDwaipayan Ray $new_comment =~ s/^\((.*)\)$/$1/; 2957fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 2958fccaebf0SDwaipayan Ray $new_comment =~ s/^[\s\#]+|\s+$//g; 2959fccaebf0SDwaipayan Ray 2960fccaebf0SDwaipayan Ray $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); 2961fccaebf0SDwaipayan Ray $new_comment = " # $new_comment" if ($new_comment ne ""); 2962fccaebf0SDwaipayan Ray my $new_email = "$email_address$new_comment"; 2963fccaebf0SDwaipayan Ray 2964fccaebf0SDwaipayan Ray if (WARN("BAD_STABLE_ADDRESS_STYLE", 2965fccaebf0SDwaipayan Ray "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && 2966fccaebf0SDwaipayan Ray $fix) { 2967fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 2968fccaebf0SDwaipayan Ray } 2969fccaebf0SDwaipayan Ray } 2970fccaebf0SDwaipayan Ray } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { 2971fccaebf0SDwaipayan Ray my $new_comment = $comment; 2972fccaebf0SDwaipayan Ray 2973fccaebf0SDwaipayan Ray # Extract comment text from within brackets or 2974fccaebf0SDwaipayan Ray # c89 style /*...*/ comments 2975fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 2976fccaebf0SDwaipayan Ray $new_comment =~ s/^\/\*(.*)\*\/$/$1/; 2977fccaebf0SDwaipayan Ray 2978fccaebf0SDwaipayan Ray $new_comment = trim($new_comment); 2979fccaebf0SDwaipayan Ray $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo 2980fccaebf0SDwaipayan Ray $new_comment = "($new_comment)" if ($new_comment ne ""); 2981fccaebf0SDwaipayan Ray my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); 2982fccaebf0SDwaipayan Ray 2983fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 2984fccaebf0SDwaipayan Ray "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && 2985fccaebf0SDwaipayan Ray $fix) { 2986fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 2987fccaebf0SDwaipayan Ray } 298820112475SJoe Perches } 29890a920b5bSAndy Whitcroft } 29907e51f197SJoe Perches 29917e51f197SJoe Perches# Check for duplicate signatures 29927e51f197SJoe Perches my $sig_nospace = $line; 29937e51f197SJoe Perches $sig_nospace =~ s/\s//g; 29947e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 29957e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 29967e51f197SJoe Perches WARN("BAD_SIGN_OFF", 29977e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 29987e51f197SJoe Perches } else { 29997e51f197SJoe Perches $signatures{$sig_nospace} = 1; 30007e51f197SJoe Perches } 30016c5d24eeSSean Christopherson 30026c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 30036c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 30046c5d24eeSSean Christopherson if ($email eq $author) { 30056c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 30066c5d24eeSSean Christopherson "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); 30076c5d24eeSSean Christopherson } 30086c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 30096c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 30106c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); 30116c5d24eeSSean Christopherson } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { 30126c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 30136c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 30146c5d24eeSSean Christopherson } elsif ($1 ne $email) { 30156c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 30166c5d24eeSSean Christopherson "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 30176c5d24eeSSean Christopherson } 30186c5d24eeSSean Christopherson } 30190a920b5bSAndy Whitcroft } 30200a920b5bSAndy Whitcroft 3021a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 3022a2fe16b9SJoe Perches if ($in_header_lines && 3023a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 3024a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 3025a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 3026a2fe16b9SJoe Perches } 3027a2fe16b9SJoe Perches 302844d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context 302944d303ebSJoe Perches if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { 30307580c5b9SAditya Srivastava if (ERROR("GERRIT_CHANGE_ID", 30317580c5b9SAditya Srivastava "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && 30327580c5b9SAditya Srivastava $fix) { 30337580c5b9SAditya Srivastava fix_delete_line($fixlinenr, $rawline); 30347580c5b9SAditya Srivastava } 30357ebd05efSChristopher Covington } 30367ebd05efSChristopher Covington 3037369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 3038369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3039369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 3040369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 3041369c8dd3SJoe Perches # timestamp 3042634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 3043634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 3044634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 3045634cffccSJoe Perches # stack dump address styles 3046369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 3047369c8dd3SJoe Perches } 3048369c8dd3SJoe Perches 30492a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 30502a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 3051bf4daf12SJoe Perches length($line) > 75 && 3052bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 3053bf4daf12SJoe Perches # file delta changes 3054bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 3055bf4daf12SJoe Perches # filename then : 305627b379afSAditya Srivastava $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i || 305727b379afSAditya Srivastava # A Fixes: or Link: line or signature tag line 3058bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 30592a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 30602a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 30612a076f40SJoe Perches $commit_log_long_line = 1; 30622a076f40SJoe Perches } 30632a076f40SJoe Perches 3064bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 3065bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 3066bf4daf12SJoe Perches $line =~ /^\s*$/) { 3067bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 3068bf4daf12SJoe Perches } 3069bf4daf12SJoe Perches 3070084a617aSDwaipayan Ray# Check for lines starting with a # 3071084a617aSDwaipayan Ray if ($in_commit_log && $line =~ /^#/) { 3072084a617aSDwaipayan Ray if (WARN("COMMIT_COMMENT_SYMBOL", 3073084a617aSDwaipayan Ray "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && 3074084a617aSDwaipayan Ray $fix) { 3075084a617aSDwaipayan Ray $fixed[$fixlinenr] =~ s/^/ /; 3076084a617aSDwaipayan Ray } 3077084a617aSDwaipayan Ray } 3078084a617aSDwaipayan Ray 30790d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 3080369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3081a8972573SJohn Hubbard $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && 3082e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 3083fe043ea1SJoe Perches ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 3084aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 3085369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 3086bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 3087fe043ea1SJoe Perches my $init_char = "c"; 3088fe043ea1SJoe Perches my $orig_commit = ""; 30890d7835fcSJoe Perches my $short = 1; 30900d7835fcSJoe Perches my $long = 0; 30910d7835fcSJoe Perches my $case = 1; 30920d7835fcSJoe Perches my $space = 1; 30930d7835fcSJoe Perches my $hasdesc = 0; 309419c146a6SJoe Perches my $hasparens = 0; 30950d7835fcSJoe Perches my $id = '0123456789ab'; 30960d7835fcSJoe Perches my $orig_desc = "commit description"; 30970d7835fcSJoe Perches my $description = ""; 30980d7835fcSJoe Perches 3099fe043ea1SJoe Perches if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 3100fe043ea1SJoe Perches $init_char = $1; 3101fe043ea1SJoe Perches $orig_commit = lc($2); 3102fe043ea1SJoe Perches } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { 3103fe043ea1SJoe Perches $orig_commit = lc($1); 3104fe043ea1SJoe Perches } 3105fe043ea1SJoe Perches 31060d7835fcSJoe Perches $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 31070d7835fcSJoe Perches $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 31080d7835fcSJoe Perches $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 31090d7835fcSJoe Perches $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 31100d7835fcSJoe Perches if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 31110d7835fcSJoe Perches $orig_desc = $1; 311219c146a6SJoe Perches $hasparens = 1; 31130d7835fcSJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 31140d7835fcSJoe Perches defined $rawlines[$linenr] && 31150d7835fcSJoe Perches $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 31160d7835fcSJoe Perches $orig_desc = $1; 311719c146a6SJoe Perches $hasparens = 1; 3118b671fde0SJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 3119b671fde0SJoe Perches defined $rawlines[$linenr] && 3120b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 3121b671fde0SJoe Perches $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 3122b671fde0SJoe Perches $orig_desc = $1; 3123b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 3124b671fde0SJoe Perches $orig_desc .= " " . $1; 312519c146a6SJoe Perches $hasparens = 1; 31260d7835fcSJoe Perches } 31270d7835fcSJoe Perches 31280d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 31290d7835fcSJoe Perches $id, $orig_desc); 31300d7835fcSJoe Perches 3131948b133aSHeinrich Schuchardt if (defined($id) && 3132948b133aSHeinrich Schuchardt ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { 3133d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 31340d7835fcSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 31350d7835fcSJoe Perches } 3136d311cd44SJoe Perches } 3137d311cd44SJoe Perches 313813f1937eSJoe Perches# Check for added, moved or deleted files 313913f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 314013f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 314113f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 314213f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 314313f1937eSJoe Perches (defined($1) || defined($2))))) { 3144a82603a8SAndrew Jeffery $is_patch = 1; 314513f1937eSJoe Perches $reported_maintainer_file = 1; 314613f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 314713f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 314813f1937eSJoe Perches } 314913f1937eSJoe Perches 3150e400edb1SRob Herring# Check for adding new DT bindings not in schema format 3151e400edb1SRob Herring if (!$in_commit_log && 3152e400edb1SRob Herring ($line =~ /^new file mode\s*\d+\s*$/) && 3153e400edb1SRob Herring ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { 3154e400edb1SRob Herring WARN("DT_SCHEMA_BINDING_PATCH", 3155*56ddc4cdSMauro Carvalho Chehab "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n"); 3156e400edb1SRob Herring } 3157e400edb1SRob Herring 315800df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 31598905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 3160000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 3161000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 31626c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 3163de7d4f0eSAndy Whitcroft } 3164de7d4f0eSAndy Whitcroft 3165de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 3166de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 3167171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 3168171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 3169171ae1a4SAndy Whitcroft 3170171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 3171171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 3172171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 3173171ae1a4SAndy Whitcroft 317434d99219SJoe Perches CHK("INVALID_UTF8", 3175000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 317600df344fSAndy Whitcroft } 31770a920b5bSAndy Whitcroft 317815662b3eSJoe Perches# Check if it's the start of a commit log 317915662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 318015662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 3181eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 3182eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 318315662b3eSJoe Perches $in_header_lines = 0; 318415662b3eSJoe Perches $in_commit_log = 1; 3185ed43c4e5SAllen Hubbe $has_commit_log = 1; 318615662b3eSJoe Perches } 318715662b3eSJoe Perches 3188fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 3189fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 3190fa64205dSPasi Savanainen if ($in_header_lines && 3191fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 3192fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 3193fa64205dSPasi Savanainen $non_utf8_charset = 1; 3194fa64205dSPasi Savanainen } 3195fa64205dSPasi Savanainen 3196fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 319715662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 3198fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 319915662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 320015662b3eSJoe Perches } 320115662b3eSJoe Perches 3202d6430f71SJoe Perches# Check for absolute kernel paths in commit message 3203d6430f71SJoe Perches if ($tree && $in_commit_log) { 3204d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 3205d6430f71SJoe Perches my $file = $1; 3206d6430f71SJoe Perches 3207d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 3208d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 3209d6430f71SJoe Perches # 3210d6430f71SJoe Perches } else { 3211d6430f71SJoe Perches check_absolute_file($file, $herecurr); 3212d6430f71SJoe Perches } 3213d6430f71SJoe Perches } 3214d6430f71SJoe Perches } 3215d6430f71SJoe Perches 321666b47b4aSKees Cook# Check for various typo / spelling mistakes 321766d7a382SJoe Perches if (defined($misspellings) && 321866d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 32197da07c31SDwaipayan Ray while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { 322066b47b4aSKees Cook my $typo = $1; 32217da07c31SDwaipayan Ray my $blank = copy_spacing($rawline); 32227da07c31SDwaipayan Ray my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); 32237da07c31SDwaipayan Ray my $hereptr = "$hereline$ptr\n"; 322466b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 322566b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 322666b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 32270675a8fbSJean Delvare my $msg_level = \&WARN; 32280675a8fbSJean Delvare $msg_level = \&CHK if ($file); 32290675a8fbSJean Delvare if (&{$msg_level}("TYPO_SPELLING", 32307da07c31SDwaipayan Ray "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && 323166b47b4aSKees Cook $fix) { 323266b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 323366b47b4aSKees Cook } 323466b47b4aSKees Cook } 323566b47b4aSKees Cook } 323666b47b4aSKees Cook 3237a8dd86bfSMatteo Croce# check for invalid commit id 3238a8dd86bfSMatteo Croce if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 3239a8dd86bfSMatteo Croce my $id; 3240a8dd86bfSMatteo Croce my $description; 3241a8dd86bfSMatteo Croce ($id, $description) = git_commit_info($2, undef, undef); 3242a8dd86bfSMatteo Croce if (!defined($id)) { 3243a8dd86bfSMatteo Croce WARN("UNKNOWN_COMMIT_ID", 3244a8dd86bfSMatteo Croce "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 3245a8dd86bfSMatteo Croce } 3246a8dd86bfSMatteo Croce } 3247a8dd86bfSMatteo Croce 3248310cd06bSJoe Perches# check for repeated words separated by a single space 32498d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root' 32508d0325ccSAditya Srivastava if (($rawline =~ /^\+/ || $in_commit_log) && 32518d0325ccSAditya Srivastava $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { 32521db81a68SDwaipayan Ray pos($rawline) = 1 if (!$in_commit_log); 3253310cd06bSJoe Perches while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { 3254310cd06bSJoe Perches 3255310cd06bSJoe Perches my $first = $1; 3256310cd06bSJoe Perches my $second = $2; 32571db81a68SDwaipayan Ray my $start_pos = $-[1]; 32581db81a68SDwaipayan Ray my $end_pos = $+[2]; 3259310cd06bSJoe Perches if ($first =~ /(?:struct|union|enum)/) { 3260310cd06bSJoe Perches pos($rawline) += length($first) + length($second) + 1; 3261310cd06bSJoe Perches next; 3262310cd06bSJoe Perches } 3263310cd06bSJoe Perches 32641db81a68SDwaipayan Ray next if (lc($first) ne lc($second)); 3265310cd06bSJoe Perches next if ($first eq 'long'); 3266310cd06bSJoe Perches 32671db81a68SDwaipayan Ray # check for character before and after the word matches 32681db81a68SDwaipayan Ray my $start_char = ''; 32691db81a68SDwaipayan Ray my $end_char = ''; 32701db81a68SDwaipayan Ray $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); 32711db81a68SDwaipayan Ray $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); 32721db81a68SDwaipayan Ray 32731db81a68SDwaipayan Ray next if ($start_char =~ /^\S$/); 32741db81a68SDwaipayan Ray next if (index(" \t.,;?!", $end_char) == -1); 32751db81a68SDwaipayan Ray 32768d0325ccSAditya Srivastava # avoid repeating hex occurrences like 'ff ff fe 09 ...' 32778d0325ccSAditya Srivastava if ($first =~ /\b[0-9a-f]{2,}\b/i) { 32788d0325ccSAditya Srivastava next if (!exists($allow_repeated_words{lc($first)})); 32798d0325ccSAditya Srivastava } 32808d0325ccSAditya Srivastava 3281310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3282310cd06bSJoe Perches "Possible repeated word: '$first'\n" . $herecurr) && 3283310cd06bSJoe Perches $fix) { 3284310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; 3285310cd06bSJoe Perches } 3286310cd06bSJoe Perches } 3287310cd06bSJoe Perches 3288310cd06bSJoe Perches # if it's a repeated word on consecutive lines in a comment block 3289310cd06bSJoe Perches if ($prevline =~ /$;+\s*$/ && 3290310cd06bSJoe Perches $prevrawline =~ /($word_pattern)\s*$/) { 3291310cd06bSJoe Perches my $last_word = $1; 3292310cd06bSJoe Perches if ($rawline =~ /^\+\s*\*\s*$last_word /) { 3293310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3294310cd06bSJoe Perches "Possible repeated word: '$last_word'\n" . $hereprev) && 3295310cd06bSJoe Perches $fix) { 3296310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; 3297310cd06bSJoe Perches } 3298310cd06bSJoe Perches } 3299310cd06bSJoe Perches } 3300310cd06bSJoe Perches } 3301310cd06bSJoe Perches 330230670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 330330670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 330400df344fSAndy Whitcroft 33050a920b5bSAndy Whitcroft#trailing whitespace 33069c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 3307c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3308d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 3309d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 3310d5e616fcSJoe Perches $fix) { 3311194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 3312d5e616fcSJoe Perches } 3313c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 3314c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 33153705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 33163705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 33173705ce5bSJoe Perches $fix) { 3318194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 33193705ce5bSJoe Perches } 33203705ce5bSJoe Perches 3321d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 33220a920b5bSAndy Whitcroft } 33235368df20SAndy Whitcroft 33244783f894SJosh Triplett# Check for FSF mailing addresses. 3325109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 33261bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 33273e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 33283e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 33294783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 33300675a8fbSJean Delvare my $msg_level = \&ERROR; 33310675a8fbSJean Delvare $msg_level = \&CHK if ($file); 33320675a8fbSJean Delvare &{$msg_level}("FSF_MAILING_ADDRESS", 33334783f894SJosh Triplett "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) 33344783f894SJosh Triplett } 33354783f894SJosh Triplett 33363354957aSAndi Kleen# check for Kconfig help text having a real description 33379fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 33389fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 33393354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 3340678ae162SUlf Magnusson # 'choice' is usually the last thing on the line (though 3341678ae162SUlf Magnusson # Kconfig supports named choices), so use a word boundary 3342678ae162SUlf Magnusson # (\b) rather than a whitespace character (\s) 3343678ae162SUlf Magnusson $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 33443354957aSAndi Kleen my $length = 0; 33459fe287d7SAndy Whitcroft my $cnt = $realcnt; 33469fe287d7SAndy Whitcroft my $ln = $linenr + 1; 33479fe287d7SAndy Whitcroft my $f; 3348a1385803SAndy Whitcroft my $is_start = 0; 33499fe287d7SAndy Whitcroft my $is_end = 0; 3350a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 33519fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 33529fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 33539fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 33549fe287d7SAndy Whitcroft 33559fe287d7SAndy Whitcroft next if ($f =~ /^-/); 33568d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 3357a1385803SAndy Whitcroft 335886adf1a0SUlf Magnusson if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 3359a1385803SAndy Whitcroft $is_start = 1; 336022a4ac02SMasahiro Yamada } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 3361a1385803SAndy Whitcroft $length = -1; 3362a1385803SAndy Whitcroft } 3363a1385803SAndy Whitcroft 33649fe287d7SAndy Whitcroft $f =~ s/^.//; 33653354957aSAndi Kleen $f =~ s/#.*//; 33663354957aSAndi Kleen $f =~ s/^\s+//; 33673354957aSAndi Kleen next if ($f =~ /^$/); 3368678ae162SUlf Magnusson 3369678ae162SUlf Magnusson # This only checks context lines in the patch 3370678ae162SUlf Magnusson # and so hopefully shouldn't trigger false 3371678ae162SUlf Magnusson # positives, even though some of these are 3372678ae162SUlf Magnusson # common words in help texts 3373678ae162SUlf Magnusson if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| 3374678ae162SUlf Magnusson if|endif|menu|endmenu|source)\b/x) { 33759fe287d7SAndy Whitcroft $is_end = 1; 33769fe287d7SAndy Whitcroft last; 33779fe287d7SAndy Whitcroft } 33783354957aSAndi Kleen $length++; 33793354957aSAndi Kleen } 338056193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 3381000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 338256193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 338356193274SVadim Bendebury } 3384a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 33853354957aSAndi Kleen } 33863354957aSAndi Kleen 33877ccf41a8SJoe Perches# check MAINTAINERS entries 33887ccf41a8SJoe Perches if ($realfile =~ /^MAINTAINERS$/) { 33897ccf41a8SJoe Perches# check MAINTAINERS entries for the right form 33907ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 3391628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3392628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3393628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3394628f91a2SJoe Perches $fix) { 3395628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3396628f91a2SJoe Perches } 3397628f91a2SJoe Perches } 33987ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too 33997ccf41a8SJoe Perches my $preferred_order = 'MRLSWQBCPTFXNK'; 34007ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 34017ccf41a8SJoe Perches $prevrawline =~ /^[\+ ][A-Z]:/) { 34027ccf41a8SJoe Perches $rawline =~ /^\+([A-Z]):\s*(.*)/; 34037ccf41a8SJoe Perches my $cur = $1; 34047ccf41a8SJoe Perches my $curval = $2; 34057ccf41a8SJoe Perches $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; 34067ccf41a8SJoe Perches my $prev = $1; 34077ccf41a8SJoe Perches my $prevval = $2; 34087ccf41a8SJoe Perches my $curindex = index($preferred_order, $cur); 34097ccf41a8SJoe Perches my $previndex = index($preferred_order, $prev); 34107ccf41a8SJoe Perches if ($curindex < 0) { 34117ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 34127ccf41a8SJoe Perches "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); 34137ccf41a8SJoe Perches } else { 34147ccf41a8SJoe Perches if ($previndex >= 0 && $curindex < $previndex) { 34157ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 34167ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); 34177ccf41a8SJoe Perches } elsif ((($prev eq 'F' && $cur eq 'F') || 34187ccf41a8SJoe Perches ($prev eq 'X' && $cur eq 'X')) && 34197ccf41a8SJoe Perches ($prevval cmp $curval) > 0) { 34207ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 34217ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); 34227ccf41a8SJoe Perches } 34237ccf41a8SJoe Perches } 34247ccf41a8SJoe Perches } 34257ccf41a8SJoe Perches } 3426628f91a2SJoe Perches 3427c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3428c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3429c68e5878SArnaud Lacombe my $flag = $1; 3430c68e5878SArnaud Lacombe my $replacement = { 3431c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 3432c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 3433c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 3434c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 3435c68e5878SArnaud Lacombe }; 3436c68e5878SArnaud Lacombe 3437c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 3438c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3439c68e5878SArnaud Lacombe } 3440c68e5878SArnaud Lacombe 3441bff5da43SRob Herring# check for DT compatible documentation 34427dd05b38SFlorian Vaussard if (defined $root && 34437dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 34447dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 34457dd05b38SFlorian Vaussard 3446bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3447bff5da43SRob Herring 3448cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3449852d095dSRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3450cc93319bSFlorian Vaussard 3451bff5da43SRob Herring foreach my $compat (@compats) { 3452bff5da43SRob Herring my $compat2 = $compat; 3453185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3454185d566bSRob Herring my $compat3 = $compat; 3455185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3456185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3457bff5da43SRob Herring if ( $? >> 8 ) { 3458bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3459bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3460bff5da43SRob Herring } 3461bff5da43SRob Herring 34624fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 34634fbf32a6SFlorian Vaussard my $vendor = $1; 3464852d095dSRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3465bff5da43SRob Herring if ( $? >> 8 ) { 3466bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3467cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3468bff5da43SRob Herring } 3469bff5da43SRob Herring } 3470bff5da43SRob Herring } 3471bff5da43SRob Herring 34729f3a8992SRob Herring# check for using SPDX license tag at beginning of files 34739f3a8992SRob Herring if ($realline == $checklicenseline) { 34749f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 34759f3a8992SRob Herring $checklicenseline = 2; 34769f3a8992SRob Herring } elsif ($rawline =~ /^\+/) { 34779f3a8992SRob Herring my $comment = ""; 34789f3a8992SRob Herring if ($realfile =~ /\.(h|s|S)$/) { 34799f3a8992SRob Herring $comment = '/*'; 34809f3a8992SRob Herring } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { 34819f3a8992SRob Herring $comment = '//'; 3482c8df0ab6SLubomir Rintel } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 34839f3a8992SRob Herring $comment = '#'; 34849f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 34859f3a8992SRob Herring $comment = '..'; 34869f3a8992SRob Herring } 34879f3a8992SRob Herring 3488fdf13693SJoe Perches# check SPDX comment style for .[chsS] files 3489fdf13693SJoe Perches if ($realfile =~ /\.[chsS]$/ && 3490fdf13693SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 3491ffbce897SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 3492fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3493fdf13693SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3494fdf13693SJoe Perches } 3495fdf13693SJoe Perches 34969f3a8992SRob Herring if ($comment !~ /^$/ && 3497ffbce897SJoe Perches $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 34989f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 34999f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 35003b6e8ac9SJoe Perches } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 35013b6e8ac9SJoe Perches my $spdx_license = $1; 35023b6e8ac9SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 35033b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 35043b6e8ac9SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 35053b6e8ac9SJoe Perches } 350650c92900SLubomir Rintel if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 350750c92900SLubomir Rintel not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { 350850c92900SLubomir Rintel my $msg_level = \&WARN; 350950c92900SLubomir Rintel $msg_level = \&CHK if ($file); 351050c92900SLubomir Rintel if (&{$msg_level}("SPDX_LICENSE_TAG", 351150c92900SLubomir Rintel 351250c92900SLubomir Rintel "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 351350c92900SLubomir Rintel $fix) { 351450c92900SLubomir Rintel $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 351550c92900SLubomir Rintel } 351650c92900SLubomir Rintel } 35179f3a8992SRob Herring } 35189f3a8992SRob Herring } 35199f3a8992SRob Herring } 35209f3a8992SRob Herring 3521a0154cdbSJoe Perches# check for embedded filenames 3522a0154cdbSJoe Perches if ($rawline =~ /^\+.*\Q$realfile\E/) { 3523a0154cdbSJoe Perches WARN("EMBEDDED_FILENAME", 3524a0154cdbSJoe Perches "It's generally not useful to have the filename in the file\n" . $herecurr); 3525a0154cdbSJoe Perches } 3526a0154cdbSJoe Perches 35275368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 3528d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 35295368df20SAndy Whitcroft 3530a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3531a8da38a9SJoe Perches if ($realline != $checklicenseline && 3532a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3533a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3534a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3535a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3536a8da38a9SJoe Perches } 3537a8da38a9SJoe Perches 353847e0c88bSJoe Perches# line length limit (with some exclusions) 353947e0c88bSJoe Perches# 354047e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 354147e0c88bSJoe Perches# logging functions like pr_info that end in a string 354247e0c88bSJoe Perches# lines with a single string 354347e0c88bSJoe Perches# #defines that are a single string 35442e4bbbc5SAndreas Brauchli# lines with an RFC3986 like URL 354547e0c88bSJoe Perches# 354647e0c88bSJoe Perches# There are 3 different line length message types: 3547ab1ecabfSJean Delvare# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 354847e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 354947e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 355047e0c88bSJoe Perches# 355147e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 355247e0c88bSJoe Perches# 355347e0c88bSJoe Perches 3554b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 355547e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 355647e0c88bSJoe Perches 355747e0c88bSJoe Perches # Check the allowed long line types first 355847e0c88bSJoe Perches 355947e0c88bSJoe Perches # logging functions that end in a string that starts 356047e0c88bSJoe Perches # before $max_line_length 356147e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 356247e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 356347e0c88bSJoe Perches $msg_type = ""; 356447e0c88bSJoe Perches 356547e0c88bSJoe Perches # lines with only strings (w/ possible termination) 356647e0c88bSJoe Perches # #defines with only strings 356747e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 356847e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 356947e0c88bSJoe Perches $msg_type = ""; 357047e0c88bSJoe Perches 3571cc147506SJoe Perches # More special cases 3572cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3573cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3574d560a5f8SJoe Perches $msg_type = ""; 3575d560a5f8SJoe Perches 35762e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 35772e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 35782e4bbbc5SAndreas Brauchli $msg_type = ""; 35792e4bbbc5SAndreas Brauchli 358047e0c88bSJoe Perches # Otherwise set the alternate message types 358147e0c88bSJoe Perches 358247e0c88bSJoe Perches # a comment starts before $max_line_length 358347e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 358447e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 358547e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 358647e0c88bSJoe Perches 358747e0c88bSJoe Perches # a quoted string starts before $max_line_length 358847e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 358947e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 359047e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 359147e0c88bSJoe Perches } 359247e0c88bSJoe Perches 359347e0c88bSJoe Perches if ($msg_type ne "" && 359447e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 3595bdc48fa1SJoe Perches my $msg_level = \&WARN; 3596bdc48fa1SJoe Perches $msg_level = \&CHK if ($file); 3597bdc48fa1SJoe Perches &{$msg_level}($msg_type, 3598bdc48fa1SJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 35990a920b5bSAndy Whitcroft } 360047e0c88bSJoe Perches } 36010a920b5bSAndy Whitcroft 36028905a67cSAndy Whitcroft# check for adding lines without a newline. 36038905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 360447ca69b8STom Rix if (WARN("MISSING_EOF_NEWLINE", 360547ca69b8STom Rix "adding a line without newline at end of file\n" . $herecurr) && 360647ca69b8STom Rix $fix) { 360747ca69b8STom Rix fix_delete_line($fixlinenr+1, "No newline at end of file"); 360847ca69b8STom Rix } 36098905a67cSAndy Whitcroft } 36108905a67cSAndy Whitcroft 3611de93245cSAditya Srivastava# check for .L prefix local symbols in .S files 3612de93245cSAditya Srivastava if ($realfile =~ /\.S$/ && 3613de93245cSAditya Srivastava $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { 3614de93245cSAditya Srivastava WARN("AVOID_L_PREFIX", 3615de93245cSAditya Srivastava "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\n" . $herecurr); 3616de93245cSAditya Srivastava } 3617de93245cSAditya Srivastava 3618b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3619de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 36200a920b5bSAndy Whitcroft 36210a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 3622713a09deSAntonio Borneo# more than $tabsize must use tabs. 3623c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3624c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3625c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3626d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 36273705ce5bSJoe Perches if (ERROR("CODE_INDENT", 36283705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 36293705ce5bSJoe Perches $fix) { 3630194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 36313705ce5bSJoe Perches } 36320a920b5bSAndy Whitcroft } 36330a920b5bSAndy Whitcroft 363408e44365SAlberto Panizzo# check for space before tabs. 363508e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 363608e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 36373705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 36383705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 36393705ce5bSJoe Perches $fix) { 3640194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3641713a09deSAntonio Borneo s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 3642194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3643c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 36443705ce5bSJoe Perches } 364508e44365SAlberto Panizzo } 364608e44365SAlberto Panizzo 36476a487211SJoe Perches# check for assignments on the start of a line 36486a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 3649da7355abSAditya Srivastava my $operator = $1; 3650da7355abSAditya Srivastava if (CHK("ASSIGNMENT_CONTINUATIONS", 3651da7355abSAditya Srivastava "Assignment operator '$1' should be on the previous line\n" . $hereprev) && 3652da7355abSAditya Srivastava $fix && $prevrawline =~ /^\+/) { 3653da7355abSAditya Srivastava # add assignment operator to the previous line, remove from current line 3654da7355abSAditya Srivastava $fixed[$fixlinenr - 1] .= " $operator"; 3655da7355abSAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 3656da7355abSAditya Srivastava } 36576a487211SJoe Perches } 36586a487211SJoe Perches 3659d1fe9c09SJoe Perches# check for && or || at the start of a line 3660d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 36618e08f076SAditya Srivastava my $operator = $1; 36628e08f076SAditya Srivastava if (CHK("LOGICAL_CONTINUATIONS", 36638e08f076SAditya Srivastava "Logical continuations should be on the previous line\n" . $hereprev) && 36648e08f076SAditya Srivastava $fix && $prevrawline =~ /^\+/) { 36658e08f076SAditya Srivastava # insert logical operator at last non-comment, non-whitepsace char on previous line 36668e08f076SAditya Srivastava $prevline =~ /[\s$;]*$/; 36678e08f076SAditya Srivastava my $line_end = substr($prevrawline, $-[0]); 36688e08f076SAditya Srivastava $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; 36698e08f076SAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 36708e08f076SAditya Srivastava } 3671d1fe9c09SJoe Perches } 3672d1fe9c09SJoe Perches 3673a91e8994SJoe Perches# check indentation starts on a tab stop 36745b57980dSJoe Perches if ($perl_version_ok && 3675bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3676a91e8994SJoe Perches my $indent = length($1); 3677713a09deSAntonio Borneo if ($indent % $tabsize) { 3678a91e8994SJoe Perches if (WARN("TABSTOP", 3679a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3680a91e8994SJoe Perches $fix) { 3681713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 3682a91e8994SJoe Perches } 3683a91e8994SJoe Perches } 3684a91e8994SJoe Perches } 3685a91e8994SJoe Perches 3686d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 36875b57980dSJoe Perches if ($perl_version_ok && 3688fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3689d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3690d1fe9c09SJoe Perches my $oldindent = $1; 3691d1fe9c09SJoe Perches my $rest = $2; 3692d1fe9c09SJoe Perches 3693d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3694d1fe9c09SJoe Perches if ($pos >= 0) { 3695b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3696b34a26f3SJoe Perches my $newindent = $2; 3697d1fe9c09SJoe Perches 3698d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3699713a09deSAntonio Borneo "\t" x ($pos / $tabsize) . 3700713a09deSAntonio Borneo " " x ($pos % $tabsize); 3701d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3702d1fe9c09SJoe Perches 3703d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3704d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 37053705ce5bSJoe Perches 37063705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 37073705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 37083705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3709194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37103705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 37113705ce5bSJoe Perches } 3712d1fe9c09SJoe Perches } 3713d1fe9c09SJoe Perches } 3714d1fe9c09SJoe Perches } 3715d1fe9c09SJoe Perches 37166ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 37176ab3a970SJoe Perches# avoid checking a few false positives: 37186ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 37196ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 37206ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 37216ab3a970SJoe Perches# multiline macros that define functions 37226ab3a970SJoe Perches# known attributes or the __attribute__ keyword 37236ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 37246ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 37253705ce5bSJoe Perches if (CHK("SPACING", 3726f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 37273705ce5bSJoe Perches $fix) { 3728194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3729f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 37303705ce5bSJoe Perches } 3731aad4f614SJoe Perches } 3732aad4f614SJoe Perches 373386406b1cSJoe Perches# Block comment styles 373486406b1cSJoe Perches# Networking with an initial /* 373505880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3736fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 373785ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 3738c70735c2SŁukasz Stelmach $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier 373905880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 374005880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 374105880600SJoe Perches } 374205880600SJoe Perches 374386406b1cSJoe Perches# Block comments use * on subsequent lines 374486406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 374586406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3746a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 374761135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3748a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 374986406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 375086406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3751a605e32eSJoe Perches } 3752a605e32eSJoe Perches 375386406b1cSJoe Perches# Block comments use */ on trailing lines 375486406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3755c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3756c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3757c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 375886406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 375986406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 376005880600SJoe Perches } 376105880600SJoe Perches 376208eb9b80SJoe Perches# Block comment * alignment 376308eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3764af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3765af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3766af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 376708eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3768af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3769af207524SJoe Perches my $oldindent; 377008eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3771af207524SJoe Perches if (defined($1)) { 3772af207524SJoe Perches $oldindent = expand_tabs($1); 3773af207524SJoe Perches } else { 3774af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3775af207524SJoe Perches $oldindent = expand_tabs($1); 3776af207524SJoe Perches } 377708eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 377808eb9b80SJoe Perches my $newindent = $1; 377908eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3780af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 378108eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 378208eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 378308eb9b80SJoe Perches } 378408eb9b80SJoe Perches } 378508eb9b80SJoe Perches 37867f619191SJoe Perches# check for missing blank lines after struct/union declarations 37877f619191SJoe Perches# with exceptions for various attributes and macros 37887f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 37897f619191SJoe Perches $line =~ /^\+/ && 37907f619191SJoe Perches !($line =~ /^\+\s*$/ || 37917f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 37927f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 37937f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 37947f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 37957f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 37967f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 37970bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 37987f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3799d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3800d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3801d752fcc8SJoe Perches $fix) { 3802f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3803d752fcc8SJoe Perches } 38047f619191SJoe Perches } 38057f619191SJoe Perches 3806365dd4eaSJoe Perches# check for multiple consecutive blank lines 3807365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3808365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3809365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3810d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3811d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3812d752fcc8SJoe Perches $fix) { 3813f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3814d752fcc8SJoe Perches } 3815d752fcc8SJoe Perches 3816365dd4eaSJoe Perches $last_blank_line = $linenr; 3817365dd4eaSJoe Perches } 3818365dd4eaSJoe Perches 38193b617e3bSJoe Perches# check for missing blank lines after declarations 3820b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line) 3821b5e8736aSJoe Perches if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) { 3822b5e8736aSJoe Perches # use temporaries 3823b5e8736aSJoe Perches my $sl = $sline; 3824b5e8736aSJoe Perches my $pl = $prevline; 3825b5e8736aSJoe Perches # remove $Attribute/$Sparse uses to simplify comparisons 3826b5e8736aSJoe Perches $sl =~ s/\b(?:$Attribute|$Sparse)\b//g; 3827b5e8736aSJoe Perches $pl =~ s/\b(?:$Attribute|$Sparse)\b//g; 3828b5e8736aSJoe Perches if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 38295a4e1fd3SJoe Perches # function pointer declarations 3830b5e8736aSJoe Perches $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 38313f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 3832b5e8736aSJoe Perches $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 38333f7bac03SJoe Perches # known declaration macros 3834b5e8736aSJoe Perches $pl =~ /^\+\s+$declaration_macros/) && 38353f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 3836b5e8736aSJoe Perches !($pl =~ /^\+\s+$c90_Keywords\b/ || 38373f7bac03SJoe Perches # other possible extensions of declaration lines 3838b5e8736aSJoe Perches $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 38393f7bac03SJoe Perches # not starting a section or a macro "\" extended line 3840b5e8736aSJoe Perches $pl =~ /(?:\{\s*|\\)$/) && 38413f7bac03SJoe Perches # looks like a declaration 3842b5e8736aSJoe Perches !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 38435a4e1fd3SJoe Perches # function pointer declarations 3844b5e8736aSJoe Perches $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 38453f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 3846b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 38473f7bac03SJoe Perches # known declaration macros 3848b5e8736aSJoe Perches $sl =~ /^\+\s+$declaration_macros/ || 38493f7bac03SJoe Perches # start of struct or union or enum 3850b5e8736aSJoe Perches $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 38513f7bac03SJoe Perches # start or end of block or continuation of declaration 3852b5e8736aSJoe Perches $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 38533f7bac03SJoe Perches # bitfield continuation 3854b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 38553f7bac03SJoe Perches # other possible extensions of declaration lines 3856b5e8736aSJoe Perches $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) { 3857d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3858d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3859d752fcc8SJoe Perches $fix) { 3860f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3861d752fcc8SJoe Perches } 38623b617e3bSJoe Perches } 3863b5e8736aSJoe Perches } 38643b617e3bSJoe Perches 38655f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 38666b4c5bebSAndy Whitcroft# Exceptions: 38676b4c5bebSAndy Whitcroft# 1) within comments 38686b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 38696b4c5bebSAndy Whitcroft# 3) hanging labels 38703705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 38715f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 38723705ce5bSJoe Perches if (WARN("LEADING_SPACE", 38733705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 38743705ce5bSJoe Perches $fix) { 3875194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 38763705ce5bSJoe Perches } 38775f7ddae6SRaffaele Recalcati } 38785f7ddae6SRaffaele Recalcati 3879b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3880b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3881b9ea10d6SAndy Whitcroft 38825751a24eSJoe Perches# check for unusual line ending [ or ( 38835751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 38845751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 38855751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 38865751a24eSJoe Perches } 38875751a24eSJoe Perches 38884dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 38894dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 38904dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 38914dbed76fSJoe Perches $context_function = $1; 38924dbed76fSJoe Perches } 38934dbed76fSJoe Perches 38944dbed76fSJoe Perches# check if this appears to be the end of function declaration 38954dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 38964dbed76fSJoe Perches undef $context_function; 38974dbed76fSJoe Perches } 38984dbed76fSJoe Perches 3899032a4c0fSJoe Perches# check indentation of any line with a bare else 3900840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3901032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3902032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3903032a4c0fSJoe Perches my $tabs = length($1) + 1; 3904840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3905840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3906840080a0SJoe Perches defined $lines[$linenr] && 3907840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3908032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3909032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3910032a4c0fSJoe Perches } 3911032a4c0fSJoe Perches } 3912032a4c0fSJoe Perches 3913c00df19aSJoe Perches# check indentation of a line with a break; 3914dc58bc55SJoe Perches# if the previous line is a goto, return or break 3915dc58bc55SJoe Perches# and is indented the same # of tabs 3916c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3917c00df19aSJoe Perches my $tabs = $1; 3918dc58bc55SJoe Perches if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { 3919dc58bc55SJoe Perches if (WARN("UNNECESSARY_BREAK", 3920dc58bc55SJoe Perches "break is not useful after a $1\n" . $hereprev) && 3921dc58bc55SJoe Perches $fix) { 3922dc58bc55SJoe Perches fix_delete_line($fixlinenr, $rawline); 3923dc58bc55SJoe Perches } 3924c00df19aSJoe Perches } 3925c00df19aSJoe Perches } 3926c00df19aSJoe Perches 3927c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3928cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3929000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3930000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3931c2fdda0dSAndy Whitcroft } 393222f2a2efSAndy Whitcroft 393356e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 393456e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 393556e77d70SJoe Perches WARN("HOTPLUG_SECTION", 393656e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 393756e77d70SJoe Perches } 393856e77d70SJoe Perches 39399c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 39402b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 39412b474a1aSAndy Whitcroft $realline_next); 39423e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 3943ca819864SJoe Perches if ($linenr > $suppress_statement && 39441b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3945170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3946f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3947171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3948171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3949171ae1a4SAndy Whitcroft 39503e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 39513e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 39523e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 39533e469cdcSAndy Whitcroft # until we hit end of it. 39543e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 39553e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 39563e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 39573e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 39583e469cdcSAndy Whitcroft } 3959f74bd194SAndy Whitcroft 39602b474a1aSAndy Whitcroft # Find the real next line. 39612b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 39622b474a1aSAndy Whitcroft if (defined $realline_next && 39632b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 39642b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 39652b474a1aSAndy Whitcroft $realline_next++; 39662b474a1aSAndy Whitcroft } 39672b474a1aSAndy Whitcroft 3968171ae1a4SAndy Whitcroft my $s = $stat; 3969171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3970cf655043SAndy Whitcroft 3971c2fdda0dSAndy Whitcroft # Ignore goto labels. 3972171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3973c2fdda0dSAndy Whitcroft 3974c2fdda0dSAndy Whitcroft # Ignore functions being called 3975171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3976c2fdda0dSAndy Whitcroft 3977463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3978463f2864SAndy Whitcroft 3979c45dcabdSAndy Whitcroft # declarations always start with types 3980d2506586SAndy Whitcroft } 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) { 3981c45dcabdSAndy Whitcroft my $type = $1; 3982c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3983c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3984c45dcabdSAndy Whitcroft 39856c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3986a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3987c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3988c2fdda0dSAndy Whitcroft } 39898905a67cSAndy Whitcroft 39906c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 399165863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3992c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 39939c0ca6f9SAndy Whitcroft } 39948905a67cSAndy Whitcroft 39958905a67cSAndy Whitcroft # Check for any sort of function declaration. 39968905a67cSAndy Whitcroft # int foo(something bar, other baz); 39978905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3998171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 39998905a67cSAndy Whitcroft my ($name_len) = length($1); 40008905a67cSAndy Whitcroft 4001cf655043SAndy Whitcroft my $ctx = $s; 4002773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 40038905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 4004cf655043SAndy Whitcroft 40058905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 4006c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 40078905a67cSAndy Whitcroft 4008c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 40098905a67cSAndy Whitcroft } 40108905a67cSAndy Whitcroft } 40118905a67cSAndy Whitcroft } 40128905a67cSAndy Whitcroft 40139c0ca6f9SAndy Whitcroft } 40149c0ca6f9SAndy Whitcroft 401500df344fSAndy Whitcroft# 401600df344fSAndy Whitcroft# Checks which may be anchored in the context. 401700df344fSAndy Whitcroft# 401800df344fSAndy Whitcroft 401900df344fSAndy Whitcroft# Check for switch () and associated case and default 402000df344fSAndy Whitcroft# statements should be at the same indent. 402100df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 402200df344fSAndy Whitcroft my $err = ''; 402300df344fSAndy Whitcroft my $sep = ''; 402400df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 402500df344fSAndy Whitcroft shift(@ctx); 402600df344fSAndy Whitcroft for my $ctx (@ctx) { 402700df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 402800df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 402900df344fSAndy Whitcroft $indent != $cindent) { 403000df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 403100df344fSAndy Whitcroft $sep = ''; 403200df344fSAndy Whitcroft } else { 403300df344fSAndy Whitcroft $sep = "[...]\n"; 403400df344fSAndy Whitcroft } 403500df344fSAndy Whitcroft } 403600df344fSAndy Whitcroft if ($err ne '') { 4037000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 4038000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 4039de7d4f0eSAndy Whitcroft } 4040de7d4f0eSAndy Whitcroft } 4041de7d4f0eSAndy Whitcroft 4042de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 4043de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 40440fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 4045773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 4046773647a0SAndy Whitcroft 40479c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 40488eef05ddSJoe Perches 40498eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 40508eef05ddSJoe Perches WARN("DEEP_INDENTATION", 40518eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 40528eef05ddSJoe Perches } 40538eef05ddSJoe Perches 4054de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 4055de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 4056de7d4f0eSAndy Whitcroft 4057548596d5SAndy Whitcroft my $ctx_ln = $linenr; 4058548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 4059de7d4f0eSAndy Whitcroft 4060548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 4061548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 4062548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 4063548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 4064548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 4065773647a0SAndy Whitcroft $ctx_ln++; 4066773647a0SAndy Whitcroft } 4067548596d5SAndy Whitcroft 406853210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 406953210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 4070773647a0SAndy Whitcroft 4071773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 4072000d1cc1SJoe Perches ERROR("OPEN_BRACE", 4073000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 407401464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 407500df344fSAndy Whitcroft } 4076773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 4077773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 4078773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 4079773647a0SAndy Whitcroft { 40809c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 40819c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 4082000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 4083000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 408401464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 40859c0ca6f9SAndy Whitcroft } 40869c0ca6f9SAndy Whitcroft } 408700df344fSAndy Whitcroft } 408800df344fSAndy Whitcroft 40894d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 4090f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 40913e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 40923e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 40933e469cdcSAndy Whitcroft if (!defined $stat); 40944d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 40954d001e4dSAndy Whitcroft 40964d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 40974d001e4dSAndy Whitcroft 40989f5af480SJoe Perches # remove inline comments 40999f5af480SJoe Perches $s =~ s/$;/ /g; 41009f5af480SJoe Perches $c =~ s/$;/ /g; 41014d001e4dSAndy Whitcroft 41024d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 41036f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 41046f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 41054d001e4dSAndy Whitcroft 41069f5af480SJoe Perches # Make sure we remove the line prefixes as we have 41079f5af480SJoe Perches # none on the first line, and are going to readd them 41089f5af480SJoe Perches # where necessary. 41099f5af480SJoe Perches $s =~ s/\n./\n/gs; 41109f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 41119f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 41129f5af480SJoe Perches } 41139f5af480SJoe Perches 41144d001e4dSAndy Whitcroft # We want to check the first line inside the block 41154d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 41164d001e4dSAndy Whitcroft # 1) any blank line termination 41174d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 41184d001e4dSAndy Whitcroft # 3) any do (...) { 41194d001e4dSAndy Whitcroft my $continuation = 0; 41204d001e4dSAndy Whitcroft my $check = 0; 41214d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 41224d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 41234d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 41244d001e4dSAndy Whitcroft $continuation = 1; 41254d001e4dSAndy Whitcroft } 41269bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 41274d001e4dSAndy Whitcroft $check = 1; 41284d001e4dSAndy Whitcroft $cond_lines++; 41294d001e4dSAndy Whitcroft } 41304d001e4dSAndy Whitcroft 41314d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 41324d001e4dSAndy Whitcroft # preprocessor statement. 41334d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 41344d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 41354d001e4dSAndy Whitcroft $check = 0; 41364d001e4dSAndy Whitcroft } 41374d001e4dSAndy Whitcroft 41389bd49efeSAndy Whitcroft my $cond_ptr = -1; 4139740504c6SAndy Whitcroft $continuation = 0; 41409bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 41419bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 41424d001e4dSAndy Whitcroft 4143f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 4144f16fa28fSAndy Whitcroft # is not linear. 4145f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 4146f16fa28fSAndy Whitcroft $check = 0; 4147f16fa28fSAndy Whitcroft } 4148f16fa28fSAndy Whitcroft 41499bd49efeSAndy Whitcroft # Ignore: 41509bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 41519bd49efeSAndy Whitcroft # 2) preprocessor lines, and 41529bd49efeSAndy Whitcroft # 3) labels. 4153740504c6SAndy Whitcroft if ($continuation || 4154740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 41559bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 41569bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 4157740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 415830dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 41599bd49efeSAndy Whitcroft $cond_lines++; 41609bd49efeSAndy Whitcroft } 41614d001e4dSAndy Whitcroft } 416230dad6ebSAndy Whitcroft } 41634d001e4dSAndy Whitcroft 41644d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 41654d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 41664d001e4dSAndy Whitcroft 41674d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 41684d001e4dSAndy Whitcroft # this is not this patch's fault. 41694d001e4dSAndy Whitcroft if (!defined($stat_real) || 41704d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 41714d001e4dSAndy Whitcroft $check = 0; 41724d001e4dSAndy Whitcroft } 41734d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 41744d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 41754d001e4dSAndy Whitcroft } 41764d001e4dSAndy Whitcroft 41779bd49efeSAndy Whitcroft #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"; 41784d001e4dSAndy Whitcroft 41799f5af480SJoe Perches if ($check && $s ne '' && 4180713a09deSAntonio Borneo (($sindent % $tabsize) != 0 || 41819f5af480SJoe Perches ($sindent < $indent) || 4182f6950a73SJoe Perches ($sindent == $indent && 4183f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 4184713a09deSAntonio Borneo ($sindent > $indent + $tabsize))) { 4185000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 4186000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 41874d001e4dSAndy Whitcroft } 41884d001e4dSAndy Whitcroft } 41894d001e4dSAndy Whitcroft 41906c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 41916c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 41921f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 41931f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 41946c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 4195c2fdda0dSAndy Whitcroft if ($dbg_values) { 4196c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 4197cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 4198cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 41991f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 4200c2fdda0dSAndy Whitcroft } 42016c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 42026c72ffaaSAndy Whitcroft 420300df344fSAndy Whitcroft#ignore lines not being added 42043705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 420500df344fSAndy Whitcroft 420699ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings 420799ca38c2SJoe Perches# e.g.: int foo = foo, *bar = NULL; 420899ca38c2SJoe Perches# struct foo bar = *(&(bar)); 420999ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { 421099ca38c2SJoe Perches my $var = $1; 421199ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { 421299ca38c2SJoe Perches WARN("SELF_ASSIGNMENT", 421399ca38c2SJoe Perches "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); 421499ca38c2SJoe Perches } 421599ca38c2SJoe Perches } 421699ca38c2SJoe Perches 421711ca40a0SJoe Perches# check for dereferences that span multiple lines 421811ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 421911ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 422011ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 422111ca40a0SJoe Perches my $ref = $1; 422211ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 422311ca40a0SJoe Perches $ref .= $1; 422411ca40a0SJoe Perches $ref =~ s/\s//g; 422511ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 422611ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 422711ca40a0SJoe Perches } 422811ca40a0SJoe Perches 4229a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 4230c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 4231a1ce18e4SJoe Perches my $type = $1; 4232a1ce18e4SJoe Perches my $var = $2; 4233207a8e84SJoe Perches $var = "" if (!defined $var); 4234207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 4235a1ce18e4SJoe Perches my $sign = $1; 4236a1ce18e4SJoe Perches my $pointer = $2; 4237a1ce18e4SJoe Perches 4238a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 4239a1ce18e4SJoe Perches 4240a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 4241a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 4242a1ce18e4SJoe Perches $fix) { 4243a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 4244207a8e84SJoe Perches my $comp_pointer = $pointer; 4245207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 4246207a8e84SJoe Perches $decl .= $comp_pointer; 4247207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 4248207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 4249a1ce18e4SJoe Perches } 4250a1ce18e4SJoe Perches } 4251a1ce18e4SJoe Perches } 4252a1ce18e4SJoe Perches 4253653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 42547429c690SAndy Whitcroft if ($dbg_type) { 42557429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 4256000d1cc1SJoe Perches ERROR("TEST_TYPE", 4257000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 42587429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 4259000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 4260000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 42617429c690SAndy Whitcroft } 4262653d4876SAndy Whitcroft next; 4263653d4876SAndy Whitcroft } 4264a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 4265a1ef277eSAndy Whitcroft if ($dbg_attr) { 42669360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 4267000d1cc1SJoe Perches ERROR("TEST_ATTR", 4268000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 42699360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 4270000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 4271000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 4272a1ef277eSAndy Whitcroft } 4273a1ef277eSAndy Whitcroft next; 4274a1ef277eSAndy Whitcroft } 4275653d4876SAndy Whitcroft 4276f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 427799423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 427899423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 4279d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 4280d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 4281f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 4282f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 4283f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 4284d752fcc8SJoe Perches my $fixedline = $prevrawline; 4285d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 4286f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4287d752fcc8SJoe Perches $fixedline = $line; 42888d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 4289f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4290d752fcc8SJoe Perches } 4291f0a594c1SAndy Whitcroft } 4292f0a594c1SAndy Whitcroft 429300df344fSAndy Whitcroft# 429400df344fSAndy Whitcroft# Checks which are anchored on the added line. 429500df344fSAndy Whitcroft# 429600df344fSAndy Whitcroft 4297653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 4298c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 4299653d4876SAndy Whitcroft my $path = $1; 4300653d4876SAndy Whitcroft if ($path =~ m{//}) { 4301000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 4302495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 4303495e9d84SJoe Perches } 4304495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 4305495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 4306495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 4307653d4876SAndy Whitcroft } 4308653d4876SAndy Whitcroft } 4309653d4876SAndy Whitcroft 431000df344fSAndy Whitcroft# no C99 // comments 431100df344fSAndy Whitcroft if ($line =~ m{//}) { 43123705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 43133705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 43143705ce5bSJoe Perches $fix) { 4315194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 43163705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 43173705ce5bSJoe Perches my $comment = trim($1); 4318194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 43193705ce5bSJoe Perches } 43203705ce5bSJoe Perches } 432100df344fSAndy Whitcroft } 432200df344fSAndy Whitcroft # Remove C99 comments. 43230a920b5bSAndy Whitcroft $line =~ s@//.*@@; 43246c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 43250a920b5bSAndy Whitcroft 43262b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 43272b474a1aSAndy Whitcroft# the whole statement. 43282b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 43292b474a1aSAndy Whitcroft if (defined $realline_next && 43302b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 43312b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 433236794822SChristoph Hellwig ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 43333cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 43343cbf62dfSAndy Whitcroft # a prefix: 43353cbf62dfSAndy Whitcroft # XXX(foo); 43363cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 4337653d4876SAndy Whitcroft my $name = $1; 433887a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 43393cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 43403cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 43413cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 43423cbf62dfSAndy Whitcroft 43433cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 43442b474a1aSAndy Whitcroft \n.}\s*$| 434548012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 434648012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 434748012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 43482b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 43492b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 435048012058SAndy Whitcroft )/x) { 43512b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 43522b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 43532b474a1aSAndy Whitcroft } else { 43542b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 43550a920b5bSAndy Whitcroft } 43560a920b5bSAndy Whitcroft } 43572b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 43582b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 435936794822SChristoph Hellwig ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 43602b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 43612b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 43622b474a1aSAndy Whitcroft } 43632b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 43642b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 4365000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 4366000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 43672b474a1aSAndy Whitcroft } 43680a920b5bSAndy Whitcroft 43695150bda4SJoe Eloff# check for global initialisers. 43705b8f82e1SSong Liu if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ && 43715b8f82e1SSong Liu !exclude_global_initialisers($realfile)) { 4372d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 43736d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 4374d5e616fcSJoe Perches $fix) { 43756d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 4376d5e616fcSJoe Perches } 4377f0a594c1SAndy Whitcroft } 43780a920b5bSAndy Whitcroft# check for static initialisers. 43796d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 4380d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 43816d32f7a3SJoe Perches "do not initialise statics to $1\n" . 4382d5e616fcSJoe Perches $herecurr) && 4383d5e616fcSJoe Perches $fix) { 43846d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 4385d5e616fcSJoe Perches } 43860a920b5bSAndy Whitcroft } 43870a920b5bSAndy Whitcroft 43881813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 43891813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 43901813087dSJoe Perches my $tmp = trim($1); 43911813087dSJoe Perches WARN("MISORDERED_TYPE", 43921813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 43931813087dSJoe Perches } 43941813087dSJoe Perches 4395809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4396809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4397809e082eSJoe Perches my $type = trim($1); 4398809e082eSJoe Perches next if ($type !~ /\bint\b/); 4399809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 4400809e082eSJoe Perches my $new_type = $type; 4401809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 4402809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 4403809e082eSJoe Perches $new_type =~ s/^const\s+//; 4404809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 4405809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 4406809e082eSJoe Perches $new_type =~ s/\s+/ /g; 4407809e082eSJoe Perches $new_type = trim($new_type); 4408809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 4409809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4410809e082eSJoe Perches $fix) { 4411809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4412809e082eSJoe Perches } 4413809e082eSJoe Perches } 4414809e082eSJoe Perches 4415cb710ecaSJoe Perches# check for static const char * arrays. 4416cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4417000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4418000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 4419cb710ecaSJoe Perches $herecurr); 4420cb710ecaSJoe Perches } 4421cb710ecaSJoe Perches 442277b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 442377b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 442477b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 442577b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 442677b8c0a8SJoe Perches $fix) { 442777b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 442877b8c0a8SJoe Perches } 442977b8c0a8SJoe Perches } 443077b8c0a8SJoe Perches 4431cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 4432cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4433000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4434000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 4435cb710ecaSJoe Perches $herecurr); 4436cb710ecaSJoe Perches } 4437cb710ecaSJoe Perches 4438ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 4439ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 4440ab7e23f3SJoe Perches my $found = $1; 4441ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 4442ab7e23f3SJoe Perches WARN("CONST_CONST", 4443ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 4444ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4445ab7e23f3SJoe Perches WARN("CONST_CONST", 4446ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4447ab7e23f3SJoe Perches } 4448ab7e23f3SJoe Perches } 4449ab7e23f3SJoe Perches 445073169765SJoe Perches# check for const static or static <non ptr type> const declarations 445173169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const' 445273169765SJoe Perches if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || 445373169765SJoe Perches $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { 445473169765SJoe Perches if (WARN("STATIC_CONST", 445573169765SJoe Perches "Move const after static - use 'static const $1'\n" . $herecurr) && 445673169765SJoe Perches $fix) { 445773169765SJoe Perches $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; 445873169765SJoe Perches $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; 445973169765SJoe Perches } 446073169765SJoe Perches } 446173169765SJoe Perches 44629b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 44639b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 44649b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 44659b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 44669b0fa60dSJoe Perches $herecurr); 44679b0fa60dSJoe Perches } 44689b0fa60dSJoe Perches 4469b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 4470b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 4471b598b670SJoe Perches my $array = $1; 4472b598b670SJoe Perches if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { 4473b598b670SJoe Perches my $array_div = $1; 4474b598b670SJoe Perches if (WARN("ARRAY_SIZE", 4475b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 4476b598b670SJoe Perches $fix) { 4477b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4478b598b670SJoe Perches } 4479b598b670SJoe Perches } 4480b598b670SJoe Perches } 4481b598b670SJoe Perches 4482b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 448316b7f3c8SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4484b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4485b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4486b36190c5SJoe Perches $fix) { 4487194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4488b36190c5SJoe Perches } 4489b36190c5SJoe Perches } 4490b36190c5SJoe Perches 4491653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4492653d4876SAndy Whitcroft# make sense. 4493653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 44948054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4495c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 44968ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 449746d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4498000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4499000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 45000a920b5bSAndy Whitcroft } 45010a920b5bSAndy Whitcroft 45020a920b5bSAndy Whitcroft# * goes on variable not on type 450365863862SAndy Whitcroft # (char*[ const]) 4504bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4505bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 45063705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4507d8aaf121SAndy Whitcroft 450865863862SAndy Whitcroft # Should start with a space. 450965863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 451065863862SAndy Whitcroft # Should not end with a space. 451165863862SAndy Whitcroft $to =~ s/\s+$//; 451265863862SAndy Whitcroft # '*'s should not have spaces between. 4513f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 451465863862SAndy Whitcroft } 4515d8aaf121SAndy Whitcroft 45163705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 451765863862SAndy Whitcroft if ($from ne $to) { 45183705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 45193705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 45203705ce5bSJoe Perches $fix) { 45213705ce5bSJoe Perches my $sub_from = $ident; 45223705ce5bSJoe Perches my $sub_to = $ident; 45233705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4524194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45253705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 45263705ce5bSJoe Perches } 452765863862SAndy Whitcroft } 4528bfcb2cc7SAndy Whitcroft } 4529bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4530bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 45313705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4532d8aaf121SAndy Whitcroft 453365863862SAndy Whitcroft # Should start with a space. 453465863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 453565863862SAndy Whitcroft # Should not end with a space. 453665863862SAndy Whitcroft $to =~ s/\s+$//; 453765863862SAndy Whitcroft # '*'s should not have spaces between. 4538f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 453965863862SAndy Whitcroft } 454065863862SAndy Whitcroft # Modifiers should have spaces. 454165863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 454265863862SAndy Whitcroft 45433705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4544667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 45453705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 45463705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 45473705ce5bSJoe Perches $fix) { 45483705ce5bSJoe Perches 45493705ce5bSJoe Perches my $sub_from = $match; 45503705ce5bSJoe Perches my $sub_to = $match; 45513705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4552194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45533705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 45543705ce5bSJoe Perches } 455565863862SAndy Whitcroft } 45560a920b5bSAndy Whitcroft } 45570a920b5bSAndy Whitcroft 45589d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 45599d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 45600675a8fbSJean Delvare my $msg_level = \&WARN; 45610675a8fbSJean Delvare $msg_level = \&CHK if ($file); 45620675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 45639d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 45649d3e3c70SJoe Perches } 45650a920b5bSAndy Whitcroft 45669d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 45678905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4568000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4569000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 45708905a67cSAndy Whitcroft } 45718905a67cSAndy Whitcroft 457217441227SJoe Perches# check for uses of printk_ratelimit 457317441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4574000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4575000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 457617441227SJoe Perches } 457717441227SJoe Perches 4578eeef5733SJoe Perches# printk should use KERN_* levels 4579eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4580000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4581eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 458200df344fSAndy Whitcroft } 45830a920b5bSAndy Whitcroft 4584f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL> 4585f5eea3b0SJoe Perches if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { 4586f5eea3b0SJoe Perches my $printk = $1; 4587f5eea3b0SJoe Perches my $modifier = $2; 4588f5eea3b0SJoe Perches my $orig = $3; 4589f5eea3b0SJoe Perches $modifier = "" if (!defined($modifier)); 4590243f3803SJoe Perches my $level = lc($orig); 4591243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 45928f26b837SJoe Perches my $level2 = $level; 45938f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4594f5eea3b0SJoe Perches $level .= $modifier; 4595f5eea3b0SJoe Perches $level2 .= $modifier; 4596243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4597f5eea3b0SJoe Perches "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); 4598243f3803SJoe Perches } 4599243f3803SJoe Perches 4600f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL> 4601dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4602dc139313SJoe Perches my $orig = $1; 4603dc139313SJoe Perches my $level = lc($orig); 4604dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4605dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4606dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4607dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4608dc139313SJoe Perches } 4609dc139313SJoe Perches 46108020b253SNicolas Boichat# trace_printk should not be used in production code. 46118020b253SNicolas Boichat if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { 46128020b253SNicolas Boichat WARN("TRACE_PRINTK", 46138020b253SNicolas Boichat "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); 46148020b253SNicolas Boichat } 46158020b253SNicolas Boichat 461691c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 461791c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 461891c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 461991c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 462091c9afafSAndy Lutomirski WARN("ENOSYS", 462191c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 462291c9afafSAndy Lutomirski } 462391c9afafSAndy Lutomirski 46246b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches. 46256b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. 46266b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected. 46276b9ea5ffSJakub Kicinski if (!$file && $line =~ /\bENOTSUPP\b/) { 46286b9ea5ffSJakub Kicinski if (WARN("ENOTSUPP", 46296b9ea5ffSJakub Kicinski "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && 46306b9ea5ffSJakub Kicinski $fix) { 46316b9ea5ffSJakub Kicinski $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; 46326b9ea5ffSJakub Kicinski } 46336b9ea5ffSJakub Kicinski } 46346b9ea5ffSJakub Kicinski 4635653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4636653d4876SAndy Whitcroft# or if closed on same line 46375b57980dSJoe Perches if ($perl_version_ok && 46382d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 46392d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 46402d453e3bSJoe Perches $sline !~ /}/) { 46418d182478SJoe Perches if (ERROR("OPEN_BRACE", 46422d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 46438d182478SJoe Perches $fix) { 46448d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 46458d182478SJoe Perches my $fixed_line = $rawline; 464603f49351SDwaipayan Ray $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; 46478d182478SJoe Perches my $line1 = $1; 46488d182478SJoe Perches my $line2 = $2; 46498d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 46508d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 46518d182478SJoe Perches if ($line2 !~ /^\s*$/) { 46528d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 46538d182478SJoe Perches } 46548d182478SJoe Perches } 46550a920b5bSAndy Whitcroft } 4656653d4876SAndy Whitcroft 46578905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 46588905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 46598905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 46608d182478SJoe Perches if (ERROR("OPEN_BRACE", 46618d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 46628d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46638d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46648d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 46658d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 46668d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46678d182478SJoe Perches $fixedline = $rawline; 46688d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 46698d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 46708d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46718d182478SJoe Perches } 46728d182478SJoe Perches } 46738905a67cSAndy Whitcroft } 46748905a67cSAndy Whitcroft 46750c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 46763705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 46773705ce5bSJoe Perches if (WARN("SPACING", 46783705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 46793705ce5bSJoe Perches $fix) { 4680194f66fcSJoe Perches $fixed[$fixlinenr] =~ 46813705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 46823705ce5bSJoe Perches } 46830c73b4ebSAndy Whitcroft } 46840c73b4ebSAndy Whitcroft 468531070b5dSJoe Perches# Function pointer declarations 468631070b5dSJoe Perches# check spacing between type, funcptr, and args 468731070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 468891f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 468931070b5dSJoe Perches my $declare = $1; 469031070b5dSJoe Perches my $pre_pointer_space = $2; 469131070b5dSJoe Perches my $post_pointer_space = $3; 469231070b5dSJoe Perches my $funcname = $4; 469331070b5dSJoe Perches my $post_funcname_space = $5; 469431070b5dSJoe Perches my $pre_args_space = $6; 469531070b5dSJoe Perches 469691f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 469791f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 469891f72e9cSJoe Perches# don't need a space so don't warn for those. 469991f72e9cSJoe Perches my $post_declare_space = ""; 470091f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 470191f72e9cSJoe Perches $post_declare_space = $1; 470291f72e9cSJoe Perches $declare = rtrim($declare); 470391f72e9cSJoe Perches } 470491f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 470531070b5dSJoe Perches WARN("SPACING", 470631070b5dSJoe Perches "missing space after return type\n" . $herecurr); 470791f72e9cSJoe Perches $post_declare_space = " "; 470831070b5dSJoe Perches } 470931070b5dSJoe Perches 471031070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 471191f72e9cSJoe Perches# This test is not currently implemented because these declarations are 471291f72e9cSJoe Perches# equivalent to 471391f72e9cSJoe Perches# int foo(int bar, ...) 471491f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 471591f72e9cSJoe Perches# 471691f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 471791f72e9cSJoe Perches# WARN("SPACING", 471891f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 471991f72e9cSJoe Perches# } 472031070b5dSJoe Perches 472131070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 472231070b5dSJoe Perches if (defined $pre_pointer_space && 472331070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 472431070b5dSJoe Perches WARN("SPACING", 472531070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 472631070b5dSJoe Perches } 472731070b5dSJoe Perches 472831070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 472931070b5dSJoe Perches if (defined $post_pointer_space && 473031070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 473131070b5dSJoe Perches WARN("SPACING", 473231070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 473331070b5dSJoe Perches } 473431070b5dSJoe Perches 473531070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 473631070b5dSJoe Perches if (defined $post_funcname_space && 473731070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 473831070b5dSJoe Perches WARN("SPACING", 473931070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 474031070b5dSJoe Perches } 474131070b5dSJoe Perches 474231070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 474331070b5dSJoe Perches if (defined $pre_args_space && 474431070b5dSJoe Perches $pre_args_space =~ /^\s/) { 474531070b5dSJoe Perches WARN("SPACING", 474631070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 474731070b5dSJoe Perches } 474831070b5dSJoe Perches 474931070b5dSJoe Perches if (show_type("SPACING") && $fix) { 4750194f66fcSJoe Perches $fixed[$fixlinenr] =~ 475191f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 475231070b5dSJoe Perches } 475331070b5dSJoe Perches } 475431070b5dSJoe Perches 47558d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 47568d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 4757fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4758fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 47598d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 47608d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 47618d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 4762fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 476338dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 47643705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 47653705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 47663705ce5bSJoe Perches $fix) { 4767194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47683705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 47693705ce5bSJoe Perches } 47708d31cfceSAndy Whitcroft } 47718d31cfceSAndy Whitcroft } 47728d31cfceSAndy Whitcroft 4773f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 47746c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4775c2fdda0dSAndy Whitcroft my $name = $1; 4776773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4777773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4778c2fdda0dSAndy Whitcroft 4779c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4780773647a0SAndy Whitcroft if ($name =~ /^(?: 4781773647a0SAndy Whitcroft if|for|while|switch|return|case| 4782773647a0SAndy Whitcroft volatile|__volatile__| 4783773647a0SAndy Whitcroft __attribute__|format|__extension__| 4784773647a0SAndy Whitcroft asm|__asm__)$/x) 4785773647a0SAndy Whitcroft { 4786c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4787c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4788c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4789c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4790773647a0SAndy Whitcroft 4791773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4792c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4793c2fdda0dSAndy Whitcroft 4794c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4795c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4796773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4797c2fdda0dSAndy Whitcroft 4798c2fdda0dSAndy Whitcroft } else { 47993705ce5bSJoe Perches if (WARN("SPACING", 48003705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 48013705ce5bSJoe Perches $fix) { 4802194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48033705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 48043705ce5bSJoe Perches } 4805f0a594c1SAndy Whitcroft } 48066c72ffaaSAndy Whitcroft } 48079a4cad4eSEric Nelson 4808653d4876SAndy Whitcroft# Check operator spacing. 48090a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 48103705ce5bSJoe Perches my $fixed_line = ""; 48113705ce5bSJoe Perches my $line_fixed = 0; 48123705ce5bSJoe Perches 48139c0ca6f9SAndy Whitcroft my $ops = qr{ 48149c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 48159c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 48169c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 48171f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 481884731623SJoe Perches \?:|\?|: 48199c0ca6f9SAndy Whitcroft }x; 4820cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 48213705ce5bSJoe Perches 48223705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 48233705ce5bSJoe Perches## foreach my $el (@elements) { 48243705ce5bSJoe Perches## print("el: <$el>\n"); 48253705ce5bSJoe Perches## } 48263705ce5bSJoe Perches 48273705ce5bSJoe Perches my @fix_elements = (); 482800df344fSAndy Whitcroft my $off = 0; 48296c72ffaaSAndy Whitcroft 48303705ce5bSJoe Perches foreach my $el (@elements) { 48313705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 48323705ce5bSJoe Perches $off += length($el); 48333705ce5bSJoe Perches } 48343705ce5bSJoe Perches 48353705ce5bSJoe Perches $off = 0; 48363705ce5bSJoe Perches 48376c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4838b34c648bSJoe Perches my $last_after = -1; 48396c72ffaaSAndy Whitcroft 48400a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 48413705ce5bSJoe Perches 48423705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 48433705ce5bSJoe Perches 48443705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 48453705ce5bSJoe Perches 48464a0df2efSAndy Whitcroft $off += length($elements[$n]); 48474a0df2efSAndy Whitcroft 484825985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4849773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4850773647a0SAndy Whitcroft my $cc = ''; 4851773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4852773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4853773647a0SAndy Whitcroft } 4854773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4855773647a0SAndy Whitcroft 48564a0df2efSAndy Whitcroft my $a = ''; 48574a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 48584a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4859cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 48604a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 48614a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4862773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 48634a0df2efSAndy Whitcroft 48640a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 48654a0df2efSAndy Whitcroft 48664a0df2efSAndy Whitcroft my $c = ''; 48670a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 48684a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 48694a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4870cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 48714a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 48724a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 48738b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 48744a0df2efSAndy Whitcroft } else { 48754a0df2efSAndy Whitcroft $c = 'E'; 48760a920b5bSAndy Whitcroft } 48770a920b5bSAndy Whitcroft 48784a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 48794a0df2efSAndy Whitcroft 48804a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 48814a0df2efSAndy Whitcroft 48826c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4883de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 48840a920b5bSAndy Whitcroft 488574048ed8SAndy Whitcroft # Pull out the value of this operator. 48866c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 48870a920b5bSAndy Whitcroft 48881f65f947SAndy Whitcroft # Get the full operator variant. 48891f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 48901f65f947SAndy Whitcroft 489113214adfSAndy Whitcroft # Ignore operators passed as parameters. 489213214adfSAndy Whitcroft if ($op_type ne 'V' && 4893d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 489413214adfSAndy Whitcroft 4895cf655043SAndy Whitcroft# # Ignore comments 4896cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 489713214adfSAndy Whitcroft 4898d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 489913214adfSAndy Whitcroft } elsif ($op eq ';') { 4900cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4901cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 49023705ce5bSJoe Perches if (ERROR("SPACING", 49033705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4904b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 49053705ce5bSJoe Perches $line_fixed = 1; 49063705ce5bSJoe Perches } 4907d8aaf121SAndy Whitcroft } 4908d8aaf121SAndy Whitcroft 4909d8aaf121SAndy Whitcroft # // is a comment 4910d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 49110a920b5bSAndy Whitcroft 4912b00e4814SJoe Perches # : when part of a bitfield 4913b00e4814SJoe Perches } elsif ($opv eq ':B') { 4914b00e4814SJoe Perches # skip the bitfield test for now 4915b00e4814SJoe Perches 49161f65f947SAndy Whitcroft # No spaces for: 49171f65f947SAndy Whitcroft # -> 4918b00e4814SJoe Perches } elsif ($op eq '->') { 49194a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 49203705ce5bSJoe Perches if (ERROR("SPACING", 49213705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4922b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 49233705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 49243705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 49253705ce5bSJoe Perches } 4926b34c648bSJoe Perches $line_fixed = 1; 49273705ce5bSJoe Perches } 49280a920b5bSAndy Whitcroft } 49290a920b5bSAndy Whitcroft 49302381097bSJoe Perches # , must not have a space before and must have a space on the right. 49310a920b5bSAndy Whitcroft } elsif ($op eq ',') { 49322381097bSJoe Perches my $rtrim_before = 0; 49332381097bSJoe Perches my $space_after = 0; 49342381097bSJoe Perches if ($ctx =~ /Wx./) { 49352381097bSJoe Perches if (ERROR("SPACING", 49362381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 49372381097bSJoe Perches $line_fixed = 1; 49382381097bSJoe Perches $rtrim_before = 1; 49392381097bSJoe Perches } 49402381097bSJoe Perches } 4941cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 49423705ce5bSJoe Perches if (ERROR("SPACING", 49433705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 49443705ce5bSJoe Perches $line_fixed = 1; 4945b34c648bSJoe Perches $last_after = $n; 49462381097bSJoe Perches $space_after = 1; 49472381097bSJoe Perches } 49482381097bSJoe Perches } 49492381097bSJoe Perches if ($rtrim_before || $space_after) { 49502381097bSJoe Perches if ($rtrim_before) { 49512381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 49522381097bSJoe Perches } else { 49532381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 49542381097bSJoe Perches } 49552381097bSJoe Perches if ($space_after) { 49562381097bSJoe Perches $good .= " "; 49573705ce5bSJoe Perches } 49580a920b5bSAndy Whitcroft } 49590a920b5bSAndy Whitcroft 49609c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 496174048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 49629c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 49639c0ca6f9SAndy Whitcroft 49649c0ca6f9SAndy Whitcroft # unary operators should have a space before and 49659c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 49669c0ca6f9SAndy Whitcroft # unary operator, or a cast 49679c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 496874048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 49690d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4970cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 49713705ce5bSJoe Perches if (ERROR("SPACING", 49723705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4973b34c648bSJoe Perches if ($n != $last_after + 2) { 4974b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 49753705ce5bSJoe Perches $line_fixed = 1; 49763705ce5bSJoe Perches } 49770a920b5bSAndy Whitcroft } 4978b34c648bSJoe Perches } 4979a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4980171ae1a4SAndy Whitcroft # A unary '*' may be const 4981171ae1a4SAndy Whitcroft 4982171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 49833705ce5bSJoe Perches if (ERROR("SPACING", 49843705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4985b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 49863705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 49873705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 49883705ce5bSJoe Perches } 4989b34c648bSJoe Perches $line_fixed = 1; 49903705ce5bSJoe Perches } 49910a920b5bSAndy Whitcroft } 49920a920b5bSAndy Whitcroft 49930a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 49940a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4995773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 49963705ce5bSJoe Perches if (ERROR("SPACING", 49973705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4998b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 49993705ce5bSJoe Perches $line_fixed = 1; 50003705ce5bSJoe Perches } 50010a920b5bSAndy Whitcroft } 5002773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 5003773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 50043705ce5bSJoe Perches if (ERROR("SPACING", 50053705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5006b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 50073705ce5bSJoe Perches $line_fixed = 1; 50083705ce5bSJoe Perches } 5009653d4876SAndy Whitcroft } 5010773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 50113705ce5bSJoe Perches if (ERROR("SPACING", 50123705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5013b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 50143705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 50153705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5016773647a0SAndy Whitcroft } 5017b34c648bSJoe Perches $line_fixed = 1; 50183705ce5bSJoe Perches } 50193705ce5bSJoe Perches } 50200a920b5bSAndy Whitcroft 50210a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 50229c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 50239c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 50249c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 5025c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 5026c2fdda0dSAndy Whitcroft $op eq '%') 50270a920b5bSAndy Whitcroft { 5028d2e025f3SJoe Perches if ($check) { 5029d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 5030d2e025f3SJoe Perches if (CHK("SPACING", 5031d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 5032d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5033d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5034d2e025f3SJoe Perches $line_fixed = 1; 5035d2e025f3SJoe Perches } 5036d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 5037d2e025f3SJoe Perches if (CHK("SPACING", 5038d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 5039d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 5040d2e025f3SJoe Perches $line_fixed = 1; 5041d2e025f3SJoe Perches } 5042d2e025f3SJoe Perches } 5043d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 50443705ce5bSJoe Perches if (ERROR("SPACING", 50453705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 5046b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5047b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5048b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5049b34c648bSJoe Perches } 50503705ce5bSJoe Perches $line_fixed = 1; 50513705ce5bSJoe Perches } 50520a920b5bSAndy Whitcroft } 50530a920b5bSAndy Whitcroft 50541f65f947SAndy Whitcroft # A colon needs no spaces before when it is 50551f65f947SAndy Whitcroft # terminating a case value or a label. 50561f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 5057263afd39SChris Down if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) { 50583705ce5bSJoe Perches if (ERROR("SPACING", 50593705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5060b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 50613705ce5bSJoe Perches $line_fixed = 1; 50623705ce5bSJoe Perches } 50631f65f947SAndy Whitcroft } 50641f65f947SAndy Whitcroft 50650a920b5bSAndy Whitcroft # All the others need spaces both sides. 5066cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 50671f65f947SAndy Whitcroft my $ok = 0; 50681f65f947SAndy Whitcroft 506922f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 50701f65f947SAndy Whitcroft if (($op eq '<' && 50711f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 50721f65f947SAndy Whitcroft ($op eq '>' && 50731f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 50741f65f947SAndy Whitcroft { 50751f65f947SAndy Whitcroft $ok = 1; 50761f65f947SAndy Whitcroft } 50771f65f947SAndy Whitcroft 5078e0df7e1fSJoe Perches # for asm volatile statements 5079e0df7e1fSJoe Perches # ignore a colon with another 5080e0df7e1fSJoe Perches # colon immediately before or after 5081e0df7e1fSJoe Perches if (($op eq ':') && 5082e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 5083e0df7e1fSJoe Perches $ok = 1; 5084e0df7e1fSJoe Perches } 5085e0df7e1fSJoe Perches 508684731623SJoe Perches # messages are ERROR, but ?: are CHK 50871f65f947SAndy Whitcroft if ($ok == 0) { 50880675a8fbSJean Delvare my $msg_level = \&ERROR; 50890675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 509084731623SJoe Perches 50910675a8fbSJean Delvare if (&{$msg_level}("SPACING", 50923705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 5093b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5094b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5095b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5096b34c648bSJoe Perches } 50973705ce5bSJoe Perches $line_fixed = 1; 50983705ce5bSJoe Perches } 50990a920b5bSAndy Whitcroft } 510022f2a2efSAndy Whitcroft } 51014a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 51023705ce5bSJoe Perches 51033705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 51043705ce5bSJoe Perches 51053705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 51060a920b5bSAndy Whitcroft } 51073705ce5bSJoe Perches 51083705ce5bSJoe Perches if (($#elements % 2) == 0) { 51093705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 51103705ce5bSJoe Perches } 51113705ce5bSJoe Perches 5112194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 5113194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 51143705ce5bSJoe Perches } 51153705ce5bSJoe Perches 51163705ce5bSJoe Perches 51170a920b5bSAndy Whitcroft } 51180a920b5bSAndy Whitcroft 5119786b6326SJoe Perches# check for whitespace before a non-naked semicolon 5120d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 5121786b6326SJoe Perches if (WARN("SPACING", 5122786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 5123786b6326SJoe Perches $fix) { 5124194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 5125786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 5126786b6326SJoe Perches } 5127786b6326SJoe Perches } 5128786b6326SJoe Perches 5129f0a594c1SAndy Whitcroft# check for multiple assignments 5130f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 5131000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 5132000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 5133f0a594c1SAndy Whitcroft } 5134f0a594c1SAndy Whitcroft 513522f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 513622f2a2efSAndy Whitcroft## # continuation. 513722f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 513822f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 513922f2a2efSAndy Whitcroft## 514022f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 5141e73d2715SDwaipayan Ray## # falsely report the parameters of functions. 514222f2a2efSAndy Whitcroft## my $ln = $line; 514322f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 514422f2a2efSAndy Whitcroft## } 514522f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 5146000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 5147000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 514822f2a2efSAndy Whitcroft## } 514922f2a2efSAndy Whitcroft## } 5150f0a594c1SAndy Whitcroft 51510a920b5bSAndy Whitcroft#need space before brace following if, while, etc 51526b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 51536ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 51543705ce5bSJoe Perches if (ERROR("SPACING", 51553705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 51563705ce5bSJoe Perches $fix) { 51576ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 51583705ce5bSJoe Perches } 5159de7d4f0eSAndy Whitcroft } 5160de7d4f0eSAndy Whitcroft 5161c4a62ef9SJoe Perches## # check for blank lines before declarations 5162c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 5163c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 5164c4a62ef9SJoe Perches## WARN("SPACING", 5165c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 5166c4a62ef9SJoe Perches## } 5167c4a62ef9SJoe Perches## 5168c4a62ef9SJoe Perches 5169de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 5170de7d4f0eSAndy Whitcroft# on the line 517194fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 5172d5e616fcSJoe Perches if (ERROR("SPACING", 5173d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 5174d5e616fcSJoe Perches $fix) { 5175194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5176d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 5177d5e616fcSJoe Perches } 51780a920b5bSAndy Whitcroft } 51790a920b5bSAndy Whitcroft 518022f2a2efSAndy Whitcroft# check spacing on square brackets 518122f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 51823705ce5bSJoe Perches if (ERROR("SPACING", 51833705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 51843705ce5bSJoe Perches $fix) { 5185194f66fcSJoe Perches $fixed[$fixlinenr] =~ 51863705ce5bSJoe Perches s/\[\s+/\[/; 51873705ce5bSJoe Perches } 518822f2a2efSAndy Whitcroft } 518922f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 51903705ce5bSJoe Perches if (ERROR("SPACING", 51913705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 51923705ce5bSJoe Perches $fix) { 5193194f66fcSJoe Perches $fixed[$fixlinenr] =~ 51943705ce5bSJoe Perches s/\s+\]/\]/; 51953705ce5bSJoe Perches } 519622f2a2efSAndy Whitcroft } 519722f2a2efSAndy Whitcroft 5198c45dcabdSAndy Whitcroft# check spacing on parentheses 51999c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 52009c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 52013705ce5bSJoe Perches if (ERROR("SPACING", 52023705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 52033705ce5bSJoe Perches $fix) { 5204194f66fcSJoe Perches $fixed[$fixlinenr] =~ 52053705ce5bSJoe Perches s/\(\s+/\(/; 52063705ce5bSJoe Perches } 520722f2a2efSAndy Whitcroft } 520813214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 5209c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 5210c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 52113705ce5bSJoe Perches if (ERROR("SPACING", 52123705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 52133705ce5bSJoe Perches $fix) { 5214194f66fcSJoe Perches $fixed[$fixlinenr] =~ 52153705ce5bSJoe Perches s/\s+\)/\)/; 52163705ce5bSJoe Perches } 521722f2a2efSAndy Whitcroft } 521822f2a2efSAndy Whitcroft 5219e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 5220e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 5221e2826fd0SJoe Perches 5222e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 5223ea4acbb1SJoe Perches my $var = $1; 5224ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5225ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 5226ea4acbb1SJoe Perches $fix) { 5227ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 5228ea4acbb1SJoe Perches } 5229ea4acbb1SJoe Perches } 5230ea4acbb1SJoe Perches 5231ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 5232ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 5233ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 5234ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 5235ea4acbb1SJoe Perches my $var = $2; 5236ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5237ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 5238ea4acbb1SJoe Perches $fix) { 5239ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 5240ea4acbb1SJoe Perches $var2 =~ s/\s//g; 5241ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 5242ea4acbb1SJoe Perches } 5243e2826fd0SJoe Perches } 5244e2826fd0SJoe Perches 524563b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 5246a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 5247a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 52485b57980dSJoe Perches $perl_version_ok && defined($stat) && 524963b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 525063b7c73eSJoe Perches my $if_stat = $1; 525163b7c73eSJoe Perches my $test = substr($2, 1, -1); 525263b7c73eSJoe Perches my $herectx; 525363b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 525463b7c73eSJoe Perches my $match = $1; 525563b7c73eSJoe Perches # avoid parentheses around potential macro args 525663b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 525763b7c73eSJoe Perches if (!defined($herectx)) { 525863b7c73eSJoe Perches $herectx = $here . "\n"; 525963b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 526063b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 526163b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 526263b7c73eSJoe Perches $herectx .= $rl . "\n"; 526363b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 526463b7c73eSJoe Perches } 526563b7c73eSJoe Perches } 526663b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 526763b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 526863b7c73eSJoe Perches } 526963b7c73eSJoe Perches } 527063b7c73eSJoe Perches 52710a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 52724a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 52730a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 52743705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 52753705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 52763705ce5bSJoe Perches $fix) { 5277194f66fcSJoe Perches $fixed[$fixlinenr] =~ 52783705ce5bSJoe Perches s/^(.)\s+/$1/; 52793705ce5bSJoe Perches } 52800a920b5bSAndy Whitcroft } 52810a920b5bSAndy Whitcroft 528240873abaSJoe Perches# check if a statement with a comma should be two statements like: 528340873abaSJoe Perches# foo = bar(), /* comma should be semicolon */ 528440873abaSJoe Perches# bar = baz(); 528540873abaSJoe Perches if (defined($stat) && 528640873abaSJoe Perches $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { 528740873abaSJoe Perches my $cnt = statement_rawlines($stat); 528840873abaSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 528940873abaSJoe Perches WARN("SUSPECT_COMMA_SEMICOLON", 529040873abaSJoe Perches "Possible comma where semicolon could be used\n" . $herectx); 529140873abaSJoe Perches } 529240873abaSJoe Perches 52935b9553abSJoe Perches# return is not a function 5294507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 5295c45dcabdSAndy Whitcroft my $spacing = $1; 52965b57980dSJoe Perches if ($perl_version_ok && 52975b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 52985b9553abSJoe Perches my $value = $1; 52995b9553abSJoe Perches $value = deparenthesize($value); 53005b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 5301000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 5302000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 53035b9553abSJoe Perches } 5304c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 5305000d1cc1SJoe Perches ERROR("SPACING", 5306000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 5307c45dcabdSAndy Whitcroft } 5308c45dcabdSAndy Whitcroft } 5309507e5141SJoe Perches 5310b43ae21bSJoe Perches# unnecessary return in a void function 5311b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 5312b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 5313b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 5314b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 5315b43ae21bSJoe Perches $linenr >= 3 && 5316b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 5317b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 53189819cf25SJoe Perches WARN("RETURN_VOID", 5319b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 53209819cf25SJoe Perches } 53219819cf25SJoe Perches 5322189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 53235b57980dSJoe Perches if ($perl_version_ok && 5324189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 5325189248d8SJoe Perches my $openparens = $1; 5326189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 5327189248d8SJoe Perches my $msg = ""; 5328189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 5329189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 5330189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 5331189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 5332189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 5333189248d8SJoe Perches } 5334189248d8SJoe Perches } 5335189248d8SJoe Perches 5336c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 5337c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 5338c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 5339c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 53405b57980dSJoe Perches if ($perl_version_ok && 5341c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 5342c5595fa2SJoe Perches my $lead = $1; 5343c5595fa2SJoe Perches my $const = $2; 5344c5595fa2SJoe Perches my $comp = $3; 5345c5595fa2SJoe Perches my $to = $4; 5346c5595fa2SJoe Perches my $newcomp = $comp; 5347f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 5348c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 5349c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 5350c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 5351c5595fa2SJoe Perches $fix) { 5352c5595fa2SJoe Perches if ($comp eq "<") { 5353c5595fa2SJoe Perches $newcomp = ">"; 5354c5595fa2SJoe Perches } elsif ($comp eq "<=") { 5355c5595fa2SJoe Perches $newcomp = ">="; 5356c5595fa2SJoe Perches } elsif ($comp eq ">") { 5357c5595fa2SJoe Perches $newcomp = "<"; 5358c5595fa2SJoe Perches } elsif ($comp eq ">=") { 5359c5595fa2SJoe Perches $newcomp = "<="; 5360c5595fa2SJoe Perches } 5361c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 5362c5595fa2SJoe Perches } 5363c5595fa2SJoe Perches } 5364c5595fa2SJoe Perches 5365f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 5366f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 536753a3c448SAndy Whitcroft my $name = $1; 536853a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 5369000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 5370f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 537153a3c448SAndy Whitcroft } 537253a3c448SAndy Whitcroft } 5373c45dcabdSAndy Whitcroft 53740a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 53754a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 53763705ce5bSJoe Perches if (ERROR("SPACING", 53773705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 53783705ce5bSJoe Perches $fix) { 5379194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53803705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 53813705ce5bSJoe Perches } 53820a920b5bSAndy Whitcroft } 53830a920b5bSAndy Whitcroft 5384f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 5385f5fe35ddSAndy Whitcroft# statements after the conditional. 5386170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 53873e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 53883e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 53893e469cdcSAndy Whitcroft if (!defined $stat); 5390170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 5391170d3a22SAndy Whitcroft $remain_next, $off_next); 5392170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 5393170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 5394170d3a22SAndy Whitcroft 5395170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 5396170d3a22SAndy Whitcroft # If the statement carries leading newlines, 5397170d3a22SAndy Whitcroft # then count those as offsets. 5398170d3a22SAndy Whitcroft my ($whitespace) = 5399170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 5400170d3a22SAndy Whitcroft my $offset = 5401170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 5402170d3a22SAndy Whitcroft 5403170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 5404170d3a22SAndy Whitcroft $offset} = 1; 5405170d3a22SAndy Whitcroft } 5406170d3a22SAndy Whitcroft } 5407170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 5408c11230f4SJoe Perches defined($stat) && defined($cond) && 5409170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 5410171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 54118905a67cSAndy Whitcroft 5412b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 541365b64b3bSJoe Perches if (ERROR("ASSIGN_IN_IF", 541465b64b3bSJoe Perches "do not use assignment in if condition\n" . $herecurr) && 541565b64b3bSJoe Perches $fix && $perl_version_ok) { 541665b64b3bSJoe Perches if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { 541765b64b3bSJoe Perches my $space = $1; 541865b64b3bSJoe Perches my $not = $2; 541965b64b3bSJoe Perches my $statement = $3; 542065b64b3bSJoe Perches my $assigned = $4; 542165b64b3bSJoe Perches my $test = $8; 542265b64b3bSJoe Perches my $against = $9; 542365b64b3bSJoe Perches my $brace = $15; 542465b64b3bSJoe Perches fix_delete_line($fixlinenr, $rawline); 542565b64b3bSJoe Perches fix_insert_line($fixlinenr, "$space$statement;"); 542665b64b3bSJoe Perches my $newline = "${space}if ("; 542765b64b3bSJoe Perches $newline .= '!' if defined($not); 542865b64b3bSJoe Perches $newline .= '(' if (defined $not && defined($test) && defined($against)); 542965b64b3bSJoe Perches $newline .= "$assigned"; 543065b64b3bSJoe Perches $newline .= " $test $against" if (defined($test) && defined($against)); 543165b64b3bSJoe Perches $newline .= ')' if (defined $not && defined($test) && defined($against)); 543265b64b3bSJoe Perches $newline .= ')'; 543365b64b3bSJoe Perches $newline .= " {" if (defined($brace)); 543465b64b3bSJoe Perches fix_insert_line($fixlinenr + 1, $newline); 543565b64b3bSJoe Perches } 543665b64b3bSJoe Perches } 54378905a67cSAndy Whitcroft } 54388905a67cSAndy Whitcroft 54398905a67cSAndy Whitcroft # Find out what is on the end of the line after the 54408905a67cSAndy Whitcroft # conditional. 5441773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 54428905a67cSAndy Whitcroft $s =~ s/\n.*//g; 544313214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 544453210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 544553210168SAndy Whitcroft $c !~ /}\s*while\s*/) 5446773647a0SAndy Whitcroft { 5447bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 5448bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 5449bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 545042bdf74cSHidetoshi Seto my $stat_real = ''; 5451bb44ad39SAndy Whitcroft 545242bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 545342bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 5454bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 5455bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 5456bb44ad39SAndy Whitcroft } 5457bb44ad39SAndy Whitcroft 5458000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5459000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 54608905a67cSAndy Whitcroft } 54618905a67cSAndy Whitcroft } 54628905a67cSAndy Whitcroft 546313214adfSAndy Whitcroft# Check for bitwise tests written as boolean 546413214adfSAndy Whitcroft if ($line =~ / 546513214adfSAndy Whitcroft (?: 546613214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 546713214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 546813214adfSAndy Whitcroft (?:\&\&|\|\|) 546913214adfSAndy Whitcroft | 547013214adfSAndy Whitcroft (?:\&\&|\|\|) 547113214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 547213214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 547313214adfSAndy Whitcroft )/x) 547413214adfSAndy Whitcroft { 5475000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 5476000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 547713214adfSAndy Whitcroft } 547813214adfSAndy Whitcroft 54798905a67cSAndy Whitcroft# if and else should not have general statements after it 548013214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 548113214adfSAndy Whitcroft my $s = $1; 548213214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 548313214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 5484000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5485000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 54860a920b5bSAndy Whitcroft } 548713214adfSAndy Whitcroft } 548839667782SAndy Whitcroft# if should not continue a brace 548939667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 5490000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5491048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 549239667782SAndy Whitcroft $herecurr); 549339667782SAndy Whitcroft } 5494a1080bf8SAndy Whitcroft# case and default should not have general statements after them 5495a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 5496a1080bf8SAndy Whitcroft $line !~ /\G(?: 54973fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5498a1080bf8SAndy Whitcroft \s*return\s+ 5499a1080bf8SAndy Whitcroft )/xg) 5500a1080bf8SAndy Whitcroft { 5501000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5502000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 5503a1080bf8SAndy Whitcroft } 55040a920b5bSAndy Whitcroft 55050a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 55060a920b5bSAndy Whitcroft # indent level to be relevant to each other. 55078b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 55080a920b5bSAndy Whitcroft $previndent == $indent) { 55098b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 55108b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 55118b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 55128b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 55138b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 55148b8856f4SJoe Perches my $fixedline = $prevrawline; 55158b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 55168b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 55178b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 55188b8856f4SJoe Perches } 55198b8856f4SJoe Perches $fixedline = $rawline; 55208b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 55218b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 55228b8856f4SJoe Perches } 55230a920b5bSAndy Whitcroft } 55240a920b5bSAndy Whitcroft 55258b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5526c2fdda0dSAndy Whitcroft $previndent == $indent) { 5527c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5528c2fdda0dSAndy Whitcroft 5529c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5530c2fdda0dSAndy Whitcroft # conditional. 5531773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5532c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5533c2fdda0dSAndy Whitcroft 5534c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 55358b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 55368b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 55378b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 55388b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 55398b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 55408b8856f4SJoe Perches my $fixedline = $prevrawline; 55418b8856f4SJoe Perches my $trailing = $rawline; 55428b8856f4SJoe Perches $trailing =~ s/^\+//; 55438b8856f4SJoe Perches $trailing = trim($trailing); 55448b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 55458b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 55468b8856f4SJoe Perches } 5547c2fdda0dSAndy Whitcroft } 5548c2fdda0dSAndy Whitcroft } 5549c2fdda0dSAndy Whitcroft 555095e2c602SJoe Perches#Specific variable tests 5551323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5552323c1260SJoe Perches my $var = $1; 555395e2c602SJoe Perches 555495e2c602SJoe Perches#CamelCase 5555807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5556be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 55574104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values 55584104a206SŁukasz Stelmach $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && 555922735ce8SJoe Perches#Ignore Page<foo> variants 5560807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5561d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB 5562d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 5563d439e6a5SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5564f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5565f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 55667e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 55677e781f67SJoe Perches my $word = $1; 55687e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5569d8b07710SJoe Perches if ($check) { 5570d8b07710SJoe Perches seed_camelcase_includes(); 5571d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5572d8b07710SJoe Perches seed_camelcase_file($realfile); 5573d8b07710SJoe Perches $camelcase_file_seeded = 1; 5574d8b07710SJoe Perches } 5575d8b07710SJoe Perches } 55767e781f67SJoe Perches if (!defined $camelcase{$word}) { 55777e781f67SJoe Perches $camelcase{$word} = 1; 5578be79794bSJoe Perches CHK("CAMELCASE", 55797e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 55807e781f67SJoe Perches } 5581323c1260SJoe Perches } 5582323c1260SJoe Perches } 55833445686aSJoe Perches } 55840a920b5bSAndy Whitcroft 55850a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5586d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5587d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5588d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5589d5e616fcSJoe Perches $fix) { 5590194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5591d5e616fcSJoe Perches } 55920a920b5bSAndy Whitcroft } 55930a920b5bSAndy Whitcroft 55940e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 55950e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5596c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5597e09dec48SAndy Whitcroft my $file = "$1.h"; 5598e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5599e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5600e09dec48SAndy Whitcroft $realfile ne $checkfile && 56017840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5602c45dcabdSAndy Whitcroft { 56030e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 56040e212e0aSFabian Frederick if ($asminclude > 0) { 5605e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5606000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5607000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5608e09dec48SAndy Whitcroft } else { 5609000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5610000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5611e09dec48SAndy Whitcroft } 56120a920b5bSAndy Whitcroft } 56130a920b5bSAndy Whitcroft } 56140e212e0aSFabian Frederick } 56150a920b5bSAndy Whitcroft 5616653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5617653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5618cf655043SAndy Whitcroft# in a known good container 5619b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5620b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5621d8aaf121SAndy Whitcroft my $ln = $linenr; 5622d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5623c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5624c45dcabdSAndy Whitcroft my $ctx = ''; 562508a2843eSJoe Perches my $has_flow_statement = 0; 562608a2843eSJoe Perches my $has_arg_concat = 0; 5627c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5628f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5629f74bd194SAndy Whitcroft $ctx = $dstat; 5630c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5631a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5632c45dcabdSAndy Whitcroft 563308a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 563462e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 563508a2843eSJoe Perches 5636f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5637f59b64bfSJoe Perches my $define_args = $1; 5638f59b64bfSJoe Perches my $define_stmt = $dstat; 5639f59b64bfSJoe Perches my @def_args = (); 5640f59b64bfSJoe Perches 5641f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5642f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5643f59b64bfSJoe Perches $define_args =~ s/\s*//g; 56448c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5645f59b64bfSJoe Perches @def_args = split(",", $define_args); 5646f59b64bfSJoe Perches } 5647f59b64bfSJoe Perches 5648292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5649c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5650c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5651c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5652c45dcabdSAndy Whitcroft 5653c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 56542e44e803SDwaipayan Ray while ($dstat =~ s/\([^\(\)]*\)/1u/ || 56552e44e803SDwaipayan Ray $dstat =~ s/\{[^\{\}]*\}/1u/ || 56562e44e803SDwaipayan Ray $dstat =~ s/.\[[^\[\]]*\]/1u/) 5657bf30d6edSAndy Whitcroft { 5658c45dcabdSAndy Whitcroft } 5659c45dcabdSAndy Whitcroft 5660342d3d2fSAntonio Borneo # Flatten any obvious string concatenation. 566133acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 566233acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5663e45bab8eSAndy Whitcroft { 5664e45bab8eSAndy Whitcroft } 5665e45bab8eSAndy Whitcroft 566642e15293SJoe Perches # Make asm volatile uses seem like a generic function 566742e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 566842e15293SJoe Perches 5669c45dcabdSAndy Whitcroft my $exceptions = qr{ 5670c45dcabdSAndy Whitcroft $Declare| 5671c45dcabdSAndy Whitcroft module_param_named| 5672a0a0a7a9SKees Cook MODULE_PARM_DESC| 5673c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5674c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5675383099fdSAndy Whitcroft __typeof__\(| 567622fd2d3eSStefani Seibold union| 567722fd2d3eSStefani Seibold struct| 5678ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 56796b10df42SVladimir Zapolskiy ^\"|\"$| 56806b10df42SVladimir Zapolskiy ^\[ 5681c45dcabdSAndy Whitcroft }x; 56825eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5683f59b64bfSJoe Perches 5684f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5685f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5686e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5687f59b64bfSJoe Perches 5688f74bd194SAndy Whitcroft if ($dstat ne '' && 5689f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5690f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 56913cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5692356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5693f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5694f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5695e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 569672f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 56972e44e803SDwaipayan Ray $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} 5698f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5699f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5700f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 57014e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5702f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5703c45dcabdSAndy Whitcroft { 5704e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5705e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5706e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5707e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5708f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5709f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5710f74bd194SAndy Whitcroft } else { 5711000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 5712388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5713d8aaf121SAndy Whitcroft } 5714f59b64bfSJoe Perches 5715f59b64bfSJoe Perches } 57165207649bSJoe Perches 57175207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 57185207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 57195207649bSJoe Perches my $first = 1; 57205207649bSJoe Perches $define_stmt = ""; 57215207649bSJoe Perches foreach my $l (@stmt_array) { 57225207649bSJoe Perches $l =~ s/\\$//; 57235207649bSJoe Perches if ($first) { 57245207649bSJoe Perches $define_stmt = $l; 57255207649bSJoe Perches $first = 0; 57265207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 57275207649bSJoe Perches $define_stmt .= substr($l, 1); 57285207649bSJoe Perches } 57295207649bSJoe Perches } 57305207649bSJoe Perches $define_stmt =~ s/$;//g; 57315207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 57325207649bSJoe Perches $define_stmt = trim($define_stmt); 57335207649bSJoe Perches 5734f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 5735f59b64bfSJoe Perches foreach my $arg (@def_args) { 5736f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 57379192d41aSJoe Perches next if ($arg =~ /^type$/i); 57387fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 57396dba824eSBrendan Jackman $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 57407fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 57417fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5742d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 5743f59b64bfSJoe Perches if ($use_cnt > 1) { 5744f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 5745f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5746f59b64bfSJoe Perches } 57479192d41aSJoe Perches# check if any macro arguments may have other precedence issues 57487fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 57499192d41aSJoe Perches ((defined($1) && $1 ne ',') || 57509192d41aSJoe Perches (defined($2) && $2 ne ','))) { 57519192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 57529192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 57539192d41aSJoe Perches } 57540a920b5bSAndy Whitcroft } 57555023d347SJoe Perches 575608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 575708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 575808a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 575908a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 5760e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 576108a2843eSJoe Perches 576208a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 576308a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 576408a2843eSJoe Perches } 576508a2843eSJoe Perches 5766481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 57675023d347SJoe Perches 57685023d347SJoe Perches } else { 57695023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 5770481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 5771481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 57725023d347SJoe Perches $line =~ /^\+.*\\$/) { 57735023d347SJoe Perches WARN("LINE_CONTINUATIONS", 57745023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 57755023d347SJoe Perches } 5776653d4876SAndy Whitcroft } 57770a920b5bSAndy Whitcroft 5778b13edf7fSJoe Perches# do {} while (0) macro tests: 5779b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 5780b13edf7fSJoe Perches# macro should not end with a semicolon 57815b57980dSJoe Perches if ($perl_version_ok && 5782b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 5783b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5784b13edf7fSJoe Perches my $ln = $linenr; 5785b13edf7fSJoe Perches my $cnt = $realcnt; 5786b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 5787b13edf7fSJoe Perches my $ctx = ''; 5788b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 5789b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 5790b13edf7fSJoe Perches $ctx = $dstat; 5791b13edf7fSJoe Perches 5792b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 57931b36b201SJoe Perches $dstat =~ s/$;/ /g; 5794b13edf7fSJoe Perches 5795b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 5796b13edf7fSJoe Perches my $stmts = $2; 5797b13edf7fSJoe Perches my $semis = $3; 5798b13edf7fSJoe Perches 5799b13edf7fSJoe Perches $ctx =~ s/\n*$//; 5800b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 5801e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5802b13edf7fSJoe Perches 5803ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 5804ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 5805b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 5806b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 5807b13edf7fSJoe Perches } 5808b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 5809b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 5810b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5811b13edf7fSJoe Perches } 5812f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5813f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5814f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5815e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5816f5ef95b1SJoe Perches 5817f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5818f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5819b13edf7fSJoe Perches } 5820b13edf7fSJoe Perches } 5821b13edf7fSJoe Perches 5822f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 582313214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 582413214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5825cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 582613214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5827cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5828cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5829aad4f614SJoe Perches my @allowed = (); 5830aad4f614SJoe Perches my $allow = 0; 583113214adfSAndy Whitcroft my $seen = 0; 5832773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5833cf655043SAndy Whitcroft my $ln = $linenr - 1; 583413214adfSAndy Whitcroft for my $chunk (@chunks) { 583513214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 583613214adfSAndy Whitcroft 5837773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5838773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5839773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5840773647a0SAndy Whitcroft 5841aad4f614SJoe Perches $allowed[$allow] = 0; 5842773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5843773647a0SAndy Whitcroft 5844773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5845773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5846773647a0SAndy Whitcroft 5847773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5848cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5849cf655043SAndy Whitcroft 5850773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 585113214adfSAndy Whitcroft 585213214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 585313214adfSAndy Whitcroft 5854aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5855cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5856cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5857aad4f614SJoe Perches $allowed[$allow] = 1; 585813214adfSAndy Whitcroft } 585913214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5860cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5861aad4f614SJoe Perches $allowed[$allow] = 1; 586213214adfSAndy Whitcroft } 5863cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5864cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5865aad4f614SJoe Perches $allowed[$allow] = 1; 586613214adfSAndy Whitcroft } 5867aad4f614SJoe Perches $allow++; 586813214adfSAndy Whitcroft } 5869aad4f614SJoe Perches if ($seen) { 5870aad4f614SJoe Perches my $sum_allowed = 0; 5871aad4f614SJoe Perches foreach (@allowed) { 5872aad4f614SJoe Perches $sum_allowed += $_; 5873aad4f614SJoe Perches } 5874aad4f614SJoe Perches if ($sum_allowed == 0) { 5875000d1cc1SJoe Perches WARN("BRACES", 5876000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5877aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5878aad4f614SJoe Perches $seen != $allow) { 5879aad4f614SJoe Perches CHK("BRACES", 5880aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5881aad4f614SJoe Perches } 588213214adfSAndy Whitcroft } 588313214adfSAndy Whitcroft } 588413214adfSAndy Whitcroft } 5885773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 588613214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5887cf655043SAndy Whitcroft my $allowed = 0; 5888f0a594c1SAndy Whitcroft 5889cf655043SAndy Whitcroft # Check the pre-context. 5890cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5891cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5892cf655043SAndy Whitcroft $allowed = 1; 5893f0a594c1SAndy Whitcroft } 5894773647a0SAndy Whitcroft 5895773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5896773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5897773647a0SAndy Whitcroft 5898cf655043SAndy Whitcroft # Check the condition. 5899cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5900773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5901cf655043SAndy Whitcroft if (defined $cond) { 5902773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5903cf655043SAndy Whitcroft } 5904cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5905cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5906cf655043SAndy Whitcroft $allowed = 1; 5907cf655043SAndy Whitcroft } 5908cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5909cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5910cf655043SAndy Whitcroft $allowed = 1; 5911cf655043SAndy Whitcroft } 5912cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5913cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5914cf655043SAndy Whitcroft $allowed = 1; 5915cf655043SAndy Whitcroft } 5916cf655043SAndy Whitcroft # Check the post-context. 5917cf655043SAndy Whitcroft if (defined $chunks[1]) { 5918cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5919cf655043SAndy Whitcroft if (defined $cond) { 5920773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5921cf655043SAndy Whitcroft } 5922cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5923cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5924cf655043SAndy Whitcroft $allowed = 1; 5925cf655043SAndy Whitcroft } 5926cf655043SAndy Whitcroft } 5927cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 5928f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5929e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5930cf655043SAndy Whitcroft 5931000d1cc1SJoe Perches WARN("BRACES", 5932000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5933f0a594c1SAndy Whitcroft } 5934f0a594c1SAndy Whitcroft } 5935f0a594c1SAndy Whitcroft 5936e4c5babdSJoe Perches# check for single line unbalanced braces 593795330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 593895330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5939e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5940e4c5babdSJoe Perches } 5941e4c5babdSJoe Perches 59420979ae66SJoe Perches# check for unnecessary blank lines around braces 594377b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5944f8e58219SJoe Perches if (CHK("BRACES", 5945f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5946f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5947f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5948f8e58219SJoe Perches } 59490979ae66SJoe Perches } 595077b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5951f8e58219SJoe Perches if (CHK("BRACES", 5952f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5953f8e58219SJoe Perches $fix) { 5954f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5955f8e58219SJoe Perches } 59560979ae66SJoe Perches } 59570979ae66SJoe Perches 59584a0df2efSAndy Whitcroft# no volatiles please 59596c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 59606c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5961000d1cc1SJoe Perches WARN("VOLATILE", 59628c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 59634a0df2efSAndy Whitcroft } 59644a0df2efSAndy Whitcroft 59655e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 59665e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 59675e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 59685e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 596933acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 59705e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 59715e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 59725e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 59735e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 59745e4f6ba5SJoe Perches $fix && 59755e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 59765e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 59775e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 59785e4f6ba5SJoe Perches my $comma_close = ""; 59795e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 59805e4f6ba5SJoe Perches $comma_close = $1; 59815e4f6ba5SJoe Perches } 59825e4f6ba5SJoe Perches 59835e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 59845e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 59855e4f6ba5SJoe Perches my $fixedline = $prevrawline; 59865e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 59875e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 59885e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 59895e4f6ba5SJoe Perches $fixedline = $rawline; 59905e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 59915e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 59925e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 59935e4f6ba5SJoe Perches } 59945e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 59955e4f6ba5SJoe Perches } 59965e4f6ba5SJoe Perches } 59975e4f6ba5SJoe Perches 59985e4f6ba5SJoe Perches# check for missing a space in a string concatenation 59995e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 60005e4f6ba5SJoe Perches WARN('MISSING_SPACE', 60015e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 60025e4f6ba5SJoe Perches } 60035e4f6ba5SJoe Perches 600477cb8546SJoe Perches# check for an embedded function name in a string when the function is known 6005e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 6006e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 6007e4b7d309SJoe Perches# function declarations 600877cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 600977cb8546SJoe Perches defined($context_function) && 6010e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 6011e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 601277cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 6013e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 601477cb8546SJoe Perches } 601577cb8546SJoe Perches 6016adb2da82SJoe Perches# check for unnecessary function tracing like uses 6017adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like 6018adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions 6019adb2da82SJoe Perches if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) { 6020adb2da82SJoe Perches if (WARN("TRACING_LOGGING", 6021adb2da82SJoe Perches "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) && 6022adb2da82SJoe Perches $fix) { 6023adb2da82SJoe Perches fix_delete_line($fixlinenr, $rawline); 6024adb2da82SJoe Perches } 6025adb2da82SJoe Perches } 6026adb2da82SJoe Perches 60275e4f6ba5SJoe Perches# check for spaces before a quoted newline 60285e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 60295e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 60305e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 60315e4f6ba5SJoe Perches $fix) { 60325e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 60335e4f6ba5SJoe Perches } 60345e4f6ba5SJoe Perches 60355e4f6ba5SJoe Perches } 60365e4f6ba5SJoe Perches 6037f17dba4fSJoe Perches# concatenated string without spaces between elements 603879682c0cSJoe Perches if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) { 603979682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 604079682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 604179682c0cSJoe Perches $fix) { 604279682c0cSJoe Perches while ($line =~ /($String)/g) { 604379682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 604479682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 604579682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 604679682c0cSJoe Perches } 604779682c0cSJoe Perches } 6048f17dba4fSJoe Perches } 6049f17dba4fSJoe Perches 605090ad30e5SJoe Perches# uncoalesced string fragments 605133acb54aSJoe Perches if ($line =~ /$String\s*"/) { 605279682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 605379682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 605479682c0cSJoe Perches $fix) { 605579682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 605679682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 605779682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 605879682c0cSJoe Perches } 605979682c0cSJoe Perches } 606090ad30e5SJoe Perches } 606190ad30e5SJoe Perches 6062522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 6063522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 6064522b837cSAlexey Dobriyan my $show_Z = 1; 60655e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 6066522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 60675e4f6ba5SJoe Perches $string =~ s/%%/__/g; 6068522b837cSAlexey Dobriyan # check for %L 6069522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 60705e4f6ba5SJoe Perches WARN("PRINTF_L", 6071522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 6072522b837cSAlexey Dobriyan $show_L = 0; 60735e4f6ba5SJoe Perches } 6074522b837cSAlexey Dobriyan # check for %Z 6075522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 6076522b837cSAlexey Dobriyan WARN("PRINTF_Z", 6077522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 6078522b837cSAlexey Dobriyan $show_Z = 0; 6079522b837cSAlexey Dobriyan } 6080522b837cSAlexey Dobriyan # check for 0x<decimal> 6081522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 6082522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 60836e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 60846e300757SJoe Perches } 60855e4f6ba5SJoe Perches } 60865e4f6ba5SJoe Perches 60875e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 60883f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 60895e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 60905e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 60915e4f6ba5SJoe Perches } 60925e4f6ba5SJoe Perches 609300df344fSAndy Whitcroft# warn about #if 0 6094c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 609560f89010SPrakruthi Deepak Heragu WARN("IF_0", 609660f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 609760f89010SPrakruthi Deepak Heragu } 609860f89010SPrakruthi Deepak Heragu 609960f89010SPrakruthi Deepak Heragu# warn about #if 1 610060f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 610160f89010SPrakruthi Deepak Heragu WARN("IF_1", 610260f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 61034a0df2efSAndy Whitcroft } 61044a0df2efSAndy Whitcroft 610503df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 610603df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 6107100425deSJoe Perches my $tested = quotemeta($1); 6108100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 6109100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 6110100425deSJoe Perches my $func = $1; 6111100425deSJoe Perches if (WARN('NEEDLESS_IF', 6112100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 6113100425deSJoe Perches $fix) { 6114100425deSJoe Perches my $do_fix = 1; 6115100425deSJoe Perches my $leading_tabs = ""; 6116100425deSJoe Perches my $new_leading_tabs = ""; 6117100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 6118100425deSJoe Perches $leading_tabs = $1; 6119100425deSJoe Perches } else { 6120100425deSJoe Perches $do_fix = 0; 6121100425deSJoe Perches } 6122100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 6123100425deSJoe Perches $new_leading_tabs = $1; 6124100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 6125100425deSJoe Perches $do_fix = 0; 6126100425deSJoe Perches } 6127100425deSJoe Perches } else { 6128100425deSJoe Perches $do_fix = 0; 6129100425deSJoe Perches } 6130100425deSJoe Perches if ($do_fix) { 6131100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6132100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 6133100425deSJoe Perches } 6134100425deSJoe Perches } 61354c432a8fSGreg Kroah-Hartman } 61364c432a8fSGreg Kroah-Hartman } 6137f0a594c1SAndy Whitcroft 6138ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 6139ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 6140ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 6141ebfdc409SJoe Perches (defined $1 || defined $3) && 6142ebfdc409SJoe Perches $linenr > 3) { 6143ebfdc409SJoe Perches my $testval = $2; 6144ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 6145ebfdc409SJoe Perches 6146ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 6147ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 6148ebfdc409SJoe Perches 6149e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 6150e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 6151ebfdc409SJoe Perches WARN("OOM_MESSAGE", 6152ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 6153ebfdc409SJoe Perches } 6154ebfdc409SJoe Perches } 6155ebfdc409SJoe Perches 6156f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 6157dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 6158f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 6159f78d98f6SJoe Perches my $level = $1; 6160f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 6161f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 6162f78d98f6SJoe Perches $fix) { 6163f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 6164f78d98f6SJoe Perches } 6165f78d98f6SJoe Perches } 6166f78d98f6SJoe Perches 616745c55e92SJoe Perches# check for logging continuations 616845c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 616945c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 617045c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 617145c55e92SJoe Perches } 617245c55e92SJoe Perches 617370eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions 617470eb2275SDwaipayan Ray if (defined $stat && 617570eb2275SDwaipayan Ray $line =~ /\b$logFunctions\s*\(/ && 617670eb2275SDwaipayan Ray index($stat, '"') >= 0) { 617770eb2275SDwaipayan Ray my $lc = $stat =~ tr@\n@@; 617870eb2275SDwaipayan Ray $lc = $lc + $linenr; 617970eb2275SDwaipayan Ray my $stat_real = get_stat_real($linenr, $lc); 618070eb2275SDwaipayan Ray pos($stat_real) = index($stat_real, '"'); 618170eb2275SDwaipayan Ray while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { 618270eb2275SDwaipayan Ray my $pspec = $1; 618370eb2275SDwaipayan Ray my $h = $2; 618470eb2275SDwaipayan Ray my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; 618570eb2275SDwaipayan Ray if (WARN("UNNECESSARY_MODIFIER", 618670eb2275SDwaipayan Ray "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && 618770eb2275SDwaipayan Ray $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { 618870eb2275SDwaipayan Ray my $nspec = $pspec; 618970eb2275SDwaipayan Ray $nspec =~ s/h//g; 619070eb2275SDwaipayan Ray $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; 619170eb2275SDwaipayan Ray } 619270eb2275SDwaipayan Ray } 619370eb2275SDwaipayan Ray } 619470eb2275SDwaipayan Ray 6195abb08a53SJoe Perches# check for mask then right shift without a parentheses 61965b57980dSJoe Perches if ($perl_version_ok && 6197abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 6198abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 6199abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 6200abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 6201abb08a53SJoe Perches } 6202abb08a53SJoe Perches 6203b75ac618SJoe Perches# check for pointer comparisons to NULL 62045b57980dSJoe Perches if ($perl_version_ok) { 6205b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 6206b75ac618SJoe Perches my $val = $1; 6207b75ac618SJoe Perches my $equal = "!"; 6208b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 6209b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 6210b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 6211b75ac618SJoe Perches $fix) { 6212b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 6213b75ac618SJoe Perches } 6214b75ac618SJoe Perches } 6215b75ac618SJoe Perches } 6216b75ac618SJoe Perches 62178716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 62188716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 62198716de38SJoe Perches my $attr = $1; 62208716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 62218716de38SJoe Perches my $ptr = $1; 62228716de38SJoe Perches my $var = $2; 62238716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 62248716de38SJoe Perches ERROR("MISPLACED_INIT", 62258716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 62268716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 62278716de38SJoe Perches WARN("MISPLACED_INIT", 62288716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 62298716de38SJoe Perches $fix) { 6230194f66fcSJoe Perches $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; 62318716de38SJoe Perches } 62328716de38SJoe Perches } 62338716de38SJoe Perches } 62348716de38SJoe Perches 6235e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 6236e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 6237e970b884SJoe Perches my $attr = $1; 6238e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 6239e970b884SJoe Perches my $attr_prefix = $1; 6240e970b884SJoe Perches my $attr_type = $2; 6241e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6242e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 6243e970b884SJoe Perches $fix) { 6244194f66fcSJoe Perches $fixed[$fixlinenr] =~ 6245e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 6246e970b884SJoe Perches } 6247e970b884SJoe Perches } 6248e970b884SJoe Perches 6249e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 6250e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 6251e970b884SJoe Perches my $attr = $1; 6252e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6253e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 6254e970b884SJoe Perches $fix) { 6255194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 6256e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 6257e970b884SJoe Perches $lead = rtrim($1); 6258e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 6259e970b884SJoe Perches $lead = "${lead}const "; 6260194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 6261e970b884SJoe Perches } 6262e970b884SJoe Perches } 6263e970b884SJoe Perches 6264c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 6265c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 6266c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 6267c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 6268c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 6269c17893c7SJoe Perches $fix) { 6270c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 6271c17893c7SJoe Perches } 6272c17893c7SJoe Perches } 6273c17893c7SJoe Perches 6274fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 6275fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 6276fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 6277fbdb8138SJoe Perches my $constant_func = $1; 6278fbdb8138SJoe Perches my $func = $constant_func; 6279fbdb8138SJoe Perches $func =~ s/^__constant_//; 6280fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 6281fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 6282fbdb8138SJoe Perches $fix) { 6283194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 6284fbdb8138SJoe Perches } 6285fbdb8138SJoe Perches } 6286fbdb8138SJoe Perches 62871a15a250SPatrick Pannuto# prefer usleep_range over udelay 628837581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 628943c1d77cSJoe Perches my $delay = $1; 62901a15a250SPatrick Pannuto # ignore udelay's < 10, however 629143c1d77cSJoe Perches if (! ($delay < 10) ) { 6292000d1cc1SJoe Perches CHK("USLEEP_RANGE", 6293458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 629443c1d77cSJoe Perches } 629543c1d77cSJoe Perches if ($delay > 2000) { 629643c1d77cSJoe Perches WARN("LONG_UDELAY", 629743c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 62981a15a250SPatrick Pannuto } 62991a15a250SPatrick Pannuto } 63001a15a250SPatrick Pannuto 630109ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 630209ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 630309ef8725SPatrick Pannuto if ($1 < 20) { 6304000d1cc1SJoe Perches WARN("MSLEEP", 6305458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 630609ef8725SPatrick Pannuto } 630709ef8725SPatrick Pannuto } 630809ef8725SPatrick Pannuto 630936ec1939SJoe Perches# check for comparisons of jiffies 631036ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 631136ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 631236ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 631336ec1939SJoe Perches } 631436ec1939SJoe Perches 63159d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 63169d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 63179d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 63189d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 63199d7a34a5SJoe Perches } 63209d7a34a5SJoe Perches 632100df344fSAndy Whitcroft# warn about #ifdefs in C files 6322c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 632300df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 632400df344fSAndy Whitcroft# print "$herecurr"; 632500df344fSAndy Whitcroft# $clean = 0; 632600df344fSAndy Whitcroft# } 632700df344fSAndy Whitcroft 632822f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 6329c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 63303705ce5bSJoe Perches if (ERROR("SPACING", 63313705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 63323705ce5bSJoe Perches $fix) { 6333194f66fcSJoe Perches $fixed[$fixlinenr] =~ 63343705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 63353705ce5bSJoe Perches } 63363705ce5bSJoe Perches 633722f2a2efSAndy Whitcroft } 633822f2a2efSAndy Whitcroft 63394a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 6340171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 6341171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 63424a0df2efSAndy Whitcroft my $which = $1; 63434a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6344000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 6345000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 63464a0df2efSAndy Whitcroft } 63474a0df2efSAndy Whitcroft } 63484a0df2efSAndy Whitcroft# check for memory barriers without a comment. 6349402c2553SMichael S. Tsirkin 6350402c2553SMichael S. Tsirkin my $barriers = qr{ 6351402c2553SMichael S. Tsirkin mb| 6352402c2553SMichael S. Tsirkin rmb| 6353ad83ec6cSWill Deacon wmb 6354402c2553SMichael S. Tsirkin }x; 6355402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 6356402c2553SMichael S. Tsirkin mb__before_atomic| 6357402c2553SMichael S. Tsirkin mb__after_atomic| 6358402c2553SMichael S. Tsirkin store_release| 6359402c2553SMichael S. Tsirkin load_acquire| 6360402c2553SMichael S. Tsirkin store_mb| 6361402c2553SMichael S. Tsirkin (?:$barriers) 6362402c2553SMichael S. Tsirkin }x; 6363402c2553SMichael S. Tsirkin my $all_barriers = qr{ 6364402c2553SMichael S. Tsirkin (?:$barriers)| 636543e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 636643e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 6367402c2553SMichael S. Tsirkin }x; 6368402c2553SMichael S. Tsirkin 6369402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 63704a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6371c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 6372000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 63734a0df2efSAndy Whitcroft } 63744a0df2efSAndy Whitcroft } 63753ad81779SPaul E. McKenney 6376f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 6377f4073b0fSMichael S. Tsirkin 6378f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 6379f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 6380f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 6381f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 6382f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 6383f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 6384f4073b0fSMichael S. Tsirkin } 6385f4073b0fSMichael S. Tsirkin 6386cb426e99SJoe Perches# check for waitqueue_active without a comment. 6387cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 6388cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 6389cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 6390cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 6391cb426e99SJoe Perches } 6392cb426e99SJoe Perches } 63933ad81779SPaul E. McKenney 63945099a722SMarco Elver# check for data_race without a comment. 63955099a722SMarco Elver if ($line =~ /\bdata_race\s*\(/) { 63965099a722SMarco Elver if (!ctx_has_comment($first_line, $linenr)) { 63975099a722SMarco Elver WARN("DATA_RACE", 63985099a722SMarco Elver "data_race without comment\n" . $herecurr); 63995099a722SMarco Elver } 64005099a722SMarco Elver } 64015099a722SMarco Elver 64024a0df2efSAndy Whitcroft# check of hardware specific defines 6403c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 6404000d1cc1SJoe Perches CHK("ARCH_DEFINES", 6405000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 64060a920b5bSAndy Whitcroft } 6407653d4876SAndy Whitcroft 6408596ed45bSJoe Perches# check that the storage class is not after a type 6409596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 6410000d1cc1SJoe Perches WARN("STORAGE_CLASS", 6411596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 6412596ed45bSJoe Perches } 6413596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 6414596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 6415596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 6416596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 6417596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 6418596ed45bSJoe Perches WARN("STORAGE_CLASS", 6419596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 6420d4977c78STobias Klauser } 6421d4977c78STobias Klauser 6422de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 6423de7d4f0eSAndy Whitcroft# storage class and type. 64249c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 64259c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 6426000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 6427000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 6428de7d4f0eSAndy Whitcroft } 6429de7d4f0eSAndy Whitcroft 64308905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 64312b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 64322b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 6433d5e616fcSJoe Perches if (WARN("INLINE", 6434d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 6435d5e616fcSJoe Perches $fix) { 6436194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 6437d5e616fcSJoe Perches 6438d5e616fcSJoe Perches } 64398905a67cSAndy Whitcroft } 64408905a67cSAndy Whitcroft 64417ebe1d17SDwaipayan Ray# Check for compiler attributes 64422b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 64437ebe1d17SDwaipayan Ray $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { 64447ebe1d17SDwaipayan Ray my $attr = $1; 64457ebe1d17SDwaipayan Ray $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; 64467ebe1d17SDwaipayan Ray 64477ebe1d17SDwaipayan Ray my %attr_list = ( 64480830aab0SJoe Perches "alias" => "__alias", 64497ebe1d17SDwaipayan Ray "aligned" => "__aligned", 64507ebe1d17SDwaipayan Ray "always_inline" => "__always_inline", 64517ebe1d17SDwaipayan Ray "assume_aligned" => "__assume_aligned", 64527ebe1d17SDwaipayan Ray "cold" => "__cold", 64537ebe1d17SDwaipayan Ray "const" => "__attribute_const__", 64547ebe1d17SDwaipayan Ray "copy" => "__copy", 64557ebe1d17SDwaipayan Ray "designated_init" => "__designated_init", 64567ebe1d17SDwaipayan Ray "externally_visible" => "__visible", 64577ebe1d17SDwaipayan Ray "format" => "printf|scanf", 64587ebe1d17SDwaipayan Ray "gnu_inline" => "__gnu_inline", 64597ebe1d17SDwaipayan Ray "malloc" => "__malloc", 64607ebe1d17SDwaipayan Ray "mode" => "__mode", 64617ebe1d17SDwaipayan Ray "no_caller_saved_registers" => "__no_caller_saved_registers", 64627ebe1d17SDwaipayan Ray "noclone" => "__noclone", 64637ebe1d17SDwaipayan Ray "noinline" => "noinline", 64647ebe1d17SDwaipayan Ray "nonstring" => "__nonstring", 64657ebe1d17SDwaipayan Ray "noreturn" => "__noreturn", 64667ebe1d17SDwaipayan Ray "packed" => "__packed", 64677ebe1d17SDwaipayan Ray "pure" => "__pure", 6468339f29d9SJoe Perches "section" => "__section", 64690830aab0SJoe Perches "used" => "__used", 64700830aab0SJoe Perches "weak" => "__weak" 64717ebe1d17SDwaipayan Ray ); 64727ebe1d17SDwaipayan Ray 64737ebe1d17SDwaipayan Ray while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { 6474339f29d9SJoe Perches my $orig_attr = $1; 64757ebe1d17SDwaipayan Ray my $params = ''; 64767ebe1d17SDwaipayan Ray $params = $2 if defined($2); 6477339f29d9SJoe Perches my $curr_attr = $orig_attr; 64787ebe1d17SDwaipayan Ray $curr_attr =~ s/^[\s_]+|[\s_]+$//g; 64797ebe1d17SDwaipayan Ray if (exists($attr_list{$curr_attr})) { 6480339f29d9SJoe Perches my $new = $attr_list{$curr_attr}; 64817ebe1d17SDwaipayan Ray if ($curr_attr eq "format" && $params) { 64827ebe1d17SDwaipayan Ray $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; 6483339f29d9SJoe Perches $new = "__$1\($2"; 64847ebe1d17SDwaipayan Ray } else { 6485339f29d9SJoe Perches $new = "$new$params"; 64867ebe1d17SDwaipayan Ray } 64877ebe1d17SDwaipayan Ray if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 6488339f29d9SJoe Perches "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && 64897ebe1d17SDwaipayan Ray $fix) { 6490339f29d9SJoe Perches my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; 6491339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/$remove//; 6492339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; 6493339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; 6494339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; 64957ebe1d17SDwaipayan Ray } 649639b7e287SJoe Perches } 6497462811d9SJoe Perches } 6498462811d9SJoe Perches 64997ebe1d17SDwaipayan Ray # Check for __attribute__ unused, prefer __always_unused or __maybe_unused 65007ebe1d17SDwaipayan Ray if ($attr =~ /^_*unused/) { 65017ebe1d17SDwaipayan Ray WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 65027ebe1d17SDwaipayan Ray "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); 6503d5e616fcSJoe Perches } 65046061d949SJoe Perches } 65056061d949SJoe Perches 6506619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 65075b57980dSJoe Perches if ($perl_version_ok && 6508619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 6509619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 6510619a908aSJoe Perches $line =~ /\b__weak\b/)) { 6511619a908aSJoe Perches ERROR("WEAK_DECLARATION", 6512619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 6513619a908aSJoe Perches } 6514619a908aSJoe Perches 6515fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 6516e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6517fd39f904STomas Winkler $realfile !~ m@\btools/@ && 6518e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 6519e6176fa4SJoe Perches my $type = $1; 6520e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 6521e6176fa4SJoe Perches $type = $1; 6522e6176fa4SJoe Perches my $kernel_type = 'u'; 6523e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6524e6176fa4SJoe Perches $type =~ /(\d+)/; 6525e6176fa4SJoe Perches $kernel_type .= $1; 6526e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6527e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6528e6176fa4SJoe Perches $fix) { 6529e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6530e6176fa4SJoe Perches } 6531e6176fa4SJoe Perches } 6532e6176fa4SJoe Perches } 6533e6176fa4SJoe Perches 6534938224b5SJoe Perches# check for cast of C90 native int or longer types constants 6535938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6536938224b5SJoe Perches my $cast = $1; 6537938224b5SJoe Perches my $const = $2; 6538938224b5SJoe Perches my $suffix = ""; 6539938224b5SJoe Perches my $newconst = $const; 6540938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 6541938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6542938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6543938224b5SJoe Perches $suffix .= 'LL'; 6544938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 6545938224b5SJoe Perches $suffix .= 'L'; 6546938224b5SJoe Perches } 65470972b8bfSJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 65480972b8bfSJoe Perches "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) && 65490972b8bfSJoe Perches $fix) { 6550938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6551938224b5SJoe Perches } 6552938224b5SJoe Perches } 6553938224b5SJoe Perches 65548f53a9b8SJoe Perches# check for sizeof(&) 65558f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6556000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 6557000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 65588f53a9b8SJoe Perches } 65598f53a9b8SJoe Perches 656066c80b60SJoe Perches# check for sizeof without parenthesis 656166c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 6562d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 6563d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6564d5e616fcSJoe Perches $fix) { 6565194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6566d5e616fcSJoe Perches } 656766c80b60SJoe Perches } 656866c80b60SJoe Perches 656988982feaSJoe Perches# check for struct spinlock declarations 657088982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 657188982feaSJoe Perches WARN("USE_SPINLOCK_T", 657288982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 657388982feaSJoe Perches } 657488982feaSJoe Perches 6575a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 657606668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6577a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 6578caac1d5fSHeba Aamer $fmt =~ s/%%//g; 6579caac1d5fSHeba Aamer if ($fmt !~ /%/) { 6580d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 6581d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6582d5e616fcSJoe Perches $fix) { 6583194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6584d5e616fcSJoe Perches } 6585a6962d72SJoe Perches } 6586a6962d72SJoe Perches } 6587a6962d72SJoe Perches 65880b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 65895b57980dSJoe Perches if ($perl_version_ok && 65900b523769SJoe Perches defined $stat && 65910b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 65920b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6593e3c6bc95STobin C. Harding my $stat_real; 6594e3c6bc95STobin C. Harding 65950b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 65960b523769SJoe Perches $lc = $lc + $linenr; 65970b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6598ffe07513SJoe Perches my $specifier; 6599ffe07513SJoe Perches my $extension; 66003bd32d6aSSakari Ailus my $qualifier; 6601ffe07513SJoe Perches my $bad_specifier = ""; 66020b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 66030b523769SJoe Perches $fmt =~ s/%%//g; 6604e3c6bc95STobin C. Harding 66053bd32d6aSSakari Ailus while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 6606e3c6bc95STobin C. Harding $specifier = $1; 6607e3c6bc95STobin C. Harding $extension = $2; 66083bd32d6aSSakari Ailus $qualifier = $3; 6609361b0d28SLinus Torvalds if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 66103bd32d6aSSakari Ailus ($extension eq "f" && 66113bd32d6aSSakari Ailus defined $qualifier && $qualifier !~ /^w/)) { 6612e3c6bc95STobin C. Harding $bad_specifier = $specifier; 66130b523769SJoe Perches last; 66140b523769SJoe Perches } 6615e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6616e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6617e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 66180b523769SJoe Perches } 6619e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6620e3c6bc95STobin C. Harding "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n"); 6621e3c6bc95STobin C. Harding } 6622e3c6bc95STobin C. Harding } 6623e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 66242a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 66251df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 66261df7338aSSergey Senozhatsky my $use = ""; 6627e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 66281df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6629e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 66301df7338aSSergey Senozhatsky } 66312a9f9d85STobin C. Harding 66320b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 6633e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6634e3c6bc95STobin C. Harding } 66350b523769SJoe Perches } 66360b523769SJoe Perches } 66370b523769SJoe Perches 6638554e165cSAndy Whitcroft# Check for misused memsets 66395b57980dSJoe Perches if ($perl_version_ok && 6640d1fe9c09SJoe Perches defined $stat && 66419e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6642554e165cSAndy Whitcroft 6643d7c76ba7SJoe Perches my $ms_addr = $2; 6644d1fe9c09SJoe Perches my $ms_val = $7; 6645d1fe9c09SJoe Perches my $ms_size = $12; 6646d7c76ba7SJoe Perches 6647554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6648554e165cSAndy Whitcroft ERROR("MEMSET", 6649d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6650554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6651554e165cSAndy Whitcroft WARN("MEMSET", 6652d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6653d7c76ba7SJoe Perches } 6654d7c76ba7SJoe Perches } 6655d7c76ba7SJoe Perches 665698a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 66575b57980dSJoe Perches# if ($perl_version_ok && 6658f333195dSJoe Perches# defined $stat && 6659f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6660f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6661f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6662f333195dSJoe Perches# $fix) { 6663f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6664f333195dSJoe Perches# } 6665f333195dSJoe Perches# } 666698a9bba5SJoe Perches 6667b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 66685b57980dSJoe Perches# if ($perl_version_ok && 6669f333195dSJoe Perches# defined $stat && 6670f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6671f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6672f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6673f333195dSJoe Perches# } 6674b6117d17SMateusz Kulikowski 66758617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 66768617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 66775b57980dSJoe Perches# if ($perl_version_ok && 6678f333195dSJoe Perches# defined $stat && 6679f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6680f333195dSJoe Perches# 6681f333195dSJoe Perches# my $ms_val = $7; 6682f333195dSJoe Perches# 6683f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6684f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6685f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6686f333195dSJoe Perches# $fix) { 6687f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6688f333195dSJoe Perches# } 6689f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6690f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6691f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6692f333195dSJoe Perches# $fix) { 6693f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6694f333195dSJoe Perches# } 6695f333195dSJoe Perches# } 6696f333195dSJoe Perches# } 66978617cd09SMateusz Kulikowski 66985dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy 66995dbdb2d8SJoe Perches if ($line =~ /\bstrlcpy\s*\(/) { 67005dbdb2d8SJoe Perches WARN("STRLCPY", 67015dbdb2d8SJoe Perches "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr); 67025dbdb2d8SJoe Perches } 67035dbdb2d8SJoe Perches 6704d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 67055b57980dSJoe Perches if ($perl_version_ok && 6706d1fe9c09SJoe Perches defined $stat && 6707d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6708d1fe9c09SJoe Perches if (defined $2 || defined $7) { 6709d7c76ba7SJoe Perches my $call = $1; 6710d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 6711d7c76ba7SJoe Perches my $arg1 = $3; 6712d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 6713d1fe9c09SJoe Perches my $arg2 = $8; 6714d7c76ba7SJoe Perches my $cast; 6715d7c76ba7SJoe Perches 6716d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 6717d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 6718d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 6719d7c76ba7SJoe Perches $cast = $cast1; 6720d7c76ba7SJoe Perches } else { 6721d7c76ba7SJoe Perches $cast = $cast2; 6722d7c76ba7SJoe Perches } 6723d7c76ba7SJoe Perches WARN("MINMAX", 6724d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 6725554e165cSAndy Whitcroft } 6726554e165cSAndy Whitcroft } 6727554e165cSAndy Whitcroft 67284a273195SJoe Perches# check usleep_range arguments 67295b57980dSJoe Perches if ($perl_version_ok && 67304a273195SJoe Perches defined $stat && 67314a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 67324a273195SJoe Perches my $min = $1; 67334a273195SJoe Perches my $max = $7; 67344a273195SJoe Perches if ($min eq $max) { 67354a273195SJoe Perches WARN("USLEEP_RANGE", 6736458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 67374a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 67384a273195SJoe Perches $min > $max) { 67394a273195SJoe Perches WARN("USLEEP_RANGE", 6740458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 67414a273195SJoe Perches } 67424a273195SJoe Perches } 67434a273195SJoe Perches 6744823b794cSJoe Perches# check for naked sscanf 67455b57980dSJoe Perches if ($perl_version_ok && 6746823b794cSJoe Perches defined $stat && 67476c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 6748823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6749823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 6750823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6751823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 6752823b794cSJoe Perches $lc = $lc + $linenr; 67532a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6754823b794cSJoe Perches WARN("NAKED_SSCANF", 6755823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6756823b794cSJoe Perches } 6757823b794cSJoe Perches 6758afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 67595b57980dSJoe Perches if ($perl_version_ok && 6760afc819abSJoe Perches defined $stat && 6761afc819abSJoe Perches $line =~ /\bsscanf\b/) { 6762afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 6763afc819abSJoe Perches $lc = $lc + $linenr; 67642a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6765afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6766afc819abSJoe Perches my $format = $6; 6767afc819abSJoe Perches my $count = $format =~ tr@%@%@; 6768afc819abSJoe Perches if ($count == 1 && 6769afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 6770afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 6771afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 6772afc819abSJoe Perches } 6773afc819abSJoe Perches } 6774afc819abSJoe Perches } 6775afc819abSJoe Perches 677670dc8a48SJoe Perches# check for new externs in .h files. 677770dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 677870dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 6779d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 678070dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 678170dc8a48SJoe Perches $fix) { 6782194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 678370dc8a48SJoe Perches } 678470dc8a48SJoe Perches } 678570dc8a48SJoe Perches 6786de7d4f0eSAndy Whitcroft# check for new externs in .c files. 6787171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 6788c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 6789171ae1a4SAndy Whitcroft { 6790c45dcabdSAndy Whitcroft my $function_name = $1; 6791c45dcabdSAndy Whitcroft my $paren_space = $2; 6792171ae1a4SAndy Whitcroft 6793171ae1a4SAndy Whitcroft my $s = $stat; 6794171ae1a4SAndy Whitcroft if (defined $cond) { 6795171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 6796171ae1a4SAndy Whitcroft } 6797d8b44b58SKees Cook if ($s =~ /^\s*;/) 6798c45dcabdSAndy Whitcroft { 6799000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6800000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6801de7d4f0eSAndy Whitcroft } 6802de7d4f0eSAndy Whitcroft 6803171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 6804000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 6805000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 6806171ae1a4SAndy Whitcroft } 68079c9ba34eSAndy Whitcroft 68089c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 68099c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 68109c9ba34eSAndy Whitcroft { 6811000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6812000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6813171ae1a4SAndy Whitcroft } 6814171ae1a4SAndy Whitcroft 6815a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 6816a0ad7596SJoe Perches if (defined $stat && 6817d8b44b58SKees Cook $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 6818d8b44b58SKees Cook $1 ne "void") { 6819d8b44b58SKees Cook my $args = trim($1); 6820ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 6821ca0d8929SJoe Perches my $arg = trim($1); 6822d8b44b58SKees Cook if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 6823ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 6824ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 6825ca0d8929SJoe Perches } 6826ca0d8929SJoe Perches } 6827ca0d8929SJoe Perches } 6828ca0d8929SJoe Perches 6829a0ad7596SJoe Perches# check for function definitions 68305b57980dSJoe Perches if ($perl_version_ok && 6831a0ad7596SJoe Perches defined $stat && 6832a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 6833a0ad7596SJoe Perches $context_function = $1; 6834a0ad7596SJoe Perches 6835a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 6836a0ad7596SJoe Perches my $ok = 0; 6837a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 6838a0ad7596SJoe Perches my $herectx = $here . "\n"; 6839a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6840a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 6841a0ad7596SJoe Perches $herectx .= $rl . "\n"; 6842a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 6843a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 6844a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 6845a0ad7596SJoe Perches } 6846a0ad7596SJoe Perches if (!$ok) { 6847a0ad7596SJoe Perches ERROR("OPEN_BRACE", 6848a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 6849a0ad7596SJoe Perches } 6850a0ad7596SJoe Perches } 6851a0ad7596SJoe Perches 6852de7d4f0eSAndy Whitcroft# checks for new __setup's 6853de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 6854de7d4f0eSAndy Whitcroft my $name = $1; 6855de7d4f0eSAndy Whitcroft 6856de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 6857000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 68582581ac7cSTim Froidcoeur "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); 6859de7d4f0eSAndy Whitcroft } 6860653d4876SAndy Whitcroft } 68619c0ca6f9SAndy Whitcroft 6862e29a70f1SJoe Perches# check for pointless casting of alloc functions 6863e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 6864000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 6865000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 68669c0ca6f9SAndy Whitcroft } 686713214adfSAndy Whitcroft 6868a640d25cSJoe Perches# alloc style 6869a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 68705b57980dSJoe Perches if ($perl_version_ok && 6871e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 6872a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 6873a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 6874a640d25cSJoe Perches } 6875a640d25cSJoe Perches 687660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 68775b57980dSJoe Perches if ($perl_version_ok && 68781b4a2ed4SJoe Perches defined $stat && 68791b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 688060a55369SJoe Perches my $oldfunc = $3; 688160a55369SJoe Perches my $a1 = $4; 688260a55369SJoe Perches my $a2 = $10; 688360a55369SJoe Perches my $newfunc = "kmalloc_array"; 688460a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 688560a55369SJoe Perches my $r1 = $a1; 688660a55369SJoe Perches my $r2 = $a2; 688760a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 688860a55369SJoe Perches $r1 = $a2; 688960a55369SJoe Perches $r2 = $a1; 689060a55369SJoe Perches } 6891e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 6892e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 68931b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 6894e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6895e3d95a2aSTobin C. Harding 6896e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 68971b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 68981b4a2ed4SJoe Perches $cnt == 1 && 6899e367455aSJoe Perches $fix) { 6900194f66fcSJoe Perches $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; 690160a55369SJoe Perches } 690260a55369SJoe Perches } 690360a55369SJoe Perches } 690460a55369SJoe Perches 6905972fdea2SJoe Perches# check for krealloc arg reuse 69065b57980dSJoe Perches if ($perl_version_ok && 69074cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 69084cab63ceSJoe Perches $1 eq $3) { 6909972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 6910972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 6911972fdea2SJoe Perches } 6912972fdea2SJoe Perches 69135ce59ae0SJoe Perches# check for alloc argument mismatch 69145ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 69155ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 69165ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 69175ce59ae0SJoe Perches } 69185ce59ae0SJoe Perches 6919caf2a54fSJoe Perches# check for multiple semicolons 6920caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 6921d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 6922d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 6923d5e616fcSJoe Perches $fix) { 6924194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 6925d5e616fcSJoe Perches } 6926d1e2ad07SJoe Perches } 6927d1e2ad07SJoe Perches 6928cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 6929cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 6930cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 69310ab90191SJoe Perches my $ull = ""; 69320ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 69330ab90191SJoe Perches if (CHK("BIT_MACRO", 69340ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 69350ab90191SJoe Perches $fix) { 69360ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 69370ab90191SJoe Perches } 69380ab90191SJoe Perches } 69390ab90191SJoe Perches 694050161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) 69413e89ad85SJerome Forissier if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { 694250161266SJoe Perches WARN("IS_ENABLED_CONFIG", 69433e89ad85SJerome Forissier "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); 694450161266SJoe Perches } 694550161266SJoe Perches 69462d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 69473e89ad85SJerome Forissier if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { 69482d632745SJoe Perches my $config = $1; 69492d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 69503e89ad85SJerome Forissier "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && 69512d632745SJoe Perches $fix) { 69522d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 69532d632745SJoe Perches } 69542d632745SJoe Perches } 69552d632745SJoe Perches 6956f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 6957f36d3eb8SJoe Perches my @fallthroughs = ( 6958f36d3eb8SJoe Perches 'fallthrough', 6959f36d3eb8SJoe Perches '@fallthrough@', 6960f36d3eb8SJoe Perches 'lint -fallthrough[ \t]*', 6961f36d3eb8SJoe Perches 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 6962f36d3eb8SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 6963f36d3eb8SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 6964f36d3eb8SJoe Perches 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 6965f36d3eb8SJoe Perches ); 6966f36d3eb8SJoe Perches if ($raw_comment ne '') { 6967f36d3eb8SJoe Perches foreach my $ft (@fallthroughs) { 6968f36d3eb8SJoe Perches if ($raw_comment =~ /$ft/) { 6969f36d3eb8SJoe Perches my $msg_level = \&WARN; 6970f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 6971f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 6972f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 6973f36d3eb8SJoe Perches last; 6974f36d3eb8SJoe Perches } 6975f36d3eb8SJoe Perches } 6976f36d3eb8SJoe Perches } 6977f36d3eb8SJoe Perches 6978d1e2ad07SJoe Perches# check for switch/default statements without a break; 69795b57980dSJoe Perches if ($perl_version_ok && 6980d1e2ad07SJoe Perches defined $stat && 6981d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6982d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6983e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6984e3d95a2aSTobin C. Harding 6985d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6986d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6987caf2a54fSJoe Perches } 6988caf2a54fSJoe Perches 698913214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6990d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6991d5e616fcSJoe Perches if (WARN("USE_FUNC", 6992d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6993d5e616fcSJoe Perches $fix) { 6994194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6995d5e616fcSJoe Perches } 699613214adfSAndy Whitcroft } 6997773647a0SAndy Whitcroft 699862ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 699962ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 700062ec818fSJoe Perches ERROR("DATE_TIME", 700162ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 700262ec818fSJoe Perches } 700362ec818fSJoe Perches 70042c92488aSJoe Perches# check for use of yield() 70052c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 70062c92488aSJoe Perches WARN("YIELD", 70072c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 70082c92488aSJoe Perches } 70092c92488aSJoe Perches 7010179f8f40SJoe Perches# check for comparisons against true and false 7011179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 7012179f8f40SJoe Perches my $lead = $1; 7013179f8f40SJoe Perches my $arg = $2; 7014179f8f40SJoe Perches my $test = $3; 7015179f8f40SJoe Perches my $otype = $4; 7016179f8f40SJoe Perches my $trail = $5; 7017179f8f40SJoe Perches my $op = "!"; 7018179f8f40SJoe Perches 7019179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 7020179f8f40SJoe Perches 7021179f8f40SJoe Perches my $type = lc($otype); 7022179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 7023179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 7024179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 7025179f8f40SJoe Perches $op = ""; 7026179f8f40SJoe Perches } 7027179f8f40SJoe Perches 7028179f8f40SJoe Perches CHK("BOOL_COMPARISON", 7029179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 7030179f8f40SJoe Perches 7031179f8f40SJoe Perches## maybe suggesting a correct construct would better 7032179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 7033179f8f40SJoe Perches 7034179f8f40SJoe Perches } 7035179f8f40SJoe Perches } 7036179f8f40SJoe Perches 70374882720bSThomas Gleixner# check for semaphores initialized locked 70384882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 7039000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 7040000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 7041773647a0SAndy Whitcroft } 70426712d858SJoe Perches 704367d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 704467d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 7045000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 704667d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 7047773647a0SAndy Whitcroft } 70486712d858SJoe Perches 7049ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 7050f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 7051000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 7052ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 7053f3db6639SMichael Ellerman } 70546712d858SJoe Perches 70553d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 70563d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 70573d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 70583d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 70593d709ab5SPaul E. McKenney } 70603d709ab5SPaul E. McKenney 70619189c7e7SJoe Perches# check for deprecated apis 70629189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 70639189c7e7SJoe Perches my $deprecated_api = $1; 70649189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 70659189c7e7SJoe Perches WARN("DEPRECATED_API", 70669189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 70679189c7e7SJoe Perches } 70689189c7e7SJoe Perches 70690f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 7070d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 7071ced69da1SQuentin Monnet if (defined($const_structs) && 7072ced69da1SQuentin Monnet $line !~ /\bconst\b/ && 7073d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 7074000d1cc1SJoe Perches WARN("CONST_STRUCT", 7075d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 70762b6db5cbSAndy Whitcroft } 7077773647a0SAndy Whitcroft 7078773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 7079773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 708035cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS 7081773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 7082c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 7083c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 7084171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 7085171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 708635cdcbfcSPeng Wang $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ && 708735cdcbfcSPeng Wang $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/) 7088773647a0SAndy Whitcroft { 7089000d1cc1SJoe Perches WARN("NR_CPUS", 7090000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 7091773647a0SAndy Whitcroft } 70929c9ba34eSAndy Whitcroft 709352ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 709452ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 709552ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 709652ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 709752ea8506SJoe Perches } 709852ea8506SJoe Perches 7099acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 71005b57980dSJoe Perches if ($perl_version_ok && 7101acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 7102acd9362cSJoe Perches WARN("LIKELY_MISUSE", 7103acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 7104acd9362cSJoe Perches } 7105acd9362cSJoe Perches 7106de3f186fSDenis Efremov# nested likely/unlikely calls 7107de3f186fSDenis Efremov if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 7108de3f186fSDenis Efremov WARN("LIKELY_MISUSE", 7109de3f186fSDenis Efremov "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 7110de3f186fSDenis Efremov } 7111de3f186fSDenis Efremov 7112691d77b6SAndy Whitcroft# whine mightly about in_atomic 7113691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 7114691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 7115000d1cc1SJoe Perches ERROR("IN_ATOMIC", 7116000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 7117f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 7118000d1cc1SJoe Perches WARN("IN_ATOMIC", 7119000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 7120691d77b6SAndy Whitcroft } 7121691d77b6SAndy Whitcroft } 71221704f47bSPeter Zijlstra 71231704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 71241704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 71251704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 71261704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 71271704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 71281704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 7129000d1cc1SJoe Perches ERROR("LOCKDEP", 7130000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 71311704f47bSPeter Zijlstra } 71321704f47bSPeter Zijlstra } 713388f8831cSDave Jones 7134b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 7135b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 7136000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 7137000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 713888f8831cSDave Jones } 71392435880fSJoe Perches 714000180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 714100180468SJoe Perches# and whether or not function naming is typical and if 714200180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 71435b57980dSJoe Perches if ($perl_version_ok && 714400180468SJoe Perches defined $stat && 714500180468SJoe Perches $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) { 714600180468SJoe Perches my $var = $1; 714700180468SJoe Perches my $perms = $2; 714800180468SJoe Perches my $show = $3; 714900180468SJoe Perches my $store = $4; 715000180468SJoe Perches my $octal_perms = perms_to_octal($perms); 715100180468SJoe Perches if ($show =~ /^${var}_show$/ && 715200180468SJoe Perches $store =~ /^${var}_store$/ && 715300180468SJoe Perches $octal_perms eq "0644") { 715400180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 715500180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 715600180468SJoe Perches $fix) { 715700180468SJoe Perches $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/; 715800180468SJoe Perches } 715900180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 716000180468SJoe Perches $store =~ /^NULL$/ && 716100180468SJoe Perches $octal_perms eq "0444") { 716200180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 716300180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 716400180468SJoe Perches $fix) { 716500180468SJoe Perches $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/; 716600180468SJoe Perches } 716700180468SJoe Perches } elsif ($show =~ /^NULL$/ && 716800180468SJoe Perches $store =~ /^${var}_store$/ && 716900180468SJoe Perches $octal_perms eq "0200") { 717000180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 717100180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 717200180468SJoe Perches $fix) { 717300180468SJoe Perches $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/; 717400180468SJoe Perches } 717500180468SJoe Perches } elsif ($octal_perms eq "0644" || 717600180468SJoe Perches $octal_perms eq "0444" || 717700180468SJoe Perches $octal_perms eq "0200") { 717800180468SJoe Perches my $newshow = "$show"; 717900180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 718000180468SJoe Perches my $newstore = $store; 718100180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 718200180468SJoe Perches my $rename = ""; 718300180468SJoe Perches if ($show ne $newshow) { 718400180468SJoe Perches $rename .= " '$show' to '$newshow'"; 718500180468SJoe Perches } 718600180468SJoe Perches if ($store ne $newstore) { 718700180468SJoe Perches $rename .= " '$store' to '$newstore'"; 718800180468SJoe Perches } 718900180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 719000180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 719100180468SJoe Perches } else { 719200180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 719300180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 719400180468SJoe Perches } 719500180468SJoe Perches } 719600180468SJoe Perches 7197515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 7198515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 719973121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 720073121534SJoe Perches# specific definition of not visible in sysfs. 720173121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 720273121534SJoe Perches# use the default permissions 72035b57980dSJoe Perches if ($perl_version_ok && 7204459cf0aeSJoe Perches defined $stat && 7205515a235eSJoe Perches $line =~ /$mode_perms_search/) { 72062435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 72072435880fSJoe Perches my $func = $entry->[0]; 72082435880fSJoe Perches my $arg_pos = $entry->[1]; 72092435880fSJoe Perches 7210459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 7211459cf0aeSJoe Perches $lc = $lc + $linenr; 72122a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 7213459cf0aeSJoe Perches 72142435880fSJoe Perches my $skip_args = ""; 72152435880fSJoe Perches if ($arg_pos > 1) { 72162435880fSJoe Perches $arg_pos--; 72172435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 72182435880fSJoe Perches } 7219f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 7220459cf0aeSJoe Perches if ($stat =~ /$test/) { 72212435880fSJoe Perches my $val = $1; 72222435880fSJoe Perches $val = $6 if ($skip_args ne ""); 722373121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 722473121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 722573121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 72262435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 7227459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 7228f90774e1SJoe Perches } 7229f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 7230c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 7231459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 72322435880fSJoe Perches } 7233459cf0aeSJoe Perches } 7234459cf0aeSJoe Perches } 7235459cf0aeSJoe Perches } 7236459cf0aeSJoe Perches 7237459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 7238bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 723900180468SJoe Perches my $oval = $1; 724000180468SJoe Perches my $octal = perms_to_octal($oval); 7241f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 7242459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 7243f90774e1SJoe Perches $fix) { 724400180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 72452435880fSJoe Perches } 724613214adfSAndy Whitcroft } 72475a6d20ceSBjorn Andersson 72485a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 72495a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 72505a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 72515a6d20ceSBjorn Andersson my $valid_licenses = qr{ 72525a6d20ceSBjorn Andersson GPL| 72535a6d20ceSBjorn Andersson GPL\ v2| 72545a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 72555a6d20ceSBjorn Andersson Dual\ BSD/GPL| 72565a6d20ceSBjorn Andersson Dual\ MIT/GPL| 72575a6d20ceSBjorn Andersson Dual\ MPL/GPL| 72585a6d20ceSBjorn Andersson Proprietary 72595a6d20ceSBjorn Andersson }x; 72605a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 72615a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 72625a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 72635a6d20ceSBjorn Andersson } 72645a6d20ceSBjorn Andersson } 72656a8d76cbSMatteo Croce 72666a8d76cbSMatteo Croce# check for sysctl duplicate constants 72676a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 72686a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 72696a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 72706a8d76cbSMatteo Croce } 7271515a235eSJoe Perches } 727213214adfSAndy Whitcroft 727313214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 727413214adfSAndy Whitcroft # so just keep quiet. 727513214adfSAndy Whitcroft if ($#rawlines == -1) { 727613214adfSAndy Whitcroft exit(0); 72770a920b5bSAndy Whitcroft } 72780a920b5bSAndy Whitcroft 72798905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 72808905a67cSAndy Whitcroft # things that appear to be patches. 72818905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 72828905a67cSAndy Whitcroft exit(0); 72838905a67cSAndy Whitcroft } 72848905a67cSAndy Whitcroft 7285e73d2715SDwaipayan Ray # This is not a patch, and we are in 'no-patch' mode so 72868905a67cSAndy Whitcroft # just keep quiet. 72878905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 72888905a67cSAndy Whitcroft exit(0); 72898905a67cSAndy Whitcroft } 72908905a67cSAndy Whitcroft 7291a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 7292000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 7293000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 72940a920b5bSAndy Whitcroft } 7295cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 7296cd261496SGeert Uytterhoeven if ($signoff == 0) { 7297000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 7298000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 729948ca2d8aSDwaipayan Ray } elsif ($authorsignoff != 1) { 730048ca2d8aSDwaipayan Ray # authorsignoff values: 730148ca2d8aSDwaipayan Ray # 0 -> missing sign off 730248ca2d8aSDwaipayan Ray # 1 -> sign off identical 730348ca2d8aSDwaipayan Ray # 2 -> names and addresses match, comments mismatch 730448ca2d8aSDwaipayan Ray # 3 -> addresses match, names different 730548ca2d8aSDwaipayan Ray # 4 -> names match, addresses different 730648ca2d8aSDwaipayan Ray # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match 730748ca2d8aSDwaipayan Ray 730848ca2d8aSDwaipayan Ray my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; 730948ca2d8aSDwaipayan Ray 731048ca2d8aSDwaipayan Ray if ($authorsignoff == 0) { 731148ca2d8aSDwaipayan Ray ERROR("NO_AUTHOR_SIGN_OFF", 7312cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 731348ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 2) { 731448ca2d8aSDwaipayan Ray CHK("FROM_SIGN_OFF_MISMATCH", 731548ca2d8aSDwaipayan Ray "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); 731648ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 3) { 731748ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 731848ca2d8aSDwaipayan Ray "From:/Signed-off-by: email name mismatch: $sob_msg\n"); 731948ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 4) { 732048ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 732148ca2d8aSDwaipayan Ray "From:/Signed-off-by: email address mismatch: $sob_msg\n"); 732248ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 5) { 732348ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 732448ca2d8aSDwaipayan Ray "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); 732548ca2d8aSDwaipayan Ray } 7326cd261496SGeert Uytterhoeven } 73270a920b5bSAndy Whitcroft } 73280a920b5bSAndy Whitcroft 7329f0a594c1SAndy Whitcroft print report_dump(); 733013214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 733113214adfSAndy Whitcroft print "$filename " if ($summary_file); 73326c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 73336c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 73346c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 73356c72ffaaSAndy Whitcroft } 73368905a67cSAndy Whitcroft 7337d2c0a235SAndy Whitcroft if ($quiet == 0) { 7338ef212196SJoe Perches # If there were any defects found and not already fixing them 7339ef212196SJoe Perches if (!$clean and !$fix) { 7340ef212196SJoe Perches print << "EOM" 7341ef212196SJoe Perches 7342ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 7343ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 7344ef212196SJoe PerchesEOM 7345ef212196SJoe Perches } 7346d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 7347d2c0a235SAndy Whitcroft # then suggest that. 7348d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 7349b0781216SMike Frysinger $rpt_cleaners = 0; 7350d8469f16SJoe Perches print << "EOM" 7351d8469f16SJoe Perches 7352d8469f16SJoe PerchesNOTE: Whitespace errors detected. 7353d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 7354d8469f16SJoe PerchesEOM 7355d2c0a235SAndy Whitcroft } 7356d2c0a235SAndy Whitcroft } 7357d2c0a235SAndy Whitcroft 7358d752fcc8SJoe Perches if ($clean == 0 && $fix && 7359d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 7360d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 73619624b8d6SJoe Perches my $newfile = $filename; 73629624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 73633705ce5bSJoe Perches my $linecount = 0; 73643705ce5bSJoe Perches my $f; 73653705ce5bSJoe Perches 7366d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 7367d752fcc8SJoe Perches 73683705ce5bSJoe Perches open($f, '>', $newfile) 73693705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 73703705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 73713705ce5bSJoe Perches $linecount++; 73723705ce5bSJoe Perches if ($file) { 73733705ce5bSJoe Perches if ($linecount > 3) { 73743705ce5bSJoe Perches $fixed_line =~ s/^\+//; 73753705ce5bSJoe Perches print $f $fixed_line . "\n"; 73763705ce5bSJoe Perches } 73773705ce5bSJoe Perches } else { 73783705ce5bSJoe Perches print $f $fixed_line . "\n"; 73793705ce5bSJoe Perches } 73803705ce5bSJoe Perches } 73813705ce5bSJoe Perches close($f); 73823705ce5bSJoe Perches 73833705ce5bSJoe Perches if (!$quiet) { 73843705ce5bSJoe Perches print << "EOM"; 7385d8469f16SJoe Perches 73863705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 73873705ce5bSJoe Perches 73883705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 73893705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 73903705ce5bSJoe Perches 73913705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 73923705ce5bSJoe PerchesNo warranties, expressed or implied... 73933705ce5bSJoe PerchesEOM 73943705ce5bSJoe Perches } 73953705ce5bSJoe Perches } 73963705ce5bSJoe Perches 7397d8469f16SJoe Perches if ($quiet == 0) { 7398d8469f16SJoe Perches print "\n"; 7399d8469f16SJoe Perches if ($clean == 1) { 7400d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 7401d8469f16SJoe Perches } else { 7402d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 74030a920b5bSAndy Whitcroft } 74040a920b5bSAndy Whitcroft } 74050a920b5bSAndy Whitcroft return $clean; 74060a920b5bSAndy Whitcroft} 7407