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; 2652178ce0SDwaipayan Raymy $verbose = 0; 2752178ce0SDwaipayan Raymy %verbose_messages = (); 2852178ce0SDwaipayan Raymy %verbose_emitted = (); 290a920b5bSAndy Whitcroftmy $tree = 1; 300a920b5bSAndy Whitcroftmy $chk_signoff = 1; 310a920b5bSAndy Whitcroftmy $chk_patch = 1; 32773647a0SAndy Whitcroftmy $tst_only; 336c72ffaaSAndy Whitcroftmy $emacs = 0; 348905a67cSAndy Whitcroftmy $terse = 0; 3534d8815fSJoe Perchesmy $showfile = 0; 366c72ffaaSAndy Whitcroftmy $file = 0; 374a593c34SDu, Changbinmy $git = 0; 380dea9f1eSJoe Perchesmy %git_commits = (); 396c72ffaaSAndy Whitcroftmy $check = 0; 402ac73b4fSJoe Perchesmy $check_orig = 0; 418905a67cSAndy Whitcroftmy $summary = 1; 428905a67cSAndy Whitcroftmy $mailback = 0; 4313214adfSAndy Whitcroftmy $summary_file = 0; 44000d1cc1SJoe Perchesmy $show_types = 0; 453beb42ecSJoe Perchesmy $list_types = 0; 463705ce5bSJoe Perchesmy $fix = 0; 479624b8d6SJoe Perchesmy $fix_inplace = 0; 486c72ffaaSAndy Whitcroftmy $root; 490f7f635bSJoe Perchesmy $gitroot = $ENV{'GIT_DIR'}; 500f7f635bSJoe Perches$gitroot = ".git" if !defined($gitroot); 51c2fdda0dSAndy Whitcroftmy %debug; 523445686aSJoe Perchesmy %camelcase = (); 5391bfe484SJoe Perchesmy %use_type = (); 5491bfe484SJoe Perchesmy @use = (); 5591bfe484SJoe Perchesmy %ignore_type = (); 56000d1cc1SJoe Perchesmy @ignore = (); 5777f5b10aSHannes Edermy $help = 0; 58000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 59bdc48fa1SJoe Perchesmy $max_line_length = 100; 60d62a201fSDave Hansenmy $ignore_perl_version = 0; 61d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 6256193274SVadim Bendeburymy $min_conf_desc_length = 4; 6366b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 64ebfd7d62SJoe Perchesmy $codespell = 0; 65f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt"; 660ee3e7b8SPeter Ujfalusimy $user_codespellfile = ""; 67bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 6852178ce0SDwaipayan Raymy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst"; 69ced69da1SQuentin Monnetmy $typedefsfile; 70737c0767SJohn Brooksmy $color = "auto"; 7198005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE 72dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE 73dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git'; 74713a09deSAntonio Borneomy $tabsize = 8; 753e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_"; 7677f5b10aSHannes Eder 7777f5b10aSHannes Edersub help { 7877f5b10aSHannes Eder my ($exitcode) = @_; 7977f5b10aSHannes Eder 8077f5b10aSHannes Eder print << "EOM"; 8177f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 8277f5b10aSHannes EderVersion: $V 8377f5b10aSHannes Eder 8477f5b10aSHannes EderOptions: 8577f5b10aSHannes Eder -q, --quiet quiet 8652178ce0SDwaipayan Ray -v, --verbose verbose mode 8777f5b10aSHannes Eder --no-tree run without a kernel tree 8877f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 8977f5b10aSHannes Eder --patch treat FILE as patchfile (default) 9077f5b10aSHannes Eder --emacs emacs compile window format 9177f5b10aSHannes Eder --terse one line per report 9234d8815fSJoe Perches --showfile emit diffed file position, not input file position 934a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 944a593c34SDu, Changbin single git commit with: 954a593c34SDu, Changbin <rev> 964a593c34SDu, Changbin <rev>^ 974a593c34SDu, Changbin <rev>~n 984a593c34SDu, Changbin multiple git commits with: 994a593c34SDu, Changbin <rev1>..<rev2> 1004a593c34SDu, Changbin <rev1>...<rev2> 1014a593c34SDu, Changbin <rev>-<count> 1024a593c34SDu, Changbin git merges are ignored 10377f5b10aSHannes Eder -f, --file treat FILE as regular source file 10477f5b10aSHannes Eder --subjective, --strict enable more subjective tests 1053beb42ecSJoe Perches --list-types list the possible message types 10691bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 107000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 1083beb42ecSJoe Perches --show-types show the specific message type in the output 109bdc48fa1SJoe Perches --max-line-length=n set the maximum line length, (default $max_line_length) 110bdc48fa1SJoe Perches if exceeded, warn on patches 111bdc48fa1SJoe Perches requires --strict for use with --file 11256193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 113bdc48fa1SJoe Perches --tab-size=n set the number of spaces for tab (default $tabsize) 11477f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 11577f5b10aSHannes Eder --no-summary suppress the per-file summary 11677f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 11777f5b10aSHannes Eder --summary-file include the filename in summary 11877f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 11977f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 12077f5b10aSHannes Eder is all off) 12177f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 12277f5b10aSHannes Eder literally 1233705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1243705ce5bSJoe Perches If correctable single-line errors exist, create 1253705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1263705ce5bSJoe Perches with potential errors corrected to the preferred 1273705ce5bSJoe Perches checkpatch style 1289624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1299624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1309624b8d6SJoe Perches file. It's your fault if there's no backup or git 131d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 132d62a201fSDave Hansen runtime errors. 133ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 1340ee3e7b8SPeter Ujfalusi (default:$codespellfile) 135ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 13675ad8c57SJerome Forissier --typedefsfile Read additional types from this file 137737c0767SJohn Brooks --color[=WHEN] Use colors 'always', 'never', or only when output 138737c0767SJohn Brooks is a terminal ('auto'). Default is 'auto'. 1393e89ad85SJerome Forissier --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default 1403e89ad85SJerome Forissier ${CONFIG_}) 14177f5b10aSHannes Eder -h, --help, --version display this help and exit 14277f5b10aSHannes Eder 14377f5b10aSHannes EderWhen FILE is - read standard input. 14477f5b10aSHannes EderEOM 14577f5b10aSHannes Eder 14677f5b10aSHannes Eder exit($exitcode); 14777f5b10aSHannes Eder} 14877f5b10aSHannes Eder 1493beb42ecSJoe Perchessub uniq { 1503beb42ecSJoe Perches my %seen; 1513beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1523beb42ecSJoe Perches} 1533beb42ecSJoe Perches 1543beb42ecSJoe Perchessub list_types { 1553beb42ecSJoe Perches my ($exitcode) = @_; 1563beb42ecSJoe Perches 1573beb42ecSJoe Perches my $count = 0; 1583beb42ecSJoe Perches 1593beb42ecSJoe Perches local $/ = undef; 1603beb42ecSJoe Perches 1613beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1623beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1633beb42ecSJoe Perches 1643beb42ecSJoe Perches my $text = <$script>; 1653beb42ecSJoe Perches close($script); 1663beb42ecSJoe Perches 16752178ce0SDwaipayan Ray my %types = (); 1680547fa58SJean Delvare # Also catch when type or level is passed through a variable 16952178ce0SDwaipayan Ray while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { 17052178ce0SDwaipayan Ray if (defined($1)) { 17152178ce0SDwaipayan Ray if (exists($types{$2})) { 17252178ce0SDwaipayan Ray $types{$2} .= ",$1" if ($types{$2} ne $1); 17352178ce0SDwaipayan Ray } else { 17452178ce0SDwaipayan Ray $types{$2} = $1; 1753beb42ecSJoe Perches } 17652178ce0SDwaipayan Ray } else { 17752178ce0SDwaipayan Ray $types{$2} = "UNDETERMINED"; 17852178ce0SDwaipayan Ray } 17952178ce0SDwaipayan Ray } 18052178ce0SDwaipayan Ray 1813beb42ecSJoe Perches print("#\tMessage type\n\n"); 18252178ce0SDwaipayan Ray if ($color) { 18352178ce0SDwaipayan Ray print(" ( Color coding: "); 18452178ce0SDwaipayan Ray print(RED . "ERROR" . RESET); 18552178ce0SDwaipayan Ray print(" | "); 18652178ce0SDwaipayan Ray print(YELLOW . "WARNING" . RESET); 18752178ce0SDwaipayan Ray print(" | "); 18852178ce0SDwaipayan Ray print(GREEN . "CHECK" . RESET); 18952178ce0SDwaipayan Ray print(" | "); 19052178ce0SDwaipayan Ray print("Multiple levels / Undetermined"); 19152178ce0SDwaipayan Ray print(" )\n\n"); 19252178ce0SDwaipayan Ray } 19352178ce0SDwaipayan Ray 19452178ce0SDwaipayan Ray foreach my $type (sort keys %types) { 19552178ce0SDwaipayan Ray my $orig_type = $type; 19652178ce0SDwaipayan Ray if ($color) { 19752178ce0SDwaipayan Ray my $level = $types{$type}; 19852178ce0SDwaipayan Ray if ($level eq "ERROR") { 19952178ce0SDwaipayan Ray $type = RED . $type . RESET; 20052178ce0SDwaipayan Ray } elsif ($level eq "WARN") { 20152178ce0SDwaipayan Ray $type = YELLOW . $type . RESET; 20252178ce0SDwaipayan Ray } elsif ($level eq "CHK") { 20352178ce0SDwaipayan Ray $type = GREEN . $type . RESET; 20452178ce0SDwaipayan Ray } 20552178ce0SDwaipayan Ray } 2063beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 20752178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$orig_type})) { 20852178ce0SDwaipayan Ray my $message = $verbose_messages{$orig_type}; 20952178ce0SDwaipayan Ray $message =~ s/\n/\n\t/g; 21052178ce0SDwaipayan Ray print("\t" . $message . "\n\n"); 21152178ce0SDwaipayan Ray } 2123beb42ecSJoe Perches } 2133beb42ecSJoe Perches 2143beb42ecSJoe Perches exit($exitcode); 2153beb42ecSJoe Perches} 2163beb42ecSJoe Perches 217000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 218000d1cc1SJoe Perchesif (-f $conf) { 219000d1cc1SJoe Perches my @conf_args; 220000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 221000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 222000d1cc1SJoe Perches 223000d1cc1SJoe Perches while (<$conffile>) { 224000d1cc1SJoe Perches my $line = $_; 225000d1cc1SJoe Perches 226000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 227000d1cc1SJoe Perches $line =~ s/^\s*//g; 228000d1cc1SJoe Perches $line =~ s/\s+/ /g; 229000d1cc1SJoe Perches 230000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 231000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 232000d1cc1SJoe Perches 233000d1cc1SJoe Perches my @words = split(" ", $line); 234000d1cc1SJoe Perches foreach my $word (@words) { 235000d1cc1SJoe Perches last if ($word =~ m/^#/); 236000d1cc1SJoe Perches push (@conf_args, $word); 237000d1cc1SJoe Perches } 238000d1cc1SJoe Perches } 239000d1cc1SJoe Perches close($conffile); 240000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 241000d1cc1SJoe Perches} 242000d1cc1SJoe Perches 24352178ce0SDwaipayan Raysub load_docs { 24452178ce0SDwaipayan Ray open(my $docs, '<', "$docsfile") 24552178ce0SDwaipayan Ray or warn "$P: Can't read the documentation file $docsfile $!\n"; 24652178ce0SDwaipayan Ray 24752178ce0SDwaipayan Ray my $type = ''; 24852178ce0SDwaipayan Ray my $desc = ''; 24952178ce0SDwaipayan Ray my $in_desc = 0; 25052178ce0SDwaipayan Ray 25152178ce0SDwaipayan Ray while (<$docs>) { 25252178ce0SDwaipayan Ray chomp; 25352178ce0SDwaipayan Ray my $line = $_; 25452178ce0SDwaipayan Ray $line =~ s/\s+$//; 25552178ce0SDwaipayan Ray 25652178ce0SDwaipayan Ray if ($line =~ /^\s*\*\*(.+)\*\*$/) { 25752178ce0SDwaipayan Ray if ($desc ne '') { 25852178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 25952178ce0SDwaipayan Ray } 26052178ce0SDwaipayan Ray $type = $1; 26152178ce0SDwaipayan Ray $desc = ''; 26252178ce0SDwaipayan Ray $in_desc = 1; 26352178ce0SDwaipayan Ray } elsif ($in_desc) { 26452178ce0SDwaipayan Ray if ($line =~ /^(?:\s{4,}|$)/) { 26552178ce0SDwaipayan Ray $line =~ s/^\s{4}//; 26652178ce0SDwaipayan Ray $desc .= $line; 26752178ce0SDwaipayan Ray $desc .= "\n"; 26852178ce0SDwaipayan Ray } else { 26952178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 27052178ce0SDwaipayan Ray $type = ''; 27152178ce0SDwaipayan Ray $desc = ''; 27252178ce0SDwaipayan Ray $in_desc = 0; 27352178ce0SDwaipayan Ray } 27452178ce0SDwaipayan Ray } 27552178ce0SDwaipayan Ray } 27652178ce0SDwaipayan Ray 27752178ce0SDwaipayan Ray if ($desc ne '') { 27852178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 27952178ce0SDwaipayan Ray } 28052178ce0SDwaipayan Ray close($docs); 28152178ce0SDwaipayan Ray} 28252178ce0SDwaipayan Ray 283737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space. 284737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments 285737c0767SJohn Brooksforeach (@ARGV) { 286737c0767SJohn Brooks if ($_ eq "--color" || $_ eq "-color") { 287737c0767SJohn Brooks $_ = "--color=$color"; 288737c0767SJohn Brooks } 289737c0767SJohn Brooks} 290737c0767SJohn Brooks 2910a920b5bSAndy WhitcroftGetOptions( 2926c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 29352178ce0SDwaipayan Ray 'v|verbose!' => \$verbose, 2940a920b5bSAndy Whitcroft 'tree!' => \$tree, 2950a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 2960a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 2976c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 2988905a67cSAndy Whitcroft 'terse!' => \$terse, 29934d8815fSJoe Perches 'showfile!' => \$showfile, 30077f5b10aSHannes Eder 'f|file!' => \$file, 3014a593c34SDu, Changbin 'g|git!' => \$git, 3026c72ffaaSAndy Whitcroft 'subjective!' => \$check, 3036c72ffaaSAndy Whitcroft 'strict!' => \$check, 304000d1cc1SJoe Perches 'ignore=s' => \@ignore, 30591bfe484SJoe Perches 'types=s' => \@use, 306000d1cc1SJoe Perches 'show-types!' => \$show_types, 3073beb42ecSJoe Perches 'list-types!' => \$list_types, 3086cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 30956193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 310713a09deSAntonio Borneo 'tab-size=i' => \$tabsize, 3116c72ffaaSAndy Whitcroft 'root=s' => \$root, 3128905a67cSAndy Whitcroft 'summary!' => \$summary, 3138905a67cSAndy Whitcroft 'mailback!' => \$mailback, 31413214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 3153705ce5bSJoe Perches 'fix!' => \$fix, 3169624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 317d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 318c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 319773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 320ebfd7d62SJoe Perches 'codespell!' => \$codespell, 3210ee3e7b8SPeter Ujfalusi 'codespellfile=s' => \$user_codespellfile, 32275ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 323737c0767SJohn Brooks 'color=s' => \$color, 324737c0767SJohn Brooks 'no-color' => \$color, #keep old behaviors of -nocolor 325737c0767SJohn Brooks 'nocolor' => \$color, #keep old behaviors of -nocolor 3263e89ad85SJerome Forissier 'kconfig-prefix=s' => \${CONFIG_}, 32777f5b10aSHannes Eder 'h|help' => \$help, 32877f5b10aSHannes Eder 'version' => \$help 3290ee3e7b8SPeter Ujfalusi) or $help = 2; 33077f5b10aSHannes Eder 3310ee3e7b8SPeter Ujfalusiif ($user_codespellfile) { 3320ee3e7b8SPeter Ujfalusi # Use the user provided codespell file unconditionally 3330ee3e7b8SPeter Ujfalusi $codespellfile = $user_codespellfile; 3340ee3e7b8SPeter Ujfalusi} elsif (!(-f $codespellfile)) { 3350ee3e7b8SPeter Ujfalusi # If /usr/share/codespell/dictionary.txt is not present, try to find it 3360ee3e7b8SPeter Ujfalusi # under codespell's install directory: <codespell_root>/data/dictionary.txt 337c882c6b1SSagar Patel if (($codespell || $help) && which("python3") ne "") { 3380ee3e7b8SPeter Ujfalusi my $python_codespell_dict = << "EOF"; 3390ee3e7b8SPeter Ujfalusi 3400ee3e7b8SPeter Ujfalusiimport os.path as op 3410ee3e7b8SPeter Ujfalusiimport codespell_lib 3420ee3e7b8SPeter Ujfalusicodespell_dir = op.dirname(codespell_lib.__file__) 3430ee3e7b8SPeter Ujfalusicodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt') 3440ee3e7b8SPeter Ujfalusiprint(codespell_file, end='') 3450ee3e7b8SPeter UjfalusiEOF 3460ee3e7b8SPeter Ujfalusi 347c882c6b1SSagar Patel my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`; 3480ee3e7b8SPeter Ujfalusi $codespellfile = $codespell_dict if (-f $codespell_dict); 3490ee3e7b8SPeter Ujfalusi } 3500ee3e7b8SPeter Ujfalusi} 3510ee3e7b8SPeter Ujfalusi 3520ee3e7b8SPeter Ujfalusi# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0 3530ee3e7b8SPeter Ujfalusi# $help is 2 if invalid option is passed - exitcode: 1 3540ee3e7b8SPeter Ujfalusihelp($help - 1) if ($help); 3550a920b5bSAndy Whitcroft 35652178ce0SDwaipayan Raydie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); 35752178ce0SDwaipayan Raydie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse); 35852178ce0SDwaipayan Ray 35952178ce0SDwaipayan Rayif ($color =~ /^[01]$/) { 36052178ce0SDwaipayan Ray $color = !$color; 36152178ce0SDwaipayan Ray} elsif ($color =~ /^always$/i) { 36252178ce0SDwaipayan Ray $color = 1; 36352178ce0SDwaipayan Ray} elsif ($color =~ /^never$/i) { 36452178ce0SDwaipayan Ray $color = 0; 36552178ce0SDwaipayan Ray} elsif ($color =~ /^auto$/i) { 36652178ce0SDwaipayan Ray $color = (-t STDOUT); 36752178ce0SDwaipayan Ray} else { 36852178ce0SDwaipayan Ray die "$P: Invalid color mode: $color\n"; 36952178ce0SDwaipayan Ray} 37052178ce0SDwaipayan Ray 37152178ce0SDwaipayan Rayload_docs() if ($verbose); 3723beb42ecSJoe Percheslist_types(0) if ($list_types); 3733beb42ecSJoe Perches 3749624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 3752ac73b4fSJoe Perches$check_orig = $check; 3769624b8d6SJoe Perches 3770a920b5bSAndy Whitcroftmy $exit = 0; 3780a920b5bSAndy Whitcroft 3795b57980dSJoe Perchesmy $perl_version_ok = 1; 380d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 3815b57980dSJoe Perches $perl_version_ok = 0; 382d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 3835b57980dSJoe Perches exit(1) if (!$ignore_perl_version); 384d62a201fSDave Hansen} 385d62a201fSDave Hansen 38645107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 3870a920b5bSAndy Whitcroftif ($#ARGV < 0) { 38845107ff6SAllen Hubbe push(@ARGV, '-'); 3890a920b5bSAndy Whitcroft} 3900a920b5bSAndy Whitcroft 391713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1 39232f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); 393713a09deSAntonio Borneo 39491bfe484SJoe Perchessub hash_save_array_words { 39591bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 39691bfe484SJoe Perches 39791bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 39891bfe484SJoe Perches foreach my $word (@array) { 399000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 400000d1cc1SJoe Perches $word =~ s/^\s*//g; 401000d1cc1SJoe Perches $word =~ s/\s+/ /g; 402000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 403000d1cc1SJoe Perches 404000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 405000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 406000d1cc1SJoe Perches 40791bfe484SJoe Perches $hashRef->{$word}++; 408000d1cc1SJoe Perches } 40991bfe484SJoe Perches} 41091bfe484SJoe Perches 41191bfe484SJoe Perchessub hash_show_words { 41291bfe484SJoe Perches my ($hashRef, $prefix) = @_; 41391bfe484SJoe Perches 4143c816e49SJoe Perches if (keys %$hashRef) { 415d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 41658cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 41791bfe484SJoe Perches print " $word"; 41891bfe484SJoe Perches } 419d8469f16SJoe Perches print "\n"; 42091bfe484SJoe Perches } 42191bfe484SJoe Perches} 42291bfe484SJoe Perches 42391bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 42491bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 425000d1cc1SJoe Perches 426c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 427c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 4287429c690SAndy Whitcroftmy $dbg_type = 0; 429a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 430c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 43121caa13cSAndy Whitcroft ## no critic 43221caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 43321caa13cSAndy Whitcroft die "$@" if ($@); 434c2fdda0dSAndy Whitcroft} 435c2fdda0dSAndy Whitcroft 436d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 437d2c0a235SAndy Whitcroft 4388905a67cSAndy Whitcroftif ($terse) { 4398905a67cSAndy Whitcroft $emacs = 1; 4408905a67cSAndy Whitcroft $quiet++; 4418905a67cSAndy Whitcroft} 4428905a67cSAndy Whitcroft 4436c72ffaaSAndy Whitcroftif ($tree) { 4446c72ffaaSAndy Whitcroft if (defined $root) { 4456c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 4466c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 4476c72ffaaSAndy Whitcroft } 4486c72ffaaSAndy Whitcroft } else { 4496c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 4506c72ffaaSAndy Whitcroft $root = '.'; 4516c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 4526c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 4536c72ffaaSAndy Whitcroft $root = $1; 4546c72ffaaSAndy Whitcroft } 4556c72ffaaSAndy Whitcroft } 4566c72ffaaSAndy Whitcroft 4576c72ffaaSAndy Whitcroft if (!defined $root) { 4580a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 4590a920b5bSAndy Whitcroft exit(2); 4600a920b5bSAndy Whitcroft } 4616c72ffaaSAndy Whitcroft} 4626c72ffaaSAndy Whitcroft 4636c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 4646c72ffaaSAndy Whitcroft 4652ceb532bSAndy Whitcroftour $Ident = qr{ 4662ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 4672ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 4682ceb532bSAndy Whitcroft }x; 4696c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 4706c72ffaaSAndy Whitcroftour $Sparse = qr{ 4716c72ffaaSAndy Whitcroft __user| 4726c72ffaaSAndy Whitcroft __kernel| 4736c72ffaaSAndy Whitcroft __force| 4746c72ffaaSAndy Whitcroft __iomem| 4756c72ffaaSAndy Whitcroft __must_check| 476417495edSAndy Whitcroft __kprobes| 477165e72a6SSven Eckelmann __ref| 47833aa4597SGeert Uytterhoeven __refconst| 47933aa4597SGeert Uytterhoeven __refdata| 480ad315455SBoqun Feng __rcu| 481ad315455SBoqun Feng __private 4826c72ffaaSAndy Whitcroft }x; 483e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 484e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 485e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 486e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 487e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 4888716de38SJoe Perches 48952131292SWolfram Sang# Notes to $Attribute: 49052131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 4916c72ffaaSAndy Whitcroftour $Attribute = qr{ 4926c72ffaaSAndy Whitcroft const| 493b5e8736aSJoe Perches volatile| 49403f1df7dSJoe Perches __percpu| 49503f1df7dSJoe Perches __nocast| 49603f1df7dSJoe Perches __safe| 49746d832f5SMichael S. Tsirkin __bitwise| 49803f1df7dSJoe Perches __packed__| 49903f1df7dSJoe Perches __packed2__| 50003f1df7dSJoe Perches __naked| 50103f1df7dSJoe Perches __maybe_unused| 50203f1df7dSJoe Perches __always_unused| 50303f1df7dSJoe Perches __noreturn| 50403f1df7dSJoe Perches __used| 50503f1df7dSJoe Perches __cold| 506e23ef1f3SJoe Perches __pure| 50703f1df7dSJoe Perches __noclone| 50803f1df7dSJoe Perches __deprecated| 5096c72ffaaSAndy Whitcroft __read_mostly| 510c5967e98SJoe Perches __ro_after_init| 5116c72ffaaSAndy Whitcroft __kprobes| 5128716de38SJoe Perches $InitAttribute| 51324e1d81aSAndy Whitcroft ____cacheline_aligned| 51424e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 5155fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 51686cffecdSKees Cook __weak| 51786cffecdSKees Cook __alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) 5186c72ffaaSAndy Whitcroft }x; 519c45dcabdSAndy Whitcroftour $Modifier; 52091cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 5216c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 5226c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 5236c72ffaaSAndy Whitcroft 52495e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 52595e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 52695e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 52795e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 5282435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 529d2af5aa6SJoe Perchesour $String = qr{(?:\b[Lu])?"[X\t]*"}; 530326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 531326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 532326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 53374349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 5342435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 535326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 536447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 53723f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 5386c72ffaaSAndy Whitcroftour $Operators = qr{ 5396c72ffaaSAndy Whitcroft <=|>=|==|!=| 5406c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 54123f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 5426c72ffaaSAndy Whitcroft }x; 5436c72ffaaSAndy Whitcroft 54491cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 54591cb5195SJoe Perches 546ab7e23f3SJoe Perchesour $BasicType; 5478905a67cSAndy Whitcroftour $NonptrType; 5481813087dSJoe Perchesour $NonptrTypeMisordered; 5498716de38SJoe Perchesour $NonptrTypeWithAttr; 5508905a67cSAndy Whitcroftour $Type; 5511813087dSJoe Perchesour $TypeMisordered; 5528905a67cSAndy Whitcroftour $Declare; 5531813087dSJoe Perchesour $DeclareMisordered; 5548905a67cSAndy Whitcroft 55515662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 55615662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 557171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 558171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 559171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 560171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 561171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 562171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 563171ae1a4SAndy Whitcroft}x; 564171ae1a4SAndy Whitcroft 56515662b3eSJoe Perchesour $UTF8 = qr{ 56615662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 56715662b3eSJoe Perches | $NON_ASCII_UTF8 56815662b3eSJoe Perches}x; 56915662b3eSJoe Perches 570e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 571021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 572021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 573021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 574021158b4SJoe Perches)}; 575e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 576fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 5778ed22cadSAndy Whitcroft atomic_t 5788ed22cadSAndy Whitcroft)}; 5798ea0114eSMickaël Salaünour $typeStdioTypedefs = qr{(?x: 5808ea0114eSMickaël Salaün FILE 5818ea0114eSMickaël Salaün)}; 582e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 583e6176fa4SJoe Perches $typeC99Typedefs\b| 584e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 5858ea0114eSMickaël Salaün $typeKernelTypedefs\b| 5868ea0114eSMickaël Salaün $typeStdioTypedefs\b 587e6176fa4SJoe Perches)}; 5888ed22cadSAndy Whitcroft 5896d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 5906d32f7a3SJoe Perches 591691e669bSJoe Perchesour $logFunctions = qr{(?x: 592758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 5937d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 59487bd499aSJoe Perches TP_printk| 5956e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 596b0531722SJoe Perches panic| 59706668727SJoe Perches MODULE_[A-Z_]+| 59806668727SJoe Perches seq_vprintf|seq_printf|seq_puts 599691e669bSJoe Perches)}; 600691e669bSJoe Perches 601e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 602e29a70f1SJoe Perches (?:(?:devm_)? 60358f02267SJoe Perches (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? | 604e29a70f1SJoe Perches kstrdup(?:_const)? | 605e29a70f1SJoe Perches kmemdup(?:_nul)?) | 606461e1565SChristophe JAILLET (?:\w+)?alloc_skb(?:_ip_align)? | 607e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 608e29a70f1SJoe Perches dma_alloc_coherent 609e29a70f1SJoe Perches)}; 610e29a70f1SJoe Perches 61120112475SJoe Perchesour $signature_tags = qr{(?xi: 61220112475SJoe Perches Signed-off-by:| 613d499480cSJorge Ramirez-Ortiz Co-developed-by:| 61420112475SJoe Perches Acked-by:| 61520112475SJoe Perches Tested-by:| 61620112475SJoe Perches Reviewed-by:| 61720112475SJoe Perches Reported-by:| 6188543ae12SMugunthan V N Suggested-by:| 61920112475SJoe Perches To:| 62020112475SJoe Perches Cc: 62120112475SJoe Perches)}; 62220112475SJoe Perches 623adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi: 624adb2da82SJoe Perches [=-]*> | 625adb2da82SJoe Perches <[=-]* | 626adb2da82SJoe Perches \[ | 627adb2da82SJoe Perches \] | 628adb2da82SJoe Perches start | 629adb2da82SJoe Perches called | 630adb2da82SJoe Perches entered | 631adb2da82SJoe Perches entry | 632adb2da82SJoe Perches enter | 633adb2da82SJoe Perches in | 634adb2da82SJoe Perches inside | 635adb2da82SJoe Perches here | 636adb2da82SJoe Perches begin | 637adb2da82SJoe Perches exit | 638adb2da82SJoe Perches end | 639adb2da82SJoe Perches done | 640adb2da82SJoe Perches leave | 641adb2da82SJoe Perches completed | 642adb2da82SJoe Perches out | 643adb2da82SJoe Perches return | 644adb2da82SJoe Perches [\.\!:\s]* 645adb2da82SJoe Perches)}; 646adb2da82SJoe Perches 647831242abSAditya Srivastavasub edit_distance_min { 648831242abSAditya Srivastava my (@arr) = @_; 649831242abSAditya Srivastava my $len = scalar @arr; 650831242abSAditya Srivastava if ((scalar @arr) < 1) { 651831242abSAditya Srivastava # if underflow, return 652831242abSAditya Srivastava return; 653831242abSAditya Srivastava } 654831242abSAditya Srivastava my $min = $arr[0]; 655831242abSAditya Srivastava for my $i (0 .. ($len-1)) { 656831242abSAditya Srivastava if ($arr[$i] < $min) { 657831242abSAditya Srivastava $min = $arr[$i]; 658831242abSAditya Srivastava } 659831242abSAditya Srivastava } 660831242abSAditya Srivastava return $min; 661831242abSAditya Srivastava} 662831242abSAditya Srivastava 663831242abSAditya Srivastavasub get_edit_distance { 664831242abSAditya Srivastava my ($str1, $str2) = @_; 665831242abSAditya Srivastava $str1 = lc($str1); 666831242abSAditya Srivastava $str2 = lc($str2); 667831242abSAditya Srivastava $str1 =~ s/-//g; 668831242abSAditya Srivastava $str2 =~ s/-//g; 669831242abSAditya Srivastava my $len1 = length($str1); 670831242abSAditya Srivastava my $len2 = length($str2); 671831242abSAditya Srivastava # two dimensional array storing minimum edit distance 672831242abSAditya Srivastava my @distance; 673831242abSAditya Srivastava for my $i (0 .. $len1) { 674831242abSAditya Srivastava for my $j (0 .. $len2) { 675831242abSAditya Srivastava if ($i == 0) { 676831242abSAditya Srivastava $distance[$i][$j] = $j; 677831242abSAditya Srivastava } elsif ($j == 0) { 678831242abSAditya Srivastava $distance[$i][$j] = $i; 679831242abSAditya Srivastava } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { 680831242abSAditya Srivastava $distance[$i][$j] = $distance[$i - 1][$j - 1]; 681831242abSAditya Srivastava } else { 682831242abSAditya Srivastava my $dist1 = $distance[$i][$j - 1]; #insert distance 683831242abSAditya Srivastava my $dist2 = $distance[$i - 1][$j]; # remove 684831242abSAditya Srivastava my $dist3 = $distance[$i - 1][$j - 1]; #replace 685831242abSAditya Srivastava $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); 686831242abSAditya Srivastava } 687831242abSAditya Srivastava } 688831242abSAditya Srivastava } 689831242abSAditya Srivastava return $distance[$len1][$len2]; 690831242abSAditya Srivastava} 691831242abSAditya Srivastava 692831242abSAditya Srivastavasub find_standard_signature { 693831242abSAditya Srivastava my ($sign_off) = @_; 694831242abSAditya Srivastava my @standard_signature_tags = ( 695831242abSAditya Srivastava 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', 696831242abSAditya Srivastava 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' 697831242abSAditya Srivastava ); 698831242abSAditya Srivastava foreach my $signature (@standard_signature_tags) { 699831242abSAditya Srivastava return $signature if (get_edit_distance($sign_off, $signature) <= 2); 700831242abSAditya Srivastava } 701831242abSAditya Srivastava 702831242abSAditya Srivastava return ""; 703831242abSAditya Srivastava} 704831242abSAditya Srivastava 7051813087dSJoe Perchesour @typeListMisordered = ( 7061813087dSJoe Perches qr{char\s+(?:un)?signed}, 7071813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 7081813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 7091813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 7101813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 7111813087dSJoe Perches qr{short\s+(?:un)?signed}, 7121813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 7131813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 7141813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 7151813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 7161813087dSJoe Perches qr{int\s+(?:un)?signed}, 7171813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 7181813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 7191813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 7201813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 7211813087dSJoe Perches qr{long\s+(?:un)?signed}, 7221813087dSJoe Perches); 7231813087dSJoe Perches 7248905a67cSAndy Whitcroftour @typeList = ( 7258905a67cSAndy Whitcroft qr{void}, 7260c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 7270c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 7280c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 7290c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 7300c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 7310c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 7320c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 7330c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 7340c773d9dSJoe Perches qr{(?:un)?signed}, 7358905a67cSAndy Whitcroft qr{float}, 7368905a67cSAndy Whitcroft qr{double}, 7378905a67cSAndy Whitcroft qr{bool}, 7388905a67cSAndy Whitcroft qr{struct\s+$Ident}, 7398905a67cSAndy Whitcroft qr{union\s+$Ident}, 7408905a67cSAndy Whitcroft qr{enum\s+$Ident}, 7418905a67cSAndy Whitcroft qr{${Ident}_t}, 7428905a67cSAndy Whitcroft qr{${Ident}_handler}, 7438905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 7441813087dSJoe Perches @typeListMisordered, 7458905a67cSAndy Whitcroft); 746938224b5SJoe Perches 747938224b5SJoe Perchesour $C90_int_types = qr{(?x: 748938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 749938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 750938224b5SJoe Perches long\s+long\s+(?:un)?signed| 751938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 752938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 753938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 754938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 755938224b5SJoe Perches 756938224b5SJoe Perches long\s+int\s+(?:un)?signed| 757938224b5SJoe Perches long\s+(?:un)?signed\s+int| 758938224b5SJoe Perches long\s+(?:un)?signed| 759938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 760938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 761938224b5SJoe Perches int\s+long\s+(?:un)?signed| 762938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 763938224b5SJoe Perches 764938224b5SJoe Perches int\s+(?:un)?signed| 765938224b5SJoe Perches (?:(?:un)?signed\s+)?int 766938224b5SJoe Perches)}; 767938224b5SJoe Perches 768485ff23eSAlex Dowadour @typeListFile = (); 7698716de38SJoe Perchesour @typeListWithAttr = ( 7708716de38SJoe Perches @typeList, 7718716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 7728716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 7738716de38SJoe Perches); 7748716de38SJoe Perches 775c45dcabdSAndy Whitcroftour @modifierList = ( 776c45dcabdSAndy Whitcroft qr{fastcall}, 777c45dcabdSAndy Whitcroft); 778485ff23eSAlex Dowadour @modifierListFile = (); 7798905a67cSAndy Whitcroft 7802435880fSJoe Perchesour @mode_permission_funcs = ( 7812435880fSJoe Perches ["module_param", 3], 7822435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 7832435880fSJoe Perches ["module_param_array_named", 5], 7842435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 7852435880fSJoe Perches ["proc_create(?:_data|)", 2], 786459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 787459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 788459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 789459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 790459cf0aeSJoe Perches ["__ATTR", 2], 7912435880fSJoe Perches); 7922435880fSJoe Perches 7931a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; 7941a3dcf2eSJoe Perches 795515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 796515a235eSJoe Perchesour $mode_perms_search = ""; 797515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 798515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 799515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 800515a235eSJoe Perches} 80100180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 802515a235eSJoe Perches 8039189c7e7SJoe Perchesour %deprecated_apis = ( 8049189c7e7SJoe Perches "synchronize_rcu_bh" => "synchronize_rcu", 8059189c7e7SJoe Perches "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 8069189c7e7SJoe Perches "call_rcu_bh" => "call_rcu", 8079189c7e7SJoe Perches "rcu_barrier_bh" => "rcu_barrier", 8089189c7e7SJoe Perches "synchronize_sched" => "synchronize_rcu", 8099189c7e7SJoe Perches "synchronize_sched_expedited" => "synchronize_rcu_expedited", 8109189c7e7SJoe Perches "call_rcu_sched" => "call_rcu", 8119189c7e7SJoe Perches "rcu_barrier_sched" => "rcu_barrier", 8129189c7e7SJoe Perches "get_state_synchronize_sched" => "get_state_synchronize_rcu", 8139189c7e7SJoe Perches "cond_synchronize_sched" => "cond_synchronize_rcu", 814defdaff1SIra Weiny "kmap" => "kmap_local_page", 815defdaff1SIra Weiny "kmap_atomic" => "kmap_local_page", 8169189c7e7SJoe Perches); 8179189c7e7SJoe Perches 8189189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 8199189c7e7SJoe Perchesour $deprecated_apis_search = ""; 8209189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 8219189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 8229189c7e7SJoe Perches $deprecated_apis_search .= $entry; 8239189c7e7SJoe Perches} 8249189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 8259189c7e7SJoe Perches 826b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 827b392c64fSJoe Perches S_IWUGO | 828b392c64fSJoe Perches S_IWOTH | 829b392c64fSJoe Perches S_IRWXUGO | 830b392c64fSJoe Perches S_IALLUGO | 831b392c64fSJoe Perches 0[0-7][0-7][2367] 832b392c64fSJoe Perches}x; 833b392c64fSJoe Perches 834f90774e1SJoe Perchesour %mode_permission_string_types = ( 835f90774e1SJoe Perches "S_IRWXU" => 0700, 836f90774e1SJoe Perches "S_IRUSR" => 0400, 837f90774e1SJoe Perches "S_IWUSR" => 0200, 838f90774e1SJoe Perches "S_IXUSR" => 0100, 839f90774e1SJoe Perches "S_IRWXG" => 0070, 840f90774e1SJoe Perches "S_IRGRP" => 0040, 841f90774e1SJoe Perches "S_IWGRP" => 0020, 842f90774e1SJoe Perches "S_IXGRP" => 0010, 843f90774e1SJoe Perches "S_IRWXO" => 0007, 844f90774e1SJoe Perches "S_IROTH" => 0004, 845f90774e1SJoe Perches "S_IWOTH" => 0002, 846f90774e1SJoe Perches "S_IXOTH" => 0001, 847f90774e1SJoe Perches "S_IRWXUGO" => 0777, 848f90774e1SJoe Perches "S_IRUGO" => 0444, 849f90774e1SJoe Perches "S_IWUGO" => 0222, 850f90774e1SJoe Perches "S_IXUGO" => 0111, 851f90774e1SJoe Perches); 852f90774e1SJoe Perches 853f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 854f90774e1SJoe Perchesour $mode_perms_string_search = ""; 855f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 856f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 857f90774e1SJoe Perches $mode_perms_string_search .= $entry; 858f90774e1SJoe Perches} 85900180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 86000180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 86100180468SJoe Perches ${single_mode_perms_string_search} 86200180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 86300180468SJoe Perches}x; 86400180468SJoe Perches 86500180468SJoe Perchessub perms_to_octal { 86600180468SJoe Perches my ($string) = @_; 86700180468SJoe Perches 86800180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 86900180468SJoe Perches 87000180468SJoe Perches my $val = ""; 87100180468SJoe Perches my $oval = ""; 87200180468SJoe Perches my $to = 0; 87300180468SJoe Perches my $curpos = 0; 87400180468SJoe Perches my $lastpos = 0; 87500180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 87600180468SJoe Perches $curpos = pos($string); 87700180468SJoe Perches my $match = $2; 87800180468SJoe Perches my $omatch = $1; 87900180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 88000180468SJoe Perches $lastpos = $curpos; 88100180468SJoe Perches $to |= $mode_permission_string_types{$match}; 88200180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 88300180468SJoe Perches $val .= $match; 88400180468SJoe Perches $oval .= $omatch; 88500180468SJoe Perches } 88600180468SJoe Perches $oval =~ s/^\s*\|\s*//; 88700180468SJoe Perches $oval =~ s/\s*\|\s*$//; 88800180468SJoe Perches return sprintf("%04o", $to); 88900180468SJoe Perches} 890f90774e1SJoe Perches 8917840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 8927840a94cSWolfram Sang irq| 893cdcee686SSergey Ryazanov memory| 894cdcee686SSergey Ryazanov time| 895cdcee686SSergey Ryazanov reboot 8967840a94cSWolfram Sang)}; 8977840a94cSWolfram Sang# memory.h: ARM has a custom one 8987840a94cSWolfram Sang 89966b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 90066b47b4aSKees Cookmy $misspellings; 90166b47b4aSKees Cookmy %spelling_fix; 90236061e38SJoe Perches 90336061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 90466b47b4aSKees Cook while (<$spelling>) { 90566b47b4aSKees Cook my $line = $_; 90666b47b4aSKees Cook 90766b47b4aSKees Cook $line =~ s/\s*\n?$//g; 90866b47b4aSKees Cook $line =~ s/^\s*//g; 90966b47b4aSKees Cook 91066b47b4aSKees Cook next if ($line =~ m/^\s*#/); 91166b47b4aSKees Cook next if ($line =~ m/^\s*$/); 91266b47b4aSKees Cook 91366b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 91466b47b4aSKees Cook 91566b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 91666b47b4aSKees Cook } 91766b47b4aSKees Cook close($spelling); 91836061e38SJoe Perches} else { 91936061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 92036061e38SJoe Perches} 92166b47b4aSKees Cook 922ebfd7d62SJoe Perchesif ($codespell) { 923ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 924ebfd7d62SJoe Perches while (<$spelling>) { 925ebfd7d62SJoe Perches my $line = $_; 926ebfd7d62SJoe Perches 927ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 928ebfd7d62SJoe Perches $line =~ s/^\s*//g; 929ebfd7d62SJoe Perches 930ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 931ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 932ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 933ebfd7d62SJoe Perches 934ebfd7d62SJoe Perches $line =~ s/,.*$//; 935ebfd7d62SJoe Perches 936ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 937ebfd7d62SJoe Perches 938ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 939ebfd7d62SJoe Perches } 940ebfd7d62SJoe Perches close($spelling); 941ebfd7d62SJoe Perches } else { 942ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 943ebfd7d62SJoe Perches } 944ebfd7d62SJoe Perches} 945ebfd7d62SJoe Perches 946ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 947ebfd7d62SJoe Perches 94875ad8c57SJerome Forissiersub read_words { 94975ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 95075ad8c57SJerome Forissier 95175ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 95275ad8c57SJerome Forissier while (<$words>) { 953bf1fa1daSJoe Perches my $line = $_; 954bf1fa1daSJoe Perches 955bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 956bf1fa1daSJoe Perches $line =~ s/^\s*//g; 957bf1fa1daSJoe Perches 958bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 959bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 960bf1fa1daSJoe Perches if ($line =~ /\s/) { 96175ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 962bf1fa1daSJoe Perches next; 963bf1fa1daSJoe Perches } 964bf1fa1daSJoe Perches 965ced69da1SQuentin Monnet $$wordsRef .= '|' if (defined $$wordsRef); 96675ad8c57SJerome Forissier $$wordsRef .= $line; 967bf1fa1daSJoe Perches } 96875ad8c57SJerome Forissier close($file); 96975ad8c57SJerome Forissier return 1; 970bf1fa1daSJoe Perches } 971bf1fa1daSJoe Perches 97275ad8c57SJerome Forissier return 0; 97375ad8c57SJerome Forissier} 97475ad8c57SJerome Forissier 975ced69da1SQuentin Monnetmy $const_structs; 976ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) { 97775ad8c57SJerome Forissier read_words(\$const_structs, $conststructsfile) 97875ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 979ced69da1SQuentin Monnet} 98075ad8c57SJerome Forissier 981ced69da1SQuentin Monnetif (defined($typedefsfile)) { 982ced69da1SQuentin Monnet my $typeOtherTypedefs; 98375ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 98475ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 985ced69da1SQuentin Monnet $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); 98675ad8c57SJerome Forissier} 98775ad8c57SJerome Forissier 9888905a67cSAndy Whitcroftsub build_types { 989485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 990485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 9911813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 9928716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 993c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 994ab7e23f3SJoe Perches $BasicType = qr{ 995ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 996ab7e23f3SJoe Perches (?:${all}\b) 997ab7e23f3SJoe Perches }x; 9988905a67cSAndy Whitcroft $NonptrType = qr{ 999d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 1000cf655043SAndy Whitcroft (?: 10016b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 10028ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 1003c45dcabdSAndy Whitcroft (?:${all}\b) 1004cf655043SAndy Whitcroft ) 1005c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 10068905a67cSAndy Whitcroft }x; 10071813087dSJoe Perches $NonptrTypeMisordered = qr{ 10081813087dSJoe Perches (?:$Modifier\s+|const\s+)* 10091813087dSJoe Perches (?: 10101813087dSJoe Perches (?:${Misordered}\b) 10111813087dSJoe Perches ) 10121813087dSJoe Perches (?:\s+$Modifier|\s+const)* 10131813087dSJoe Perches }x; 10148716de38SJoe Perches $NonptrTypeWithAttr = qr{ 10158716de38SJoe Perches (?:$Modifier\s+|const\s+)* 10168716de38SJoe Perches (?: 10178716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 10188716de38SJoe Perches (?:$typeTypedefs\b)| 10198716de38SJoe Perches (?:${allWithAttr}\b) 10208716de38SJoe Perches ) 10218716de38SJoe Perches (?:\s+$Modifier|\s+const)* 10228716de38SJoe Perches }x; 10238905a67cSAndy Whitcroft $Type = qr{ 1024c45dcabdSAndy Whitcroft $NonptrType 10257b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 1026c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 10278905a67cSAndy Whitcroft }x; 10281813087dSJoe Perches $TypeMisordered = qr{ 10291813087dSJoe Perches $NonptrTypeMisordered 10307b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 10311813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 10321813087dSJoe Perches }x; 103391cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 10341813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 10358905a67cSAndy Whitcroft} 10368905a67cSAndy Whitcroftbuild_types(); 10376c72ffaaSAndy Whitcroft 10387d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 1039d1fe9c09SJoe Perches 1040d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 1041d1fe9c09SJoe Perches# requires at least perl version v5.10.0 1042d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 1043d1fe9c09SJoe Perches 1044d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 10452435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 1046c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 10477d2367afSJoe Perches 1048f8422308SJoe Perchesour $declaration_macros = qr{(?x: 10493e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 1050fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 1051dcea7964SJoe Perches (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(| 1052dcea7964SJoe Perches (?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\( 1053f8422308SJoe Perches)}; 1054f8422308SJoe Perches 10558d0325ccSAditya Srivastavaour %allow_repeated_words = ( 10568d0325ccSAditya Srivastava add => '', 10578d0325ccSAditya Srivastava added => '', 10588d0325ccSAditya Srivastava bad => '', 10598d0325ccSAditya Srivastava be => '', 10608d0325ccSAditya Srivastava); 10618d0325ccSAditya Srivastava 10627d2367afSJoe Perchessub deparenthesize { 10637d2367afSJoe Perches my ($string) = @_; 10647d2367afSJoe Perches return "" if (!defined($string)); 10655b9553abSJoe Perches 10665b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 10675b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 10685b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 10695b9553abSJoe Perches } 10705b9553abSJoe Perches 10717d2367afSJoe Perches $string =~ s@\s+@ @g; 10725b9553abSJoe Perches 10737d2367afSJoe Perches return $string; 10747d2367afSJoe Perches} 10757d2367afSJoe Perches 10763445686aSJoe Perchessub seed_camelcase_file { 10773445686aSJoe Perches my ($file) = @_; 10783445686aSJoe Perches 10793445686aSJoe Perches return if (!(-f $file)); 10803445686aSJoe Perches 10813445686aSJoe Perches local $/; 10823445686aSJoe Perches 10833445686aSJoe Perches open(my $include_file, '<', "$file") 10843445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 10853445686aSJoe Perches my $text = <$include_file>; 10863445686aSJoe Perches close($include_file); 10873445686aSJoe Perches 10883445686aSJoe Perches my @lines = split('\n', $text); 10893445686aSJoe Perches 10903445686aSJoe Perches foreach my $line (@lines) { 10913445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 10923445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 10933445686aSJoe Perches $camelcase{$1} = 1; 109411ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 109511ea516aSJoe Perches $camelcase{$1} = 1; 109611ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 10973445686aSJoe Perches $camelcase{$1} = 1; 10983445686aSJoe Perches } 10993445686aSJoe Perches } 11003445686aSJoe Perches} 11013445686aSJoe Perches 1102cd28b119SJoe Perchesour %maintained_status = (); 1103cd28b119SJoe Perches 110485b0ee18SJoe Perchessub is_maintained_obsolete { 110585b0ee18SJoe Perches my ($filename) = @_; 110685b0ee18SJoe Perches 1107f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 110885b0ee18SJoe Perches 1109cd28b119SJoe Perches if (!exists($maintained_status{$filename})) { 1110cd28b119SJoe Perches $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 1111cd28b119SJoe Perches } 111285b0ee18SJoe Perches 1113cd28b119SJoe Perches return $maintained_status{$filename} =~ /obsolete/i; 111485b0ee18SJoe Perches} 111585b0ee18SJoe Perches 11163b6e8ac9SJoe Perchessub is_SPDX_License_valid { 11173b6e8ac9SJoe Perches my ($license) = @_; 11183b6e8ac9SJoe Perches 1119f9363b31SGuenter Roeck return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); 11203b6e8ac9SJoe Perches 112156294112SJoe Perches my $root_path = abs_path($root); 1122f9363b31SGuenter Roeck my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`; 11233b6e8ac9SJoe Perches return 0 if ($status ne ""); 11243b6e8ac9SJoe Perches return 1; 11253b6e8ac9SJoe Perches} 11263b6e8ac9SJoe Perches 11273445686aSJoe Perchesmy $camelcase_seeded = 0; 11283445686aSJoe Perchessub seed_camelcase_includes { 11293445686aSJoe Perches return if ($camelcase_seeded); 11303445686aSJoe Perches 11313445686aSJoe Perches my $files; 1132c707a81dSJoe Perches my $camelcase_cache = ""; 1133c707a81dSJoe Perches my @include_files = (); 1134c707a81dSJoe Perches 1135c707a81dSJoe Perches $camelcase_seeded = 1; 1136351b2a1fSJoe Perches 11370f7f635bSJoe Perches if (-e "$gitroot") { 1138dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 1139351b2a1fSJoe Perches chomp $git_last_include_commit; 1140c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 1141c707a81dSJoe Perches } else { 1142c707a81dSJoe Perches my $last_mod_date = 0; 1143c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 1144c707a81dSJoe Perches @include_files = split('\n', $files); 1145c707a81dSJoe Perches foreach my $file (@include_files) { 1146c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 1147c707a81dSJoe Perches localtime((stat $file)[9])); 1148c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 1149c707a81dSJoe Perches } 1150c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 1151c707a81dSJoe Perches } 1152c707a81dSJoe Perches 1153c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 1154c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 1155c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 1156351b2a1fSJoe Perches while (<$camelcase_file>) { 1157351b2a1fSJoe Perches chomp; 1158351b2a1fSJoe Perches $camelcase{$_} = 1; 1159351b2a1fSJoe Perches } 1160351b2a1fSJoe Perches close($camelcase_file); 1161351b2a1fSJoe Perches 1162351b2a1fSJoe Perches return; 1163351b2a1fSJoe Perches } 1164c707a81dSJoe Perches 11650f7f635bSJoe Perches if (-e "$gitroot") { 1166dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 1167c707a81dSJoe Perches @include_files = split('\n', $files); 11683445686aSJoe Perches } 1169c707a81dSJoe Perches 11703445686aSJoe Perches foreach my $file (@include_files) { 11713445686aSJoe Perches seed_camelcase_file($file); 11723445686aSJoe Perches } 1173351b2a1fSJoe Perches 1174c707a81dSJoe Perches if ($camelcase_cache ne "") { 1175351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 1176c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 1177c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 1178351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 1179351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 1180351b2a1fSJoe Perches } 1181351b2a1fSJoe Perches close($camelcase_file); 1182351b2a1fSJoe Perches } 11833445686aSJoe Perches} 11843445686aSJoe Perches 1185f5f61325SJoe Perchessub git_is_single_file { 1186f5f61325SJoe Perches my ($filename) = @_; 1187f5f61325SJoe Perches 1188f5f61325SJoe Perches return 0 if ((which("git") eq "") || !(-e "$gitroot")); 1189f5f61325SJoe Perches 1190f5f61325SJoe Perches my $output = `${git_command} ls-files -- $filename 2>/dev/null`; 1191f5f61325SJoe Perches my $count = $output =~ tr/\n//; 1192f5f61325SJoe Perches return $count eq 1 && $output =~ m{^${filename}$}; 1193f5f61325SJoe Perches} 1194f5f61325SJoe Perches 1195d311cd44SJoe Perchessub git_commit_info { 1196d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 1197d311cd44SJoe Perches 11980f7f635bSJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); 1199d311cd44SJoe Perches 1200dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 1201d311cd44SJoe Perches $output =~ s/^\s*//gm; 1202d311cd44SJoe Perches my @lines = split("\n", $output); 1203d311cd44SJoe Perches 12040d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 12050d7835fcSJoe Perches 12065a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 1207d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 1208d311cd44SJoe Perches# all matching commit ids, but it's very slow... 1209d311cd44SJoe Perches# 1210d311cd44SJoe Perches# echo "checking commits $1..." 1211d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 1212d311cd44SJoe Perches# while read line ; do 1213d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 1214d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 1215d311cd44SJoe Perches# done 12164ce9f970SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ || 12174ce9f970SJoe Perches $lines[0] =~ /^fatal: bad object $commit/) { 1218948b133aSHeinrich Schuchardt $id = undef; 1219d311cd44SJoe Perches } else { 1220d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 1221d311cd44SJoe Perches $desc = substr($lines[0], 41); 1222d311cd44SJoe Perches } 1223d311cd44SJoe Perches 1224d311cd44SJoe Perches return ($id, $desc); 1225d311cd44SJoe Perches} 1226d311cd44SJoe Perches 12276c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 12280a920b5bSAndy Whitcroft 122900df344fSAndy Whitcroftmy @rawlines = (); 1230c2fdda0dSAndy Whitcroftmy @lines = (); 12313705ce5bSJoe Perchesmy @fixed = (); 1232d752fcc8SJoe Perchesmy @fixed_inserted = (); 1233d752fcc8SJoe Perchesmy @fixed_deleted = (); 1234194f66fcSJoe Perchesmy $fixlinenr = -1; 1235194f66fcSJoe Perches 12364a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 12374a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 12380f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot"); 12394a593c34SDu, Changbin 12404a593c34SDu, Changbinif ($git) { 12414a593c34SDu, Changbin my @commits = (); 12420dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 12434a593c34SDu, Changbin my $git_range; 124428898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 124528898fd1SJoe Perches $git_range = "-$2 $1"; 12464a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 12474a593c34SDu, Changbin $git_range = "$commit_expr"; 12484a593c34SDu, Changbin } else { 12490dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 12500dea9f1eSJoe Perches } 1251dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 12520dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 125328898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 125428898fd1SJoe Perches next if (!defined($1) || !defined($2)); 12550dea9f1eSJoe Perches my $sha1 = $1; 12560dea9f1eSJoe Perches my $subject = $2; 12570dea9f1eSJoe Perches unshift(@commits, $sha1); 12580dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 12594a593c34SDu, Changbin } 12604a593c34SDu, Changbin } 12614a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 12624a593c34SDu, Changbin @ARGV = @commits; 12634a593c34SDu, Changbin} 12644a593c34SDu, Changbin 1265c2fdda0dSAndy Whitcroftmy $vname; 126698005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 12676c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 126821caa13cSAndy Whitcroft my $FILE; 1269f5f61325SJoe Perches my $is_git_file = git_is_single_file($filename); 1270f5f61325SJoe Perches my $oldfile = $file; 1271f5f61325SJoe Perches $file = 1 if ($is_git_file); 12724a593c34SDu, Changbin if ($git) { 12734a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 12744a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 12754a593c34SDu, Changbin } elsif ($file) { 127621caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 12776c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 127821caa13cSAndy Whitcroft } elsif ($filename eq '-') { 127921caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 12806c72ffaaSAndy Whitcroft } else { 128121caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 12826c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 12836c72ffaaSAndy Whitcroft } 1284c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1285c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 12864a593c34SDu, Changbin } elsif ($git) { 12870dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1288c2fdda0dSAndy Whitcroft } else { 1289c2fdda0dSAndy Whitcroft $vname = $filename; 1290c2fdda0dSAndy Whitcroft } 129121caa13cSAndy Whitcroft while (<$FILE>) { 12920a920b5bSAndy Whitcroft chomp; 129300df344fSAndy Whitcroft push(@rawlines, $_); 1294c7f574d0SGeert Uytterhoeven $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); 12956c72ffaaSAndy Whitcroft } 129621caa13cSAndy Whitcroft close($FILE); 1297d8469f16SJoe Perches 1298d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1299d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1300d8469f16SJoe Perches print "$vname\n"; 1301d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1302d8469f16SJoe Perches } 1303d8469f16SJoe Perches 1304c2fdda0dSAndy Whitcroft if (!process($filename)) { 13050a920b5bSAndy Whitcroft $exit = 1; 13060a920b5bSAndy Whitcroft } 130700df344fSAndy Whitcroft @rawlines = (); 130813214adfSAndy Whitcroft @lines = (); 13093705ce5bSJoe Perches @fixed = (); 1310d752fcc8SJoe Perches @fixed_inserted = (); 1311d752fcc8SJoe Perches @fixed_deleted = (); 1312194f66fcSJoe Perches $fixlinenr = -1; 1313485ff23eSAlex Dowad @modifierListFile = (); 1314485ff23eSAlex Dowad @typeListFile = (); 1315485ff23eSAlex Dowad build_types(); 1316f5f61325SJoe Perches $file = $oldfile if ($is_git_file); 13170a920b5bSAndy Whitcroft} 13180a920b5bSAndy Whitcroft 1319d8469f16SJoe Perchesif (!$quiet) { 13203c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 13213c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 13223c816e49SJoe Perches 13235b57980dSJoe Perches if (!$perl_version_ok) { 1324d8469f16SJoe Perches print << "EOM" 1325d8469f16SJoe Perches 1326d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 13275b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1328d8469f16SJoe PerchesEOM 1329d8469f16SJoe Perches } 1330d8469f16SJoe Perches if ($exit) { 1331d8469f16SJoe Perches print << "EOM" 1332d8469f16SJoe Perches 1333d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1334d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1335d8469f16SJoe PerchesEOM 1336d8469f16SJoe Perches } 1337d8469f16SJoe Perches} 1338d8469f16SJoe Perches 13390a920b5bSAndy Whitcroftexit($exit); 13400a920b5bSAndy Whitcroft 13410a920b5bSAndy Whitcroftsub top_of_kernel_tree { 13426c72ffaaSAndy Whitcroft my ($root) = @_; 13436c72ffaaSAndy Whitcroft 13446c72ffaaSAndy Whitcroft my @tree_check = ( 13456c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 13466c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 13476c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 13486c72ffaaSAndy Whitcroft ); 13496c72ffaaSAndy Whitcroft 13506c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 13516c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 13520a920b5bSAndy Whitcroft return 0; 13530a920b5bSAndy Whitcroft } 13546c72ffaaSAndy Whitcroft } 13556c72ffaaSAndy Whitcroft return 1; 13566c72ffaaSAndy Whitcroft} 13570a920b5bSAndy Whitcroft 135820112475SJoe Perchessub parse_email { 135920112475SJoe Perches my ($formatted_email) = @_; 136020112475SJoe Perches 136120112475SJoe Perches my $name = ""; 1362fccaebf0SDwaipayan Ray my $quoted = ""; 1363dfa05c28SJoe Perches my $name_comment = ""; 136420112475SJoe Perches my $address = ""; 136520112475SJoe Perches my $comment = ""; 136620112475SJoe Perches 136720112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 136820112475SJoe Perches $name = $1; 136920112475SJoe Perches $address = $2; 137020112475SJoe Perches $comment = $3 if defined $3; 137120112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 137220112475SJoe Perches $address = $1; 137320112475SJoe Perches $comment = $2 if defined $2; 137420112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 137520112475SJoe Perches $address = $1; 137620112475SJoe Perches $comment = $2 if defined $2; 137785e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 137820112475SJoe Perches $name = $formatted_email; 13793705ce5bSJoe Perches $name = trim($name); 138020112475SJoe Perches $name =~ s/^\"|\"$//g; 138120112475SJoe Perches # If there's a name left after stripping spaces and 138220112475SJoe Perches # leading quotes, and the address doesn't have both 138320112475SJoe Perches # leading and trailing angle brackets, the address 138420112475SJoe Perches # is invalid. ie: 138520112475SJoe Perches # "joe smith [email protected]" bad 138620112475SJoe Perches # "joe smith <[email protected]" bad 138720112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 138820112475SJoe Perches $name = ""; 138920112475SJoe Perches $address = ""; 139020112475SJoe Perches $comment = ""; 139120112475SJoe Perches } 139220112475SJoe Perches } 139320112475SJoe Perches 1394fccaebf0SDwaipayan Ray # Extract comments from names excluding quoted parts 1395fccaebf0SDwaipayan Ray # "John D. (Doe)" - Do not extract 1396fccaebf0SDwaipayan Ray if ($name =~ s/\"(.+)\"//) { 1397fccaebf0SDwaipayan Ray $quoted = $1; 1398dfa05c28SJoe Perches } 1399fccaebf0SDwaipayan Ray while ($name =~ s/\s*($balanced_parens)\s*/ /) { 1400fccaebf0SDwaipayan Ray $name_comment .= trim($1); 1401fccaebf0SDwaipayan Ray } 1402fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 1403fccaebf0SDwaipayan Ray $name = trim("$quoted $name"); 1404fccaebf0SDwaipayan Ray 14053705ce5bSJoe Perches $address = trim($address); 140620112475SJoe Perches $address =~ s/^\<|\>$//g; 1407fccaebf0SDwaipayan Ray $comment = trim($comment); 140820112475SJoe Perches 140920112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 141020112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 141120112475SJoe Perches $name = "\"$name\""; 141220112475SJoe Perches } 141320112475SJoe Perches 1414dfa05c28SJoe Perches return ($name, $name_comment, $address, $comment); 141520112475SJoe Perches} 141620112475SJoe Perches 141720112475SJoe Perchessub format_email { 141848ca2d8aSDwaipayan Ray my ($name, $name_comment, $address, $comment) = @_; 141920112475SJoe Perches 142020112475SJoe Perches my $formatted_email; 142120112475SJoe Perches 1422fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 14233705ce5bSJoe Perches $address = trim($address); 1424fccaebf0SDwaipayan Ray $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes 142520112475SJoe Perches 142620112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 142720112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 142820112475SJoe Perches $name = "\"$name\""; 142920112475SJoe Perches } 143020112475SJoe Perches 1431fccaebf0SDwaipayan Ray $name_comment = trim($name_comment); 1432fccaebf0SDwaipayan Ray $name_comment = " $name_comment" if ($name_comment ne ""); 1433fccaebf0SDwaipayan Ray $comment = trim($comment); 1434fccaebf0SDwaipayan Ray $comment = " $comment" if ($comment ne ""); 1435fccaebf0SDwaipayan Ray 143620112475SJoe Perches if ("$name" eq "") { 143720112475SJoe Perches $formatted_email = "$address"; 143820112475SJoe Perches } else { 143948ca2d8aSDwaipayan Ray $formatted_email = "$name$name_comment <$address>"; 144020112475SJoe Perches } 144148ca2d8aSDwaipayan Ray $formatted_email .= "$comment"; 144220112475SJoe Perches return $formatted_email; 144320112475SJoe Perches} 144420112475SJoe Perches 1445dfa05c28SJoe Perchessub reformat_email { 1446dfa05c28SJoe Perches my ($email) = @_; 1447dfa05c28SJoe Perches 1448dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 144948ca2d8aSDwaipayan Ray return format_email($email_name, $name_comment, $email_address, $comment); 1450dfa05c28SJoe Perches} 1451dfa05c28SJoe Perches 1452dfa05c28SJoe Perchessub same_email_addresses { 1453fccaebf0SDwaipayan Ray my ($email1, $email2) = @_; 1454dfa05c28SJoe Perches 1455dfa05c28SJoe Perches my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); 1456dfa05c28SJoe Perches my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); 1457dfa05c28SJoe Perches 145848ca2d8aSDwaipayan Ray return $email1_name eq $email2_name && 145948ca2d8aSDwaipayan Ray $email1_address eq $email2_address && 146048ca2d8aSDwaipayan Ray $name1_comment eq $name2_comment && 146148ca2d8aSDwaipayan Ray $comment1 eq $comment2; 146248ca2d8aSDwaipayan Ray} 1463dfa05c28SJoe Perches 1464d311cd44SJoe Perchessub which { 1465d311cd44SJoe Perches my ($bin) = @_; 1466d311cd44SJoe Perches 1467d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1468d311cd44SJoe Perches if (-e "$path/$bin") { 1469d311cd44SJoe Perches return "$path/$bin"; 1470d311cd44SJoe Perches } 1471d311cd44SJoe Perches } 1472d311cd44SJoe Perches 1473d311cd44SJoe Perches return ""; 1474d311cd44SJoe Perches} 1475d311cd44SJoe Perches 1476000d1cc1SJoe Perchessub which_conf { 1477000d1cc1SJoe Perches my ($conf) = @_; 1478000d1cc1SJoe Perches 1479000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1480000d1cc1SJoe Perches if (-e "$path/$conf") { 1481000d1cc1SJoe Perches return "$path/$conf"; 1482000d1cc1SJoe Perches } 1483000d1cc1SJoe Perches } 1484000d1cc1SJoe Perches 1485000d1cc1SJoe Perches return ""; 1486000d1cc1SJoe Perches} 1487000d1cc1SJoe Perches 14880a920b5bSAndy Whitcroftsub expand_tabs { 14890a920b5bSAndy Whitcroft my ($str) = @_; 14900a920b5bSAndy Whitcroft 14910a920b5bSAndy Whitcroft my $res = ''; 14920a920b5bSAndy Whitcroft my $n = 0; 14930a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 14940a920b5bSAndy Whitcroft if ($c eq "\t") { 14950a920b5bSAndy Whitcroft $res .= ' '; 14960a920b5bSAndy Whitcroft $n++; 1497713a09deSAntonio Borneo for (; ($n % $tabsize) != 0; $n++) { 14980a920b5bSAndy Whitcroft $res .= ' '; 14990a920b5bSAndy Whitcroft } 15000a920b5bSAndy Whitcroft next; 15010a920b5bSAndy Whitcroft } 15020a920b5bSAndy Whitcroft $res .= $c; 15030a920b5bSAndy Whitcroft $n++; 15040a920b5bSAndy Whitcroft } 15050a920b5bSAndy Whitcroft 15060a920b5bSAndy Whitcroft return $res; 15070a920b5bSAndy Whitcroft} 15086c72ffaaSAndy Whitcroftsub copy_spacing { 1509773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 15106c72ffaaSAndy Whitcroft return $res; 15116c72ffaaSAndy Whitcroft} 15120a920b5bSAndy Whitcroft 15134a0df2efSAndy Whitcroftsub line_stats { 15144a0df2efSAndy Whitcroft my ($line) = @_; 15154a0df2efSAndy Whitcroft 15164a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 15174a0df2efSAndy Whitcroft $line =~ s/^.//; 15184a0df2efSAndy Whitcroft $line = expand_tabs($line); 15194a0df2efSAndy Whitcroft 15204a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 15214a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 15224a0df2efSAndy Whitcroft 15234a0df2efSAndy Whitcroft return (length($line), length($white)); 15244a0df2efSAndy Whitcroft} 15254a0df2efSAndy Whitcroft 1526773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1527773647a0SAndy Whitcroft 1528773647a0SAndy Whitcroftsub sanitise_line_reset { 1529773647a0SAndy Whitcroft my ($in_comment) = @_; 1530773647a0SAndy Whitcroft 1531773647a0SAndy Whitcroft if ($in_comment) { 1532773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1533773647a0SAndy Whitcroft } else { 1534773647a0SAndy Whitcroft $sanitise_quote = ''; 1535773647a0SAndy Whitcroft } 1536773647a0SAndy Whitcroft} 153700df344fSAndy Whitcroftsub sanitise_line { 153800df344fSAndy Whitcroft my ($line) = @_; 153900df344fSAndy Whitcroft 154000df344fSAndy Whitcroft my $res = ''; 154100df344fSAndy Whitcroft my $l = ''; 154200df344fSAndy Whitcroft 1543c2fdda0dSAndy Whitcroft my $qlen = 0; 1544773647a0SAndy Whitcroft my $off = 0; 1545773647a0SAndy Whitcroft my $c; 154600df344fSAndy Whitcroft 1547773647a0SAndy Whitcroft # Always copy over the diff marker. 1548773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1549773647a0SAndy Whitcroft 1550773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1551773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1552773647a0SAndy Whitcroft 15538d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1554773647a0SAndy Whitcroft # and end, all to $;. 1555773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1556773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1557773647a0SAndy Whitcroft 1558773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1559773647a0SAndy Whitcroft $off++; 156000df344fSAndy Whitcroft next; 1561773647a0SAndy Whitcroft } 156281bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1563773647a0SAndy Whitcroft $sanitise_quote = ''; 1564773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1565773647a0SAndy Whitcroft $off++; 1566773647a0SAndy Whitcroft next; 1567773647a0SAndy Whitcroft } 1568113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1569113f04a8SDaniel Walker $sanitise_quote = '//'; 1570113f04a8SDaniel Walker 1571113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1572113f04a8SDaniel Walker $off++; 1573113f04a8SDaniel Walker next; 1574113f04a8SDaniel Walker } 1575773647a0SAndy Whitcroft 1576773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1577773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1578773647a0SAndy Whitcroft $c eq "\\") { 1579773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1580773647a0SAndy Whitcroft $off++; 1581773647a0SAndy Whitcroft next; 1582773647a0SAndy Whitcroft } 1583773647a0SAndy Whitcroft # Regular quotes. 1584773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1585773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1586773647a0SAndy Whitcroft $sanitise_quote = $c; 1587773647a0SAndy Whitcroft 1588773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1589773647a0SAndy Whitcroft next; 1590773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1591773647a0SAndy Whitcroft $sanitise_quote = ''; 159200df344fSAndy Whitcroft } 159300df344fSAndy Whitcroft } 1594773647a0SAndy Whitcroft 1595fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1596773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1597773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1598113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1599113f04a8SDaniel Walker substr($res, $off, 1, $;); 1600773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1601773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 160200df344fSAndy Whitcroft } else { 1603773647a0SAndy Whitcroft substr($res, $off, 1, $c); 160400df344fSAndy Whitcroft } 1605c2fdda0dSAndy Whitcroft } 1606c2fdda0dSAndy Whitcroft 1607113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1608113f04a8SDaniel Walker $sanitise_quote = ''; 1609113f04a8SDaniel Walker } 1610113f04a8SDaniel Walker 1611c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1612c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1613c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1614c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1615c2fdda0dSAndy Whitcroft 1616c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1617c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1618c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1619c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1620c2fdda0dSAndy Whitcroft } 1621c2fdda0dSAndy Whitcroft 1622dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1623dadf680dSJoe Perches my $match = $1; 1624dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1625dadf680dSJoe Perches } 1626dadf680dSJoe Perches 162700df344fSAndy Whitcroft return $res; 162800df344fSAndy Whitcroft} 162900df344fSAndy Whitcroft 1630a6962d72SJoe Perchessub get_quoted_string { 1631a6962d72SJoe Perches my ($line, $rawline) = @_; 1632a6962d72SJoe Perches 1633478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 163433acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1635a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1636a6962d72SJoe Perches} 1637a6962d72SJoe Perches 16388905a67cSAndy Whitcroftsub ctx_statement_block { 16398905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 16408905a67cSAndy Whitcroft my $line = $linenr - 1; 16418905a67cSAndy Whitcroft my $blk = ''; 16428905a67cSAndy Whitcroft my $soff = $off; 16438905a67cSAndy Whitcroft my $coff = $off - 1; 1644773647a0SAndy Whitcroft my $coff_set = 0; 16458905a67cSAndy Whitcroft 164613214adfSAndy Whitcroft my $loff = 0; 164713214adfSAndy Whitcroft 16488905a67cSAndy Whitcroft my $type = ''; 16498905a67cSAndy Whitcroft my $level = 0; 1650a2750645SAndy Whitcroft my @stack = (); 1651cf655043SAndy Whitcroft my $p; 16528905a67cSAndy Whitcroft my $c; 16538905a67cSAndy Whitcroft my $len = 0; 165413214adfSAndy Whitcroft 165513214adfSAndy Whitcroft my $remainder; 16568905a67cSAndy Whitcroft while (1) { 1657a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1658a2750645SAndy Whitcroft 1659773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 16608905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 16618905a67cSAndy Whitcroft # context. 16628905a67cSAndy Whitcroft if ($off >= $len) { 16638905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1664dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1665c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 16668905a67cSAndy Whitcroft $remain--; 166713214adfSAndy Whitcroft $loff = $len; 1668c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 16698905a67cSAndy Whitcroft $len = length($blk); 16708905a67cSAndy Whitcroft $line++; 16718905a67cSAndy Whitcroft last; 16728905a67cSAndy Whitcroft } 16738905a67cSAndy Whitcroft # Bail if there is no further context. 16748905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 167513214adfSAndy Whitcroft if ($off >= $len) { 16768905a67cSAndy Whitcroft last; 16778905a67cSAndy Whitcroft } 1678f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1679f74bd194SAndy Whitcroft $level++; 1680f74bd194SAndy Whitcroft $type = '#'; 1681f74bd194SAndy Whitcroft } 16828905a67cSAndy Whitcroft } 1683cf655043SAndy Whitcroft $p = $c; 16848905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 168513214adfSAndy Whitcroft $remainder = substr($blk, $off); 16868905a67cSAndy Whitcroft 1687773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 16884635f4fbSAndy Whitcroft 16894635f4fbSAndy Whitcroft # Handle nested #if/#else. 16904635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 16914635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 16924635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 16934635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 16944635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 16954635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 16964635f4fbSAndy Whitcroft } 16974635f4fbSAndy Whitcroft 16988905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 16998905a67cSAndy Whitcroft # outermost level. 17008905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 17018905a67cSAndy Whitcroft last; 17028905a67cSAndy Whitcroft } 17038905a67cSAndy Whitcroft 170413214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1705773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1706773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1707773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1708773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1709773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1710773647a0SAndy Whitcroft $coff_set = 1; 1711773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1712773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 171313214adfSAndy Whitcroft } 171413214adfSAndy Whitcroft 17158905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 17168905a67cSAndy Whitcroft $level++; 17178905a67cSAndy Whitcroft $type = '('; 17188905a67cSAndy Whitcroft } 17198905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 17208905a67cSAndy Whitcroft $level--; 17218905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 17228905a67cSAndy Whitcroft 17238905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 17248905a67cSAndy Whitcroft $coff = $off; 1725773647a0SAndy Whitcroft $coff_set = 1; 1726773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 17278905a67cSAndy Whitcroft } 17288905a67cSAndy Whitcroft } 17298905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 17308905a67cSAndy Whitcroft $level++; 17318905a67cSAndy Whitcroft $type = '{'; 17328905a67cSAndy Whitcroft } 17338905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 17348905a67cSAndy Whitcroft $level--; 17358905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 17368905a67cSAndy Whitcroft 17378905a67cSAndy Whitcroft if ($level == 0) { 1738b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1739b998e001SPatrick Pannuto $off++; 1740b998e001SPatrick Pannuto } 17418905a67cSAndy Whitcroft last; 17428905a67cSAndy Whitcroft } 17438905a67cSAndy Whitcroft } 1744f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1745f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1746f74bd194SAndy Whitcroft $level--; 1747f74bd194SAndy Whitcroft $type = ''; 1748f74bd194SAndy Whitcroft $off++; 1749f74bd194SAndy Whitcroft last; 1750f74bd194SAndy Whitcroft } 17518905a67cSAndy Whitcroft $off++; 17528905a67cSAndy Whitcroft } 1753a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 175413214adfSAndy Whitcroft if ($off == $len) { 1755a3bb97a7SAndy Whitcroft $loff = $len + 1; 175613214adfSAndy Whitcroft $line++; 175713214adfSAndy Whitcroft $remain--; 175813214adfSAndy Whitcroft } 17598905a67cSAndy Whitcroft 17608905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 17618905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 17628905a67cSAndy Whitcroft 17638905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 17648905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 17658905a67cSAndy Whitcroft 1766773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 176713214adfSAndy Whitcroft 176813214adfSAndy Whitcroft return ($statement, $condition, 176913214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 177013214adfSAndy Whitcroft} 177113214adfSAndy Whitcroft 1772cf655043SAndy Whitcroftsub statement_lines { 1773cf655043SAndy Whitcroft my ($stmt) = @_; 1774cf655043SAndy Whitcroft 1775cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1776cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1777cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1778cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1779cf655043SAndy Whitcroft 1780cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1781cf655043SAndy Whitcroft 1782cf655043SAndy Whitcroft return $#stmt_lines + 2; 1783cf655043SAndy Whitcroft} 1784cf655043SAndy Whitcroft 1785cf655043SAndy Whitcroftsub statement_rawlines { 1786cf655043SAndy Whitcroft my ($stmt) = @_; 1787cf655043SAndy Whitcroft 1788cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1789cf655043SAndy Whitcroft 1790cf655043SAndy Whitcroft return $#stmt_lines + 2; 1791cf655043SAndy Whitcroft} 1792cf655043SAndy Whitcroft 1793cf655043SAndy Whitcroftsub statement_block_size { 1794cf655043SAndy Whitcroft my ($stmt) = @_; 1795cf655043SAndy Whitcroft 1796cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1797cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1798cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1799cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1800cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1801cf655043SAndy Whitcroft 1802cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1803cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1804cf655043SAndy Whitcroft 1805cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1806cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1807cf655043SAndy Whitcroft 1808cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1809cf655043SAndy Whitcroft return $stmt_lines; 1810cf655043SAndy Whitcroft } else { 1811cf655043SAndy Whitcroft return $stmt_statements; 1812cf655043SAndy Whitcroft } 1813cf655043SAndy Whitcroft} 1814cf655043SAndy Whitcroft 181513214adfSAndy Whitcroftsub ctx_statement_full { 181613214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 181713214adfSAndy Whitcroft my ($statement, $condition, $level); 181813214adfSAndy Whitcroft 181913214adfSAndy Whitcroft my (@chunks); 182013214adfSAndy Whitcroft 1821cf655043SAndy Whitcroft # Grab the first conditional/block pair. 182213214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 182313214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1824773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 182513214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1826cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1827cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1828cf655043SAndy Whitcroft } 1829cf655043SAndy Whitcroft 1830cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1831cf655043SAndy Whitcroft # could continue the statement. 1832cf655043SAndy Whitcroft for (;;) { 183313214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 183413214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1835cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1836773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1837cf655043SAndy Whitcroft #print "C: push\n"; 1838cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 183913214adfSAndy Whitcroft } 184013214adfSAndy Whitcroft 184113214adfSAndy Whitcroft return ($level, $linenr, @chunks); 18428905a67cSAndy Whitcroft} 18438905a67cSAndy Whitcroft 18444a0df2efSAndy Whitcroftsub ctx_block_get { 1845f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 18464a0df2efSAndy Whitcroft my $line; 18474a0df2efSAndy Whitcroft my $start = $linenr - 1; 18484a0df2efSAndy Whitcroft my $blk = ''; 18494a0df2efSAndy Whitcroft my @o; 18504a0df2efSAndy Whitcroft my @c; 18514a0df2efSAndy Whitcroft my @res = (); 18524a0df2efSAndy Whitcroft 1853f0a594c1SAndy Whitcroft my $level = 0; 18544635f4fbSAndy Whitcroft my @stack = ($level); 185500df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 185600df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 185700df344fSAndy Whitcroft $remain--; 185800df344fSAndy Whitcroft 185900df344fSAndy Whitcroft $blk .= $rawlines[$line]; 18604635f4fbSAndy Whitcroft 18614635f4fbSAndy Whitcroft # Handle nested #if/#else. 186201464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 18634635f4fbSAndy Whitcroft push(@stack, $level); 186401464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 18654635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 186601464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 18674635f4fbSAndy Whitcroft $level = pop(@stack); 18684635f4fbSAndy Whitcroft } 18694635f4fbSAndy Whitcroft 187001464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1871f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1872f0a594c1SAndy Whitcroft if ($off > 0) { 1873f0a594c1SAndy Whitcroft $off--; 1874f0a594c1SAndy Whitcroft next; 1875f0a594c1SAndy Whitcroft } 18764a0df2efSAndy Whitcroft 1877f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1878f0a594c1SAndy Whitcroft $level--; 1879f0a594c1SAndy Whitcroft last if ($level == 0); 1880f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1881f0a594c1SAndy Whitcroft $level++; 1882f0a594c1SAndy Whitcroft } 1883f0a594c1SAndy Whitcroft } 18844a0df2efSAndy Whitcroft 1885f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 188600df344fSAndy Whitcroft push(@res, $rawlines[$line]); 18874a0df2efSAndy Whitcroft } 18884a0df2efSAndy Whitcroft 1889f0a594c1SAndy Whitcroft last if ($level == 0); 18904a0df2efSAndy Whitcroft } 18914a0df2efSAndy Whitcroft 1892f0a594c1SAndy Whitcroft return ($level, @res); 18934a0df2efSAndy Whitcroft} 18944a0df2efSAndy Whitcroftsub ctx_block_outer { 18954a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 18964a0df2efSAndy Whitcroft 1897f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1898f0a594c1SAndy Whitcroft return @r; 18994a0df2efSAndy Whitcroft} 19004a0df2efSAndy Whitcroftsub ctx_block { 19014a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 19024a0df2efSAndy Whitcroft 1903f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1904f0a594c1SAndy Whitcroft return @r; 1905653d4876SAndy Whitcroft} 1906653d4876SAndy Whitcroftsub ctx_statement { 1907f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1908f0a594c1SAndy Whitcroft 1909f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1910f0a594c1SAndy Whitcroft return @r; 1911f0a594c1SAndy Whitcroft} 1912f0a594c1SAndy Whitcroftsub ctx_block_level { 1913653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1914653d4876SAndy Whitcroft 1915f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 19164a0df2efSAndy Whitcroft} 19179c0ca6f9SAndy Whitcroftsub ctx_statement_level { 19189c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 19199c0ca6f9SAndy Whitcroft 19209c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 19219c0ca6f9SAndy Whitcroft} 19224a0df2efSAndy Whitcroft 19234a0df2efSAndy Whitcroftsub ctx_locate_comment { 19244a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 19254a0df2efSAndy Whitcroft 1926a55ee0ccSJoe Perches # If c99 comment on the current line, or the line before or after 1927a55ee0ccSJoe Perches my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); 1928a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1929a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); 1930a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1931a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); 1932a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1933a55ee0ccSJoe Perches 19344a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1935a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 19364a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 19374a0df2efSAndy Whitcroft 19384a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 19394a0df2efSAndy Whitcroft # comment. 19404a0df2efSAndy Whitcroft my $in_comment = 0; 19414a0df2efSAndy Whitcroft $current_comment = ''; 19424a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 194300df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 194400df344fSAndy Whitcroft #warn " $line\n"; 19454a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 19464a0df2efSAndy Whitcroft $in_comment = 1; 19474a0df2efSAndy Whitcroft } 19484a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 19494a0df2efSAndy Whitcroft $in_comment = 1; 19504a0df2efSAndy Whitcroft } 19514a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 19524a0df2efSAndy Whitcroft $current_comment = ''; 19534a0df2efSAndy Whitcroft } 19544a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 19554a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 19564a0df2efSAndy Whitcroft $in_comment = 0; 19574a0df2efSAndy Whitcroft } 19584a0df2efSAndy Whitcroft } 19594a0df2efSAndy Whitcroft 19604a0df2efSAndy Whitcroft chomp($current_comment); 19614a0df2efSAndy Whitcroft return($current_comment); 19624a0df2efSAndy Whitcroft} 19634a0df2efSAndy Whitcroftsub ctx_has_comment { 19644a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 19654a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 19664a0df2efSAndy Whitcroft 196700df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 19684a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 19694a0df2efSAndy Whitcroft 19704a0df2efSAndy Whitcroft return ($cmt ne ''); 19714a0df2efSAndy Whitcroft} 19724a0df2efSAndy Whitcroft 19734d001e4dSAndy Whitcroftsub raw_line { 19744d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 19754d001e4dSAndy Whitcroft 19764d001e4dSAndy Whitcroft my $offset = $linenr - 1; 19774d001e4dSAndy Whitcroft $cnt++; 19784d001e4dSAndy Whitcroft 19794d001e4dSAndy Whitcroft my $line; 19804d001e4dSAndy Whitcroft while ($cnt) { 19814d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 19824d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 19834d001e4dSAndy Whitcroft $cnt--; 19844d001e4dSAndy Whitcroft } 19854d001e4dSAndy Whitcroft 19864d001e4dSAndy Whitcroft return $line; 19874d001e4dSAndy Whitcroft} 19884d001e4dSAndy Whitcroft 19892a9f9d85STobin C. Hardingsub get_stat_real { 19902a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 19912a9f9d85STobin C. Harding 19922a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 19932a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 19942a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 19952a9f9d85STobin C. Harding } 19962a9f9d85STobin C. Harding 19972a9f9d85STobin C. Harding return $stat_real; 19982a9f9d85STobin C. Harding} 19992a9f9d85STobin C. Harding 2000e3d95a2aSTobin C. Hardingsub get_stat_here { 2001e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 2002e3d95a2aSTobin C. Harding 2003e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 2004e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 2005e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 2006e3d95a2aSTobin C. Harding } 2007e3d95a2aSTobin C. Harding 2008e3d95a2aSTobin C. Harding return $herectx; 2009e3d95a2aSTobin C. Harding} 2010e3d95a2aSTobin C. Harding 20110a920b5bSAndy Whitcroftsub cat_vet { 20120a920b5bSAndy Whitcroft my ($vet) = @_; 20139c0ca6f9SAndy Whitcroft my ($res, $coded); 20140a920b5bSAndy Whitcroft 20159c0ca6f9SAndy Whitcroft $res = ''; 20166c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 20176c72ffaaSAndy Whitcroft $res .= $1; 20186c72ffaaSAndy Whitcroft if ($2 ne '') { 20199c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 20206c72ffaaSAndy Whitcroft $res .= $coded; 20216c72ffaaSAndy Whitcroft } 20229c0ca6f9SAndy Whitcroft } 20239c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 20240a920b5bSAndy Whitcroft 20259c0ca6f9SAndy Whitcroft return $res; 20260a920b5bSAndy Whitcroft} 20270a920b5bSAndy Whitcroft 2028c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 2029cf655043SAndy Whitcroftmy $av_pending; 2030c2fdda0dSAndy Whitcroftmy @av_paren_type; 20311f65f947SAndy Whitcroftmy $av_pend_colon; 2032c2fdda0dSAndy Whitcroft 2033c2fdda0dSAndy Whitcroftsub annotate_reset { 2034c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 2035cf655043SAndy Whitcroft $av_pending = '_'; 2036cf655043SAndy Whitcroft @av_paren_type = ('E'); 20371f65f947SAndy Whitcroft $av_pend_colon = 'O'; 2038c2fdda0dSAndy Whitcroft} 2039c2fdda0dSAndy Whitcroft 20406c72ffaaSAndy Whitcroftsub annotate_values { 20416c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 20426c72ffaaSAndy Whitcroft 20436c72ffaaSAndy Whitcroft my $res; 20441f65f947SAndy Whitcroft my $var = '_' x length($stream); 20456c72ffaaSAndy Whitcroft my $cur = $stream; 20466c72ffaaSAndy Whitcroft 2047c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 20486c72ffaaSAndy Whitcroft 20496c72ffaaSAndy Whitcroft while (length($cur)) { 2050773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 2051cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 2052171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 20536c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 2054c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 2055c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 2056cf655043SAndy Whitcroft $type = pop(@av_paren_type); 2057c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 20586c72ffaaSAndy Whitcroft } 20596c72ffaaSAndy Whitcroft 2060c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 20619446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 20629446ef56SAndy Whitcroft push(@av_paren_type, $type); 2063addcdceaSAndy Whitcroft $type = 'c'; 20649446ef56SAndy Whitcroft 2065e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 2066c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 20676c72ffaaSAndy Whitcroft $type = 'T'; 20686c72ffaaSAndy Whitcroft 2069389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 2070389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 2071389a2fe5SAndy Whitcroft $type = 'T'; 2072389a2fe5SAndy Whitcroft 2073c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 2074171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 2075c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2076171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 2077171ae1a4SAndy Whitcroft if ($2 ne '') { 2078cf655043SAndy Whitcroft $av_pending = 'N'; 2079171ae1a4SAndy Whitcroft } 2080171ae1a4SAndy Whitcroft $type = 'E'; 2081171ae1a4SAndy Whitcroft 2082c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 2083171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 2084171ae1a4SAndy Whitcroft $av_preprocessor = 1; 2085171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 20866c72ffaaSAndy Whitcroft 2087c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 2088cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 2089c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2090cf655043SAndy Whitcroft 2091cf655043SAndy Whitcroft push(@av_paren_type, $type); 2092cf655043SAndy Whitcroft push(@av_paren_type, $type); 2093171ae1a4SAndy Whitcroft $type = 'E'; 2094cf655043SAndy Whitcroft 2095c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 2096cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 2097cf655043SAndy Whitcroft $av_preprocessor = 1; 2098cf655043SAndy Whitcroft 2099cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 2100cf655043SAndy Whitcroft 2101171ae1a4SAndy Whitcroft $type = 'E'; 2102cf655043SAndy Whitcroft 2103c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 2104cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 2105cf655043SAndy Whitcroft 2106cf655043SAndy Whitcroft $av_preprocessor = 1; 2107cf655043SAndy Whitcroft 2108cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 2109cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 2110cf655043SAndy Whitcroft pop(@av_paren_type); 2111cf655043SAndy Whitcroft push(@av_paren_type, $type); 2112171ae1a4SAndy Whitcroft $type = 'E'; 21136c72ffaaSAndy Whitcroft 21146c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 2115c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 21166c72ffaaSAndy Whitcroft 2117171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 2118171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 2119171ae1a4SAndy Whitcroft $av_pending = $type; 2120171ae1a4SAndy Whitcroft $type = 'N'; 2121171ae1a4SAndy Whitcroft 21226c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 2123c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 21246c72ffaaSAndy Whitcroft if (defined $2) { 2125cf655043SAndy Whitcroft $av_pending = 'V'; 21266c72ffaaSAndy Whitcroft } 21276c72ffaaSAndy Whitcroft $type = 'N'; 21286c72ffaaSAndy Whitcroft 212914b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 2130c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 213114b111c1SAndy Whitcroft $av_pending = 'E'; 21326c72ffaaSAndy Whitcroft $type = 'N'; 21336c72ffaaSAndy Whitcroft 21341f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 21351f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 21361f65f947SAndy Whitcroft $av_pend_colon = 'C'; 21371f65f947SAndy Whitcroft $type = 'N'; 21381f65f947SAndy Whitcroft 213914b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 2140c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 21416c72ffaaSAndy Whitcroft $type = 'N'; 21426c72ffaaSAndy Whitcroft 21436c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 2144c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 2145cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 2146cf655043SAndy Whitcroft $av_pending = '_'; 21476c72ffaaSAndy Whitcroft $type = 'N'; 21486c72ffaaSAndy Whitcroft 21496c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 2150cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 2151cf655043SAndy Whitcroft if ($new_type ne '_') { 2152cf655043SAndy Whitcroft $type = $new_type; 2153c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 2154c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 21556c72ffaaSAndy Whitcroft } else { 2156c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 21576c72ffaaSAndy Whitcroft } 21586c72ffaaSAndy Whitcroft 2159c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 2160c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 2161c8cb2ca3SAndy Whitcroft $type = 'V'; 2162cf655043SAndy Whitcroft $av_pending = 'V'; 21636c72ffaaSAndy Whitcroft 21648e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 21658e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 21661f65f947SAndy Whitcroft $av_pend_colon = 'B'; 21678e761b04SAndy Whitcroft } elsif ($type eq 'E') { 21688e761b04SAndy Whitcroft $av_pend_colon = 'L'; 21691f65f947SAndy Whitcroft } 21701f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 21711f65f947SAndy Whitcroft $type = 'V'; 21721f65f947SAndy Whitcroft 21736c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 2174c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 21756c72ffaaSAndy Whitcroft $type = 'V'; 21766c72ffaaSAndy Whitcroft 21776c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 2178c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 21796c72ffaaSAndy Whitcroft $type = 'N'; 21806c72ffaaSAndy Whitcroft 2181cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 2182c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 218313214adfSAndy Whitcroft $type = 'E'; 21841f65f947SAndy Whitcroft $av_pend_colon = 'O'; 218513214adfSAndy Whitcroft 21868e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 21878e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 21888e761b04SAndy Whitcroft $type = 'C'; 21898e761b04SAndy Whitcroft 21901f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 21911f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 21921f65f947SAndy Whitcroft $type = 'N'; 21931f65f947SAndy Whitcroft 21941f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 21951f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 21961f65f947SAndy Whitcroft 21971f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 21981f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 21991f65f947SAndy Whitcroft $type = 'E'; 22001f65f947SAndy Whitcroft } else { 22011f65f947SAndy Whitcroft $type = 'N'; 22021f65f947SAndy Whitcroft } 22031f65f947SAndy Whitcroft $av_pend_colon = 'O'; 22041f65f947SAndy Whitcroft 22058e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 220613214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 22076c72ffaaSAndy Whitcroft $type = 'N'; 22086c72ffaaSAndy Whitcroft 22090d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 221074048ed8SAndy Whitcroft my $variant; 221174048ed8SAndy Whitcroft 221274048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 221374048ed8SAndy Whitcroft if ($type eq 'V') { 221474048ed8SAndy Whitcroft $variant = 'B'; 221574048ed8SAndy Whitcroft } else { 221674048ed8SAndy Whitcroft $variant = 'U'; 221774048ed8SAndy Whitcroft } 221874048ed8SAndy Whitcroft 221974048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 222074048ed8SAndy Whitcroft $type = 'N'; 222174048ed8SAndy Whitcroft 22226c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 2223c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 22246c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 22256c72ffaaSAndy Whitcroft $type = 'N'; 22266c72ffaaSAndy Whitcroft } 22276c72ffaaSAndy Whitcroft 22286c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 2229c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 22306c72ffaaSAndy Whitcroft } 22316c72ffaaSAndy Whitcroft if (defined $1) { 22326c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 22336c72ffaaSAndy Whitcroft $res .= $type x length($1); 22346c72ffaaSAndy Whitcroft } 22356c72ffaaSAndy Whitcroft } 22366c72ffaaSAndy Whitcroft 22371f65f947SAndy Whitcroft return ($res, $var); 22386c72ffaaSAndy Whitcroft} 22396c72ffaaSAndy Whitcroft 22408905a67cSAndy Whitcroftsub possible { 224113214adfSAndy Whitcroft my ($possible, $line) = @_; 22429a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 22430776e594SAndy Whitcroft ^(?: 22440776e594SAndy Whitcroft $Modifier| 22450776e594SAndy Whitcroft $Storage| 22460776e594SAndy Whitcroft $Type| 22479a974fdbSAndy Whitcroft DEFINE_\S+ 22489a974fdbSAndy Whitcroft )$| 22499a974fdbSAndy Whitcroft ^(?: 22500776e594SAndy Whitcroft goto| 22510776e594SAndy Whitcroft return| 22520776e594SAndy Whitcroft case| 22530776e594SAndy Whitcroft else| 22540776e594SAndy Whitcroft asm|__asm__| 225589a88353SAndy Whitcroft do| 225689a88353SAndy Whitcroft \#| 225789a88353SAndy Whitcroft \#\#| 22589a974fdbSAndy Whitcroft )(?:\s|$)| 22590776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 22609a974fdbSAndy Whitcroft )}x; 22619a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 22629a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 2263c45dcabdSAndy Whitcroft # Check for modifiers. 2264c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 2265c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 2266c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 2267c45dcabdSAndy Whitcroft 2268c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 2269c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 2270d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 22719a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 2272d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 2273485ff23eSAlex Dowad push(@modifierListFile, $modifier); 2274d2506586SAndy Whitcroft } 22759a974fdbSAndy Whitcroft } 2276c45dcabdSAndy Whitcroft 2277c45dcabdSAndy Whitcroft } else { 227813214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 2279485ff23eSAlex Dowad push(@typeListFile, $possible); 2280c45dcabdSAndy Whitcroft } 22818905a67cSAndy Whitcroft build_types(); 22820776e594SAndy Whitcroft } else { 22830776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 22848905a67cSAndy Whitcroft } 22858905a67cSAndy Whitcroft} 22868905a67cSAndy Whitcroft 22876c72ffaaSAndy Whitcroftmy $prefix = ''; 22886c72ffaaSAndy Whitcroft 2289000d1cc1SJoe Perchessub show_type { 2290cbec18afSJoe Perches my ($type) = @_; 229191bfe484SJoe Perches 2292522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2293522b837cSAlexey Dobriyan 2294cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2295cbec18afSJoe Perches 2296cbec18afSJoe Perches return !defined $ignore_type{$type}; 2297000d1cc1SJoe Perches} 2298000d1cc1SJoe Perches 2299f0a594c1SAndy Whitcroftsub report { 2300cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2301cbec18afSJoe Perches 2302cbec18afSJoe Perches if (!show_type($type) || 2303cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2304773647a0SAndy Whitcroft return 0; 2305773647a0SAndy Whitcroft } 230657230297SJoe Perches my $output = ''; 2307737c0767SJohn Brooks if ($color) { 230857230297SJoe Perches if ($level eq 'ERROR') { 230957230297SJoe Perches $output .= RED; 231057230297SJoe Perches } elsif ($level eq 'WARNING') { 231157230297SJoe Perches $output .= YELLOW; 2312000d1cc1SJoe Perches } else { 231357230297SJoe Perches $output .= GREEN; 2314000d1cc1SJoe Perches } 231557230297SJoe Perches } 231657230297SJoe Perches $output .= $prefix . $level . ':'; 231757230297SJoe Perches if ($show_types) { 2318737c0767SJohn Brooks $output .= BLUE if ($color); 231957230297SJoe Perches $output .= "$type:"; 232057230297SJoe Perches } 2321737c0767SJohn Brooks $output .= RESET if ($color); 232257230297SJoe Perches $output .= ' ' . $msg . "\n"; 232334d8815fSJoe Perches 232434d8815fSJoe Perches if ($showfile) { 232534d8815fSJoe Perches my @lines = split("\n", $output, -1); 232634d8815fSJoe Perches splice(@lines, 1, 1); 232734d8815fSJoe Perches $output = join("\n", @lines); 232834d8815fSJoe Perches } 232952178ce0SDwaipayan Ray 233052178ce0SDwaipayan Ray if ($terse) { 233152178ce0SDwaipayan Ray $output = (split('\n', $output))[0] . "\n"; 233252178ce0SDwaipayan Ray } 233352178ce0SDwaipayan Ray 233452178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$type}) && 233552178ce0SDwaipayan Ray !exists($verbose_emitted{$type})) { 233652178ce0SDwaipayan Ray $output .= $verbose_messages{$type} . "\n\n"; 233752178ce0SDwaipayan Ray $verbose_emitted{$type} = 1; 233852178ce0SDwaipayan Ray } 23398905a67cSAndy Whitcroft 234057230297SJoe Perches push(our @report, $output); 2341773647a0SAndy Whitcroft 2342773647a0SAndy Whitcroft return 1; 2343f0a594c1SAndy Whitcroft} 2344cbec18afSJoe Perches 2345f0a594c1SAndy Whitcroftsub report_dump { 234613214adfSAndy Whitcroft our @report; 2347f0a594c1SAndy Whitcroft} 2348000d1cc1SJoe Perches 2349d752fcc8SJoe Perchessub fixup_current_range { 2350d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2351d752fcc8SJoe Perches 2352d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2353d752fcc8SJoe Perches my $o = $1; 2354d752fcc8SJoe Perches my $l = $2; 2355d752fcc8SJoe Perches my $no = $o + $offset; 2356d752fcc8SJoe Perches my $nl = $l + $length; 2357d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2358d752fcc8SJoe Perches } 2359d752fcc8SJoe Perches} 2360d752fcc8SJoe Perches 2361d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2362d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2363d752fcc8SJoe Perches 2364d752fcc8SJoe Perches my $range_last_linenr = 0; 2365d752fcc8SJoe Perches my $delta_offset = 0; 2366d752fcc8SJoe Perches 2367d752fcc8SJoe Perches my $old_linenr = 0; 2368d752fcc8SJoe Perches my $new_linenr = 0; 2369d752fcc8SJoe Perches 2370d752fcc8SJoe Perches my $next_insert = 0; 2371d752fcc8SJoe Perches my $next_delete = 0; 2372d752fcc8SJoe Perches 2373d752fcc8SJoe Perches my @lines = (); 2374d752fcc8SJoe Perches 2375d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2376d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2377d752fcc8SJoe Perches 2378d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2379d752fcc8SJoe Perches my $save_line = 1; 2380d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2381323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2382d752fcc8SJoe Perches $delta_offset = 0; 2383d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2384d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2385d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2386d752fcc8SJoe Perches } 2387d752fcc8SJoe Perches 2388d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2389d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2390d752fcc8SJoe Perches $save_line = 0; 2391d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2392d752fcc8SJoe Perches } 2393d752fcc8SJoe Perches 2394d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2395d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2396d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2397d752fcc8SJoe Perches $new_linenr++; 2398d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2399d752fcc8SJoe Perches } 2400d752fcc8SJoe Perches 2401d752fcc8SJoe Perches if ($save_line) { 2402d752fcc8SJoe Perches push(@lines, $line); 2403d752fcc8SJoe Perches $new_linenr++; 2404d752fcc8SJoe Perches } 2405d752fcc8SJoe Perches 2406d752fcc8SJoe Perches $old_linenr++; 2407d752fcc8SJoe Perches } 2408d752fcc8SJoe Perches 2409d752fcc8SJoe Perches return @lines; 2410d752fcc8SJoe Perches} 2411d752fcc8SJoe Perches 2412f2d7e4d4SJoe Perchessub fix_insert_line { 2413f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2414f2d7e4d4SJoe Perches 2415f2d7e4d4SJoe Perches my $inserted = { 2416f2d7e4d4SJoe Perches LINENR => $linenr, 2417f2d7e4d4SJoe Perches LINE => $line, 2418f2d7e4d4SJoe Perches }; 2419f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2420f2d7e4d4SJoe Perches} 2421f2d7e4d4SJoe Perches 2422f2d7e4d4SJoe Perchessub fix_delete_line { 2423f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2424f2d7e4d4SJoe Perches 2425f2d7e4d4SJoe Perches my $deleted = { 2426f2d7e4d4SJoe Perches LINENR => $linenr, 2427f2d7e4d4SJoe Perches LINE => $line, 2428f2d7e4d4SJoe Perches }; 2429f2d7e4d4SJoe Perches 2430f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2431f2d7e4d4SJoe Perches} 2432f2d7e4d4SJoe Perches 2433de7d4f0eSAndy Whitcroftsub ERROR { 2434cbec18afSJoe Perches my ($type, $msg) = @_; 2435cbec18afSJoe Perches 2436cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2437de7d4f0eSAndy Whitcroft our $clean = 0; 24386c72ffaaSAndy Whitcroft our $cnt_error++; 24393705ce5bSJoe Perches return 1; 2440de7d4f0eSAndy Whitcroft } 24413705ce5bSJoe Perches return 0; 2442773647a0SAndy Whitcroft} 2443de7d4f0eSAndy Whitcroftsub WARN { 2444cbec18afSJoe Perches my ($type, $msg) = @_; 2445cbec18afSJoe Perches 2446cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2447de7d4f0eSAndy Whitcroft our $clean = 0; 24486c72ffaaSAndy Whitcroft our $cnt_warn++; 24493705ce5bSJoe Perches return 1; 2450de7d4f0eSAndy Whitcroft } 24513705ce5bSJoe Perches return 0; 2452773647a0SAndy Whitcroft} 2453de7d4f0eSAndy Whitcroftsub CHK { 2454cbec18afSJoe Perches my ($type, $msg) = @_; 2455cbec18afSJoe Perches 2456cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2457de7d4f0eSAndy Whitcroft our $clean = 0; 24586c72ffaaSAndy Whitcroft our $cnt_chk++; 24593705ce5bSJoe Perches return 1; 24606c72ffaaSAndy Whitcroft } 24613705ce5bSJoe Perches return 0; 2462de7d4f0eSAndy Whitcroft} 2463de7d4f0eSAndy Whitcroft 24646ecd9674SAndy Whitcroftsub check_absolute_file { 24656ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 24666ecd9674SAndy Whitcroft my $file = $absolute; 24676ecd9674SAndy Whitcroft 24686ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 24696ecd9674SAndy Whitcroft 24706ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 24716ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 24726ecd9674SAndy Whitcroft if (-f "$root/$file") { 24736ecd9674SAndy Whitcroft ##print "file<$file>\n"; 24746ecd9674SAndy Whitcroft last; 24756ecd9674SAndy Whitcroft } 24766ecd9674SAndy Whitcroft } 24776ecd9674SAndy Whitcroft if (! -f _) { 24786ecd9674SAndy Whitcroft return 0; 24796ecd9674SAndy Whitcroft } 24806ecd9674SAndy Whitcroft 24816ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 24826ecd9674SAndy Whitcroft my $prefix = $absolute; 24836ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 24846ecd9674SAndy Whitcroft 24856ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 24866ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2487000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2488000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 24896ecd9674SAndy Whitcroft } 24906ecd9674SAndy Whitcroft} 24916ecd9674SAndy Whitcroft 24923705ce5bSJoe Perchessub trim { 24933705ce5bSJoe Perches my ($string) = @_; 24943705ce5bSJoe Perches 2495b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2496b34c648bSJoe Perches 2497b34c648bSJoe Perches return $string; 2498b34c648bSJoe Perches} 2499b34c648bSJoe Perches 2500b34c648bSJoe Perchessub ltrim { 2501b34c648bSJoe Perches my ($string) = @_; 2502b34c648bSJoe Perches 2503b34c648bSJoe Perches $string =~ s/^\s+//; 2504b34c648bSJoe Perches 2505b34c648bSJoe Perches return $string; 2506b34c648bSJoe Perches} 2507b34c648bSJoe Perches 2508b34c648bSJoe Perchessub rtrim { 2509b34c648bSJoe Perches my ($string) = @_; 2510b34c648bSJoe Perches 2511b34c648bSJoe Perches $string =~ s/\s+$//; 25123705ce5bSJoe Perches 25133705ce5bSJoe Perches return $string; 25143705ce5bSJoe Perches} 25153705ce5bSJoe Perches 251652ea8506SJoe Perchessub string_find_replace { 251752ea8506SJoe Perches my ($string, $find, $replace) = @_; 251852ea8506SJoe Perches 251952ea8506SJoe Perches $string =~ s/$find/$replace/g; 252052ea8506SJoe Perches 252152ea8506SJoe Perches return $string; 252252ea8506SJoe Perches} 252352ea8506SJoe Perches 25243705ce5bSJoe Perchessub tabify { 25253705ce5bSJoe Perches my ($leading) = @_; 25263705ce5bSJoe Perches 2527713a09deSAntonio Borneo my $source_indent = $tabsize; 25283705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 25293705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 25303705ce5bSJoe Perches 25313705ce5bSJoe Perches #convert leading spaces to tabs 25323705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 25333705ce5bSJoe Perches #Remove spaces before a tab 25343705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 25353705ce5bSJoe Perches 25363705ce5bSJoe Perches return "$leading"; 25373705ce5bSJoe Perches} 25383705ce5bSJoe Perches 2539d1fe9c09SJoe Perchessub pos_last_openparen { 2540d1fe9c09SJoe Perches my ($line) = @_; 2541d1fe9c09SJoe Perches 2542d1fe9c09SJoe Perches my $pos = 0; 2543d1fe9c09SJoe Perches 2544d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2545d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2546d1fe9c09SJoe Perches 2547d1fe9c09SJoe Perches my $last_openparen = 0; 2548d1fe9c09SJoe Perches 2549d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2550d1fe9c09SJoe Perches return -1; 2551d1fe9c09SJoe Perches } 2552d1fe9c09SJoe Perches 2553d1fe9c09SJoe Perches my $len = length($line); 2554d1fe9c09SJoe Perches 2555d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2556d1fe9c09SJoe Perches my $string = substr($line, $pos); 2557d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2558d1fe9c09SJoe Perches $pos += length($1) - 1; 2559d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2560d1fe9c09SJoe Perches $last_openparen = $pos; 2561d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2562d1fe9c09SJoe Perches last; 2563d1fe9c09SJoe Perches } 2564d1fe9c09SJoe Perches } 2565d1fe9c09SJoe Perches 256691cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2567d1fe9c09SJoe Perches} 2568d1fe9c09SJoe Perches 2569f36d3eb8SJoe Perchessub get_raw_comment { 2570f36d3eb8SJoe Perches my ($line, $rawline) = @_; 2571f36d3eb8SJoe Perches my $comment = ''; 2572f36d3eb8SJoe Perches 2573f36d3eb8SJoe Perches for my $i (0 .. (length($line) - 1)) { 2574f36d3eb8SJoe Perches if (substr($line, $i, 1) eq "$;") { 2575f36d3eb8SJoe Perches $comment .= substr($rawline, $i, 1); 2576f36d3eb8SJoe Perches } 2577f36d3eb8SJoe Perches } 2578f36d3eb8SJoe Perches 2579f36d3eb8SJoe Perches return $comment; 2580f36d3eb8SJoe Perches} 2581f36d3eb8SJoe Perches 25825b8f82e1SSong Liusub exclude_global_initialisers { 25835b8f82e1SSong Liu my ($realfile) = @_; 25845b8f82e1SSong Liu 25855b8f82e1SSong Liu # Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c). 25865b8f82e1SSong Liu return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ || 25875b8f82e1SSong Liu $realfile =~ m@^samples/bpf/.*_kern\.c$@ || 25885b8f82e1SSong Liu $realfile =~ m@/bpf/.*\.bpf\.c$@; 25895b8f82e1SSong Liu} 25905b8f82e1SSong Liu 25910a920b5bSAndy Whitcroftsub process { 25920a920b5bSAndy Whitcroft my $filename = shift; 25930a920b5bSAndy Whitcroft 25940a920b5bSAndy Whitcroft my $linenr=0; 25950a920b5bSAndy Whitcroft my $prevline=""; 2596c2fdda0dSAndy Whitcroft my $prevrawline=""; 25970a920b5bSAndy Whitcroft my $stashline=""; 2598c2fdda0dSAndy Whitcroft my $stashrawline=""; 25990a920b5bSAndy Whitcroft 26004a0df2efSAndy Whitcroft my $length; 26010a920b5bSAndy Whitcroft my $indent; 26020a920b5bSAndy Whitcroft my $previndent=0; 26030a920b5bSAndy Whitcroft my $stashindent=0; 26040a920b5bSAndy Whitcroft 2605de7d4f0eSAndy Whitcroft our $clean = 1; 26060a920b5bSAndy Whitcroft my $signoff = 0; 2607cd261496SGeert Uytterhoeven my $author = ''; 2608cd261496SGeert Uytterhoeven my $authorsignoff = 0; 260948ca2d8aSDwaipayan Ray my $author_sob = ''; 26100a920b5bSAndy Whitcroft my $is_patch = 0; 2611133712a2SRob Herring my $is_binding_patch = -1; 261229ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 261315662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 261444d303ebSJoe Perches my $has_patch_separator = 0; #Found a --- line 2615ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2616490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2617bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 26182a076f40SJoe Perches my $commit_log_long_line = 0; 2619e518e9a5SJoe Perches my $commit_log_has_diff = 0; 262013f1937eSJoe Perches my $reported_maintainer_file = 0; 2621fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2622fa64205dSPasi Savanainen 26234ce9f970SJoe Perches my $last_git_commit_id_linenr = -1; 26244ce9f970SJoe Perches 2625365dd4eaSJoe Perches my $last_blank_line = 0; 26265e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2627365dd4eaSJoe Perches 262813214adfSAndy Whitcroft our @report = (); 26296c72ffaaSAndy Whitcroft our $cnt_lines = 0; 26306c72ffaaSAndy Whitcroft our $cnt_error = 0; 26316c72ffaaSAndy Whitcroft our $cnt_warn = 0; 26326c72ffaaSAndy Whitcroft our $cnt_chk = 0; 26336c72ffaaSAndy Whitcroft 26340a920b5bSAndy Whitcroft # Trace the real file/line as we go. 26350a920b5bSAndy Whitcroft my $realfile = ''; 26360a920b5bSAndy Whitcroft my $realline = 0; 26370a920b5bSAndy Whitcroft my $realcnt = 0; 26380a920b5bSAndy Whitcroft my $here = ''; 263977cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 26400a920b5bSAndy Whitcroft my $in_comment = 0; 2641c2fdda0dSAndy Whitcroft my $comment_edge = 0; 26420a920b5bSAndy Whitcroft my $first_line = 0; 26431e855726SWolfram Sang my $p1_prefix = ''; 26440a920b5bSAndy Whitcroft 264513214adfSAndy Whitcroft my $prev_values = 'E'; 264613214adfSAndy Whitcroft 264713214adfSAndy Whitcroft # suppression flags 2648773647a0SAndy Whitcroft my %suppress_ifbraces; 2649170d3a22SAndy Whitcroft my %suppress_whiletrailers; 26502b474a1aSAndy Whitcroft my %suppress_export; 26513e469cdcSAndy Whitcroft my $suppress_statement = 0; 2652653d4876SAndy Whitcroft 26537e51f197SJoe Perches my %signatures = (); 2654323c1260SJoe Perches 2655c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2656de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2657c2fdda0dSAndy Whitcroft # 2658de7d4f0eSAndy Whitcroft my @setup_docs = (); 2659de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2660773647a0SAndy Whitcroft 2661d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2662d8b07710SJoe Perches 26639f3a8992SRob Herring my $checklicenseline = 1; 26649f3a8992SRob Herring 2665773647a0SAndy Whitcroft sanitise_line_reset(); 2666c2fdda0dSAndy Whitcroft my $line; 2667c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2668773647a0SAndy Whitcroft $linenr++; 2669773647a0SAndy Whitcroft $line = $rawline; 2670c2fdda0dSAndy Whitcroft 26713705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 26723705ce5bSJoe Perches 2673773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2674de7d4f0eSAndy Whitcroft $setup_docs = 0; 26752581ac7cSTim Froidcoeur if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { 2676de7d4f0eSAndy Whitcroft $setup_docs = 1; 2677de7d4f0eSAndy Whitcroft } 2678773647a0SAndy Whitcroft #next; 2679de7d4f0eSAndy Whitcroft } 268074fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2681773647a0SAndy Whitcroft $realline=$1-1; 2682773647a0SAndy Whitcroft if (defined $2) { 2683773647a0SAndy Whitcroft $realcnt=$3+1; 2684773647a0SAndy Whitcroft } else { 2685773647a0SAndy Whitcroft $realcnt=1+1; 2686773647a0SAndy Whitcroft } 2687c45dcabdSAndy Whitcroft $in_comment = 0; 2688773647a0SAndy Whitcroft 2689773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2690773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2691773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2692773647a0SAndy Whitcroft # at context start. 2693773647a0SAndy Whitcroft my $edge; 269401fa9147SAndy Whitcroft my $cnt = $realcnt; 269501fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 269601fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 269701fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 269801fa9147SAndy Whitcroft $cnt--; 269901fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2700721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2701fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2702fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2703fae17daeSAndy Whitcroft ($edge) = $1; 2704fae17daeSAndy Whitcroft last; 2705fae17daeSAndy Whitcroft } 2706773647a0SAndy Whitcroft } 2707773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2708773647a0SAndy Whitcroft $in_comment = 1; 2709773647a0SAndy Whitcroft } 2710773647a0SAndy Whitcroft 2711773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2712773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2713773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2714773647a0SAndy Whitcroft if (!defined $edge && 271583242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2716773647a0SAndy Whitcroft { 2717773647a0SAndy Whitcroft $in_comment = 1; 2718773647a0SAndy Whitcroft } 2719773647a0SAndy Whitcroft 2720773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2721773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2722773647a0SAndy Whitcroft 2723171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2724773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2725171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2726773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2727773647a0SAndy Whitcroft } 2728773647a0SAndy Whitcroft push(@lines, $line); 2729773647a0SAndy Whitcroft 2730773647a0SAndy Whitcroft if ($realcnt > 1) { 2731773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2732773647a0SAndy Whitcroft } else { 2733773647a0SAndy Whitcroft $realcnt = 0; 2734773647a0SAndy Whitcroft } 2735773647a0SAndy Whitcroft 2736773647a0SAndy Whitcroft #print "==>$rawline\n"; 2737773647a0SAndy Whitcroft #print "-->$line\n"; 2738de7d4f0eSAndy Whitcroft 2739de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2740de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2741de7d4f0eSAndy Whitcroft } 2742de7d4f0eSAndy Whitcroft } 2743de7d4f0eSAndy Whitcroft 27446c72ffaaSAndy Whitcroft $prefix = ''; 27456c72ffaaSAndy Whitcroft 2746773647a0SAndy Whitcroft $realcnt = 0; 2747773647a0SAndy Whitcroft $linenr = 0; 2748194f66fcSJoe Perches $fixlinenr = -1; 27490a920b5bSAndy Whitcroft foreach my $line (@lines) { 27500a920b5bSAndy Whitcroft $linenr++; 2751194f66fcSJoe Perches $fixlinenr++; 27521b5539b1SJoe Perches my $sline = $line; #copy of $line 27531b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 27540a920b5bSAndy Whitcroft 2755c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 2756f36d3eb8SJoe Perches my $raw_comment = get_raw_comment($line, $rawline); 27576c72ffaaSAndy Whitcroft 275812c253abSJoe Perches# check if it's a mode change, rename or start of a patch 275912c253abSJoe Perches if (!$in_commit_log && 276012c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 276112c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 276212c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 276312c253abSJoe Perches $is_patch = 1; 276412c253abSJoe Perches } 276512c253abSJoe Perches 27660a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2767e518e9a5SJoe Perches if (!$in_commit_log && 276874fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 276974fd4f34SJoe Perches my $context = $4; 27700a920b5bSAndy Whitcroft $is_patch = 1; 27714a0df2efSAndy Whitcroft $first_line = $linenr + 1; 27720a920b5bSAndy Whitcroft $realline=$1-1; 27730a920b5bSAndy Whitcroft if (defined $2) { 27740a920b5bSAndy Whitcroft $realcnt=$3+1; 27750a920b5bSAndy Whitcroft } else { 27760a920b5bSAndy Whitcroft $realcnt=1+1; 27770a920b5bSAndy Whitcroft } 2778c2fdda0dSAndy Whitcroft annotate_reset(); 277913214adfSAndy Whitcroft $prev_values = 'E'; 278013214adfSAndy Whitcroft 2781773647a0SAndy Whitcroft %suppress_ifbraces = (); 2782170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 27832b474a1aSAndy Whitcroft %suppress_export = (); 27843e469cdcSAndy Whitcroft $suppress_statement = 0; 278574fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 278674fd4f34SJoe Perches $context_function = $1; 278774fd4f34SJoe Perches } else { 278874fd4f34SJoe Perches undef $context_function; 278974fd4f34SJoe Perches } 27900a920b5bSAndy Whitcroft next; 27910a920b5bSAndy Whitcroft 27924a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 27934a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 27944a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2795773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 27960a920b5bSAndy Whitcroft $realline++; 2797d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 27980a920b5bSAndy Whitcroft 27994a0df2efSAndy Whitcroft # Measure the line length and indent. 2800c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 28010a920b5bSAndy Whitcroft 28020a920b5bSAndy Whitcroft # Track the previous line. 28030a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 28040a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2805c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2806c2fdda0dSAndy Whitcroft 2807773647a0SAndy Whitcroft #warn "line<$line>\n"; 28086c72ffaaSAndy Whitcroft 2809d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2810d8aaf121SAndy Whitcroft $realcnt--; 28110a920b5bSAndy Whitcroft } 28120a920b5bSAndy Whitcroft 2813cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2814cc77cdcaSAndy Whitcroft 28156c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 28166c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2817773647a0SAndy Whitcroft 28182ac73b4fSJoe Perches my $found_file = 0; 2819773647a0SAndy Whitcroft # extract the filename as it passes 28203bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 28213bf9a009SRabin Vincent $realfile = $1; 28222b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2823270c49a0SJoe Perches $in_commit_log = 0; 28242ac73b4fSJoe Perches $found_file = 1; 28253bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2826773647a0SAndy Whitcroft $realfile = $1; 28272b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2828270c49a0SJoe Perches $in_commit_log = 0; 28291e855726SWolfram Sang 28301e855726SWolfram Sang $p1_prefix = $1; 2831e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2832e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2833000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2834000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 28351e855726SWolfram Sang } 2836773647a0SAndy Whitcroft 2837c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2838000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2839000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2840773647a0SAndy Whitcroft } 28412ac73b4fSJoe Perches $found_file = 1; 28422ac73b4fSJoe Perches } 28432ac73b4fSJoe Perches 284434d8815fSJoe Perches#make up the handle for any error we report on this line 284534d8815fSJoe Perches if ($showfile) { 284634d8815fSJoe Perches $prefix = "$realfile:$realline: " 284734d8815fSJoe Perches } elsif ($emacs) { 28487d3a9f67SJoe Perches if ($file) { 28497d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 28507d3a9f67SJoe Perches } else { 285134d8815fSJoe Perches $prefix = "$filename:$linenr: "; 285234d8815fSJoe Perches } 28537d3a9f67SJoe Perches } 285434d8815fSJoe Perches 28552ac73b4fSJoe Perches if ($found_file) { 285685b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 285785b0ee18SJoe Perches WARN("OBSOLETE", 285885b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 285985b0ee18SJoe Perches } 28607bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 28612ac73b4fSJoe Perches $check = 1; 28622ac73b4fSJoe Perches } else { 28632ac73b4fSJoe Perches $check = $check_orig; 28642ac73b4fSJoe Perches } 28659f3a8992SRob Herring $checklicenseline = 1; 2866133712a2SRob Herring 2867133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2868133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2869133712a2SRob Herring 2870133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2871133712a2SRob Herring 2872133712a2SRob Herring if (($last_binding_patch != -1) && 2873133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2874133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2875858e6845SMauro Carvalho Chehab "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); 2876133712a2SRob Herring } 2877133712a2SRob Herring } 2878133712a2SRob Herring 2879773647a0SAndy Whitcroft next; 2880773647a0SAndy Whitcroft } 2881773647a0SAndy Whitcroft 2882389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 28830a920b5bSAndy Whitcroft 2884c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2885c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2886c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 28870a920b5bSAndy Whitcroft 28886c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 28896c72ffaaSAndy Whitcroft 2890490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2891490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2892490b292cSJoe Perches if ($in_commit_log) { 2893490b292cSJoe Perches if ($line !~ /^\s*$/) { 2894490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2895490b292cSJoe Perches } 2896490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2897490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2898490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2899490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2900490b292cSJoe Perches } 2901490b292cSJoe Perches 2902e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2903e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 290413e45417SMrinal Pandey (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && 290513e45417SMrinal Pandey $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || 2906e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2907e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2908e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2909e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2910e518e9a5SJoe Perches $commit_log_has_diff = 1; 2911e518e9a5SJoe Perches } 2912e518e9a5SJoe Perches 29133bf9a009SRabin Vincent# Check for incorrect file permissions 29143bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 29153bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 291604db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 291704db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2918000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2919000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 29203bf9a009SRabin Vincent } 29213bf9a009SRabin Vincent } 29223bf9a009SRabin Vincent 2923cd261496SGeert Uytterhoeven# Check the patch for a From: 2924cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2925cd261496SGeert Uytterhoeven $author = $1; 2926e7f929f3SDwaipayan Ray my $curline = $linenr; 2927e7f929f3SDwaipayan Ray while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { 2928e7f929f3SDwaipayan Ray $author .= $1; 2929e7f929f3SDwaipayan Ray } 2930cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2931cd261496SGeert Uytterhoeven $author =~ s/"//g; 2932dfa05c28SJoe Perches $author = reformat_email($author); 2933cd261496SGeert Uytterhoeven } 2934cd261496SGeert Uytterhoeven 293520112475SJoe Perches# Check the patch for a signoff: 2936dfa05c28SJoe Perches if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { 29374a0df2efSAndy Whitcroft $signoff++; 293815662b3eSJoe Perches $in_commit_log = 0; 293948ca2d8aSDwaipayan Ray if ($author ne '' && $authorsignoff != 1) { 2940fccaebf0SDwaipayan Ray if (same_email_addresses($1, $author)) { 2941cd261496SGeert Uytterhoeven $authorsignoff = 1; 294248ca2d8aSDwaipayan Ray } else { 294348ca2d8aSDwaipayan Ray my $ctx = $1; 294448ca2d8aSDwaipayan Ray my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); 294548ca2d8aSDwaipayan Ray my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); 294648ca2d8aSDwaipayan Ray 2947046fc741SMimi Zohar if (lc $email_address eq lc $author_address && $email_name eq $author_name) { 294848ca2d8aSDwaipayan Ray $author_sob = $ctx; 294948ca2d8aSDwaipayan Ray $authorsignoff = 2; 2950046fc741SMimi Zohar } elsif (lc $email_address eq lc $author_address) { 295148ca2d8aSDwaipayan Ray $author_sob = $ctx; 295248ca2d8aSDwaipayan Ray $authorsignoff = 3; 295348ca2d8aSDwaipayan Ray } elsif ($email_name eq $author_name) { 295448ca2d8aSDwaipayan Ray $author_sob = $ctx; 295548ca2d8aSDwaipayan Ray $authorsignoff = 4; 295648ca2d8aSDwaipayan Ray 295748ca2d8aSDwaipayan Ray my $address1 = $email_address; 295848ca2d8aSDwaipayan Ray my $address2 = $author_address; 295948ca2d8aSDwaipayan Ray 296048ca2d8aSDwaipayan Ray if ($address1 =~ /(\S+)\+\S+(\@.*)/) { 296148ca2d8aSDwaipayan Ray $address1 = "$1$2"; 296248ca2d8aSDwaipayan Ray } 296348ca2d8aSDwaipayan Ray if ($address2 =~ /(\S+)\+\S+(\@.*)/) { 296448ca2d8aSDwaipayan Ray $address2 = "$1$2"; 296548ca2d8aSDwaipayan Ray } 296648ca2d8aSDwaipayan Ray if ($address1 eq $address2) { 296748ca2d8aSDwaipayan Ray $authorsignoff = 5; 296848ca2d8aSDwaipayan Ray } 296948ca2d8aSDwaipayan Ray } 2970cd261496SGeert Uytterhoeven } 2971cd261496SGeert Uytterhoeven } 29720a920b5bSAndy Whitcroft } 297320112475SJoe Perches 297444d303ebSJoe Perches# Check for patch separator 297544d303ebSJoe Perches if ($line =~ /^---$/) { 297644d303ebSJoe Perches $has_patch_separator = 1; 297744d303ebSJoe Perches $in_commit_log = 0; 297844d303ebSJoe Perches } 297944d303ebSJoe Perches 2980e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2981e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2982e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2983e0d975b1SJoe Perches $reported_maintainer_file = 1; 2984e0d975b1SJoe Perches } 2985e0d975b1SJoe Perches 298620112475SJoe Perches# Check signature styles 2987270c49a0SJoe Perches if (!$in_header_lines && 2988ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 298920112475SJoe Perches my $space_before = $1; 299020112475SJoe Perches my $sign_off = $2; 299120112475SJoe Perches my $space_after = $3; 299220112475SJoe Perches my $email = $4; 299320112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 299420112475SJoe Perches 2995ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2996831242abSAditya Srivastava my $suggested_signature = find_standard_signature($sign_off); 2997831242abSAditya Srivastava if ($suggested_signature eq "") { 2998ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2999ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 3000831242abSAditya Srivastava } else { 3001831242abSAditya Srivastava if (WARN("BAD_SIGN_OFF", 3002831242abSAditya Srivastava "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && 3003831242abSAditya Srivastava $fix) { 3004831242abSAditya Srivastava $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; 3005831242abSAditya Srivastava } 3006831242abSAditya Srivastava } 3007ce0338dfSJoe Perches } 300820112475SJoe Perches if (defined $space_before && $space_before ne "") { 30093705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30103705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 30113705ce5bSJoe Perches $fix) { 3012194f66fcSJoe Perches $fixed[$fixlinenr] = 30133705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30143705ce5bSJoe Perches } 301520112475SJoe Perches } 301620112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 30173705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30183705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 30193705ce5bSJoe Perches $fix) { 3020194f66fcSJoe Perches $fixed[$fixlinenr] = 30213705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30223705ce5bSJoe Perches } 30233705ce5bSJoe Perches 302420112475SJoe Perches } 302520112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 30263705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30273705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 30283705ce5bSJoe Perches $fix) { 3029194f66fcSJoe Perches $fixed[$fixlinenr] = 30303705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30313705ce5bSJoe Perches } 303220112475SJoe Perches } 303320112475SJoe Perches 3034dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 303548ca2d8aSDwaipayan Ray my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); 303620112475SJoe Perches if ($suggested_email eq "") { 3037000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 3038000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 303920112475SJoe Perches } else { 304020112475SJoe Perches my $dequoted = $suggested_email; 304120112475SJoe Perches $dequoted =~ s/^"//; 304220112475SJoe Perches $dequoted =~ s/" </ </; 304320112475SJoe Perches # Don't force email to have quotes 304420112475SJoe Perches # Allow just an angle bracketed address 3045fccaebf0SDwaipayan Ray if (!same_email_addresses($email, $suggested_email)) { 3046fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3047fccaebf0SDwaipayan Ray "email address '$email' might be better as '$suggested_email'\n" . $herecurr) && 3048fccaebf0SDwaipayan Ray $fix) { 3049fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/; 3050fccaebf0SDwaipayan Ray } 3051fccaebf0SDwaipayan Ray } 3052fccaebf0SDwaipayan Ray 3053fccaebf0SDwaipayan Ray # Address part shouldn't have comments 3054fccaebf0SDwaipayan Ray my $stripped_address = $email_address; 3055fccaebf0SDwaipayan Ray $stripped_address =~ s/\([^\(\)]*\)//g; 3056fccaebf0SDwaipayan Ray if ($email_address ne $stripped_address) { 3057fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3058fccaebf0SDwaipayan Ray "address part of email should not have comments: '$email_address'\n" . $herecurr) && 3059fccaebf0SDwaipayan Ray $fix) { 3060fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/; 3061fccaebf0SDwaipayan Ray } 3062fccaebf0SDwaipayan Ray } 3063fccaebf0SDwaipayan Ray 3064fccaebf0SDwaipayan Ray # Only one name comment should be allowed 3065fccaebf0SDwaipayan Ray my $comment_count = () = $name_comment =~ /\([^\)]+\)/g; 3066fccaebf0SDwaipayan Ray if ($comment_count > 1) { 3067000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 3068fccaebf0SDwaipayan Ray "Use a single name comment in email: '$email'\n" . $herecurr); 3069fccaebf0SDwaipayan Ray } 3070fccaebf0SDwaipayan Ray 3071fccaebf0SDwaipayan Ray 3072fccaebf0SDwaipayan Ray # [email protected] or [email protected] shouldn't 3073e73d2715SDwaipayan Ray # have an email name. In addition comments should strictly 3074fccaebf0SDwaipayan Ray # begin with a # 3075fccaebf0SDwaipayan Ray if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { 3076fccaebf0SDwaipayan Ray if (($comment ne "" && $comment !~ /^#.+/) || 3077fccaebf0SDwaipayan Ray ($email_name ne "")) { 3078fccaebf0SDwaipayan Ray my $cur_name = $email_name; 3079fccaebf0SDwaipayan Ray my $new_comment = $comment; 3080fccaebf0SDwaipayan Ray $cur_name =~ s/[a-zA-Z\s\-\"]+//g; 3081fccaebf0SDwaipayan Ray 3082fccaebf0SDwaipayan Ray # Remove brackets enclosing comment text 3083fccaebf0SDwaipayan Ray # and # from start of comments to get comment text 3084fccaebf0SDwaipayan Ray $new_comment =~ s/^\((.*)\)$/$1/; 3085fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3086fccaebf0SDwaipayan Ray $new_comment =~ s/^[\s\#]+|\s+$//g; 3087fccaebf0SDwaipayan Ray 3088fccaebf0SDwaipayan Ray $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); 3089fccaebf0SDwaipayan Ray $new_comment = " # $new_comment" if ($new_comment ne ""); 3090fccaebf0SDwaipayan Ray my $new_email = "$email_address$new_comment"; 3091fccaebf0SDwaipayan Ray 3092fccaebf0SDwaipayan Ray if (WARN("BAD_STABLE_ADDRESS_STYLE", 3093fccaebf0SDwaipayan Ray "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && 3094fccaebf0SDwaipayan Ray $fix) { 3095fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3096fccaebf0SDwaipayan Ray } 3097fccaebf0SDwaipayan Ray } 3098fccaebf0SDwaipayan Ray } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { 3099fccaebf0SDwaipayan Ray my $new_comment = $comment; 3100fccaebf0SDwaipayan Ray 3101fccaebf0SDwaipayan Ray # Extract comment text from within brackets or 3102fccaebf0SDwaipayan Ray # c89 style /*...*/ comments 3103fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3104fccaebf0SDwaipayan Ray $new_comment =~ s/^\/\*(.*)\*\/$/$1/; 3105fccaebf0SDwaipayan Ray 3106fccaebf0SDwaipayan Ray $new_comment = trim($new_comment); 3107fccaebf0SDwaipayan Ray $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo 3108fccaebf0SDwaipayan Ray $new_comment = "($new_comment)" if ($new_comment ne ""); 3109fccaebf0SDwaipayan Ray my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); 3110fccaebf0SDwaipayan Ray 3111fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3112fccaebf0SDwaipayan Ray "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && 3113fccaebf0SDwaipayan Ray $fix) { 3114fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3115fccaebf0SDwaipayan Ray } 311620112475SJoe Perches } 31170a920b5bSAndy Whitcroft } 31187e51f197SJoe Perches 31197e51f197SJoe Perches# Check for duplicate signatures 31207e51f197SJoe Perches my $sig_nospace = $line; 31217e51f197SJoe Perches $sig_nospace =~ s/\s//g; 31227e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 31237e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 31247e51f197SJoe Perches WARN("BAD_SIGN_OFF", 31257e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 31267e51f197SJoe Perches } else { 31277e51f197SJoe Perches $signatures{$sig_nospace} = 1; 31287e51f197SJoe Perches } 31296c5d24eeSSean Christopherson 31306c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 31316c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 31326c5d24eeSSean Christopherson if ($email eq $author) { 31336c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31346c5d24eeSSean Christopherson "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); 31356c5d24eeSSean Christopherson } 31366c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 31376c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31386c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); 31396c5d24eeSSean Christopherson } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { 31406c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31416c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 31426c5d24eeSSean Christopherson } elsif ($1 ne $email) { 31436c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31446c5d24eeSSean Christopherson "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 31456c5d24eeSSean Christopherson } 31466c5d24eeSSean Christopherson } 31470a920b5bSAndy Whitcroft } 31480a920b5bSAndy Whitcroft 3149*bd17e036SNiklas Söderlund# Check Fixes: styles is correct 3150*bd17e036SNiklas Söderlund if (!$in_header_lines && 3151*bd17e036SNiklas Söderlund $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) { 3152*bd17e036SNiklas Söderlund my $orig_commit = ""; 3153*bd17e036SNiklas Söderlund my $id = "0123456789ab"; 3154*bd17e036SNiklas Söderlund my $title = "commit title"; 3155*bd17e036SNiklas Söderlund my $tag_case = 1; 3156*bd17e036SNiklas Söderlund my $tag_space = 1; 3157*bd17e036SNiklas Söderlund my $id_length = 1; 3158*bd17e036SNiklas Söderlund my $id_case = 1; 3159*bd17e036SNiklas Söderlund my $title_has_quotes = 0; 3160*bd17e036SNiklas Söderlund 3161*bd17e036SNiklas Söderlund if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) { 3162*bd17e036SNiklas Söderlund my $tag = $1; 3163*bd17e036SNiklas Söderlund $orig_commit = $2; 3164*bd17e036SNiklas Söderlund $title = $3; 3165*bd17e036SNiklas Söderlund 3166*bd17e036SNiklas Söderlund $tag_case = 0 if $tag eq "Fixes:"; 3167*bd17e036SNiklas Söderlund $tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i); 3168*bd17e036SNiklas Söderlund 3169*bd17e036SNiklas Söderlund $id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i); 3170*bd17e036SNiklas Söderlund $id_case = 0 if ($orig_commit !~ /[A-F]/); 3171*bd17e036SNiklas Söderlund 3172*bd17e036SNiklas Söderlund # Always strip leading/trailing parens then double quotes if existing 3173*bd17e036SNiklas Söderlund $title = substr($title, 1, -1); 3174*bd17e036SNiklas Söderlund if ($title =~ /^".*"$/) { 3175*bd17e036SNiklas Söderlund $title = substr($title, 1, -1); 3176*bd17e036SNiklas Söderlund $title_has_quotes = 1; 3177*bd17e036SNiklas Söderlund } 3178*bd17e036SNiklas Söderlund } 3179*bd17e036SNiklas Söderlund 3180*bd17e036SNiklas Söderlund my ($cid, $ctitle) = git_commit_info($orig_commit, $id, 3181*bd17e036SNiklas Söderlund $title); 3182*bd17e036SNiklas Söderlund 3183*bd17e036SNiklas Söderlund if ($ctitle ne $title || $tag_case || $tag_space || 3184*bd17e036SNiklas Söderlund $id_length || $id_case || !$title_has_quotes) { 3185*bd17e036SNiklas Söderlund if (WARN("BAD_FIXES_TAG", 3186*bd17e036SNiklas Söderlund "Please use correct Fixes: style 'Fixes: <12 chars of sha1> (\"<title line>\")' - ie: 'Fixes: $cid (\"$ctitle\")'\n" . $herecurr) && 3187*bd17e036SNiklas Söderlund $fix) { 3188*bd17e036SNiklas Söderlund $fixed[$fixlinenr] = "Fixes: $cid (\"$ctitle\")"; 3189*bd17e036SNiklas Söderlund } 3190*bd17e036SNiklas Söderlund } 3191*bd17e036SNiklas Söderlund } 3192*bd17e036SNiklas Söderlund 3193a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 3194a2fe16b9SJoe Perches if ($in_header_lines && 3195a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 3196a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 3197a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 3198a2fe16b9SJoe Perches } 3199a2fe16b9SJoe Perches 320044d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context 320144d303ebSJoe Perches if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { 32027580c5b9SAditya Srivastava if (ERROR("GERRIT_CHANGE_ID", 32037580c5b9SAditya Srivastava "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && 32047580c5b9SAditya Srivastava $fix) { 32057580c5b9SAditya Srivastava fix_delete_line($fixlinenr, $rawline); 32067580c5b9SAditya Srivastava } 32077ebd05efSChristopher Covington } 32087ebd05efSChristopher Covington 3209369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 3210369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3211369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 3212369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 3213369c8dd3SJoe Perches # timestamp 3214634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 3215634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 3216634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 3217634cffccSJoe Perches # stack dump address styles 3218369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 3219369c8dd3SJoe Perches } 3220369c8dd3SJoe Perches 32212a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 32222a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 3223bf4daf12SJoe Perches length($line) > 75 && 3224bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 3225bf4daf12SJoe Perches # file delta changes 322636f8b348SJerome Forissier $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ || 3227bf4daf12SJoe Perches # filename then : 322827b379afSAditya Srivastava $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i || 322927b379afSAditya Srivastava # A Fixes: or Link: line or signature tag line 3230bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 32312a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 32322a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 32332a076f40SJoe Perches $commit_log_long_line = 1; 32342a076f40SJoe Perches } 32352a076f40SJoe Perches 3236bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 3237bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 3238bf4daf12SJoe Perches $line =~ /^\s*$/) { 3239bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 3240bf4daf12SJoe Perches } 3241bf4daf12SJoe Perches 3242084a617aSDwaipayan Ray# Check for lines starting with a # 3243084a617aSDwaipayan Ray if ($in_commit_log && $line =~ /^#/) { 3244084a617aSDwaipayan Ray if (WARN("COMMIT_COMMENT_SYMBOL", 3245084a617aSDwaipayan Ray "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && 3246084a617aSDwaipayan Ray $fix) { 3247084a617aSDwaipayan Ray $fixed[$fixlinenr] =~ s/^/ /; 3248084a617aSDwaipayan Ray } 3249084a617aSDwaipayan Ray } 3250084a617aSDwaipayan Ray 32510d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 32524ce9f970SJoe Perches# A correctly formed commit description is: 32534ce9f970SJoe Perches# commit <SHA-1 hash length 12+ chars> ("Complete commit subject") 32544ce9f970SJoe Perches# with the commit subject '("' prefix and '")' suffix 32554ce9f970SJoe Perches# This is a fairly compilicated block as it tests for what appears to be 32564ce9f970SJoe Perches# bare SHA-1 hash with minimum length of 5. It also avoids several types of 32574ce9f970SJoe Perches# possible SHA-1 matches. 32584ce9f970SJoe Perches# A commit match can span multiple lines so this block attempts to find a 32594ce9f970SJoe Perches# complete typical commit on a maximum of 3 lines 32604ce9f970SJoe Perches if ($perl_version_ok && 32614ce9f970SJoe Perches $in_commit_log && !$commit_log_possible_stack_dump && 3262a8972573SJohn Hubbard $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && 3263e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 32644ce9f970SJoe Perches (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 32654ce9f970SJoe Perches ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) || 3266aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 3267369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 3268bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 3269fe043ea1SJoe Perches my $init_char = "c"; 3270fe043ea1SJoe Perches my $orig_commit = ""; 32710d7835fcSJoe Perches my $short = 1; 32720d7835fcSJoe Perches my $long = 0; 32730d7835fcSJoe Perches my $case = 1; 32740d7835fcSJoe Perches my $space = 1; 32750d7835fcSJoe Perches my $id = '0123456789ab'; 32760d7835fcSJoe Perches my $orig_desc = "commit description"; 32770d7835fcSJoe Perches my $description = ""; 32784ce9f970SJoe Perches my $herectx = $herecurr; 32794ce9f970SJoe Perches my $has_parens = 0; 32804ce9f970SJoe Perches my $has_quotes = 0; 32810d7835fcSJoe Perches 32824ce9f970SJoe Perches my $input = $line; 32834ce9f970SJoe Perches if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) { 32844ce9f970SJoe Perches for (my $n = 0; $n < 2; $n++) { 32854ce9f970SJoe Perches if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) { 32864ce9f970SJoe Perches $orig_desc = $1; 32874ce9f970SJoe Perches $has_parens = 1; 32884ce9f970SJoe Perches # Always strip leading/trailing parens then double quotes if existing 32894ce9f970SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 32904ce9f970SJoe Perches if ($orig_desc =~ /^".*"$/) { 32914ce9f970SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 32924ce9f970SJoe Perches $has_quotes = 1; 32934ce9f970SJoe Perches } 32944ce9f970SJoe Perches last; 32954ce9f970SJoe Perches } 32964ce9f970SJoe Perches last if ($#lines < $linenr + $n); 32974ce9f970SJoe Perches $input .= " " . trim($rawlines[$linenr + $n]); 32984ce9f970SJoe Perches $herectx .= "$rawlines[$linenr + $n]\n"; 32994ce9f970SJoe Perches } 33004ce9f970SJoe Perches $herectx = $herecurr if (!$has_parens); 3301fe043ea1SJoe Perches } 3302fe043ea1SJoe Perches 33034ce9f970SJoe Perches if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 33044ce9f970SJoe Perches $init_char = $1; 33054ce9f970SJoe Perches $orig_commit = lc($2); 33064ce9f970SJoe Perches $short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i); 33074ce9f970SJoe Perches $long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i); 33084ce9f970SJoe Perches $space = 0 if ($input =~ /\bcommit [0-9a-f]/i); 33094ce9f970SJoe Perches $case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 33104ce9f970SJoe Perches } elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) { 33114ce9f970SJoe Perches $orig_commit = lc($1); 33120d7835fcSJoe Perches } 33130d7835fcSJoe Perches 33140d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 33150d7835fcSJoe Perches $id, $orig_desc); 33160d7835fcSJoe Perches 3317948b133aSHeinrich Schuchardt if (defined($id) && 33184ce9f970SJoe Perches ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) && 33194ce9f970SJoe Perches $last_git_commit_id_linenr != $linenr - 1) { 3320d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 33214ce9f970SJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx); 33220d7835fcSJoe Perches } 33234ce9f970SJoe Perches #don't report the next line if this line ends in commit and the sha1 hash is the next line 33244ce9f970SJoe Perches $last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i); 3325d311cd44SJoe Perches } 3326d311cd44SJoe Perches 332713f1937eSJoe Perches# Check for added, moved or deleted files 332813f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 332913f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 333013f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 333113f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 333213f1937eSJoe Perches (defined($1) || defined($2))))) { 3333a82603a8SAndrew Jeffery $is_patch = 1; 333413f1937eSJoe Perches $reported_maintainer_file = 1; 333513f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 333613f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 333713f1937eSJoe Perches } 333813f1937eSJoe Perches 3339e400edb1SRob Herring# Check for adding new DT bindings not in schema format 3340e400edb1SRob Herring if (!$in_commit_log && 3341e400edb1SRob Herring ($line =~ /^new file mode\s*\d+\s*$/) && 3342e400edb1SRob Herring ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { 3343e400edb1SRob Herring WARN("DT_SCHEMA_BINDING_PATCH", 334456ddc4cdSMauro Carvalho Chehab "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n"); 3345e400edb1SRob Herring } 3346e400edb1SRob Herring 334700df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 33488905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 3349000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 3350000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 33516c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 3352de7d4f0eSAndy Whitcroft } 3353de7d4f0eSAndy Whitcroft 3354de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 3355de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 3356171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 3357171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 3358171ae1a4SAndy Whitcroft 3359171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 3360171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 3361171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 3362171ae1a4SAndy Whitcroft 336334d99219SJoe Perches CHK("INVALID_UTF8", 3364000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 336500df344fSAndy Whitcroft } 33660a920b5bSAndy Whitcroft 336715662b3eSJoe Perches# Check if it's the start of a commit log 336815662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 336915662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 3370eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 3371eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 337215662b3eSJoe Perches $in_header_lines = 0; 337315662b3eSJoe Perches $in_commit_log = 1; 3374ed43c4e5SAllen Hubbe $has_commit_log = 1; 337515662b3eSJoe Perches } 337615662b3eSJoe Perches 3377fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 3378fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 3379fa64205dSPasi Savanainen if ($in_header_lines && 3380fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 3381fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 3382fa64205dSPasi Savanainen $non_utf8_charset = 1; 3383fa64205dSPasi Savanainen } 3384fa64205dSPasi Savanainen 3385fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 338615662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 3387fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 338815662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 338915662b3eSJoe Perches } 339015662b3eSJoe Perches 3391d6430f71SJoe Perches# Check for absolute kernel paths in commit message 3392d6430f71SJoe Perches if ($tree && $in_commit_log) { 3393d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 3394d6430f71SJoe Perches my $file = $1; 3395d6430f71SJoe Perches 3396d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 3397d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 3398d6430f71SJoe Perches # 3399d6430f71SJoe Perches } else { 3400d6430f71SJoe Perches check_absolute_file($file, $herecurr); 3401d6430f71SJoe Perches } 3402d6430f71SJoe Perches } 3403d6430f71SJoe Perches } 3404d6430f71SJoe Perches 340566b47b4aSKees Cook# Check for various typo / spelling mistakes 340666d7a382SJoe Perches if (defined($misspellings) && 340766d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 34087da07c31SDwaipayan Ray while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { 340966b47b4aSKees Cook my $typo = $1; 34107da07c31SDwaipayan Ray my $blank = copy_spacing($rawline); 34117da07c31SDwaipayan Ray my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); 34127da07c31SDwaipayan Ray my $hereptr = "$hereline$ptr\n"; 341366b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 341466b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 341566b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 34160675a8fbSJean Delvare my $msg_level = \&WARN; 34170675a8fbSJean Delvare $msg_level = \&CHK if ($file); 34180675a8fbSJean Delvare if (&{$msg_level}("TYPO_SPELLING", 34197da07c31SDwaipayan Ray "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && 342066b47b4aSKees Cook $fix) { 342166b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 342266b47b4aSKees Cook } 342366b47b4aSKees Cook } 342466b47b4aSKees Cook } 342566b47b4aSKees Cook 3426a8dd86bfSMatteo Croce# check for invalid commit id 3427a8dd86bfSMatteo Croce if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 3428a8dd86bfSMatteo Croce my $id; 3429a8dd86bfSMatteo Croce my $description; 3430a8dd86bfSMatteo Croce ($id, $description) = git_commit_info($2, undef, undef); 3431a8dd86bfSMatteo Croce if (!defined($id)) { 3432a8dd86bfSMatteo Croce WARN("UNKNOWN_COMMIT_ID", 3433a8dd86bfSMatteo Croce "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 3434a8dd86bfSMatteo Croce } 3435a8dd86bfSMatteo Croce } 3436a8dd86bfSMatteo Croce 3437310cd06bSJoe Perches# check for repeated words separated by a single space 34388d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root' 34398d0325ccSAditya Srivastava if (($rawline =~ /^\+/ || $in_commit_log) && 34408d0325ccSAditya Srivastava $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { 34411db81a68SDwaipayan Ray pos($rawline) = 1 if (!$in_commit_log); 3442310cd06bSJoe Perches while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { 3443310cd06bSJoe Perches 3444310cd06bSJoe Perches my $first = $1; 3445310cd06bSJoe Perches my $second = $2; 34461db81a68SDwaipayan Ray my $start_pos = $-[1]; 34471db81a68SDwaipayan Ray my $end_pos = $+[2]; 3448310cd06bSJoe Perches if ($first =~ /(?:struct|union|enum)/) { 3449310cd06bSJoe Perches pos($rawline) += length($first) + length($second) + 1; 3450310cd06bSJoe Perches next; 3451310cd06bSJoe Perches } 3452310cd06bSJoe Perches 34531db81a68SDwaipayan Ray next if (lc($first) ne lc($second)); 3454310cd06bSJoe Perches next if ($first eq 'long'); 3455310cd06bSJoe Perches 34561db81a68SDwaipayan Ray # check for character before and after the word matches 34571db81a68SDwaipayan Ray my $start_char = ''; 34581db81a68SDwaipayan Ray my $end_char = ''; 34591db81a68SDwaipayan Ray $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); 34601db81a68SDwaipayan Ray $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); 34611db81a68SDwaipayan Ray 34621db81a68SDwaipayan Ray next if ($start_char =~ /^\S$/); 34631db81a68SDwaipayan Ray next if (index(" \t.,;?!", $end_char) == -1); 34641db81a68SDwaipayan Ray 34658d0325ccSAditya Srivastava # avoid repeating hex occurrences like 'ff ff fe 09 ...' 34668d0325ccSAditya Srivastava if ($first =~ /\b[0-9a-f]{2,}\b/i) { 34678d0325ccSAditya Srivastava next if (!exists($allow_repeated_words{lc($first)})); 34688d0325ccSAditya Srivastava } 34698d0325ccSAditya Srivastava 3470310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3471310cd06bSJoe Perches "Possible repeated word: '$first'\n" . $herecurr) && 3472310cd06bSJoe Perches $fix) { 3473310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; 3474310cd06bSJoe Perches } 3475310cd06bSJoe Perches } 3476310cd06bSJoe Perches 3477310cd06bSJoe Perches # if it's a repeated word on consecutive lines in a comment block 3478310cd06bSJoe Perches if ($prevline =~ /$;+\s*$/ && 3479310cd06bSJoe Perches $prevrawline =~ /($word_pattern)\s*$/) { 3480310cd06bSJoe Perches my $last_word = $1; 3481310cd06bSJoe Perches if ($rawline =~ /^\+\s*\*\s*$last_word /) { 3482310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3483310cd06bSJoe Perches "Possible repeated word: '$last_word'\n" . $hereprev) && 3484310cd06bSJoe Perches $fix) { 3485310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; 3486310cd06bSJoe Perches } 3487310cd06bSJoe Perches } 3488310cd06bSJoe Perches } 3489310cd06bSJoe Perches } 3490310cd06bSJoe Perches 349130670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 349230670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 349300df344fSAndy Whitcroft 34940a920b5bSAndy Whitcroft#trailing whitespace 34959c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 3496c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3497d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 3498d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 3499d5e616fcSJoe Perches $fix) { 3500194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 3501d5e616fcSJoe Perches } 3502c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 3503c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 35043705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 35053705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 35063705ce5bSJoe Perches $fix) { 3507194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 35083705ce5bSJoe Perches } 35093705ce5bSJoe Perches 3510d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 35110a920b5bSAndy Whitcroft } 35125368df20SAndy Whitcroft 35134783f894SJosh Triplett# Check for FSF mailing addresses. 3514109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 35151bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 35163e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 35173e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 35184783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 35190675a8fbSJean Delvare my $msg_level = \&ERROR; 35200675a8fbSJean Delvare $msg_level = \&CHK if ($file); 35210675a8fbSJean Delvare &{$msg_level}("FSF_MAILING_ADDRESS", 35224783f894SJosh 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) 35234783f894SJosh Triplett } 35244783f894SJosh Triplett 35253354957aSAndi Kleen# check for Kconfig help text having a real description 35269fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 35279fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 35283354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 3529678ae162SUlf Magnusson # 'choice' is usually the last thing on the line (though 3530678ae162SUlf Magnusson # Kconfig supports named choices), so use a word boundary 3531678ae162SUlf Magnusson # (\b) rather than a whitespace character (\s) 3532678ae162SUlf Magnusson $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 3533b8709bceSJoe Perches my $ln = $linenr; 3534b8709bceSJoe Perches my $needs_help = 0; 3535b8709bceSJoe Perches my $has_help = 0; 3536b8709bceSJoe Perches my $help_length = 0; 3537b8709bceSJoe Perches while (defined $lines[$ln]) { 3538b8709bceSJoe Perches my $f = $lines[$ln++]; 35399fe287d7SAndy Whitcroft 35409fe287d7SAndy Whitcroft next if ($f =~ /^-/); 3541b8709bceSJoe Perches last if ($f !~ /^[\+ ]/); # !patch context 3542a1385803SAndy Whitcroft 3543b8709bceSJoe Perches if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 3544b8709bceSJoe Perches $needs_help = 1; 3545b8709bceSJoe Perches next; 3546b8709bceSJoe Perches } 3547b8709bceSJoe Perches if ($f =~ /^\+\s*help\s*$/) { 3548b8709bceSJoe Perches $has_help = 1; 3549b8709bceSJoe Perches next; 3550a1385803SAndy Whitcroft } 3551a1385803SAndy Whitcroft 3552b8709bceSJoe Perches $f =~ s/^.//; # strip patch context [+ ] 3553b8709bceSJoe Perches $f =~ s/#.*//; # strip # directives 3554b8709bceSJoe Perches $f =~ s/^\s+//; # strip leading blanks 3555b8709bceSJoe Perches next if ($f =~ /^$/); # skip blank lines 3556678ae162SUlf Magnusson 3557b8709bceSJoe Perches # At the end of this Kconfig block: 3558678ae162SUlf Magnusson # This only checks context lines in the patch 3559678ae162SUlf Magnusson # and so hopefully shouldn't trigger false 3560678ae162SUlf Magnusson # positives, even though some of these are 3561678ae162SUlf Magnusson # common words in help texts 3562b8709bceSJoe Perches if ($f =~ /^(?:config|menuconfig|choice|endchoice| 3563678ae162SUlf Magnusson if|endif|menu|endmenu|source)\b/x) { 35649fe287d7SAndy Whitcroft last; 35659fe287d7SAndy Whitcroft } 3566b8709bceSJoe Perches $help_length++ if ($has_help); 35673354957aSAndi Kleen } 3568b8709bceSJoe Perches if ($needs_help && 3569b8709bceSJoe Perches $help_length < $min_conf_desc_length) { 3570b8709bceSJoe Perches my $stat_real = get_stat_real($linenr, $ln - 1); 3571000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 3572b8709bceSJoe Perches "please write a help paragraph that fully describes the config symbol\n" . "$here\n$stat_real\n"); 357356193274SVadim Bendebury } 35743354957aSAndi Kleen } 35753354957aSAndi Kleen 35767ccf41a8SJoe Perches# check MAINTAINERS entries 35777ccf41a8SJoe Perches if ($realfile =~ /^MAINTAINERS$/) { 35787ccf41a8SJoe Perches# check MAINTAINERS entries for the right form 35797ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 3580628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3581628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3582628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3583628f91a2SJoe Perches $fix) { 3584628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3585628f91a2SJoe Perches } 3586628f91a2SJoe Perches } 35877ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too 35887ccf41a8SJoe Perches my $preferred_order = 'MRLSWQBCPTFXNK'; 35897ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 35907ccf41a8SJoe Perches $prevrawline =~ /^[\+ ][A-Z]:/) { 35917ccf41a8SJoe Perches $rawline =~ /^\+([A-Z]):\s*(.*)/; 35927ccf41a8SJoe Perches my $cur = $1; 35937ccf41a8SJoe Perches my $curval = $2; 35947ccf41a8SJoe Perches $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; 35957ccf41a8SJoe Perches my $prev = $1; 35967ccf41a8SJoe Perches my $prevval = $2; 35977ccf41a8SJoe Perches my $curindex = index($preferred_order, $cur); 35987ccf41a8SJoe Perches my $previndex = index($preferred_order, $prev); 35997ccf41a8SJoe Perches if ($curindex < 0) { 36007ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 36017ccf41a8SJoe Perches "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); 36027ccf41a8SJoe Perches } else { 36037ccf41a8SJoe Perches if ($previndex >= 0 && $curindex < $previndex) { 36047ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 36057ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); 36067ccf41a8SJoe Perches } elsif ((($prev eq 'F' && $cur eq 'F') || 36077ccf41a8SJoe Perches ($prev eq 'X' && $cur eq 'X')) && 36087ccf41a8SJoe Perches ($prevval cmp $curval) > 0) { 36097ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 36107ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); 36117ccf41a8SJoe Perches } 36127ccf41a8SJoe Perches } 36137ccf41a8SJoe Perches } 36147ccf41a8SJoe Perches } 3615628f91a2SJoe Perches 3616c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3617c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3618c68e5878SArnaud Lacombe my $flag = $1; 3619c68e5878SArnaud Lacombe my $replacement = { 3620c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 3621c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 3622c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 3623c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 3624c68e5878SArnaud Lacombe }; 3625c68e5878SArnaud Lacombe 3626c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 3627c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3628c68e5878SArnaud Lacombe } 3629c68e5878SArnaud Lacombe 3630bff5da43SRob Herring# check for DT compatible documentation 36317dd05b38SFlorian Vaussard if (defined $root && 36327dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 36337dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 36347dd05b38SFlorian Vaussard 3635bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3636bff5da43SRob Herring 3637cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3638852d095dSRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3639cc93319bSFlorian Vaussard 3640bff5da43SRob Herring foreach my $compat (@compats) { 3641bff5da43SRob Herring my $compat2 = $compat; 3642185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3643185d566bSRob Herring my $compat3 = $compat; 3644185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3645185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3646bff5da43SRob Herring if ( $? >> 8 ) { 3647bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3648bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3649bff5da43SRob Herring } 3650bff5da43SRob Herring 36514fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 36524fbf32a6SFlorian Vaussard my $vendor = $1; 3653852d095dSRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3654bff5da43SRob Herring if ( $? >> 8 ) { 3655bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3656cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3657bff5da43SRob Herring } 3658bff5da43SRob Herring } 3659bff5da43SRob Herring } 3660bff5da43SRob Herring 36619f3a8992SRob Herring# check for using SPDX license tag at beginning of files 36629f3a8992SRob Herring if ($realline == $checklicenseline) { 36639f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 36649f3a8992SRob Herring $checklicenseline = 2; 36659f3a8992SRob Herring } elsif ($rawline =~ /^\+/) { 36669f3a8992SRob Herring my $comment = ""; 36679f3a8992SRob Herring if ($realfile =~ /\.(h|s|S)$/) { 36689f3a8992SRob Herring $comment = '/*'; 36699f3a8992SRob Herring } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { 36709f3a8992SRob Herring $comment = '//'; 3671c8df0ab6SLubomir Rintel } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 36729f3a8992SRob Herring $comment = '#'; 36739f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 36749f3a8992SRob Herring $comment = '..'; 36759f3a8992SRob Herring } 36769f3a8992SRob Herring 3677fdf13693SJoe Perches# check SPDX comment style for .[chsS] files 3678fdf13693SJoe Perches if ($realfile =~ /\.[chsS]$/ && 3679fdf13693SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 3680ffbce897SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 3681fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3682fdf13693SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3683fdf13693SJoe Perches } 3684fdf13693SJoe Perches 36859f3a8992SRob Herring if ($comment !~ /^$/ && 3686ffbce897SJoe Perches $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 36879f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 36889f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 36893b6e8ac9SJoe Perches } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 36903b6e8ac9SJoe Perches my $spdx_license = $1; 36913b6e8ac9SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 36923b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 36933b6e8ac9SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 36943b6e8ac9SJoe Perches } 369550c92900SLubomir Rintel if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 369650c92900SLubomir Rintel not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { 369750c92900SLubomir Rintel my $msg_level = \&WARN; 369850c92900SLubomir Rintel $msg_level = \&CHK if ($file); 369950c92900SLubomir Rintel if (&{$msg_level}("SPDX_LICENSE_TAG", 370050c92900SLubomir Rintel 370150c92900SLubomir Rintel "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 370250c92900SLubomir Rintel $fix) { 370350c92900SLubomir Rintel $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 370450c92900SLubomir Rintel } 370550c92900SLubomir Rintel } 37069f3a8992SRob Herring } 37079f3a8992SRob Herring } 37089f3a8992SRob Herring } 37099f3a8992SRob Herring 3710a0154cdbSJoe Perches# check for embedded filenames 3711a0154cdbSJoe Perches if ($rawline =~ /^\+.*\Q$realfile\E/) { 3712a0154cdbSJoe Perches WARN("EMBEDDED_FILENAME", 3713a0154cdbSJoe Perches "It's generally not useful to have the filename in the file\n" . $herecurr); 3714a0154cdbSJoe Perches } 3715a0154cdbSJoe Perches 37165368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 3717d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 37185368df20SAndy Whitcroft 3719a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3720a8da38a9SJoe Perches if ($realline != $checklicenseline && 3721a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3722a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3723a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3724a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3725a8da38a9SJoe Perches } 3726a8da38a9SJoe Perches 372747e0c88bSJoe Perches# line length limit (with some exclusions) 372847e0c88bSJoe Perches# 372947e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 373047e0c88bSJoe Perches# logging functions like pr_info that end in a string 373147e0c88bSJoe Perches# lines with a single string 373247e0c88bSJoe Perches# #defines that are a single string 37332e4bbbc5SAndreas Brauchli# lines with an RFC3986 like URL 373447e0c88bSJoe Perches# 373547e0c88bSJoe Perches# There are 3 different line length message types: 3736ab1ecabfSJean Delvare# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 373747e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 373847e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 373947e0c88bSJoe Perches# 374047e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 374147e0c88bSJoe Perches# 374247e0c88bSJoe Perches 3743b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 374447e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 374547e0c88bSJoe Perches 374647e0c88bSJoe Perches # Check the allowed long line types first 374747e0c88bSJoe Perches 374847e0c88bSJoe Perches # logging functions that end in a string that starts 374947e0c88bSJoe Perches # before $max_line_length 375047e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 375147e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 375247e0c88bSJoe Perches $msg_type = ""; 375347e0c88bSJoe Perches 375447e0c88bSJoe Perches # lines with only strings (w/ possible termination) 375547e0c88bSJoe Perches # #defines with only strings 375647e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 375747e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 375847e0c88bSJoe Perches $msg_type = ""; 375947e0c88bSJoe Perches 3760cc147506SJoe Perches # More special cases 3761cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3762cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3763d560a5f8SJoe Perches $msg_type = ""; 3764d560a5f8SJoe Perches 37652e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 37662e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 37672e4bbbc5SAndreas Brauchli $msg_type = ""; 37682e4bbbc5SAndreas Brauchli 376947e0c88bSJoe Perches # Otherwise set the alternate message types 377047e0c88bSJoe Perches 377147e0c88bSJoe Perches # a comment starts before $max_line_length 377247e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 377347e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 377447e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 377547e0c88bSJoe Perches 377647e0c88bSJoe Perches # a quoted string starts before $max_line_length 377747e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 377847e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 377947e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 378047e0c88bSJoe Perches } 378147e0c88bSJoe Perches 378247e0c88bSJoe Perches if ($msg_type ne "" && 378347e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 3784bdc48fa1SJoe Perches my $msg_level = \&WARN; 3785bdc48fa1SJoe Perches $msg_level = \&CHK if ($file); 3786bdc48fa1SJoe Perches &{$msg_level}($msg_type, 3787bdc48fa1SJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 37880a920b5bSAndy Whitcroft } 378947e0c88bSJoe Perches } 37900a920b5bSAndy Whitcroft 37918905a67cSAndy Whitcroft# check for adding lines without a newline. 37928905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 379347ca69b8STom Rix if (WARN("MISSING_EOF_NEWLINE", 379447ca69b8STom Rix "adding a line without newline at end of file\n" . $herecurr) && 379547ca69b8STom Rix $fix) { 379647ca69b8STom Rix fix_delete_line($fixlinenr+1, "No newline at end of file"); 379747ca69b8STom Rix } 37988905a67cSAndy Whitcroft } 37998905a67cSAndy Whitcroft 3800de93245cSAditya Srivastava# check for .L prefix local symbols in .S files 3801de93245cSAditya Srivastava if ($realfile =~ /\.S$/ && 3802de93245cSAditya Srivastava $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { 3803de93245cSAditya Srivastava WARN("AVOID_L_PREFIX", 3804de93245cSAditya 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); 3805de93245cSAditya Srivastava } 3806de93245cSAditya Srivastava 3807b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3808de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 38090a920b5bSAndy Whitcroft 38100a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 3811713a09deSAntonio Borneo# more than $tabsize must use tabs. 3812c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3813c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3814c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3815d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 38163705ce5bSJoe Perches if (ERROR("CODE_INDENT", 38173705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 38183705ce5bSJoe Perches $fix) { 3819194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 38203705ce5bSJoe Perches } 38210a920b5bSAndy Whitcroft } 38220a920b5bSAndy Whitcroft 382308e44365SAlberto Panizzo# check for space before tabs. 382408e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 382508e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 38263705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 38273705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 38283705ce5bSJoe Perches $fix) { 3829194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3830713a09deSAntonio Borneo s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 3831194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3832c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 38333705ce5bSJoe Perches } 383408e44365SAlberto Panizzo } 383508e44365SAlberto Panizzo 38366a487211SJoe Perches# check for assignments on the start of a line 38376a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 3838da7355abSAditya Srivastava my $operator = $1; 3839da7355abSAditya Srivastava if (CHK("ASSIGNMENT_CONTINUATIONS", 3840da7355abSAditya Srivastava "Assignment operator '$1' should be on the previous line\n" . $hereprev) && 3841da7355abSAditya Srivastava $fix && $prevrawline =~ /^\+/) { 3842da7355abSAditya Srivastava # add assignment operator to the previous line, remove from current line 3843da7355abSAditya Srivastava $fixed[$fixlinenr - 1] .= " $operator"; 3844da7355abSAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 3845da7355abSAditya Srivastava } 38466a487211SJoe Perches } 38476a487211SJoe Perches 3848d1fe9c09SJoe Perches# check for && or || at the start of a line 3849d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 38508e08f076SAditya Srivastava my $operator = $1; 38518e08f076SAditya Srivastava if (CHK("LOGICAL_CONTINUATIONS", 38528e08f076SAditya Srivastava "Logical continuations should be on the previous line\n" . $hereprev) && 38538e08f076SAditya Srivastava $fix && $prevrawline =~ /^\+/) { 38548e08f076SAditya Srivastava # insert logical operator at last non-comment, non-whitepsace char on previous line 38558e08f076SAditya Srivastava $prevline =~ /[\s$;]*$/; 38568e08f076SAditya Srivastava my $line_end = substr($prevrawline, $-[0]); 38578e08f076SAditya Srivastava $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; 38588e08f076SAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 38598e08f076SAditya Srivastava } 3860d1fe9c09SJoe Perches } 3861d1fe9c09SJoe Perches 3862a91e8994SJoe Perches# check indentation starts on a tab stop 38635b57980dSJoe Perches if ($perl_version_ok && 3864bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3865a91e8994SJoe Perches my $indent = length($1); 3866713a09deSAntonio Borneo if ($indent % $tabsize) { 3867a91e8994SJoe Perches if (WARN("TABSTOP", 3868a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3869a91e8994SJoe Perches $fix) { 3870713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 3871a91e8994SJoe Perches } 3872a91e8994SJoe Perches } 3873a91e8994SJoe Perches } 3874a91e8994SJoe Perches 3875d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 38765b57980dSJoe Perches if ($perl_version_ok && 3877fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3878d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3879d1fe9c09SJoe Perches my $oldindent = $1; 3880d1fe9c09SJoe Perches my $rest = $2; 3881d1fe9c09SJoe Perches 3882d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3883d1fe9c09SJoe Perches if ($pos >= 0) { 3884b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3885b34a26f3SJoe Perches my $newindent = $2; 3886d1fe9c09SJoe Perches 3887d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3888713a09deSAntonio Borneo "\t" x ($pos / $tabsize) . 3889713a09deSAntonio Borneo " " x ($pos % $tabsize); 3890d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3891d1fe9c09SJoe Perches 3892d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3893d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 38943705ce5bSJoe Perches 38953705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 38963705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 38973705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3898194f66fcSJoe Perches $fixed[$fixlinenr] =~ 38993705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 39003705ce5bSJoe Perches } 3901d1fe9c09SJoe Perches } 3902d1fe9c09SJoe Perches } 3903d1fe9c09SJoe Perches } 3904d1fe9c09SJoe Perches 39056ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 39066ab3a970SJoe Perches# avoid checking a few false positives: 39076ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 39086ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 39096ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 39106ab3a970SJoe Perches# multiline macros that define functions 39116ab3a970SJoe Perches# known attributes or the __attribute__ keyword 39126ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 39136ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 39143705ce5bSJoe Perches if (CHK("SPACING", 3915f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 39163705ce5bSJoe Perches $fix) { 3917194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3918f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 39193705ce5bSJoe Perches } 3920aad4f614SJoe Perches } 3921aad4f614SJoe Perches 392286406b1cSJoe Perches# Block comment styles 392386406b1cSJoe Perches# Networking with an initial /* 392405880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3925fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 392685ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 3927c70735c2SŁukasz Stelmach $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier 392805880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 392905880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 393005880600SJoe Perches } 393105880600SJoe Perches 393286406b1cSJoe Perches# Block comments use * on subsequent lines 393386406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 393486406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3935a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 393661135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3937a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 393886406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 393986406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3940a605e32eSJoe Perches } 3941a605e32eSJoe Perches 394286406b1cSJoe Perches# Block comments use */ on trailing lines 394386406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3944c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3945c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3946c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 394786406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 394886406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 394905880600SJoe Perches } 395005880600SJoe Perches 395108eb9b80SJoe Perches# Block comment * alignment 395208eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3953af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3954af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3955af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 395608eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3957af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3958af207524SJoe Perches my $oldindent; 395908eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3960af207524SJoe Perches if (defined($1)) { 3961af207524SJoe Perches $oldindent = expand_tabs($1); 3962af207524SJoe Perches } else { 3963af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3964af207524SJoe Perches $oldindent = expand_tabs($1); 3965af207524SJoe Perches } 396608eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 396708eb9b80SJoe Perches my $newindent = $1; 396808eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3969af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 397008eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 397108eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 397208eb9b80SJoe Perches } 397308eb9b80SJoe Perches } 397408eb9b80SJoe Perches 39757f619191SJoe Perches# check for missing blank lines after struct/union declarations 39767f619191SJoe Perches# with exceptions for various attributes and macros 39777f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 39787f619191SJoe Perches $line =~ /^\+/ && 39797f619191SJoe Perches !($line =~ /^\+\s*$/ || 398005dc40e6SJoe Perches $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param)/ || 39817f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 39827f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 39837f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 39847f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 39857f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 39860bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 39877f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3988d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3989d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3990d752fcc8SJoe Perches $fix) { 3991f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3992d752fcc8SJoe Perches } 39937f619191SJoe Perches } 39947f619191SJoe Perches 3995365dd4eaSJoe Perches# check for multiple consecutive blank lines 3996365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3997365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3998365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3999d752fcc8SJoe Perches if (CHK("LINE_SPACING", 4000d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 4001d752fcc8SJoe Perches $fix) { 4002f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 4003d752fcc8SJoe Perches } 4004d752fcc8SJoe Perches 4005365dd4eaSJoe Perches $last_blank_line = $linenr; 4006365dd4eaSJoe Perches } 4007365dd4eaSJoe Perches 40083b617e3bSJoe Perches# check for missing blank lines after declarations 4009b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line) 4010b5e8736aSJoe Perches if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) { 4011b5e8736aSJoe Perches # use temporaries 4012b5e8736aSJoe Perches my $sl = $sline; 4013b5e8736aSJoe Perches my $pl = $prevline; 4014b5e8736aSJoe Perches # remove $Attribute/$Sparse uses to simplify comparisons 4015b5e8736aSJoe Perches $sl =~ s/\b(?:$Attribute|$Sparse)\b//g; 4016b5e8736aSJoe Perches $pl =~ s/\b(?:$Attribute|$Sparse)\b//g; 4017b5e8736aSJoe Perches if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 40185a4e1fd3SJoe Perches # function pointer declarations 4019b5e8736aSJoe Perches $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 40203f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 4021b5e8736aSJoe Perches $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 40223f7bac03SJoe Perches # known declaration macros 4023b5e8736aSJoe Perches $pl =~ /^\+\s+$declaration_macros/) && 40243f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 4025b5e8736aSJoe Perches !($pl =~ /^\+\s+$c90_Keywords\b/ || 40263f7bac03SJoe Perches # other possible extensions of declaration lines 4027b5e8736aSJoe Perches $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 40283f7bac03SJoe Perches # not starting a section or a macro "\" extended line 4029b5e8736aSJoe Perches $pl =~ /(?:\{\s*|\\)$/) && 40303f7bac03SJoe Perches # looks like a declaration 4031b5e8736aSJoe Perches !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 40325a4e1fd3SJoe Perches # function pointer declarations 4033b5e8736aSJoe Perches $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 40343f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 4035b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 40363f7bac03SJoe Perches # known declaration macros 4037b5e8736aSJoe Perches $sl =~ /^\+\s+$declaration_macros/ || 40383f7bac03SJoe Perches # start of struct or union or enum 4039b5e8736aSJoe Perches $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 40403f7bac03SJoe Perches # start or end of block or continuation of declaration 4041b5e8736aSJoe Perches $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 40423f7bac03SJoe Perches # bitfield continuation 4043b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 40443f7bac03SJoe Perches # other possible extensions of declaration lines 4045b5e8736aSJoe Perches $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) { 4046d752fcc8SJoe Perches if (WARN("LINE_SPACING", 4047d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 4048d752fcc8SJoe Perches $fix) { 4049f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 4050d752fcc8SJoe Perches } 40513b617e3bSJoe Perches } 4052b5e8736aSJoe Perches } 40533b617e3bSJoe Perches 40545f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 40556b4c5bebSAndy Whitcroft# Exceptions: 40566b4c5bebSAndy Whitcroft# 1) within comments 40576b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 40586b4c5bebSAndy Whitcroft# 3) hanging labels 40593705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 40605f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 40613705ce5bSJoe Perches if (WARN("LEADING_SPACE", 40623705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 40633705ce5bSJoe Perches $fix) { 4064194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 40653705ce5bSJoe Perches } 40665f7ddae6SRaffaele Recalcati } 40675f7ddae6SRaffaele Recalcati 4068b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 4069b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 4070b9ea10d6SAndy Whitcroft 40715751a24eSJoe Perches# check for unusual line ending [ or ( 40725751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 40735751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 40745751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 40755751a24eSJoe Perches } 40765751a24eSJoe Perches 40774dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 40784dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 40794dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 40804dbed76fSJoe Perches $context_function = $1; 40814dbed76fSJoe Perches } 40824dbed76fSJoe Perches 40834dbed76fSJoe Perches# check if this appears to be the end of function declaration 40844dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 40854dbed76fSJoe Perches undef $context_function; 40864dbed76fSJoe Perches } 40874dbed76fSJoe Perches 4088032a4c0fSJoe Perches# check indentation of any line with a bare else 4089840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 4090032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 4091032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 4092032a4c0fSJoe Perches my $tabs = length($1) + 1; 4093840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 4094840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 4095840080a0SJoe Perches defined $lines[$linenr] && 4096840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 4097032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 4098032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 4099032a4c0fSJoe Perches } 4100032a4c0fSJoe Perches } 4101032a4c0fSJoe Perches 4102c00df19aSJoe Perches# check indentation of a line with a break; 4103dc58bc55SJoe Perches# if the previous line is a goto, return or break 4104dc58bc55SJoe Perches# and is indented the same # of tabs 4105c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 4106c00df19aSJoe Perches my $tabs = $1; 4107dc58bc55SJoe Perches if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { 4108dc58bc55SJoe Perches if (WARN("UNNECESSARY_BREAK", 4109dc58bc55SJoe Perches "break is not useful after a $1\n" . $hereprev) && 4110dc58bc55SJoe Perches $fix) { 4111dc58bc55SJoe Perches fix_delete_line($fixlinenr, $rawline); 4112dc58bc55SJoe Perches } 4113c00df19aSJoe Perches } 4114c00df19aSJoe Perches } 4115c00df19aSJoe Perches 4116c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 4117cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 4118000d1cc1SJoe Perches WARN("CVS_KEYWORD", 4119000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 4120c2fdda0dSAndy Whitcroft } 412122f2a2efSAndy Whitcroft 412256e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 412356e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 412456e77d70SJoe Perches WARN("HOTPLUG_SECTION", 412556e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 412656e77d70SJoe Perches } 412756e77d70SJoe Perches 41289c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 41292b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 41302b474a1aSAndy Whitcroft $realline_next); 41313e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 4132ca819864SJoe Perches if ($linenr > $suppress_statement && 41331b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 4134170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 4135f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4136171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 4137171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 4138171ae1a4SAndy Whitcroft 41393e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 41403e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 41413e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 41423e469cdcSAndy Whitcroft # until we hit end of it. 41433e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 41443e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 41453e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 41463e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 41473e469cdcSAndy Whitcroft } 4148f74bd194SAndy Whitcroft 41492b474a1aSAndy Whitcroft # Find the real next line. 41502b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 41512b474a1aSAndy Whitcroft if (defined $realline_next && 41522b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 41532b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 41542b474a1aSAndy Whitcroft $realline_next++; 41552b474a1aSAndy Whitcroft } 41562b474a1aSAndy Whitcroft 4157171ae1a4SAndy Whitcroft my $s = $stat; 4158171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 4159cf655043SAndy Whitcroft 4160c2fdda0dSAndy Whitcroft # Ignore goto labels. 4161171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 4162c2fdda0dSAndy Whitcroft 4163c2fdda0dSAndy Whitcroft # Ignore functions being called 4164171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 4165c2fdda0dSAndy Whitcroft 4166463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 4167463f2864SAndy Whitcroft 4168c45dcabdSAndy Whitcroft # declarations always start with types 4169d2506586SAndy 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) { 4170c45dcabdSAndy Whitcroft my $type = $1; 4171c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 4172c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 4173c45dcabdSAndy Whitcroft 41746c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 4175a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 4176c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 4177c2fdda0dSAndy Whitcroft } 41788905a67cSAndy Whitcroft 41796c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 418065863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 4181c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 41829c0ca6f9SAndy Whitcroft } 41838905a67cSAndy Whitcroft 41848905a67cSAndy Whitcroft # Check for any sort of function declaration. 41858905a67cSAndy Whitcroft # int foo(something bar, other baz); 41868905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 4187171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 41888905a67cSAndy Whitcroft my ($name_len) = length($1); 41898905a67cSAndy Whitcroft 4190cf655043SAndy Whitcroft my $ctx = $s; 4191773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 41928905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 4193cf655043SAndy Whitcroft 41948905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 4195c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 41968905a67cSAndy Whitcroft 4197c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 41988905a67cSAndy Whitcroft } 41998905a67cSAndy Whitcroft } 42008905a67cSAndy Whitcroft } 42018905a67cSAndy Whitcroft 42029c0ca6f9SAndy Whitcroft } 42039c0ca6f9SAndy Whitcroft 420400df344fSAndy Whitcroft# 420500df344fSAndy Whitcroft# Checks which may be anchored in the context. 420600df344fSAndy Whitcroft# 420700df344fSAndy Whitcroft 420800df344fSAndy Whitcroft# Check for switch () and associated case and default 420900df344fSAndy Whitcroft# statements should be at the same indent. 421000df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 421100df344fSAndy Whitcroft my $err = ''; 421200df344fSAndy Whitcroft my $sep = ''; 421300df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 421400df344fSAndy Whitcroft shift(@ctx); 421500df344fSAndy Whitcroft for my $ctx (@ctx) { 421600df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 421700df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 421800df344fSAndy Whitcroft $indent != $cindent) { 421900df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 422000df344fSAndy Whitcroft $sep = ''; 422100df344fSAndy Whitcroft } else { 422200df344fSAndy Whitcroft $sep = "[...]\n"; 422300df344fSAndy Whitcroft } 422400df344fSAndy Whitcroft } 422500df344fSAndy Whitcroft if ($err ne '') { 4226000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 4227000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 4228de7d4f0eSAndy Whitcroft } 4229de7d4f0eSAndy Whitcroft } 4230de7d4f0eSAndy Whitcroft 4231de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 4232de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 42330fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 4234773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 4235773647a0SAndy Whitcroft 42369c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 42378eef05ddSJoe Perches 42388eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 42398eef05ddSJoe Perches WARN("DEEP_INDENTATION", 42408eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 42418eef05ddSJoe Perches } 42428eef05ddSJoe Perches 4243de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 4244de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 4245de7d4f0eSAndy Whitcroft 4246548596d5SAndy Whitcroft my $ctx_ln = $linenr; 4247548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 4248de7d4f0eSAndy Whitcroft 4249548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 4250548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 4251548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 4252548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 4253548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 4254773647a0SAndy Whitcroft $ctx_ln++; 4255773647a0SAndy Whitcroft } 4256548596d5SAndy Whitcroft 425753210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 425853210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 4259773647a0SAndy Whitcroft 4260773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 4261000d1cc1SJoe Perches ERROR("OPEN_BRACE", 4262000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 426301464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 426400df344fSAndy Whitcroft } 4265773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 4266773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 4267773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 4268773647a0SAndy Whitcroft { 42699c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 42709c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 4271000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 4272000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 427301464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 42749c0ca6f9SAndy Whitcroft } 42759c0ca6f9SAndy Whitcroft } 427600df344fSAndy Whitcroft } 427700df344fSAndy Whitcroft 42784d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 4279f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 42803e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 42813e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 42823e469cdcSAndy Whitcroft if (!defined $stat); 42834d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 42844d001e4dSAndy Whitcroft 42854d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 42864d001e4dSAndy Whitcroft 42879f5af480SJoe Perches # remove inline comments 42889f5af480SJoe Perches $s =~ s/$;/ /g; 42899f5af480SJoe Perches $c =~ s/$;/ /g; 42904d001e4dSAndy Whitcroft 42914d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 42926f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 42936f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 42944d001e4dSAndy Whitcroft 42959f5af480SJoe Perches # Make sure we remove the line prefixes as we have 42969f5af480SJoe Perches # none on the first line, and are going to readd them 42979f5af480SJoe Perches # where necessary. 42989f5af480SJoe Perches $s =~ s/\n./\n/gs; 42999f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 43009f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 43019f5af480SJoe Perches } 43029f5af480SJoe Perches 43034d001e4dSAndy Whitcroft # We want to check the first line inside the block 43044d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 43054d001e4dSAndy Whitcroft # 1) any blank line termination 43064d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 43074d001e4dSAndy Whitcroft # 3) any do (...) { 43084d001e4dSAndy Whitcroft my $continuation = 0; 43094d001e4dSAndy Whitcroft my $check = 0; 43104d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 43114d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 43124d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 43134d001e4dSAndy Whitcroft $continuation = 1; 43144d001e4dSAndy Whitcroft } 43159bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 43164d001e4dSAndy Whitcroft $check = 1; 43174d001e4dSAndy Whitcroft $cond_lines++; 43184d001e4dSAndy Whitcroft } 43194d001e4dSAndy Whitcroft 43204d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 43214d001e4dSAndy Whitcroft # preprocessor statement. 43224d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 43234d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 43244d001e4dSAndy Whitcroft $check = 0; 43254d001e4dSAndy Whitcroft } 43264d001e4dSAndy Whitcroft 43279bd49efeSAndy Whitcroft my $cond_ptr = -1; 4328740504c6SAndy Whitcroft $continuation = 0; 43299bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 43309bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 43314d001e4dSAndy Whitcroft 4332f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 4333f16fa28fSAndy Whitcroft # is not linear. 4334f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 4335f16fa28fSAndy Whitcroft $check = 0; 4336f16fa28fSAndy Whitcroft } 4337f16fa28fSAndy Whitcroft 43389bd49efeSAndy Whitcroft # Ignore: 43399bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 43409bd49efeSAndy Whitcroft # 2) preprocessor lines, and 43419bd49efeSAndy Whitcroft # 3) labels. 4342740504c6SAndy Whitcroft if ($continuation || 4343740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 43449bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 43459bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 4346740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 434730dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 43489bd49efeSAndy Whitcroft $cond_lines++; 43499bd49efeSAndy Whitcroft } 43504d001e4dSAndy Whitcroft } 435130dad6ebSAndy Whitcroft } 43524d001e4dSAndy Whitcroft 43534d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 43544d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 43554d001e4dSAndy Whitcroft 43564d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 43574d001e4dSAndy Whitcroft # this is not this patch's fault. 43584d001e4dSAndy Whitcroft if (!defined($stat_real) || 43594d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 43604d001e4dSAndy Whitcroft $check = 0; 43614d001e4dSAndy Whitcroft } 43624d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 43634d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 43644d001e4dSAndy Whitcroft } 43654d001e4dSAndy Whitcroft 43669bd49efeSAndy 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"; 43674d001e4dSAndy Whitcroft 43689f5af480SJoe Perches if ($check && $s ne '' && 4369713a09deSAntonio Borneo (($sindent % $tabsize) != 0 || 43709f5af480SJoe Perches ($sindent < $indent) || 4371f6950a73SJoe Perches ($sindent == $indent && 4372f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 4373713a09deSAntonio Borneo ($sindent > $indent + $tabsize))) { 4374000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 4375000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 43764d001e4dSAndy Whitcroft } 43774d001e4dSAndy Whitcroft } 43784d001e4dSAndy Whitcroft 43796c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 43806c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 43811f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 43821f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 43836c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 4384c2fdda0dSAndy Whitcroft if ($dbg_values) { 4385c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 4386cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 4387cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 43881f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 4389c2fdda0dSAndy Whitcroft } 43906c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 43916c72ffaaSAndy Whitcroft 439200df344fSAndy Whitcroft#ignore lines not being added 43933705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 439400df344fSAndy Whitcroft 439599ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings 439699ca38c2SJoe Perches# e.g.: int foo = foo, *bar = NULL; 439799ca38c2SJoe Perches# struct foo bar = *(&(bar)); 439899ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { 439999ca38c2SJoe Perches my $var = $1; 440099ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { 440199ca38c2SJoe Perches WARN("SELF_ASSIGNMENT", 440299ca38c2SJoe Perches "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); 440399ca38c2SJoe Perches } 440499ca38c2SJoe Perches } 440599ca38c2SJoe Perches 440611ca40a0SJoe Perches# check for dereferences that span multiple lines 440711ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 440811ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 440911ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 441011ca40a0SJoe Perches my $ref = $1; 441111ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 441211ca40a0SJoe Perches $ref .= $1; 441311ca40a0SJoe Perches $ref =~ s/\s//g; 441411ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 441511ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 441611ca40a0SJoe Perches } 441711ca40a0SJoe Perches 4418a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 4419c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 4420a1ce18e4SJoe Perches my $type = $1; 4421a1ce18e4SJoe Perches my $var = $2; 4422207a8e84SJoe Perches $var = "" if (!defined $var); 4423207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 4424a1ce18e4SJoe Perches my $sign = $1; 4425a1ce18e4SJoe Perches my $pointer = $2; 4426a1ce18e4SJoe Perches 4427a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 4428a1ce18e4SJoe Perches 4429a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 4430a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 4431a1ce18e4SJoe Perches $fix) { 4432a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 4433207a8e84SJoe Perches my $comp_pointer = $pointer; 4434207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 4435207a8e84SJoe Perches $decl .= $comp_pointer; 4436207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 4437207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 4438a1ce18e4SJoe Perches } 4439a1ce18e4SJoe Perches } 4440a1ce18e4SJoe Perches } 4441a1ce18e4SJoe Perches 4442653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 44437429c690SAndy Whitcroft if ($dbg_type) { 44447429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 4445000d1cc1SJoe Perches ERROR("TEST_TYPE", 4446000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 44477429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 4448000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 4449000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 44507429c690SAndy Whitcroft } 4451653d4876SAndy Whitcroft next; 4452653d4876SAndy Whitcroft } 4453a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 4454a1ef277eSAndy Whitcroft if ($dbg_attr) { 44559360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 4456000d1cc1SJoe Perches ERROR("TEST_ATTR", 4457000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 44589360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 4459000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 4460000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 4461a1ef277eSAndy Whitcroft } 4462a1ef277eSAndy Whitcroft next; 4463a1ef277eSAndy Whitcroft } 4464653d4876SAndy Whitcroft 4465f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 446699423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 446799423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 4468d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 4469d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 4470f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 4471f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 4472f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 4473d752fcc8SJoe Perches my $fixedline = $prevrawline; 4474d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 4475f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4476d752fcc8SJoe Perches $fixedline = $line; 44778d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 4478f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4479d752fcc8SJoe Perches } 4480f0a594c1SAndy Whitcroft } 4481f0a594c1SAndy Whitcroft 448200df344fSAndy Whitcroft# 448300df344fSAndy Whitcroft# Checks which are anchored on the added line. 448400df344fSAndy Whitcroft# 448500df344fSAndy Whitcroft 4486653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 4487c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 4488653d4876SAndy Whitcroft my $path = $1; 4489653d4876SAndy Whitcroft if ($path =~ m{//}) { 4490000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 4491495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 4492495e9d84SJoe Perches } 4493495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 4494495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 4495495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 4496653d4876SAndy Whitcroft } 4497653d4876SAndy Whitcroft } 4498653d4876SAndy Whitcroft 449900df344fSAndy Whitcroft# no C99 // comments 450000df344fSAndy Whitcroft if ($line =~ m{//}) { 45013705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 45023705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 45033705ce5bSJoe Perches $fix) { 4504194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 45053705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 45063705ce5bSJoe Perches my $comment = trim($1); 4507194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 45083705ce5bSJoe Perches } 45093705ce5bSJoe Perches } 451000df344fSAndy Whitcroft } 451100df344fSAndy Whitcroft # Remove C99 comments. 45120a920b5bSAndy Whitcroft $line =~ s@//.*@@; 45136c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 45140a920b5bSAndy Whitcroft 45152b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 45162b474a1aSAndy Whitcroft# the whole statement. 45172b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 45182b474a1aSAndy Whitcroft if (defined $realline_next && 45192b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 45202b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 452136794822SChristoph Hellwig ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 45223cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 45233cbf62dfSAndy Whitcroft # a prefix: 45243cbf62dfSAndy Whitcroft # XXX(foo); 45253cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 4526653d4876SAndy Whitcroft my $name = $1; 452770a11659SJoe Perches $name =~ s/^\s*($Ident).*/$1/; 452887a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 45293cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 45303cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 45313cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 45323cbf62dfSAndy Whitcroft 45333cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 45342b474a1aSAndy Whitcroft \n.}\s*$| 453548012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 453648012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 453748012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 45382b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 45392b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 454048012058SAndy Whitcroft )/x) { 45412b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 45422b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 45432b474a1aSAndy Whitcroft } else { 45442b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 45450a920b5bSAndy Whitcroft } 45460a920b5bSAndy Whitcroft } 45472b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 45482b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 454936794822SChristoph Hellwig ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 45502b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 45512b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 45522b474a1aSAndy Whitcroft } 45532b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 45542b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 4555000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 4556000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 45572b474a1aSAndy Whitcroft } 45580a920b5bSAndy Whitcroft 45595150bda4SJoe Eloff# check for global initialisers. 45605b8f82e1SSong Liu if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ && 45615b8f82e1SSong Liu !exclude_global_initialisers($realfile)) { 4562d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 45636d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 4564d5e616fcSJoe Perches $fix) { 45656d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 4566d5e616fcSJoe Perches } 4567f0a594c1SAndy Whitcroft } 45680a920b5bSAndy Whitcroft# check for static initialisers. 45696d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 4570d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 45716d32f7a3SJoe Perches "do not initialise statics to $1\n" . 4572d5e616fcSJoe Perches $herecurr) && 4573d5e616fcSJoe Perches $fix) { 45746d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 4575d5e616fcSJoe Perches } 45760a920b5bSAndy Whitcroft } 45770a920b5bSAndy Whitcroft 45781813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 45791813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 45801813087dSJoe Perches my $tmp = trim($1); 45811813087dSJoe Perches WARN("MISORDERED_TYPE", 45821813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 45831813087dSJoe Perches } 45841813087dSJoe Perches 4585809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4586809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4587809e082eSJoe Perches my $type = trim($1); 4588809e082eSJoe Perches next if ($type !~ /\bint\b/); 4589809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 4590809e082eSJoe Perches my $new_type = $type; 4591809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 4592809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 4593809e082eSJoe Perches $new_type =~ s/^const\s+//; 4594809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 4595809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 4596809e082eSJoe Perches $new_type =~ s/\s+/ /g; 4597809e082eSJoe Perches $new_type = trim($new_type); 4598809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 4599809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4600809e082eSJoe Perches $fix) { 4601809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4602809e082eSJoe Perches } 4603809e082eSJoe Perches } 4604809e082eSJoe Perches 4605cb710ecaSJoe Perches# check for static const char * arrays. 4606cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4607000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4608000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 4609cb710ecaSJoe Perches $herecurr); 4610cb710ecaSJoe Perches } 4611cb710ecaSJoe Perches 461277b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 461377b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 461477b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 461577b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 461677b8c0a8SJoe Perches $fix) { 461777b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 461877b8c0a8SJoe Perches } 461977b8c0a8SJoe Perches } 462077b8c0a8SJoe Perches 4621cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 4622cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4623000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4624000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 4625cb710ecaSJoe Perches $herecurr); 4626cb710ecaSJoe Perches } 4627cb710ecaSJoe Perches 4628ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 4629ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 4630ab7e23f3SJoe Perches my $found = $1; 4631ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 4632ab7e23f3SJoe Perches WARN("CONST_CONST", 4633ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 4634ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4635ab7e23f3SJoe Perches WARN("CONST_CONST", 4636ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4637ab7e23f3SJoe Perches } 4638ab7e23f3SJoe Perches } 4639ab7e23f3SJoe Perches 464073169765SJoe Perches# check for const static or static <non ptr type> const declarations 464173169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const' 464273169765SJoe Perches if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || 464373169765SJoe Perches $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { 464473169765SJoe Perches if (WARN("STATIC_CONST", 464573169765SJoe Perches "Move const after static - use 'static const $1'\n" . $herecurr) && 464673169765SJoe Perches $fix) { 464773169765SJoe Perches $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; 464873169765SJoe Perches $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; 464973169765SJoe Perches } 465073169765SJoe Perches } 465173169765SJoe Perches 46529b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 46539b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 46549b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 46559b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 46569b0fa60dSJoe Perches $herecurr); 46579b0fa60dSJoe Perches } 46589b0fa60dSJoe Perches 4659b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 4660b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 4661b598b670SJoe Perches my $array = $1; 4662b598b670SJoe 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*\))@) { 4663b598b670SJoe Perches my $array_div = $1; 4664b598b670SJoe Perches if (WARN("ARRAY_SIZE", 4665b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 4666b598b670SJoe Perches $fix) { 4667b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4668b598b670SJoe Perches } 4669b598b670SJoe Perches } 4670b598b670SJoe Perches } 4671b598b670SJoe Perches 4672b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 467316b7f3c8SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4674b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4675b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4676b36190c5SJoe Perches $fix) { 4677194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4678b36190c5SJoe Perches } 4679b36190c5SJoe Perches } 4680b36190c5SJoe Perches 4681653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4682653d4876SAndy Whitcroft# make sense. 4683653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 46848054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4685c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 46868ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 468746d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4688000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4689000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 46900a920b5bSAndy Whitcroft } 46910a920b5bSAndy Whitcroft 46920a920b5bSAndy Whitcroft# * goes on variable not on type 469365863862SAndy Whitcroft # (char*[ const]) 4694bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4695bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 46963705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4697d8aaf121SAndy Whitcroft 469865863862SAndy Whitcroft # Should start with a space. 469965863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 470065863862SAndy Whitcroft # Should not end with a space. 470165863862SAndy Whitcroft $to =~ s/\s+$//; 470265863862SAndy Whitcroft # '*'s should not have spaces between. 4703f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 470465863862SAndy Whitcroft } 4705d8aaf121SAndy Whitcroft 47063705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 470765863862SAndy Whitcroft if ($from ne $to) { 47083705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 47093705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 47103705ce5bSJoe Perches $fix) { 47113705ce5bSJoe Perches my $sub_from = $ident; 47123705ce5bSJoe Perches my $sub_to = $ident; 47133705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4714194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47153705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 47163705ce5bSJoe Perches } 471765863862SAndy Whitcroft } 4718bfcb2cc7SAndy Whitcroft } 4719bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4720bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 47213705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4722d8aaf121SAndy Whitcroft 472365863862SAndy Whitcroft # Should start with a space. 472465863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 472565863862SAndy Whitcroft # Should not end with a space. 472665863862SAndy Whitcroft $to =~ s/\s+$//; 472765863862SAndy Whitcroft # '*'s should not have spaces between. 4728f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 472965863862SAndy Whitcroft } 473065863862SAndy Whitcroft # Modifiers should have spaces. 473165863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 473265863862SAndy Whitcroft 47333705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4734667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 47353705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 47363705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 47373705ce5bSJoe Perches $fix) { 47383705ce5bSJoe Perches 47393705ce5bSJoe Perches my $sub_from = $match; 47403705ce5bSJoe Perches my $sub_to = $match; 47413705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4742194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47433705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 47443705ce5bSJoe Perches } 474565863862SAndy Whitcroft } 47460a920b5bSAndy Whitcroft } 47470a920b5bSAndy Whitcroft 47489d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 47499d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 47500675a8fbSJean Delvare my $msg_level = \&WARN; 47510675a8fbSJean Delvare $msg_level = \&CHK if ($file); 47520675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 47539d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 47549d3e3c70SJoe Perches } 47550a920b5bSAndy Whitcroft 47569d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 47578905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4758000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4759000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 47608905a67cSAndy Whitcroft } 47618905a67cSAndy Whitcroft 476217441227SJoe Perches# check for uses of printk_ratelimit 476317441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4764000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4765000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 476617441227SJoe Perches } 476717441227SJoe Perches 4768eeef5733SJoe Perches# printk should use KERN_* levels 4769eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4770000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4771eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 477200df344fSAndy Whitcroft } 47730a920b5bSAndy Whitcroft 4774f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL> 4775f5eea3b0SJoe Perches if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { 4776f5eea3b0SJoe Perches my $printk = $1; 4777f5eea3b0SJoe Perches my $modifier = $2; 4778f5eea3b0SJoe Perches my $orig = $3; 4779f5eea3b0SJoe Perches $modifier = "" if (!defined($modifier)); 4780243f3803SJoe Perches my $level = lc($orig); 4781243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 47828f26b837SJoe Perches my $level2 = $level; 47838f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4784f5eea3b0SJoe Perches $level .= $modifier; 4785f5eea3b0SJoe Perches $level2 .= $modifier; 4786243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4787f5eea3b0SJoe Perches "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); 4788243f3803SJoe Perches } 4789243f3803SJoe Perches 4790f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL> 4791dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4792dc139313SJoe Perches my $orig = $1; 4793dc139313SJoe Perches my $level = lc($orig); 4794dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4795dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4796dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4797dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4798dc139313SJoe Perches } 4799dc139313SJoe Perches 48008020b253SNicolas Boichat# trace_printk should not be used in production code. 48018020b253SNicolas Boichat if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { 48028020b253SNicolas Boichat WARN("TRACE_PRINTK", 48038020b253SNicolas Boichat "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); 48048020b253SNicolas Boichat } 48058020b253SNicolas Boichat 480691c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 480791c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 480891c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 480991c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 481091c9afafSAndy Lutomirski WARN("ENOSYS", 481191c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 481291c9afafSAndy Lutomirski } 481391c9afafSAndy Lutomirski 48146b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches. 48156b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. 48166b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected. 48176b9ea5ffSJakub Kicinski if (!$file && $line =~ /\bENOTSUPP\b/) { 48186b9ea5ffSJakub Kicinski if (WARN("ENOTSUPP", 48196b9ea5ffSJakub Kicinski "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && 48206b9ea5ffSJakub Kicinski $fix) { 48216b9ea5ffSJakub Kicinski $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; 48226b9ea5ffSJakub Kicinski } 48236b9ea5ffSJakub Kicinski } 48246b9ea5ffSJakub Kicinski 4825653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4826653d4876SAndy Whitcroft# or if closed on same line 48275b57980dSJoe Perches if ($perl_version_ok && 48282d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 48292d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 48302d453e3bSJoe Perches $sline !~ /}/) { 48318d182478SJoe Perches if (ERROR("OPEN_BRACE", 48322d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 48338d182478SJoe Perches $fix) { 48348d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 48358d182478SJoe Perches my $fixed_line = $rawline; 483603f49351SDwaipayan Ray $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; 48378d182478SJoe Perches my $line1 = $1; 48388d182478SJoe Perches my $line2 = $2; 48398d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 48408d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 48418d182478SJoe Perches if ($line2 !~ /^\s*$/) { 48428d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 48438d182478SJoe Perches } 48448d182478SJoe Perches } 48450a920b5bSAndy Whitcroft } 4846653d4876SAndy Whitcroft 48478905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 48488905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 48498905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 48508d182478SJoe Perches if (ERROR("OPEN_BRACE", 48518d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 48528d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 48538d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 48548d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 48558d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 48568d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 48578d182478SJoe Perches $fixedline = $rawline; 48588d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 48598d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 48608d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 48618d182478SJoe Perches } 48628d182478SJoe Perches } 48638905a67cSAndy Whitcroft } 48648905a67cSAndy Whitcroft 48650c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 48663705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 48673705ce5bSJoe Perches if (WARN("SPACING", 48683705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 48693705ce5bSJoe Perches $fix) { 4870194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48713705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 48723705ce5bSJoe Perches } 48730c73b4ebSAndy Whitcroft } 48740c73b4ebSAndy Whitcroft 487531070b5dSJoe Perches# Function pointer declarations 487631070b5dSJoe Perches# check spacing between type, funcptr, and args 487731070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 487891f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 487931070b5dSJoe Perches my $declare = $1; 488031070b5dSJoe Perches my $pre_pointer_space = $2; 488131070b5dSJoe Perches my $post_pointer_space = $3; 488231070b5dSJoe Perches my $funcname = $4; 488331070b5dSJoe Perches my $post_funcname_space = $5; 488431070b5dSJoe Perches my $pre_args_space = $6; 488531070b5dSJoe Perches 488691f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 488791f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 488891f72e9cSJoe Perches# don't need a space so don't warn for those. 488991f72e9cSJoe Perches my $post_declare_space = ""; 489091f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 489191f72e9cSJoe Perches $post_declare_space = $1; 489291f72e9cSJoe Perches $declare = rtrim($declare); 489391f72e9cSJoe Perches } 489491f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 489531070b5dSJoe Perches WARN("SPACING", 489631070b5dSJoe Perches "missing space after return type\n" . $herecurr); 489791f72e9cSJoe Perches $post_declare_space = " "; 489831070b5dSJoe Perches } 489931070b5dSJoe Perches 490031070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 490191f72e9cSJoe Perches# This test is not currently implemented because these declarations are 490291f72e9cSJoe Perches# equivalent to 490391f72e9cSJoe Perches# int foo(int bar, ...) 490491f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 490591f72e9cSJoe Perches# 490691f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 490791f72e9cSJoe Perches# WARN("SPACING", 490891f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 490991f72e9cSJoe Perches# } 491031070b5dSJoe Perches 491131070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 491231070b5dSJoe Perches if (defined $pre_pointer_space && 491331070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 491431070b5dSJoe Perches WARN("SPACING", 491531070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 491631070b5dSJoe Perches } 491731070b5dSJoe Perches 491831070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 491931070b5dSJoe Perches if (defined $post_pointer_space && 492031070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 492131070b5dSJoe Perches WARN("SPACING", 492231070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 492331070b5dSJoe Perches } 492431070b5dSJoe Perches 492531070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 492631070b5dSJoe Perches if (defined $post_funcname_space && 492731070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 492831070b5dSJoe Perches WARN("SPACING", 492931070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 493031070b5dSJoe Perches } 493131070b5dSJoe Perches 493231070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 493331070b5dSJoe Perches if (defined $pre_args_space && 493431070b5dSJoe Perches $pre_args_space =~ /^\s/) { 493531070b5dSJoe Perches WARN("SPACING", 493631070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 493731070b5dSJoe Perches } 493831070b5dSJoe Perches 493931070b5dSJoe Perches if (show_type("SPACING") && $fix) { 4940194f66fcSJoe Perches $fixed[$fixlinenr] =~ 494191f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 494231070b5dSJoe Perches } 494331070b5dSJoe Perches } 494431070b5dSJoe Perches 49458d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 49468d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 4947fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4948fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 49498d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 49508d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 49518d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 4952fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 495338dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 49543705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 49553705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 49563705ce5bSJoe Perches $fix) { 4957194f66fcSJoe Perches $fixed[$fixlinenr] =~ 49583705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 49593705ce5bSJoe Perches } 49608d31cfceSAndy Whitcroft } 49618d31cfceSAndy Whitcroft } 49628d31cfceSAndy Whitcroft 4963f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 49646c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4965c2fdda0dSAndy Whitcroft my $name = $1; 4966773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4967773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4968c2fdda0dSAndy Whitcroft 4969c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4970773647a0SAndy Whitcroft if ($name =~ /^(?: 4971773647a0SAndy Whitcroft if|for|while|switch|return|case| 4972773647a0SAndy Whitcroft volatile|__volatile__| 4973773647a0SAndy Whitcroft __attribute__|format|__extension__| 4974773647a0SAndy Whitcroft asm|__asm__)$/x) 4975773647a0SAndy Whitcroft { 4976c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4977c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4978c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4979c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4980773647a0SAndy Whitcroft 4981773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4982c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4983c2fdda0dSAndy Whitcroft 4984c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4985c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4986773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4987c2fdda0dSAndy Whitcroft 4988c2fdda0dSAndy Whitcroft } else { 49893705ce5bSJoe Perches if (WARN("SPACING", 49903705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 49913705ce5bSJoe Perches $fix) { 4992194f66fcSJoe Perches $fixed[$fixlinenr] =~ 49933705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 49943705ce5bSJoe Perches } 4995f0a594c1SAndy Whitcroft } 49966c72ffaaSAndy Whitcroft } 49979a4cad4eSEric Nelson 4998653d4876SAndy Whitcroft# Check operator spacing. 49990a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 50003705ce5bSJoe Perches my $fixed_line = ""; 50013705ce5bSJoe Perches my $line_fixed = 0; 50023705ce5bSJoe Perches 50039c0ca6f9SAndy Whitcroft my $ops = qr{ 50049c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 50059c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 50069c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 50071f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 500884731623SJoe Perches \?:|\?|: 50099c0ca6f9SAndy Whitcroft }x; 5010cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 50113705ce5bSJoe Perches 50123705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 50133705ce5bSJoe Perches## foreach my $el (@elements) { 50143705ce5bSJoe Perches## print("el: <$el>\n"); 50153705ce5bSJoe Perches## } 50163705ce5bSJoe Perches 50173705ce5bSJoe Perches my @fix_elements = (); 501800df344fSAndy Whitcroft my $off = 0; 50196c72ffaaSAndy Whitcroft 50203705ce5bSJoe Perches foreach my $el (@elements) { 50213705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 50223705ce5bSJoe Perches $off += length($el); 50233705ce5bSJoe Perches } 50243705ce5bSJoe Perches 50253705ce5bSJoe Perches $off = 0; 50263705ce5bSJoe Perches 50276c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 5028b34c648bSJoe Perches my $last_after = -1; 50296c72ffaaSAndy Whitcroft 50300a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 50313705ce5bSJoe Perches 50323705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 50333705ce5bSJoe Perches 50343705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 50353705ce5bSJoe Perches 50364a0df2efSAndy Whitcroft $off += length($elements[$n]); 50374a0df2efSAndy Whitcroft 503825985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 5039773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 5040773647a0SAndy Whitcroft my $cc = ''; 5041773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 5042773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 5043773647a0SAndy Whitcroft } 5044773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 5045773647a0SAndy Whitcroft 50464a0df2efSAndy Whitcroft my $a = ''; 50474a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 50484a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 5049cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 50504a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 50514a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 5052773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 50534a0df2efSAndy Whitcroft 50540a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 50554a0df2efSAndy Whitcroft 50564a0df2efSAndy Whitcroft my $c = ''; 50570a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 50584a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 50594a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 5060cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 50614a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 50624a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 50638b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 50644a0df2efSAndy Whitcroft } else { 50654a0df2efSAndy Whitcroft $c = 'E'; 50660a920b5bSAndy Whitcroft } 50670a920b5bSAndy Whitcroft 50684a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 50694a0df2efSAndy Whitcroft 50704a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 50714a0df2efSAndy Whitcroft 50726c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 5073de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 50740a920b5bSAndy Whitcroft 507574048ed8SAndy Whitcroft # Pull out the value of this operator. 50766c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 50770a920b5bSAndy Whitcroft 50781f65f947SAndy Whitcroft # Get the full operator variant. 50791f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 50801f65f947SAndy Whitcroft 508113214adfSAndy Whitcroft # Ignore operators passed as parameters. 508213214adfSAndy Whitcroft if ($op_type ne 'V' && 5083d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 508413214adfSAndy Whitcroft 5085cf655043SAndy Whitcroft# # Ignore comments 5086cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 508713214adfSAndy Whitcroft 5088d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 508913214adfSAndy Whitcroft } elsif ($op eq ';') { 5090cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 5091cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 50923705ce5bSJoe Perches if (ERROR("SPACING", 50933705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 5094b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 50953705ce5bSJoe Perches $line_fixed = 1; 50963705ce5bSJoe Perches } 5097d8aaf121SAndy Whitcroft } 5098d8aaf121SAndy Whitcroft 5099d8aaf121SAndy Whitcroft # // is a comment 5100d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 51010a920b5bSAndy Whitcroft 5102b00e4814SJoe Perches # : when part of a bitfield 5103b00e4814SJoe Perches } elsif ($opv eq ':B') { 5104b00e4814SJoe Perches # skip the bitfield test for now 5105b00e4814SJoe Perches 51061f65f947SAndy Whitcroft # No spaces for: 51071f65f947SAndy Whitcroft # -> 5108b00e4814SJoe Perches } elsif ($op eq '->') { 51094a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 51103705ce5bSJoe Perches if (ERROR("SPACING", 51113705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 5112b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 51133705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 51143705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 51153705ce5bSJoe Perches } 5116b34c648bSJoe Perches $line_fixed = 1; 51173705ce5bSJoe Perches } 51180a920b5bSAndy Whitcroft } 51190a920b5bSAndy Whitcroft 51202381097bSJoe Perches # , must not have a space before and must have a space on the right. 51210a920b5bSAndy Whitcroft } elsif ($op eq ',') { 51222381097bSJoe Perches my $rtrim_before = 0; 51232381097bSJoe Perches my $space_after = 0; 51242381097bSJoe Perches if ($ctx =~ /Wx./) { 51252381097bSJoe Perches if (ERROR("SPACING", 51262381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 51272381097bSJoe Perches $line_fixed = 1; 51282381097bSJoe Perches $rtrim_before = 1; 51292381097bSJoe Perches } 51302381097bSJoe Perches } 5131cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 51323705ce5bSJoe Perches if (ERROR("SPACING", 51333705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 51343705ce5bSJoe Perches $line_fixed = 1; 5135b34c648bSJoe Perches $last_after = $n; 51362381097bSJoe Perches $space_after = 1; 51372381097bSJoe Perches } 51382381097bSJoe Perches } 51392381097bSJoe Perches if ($rtrim_before || $space_after) { 51402381097bSJoe Perches if ($rtrim_before) { 51412381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 51422381097bSJoe Perches } else { 51432381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 51442381097bSJoe Perches } 51452381097bSJoe Perches if ($space_after) { 51462381097bSJoe Perches $good .= " "; 51473705ce5bSJoe Perches } 51480a920b5bSAndy Whitcroft } 51490a920b5bSAndy Whitcroft 51509c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 515174048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 51529c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 51539c0ca6f9SAndy Whitcroft 51549c0ca6f9SAndy Whitcroft # unary operators should have a space before and 51559c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 51569c0ca6f9SAndy Whitcroft # unary operator, or a cast 51579c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 515874048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 51590d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 5160cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 51613705ce5bSJoe Perches if (ERROR("SPACING", 51623705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 5163b34c648bSJoe Perches if ($n != $last_after + 2) { 5164b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 51653705ce5bSJoe Perches $line_fixed = 1; 51663705ce5bSJoe Perches } 51670a920b5bSAndy Whitcroft } 5168b34c648bSJoe Perches } 5169a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 5170171ae1a4SAndy Whitcroft # A unary '*' may be const 5171171ae1a4SAndy Whitcroft 5172171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 51733705ce5bSJoe Perches if (ERROR("SPACING", 51743705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5175b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 51763705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 51773705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 51783705ce5bSJoe Perches } 5179b34c648bSJoe Perches $line_fixed = 1; 51803705ce5bSJoe Perches } 51810a920b5bSAndy Whitcroft } 51820a920b5bSAndy Whitcroft 51830a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 51840a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 5185773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 51863705ce5bSJoe Perches if (ERROR("SPACING", 51873705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 5188b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 51893705ce5bSJoe Perches $line_fixed = 1; 51903705ce5bSJoe Perches } 51910a920b5bSAndy Whitcroft } 5192773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 5193773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 51943705ce5bSJoe Perches if (ERROR("SPACING", 51953705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5196b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 51973705ce5bSJoe Perches $line_fixed = 1; 51983705ce5bSJoe Perches } 5199653d4876SAndy Whitcroft } 5200773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 52013705ce5bSJoe Perches if (ERROR("SPACING", 52023705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5203b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 52043705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 52053705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5206773647a0SAndy Whitcroft } 5207b34c648bSJoe Perches $line_fixed = 1; 52083705ce5bSJoe Perches } 52093705ce5bSJoe Perches } 52100a920b5bSAndy Whitcroft 52110a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 52129c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 52139c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 52149c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 5215c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 5216c2fdda0dSAndy Whitcroft $op eq '%') 52170a920b5bSAndy Whitcroft { 5218d2e025f3SJoe Perches if ($check) { 5219d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 5220d2e025f3SJoe Perches if (CHK("SPACING", 5221d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 5222d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5223d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5224d2e025f3SJoe Perches $line_fixed = 1; 5225d2e025f3SJoe Perches } 5226d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 5227d2e025f3SJoe Perches if (CHK("SPACING", 5228d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 5229d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 5230d2e025f3SJoe Perches $line_fixed = 1; 5231d2e025f3SJoe Perches } 5232d2e025f3SJoe Perches } 5233d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 52343705ce5bSJoe Perches if (ERROR("SPACING", 52353705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 5236b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5237b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5238b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5239b34c648bSJoe Perches } 52403705ce5bSJoe Perches $line_fixed = 1; 52413705ce5bSJoe Perches } 52420a920b5bSAndy Whitcroft } 52430a920b5bSAndy Whitcroft 52441f65f947SAndy Whitcroft # A colon needs no spaces before when it is 52451f65f947SAndy Whitcroft # terminating a case value or a label. 52461f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 5247263afd39SChris Down if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) { 52483705ce5bSJoe Perches if (ERROR("SPACING", 52493705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5250b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 52513705ce5bSJoe Perches $line_fixed = 1; 52523705ce5bSJoe Perches } 52531f65f947SAndy Whitcroft } 52541f65f947SAndy Whitcroft 52550a920b5bSAndy Whitcroft # All the others need spaces both sides. 5256cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 52571f65f947SAndy Whitcroft my $ok = 0; 52581f65f947SAndy Whitcroft 525922f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 52601f65f947SAndy Whitcroft if (($op eq '<' && 52611f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 52621f65f947SAndy Whitcroft ($op eq '>' && 52631f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 52641f65f947SAndy Whitcroft { 52651f65f947SAndy Whitcroft $ok = 1; 52661f65f947SAndy Whitcroft } 52671f65f947SAndy Whitcroft 5268e0df7e1fSJoe Perches # for asm volatile statements 5269e0df7e1fSJoe Perches # ignore a colon with another 5270e0df7e1fSJoe Perches # colon immediately before or after 5271e0df7e1fSJoe Perches if (($op eq ':') && 5272e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 5273e0df7e1fSJoe Perches $ok = 1; 5274e0df7e1fSJoe Perches } 5275e0df7e1fSJoe Perches 527684731623SJoe Perches # messages are ERROR, but ?: are CHK 52771f65f947SAndy Whitcroft if ($ok == 0) { 52780675a8fbSJean Delvare my $msg_level = \&ERROR; 52790675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 528084731623SJoe Perches 52810675a8fbSJean Delvare if (&{$msg_level}("SPACING", 52823705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 5283b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5284b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5285b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5286b34c648bSJoe Perches } 52873705ce5bSJoe Perches $line_fixed = 1; 52883705ce5bSJoe Perches } 52890a920b5bSAndy Whitcroft } 529022f2a2efSAndy Whitcroft } 52914a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 52923705ce5bSJoe Perches 52933705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 52943705ce5bSJoe Perches 52953705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 52960a920b5bSAndy Whitcroft } 52973705ce5bSJoe Perches 52983705ce5bSJoe Perches if (($#elements % 2) == 0) { 52993705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 53003705ce5bSJoe Perches } 53013705ce5bSJoe Perches 5302194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 5303194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 53043705ce5bSJoe Perches } 53053705ce5bSJoe Perches 53063705ce5bSJoe Perches 53070a920b5bSAndy Whitcroft } 53080a920b5bSAndy Whitcroft 5309786b6326SJoe Perches# check for whitespace before a non-naked semicolon 5310d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 5311786b6326SJoe Perches if (WARN("SPACING", 5312786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 5313786b6326SJoe Perches $fix) { 5314194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 5315786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 5316786b6326SJoe Perches } 5317786b6326SJoe Perches } 5318786b6326SJoe Perches 5319f0a594c1SAndy Whitcroft# check for multiple assignments 5320f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 5321000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 5322000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 5323f0a594c1SAndy Whitcroft } 5324f0a594c1SAndy Whitcroft 532522f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 532622f2a2efSAndy Whitcroft## # continuation. 532722f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 532822f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 532922f2a2efSAndy Whitcroft## 533022f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 5331e73d2715SDwaipayan Ray## # falsely report the parameters of functions. 533222f2a2efSAndy Whitcroft## my $ln = $line; 533322f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 533422f2a2efSAndy Whitcroft## } 533522f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 5336000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 5337000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 533822f2a2efSAndy Whitcroft## } 533922f2a2efSAndy Whitcroft## } 5340f0a594c1SAndy Whitcroft 53410a920b5bSAndy Whitcroft#need space before brace following if, while, etc 53426b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 53436ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 53443705ce5bSJoe Perches if (ERROR("SPACING", 53453705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 53463705ce5bSJoe Perches $fix) { 53476ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 53483705ce5bSJoe Perches } 5349de7d4f0eSAndy Whitcroft } 5350de7d4f0eSAndy Whitcroft 5351c4a62ef9SJoe Perches## # check for blank lines before declarations 5352c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 5353c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 5354c4a62ef9SJoe Perches## WARN("SPACING", 5355c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 5356c4a62ef9SJoe Perches## } 5357c4a62ef9SJoe Perches## 5358c4a62ef9SJoe Perches 5359de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 5360de7d4f0eSAndy Whitcroft# on the line 536194fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 5362d5e616fcSJoe Perches if (ERROR("SPACING", 5363d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 5364d5e616fcSJoe Perches $fix) { 5365194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5366d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 5367d5e616fcSJoe Perches } 53680a920b5bSAndy Whitcroft } 53690a920b5bSAndy Whitcroft 537022f2a2efSAndy Whitcroft# check spacing on square brackets 537122f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 53723705ce5bSJoe Perches if (ERROR("SPACING", 53733705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 53743705ce5bSJoe Perches $fix) { 5375194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53763705ce5bSJoe Perches s/\[\s+/\[/; 53773705ce5bSJoe Perches } 537822f2a2efSAndy Whitcroft } 537922f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 53803705ce5bSJoe Perches if (ERROR("SPACING", 53813705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 53823705ce5bSJoe Perches $fix) { 5383194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53843705ce5bSJoe Perches s/\s+\]/\]/; 53853705ce5bSJoe Perches } 538622f2a2efSAndy Whitcroft } 538722f2a2efSAndy Whitcroft 5388c45dcabdSAndy Whitcroft# check spacing on parentheses 53899c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 53909c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 53913705ce5bSJoe Perches if (ERROR("SPACING", 53923705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 53933705ce5bSJoe Perches $fix) { 5394194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53953705ce5bSJoe Perches s/\(\s+/\(/; 53963705ce5bSJoe Perches } 539722f2a2efSAndy Whitcroft } 539813214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 5399c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 5400c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 54013705ce5bSJoe Perches if (ERROR("SPACING", 54023705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 54033705ce5bSJoe Perches $fix) { 5404194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54053705ce5bSJoe Perches s/\s+\)/\)/; 54063705ce5bSJoe Perches } 540722f2a2efSAndy Whitcroft } 540822f2a2efSAndy Whitcroft 5409e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 5410e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 5411e2826fd0SJoe Perches 5412e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 5413ea4acbb1SJoe Perches my $var = $1; 5414ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5415ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 5416ea4acbb1SJoe Perches $fix) { 5417ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 5418ea4acbb1SJoe Perches } 5419ea4acbb1SJoe Perches } 5420ea4acbb1SJoe Perches 5421ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 5422ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 5423ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 5424ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 5425ea4acbb1SJoe Perches my $var = $2; 5426ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5427ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 5428ea4acbb1SJoe Perches $fix) { 5429ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 5430ea4acbb1SJoe Perches $var2 =~ s/\s//g; 5431ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 5432ea4acbb1SJoe Perches } 5433e2826fd0SJoe Perches } 5434e2826fd0SJoe Perches 543563b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 5436a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 5437a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 54385b57980dSJoe Perches $perl_version_ok && defined($stat) && 543963b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 544063b7c73eSJoe Perches my $if_stat = $1; 544163b7c73eSJoe Perches my $test = substr($2, 1, -1); 544263b7c73eSJoe Perches my $herectx; 544363b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 544463b7c73eSJoe Perches my $match = $1; 544563b7c73eSJoe Perches # avoid parentheses around potential macro args 544663b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 544763b7c73eSJoe Perches if (!defined($herectx)) { 544863b7c73eSJoe Perches $herectx = $here . "\n"; 544963b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 545063b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 545163b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 545263b7c73eSJoe Perches $herectx .= $rl . "\n"; 545363b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 545463b7c73eSJoe Perches } 545563b7c73eSJoe Perches } 545663b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 545763b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 545863b7c73eSJoe Perches } 545963b7c73eSJoe Perches } 546063b7c73eSJoe Perches 546169078651SJoe Perches# check that goto labels aren't indented (allow a single space indentation) 546269078651SJoe Perches# and ignore bitfield definitions like foo:1 546369078651SJoe Perches# Strictly, labels can have whitespace after the identifier and before the : 546469078651SJoe Perches# but this is not allowed here as many ?: uses would appear to be labels 546569078651SJoe Perches if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ && 546669078651SJoe Perches $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ && 546769078651SJoe Perches $sline !~ /^.\s+default:/) { 54683705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 54693705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 54703705ce5bSJoe Perches $fix) { 5471194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54723705ce5bSJoe Perches s/^(.)\s+/$1/; 54733705ce5bSJoe Perches } 54740a920b5bSAndy Whitcroft } 54750a920b5bSAndy Whitcroft 547640873abaSJoe Perches# check if a statement with a comma should be two statements like: 547740873abaSJoe Perches# foo = bar(), /* comma should be semicolon */ 547840873abaSJoe Perches# bar = baz(); 547940873abaSJoe Perches if (defined($stat) && 548040873abaSJoe Perches $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { 548140873abaSJoe Perches my $cnt = statement_rawlines($stat); 548240873abaSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 548340873abaSJoe Perches WARN("SUSPECT_COMMA_SEMICOLON", 548440873abaSJoe Perches "Possible comma where semicolon could be used\n" . $herectx); 548540873abaSJoe Perches } 548640873abaSJoe Perches 54875b9553abSJoe Perches# return is not a function 5488507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 5489c45dcabdSAndy Whitcroft my $spacing = $1; 54905b57980dSJoe Perches if ($perl_version_ok && 54915b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 54925b9553abSJoe Perches my $value = $1; 54935b9553abSJoe Perches $value = deparenthesize($value); 54945b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 5495000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 5496000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 54975b9553abSJoe Perches } 5498c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 5499000d1cc1SJoe Perches ERROR("SPACING", 5500000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 5501c45dcabdSAndy Whitcroft } 5502c45dcabdSAndy Whitcroft } 5503507e5141SJoe Perches 5504b43ae21bSJoe Perches# unnecessary return in a void function 5505b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 5506b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 5507b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 5508b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 5509b43ae21bSJoe Perches $linenr >= 3 && 5510b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 5511b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 55129819cf25SJoe Perches WARN("RETURN_VOID", 5513b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 55149819cf25SJoe Perches } 55159819cf25SJoe Perches 5516189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 55175b57980dSJoe Perches if ($perl_version_ok && 5518189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 5519189248d8SJoe Perches my $openparens = $1; 5520189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 5521189248d8SJoe Perches my $msg = ""; 5522189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 5523189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 5524189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 5525189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 5526189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 5527189248d8SJoe Perches } 5528189248d8SJoe Perches } 5529189248d8SJoe Perches 5530c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 5531c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 5532c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 5533c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 55345b57980dSJoe Perches if ($perl_version_ok && 5535c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 5536c5595fa2SJoe Perches my $lead = $1; 5537c5595fa2SJoe Perches my $const = $2; 5538c5595fa2SJoe Perches my $comp = $3; 5539c5595fa2SJoe Perches my $to = $4; 5540c5595fa2SJoe Perches my $newcomp = $comp; 5541f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 5542c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 5543c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 5544c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 5545c5595fa2SJoe Perches $fix) { 5546c5595fa2SJoe Perches if ($comp eq "<") { 5547c5595fa2SJoe Perches $newcomp = ">"; 5548c5595fa2SJoe Perches } elsif ($comp eq "<=") { 5549c5595fa2SJoe Perches $newcomp = ">="; 5550c5595fa2SJoe Perches } elsif ($comp eq ">") { 5551c5595fa2SJoe Perches $newcomp = "<"; 5552c5595fa2SJoe Perches } elsif ($comp eq ">=") { 5553c5595fa2SJoe Perches $newcomp = "<="; 5554c5595fa2SJoe Perches } 5555c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 5556c5595fa2SJoe Perches } 5557c5595fa2SJoe Perches } 5558c5595fa2SJoe Perches 5559f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 5560f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 556153a3c448SAndy Whitcroft my $name = $1; 556246b85bf9SGuenter Roeck if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) { 5563000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 5564f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 556553a3c448SAndy Whitcroft } 556653a3c448SAndy Whitcroft } 5567c45dcabdSAndy Whitcroft 55680a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 55694a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 55703705ce5bSJoe Perches if (ERROR("SPACING", 55713705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 55723705ce5bSJoe Perches $fix) { 5573194f66fcSJoe Perches $fixed[$fixlinenr] =~ 55743705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 55753705ce5bSJoe Perches } 55760a920b5bSAndy Whitcroft } 55770a920b5bSAndy Whitcroft 5578f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 5579f5fe35ddSAndy Whitcroft# statements after the conditional. 5580170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 55813e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 55823e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 55833e469cdcSAndy Whitcroft if (!defined $stat); 5584170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 5585170d3a22SAndy Whitcroft $remain_next, $off_next); 5586170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 5587170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 5588170d3a22SAndy Whitcroft 5589170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 5590170d3a22SAndy Whitcroft # If the statement carries leading newlines, 5591170d3a22SAndy Whitcroft # then count those as offsets. 5592170d3a22SAndy Whitcroft my ($whitespace) = 5593170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 5594170d3a22SAndy Whitcroft my $offset = 5595170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 5596170d3a22SAndy Whitcroft 5597170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 5598170d3a22SAndy Whitcroft $offset} = 1; 5599170d3a22SAndy Whitcroft } 5600170d3a22SAndy Whitcroft } 5601170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 5602c11230f4SJoe Perches defined($stat) && defined($cond) && 5603170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 5604171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 5605481efd7bSJoe Perches my $fixed_assign_in_if = 0; 56068905a67cSAndy Whitcroft 5607b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 560865b64b3bSJoe Perches if (ERROR("ASSIGN_IN_IF", 560965b64b3bSJoe Perches "do not use assignment in if condition\n" . $herecurr) && 561065b64b3bSJoe Perches $fix && $perl_version_ok) { 561165b64b3bSJoe Perches if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { 561265b64b3bSJoe Perches my $space = $1; 561365b64b3bSJoe Perches my $not = $2; 561465b64b3bSJoe Perches my $statement = $3; 561565b64b3bSJoe Perches my $assigned = $4; 561665b64b3bSJoe Perches my $test = $8; 561765b64b3bSJoe Perches my $against = $9; 561865b64b3bSJoe Perches my $brace = $15; 561965b64b3bSJoe Perches fix_delete_line($fixlinenr, $rawline); 562065b64b3bSJoe Perches fix_insert_line($fixlinenr, "$space$statement;"); 562165b64b3bSJoe Perches my $newline = "${space}if ("; 562265b64b3bSJoe Perches $newline .= '!' if defined($not); 562365b64b3bSJoe Perches $newline .= '(' if (defined $not && defined($test) && defined($against)); 562465b64b3bSJoe Perches $newline .= "$assigned"; 562565b64b3bSJoe Perches $newline .= " $test $against" if (defined($test) && defined($against)); 562665b64b3bSJoe Perches $newline .= ')' if (defined $not && defined($test) && defined($against)); 562765b64b3bSJoe Perches $newline .= ')'; 562865b64b3bSJoe Perches $newline .= " {" if (defined($brace)); 562965b64b3bSJoe Perches fix_insert_line($fixlinenr + 1, $newline); 5630481efd7bSJoe Perches $fixed_assign_in_if = 1; 563165b64b3bSJoe Perches } 563265b64b3bSJoe Perches } 56338905a67cSAndy Whitcroft } 56348905a67cSAndy Whitcroft 56358905a67cSAndy Whitcroft # Find out what is on the end of the line after the 56368905a67cSAndy Whitcroft # conditional. 5637773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 56388905a67cSAndy Whitcroft $s =~ s/\n.*//g; 563913214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 564053210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 564153210168SAndy Whitcroft $c !~ /}\s*while\s*/) 5642773647a0SAndy Whitcroft { 5643bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 5644bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 5645bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 564642bdf74cSHidetoshi Seto my $stat_real = ''; 5647bb44ad39SAndy Whitcroft 564842bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 564942bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 5650bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 5651bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 5652bb44ad39SAndy Whitcroft } 5653bb44ad39SAndy Whitcroft 5654481efd7bSJoe Perches if (ERROR("TRAILING_STATEMENTS", 5655481efd7bSJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real) && 5656481efd7bSJoe Perches !$fixed_assign_in_if && 5657481efd7bSJoe Perches $cond_lines == 0 && 5658481efd7bSJoe Perches $fix && $perl_version_ok && 5659481efd7bSJoe Perches $fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) { 5660481efd7bSJoe Perches my $indent = $1; 5661481efd7bSJoe Perches my $test = $2; 5662481efd7bSJoe Perches my $rest = rtrim($4); 5663481efd7bSJoe Perches if ($rest =~ /;$/) { 5664481efd7bSJoe Perches $fixed[$fixlinenr] = "\+$indent$test"; 5665481efd7bSJoe Perches fix_insert_line($fixlinenr + 1, "$indent\t$rest"); 5666481efd7bSJoe Perches } 5667481efd7bSJoe Perches } 56688905a67cSAndy Whitcroft } 56698905a67cSAndy Whitcroft } 56708905a67cSAndy Whitcroft 567113214adfSAndy Whitcroft# Check for bitwise tests written as boolean 567213214adfSAndy Whitcroft if ($line =~ / 567313214adfSAndy Whitcroft (?: 567413214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 567513214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 567613214adfSAndy Whitcroft (?:\&\&|\|\|) 567713214adfSAndy Whitcroft | 567813214adfSAndy Whitcroft (?:\&\&|\|\|) 567913214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 568013214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 568113214adfSAndy Whitcroft )/x) 568213214adfSAndy Whitcroft { 5683000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 5684000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 568513214adfSAndy Whitcroft } 568613214adfSAndy Whitcroft 56878905a67cSAndy Whitcroft# if and else should not have general statements after it 568813214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 568913214adfSAndy Whitcroft my $s = $1; 569013214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 569113214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 5692000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5693000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 56940a920b5bSAndy Whitcroft } 569513214adfSAndy Whitcroft } 569639667782SAndy Whitcroft# if should not continue a brace 569739667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 5698000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5699048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 570039667782SAndy Whitcroft $herecurr); 570139667782SAndy Whitcroft } 5702a1080bf8SAndy Whitcroft# case and default should not have general statements after them 5703a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 5704a1080bf8SAndy Whitcroft $line !~ /\G(?: 57053fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5706a1080bf8SAndy Whitcroft \s*return\s+ 5707a1080bf8SAndy Whitcroft )/xg) 5708a1080bf8SAndy Whitcroft { 5709000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5710000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 5711a1080bf8SAndy Whitcroft } 57120a920b5bSAndy Whitcroft 57130a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 57140a920b5bSAndy Whitcroft # indent level to be relevant to each other. 57158b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 57160a920b5bSAndy Whitcroft $previndent == $indent) { 57178b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 57188b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 57198b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 57208b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 57218b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 57228b8856f4SJoe Perches my $fixedline = $prevrawline; 57238b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 57248b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 57258b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 57268b8856f4SJoe Perches } 57278b8856f4SJoe Perches $fixedline = $rawline; 57288b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 57298b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 57308b8856f4SJoe Perches } 57310a920b5bSAndy Whitcroft } 57320a920b5bSAndy Whitcroft 57338b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5734c2fdda0dSAndy Whitcroft $previndent == $indent) { 5735c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5736c2fdda0dSAndy Whitcroft 5737c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5738c2fdda0dSAndy Whitcroft # conditional. 5739773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5740c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5741c2fdda0dSAndy Whitcroft 5742c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 57438b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 57448b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 57458b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 57468b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 57478b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 57488b8856f4SJoe Perches my $fixedline = $prevrawline; 57498b8856f4SJoe Perches my $trailing = $rawline; 57508b8856f4SJoe Perches $trailing =~ s/^\+//; 57518b8856f4SJoe Perches $trailing = trim($trailing); 57528b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 57538b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 57548b8856f4SJoe Perches } 5755c2fdda0dSAndy Whitcroft } 5756c2fdda0dSAndy Whitcroft } 5757c2fdda0dSAndy Whitcroft 575895e2c602SJoe Perches#Specific variable tests 5759323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5760323c1260SJoe Perches my $var = $1; 576195e2c602SJoe Perches 576295e2c602SJoe Perches#CamelCase 5763807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5764be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 57654104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values 57664104a206SŁukasz Stelmach $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && 576722735ce8SJoe Perches#Ignore Page<foo> variants 5768807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5769d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB 5770d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 5771d439e6a5SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5772f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5773f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 5774f858e23aSAntonio Borneo while ($var =~ m{\b($Ident)}g) { 57757e781f67SJoe Perches my $word = $1; 57767e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5777d8b07710SJoe Perches if ($check) { 5778d8b07710SJoe Perches seed_camelcase_includes(); 5779d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5780d8b07710SJoe Perches seed_camelcase_file($realfile); 5781d8b07710SJoe Perches $camelcase_file_seeded = 1; 5782d8b07710SJoe Perches } 5783d8b07710SJoe Perches } 57847e781f67SJoe Perches if (!defined $camelcase{$word}) { 57857e781f67SJoe Perches $camelcase{$word} = 1; 5786be79794bSJoe Perches CHK("CAMELCASE", 57877e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 57887e781f67SJoe Perches } 5789323c1260SJoe Perches } 5790323c1260SJoe Perches } 57913445686aSJoe Perches } 57920a920b5bSAndy Whitcroft 57930a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5794d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5795d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5796d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5797d5e616fcSJoe Perches $fix) { 5798194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5799d5e616fcSJoe Perches } 58000a920b5bSAndy Whitcroft } 58010a920b5bSAndy Whitcroft 58020e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 58030e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5804c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5805e09dec48SAndy Whitcroft my $file = "$1.h"; 5806e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5807e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5808e09dec48SAndy Whitcroft $realfile ne $checkfile && 58097840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5810c45dcabdSAndy Whitcroft { 58110e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 58120e212e0aSFabian Frederick if ($asminclude > 0) { 5813e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5814000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5815000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5816e09dec48SAndy Whitcroft } else { 5817000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5818000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5819e09dec48SAndy Whitcroft } 58200a920b5bSAndy Whitcroft } 58210a920b5bSAndy Whitcroft } 58220e212e0aSFabian Frederick } 58230a920b5bSAndy Whitcroft 5824653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5825653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5826cf655043SAndy Whitcroft# in a known good container 5827b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5828b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5829d8aaf121SAndy Whitcroft my $ln = $linenr; 5830d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5831c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5832c45dcabdSAndy Whitcroft my $ctx = ''; 583308a2843eSJoe Perches my $has_flow_statement = 0; 583408a2843eSJoe Perches my $has_arg_concat = 0; 5835c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5836f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5837f74bd194SAndy Whitcroft $ctx = $dstat; 5838c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5839a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5840c45dcabdSAndy Whitcroft 584108a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 584262e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 584308a2843eSJoe Perches 5844f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5845f59b64bfSJoe Perches my $define_args = $1; 5846f59b64bfSJoe Perches my $define_stmt = $dstat; 5847f59b64bfSJoe Perches my @def_args = (); 5848f59b64bfSJoe Perches 5849f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5850f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5851f59b64bfSJoe Perches $define_args =~ s/\s*//g; 58528c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5853f59b64bfSJoe Perches @def_args = split(",", $define_args); 5854f59b64bfSJoe Perches } 5855f59b64bfSJoe Perches 5856292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5857c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5858c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5859c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5860c45dcabdSAndy Whitcroft 5861c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 58622e44e803SDwaipayan Ray while ($dstat =~ s/\([^\(\)]*\)/1u/ || 58632e44e803SDwaipayan Ray $dstat =~ s/\{[^\{\}]*\}/1u/ || 58642e44e803SDwaipayan Ray $dstat =~ s/.\[[^\[\]]*\]/1u/) 5865bf30d6edSAndy Whitcroft { 5866c45dcabdSAndy Whitcroft } 5867c45dcabdSAndy Whitcroft 5868342d3d2fSAntonio Borneo # Flatten any obvious string concatenation. 586933acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 587033acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5871e45bab8eSAndy Whitcroft { 5872e45bab8eSAndy Whitcroft } 5873e45bab8eSAndy Whitcroft 587442e15293SJoe Perches # Make asm volatile uses seem like a generic function 587542e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 587642e15293SJoe Perches 5877c45dcabdSAndy Whitcroft my $exceptions = qr{ 5878c45dcabdSAndy Whitcroft $Declare| 5879c45dcabdSAndy Whitcroft module_param_named| 5880a0a0a7a9SKees Cook MODULE_PARM_DESC| 5881c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5882c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5883383099fdSAndy Whitcroft __typeof__\(| 588422fd2d3eSStefani Seibold union| 588522fd2d3eSStefani Seibold struct| 5886ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 58876b10df42SVladimir Zapolskiy ^\"|\"$| 58886b10df42SVladimir Zapolskiy ^\[ 5889c45dcabdSAndy Whitcroft }x; 58905eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5891f59b64bfSJoe Perches 5892f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5893f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5894e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5895f59b64bfSJoe Perches 5896f74bd194SAndy Whitcroft if ($dstat ne '' && 5897f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5898f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 58993cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5900356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5901f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5902f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5903e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 590472f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 59052e44e803SDwaipayan Ray $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} 5906f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5907f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5908f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 59094e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5910f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5911c45dcabdSAndy Whitcroft { 5912e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5913e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5914e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5915e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5916f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5917f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5918f74bd194SAndy Whitcroft } else { 5919000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 5920388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5921d8aaf121SAndy Whitcroft } 5922f59b64bfSJoe Perches 5923f59b64bfSJoe Perches } 59245207649bSJoe Perches 59255207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 59265207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 59275207649bSJoe Perches my $first = 1; 59285207649bSJoe Perches $define_stmt = ""; 59295207649bSJoe Perches foreach my $l (@stmt_array) { 59305207649bSJoe Perches $l =~ s/\\$//; 59315207649bSJoe Perches if ($first) { 59325207649bSJoe Perches $define_stmt = $l; 59335207649bSJoe Perches $first = 0; 59345207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 59355207649bSJoe Perches $define_stmt .= substr($l, 1); 59365207649bSJoe Perches } 59375207649bSJoe Perches } 59385207649bSJoe Perches $define_stmt =~ s/$;//g; 59395207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 59405207649bSJoe Perches $define_stmt = trim($define_stmt); 59415207649bSJoe Perches 5942f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 5943f59b64bfSJoe Perches foreach my $arg (@def_args) { 5944f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 59459192d41aSJoe Perches next if ($arg =~ /^type$/i); 59467fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 59477b844345SVincent Mailhol $tmp_stmt =~ s/\b(__must_be_array|offsetof|sizeof|sizeof_field|__stringify|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 59487fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 59497fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5950d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 5951f59b64bfSJoe Perches if ($use_cnt > 1) { 5952f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 5953f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5954f59b64bfSJoe Perches } 59559192d41aSJoe Perches# check if any macro arguments may have other precedence issues 59567fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 59579192d41aSJoe Perches ((defined($1) && $1 ne ',') || 59589192d41aSJoe Perches (defined($2) && $2 ne ','))) { 59599192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 59609192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 59619192d41aSJoe Perches } 59620a920b5bSAndy Whitcroft } 59635023d347SJoe Perches 596408a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 596508a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 596608a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 596708a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 5968e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 596908a2843eSJoe Perches 597008a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 597108a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 597208a2843eSJoe Perches } 597308a2843eSJoe Perches 5974481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 59755023d347SJoe Perches 59765023d347SJoe Perches } else { 59775023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 5978481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 5979481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 59805023d347SJoe Perches $line =~ /^\+.*\\$/) { 59815023d347SJoe Perches WARN("LINE_CONTINUATIONS", 59825023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 59835023d347SJoe Perches } 5984653d4876SAndy Whitcroft } 59850a920b5bSAndy Whitcroft 5986b13edf7fSJoe Perches# do {} while (0) macro tests: 5987b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 5988b13edf7fSJoe Perches# macro should not end with a semicolon 59895b57980dSJoe Perches if ($perl_version_ok && 5990b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 5991b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5992b13edf7fSJoe Perches my $ln = $linenr; 5993b13edf7fSJoe Perches my $cnt = $realcnt; 5994b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 5995b13edf7fSJoe Perches my $ctx = ''; 5996b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 5997b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 5998b13edf7fSJoe Perches $ctx = $dstat; 5999b13edf7fSJoe Perches 6000b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 60011b36b201SJoe Perches $dstat =~ s/$;/ /g; 6002b13edf7fSJoe Perches 6003b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 6004b13edf7fSJoe Perches my $stmts = $2; 6005b13edf7fSJoe Perches my $semis = $3; 6006b13edf7fSJoe Perches 6007b13edf7fSJoe Perches $ctx =~ s/\n*$//; 6008b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 6009e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6010b13edf7fSJoe Perches 6011ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 6012ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 6013b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 6014b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 6015b13edf7fSJoe Perches } 6016b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 6017b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 6018b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 6019b13edf7fSJoe Perches } 6020f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 6021f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 6022f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 6023e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6024f5ef95b1SJoe Perches 6025f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 6026f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 6027b13edf7fSJoe Perches } 6028b13edf7fSJoe Perches } 6029b13edf7fSJoe Perches 6030f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 603113214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 603213214adfSAndy Whitcroft my ($level, $endln, @chunks) = 6033cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 603413214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 6035cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 6036cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 6037aad4f614SJoe Perches my @allowed = (); 6038aad4f614SJoe Perches my $allow = 0; 603913214adfSAndy Whitcroft my $seen = 0; 6040773647a0SAndy Whitcroft my $herectx = $here . "\n"; 6041cf655043SAndy Whitcroft my $ln = $linenr - 1; 604213214adfSAndy Whitcroft for my $chunk (@chunks) { 604313214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 604413214adfSAndy Whitcroft 6045773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 6046773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 6047773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 6048773647a0SAndy Whitcroft 6049aad4f614SJoe Perches $allowed[$allow] = 0; 6050773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 6051773647a0SAndy Whitcroft 6052773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 6053773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 6054773647a0SAndy Whitcroft 6055773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 6056cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 6057cf655043SAndy Whitcroft 6058773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 605913214adfSAndy Whitcroft 606013214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 606113214adfSAndy Whitcroft 6062aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 6063cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 6064cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 6065aad4f614SJoe Perches $allowed[$allow] = 1; 606613214adfSAndy Whitcroft } 606713214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 6068cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 6069aad4f614SJoe Perches $allowed[$allow] = 1; 607013214adfSAndy Whitcroft } 6071cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 6072cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 6073aad4f614SJoe Perches $allowed[$allow] = 1; 607413214adfSAndy Whitcroft } 6075aad4f614SJoe Perches $allow++; 607613214adfSAndy Whitcroft } 6077aad4f614SJoe Perches if ($seen) { 6078aad4f614SJoe Perches my $sum_allowed = 0; 6079aad4f614SJoe Perches foreach (@allowed) { 6080aad4f614SJoe Perches $sum_allowed += $_; 6081aad4f614SJoe Perches } 6082aad4f614SJoe Perches if ($sum_allowed == 0) { 6083000d1cc1SJoe Perches WARN("BRACES", 6084000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 6085aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 6086aad4f614SJoe Perches $seen != $allow) { 6087aad4f614SJoe Perches CHK("BRACES", 6088aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 6089aad4f614SJoe Perches } 609013214adfSAndy Whitcroft } 609113214adfSAndy Whitcroft } 609213214adfSAndy Whitcroft } 6093773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 609413214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 6095cf655043SAndy Whitcroft my $allowed = 0; 6096f0a594c1SAndy Whitcroft 6097cf655043SAndy Whitcroft # Check the pre-context. 6098cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 6099cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 6100cf655043SAndy Whitcroft $allowed = 1; 6101f0a594c1SAndy Whitcroft } 6102773647a0SAndy Whitcroft 6103773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 6104773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 6105773647a0SAndy Whitcroft 6106cf655043SAndy Whitcroft # Check the condition. 6107cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 6108773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 6109cf655043SAndy Whitcroft if (defined $cond) { 6110773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 6111cf655043SAndy Whitcroft } 6112cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 6113cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 6114cf655043SAndy Whitcroft $allowed = 1; 6115cf655043SAndy Whitcroft } 6116cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 6117cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 6118cf655043SAndy Whitcroft $allowed = 1; 6119cf655043SAndy Whitcroft } 6120cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 6121cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 6122cf655043SAndy Whitcroft $allowed = 1; 6123cf655043SAndy Whitcroft } 6124cf655043SAndy Whitcroft # Check the post-context. 6125cf655043SAndy Whitcroft if (defined $chunks[1]) { 6126cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 6127cf655043SAndy Whitcroft if (defined $cond) { 6128773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 6129cf655043SAndy Whitcroft } 6130cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 6131cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 6132cf655043SAndy Whitcroft $allowed = 1; 6133cf655043SAndy Whitcroft } 6134cf655043SAndy Whitcroft } 6135cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 6136f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 6137e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6138cf655043SAndy Whitcroft 6139000d1cc1SJoe Perches WARN("BRACES", 6140000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 6141f0a594c1SAndy Whitcroft } 6142f0a594c1SAndy Whitcroft } 6143f0a594c1SAndy Whitcroft 6144e4c5babdSJoe Perches# check for single line unbalanced braces 614595330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 614695330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 6147e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 6148e4c5babdSJoe Perches } 6149e4c5babdSJoe Perches 61500979ae66SJoe Perches# check for unnecessary blank lines around braces 615177b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 6152f8e58219SJoe Perches if (CHK("BRACES", 6153f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 6154f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 6155f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6156f8e58219SJoe Perches } 61570979ae66SJoe Perches } 615877b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 6159f8e58219SJoe Perches if (CHK("BRACES", 6160f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 6161f8e58219SJoe Perches $fix) { 6162f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 6163f8e58219SJoe Perches } 61640979ae66SJoe Perches } 61650979ae66SJoe Perches 61664a0df2efSAndy Whitcroft# no volatiles please 61676c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 61686c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 6169000d1cc1SJoe Perches WARN("VOLATILE", 61708c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 61714a0df2efSAndy Whitcroft } 61724a0df2efSAndy Whitcroft 61735e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 61745e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 61755e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 61765e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 617733acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 61785e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 61795e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 61805e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 61815e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 61825e4f6ba5SJoe Perches $fix && 61835e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 61845e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 61855e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 61865e4f6ba5SJoe Perches my $comma_close = ""; 61875e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 61885e4f6ba5SJoe Perches $comma_close = $1; 61895e4f6ba5SJoe Perches } 61905e4f6ba5SJoe Perches 61915e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 61925e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 61935e4f6ba5SJoe Perches my $fixedline = $prevrawline; 61945e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 61955e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 61965e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 61975e4f6ba5SJoe Perches $fixedline = $rawline; 61985e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 61995e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 62005e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 62015e4f6ba5SJoe Perches } 62025e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 62035e4f6ba5SJoe Perches } 62045e4f6ba5SJoe Perches } 62055e4f6ba5SJoe Perches 62065e4f6ba5SJoe Perches# check for missing a space in a string concatenation 62075e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 62085e4f6ba5SJoe Perches WARN('MISSING_SPACE', 62095e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 62105e4f6ba5SJoe Perches } 62115e4f6ba5SJoe Perches 621277cb8546SJoe Perches# check for an embedded function name in a string when the function is known 6213e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 6214e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 6215e4b7d309SJoe Perches# function declarations 621677cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 621777cb8546SJoe Perches defined($context_function) && 6218e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 6219e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 622077cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 6221e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 622277cb8546SJoe Perches } 622377cb8546SJoe Perches 6224adb2da82SJoe Perches# check for unnecessary function tracing like uses 6225adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like 6226adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions 6227adb2da82SJoe Perches if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) { 6228adb2da82SJoe Perches if (WARN("TRACING_LOGGING", 6229adb2da82SJoe Perches "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) && 6230adb2da82SJoe Perches $fix) { 6231adb2da82SJoe Perches fix_delete_line($fixlinenr, $rawline); 6232adb2da82SJoe Perches } 6233adb2da82SJoe Perches } 6234adb2da82SJoe Perches 62355e4f6ba5SJoe Perches# check for spaces before a quoted newline 62365e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 62375e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 62385e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 62395e4f6ba5SJoe Perches $fix) { 62405e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 62415e4f6ba5SJoe Perches } 62425e4f6ba5SJoe Perches 62435e4f6ba5SJoe Perches } 62445e4f6ba5SJoe Perches 6245f17dba4fSJoe Perches# concatenated string without spaces between elements 6246d2af5aa6SJoe Perches if ($line =~ /$String[A-Z_]/ || 6247d2af5aa6SJoe Perches ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) { 624879682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 624979682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 625079682c0cSJoe Perches $fix) { 625179682c0cSJoe Perches while ($line =~ /($String)/g) { 625279682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 625379682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 625479682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 625579682c0cSJoe Perches } 625679682c0cSJoe Perches } 6257f17dba4fSJoe Perches } 6258f17dba4fSJoe Perches 625990ad30e5SJoe Perches# uncoalesced string fragments 6260d2af5aa6SJoe Perches if ($line =~ /$String\s*[Lu]?"/) { 626179682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 626279682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 626379682c0cSJoe Perches $fix) { 626479682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 626579682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 626679682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 626779682c0cSJoe Perches } 626879682c0cSJoe Perches } 626990ad30e5SJoe Perches } 627090ad30e5SJoe Perches 6271522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 6272522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 6273522b837cSAlexey Dobriyan my $show_Z = 1; 62745e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 6275522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 62765e4f6ba5SJoe Perches $string =~ s/%%/__/g; 6277522b837cSAlexey Dobriyan # check for %L 6278522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 62795e4f6ba5SJoe Perches WARN("PRINTF_L", 6280522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 6281522b837cSAlexey Dobriyan $show_L = 0; 62825e4f6ba5SJoe Perches } 6283522b837cSAlexey Dobriyan # check for %Z 6284522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 6285522b837cSAlexey Dobriyan WARN("PRINTF_Z", 6286522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 6287522b837cSAlexey Dobriyan $show_Z = 0; 6288522b837cSAlexey Dobriyan } 6289522b837cSAlexey Dobriyan # check for 0x<decimal> 6290522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 6291522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 62926e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 62936e300757SJoe Perches } 62945e4f6ba5SJoe Perches } 62955e4f6ba5SJoe Perches 62965e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 62973f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 62985e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 62995e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 63005e4f6ba5SJoe Perches } 63015e4f6ba5SJoe Perches 630200df344fSAndy Whitcroft# warn about #if 0 6303c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 630460f89010SPrakruthi Deepak Heragu WARN("IF_0", 630560f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 630660f89010SPrakruthi Deepak Heragu } 630760f89010SPrakruthi Deepak Heragu 630860f89010SPrakruthi Deepak Heragu# warn about #if 1 630960f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 631060f89010SPrakruthi Deepak Heragu WARN("IF_1", 631160f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 63124a0df2efSAndy Whitcroft } 63134a0df2efSAndy Whitcroft 631403df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 631503df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 6316100425deSJoe Perches my $tested = quotemeta($1); 6317100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 6318100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 6319100425deSJoe Perches my $func = $1; 6320100425deSJoe Perches if (WARN('NEEDLESS_IF', 6321100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 6322100425deSJoe Perches $fix) { 6323100425deSJoe Perches my $do_fix = 1; 6324100425deSJoe Perches my $leading_tabs = ""; 6325100425deSJoe Perches my $new_leading_tabs = ""; 6326100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 6327100425deSJoe Perches $leading_tabs = $1; 6328100425deSJoe Perches } else { 6329100425deSJoe Perches $do_fix = 0; 6330100425deSJoe Perches } 6331100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 6332100425deSJoe Perches $new_leading_tabs = $1; 6333100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 6334100425deSJoe Perches $do_fix = 0; 6335100425deSJoe Perches } 6336100425deSJoe Perches } else { 6337100425deSJoe Perches $do_fix = 0; 6338100425deSJoe Perches } 6339100425deSJoe Perches if ($do_fix) { 6340100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6341100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 6342100425deSJoe Perches } 6343100425deSJoe Perches } 63444c432a8fSGreg Kroah-Hartman } 63454c432a8fSGreg Kroah-Hartman } 6346f0a594c1SAndy Whitcroft 6347ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 6348ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 6349ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 6350ebfdc409SJoe Perches (defined $1 || defined $3) && 6351ebfdc409SJoe Perches $linenr > 3) { 6352ebfdc409SJoe Perches my $testval = $2; 6353ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 6354ebfdc409SJoe Perches 6355ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 6356ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 6357ebfdc409SJoe Perches 6358e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 6359e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 6360ebfdc409SJoe Perches WARN("OOM_MESSAGE", 6361ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 6362ebfdc409SJoe Perches } 6363ebfdc409SJoe Perches } 6364ebfdc409SJoe Perches 6365f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 6366dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 6367f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 6368f78d98f6SJoe Perches my $level = $1; 6369f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 6370f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 6371f78d98f6SJoe Perches $fix) { 6372f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 6373f78d98f6SJoe Perches } 6374f78d98f6SJoe Perches } 6375f78d98f6SJoe Perches 637645c55e92SJoe Perches# check for logging continuations 637745c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 637845c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 637945c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 638045c55e92SJoe Perches } 638145c55e92SJoe Perches 638270eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions 638370eb2275SDwaipayan Ray if (defined $stat && 638470eb2275SDwaipayan Ray $line =~ /\b$logFunctions\s*\(/ && 638570eb2275SDwaipayan Ray index($stat, '"') >= 0) { 638670eb2275SDwaipayan Ray my $lc = $stat =~ tr@\n@@; 638770eb2275SDwaipayan Ray $lc = $lc + $linenr; 638870eb2275SDwaipayan Ray my $stat_real = get_stat_real($linenr, $lc); 638970eb2275SDwaipayan Ray pos($stat_real) = index($stat_real, '"'); 639070eb2275SDwaipayan Ray while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { 639170eb2275SDwaipayan Ray my $pspec = $1; 639270eb2275SDwaipayan Ray my $h = $2; 639370eb2275SDwaipayan Ray my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; 639470eb2275SDwaipayan Ray if (WARN("UNNECESSARY_MODIFIER", 639570eb2275SDwaipayan Ray "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && 639670eb2275SDwaipayan Ray $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { 639770eb2275SDwaipayan Ray my $nspec = $pspec; 639870eb2275SDwaipayan Ray $nspec =~ s/h//g; 639970eb2275SDwaipayan Ray $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; 640070eb2275SDwaipayan Ray } 640170eb2275SDwaipayan Ray } 640270eb2275SDwaipayan Ray } 640370eb2275SDwaipayan Ray 6404abb08a53SJoe Perches# check for mask then right shift without a parentheses 64055b57980dSJoe Perches if ($perl_version_ok && 6406abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 6407abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 6408abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 6409abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 6410abb08a53SJoe Perches } 6411abb08a53SJoe Perches 6412b75ac618SJoe Perches# check for pointer comparisons to NULL 64135b57980dSJoe Perches if ($perl_version_ok) { 6414b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 6415b75ac618SJoe Perches my $val = $1; 6416b75ac618SJoe Perches my $equal = "!"; 6417b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 6418b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 6419b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 6420b75ac618SJoe Perches $fix) { 6421b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 6422b75ac618SJoe Perches } 6423b75ac618SJoe Perches } 6424b75ac618SJoe Perches } 6425b75ac618SJoe Perches 64268716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 64278716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 64288716de38SJoe Perches my $attr = $1; 64298716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 64308716de38SJoe Perches my $ptr = $1; 64318716de38SJoe Perches my $var = $2; 64328716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 64338716de38SJoe Perches ERROR("MISPLACED_INIT", 64348716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 64358716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 64368716de38SJoe Perches WARN("MISPLACED_INIT", 64378716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 64388716de38SJoe Perches $fix) { 6439194f66fcSJoe 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; 64408716de38SJoe Perches } 64418716de38SJoe Perches } 64428716de38SJoe Perches } 64438716de38SJoe Perches 6444e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 6445e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 6446e970b884SJoe Perches my $attr = $1; 6447e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 6448e970b884SJoe Perches my $attr_prefix = $1; 6449e970b884SJoe Perches my $attr_type = $2; 6450e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6451e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 6452e970b884SJoe Perches $fix) { 6453194f66fcSJoe Perches $fixed[$fixlinenr] =~ 6454e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 6455e970b884SJoe Perches } 6456e970b884SJoe Perches } 6457e970b884SJoe Perches 6458e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 6459e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 6460e970b884SJoe Perches my $attr = $1; 6461e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6462e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 6463e970b884SJoe Perches $fix) { 6464194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 6465e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 6466e970b884SJoe Perches $lead = rtrim($1); 6467e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 6468e970b884SJoe Perches $lead = "${lead}const "; 6469194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 6470e970b884SJoe Perches } 6471e970b884SJoe Perches } 6472e970b884SJoe Perches 6473c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 6474c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 6475c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 6476c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 6477c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 6478c17893c7SJoe Perches $fix) { 6479c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 6480c17893c7SJoe Perches } 6481c17893c7SJoe Perches } 6482c17893c7SJoe Perches 6483fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 6484fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 6485fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 6486fbdb8138SJoe Perches my $constant_func = $1; 6487fbdb8138SJoe Perches my $func = $constant_func; 6488fbdb8138SJoe Perches $func =~ s/^__constant_//; 6489fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 6490fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 6491fbdb8138SJoe Perches $fix) { 6492194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 6493fbdb8138SJoe Perches } 6494fbdb8138SJoe Perches } 6495fbdb8138SJoe Perches 64961a15a250SPatrick Pannuto# prefer usleep_range over udelay 649737581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 649843c1d77cSJoe Perches my $delay = $1; 64991a15a250SPatrick Pannuto # ignore udelay's < 10, however 650043c1d77cSJoe Perches if (! ($delay < 10) ) { 6501000d1cc1SJoe Perches CHK("USLEEP_RANGE", 6502458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 650343c1d77cSJoe Perches } 650443c1d77cSJoe Perches if ($delay > 2000) { 650543c1d77cSJoe Perches WARN("LONG_UDELAY", 650643c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 65071a15a250SPatrick Pannuto } 65081a15a250SPatrick Pannuto } 65091a15a250SPatrick Pannuto 651009ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 651109ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 651209ef8725SPatrick Pannuto if ($1 < 20) { 6513000d1cc1SJoe Perches WARN("MSLEEP", 6514458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 651509ef8725SPatrick Pannuto } 651609ef8725SPatrick Pannuto } 651709ef8725SPatrick Pannuto 651836ec1939SJoe Perches# check for comparisons of jiffies 651936ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 652036ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 652136ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 652236ec1939SJoe Perches } 652336ec1939SJoe Perches 65249d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 65259d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 65269d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 65279d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 65289d7a34a5SJoe Perches } 65299d7a34a5SJoe Perches 653000df344fSAndy Whitcroft# warn about #ifdefs in C files 6531c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 653200df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 653300df344fSAndy Whitcroft# print "$herecurr"; 653400df344fSAndy Whitcroft# $clean = 0; 653500df344fSAndy Whitcroft# } 653600df344fSAndy Whitcroft 653722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 6538c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 65393705ce5bSJoe Perches if (ERROR("SPACING", 65403705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 65413705ce5bSJoe Perches $fix) { 6542194f66fcSJoe Perches $fixed[$fixlinenr] =~ 65433705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 65443705ce5bSJoe Perches } 65453705ce5bSJoe Perches 654622f2a2efSAndy Whitcroft } 654722f2a2efSAndy Whitcroft 65484a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 6549171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 6550171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 65514a0df2efSAndy Whitcroft my $which = $1; 65524a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6553000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 6554000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 65554a0df2efSAndy Whitcroft } 65564a0df2efSAndy Whitcroft } 65574a0df2efSAndy Whitcroft# check for memory barriers without a comment. 6558402c2553SMichael S. Tsirkin 6559402c2553SMichael S. Tsirkin my $barriers = qr{ 6560402c2553SMichael S. Tsirkin mb| 6561402c2553SMichael S. Tsirkin rmb| 6562ad83ec6cSWill Deacon wmb 6563402c2553SMichael S. Tsirkin }x; 6564402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 6565402c2553SMichael S. Tsirkin mb__before_atomic| 6566402c2553SMichael S. Tsirkin mb__after_atomic| 6567402c2553SMichael S. Tsirkin store_release| 6568402c2553SMichael S. Tsirkin load_acquire| 6569402c2553SMichael S. Tsirkin store_mb| 6570402c2553SMichael S. Tsirkin (?:$barriers) 6571402c2553SMichael S. Tsirkin }x; 6572402c2553SMichael S. Tsirkin my $all_barriers = qr{ 6573402c2553SMichael S. Tsirkin (?:$barriers)| 657443e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 657543e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 6576402c2553SMichael S. Tsirkin }x; 6577402c2553SMichael S. Tsirkin 6578402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 65794a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6580c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 6581000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 65824a0df2efSAndy Whitcroft } 65834a0df2efSAndy Whitcroft } 65843ad81779SPaul E. McKenney 6585f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 6586f4073b0fSMichael S. Tsirkin 6587f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 6588f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 6589f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 6590f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 6591f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 6592f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 6593f4073b0fSMichael S. Tsirkin } 6594f4073b0fSMichael S. Tsirkin 6595cb426e99SJoe Perches# check for waitqueue_active without a comment. 6596cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 6597cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 6598cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 6599cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 6600cb426e99SJoe Perches } 6601cb426e99SJoe Perches } 66023ad81779SPaul E. McKenney 66035099a722SMarco Elver# check for data_race without a comment. 66045099a722SMarco Elver if ($line =~ /\bdata_race\s*\(/) { 66055099a722SMarco Elver if (!ctx_has_comment($first_line, $linenr)) { 66065099a722SMarco Elver WARN("DATA_RACE", 66075099a722SMarco Elver "data_race without comment\n" . $herecurr); 66085099a722SMarco Elver } 66095099a722SMarco Elver } 66105099a722SMarco Elver 66114a0df2efSAndy Whitcroft# check of hardware specific defines 6612c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 6613000d1cc1SJoe Perches CHK("ARCH_DEFINES", 6614000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 66150a920b5bSAndy Whitcroft } 6616653d4876SAndy Whitcroft 6617596ed45bSJoe Perches# check that the storage class is not after a type 6618596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 6619000d1cc1SJoe Perches WARN("STORAGE_CLASS", 6620596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 6621596ed45bSJoe Perches } 6622596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 6623596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 6624596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 6625596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 6626596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 6627596ed45bSJoe Perches WARN("STORAGE_CLASS", 6628596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 6629d4977c78STobias Klauser } 6630d4977c78STobias Klauser 6631de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 6632de7d4f0eSAndy Whitcroft# storage class and type. 66339c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 66349c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 6635000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 6636000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 6637de7d4f0eSAndy Whitcroft } 6638de7d4f0eSAndy Whitcroft 66398905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 66402b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 66412b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 6642d5e616fcSJoe Perches if (WARN("INLINE", 6643d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 6644d5e616fcSJoe Perches $fix) { 6645194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 6646d5e616fcSJoe Perches 6647d5e616fcSJoe Perches } 66488905a67cSAndy Whitcroft } 66498905a67cSAndy Whitcroft 66507ebe1d17SDwaipayan Ray# Check for compiler attributes 66512b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 66527ebe1d17SDwaipayan Ray $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { 66537ebe1d17SDwaipayan Ray my $attr = $1; 66547ebe1d17SDwaipayan Ray $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; 66557ebe1d17SDwaipayan Ray 66567ebe1d17SDwaipayan Ray my %attr_list = ( 66570830aab0SJoe Perches "alias" => "__alias", 66587ebe1d17SDwaipayan Ray "aligned" => "__aligned", 66597ebe1d17SDwaipayan Ray "always_inline" => "__always_inline", 66607ebe1d17SDwaipayan Ray "assume_aligned" => "__assume_aligned", 66617ebe1d17SDwaipayan Ray "cold" => "__cold", 66627ebe1d17SDwaipayan Ray "const" => "__attribute_const__", 66637ebe1d17SDwaipayan Ray "copy" => "__copy", 66647ebe1d17SDwaipayan Ray "designated_init" => "__designated_init", 66657ebe1d17SDwaipayan Ray "externally_visible" => "__visible", 66667ebe1d17SDwaipayan Ray "format" => "printf|scanf", 66677ebe1d17SDwaipayan Ray "gnu_inline" => "__gnu_inline", 66687ebe1d17SDwaipayan Ray "malloc" => "__malloc", 66697ebe1d17SDwaipayan Ray "mode" => "__mode", 66707ebe1d17SDwaipayan Ray "no_caller_saved_registers" => "__no_caller_saved_registers", 66717ebe1d17SDwaipayan Ray "noclone" => "__noclone", 66727ebe1d17SDwaipayan Ray "noinline" => "noinline", 66737ebe1d17SDwaipayan Ray "nonstring" => "__nonstring", 66747ebe1d17SDwaipayan Ray "noreturn" => "__noreturn", 66757ebe1d17SDwaipayan Ray "packed" => "__packed", 66767ebe1d17SDwaipayan Ray "pure" => "__pure", 6677339f29d9SJoe Perches "section" => "__section", 66780830aab0SJoe Perches "used" => "__used", 66790830aab0SJoe Perches "weak" => "__weak" 66807ebe1d17SDwaipayan Ray ); 66817ebe1d17SDwaipayan Ray 66827ebe1d17SDwaipayan Ray while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { 6683339f29d9SJoe Perches my $orig_attr = $1; 66847ebe1d17SDwaipayan Ray my $params = ''; 66857ebe1d17SDwaipayan Ray $params = $2 if defined($2); 6686339f29d9SJoe Perches my $curr_attr = $orig_attr; 66877ebe1d17SDwaipayan Ray $curr_attr =~ s/^[\s_]+|[\s_]+$//g; 66887ebe1d17SDwaipayan Ray if (exists($attr_list{$curr_attr})) { 6689339f29d9SJoe Perches my $new = $attr_list{$curr_attr}; 66907ebe1d17SDwaipayan Ray if ($curr_attr eq "format" && $params) { 66917ebe1d17SDwaipayan Ray $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; 6692339f29d9SJoe Perches $new = "__$1\($2"; 66937ebe1d17SDwaipayan Ray } else { 6694339f29d9SJoe Perches $new = "$new$params"; 66957ebe1d17SDwaipayan Ray } 66967ebe1d17SDwaipayan Ray if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 6697339f29d9SJoe Perches "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && 66987ebe1d17SDwaipayan Ray $fix) { 6699339f29d9SJoe Perches my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; 6700339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/$remove//; 6701339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; 6702339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; 6703339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; 67047ebe1d17SDwaipayan Ray } 670539b7e287SJoe Perches } 6706462811d9SJoe Perches } 6707462811d9SJoe Perches 67087ebe1d17SDwaipayan Ray # Check for __attribute__ unused, prefer __always_unused or __maybe_unused 67097ebe1d17SDwaipayan Ray if ($attr =~ /^_*unused/) { 67107ebe1d17SDwaipayan Ray WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 67117ebe1d17SDwaipayan Ray "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); 6712d5e616fcSJoe Perches } 67136061d949SJoe Perches } 67146061d949SJoe Perches 6715619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 67165b57980dSJoe Perches if ($perl_version_ok && 6717619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 6718619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 6719619a908aSJoe Perches $line =~ /\b__weak\b/)) { 6720619a908aSJoe Perches ERROR("WEAK_DECLARATION", 6721619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 6722619a908aSJoe Perches } 6723619a908aSJoe Perches 6724fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 6725e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6726fd39f904STomas Winkler $realfile !~ m@\btools/@ && 6727e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 6728e6176fa4SJoe Perches my $type = $1; 6729e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 6730e6176fa4SJoe Perches $type = $1; 6731e6176fa4SJoe Perches my $kernel_type = 'u'; 6732e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6733e6176fa4SJoe Perches $type =~ /(\d+)/; 6734e6176fa4SJoe Perches $kernel_type .= $1; 6735e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6736e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6737e6176fa4SJoe Perches $fix) { 6738e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6739e6176fa4SJoe Perches } 6740e6176fa4SJoe Perches } 6741e6176fa4SJoe Perches } 6742e6176fa4SJoe Perches 6743938224b5SJoe Perches# check for cast of C90 native int or longer types constants 6744938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6745938224b5SJoe Perches my $cast = $1; 6746938224b5SJoe Perches my $const = $2; 6747938224b5SJoe Perches my $suffix = ""; 6748938224b5SJoe Perches my $newconst = $const; 6749938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 6750938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6751938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6752938224b5SJoe Perches $suffix .= 'LL'; 6753938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 6754938224b5SJoe Perches $suffix .= 'L'; 6755938224b5SJoe Perches } 67560972b8bfSJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 67570972b8bfSJoe Perches "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) && 67580972b8bfSJoe Perches $fix) { 6759938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6760938224b5SJoe Perches } 6761938224b5SJoe Perches } 6762938224b5SJoe Perches 67638f53a9b8SJoe Perches# check for sizeof(&) 67648f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6765000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 6766000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 67678f53a9b8SJoe Perches } 67688f53a9b8SJoe Perches 676966c80b60SJoe Perches# check for sizeof without parenthesis 677066c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 6771d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 6772d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6773d5e616fcSJoe Perches $fix) { 6774194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6775d5e616fcSJoe Perches } 677666c80b60SJoe Perches } 677766c80b60SJoe Perches 677888982feaSJoe Perches# check for struct spinlock declarations 677988982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 678088982feaSJoe Perches WARN("USE_SPINLOCK_T", 678188982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 678288982feaSJoe Perches } 678388982feaSJoe Perches 6784a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 678506668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6786a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 6787caac1d5fSHeba Aamer $fmt =~ s/%%//g; 6788caac1d5fSHeba Aamer if ($fmt !~ /%/) { 6789d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 6790d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6791d5e616fcSJoe Perches $fix) { 6792194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6793d5e616fcSJoe Perches } 6794a6962d72SJoe Perches } 6795a6962d72SJoe Perches } 6796a6962d72SJoe Perches 67970b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 67985b57980dSJoe Perches if ($perl_version_ok && 67990b523769SJoe Perches defined $stat && 68000b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 68010b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6802e3c6bc95STobin C. Harding my $stat_real; 6803e3c6bc95STobin C. Harding 68040b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 68050b523769SJoe Perches $lc = $lc + $linenr; 68060b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6807ffe07513SJoe Perches my $specifier; 6808ffe07513SJoe Perches my $extension; 68093bd32d6aSSakari Ailus my $qualifier; 6810ffe07513SJoe Perches my $bad_specifier = ""; 68110b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 68120b523769SJoe Perches $fmt =~ s/%%//g; 6813e3c6bc95STobin C. Harding 68143bd32d6aSSakari Ailus while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 6815e3c6bc95STobin C. Harding $specifier = $1; 6816e3c6bc95STobin C. Harding $extension = $2; 68173bd32d6aSSakari Ailus $qualifier = $3; 6818af612e43SSakari Ailus if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 68193bd32d6aSSakari Ailus ($extension eq "f" && 6820af612e43SSakari Ailus defined $qualifier && $qualifier !~ /^w/) || 6821af612e43SSakari Ailus ($extension eq "4" && 6822af612e43SSakari Ailus defined $qualifier && $qualifier !~ /^cc/)) { 6823e3c6bc95STobin C. Harding $bad_specifier = $specifier; 68240b523769SJoe Perches last; 68250b523769SJoe Perches } 6826e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6827e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6828e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 68290b523769SJoe Perches } 6830e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6831e3c6bc95STobin 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"); 6832e3c6bc95STobin C. Harding } 6833e3c6bc95STobin C. Harding } 6834e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 68352a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 68361df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 68371df7338aSSergey Senozhatsky my $use = ""; 6838e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 68391df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6840e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 68411df7338aSSergey Senozhatsky } 68422a9f9d85STobin C. Harding 68430b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 6844e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6845e3c6bc95STobin C. Harding } 68460b523769SJoe Perches } 68470b523769SJoe Perches } 68480b523769SJoe Perches 6849554e165cSAndy Whitcroft# Check for misused memsets 68505b57980dSJoe Perches if ($perl_version_ok && 6851d1fe9c09SJoe Perches defined $stat && 68529e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6853554e165cSAndy Whitcroft 6854d7c76ba7SJoe Perches my $ms_addr = $2; 6855d1fe9c09SJoe Perches my $ms_val = $7; 6856d1fe9c09SJoe Perches my $ms_size = $12; 6857d7c76ba7SJoe Perches 6858554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6859554e165cSAndy Whitcroft ERROR("MEMSET", 6860d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6861554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6862554e165cSAndy Whitcroft WARN("MEMSET", 6863d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6864d7c76ba7SJoe Perches } 6865d7c76ba7SJoe Perches } 6866d7c76ba7SJoe Perches 686798a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 68685b57980dSJoe Perches# if ($perl_version_ok && 6869f333195dSJoe Perches# defined $stat && 6870f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6871f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6872f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6873f333195dSJoe Perches# $fix) { 6874f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6875f333195dSJoe Perches# } 6876f333195dSJoe Perches# } 687798a9bba5SJoe Perches 6878b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 68795b57980dSJoe Perches# if ($perl_version_ok && 6880f333195dSJoe Perches# defined $stat && 6881f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6882f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6883f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6884f333195dSJoe Perches# } 6885b6117d17SMateusz Kulikowski 68868617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 68878617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 68885b57980dSJoe Perches# if ($perl_version_ok && 6889f333195dSJoe Perches# defined $stat && 6890f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6891f333195dSJoe Perches# 6892f333195dSJoe Perches# my $ms_val = $7; 6893f333195dSJoe Perches# 6894f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6895f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6896f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6897f333195dSJoe Perches# $fix) { 6898f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6899f333195dSJoe Perches# } 6900f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6901f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6902f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6903f333195dSJoe Perches# $fix) { 6904f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6905f333195dSJoe Perches# } 6906f333195dSJoe Perches# } 6907f333195dSJoe Perches# } 69088617cd09SMateusz Kulikowski 69095dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy 69105dbdb2d8SJoe Perches if ($line =~ /\bstrlcpy\s*\(/) { 69115dbdb2d8SJoe Perches WARN("STRLCPY", 69125dbdb2d8SJoe Perches "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr); 69135dbdb2d8SJoe Perches } 69145dbdb2d8SJoe Perches 6915d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 69165b57980dSJoe Perches if ($perl_version_ok && 6917d1fe9c09SJoe Perches defined $stat && 6918d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6919d1fe9c09SJoe Perches if (defined $2 || defined $7) { 6920d7c76ba7SJoe Perches my $call = $1; 6921d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 6922d7c76ba7SJoe Perches my $arg1 = $3; 6923d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 6924d1fe9c09SJoe Perches my $arg2 = $8; 6925d7c76ba7SJoe Perches my $cast; 6926d7c76ba7SJoe Perches 6927d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 6928d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 6929d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 6930d7c76ba7SJoe Perches $cast = $cast1; 6931d7c76ba7SJoe Perches } else { 6932d7c76ba7SJoe Perches $cast = $cast2; 6933d7c76ba7SJoe Perches } 6934d7c76ba7SJoe Perches WARN("MINMAX", 6935d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 6936554e165cSAndy Whitcroft } 6937554e165cSAndy Whitcroft } 6938554e165cSAndy Whitcroft 69394a273195SJoe Perches# check usleep_range arguments 69405b57980dSJoe Perches if ($perl_version_ok && 69414a273195SJoe Perches defined $stat && 69424a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 69434a273195SJoe Perches my $min = $1; 69444a273195SJoe Perches my $max = $7; 69454a273195SJoe Perches if ($min eq $max) { 69464a273195SJoe Perches WARN("USLEEP_RANGE", 6947458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 69484a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 69494a273195SJoe Perches $min > $max) { 69504a273195SJoe Perches WARN("USLEEP_RANGE", 6951458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 69524a273195SJoe Perches } 69534a273195SJoe Perches } 69544a273195SJoe Perches 6955823b794cSJoe Perches# check for naked sscanf 69565b57980dSJoe Perches if ($perl_version_ok && 6957823b794cSJoe Perches defined $stat && 69586c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 6959823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6960823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 6961823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6962823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 6963823b794cSJoe Perches $lc = $lc + $linenr; 69642a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6965823b794cSJoe Perches WARN("NAKED_SSCANF", 6966823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6967823b794cSJoe Perches } 6968823b794cSJoe Perches 6969afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 69705b57980dSJoe Perches if ($perl_version_ok && 6971afc819abSJoe Perches defined $stat && 6972afc819abSJoe Perches $line =~ /\bsscanf\b/) { 6973afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 6974afc819abSJoe Perches $lc = $lc + $linenr; 69752a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6976afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6977afc819abSJoe Perches my $format = $6; 6978afc819abSJoe Perches my $count = $format =~ tr@%@%@; 6979afc819abSJoe Perches if ($count == 1 && 6980afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 6981afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 6982afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 6983afc819abSJoe Perches } 6984afc819abSJoe Perches } 6985afc819abSJoe Perches } 6986afc819abSJoe Perches 698770dc8a48SJoe Perches# check for new externs in .h files. 698870dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 698970dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 6990d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 699170dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 699270dc8a48SJoe Perches $fix) { 6993194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 699470dc8a48SJoe Perches } 699570dc8a48SJoe Perches } 699670dc8a48SJoe Perches 6997de7d4f0eSAndy Whitcroft# check for new externs in .c files. 6998171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 6999c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 7000171ae1a4SAndy Whitcroft { 7001c45dcabdSAndy Whitcroft my $function_name = $1; 7002c45dcabdSAndy Whitcroft my $paren_space = $2; 7003171ae1a4SAndy Whitcroft 7004171ae1a4SAndy Whitcroft my $s = $stat; 7005171ae1a4SAndy Whitcroft if (defined $cond) { 7006171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 7007171ae1a4SAndy Whitcroft } 7008d8b44b58SKees Cook if ($s =~ /^\s*;/) 7009c45dcabdSAndy Whitcroft { 7010000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 7011000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 7012de7d4f0eSAndy Whitcroft } 7013de7d4f0eSAndy Whitcroft 7014171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 7015000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 7016000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 7017171ae1a4SAndy Whitcroft } 70189c9ba34eSAndy Whitcroft 70199c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 70209c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 70219c9ba34eSAndy Whitcroft { 7022000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 7023000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 7024171ae1a4SAndy Whitcroft } 7025171ae1a4SAndy Whitcroft 7026a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 7027a0ad7596SJoe Perches if (defined $stat && 7028d8b44b58SKees Cook $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 7029d8b44b58SKees Cook $1 ne "void") { 7030d8b44b58SKees Cook my $args = trim($1); 7031ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 7032ca0d8929SJoe Perches my $arg = trim($1); 7033d8b44b58SKees Cook if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 7034ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 7035ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 7036ca0d8929SJoe Perches } 7037ca0d8929SJoe Perches } 7038ca0d8929SJoe Perches } 7039ca0d8929SJoe Perches 7040a0ad7596SJoe Perches# check for function definitions 70415b57980dSJoe Perches if ($perl_version_ok && 7042a0ad7596SJoe Perches defined $stat && 7043a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 7044a0ad7596SJoe Perches $context_function = $1; 7045a0ad7596SJoe Perches 7046a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 7047a0ad7596SJoe Perches my $ok = 0; 7048a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 7049a0ad7596SJoe Perches my $herectx = $here . "\n"; 7050a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 7051a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 7052a0ad7596SJoe Perches $herectx .= $rl . "\n"; 7053a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 7054a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 7055a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 7056a0ad7596SJoe Perches } 7057a0ad7596SJoe Perches if (!$ok) { 7058a0ad7596SJoe Perches ERROR("OPEN_BRACE", 7059a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 7060a0ad7596SJoe Perches } 7061a0ad7596SJoe Perches } 7062a0ad7596SJoe Perches 7063de7d4f0eSAndy Whitcroft# checks for new __setup's 7064de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 7065de7d4f0eSAndy Whitcroft my $name = $1; 7066de7d4f0eSAndy Whitcroft 7067de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 7068000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 70692581ac7cSTim Froidcoeur "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); 7070de7d4f0eSAndy Whitcroft } 7071653d4876SAndy Whitcroft } 70729c0ca6f9SAndy Whitcroft 7073e29a70f1SJoe Perches# check for pointless casting of alloc functions 7074e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 7075000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 7076000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 70779c0ca6f9SAndy Whitcroft } 707813214adfSAndy Whitcroft 7079a640d25cSJoe Perches# alloc style 7080a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 70815b57980dSJoe Perches if ($perl_version_ok && 7082e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 7083a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 7084a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 7085a640d25cSJoe Perches } 7086a640d25cSJoe Perches 708773f1d07eSGustavo A. R. Silva# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc 70885b57980dSJoe Perches if ($perl_version_ok && 70891b4a2ed4SJoe Perches defined $stat && 709073f1d07eSGustavo A. R. Silva $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 709160a55369SJoe Perches my $oldfunc = $3; 709260a55369SJoe Perches my $a1 = $4; 709360a55369SJoe Perches my $a2 = $10; 709460a55369SJoe Perches my $newfunc = "kmalloc_array"; 709573f1d07eSGustavo A. R. Silva $newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc"); 709673f1d07eSGustavo A. R. Silva $newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc"); 709760a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 709860a55369SJoe Perches my $r1 = $a1; 709960a55369SJoe Perches my $r2 = $a2; 710060a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 710160a55369SJoe Perches $r1 = $a2; 710260a55369SJoe Perches $r2 = $a1; 710360a55369SJoe Perches } 7104e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 7105e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 71061b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 7107e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 7108e3d95a2aSTobin C. Harding 7109e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 71101b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 71111b4a2ed4SJoe Perches $cnt == 1 && 7112e367455aSJoe Perches $fix) { 711373f1d07eSGustavo A. R. Silva $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; 711460a55369SJoe Perches } 711560a55369SJoe Perches } 711660a55369SJoe Perches } 711760a55369SJoe Perches 7118972fdea2SJoe Perches# check for krealloc arg reuse 71195b57980dSJoe Perches if ($perl_version_ok && 71204cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 71214cab63ceSJoe Perches $1 eq $3) { 7122972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 7123972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 7124972fdea2SJoe Perches } 7125972fdea2SJoe Perches 71265ce59ae0SJoe Perches# check for alloc argument mismatch 71277e6cdd7fSChristophe JAILLET if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) { 71285ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 71295ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 71305ce59ae0SJoe Perches } 71315ce59ae0SJoe Perches 7132caf2a54fSJoe Perches# check for multiple semicolons 7133caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 7134d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 7135d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 7136d5e616fcSJoe Perches $fix) { 7137194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 7138d5e616fcSJoe Perches } 7139d1e2ad07SJoe Perches } 7140d1e2ad07SJoe Perches 7141cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 7142cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 7143cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 71440ab90191SJoe Perches my $ull = ""; 71450ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 71460ab90191SJoe Perches if (CHK("BIT_MACRO", 71470ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 71480ab90191SJoe Perches $fix) { 71490ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 71500ab90191SJoe Perches } 71510ab90191SJoe Perches } 71520ab90191SJoe Perches 715350161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) 71543e89ad85SJerome Forissier if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { 715550161266SJoe Perches WARN("IS_ENABLED_CONFIG", 71563e89ad85SJerome Forissier "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); 715750161266SJoe Perches } 715850161266SJoe Perches 71592d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 71603e89ad85SJerome 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*$/) { 71612d632745SJoe Perches my $config = $1; 71622d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 71633e89ad85SJerome Forissier "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && 71642d632745SJoe Perches $fix) { 71652d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 71662d632745SJoe Perches } 71672d632745SJoe Perches } 71682d632745SJoe Perches 7169f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 7170f36d3eb8SJoe Perches my @fallthroughs = ( 7171f36d3eb8SJoe Perches 'fallthrough', 7172f36d3eb8SJoe Perches '@fallthrough@', 7173f36d3eb8SJoe Perches 'lint -fallthrough[ \t]*', 7174f36d3eb8SJoe Perches 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 7175f36d3eb8SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 7176f36d3eb8SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 7177f36d3eb8SJoe Perches 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 7178f36d3eb8SJoe Perches ); 7179f36d3eb8SJoe Perches if ($raw_comment ne '') { 7180f36d3eb8SJoe Perches foreach my $ft (@fallthroughs) { 7181f36d3eb8SJoe Perches if ($raw_comment =~ /$ft/) { 7182f36d3eb8SJoe Perches my $msg_level = \&WARN; 7183f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 7184f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 7185f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 7186f36d3eb8SJoe Perches last; 7187f36d3eb8SJoe Perches } 7188f36d3eb8SJoe Perches } 7189f36d3eb8SJoe Perches } 7190f36d3eb8SJoe Perches 7191d1e2ad07SJoe Perches# check for switch/default statements without a break; 71925b57980dSJoe Perches if ($perl_version_ok && 7193d1e2ad07SJoe Perches defined $stat && 7194d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 7195d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 7196e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 7197e3d95a2aSTobin C. Harding 7198d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 7199d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 7200caf2a54fSJoe Perches } 7201caf2a54fSJoe Perches 720213214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 7203d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 7204d5e616fcSJoe Perches if (WARN("USE_FUNC", 7205d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 7206d5e616fcSJoe Perches $fix) { 7207194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 7208d5e616fcSJoe Perches } 720913214adfSAndy Whitcroft } 7210773647a0SAndy Whitcroft 721162ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 721262ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 721362ec818fSJoe Perches ERROR("DATE_TIME", 721462ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 721562ec818fSJoe Perches } 721662ec818fSJoe Perches 72172c92488aSJoe Perches# check for use of yield() 72182c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 72192c92488aSJoe Perches WARN("YIELD", 72202c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 72212c92488aSJoe Perches } 72222c92488aSJoe Perches 7223179f8f40SJoe Perches# check for comparisons against true and false 7224179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 7225179f8f40SJoe Perches my $lead = $1; 7226179f8f40SJoe Perches my $arg = $2; 7227179f8f40SJoe Perches my $test = $3; 7228179f8f40SJoe Perches my $otype = $4; 7229179f8f40SJoe Perches my $trail = $5; 7230179f8f40SJoe Perches my $op = "!"; 7231179f8f40SJoe Perches 7232179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 7233179f8f40SJoe Perches 7234179f8f40SJoe Perches my $type = lc($otype); 7235179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 7236179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 7237179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 7238179f8f40SJoe Perches $op = ""; 7239179f8f40SJoe Perches } 7240179f8f40SJoe Perches 7241179f8f40SJoe Perches CHK("BOOL_COMPARISON", 7242179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 7243179f8f40SJoe Perches 7244179f8f40SJoe Perches## maybe suggesting a correct construct would better 7245179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 7246179f8f40SJoe Perches 7247179f8f40SJoe Perches } 7248179f8f40SJoe Perches } 7249179f8f40SJoe Perches 72504882720bSThomas Gleixner# check for semaphores initialized locked 72514882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 7252000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 7253000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 7254773647a0SAndy Whitcroft } 72556712d858SJoe Perches 725667d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 725767d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 7258000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 725967d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 7260773647a0SAndy Whitcroft } 72616712d858SJoe Perches 7262ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 7263f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 7264000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 7265ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 7266f3db6639SMichael Ellerman } 72676712d858SJoe Perches 72683d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 72693d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 72703d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 72713d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 72723d709ab5SPaul E. McKenney } 72733d709ab5SPaul E. McKenney 72749189c7e7SJoe Perches# check for deprecated apis 72759189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 72769189c7e7SJoe Perches my $deprecated_api = $1; 72779189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 72789189c7e7SJoe Perches WARN("DEPRECATED_API", 72799189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 72809189c7e7SJoe Perches } 72819189c7e7SJoe Perches 72820f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 7283d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 7284ced69da1SQuentin Monnet if (defined($const_structs) && 7285ced69da1SQuentin Monnet $line !~ /\bconst\b/ && 7286d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 7287000d1cc1SJoe Perches WARN("CONST_STRUCT", 7288d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 72892b6db5cbSAndy Whitcroft } 7290773647a0SAndy Whitcroft 7291773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 7292773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 729335cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS 7294773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 7295c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 7296c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 7297171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 7298171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 729935cdcbfcSPeng Wang $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ && 730035cdcbfcSPeng Wang $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/) 7301773647a0SAndy Whitcroft { 7302000d1cc1SJoe Perches WARN("NR_CPUS", 7303000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 7304773647a0SAndy Whitcroft } 73059c9ba34eSAndy Whitcroft 730652ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 730752ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 730852ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 730952ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 731052ea8506SJoe Perches } 731152ea8506SJoe Perches 7312acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 73135b57980dSJoe Perches if ($perl_version_ok && 7314acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 7315acd9362cSJoe Perches WARN("LIKELY_MISUSE", 7316acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 7317acd9362cSJoe Perches } 7318acd9362cSJoe Perches 7319fbe74541SJoe Perches# return sysfs_emit(foo, fmt, ...) fmt without newline 7320fbe74541SJoe Perches if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ && 7321fbe74541SJoe Perches substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) { 7322fbe74541SJoe Perches my $offset = $+[6] - 1; 7323fbe74541SJoe Perches if (WARN("SYSFS_EMIT", 7324fbe74541SJoe Perches "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) && 7325fbe74541SJoe Perches $fix) { 7326fbe74541SJoe Perches substr($fixed[$fixlinenr], $offset, 0) = '\\n'; 7327fbe74541SJoe Perches } 7328fbe74541SJoe Perches } 7329fbe74541SJoe Perches 7330de3f186fSDenis Efremov# nested likely/unlikely calls 7331de3f186fSDenis Efremov if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 7332de3f186fSDenis Efremov WARN("LIKELY_MISUSE", 7333de3f186fSDenis Efremov "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 7334de3f186fSDenis Efremov } 7335de3f186fSDenis Efremov 7336691d77b6SAndy Whitcroft# whine mightly about in_atomic 7337691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 7338691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 7339000d1cc1SJoe Perches ERROR("IN_ATOMIC", 7340000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 7341f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 7342000d1cc1SJoe Perches WARN("IN_ATOMIC", 7343000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 7344691d77b6SAndy Whitcroft } 7345691d77b6SAndy Whitcroft } 73461704f47bSPeter Zijlstra 73471704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 73481704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 73491704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 73501704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 73511704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 73521704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 7353000d1cc1SJoe Perches ERROR("LOCKDEP", 7354000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 73551704f47bSPeter Zijlstra } 73561704f47bSPeter Zijlstra } 735788f8831cSDave Jones 7358b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 7359b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 7360000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 7361000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 736288f8831cSDave Jones } 73632435880fSJoe Perches 736400180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 736500180468SJoe Perches# and whether or not function naming is typical and if 736600180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 73675b57980dSJoe Perches if ($perl_version_ok && 736800180468SJoe Perches defined $stat && 736900180468SJoe 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*\)/) { 737000180468SJoe Perches my $var = $1; 737100180468SJoe Perches my $perms = $2; 737200180468SJoe Perches my $show = $3; 737300180468SJoe Perches my $store = $4; 737400180468SJoe Perches my $octal_perms = perms_to_octal($perms); 737500180468SJoe Perches if ($show =~ /^${var}_show$/ && 737600180468SJoe Perches $store =~ /^${var}_store$/ && 737700180468SJoe Perches $octal_perms eq "0644") { 737800180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 737900180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 738000180468SJoe Perches $fix) { 738100180468SJoe 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})/; 738200180468SJoe Perches } 738300180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 738400180468SJoe Perches $store =~ /^NULL$/ && 738500180468SJoe Perches $octal_perms eq "0444") { 738600180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 738700180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 738800180468SJoe Perches $fix) { 738900180468SJoe 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})/; 739000180468SJoe Perches } 739100180468SJoe Perches } elsif ($show =~ /^NULL$/ && 739200180468SJoe Perches $store =~ /^${var}_store$/ && 739300180468SJoe Perches $octal_perms eq "0200") { 739400180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 739500180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 739600180468SJoe Perches $fix) { 739700180468SJoe 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})/; 739800180468SJoe Perches } 739900180468SJoe Perches } elsif ($octal_perms eq "0644" || 740000180468SJoe Perches $octal_perms eq "0444" || 740100180468SJoe Perches $octal_perms eq "0200") { 740200180468SJoe Perches my $newshow = "$show"; 740300180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 740400180468SJoe Perches my $newstore = $store; 740500180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 740600180468SJoe Perches my $rename = ""; 740700180468SJoe Perches if ($show ne $newshow) { 740800180468SJoe Perches $rename .= " '$show' to '$newshow'"; 740900180468SJoe Perches } 741000180468SJoe Perches if ($store ne $newstore) { 741100180468SJoe Perches $rename .= " '$store' to '$newstore'"; 741200180468SJoe Perches } 741300180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 741400180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 741500180468SJoe Perches } else { 741600180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 741700180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 741800180468SJoe Perches } 741900180468SJoe Perches } 742000180468SJoe Perches 7421515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 7422515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 742373121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 742473121534SJoe Perches# specific definition of not visible in sysfs. 742573121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 742673121534SJoe Perches# use the default permissions 74275b57980dSJoe Perches if ($perl_version_ok && 7428459cf0aeSJoe Perches defined $stat && 7429515a235eSJoe Perches $line =~ /$mode_perms_search/) { 74302435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 74312435880fSJoe Perches my $func = $entry->[0]; 74322435880fSJoe Perches my $arg_pos = $entry->[1]; 74332435880fSJoe Perches 7434459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 7435459cf0aeSJoe Perches $lc = $lc + $linenr; 74362a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 7437459cf0aeSJoe Perches 74382435880fSJoe Perches my $skip_args = ""; 74392435880fSJoe Perches if ($arg_pos > 1) { 74402435880fSJoe Perches $arg_pos--; 74412435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 74422435880fSJoe Perches } 7443f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 7444459cf0aeSJoe Perches if ($stat =~ /$test/) { 74452435880fSJoe Perches my $val = $1; 74462435880fSJoe Perches $val = $6 if ($skip_args ne ""); 744773121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 744873121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 744973121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 74502435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 7451459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 7452f90774e1SJoe Perches } 7453f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 7454c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 7455459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 74562435880fSJoe Perches } 7457459cf0aeSJoe Perches } 7458459cf0aeSJoe Perches } 7459459cf0aeSJoe Perches } 7460459cf0aeSJoe Perches 7461459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 7462bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 746300180468SJoe Perches my $oval = $1; 746400180468SJoe Perches my $octal = perms_to_octal($oval); 7465f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 7466459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 7467f90774e1SJoe Perches $fix) { 746800180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 74692435880fSJoe Perches } 747013214adfSAndy Whitcroft } 74715a6d20ceSBjorn Andersson 74725a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 74735a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 74745a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 74755a6d20ceSBjorn Andersson my $valid_licenses = qr{ 74765a6d20ceSBjorn Andersson GPL| 74775a6d20ceSBjorn Andersson GPL\ v2| 74785a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 74795a6d20ceSBjorn Andersson Dual\ BSD/GPL| 74805a6d20ceSBjorn Andersson Dual\ MIT/GPL| 74815a6d20ceSBjorn Andersson Dual\ MPL/GPL| 74825a6d20ceSBjorn Andersson Proprietary 74835a6d20ceSBjorn Andersson }x; 74845a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 74855a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 74865a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 74875a6d20ceSBjorn Andersson } 74886e8f42dcSJoe Perches if (!$file && $extracted_string eq '"GPL v2"') { 74896e8f42dcSJoe Perches if (WARN("MODULE_LICENSE", 74906e8f42dcSJoe Perches "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) && 74916e8f42dcSJoe Perches $fix) { 74926e8f42dcSJoe Perches $fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/; 74936e8f42dcSJoe Perches } 74946e8f42dcSJoe Perches } 74955a6d20ceSBjorn Andersson } 74966a8d76cbSMatteo Croce 74976a8d76cbSMatteo Croce# check for sysctl duplicate constants 74986a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 74996a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 75006a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 75016a8d76cbSMatteo Croce } 7502515a235eSJoe Perches } 750313214adfSAndy Whitcroft 750413214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 750513214adfSAndy Whitcroft # so just keep quiet. 750613214adfSAndy Whitcroft if ($#rawlines == -1) { 750713214adfSAndy Whitcroft exit(0); 75080a920b5bSAndy Whitcroft } 75090a920b5bSAndy Whitcroft 75108905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 75118905a67cSAndy Whitcroft # things that appear to be patches. 75128905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 75138905a67cSAndy Whitcroft exit(0); 75148905a67cSAndy Whitcroft } 75158905a67cSAndy Whitcroft 7516e73d2715SDwaipayan Ray # This is not a patch, and we are in 'no-patch' mode so 75178905a67cSAndy Whitcroft # just keep quiet. 75188905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 75198905a67cSAndy Whitcroft exit(0); 75208905a67cSAndy Whitcroft } 75218905a67cSAndy Whitcroft 7522a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 7523000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 7524000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 75250a920b5bSAndy Whitcroft } 7526cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 7527cd261496SGeert Uytterhoeven if ($signoff == 0) { 7528000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 7529000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 753048ca2d8aSDwaipayan Ray } elsif ($authorsignoff != 1) { 753148ca2d8aSDwaipayan Ray # authorsignoff values: 753248ca2d8aSDwaipayan Ray # 0 -> missing sign off 753348ca2d8aSDwaipayan Ray # 1 -> sign off identical 753448ca2d8aSDwaipayan Ray # 2 -> names and addresses match, comments mismatch 753548ca2d8aSDwaipayan Ray # 3 -> addresses match, names different 753648ca2d8aSDwaipayan Ray # 4 -> names match, addresses different 753748ca2d8aSDwaipayan Ray # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match 753848ca2d8aSDwaipayan Ray 753948ca2d8aSDwaipayan Ray my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; 754048ca2d8aSDwaipayan Ray 754148ca2d8aSDwaipayan Ray if ($authorsignoff == 0) { 754248ca2d8aSDwaipayan Ray ERROR("NO_AUTHOR_SIGN_OFF", 7543cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 754448ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 2) { 754548ca2d8aSDwaipayan Ray CHK("FROM_SIGN_OFF_MISMATCH", 754648ca2d8aSDwaipayan Ray "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); 754748ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 3) { 754848ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 754948ca2d8aSDwaipayan Ray "From:/Signed-off-by: email name mismatch: $sob_msg\n"); 755048ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 4) { 755148ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 755248ca2d8aSDwaipayan Ray "From:/Signed-off-by: email address mismatch: $sob_msg\n"); 755348ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 5) { 755448ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 755548ca2d8aSDwaipayan Ray "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); 755648ca2d8aSDwaipayan Ray } 7557cd261496SGeert Uytterhoeven } 75580a920b5bSAndy Whitcroft } 75590a920b5bSAndy Whitcroft 7560f0a594c1SAndy Whitcroft print report_dump(); 756113214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 756213214adfSAndy Whitcroft print "$filename " if ($summary_file); 75636c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 75646c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 75656c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 75666c72ffaaSAndy Whitcroft } 75678905a67cSAndy Whitcroft 7568d2c0a235SAndy Whitcroft if ($quiet == 0) { 7569ef212196SJoe Perches # If there were any defects found and not already fixing them 7570ef212196SJoe Perches if (!$clean and !$fix) { 7571ef212196SJoe Perches print << "EOM" 7572ef212196SJoe Perches 7573ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 7574ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 7575ef212196SJoe PerchesEOM 7576ef212196SJoe Perches } 7577d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 7578d2c0a235SAndy Whitcroft # then suggest that. 7579d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 7580b0781216SMike Frysinger $rpt_cleaners = 0; 7581d8469f16SJoe Perches print << "EOM" 7582d8469f16SJoe Perches 7583d8469f16SJoe PerchesNOTE: Whitespace errors detected. 7584d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 7585d8469f16SJoe PerchesEOM 7586d2c0a235SAndy Whitcroft } 7587d2c0a235SAndy Whitcroft } 7588d2c0a235SAndy Whitcroft 7589d752fcc8SJoe Perches if ($clean == 0 && $fix && 7590d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 7591d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 75929624b8d6SJoe Perches my $newfile = $filename; 75939624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 75943705ce5bSJoe Perches my $linecount = 0; 75953705ce5bSJoe Perches my $f; 75963705ce5bSJoe Perches 7597d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 7598d752fcc8SJoe Perches 75993705ce5bSJoe Perches open($f, '>', $newfile) 76003705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 76013705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 76023705ce5bSJoe Perches $linecount++; 76033705ce5bSJoe Perches if ($file) { 76043705ce5bSJoe Perches if ($linecount > 3) { 76053705ce5bSJoe Perches $fixed_line =~ s/^\+//; 76063705ce5bSJoe Perches print $f $fixed_line . "\n"; 76073705ce5bSJoe Perches } 76083705ce5bSJoe Perches } else { 76093705ce5bSJoe Perches print $f $fixed_line . "\n"; 76103705ce5bSJoe Perches } 76113705ce5bSJoe Perches } 76123705ce5bSJoe Perches close($f); 76133705ce5bSJoe Perches 76143705ce5bSJoe Perches if (!$quiet) { 76153705ce5bSJoe Perches print << "EOM"; 7616d8469f16SJoe Perches 76173705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 76183705ce5bSJoe Perches 76193705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 76203705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 76213705ce5bSJoe Perches 76223705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 76233705ce5bSJoe PerchesNo warranties, expressed or implied... 76243705ce5bSJoe PerchesEOM 76253705ce5bSJoe Perches } 76263705ce5bSJoe Perches } 76273705ce5bSJoe Perches 7628d8469f16SJoe Perches if ($quiet == 0) { 7629d8469f16SJoe Perches print "\n"; 7630d8469f16SJoe Perches if ($clean == 1) { 7631d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 7632d8469f16SJoe Perches } else { 7633d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 76340a920b5bSAndy Whitcroft } 76350a920b5bSAndy Whitcroft } 76360a920b5bSAndy Whitcroft return $clean; 76370a920b5bSAndy Whitcroft} 7638