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"; 66bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 6752178ce0SDwaipayan Raymy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst"; 68ced69da1SQuentin Monnetmy $typedefsfile; 69737c0767SJohn Brooksmy $color = "auto"; 7098005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE 71dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE 72dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git'; 73713a09deSAntonio Borneomy $tabsize = 8; 743e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_"; 7577f5b10aSHannes Eder 7677f5b10aSHannes Edersub help { 7777f5b10aSHannes Eder my ($exitcode) = @_; 7877f5b10aSHannes Eder 7977f5b10aSHannes Eder print << "EOM"; 8077f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 8177f5b10aSHannes EderVersion: $V 8277f5b10aSHannes Eder 8377f5b10aSHannes EderOptions: 8477f5b10aSHannes Eder -q, --quiet quiet 8552178ce0SDwaipayan Ray -v, --verbose verbose mode 8677f5b10aSHannes Eder --no-tree run without a kernel tree 8777f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 8877f5b10aSHannes Eder --patch treat FILE as patchfile (default) 8977f5b10aSHannes Eder --emacs emacs compile window format 9077f5b10aSHannes Eder --terse one line per report 9134d8815fSJoe Perches --showfile emit diffed file position, not input file position 924a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 934a593c34SDu, Changbin single git commit with: 944a593c34SDu, Changbin <rev> 954a593c34SDu, Changbin <rev>^ 964a593c34SDu, Changbin <rev>~n 974a593c34SDu, Changbin multiple git commits with: 984a593c34SDu, Changbin <rev1>..<rev2> 994a593c34SDu, Changbin <rev1>...<rev2> 1004a593c34SDu, Changbin <rev>-<count> 1014a593c34SDu, Changbin git merges are ignored 10277f5b10aSHannes Eder -f, --file treat FILE as regular source file 10377f5b10aSHannes Eder --subjective, --strict enable more subjective tests 1043beb42ecSJoe Perches --list-types list the possible message types 10591bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 106000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 1073beb42ecSJoe Perches --show-types show the specific message type in the output 108bdc48fa1SJoe Perches --max-line-length=n set the maximum line length, (default $max_line_length) 109bdc48fa1SJoe Perches if exceeded, warn on patches 110bdc48fa1SJoe Perches requires --strict for use with --file 11156193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 112bdc48fa1SJoe Perches --tab-size=n set the number of spaces for tab (default $tabsize) 11377f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 11477f5b10aSHannes Eder --no-summary suppress the per-file summary 11577f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 11677f5b10aSHannes Eder --summary-file include the filename in summary 11777f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 11877f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 11977f5b10aSHannes Eder is all off) 12077f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 12177f5b10aSHannes Eder literally 1223705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1233705ce5bSJoe Perches If correctable single-line errors exist, create 1243705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1253705ce5bSJoe Perches with potential errors corrected to the preferred 1263705ce5bSJoe Perches checkpatch style 1279624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1289624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1299624b8d6SJoe Perches file. It's your fault if there's no backup or git 130d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 131d62a201fSDave Hansen runtime errors. 132ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 133f1a63678SMaxim Uvarov (default:/usr/share/codespell/dictionary.txt) 134ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 13575ad8c57SJerome Forissier --typedefsfile Read additional types from this file 136737c0767SJohn Brooks --color[=WHEN] Use colors 'always', 'never', or only when output 137737c0767SJohn Brooks is a terminal ('auto'). Default is 'auto'. 1383e89ad85SJerome Forissier --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default 1393e89ad85SJerome Forissier ${CONFIG_}) 14077f5b10aSHannes Eder -h, --help, --version display this help and exit 14177f5b10aSHannes Eder 14277f5b10aSHannes EderWhen FILE is - read standard input. 14377f5b10aSHannes EderEOM 14477f5b10aSHannes Eder 14577f5b10aSHannes Eder exit($exitcode); 14677f5b10aSHannes Eder} 14777f5b10aSHannes Eder 1483beb42ecSJoe Perchessub uniq { 1493beb42ecSJoe Perches my %seen; 1503beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1513beb42ecSJoe Perches} 1523beb42ecSJoe Perches 1533beb42ecSJoe Perchessub list_types { 1543beb42ecSJoe Perches my ($exitcode) = @_; 1553beb42ecSJoe Perches 1563beb42ecSJoe Perches my $count = 0; 1573beb42ecSJoe Perches 1583beb42ecSJoe Perches local $/ = undef; 1593beb42ecSJoe Perches 1603beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1613beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1623beb42ecSJoe Perches 1633beb42ecSJoe Perches my $text = <$script>; 1643beb42ecSJoe Perches close($script); 1653beb42ecSJoe Perches 16652178ce0SDwaipayan Ray my %types = (); 1670547fa58SJean Delvare # Also catch when type or level is passed through a variable 16852178ce0SDwaipayan Ray while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { 16952178ce0SDwaipayan Ray if (defined($1)) { 17052178ce0SDwaipayan Ray if (exists($types{$2})) { 17152178ce0SDwaipayan Ray $types{$2} .= ",$1" if ($types{$2} ne $1); 17252178ce0SDwaipayan Ray } else { 17352178ce0SDwaipayan Ray $types{$2} = $1; 1743beb42ecSJoe Perches } 17552178ce0SDwaipayan Ray } else { 17652178ce0SDwaipayan Ray $types{$2} = "UNDETERMINED"; 17752178ce0SDwaipayan Ray } 17852178ce0SDwaipayan Ray } 17952178ce0SDwaipayan Ray 1803beb42ecSJoe Perches print("#\tMessage type\n\n"); 18152178ce0SDwaipayan Ray if ($color) { 18252178ce0SDwaipayan Ray print(" ( Color coding: "); 18352178ce0SDwaipayan Ray print(RED . "ERROR" . RESET); 18452178ce0SDwaipayan Ray print(" | "); 18552178ce0SDwaipayan Ray print(YELLOW . "WARNING" . RESET); 18652178ce0SDwaipayan Ray print(" | "); 18752178ce0SDwaipayan Ray print(GREEN . "CHECK" . RESET); 18852178ce0SDwaipayan Ray print(" | "); 18952178ce0SDwaipayan Ray print("Multiple levels / Undetermined"); 19052178ce0SDwaipayan Ray print(" )\n\n"); 19152178ce0SDwaipayan Ray } 19252178ce0SDwaipayan Ray 19352178ce0SDwaipayan Ray foreach my $type (sort keys %types) { 19452178ce0SDwaipayan Ray my $orig_type = $type; 19552178ce0SDwaipayan Ray if ($color) { 19652178ce0SDwaipayan Ray my $level = $types{$type}; 19752178ce0SDwaipayan Ray if ($level eq "ERROR") { 19852178ce0SDwaipayan Ray $type = RED . $type . RESET; 19952178ce0SDwaipayan Ray } elsif ($level eq "WARN") { 20052178ce0SDwaipayan Ray $type = YELLOW . $type . RESET; 20152178ce0SDwaipayan Ray } elsif ($level eq "CHK") { 20252178ce0SDwaipayan Ray $type = GREEN . $type . RESET; 20352178ce0SDwaipayan Ray } 20452178ce0SDwaipayan Ray } 2053beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 20652178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$orig_type})) { 20752178ce0SDwaipayan Ray my $message = $verbose_messages{$orig_type}; 20852178ce0SDwaipayan Ray $message =~ s/\n/\n\t/g; 20952178ce0SDwaipayan Ray print("\t" . $message . "\n\n"); 21052178ce0SDwaipayan Ray } 2113beb42ecSJoe Perches } 2123beb42ecSJoe Perches 2133beb42ecSJoe Perches exit($exitcode); 2143beb42ecSJoe Perches} 2153beb42ecSJoe Perches 216000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 217000d1cc1SJoe Perchesif (-f $conf) { 218000d1cc1SJoe Perches my @conf_args; 219000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 220000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 221000d1cc1SJoe Perches 222000d1cc1SJoe Perches while (<$conffile>) { 223000d1cc1SJoe Perches my $line = $_; 224000d1cc1SJoe Perches 225000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 226000d1cc1SJoe Perches $line =~ s/^\s*//g; 227000d1cc1SJoe Perches $line =~ s/\s+/ /g; 228000d1cc1SJoe Perches 229000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 230000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 231000d1cc1SJoe Perches 232000d1cc1SJoe Perches my @words = split(" ", $line); 233000d1cc1SJoe Perches foreach my $word (@words) { 234000d1cc1SJoe Perches last if ($word =~ m/^#/); 235000d1cc1SJoe Perches push (@conf_args, $word); 236000d1cc1SJoe Perches } 237000d1cc1SJoe Perches } 238000d1cc1SJoe Perches close($conffile); 239000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 240000d1cc1SJoe Perches} 241000d1cc1SJoe Perches 24252178ce0SDwaipayan Raysub load_docs { 24352178ce0SDwaipayan Ray open(my $docs, '<', "$docsfile") 24452178ce0SDwaipayan Ray or warn "$P: Can't read the documentation file $docsfile $!\n"; 24552178ce0SDwaipayan Ray 24652178ce0SDwaipayan Ray my $type = ''; 24752178ce0SDwaipayan Ray my $desc = ''; 24852178ce0SDwaipayan Ray my $in_desc = 0; 24952178ce0SDwaipayan Ray 25052178ce0SDwaipayan Ray while (<$docs>) { 25152178ce0SDwaipayan Ray chomp; 25252178ce0SDwaipayan Ray my $line = $_; 25352178ce0SDwaipayan Ray $line =~ s/\s+$//; 25452178ce0SDwaipayan Ray 25552178ce0SDwaipayan Ray if ($line =~ /^\s*\*\*(.+)\*\*$/) { 25652178ce0SDwaipayan Ray if ($desc ne '') { 25752178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 25852178ce0SDwaipayan Ray } 25952178ce0SDwaipayan Ray $type = $1; 26052178ce0SDwaipayan Ray $desc = ''; 26152178ce0SDwaipayan Ray $in_desc = 1; 26252178ce0SDwaipayan Ray } elsif ($in_desc) { 26352178ce0SDwaipayan Ray if ($line =~ /^(?:\s{4,}|$)/) { 26452178ce0SDwaipayan Ray $line =~ s/^\s{4}//; 26552178ce0SDwaipayan Ray $desc .= $line; 26652178ce0SDwaipayan Ray $desc .= "\n"; 26752178ce0SDwaipayan Ray } else { 26852178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 26952178ce0SDwaipayan Ray $type = ''; 27052178ce0SDwaipayan Ray $desc = ''; 27152178ce0SDwaipayan Ray $in_desc = 0; 27252178ce0SDwaipayan Ray } 27352178ce0SDwaipayan Ray } 27452178ce0SDwaipayan Ray } 27552178ce0SDwaipayan Ray 27652178ce0SDwaipayan Ray if ($desc ne '') { 27752178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 27852178ce0SDwaipayan Ray } 27952178ce0SDwaipayan Ray close($docs); 28052178ce0SDwaipayan Ray} 28152178ce0SDwaipayan Ray 282737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space. 283737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments 284737c0767SJohn Brooksforeach (@ARGV) { 285737c0767SJohn Brooks if ($_ eq "--color" || $_ eq "-color") { 286737c0767SJohn Brooks $_ = "--color=$color"; 287737c0767SJohn Brooks } 288737c0767SJohn Brooks} 289737c0767SJohn Brooks 2900a920b5bSAndy WhitcroftGetOptions( 2916c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 29252178ce0SDwaipayan Ray 'v|verbose!' => \$verbose, 2930a920b5bSAndy Whitcroft 'tree!' => \$tree, 2940a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 2950a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 2966c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 2978905a67cSAndy Whitcroft 'terse!' => \$terse, 29834d8815fSJoe Perches 'showfile!' => \$showfile, 29977f5b10aSHannes Eder 'f|file!' => \$file, 3004a593c34SDu, Changbin 'g|git!' => \$git, 3016c72ffaaSAndy Whitcroft 'subjective!' => \$check, 3026c72ffaaSAndy Whitcroft 'strict!' => \$check, 303000d1cc1SJoe Perches 'ignore=s' => \@ignore, 30491bfe484SJoe Perches 'types=s' => \@use, 305000d1cc1SJoe Perches 'show-types!' => \$show_types, 3063beb42ecSJoe Perches 'list-types!' => \$list_types, 3076cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 30856193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 309713a09deSAntonio Borneo 'tab-size=i' => \$tabsize, 3106c72ffaaSAndy Whitcroft 'root=s' => \$root, 3118905a67cSAndy Whitcroft 'summary!' => \$summary, 3128905a67cSAndy Whitcroft 'mailback!' => \$mailback, 31313214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 3143705ce5bSJoe Perches 'fix!' => \$fix, 3159624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 316d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 317c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 318773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 319ebfd7d62SJoe Perches 'codespell!' => \$codespell, 320ebfd7d62SJoe Perches 'codespellfile=s' => \$codespellfile, 32175ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 322737c0767SJohn Brooks 'color=s' => \$color, 323737c0767SJohn Brooks 'no-color' => \$color, #keep old behaviors of -nocolor 324737c0767SJohn Brooks 'nocolor' => \$color, #keep old behaviors of -nocolor 3253e89ad85SJerome Forissier 'kconfig-prefix=s' => \${CONFIG_}, 32677f5b10aSHannes Eder 'h|help' => \$help, 32777f5b10aSHannes Eder 'version' => \$help 32877f5b10aSHannes Eder) or help(1); 32977f5b10aSHannes Eder 33077f5b10aSHannes Ederhelp(0) if ($help); 3310a920b5bSAndy Whitcroft 33252178ce0SDwaipayan Raydie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); 33352178ce0SDwaipayan Raydie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse); 33452178ce0SDwaipayan Ray 33552178ce0SDwaipayan Rayif ($color =~ /^[01]$/) { 33652178ce0SDwaipayan Ray $color = !$color; 33752178ce0SDwaipayan Ray} elsif ($color =~ /^always$/i) { 33852178ce0SDwaipayan Ray $color = 1; 33952178ce0SDwaipayan Ray} elsif ($color =~ /^never$/i) { 34052178ce0SDwaipayan Ray $color = 0; 34152178ce0SDwaipayan Ray} elsif ($color =~ /^auto$/i) { 34252178ce0SDwaipayan Ray $color = (-t STDOUT); 34352178ce0SDwaipayan Ray} else { 34452178ce0SDwaipayan Ray die "$P: Invalid color mode: $color\n"; 34552178ce0SDwaipayan Ray} 34652178ce0SDwaipayan Ray 34752178ce0SDwaipayan Rayload_docs() if ($verbose); 3483beb42ecSJoe Percheslist_types(0) if ($list_types); 3493beb42ecSJoe Perches 3509624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 3512ac73b4fSJoe Perches$check_orig = $check; 3529624b8d6SJoe Perches 3530a920b5bSAndy Whitcroftmy $exit = 0; 3540a920b5bSAndy Whitcroft 3555b57980dSJoe Perchesmy $perl_version_ok = 1; 356d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 3575b57980dSJoe Perches $perl_version_ok = 0; 358d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 3595b57980dSJoe Perches exit(1) if (!$ignore_perl_version); 360d62a201fSDave Hansen} 361d62a201fSDave Hansen 36245107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 3630a920b5bSAndy Whitcroftif ($#ARGV < 0) { 36445107ff6SAllen Hubbe push(@ARGV, '-'); 3650a920b5bSAndy Whitcroft} 3660a920b5bSAndy Whitcroft 367713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1 36832f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); 369713a09deSAntonio Borneo 37091bfe484SJoe Perchessub hash_save_array_words { 37191bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 37291bfe484SJoe Perches 37391bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 37491bfe484SJoe Perches foreach my $word (@array) { 375000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 376000d1cc1SJoe Perches $word =~ s/^\s*//g; 377000d1cc1SJoe Perches $word =~ s/\s+/ /g; 378000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 379000d1cc1SJoe Perches 380000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 381000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 382000d1cc1SJoe Perches 38391bfe484SJoe Perches $hashRef->{$word}++; 384000d1cc1SJoe Perches } 38591bfe484SJoe Perches} 38691bfe484SJoe Perches 38791bfe484SJoe Perchessub hash_show_words { 38891bfe484SJoe Perches my ($hashRef, $prefix) = @_; 38991bfe484SJoe Perches 3903c816e49SJoe Perches if (keys %$hashRef) { 391d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 39258cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 39391bfe484SJoe Perches print " $word"; 39491bfe484SJoe Perches } 395d8469f16SJoe Perches print "\n"; 39691bfe484SJoe Perches } 39791bfe484SJoe Perches} 39891bfe484SJoe Perches 39991bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 40091bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 401000d1cc1SJoe Perches 402c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 403c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 4047429c690SAndy Whitcroftmy $dbg_type = 0; 405a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 406c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 40721caa13cSAndy Whitcroft ## no critic 40821caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 40921caa13cSAndy Whitcroft die "$@" if ($@); 410c2fdda0dSAndy Whitcroft} 411c2fdda0dSAndy Whitcroft 412d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 413d2c0a235SAndy Whitcroft 4148905a67cSAndy Whitcroftif ($terse) { 4158905a67cSAndy Whitcroft $emacs = 1; 4168905a67cSAndy Whitcroft $quiet++; 4178905a67cSAndy Whitcroft} 4188905a67cSAndy Whitcroft 4196c72ffaaSAndy Whitcroftif ($tree) { 4206c72ffaaSAndy Whitcroft if (defined $root) { 4216c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 4226c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 4236c72ffaaSAndy Whitcroft } 4246c72ffaaSAndy Whitcroft } else { 4256c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 4266c72ffaaSAndy Whitcroft $root = '.'; 4276c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 4286c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 4296c72ffaaSAndy Whitcroft $root = $1; 4306c72ffaaSAndy Whitcroft } 4316c72ffaaSAndy Whitcroft } 4326c72ffaaSAndy Whitcroft 4336c72ffaaSAndy Whitcroft if (!defined $root) { 4340a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 4350a920b5bSAndy Whitcroft exit(2); 4360a920b5bSAndy Whitcroft } 4376c72ffaaSAndy Whitcroft} 4386c72ffaaSAndy Whitcroft 4396c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 4406c72ffaaSAndy Whitcroft 4412ceb532bSAndy Whitcroftour $Ident = qr{ 4422ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 4432ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 4442ceb532bSAndy Whitcroft }x; 4456c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 4466c72ffaaSAndy Whitcroftour $Sparse = qr{ 4476c72ffaaSAndy Whitcroft __user| 4486c72ffaaSAndy Whitcroft __kernel| 4496c72ffaaSAndy Whitcroft __force| 4506c72ffaaSAndy Whitcroft __iomem| 4516c72ffaaSAndy Whitcroft __must_check| 452417495edSAndy Whitcroft __kprobes| 453165e72a6SSven Eckelmann __ref| 45433aa4597SGeert Uytterhoeven __refconst| 45533aa4597SGeert Uytterhoeven __refdata| 456ad315455SBoqun Feng __rcu| 457ad315455SBoqun Feng __private 4586c72ffaaSAndy Whitcroft }x; 459e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 460e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 461e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 462e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 463e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 4648716de38SJoe Perches 46552131292SWolfram Sang# Notes to $Attribute: 46652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 4676c72ffaaSAndy Whitcroftour $Attribute = qr{ 4686c72ffaaSAndy Whitcroft const| 469b5e8736aSJoe Perches volatile| 47003f1df7dSJoe Perches __percpu| 47103f1df7dSJoe Perches __nocast| 47203f1df7dSJoe Perches __safe| 47346d832f5SMichael S. Tsirkin __bitwise| 47403f1df7dSJoe Perches __packed__| 47503f1df7dSJoe Perches __packed2__| 47603f1df7dSJoe Perches __naked| 47703f1df7dSJoe Perches __maybe_unused| 47803f1df7dSJoe Perches __always_unused| 47903f1df7dSJoe Perches __noreturn| 48003f1df7dSJoe Perches __used| 48103f1df7dSJoe Perches __cold| 482e23ef1f3SJoe Perches __pure| 48303f1df7dSJoe Perches __noclone| 48403f1df7dSJoe Perches __deprecated| 4856c72ffaaSAndy Whitcroft __read_mostly| 486c5967e98SJoe Perches __ro_after_init| 4876c72ffaaSAndy Whitcroft __kprobes| 4888716de38SJoe Perches $InitAttribute| 48924e1d81aSAndy Whitcroft ____cacheline_aligned| 49024e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 4915fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 492*86cffecdSKees Cook __weak| 493*86cffecdSKees Cook __alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) 4946c72ffaaSAndy Whitcroft }x; 495c45dcabdSAndy Whitcroftour $Modifier; 49691cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 4976c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 4986c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 4996c72ffaaSAndy Whitcroft 50095e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 50195e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 50295e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 50395e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 5042435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 505d2af5aa6SJoe Perchesour $String = qr{(?:\b[Lu])?"[X\t]*"}; 506326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 507326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 508326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 50974349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 5102435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 511326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 512447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 51323f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 5146c72ffaaSAndy Whitcroftour $Operators = qr{ 5156c72ffaaSAndy Whitcroft <=|>=|==|!=| 5166c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 51723f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 5186c72ffaaSAndy Whitcroft }x; 5196c72ffaaSAndy Whitcroft 52091cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 52191cb5195SJoe Perches 522ab7e23f3SJoe Perchesour $BasicType; 5238905a67cSAndy Whitcroftour $NonptrType; 5241813087dSJoe Perchesour $NonptrTypeMisordered; 5258716de38SJoe Perchesour $NonptrTypeWithAttr; 5268905a67cSAndy Whitcroftour $Type; 5271813087dSJoe Perchesour $TypeMisordered; 5288905a67cSAndy Whitcroftour $Declare; 5291813087dSJoe Perchesour $DeclareMisordered; 5308905a67cSAndy Whitcroft 53115662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 53215662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 533171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 534171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 535171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 536171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 537171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 538171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 539171ae1a4SAndy Whitcroft}x; 540171ae1a4SAndy Whitcroft 54115662b3eSJoe Perchesour $UTF8 = qr{ 54215662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 54315662b3eSJoe Perches | $NON_ASCII_UTF8 54415662b3eSJoe Perches}x; 54515662b3eSJoe Perches 546e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 547021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 548021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 549021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 550021158b4SJoe Perches)}; 551e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 552fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 5538ed22cadSAndy Whitcroft atomic_t 5548ed22cadSAndy Whitcroft)}; 555e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 556e6176fa4SJoe Perches $typeC99Typedefs\b| 557e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 558e6176fa4SJoe Perches $typeKernelTypedefs\b 559e6176fa4SJoe Perches)}; 5608ed22cadSAndy Whitcroft 5616d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 5626d32f7a3SJoe Perches 563691e669bSJoe Perchesour $logFunctions = qr{(?x: 564758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 5657d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 56687bd499aSJoe Perches TP_printk| 5676e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 568b0531722SJoe Perches panic| 56906668727SJoe Perches MODULE_[A-Z_]+| 57006668727SJoe Perches seq_vprintf|seq_printf|seq_puts 571691e669bSJoe Perches)}; 572691e669bSJoe Perches 573e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 574e29a70f1SJoe Perches (?:(?:devm_)? 57558f02267SJoe Perches (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? | 576e29a70f1SJoe Perches kstrdup(?:_const)? | 577e29a70f1SJoe Perches kmemdup(?:_nul)?) | 578461e1565SChristophe JAILLET (?:\w+)?alloc_skb(?:_ip_align)? | 579e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 580e29a70f1SJoe Perches dma_alloc_coherent 581e29a70f1SJoe Perches)}; 582e29a70f1SJoe Perches 58320112475SJoe Perchesour $signature_tags = qr{(?xi: 58420112475SJoe Perches Signed-off-by:| 585d499480cSJorge Ramirez-Ortiz Co-developed-by:| 58620112475SJoe Perches Acked-by:| 58720112475SJoe Perches Tested-by:| 58820112475SJoe Perches Reviewed-by:| 58920112475SJoe Perches Reported-by:| 5908543ae12SMugunthan V N Suggested-by:| 59120112475SJoe Perches To:| 59220112475SJoe Perches Cc: 59320112475SJoe Perches)}; 59420112475SJoe Perches 595adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi: 596adb2da82SJoe Perches [=-]*> | 597adb2da82SJoe Perches <[=-]* | 598adb2da82SJoe Perches \[ | 599adb2da82SJoe Perches \] | 600adb2da82SJoe Perches start | 601adb2da82SJoe Perches called | 602adb2da82SJoe Perches entered | 603adb2da82SJoe Perches entry | 604adb2da82SJoe Perches enter | 605adb2da82SJoe Perches in | 606adb2da82SJoe Perches inside | 607adb2da82SJoe Perches here | 608adb2da82SJoe Perches begin | 609adb2da82SJoe Perches exit | 610adb2da82SJoe Perches end | 611adb2da82SJoe Perches done | 612adb2da82SJoe Perches leave | 613adb2da82SJoe Perches completed | 614adb2da82SJoe Perches out | 615adb2da82SJoe Perches return | 616adb2da82SJoe Perches [\.\!:\s]* 617adb2da82SJoe Perches)}; 618adb2da82SJoe Perches 619831242abSAditya Srivastavasub edit_distance_min { 620831242abSAditya Srivastava my (@arr) = @_; 621831242abSAditya Srivastava my $len = scalar @arr; 622831242abSAditya Srivastava if ((scalar @arr) < 1) { 623831242abSAditya Srivastava # if underflow, return 624831242abSAditya Srivastava return; 625831242abSAditya Srivastava } 626831242abSAditya Srivastava my $min = $arr[0]; 627831242abSAditya Srivastava for my $i (0 .. ($len-1)) { 628831242abSAditya Srivastava if ($arr[$i] < $min) { 629831242abSAditya Srivastava $min = $arr[$i]; 630831242abSAditya Srivastava } 631831242abSAditya Srivastava } 632831242abSAditya Srivastava return $min; 633831242abSAditya Srivastava} 634831242abSAditya Srivastava 635831242abSAditya Srivastavasub get_edit_distance { 636831242abSAditya Srivastava my ($str1, $str2) = @_; 637831242abSAditya Srivastava $str1 = lc($str1); 638831242abSAditya Srivastava $str2 = lc($str2); 639831242abSAditya Srivastava $str1 =~ s/-//g; 640831242abSAditya Srivastava $str2 =~ s/-//g; 641831242abSAditya Srivastava my $len1 = length($str1); 642831242abSAditya Srivastava my $len2 = length($str2); 643831242abSAditya Srivastava # two dimensional array storing minimum edit distance 644831242abSAditya Srivastava my @distance; 645831242abSAditya Srivastava for my $i (0 .. $len1) { 646831242abSAditya Srivastava for my $j (0 .. $len2) { 647831242abSAditya Srivastava if ($i == 0) { 648831242abSAditya Srivastava $distance[$i][$j] = $j; 649831242abSAditya Srivastava } elsif ($j == 0) { 650831242abSAditya Srivastava $distance[$i][$j] = $i; 651831242abSAditya Srivastava } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { 652831242abSAditya Srivastava $distance[$i][$j] = $distance[$i - 1][$j - 1]; 653831242abSAditya Srivastava } else { 654831242abSAditya Srivastava my $dist1 = $distance[$i][$j - 1]; #insert distance 655831242abSAditya Srivastava my $dist2 = $distance[$i - 1][$j]; # remove 656831242abSAditya Srivastava my $dist3 = $distance[$i - 1][$j - 1]; #replace 657831242abSAditya Srivastava $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); 658831242abSAditya Srivastava } 659831242abSAditya Srivastava } 660831242abSAditya Srivastava } 661831242abSAditya Srivastava return $distance[$len1][$len2]; 662831242abSAditya Srivastava} 663831242abSAditya Srivastava 664831242abSAditya Srivastavasub find_standard_signature { 665831242abSAditya Srivastava my ($sign_off) = @_; 666831242abSAditya Srivastava my @standard_signature_tags = ( 667831242abSAditya Srivastava 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', 668831242abSAditya Srivastava 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' 669831242abSAditya Srivastava ); 670831242abSAditya Srivastava foreach my $signature (@standard_signature_tags) { 671831242abSAditya Srivastava return $signature if (get_edit_distance($sign_off, $signature) <= 2); 672831242abSAditya Srivastava } 673831242abSAditya Srivastava 674831242abSAditya Srivastava return ""; 675831242abSAditya Srivastava} 676831242abSAditya Srivastava 6771813087dSJoe Perchesour @typeListMisordered = ( 6781813087dSJoe Perches qr{char\s+(?:un)?signed}, 6791813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 6801813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 6811813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 6821813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 6831813087dSJoe Perches qr{short\s+(?:un)?signed}, 6841813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 6851813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 6861813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 6871813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 6881813087dSJoe Perches qr{int\s+(?:un)?signed}, 6891813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 6901813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 6911813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 6921813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 6931813087dSJoe Perches qr{long\s+(?:un)?signed}, 6941813087dSJoe Perches); 6951813087dSJoe Perches 6968905a67cSAndy Whitcroftour @typeList = ( 6978905a67cSAndy Whitcroft qr{void}, 6980c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 6990c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 7000c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 7010c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 7020c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 7030c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 7040c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 7050c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 7060c773d9dSJoe Perches qr{(?:un)?signed}, 7078905a67cSAndy Whitcroft qr{float}, 7088905a67cSAndy Whitcroft qr{double}, 7098905a67cSAndy Whitcroft qr{bool}, 7108905a67cSAndy Whitcroft qr{struct\s+$Ident}, 7118905a67cSAndy Whitcroft qr{union\s+$Ident}, 7128905a67cSAndy Whitcroft qr{enum\s+$Ident}, 7138905a67cSAndy Whitcroft qr{${Ident}_t}, 7148905a67cSAndy Whitcroft qr{${Ident}_handler}, 7158905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 7161813087dSJoe Perches @typeListMisordered, 7178905a67cSAndy Whitcroft); 718938224b5SJoe Perches 719938224b5SJoe Perchesour $C90_int_types = qr{(?x: 720938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 721938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 722938224b5SJoe Perches long\s+long\s+(?:un)?signed| 723938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 724938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 725938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 726938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 727938224b5SJoe Perches 728938224b5SJoe Perches long\s+int\s+(?:un)?signed| 729938224b5SJoe Perches long\s+(?:un)?signed\s+int| 730938224b5SJoe Perches long\s+(?:un)?signed| 731938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 732938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 733938224b5SJoe Perches int\s+long\s+(?:un)?signed| 734938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 735938224b5SJoe Perches 736938224b5SJoe Perches int\s+(?:un)?signed| 737938224b5SJoe Perches (?:(?:un)?signed\s+)?int 738938224b5SJoe Perches)}; 739938224b5SJoe Perches 740485ff23eSAlex Dowadour @typeListFile = (); 7418716de38SJoe Perchesour @typeListWithAttr = ( 7428716de38SJoe Perches @typeList, 7438716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 7448716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 7458716de38SJoe Perches); 7468716de38SJoe Perches 747c45dcabdSAndy Whitcroftour @modifierList = ( 748c45dcabdSAndy Whitcroft qr{fastcall}, 749c45dcabdSAndy Whitcroft); 750485ff23eSAlex Dowadour @modifierListFile = (); 7518905a67cSAndy Whitcroft 7522435880fSJoe Perchesour @mode_permission_funcs = ( 7532435880fSJoe Perches ["module_param", 3], 7542435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 7552435880fSJoe Perches ["module_param_array_named", 5], 7562435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 7572435880fSJoe Perches ["proc_create(?:_data|)", 2], 758459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 759459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 760459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 761459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 762459cf0aeSJoe Perches ["__ATTR", 2], 7632435880fSJoe Perches); 7642435880fSJoe Perches 7651a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; 7661a3dcf2eSJoe Perches 767515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 768515a235eSJoe Perchesour $mode_perms_search = ""; 769515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 770515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 771515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 772515a235eSJoe Perches} 77300180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 774515a235eSJoe Perches 7759189c7e7SJoe Perchesour %deprecated_apis = ( 7769189c7e7SJoe Perches "synchronize_rcu_bh" => "synchronize_rcu", 7779189c7e7SJoe Perches "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 7789189c7e7SJoe Perches "call_rcu_bh" => "call_rcu", 7799189c7e7SJoe Perches "rcu_barrier_bh" => "rcu_barrier", 7809189c7e7SJoe Perches "synchronize_sched" => "synchronize_rcu", 7819189c7e7SJoe Perches "synchronize_sched_expedited" => "synchronize_rcu_expedited", 7829189c7e7SJoe Perches "call_rcu_sched" => "call_rcu", 7839189c7e7SJoe Perches "rcu_barrier_sched" => "rcu_barrier", 7849189c7e7SJoe Perches "get_state_synchronize_sched" => "get_state_synchronize_rcu", 7859189c7e7SJoe Perches "cond_synchronize_sched" => "cond_synchronize_rcu", 7869189c7e7SJoe Perches); 7879189c7e7SJoe Perches 7889189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 7899189c7e7SJoe Perchesour $deprecated_apis_search = ""; 7909189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 7919189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 7929189c7e7SJoe Perches $deprecated_apis_search .= $entry; 7939189c7e7SJoe Perches} 7949189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 7959189c7e7SJoe Perches 796b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 797b392c64fSJoe Perches S_IWUGO | 798b392c64fSJoe Perches S_IWOTH | 799b392c64fSJoe Perches S_IRWXUGO | 800b392c64fSJoe Perches S_IALLUGO | 801b392c64fSJoe Perches 0[0-7][0-7][2367] 802b392c64fSJoe Perches}x; 803b392c64fSJoe Perches 804f90774e1SJoe Perchesour %mode_permission_string_types = ( 805f90774e1SJoe Perches "S_IRWXU" => 0700, 806f90774e1SJoe Perches "S_IRUSR" => 0400, 807f90774e1SJoe Perches "S_IWUSR" => 0200, 808f90774e1SJoe Perches "S_IXUSR" => 0100, 809f90774e1SJoe Perches "S_IRWXG" => 0070, 810f90774e1SJoe Perches "S_IRGRP" => 0040, 811f90774e1SJoe Perches "S_IWGRP" => 0020, 812f90774e1SJoe Perches "S_IXGRP" => 0010, 813f90774e1SJoe Perches "S_IRWXO" => 0007, 814f90774e1SJoe Perches "S_IROTH" => 0004, 815f90774e1SJoe Perches "S_IWOTH" => 0002, 816f90774e1SJoe Perches "S_IXOTH" => 0001, 817f90774e1SJoe Perches "S_IRWXUGO" => 0777, 818f90774e1SJoe Perches "S_IRUGO" => 0444, 819f90774e1SJoe Perches "S_IWUGO" => 0222, 820f90774e1SJoe Perches "S_IXUGO" => 0111, 821f90774e1SJoe Perches); 822f90774e1SJoe Perches 823f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 824f90774e1SJoe Perchesour $mode_perms_string_search = ""; 825f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 826f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 827f90774e1SJoe Perches $mode_perms_string_search .= $entry; 828f90774e1SJoe Perches} 82900180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 83000180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 83100180468SJoe Perches ${single_mode_perms_string_search} 83200180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 83300180468SJoe Perches}x; 83400180468SJoe Perches 83500180468SJoe Perchessub perms_to_octal { 83600180468SJoe Perches my ($string) = @_; 83700180468SJoe Perches 83800180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 83900180468SJoe Perches 84000180468SJoe Perches my $val = ""; 84100180468SJoe Perches my $oval = ""; 84200180468SJoe Perches my $to = 0; 84300180468SJoe Perches my $curpos = 0; 84400180468SJoe Perches my $lastpos = 0; 84500180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 84600180468SJoe Perches $curpos = pos($string); 84700180468SJoe Perches my $match = $2; 84800180468SJoe Perches my $omatch = $1; 84900180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 85000180468SJoe Perches $lastpos = $curpos; 85100180468SJoe Perches $to |= $mode_permission_string_types{$match}; 85200180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 85300180468SJoe Perches $val .= $match; 85400180468SJoe Perches $oval .= $omatch; 85500180468SJoe Perches } 85600180468SJoe Perches $oval =~ s/^\s*\|\s*//; 85700180468SJoe Perches $oval =~ s/\s*\|\s*$//; 85800180468SJoe Perches return sprintf("%04o", $to); 85900180468SJoe Perches} 860f90774e1SJoe Perches 8617840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 8627840a94cSWolfram Sang irq| 863cdcee686SSergey Ryazanov memory| 864cdcee686SSergey Ryazanov time| 865cdcee686SSergey Ryazanov reboot 8667840a94cSWolfram Sang)}; 8677840a94cSWolfram Sang# memory.h: ARM has a custom one 8687840a94cSWolfram Sang 86966b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 87066b47b4aSKees Cookmy $misspellings; 87166b47b4aSKees Cookmy %spelling_fix; 87236061e38SJoe Perches 87336061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 87466b47b4aSKees Cook while (<$spelling>) { 87566b47b4aSKees Cook my $line = $_; 87666b47b4aSKees Cook 87766b47b4aSKees Cook $line =~ s/\s*\n?$//g; 87866b47b4aSKees Cook $line =~ s/^\s*//g; 87966b47b4aSKees Cook 88066b47b4aSKees Cook next if ($line =~ m/^\s*#/); 88166b47b4aSKees Cook next if ($line =~ m/^\s*$/); 88266b47b4aSKees Cook 88366b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 88466b47b4aSKees Cook 88566b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 88666b47b4aSKees Cook } 88766b47b4aSKees Cook close($spelling); 88836061e38SJoe Perches} else { 88936061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 89036061e38SJoe Perches} 89166b47b4aSKees Cook 892ebfd7d62SJoe Perchesif ($codespell) { 893ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 894ebfd7d62SJoe Perches while (<$spelling>) { 895ebfd7d62SJoe Perches my $line = $_; 896ebfd7d62SJoe Perches 897ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 898ebfd7d62SJoe Perches $line =~ s/^\s*//g; 899ebfd7d62SJoe Perches 900ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 901ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 902ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 903ebfd7d62SJoe Perches 904ebfd7d62SJoe Perches $line =~ s/,.*$//; 905ebfd7d62SJoe Perches 906ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 907ebfd7d62SJoe Perches 908ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 909ebfd7d62SJoe Perches } 910ebfd7d62SJoe Perches close($spelling); 911ebfd7d62SJoe Perches } else { 912ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 913ebfd7d62SJoe Perches } 914ebfd7d62SJoe Perches} 915ebfd7d62SJoe Perches 916ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 917ebfd7d62SJoe Perches 91875ad8c57SJerome Forissiersub read_words { 91975ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 92075ad8c57SJerome Forissier 92175ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 92275ad8c57SJerome Forissier while (<$words>) { 923bf1fa1daSJoe Perches my $line = $_; 924bf1fa1daSJoe Perches 925bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 926bf1fa1daSJoe Perches $line =~ s/^\s*//g; 927bf1fa1daSJoe Perches 928bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 929bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 930bf1fa1daSJoe Perches if ($line =~ /\s/) { 93175ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 932bf1fa1daSJoe Perches next; 933bf1fa1daSJoe Perches } 934bf1fa1daSJoe Perches 935ced69da1SQuentin Monnet $$wordsRef .= '|' if (defined $$wordsRef); 93675ad8c57SJerome Forissier $$wordsRef .= $line; 937bf1fa1daSJoe Perches } 93875ad8c57SJerome Forissier close($file); 93975ad8c57SJerome Forissier return 1; 940bf1fa1daSJoe Perches } 941bf1fa1daSJoe Perches 94275ad8c57SJerome Forissier return 0; 94375ad8c57SJerome Forissier} 94475ad8c57SJerome Forissier 945ced69da1SQuentin Monnetmy $const_structs; 946ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) { 94775ad8c57SJerome Forissier read_words(\$const_structs, $conststructsfile) 94875ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 949ced69da1SQuentin Monnet} 95075ad8c57SJerome Forissier 951ced69da1SQuentin Monnetif (defined($typedefsfile)) { 952ced69da1SQuentin Monnet my $typeOtherTypedefs; 95375ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 95475ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 955ced69da1SQuentin Monnet $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); 95675ad8c57SJerome Forissier} 95775ad8c57SJerome Forissier 9588905a67cSAndy Whitcroftsub build_types { 959485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 960485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 9611813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 9628716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 963c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 964ab7e23f3SJoe Perches $BasicType = qr{ 965ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 966ab7e23f3SJoe Perches (?:${all}\b) 967ab7e23f3SJoe Perches }x; 9688905a67cSAndy Whitcroft $NonptrType = qr{ 969d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 970cf655043SAndy Whitcroft (?: 9716b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 9728ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 973c45dcabdSAndy Whitcroft (?:${all}\b) 974cf655043SAndy Whitcroft ) 975c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 9768905a67cSAndy Whitcroft }x; 9771813087dSJoe Perches $NonptrTypeMisordered = qr{ 9781813087dSJoe Perches (?:$Modifier\s+|const\s+)* 9791813087dSJoe Perches (?: 9801813087dSJoe Perches (?:${Misordered}\b) 9811813087dSJoe Perches ) 9821813087dSJoe Perches (?:\s+$Modifier|\s+const)* 9831813087dSJoe Perches }x; 9848716de38SJoe Perches $NonptrTypeWithAttr = qr{ 9858716de38SJoe Perches (?:$Modifier\s+|const\s+)* 9868716de38SJoe Perches (?: 9878716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 9888716de38SJoe Perches (?:$typeTypedefs\b)| 9898716de38SJoe Perches (?:${allWithAttr}\b) 9908716de38SJoe Perches ) 9918716de38SJoe Perches (?:\s+$Modifier|\s+const)* 9928716de38SJoe Perches }x; 9938905a67cSAndy Whitcroft $Type = qr{ 994c45dcabdSAndy Whitcroft $NonptrType 9957b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 996c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 9978905a67cSAndy Whitcroft }x; 9981813087dSJoe Perches $TypeMisordered = qr{ 9991813087dSJoe Perches $NonptrTypeMisordered 10007b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 10011813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 10021813087dSJoe Perches }x; 100391cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 10041813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 10058905a67cSAndy Whitcroft} 10068905a67cSAndy Whitcroftbuild_types(); 10076c72ffaaSAndy Whitcroft 10087d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 1009d1fe9c09SJoe Perches 1010d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 1011d1fe9c09SJoe Perches# requires at least perl version v5.10.0 1012d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 1013d1fe9c09SJoe Perches 1014d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 10152435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 1016c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 10177d2367afSJoe Perches 1018f8422308SJoe Perchesour $declaration_macros = qr{(?x: 10193e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 1020fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 10213d102fc0SGilad Ben-Yossef (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( 1022f8422308SJoe Perches)}; 1023f8422308SJoe Perches 10248d0325ccSAditya Srivastavaour %allow_repeated_words = ( 10258d0325ccSAditya Srivastava add => '', 10268d0325ccSAditya Srivastava added => '', 10278d0325ccSAditya Srivastava bad => '', 10288d0325ccSAditya Srivastava be => '', 10298d0325ccSAditya Srivastava); 10308d0325ccSAditya Srivastava 10317d2367afSJoe Perchessub deparenthesize { 10327d2367afSJoe Perches my ($string) = @_; 10337d2367afSJoe Perches return "" if (!defined($string)); 10345b9553abSJoe Perches 10355b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 10365b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 10375b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 10385b9553abSJoe Perches } 10395b9553abSJoe Perches 10407d2367afSJoe Perches $string =~ s@\s+@ @g; 10415b9553abSJoe Perches 10427d2367afSJoe Perches return $string; 10437d2367afSJoe Perches} 10447d2367afSJoe Perches 10453445686aSJoe Perchessub seed_camelcase_file { 10463445686aSJoe Perches my ($file) = @_; 10473445686aSJoe Perches 10483445686aSJoe Perches return if (!(-f $file)); 10493445686aSJoe Perches 10503445686aSJoe Perches local $/; 10513445686aSJoe Perches 10523445686aSJoe Perches open(my $include_file, '<', "$file") 10533445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 10543445686aSJoe Perches my $text = <$include_file>; 10553445686aSJoe Perches close($include_file); 10563445686aSJoe Perches 10573445686aSJoe Perches my @lines = split('\n', $text); 10583445686aSJoe Perches 10593445686aSJoe Perches foreach my $line (@lines) { 10603445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 10613445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 10623445686aSJoe Perches $camelcase{$1} = 1; 106311ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 106411ea516aSJoe Perches $camelcase{$1} = 1; 106511ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 10663445686aSJoe Perches $camelcase{$1} = 1; 10673445686aSJoe Perches } 10683445686aSJoe Perches } 10693445686aSJoe Perches} 10703445686aSJoe Perches 1071cd28b119SJoe Perchesour %maintained_status = (); 1072cd28b119SJoe Perches 107385b0ee18SJoe Perchessub is_maintained_obsolete { 107485b0ee18SJoe Perches my ($filename) = @_; 107585b0ee18SJoe Perches 1076f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 107785b0ee18SJoe Perches 1078cd28b119SJoe Perches if (!exists($maintained_status{$filename})) { 1079cd28b119SJoe Perches $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 1080cd28b119SJoe Perches } 108185b0ee18SJoe Perches 1082cd28b119SJoe Perches return $maintained_status{$filename} =~ /obsolete/i; 108385b0ee18SJoe Perches} 108485b0ee18SJoe Perches 10853b6e8ac9SJoe Perchessub is_SPDX_License_valid { 10863b6e8ac9SJoe Perches my ($license) = @_; 10873b6e8ac9SJoe Perches 1088f9363b31SGuenter Roeck return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); 10893b6e8ac9SJoe Perches 109056294112SJoe Perches my $root_path = abs_path($root); 1091f9363b31SGuenter Roeck my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`; 10923b6e8ac9SJoe Perches return 0 if ($status ne ""); 10933b6e8ac9SJoe Perches return 1; 10943b6e8ac9SJoe Perches} 10953b6e8ac9SJoe Perches 10963445686aSJoe Perchesmy $camelcase_seeded = 0; 10973445686aSJoe Perchessub seed_camelcase_includes { 10983445686aSJoe Perches return if ($camelcase_seeded); 10993445686aSJoe Perches 11003445686aSJoe Perches my $files; 1101c707a81dSJoe Perches my $camelcase_cache = ""; 1102c707a81dSJoe Perches my @include_files = (); 1103c707a81dSJoe Perches 1104c707a81dSJoe Perches $camelcase_seeded = 1; 1105351b2a1fSJoe Perches 11060f7f635bSJoe Perches if (-e "$gitroot") { 1107dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 1108351b2a1fSJoe Perches chomp $git_last_include_commit; 1109c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 1110c707a81dSJoe Perches } else { 1111c707a81dSJoe Perches my $last_mod_date = 0; 1112c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 1113c707a81dSJoe Perches @include_files = split('\n', $files); 1114c707a81dSJoe Perches foreach my $file (@include_files) { 1115c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 1116c707a81dSJoe Perches localtime((stat $file)[9])); 1117c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 1118c707a81dSJoe Perches } 1119c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 1120c707a81dSJoe Perches } 1121c707a81dSJoe Perches 1122c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 1123c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 1124c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 1125351b2a1fSJoe Perches while (<$camelcase_file>) { 1126351b2a1fSJoe Perches chomp; 1127351b2a1fSJoe Perches $camelcase{$_} = 1; 1128351b2a1fSJoe Perches } 1129351b2a1fSJoe Perches close($camelcase_file); 1130351b2a1fSJoe Perches 1131351b2a1fSJoe Perches return; 1132351b2a1fSJoe Perches } 1133c707a81dSJoe Perches 11340f7f635bSJoe Perches if (-e "$gitroot") { 1135dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 1136c707a81dSJoe Perches @include_files = split('\n', $files); 11373445686aSJoe Perches } 1138c707a81dSJoe Perches 11393445686aSJoe Perches foreach my $file (@include_files) { 11403445686aSJoe Perches seed_camelcase_file($file); 11413445686aSJoe Perches } 1142351b2a1fSJoe Perches 1143c707a81dSJoe Perches if ($camelcase_cache ne "") { 1144351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 1145c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 1146c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 1147351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 1148351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 1149351b2a1fSJoe Perches } 1150351b2a1fSJoe Perches close($camelcase_file); 1151351b2a1fSJoe Perches } 11523445686aSJoe Perches} 11533445686aSJoe Perches 1154f5f61325SJoe Perchessub git_is_single_file { 1155f5f61325SJoe Perches my ($filename) = @_; 1156f5f61325SJoe Perches 1157f5f61325SJoe Perches return 0 if ((which("git") eq "") || !(-e "$gitroot")); 1158f5f61325SJoe Perches 1159f5f61325SJoe Perches my $output = `${git_command} ls-files -- $filename 2>/dev/null`; 1160f5f61325SJoe Perches my $count = $output =~ tr/\n//; 1161f5f61325SJoe Perches return $count eq 1 && $output =~ m{^${filename}$}; 1162f5f61325SJoe Perches} 1163f5f61325SJoe Perches 1164d311cd44SJoe Perchessub git_commit_info { 1165d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 1166d311cd44SJoe Perches 11670f7f635bSJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); 1168d311cd44SJoe Perches 1169dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 1170d311cd44SJoe Perches $output =~ s/^\s*//gm; 1171d311cd44SJoe Perches my @lines = split("\n", $output); 1172d311cd44SJoe Perches 11730d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 11740d7835fcSJoe Perches 11755a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 1176d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 1177d311cd44SJoe Perches# all matching commit ids, but it's very slow... 1178d311cd44SJoe Perches# 1179d311cd44SJoe Perches# echo "checking commits $1..." 1180d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 1181d311cd44SJoe Perches# while read line ; do 1182d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 1183d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 1184d311cd44SJoe Perches# done 11854ce9f970SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ || 11864ce9f970SJoe Perches $lines[0] =~ /^fatal: bad object $commit/) { 1187948b133aSHeinrich Schuchardt $id = undef; 1188d311cd44SJoe Perches } else { 1189d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 1190d311cd44SJoe Perches $desc = substr($lines[0], 41); 1191d311cd44SJoe Perches } 1192d311cd44SJoe Perches 1193d311cd44SJoe Perches return ($id, $desc); 1194d311cd44SJoe Perches} 1195d311cd44SJoe Perches 11966c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 11970a920b5bSAndy Whitcroft 119800df344fSAndy Whitcroftmy @rawlines = (); 1199c2fdda0dSAndy Whitcroftmy @lines = (); 12003705ce5bSJoe Perchesmy @fixed = (); 1201d752fcc8SJoe Perchesmy @fixed_inserted = (); 1202d752fcc8SJoe Perchesmy @fixed_deleted = (); 1203194f66fcSJoe Perchesmy $fixlinenr = -1; 1204194f66fcSJoe Perches 12054a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 12064a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 12070f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot"); 12084a593c34SDu, Changbin 12094a593c34SDu, Changbinif ($git) { 12104a593c34SDu, Changbin my @commits = (); 12110dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 12124a593c34SDu, Changbin my $git_range; 121328898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 121428898fd1SJoe Perches $git_range = "-$2 $1"; 12154a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 12164a593c34SDu, Changbin $git_range = "$commit_expr"; 12174a593c34SDu, Changbin } else { 12180dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 12190dea9f1eSJoe Perches } 1220dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 12210dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 122228898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 122328898fd1SJoe Perches next if (!defined($1) || !defined($2)); 12240dea9f1eSJoe Perches my $sha1 = $1; 12250dea9f1eSJoe Perches my $subject = $2; 12260dea9f1eSJoe Perches unshift(@commits, $sha1); 12270dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 12284a593c34SDu, Changbin } 12294a593c34SDu, Changbin } 12304a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 12314a593c34SDu, Changbin @ARGV = @commits; 12324a593c34SDu, Changbin} 12334a593c34SDu, Changbin 1234c2fdda0dSAndy Whitcroftmy $vname; 123598005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 12366c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 123721caa13cSAndy Whitcroft my $FILE; 1238f5f61325SJoe Perches my $is_git_file = git_is_single_file($filename); 1239f5f61325SJoe Perches my $oldfile = $file; 1240f5f61325SJoe Perches $file = 1 if ($is_git_file); 12414a593c34SDu, Changbin if ($git) { 12424a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 12434a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 12444a593c34SDu, Changbin } elsif ($file) { 124521caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 12466c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 124721caa13cSAndy Whitcroft } elsif ($filename eq '-') { 124821caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 12496c72ffaaSAndy Whitcroft } else { 125021caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 12516c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 12526c72ffaaSAndy Whitcroft } 1253c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1254c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 12554a593c34SDu, Changbin } elsif ($git) { 12560dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1257c2fdda0dSAndy Whitcroft } else { 1258c2fdda0dSAndy Whitcroft $vname = $filename; 1259c2fdda0dSAndy Whitcroft } 126021caa13cSAndy Whitcroft while (<$FILE>) { 12610a920b5bSAndy Whitcroft chomp; 126200df344fSAndy Whitcroft push(@rawlines, $_); 1263c7f574d0SGeert Uytterhoeven $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); 12646c72ffaaSAndy Whitcroft } 126521caa13cSAndy Whitcroft close($FILE); 1266d8469f16SJoe Perches 1267d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1268d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1269d8469f16SJoe Perches print "$vname\n"; 1270d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1271d8469f16SJoe Perches } 1272d8469f16SJoe Perches 1273c2fdda0dSAndy Whitcroft if (!process($filename)) { 12740a920b5bSAndy Whitcroft $exit = 1; 12750a920b5bSAndy Whitcroft } 127600df344fSAndy Whitcroft @rawlines = (); 127713214adfSAndy Whitcroft @lines = (); 12783705ce5bSJoe Perches @fixed = (); 1279d752fcc8SJoe Perches @fixed_inserted = (); 1280d752fcc8SJoe Perches @fixed_deleted = (); 1281194f66fcSJoe Perches $fixlinenr = -1; 1282485ff23eSAlex Dowad @modifierListFile = (); 1283485ff23eSAlex Dowad @typeListFile = (); 1284485ff23eSAlex Dowad build_types(); 1285f5f61325SJoe Perches $file = $oldfile if ($is_git_file); 12860a920b5bSAndy Whitcroft} 12870a920b5bSAndy Whitcroft 1288d8469f16SJoe Perchesif (!$quiet) { 12893c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 12903c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 12913c816e49SJoe Perches 12925b57980dSJoe Perches if (!$perl_version_ok) { 1293d8469f16SJoe Perches print << "EOM" 1294d8469f16SJoe Perches 1295d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 12965b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1297d8469f16SJoe PerchesEOM 1298d8469f16SJoe Perches } 1299d8469f16SJoe Perches if ($exit) { 1300d8469f16SJoe Perches print << "EOM" 1301d8469f16SJoe Perches 1302d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1303d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1304d8469f16SJoe PerchesEOM 1305d8469f16SJoe Perches } 1306d8469f16SJoe Perches} 1307d8469f16SJoe Perches 13080a920b5bSAndy Whitcroftexit($exit); 13090a920b5bSAndy Whitcroft 13100a920b5bSAndy Whitcroftsub top_of_kernel_tree { 13116c72ffaaSAndy Whitcroft my ($root) = @_; 13126c72ffaaSAndy Whitcroft 13136c72ffaaSAndy Whitcroft my @tree_check = ( 13146c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 13156c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 13166c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 13176c72ffaaSAndy Whitcroft ); 13186c72ffaaSAndy Whitcroft 13196c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 13206c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 13210a920b5bSAndy Whitcroft return 0; 13220a920b5bSAndy Whitcroft } 13236c72ffaaSAndy Whitcroft } 13246c72ffaaSAndy Whitcroft return 1; 13256c72ffaaSAndy Whitcroft} 13260a920b5bSAndy Whitcroft 132720112475SJoe Perchessub parse_email { 132820112475SJoe Perches my ($formatted_email) = @_; 132920112475SJoe Perches 133020112475SJoe Perches my $name = ""; 1331fccaebf0SDwaipayan Ray my $quoted = ""; 1332dfa05c28SJoe Perches my $name_comment = ""; 133320112475SJoe Perches my $address = ""; 133420112475SJoe Perches my $comment = ""; 133520112475SJoe Perches 133620112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 133720112475SJoe Perches $name = $1; 133820112475SJoe Perches $address = $2; 133920112475SJoe Perches $comment = $3 if defined $3; 134020112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 134120112475SJoe Perches $address = $1; 134220112475SJoe Perches $comment = $2 if defined $2; 134320112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 134420112475SJoe Perches $address = $1; 134520112475SJoe Perches $comment = $2 if defined $2; 134685e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 134720112475SJoe Perches $name = $formatted_email; 13483705ce5bSJoe Perches $name = trim($name); 134920112475SJoe Perches $name =~ s/^\"|\"$//g; 135020112475SJoe Perches # If there's a name left after stripping spaces and 135120112475SJoe Perches # leading quotes, and the address doesn't have both 135220112475SJoe Perches # leading and trailing angle brackets, the address 135320112475SJoe Perches # is invalid. ie: 135420112475SJoe Perches # "joe smith [email protected]" bad 135520112475SJoe Perches # "joe smith <[email protected]" bad 135620112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 135720112475SJoe Perches $name = ""; 135820112475SJoe Perches $address = ""; 135920112475SJoe Perches $comment = ""; 136020112475SJoe Perches } 136120112475SJoe Perches } 136220112475SJoe Perches 1363fccaebf0SDwaipayan Ray # Extract comments from names excluding quoted parts 1364fccaebf0SDwaipayan Ray # "John D. (Doe)" - Do not extract 1365fccaebf0SDwaipayan Ray if ($name =~ s/\"(.+)\"//) { 1366fccaebf0SDwaipayan Ray $quoted = $1; 1367dfa05c28SJoe Perches } 1368fccaebf0SDwaipayan Ray while ($name =~ s/\s*($balanced_parens)\s*/ /) { 1369fccaebf0SDwaipayan Ray $name_comment .= trim($1); 1370fccaebf0SDwaipayan Ray } 1371fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 1372fccaebf0SDwaipayan Ray $name = trim("$quoted $name"); 1373fccaebf0SDwaipayan Ray 13743705ce5bSJoe Perches $address = trim($address); 137520112475SJoe Perches $address =~ s/^\<|\>$//g; 1376fccaebf0SDwaipayan Ray $comment = trim($comment); 137720112475SJoe Perches 137820112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 137920112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 138020112475SJoe Perches $name = "\"$name\""; 138120112475SJoe Perches } 138220112475SJoe Perches 1383dfa05c28SJoe Perches return ($name, $name_comment, $address, $comment); 138420112475SJoe Perches} 138520112475SJoe Perches 138620112475SJoe Perchessub format_email { 138748ca2d8aSDwaipayan Ray my ($name, $name_comment, $address, $comment) = @_; 138820112475SJoe Perches 138920112475SJoe Perches my $formatted_email; 139020112475SJoe Perches 1391fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 13923705ce5bSJoe Perches $address = trim($address); 1393fccaebf0SDwaipayan Ray $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes 139420112475SJoe Perches 139520112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 139620112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 139720112475SJoe Perches $name = "\"$name\""; 139820112475SJoe Perches } 139920112475SJoe Perches 1400fccaebf0SDwaipayan Ray $name_comment = trim($name_comment); 1401fccaebf0SDwaipayan Ray $name_comment = " $name_comment" if ($name_comment ne ""); 1402fccaebf0SDwaipayan Ray $comment = trim($comment); 1403fccaebf0SDwaipayan Ray $comment = " $comment" if ($comment ne ""); 1404fccaebf0SDwaipayan Ray 140520112475SJoe Perches if ("$name" eq "") { 140620112475SJoe Perches $formatted_email = "$address"; 140720112475SJoe Perches } else { 140848ca2d8aSDwaipayan Ray $formatted_email = "$name$name_comment <$address>"; 140920112475SJoe Perches } 141048ca2d8aSDwaipayan Ray $formatted_email .= "$comment"; 141120112475SJoe Perches return $formatted_email; 141220112475SJoe Perches} 141320112475SJoe Perches 1414dfa05c28SJoe Perchessub reformat_email { 1415dfa05c28SJoe Perches my ($email) = @_; 1416dfa05c28SJoe Perches 1417dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 141848ca2d8aSDwaipayan Ray return format_email($email_name, $name_comment, $email_address, $comment); 1419dfa05c28SJoe Perches} 1420dfa05c28SJoe Perches 1421dfa05c28SJoe Perchessub same_email_addresses { 1422fccaebf0SDwaipayan Ray my ($email1, $email2) = @_; 1423dfa05c28SJoe Perches 1424dfa05c28SJoe Perches my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); 1425dfa05c28SJoe Perches my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); 1426dfa05c28SJoe Perches 142748ca2d8aSDwaipayan Ray return $email1_name eq $email2_name && 142848ca2d8aSDwaipayan Ray $email1_address eq $email2_address && 142948ca2d8aSDwaipayan Ray $name1_comment eq $name2_comment && 143048ca2d8aSDwaipayan Ray $comment1 eq $comment2; 143148ca2d8aSDwaipayan Ray} 1432dfa05c28SJoe Perches 1433d311cd44SJoe Perchessub which { 1434d311cd44SJoe Perches my ($bin) = @_; 1435d311cd44SJoe Perches 1436d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1437d311cd44SJoe Perches if (-e "$path/$bin") { 1438d311cd44SJoe Perches return "$path/$bin"; 1439d311cd44SJoe Perches } 1440d311cd44SJoe Perches } 1441d311cd44SJoe Perches 1442d311cd44SJoe Perches return ""; 1443d311cd44SJoe Perches} 1444d311cd44SJoe Perches 1445000d1cc1SJoe Perchessub which_conf { 1446000d1cc1SJoe Perches my ($conf) = @_; 1447000d1cc1SJoe Perches 1448000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1449000d1cc1SJoe Perches if (-e "$path/$conf") { 1450000d1cc1SJoe Perches return "$path/$conf"; 1451000d1cc1SJoe Perches } 1452000d1cc1SJoe Perches } 1453000d1cc1SJoe Perches 1454000d1cc1SJoe Perches return ""; 1455000d1cc1SJoe Perches} 1456000d1cc1SJoe Perches 14570a920b5bSAndy Whitcroftsub expand_tabs { 14580a920b5bSAndy Whitcroft my ($str) = @_; 14590a920b5bSAndy Whitcroft 14600a920b5bSAndy Whitcroft my $res = ''; 14610a920b5bSAndy Whitcroft my $n = 0; 14620a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 14630a920b5bSAndy Whitcroft if ($c eq "\t") { 14640a920b5bSAndy Whitcroft $res .= ' '; 14650a920b5bSAndy Whitcroft $n++; 1466713a09deSAntonio Borneo for (; ($n % $tabsize) != 0; $n++) { 14670a920b5bSAndy Whitcroft $res .= ' '; 14680a920b5bSAndy Whitcroft } 14690a920b5bSAndy Whitcroft next; 14700a920b5bSAndy Whitcroft } 14710a920b5bSAndy Whitcroft $res .= $c; 14720a920b5bSAndy Whitcroft $n++; 14730a920b5bSAndy Whitcroft } 14740a920b5bSAndy Whitcroft 14750a920b5bSAndy Whitcroft return $res; 14760a920b5bSAndy Whitcroft} 14776c72ffaaSAndy Whitcroftsub copy_spacing { 1478773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 14796c72ffaaSAndy Whitcroft return $res; 14806c72ffaaSAndy Whitcroft} 14810a920b5bSAndy Whitcroft 14824a0df2efSAndy Whitcroftsub line_stats { 14834a0df2efSAndy Whitcroft my ($line) = @_; 14844a0df2efSAndy Whitcroft 14854a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 14864a0df2efSAndy Whitcroft $line =~ s/^.//; 14874a0df2efSAndy Whitcroft $line = expand_tabs($line); 14884a0df2efSAndy Whitcroft 14894a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 14904a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 14914a0df2efSAndy Whitcroft 14924a0df2efSAndy Whitcroft return (length($line), length($white)); 14934a0df2efSAndy Whitcroft} 14944a0df2efSAndy Whitcroft 1495773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1496773647a0SAndy Whitcroft 1497773647a0SAndy Whitcroftsub sanitise_line_reset { 1498773647a0SAndy Whitcroft my ($in_comment) = @_; 1499773647a0SAndy Whitcroft 1500773647a0SAndy Whitcroft if ($in_comment) { 1501773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1502773647a0SAndy Whitcroft } else { 1503773647a0SAndy Whitcroft $sanitise_quote = ''; 1504773647a0SAndy Whitcroft } 1505773647a0SAndy Whitcroft} 150600df344fSAndy Whitcroftsub sanitise_line { 150700df344fSAndy Whitcroft my ($line) = @_; 150800df344fSAndy Whitcroft 150900df344fSAndy Whitcroft my $res = ''; 151000df344fSAndy Whitcroft my $l = ''; 151100df344fSAndy Whitcroft 1512c2fdda0dSAndy Whitcroft my $qlen = 0; 1513773647a0SAndy Whitcroft my $off = 0; 1514773647a0SAndy Whitcroft my $c; 151500df344fSAndy Whitcroft 1516773647a0SAndy Whitcroft # Always copy over the diff marker. 1517773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1518773647a0SAndy Whitcroft 1519773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1520773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1521773647a0SAndy Whitcroft 15228d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1523773647a0SAndy Whitcroft # and end, all to $;. 1524773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1525773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1526773647a0SAndy Whitcroft 1527773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1528773647a0SAndy Whitcroft $off++; 152900df344fSAndy Whitcroft next; 1530773647a0SAndy Whitcroft } 153181bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1532773647a0SAndy Whitcroft $sanitise_quote = ''; 1533773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1534773647a0SAndy Whitcroft $off++; 1535773647a0SAndy Whitcroft next; 1536773647a0SAndy Whitcroft } 1537113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1538113f04a8SDaniel Walker $sanitise_quote = '//'; 1539113f04a8SDaniel Walker 1540113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1541113f04a8SDaniel Walker $off++; 1542113f04a8SDaniel Walker next; 1543113f04a8SDaniel Walker } 1544773647a0SAndy Whitcroft 1545773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1546773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1547773647a0SAndy Whitcroft $c eq "\\") { 1548773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1549773647a0SAndy Whitcroft $off++; 1550773647a0SAndy Whitcroft next; 1551773647a0SAndy Whitcroft } 1552773647a0SAndy Whitcroft # Regular quotes. 1553773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1554773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1555773647a0SAndy Whitcroft $sanitise_quote = $c; 1556773647a0SAndy Whitcroft 1557773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1558773647a0SAndy Whitcroft next; 1559773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1560773647a0SAndy Whitcroft $sanitise_quote = ''; 156100df344fSAndy Whitcroft } 156200df344fSAndy Whitcroft } 1563773647a0SAndy Whitcroft 1564fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1565773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1566773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1567113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1568113f04a8SDaniel Walker substr($res, $off, 1, $;); 1569773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1570773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 157100df344fSAndy Whitcroft } else { 1572773647a0SAndy Whitcroft substr($res, $off, 1, $c); 157300df344fSAndy Whitcroft } 1574c2fdda0dSAndy Whitcroft } 1575c2fdda0dSAndy Whitcroft 1576113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1577113f04a8SDaniel Walker $sanitise_quote = ''; 1578113f04a8SDaniel Walker } 1579113f04a8SDaniel Walker 1580c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1581c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1582c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1583c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1584c2fdda0dSAndy Whitcroft 1585c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1586c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1587c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1588c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1589c2fdda0dSAndy Whitcroft } 1590c2fdda0dSAndy Whitcroft 1591dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1592dadf680dSJoe Perches my $match = $1; 1593dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1594dadf680dSJoe Perches } 1595dadf680dSJoe Perches 159600df344fSAndy Whitcroft return $res; 159700df344fSAndy Whitcroft} 159800df344fSAndy Whitcroft 1599a6962d72SJoe Perchessub get_quoted_string { 1600a6962d72SJoe Perches my ($line, $rawline) = @_; 1601a6962d72SJoe Perches 1602478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 160333acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1604a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1605a6962d72SJoe Perches} 1606a6962d72SJoe Perches 16078905a67cSAndy Whitcroftsub ctx_statement_block { 16088905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 16098905a67cSAndy Whitcroft my $line = $linenr - 1; 16108905a67cSAndy Whitcroft my $blk = ''; 16118905a67cSAndy Whitcroft my $soff = $off; 16128905a67cSAndy Whitcroft my $coff = $off - 1; 1613773647a0SAndy Whitcroft my $coff_set = 0; 16148905a67cSAndy Whitcroft 161513214adfSAndy Whitcroft my $loff = 0; 161613214adfSAndy Whitcroft 16178905a67cSAndy Whitcroft my $type = ''; 16188905a67cSAndy Whitcroft my $level = 0; 1619a2750645SAndy Whitcroft my @stack = (); 1620cf655043SAndy Whitcroft my $p; 16218905a67cSAndy Whitcroft my $c; 16228905a67cSAndy Whitcroft my $len = 0; 162313214adfSAndy Whitcroft 162413214adfSAndy Whitcroft my $remainder; 16258905a67cSAndy Whitcroft while (1) { 1626a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1627a2750645SAndy Whitcroft 1628773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 16298905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 16308905a67cSAndy Whitcroft # context. 16318905a67cSAndy Whitcroft if ($off >= $len) { 16328905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1633dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1634c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 16358905a67cSAndy Whitcroft $remain--; 163613214adfSAndy Whitcroft $loff = $len; 1637c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 16388905a67cSAndy Whitcroft $len = length($blk); 16398905a67cSAndy Whitcroft $line++; 16408905a67cSAndy Whitcroft last; 16418905a67cSAndy Whitcroft } 16428905a67cSAndy Whitcroft # Bail if there is no further context. 16438905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 164413214adfSAndy Whitcroft if ($off >= $len) { 16458905a67cSAndy Whitcroft last; 16468905a67cSAndy Whitcroft } 1647f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1648f74bd194SAndy Whitcroft $level++; 1649f74bd194SAndy Whitcroft $type = '#'; 1650f74bd194SAndy Whitcroft } 16518905a67cSAndy Whitcroft } 1652cf655043SAndy Whitcroft $p = $c; 16538905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 165413214adfSAndy Whitcroft $remainder = substr($blk, $off); 16558905a67cSAndy Whitcroft 1656773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 16574635f4fbSAndy Whitcroft 16584635f4fbSAndy Whitcroft # Handle nested #if/#else. 16594635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 16604635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 16614635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 16624635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 16634635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 16644635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 16654635f4fbSAndy Whitcroft } 16664635f4fbSAndy Whitcroft 16678905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 16688905a67cSAndy Whitcroft # outermost level. 16698905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 16708905a67cSAndy Whitcroft last; 16718905a67cSAndy Whitcroft } 16728905a67cSAndy Whitcroft 167313214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1674773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1675773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1676773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1677773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1678773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1679773647a0SAndy Whitcroft $coff_set = 1; 1680773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1681773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 168213214adfSAndy Whitcroft } 168313214adfSAndy Whitcroft 16848905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 16858905a67cSAndy Whitcroft $level++; 16868905a67cSAndy Whitcroft $type = '('; 16878905a67cSAndy Whitcroft } 16888905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 16898905a67cSAndy Whitcroft $level--; 16908905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 16918905a67cSAndy Whitcroft 16928905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 16938905a67cSAndy Whitcroft $coff = $off; 1694773647a0SAndy Whitcroft $coff_set = 1; 1695773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 16968905a67cSAndy Whitcroft } 16978905a67cSAndy Whitcroft } 16988905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 16998905a67cSAndy Whitcroft $level++; 17008905a67cSAndy Whitcroft $type = '{'; 17018905a67cSAndy Whitcroft } 17028905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 17038905a67cSAndy Whitcroft $level--; 17048905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 17058905a67cSAndy Whitcroft 17068905a67cSAndy Whitcroft if ($level == 0) { 1707b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1708b998e001SPatrick Pannuto $off++; 1709b998e001SPatrick Pannuto } 17108905a67cSAndy Whitcroft last; 17118905a67cSAndy Whitcroft } 17128905a67cSAndy Whitcroft } 1713f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1714f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1715f74bd194SAndy Whitcroft $level--; 1716f74bd194SAndy Whitcroft $type = ''; 1717f74bd194SAndy Whitcroft $off++; 1718f74bd194SAndy Whitcroft last; 1719f74bd194SAndy Whitcroft } 17208905a67cSAndy Whitcroft $off++; 17218905a67cSAndy Whitcroft } 1722a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 172313214adfSAndy Whitcroft if ($off == $len) { 1724a3bb97a7SAndy Whitcroft $loff = $len + 1; 172513214adfSAndy Whitcroft $line++; 172613214adfSAndy Whitcroft $remain--; 172713214adfSAndy Whitcroft } 17288905a67cSAndy Whitcroft 17298905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 17308905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 17318905a67cSAndy Whitcroft 17328905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 17338905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 17348905a67cSAndy Whitcroft 1735773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 173613214adfSAndy Whitcroft 173713214adfSAndy Whitcroft return ($statement, $condition, 173813214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 173913214adfSAndy Whitcroft} 174013214adfSAndy Whitcroft 1741cf655043SAndy Whitcroftsub statement_lines { 1742cf655043SAndy Whitcroft my ($stmt) = @_; 1743cf655043SAndy Whitcroft 1744cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1745cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1746cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1747cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1748cf655043SAndy Whitcroft 1749cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1750cf655043SAndy Whitcroft 1751cf655043SAndy Whitcroft return $#stmt_lines + 2; 1752cf655043SAndy Whitcroft} 1753cf655043SAndy Whitcroft 1754cf655043SAndy Whitcroftsub statement_rawlines { 1755cf655043SAndy Whitcroft my ($stmt) = @_; 1756cf655043SAndy Whitcroft 1757cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1758cf655043SAndy Whitcroft 1759cf655043SAndy Whitcroft return $#stmt_lines + 2; 1760cf655043SAndy Whitcroft} 1761cf655043SAndy Whitcroft 1762cf655043SAndy Whitcroftsub statement_block_size { 1763cf655043SAndy Whitcroft my ($stmt) = @_; 1764cf655043SAndy Whitcroft 1765cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1766cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1767cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1768cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1769cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1770cf655043SAndy Whitcroft 1771cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1772cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1773cf655043SAndy Whitcroft 1774cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1775cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1776cf655043SAndy Whitcroft 1777cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1778cf655043SAndy Whitcroft return $stmt_lines; 1779cf655043SAndy Whitcroft } else { 1780cf655043SAndy Whitcroft return $stmt_statements; 1781cf655043SAndy Whitcroft } 1782cf655043SAndy Whitcroft} 1783cf655043SAndy Whitcroft 178413214adfSAndy Whitcroftsub ctx_statement_full { 178513214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 178613214adfSAndy Whitcroft my ($statement, $condition, $level); 178713214adfSAndy Whitcroft 178813214adfSAndy Whitcroft my (@chunks); 178913214adfSAndy Whitcroft 1790cf655043SAndy Whitcroft # Grab the first conditional/block pair. 179113214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 179213214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1793773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 179413214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1795cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1796cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1797cf655043SAndy Whitcroft } 1798cf655043SAndy Whitcroft 1799cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1800cf655043SAndy Whitcroft # could continue the statement. 1801cf655043SAndy Whitcroft for (;;) { 180213214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 180313214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1804cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1805773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1806cf655043SAndy Whitcroft #print "C: push\n"; 1807cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 180813214adfSAndy Whitcroft } 180913214adfSAndy Whitcroft 181013214adfSAndy Whitcroft return ($level, $linenr, @chunks); 18118905a67cSAndy Whitcroft} 18128905a67cSAndy Whitcroft 18134a0df2efSAndy Whitcroftsub ctx_block_get { 1814f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 18154a0df2efSAndy Whitcroft my $line; 18164a0df2efSAndy Whitcroft my $start = $linenr - 1; 18174a0df2efSAndy Whitcroft my $blk = ''; 18184a0df2efSAndy Whitcroft my @o; 18194a0df2efSAndy Whitcroft my @c; 18204a0df2efSAndy Whitcroft my @res = (); 18214a0df2efSAndy Whitcroft 1822f0a594c1SAndy Whitcroft my $level = 0; 18234635f4fbSAndy Whitcroft my @stack = ($level); 182400df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 182500df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 182600df344fSAndy Whitcroft $remain--; 182700df344fSAndy Whitcroft 182800df344fSAndy Whitcroft $blk .= $rawlines[$line]; 18294635f4fbSAndy Whitcroft 18304635f4fbSAndy Whitcroft # Handle nested #if/#else. 183101464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 18324635f4fbSAndy Whitcroft push(@stack, $level); 183301464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 18344635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 183501464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 18364635f4fbSAndy Whitcroft $level = pop(@stack); 18374635f4fbSAndy Whitcroft } 18384635f4fbSAndy Whitcroft 183901464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1840f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1841f0a594c1SAndy Whitcroft if ($off > 0) { 1842f0a594c1SAndy Whitcroft $off--; 1843f0a594c1SAndy Whitcroft next; 1844f0a594c1SAndy Whitcroft } 18454a0df2efSAndy Whitcroft 1846f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1847f0a594c1SAndy Whitcroft $level--; 1848f0a594c1SAndy Whitcroft last if ($level == 0); 1849f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1850f0a594c1SAndy Whitcroft $level++; 1851f0a594c1SAndy Whitcroft } 1852f0a594c1SAndy Whitcroft } 18534a0df2efSAndy Whitcroft 1854f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 185500df344fSAndy Whitcroft push(@res, $rawlines[$line]); 18564a0df2efSAndy Whitcroft } 18574a0df2efSAndy Whitcroft 1858f0a594c1SAndy Whitcroft last if ($level == 0); 18594a0df2efSAndy Whitcroft } 18604a0df2efSAndy Whitcroft 1861f0a594c1SAndy Whitcroft return ($level, @res); 18624a0df2efSAndy Whitcroft} 18634a0df2efSAndy Whitcroftsub ctx_block_outer { 18644a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 18654a0df2efSAndy Whitcroft 1866f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1867f0a594c1SAndy Whitcroft return @r; 18684a0df2efSAndy Whitcroft} 18694a0df2efSAndy Whitcroftsub ctx_block { 18704a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 18714a0df2efSAndy Whitcroft 1872f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1873f0a594c1SAndy Whitcroft return @r; 1874653d4876SAndy Whitcroft} 1875653d4876SAndy Whitcroftsub ctx_statement { 1876f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1877f0a594c1SAndy Whitcroft 1878f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1879f0a594c1SAndy Whitcroft return @r; 1880f0a594c1SAndy Whitcroft} 1881f0a594c1SAndy Whitcroftsub ctx_block_level { 1882653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1883653d4876SAndy Whitcroft 1884f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 18854a0df2efSAndy Whitcroft} 18869c0ca6f9SAndy Whitcroftsub ctx_statement_level { 18879c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 18889c0ca6f9SAndy Whitcroft 18899c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 18909c0ca6f9SAndy Whitcroft} 18914a0df2efSAndy Whitcroft 18924a0df2efSAndy Whitcroftsub ctx_locate_comment { 18934a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 18944a0df2efSAndy Whitcroft 1895a55ee0ccSJoe Perches # If c99 comment on the current line, or the line before or after 1896a55ee0ccSJoe Perches my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); 1897a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1898a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); 1899a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1900a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); 1901a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1902a55ee0ccSJoe Perches 19034a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1904a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 19054a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 19064a0df2efSAndy Whitcroft 19074a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 19084a0df2efSAndy Whitcroft # comment. 19094a0df2efSAndy Whitcroft my $in_comment = 0; 19104a0df2efSAndy Whitcroft $current_comment = ''; 19114a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 191200df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 191300df344fSAndy Whitcroft #warn " $line\n"; 19144a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 19154a0df2efSAndy Whitcroft $in_comment = 1; 19164a0df2efSAndy Whitcroft } 19174a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 19184a0df2efSAndy Whitcroft $in_comment = 1; 19194a0df2efSAndy Whitcroft } 19204a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 19214a0df2efSAndy Whitcroft $current_comment = ''; 19224a0df2efSAndy Whitcroft } 19234a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 19244a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 19254a0df2efSAndy Whitcroft $in_comment = 0; 19264a0df2efSAndy Whitcroft } 19274a0df2efSAndy Whitcroft } 19284a0df2efSAndy Whitcroft 19294a0df2efSAndy Whitcroft chomp($current_comment); 19304a0df2efSAndy Whitcroft return($current_comment); 19314a0df2efSAndy Whitcroft} 19324a0df2efSAndy Whitcroftsub ctx_has_comment { 19334a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 19344a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 19354a0df2efSAndy Whitcroft 193600df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 19374a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 19384a0df2efSAndy Whitcroft 19394a0df2efSAndy Whitcroft return ($cmt ne ''); 19404a0df2efSAndy Whitcroft} 19414a0df2efSAndy Whitcroft 19424d001e4dSAndy Whitcroftsub raw_line { 19434d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 19444d001e4dSAndy Whitcroft 19454d001e4dSAndy Whitcroft my $offset = $linenr - 1; 19464d001e4dSAndy Whitcroft $cnt++; 19474d001e4dSAndy Whitcroft 19484d001e4dSAndy Whitcroft my $line; 19494d001e4dSAndy Whitcroft while ($cnt) { 19504d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 19514d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 19524d001e4dSAndy Whitcroft $cnt--; 19534d001e4dSAndy Whitcroft } 19544d001e4dSAndy Whitcroft 19554d001e4dSAndy Whitcroft return $line; 19564d001e4dSAndy Whitcroft} 19574d001e4dSAndy Whitcroft 19582a9f9d85STobin C. Hardingsub get_stat_real { 19592a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 19602a9f9d85STobin C. Harding 19612a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 19622a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 19632a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 19642a9f9d85STobin C. Harding } 19652a9f9d85STobin C. Harding 19662a9f9d85STobin C. Harding return $stat_real; 19672a9f9d85STobin C. Harding} 19682a9f9d85STobin C. Harding 1969e3d95a2aSTobin C. Hardingsub get_stat_here { 1970e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 1971e3d95a2aSTobin C. Harding 1972e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 1973e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 1974e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 1975e3d95a2aSTobin C. Harding } 1976e3d95a2aSTobin C. Harding 1977e3d95a2aSTobin C. Harding return $herectx; 1978e3d95a2aSTobin C. Harding} 1979e3d95a2aSTobin C. Harding 19800a920b5bSAndy Whitcroftsub cat_vet { 19810a920b5bSAndy Whitcroft my ($vet) = @_; 19829c0ca6f9SAndy Whitcroft my ($res, $coded); 19830a920b5bSAndy Whitcroft 19849c0ca6f9SAndy Whitcroft $res = ''; 19856c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 19866c72ffaaSAndy Whitcroft $res .= $1; 19876c72ffaaSAndy Whitcroft if ($2 ne '') { 19889c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 19896c72ffaaSAndy Whitcroft $res .= $coded; 19906c72ffaaSAndy Whitcroft } 19919c0ca6f9SAndy Whitcroft } 19929c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 19930a920b5bSAndy Whitcroft 19949c0ca6f9SAndy Whitcroft return $res; 19950a920b5bSAndy Whitcroft} 19960a920b5bSAndy Whitcroft 1997c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1998cf655043SAndy Whitcroftmy $av_pending; 1999c2fdda0dSAndy Whitcroftmy @av_paren_type; 20001f65f947SAndy Whitcroftmy $av_pend_colon; 2001c2fdda0dSAndy Whitcroft 2002c2fdda0dSAndy Whitcroftsub annotate_reset { 2003c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 2004cf655043SAndy Whitcroft $av_pending = '_'; 2005cf655043SAndy Whitcroft @av_paren_type = ('E'); 20061f65f947SAndy Whitcroft $av_pend_colon = 'O'; 2007c2fdda0dSAndy Whitcroft} 2008c2fdda0dSAndy Whitcroft 20096c72ffaaSAndy Whitcroftsub annotate_values { 20106c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 20116c72ffaaSAndy Whitcroft 20126c72ffaaSAndy Whitcroft my $res; 20131f65f947SAndy Whitcroft my $var = '_' x length($stream); 20146c72ffaaSAndy Whitcroft my $cur = $stream; 20156c72ffaaSAndy Whitcroft 2016c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 20176c72ffaaSAndy Whitcroft 20186c72ffaaSAndy Whitcroft while (length($cur)) { 2019773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 2020cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 2021171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 20226c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 2023c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 2024c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 2025cf655043SAndy Whitcroft $type = pop(@av_paren_type); 2026c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 20276c72ffaaSAndy Whitcroft } 20286c72ffaaSAndy Whitcroft 2029c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 20309446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 20319446ef56SAndy Whitcroft push(@av_paren_type, $type); 2032addcdceaSAndy Whitcroft $type = 'c'; 20339446ef56SAndy Whitcroft 2034e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 2035c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 20366c72ffaaSAndy Whitcroft $type = 'T'; 20376c72ffaaSAndy Whitcroft 2038389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 2039389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 2040389a2fe5SAndy Whitcroft $type = 'T'; 2041389a2fe5SAndy Whitcroft 2042c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 2043171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 2044c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2045171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 2046171ae1a4SAndy Whitcroft if ($2 ne '') { 2047cf655043SAndy Whitcroft $av_pending = 'N'; 2048171ae1a4SAndy Whitcroft } 2049171ae1a4SAndy Whitcroft $type = 'E'; 2050171ae1a4SAndy Whitcroft 2051c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 2052171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 2053171ae1a4SAndy Whitcroft $av_preprocessor = 1; 2054171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 20556c72ffaaSAndy Whitcroft 2056c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 2057cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 2058c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2059cf655043SAndy Whitcroft 2060cf655043SAndy Whitcroft push(@av_paren_type, $type); 2061cf655043SAndy Whitcroft push(@av_paren_type, $type); 2062171ae1a4SAndy Whitcroft $type = 'E'; 2063cf655043SAndy Whitcroft 2064c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 2065cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 2066cf655043SAndy Whitcroft $av_preprocessor = 1; 2067cf655043SAndy Whitcroft 2068cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 2069cf655043SAndy Whitcroft 2070171ae1a4SAndy Whitcroft $type = 'E'; 2071cf655043SAndy Whitcroft 2072c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 2073cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 2074cf655043SAndy Whitcroft 2075cf655043SAndy Whitcroft $av_preprocessor = 1; 2076cf655043SAndy Whitcroft 2077cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 2078cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 2079cf655043SAndy Whitcroft pop(@av_paren_type); 2080cf655043SAndy Whitcroft push(@av_paren_type, $type); 2081171ae1a4SAndy Whitcroft $type = 'E'; 20826c72ffaaSAndy Whitcroft 20836c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 2084c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 20856c72ffaaSAndy Whitcroft 2086171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 2087171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 2088171ae1a4SAndy Whitcroft $av_pending = $type; 2089171ae1a4SAndy Whitcroft $type = 'N'; 2090171ae1a4SAndy Whitcroft 20916c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 2092c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 20936c72ffaaSAndy Whitcroft if (defined $2) { 2094cf655043SAndy Whitcroft $av_pending = 'V'; 20956c72ffaaSAndy Whitcroft } 20966c72ffaaSAndy Whitcroft $type = 'N'; 20976c72ffaaSAndy Whitcroft 209814b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 2099c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 210014b111c1SAndy Whitcroft $av_pending = 'E'; 21016c72ffaaSAndy Whitcroft $type = 'N'; 21026c72ffaaSAndy Whitcroft 21031f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 21041f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 21051f65f947SAndy Whitcroft $av_pend_colon = 'C'; 21061f65f947SAndy Whitcroft $type = 'N'; 21071f65f947SAndy Whitcroft 210814b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 2109c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 21106c72ffaaSAndy Whitcroft $type = 'N'; 21116c72ffaaSAndy Whitcroft 21126c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 2113c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 2114cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 2115cf655043SAndy Whitcroft $av_pending = '_'; 21166c72ffaaSAndy Whitcroft $type = 'N'; 21176c72ffaaSAndy Whitcroft 21186c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 2119cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 2120cf655043SAndy Whitcroft if ($new_type ne '_') { 2121cf655043SAndy Whitcroft $type = $new_type; 2122c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 2123c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 21246c72ffaaSAndy Whitcroft } else { 2125c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 21266c72ffaaSAndy Whitcroft } 21276c72ffaaSAndy Whitcroft 2128c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 2129c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 2130c8cb2ca3SAndy Whitcroft $type = 'V'; 2131cf655043SAndy Whitcroft $av_pending = 'V'; 21326c72ffaaSAndy Whitcroft 21338e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 21348e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 21351f65f947SAndy Whitcroft $av_pend_colon = 'B'; 21368e761b04SAndy Whitcroft } elsif ($type eq 'E') { 21378e761b04SAndy Whitcroft $av_pend_colon = 'L'; 21381f65f947SAndy Whitcroft } 21391f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 21401f65f947SAndy Whitcroft $type = 'V'; 21411f65f947SAndy Whitcroft 21426c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 2143c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 21446c72ffaaSAndy Whitcroft $type = 'V'; 21456c72ffaaSAndy Whitcroft 21466c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 2147c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 21486c72ffaaSAndy Whitcroft $type = 'N'; 21496c72ffaaSAndy Whitcroft 2150cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 2151c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 215213214adfSAndy Whitcroft $type = 'E'; 21531f65f947SAndy Whitcroft $av_pend_colon = 'O'; 215413214adfSAndy Whitcroft 21558e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 21568e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 21578e761b04SAndy Whitcroft $type = 'C'; 21588e761b04SAndy Whitcroft 21591f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 21601f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 21611f65f947SAndy Whitcroft $type = 'N'; 21621f65f947SAndy Whitcroft 21631f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 21641f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 21651f65f947SAndy Whitcroft 21661f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 21671f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 21681f65f947SAndy Whitcroft $type = 'E'; 21691f65f947SAndy Whitcroft } else { 21701f65f947SAndy Whitcroft $type = 'N'; 21711f65f947SAndy Whitcroft } 21721f65f947SAndy Whitcroft $av_pend_colon = 'O'; 21731f65f947SAndy Whitcroft 21748e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 217513214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 21766c72ffaaSAndy Whitcroft $type = 'N'; 21776c72ffaaSAndy Whitcroft 21780d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 217974048ed8SAndy Whitcroft my $variant; 218074048ed8SAndy Whitcroft 218174048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 218274048ed8SAndy Whitcroft if ($type eq 'V') { 218374048ed8SAndy Whitcroft $variant = 'B'; 218474048ed8SAndy Whitcroft } else { 218574048ed8SAndy Whitcroft $variant = 'U'; 218674048ed8SAndy Whitcroft } 218774048ed8SAndy Whitcroft 218874048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 218974048ed8SAndy Whitcroft $type = 'N'; 219074048ed8SAndy Whitcroft 21916c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 2192c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 21936c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 21946c72ffaaSAndy Whitcroft $type = 'N'; 21956c72ffaaSAndy Whitcroft } 21966c72ffaaSAndy Whitcroft 21976c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 2198c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 21996c72ffaaSAndy Whitcroft } 22006c72ffaaSAndy Whitcroft if (defined $1) { 22016c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 22026c72ffaaSAndy Whitcroft $res .= $type x length($1); 22036c72ffaaSAndy Whitcroft } 22046c72ffaaSAndy Whitcroft } 22056c72ffaaSAndy Whitcroft 22061f65f947SAndy Whitcroft return ($res, $var); 22076c72ffaaSAndy Whitcroft} 22086c72ffaaSAndy Whitcroft 22098905a67cSAndy Whitcroftsub possible { 221013214adfSAndy Whitcroft my ($possible, $line) = @_; 22119a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 22120776e594SAndy Whitcroft ^(?: 22130776e594SAndy Whitcroft $Modifier| 22140776e594SAndy Whitcroft $Storage| 22150776e594SAndy Whitcroft $Type| 22169a974fdbSAndy Whitcroft DEFINE_\S+ 22179a974fdbSAndy Whitcroft )$| 22189a974fdbSAndy Whitcroft ^(?: 22190776e594SAndy Whitcroft goto| 22200776e594SAndy Whitcroft return| 22210776e594SAndy Whitcroft case| 22220776e594SAndy Whitcroft else| 22230776e594SAndy Whitcroft asm|__asm__| 222489a88353SAndy Whitcroft do| 222589a88353SAndy Whitcroft \#| 222689a88353SAndy Whitcroft \#\#| 22279a974fdbSAndy Whitcroft )(?:\s|$)| 22280776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 22299a974fdbSAndy Whitcroft )}x; 22309a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 22319a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 2232c45dcabdSAndy Whitcroft # Check for modifiers. 2233c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 2234c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 2235c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 2236c45dcabdSAndy Whitcroft 2237c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 2238c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 2239d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 22409a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 2241d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 2242485ff23eSAlex Dowad push(@modifierListFile, $modifier); 2243d2506586SAndy Whitcroft } 22449a974fdbSAndy Whitcroft } 2245c45dcabdSAndy Whitcroft 2246c45dcabdSAndy Whitcroft } else { 224713214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 2248485ff23eSAlex Dowad push(@typeListFile, $possible); 2249c45dcabdSAndy Whitcroft } 22508905a67cSAndy Whitcroft build_types(); 22510776e594SAndy Whitcroft } else { 22520776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 22538905a67cSAndy Whitcroft } 22548905a67cSAndy Whitcroft} 22558905a67cSAndy Whitcroft 22566c72ffaaSAndy Whitcroftmy $prefix = ''; 22576c72ffaaSAndy Whitcroft 2258000d1cc1SJoe Perchessub show_type { 2259cbec18afSJoe Perches my ($type) = @_; 226091bfe484SJoe Perches 2261522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2262522b837cSAlexey Dobriyan 2263cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2264cbec18afSJoe Perches 2265cbec18afSJoe Perches return !defined $ignore_type{$type}; 2266000d1cc1SJoe Perches} 2267000d1cc1SJoe Perches 2268f0a594c1SAndy Whitcroftsub report { 2269cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2270cbec18afSJoe Perches 2271cbec18afSJoe Perches if (!show_type($type) || 2272cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2273773647a0SAndy Whitcroft return 0; 2274773647a0SAndy Whitcroft } 227557230297SJoe Perches my $output = ''; 2276737c0767SJohn Brooks if ($color) { 227757230297SJoe Perches if ($level eq 'ERROR') { 227857230297SJoe Perches $output .= RED; 227957230297SJoe Perches } elsif ($level eq 'WARNING') { 228057230297SJoe Perches $output .= YELLOW; 2281000d1cc1SJoe Perches } else { 228257230297SJoe Perches $output .= GREEN; 2283000d1cc1SJoe Perches } 228457230297SJoe Perches } 228557230297SJoe Perches $output .= $prefix . $level . ':'; 228657230297SJoe Perches if ($show_types) { 2287737c0767SJohn Brooks $output .= BLUE if ($color); 228857230297SJoe Perches $output .= "$type:"; 228957230297SJoe Perches } 2290737c0767SJohn Brooks $output .= RESET if ($color); 229157230297SJoe Perches $output .= ' ' . $msg . "\n"; 229234d8815fSJoe Perches 229334d8815fSJoe Perches if ($showfile) { 229434d8815fSJoe Perches my @lines = split("\n", $output, -1); 229534d8815fSJoe Perches splice(@lines, 1, 1); 229634d8815fSJoe Perches $output = join("\n", @lines); 229734d8815fSJoe Perches } 229852178ce0SDwaipayan Ray 229952178ce0SDwaipayan Ray if ($terse) { 230052178ce0SDwaipayan Ray $output = (split('\n', $output))[0] . "\n"; 230152178ce0SDwaipayan Ray } 230252178ce0SDwaipayan Ray 230352178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$type}) && 230452178ce0SDwaipayan Ray !exists($verbose_emitted{$type})) { 230552178ce0SDwaipayan Ray $output .= $verbose_messages{$type} . "\n\n"; 230652178ce0SDwaipayan Ray $verbose_emitted{$type} = 1; 230752178ce0SDwaipayan Ray } 23088905a67cSAndy Whitcroft 230957230297SJoe Perches push(our @report, $output); 2310773647a0SAndy Whitcroft 2311773647a0SAndy Whitcroft return 1; 2312f0a594c1SAndy Whitcroft} 2313cbec18afSJoe Perches 2314f0a594c1SAndy Whitcroftsub report_dump { 231513214adfSAndy Whitcroft our @report; 2316f0a594c1SAndy Whitcroft} 2317000d1cc1SJoe Perches 2318d752fcc8SJoe Perchessub fixup_current_range { 2319d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2320d752fcc8SJoe Perches 2321d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2322d752fcc8SJoe Perches my $o = $1; 2323d752fcc8SJoe Perches my $l = $2; 2324d752fcc8SJoe Perches my $no = $o + $offset; 2325d752fcc8SJoe Perches my $nl = $l + $length; 2326d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2327d752fcc8SJoe Perches } 2328d752fcc8SJoe Perches} 2329d752fcc8SJoe Perches 2330d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2331d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2332d752fcc8SJoe Perches 2333d752fcc8SJoe Perches my $range_last_linenr = 0; 2334d752fcc8SJoe Perches my $delta_offset = 0; 2335d752fcc8SJoe Perches 2336d752fcc8SJoe Perches my $old_linenr = 0; 2337d752fcc8SJoe Perches my $new_linenr = 0; 2338d752fcc8SJoe Perches 2339d752fcc8SJoe Perches my $next_insert = 0; 2340d752fcc8SJoe Perches my $next_delete = 0; 2341d752fcc8SJoe Perches 2342d752fcc8SJoe Perches my @lines = (); 2343d752fcc8SJoe Perches 2344d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2345d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2346d752fcc8SJoe Perches 2347d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2348d752fcc8SJoe Perches my $save_line = 1; 2349d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2350323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2351d752fcc8SJoe Perches $delta_offset = 0; 2352d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2353d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2354d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2355d752fcc8SJoe Perches } 2356d752fcc8SJoe Perches 2357d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2358d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2359d752fcc8SJoe Perches $save_line = 0; 2360d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2361d752fcc8SJoe Perches } 2362d752fcc8SJoe Perches 2363d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2364d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2365d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2366d752fcc8SJoe Perches $new_linenr++; 2367d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2368d752fcc8SJoe Perches } 2369d752fcc8SJoe Perches 2370d752fcc8SJoe Perches if ($save_line) { 2371d752fcc8SJoe Perches push(@lines, $line); 2372d752fcc8SJoe Perches $new_linenr++; 2373d752fcc8SJoe Perches } 2374d752fcc8SJoe Perches 2375d752fcc8SJoe Perches $old_linenr++; 2376d752fcc8SJoe Perches } 2377d752fcc8SJoe Perches 2378d752fcc8SJoe Perches return @lines; 2379d752fcc8SJoe Perches} 2380d752fcc8SJoe Perches 2381f2d7e4d4SJoe Perchessub fix_insert_line { 2382f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2383f2d7e4d4SJoe Perches 2384f2d7e4d4SJoe Perches my $inserted = { 2385f2d7e4d4SJoe Perches LINENR => $linenr, 2386f2d7e4d4SJoe Perches LINE => $line, 2387f2d7e4d4SJoe Perches }; 2388f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2389f2d7e4d4SJoe Perches} 2390f2d7e4d4SJoe Perches 2391f2d7e4d4SJoe Perchessub fix_delete_line { 2392f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2393f2d7e4d4SJoe Perches 2394f2d7e4d4SJoe Perches my $deleted = { 2395f2d7e4d4SJoe Perches LINENR => $linenr, 2396f2d7e4d4SJoe Perches LINE => $line, 2397f2d7e4d4SJoe Perches }; 2398f2d7e4d4SJoe Perches 2399f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2400f2d7e4d4SJoe Perches} 2401f2d7e4d4SJoe Perches 2402de7d4f0eSAndy Whitcroftsub ERROR { 2403cbec18afSJoe Perches my ($type, $msg) = @_; 2404cbec18afSJoe Perches 2405cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2406de7d4f0eSAndy Whitcroft our $clean = 0; 24076c72ffaaSAndy Whitcroft our $cnt_error++; 24083705ce5bSJoe Perches return 1; 2409de7d4f0eSAndy Whitcroft } 24103705ce5bSJoe Perches return 0; 2411773647a0SAndy Whitcroft} 2412de7d4f0eSAndy Whitcroftsub WARN { 2413cbec18afSJoe Perches my ($type, $msg) = @_; 2414cbec18afSJoe Perches 2415cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2416de7d4f0eSAndy Whitcroft our $clean = 0; 24176c72ffaaSAndy Whitcroft our $cnt_warn++; 24183705ce5bSJoe Perches return 1; 2419de7d4f0eSAndy Whitcroft } 24203705ce5bSJoe Perches return 0; 2421773647a0SAndy Whitcroft} 2422de7d4f0eSAndy Whitcroftsub CHK { 2423cbec18afSJoe Perches my ($type, $msg) = @_; 2424cbec18afSJoe Perches 2425cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2426de7d4f0eSAndy Whitcroft our $clean = 0; 24276c72ffaaSAndy Whitcroft our $cnt_chk++; 24283705ce5bSJoe Perches return 1; 24296c72ffaaSAndy Whitcroft } 24303705ce5bSJoe Perches return 0; 2431de7d4f0eSAndy Whitcroft} 2432de7d4f0eSAndy Whitcroft 24336ecd9674SAndy Whitcroftsub check_absolute_file { 24346ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 24356ecd9674SAndy Whitcroft my $file = $absolute; 24366ecd9674SAndy Whitcroft 24376ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 24386ecd9674SAndy Whitcroft 24396ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 24406ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 24416ecd9674SAndy Whitcroft if (-f "$root/$file") { 24426ecd9674SAndy Whitcroft ##print "file<$file>\n"; 24436ecd9674SAndy Whitcroft last; 24446ecd9674SAndy Whitcroft } 24456ecd9674SAndy Whitcroft } 24466ecd9674SAndy Whitcroft if (! -f _) { 24476ecd9674SAndy Whitcroft return 0; 24486ecd9674SAndy Whitcroft } 24496ecd9674SAndy Whitcroft 24506ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 24516ecd9674SAndy Whitcroft my $prefix = $absolute; 24526ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 24536ecd9674SAndy Whitcroft 24546ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 24556ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2456000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2457000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 24586ecd9674SAndy Whitcroft } 24596ecd9674SAndy Whitcroft} 24606ecd9674SAndy Whitcroft 24613705ce5bSJoe Perchessub trim { 24623705ce5bSJoe Perches my ($string) = @_; 24633705ce5bSJoe Perches 2464b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2465b34c648bSJoe Perches 2466b34c648bSJoe Perches return $string; 2467b34c648bSJoe Perches} 2468b34c648bSJoe Perches 2469b34c648bSJoe Perchessub ltrim { 2470b34c648bSJoe Perches my ($string) = @_; 2471b34c648bSJoe Perches 2472b34c648bSJoe Perches $string =~ s/^\s+//; 2473b34c648bSJoe Perches 2474b34c648bSJoe Perches return $string; 2475b34c648bSJoe Perches} 2476b34c648bSJoe Perches 2477b34c648bSJoe Perchessub rtrim { 2478b34c648bSJoe Perches my ($string) = @_; 2479b34c648bSJoe Perches 2480b34c648bSJoe Perches $string =~ s/\s+$//; 24813705ce5bSJoe Perches 24823705ce5bSJoe Perches return $string; 24833705ce5bSJoe Perches} 24843705ce5bSJoe Perches 248552ea8506SJoe Perchessub string_find_replace { 248652ea8506SJoe Perches my ($string, $find, $replace) = @_; 248752ea8506SJoe Perches 248852ea8506SJoe Perches $string =~ s/$find/$replace/g; 248952ea8506SJoe Perches 249052ea8506SJoe Perches return $string; 249152ea8506SJoe Perches} 249252ea8506SJoe Perches 24933705ce5bSJoe Perchessub tabify { 24943705ce5bSJoe Perches my ($leading) = @_; 24953705ce5bSJoe Perches 2496713a09deSAntonio Borneo my $source_indent = $tabsize; 24973705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 24983705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 24993705ce5bSJoe Perches 25003705ce5bSJoe Perches #convert leading spaces to tabs 25013705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 25023705ce5bSJoe Perches #Remove spaces before a tab 25033705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 25043705ce5bSJoe Perches 25053705ce5bSJoe Perches return "$leading"; 25063705ce5bSJoe Perches} 25073705ce5bSJoe Perches 2508d1fe9c09SJoe Perchessub pos_last_openparen { 2509d1fe9c09SJoe Perches my ($line) = @_; 2510d1fe9c09SJoe Perches 2511d1fe9c09SJoe Perches my $pos = 0; 2512d1fe9c09SJoe Perches 2513d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2514d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2515d1fe9c09SJoe Perches 2516d1fe9c09SJoe Perches my $last_openparen = 0; 2517d1fe9c09SJoe Perches 2518d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2519d1fe9c09SJoe Perches return -1; 2520d1fe9c09SJoe Perches } 2521d1fe9c09SJoe Perches 2522d1fe9c09SJoe Perches my $len = length($line); 2523d1fe9c09SJoe Perches 2524d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2525d1fe9c09SJoe Perches my $string = substr($line, $pos); 2526d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2527d1fe9c09SJoe Perches $pos += length($1) - 1; 2528d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2529d1fe9c09SJoe Perches $last_openparen = $pos; 2530d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2531d1fe9c09SJoe Perches last; 2532d1fe9c09SJoe Perches } 2533d1fe9c09SJoe Perches } 2534d1fe9c09SJoe Perches 253591cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2536d1fe9c09SJoe Perches} 2537d1fe9c09SJoe Perches 2538f36d3eb8SJoe Perchessub get_raw_comment { 2539f36d3eb8SJoe Perches my ($line, $rawline) = @_; 2540f36d3eb8SJoe Perches my $comment = ''; 2541f36d3eb8SJoe Perches 2542f36d3eb8SJoe Perches for my $i (0 .. (length($line) - 1)) { 2543f36d3eb8SJoe Perches if (substr($line, $i, 1) eq "$;") { 2544f36d3eb8SJoe Perches $comment .= substr($rawline, $i, 1); 2545f36d3eb8SJoe Perches } 2546f36d3eb8SJoe Perches } 2547f36d3eb8SJoe Perches 2548f36d3eb8SJoe Perches return $comment; 2549f36d3eb8SJoe Perches} 2550f36d3eb8SJoe Perches 25515b8f82e1SSong Liusub exclude_global_initialisers { 25525b8f82e1SSong Liu my ($realfile) = @_; 25535b8f82e1SSong Liu 25545b8f82e1SSong Liu # Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c). 25555b8f82e1SSong Liu return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ || 25565b8f82e1SSong Liu $realfile =~ m@^samples/bpf/.*_kern\.c$@ || 25575b8f82e1SSong Liu $realfile =~ m@/bpf/.*\.bpf\.c$@; 25585b8f82e1SSong Liu} 25595b8f82e1SSong Liu 25600a920b5bSAndy Whitcroftsub process { 25610a920b5bSAndy Whitcroft my $filename = shift; 25620a920b5bSAndy Whitcroft 25630a920b5bSAndy Whitcroft my $linenr=0; 25640a920b5bSAndy Whitcroft my $prevline=""; 2565c2fdda0dSAndy Whitcroft my $prevrawline=""; 25660a920b5bSAndy Whitcroft my $stashline=""; 2567c2fdda0dSAndy Whitcroft my $stashrawline=""; 25680a920b5bSAndy Whitcroft 25694a0df2efSAndy Whitcroft my $length; 25700a920b5bSAndy Whitcroft my $indent; 25710a920b5bSAndy Whitcroft my $previndent=0; 25720a920b5bSAndy Whitcroft my $stashindent=0; 25730a920b5bSAndy Whitcroft 2574de7d4f0eSAndy Whitcroft our $clean = 1; 25750a920b5bSAndy Whitcroft my $signoff = 0; 2576cd261496SGeert Uytterhoeven my $author = ''; 2577cd261496SGeert Uytterhoeven my $authorsignoff = 0; 257848ca2d8aSDwaipayan Ray my $author_sob = ''; 25790a920b5bSAndy Whitcroft my $is_patch = 0; 2580133712a2SRob Herring my $is_binding_patch = -1; 258129ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 258215662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 258344d303ebSJoe Perches my $has_patch_separator = 0; #Found a --- line 2584ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2585490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2586bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 25872a076f40SJoe Perches my $commit_log_long_line = 0; 2588e518e9a5SJoe Perches my $commit_log_has_diff = 0; 258913f1937eSJoe Perches my $reported_maintainer_file = 0; 2590fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2591fa64205dSPasi Savanainen 25924ce9f970SJoe Perches my $last_git_commit_id_linenr = -1; 25934ce9f970SJoe Perches 2594365dd4eaSJoe Perches my $last_blank_line = 0; 25955e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2596365dd4eaSJoe Perches 259713214adfSAndy Whitcroft our @report = (); 25986c72ffaaSAndy Whitcroft our $cnt_lines = 0; 25996c72ffaaSAndy Whitcroft our $cnt_error = 0; 26006c72ffaaSAndy Whitcroft our $cnt_warn = 0; 26016c72ffaaSAndy Whitcroft our $cnt_chk = 0; 26026c72ffaaSAndy Whitcroft 26030a920b5bSAndy Whitcroft # Trace the real file/line as we go. 26040a920b5bSAndy Whitcroft my $realfile = ''; 26050a920b5bSAndy Whitcroft my $realline = 0; 26060a920b5bSAndy Whitcroft my $realcnt = 0; 26070a920b5bSAndy Whitcroft my $here = ''; 260877cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 26090a920b5bSAndy Whitcroft my $in_comment = 0; 2610c2fdda0dSAndy Whitcroft my $comment_edge = 0; 26110a920b5bSAndy Whitcroft my $first_line = 0; 26121e855726SWolfram Sang my $p1_prefix = ''; 26130a920b5bSAndy Whitcroft 261413214adfSAndy Whitcroft my $prev_values = 'E'; 261513214adfSAndy Whitcroft 261613214adfSAndy Whitcroft # suppression flags 2617773647a0SAndy Whitcroft my %suppress_ifbraces; 2618170d3a22SAndy Whitcroft my %suppress_whiletrailers; 26192b474a1aSAndy Whitcroft my %suppress_export; 26203e469cdcSAndy Whitcroft my $suppress_statement = 0; 2621653d4876SAndy Whitcroft 26227e51f197SJoe Perches my %signatures = (); 2623323c1260SJoe Perches 2624c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2625de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2626c2fdda0dSAndy Whitcroft # 2627de7d4f0eSAndy Whitcroft my @setup_docs = (); 2628de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2629773647a0SAndy Whitcroft 2630d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2631d8b07710SJoe Perches 26329f3a8992SRob Herring my $checklicenseline = 1; 26339f3a8992SRob Herring 2634773647a0SAndy Whitcroft sanitise_line_reset(); 2635c2fdda0dSAndy Whitcroft my $line; 2636c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2637773647a0SAndy Whitcroft $linenr++; 2638773647a0SAndy Whitcroft $line = $rawline; 2639c2fdda0dSAndy Whitcroft 26403705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 26413705ce5bSJoe Perches 2642773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2643de7d4f0eSAndy Whitcroft $setup_docs = 0; 26442581ac7cSTim Froidcoeur if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { 2645de7d4f0eSAndy Whitcroft $setup_docs = 1; 2646de7d4f0eSAndy Whitcroft } 2647773647a0SAndy Whitcroft #next; 2648de7d4f0eSAndy Whitcroft } 264974fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2650773647a0SAndy Whitcroft $realline=$1-1; 2651773647a0SAndy Whitcroft if (defined $2) { 2652773647a0SAndy Whitcroft $realcnt=$3+1; 2653773647a0SAndy Whitcroft } else { 2654773647a0SAndy Whitcroft $realcnt=1+1; 2655773647a0SAndy Whitcroft } 2656c45dcabdSAndy Whitcroft $in_comment = 0; 2657773647a0SAndy Whitcroft 2658773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2659773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2660773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2661773647a0SAndy Whitcroft # at context start. 2662773647a0SAndy Whitcroft my $edge; 266301fa9147SAndy Whitcroft my $cnt = $realcnt; 266401fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 266501fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 266601fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 266701fa9147SAndy Whitcroft $cnt--; 266801fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2669721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2670fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2671fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2672fae17daeSAndy Whitcroft ($edge) = $1; 2673fae17daeSAndy Whitcroft last; 2674fae17daeSAndy Whitcroft } 2675773647a0SAndy Whitcroft } 2676773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2677773647a0SAndy Whitcroft $in_comment = 1; 2678773647a0SAndy Whitcroft } 2679773647a0SAndy Whitcroft 2680773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2681773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2682773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2683773647a0SAndy Whitcroft if (!defined $edge && 268483242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2685773647a0SAndy Whitcroft { 2686773647a0SAndy Whitcroft $in_comment = 1; 2687773647a0SAndy Whitcroft } 2688773647a0SAndy Whitcroft 2689773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2690773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2691773647a0SAndy Whitcroft 2692171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2693773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2694171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2695773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2696773647a0SAndy Whitcroft } 2697773647a0SAndy Whitcroft push(@lines, $line); 2698773647a0SAndy Whitcroft 2699773647a0SAndy Whitcroft if ($realcnt > 1) { 2700773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2701773647a0SAndy Whitcroft } else { 2702773647a0SAndy Whitcroft $realcnt = 0; 2703773647a0SAndy Whitcroft } 2704773647a0SAndy Whitcroft 2705773647a0SAndy Whitcroft #print "==>$rawline\n"; 2706773647a0SAndy Whitcroft #print "-->$line\n"; 2707de7d4f0eSAndy Whitcroft 2708de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2709de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2710de7d4f0eSAndy Whitcroft } 2711de7d4f0eSAndy Whitcroft } 2712de7d4f0eSAndy Whitcroft 27136c72ffaaSAndy Whitcroft $prefix = ''; 27146c72ffaaSAndy Whitcroft 2715773647a0SAndy Whitcroft $realcnt = 0; 2716773647a0SAndy Whitcroft $linenr = 0; 2717194f66fcSJoe Perches $fixlinenr = -1; 27180a920b5bSAndy Whitcroft foreach my $line (@lines) { 27190a920b5bSAndy Whitcroft $linenr++; 2720194f66fcSJoe Perches $fixlinenr++; 27211b5539b1SJoe Perches my $sline = $line; #copy of $line 27221b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 27230a920b5bSAndy Whitcroft 2724c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 2725f36d3eb8SJoe Perches my $raw_comment = get_raw_comment($line, $rawline); 27266c72ffaaSAndy Whitcroft 272712c253abSJoe Perches# check if it's a mode change, rename or start of a patch 272812c253abSJoe Perches if (!$in_commit_log && 272912c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 273012c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 273112c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 273212c253abSJoe Perches $is_patch = 1; 273312c253abSJoe Perches } 273412c253abSJoe Perches 27350a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2736e518e9a5SJoe Perches if (!$in_commit_log && 273774fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 273874fd4f34SJoe Perches my $context = $4; 27390a920b5bSAndy Whitcroft $is_patch = 1; 27404a0df2efSAndy Whitcroft $first_line = $linenr + 1; 27410a920b5bSAndy Whitcroft $realline=$1-1; 27420a920b5bSAndy Whitcroft if (defined $2) { 27430a920b5bSAndy Whitcroft $realcnt=$3+1; 27440a920b5bSAndy Whitcroft } else { 27450a920b5bSAndy Whitcroft $realcnt=1+1; 27460a920b5bSAndy Whitcroft } 2747c2fdda0dSAndy Whitcroft annotate_reset(); 274813214adfSAndy Whitcroft $prev_values = 'E'; 274913214adfSAndy Whitcroft 2750773647a0SAndy Whitcroft %suppress_ifbraces = (); 2751170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 27522b474a1aSAndy Whitcroft %suppress_export = (); 27533e469cdcSAndy Whitcroft $suppress_statement = 0; 275474fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 275574fd4f34SJoe Perches $context_function = $1; 275674fd4f34SJoe Perches } else { 275774fd4f34SJoe Perches undef $context_function; 275874fd4f34SJoe Perches } 27590a920b5bSAndy Whitcroft next; 27600a920b5bSAndy Whitcroft 27614a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 27624a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 27634a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2764773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 27650a920b5bSAndy Whitcroft $realline++; 2766d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 27670a920b5bSAndy Whitcroft 27684a0df2efSAndy Whitcroft # Measure the line length and indent. 2769c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 27700a920b5bSAndy Whitcroft 27710a920b5bSAndy Whitcroft # Track the previous line. 27720a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 27730a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2774c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2775c2fdda0dSAndy Whitcroft 2776773647a0SAndy Whitcroft #warn "line<$line>\n"; 27776c72ffaaSAndy Whitcroft 2778d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2779d8aaf121SAndy Whitcroft $realcnt--; 27800a920b5bSAndy Whitcroft } 27810a920b5bSAndy Whitcroft 2782cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2783cc77cdcaSAndy Whitcroft 27846c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 27856c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2786773647a0SAndy Whitcroft 27872ac73b4fSJoe Perches my $found_file = 0; 2788773647a0SAndy Whitcroft # extract the filename as it passes 27893bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 27903bf9a009SRabin Vincent $realfile = $1; 27912b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2792270c49a0SJoe Perches $in_commit_log = 0; 27932ac73b4fSJoe Perches $found_file = 1; 27943bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2795773647a0SAndy Whitcroft $realfile = $1; 27962b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2797270c49a0SJoe Perches $in_commit_log = 0; 27981e855726SWolfram Sang 27991e855726SWolfram Sang $p1_prefix = $1; 2800e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2801e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2802000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2803000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 28041e855726SWolfram Sang } 2805773647a0SAndy Whitcroft 2806c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2807000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2808000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2809773647a0SAndy Whitcroft } 28102ac73b4fSJoe Perches $found_file = 1; 28112ac73b4fSJoe Perches } 28122ac73b4fSJoe Perches 281334d8815fSJoe Perches#make up the handle for any error we report on this line 281434d8815fSJoe Perches if ($showfile) { 281534d8815fSJoe Perches $prefix = "$realfile:$realline: " 281634d8815fSJoe Perches } elsif ($emacs) { 28177d3a9f67SJoe Perches if ($file) { 28187d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 28197d3a9f67SJoe Perches } else { 282034d8815fSJoe Perches $prefix = "$filename:$linenr: "; 282134d8815fSJoe Perches } 28227d3a9f67SJoe Perches } 282334d8815fSJoe Perches 28242ac73b4fSJoe Perches if ($found_file) { 282585b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 282685b0ee18SJoe Perches WARN("OBSOLETE", 282785b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 282885b0ee18SJoe Perches } 28297bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 28302ac73b4fSJoe Perches $check = 1; 28312ac73b4fSJoe Perches } else { 28322ac73b4fSJoe Perches $check = $check_orig; 28332ac73b4fSJoe Perches } 28349f3a8992SRob Herring $checklicenseline = 1; 2835133712a2SRob Herring 2836133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2837133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2838133712a2SRob Herring 2839133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2840133712a2SRob Herring 2841133712a2SRob Herring if (($last_binding_patch != -1) && 2842133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2843133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2844858e6845SMauro Carvalho Chehab "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); 2845133712a2SRob Herring } 2846133712a2SRob Herring } 2847133712a2SRob Herring 2848773647a0SAndy Whitcroft next; 2849773647a0SAndy Whitcroft } 2850773647a0SAndy Whitcroft 2851389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 28520a920b5bSAndy Whitcroft 2853c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2854c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2855c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 28560a920b5bSAndy Whitcroft 28576c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 28586c72ffaaSAndy Whitcroft 2859490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2860490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2861490b292cSJoe Perches if ($in_commit_log) { 2862490b292cSJoe Perches if ($line !~ /^\s*$/) { 2863490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2864490b292cSJoe Perches } 2865490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2866490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2867490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2868490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2869490b292cSJoe Perches } 2870490b292cSJoe Perches 2871e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2872e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 287313e45417SMrinal Pandey (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && 287413e45417SMrinal Pandey $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || 2875e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2876e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2877e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2878e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2879e518e9a5SJoe Perches $commit_log_has_diff = 1; 2880e518e9a5SJoe Perches } 2881e518e9a5SJoe Perches 28823bf9a009SRabin Vincent# Check for incorrect file permissions 28833bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 28843bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 288504db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 288604db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2887000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2888000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 28893bf9a009SRabin Vincent } 28903bf9a009SRabin Vincent } 28913bf9a009SRabin Vincent 2892cd261496SGeert Uytterhoeven# Check the patch for a From: 2893cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2894cd261496SGeert Uytterhoeven $author = $1; 2895e7f929f3SDwaipayan Ray my $curline = $linenr; 2896e7f929f3SDwaipayan Ray while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { 2897e7f929f3SDwaipayan Ray $author .= $1; 2898e7f929f3SDwaipayan Ray } 2899cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2900cd261496SGeert Uytterhoeven $author =~ s/"//g; 2901dfa05c28SJoe Perches $author = reformat_email($author); 2902cd261496SGeert Uytterhoeven } 2903cd261496SGeert Uytterhoeven 290420112475SJoe Perches# Check the patch for a signoff: 2905dfa05c28SJoe Perches if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { 29064a0df2efSAndy Whitcroft $signoff++; 290715662b3eSJoe Perches $in_commit_log = 0; 290848ca2d8aSDwaipayan Ray if ($author ne '' && $authorsignoff != 1) { 2909fccaebf0SDwaipayan Ray if (same_email_addresses($1, $author)) { 2910cd261496SGeert Uytterhoeven $authorsignoff = 1; 291148ca2d8aSDwaipayan Ray } else { 291248ca2d8aSDwaipayan Ray my $ctx = $1; 291348ca2d8aSDwaipayan Ray my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); 291448ca2d8aSDwaipayan Ray my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); 291548ca2d8aSDwaipayan Ray 2916046fc741SMimi Zohar if (lc $email_address eq lc $author_address && $email_name eq $author_name) { 291748ca2d8aSDwaipayan Ray $author_sob = $ctx; 291848ca2d8aSDwaipayan Ray $authorsignoff = 2; 2919046fc741SMimi Zohar } elsif (lc $email_address eq lc $author_address) { 292048ca2d8aSDwaipayan Ray $author_sob = $ctx; 292148ca2d8aSDwaipayan Ray $authorsignoff = 3; 292248ca2d8aSDwaipayan Ray } elsif ($email_name eq $author_name) { 292348ca2d8aSDwaipayan Ray $author_sob = $ctx; 292448ca2d8aSDwaipayan Ray $authorsignoff = 4; 292548ca2d8aSDwaipayan Ray 292648ca2d8aSDwaipayan Ray my $address1 = $email_address; 292748ca2d8aSDwaipayan Ray my $address2 = $author_address; 292848ca2d8aSDwaipayan Ray 292948ca2d8aSDwaipayan Ray if ($address1 =~ /(\S+)\+\S+(\@.*)/) { 293048ca2d8aSDwaipayan Ray $address1 = "$1$2"; 293148ca2d8aSDwaipayan Ray } 293248ca2d8aSDwaipayan Ray if ($address2 =~ /(\S+)\+\S+(\@.*)/) { 293348ca2d8aSDwaipayan Ray $address2 = "$1$2"; 293448ca2d8aSDwaipayan Ray } 293548ca2d8aSDwaipayan Ray if ($address1 eq $address2) { 293648ca2d8aSDwaipayan Ray $authorsignoff = 5; 293748ca2d8aSDwaipayan Ray } 293848ca2d8aSDwaipayan Ray } 2939cd261496SGeert Uytterhoeven } 2940cd261496SGeert Uytterhoeven } 29410a920b5bSAndy Whitcroft } 294220112475SJoe Perches 294344d303ebSJoe Perches# Check for patch separator 294444d303ebSJoe Perches if ($line =~ /^---$/) { 294544d303ebSJoe Perches $has_patch_separator = 1; 294644d303ebSJoe Perches $in_commit_log = 0; 294744d303ebSJoe Perches } 294844d303ebSJoe Perches 2949e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2950e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2951e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2952e0d975b1SJoe Perches $reported_maintainer_file = 1; 2953e0d975b1SJoe Perches } 2954e0d975b1SJoe Perches 295520112475SJoe Perches# Check signature styles 2956270c49a0SJoe Perches if (!$in_header_lines && 2957ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 295820112475SJoe Perches my $space_before = $1; 295920112475SJoe Perches my $sign_off = $2; 296020112475SJoe Perches my $space_after = $3; 296120112475SJoe Perches my $email = $4; 296220112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 296320112475SJoe Perches 2964ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2965831242abSAditya Srivastava my $suggested_signature = find_standard_signature($sign_off); 2966831242abSAditya Srivastava if ($suggested_signature eq "") { 2967ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2968ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2969831242abSAditya Srivastava } else { 2970831242abSAditya Srivastava if (WARN("BAD_SIGN_OFF", 2971831242abSAditya Srivastava "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && 2972831242abSAditya Srivastava $fix) { 2973831242abSAditya Srivastava $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; 2974831242abSAditya Srivastava } 2975831242abSAditya Srivastava } 2976ce0338dfSJoe Perches } 297720112475SJoe Perches if (defined $space_before && $space_before ne "") { 29783705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 29793705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 29803705ce5bSJoe Perches $fix) { 2981194f66fcSJoe Perches $fixed[$fixlinenr] = 29823705ce5bSJoe Perches "$ucfirst_sign_off $email"; 29833705ce5bSJoe Perches } 298420112475SJoe Perches } 298520112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 29863705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 29873705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 29883705ce5bSJoe Perches $fix) { 2989194f66fcSJoe Perches $fixed[$fixlinenr] = 29903705ce5bSJoe Perches "$ucfirst_sign_off $email"; 29913705ce5bSJoe Perches } 29923705ce5bSJoe Perches 299320112475SJoe Perches } 299420112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 29953705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 29963705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 29973705ce5bSJoe Perches $fix) { 2998194f66fcSJoe Perches $fixed[$fixlinenr] = 29993705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30003705ce5bSJoe Perches } 300120112475SJoe Perches } 300220112475SJoe Perches 3003dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 300448ca2d8aSDwaipayan Ray my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); 300520112475SJoe Perches if ($suggested_email eq "") { 3006000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 3007000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 300820112475SJoe Perches } else { 300920112475SJoe Perches my $dequoted = $suggested_email; 301020112475SJoe Perches $dequoted =~ s/^"//; 301120112475SJoe Perches $dequoted =~ s/" </ </; 301220112475SJoe Perches # Don't force email to have quotes 301320112475SJoe Perches # Allow just an angle bracketed address 3014fccaebf0SDwaipayan Ray if (!same_email_addresses($email, $suggested_email)) { 3015fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3016fccaebf0SDwaipayan Ray "email address '$email' might be better as '$suggested_email'\n" . $herecurr) && 3017fccaebf0SDwaipayan Ray $fix) { 3018fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/; 3019fccaebf0SDwaipayan Ray } 3020fccaebf0SDwaipayan Ray } 3021fccaebf0SDwaipayan Ray 3022fccaebf0SDwaipayan Ray # Address part shouldn't have comments 3023fccaebf0SDwaipayan Ray my $stripped_address = $email_address; 3024fccaebf0SDwaipayan Ray $stripped_address =~ s/\([^\(\)]*\)//g; 3025fccaebf0SDwaipayan Ray if ($email_address ne $stripped_address) { 3026fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3027fccaebf0SDwaipayan Ray "address part of email should not have comments: '$email_address'\n" . $herecurr) && 3028fccaebf0SDwaipayan Ray $fix) { 3029fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/; 3030fccaebf0SDwaipayan Ray } 3031fccaebf0SDwaipayan Ray } 3032fccaebf0SDwaipayan Ray 3033fccaebf0SDwaipayan Ray # Only one name comment should be allowed 3034fccaebf0SDwaipayan Ray my $comment_count = () = $name_comment =~ /\([^\)]+\)/g; 3035fccaebf0SDwaipayan Ray if ($comment_count > 1) { 3036000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 3037fccaebf0SDwaipayan Ray "Use a single name comment in email: '$email'\n" . $herecurr); 3038fccaebf0SDwaipayan Ray } 3039fccaebf0SDwaipayan Ray 3040fccaebf0SDwaipayan Ray 3041fccaebf0SDwaipayan Ray # [email protected] or [email protected] shouldn't 3042e73d2715SDwaipayan Ray # have an email name. In addition comments should strictly 3043fccaebf0SDwaipayan Ray # begin with a # 3044fccaebf0SDwaipayan Ray if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { 3045fccaebf0SDwaipayan Ray if (($comment ne "" && $comment !~ /^#.+/) || 3046fccaebf0SDwaipayan Ray ($email_name ne "")) { 3047fccaebf0SDwaipayan Ray my $cur_name = $email_name; 3048fccaebf0SDwaipayan Ray my $new_comment = $comment; 3049fccaebf0SDwaipayan Ray $cur_name =~ s/[a-zA-Z\s\-\"]+//g; 3050fccaebf0SDwaipayan Ray 3051fccaebf0SDwaipayan Ray # Remove brackets enclosing comment text 3052fccaebf0SDwaipayan Ray # and # from start of comments to get comment text 3053fccaebf0SDwaipayan Ray $new_comment =~ s/^\((.*)\)$/$1/; 3054fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3055fccaebf0SDwaipayan Ray $new_comment =~ s/^[\s\#]+|\s+$//g; 3056fccaebf0SDwaipayan Ray 3057fccaebf0SDwaipayan Ray $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); 3058fccaebf0SDwaipayan Ray $new_comment = " # $new_comment" if ($new_comment ne ""); 3059fccaebf0SDwaipayan Ray my $new_email = "$email_address$new_comment"; 3060fccaebf0SDwaipayan Ray 3061fccaebf0SDwaipayan Ray if (WARN("BAD_STABLE_ADDRESS_STYLE", 3062fccaebf0SDwaipayan Ray "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && 3063fccaebf0SDwaipayan Ray $fix) { 3064fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3065fccaebf0SDwaipayan Ray } 3066fccaebf0SDwaipayan Ray } 3067fccaebf0SDwaipayan Ray } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { 3068fccaebf0SDwaipayan Ray my $new_comment = $comment; 3069fccaebf0SDwaipayan Ray 3070fccaebf0SDwaipayan Ray # Extract comment text from within brackets or 3071fccaebf0SDwaipayan Ray # c89 style /*...*/ comments 3072fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3073fccaebf0SDwaipayan Ray $new_comment =~ s/^\/\*(.*)\*\/$/$1/; 3074fccaebf0SDwaipayan Ray 3075fccaebf0SDwaipayan Ray $new_comment = trim($new_comment); 3076fccaebf0SDwaipayan Ray $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo 3077fccaebf0SDwaipayan Ray $new_comment = "($new_comment)" if ($new_comment ne ""); 3078fccaebf0SDwaipayan Ray my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); 3079fccaebf0SDwaipayan Ray 3080fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3081fccaebf0SDwaipayan Ray "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && 3082fccaebf0SDwaipayan Ray $fix) { 3083fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3084fccaebf0SDwaipayan Ray } 308520112475SJoe Perches } 30860a920b5bSAndy Whitcroft } 30877e51f197SJoe Perches 30887e51f197SJoe Perches# Check for duplicate signatures 30897e51f197SJoe Perches my $sig_nospace = $line; 30907e51f197SJoe Perches $sig_nospace =~ s/\s//g; 30917e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 30927e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 30937e51f197SJoe Perches WARN("BAD_SIGN_OFF", 30947e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 30957e51f197SJoe Perches } else { 30967e51f197SJoe Perches $signatures{$sig_nospace} = 1; 30977e51f197SJoe Perches } 30986c5d24eeSSean Christopherson 30996c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 31006c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 31016c5d24eeSSean Christopherson if ($email eq $author) { 31026c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31036c5d24eeSSean Christopherson "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); 31046c5d24eeSSean Christopherson } 31056c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 31066c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31076c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); 31086c5d24eeSSean Christopherson } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { 31096c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31106c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 31116c5d24eeSSean Christopherson } elsif ($1 ne $email) { 31126c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31136c5d24eeSSean Christopherson "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 31146c5d24eeSSean Christopherson } 31156c5d24eeSSean Christopherson } 31160a920b5bSAndy Whitcroft } 31170a920b5bSAndy Whitcroft 3118a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 3119a2fe16b9SJoe Perches if ($in_header_lines && 3120a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 3121a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 3122a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 3123a2fe16b9SJoe Perches } 3124a2fe16b9SJoe Perches 312544d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context 312644d303ebSJoe Perches if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { 31277580c5b9SAditya Srivastava if (ERROR("GERRIT_CHANGE_ID", 31287580c5b9SAditya Srivastava "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && 31297580c5b9SAditya Srivastava $fix) { 31307580c5b9SAditya Srivastava fix_delete_line($fixlinenr, $rawline); 31317580c5b9SAditya Srivastava } 31327ebd05efSChristopher Covington } 31337ebd05efSChristopher Covington 3134369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 3135369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3136369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 3137369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 3138369c8dd3SJoe Perches # timestamp 3139634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 3140634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 3141634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 3142634cffccSJoe Perches # stack dump address styles 3143369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 3144369c8dd3SJoe Perches } 3145369c8dd3SJoe Perches 31462a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 31472a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 3148bf4daf12SJoe Perches length($line) > 75 && 3149bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 3150bf4daf12SJoe Perches # file delta changes 3151bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 3152bf4daf12SJoe Perches # filename then : 315327b379afSAditya Srivastava $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i || 315427b379afSAditya Srivastava # A Fixes: or Link: line or signature tag line 3155bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 31562a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 31572a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 31582a076f40SJoe Perches $commit_log_long_line = 1; 31592a076f40SJoe Perches } 31602a076f40SJoe Perches 3161bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 3162bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 3163bf4daf12SJoe Perches $line =~ /^\s*$/) { 3164bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 3165bf4daf12SJoe Perches } 3166bf4daf12SJoe Perches 3167084a617aSDwaipayan Ray# Check for lines starting with a # 3168084a617aSDwaipayan Ray if ($in_commit_log && $line =~ /^#/) { 3169084a617aSDwaipayan Ray if (WARN("COMMIT_COMMENT_SYMBOL", 3170084a617aSDwaipayan Ray "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && 3171084a617aSDwaipayan Ray $fix) { 3172084a617aSDwaipayan Ray $fixed[$fixlinenr] =~ s/^/ /; 3173084a617aSDwaipayan Ray } 3174084a617aSDwaipayan Ray } 3175084a617aSDwaipayan Ray 31760d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 31774ce9f970SJoe Perches# A correctly formed commit description is: 31784ce9f970SJoe Perches# commit <SHA-1 hash length 12+ chars> ("Complete commit subject") 31794ce9f970SJoe Perches# with the commit subject '("' prefix and '")' suffix 31804ce9f970SJoe Perches# This is a fairly compilicated block as it tests for what appears to be 31814ce9f970SJoe Perches# bare SHA-1 hash with minimum length of 5. It also avoids several types of 31824ce9f970SJoe Perches# possible SHA-1 matches. 31834ce9f970SJoe Perches# A commit match can span multiple lines so this block attempts to find a 31844ce9f970SJoe Perches# complete typical commit on a maximum of 3 lines 31854ce9f970SJoe Perches if ($perl_version_ok && 31864ce9f970SJoe Perches $in_commit_log && !$commit_log_possible_stack_dump && 3187a8972573SJohn Hubbard $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && 3188e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 31894ce9f970SJoe Perches (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 31904ce9f970SJoe Perches ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) || 3191aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 3192369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 3193bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 3194fe043ea1SJoe Perches my $init_char = "c"; 3195fe043ea1SJoe Perches my $orig_commit = ""; 31960d7835fcSJoe Perches my $short = 1; 31970d7835fcSJoe Perches my $long = 0; 31980d7835fcSJoe Perches my $case = 1; 31990d7835fcSJoe Perches my $space = 1; 32000d7835fcSJoe Perches my $id = '0123456789ab'; 32010d7835fcSJoe Perches my $orig_desc = "commit description"; 32020d7835fcSJoe Perches my $description = ""; 32034ce9f970SJoe Perches my $herectx = $herecurr; 32044ce9f970SJoe Perches my $has_parens = 0; 32054ce9f970SJoe Perches my $has_quotes = 0; 32060d7835fcSJoe Perches 32074ce9f970SJoe Perches my $input = $line; 32084ce9f970SJoe Perches if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) { 32094ce9f970SJoe Perches for (my $n = 0; $n < 2; $n++) { 32104ce9f970SJoe Perches if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) { 32114ce9f970SJoe Perches $orig_desc = $1; 32124ce9f970SJoe Perches $has_parens = 1; 32134ce9f970SJoe Perches # Always strip leading/trailing parens then double quotes if existing 32144ce9f970SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 32154ce9f970SJoe Perches if ($orig_desc =~ /^".*"$/) { 32164ce9f970SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 32174ce9f970SJoe Perches $has_quotes = 1; 32184ce9f970SJoe Perches } 32194ce9f970SJoe Perches last; 32204ce9f970SJoe Perches } 32214ce9f970SJoe Perches last if ($#lines < $linenr + $n); 32224ce9f970SJoe Perches $input .= " " . trim($rawlines[$linenr + $n]); 32234ce9f970SJoe Perches $herectx .= "$rawlines[$linenr + $n]\n"; 32244ce9f970SJoe Perches } 32254ce9f970SJoe Perches $herectx = $herecurr if (!$has_parens); 3226fe043ea1SJoe Perches } 3227fe043ea1SJoe Perches 32284ce9f970SJoe Perches if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 32294ce9f970SJoe Perches $init_char = $1; 32304ce9f970SJoe Perches $orig_commit = lc($2); 32314ce9f970SJoe Perches $short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i); 32324ce9f970SJoe Perches $long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i); 32334ce9f970SJoe Perches $space = 0 if ($input =~ /\bcommit [0-9a-f]/i); 32344ce9f970SJoe Perches $case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 32354ce9f970SJoe Perches } elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) { 32364ce9f970SJoe Perches $orig_commit = lc($1); 32370d7835fcSJoe Perches } 32380d7835fcSJoe Perches 32390d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 32400d7835fcSJoe Perches $id, $orig_desc); 32410d7835fcSJoe Perches 3242948b133aSHeinrich Schuchardt if (defined($id) && 32434ce9f970SJoe Perches ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) && 32444ce9f970SJoe Perches $last_git_commit_id_linenr != $linenr - 1) { 3245d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 32464ce9f970SJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx); 32470d7835fcSJoe Perches } 32484ce9f970SJoe Perches #don't report the next line if this line ends in commit and the sha1 hash is the next line 32494ce9f970SJoe Perches $last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i); 3250d311cd44SJoe Perches } 3251d311cd44SJoe Perches 325213f1937eSJoe Perches# Check for added, moved or deleted files 325313f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 325413f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 325513f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 325613f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 325713f1937eSJoe Perches (defined($1) || defined($2))))) { 3258a82603a8SAndrew Jeffery $is_patch = 1; 325913f1937eSJoe Perches $reported_maintainer_file = 1; 326013f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 326113f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 326213f1937eSJoe Perches } 326313f1937eSJoe Perches 3264e400edb1SRob Herring# Check for adding new DT bindings not in schema format 3265e400edb1SRob Herring if (!$in_commit_log && 3266e400edb1SRob Herring ($line =~ /^new file mode\s*\d+\s*$/) && 3267e400edb1SRob Herring ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { 3268e400edb1SRob Herring WARN("DT_SCHEMA_BINDING_PATCH", 326956ddc4cdSMauro Carvalho Chehab "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n"); 3270e400edb1SRob Herring } 3271e400edb1SRob Herring 327200df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 32738905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 3274000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 3275000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 32766c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 3277de7d4f0eSAndy Whitcroft } 3278de7d4f0eSAndy Whitcroft 3279de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 3280de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 3281171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 3282171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 3283171ae1a4SAndy Whitcroft 3284171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 3285171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 3286171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 3287171ae1a4SAndy Whitcroft 328834d99219SJoe Perches CHK("INVALID_UTF8", 3289000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 329000df344fSAndy Whitcroft } 32910a920b5bSAndy Whitcroft 329215662b3eSJoe Perches# Check if it's the start of a commit log 329315662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 329415662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 3295eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 3296eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 329715662b3eSJoe Perches $in_header_lines = 0; 329815662b3eSJoe Perches $in_commit_log = 1; 3299ed43c4e5SAllen Hubbe $has_commit_log = 1; 330015662b3eSJoe Perches } 330115662b3eSJoe Perches 3302fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 3303fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 3304fa64205dSPasi Savanainen if ($in_header_lines && 3305fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 3306fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 3307fa64205dSPasi Savanainen $non_utf8_charset = 1; 3308fa64205dSPasi Savanainen } 3309fa64205dSPasi Savanainen 3310fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 331115662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 3312fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 331315662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 331415662b3eSJoe Perches } 331515662b3eSJoe Perches 3316d6430f71SJoe Perches# Check for absolute kernel paths in commit message 3317d6430f71SJoe Perches if ($tree && $in_commit_log) { 3318d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 3319d6430f71SJoe Perches my $file = $1; 3320d6430f71SJoe Perches 3321d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 3322d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 3323d6430f71SJoe Perches # 3324d6430f71SJoe Perches } else { 3325d6430f71SJoe Perches check_absolute_file($file, $herecurr); 3326d6430f71SJoe Perches } 3327d6430f71SJoe Perches } 3328d6430f71SJoe Perches } 3329d6430f71SJoe Perches 333066b47b4aSKees Cook# Check for various typo / spelling mistakes 333166d7a382SJoe Perches if (defined($misspellings) && 333266d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 33337da07c31SDwaipayan Ray while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { 333466b47b4aSKees Cook my $typo = $1; 33357da07c31SDwaipayan Ray my $blank = copy_spacing($rawline); 33367da07c31SDwaipayan Ray my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); 33377da07c31SDwaipayan Ray my $hereptr = "$hereline$ptr\n"; 333866b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 333966b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 334066b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 33410675a8fbSJean Delvare my $msg_level = \&WARN; 33420675a8fbSJean Delvare $msg_level = \&CHK if ($file); 33430675a8fbSJean Delvare if (&{$msg_level}("TYPO_SPELLING", 33447da07c31SDwaipayan Ray "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && 334566b47b4aSKees Cook $fix) { 334666b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 334766b47b4aSKees Cook } 334866b47b4aSKees Cook } 334966b47b4aSKees Cook } 335066b47b4aSKees Cook 3351a8dd86bfSMatteo Croce# check for invalid commit id 3352a8dd86bfSMatteo Croce if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 3353a8dd86bfSMatteo Croce my $id; 3354a8dd86bfSMatteo Croce my $description; 3355a8dd86bfSMatteo Croce ($id, $description) = git_commit_info($2, undef, undef); 3356a8dd86bfSMatteo Croce if (!defined($id)) { 3357a8dd86bfSMatteo Croce WARN("UNKNOWN_COMMIT_ID", 3358a8dd86bfSMatteo Croce "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 3359a8dd86bfSMatteo Croce } 3360a8dd86bfSMatteo Croce } 3361a8dd86bfSMatteo Croce 3362310cd06bSJoe Perches# check for repeated words separated by a single space 33638d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root' 33648d0325ccSAditya Srivastava if (($rawline =~ /^\+/ || $in_commit_log) && 33658d0325ccSAditya Srivastava $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { 33661db81a68SDwaipayan Ray pos($rawline) = 1 if (!$in_commit_log); 3367310cd06bSJoe Perches while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { 3368310cd06bSJoe Perches 3369310cd06bSJoe Perches my $first = $1; 3370310cd06bSJoe Perches my $second = $2; 33711db81a68SDwaipayan Ray my $start_pos = $-[1]; 33721db81a68SDwaipayan Ray my $end_pos = $+[2]; 3373310cd06bSJoe Perches if ($first =~ /(?:struct|union|enum)/) { 3374310cd06bSJoe Perches pos($rawline) += length($first) + length($second) + 1; 3375310cd06bSJoe Perches next; 3376310cd06bSJoe Perches } 3377310cd06bSJoe Perches 33781db81a68SDwaipayan Ray next if (lc($first) ne lc($second)); 3379310cd06bSJoe Perches next if ($first eq 'long'); 3380310cd06bSJoe Perches 33811db81a68SDwaipayan Ray # check for character before and after the word matches 33821db81a68SDwaipayan Ray my $start_char = ''; 33831db81a68SDwaipayan Ray my $end_char = ''; 33841db81a68SDwaipayan Ray $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); 33851db81a68SDwaipayan Ray $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); 33861db81a68SDwaipayan Ray 33871db81a68SDwaipayan Ray next if ($start_char =~ /^\S$/); 33881db81a68SDwaipayan Ray next if (index(" \t.,;?!", $end_char) == -1); 33891db81a68SDwaipayan Ray 33908d0325ccSAditya Srivastava # avoid repeating hex occurrences like 'ff ff fe 09 ...' 33918d0325ccSAditya Srivastava if ($first =~ /\b[0-9a-f]{2,}\b/i) { 33928d0325ccSAditya Srivastava next if (!exists($allow_repeated_words{lc($first)})); 33938d0325ccSAditya Srivastava } 33948d0325ccSAditya Srivastava 3395310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3396310cd06bSJoe Perches "Possible repeated word: '$first'\n" . $herecurr) && 3397310cd06bSJoe Perches $fix) { 3398310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; 3399310cd06bSJoe Perches } 3400310cd06bSJoe Perches } 3401310cd06bSJoe Perches 3402310cd06bSJoe Perches # if it's a repeated word on consecutive lines in a comment block 3403310cd06bSJoe Perches if ($prevline =~ /$;+\s*$/ && 3404310cd06bSJoe Perches $prevrawline =~ /($word_pattern)\s*$/) { 3405310cd06bSJoe Perches my $last_word = $1; 3406310cd06bSJoe Perches if ($rawline =~ /^\+\s*\*\s*$last_word /) { 3407310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3408310cd06bSJoe Perches "Possible repeated word: '$last_word'\n" . $hereprev) && 3409310cd06bSJoe Perches $fix) { 3410310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; 3411310cd06bSJoe Perches } 3412310cd06bSJoe Perches } 3413310cd06bSJoe Perches } 3414310cd06bSJoe Perches } 3415310cd06bSJoe Perches 341630670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 341730670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 341800df344fSAndy Whitcroft 34190a920b5bSAndy Whitcroft#trailing whitespace 34209c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 3421c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3422d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 3423d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 3424d5e616fcSJoe Perches $fix) { 3425194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 3426d5e616fcSJoe Perches } 3427c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 3428c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 34293705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 34303705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 34313705ce5bSJoe Perches $fix) { 3432194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 34333705ce5bSJoe Perches } 34343705ce5bSJoe Perches 3435d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 34360a920b5bSAndy Whitcroft } 34375368df20SAndy Whitcroft 34384783f894SJosh Triplett# Check for FSF mailing addresses. 3439109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 34401bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 34413e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 34423e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 34434783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 34440675a8fbSJean Delvare my $msg_level = \&ERROR; 34450675a8fbSJean Delvare $msg_level = \&CHK if ($file); 34460675a8fbSJean Delvare &{$msg_level}("FSF_MAILING_ADDRESS", 34474783f894SJosh 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) 34484783f894SJosh Triplett } 34494783f894SJosh Triplett 34503354957aSAndi Kleen# check for Kconfig help text having a real description 34519fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 34529fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 34533354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 3454678ae162SUlf Magnusson # 'choice' is usually the last thing on the line (though 3455678ae162SUlf Magnusson # Kconfig supports named choices), so use a word boundary 3456678ae162SUlf Magnusson # (\b) rather than a whitespace character (\s) 3457678ae162SUlf Magnusson $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 34583354957aSAndi Kleen my $length = 0; 34599fe287d7SAndy Whitcroft my $cnt = $realcnt; 34609fe287d7SAndy Whitcroft my $ln = $linenr + 1; 34619fe287d7SAndy Whitcroft my $f; 3462a1385803SAndy Whitcroft my $is_start = 0; 34639fe287d7SAndy Whitcroft my $is_end = 0; 3464a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 34659fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 34669fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 34679fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 34689fe287d7SAndy Whitcroft 34699fe287d7SAndy Whitcroft next if ($f =~ /^-/); 34708d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 3471a1385803SAndy Whitcroft 347286adf1a0SUlf Magnusson if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 3473a1385803SAndy Whitcroft $is_start = 1; 347422a4ac02SMasahiro Yamada } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 3475a1385803SAndy Whitcroft $length = -1; 3476a1385803SAndy Whitcroft } 3477a1385803SAndy Whitcroft 34789fe287d7SAndy Whitcroft $f =~ s/^.//; 34793354957aSAndi Kleen $f =~ s/#.*//; 34803354957aSAndi Kleen $f =~ s/^\s+//; 34813354957aSAndi Kleen next if ($f =~ /^$/); 3482678ae162SUlf Magnusson 3483678ae162SUlf Magnusson # This only checks context lines in the patch 3484678ae162SUlf Magnusson # and so hopefully shouldn't trigger false 3485678ae162SUlf Magnusson # positives, even though some of these are 3486678ae162SUlf Magnusson # common words in help texts 3487678ae162SUlf Magnusson if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| 3488678ae162SUlf Magnusson if|endif|menu|endmenu|source)\b/x) { 34899fe287d7SAndy Whitcroft $is_end = 1; 34909fe287d7SAndy Whitcroft last; 34919fe287d7SAndy Whitcroft } 34923354957aSAndi Kleen $length++; 34933354957aSAndi Kleen } 349456193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 3495000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 349656193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 349756193274SVadim Bendebury } 3498a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 34993354957aSAndi Kleen } 35003354957aSAndi Kleen 35017ccf41a8SJoe Perches# check MAINTAINERS entries 35027ccf41a8SJoe Perches if ($realfile =~ /^MAINTAINERS$/) { 35037ccf41a8SJoe Perches# check MAINTAINERS entries for the right form 35047ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 3505628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3506628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3507628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3508628f91a2SJoe Perches $fix) { 3509628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3510628f91a2SJoe Perches } 3511628f91a2SJoe Perches } 35127ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too 35137ccf41a8SJoe Perches my $preferred_order = 'MRLSWQBCPTFXNK'; 35147ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 35157ccf41a8SJoe Perches $prevrawline =~ /^[\+ ][A-Z]:/) { 35167ccf41a8SJoe Perches $rawline =~ /^\+([A-Z]):\s*(.*)/; 35177ccf41a8SJoe Perches my $cur = $1; 35187ccf41a8SJoe Perches my $curval = $2; 35197ccf41a8SJoe Perches $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; 35207ccf41a8SJoe Perches my $prev = $1; 35217ccf41a8SJoe Perches my $prevval = $2; 35227ccf41a8SJoe Perches my $curindex = index($preferred_order, $cur); 35237ccf41a8SJoe Perches my $previndex = index($preferred_order, $prev); 35247ccf41a8SJoe Perches if ($curindex < 0) { 35257ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 35267ccf41a8SJoe Perches "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); 35277ccf41a8SJoe Perches } else { 35287ccf41a8SJoe Perches if ($previndex >= 0 && $curindex < $previndex) { 35297ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 35307ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); 35317ccf41a8SJoe Perches } elsif ((($prev eq 'F' && $cur eq 'F') || 35327ccf41a8SJoe Perches ($prev eq 'X' && $cur eq 'X')) && 35337ccf41a8SJoe Perches ($prevval cmp $curval) > 0) { 35347ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 35357ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); 35367ccf41a8SJoe Perches } 35377ccf41a8SJoe Perches } 35387ccf41a8SJoe Perches } 35397ccf41a8SJoe Perches } 3540628f91a2SJoe Perches 3541c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3542c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3543c68e5878SArnaud Lacombe my $flag = $1; 3544c68e5878SArnaud Lacombe my $replacement = { 3545c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 3546c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 3547c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 3548c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 3549c68e5878SArnaud Lacombe }; 3550c68e5878SArnaud Lacombe 3551c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 3552c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3553c68e5878SArnaud Lacombe } 3554c68e5878SArnaud Lacombe 3555bff5da43SRob Herring# check for DT compatible documentation 35567dd05b38SFlorian Vaussard if (defined $root && 35577dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 35587dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 35597dd05b38SFlorian Vaussard 3560bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3561bff5da43SRob Herring 3562cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3563852d095dSRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3564cc93319bSFlorian Vaussard 3565bff5da43SRob Herring foreach my $compat (@compats) { 3566bff5da43SRob Herring my $compat2 = $compat; 3567185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3568185d566bSRob Herring my $compat3 = $compat; 3569185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3570185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3571bff5da43SRob Herring if ( $? >> 8 ) { 3572bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3573bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3574bff5da43SRob Herring } 3575bff5da43SRob Herring 35764fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 35774fbf32a6SFlorian Vaussard my $vendor = $1; 3578852d095dSRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3579bff5da43SRob Herring if ( $? >> 8 ) { 3580bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3581cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3582bff5da43SRob Herring } 3583bff5da43SRob Herring } 3584bff5da43SRob Herring } 3585bff5da43SRob Herring 35869f3a8992SRob Herring# check for using SPDX license tag at beginning of files 35879f3a8992SRob Herring if ($realline == $checklicenseline) { 35889f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 35899f3a8992SRob Herring $checklicenseline = 2; 35909f3a8992SRob Herring } elsif ($rawline =~ /^\+/) { 35919f3a8992SRob Herring my $comment = ""; 35929f3a8992SRob Herring if ($realfile =~ /\.(h|s|S)$/) { 35939f3a8992SRob Herring $comment = '/*'; 35949f3a8992SRob Herring } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { 35959f3a8992SRob Herring $comment = '//'; 3596c8df0ab6SLubomir Rintel } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 35979f3a8992SRob Herring $comment = '#'; 35989f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 35999f3a8992SRob Herring $comment = '..'; 36009f3a8992SRob Herring } 36019f3a8992SRob Herring 3602fdf13693SJoe Perches# check SPDX comment style for .[chsS] files 3603fdf13693SJoe Perches if ($realfile =~ /\.[chsS]$/ && 3604fdf13693SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 3605ffbce897SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 3606fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3607fdf13693SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3608fdf13693SJoe Perches } 3609fdf13693SJoe Perches 36109f3a8992SRob Herring if ($comment !~ /^$/ && 3611ffbce897SJoe Perches $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 36129f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 36139f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 36143b6e8ac9SJoe Perches } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 36153b6e8ac9SJoe Perches my $spdx_license = $1; 36163b6e8ac9SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 36173b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 36183b6e8ac9SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 36193b6e8ac9SJoe Perches } 362050c92900SLubomir Rintel if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 362150c92900SLubomir Rintel not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { 362250c92900SLubomir Rintel my $msg_level = \&WARN; 362350c92900SLubomir Rintel $msg_level = \&CHK if ($file); 362450c92900SLubomir Rintel if (&{$msg_level}("SPDX_LICENSE_TAG", 362550c92900SLubomir Rintel 362650c92900SLubomir Rintel "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 362750c92900SLubomir Rintel $fix) { 362850c92900SLubomir Rintel $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 362950c92900SLubomir Rintel } 363050c92900SLubomir Rintel } 36319f3a8992SRob Herring } 36329f3a8992SRob Herring } 36339f3a8992SRob Herring } 36349f3a8992SRob Herring 3635a0154cdbSJoe Perches# check for embedded filenames 3636a0154cdbSJoe Perches if ($rawline =~ /^\+.*\Q$realfile\E/) { 3637a0154cdbSJoe Perches WARN("EMBEDDED_FILENAME", 3638a0154cdbSJoe Perches "It's generally not useful to have the filename in the file\n" . $herecurr); 3639a0154cdbSJoe Perches } 3640a0154cdbSJoe Perches 36415368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 3642d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 36435368df20SAndy Whitcroft 3644a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3645a8da38a9SJoe Perches if ($realline != $checklicenseline && 3646a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3647a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3648a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3649a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3650a8da38a9SJoe Perches } 3651a8da38a9SJoe Perches 365247e0c88bSJoe Perches# line length limit (with some exclusions) 365347e0c88bSJoe Perches# 365447e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 365547e0c88bSJoe Perches# logging functions like pr_info that end in a string 365647e0c88bSJoe Perches# lines with a single string 365747e0c88bSJoe Perches# #defines that are a single string 36582e4bbbc5SAndreas Brauchli# lines with an RFC3986 like URL 365947e0c88bSJoe Perches# 366047e0c88bSJoe Perches# There are 3 different line length message types: 3661ab1ecabfSJean Delvare# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 366247e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 366347e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 366447e0c88bSJoe Perches# 366547e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 366647e0c88bSJoe Perches# 366747e0c88bSJoe Perches 3668b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 366947e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 367047e0c88bSJoe Perches 367147e0c88bSJoe Perches # Check the allowed long line types first 367247e0c88bSJoe Perches 367347e0c88bSJoe Perches # logging functions that end in a string that starts 367447e0c88bSJoe Perches # before $max_line_length 367547e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 367647e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 367747e0c88bSJoe Perches $msg_type = ""; 367847e0c88bSJoe Perches 367947e0c88bSJoe Perches # lines with only strings (w/ possible termination) 368047e0c88bSJoe Perches # #defines with only strings 368147e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 368247e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 368347e0c88bSJoe Perches $msg_type = ""; 368447e0c88bSJoe Perches 3685cc147506SJoe Perches # More special cases 3686cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3687cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3688d560a5f8SJoe Perches $msg_type = ""; 3689d560a5f8SJoe Perches 36902e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 36912e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 36922e4bbbc5SAndreas Brauchli $msg_type = ""; 36932e4bbbc5SAndreas Brauchli 369447e0c88bSJoe Perches # Otherwise set the alternate message types 369547e0c88bSJoe Perches 369647e0c88bSJoe Perches # a comment starts before $max_line_length 369747e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 369847e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 369947e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 370047e0c88bSJoe Perches 370147e0c88bSJoe Perches # a quoted string starts before $max_line_length 370247e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 370347e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 370447e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 370547e0c88bSJoe Perches } 370647e0c88bSJoe Perches 370747e0c88bSJoe Perches if ($msg_type ne "" && 370847e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 3709bdc48fa1SJoe Perches my $msg_level = \&WARN; 3710bdc48fa1SJoe Perches $msg_level = \&CHK if ($file); 3711bdc48fa1SJoe Perches &{$msg_level}($msg_type, 3712bdc48fa1SJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 37130a920b5bSAndy Whitcroft } 371447e0c88bSJoe Perches } 37150a920b5bSAndy Whitcroft 37168905a67cSAndy Whitcroft# check for adding lines without a newline. 37178905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 371847ca69b8STom Rix if (WARN("MISSING_EOF_NEWLINE", 371947ca69b8STom Rix "adding a line without newline at end of file\n" . $herecurr) && 372047ca69b8STom Rix $fix) { 372147ca69b8STom Rix fix_delete_line($fixlinenr+1, "No newline at end of file"); 372247ca69b8STom Rix } 37238905a67cSAndy Whitcroft } 37248905a67cSAndy Whitcroft 3725de93245cSAditya Srivastava# check for .L prefix local symbols in .S files 3726de93245cSAditya Srivastava if ($realfile =~ /\.S$/ && 3727de93245cSAditya Srivastava $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { 3728de93245cSAditya Srivastava WARN("AVOID_L_PREFIX", 3729de93245cSAditya 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); 3730de93245cSAditya Srivastava } 3731de93245cSAditya Srivastava 3732b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3733de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 37340a920b5bSAndy Whitcroft 37350a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 3736713a09deSAntonio Borneo# more than $tabsize must use tabs. 3737c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3738c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3739c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3740d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 37413705ce5bSJoe Perches if (ERROR("CODE_INDENT", 37423705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 37433705ce5bSJoe Perches $fix) { 3744194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 37453705ce5bSJoe Perches } 37460a920b5bSAndy Whitcroft } 37470a920b5bSAndy Whitcroft 374808e44365SAlberto Panizzo# check for space before tabs. 374908e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 375008e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 37513705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 37523705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 37533705ce5bSJoe Perches $fix) { 3754194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3755713a09deSAntonio Borneo s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 3756194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3757c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 37583705ce5bSJoe Perches } 375908e44365SAlberto Panizzo } 376008e44365SAlberto Panizzo 37616a487211SJoe Perches# check for assignments on the start of a line 37626a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 3763da7355abSAditya Srivastava my $operator = $1; 3764da7355abSAditya Srivastava if (CHK("ASSIGNMENT_CONTINUATIONS", 3765da7355abSAditya Srivastava "Assignment operator '$1' should be on the previous line\n" . $hereprev) && 3766da7355abSAditya Srivastava $fix && $prevrawline =~ /^\+/) { 3767da7355abSAditya Srivastava # add assignment operator to the previous line, remove from current line 3768da7355abSAditya Srivastava $fixed[$fixlinenr - 1] .= " $operator"; 3769da7355abSAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 3770da7355abSAditya Srivastava } 37716a487211SJoe Perches } 37726a487211SJoe Perches 3773d1fe9c09SJoe Perches# check for && or || at the start of a line 3774d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 37758e08f076SAditya Srivastava my $operator = $1; 37768e08f076SAditya Srivastava if (CHK("LOGICAL_CONTINUATIONS", 37778e08f076SAditya Srivastava "Logical continuations should be on the previous line\n" . $hereprev) && 37788e08f076SAditya Srivastava $fix && $prevrawline =~ /^\+/) { 37798e08f076SAditya Srivastava # insert logical operator at last non-comment, non-whitepsace char on previous line 37808e08f076SAditya Srivastava $prevline =~ /[\s$;]*$/; 37818e08f076SAditya Srivastava my $line_end = substr($prevrawline, $-[0]); 37828e08f076SAditya Srivastava $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; 37838e08f076SAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 37848e08f076SAditya Srivastava } 3785d1fe9c09SJoe Perches } 3786d1fe9c09SJoe Perches 3787a91e8994SJoe Perches# check indentation starts on a tab stop 37885b57980dSJoe Perches if ($perl_version_ok && 3789bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3790a91e8994SJoe Perches my $indent = length($1); 3791713a09deSAntonio Borneo if ($indent % $tabsize) { 3792a91e8994SJoe Perches if (WARN("TABSTOP", 3793a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3794a91e8994SJoe Perches $fix) { 3795713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 3796a91e8994SJoe Perches } 3797a91e8994SJoe Perches } 3798a91e8994SJoe Perches } 3799a91e8994SJoe Perches 3800d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 38015b57980dSJoe Perches if ($perl_version_ok && 3802fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3803d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3804d1fe9c09SJoe Perches my $oldindent = $1; 3805d1fe9c09SJoe Perches my $rest = $2; 3806d1fe9c09SJoe Perches 3807d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3808d1fe9c09SJoe Perches if ($pos >= 0) { 3809b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3810b34a26f3SJoe Perches my $newindent = $2; 3811d1fe9c09SJoe Perches 3812d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3813713a09deSAntonio Borneo "\t" x ($pos / $tabsize) . 3814713a09deSAntonio Borneo " " x ($pos % $tabsize); 3815d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3816d1fe9c09SJoe Perches 3817d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3818d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 38193705ce5bSJoe Perches 38203705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 38213705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 38223705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3823194f66fcSJoe Perches $fixed[$fixlinenr] =~ 38243705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 38253705ce5bSJoe Perches } 3826d1fe9c09SJoe Perches } 3827d1fe9c09SJoe Perches } 3828d1fe9c09SJoe Perches } 3829d1fe9c09SJoe Perches 38306ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 38316ab3a970SJoe Perches# avoid checking a few false positives: 38326ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 38336ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 38346ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 38356ab3a970SJoe Perches# multiline macros that define functions 38366ab3a970SJoe Perches# known attributes or the __attribute__ keyword 38376ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 38386ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 38393705ce5bSJoe Perches if (CHK("SPACING", 3840f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 38413705ce5bSJoe Perches $fix) { 3842194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3843f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 38443705ce5bSJoe Perches } 3845aad4f614SJoe Perches } 3846aad4f614SJoe Perches 384786406b1cSJoe Perches# Block comment styles 384886406b1cSJoe Perches# Networking with an initial /* 384905880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3850fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 385185ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 3852c70735c2SŁukasz Stelmach $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier 385305880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 385405880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 385505880600SJoe Perches } 385605880600SJoe Perches 385786406b1cSJoe Perches# Block comments use * on subsequent lines 385886406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 385986406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3860a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 386161135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3862a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 386386406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 386486406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3865a605e32eSJoe Perches } 3866a605e32eSJoe Perches 386786406b1cSJoe Perches# Block comments use */ on trailing lines 386886406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3869c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3870c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3871c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 387286406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 387386406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 387405880600SJoe Perches } 387505880600SJoe Perches 387608eb9b80SJoe Perches# Block comment * alignment 387708eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3878af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3879af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3880af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 388108eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3882af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3883af207524SJoe Perches my $oldindent; 388408eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3885af207524SJoe Perches if (defined($1)) { 3886af207524SJoe Perches $oldindent = expand_tabs($1); 3887af207524SJoe Perches } else { 3888af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3889af207524SJoe Perches $oldindent = expand_tabs($1); 3890af207524SJoe Perches } 389108eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 389208eb9b80SJoe Perches my $newindent = $1; 389308eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3894af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 389508eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 389608eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 389708eb9b80SJoe Perches } 389808eb9b80SJoe Perches } 389908eb9b80SJoe Perches 39007f619191SJoe Perches# check for missing blank lines after struct/union declarations 39017f619191SJoe Perches# with exceptions for various attributes and macros 39027f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 39037f619191SJoe Perches $line =~ /^\+/ && 39047f619191SJoe Perches !($line =~ /^\+\s*$/ || 39057f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 39067f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 39077f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 39087f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 39097f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 39107f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 39110bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 39127f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3913d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3914d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3915d752fcc8SJoe Perches $fix) { 3916f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3917d752fcc8SJoe Perches } 39187f619191SJoe Perches } 39197f619191SJoe Perches 3920365dd4eaSJoe Perches# check for multiple consecutive blank lines 3921365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3922365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3923365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3924d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3925d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3926d752fcc8SJoe Perches $fix) { 3927f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3928d752fcc8SJoe Perches } 3929d752fcc8SJoe Perches 3930365dd4eaSJoe Perches $last_blank_line = $linenr; 3931365dd4eaSJoe Perches } 3932365dd4eaSJoe Perches 39333b617e3bSJoe Perches# check for missing blank lines after declarations 3934b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line) 3935b5e8736aSJoe Perches if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) { 3936b5e8736aSJoe Perches # use temporaries 3937b5e8736aSJoe Perches my $sl = $sline; 3938b5e8736aSJoe Perches my $pl = $prevline; 3939b5e8736aSJoe Perches # remove $Attribute/$Sparse uses to simplify comparisons 3940b5e8736aSJoe Perches $sl =~ s/\b(?:$Attribute|$Sparse)\b//g; 3941b5e8736aSJoe Perches $pl =~ s/\b(?:$Attribute|$Sparse)\b//g; 3942b5e8736aSJoe Perches if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 39435a4e1fd3SJoe Perches # function pointer declarations 3944b5e8736aSJoe Perches $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 39453f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 3946b5e8736aSJoe Perches $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 39473f7bac03SJoe Perches # known declaration macros 3948b5e8736aSJoe Perches $pl =~ /^\+\s+$declaration_macros/) && 39493f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 3950b5e8736aSJoe Perches !($pl =~ /^\+\s+$c90_Keywords\b/ || 39513f7bac03SJoe Perches # other possible extensions of declaration lines 3952b5e8736aSJoe Perches $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 39533f7bac03SJoe Perches # not starting a section or a macro "\" extended line 3954b5e8736aSJoe Perches $pl =~ /(?:\{\s*|\\)$/) && 39553f7bac03SJoe Perches # looks like a declaration 3956b5e8736aSJoe Perches !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 39575a4e1fd3SJoe Perches # function pointer declarations 3958b5e8736aSJoe Perches $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 39593f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 3960b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 39613f7bac03SJoe Perches # known declaration macros 3962b5e8736aSJoe Perches $sl =~ /^\+\s+$declaration_macros/ || 39633f7bac03SJoe Perches # start of struct or union or enum 3964b5e8736aSJoe Perches $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 39653f7bac03SJoe Perches # start or end of block or continuation of declaration 3966b5e8736aSJoe Perches $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 39673f7bac03SJoe Perches # bitfield continuation 3968b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 39693f7bac03SJoe Perches # other possible extensions of declaration lines 3970b5e8736aSJoe Perches $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) { 3971d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3972d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3973d752fcc8SJoe Perches $fix) { 3974f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3975d752fcc8SJoe Perches } 39763b617e3bSJoe Perches } 3977b5e8736aSJoe Perches } 39783b617e3bSJoe Perches 39795f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 39806b4c5bebSAndy Whitcroft# Exceptions: 39816b4c5bebSAndy Whitcroft# 1) within comments 39826b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 39836b4c5bebSAndy Whitcroft# 3) hanging labels 39843705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 39855f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 39863705ce5bSJoe Perches if (WARN("LEADING_SPACE", 39873705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 39883705ce5bSJoe Perches $fix) { 3989194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 39903705ce5bSJoe Perches } 39915f7ddae6SRaffaele Recalcati } 39925f7ddae6SRaffaele Recalcati 3993b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3994b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3995b9ea10d6SAndy Whitcroft 39965751a24eSJoe Perches# check for unusual line ending [ or ( 39975751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 39985751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 39995751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 40005751a24eSJoe Perches } 40015751a24eSJoe Perches 40024dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 40034dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 40044dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 40054dbed76fSJoe Perches $context_function = $1; 40064dbed76fSJoe Perches } 40074dbed76fSJoe Perches 40084dbed76fSJoe Perches# check if this appears to be the end of function declaration 40094dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 40104dbed76fSJoe Perches undef $context_function; 40114dbed76fSJoe Perches } 40124dbed76fSJoe Perches 4013032a4c0fSJoe Perches# check indentation of any line with a bare else 4014840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 4015032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 4016032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 4017032a4c0fSJoe Perches my $tabs = length($1) + 1; 4018840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 4019840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 4020840080a0SJoe Perches defined $lines[$linenr] && 4021840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 4022032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 4023032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 4024032a4c0fSJoe Perches } 4025032a4c0fSJoe Perches } 4026032a4c0fSJoe Perches 4027c00df19aSJoe Perches# check indentation of a line with a break; 4028dc58bc55SJoe Perches# if the previous line is a goto, return or break 4029dc58bc55SJoe Perches# and is indented the same # of tabs 4030c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 4031c00df19aSJoe Perches my $tabs = $1; 4032dc58bc55SJoe Perches if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { 4033dc58bc55SJoe Perches if (WARN("UNNECESSARY_BREAK", 4034dc58bc55SJoe Perches "break is not useful after a $1\n" . $hereprev) && 4035dc58bc55SJoe Perches $fix) { 4036dc58bc55SJoe Perches fix_delete_line($fixlinenr, $rawline); 4037dc58bc55SJoe Perches } 4038c00df19aSJoe Perches } 4039c00df19aSJoe Perches } 4040c00df19aSJoe Perches 4041c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 4042cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 4043000d1cc1SJoe Perches WARN("CVS_KEYWORD", 4044000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 4045c2fdda0dSAndy Whitcroft } 404622f2a2efSAndy Whitcroft 404756e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 404856e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 404956e77d70SJoe Perches WARN("HOTPLUG_SECTION", 405056e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 405156e77d70SJoe Perches } 405256e77d70SJoe Perches 40539c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 40542b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 40552b474a1aSAndy Whitcroft $realline_next); 40563e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 4057ca819864SJoe Perches if ($linenr > $suppress_statement && 40581b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 4059170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 4060f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4061171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 4062171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 4063171ae1a4SAndy Whitcroft 40643e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 40653e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 40663e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 40673e469cdcSAndy Whitcroft # until we hit end of it. 40683e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 40693e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 40703e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 40713e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 40723e469cdcSAndy Whitcroft } 4073f74bd194SAndy Whitcroft 40742b474a1aSAndy Whitcroft # Find the real next line. 40752b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 40762b474a1aSAndy Whitcroft if (defined $realline_next && 40772b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 40782b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 40792b474a1aSAndy Whitcroft $realline_next++; 40802b474a1aSAndy Whitcroft } 40812b474a1aSAndy Whitcroft 4082171ae1a4SAndy Whitcroft my $s = $stat; 4083171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 4084cf655043SAndy Whitcroft 4085c2fdda0dSAndy Whitcroft # Ignore goto labels. 4086171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 4087c2fdda0dSAndy Whitcroft 4088c2fdda0dSAndy Whitcroft # Ignore functions being called 4089171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 4090c2fdda0dSAndy Whitcroft 4091463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 4092463f2864SAndy Whitcroft 4093c45dcabdSAndy Whitcroft # declarations always start with types 4094d2506586SAndy 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) { 4095c45dcabdSAndy Whitcroft my $type = $1; 4096c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 4097c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 4098c45dcabdSAndy Whitcroft 40996c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 4100a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 4101c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 4102c2fdda0dSAndy Whitcroft } 41038905a67cSAndy Whitcroft 41046c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 410565863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 4106c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 41079c0ca6f9SAndy Whitcroft } 41088905a67cSAndy Whitcroft 41098905a67cSAndy Whitcroft # Check for any sort of function declaration. 41108905a67cSAndy Whitcroft # int foo(something bar, other baz); 41118905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 4112171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 41138905a67cSAndy Whitcroft my ($name_len) = length($1); 41148905a67cSAndy Whitcroft 4115cf655043SAndy Whitcroft my $ctx = $s; 4116773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 41178905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 4118cf655043SAndy Whitcroft 41198905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 4120c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 41218905a67cSAndy Whitcroft 4122c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 41238905a67cSAndy Whitcroft } 41248905a67cSAndy Whitcroft } 41258905a67cSAndy Whitcroft } 41268905a67cSAndy Whitcroft 41279c0ca6f9SAndy Whitcroft } 41289c0ca6f9SAndy Whitcroft 412900df344fSAndy Whitcroft# 413000df344fSAndy Whitcroft# Checks which may be anchored in the context. 413100df344fSAndy Whitcroft# 413200df344fSAndy Whitcroft 413300df344fSAndy Whitcroft# Check for switch () and associated case and default 413400df344fSAndy Whitcroft# statements should be at the same indent. 413500df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 413600df344fSAndy Whitcroft my $err = ''; 413700df344fSAndy Whitcroft my $sep = ''; 413800df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 413900df344fSAndy Whitcroft shift(@ctx); 414000df344fSAndy Whitcroft for my $ctx (@ctx) { 414100df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 414200df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 414300df344fSAndy Whitcroft $indent != $cindent) { 414400df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 414500df344fSAndy Whitcroft $sep = ''; 414600df344fSAndy Whitcroft } else { 414700df344fSAndy Whitcroft $sep = "[...]\n"; 414800df344fSAndy Whitcroft } 414900df344fSAndy Whitcroft } 415000df344fSAndy Whitcroft if ($err ne '') { 4151000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 4152000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 4153de7d4f0eSAndy Whitcroft } 4154de7d4f0eSAndy Whitcroft } 4155de7d4f0eSAndy Whitcroft 4156de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 4157de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 41580fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 4159773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 4160773647a0SAndy Whitcroft 41619c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 41628eef05ddSJoe Perches 41638eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 41648eef05ddSJoe Perches WARN("DEEP_INDENTATION", 41658eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 41668eef05ddSJoe Perches } 41678eef05ddSJoe Perches 4168de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 4169de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 4170de7d4f0eSAndy Whitcroft 4171548596d5SAndy Whitcroft my $ctx_ln = $linenr; 4172548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 4173de7d4f0eSAndy Whitcroft 4174548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 4175548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 4176548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 4177548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 4178548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 4179773647a0SAndy Whitcroft $ctx_ln++; 4180773647a0SAndy Whitcroft } 4181548596d5SAndy Whitcroft 418253210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 418353210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 4184773647a0SAndy Whitcroft 4185773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 4186000d1cc1SJoe Perches ERROR("OPEN_BRACE", 4187000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 418801464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 418900df344fSAndy Whitcroft } 4190773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 4191773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 4192773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 4193773647a0SAndy Whitcroft { 41949c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 41959c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 4196000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 4197000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 419801464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 41999c0ca6f9SAndy Whitcroft } 42009c0ca6f9SAndy Whitcroft } 420100df344fSAndy Whitcroft } 420200df344fSAndy Whitcroft 42034d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 4204f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 42053e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 42063e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 42073e469cdcSAndy Whitcroft if (!defined $stat); 42084d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 42094d001e4dSAndy Whitcroft 42104d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 42114d001e4dSAndy Whitcroft 42129f5af480SJoe Perches # remove inline comments 42139f5af480SJoe Perches $s =~ s/$;/ /g; 42149f5af480SJoe Perches $c =~ s/$;/ /g; 42154d001e4dSAndy Whitcroft 42164d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 42176f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 42186f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 42194d001e4dSAndy Whitcroft 42209f5af480SJoe Perches # Make sure we remove the line prefixes as we have 42219f5af480SJoe Perches # none on the first line, and are going to readd them 42229f5af480SJoe Perches # where necessary. 42239f5af480SJoe Perches $s =~ s/\n./\n/gs; 42249f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 42259f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 42269f5af480SJoe Perches } 42279f5af480SJoe Perches 42284d001e4dSAndy Whitcroft # We want to check the first line inside the block 42294d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 42304d001e4dSAndy Whitcroft # 1) any blank line termination 42314d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 42324d001e4dSAndy Whitcroft # 3) any do (...) { 42334d001e4dSAndy Whitcroft my $continuation = 0; 42344d001e4dSAndy Whitcroft my $check = 0; 42354d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 42364d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 42374d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 42384d001e4dSAndy Whitcroft $continuation = 1; 42394d001e4dSAndy Whitcroft } 42409bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 42414d001e4dSAndy Whitcroft $check = 1; 42424d001e4dSAndy Whitcroft $cond_lines++; 42434d001e4dSAndy Whitcroft } 42444d001e4dSAndy Whitcroft 42454d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 42464d001e4dSAndy Whitcroft # preprocessor statement. 42474d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 42484d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 42494d001e4dSAndy Whitcroft $check = 0; 42504d001e4dSAndy Whitcroft } 42514d001e4dSAndy Whitcroft 42529bd49efeSAndy Whitcroft my $cond_ptr = -1; 4253740504c6SAndy Whitcroft $continuation = 0; 42549bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 42559bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 42564d001e4dSAndy Whitcroft 4257f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 4258f16fa28fSAndy Whitcroft # is not linear. 4259f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 4260f16fa28fSAndy Whitcroft $check = 0; 4261f16fa28fSAndy Whitcroft } 4262f16fa28fSAndy Whitcroft 42639bd49efeSAndy Whitcroft # Ignore: 42649bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 42659bd49efeSAndy Whitcroft # 2) preprocessor lines, and 42669bd49efeSAndy Whitcroft # 3) labels. 4267740504c6SAndy Whitcroft if ($continuation || 4268740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 42699bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 42709bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 4271740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 427230dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 42739bd49efeSAndy Whitcroft $cond_lines++; 42749bd49efeSAndy Whitcroft } 42754d001e4dSAndy Whitcroft } 427630dad6ebSAndy Whitcroft } 42774d001e4dSAndy Whitcroft 42784d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 42794d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 42804d001e4dSAndy Whitcroft 42814d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 42824d001e4dSAndy Whitcroft # this is not this patch's fault. 42834d001e4dSAndy Whitcroft if (!defined($stat_real) || 42844d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 42854d001e4dSAndy Whitcroft $check = 0; 42864d001e4dSAndy Whitcroft } 42874d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 42884d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 42894d001e4dSAndy Whitcroft } 42904d001e4dSAndy Whitcroft 42919bd49efeSAndy 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"; 42924d001e4dSAndy Whitcroft 42939f5af480SJoe Perches if ($check && $s ne '' && 4294713a09deSAntonio Borneo (($sindent % $tabsize) != 0 || 42959f5af480SJoe Perches ($sindent < $indent) || 4296f6950a73SJoe Perches ($sindent == $indent && 4297f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 4298713a09deSAntonio Borneo ($sindent > $indent + $tabsize))) { 4299000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 4300000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 43014d001e4dSAndy Whitcroft } 43024d001e4dSAndy Whitcroft } 43034d001e4dSAndy Whitcroft 43046c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 43056c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 43061f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 43071f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 43086c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 4309c2fdda0dSAndy Whitcroft if ($dbg_values) { 4310c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 4311cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 4312cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 43131f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 4314c2fdda0dSAndy Whitcroft } 43156c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 43166c72ffaaSAndy Whitcroft 431700df344fSAndy Whitcroft#ignore lines not being added 43183705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 431900df344fSAndy Whitcroft 432099ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings 432199ca38c2SJoe Perches# e.g.: int foo = foo, *bar = NULL; 432299ca38c2SJoe Perches# struct foo bar = *(&(bar)); 432399ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { 432499ca38c2SJoe Perches my $var = $1; 432599ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { 432699ca38c2SJoe Perches WARN("SELF_ASSIGNMENT", 432799ca38c2SJoe Perches "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); 432899ca38c2SJoe Perches } 432999ca38c2SJoe Perches } 433099ca38c2SJoe Perches 433111ca40a0SJoe Perches# check for dereferences that span multiple lines 433211ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 433311ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 433411ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 433511ca40a0SJoe Perches my $ref = $1; 433611ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 433711ca40a0SJoe Perches $ref .= $1; 433811ca40a0SJoe Perches $ref =~ s/\s//g; 433911ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 434011ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 434111ca40a0SJoe Perches } 434211ca40a0SJoe Perches 4343a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 4344c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 4345a1ce18e4SJoe Perches my $type = $1; 4346a1ce18e4SJoe Perches my $var = $2; 4347207a8e84SJoe Perches $var = "" if (!defined $var); 4348207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 4349a1ce18e4SJoe Perches my $sign = $1; 4350a1ce18e4SJoe Perches my $pointer = $2; 4351a1ce18e4SJoe Perches 4352a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 4353a1ce18e4SJoe Perches 4354a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 4355a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 4356a1ce18e4SJoe Perches $fix) { 4357a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 4358207a8e84SJoe Perches my $comp_pointer = $pointer; 4359207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 4360207a8e84SJoe Perches $decl .= $comp_pointer; 4361207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 4362207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 4363a1ce18e4SJoe Perches } 4364a1ce18e4SJoe Perches } 4365a1ce18e4SJoe Perches } 4366a1ce18e4SJoe Perches 4367653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 43687429c690SAndy Whitcroft if ($dbg_type) { 43697429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 4370000d1cc1SJoe Perches ERROR("TEST_TYPE", 4371000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 43727429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 4373000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 4374000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 43757429c690SAndy Whitcroft } 4376653d4876SAndy Whitcroft next; 4377653d4876SAndy Whitcroft } 4378a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 4379a1ef277eSAndy Whitcroft if ($dbg_attr) { 43809360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 4381000d1cc1SJoe Perches ERROR("TEST_ATTR", 4382000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 43839360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 4384000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 4385000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 4386a1ef277eSAndy Whitcroft } 4387a1ef277eSAndy Whitcroft next; 4388a1ef277eSAndy Whitcroft } 4389653d4876SAndy Whitcroft 4390f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 439199423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 439299423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 4393d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 4394d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 4395f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 4396f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 4397f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 4398d752fcc8SJoe Perches my $fixedline = $prevrawline; 4399d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 4400f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4401d752fcc8SJoe Perches $fixedline = $line; 44028d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 4403f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4404d752fcc8SJoe Perches } 4405f0a594c1SAndy Whitcroft } 4406f0a594c1SAndy Whitcroft 440700df344fSAndy Whitcroft# 440800df344fSAndy Whitcroft# Checks which are anchored on the added line. 440900df344fSAndy Whitcroft# 441000df344fSAndy Whitcroft 4411653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 4412c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 4413653d4876SAndy Whitcroft my $path = $1; 4414653d4876SAndy Whitcroft if ($path =~ m{//}) { 4415000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 4416495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 4417495e9d84SJoe Perches } 4418495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 4419495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 4420495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 4421653d4876SAndy Whitcroft } 4422653d4876SAndy Whitcroft } 4423653d4876SAndy Whitcroft 442400df344fSAndy Whitcroft# no C99 // comments 442500df344fSAndy Whitcroft if ($line =~ m{//}) { 44263705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 44273705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 44283705ce5bSJoe Perches $fix) { 4429194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 44303705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 44313705ce5bSJoe Perches my $comment = trim($1); 4432194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 44333705ce5bSJoe Perches } 44343705ce5bSJoe Perches } 443500df344fSAndy Whitcroft } 443600df344fSAndy Whitcroft # Remove C99 comments. 44370a920b5bSAndy Whitcroft $line =~ s@//.*@@; 44386c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 44390a920b5bSAndy Whitcroft 44402b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 44412b474a1aSAndy Whitcroft# the whole statement. 44422b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 44432b474a1aSAndy Whitcroft if (defined $realline_next && 44442b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 44452b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 444636794822SChristoph Hellwig ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 44473cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 44483cbf62dfSAndy Whitcroft # a prefix: 44493cbf62dfSAndy Whitcroft # XXX(foo); 44503cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 4451653d4876SAndy Whitcroft my $name = $1; 445287a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 44533cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 44543cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 44553cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 44563cbf62dfSAndy Whitcroft 44573cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 44582b474a1aSAndy Whitcroft \n.}\s*$| 445948012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 446048012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 446148012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 44622b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 44632b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 446448012058SAndy Whitcroft )/x) { 44652b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 44662b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 44672b474a1aSAndy Whitcroft } else { 44682b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 44690a920b5bSAndy Whitcroft } 44700a920b5bSAndy Whitcroft } 44712b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 44722b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 447336794822SChristoph Hellwig ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 44742b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 44752b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 44762b474a1aSAndy Whitcroft } 44772b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 44782b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 4479000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 4480000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 44812b474a1aSAndy Whitcroft } 44820a920b5bSAndy Whitcroft 44835150bda4SJoe Eloff# check for global initialisers. 44845b8f82e1SSong Liu if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ && 44855b8f82e1SSong Liu !exclude_global_initialisers($realfile)) { 4486d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 44876d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 4488d5e616fcSJoe Perches $fix) { 44896d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 4490d5e616fcSJoe Perches } 4491f0a594c1SAndy Whitcroft } 44920a920b5bSAndy Whitcroft# check for static initialisers. 44936d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 4494d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 44956d32f7a3SJoe Perches "do not initialise statics to $1\n" . 4496d5e616fcSJoe Perches $herecurr) && 4497d5e616fcSJoe Perches $fix) { 44986d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 4499d5e616fcSJoe Perches } 45000a920b5bSAndy Whitcroft } 45010a920b5bSAndy Whitcroft 45021813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 45031813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 45041813087dSJoe Perches my $tmp = trim($1); 45051813087dSJoe Perches WARN("MISORDERED_TYPE", 45061813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 45071813087dSJoe Perches } 45081813087dSJoe Perches 4509809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4510809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4511809e082eSJoe Perches my $type = trim($1); 4512809e082eSJoe Perches next if ($type !~ /\bint\b/); 4513809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 4514809e082eSJoe Perches my $new_type = $type; 4515809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 4516809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 4517809e082eSJoe Perches $new_type =~ s/^const\s+//; 4518809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 4519809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 4520809e082eSJoe Perches $new_type =~ s/\s+/ /g; 4521809e082eSJoe Perches $new_type = trim($new_type); 4522809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 4523809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4524809e082eSJoe Perches $fix) { 4525809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4526809e082eSJoe Perches } 4527809e082eSJoe Perches } 4528809e082eSJoe Perches 4529cb710ecaSJoe Perches# check for static const char * arrays. 4530cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4531000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4532000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 4533cb710ecaSJoe Perches $herecurr); 4534cb710ecaSJoe Perches } 4535cb710ecaSJoe Perches 453677b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 453777b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 453877b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 453977b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 454077b8c0a8SJoe Perches $fix) { 454177b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 454277b8c0a8SJoe Perches } 454377b8c0a8SJoe Perches } 454477b8c0a8SJoe Perches 4545cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 4546cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4547000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4548000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 4549cb710ecaSJoe Perches $herecurr); 4550cb710ecaSJoe Perches } 4551cb710ecaSJoe Perches 4552ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 4553ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 4554ab7e23f3SJoe Perches my $found = $1; 4555ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 4556ab7e23f3SJoe Perches WARN("CONST_CONST", 4557ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 4558ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4559ab7e23f3SJoe Perches WARN("CONST_CONST", 4560ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4561ab7e23f3SJoe Perches } 4562ab7e23f3SJoe Perches } 4563ab7e23f3SJoe Perches 456473169765SJoe Perches# check for const static or static <non ptr type> const declarations 456573169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const' 456673169765SJoe Perches if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || 456773169765SJoe Perches $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { 456873169765SJoe Perches if (WARN("STATIC_CONST", 456973169765SJoe Perches "Move const after static - use 'static const $1'\n" . $herecurr) && 457073169765SJoe Perches $fix) { 457173169765SJoe Perches $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; 457273169765SJoe Perches $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; 457373169765SJoe Perches } 457473169765SJoe Perches } 457573169765SJoe Perches 45769b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 45779b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 45789b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 45799b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 45809b0fa60dSJoe Perches $herecurr); 45819b0fa60dSJoe Perches } 45829b0fa60dSJoe Perches 4583b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 4584b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 4585b598b670SJoe Perches my $array = $1; 4586b598b670SJoe 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*\))@) { 4587b598b670SJoe Perches my $array_div = $1; 4588b598b670SJoe Perches if (WARN("ARRAY_SIZE", 4589b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 4590b598b670SJoe Perches $fix) { 4591b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4592b598b670SJoe Perches } 4593b598b670SJoe Perches } 4594b598b670SJoe Perches } 4595b598b670SJoe Perches 4596b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 459716b7f3c8SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4598b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4599b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4600b36190c5SJoe Perches $fix) { 4601194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4602b36190c5SJoe Perches } 4603b36190c5SJoe Perches } 4604b36190c5SJoe Perches 4605653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4606653d4876SAndy Whitcroft# make sense. 4607653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 46088054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4609c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 46108ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 461146d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4612000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4613000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 46140a920b5bSAndy Whitcroft } 46150a920b5bSAndy Whitcroft 46160a920b5bSAndy Whitcroft# * goes on variable not on type 461765863862SAndy Whitcroft # (char*[ const]) 4618bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4619bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 46203705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4621d8aaf121SAndy Whitcroft 462265863862SAndy Whitcroft # Should start with a space. 462365863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 462465863862SAndy Whitcroft # Should not end with a space. 462565863862SAndy Whitcroft $to =~ s/\s+$//; 462665863862SAndy Whitcroft # '*'s should not have spaces between. 4627f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 462865863862SAndy Whitcroft } 4629d8aaf121SAndy Whitcroft 46303705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 463165863862SAndy Whitcroft if ($from ne $to) { 46323705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 46333705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 46343705ce5bSJoe Perches $fix) { 46353705ce5bSJoe Perches my $sub_from = $ident; 46363705ce5bSJoe Perches my $sub_to = $ident; 46373705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4638194f66fcSJoe Perches $fixed[$fixlinenr] =~ 46393705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 46403705ce5bSJoe Perches } 464165863862SAndy Whitcroft } 4642bfcb2cc7SAndy Whitcroft } 4643bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4644bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 46453705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4646d8aaf121SAndy Whitcroft 464765863862SAndy Whitcroft # Should start with a space. 464865863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 464965863862SAndy Whitcroft # Should not end with a space. 465065863862SAndy Whitcroft $to =~ s/\s+$//; 465165863862SAndy Whitcroft # '*'s should not have spaces between. 4652f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 465365863862SAndy Whitcroft } 465465863862SAndy Whitcroft # Modifiers should have spaces. 465565863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 465665863862SAndy Whitcroft 46573705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4658667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 46593705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 46603705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 46613705ce5bSJoe Perches $fix) { 46623705ce5bSJoe Perches 46633705ce5bSJoe Perches my $sub_from = $match; 46643705ce5bSJoe Perches my $sub_to = $match; 46653705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4666194f66fcSJoe Perches $fixed[$fixlinenr] =~ 46673705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 46683705ce5bSJoe Perches } 466965863862SAndy Whitcroft } 46700a920b5bSAndy Whitcroft } 46710a920b5bSAndy Whitcroft 46729d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 46739d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 46740675a8fbSJean Delvare my $msg_level = \&WARN; 46750675a8fbSJean Delvare $msg_level = \&CHK if ($file); 46760675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 46779d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 46789d3e3c70SJoe Perches } 46790a920b5bSAndy Whitcroft 46809d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 46818905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4682000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4683000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 46848905a67cSAndy Whitcroft } 46858905a67cSAndy Whitcroft 468617441227SJoe Perches# check for uses of printk_ratelimit 468717441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4688000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4689000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 469017441227SJoe Perches } 469117441227SJoe Perches 4692eeef5733SJoe Perches# printk should use KERN_* levels 4693eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4694000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4695eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 469600df344fSAndy Whitcroft } 46970a920b5bSAndy Whitcroft 4698f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL> 4699f5eea3b0SJoe Perches if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { 4700f5eea3b0SJoe Perches my $printk = $1; 4701f5eea3b0SJoe Perches my $modifier = $2; 4702f5eea3b0SJoe Perches my $orig = $3; 4703f5eea3b0SJoe Perches $modifier = "" if (!defined($modifier)); 4704243f3803SJoe Perches my $level = lc($orig); 4705243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 47068f26b837SJoe Perches my $level2 = $level; 47078f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4708f5eea3b0SJoe Perches $level .= $modifier; 4709f5eea3b0SJoe Perches $level2 .= $modifier; 4710243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4711f5eea3b0SJoe Perches "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); 4712243f3803SJoe Perches } 4713243f3803SJoe Perches 4714f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL> 4715dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4716dc139313SJoe Perches my $orig = $1; 4717dc139313SJoe Perches my $level = lc($orig); 4718dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4719dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4720dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4721dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4722dc139313SJoe Perches } 4723dc139313SJoe Perches 47248020b253SNicolas Boichat# trace_printk should not be used in production code. 47258020b253SNicolas Boichat if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { 47268020b253SNicolas Boichat WARN("TRACE_PRINTK", 47278020b253SNicolas Boichat "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); 47288020b253SNicolas Boichat } 47298020b253SNicolas Boichat 473091c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 473191c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 473291c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 473391c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 473491c9afafSAndy Lutomirski WARN("ENOSYS", 473591c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 473691c9afafSAndy Lutomirski } 473791c9afafSAndy Lutomirski 47386b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches. 47396b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. 47406b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected. 47416b9ea5ffSJakub Kicinski if (!$file && $line =~ /\bENOTSUPP\b/) { 47426b9ea5ffSJakub Kicinski if (WARN("ENOTSUPP", 47436b9ea5ffSJakub Kicinski "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && 47446b9ea5ffSJakub Kicinski $fix) { 47456b9ea5ffSJakub Kicinski $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; 47466b9ea5ffSJakub Kicinski } 47476b9ea5ffSJakub Kicinski } 47486b9ea5ffSJakub Kicinski 4749653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4750653d4876SAndy Whitcroft# or if closed on same line 47515b57980dSJoe Perches if ($perl_version_ok && 47522d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 47532d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 47542d453e3bSJoe Perches $sline !~ /}/) { 47558d182478SJoe Perches if (ERROR("OPEN_BRACE", 47562d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 47578d182478SJoe Perches $fix) { 47588d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 47598d182478SJoe Perches my $fixed_line = $rawline; 476003f49351SDwaipayan Ray $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; 47618d182478SJoe Perches my $line1 = $1; 47628d182478SJoe Perches my $line2 = $2; 47638d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 47648d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 47658d182478SJoe Perches if ($line2 !~ /^\s*$/) { 47668d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 47678d182478SJoe Perches } 47688d182478SJoe Perches } 47690a920b5bSAndy Whitcroft } 4770653d4876SAndy Whitcroft 47718905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 47728905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 47738905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 47748d182478SJoe Perches if (ERROR("OPEN_BRACE", 47758d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 47768d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 47778d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 47788d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 47798d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 47808d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47818d182478SJoe Perches $fixedline = $rawline; 47828d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 47838d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 47848d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47858d182478SJoe Perches } 47868d182478SJoe Perches } 47878905a67cSAndy Whitcroft } 47888905a67cSAndy Whitcroft 47890c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 47903705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 47913705ce5bSJoe Perches if (WARN("SPACING", 47923705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 47933705ce5bSJoe Perches $fix) { 4794194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47953705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 47963705ce5bSJoe Perches } 47970c73b4ebSAndy Whitcroft } 47980c73b4ebSAndy Whitcroft 479931070b5dSJoe Perches# Function pointer declarations 480031070b5dSJoe Perches# check spacing between type, funcptr, and args 480131070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 480291f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 480331070b5dSJoe Perches my $declare = $1; 480431070b5dSJoe Perches my $pre_pointer_space = $2; 480531070b5dSJoe Perches my $post_pointer_space = $3; 480631070b5dSJoe Perches my $funcname = $4; 480731070b5dSJoe Perches my $post_funcname_space = $5; 480831070b5dSJoe Perches my $pre_args_space = $6; 480931070b5dSJoe Perches 481091f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 481191f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 481291f72e9cSJoe Perches# don't need a space so don't warn for those. 481391f72e9cSJoe Perches my $post_declare_space = ""; 481491f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 481591f72e9cSJoe Perches $post_declare_space = $1; 481691f72e9cSJoe Perches $declare = rtrim($declare); 481791f72e9cSJoe Perches } 481891f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 481931070b5dSJoe Perches WARN("SPACING", 482031070b5dSJoe Perches "missing space after return type\n" . $herecurr); 482191f72e9cSJoe Perches $post_declare_space = " "; 482231070b5dSJoe Perches } 482331070b5dSJoe Perches 482431070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 482591f72e9cSJoe Perches# This test is not currently implemented because these declarations are 482691f72e9cSJoe Perches# equivalent to 482791f72e9cSJoe Perches# int foo(int bar, ...) 482891f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 482991f72e9cSJoe Perches# 483091f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 483191f72e9cSJoe Perches# WARN("SPACING", 483291f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 483391f72e9cSJoe Perches# } 483431070b5dSJoe Perches 483531070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 483631070b5dSJoe Perches if (defined $pre_pointer_space && 483731070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 483831070b5dSJoe Perches WARN("SPACING", 483931070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 484031070b5dSJoe Perches } 484131070b5dSJoe Perches 484231070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 484331070b5dSJoe Perches if (defined $post_pointer_space && 484431070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 484531070b5dSJoe Perches WARN("SPACING", 484631070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 484731070b5dSJoe Perches } 484831070b5dSJoe Perches 484931070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 485031070b5dSJoe Perches if (defined $post_funcname_space && 485131070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 485231070b5dSJoe Perches WARN("SPACING", 485331070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 485431070b5dSJoe Perches } 485531070b5dSJoe Perches 485631070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 485731070b5dSJoe Perches if (defined $pre_args_space && 485831070b5dSJoe Perches $pre_args_space =~ /^\s/) { 485931070b5dSJoe Perches WARN("SPACING", 486031070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 486131070b5dSJoe Perches } 486231070b5dSJoe Perches 486331070b5dSJoe Perches if (show_type("SPACING") && $fix) { 4864194f66fcSJoe Perches $fixed[$fixlinenr] =~ 486591f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 486631070b5dSJoe Perches } 486731070b5dSJoe Perches } 486831070b5dSJoe Perches 48698d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 48708d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 4871fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4872fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 48738d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 48748d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 48758d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 4876fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 487738dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 48783705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 48793705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 48803705ce5bSJoe Perches $fix) { 4881194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48823705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 48833705ce5bSJoe Perches } 48848d31cfceSAndy Whitcroft } 48858d31cfceSAndy Whitcroft } 48868d31cfceSAndy Whitcroft 4887f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 48886c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4889c2fdda0dSAndy Whitcroft my $name = $1; 4890773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4891773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4892c2fdda0dSAndy Whitcroft 4893c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4894773647a0SAndy Whitcroft if ($name =~ /^(?: 4895773647a0SAndy Whitcroft if|for|while|switch|return|case| 4896773647a0SAndy Whitcroft volatile|__volatile__| 4897773647a0SAndy Whitcroft __attribute__|format|__extension__| 4898773647a0SAndy Whitcroft asm|__asm__)$/x) 4899773647a0SAndy Whitcroft { 4900c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4901c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4902c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4903c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4904773647a0SAndy Whitcroft 4905773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4906c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4907c2fdda0dSAndy Whitcroft 4908c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4909c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4910773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4911c2fdda0dSAndy Whitcroft 4912c2fdda0dSAndy Whitcroft } else { 49133705ce5bSJoe Perches if (WARN("SPACING", 49143705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 49153705ce5bSJoe Perches $fix) { 4916194f66fcSJoe Perches $fixed[$fixlinenr] =~ 49173705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 49183705ce5bSJoe Perches } 4919f0a594c1SAndy Whitcroft } 49206c72ffaaSAndy Whitcroft } 49219a4cad4eSEric Nelson 4922653d4876SAndy Whitcroft# Check operator spacing. 49230a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 49243705ce5bSJoe Perches my $fixed_line = ""; 49253705ce5bSJoe Perches my $line_fixed = 0; 49263705ce5bSJoe Perches 49279c0ca6f9SAndy Whitcroft my $ops = qr{ 49289c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 49299c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 49309c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 49311f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 493284731623SJoe Perches \?:|\?|: 49339c0ca6f9SAndy Whitcroft }x; 4934cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 49353705ce5bSJoe Perches 49363705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 49373705ce5bSJoe Perches## foreach my $el (@elements) { 49383705ce5bSJoe Perches## print("el: <$el>\n"); 49393705ce5bSJoe Perches## } 49403705ce5bSJoe Perches 49413705ce5bSJoe Perches my @fix_elements = (); 494200df344fSAndy Whitcroft my $off = 0; 49436c72ffaaSAndy Whitcroft 49443705ce5bSJoe Perches foreach my $el (@elements) { 49453705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 49463705ce5bSJoe Perches $off += length($el); 49473705ce5bSJoe Perches } 49483705ce5bSJoe Perches 49493705ce5bSJoe Perches $off = 0; 49503705ce5bSJoe Perches 49516c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4952b34c648bSJoe Perches my $last_after = -1; 49536c72ffaaSAndy Whitcroft 49540a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 49553705ce5bSJoe Perches 49563705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 49573705ce5bSJoe Perches 49583705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 49593705ce5bSJoe Perches 49604a0df2efSAndy Whitcroft $off += length($elements[$n]); 49614a0df2efSAndy Whitcroft 496225985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4963773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4964773647a0SAndy Whitcroft my $cc = ''; 4965773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4966773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4967773647a0SAndy Whitcroft } 4968773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4969773647a0SAndy Whitcroft 49704a0df2efSAndy Whitcroft my $a = ''; 49714a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 49724a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4973cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 49744a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 49754a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4976773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 49774a0df2efSAndy Whitcroft 49780a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 49794a0df2efSAndy Whitcroft 49804a0df2efSAndy Whitcroft my $c = ''; 49810a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 49824a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 49834a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4984cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 49854a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 49864a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 49878b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 49884a0df2efSAndy Whitcroft } else { 49894a0df2efSAndy Whitcroft $c = 'E'; 49900a920b5bSAndy Whitcroft } 49910a920b5bSAndy Whitcroft 49924a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 49934a0df2efSAndy Whitcroft 49944a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 49954a0df2efSAndy Whitcroft 49966c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4997de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 49980a920b5bSAndy Whitcroft 499974048ed8SAndy Whitcroft # Pull out the value of this operator. 50006c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 50010a920b5bSAndy Whitcroft 50021f65f947SAndy Whitcroft # Get the full operator variant. 50031f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 50041f65f947SAndy Whitcroft 500513214adfSAndy Whitcroft # Ignore operators passed as parameters. 500613214adfSAndy Whitcroft if ($op_type ne 'V' && 5007d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 500813214adfSAndy Whitcroft 5009cf655043SAndy Whitcroft# # Ignore comments 5010cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 501113214adfSAndy Whitcroft 5012d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 501313214adfSAndy Whitcroft } elsif ($op eq ';') { 5014cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 5015cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 50163705ce5bSJoe Perches if (ERROR("SPACING", 50173705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 5018b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 50193705ce5bSJoe Perches $line_fixed = 1; 50203705ce5bSJoe Perches } 5021d8aaf121SAndy Whitcroft } 5022d8aaf121SAndy Whitcroft 5023d8aaf121SAndy Whitcroft # // is a comment 5024d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 50250a920b5bSAndy Whitcroft 5026b00e4814SJoe Perches # : when part of a bitfield 5027b00e4814SJoe Perches } elsif ($opv eq ':B') { 5028b00e4814SJoe Perches # skip the bitfield test for now 5029b00e4814SJoe Perches 50301f65f947SAndy Whitcroft # No spaces for: 50311f65f947SAndy Whitcroft # -> 5032b00e4814SJoe Perches } elsif ($op eq '->') { 50334a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 50343705ce5bSJoe Perches if (ERROR("SPACING", 50353705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 5036b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 50373705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 50383705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 50393705ce5bSJoe Perches } 5040b34c648bSJoe Perches $line_fixed = 1; 50413705ce5bSJoe Perches } 50420a920b5bSAndy Whitcroft } 50430a920b5bSAndy Whitcroft 50442381097bSJoe Perches # , must not have a space before and must have a space on the right. 50450a920b5bSAndy Whitcroft } elsif ($op eq ',') { 50462381097bSJoe Perches my $rtrim_before = 0; 50472381097bSJoe Perches my $space_after = 0; 50482381097bSJoe Perches if ($ctx =~ /Wx./) { 50492381097bSJoe Perches if (ERROR("SPACING", 50502381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 50512381097bSJoe Perches $line_fixed = 1; 50522381097bSJoe Perches $rtrim_before = 1; 50532381097bSJoe Perches } 50542381097bSJoe Perches } 5055cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 50563705ce5bSJoe Perches if (ERROR("SPACING", 50573705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 50583705ce5bSJoe Perches $line_fixed = 1; 5059b34c648bSJoe Perches $last_after = $n; 50602381097bSJoe Perches $space_after = 1; 50612381097bSJoe Perches } 50622381097bSJoe Perches } 50632381097bSJoe Perches if ($rtrim_before || $space_after) { 50642381097bSJoe Perches if ($rtrim_before) { 50652381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 50662381097bSJoe Perches } else { 50672381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 50682381097bSJoe Perches } 50692381097bSJoe Perches if ($space_after) { 50702381097bSJoe Perches $good .= " "; 50713705ce5bSJoe Perches } 50720a920b5bSAndy Whitcroft } 50730a920b5bSAndy Whitcroft 50749c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 507574048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 50769c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 50779c0ca6f9SAndy Whitcroft 50789c0ca6f9SAndy Whitcroft # unary operators should have a space before and 50799c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 50809c0ca6f9SAndy Whitcroft # unary operator, or a cast 50819c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 508274048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 50830d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 5084cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 50853705ce5bSJoe Perches if (ERROR("SPACING", 50863705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 5087b34c648bSJoe Perches if ($n != $last_after + 2) { 5088b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 50893705ce5bSJoe Perches $line_fixed = 1; 50903705ce5bSJoe Perches } 50910a920b5bSAndy Whitcroft } 5092b34c648bSJoe Perches } 5093a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 5094171ae1a4SAndy Whitcroft # A unary '*' may be const 5095171ae1a4SAndy Whitcroft 5096171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 50973705ce5bSJoe Perches if (ERROR("SPACING", 50983705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5099b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 51003705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 51013705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 51023705ce5bSJoe Perches } 5103b34c648bSJoe Perches $line_fixed = 1; 51043705ce5bSJoe Perches } 51050a920b5bSAndy Whitcroft } 51060a920b5bSAndy Whitcroft 51070a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 51080a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 5109773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 51103705ce5bSJoe Perches if (ERROR("SPACING", 51113705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 5112b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 51133705ce5bSJoe Perches $line_fixed = 1; 51143705ce5bSJoe Perches } 51150a920b5bSAndy Whitcroft } 5116773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 5117773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 51183705ce5bSJoe Perches if (ERROR("SPACING", 51193705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5120b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 51213705ce5bSJoe Perches $line_fixed = 1; 51223705ce5bSJoe Perches } 5123653d4876SAndy Whitcroft } 5124773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 51253705ce5bSJoe Perches if (ERROR("SPACING", 51263705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5127b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 51283705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 51293705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5130773647a0SAndy Whitcroft } 5131b34c648bSJoe Perches $line_fixed = 1; 51323705ce5bSJoe Perches } 51333705ce5bSJoe Perches } 51340a920b5bSAndy Whitcroft 51350a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 51369c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 51379c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 51389c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 5139c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 5140c2fdda0dSAndy Whitcroft $op eq '%') 51410a920b5bSAndy Whitcroft { 5142d2e025f3SJoe Perches if ($check) { 5143d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 5144d2e025f3SJoe Perches if (CHK("SPACING", 5145d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 5146d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5147d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5148d2e025f3SJoe Perches $line_fixed = 1; 5149d2e025f3SJoe Perches } 5150d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 5151d2e025f3SJoe Perches if (CHK("SPACING", 5152d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 5153d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 5154d2e025f3SJoe Perches $line_fixed = 1; 5155d2e025f3SJoe Perches } 5156d2e025f3SJoe Perches } 5157d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 51583705ce5bSJoe Perches if (ERROR("SPACING", 51593705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 5160b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5161b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5162b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5163b34c648bSJoe Perches } 51643705ce5bSJoe Perches $line_fixed = 1; 51653705ce5bSJoe Perches } 51660a920b5bSAndy Whitcroft } 51670a920b5bSAndy Whitcroft 51681f65f947SAndy Whitcroft # A colon needs no spaces before when it is 51691f65f947SAndy Whitcroft # terminating a case value or a label. 51701f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 5171263afd39SChris Down if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) { 51723705ce5bSJoe Perches if (ERROR("SPACING", 51733705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5174b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 51753705ce5bSJoe Perches $line_fixed = 1; 51763705ce5bSJoe Perches } 51771f65f947SAndy Whitcroft } 51781f65f947SAndy Whitcroft 51790a920b5bSAndy Whitcroft # All the others need spaces both sides. 5180cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 51811f65f947SAndy Whitcroft my $ok = 0; 51821f65f947SAndy Whitcroft 518322f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 51841f65f947SAndy Whitcroft if (($op eq '<' && 51851f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 51861f65f947SAndy Whitcroft ($op eq '>' && 51871f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 51881f65f947SAndy Whitcroft { 51891f65f947SAndy Whitcroft $ok = 1; 51901f65f947SAndy Whitcroft } 51911f65f947SAndy Whitcroft 5192e0df7e1fSJoe Perches # for asm volatile statements 5193e0df7e1fSJoe Perches # ignore a colon with another 5194e0df7e1fSJoe Perches # colon immediately before or after 5195e0df7e1fSJoe Perches if (($op eq ':') && 5196e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 5197e0df7e1fSJoe Perches $ok = 1; 5198e0df7e1fSJoe Perches } 5199e0df7e1fSJoe Perches 520084731623SJoe Perches # messages are ERROR, but ?: are CHK 52011f65f947SAndy Whitcroft if ($ok == 0) { 52020675a8fbSJean Delvare my $msg_level = \&ERROR; 52030675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 520484731623SJoe Perches 52050675a8fbSJean Delvare if (&{$msg_level}("SPACING", 52063705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 5207b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5208b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5209b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5210b34c648bSJoe Perches } 52113705ce5bSJoe Perches $line_fixed = 1; 52123705ce5bSJoe Perches } 52130a920b5bSAndy Whitcroft } 521422f2a2efSAndy Whitcroft } 52154a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 52163705ce5bSJoe Perches 52173705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 52183705ce5bSJoe Perches 52193705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 52200a920b5bSAndy Whitcroft } 52213705ce5bSJoe Perches 52223705ce5bSJoe Perches if (($#elements % 2) == 0) { 52233705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 52243705ce5bSJoe Perches } 52253705ce5bSJoe Perches 5226194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 5227194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 52283705ce5bSJoe Perches } 52293705ce5bSJoe Perches 52303705ce5bSJoe Perches 52310a920b5bSAndy Whitcroft } 52320a920b5bSAndy Whitcroft 5233786b6326SJoe Perches# check for whitespace before a non-naked semicolon 5234d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 5235786b6326SJoe Perches if (WARN("SPACING", 5236786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 5237786b6326SJoe Perches $fix) { 5238194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 5239786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 5240786b6326SJoe Perches } 5241786b6326SJoe Perches } 5242786b6326SJoe Perches 5243f0a594c1SAndy Whitcroft# check for multiple assignments 5244f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 5245000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 5246000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 5247f0a594c1SAndy Whitcroft } 5248f0a594c1SAndy Whitcroft 524922f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 525022f2a2efSAndy Whitcroft## # continuation. 525122f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 525222f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 525322f2a2efSAndy Whitcroft## 525422f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 5255e73d2715SDwaipayan Ray## # falsely report the parameters of functions. 525622f2a2efSAndy Whitcroft## my $ln = $line; 525722f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 525822f2a2efSAndy Whitcroft## } 525922f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 5260000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 5261000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 526222f2a2efSAndy Whitcroft## } 526322f2a2efSAndy Whitcroft## } 5264f0a594c1SAndy Whitcroft 52650a920b5bSAndy Whitcroft#need space before brace following if, while, etc 52666b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 52676ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 52683705ce5bSJoe Perches if (ERROR("SPACING", 52693705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 52703705ce5bSJoe Perches $fix) { 52716ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 52723705ce5bSJoe Perches } 5273de7d4f0eSAndy Whitcroft } 5274de7d4f0eSAndy Whitcroft 5275c4a62ef9SJoe Perches## # check for blank lines before declarations 5276c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 5277c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 5278c4a62ef9SJoe Perches## WARN("SPACING", 5279c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 5280c4a62ef9SJoe Perches## } 5281c4a62ef9SJoe Perches## 5282c4a62ef9SJoe Perches 5283de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 5284de7d4f0eSAndy Whitcroft# on the line 528594fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 5286d5e616fcSJoe Perches if (ERROR("SPACING", 5287d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 5288d5e616fcSJoe Perches $fix) { 5289194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5290d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 5291d5e616fcSJoe Perches } 52920a920b5bSAndy Whitcroft } 52930a920b5bSAndy Whitcroft 529422f2a2efSAndy Whitcroft# check spacing on square brackets 529522f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 52963705ce5bSJoe Perches if (ERROR("SPACING", 52973705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 52983705ce5bSJoe Perches $fix) { 5299194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53003705ce5bSJoe Perches s/\[\s+/\[/; 53013705ce5bSJoe Perches } 530222f2a2efSAndy Whitcroft } 530322f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 53043705ce5bSJoe Perches if (ERROR("SPACING", 53053705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 53063705ce5bSJoe Perches $fix) { 5307194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53083705ce5bSJoe Perches s/\s+\]/\]/; 53093705ce5bSJoe Perches } 531022f2a2efSAndy Whitcroft } 531122f2a2efSAndy Whitcroft 5312c45dcabdSAndy Whitcroft# check spacing on parentheses 53139c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 53149c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 53153705ce5bSJoe Perches if (ERROR("SPACING", 53163705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 53173705ce5bSJoe Perches $fix) { 5318194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53193705ce5bSJoe Perches s/\(\s+/\(/; 53203705ce5bSJoe Perches } 532122f2a2efSAndy Whitcroft } 532213214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 5323c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 5324c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 53253705ce5bSJoe Perches if (ERROR("SPACING", 53263705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 53273705ce5bSJoe Perches $fix) { 5328194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53293705ce5bSJoe Perches s/\s+\)/\)/; 53303705ce5bSJoe Perches } 533122f2a2efSAndy Whitcroft } 533222f2a2efSAndy Whitcroft 5333e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 5334e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 5335e2826fd0SJoe Perches 5336e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 5337ea4acbb1SJoe Perches my $var = $1; 5338ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5339ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 5340ea4acbb1SJoe Perches $fix) { 5341ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 5342ea4acbb1SJoe Perches } 5343ea4acbb1SJoe Perches } 5344ea4acbb1SJoe Perches 5345ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 5346ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 5347ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 5348ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 5349ea4acbb1SJoe Perches my $var = $2; 5350ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5351ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 5352ea4acbb1SJoe Perches $fix) { 5353ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 5354ea4acbb1SJoe Perches $var2 =~ s/\s//g; 5355ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 5356ea4acbb1SJoe Perches } 5357e2826fd0SJoe Perches } 5358e2826fd0SJoe Perches 535963b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 5360a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 5361a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 53625b57980dSJoe Perches $perl_version_ok && defined($stat) && 536363b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 536463b7c73eSJoe Perches my $if_stat = $1; 536563b7c73eSJoe Perches my $test = substr($2, 1, -1); 536663b7c73eSJoe Perches my $herectx; 536763b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 536863b7c73eSJoe Perches my $match = $1; 536963b7c73eSJoe Perches # avoid parentheses around potential macro args 537063b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 537163b7c73eSJoe Perches if (!defined($herectx)) { 537263b7c73eSJoe Perches $herectx = $here . "\n"; 537363b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 537463b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 537563b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 537663b7c73eSJoe Perches $herectx .= $rl . "\n"; 537763b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 537863b7c73eSJoe Perches } 537963b7c73eSJoe Perches } 538063b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 538163b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 538263b7c73eSJoe Perches } 538363b7c73eSJoe Perches } 538463b7c73eSJoe Perches 538569078651SJoe Perches# check that goto labels aren't indented (allow a single space indentation) 538669078651SJoe Perches# and ignore bitfield definitions like foo:1 538769078651SJoe Perches# Strictly, labels can have whitespace after the identifier and before the : 538869078651SJoe Perches# but this is not allowed here as many ?: uses would appear to be labels 538969078651SJoe Perches if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ && 539069078651SJoe Perches $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ && 539169078651SJoe Perches $sline !~ /^.\s+default:/) { 53923705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 53933705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 53943705ce5bSJoe Perches $fix) { 5395194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53963705ce5bSJoe Perches s/^(.)\s+/$1/; 53973705ce5bSJoe Perches } 53980a920b5bSAndy Whitcroft } 53990a920b5bSAndy Whitcroft 540040873abaSJoe Perches# check if a statement with a comma should be two statements like: 540140873abaSJoe Perches# foo = bar(), /* comma should be semicolon */ 540240873abaSJoe Perches# bar = baz(); 540340873abaSJoe Perches if (defined($stat) && 540440873abaSJoe Perches $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { 540540873abaSJoe Perches my $cnt = statement_rawlines($stat); 540640873abaSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 540740873abaSJoe Perches WARN("SUSPECT_COMMA_SEMICOLON", 540840873abaSJoe Perches "Possible comma where semicolon could be used\n" . $herectx); 540940873abaSJoe Perches } 541040873abaSJoe Perches 54115b9553abSJoe Perches# return is not a function 5412507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 5413c45dcabdSAndy Whitcroft my $spacing = $1; 54145b57980dSJoe Perches if ($perl_version_ok && 54155b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 54165b9553abSJoe Perches my $value = $1; 54175b9553abSJoe Perches $value = deparenthesize($value); 54185b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 5419000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 5420000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 54215b9553abSJoe Perches } 5422c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 5423000d1cc1SJoe Perches ERROR("SPACING", 5424000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 5425c45dcabdSAndy Whitcroft } 5426c45dcabdSAndy Whitcroft } 5427507e5141SJoe Perches 5428b43ae21bSJoe Perches# unnecessary return in a void function 5429b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 5430b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 5431b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 5432b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 5433b43ae21bSJoe Perches $linenr >= 3 && 5434b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 5435b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 54369819cf25SJoe Perches WARN("RETURN_VOID", 5437b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 54389819cf25SJoe Perches } 54399819cf25SJoe Perches 5440189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 54415b57980dSJoe Perches if ($perl_version_ok && 5442189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 5443189248d8SJoe Perches my $openparens = $1; 5444189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 5445189248d8SJoe Perches my $msg = ""; 5446189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 5447189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 5448189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 5449189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 5450189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 5451189248d8SJoe Perches } 5452189248d8SJoe Perches } 5453189248d8SJoe Perches 5454c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 5455c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 5456c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 5457c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 54585b57980dSJoe Perches if ($perl_version_ok && 5459c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 5460c5595fa2SJoe Perches my $lead = $1; 5461c5595fa2SJoe Perches my $const = $2; 5462c5595fa2SJoe Perches my $comp = $3; 5463c5595fa2SJoe Perches my $to = $4; 5464c5595fa2SJoe Perches my $newcomp = $comp; 5465f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 5466c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 5467c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 5468c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 5469c5595fa2SJoe Perches $fix) { 5470c5595fa2SJoe Perches if ($comp eq "<") { 5471c5595fa2SJoe Perches $newcomp = ">"; 5472c5595fa2SJoe Perches } elsif ($comp eq "<=") { 5473c5595fa2SJoe Perches $newcomp = ">="; 5474c5595fa2SJoe Perches } elsif ($comp eq ">") { 5475c5595fa2SJoe Perches $newcomp = "<"; 5476c5595fa2SJoe Perches } elsif ($comp eq ">=") { 5477c5595fa2SJoe Perches $newcomp = "<="; 5478c5595fa2SJoe Perches } 5479c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 5480c5595fa2SJoe Perches } 5481c5595fa2SJoe Perches } 5482c5595fa2SJoe Perches 5483f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 5484f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 548553a3c448SAndy Whitcroft my $name = $1; 548646b85bf9SGuenter Roeck if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) { 5487000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 5488f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 548953a3c448SAndy Whitcroft } 549053a3c448SAndy Whitcroft } 5491c45dcabdSAndy Whitcroft 54920a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 54934a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 54943705ce5bSJoe Perches if (ERROR("SPACING", 54953705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 54963705ce5bSJoe Perches $fix) { 5497194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54983705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 54993705ce5bSJoe Perches } 55000a920b5bSAndy Whitcroft } 55010a920b5bSAndy Whitcroft 5502f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 5503f5fe35ddSAndy Whitcroft# statements after the conditional. 5504170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 55053e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 55063e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 55073e469cdcSAndy Whitcroft if (!defined $stat); 5508170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 5509170d3a22SAndy Whitcroft $remain_next, $off_next); 5510170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 5511170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 5512170d3a22SAndy Whitcroft 5513170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 5514170d3a22SAndy Whitcroft # If the statement carries leading newlines, 5515170d3a22SAndy Whitcroft # then count those as offsets. 5516170d3a22SAndy Whitcroft my ($whitespace) = 5517170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 5518170d3a22SAndy Whitcroft my $offset = 5519170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 5520170d3a22SAndy Whitcroft 5521170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 5522170d3a22SAndy Whitcroft $offset} = 1; 5523170d3a22SAndy Whitcroft } 5524170d3a22SAndy Whitcroft } 5525170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 5526c11230f4SJoe Perches defined($stat) && defined($cond) && 5527170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 5528171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 55298905a67cSAndy Whitcroft 5530b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 553165b64b3bSJoe Perches if (ERROR("ASSIGN_IN_IF", 553265b64b3bSJoe Perches "do not use assignment in if condition\n" . $herecurr) && 553365b64b3bSJoe Perches $fix && $perl_version_ok) { 553465b64b3bSJoe Perches if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { 553565b64b3bSJoe Perches my $space = $1; 553665b64b3bSJoe Perches my $not = $2; 553765b64b3bSJoe Perches my $statement = $3; 553865b64b3bSJoe Perches my $assigned = $4; 553965b64b3bSJoe Perches my $test = $8; 554065b64b3bSJoe Perches my $against = $9; 554165b64b3bSJoe Perches my $brace = $15; 554265b64b3bSJoe Perches fix_delete_line($fixlinenr, $rawline); 554365b64b3bSJoe Perches fix_insert_line($fixlinenr, "$space$statement;"); 554465b64b3bSJoe Perches my $newline = "${space}if ("; 554565b64b3bSJoe Perches $newline .= '!' if defined($not); 554665b64b3bSJoe Perches $newline .= '(' if (defined $not && defined($test) && defined($against)); 554765b64b3bSJoe Perches $newline .= "$assigned"; 554865b64b3bSJoe Perches $newline .= " $test $against" if (defined($test) && defined($against)); 554965b64b3bSJoe Perches $newline .= ')' if (defined $not && defined($test) && defined($against)); 555065b64b3bSJoe Perches $newline .= ')'; 555165b64b3bSJoe Perches $newline .= " {" if (defined($brace)); 555265b64b3bSJoe Perches fix_insert_line($fixlinenr + 1, $newline); 555365b64b3bSJoe Perches } 555465b64b3bSJoe Perches } 55558905a67cSAndy Whitcroft } 55568905a67cSAndy Whitcroft 55578905a67cSAndy Whitcroft # Find out what is on the end of the line after the 55588905a67cSAndy Whitcroft # conditional. 5559773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 55608905a67cSAndy Whitcroft $s =~ s/\n.*//g; 556113214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 556253210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 556353210168SAndy Whitcroft $c !~ /}\s*while\s*/) 5564773647a0SAndy Whitcroft { 5565bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 5566bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 5567bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 556842bdf74cSHidetoshi Seto my $stat_real = ''; 5569bb44ad39SAndy Whitcroft 557042bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 557142bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 5572bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 5573bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 5574bb44ad39SAndy Whitcroft } 5575bb44ad39SAndy Whitcroft 5576000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5577000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 55788905a67cSAndy Whitcroft } 55798905a67cSAndy Whitcroft } 55808905a67cSAndy Whitcroft 558113214adfSAndy Whitcroft# Check for bitwise tests written as boolean 558213214adfSAndy Whitcroft if ($line =~ / 558313214adfSAndy Whitcroft (?: 558413214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 558513214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 558613214adfSAndy Whitcroft (?:\&\&|\|\|) 558713214adfSAndy Whitcroft | 558813214adfSAndy Whitcroft (?:\&\&|\|\|) 558913214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 559013214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 559113214adfSAndy Whitcroft )/x) 559213214adfSAndy Whitcroft { 5593000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 5594000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 559513214adfSAndy Whitcroft } 559613214adfSAndy Whitcroft 55978905a67cSAndy Whitcroft# if and else should not have general statements after it 559813214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 559913214adfSAndy Whitcroft my $s = $1; 560013214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 560113214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 5602000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5603000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 56040a920b5bSAndy Whitcroft } 560513214adfSAndy Whitcroft } 560639667782SAndy Whitcroft# if should not continue a brace 560739667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 5608000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5609048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 561039667782SAndy Whitcroft $herecurr); 561139667782SAndy Whitcroft } 5612a1080bf8SAndy Whitcroft# case and default should not have general statements after them 5613a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 5614a1080bf8SAndy Whitcroft $line !~ /\G(?: 56153fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5616a1080bf8SAndy Whitcroft \s*return\s+ 5617a1080bf8SAndy Whitcroft )/xg) 5618a1080bf8SAndy Whitcroft { 5619000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5620000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 5621a1080bf8SAndy Whitcroft } 56220a920b5bSAndy Whitcroft 56230a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 56240a920b5bSAndy Whitcroft # indent level to be relevant to each other. 56258b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 56260a920b5bSAndy Whitcroft $previndent == $indent) { 56278b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 56288b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 56298b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 56308b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 56318b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 56328b8856f4SJoe Perches my $fixedline = $prevrawline; 56338b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 56348b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 56358b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 56368b8856f4SJoe Perches } 56378b8856f4SJoe Perches $fixedline = $rawline; 56388b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 56398b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 56408b8856f4SJoe Perches } 56410a920b5bSAndy Whitcroft } 56420a920b5bSAndy Whitcroft 56438b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5644c2fdda0dSAndy Whitcroft $previndent == $indent) { 5645c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5646c2fdda0dSAndy Whitcroft 5647c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5648c2fdda0dSAndy Whitcroft # conditional. 5649773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5650c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5651c2fdda0dSAndy Whitcroft 5652c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 56538b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 56548b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 56558b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 56568b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 56578b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 56588b8856f4SJoe Perches my $fixedline = $prevrawline; 56598b8856f4SJoe Perches my $trailing = $rawline; 56608b8856f4SJoe Perches $trailing =~ s/^\+//; 56618b8856f4SJoe Perches $trailing = trim($trailing); 56628b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 56638b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 56648b8856f4SJoe Perches } 5665c2fdda0dSAndy Whitcroft } 5666c2fdda0dSAndy Whitcroft } 5667c2fdda0dSAndy Whitcroft 566895e2c602SJoe Perches#Specific variable tests 5669323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5670323c1260SJoe Perches my $var = $1; 567195e2c602SJoe Perches 567295e2c602SJoe Perches#CamelCase 5673807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5674be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 56754104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values 56764104a206SŁukasz Stelmach $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && 567722735ce8SJoe Perches#Ignore Page<foo> variants 5678807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5679d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB 5680d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 5681d439e6a5SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5682f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5683f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 56847e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 56857e781f67SJoe Perches my $word = $1; 56867e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5687d8b07710SJoe Perches if ($check) { 5688d8b07710SJoe Perches seed_camelcase_includes(); 5689d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5690d8b07710SJoe Perches seed_camelcase_file($realfile); 5691d8b07710SJoe Perches $camelcase_file_seeded = 1; 5692d8b07710SJoe Perches } 5693d8b07710SJoe Perches } 56947e781f67SJoe Perches if (!defined $camelcase{$word}) { 56957e781f67SJoe Perches $camelcase{$word} = 1; 5696be79794bSJoe Perches CHK("CAMELCASE", 56977e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 56987e781f67SJoe Perches } 5699323c1260SJoe Perches } 5700323c1260SJoe Perches } 57013445686aSJoe Perches } 57020a920b5bSAndy Whitcroft 57030a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5704d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5705d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5706d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5707d5e616fcSJoe Perches $fix) { 5708194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5709d5e616fcSJoe Perches } 57100a920b5bSAndy Whitcroft } 57110a920b5bSAndy Whitcroft 57120e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 57130e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5714c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5715e09dec48SAndy Whitcroft my $file = "$1.h"; 5716e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5717e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5718e09dec48SAndy Whitcroft $realfile ne $checkfile && 57197840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5720c45dcabdSAndy Whitcroft { 57210e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 57220e212e0aSFabian Frederick if ($asminclude > 0) { 5723e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5724000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5725000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5726e09dec48SAndy Whitcroft } else { 5727000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5728000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5729e09dec48SAndy Whitcroft } 57300a920b5bSAndy Whitcroft } 57310a920b5bSAndy Whitcroft } 57320e212e0aSFabian Frederick } 57330a920b5bSAndy Whitcroft 5734653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5735653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5736cf655043SAndy Whitcroft# in a known good container 5737b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5738b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5739d8aaf121SAndy Whitcroft my $ln = $linenr; 5740d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5741c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5742c45dcabdSAndy Whitcroft my $ctx = ''; 574308a2843eSJoe Perches my $has_flow_statement = 0; 574408a2843eSJoe Perches my $has_arg_concat = 0; 5745c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5746f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5747f74bd194SAndy Whitcroft $ctx = $dstat; 5748c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5749a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5750c45dcabdSAndy Whitcroft 575108a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 575262e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 575308a2843eSJoe Perches 5754f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5755f59b64bfSJoe Perches my $define_args = $1; 5756f59b64bfSJoe Perches my $define_stmt = $dstat; 5757f59b64bfSJoe Perches my @def_args = (); 5758f59b64bfSJoe Perches 5759f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5760f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5761f59b64bfSJoe Perches $define_args =~ s/\s*//g; 57628c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5763f59b64bfSJoe Perches @def_args = split(",", $define_args); 5764f59b64bfSJoe Perches } 5765f59b64bfSJoe Perches 5766292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5767c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5768c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5769c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5770c45dcabdSAndy Whitcroft 5771c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 57722e44e803SDwaipayan Ray while ($dstat =~ s/\([^\(\)]*\)/1u/ || 57732e44e803SDwaipayan Ray $dstat =~ s/\{[^\{\}]*\}/1u/ || 57742e44e803SDwaipayan Ray $dstat =~ s/.\[[^\[\]]*\]/1u/) 5775bf30d6edSAndy Whitcroft { 5776c45dcabdSAndy Whitcroft } 5777c45dcabdSAndy Whitcroft 5778342d3d2fSAntonio Borneo # Flatten any obvious string concatenation. 577933acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 578033acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5781e45bab8eSAndy Whitcroft { 5782e45bab8eSAndy Whitcroft } 5783e45bab8eSAndy Whitcroft 578442e15293SJoe Perches # Make asm volatile uses seem like a generic function 578542e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 578642e15293SJoe Perches 5787c45dcabdSAndy Whitcroft my $exceptions = qr{ 5788c45dcabdSAndy Whitcroft $Declare| 5789c45dcabdSAndy Whitcroft module_param_named| 5790a0a0a7a9SKees Cook MODULE_PARM_DESC| 5791c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5792c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5793383099fdSAndy Whitcroft __typeof__\(| 579422fd2d3eSStefani Seibold union| 579522fd2d3eSStefani Seibold struct| 5796ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 57976b10df42SVladimir Zapolskiy ^\"|\"$| 57986b10df42SVladimir Zapolskiy ^\[ 5799c45dcabdSAndy Whitcroft }x; 58005eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5801f59b64bfSJoe Perches 5802f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5803f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5804e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5805f59b64bfSJoe Perches 5806f74bd194SAndy Whitcroft if ($dstat ne '' && 5807f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5808f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 58093cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5810356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5811f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5812f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5813e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 581472f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 58152e44e803SDwaipayan Ray $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} 5816f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5817f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5818f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 58194e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5820f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5821c45dcabdSAndy Whitcroft { 5822e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5823e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5824e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5825e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5826f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5827f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5828f74bd194SAndy Whitcroft } else { 5829000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 5830388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5831d8aaf121SAndy Whitcroft } 5832f59b64bfSJoe Perches 5833f59b64bfSJoe Perches } 58345207649bSJoe Perches 58355207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 58365207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 58375207649bSJoe Perches my $first = 1; 58385207649bSJoe Perches $define_stmt = ""; 58395207649bSJoe Perches foreach my $l (@stmt_array) { 58405207649bSJoe Perches $l =~ s/\\$//; 58415207649bSJoe Perches if ($first) { 58425207649bSJoe Perches $define_stmt = $l; 58435207649bSJoe Perches $first = 0; 58445207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 58455207649bSJoe Perches $define_stmt .= substr($l, 1); 58465207649bSJoe Perches } 58475207649bSJoe Perches } 58485207649bSJoe Perches $define_stmt =~ s/$;//g; 58495207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 58505207649bSJoe Perches $define_stmt = trim($define_stmt); 58515207649bSJoe Perches 5852f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 5853f59b64bfSJoe Perches foreach my $arg (@def_args) { 5854f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 58559192d41aSJoe Perches next if ($arg =~ /^type$/i); 58567fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 58577b844345SVincent 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; 58587fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 58597fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5860d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 5861f59b64bfSJoe Perches if ($use_cnt > 1) { 5862f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 5863f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5864f59b64bfSJoe Perches } 58659192d41aSJoe Perches# check if any macro arguments may have other precedence issues 58667fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 58679192d41aSJoe Perches ((defined($1) && $1 ne ',') || 58689192d41aSJoe Perches (defined($2) && $2 ne ','))) { 58699192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 58709192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 58719192d41aSJoe Perches } 58720a920b5bSAndy Whitcroft } 58735023d347SJoe Perches 587408a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 587508a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 587608a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 587708a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 5878e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 587908a2843eSJoe Perches 588008a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 588108a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 588208a2843eSJoe Perches } 588308a2843eSJoe Perches 5884481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 58855023d347SJoe Perches 58865023d347SJoe Perches } else { 58875023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 5888481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 5889481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 58905023d347SJoe Perches $line =~ /^\+.*\\$/) { 58915023d347SJoe Perches WARN("LINE_CONTINUATIONS", 58925023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 58935023d347SJoe Perches } 5894653d4876SAndy Whitcroft } 58950a920b5bSAndy Whitcroft 5896b13edf7fSJoe Perches# do {} while (0) macro tests: 5897b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 5898b13edf7fSJoe Perches# macro should not end with a semicolon 58995b57980dSJoe Perches if ($perl_version_ok && 5900b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 5901b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5902b13edf7fSJoe Perches my $ln = $linenr; 5903b13edf7fSJoe Perches my $cnt = $realcnt; 5904b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 5905b13edf7fSJoe Perches my $ctx = ''; 5906b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 5907b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 5908b13edf7fSJoe Perches $ctx = $dstat; 5909b13edf7fSJoe Perches 5910b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 59111b36b201SJoe Perches $dstat =~ s/$;/ /g; 5912b13edf7fSJoe Perches 5913b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 5914b13edf7fSJoe Perches my $stmts = $2; 5915b13edf7fSJoe Perches my $semis = $3; 5916b13edf7fSJoe Perches 5917b13edf7fSJoe Perches $ctx =~ s/\n*$//; 5918b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 5919e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5920b13edf7fSJoe Perches 5921ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 5922ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 5923b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 5924b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 5925b13edf7fSJoe Perches } 5926b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 5927b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 5928b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5929b13edf7fSJoe Perches } 5930f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5931f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5932f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5933e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5934f5ef95b1SJoe Perches 5935f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5936f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5937b13edf7fSJoe Perches } 5938b13edf7fSJoe Perches } 5939b13edf7fSJoe Perches 5940f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 594113214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 594213214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5943cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 594413214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5945cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5946cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5947aad4f614SJoe Perches my @allowed = (); 5948aad4f614SJoe Perches my $allow = 0; 594913214adfSAndy Whitcroft my $seen = 0; 5950773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5951cf655043SAndy Whitcroft my $ln = $linenr - 1; 595213214adfSAndy Whitcroft for my $chunk (@chunks) { 595313214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 595413214adfSAndy Whitcroft 5955773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5956773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5957773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5958773647a0SAndy Whitcroft 5959aad4f614SJoe Perches $allowed[$allow] = 0; 5960773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5961773647a0SAndy Whitcroft 5962773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5963773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5964773647a0SAndy Whitcroft 5965773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5966cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5967cf655043SAndy Whitcroft 5968773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 596913214adfSAndy Whitcroft 597013214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 597113214adfSAndy Whitcroft 5972aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5973cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5974cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5975aad4f614SJoe Perches $allowed[$allow] = 1; 597613214adfSAndy Whitcroft } 597713214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5978cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5979aad4f614SJoe Perches $allowed[$allow] = 1; 598013214adfSAndy Whitcroft } 5981cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5982cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5983aad4f614SJoe Perches $allowed[$allow] = 1; 598413214adfSAndy Whitcroft } 5985aad4f614SJoe Perches $allow++; 598613214adfSAndy Whitcroft } 5987aad4f614SJoe Perches if ($seen) { 5988aad4f614SJoe Perches my $sum_allowed = 0; 5989aad4f614SJoe Perches foreach (@allowed) { 5990aad4f614SJoe Perches $sum_allowed += $_; 5991aad4f614SJoe Perches } 5992aad4f614SJoe Perches if ($sum_allowed == 0) { 5993000d1cc1SJoe Perches WARN("BRACES", 5994000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5995aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5996aad4f614SJoe Perches $seen != $allow) { 5997aad4f614SJoe Perches CHK("BRACES", 5998aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5999aad4f614SJoe Perches } 600013214adfSAndy Whitcroft } 600113214adfSAndy Whitcroft } 600213214adfSAndy Whitcroft } 6003773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 600413214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 6005cf655043SAndy Whitcroft my $allowed = 0; 6006f0a594c1SAndy Whitcroft 6007cf655043SAndy Whitcroft # Check the pre-context. 6008cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 6009cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 6010cf655043SAndy Whitcroft $allowed = 1; 6011f0a594c1SAndy Whitcroft } 6012773647a0SAndy Whitcroft 6013773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 6014773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 6015773647a0SAndy Whitcroft 6016cf655043SAndy Whitcroft # Check the condition. 6017cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 6018773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 6019cf655043SAndy Whitcroft if (defined $cond) { 6020773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 6021cf655043SAndy Whitcroft } 6022cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 6023cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 6024cf655043SAndy Whitcroft $allowed = 1; 6025cf655043SAndy Whitcroft } 6026cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 6027cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 6028cf655043SAndy Whitcroft $allowed = 1; 6029cf655043SAndy Whitcroft } 6030cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 6031cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 6032cf655043SAndy Whitcroft $allowed = 1; 6033cf655043SAndy Whitcroft } 6034cf655043SAndy Whitcroft # Check the post-context. 6035cf655043SAndy Whitcroft if (defined $chunks[1]) { 6036cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 6037cf655043SAndy Whitcroft if (defined $cond) { 6038773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 6039cf655043SAndy Whitcroft } 6040cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 6041cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 6042cf655043SAndy Whitcroft $allowed = 1; 6043cf655043SAndy Whitcroft } 6044cf655043SAndy Whitcroft } 6045cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 6046f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 6047e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6048cf655043SAndy Whitcroft 6049000d1cc1SJoe Perches WARN("BRACES", 6050000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 6051f0a594c1SAndy Whitcroft } 6052f0a594c1SAndy Whitcroft } 6053f0a594c1SAndy Whitcroft 6054e4c5babdSJoe Perches# check for single line unbalanced braces 605595330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 605695330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 6057e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 6058e4c5babdSJoe Perches } 6059e4c5babdSJoe Perches 60600979ae66SJoe Perches# check for unnecessary blank lines around braces 606177b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 6062f8e58219SJoe Perches if (CHK("BRACES", 6063f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 6064f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 6065f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6066f8e58219SJoe Perches } 60670979ae66SJoe Perches } 606877b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 6069f8e58219SJoe Perches if (CHK("BRACES", 6070f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 6071f8e58219SJoe Perches $fix) { 6072f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 6073f8e58219SJoe Perches } 60740979ae66SJoe Perches } 60750979ae66SJoe Perches 60764a0df2efSAndy Whitcroft# no volatiles please 60776c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 60786c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 6079000d1cc1SJoe Perches WARN("VOLATILE", 60808c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 60814a0df2efSAndy Whitcroft } 60824a0df2efSAndy Whitcroft 60835e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 60845e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 60855e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 60865e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 608733acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 60885e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 60895e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 60905e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 60915e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 60925e4f6ba5SJoe Perches $fix && 60935e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 60945e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 60955e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 60965e4f6ba5SJoe Perches my $comma_close = ""; 60975e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 60985e4f6ba5SJoe Perches $comma_close = $1; 60995e4f6ba5SJoe Perches } 61005e4f6ba5SJoe Perches 61015e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 61025e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 61035e4f6ba5SJoe Perches my $fixedline = $prevrawline; 61045e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 61055e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 61065e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 61075e4f6ba5SJoe Perches $fixedline = $rawline; 61085e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 61095e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 61105e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 61115e4f6ba5SJoe Perches } 61125e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 61135e4f6ba5SJoe Perches } 61145e4f6ba5SJoe Perches } 61155e4f6ba5SJoe Perches 61165e4f6ba5SJoe Perches# check for missing a space in a string concatenation 61175e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 61185e4f6ba5SJoe Perches WARN('MISSING_SPACE', 61195e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 61205e4f6ba5SJoe Perches } 61215e4f6ba5SJoe Perches 612277cb8546SJoe Perches# check for an embedded function name in a string when the function is known 6123e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 6124e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 6125e4b7d309SJoe Perches# function declarations 612677cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 612777cb8546SJoe Perches defined($context_function) && 6128e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 6129e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 613077cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 6131e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 613277cb8546SJoe Perches } 613377cb8546SJoe Perches 6134adb2da82SJoe Perches# check for unnecessary function tracing like uses 6135adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like 6136adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions 6137adb2da82SJoe Perches if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) { 6138adb2da82SJoe Perches if (WARN("TRACING_LOGGING", 6139adb2da82SJoe Perches "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) && 6140adb2da82SJoe Perches $fix) { 6141adb2da82SJoe Perches fix_delete_line($fixlinenr, $rawline); 6142adb2da82SJoe Perches } 6143adb2da82SJoe Perches } 6144adb2da82SJoe Perches 61455e4f6ba5SJoe Perches# check for spaces before a quoted newline 61465e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 61475e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 61485e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 61495e4f6ba5SJoe Perches $fix) { 61505e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 61515e4f6ba5SJoe Perches } 61525e4f6ba5SJoe Perches 61535e4f6ba5SJoe Perches } 61545e4f6ba5SJoe Perches 6155f17dba4fSJoe Perches# concatenated string without spaces between elements 6156d2af5aa6SJoe Perches if ($line =~ /$String[A-Z_]/ || 6157d2af5aa6SJoe Perches ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) { 615879682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 615979682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 616079682c0cSJoe Perches $fix) { 616179682c0cSJoe Perches while ($line =~ /($String)/g) { 616279682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 616379682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 616479682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 616579682c0cSJoe Perches } 616679682c0cSJoe Perches } 6167f17dba4fSJoe Perches } 6168f17dba4fSJoe Perches 616990ad30e5SJoe Perches# uncoalesced string fragments 6170d2af5aa6SJoe Perches if ($line =~ /$String\s*[Lu]?"/) { 617179682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 617279682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 617379682c0cSJoe Perches $fix) { 617479682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 617579682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 617679682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 617779682c0cSJoe Perches } 617879682c0cSJoe Perches } 617990ad30e5SJoe Perches } 618090ad30e5SJoe Perches 6181522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 6182522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 6183522b837cSAlexey Dobriyan my $show_Z = 1; 61845e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 6185522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 61865e4f6ba5SJoe Perches $string =~ s/%%/__/g; 6187522b837cSAlexey Dobriyan # check for %L 6188522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 61895e4f6ba5SJoe Perches WARN("PRINTF_L", 6190522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 6191522b837cSAlexey Dobriyan $show_L = 0; 61925e4f6ba5SJoe Perches } 6193522b837cSAlexey Dobriyan # check for %Z 6194522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 6195522b837cSAlexey Dobriyan WARN("PRINTF_Z", 6196522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 6197522b837cSAlexey Dobriyan $show_Z = 0; 6198522b837cSAlexey Dobriyan } 6199522b837cSAlexey Dobriyan # check for 0x<decimal> 6200522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 6201522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 62026e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 62036e300757SJoe Perches } 62045e4f6ba5SJoe Perches } 62055e4f6ba5SJoe Perches 62065e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 62073f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 62085e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 62095e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 62105e4f6ba5SJoe Perches } 62115e4f6ba5SJoe Perches 621200df344fSAndy Whitcroft# warn about #if 0 6213c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 621460f89010SPrakruthi Deepak Heragu WARN("IF_0", 621560f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 621660f89010SPrakruthi Deepak Heragu } 621760f89010SPrakruthi Deepak Heragu 621860f89010SPrakruthi Deepak Heragu# warn about #if 1 621960f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 622060f89010SPrakruthi Deepak Heragu WARN("IF_1", 622160f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 62224a0df2efSAndy Whitcroft } 62234a0df2efSAndy Whitcroft 622403df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 622503df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 6226100425deSJoe Perches my $tested = quotemeta($1); 6227100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 6228100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 6229100425deSJoe Perches my $func = $1; 6230100425deSJoe Perches if (WARN('NEEDLESS_IF', 6231100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 6232100425deSJoe Perches $fix) { 6233100425deSJoe Perches my $do_fix = 1; 6234100425deSJoe Perches my $leading_tabs = ""; 6235100425deSJoe Perches my $new_leading_tabs = ""; 6236100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 6237100425deSJoe Perches $leading_tabs = $1; 6238100425deSJoe Perches } else { 6239100425deSJoe Perches $do_fix = 0; 6240100425deSJoe Perches } 6241100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 6242100425deSJoe Perches $new_leading_tabs = $1; 6243100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 6244100425deSJoe Perches $do_fix = 0; 6245100425deSJoe Perches } 6246100425deSJoe Perches } else { 6247100425deSJoe Perches $do_fix = 0; 6248100425deSJoe Perches } 6249100425deSJoe Perches if ($do_fix) { 6250100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6251100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 6252100425deSJoe Perches } 6253100425deSJoe Perches } 62544c432a8fSGreg Kroah-Hartman } 62554c432a8fSGreg Kroah-Hartman } 6256f0a594c1SAndy Whitcroft 6257ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 6258ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 6259ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 6260ebfdc409SJoe Perches (defined $1 || defined $3) && 6261ebfdc409SJoe Perches $linenr > 3) { 6262ebfdc409SJoe Perches my $testval = $2; 6263ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 6264ebfdc409SJoe Perches 6265ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 6266ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 6267ebfdc409SJoe Perches 6268e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 6269e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 6270ebfdc409SJoe Perches WARN("OOM_MESSAGE", 6271ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 6272ebfdc409SJoe Perches } 6273ebfdc409SJoe Perches } 6274ebfdc409SJoe Perches 6275f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 6276dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 6277f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 6278f78d98f6SJoe Perches my $level = $1; 6279f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 6280f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 6281f78d98f6SJoe Perches $fix) { 6282f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 6283f78d98f6SJoe Perches } 6284f78d98f6SJoe Perches } 6285f78d98f6SJoe Perches 628645c55e92SJoe Perches# check for logging continuations 628745c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 628845c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 628945c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 629045c55e92SJoe Perches } 629145c55e92SJoe Perches 629270eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions 629370eb2275SDwaipayan Ray if (defined $stat && 629470eb2275SDwaipayan Ray $line =~ /\b$logFunctions\s*\(/ && 629570eb2275SDwaipayan Ray index($stat, '"') >= 0) { 629670eb2275SDwaipayan Ray my $lc = $stat =~ tr@\n@@; 629770eb2275SDwaipayan Ray $lc = $lc + $linenr; 629870eb2275SDwaipayan Ray my $stat_real = get_stat_real($linenr, $lc); 629970eb2275SDwaipayan Ray pos($stat_real) = index($stat_real, '"'); 630070eb2275SDwaipayan Ray while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { 630170eb2275SDwaipayan Ray my $pspec = $1; 630270eb2275SDwaipayan Ray my $h = $2; 630370eb2275SDwaipayan Ray my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; 630470eb2275SDwaipayan Ray if (WARN("UNNECESSARY_MODIFIER", 630570eb2275SDwaipayan Ray "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && 630670eb2275SDwaipayan Ray $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { 630770eb2275SDwaipayan Ray my $nspec = $pspec; 630870eb2275SDwaipayan Ray $nspec =~ s/h//g; 630970eb2275SDwaipayan Ray $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; 631070eb2275SDwaipayan Ray } 631170eb2275SDwaipayan Ray } 631270eb2275SDwaipayan Ray } 631370eb2275SDwaipayan Ray 6314abb08a53SJoe Perches# check for mask then right shift without a parentheses 63155b57980dSJoe Perches if ($perl_version_ok && 6316abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 6317abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 6318abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 6319abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 6320abb08a53SJoe Perches } 6321abb08a53SJoe Perches 6322b75ac618SJoe Perches# check for pointer comparisons to NULL 63235b57980dSJoe Perches if ($perl_version_ok) { 6324b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 6325b75ac618SJoe Perches my $val = $1; 6326b75ac618SJoe Perches my $equal = "!"; 6327b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 6328b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 6329b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 6330b75ac618SJoe Perches $fix) { 6331b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 6332b75ac618SJoe Perches } 6333b75ac618SJoe Perches } 6334b75ac618SJoe Perches } 6335b75ac618SJoe Perches 63368716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 63378716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 63388716de38SJoe Perches my $attr = $1; 63398716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 63408716de38SJoe Perches my $ptr = $1; 63418716de38SJoe Perches my $var = $2; 63428716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 63438716de38SJoe Perches ERROR("MISPLACED_INIT", 63448716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 63458716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 63468716de38SJoe Perches WARN("MISPLACED_INIT", 63478716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 63488716de38SJoe Perches $fix) { 6349194f66fcSJoe 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; 63508716de38SJoe Perches } 63518716de38SJoe Perches } 63528716de38SJoe Perches } 63538716de38SJoe Perches 6354e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 6355e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 6356e970b884SJoe Perches my $attr = $1; 6357e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 6358e970b884SJoe Perches my $attr_prefix = $1; 6359e970b884SJoe Perches my $attr_type = $2; 6360e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6361e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 6362e970b884SJoe Perches $fix) { 6363194f66fcSJoe Perches $fixed[$fixlinenr] =~ 6364e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 6365e970b884SJoe Perches } 6366e970b884SJoe Perches } 6367e970b884SJoe Perches 6368e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 6369e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 6370e970b884SJoe Perches my $attr = $1; 6371e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6372e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 6373e970b884SJoe Perches $fix) { 6374194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 6375e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 6376e970b884SJoe Perches $lead = rtrim($1); 6377e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 6378e970b884SJoe Perches $lead = "${lead}const "; 6379194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 6380e970b884SJoe Perches } 6381e970b884SJoe Perches } 6382e970b884SJoe Perches 6383c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 6384c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 6385c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 6386c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 6387c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 6388c17893c7SJoe Perches $fix) { 6389c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 6390c17893c7SJoe Perches } 6391c17893c7SJoe Perches } 6392c17893c7SJoe Perches 6393fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 6394fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 6395fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 6396fbdb8138SJoe Perches my $constant_func = $1; 6397fbdb8138SJoe Perches my $func = $constant_func; 6398fbdb8138SJoe Perches $func =~ s/^__constant_//; 6399fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 6400fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 6401fbdb8138SJoe Perches $fix) { 6402194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 6403fbdb8138SJoe Perches } 6404fbdb8138SJoe Perches } 6405fbdb8138SJoe Perches 64061a15a250SPatrick Pannuto# prefer usleep_range over udelay 640737581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 640843c1d77cSJoe Perches my $delay = $1; 64091a15a250SPatrick Pannuto # ignore udelay's < 10, however 641043c1d77cSJoe Perches if (! ($delay < 10) ) { 6411000d1cc1SJoe Perches CHK("USLEEP_RANGE", 6412458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 641343c1d77cSJoe Perches } 641443c1d77cSJoe Perches if ($delay > 2000) { 641543c1d77cSJoe Perches WARN("LONG_UDELAY", 641643c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 64171a15a250SPatrick Pannuto } 64181a15a250SPatrick Pannuto } 64191a15a250SPatrick Pannuto 642009ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 642109ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 642209ef8725SPatrick Pannuto if ($1 < 20) { 6423000d1cc1SJoe Perches WARN("MSLEEP", 6424458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 642509ef8725SPatrick Pannuto } 642609ef8725SPatrick Pannuto } 642709ef8725SPatrick Pannuto 642836ec1939SJoe Perches# check for comparisons of jiffies 642936ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 643036ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 643136ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 643236ec1939SJoe Perches } 643336ec1939SJoe Perches 64349d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 64359d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 64369d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 64379d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 64389d7a34a5SJoe Perches } 64399d7a34a5SJoe Perches 644000df344fSAndy Whitcroft# warn about #ifdefs in C files 6441c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 644200df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 644300df344fSAndy Whitcroft# print "$herecurr"; 644400df344fSAndy Whitcroft# $clean = 0; 644500df344fSAndy Whitcroft# } 644600df344fSAndy Whitcroft 644722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 6448c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 64493705ce5bSJoe Perches if (ERROR("SPACING", 64503705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 64513705ce5bSJoe Perches $fix) { 6452194f66fcSJoe Perches $fixed[$fixlinenr] =~ 64533705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 64543705ce5bSJoe Perches } 64553705ce5bSJoe Perches 645622f2a2efSAndy Whitcroft } 645722f2a2efSAndy Whitcroft 64584a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 6459171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 6460171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 64614a0df2efSAndy Whitcroft my $which = $1; 64624a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6463000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 6464000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 64654a0df2efSAndy Whitcroft } 64664a0df2efSAndy Whitcroft } 64674a0df2efSAndy Whitcroft# check for memory barriers without a comment. 6468402c2553SMichael S. Tsirkin 6469402c2553SMichael S. Tsirkin my $barriers = qr{ 6470402c2553SMichael S. Tsirkin mb| 6471402c2553SMichael S. Tsirkin rmb| 6472ad83ec6cSWill Deacon wmb 6473402c2553SMichael S. Tsirkin }x; 6474402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 6475402c2553SMichael S. Tsirkin mb__before_atomic| 6476402c2553SMichael S. Tsirkin mb__after_atomic| 6477402c2553SMichael S. Tsirkin store_release| 6478402c2553SMichael S. Tsirkin load_acquire| 6479402c2553SMichael S. Tsirkin store_mb| 6480402c2553SMichael S. Tsirkin (?:$barriers) 6481402c2553SMichael S. Tsirkin }x; 6482402c2553SMichael S. Tsirkin my $all_barriers = qr{ 6483402c2553SMichael S. Tsirkin (?:$barriers)| 648443e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 648543e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 6486402c2553SMichael S. Tsirkin }x; 6487402c2553SMichael S. Tsirkin 6488402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 64894a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6490c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 6491000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 64924a0df2efSAndy Whitcroft } 64934a0df2efSAndy Whitcroft } 64943ad81779SPaul E. McKenney 6495f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 6496f4073b0fSMichael S. Tsirkin 6497f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 6498f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 6499f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 6500f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 6501f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 6502f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 6503f4073b0fSMichael S. Tsirkin } 6504f4073b0fSMichael S. Tsirkin 6505cb426e99SJoe Perches# check for waitqueue_active without a comment. 6506cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 6507cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 6508cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 6509cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 6510cb426e99SJoe Perches } 6511cb426e99SJoe Perches } 65123ad81779SPaul E. McKenney 65135099a722SMarco Elver# check for data_race without a comment. 65145099a722SMarco Elver if ($line =~ /\bdata_race\s*\(/) { 65155099a722SMarco Elver if (!ctx_has_comment($first_line, $linenr)) { 65165099a722SMarco Elver WARN("DATA_RACE", 65175099a722SMarco Elver "data_race without comment\n" . $herecurr); 65185099a722SMarco Elver } 65195099a722SMarco Elver } 65205099a722SMarco Elver 65214a0df2efSAndy Whitcroft# check of hardware specific defines 6522c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 6523000d1cc1SJoe Perches CHK("ARCH_DEFINES", 6524000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 65250a920b5bSAndy Whitcroft } 6526653d4876SAndy Whitcroft 6527596ed45bSJoe Perches# check that the storage class is not after a type 6528596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 6529000d1cc1SJoe Perches WARN("STORAGE_CLASS", 6530596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 6531596ed45bSJoe Perches } 6532596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 6533596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 6534596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 6535596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 6536596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 6537596ed45bSJoe Perches WARN("STORAGE_CLASS", 6538596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 6539d4977c78STobias Klauser } 6540d4977c78STobias Klauser 6541de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 6542de7d4f0eSAndy Whitcroft# storage class and type. 65439c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 65449c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 6545000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 6546000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 6547de7d4f0eSAndy Whitcroft } 6548de7d4f0eSAndy Whitcroft 65498905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 65502b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 65512b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 6552d5e616fcSJoe Perches if (WARN("INLINE", 6553d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 6554d5e616fcSJoe Perches $fix) { 6555194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 6556d5e616fcSJoe Perches 6557d5e616fcSJoe Perches } 65588905a67cSAndy Whitcroft } 65598905a67cSAndy Whitcroft 65607ebe1d17SDwaipayan Ray# Check for compiler attributes 65612b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 65627ebe1d17SDwaipayan Ray $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { 65637ebe1d17SDwaipayan Ray my $attr = $1; 65647ebe1d17SDwaipayan Ray $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; 65657ebe1d17SDwaipayan Ray 65667ebe1d17SDwaipayan Ray my %attr_list = ( 65670830aab0SJoe Perches "alias" => "__alias", 65687ebe1d17SDwaipayan Ray "aligned" => "__aligned", 65697ebe1d17SDwaipayan Ray "always_inline" => "__always_inline", 65707ebe1d17SDwaipayan Ray "assume_aligned" => "__assume_aligned", 65717ebe1d17SDwaipayan Ray "cold" => "__cold", 65727ebe1d17SDwaipayan Ray "const" => "__attribute_const__", 65737ebe1d17SDwaipayan Ray "copy" => "__copy", 65747ebe1d17SDwaipayan Ray "designated_init" => "__designated_init", 65757ebe1d17SDwaipayan Ray "externally_visible" => "__visible", 65767ebe1d17SDwaipayan Ray "format" => "printf|scanf", 65777ebe1d17SDwaipayan Ray "gnu_inline" => "__gnu_inline", 65787ebe1d17SDwaipayan Ray "malloc" => "__malloc", 65797ebe1d17SDwaipayan Ray "mode" => "__mode", 65807ebe1d17SDwaipayan Ray "no_caller_saved_registers" => "__no_caller_saved_registers", 65817ebe1d17SDwaipayan Ray "noclone" => "__noclone", 65827ebe1d17SDwaipayan Ray "noinline" => "noinline", 65837ebe1d17SDwaipayan Ray "nonstring" => "__nonstring", 65847ebe1d17SDwaipayan Ray "noreturn" => "__noreturn", 65857ebe1d17SDwaipayan Ray "packed" => "__packed", 65867ebe1d17SDwaipayan Ray "pure" => "__pure", 6587339f29d9SJoe Perches "section" => "__section", 65880830aab0SJoe Perches "used" => "__used", 65890830aab0SJoe Perches "weak" => "__weak" 65907ebe1d17SDwaipayan Ray ); 65917ebe1d17SDwaipayan Ray 65927ebe1d17SDwaipayan Ray while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { 6593339f29d9SJoe Perches my $orig_attr = $1; 65947ebe1d17SDwaipayan Ray my $params = ''; 65957ebe1d17SDwaipayan Ray $params = $2 if defined($2); 6596339f29d9SJoe Perches my $curr_attr = $orig_attr; 65977ebe1d17SDwaipayan Ray $curr_attr =~ s/^[\s_]+|[\s_]+$//g; 65987ebe1d17SDwaipayan Ray if (exists($attr_list{$curr_attr})) { 6599339f29d9SJoe Perches my $new = $attr_list{$curr_attr}; 66007ebe1d17SDwaipayan Ray if ($curr_attr eq "format" && $params) { 66017ebe1d17SDwaipayan Ray $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; 6602339f29d9SJoe Perches $new = "__$1\($2"; 66037ebe1d17SDwaipayan Ray } else { 6604339f29d9SJoe Perches $new = "$new$params"; 66057ebe1d17SDwaipayan Ray } 66067ebe1d17SDwaipayan Ray if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 6607339f29d9SJoe Perches "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && 66087ebe1d17SDwaipayan Ray $fix) { 6609339f29d9SJoe Perches my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; 6610339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/$remove//; 6611339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; 6612339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; 6613339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; 66147ebe1d17SDwaipayan Ray } 661539b7e287SJoe Perches } 6616462811d9SJoe Perches } 6617462811d9SJoe Perches 66187ebe1d17SDwaipayan Ray # Check for __attribute__ unused, prefer __always_unused or __maybe_unused 66197ebe1d17SDwaipayan Ray if ($attr =~ /^_*unused/) { 66207ebe1d17SDwaipayan Ray WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 66217ebe1d17SDwaipayan Ray "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); 6622d5e616fcSJoe Perches } 66236061d949SJoe Perches } 66246061d949SJoe Perches 6625619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 66265b57980dSJoe Perches if ($perl_version_ok && 6627619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 6628619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 6629619a908aSJoe Perches $line =~ /\b__weak\b/)) { 6630619a908aSJoe Perches ERROR("WEAK_DECLARATION", 6631619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 6632619a908aSJoe Perches } 6633619a908aSJoe Perches 6634fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 6635e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6636fd39f904STomas Winkler $realfile !~ m@\btools/@ && 6637e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 6638e6176fa4SJoe Perches my $type = $1; 6639e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 6640e6176fa4SJoe Perches $type = $1; 6641e6176fa4SJoe Perches my $kernel_type = 'u'; 6642e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6643e6176fa4SJoe Perches $type =~ /(\d+)/; 6644e6176fa4SJoe Perches $kernel_type .= $1; 6645e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6646e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6647e6176fa4SJoe Perches $fix) { 6648e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6649e6176fa4SJoe Perches } 6650e6176fa4SJoe Perches } 6651e6176fa4SJoe Perches } 6652e6176fa4SJoe Perches 6653938224b5SJoe Perches# check for cast of C90 native int or longer types constants 6654938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6655938224b5SJoe Perches my $cast = $1; 6656938224b5SJoe Perches my $const = $2; 6657938224b5SJoe Perches my $suffix = ""; 6658938224b5SJoe Perches my $newconst = $const; 6659938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 6660938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6661938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6662938224b5SJoe Perches $suffix .= 'LL'; 6663938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 6664938224b5SJoe Perches $suffix .= 'L'; 6665938224b5SJoe Perches } 66660972b8bfSJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 66670972b8bfSJoe Perches "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) && 66680972b8bfSJoe Perches $fix) { 6669938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6670938224b5SJoe Perches } 6671938224b5SJoe Perches } 6672938224b5SJoe Perches 66738f53a9b8SJoe Perches# check for sizeof(&) 66748f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6675000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 6676000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 66778f53a9b8SJoe Perches } 66788f53a9b8SJoe Perches 667966c80b60SJoe Perches# check for sizeof without parenthesis 668066c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 6681d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 6682d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6683d5e616fcSJoe Perches $fix) { 6684194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6685d5e616fcSJoe Perches } 668666c80b60SJoe Perches } 668766c80b60SJoe Perches 668888982feaSJoe Perches# check for struct spinlock declarations 668988982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 669088982feaSJoe Perches WARN("USE_SPINLOCK_T", 669188982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 669288982feaSJoe Perches } 669388982feaSJoe Perches 6694a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 669506668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6696a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 6697caac1d5fSHeba Aamer $fmt =~ s/%%//g; 6698caac1d5fSHeba Aamer if ($fmt !~ /%/) { 6699d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 6700d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6701d5e616fcSJoe Perches $fix) { 6702194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6703d5e616fcSJoe Perches } 6704a6962d72SJoe Perches } 6705a6962d72SJoe Perches } 6706a6962d72SJoe Perches 67070b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 67085b57980dSJoe Perches if ($perl_version_ok && 67090b523769SJoe Perches defined $stat && 67100b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 67110b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6712e3c6bc95STobin C. Harding my $stat_real; 6713e3c6bc95STobin C. Harding 67140b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 67150b523769SJoe Perches $lc = $lc + $linenr; 67160b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6717ffe07513SJoe Perches my $specifier; 6718ffe07513SJoe Perches my $extension; 67193bd32d6aSSakari Ailus my $qualifier; 6720ffe07513SJoe Perches my $bad_specifier = ""; 67210b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 67220b523769SJoe Perches $fmt =~ s/%%//g; 6723e3c6bc95STobin C. Harding 67243bd32d6aSSakari Ailus while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 6725e3c6bc95STobin C. Harding $specifier = $1; 6726e3c6bc95STobin C. Harding $extension = $2; 67273bd32d6aSSakari Ailus $qualifier = $3; 6728af612e43SSakari Ailus if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 67293bd32d6aSSakari Ailus ($extension eq "f" && 6730af612e43SSakari Ailus defined $qualifier && $qualifier !~ /^w/) || 6731af612e43SSakari Ailus ($extension eq "4" && 6732af612e43SSakari Ailus defined $qualifier && $qualifier !~ /^cc/)) { 6733e3c6bc95STobin C. Harding $bad_specifier = $specifier; 67340b523769SJoe Perches last; 67350b523769SJoe Perches } 6736e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6737e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6738e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 67390b523769SJoe Perches } 6740e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6741e3c6bc95STobin 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"); 6742e3c6bc95STobin C. Harding } 6743e3c6bc95STobin C. Harding } 6744e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 67452a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 67461df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 67471df7338aSSergey Senozhatsky my $use = ""; 6748e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 67491df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6750e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 67511df7338aSSergey Senozhatsky } 67522a9f9d85STobin C. Harding 67530b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 6754e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6755e3c6bc95STobin C. Harding } 67560b523769SJoe Perches } 67570b523769SJoe Perches } 67580b523769SJoe Perches 6759554e165cSAndy Whitcroft# Check for misused memsets 67605b57980dSJoe Perches if ($perl_version_ok && 6761d1fe9c09SJoe Perches defined $stat && 67629e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6763554e165cSAndy Whitcroft 6764d7c76ba7SJoe Perches my $ms_addr = $2; 6765d1fe9c09SJoe Perches my $ms_val = $7; 6766d1fe9c09SJoe Perches my $ms_size = $12; 6767d7c76ba7SJoe Perches 6768554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6769554e165cSAndy Whitcroft ERROR("MEMSET", 6770d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6771554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6772554e165cSAndy Whitcroft WARN("MEMSET", 6773d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6774d7c76ba7SJoe Perches } 6775d7c76ba7SJoe Perches } 6776d7c76ba7SJoe Perches 677798a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 67785b57980dSJoe Perches# if ($perl_version_ok && 6779f333195dSJoe Perches# defined $stat && 6780f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6781f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6782f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6783f333195dSJoe Perches# $fix) { 6784f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6785f333195dSJoe Perches# } 6786f333195dSJoe Perches# } 678798a9bba5SJoe Perches 6788b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 67895b57980dSJoe Perches# if ($perl_version_ok && 6790f333195dSJoe Perches# defined $stat && 6791f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6792f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6793f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6794f333195dSJoe Perches# } 6795b6117d17SMateusz Kulikowski 67968617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 67978617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 67985b57980dSJoe Perches# if ($perl_version_ok && 6799f333195dSJoe Perches# defined $stat && 6800f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6801f333195dSJoe Perches# 6802f333195dSJoe Perches# my $ms_val = $7; 6803f333195dSJoe Perches# 6804f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6805f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6806f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6807f333195dSJoe Perches# $fix) { 6808f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6809f333195dSJoe Perches# } 6810f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6811f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6812f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6813f333195dSJoe Perches# $fix) { 6814f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6815f333195dSJoe Perches# } 6816f333195dSJoe Perches# } 6817f333195dSJoe Perches# } 68188617cd09SMateusz Kulikowski 68195dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy 68205dbdb2d8SJoe Perches if ($line =~ /\bstrlcpy\s*\(/) { 68215dbdb2d8SJoe Perches WARN("STRLCPY", 68225dbdb2d8SJoe Perches "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr); 68235dbdb2d8SJoe Perches } 68245dbdb2d8SJoe Perches 6825d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 68265b57980dSJoe Perches if ($perl_version_ok && 6827d1fe9c09SJoe Perches defined $stat && 6828d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6829d1fe9c09SJoe Perches if (defined $2 || defined $7) { 6830d7c76ba7SJoe Perches my $call = $1; 6831d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 6832d7c76ba7SJoe Perches my $arg1 = $3; 6833d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 6834d1fe9c09SJoe Perches my $arg2 = $8; 6835d7c76ba7SJoe Perches my $cast; 6836d7c76ba7SJoe Perches 6837d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 6838d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 6839d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 6840d7c76ba7SJoe Perches $cast = $cast1; 6841d7c76ba7SJoe Perches } else { 6842d7c76ba7SJoe Perches $cast = $cast2; 6843d7c76ba7SJoe Perches } 6844d7c76ba7SJoe Perches WARN("MINMAX", 6845d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 6846554e165cSAndy Whitcroft } 6847554e165cSAndy Whitcroft } 6848554e165cSAndy Whitcroft 68494a273195SJoe Perches# check usleep_range arguments 68505b57980dSJoe Perches if ($perl_version_ok && 68514a273195SJoe Perches defined $stat && 68524a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 68534a273195SJoe Perches my $min = $1; 68544a273195SJoe Perches my $max = $7; 68554a273195SJoe Perches if ($min eq $max) { 68564a273195SJoe Perches WARN("USLEEP_RANGE", 6857458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 68584a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 68594a273195SJoe Perches $min > $max) { 68604a273195SJoe Perches WARN("USLEEP_RANGE", 6861458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 68624a273195SJoe Perches } 68634a273195SJoe Perches } 68644a273195SJoe Perches 6865823b794cSJoe Perches# check for naked sscanf 68665b57980dSJoe Perches if ($perl_version_ok && 6867823b794cSJoe Perches defined $stat && 68686c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 6869823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6870823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 6871823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6872823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 6873823b794cSJoe Perches $lc = $lc + $linenr; 68742a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6875823b794cSJoe Perches WARN("NAKED_SSCANF", 6876823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6877823b794cSJoe Perches } 6878823b794cSJoe Perches 6879afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 68805b57980dSJoe Perches if ($perl_version_ok && 6881afc819abSJoe Perches defined $stat && 6882afc819abSJoe Perches $line =~ /\bsscanf\b/) { 6883afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 6884afc819abSJoe Perches $lc = $lc + $linenr; 68852a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6886afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6887afc819abSJoe Perches my $format = $6; 6888afc819abSJoe Perches my $count = $format =~ tr@%@%@; 6889afc819abSJoe Perches if ($count == 1 && 6890afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 6891afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 6892afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 6893afc819abSJoe Perches } 6894afc819abSJoe Perches } 6895afc819abSJoe Perches } 6896afc819abSJoe Perches 689770dc8a48SJoe Perches# check for new externs in .h files. 689870dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 689970dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 6900d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 690170dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 690270dc8a48SJoe Perches $fix) { 6903194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 690470dc8a48SJoe Perches } 690570dc8a48SJoe Perches } 690670dc8a48SJoe Perches 6907de7d4f0eSAndy Whitcroft# check for new externs in .c files. 6908171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 6909c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 6910171ae1a4SAndy Whitcroft { 6911c45dcabdSAndy Whitcroft my $function_name = $1; 6912c45dcabdSAndy Whitcroft my $paren_space = $2; 6913171ae1a4SAndy Whitcroft 6914171ae1a4SAndy Whitcroft my $s = $stat; 6915171ae1a4SAndy Whitcroft if (defined $cond) { 6916171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 6917171ae1a4SAndy Whitcroft } 6918d8b44b58SKees Cook if ($s =~ /^\s*;/) 6919c45dcabdSAndy Whitcroft { 6920000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6921000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6922de7d4f0eSAndy Whitcroft } 6923de7d4f0eSAndy Whitcroft 6924171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 6925000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 6926000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 6927171ae1a4SAndy Whitcroft } 69289c9ba34eSAndy Whitcroft 69299c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 69309c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 69319c9ba34eSAndy Whitcroft { 6932000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6933000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6934171ae1a4SAndy Whitcroft } 6935171ae1a4SAndy Whitcroft 6936a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 6937a0ad7596SJoe Perches if (defined $stat && 6938d8b44b58SKees Cook $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 6939d8b44b58SKees Cook $1 ne "void") { 6940d8b44b58SKees Cook my $args = trim($1); 6941ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 6942ca0d8929SJoe Perches my $arg = trim($1); 6943d8b44b58SKees Cook if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 6944ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 6945ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 6946ca0d8929SJoe Perches } 6947ca0d8929SJoe Perches } 6948ca0d8929SJoe Perches } 6949ca0d8929SJoe Perches 6950a0ad7596SJoe Perches# check for function definitions 69515b57980dSJoe Perches if ($perl_version_ok && 6952a0ad7596SJoe Perches defined $stat && 6953a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 6954a0ad7596SJoe Perches $context_function = $1; 6955a0ad7596SJoe Perches 6956a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 6957a0ad7596SJoe Perches my $ok = 0; 6958a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 6959a0ad7596SJoe Perches my $herectx = $here . "\n"; 6960a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6961a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 6962a0ad7596SJoe Perches $herectx .= $rl . "\n"; 6963a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 6964a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 6965a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 6966a0ad7596SJoe Perches } 6967a0ad7596SJoe Perches if (!$ok) { 6968a0ad7596SJoe Perches ERROR("OPEN_BRACE", 6969a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 6970a0ad7596SJoe Perches } 6971a0ad7596SJoe Perches } 6972a0ad7596SJoe Perches 6973de7d4f0eSAndy Whitcroft# checks for new __setup's 6974de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 6975de7d4f0eSAndy Whitcroft my $name = $1; 6976de7d4f0eSAndy Whitcroft 6977de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 6978000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 69792581ac7cSTim Froidcoeur "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); 6980de7d4f0eSAndy Whitcroft } 6981653d4876SAndy Whitcroft } 69829c0ca6f9SAndy Whitcroft 6983e29a70f1SJoe Perches# check for pointless casting of alloc functions 6984e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 6985000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 6986000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 69879c0ca6f9SAndy Whitcroft } 698813214adfSAndy Whitcroft 6989a640d25cSJoe Perches# alloc style 6990a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 69915b57980dSJoe Perches if ($perl_version_ok && 6992e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 6993a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 6994a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 6995a640d25cSJoe Perches } 6996a640d25cSJoe Perches 699760a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 69985b57980dSJoe Perches if ($perl_version_ok && 69991b4a2ed4SJoe Perches defined $stat && 70001b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 700160a55369SJoe Perches my $oldfunc = $3; 700260a55369SJoe Perches my $a1 = $4; 700360a55369SJoe Perches my $a2 = $10; 700460a55369SJoe Perches my $newfunc = "kmalloc_array"; 700560a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 700660a55369SJoe Perches my $r1 = $a1; 700760a55369SJoe Perches my $r2 = $a2; 700860a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 700960a55369SJoe Perches $r1 = $a2; 701060a55369SJoe Perches $r2 = $a1; 701160a55369SJoe Perches } 7012e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 7013e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 70141b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 7015e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 7016e3d95a2aSTobin C. Harding 7017e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 70181b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 70191b4a2ed4SJoe Perches $cnt == 1 && 7020e367455aSJoe Perches $fix) { 7021194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; 702260a55369SJoe Perches } 702360a55369SJoe Perches } 702460a55369SJoe Perches } 702560a55369SJoe Perches 7026972fdea2SJoe Perches# check for krealloc arg reuse 70275b57980dSJoe Perches if ($perl_version_ok && 70284cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 70294cab63ceSJoe Perches $1 eq $3) { 7030972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 7031972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 7032972fdea2SJoe Perches } 7033972fdea2SJoe Perches 70345ce59ae0SJoe Perches# check for alloc argument mismatch 70357e6cdd7fSChristophe JAILLET if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) { 70365ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 70375ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 70385ce59ae0SJoe Perches } 70395ce59ae0SJoe Perches 7040caf2a54fSJoe Perches# check for multiple semicolons 7041caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 7042d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 7043d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 7044d5e616fcSJoe Perches $fix) { 7045194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 7046d5e616fcSJoe Perches } 7047d1e2ad07SJoe Perches } 7048d1e2ad07SJoe Perches 7049cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 7050cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 7051cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 70520ab90191SJoe Perches my $ull = ""; 70530ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 70540ab90191SJoe Perches if (CHK("BIT_MACRO", 70550ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 70560ab90191SJoe Perches $fix) { 70570ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 70580ab90191SJoe Perches } 70590ab90191SJoe Perches } 70600ab90191SJoe Perches 706150161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) 70623e89ad85SJerome Forissier if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { 706350161266SJoe Perches WARN("IS_ENABLED_CONFIG", 70643e89ad85SJerome Forissier "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); 706550161266SJoe Perches } 706650161266SJoe Perches 70672d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 70683e89ad85SJerome 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*$/) { 70692d632745SJoe Perches my $config = $1; 70702d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 70713e89ad85SJerome Forissier "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && 70722d632745SJoe Perches $fix) { 70732d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 70742d632745SJoe Perches } 70752d632745SJoe Perches } 70762d632745SJoe Perches 7077f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 7078f36d3eb8SJoe Perches my @fallthroughs = ( 7079f36d3eb8SJoe Perches 'fallthrough', 7080f36d3eb8SJoe Perches '@fallthrough@', 7081f36d3eb8SJoe Perches 'lint -fallthrough[ \t]*', 7082f36d3eb8SJoe Perches 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 7083f36d3eb8SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 7084f36d3eb8SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 7085f36d3eb8SJoe Perches 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 7086f36d3eb8SJoe Perches ); 7087f36d3eb8SJoe Perches if ($raw_comment ne '') { 7088f36d3eb8SJoe Perches foreach my $ft (@fallthroughs) { 7089f36d3eb8SJoe Perches if ($raw_comment =~ /$ft/) { 7090f36d3eb8SJoe Perches my $msg_level = \&WARN; 7091f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 7092f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 7093f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 7094f36d3eb8SJoe Perches last; 7095f36d3eb8SJoe Perches } 7096f36d3eb8SJoe Perches } 7097f36d3eb8SJoe Perches } 7098f36d3eb8SJoe Perches 7099d1e2ad07SJoe Perches# check for switch/default statements without a break; 71005b57980dSJoe Perches if ($perl_version_ok && 7101d1e2ad07SJoe Perches defined $stat && 7102d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 7103d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 7104e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 7105e3d95a2aSTobin C. Harding 7106d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 7107d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 7108caf2a54fSJoe Perches } 7109caf2a54fSJoe Perches 711013214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 7111d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 7112d5e616fcSJoe Perches if (WARN("USE_FUNC", 7113d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 7114d5e616fcSJoe Perches $fix) { 7115194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 7116d5e616fcSJoe Perches } 711713214adfSAndy Whitcroft } 7118773647a0SAndy Whitcroft 711962ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 712062ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 712162ec818fSJoe Perches ERROR("DATE_TIME", 712262ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 712362ec818fSJoe Perches } 712462ec818fSJoe Perches 71252c92488aSJoe Perches# check for use of yield() 71262c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 71272c92488aSJoe Perches WARN("YIELD", 71282c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 71292c92488aSJoe Perches } 71302c92488aSJoe Perches 7131179f8f40SJoe Perches# check for comparisons against true and false 7132179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 7133179f8f40SJoe Perches my $lead = $1; 7134179f8f40SJoe Perches my $arg = $2; 7135179f8f40SJoe Perches my $test = $3; 7136179f8f40SJoe Perches my $otype = $4; 7137179f8f40SJoe Perches my $trail = $5; 7138179f8f40SJoe Perches my $op = "!"; 7139179f8f40SJoe Perches 7140179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 7141179f8f40SJoe Perches 7142179f8f40SJoe Perches my $type = lc($otype); 7143179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 7144179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 7145179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 7146179f8f40SJoe Perches $op = ""; 7147179f8f40SJoe Perches } 7148179f8f40SJoe Perches 7149179f8f40SJoe Perches CHK("BOOL_COMPARISON", 7150179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 7151179f8f40SJoe Perches 7152179f8f40SJoe Perches## maybe suggesting a correct construct would better 7153179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 7154179f8f40SJoe Perches 7155179f8f40SJoe Perches } 7156179f8f40SJoe Perches } 7157179f8f40SJoe Perches 71584882720bSThomas Gleixner# check for semaphores initialized locked 71594882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 7160000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 7161000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 7162773647a0SAndy Whitcroft } 71636712d858SJoe Perches 716467d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 716567d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 7166000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 716767d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 7168773647a0SAndy Whitcroft } 71696712d858SJoe Perches 7170ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 7171f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 7172000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 7173ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 7174f3db6639SMichael Ellerman } 71756712d858SJoe Perches 71763d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 71773d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 71783d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 71793d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 71803d709ab5SPaul E. McKenney } 71813d709ab5SPaul E. McKenney 71829189c7e7SJoe Perches# check for deprecated apis 71839189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 71849189c7e7SJoe Perches my $deprecated_api = $1; 71859189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 71869189c7e7SJoe Perches WARN("DEPRECATED_API", 71879189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 71889189c7e7SJoe Perches } 71899189c7e7SJoe Perches 71900f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 7191d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 7192ced69da1SQuentin Monnet if (defined($const_structs) && 7193ced69da1SQuentin Monnet $line !~ /\bconst\b/ && 7194d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 7195000d1cc1SJoe Perches WARN("CONST_STRUCT", 7196d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 71972b6db5cbSAndy Whitcroft } 7198773647a0SAndy Whitcroft 7199773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 7200773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 720135cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS 7202773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 7203c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 7204c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 7205171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 7206171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 720735cdcbfcSPeng Wang $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ && 720835cdcbfcSPeng Wang $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/) 7209773647a0SAndy Whitcroft { 7210000d1cc1SJoe Perches WARN("NR_CPUS", 7211000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 7212773647a0SAndy Whitcroft } 72139c9ba34eSAndy Whitcroft 721452ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 721552ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 721652ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 721752ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 721852ea8506SJoe Perches } 721952ea8506SJoe Perches 7220acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 72215b57980dSJoe Perches if ($perl_version_ok && 7222acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 7223acd9362cSJoe Perches WARN("LIKELY_MISUSE", 7224acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 7225acd9362cSJoe Perches } 7226acd9362cSJoe Perches 7227fbe74541SJoe Perches# return sysfs_emit(foo, fmt, ...) fmt without newline 7228fbe74541SJoe Perches if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ && 7229fbe74541SJoe Perches substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) { 7230fbe74541SJoe Perches my $offset = $+[6] - 1; 7231fbe74541SJoe Perches if (WARN("SYSFS_EMIT", 7232fbe74541SJoe Perches "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) && 7233fbe74541SJoe Perches $fix) { 7234fbe74541SJoe Perches substr($fixed[$fixlinenr], $offset, 0) = '\\n'; 7235fbe74541SJoe Perches } 7236fbe74541SJoe Perches } 7237fbe74541SJoe Perches 7238de3f186fSDenis Efremov# nested likely/unlikely calls 7239de3f186fSDenis Efremov if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 7240de3f186fSDenis Efremov WARN("LIKELY_MISUSE", 7241de3f186fSDenis Efremov "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 7242de3f186fSDenis Efremov } 7243de3f186fSDenis Efremov 7244691d77b6SAndy Whitcroft# whine mightly about in_atomic 7245691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 7246691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 7247000d1cc1SJoe Perches ERROR("IN_ATOMIC", 7248000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 7249f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 7250000d1cc1SJoe Perches WARN("IN_ATOMIC", 7251000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 7252691d77b6SAndy Whitcroft } 7253691d77b6SAndy Whitcroft } 72541704f47bSPeter Zijlstra 72551704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 72561704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 72571704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 72581704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 72591704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 72601704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 7261000d1cc1SJoe Perches ERROR("LOCKDEP", 7262000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 72631704f47bSPeter Zijlstra } 72641704f47bSPeter Zijlstra } 726588f8831cSDave Jones 7266b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 7267b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 7268000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 7269000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 727088f8831cSDave Jones } 72712435880fSJoe Perches 727200180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 727300180468SJoe Perches# and whether or not function naming is typical and if 727400180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 72755b57980dSJoe Perches if ($perl_version_ok && 727600180468SJoe Perches defined $stat && 727700180468SJoe 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*\)/) { 727800180468SJoe Perches my $var = $1; 727900180468SJoe Perches my $perms = $2; 728000180468SJoe Perches my $show = $3; 728100180468SJoe Perches my $store = $4; 728200180468SJoe Perches my $octal_perms = perms_to_octal($perms); 728300180468SJoe Perches if ($show =~ /^${var}_show$/ && 728400180468SJoe Perches $store =~ /^${var}_store$/ && 728500180468SJoe Perches $octal_perms eq "0644") { 728600180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 728700180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 728800180468SJoe Perches $fix) { 728900180468SJoe 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})/; 729000180468SJoe Perches } 729100180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 729200180468SJoe Perches $store =~ /^NULL$/ && 729300180468SJoe Perches $octal_perms eq "0444") { 729400180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 729500180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 729600180468SJoe Perches $fix) { 729700180468SJoe 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})/; 729800180468SJoe Perches } 729900180468SJoe Perches } elsif ($show =~ /^NULL$/ && 730000180468SJoe Perches $store =~ /^${var}_store$/ && 730100180468SJoe Perches $octal_perms eq "0200") { 730200180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 730300180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 730400180468SJoe Perches $fix) { 730500180468SJoe 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})/; 730600180468SJoe Perches } 730700180468SJoe Perches } elsif ($octal_perms eq "0644" || 730800180468SJoe Perches $octal_perms eq "0444" || 730900180468SJoe Perches $octal_perms eq "0200") { 731000180468SJoe Perches my $newshow = "$show"; 731100180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 731200180468SJoe Perches my $newstore = $store; 731300180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 731400180468SJoe Perches my $rename = ""; 731500180468SJoe Perches if ($show ne $newshow) { 731600180468SJoe Perches $rename .= " '$show' to '$newshow'"; 731700180468SJoe Perches } 731800180468SJoe Perches if ($store ne $newstore) { 731900180468SJoe Perches $rename .= " '$store' to '$newstore'"; 732000180468SJoe Perches } 732100180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 732200180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 732300180468SJoe Perches } else { 732400180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 732500180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 732600180468SJoe Perches } 732700180468SJoe Perches } 732800180468SJoe Perches 7329515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 7330515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 733173121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 733273121534SJoe Perches# specific definition of not visible in sysfs. 733373121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 733473121534SJoe Perches# use the default permissions 73355b57980dSJoe Perches if ($perl_version_ok && 7336459cf0aeSJoe Perches defined $stat && 7337515a235eSJoe Perches $line =~ /$mode_perms_search/) { 73382435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 73392435880fSJoe Perches my $func = $entry->[0]; 73402435880fSJoe Perches my $arg_pos = $entry->[1]; 73412435880fSJoe Perches 7342459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 7343459cf0aeSJoe Perches $lc = $lc + $linenr; 73442a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 7345459cf0aeSJoe Perches 73462435880fSJoe Perches my $skip_args = ""; 73472435880fSJoe Perches if ($arg_pos > 1) { 73482435880fSJoe Perches $arg_pos--; 73492435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 73502435880fSJoe Perches } 7351f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 7352459cf0aeSJoe Perches if ($stat =~ /$test/) { 73532435880fSJoe Perches my $val = $1; 73542435880fSJoe Perches $val = $6 if ($skip_args ne ""); 735573121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 735673121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 735773121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 73582435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 7359459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 7360f90774e1SJoe Perches } 7361f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 7362c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 7363459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 73642435880fSJoe Perches } 7365459cf0aeSJoe Perches } 7366459cf0aeSJoe Perches } 7367459cf0aeSJoe Perches } 7368459cf0aeSJoe Perches 7369459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 7370bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 737100180468SJoe Perches my $oval = $1; 737200180468SJoe Perches my $octal = perms_to_octal($oval); 7373f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 7374459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 7375f90774e1SJoe Perches $fix) { 737600180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 73772435880fSJoe Perches } 737813214adfSAndy Whitcroft } 73795a6d20ceSBjorn Andersson 73805a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 73815a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 73825a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 73835a6d20ceSBjorn Andersson my $valid_licenses = qr{ 73845a6d20ceSBjorn Andersson GPL| 73855a6d20ceSBjorn Andersson GPL\ v2| 73865a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 73875a6d20ceSBjorn Andersson Dual\ BSD/GPL| 73885a6d20ceSBjorn Andersson Dual\ MIT/GPL| 73895a6d20ceSBjorn Andersson Dual\ MPL/GPL| 73905a6d20ceSBjorn Andersson Proprietary 73915a6d20ceSBjorn Andersson }x; 73925a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 73935a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 73945a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 73955a6d20ceSBjorn Andersson } 73965a6d20ceSBjorn Andersson } 73976a8d76cbSMatteo Croce 73986a8d76cbSMatteo Croce# check for sysctl duplicate constants 73996a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 74006a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 74016a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 74026a8d76cbSMatteo Croce } 7403515a235eSJoe Perches } 740413214adfSAndy Whitcroft 740513214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 740613214adfSAndy Whitcroft # so just keep quiet. 740713214adfSAndy Whitcroft if ($#rawlines == -1) { 740813214adfSAndy Whitcroft exit(0); 74090a920b5bSAndy Whitcroft } 74100a920b5bSAndy Whitcroft 74118905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 74128905a67cSAndy Whitcroft # things that appear to be patches. 74138905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 74148905a67cSAndy Whitcroft exit(0); 74158905a67cSAndy Whitcroft } 74168905a67cSAndy Whitcroft 7417e73d2715SDwaipayan Ray # This is not a patch, and we are in 'no-patch' mode so 74188905a67cSAndy Whitcroft # just keep quiet. 74198905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 74208905a67cSAndy Whitcroft exit(0); 74218905a67cSAndy Whitcroft } 74228905a67cSAndy Whitcroft 7423a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 7424000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 7425000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 74260a920b5bSAndy Whitcroft } 7427cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 7428cd261496SGeert Uytterhoeven if ($signoff == 0) { 7429000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 7430000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 743148ca2d8aSDwaipayan Ray } elsif ($authorsignoff != 1) { 743248ca2d8aSDwaipayan Ray # authorsignoff values: 743348ca2d8aSDwaipayan Ray # 0 -> missing sign off 743448ca2d8aSDwaipayan Ray # 1 -> sign off identical 743548ca2d8aSDwaipayan Ray # 2 -> names and addresses match, comments mismatch 743648ca2d8aSDwaipayan Ray # 3 -> addresses match, names different 743748ca2d8aSDwaipayan Ray # 4 -> names match, addresses different 743848ca2d8aSDwaipayan Ray # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match 743948ca2d8aSDwaipayan Ray 744048ca2d8aSDwaipayan Ray my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; 744148ca2d8aSDwaipayan Ray 744248ca2d8aSDwaipayan Ray if ($authorsignoff == 0) { 744348ca2d8aSDwaipayan Ray ERROR("NO_AUTHOR_SIGN_OFF", 7444cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 744548ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 2) { 744648ca2d8aSDwaipayan Ray CHK("FROM_SIGN_OFF_MISMATCH", 744748ca2d8aSDwaipayan Ray "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); 744848ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 3) { 744948ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 745048ca2d8aSDwaipayan Ray "From:/Signed-off-by: email name mismatch: $sob_msg\n"); 745148ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 4) { 745248ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 745348ca2d8aSDwaipayan Ray "From:/Signed-off-by: email address mismatch: $sob_msg\n"); 745448ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 5) { 745548ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 745648ca2d8aSDwaipayan Ray "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); 745748ca2d8aSDwaipayan Ray } 7458cd261496SGeert Uytterhoeven } 74590a920b5bSAndy Whitcroft } 74600a920b5bSAndy Whitcroft 7461f0a594c1SAndy Whitcroft print report_dump(); 746213214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 746313214adfSAndy Whitcroft print "$filename " if ($summary_file); 74646c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 74656c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 74666c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 74676c72ffaaSAndy Whitcroft } 74688905a67cSAndy Whitcroft 7469d2c0a235SAndy Whitcroft if ($quiet == 0) { 7470ef212196SJoe Perches # If there were any defects found and not already fixing them 7471ef212196SJoe Perches if (!$clean and !$fix) { 7472ef212196SJoe Perches print << "EOM" 7473ef212196SJoe Perches 7474ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 7475ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 7476ef212196SJoe PerchesEOM 7477ef212196SJoe Perches } 7478d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 7479d2c0a235SAndy Whitcroft # then suggest that. 7480d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 7481b0781216SMike Frysinger $rpt_cleaners = 0; 7482d8469f16SJoe Perches print << "EOM" 7483d8469f16SJoe Perches 7484d8469f16SJoe PerchesNOTE: Whitespace errors detected. 7485d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 7486d8469f16SJoe PerchesEOM 7487d2c0a235SAndy Whitcroft } 7488d2c0a235SAndy Whitcroft } 7489d2c0a235SAndy Whitcroft 7490d752fcc8SJoe Perches if ($clean == 0 && $fix && 7491d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 7492d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 74939624b8d6SJoe Perches my $newfile = $filename; 74949624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 74953705ce5bSJoe Perches my $linecount = 0; 74963705ce5bSJoe Perches my $f; 74973705ce5bSJoe Perches 7498d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 7499d752fcc8SJoe Perches 75003705ce5bSJoe Perches open($f, '>', $newfile) 75013705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 75023705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 75033705ce5bSJoe Perches $linecount++; 75043705ce5bSJoe Perches if ($file) { 75053705ce5bSJoe Perches if ($linecount > 3) { 75063705ce5bSJoe Perches $fixed_line =~ s/^\+//; 75073705ce5bSJoe Perches print $f $fixed_line . "\n"; 75083705ce5bSJoe Perches } 75093705ce5bSJoe Perches } else { 75103705ce5bSJoe Perches print $f $fixed_line . "\n"; 75113705ce5bSJoe Perches } 75123705ce5bSJoe Perches } 75133705ce5bSJoe Perches close($f); 75143705ce5bSJoe Perches 75153705ce5bSJoe Perches if (!$quiet) { 75163705ce5bSJoe Perches print << "EOM"; 7517d8469f16SJoe Perches 75183705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 75193705ce5bSJoe Perches 75203705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 75213705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 75223705ce5bSJoe Perches 75233705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 75243705ce5bSJoe PerchesNo warranties, expressed or implied... 75253705ce5bSJoe PerchesEOM 75263705ce5bSJoe Perches } 75273705ce5bSJoe Perches } 75283705ce5bSJoe Perches 7529d8469f16SJoe Perches if ($quiet == 0) { 7530d8469f16SJoe Perches print "\n"; 7531d8469f16SJoe Perches if ($clean == 1) { 7532d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 7533d8469f16SJoe Perches } else { 7534d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 75350a920b5bSAndy Whitcroft } 75360a920b5bSAndy Whitcroft } 75370a920b5bSAndy Whitcroft return $clean; 75380a920b5bSAndy Whitcroft} 7539