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| 4925fe3af11SAndy Whitcroft __weak 4936c72ffaaSAndy Whitcroft }x; 494c45dcabdSAndy Whitcroftour $Modifier; 49591cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 4966c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 4976c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 4986c72ffaaSAndy Whitcroft 49995e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 50095e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 50195e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 50295e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 5032435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 504d2af5aa6SJoe Perchesour $String = qr{(?:\b[Lu])?"[X\t]*"}; 505326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 506326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 507326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 50874349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 5092435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 510326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 511447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 51223f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 5136c72ffaaSAndy Whitcroftour $Operators = qr{ 5146c72ffaaSAndy Whitcroft <=|>=|==|!=| 5156c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 51623f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 5176c72ffaaSAndy Whitcroft }x; 5186c72ffaaSAndy Whitcroft 51991cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 52091cb5195SJoe Perches 521ab7e23f3SJoe Perchesour $BasicType; 5228905a67cSAndy Whitcroftour $NonptrType; 5231813087dSJoe Perchesour $NonptrTypeMisordered; 5248716de38SJoe Perchesour $NonptrTypeWithAttr; 5258905a67cSAndy Whitcroftour $Type; 5261813087dSJoe Perchesour $TypeMisordered; 5278905a67cSAndy Whitcroftour $Declare; 5281813087dSJoe Perchesour $DeclareMisordered; 5298905a67cSAndy Whitcroft 53015662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 53115662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 532171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 533171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 534171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 535171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 536171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 537171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 538171ae1a4SAndy Whitcroft}x; 539171ae1a4SAndy Whitcroft 54015662b3eSJoe Perchesour $UTF8 = qr{ 54115662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 54215662b3eSJoe Perches | $NON_ASCII_UTF8 54315662b3eSJoe Perches}x; 54415662b3eSJoe Perches 545e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 546021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 547021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 548021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 549021158b4SJoe Perches)}; 550e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 551fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 5528ed22cadSAndy Whitcroft atomic_t 5538ed22cadSAndy Whitcroft)}; 554e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 555e6176fa4SJoe Perches $typeC99Typedefs\b| 556e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 557e6176fa4SJoe Perches $typeKernelTypedefs\b 558e6176fa4SJoe Perches)}; 5598ed22cadSAndy Whitcroft 5606d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 5616d32f7a3SJoe Perches 562691e669bSJoe Perchesour $logFunctions = qr{(?x: 563758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 5647d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 56587bd499aSJoe Perches TP_printk| 5666e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 567b0531722SJoe Perches panic| 56806668727SJoe Perches MODULE_[A-Z_]+| 56906668727SJoe Perches seq_vprintf|seq_printf|seq_puts 570691e669bSJoe Perches)}; 571691e669bSJoe Perches 572e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 573e29a70f1SJoe Perches (?:(?:devm_)? 57458f02267SJoe Perches (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? | 575e29a70f1SJoe Perches kstrdup(?:_const)? | 576e29a70f1SJoe Perches kmemdup(?:_nul)?) | 577461e1565SChristophe JAILLET (?:\w+)?alloc_skb(?:_ip_align)? | 578e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 579e29a70f1SJoe Perches dma_alloc_coherent 580e29a70f1SJoe Perches)}; 581e29a70f1SJoe Perches 58220112475SJoe Perchesour $signature_tags = qr{(?xi: 58320112475SJoe Perches Signed-off-by:| 584d499480cSJorge Ramirez-Ortiz Co-developed-by:| 58520112475SJoe Perches Acked-by:| 58620112475SJoe Perches Tested-by:| 58720112475SJoe Perches Reviewed-by:| 58820112475SJoe Perches Reported-by:| 5898543ae12SMugunthan V N Suggested-by:| 59020112475SJoe Perches To:| 59120112475SJoe Perches Cc: 59220112475SJoe Perches)}; 59320112475SJoe Perches 594adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi: 595adb2da82SJoe Perches [=-]*> | 596adb2da82SJoe Perches <[=-]* | 597adb2da82SJoe Perches \[ | 598adb2da82SJoe Perches \] | 599adb2da82SJoe Perches start | 600adb2da82SJoe Perches called | 601adb2da82SJoe Perches entered | 602adb2da82SJoe Perches entry | 603adb2da82SJoe Perches enter | 604adb2da82SJoe Perches in | 605adb2da82SJoe Perches inside | 606adb2da82SJoe Perches here | 607adb2da82SJoe Perches begin | 608adb2da82SJoe Perches exit | 609adb2da82SJoe Perches end | 610adb2da82SJoe Perches done | 611adb2da82SJoe Perches leave | 612adb2da82SJoe Perches completed | 613adb2da82SJoe Perches out | 614adb2da82SJoe Perches return | 615adb2da82SJoe Perches [\.\!:\s]* 616adb2da82SJoe Perches)}; 617adb2da82SJoe Perches 618831242abSAditya Srivastavasub edit_distance_min { 619831242abSAditya Srivastava my (@arr) = @_; 620831242abSAditya Srivastava my $len = scalar @arr; 621831242abSAditya Srivastava if ((scalar @arr) < 1) { 622831242abSAditya Srivastava # if underflow, return 623831242abSAditya Srivastava return; 624831242abSAditya Srivastava } 625831242abSAditya Srivastava my $min = $arr[0]; 626831242abSAditya Srivastava for my $i (0 .. ($len-1)) { 627831242abSAditya Srivastava if ($arr[$i] < $min) { 628831242abSAditya Srivastava $min = $arr[$i]; 629831242abSAditya Srivastava } 630831242abSAditya Srivastava } 631831242abSAditya Srivastava return $min; 632831242abSAditya Srivastava} 633831242abSAditya Srivastava 634831242abSAditya Srivastavasub get_edit_distance { 635831242abSAditya Srivastava my ($str1, $str2) = @_; 636831242abSAditya Srivastava $str1 = lc($str1); 637831242abSAditya Srivastava $str2 = lc($str2); 638831242abSAditya Srivastava $str1 =~ s/-//g; 639831242abSAditya Srivastava $str2 =~ s/-//g; 640831242abSAditya Srivastava my $len1 = length($str1); 641831242abSAditya Srivastava my $len2 = length($str2); 642831242abSAditya Srivastava # two dimensional array storing minimum edit distance 643831242abSAditya Srivastava my @distance; 644831242abSAditya Srivastava for my $i (0 .. $len1) { 645831242abSAditya Srivastava for my $j (0 .. $len2) { 646831242abSAditya Srivastava if ($i == 0) { 647831242abSAditya Srivastava $distance[$i][$j] = $j; 648831242abSAditya Srivastava } elsif ($j == 0) { 649831242abSAditya Srivastava $distance[$i][$j] = $i; 650831242abSAditya Srivastava } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { 651831242abSAditya Srivastava $distance[$i][$j] = $distance[$i - 1][$j - 1]; 652831242abSAditya Srivastava } else { 653831242abSAditya Srivastava my $dist1 = $distance[$i][$j - 1]; #insert distance 654831242abSAditya Srivastava my $dist2 = $distance[$i - 1][$j]; # remove 655831242abSAditya Srivastava my $dist3 = $distance[$i - 1][$j - 1]; #replace 656831242abSAditya Srivastava $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); 657831242abSAditya Srivastava } 658831242abSAditya Srivastava } 659831242abSAditya Srivastava } 660831242abSAditya Srivastava return $distance[$len1][$len2]; 661831242abSAditya Srivastava} 662831242abSAditya Srivastava 663831242abSAditya Srivastavasub find_standard_signature { 664831242abSAditya Srivastava my ($sign_off) = @_; 665831242abSAditya Srivastava my @standard_signature_tags = ( 666831242abSAditya Srivastava 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', 667831242abSAditya Srivastava 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' 668831242abSAditya Srivastava ); 669831242abSAditya Srivastava foreach my $signature (@standard_signature_tags) { 670831242abSAditya Srivastava return $signature if (get_edit_distance($sign_off, $signature) <= 2); 671831242abSAditya Srivastava } 672831242abSAditya Srivastava 673831242abSAditya Srivastava return ""; 674831242abSAditya Srivastava} 675831242abSAditya Srivastava 6761813087dSJoe Perchesour @typeListMisordered = ( 6771813087dSJoe Perches qr{char\s+(?:un)?signed}, 6781813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 6791813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 6801813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 6811813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 6821813087dSJoe Perches qr{short\s+(?:un)?signed}, 6831813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 6841813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 6851813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 6861813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 6871813087dSJoe Perches qr{int\s+(?:un)?signed}, 6881813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 6891813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 6901813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 6911813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 6921813087dSJoe Perches qr{long\s+(?:un)?signed}, 6931813087dSJoe Perches); 6941813087dSJoe Perches 6958905a67cSAndy Whitcroftour @typeList = ( 6968905a67cSAndy Whitcroft qr{void}, 6970c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 6980c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 6990c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 7000c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 7010c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 7020c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 7030c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 7040c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 7050c773d9dSJoe Perches qr{(?:un)?signed}, 7068905a67cSAndy Whitcroft qr{float}, 7078905a67cSAndy Whitcroft qr{double}, 7088905a67cSAndy Whitcroft qr{bool}, 7098905a67cSAndy Whitcroft qr{struct\s+$Ident}, 7108905a67cSAndy Whitcroft qr{union\s+$Ident}, 7118905a67cSAndy Whitcroft qr{enum\s+$Ident}, 7128905a67cSAndy Whitcroft qr{${Ident}_t}, 7138905a67cSAndy Whitcroft qr{${Ident}_handler}, 7148905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 7151813087dSJoe Perches @typeListMisordered, 7168905a67cSAndy Whitcroft); 717938224b5SJoe Perches 718938224b5SJoe Perchesour $C90_int_types = qr{(?x: 719938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 720938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 721938224b5SJoe Perches long\s+long\s+(?:un)?signed| 722938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 723938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 724938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 725938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 726938224b5SJoe Perches 727938224b5SJoe Perches long\s+int\s+(?:un)?signed| 728938224b5SJoe Perches long\s+(?:un)?signed\s+int| 729938224b5SJoe Perches long\s+(?:un)?signed| 730938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 731938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 732938224b5SJoe Perches int\s+long\s+(?:un)?signed| 733938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 734938224b5SJoe Perches 735938224b5SJoe Perches int\s+(?:un)?signed| 736938224b5SJoe Perches (?:(?:un)?signed\s+)?int 737938224b5SJoe Perches)}; 738938224b5SJoe Perches 739485ff23eSAlex Dowadour @typeListFile = (); 7408716de38SJoe Perchesour @typeListWithAttr = ( 7418716de38SJoe Perches @typeList, 7428716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 7438716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 7448716de38SJoe Perches); 7458716de38SJoe Perches 746c45dcabdSAndy Whitcroftour @modifierList = ( 747c45dcabdSAndy Whitcroft qr{fastcall}, 748c45dcabdSAndy Whitcroft); 749485ff23eSAlex Dowadour @modifierListFile = (); 7508905a67cSAndy Whitcroft 7512435880fSJoe Perchesour @mode_permission_funcs = ( 7522435880fSJoe Perches ["module_param", 3], 7532435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 7542435880fSJoe Perches ["module_param_array_named", 5], 7552435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 7562435880fSJoe Perches ["proc_create(?:_data|)", 2], 757459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 758459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 759459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 760459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 761459cf0aeSJoe Perches ["__ATTR", 2], 7622435880fSJoe Perches); 7632435880fSJoe Perches 7641a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; 7651a3dcf2eSJoe Perches 766515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 767515a235eSJoe Perchesour $mode_perms_search = ""; 768515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 769515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 770515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 771515a235eSJoe Perches} 77200180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 773515a235eSJoe Perches 7749189c7e7SJoe Perchesour %deprecated_apis = ( 7759189c7e7SJoe Perches "synchronize_rcu_bh" => "synchronize_rcu", 7769189c7e7SJoe Perches "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 7779189c7e7SJoe Perches "call_rcu_bh" => "call_rcu", 7789189c7e7SJoe Perches "rcu_barrier_bh" => "rcu_barrier", 7799189c7e7SJoe Perches "synchronize_sched" => "synchronize_rcu", 7809189c7e7SJoe Perches "synchronize_sched_expedited" => "synchronize_rcu_expedited", 7819189c7e7SJoe Perches "call_rcu_sched" => "call_rcu", 7829189c7e7SJoe Perches "rcu_barrier_sched" => "rcu_barrier", 7839189c7e7SJoe Perches "get_state_synchronize_sched" => "get_state_synchronize_rcu", 7849189c7e7SJoe Perches "cond_synchronize_sched" => "cond_synchronize_rcu", 7859189c7e7SJoe Perches); 7869189c7e7SJoe Perches 7879189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 7889189c7e7SJoe Perchesour $deprecated_apis_search = ""; 7899189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 7909189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 7919189c7e7SJoe Perches $deprecated_apis_search .= $entry; 7929189c7e7SJoe Perches} 7939189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 7949189c7e7SJoe Perches 795b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 796b392c64fSJoe Perches S_IWUGO | 797b392c64fSJoe Perches S_IWOTH | 798b392c64fSJoe Perches S_IRWXUGO | 799b392c64fSJoe Perches S_IALLUGO | 800b392c64fSJoe Perches 0[0-7][0-7][2367] 801b392c64fSJoe Perches}x; 802b392c64fSJoe Perches 803f90774e1SJoe Perchesour %mode_permission_string_types = ( 804f90774e1SJoe Perches "S_IRWXU" => 0700, 805f90774e1SJoe Perches "S_IRUSR" => 0400, 806f90774e1SJoe Perches "S_IWUSR" => 0200, 807f90774e1SJoe Perches "S_IXUSR" => 0100, 808f90774e1SJoe Perches "S_IRWXG" => 0070, 809f90774e1SJoe Perches "S_IRGRP" => 0040, 810f90774e1SJoe Perches "S_IWGRP" => 0020, 811f90774e1SJoe Perches "S_IXGRP" => 0010, 812f90774e1SJoe Perches "S_IRWXO" => 0007, 813f90774e1SJoe Perches "S_IROTH" => 0004, 814f90774e1SJoe Perches "S_IWOTH" => 0002, 815f90774e1SJoe Perches "S_IXOTH" => 0001, 816f90774e1SJoe Perches "S_IRWXUGO" => 0777, 817f90774e1SJoe Perches "S_IRUGO" => 0444, 818f90774e1SJoe Perches "S_IWUGO" => 0222, 819f90774e1SJoe Perches "S_IXUGO" => 0111, 820f90774e1SJoe Perches); 821f90774e1SJoe Perches 822f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 823f90774e1SJoe Perchesour $mode_perms_string_search = ""; 824f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 825f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 826f90774e1SJoe Perches $mode_perms_string_search .= $entry; 827f90774e1SJoe Perches} 82800180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 82900180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 83000180468SJoe Perches ${single_mode_perms_string_search} 83100180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 83200180468SJoe Perches}x; 83300180468SJoe Perches 83400180468SJoe Perchessub perms_to_octal { 83500180468SJoe Perches my ($string) = @_; 83600180468SJoe Perches 83700180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 83800180468SJoe Perches 83900180468SJoe Perches my $val = ""; 84000180468SJoe Perches my $oval = ""; 84100180468SJoe Perches my $to = 0; 84200180468SJoe Perches my $curpos = 0; 84300180468SJoe Perches my $lastpos = 0; 84400180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 84500180468SJoe Perches $curpos = pos($string); 84600180468SJoe Perches my $match = $2; 84700180468SJoe Perches my $omatch = $1; 84800180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 84900180468SJoe Perches $lastpos = $curpos; 85000180468SJoe Perches $to |= $mode_permission_string_types{$match}; 85100180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 85200180468SJoe Perches $val .= $match; 85300180468SJoe Perches $oval .= $omatch; 85400180468SJoe Perches } 85500180468SJoe Perches $oval =~ s/^\s*\|\s*//; 85600180468SJoe Perches $oval =~ s/\s*\|\s*$//; 85700180468SJoe Perches return sprintf("%04o", $to); 85800180468SJoe Perches} 859f90774e1SJoe Perches 8607840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 8617840a94cSWolfram Sang irq| 862cdcee686SSergey Ryazanov memory| 863cdcee686SSergey Ryazanov time| 864cdcee686SSergey Ryazanov reboot 8657840a94cSWolfram Sang)}; 8667840a94cSWolfram Sang# memory.h: ARM has a custom one 8677840a94cSWolfram Sang 86866b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 86966b47b4aSKees Cookmy $misspellings; 87066b47b4aSKees Cookmy %spelling_fix; 87136061e38SJoe Perches 87236061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 87366b47b4aSKees Cook while (<$spelling>) { 87466b47b4aSKees Cook my $line = $_; 87566b47b4aSKees Cook 87666b47b4aSKees Cook $line =~ s/\s*\n?$//g; 87766b47b4aSKees Cook $line =~ s/^\s*//g; 87866b47b4aSKees Cook 87966b47b4aSKees Cook next if ($line =~ m/^\s*#/); 88066b47b4aSKees Cook next if ($line =~ m/^\s*$/); 88166b47b4aSKees Cook 88266b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 88366b47b4aSKees Cook 88466b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 88566b47b4aSKees Cook } 88666b47b4aSKees Cook close($spelling); 88736061e38SJoe Perches} else { 88836061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 88936061e38SJoe Perches} 89066b47b4aSKees Cook 891ebfd7d62SJoe Perchesif ($codespell) { 892ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 893ebfd7d62SJoe Perches while (<$spelling>) { 894ebfd7d62SJoe Perches my $line = $_; 895ebfd7d62SJoe Perches 896ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 897ebfd7d62SJoe Perches $line =~ s/^\s*//g; 898ebfd7d62SJoe Perches 899ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 900ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 901ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 902ebfd7d62SJoe Perches 903ebfd7d62SJoe Perches $line =~ s/,.*$//; 904ebfd7d62SJoe Perches 905ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 906ebfd7d62SJoe Perches 907ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 908ebfd7d62SJoe Perches } 909ebfd7d62SJoe Perches close($spelling); 910ebfd7d62SJoe Perches } else { 911ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 912ebfd7d62SJoe Perches } 913ebfd7d62SJoe Perches} 914ebfd7d62SJoe Perches 915ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 916ebfd7d62SJoe Perches 91775ad8c57SJerome Forissiersub read_words { 91875ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 91975ad8c57SJerome Forissier 92075ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 92175ad8c57SJerome Forissier while (<$words>) { 922bf1fa1daSJoe Perches my $line = $_; 923bf1fa1daSJoe Perches 924bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 925bf1fa1daSJoe Perches $line =~ s/^\s*//g; 926bf1fa1daSJoe Perches 927bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 928bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 929bf1fa1daSJoe Perches if ($line =~ /\s/) { 93075ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 931bf1fa1daSJoe Perches next; 932bf1fa1daSJoe Perches } 933bf1fa1daSJoe Perches 934ced69da1SQuentin Monnet $$wordsRef .= '|' if (defined $$wordsRef); 93575ad8c57SJerome Forissier $$wordsRef .= $line; 936bf1fa1daSJoe Perches } 93775ad8c57SJerome Forissier close($file); 93875ad8c57SJerome Forissier return 1; 939bf1fa1daSJoe Perches } 940bf1fa1daSJoe Perches 94175ad8c57SJerome Forissier return 0; 94275ad8c57SJerome Forissier} 94375ad8c57SJerome Forissier 944ced69da1SQuentin Monnetmy $const_structs; 945ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) { 94675ad8c57SJerome Forissier read_words(\$const_structs, $conststructsfile) 94775ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 948ced69da1SQuentin Monnet} 94975ad8c57SJerome Forissier 950ced69da1SQuentin Monnetif (defined($typedefsfile)) { 951ced69da1SQuentin Monnet my $typeOtherTypedefs; 95275ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 95375ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 954ced69da1SQuentin Monnet $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); 95575ad8c57SJerome Forissier} 95675ad8c57SJerome Forissier 9578905a67cSAndy Whitcroftsub build_types { 958485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 959485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 9601813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 9618716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 962c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 963ab7e23f3SJoe Perches $BasicType = qr{ 964ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 965ab7e23f3SJoe Perches (?:${all}\b) 966ab7e23f3SJoe Perches }x; 9678905a67cSAndy Whitcroft $NonptrType = qr{ 968d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 969cf655043SAndy Whitcroft (?: 9706b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 9718ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 972c45dcabdSAndy Whitcroft (?:${all}\b) 973cf655043SAndy Whitcroft ) 974c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 9758905a67cSAndy Whitcroft }x; 9761813087dSJoe Perches $NonptrTypeMisordered = qr{ 9771813087dSJoe Perches (?:$Modifier\s+|const\s+)* 9781813087dSJoe Perches (?: 9791813087dSJoe Perches (?:${Misordered}\b) 9801813087dSJoe Perches ) 9811813087dSJoe Perches (?:\s+$Modifier|\s+const)* 9821813087dSJoe Perches }x; 9838716de38SJoe Perches $NonptrTypeWithAttr = qr{ 9848716de38SJoe Perches (?:$Modifier\s+|const\s+)* 9858716de38SJoe Perches (?: 9868716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 9878716de38SJoe Perches (?:$typeTypedefs\b)| 9888716de38SJoe Perches (?:${allWithAttr}\b) 9898716de38SJoe Perches ) 9908716de38SJoe Perches (?:\s+$Modifier|\s+const)* 9918716de38SJoe Perches }x; 9928905a67cSAndy Whitcroft $Type = qr{ 993c45dcabdSAndy Whitcroft $NonptrType 9947b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 995c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 9968905a67cSAndy Whitcroft }x; 9971813087dSJoe Perches $TypeMisordered = qr{ 9981813087dSJoe Perches $NonptrTypeMisordered 9997b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 10001813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 10011813087dSJoe Perches }x; 100291cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 10031813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 10048905a67cSAndy Whitcroft} 10058905a67cSAndy Whitcroftbuild_types(); 10066c72ffaaSAndy Whitcroft 10077d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 1008d1fe9c09SJoe Perches 1009d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 1010d1fe9c09SJoe Perches# requires at least perl version v5.10.0 1011d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 1012d1fe9c09SJoe Perches 1013d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 10142435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 1015c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 10167d2367afSJoe Perches 1017f8422308SJoe Perchesour $declaration_macros = qr{(?x: 10183e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 1019fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 10203d102fc0SGilad Ben-Yossef (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( 1021f8422308SJoe Perches)}; 1022f8422308SJoe Perches 10238d0325ccSAditya Srivastavaour %allow_repeated_words = ( 10248d0325ccSAditya Srivastava add => '', 10258d0325ccSAditya Srivastava added => '', 10268d0325ccSAditya Srivastava bad => '', 10278d0325ccSAditya Srivastava be => '', 10288d0325ccSAditya Srivastava); 10298d0325ccSAditya Srivastava 10307d2367afSJoe Perchessub deparenthesize { 10317d2367afSJoe Perches my ($string) = @_; 10327d2367afSJoe Perches return "" if (!defined($string)); 10335b9553abSJoe Perches 10345b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 10355b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 10365b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 10375b9553abSJoe Perches } 10385b9553abSJoe Perches 10397d2367afSJoe Perches $string =~ s@\s+@ @g; 10405b9553abSJoe Perches 10417d2367afSJoe Perches return $string; 10427d2367afSJoe Perches} 10437d2367afSJoe Perches 10443445686aSJoe Perchessub seed_camelcase_file { 10453445686aSJoe Perches my ($file) = @_; 10463445686aSJoe Perches 10473445686aSJoe Perches return if (!(-f $file)); 10483445686aSJoe Perches 10493445686aSJoe Perches local $/; 10503445686aSJoe Perches 10513445686aSJoe Perches open(my $include_file, '<', "$file") 10523445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 10533445686aSJoe Perches my $text = <$include_file>; 10543445686aSJoe Perches close($include_file); 10553445686aSJoe Perches 10563445686aSJoe Perches my @lines = split('\n', $text); 10573445686aSJoe Perches 10583445686aSJoe Perches foreach my $line (@lines) { 10593445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 10603445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 10613445686aSJoe Perches $camelcase{$1} = 1; 106211ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 106311ea516aSJoe Perches $camelcase{$1} = 1; 106411ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 10653445686aSJoe Perches $camelcase{$1} = 1; 10663445686aSJoe Perches } 10673445686aSJoe Perches } 10683445686aSJoe Perches} 10693445686aSJoe Perches 1070cd28b119SJoe Perchesour %maintained_status = (); 1071cd28b119SJoe Perches 107285b0ee18SJoe Perchessub is_maintained_obsolete { 107385b0ee18SJoe Perches my ($filename) = @_; 107485b0ee18SJoe Perches 1075f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 107685b0ee18SJoe Perches 1077cd28b119SJoe Perches if (!exists($maintained_status{$filename})) { 1078cd28b119SJoe Perches $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 1079cd28b119SJoe Perches } 108085b0ee18SJoe Perches 1081cd28b119SJoe Perches return $maintained_status{$filename} =~ /obsolete/i; 108285b0ee18SJoe Perches} 108385b0ee18SJoe Perches 10843b6e8ac9SJoe Perchessub is_SPDX_License_valid { 10853b6e8ac9SJoe Perches my ($license) = @_; 10863b6e8ac9SJoe Perches 1087f9363b31SGuenter Roeck return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); 10883b6e8ac9SJoe Perches 108956294112SJoe Perches my $root_path = abs_path($root); 1090f9363b31SGuenter Roeck my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`; 10913b6e8ac9SJoe Perches return 0 if ($status ne ""); 10923b6e8ac9SJoe Perches return 1; 10933b6e8ac9SJoe Perches} 10943b6e8ac9SJoe Perches 10953445686aSJoe Perchesmy $camelcase_seeded = 0; 10963445686aSJoe Perchessub seed_camelcase_includes { 10973445686aSJoe Perches return if ($camelcase_seeded); 10983445686aSJoe Perches 10993445686aSJoe Perches my $files; 1100c707a81dSJoe Perches my $camelcase_cache = ""; 1101c707a81dSJoe Perches my @include_files = (); 1102c707a81dSJoe Perches 1103c707a81dSJoe Perches $camelcase_seeded = 1; 1104351b2a1fSJoe Perches 11050f7f635bSJoe Perches if (-e "$gitroot") { 1106dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 1107351b2a1fSJoe Perches chomp $git_last_include_commit; 1108c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 1109c707a81dSJoe Perches } else { 1110c707a81dSJoe Perches my $last_mod_date = 0; 1111c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 1112c707a81dSJoe Perches @include_files = split('\n', $files); 1113c707a81dSJoe Perches foreach my $file (@include_files) { 1114c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 1115c707a81dSJoe Perches localtime((stat $file)[9])); 1116c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 1117c707a81dSJoe Perches } 1118c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 1119c707a81dSJoe Perches } 1120c707a81dSJoe Perches 1121c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 1122c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 1123c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 1124351b2a1fSJoe Perches while (<$camelcase_file>) { 1125351b2a1fSJoe Perches chomp; 1126351b2a1fSJoe Perches $camelcase{$_} = 1; 1127351b2a1fSJoe Perches } 1128351b2a1fSJoe Perches close($camelcase_file); 1129351b2a1fSJoe Perches 1130351b2a1fSJoe Perches return; 1131351b2a1fSJoe Perches } 1132c707a81dSJoe Perches 11330f7f635bSJoe Perches if (-e "$gitroot") { 1134dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 1135c707a81dSJoe Perches @include_files = split('\n', $files); 11363445686aSJoe Perches } 1137c707a81dSJoe Perches 11383445686aSJoe Perches foreach my $file (@include_files) { 11393445686aSJoe Perches seed_camelcase_file($file); 11403445686aSJoe Perches } 1141351b2a1fSJoe Perches 1142c707a81dSJoe Perches if ($camelcase_cache ne "") { 1143351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 1144c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 1145c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 1146351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 1147351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 1148351b2a1fSJoe Perches } 1149351b2a1fSJoe Perches close($camelcase_file); 1150351b2a1fSJoe Perches } 11513445686aSJoe Perches} 11523445686aSJoe Perches 1153f5f61325SJoe Perchessub git_is_single_file { 1154f5f61325SJoe Perches my ($filename) = @_; 1155f5f61325SJoe Perches 1156f5f61325SJoe Perches return 0 if ((which("git") eq "") || !(-e "$gitroot")); 1157f5f61325SJoe Perches 1158f5f61325SJoe Perches my $output = `${git_command} ls-files -- $filename 2>/dev/null`; 1159f5f61325SJoe Perches my $count = $output =~ tr/\n//; 1160f5f61325SJoe Perches return $count eq 1 && $output =~ m{^${filename}$}; 1161f5f61325SJoe Perches} 1162f5f61325SJoe Perches 1163d311cd44SJoe Perchessub git_commit_info { 1164d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 1165d311cd44SJoe Perches 11660f7f635bSJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); 1167d311cd44SJoe Perches 1168dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 1169d311cd44SJoe Perches $output =~ s/^\s*//gm; 1170d311cd44SJoe Perches my @lines = split("\n", $output); 1171d311cd44SJoe Perches 11720d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 11730d7835fcSJoe Perches 11745a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 1175d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 1176d311cd44SJoe Perches# all matching commit ids, but it's very slow... 1177d311cd44SJoe Perches# 1178d311cd44SJoe Perches# echo "checking commits $1..." 1179d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 1180d311cd44SJoe Perches# while read line ; do 1181d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 1182d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 1183d311cd44SJoe Perches# done 1184*4ce9f970SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ || 1185*4ce9f970SJoe Perches $lines[0] =~ /^fatal: bad object $commit/) { 1186948b133aSHeinrich Schuchardt $id = undef; 1187d311cd44SJoe Perches } else { 1188d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 1189d311cd44SJoe Perches $desc = substr($lines[0], 41); 1190d311cd44SJoe Perches } 1191d311cd44SJoe Perches 1192d311cd44SJoe Perches return ($id, $desc); 1193d311cd44SJoe Perches} 1194d311cd44SJoe Perches 11956c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 11960a920b5bSAndy Whitcroft 119700df344fSAndy Whitcroftmy @rawlines = (); 1198c2fdda0dSAndy Whitcroftmy @lines = (); 11993705ce5bSJoe Perchesmy @fixed = (); 1200d752fcc8SJoe Perchesmy @fixed_inserted = (); 1201d752fcc8SJoe Perchesmy @fixed_deleted = (); 1202194f66fcSJoe Perchesmy $fixlinenr = -1; 1203194f66fcSJoe Perches 12044a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 12054a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 12060f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot"); 12074a593c34SDu, Changbin 12084a593c34SDu, Changbinif ($git) { 12094a593c34SDu, Changbin my @commits = (); 12100dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 12114a593c34SDu, Changbin my $git_range; 121228898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 121328898fd1SJoe Perches $git_range = "-$2 $1"; 12144a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 12154a593c34SDu, Changbin $git_range = "$commit_expr"; 12164a593c34SDu, Changbin } else { 12170dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 12180dea9f1eSJoe Perches } 1219dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 12200dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 122128898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 122228898fd1SJoe Perches next if (!defined($1) || !defined($2)); 12230dea9f1eSJoe Perches my $sha1 = $1; 12240dea9f1eSJoe Perches my $subject = $2; 12250dea9f1eSJoe Perches unshift(@commits, $sha1); 12260dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 12274a593c34SDu, Changbin } 12284a593c34SDu, Changbin } 12294a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 12304a593c34SDu, Changbin @ARGV = @commits; 12314a593c34SDu, Changbin} 12324a593c34SDu, Changbin 1233c2fdda0dSAndy Whitcroftmy $vname; 123498005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 12356c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 123621caa13cSAndy Whitcroft my $FILE; 1237f5f61325SJoe Perches my $is_git_file = git_is_single_file($filename); 1238f5f61325SJoe Perches my $oldfile = $file; 1239f5f61325SJoe Perches $file = 1 if ($is_git_file); 12404a593c34SDu, Changbin if ($git) { 12414a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 12424a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 12434a593c34SDu, Changbin } elsif ($file) { 124421caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 12456c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 124621caa13cSAndy Whitcroft } elsif ($filename eq '-') { 124721caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 12486c72ffaaSAndy Whitcroft } else { 124921caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 12506c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 12516c72ffaaSAndy Whitcroft } 1252c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1253c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 12544a593c34SDu, Changbin } elsif ($git) { 12550dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1256c2fdda0dSAndy Whitcroft } else { 1257c2fdda0dSAndy Whitcroft $vname = $filename; 1258c2fdda0dSAndy Whitcroft } 125921caa13cSAndy Whitcroft while (<$FILE>) { 12600a920b5bSAndy Whitcroft chomp; 126100df344fSAndy Whitcroft push(@rawlines, $_); 1262c7f574d0SGeert Uytterhoeven $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); 12636c72ffaaSAndy Whitcroft } 126421caa13cSAndy Whitcroft close($FILE); 1265d8469f16SJoe Perches 1266d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1267d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1268d8469f16SJoe Perches print "$vname\n"; 1269d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1270d8469f16SJoe Perches } 1271d8469f16SJoe Perches 1272c2fdda0dSAndy Whitcroft if (!process($filename)) { 12730a920b5bSAndy Whitcroft $exit = 1; 12740a920b5bSAndy Whitcroft } 127500df344fSAndy Whitcroft @rawlines = (); 127613214adfSAndy Whitcroft @lines = (); 12773705ce5bSJoe Perches @fixed = (); 1278d752fcc8SJoe Perches @fixed_inserted = (); 1279d752fcc8SJoe Perches @fixed_deleted = (); 1280194f66fcSJoe Perches $fixlinenr = -1; 1281485ff23eSAlex Dowad @modifierListFile = (); 1282485ff23eSAlex Dowad @typeListFile = (); 1283485ff23eSAlex Dowad build_types(); 1284f5f61325SJoe Perches $file = $oldfile if ($is_git_file); 12850a920b5bSAndy Whitcroft} 12860a920b5bSAndy Whitcroft 1287d8469f16SJoe Perchesif (!$quiet) { 12883c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 12893c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 12903c816e49SJoe Perches 12915b57980dSJoe Perches if (!$perl_version_ok) { 1292d8469f16SJoe Perches print << "EOM" 1293d8469f16SJoe Perches 1294d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 12955b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1296d8469f16SJoe PerchesEOM 1297d8469f16SJoe Perches } 1298d8469f16SJoe Perches if ($exit) { 1299d8469f16SJoe Perches print << "EOM" 1300d8469f16SJoe Perches 1301d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1302d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1303d8469f16SJoe PerchesEOM 1304d8469f16SJoe Perches } 1305d8469f16SJoe Perches} 1306d8469f16SJoe Perches 13070a920b5bSAndy Whitcroftexit($exit); 13080a920b5bSAndy Whitcroft 13090a920b5bSAndy Whitcroftsub top_of_kernel_tree { 13106c72ffaaSAndy Whitcroft my ($root) = @_; 13116c72ffaaSAndy Whitcroft 13126c72ffaaSAndy Whitcroft my @tree_check = ( 13136c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 13146c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 13156c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 13166c72ffaaSAndy Whitcroft ); 13176c72ffaaSAndy Whitcroft 13186c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 13196c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 13200a920b5bSAndy Whitcroft return 0; 13210a920b5bSAndy Whitcroft } 13226c72ffaaSAndy Whitcroft } 13236c72ffaaSAndy Whitcroft return 1; 13246c72ffaaSAndy Whitcroft} 13250a920b5bSAndy Whitcroft 132620112475SJoe Perchessub parse_email { 132720112475SJoe Perches my ($formatted_email) = @_; 132820112475SJoe Perches 132920112475SJoe Perches my $name = ""; 1330fccaebf0SDwaipayan Ray my $quoted = ""; 1331dfa05c28SJoe Perches my $name_comment = ""; 133220112475SJoe Perches my $address = ""; 133320112475SJoe Perches my $comment = ""; 133420112475SJoe Perches 133520112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 133620112475SJoe Perches $name = $1; 133720112475SJoe Perches $address = $2; 133820112475SJoe Perches $comment = $3 if defined $3; 133920112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 134020112475SJoe Perches $address = $1; 134120112475SJoe Perches $comment = $2 if defined $2; 134220112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 134320112475SJoe Perches $address = $1; 134420112475SJoe Perches $comment = $2 if defined $2; 134585e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 134620112475SJoe Perches $name = $formatted_email; 13473705ce5bSJoe Perches $name = trim($name); 134820112475SJoe Perches $name =~ s/^\"|\"$//g; 134920112475SJoe Perches # If there's a name left after stripping spaces and 135020112475SJoe Perches # leading quotes, and the address doesn't have both 135120112475SJoe Perches # leading and trailing angle brackets, the address 135220112475SJoe Perches # is invalid. ie: 135320112475SJoe Perches # "joe smith [email protected]" bad 135420112475SJoe Perches # "joe smith <[email protected]" bad 135520112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 135620112475SJoe Perches $name = ""; 135720112475SJoe Perches $address = ""; 135820112475SJoe Perches $comment = ""; 135920112475SJoe Perches } 136020112475SJoe Perches } 136120112475SJoe Perches 1362fccaebf0SDwaipayan Ray # Extract comments from names excluding quoted parts 1363fccaebf0SDwaipayan Ray # "John D. (Doe)" - Do not extract 1364fccaebf0SDwaipayan Ray if ($name =~ s/\"(.+)\"//) { 1365fccaebf0SDwaipayan Ray $quoted = $1; 1366dfa05c28SJoe Perches } 1367fccaebf0SDwaipayan Ray while ($name =~ s/\s*($balanced_parens)\s*/ /) { 1368fccaebf0SDwaipayan Ray $name_comment .= trim($1); 1369fccaebf0SDwaipayan Ray } 1370fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 1371fccaebf0SDwaipayan Ray $name = trim("$quoted $name"); 1372fccaebf0SDwaipayan Ray 13733705ce5bSJoe Perches $address = trim($address); 137420112475SJoe Perches $address =~ s/^\<|\>$//g; 1375fccaebf0SDwaipayan Ray $comment = trim($comment); 137620112475SJoe Perches 137720112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 137820112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 137920112475SJoe Perches $name = "\"$name\""; 138020112475SJoe Perches } 138120112475SJoe Perches 1382dfa05c28SJoe Perches return ($name, $name_comment, $address, $comment); 138320112475SJoe Perches} 138420112475SJoe Perches 138520112475SJoe Perchessub format_email { 138648ca2d8aSDwaipayan Ray my ($name, $name_comment, $address, $comment) = @_; 138720112475SJoe Perches 138820112475SJoe Perches my $formatted_email; 138920112475SJoe Perches 1390fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 13913705ce5bSJoe Perches $address = trim($address); 1392fccaebf0SDwaipayan Ray $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes 139320112475SJoe Perches 139420112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 139520112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 139620112475SJoe Perches $name = "\"$name\""; 139720112475SJoe Perches } 139820112475SJoe Perches 1399fccaebf0SDwaipayan Ray $name_comment = trim($name_comment); 1400fccaebf0SDwaipayan Ray $name_comment = " $name_comment" if ($name_comment ne ""); 1401fccaebf0SDwaipayan Ray $comment = trim($comment); 1402fccaebf0SDwaipayan Ray $comment = " $comment" if ($comment ne ""); 1403fccaebf0SDwaipayan Ray 140420112475SJoe Perches if ("$name" eq "") { 140520112475SJoe Perches $formatted_email = "$address"; 140620112475SJoe Perches } else { 140748ca2d8aSDwaipayan Ray $formatted_email = "$name$name_comment <$address>"; 140820112475SJoe Perches } 140948ca2d8aSDwaipayan Ray $formatted_email .= "$comment"; 141020112475SJoe Perches return $formatted_email; 141120112475SJoe Perches} 141220112475SJoe Perches 1413dfa05c28SJoe Perchessub reformat_email { 1414dfa05c28SJoe Perches my ($email) = @_; 1415dfa05c28SJoe Perches 1416dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 141748ca2d8aSDwaipayan Ray return format_email($email_name, $name_comment, $email_address, $comment); 1418dfa05c28SJoe Perches} 1419dfa05c28SJoe Perches 1420dfa05c28SJoe Perchessub same_email_addresses { 1421fccaebf0SDwaipayan Ray my ($email1, $email2) = @_; 1422dfa05c28SJoe Perches 1423dfa05c28SJoe Perches my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); 1424dfa05c28SJoe Perches my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); 1425dfa05c28SJoe Perches 142648ca2d8aSDwaipayan Ray return $email1_name eq $email2_name && 142748ca2d8aSDwaipayan Ray $email1_address eq $email2_address && 142848ca2d8aSDwaipayan Ray $name1_comment eq $name2_comment && 142948ca2d8aSDwaipayan Ray $comment1 eq $comment2; 143048ca2d8aSDwaipayan Ray} 1431dfa05c28SJoe Perches 1432d311cd44SJoe Perchessub which { 1433d311cd44SJoe Perches my ($bin) = @_; 1434d311cd44SJoe Perches 1435d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1436d311cd44SJoe Perches if (-e "$path/$bin") { 1437d311cd44SJoe Perches return "$path/$bin"; 1438d311cd44SJoe Perches } 1439d311cd44SJoe Perches } 1440d311cd44SJoe Perches 1441d311cd44SJoe Perches return ""; 1442d311cd44SJoe Perches} 1443d311cd44SJoe Perches 1444000d1cc1SJoe Perchessub which_conf { 1445000d1cc1SJoe Perches my ($conf) = @_; 1446000d1cc1SJoe Perches 1447000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1448000d1cc1SJoe Perches if (-e "$path/$conf") { 1449000d1cc1SJoe Perches return "$path/$conf"; 1450000d1cc1SJoe Perches } 1451000d1cc1SJoe Perches } 1452000d1cc1SJoe Perches 1453000d1cc1SJoe Perches return ""; 1454000d1cc1SJoe Perches} 1455000d1cc1SJoe Perches 14560a920b5bSAndy Whitcroftsub expand_tabs { 14570a920b5bSAndy Whitcroft my ($str) = @_; 14580a920b5bSAndy Whitcroft 14590a920b5bSAndy Whitcroft my $res = ''; 14600a920b5bSAndy Whitcroft my $n = 0; 14610a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 14620a920b5bSAndy Whitcroft if ($c eq "\t") { 14630a920b5bSAndy Whitcroft $res .= ' '; 14640a920b5bSAndy Whitcroft $n++; 1465713a09deSAntonio Borneo for (; ($n % $tabsize) != 0; $n++) { 14660a920b5bSAndy Whitcroft $res .= ' '; 14670a920b5bSAndy Whitcroft } 14680a920b5bSAndy Whitcroft next; 14690a920b5bSAndy Whitcroft } 14700a920b5bSAndy Whitcroft $res .= $c; 14710a920b5bSAndy Whitcroft $n++; 14720a920b5bSAndy Whitcroft } 14730a920b5bSAndy Whitcroft 14740a920b5bSAndy Whitcroft return $res; 14750a920b5bSAndy Whitcroft} 14766c72ffaaSAndy Whitcroftsub copy_spacing { 1477773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 14786c72ffaaSAndy Whitcroft return $res; 14796c72ffaaSAndy Whitcroft} 14800a920b5bSAndy Whitcroft 14814a0df2efSAndy Whitcroftsub line_stats { 14824a0df2efSAndy Whitcroft my ($line) = @_; 14834a0df2efSAndy Whitcroft 14844a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 14854a0df2efSAndy Whitcroft $line =~ s/^.//; 14864a0df2efSAndy Whitcroft $line = expand_tabs($line); 14874a0df2efSAndy Whitcroft 14884a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 14894a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 14904a0df2efSAndy Whitcroft 14914a0df2efSAndy Whitcroft return (length($line), length($white)); 14924a0df2efSAndy Whitcroft} 14934a0df2efSAndy Whitcroft 1494773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1495773647a0SAndy Whitcroft 1496773647a0SAndy Whitcroftsub sanitise_line_reset { 1497773647a0SAndy Whitcroft my ($in_comment) = @_; 1498773647a0SAndy Whitcroft 1499773647a0SAndy Whitcroft if ($in_comment) { 1500773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1501773647a0SAndy Whitcroft } else { 1502773647a0SAndy Whitcroft $sanitise_quote = ''; 1503773647a0SAndy Whitcroft } 1504773647a0SAndy Whitcroft} 150500df344fSAndy Whitcroftsub sanitise_line { 150600df344fSAndy Whitcroft my ($line) = @_; 150700df344fSAndy Whitcroft 150800df344fSAndy Whitcroft my $res = ''; 150900df344fSAndy Whitcroft my $l = ''; 151000df344fSAndy Whitcroft 1511c2fdda0dSAndy Whitcroft my $qlen = 0; 1512773647a0SAndy Whitcroft my $off = 0; 1513773647a0SAndy Whitcroft my $c; 151400df344fSAndy Whitcroft 1515773647a0SAndy Whitcroft # Always copy over the diff marker. 1516773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1517773647a0SAndy Whitcroft 1518773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1519773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1520773647a0SAndy Whitcroft 15218d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1522773647a0SAndy Whitcroft # and end, all to $;. 1523773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1524773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1525773647a0SAndy Whitcroft 1526773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1527773647a0SAndy Whitcroft $off++; 152800df344fSAndy Whitcroft next; 1529773647a0SAndy Whitcroft } 153081bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1531773647a0SAndy Whitcroft $sanitise_quote = ''; 1532773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1533773647a0SAndy Whitcroft $off++; 1534773647a0SAndy Whitcroft next; 1535773647a0SAndy Whitcroft } 1536113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1537113f04a8SDaniel Walker $sanitise_quote = '//'; 1538113f04a8SDaniel Walker 1539113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1540113f04a8SDaniel Walker $off++; 1541113f04a8SDaniel Walker next; 1542113f04a8SDaniel Walker } 1543773647a0SAndy Whitcroft 1544773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1545773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1546773647a0SAndy Whitcroft $c eq "\\") { 1547773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1548773647a0SAndy Whitcroft $off++; 1549773647a0SAndy Whitcroft next; 1550773647a0SAndy Whitcroft } 1551773647a0SAndy Whitcroft # Regular quotes. 1552773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1553773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1554773647a0SAndy Whitcroft $sanitise_quote = $c; 1555773647a0SAndy Whitcroft 1556773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1557773647a0SAndy Whitcroft next; 1558773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1559773647a0SAndy Whitcroft $sanitise_quote = ''; 156000df344fSAndy Whitcroft } 156100df344fSAndy Whitcroft } 1562773647a0SAndy Whitcroft 1563fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1564773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1565773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1566113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1567113f04a8SDaniel Walker substr($res, $off, 1, $;); 1568773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1569773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 157000df344fSAndy Whitcroft } else { 1571773647a0SAndy Whitcroft substr($res, $off, 1, $c); 157200df344fSAndy Whitcroft } 1573c2fdda0dSAndy Whitcroft } 1574c2fdda0dSAndy Whitcroft 1575113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1576113f04a8SDaniel Walker $sanitise_quote = ''; 1577113f04a8SDaniel Walker } 1578113f04a8SDaniel Walker 1579c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1580c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1581c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1582c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1583c2fdda0dSAndy Whitcroft 1584c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1585c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1586c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1587c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1588c2fdda0dSAndy Whitcroft } 1589c2fdda0dSAndy Whitcroft 1590dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1591dadf680dSJoe Perches my $match = $1; 1592dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1593dadf680dSJoe Perches } 1594dadf680dSJoe Perches 159500df344fSAndy Whitcroft return $res; 159600df344fSAndy Whitcroft} 159700df344fSAndy Whitcroft 1598a6962d72SJoe Perchessub get_quoted_string { 1599a6962d72SJoe Perches my ($line, $rawline) = @_; 1600a6962d72SJoe Perches 1601478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 160233acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1603a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1604a6962d72SJoe Perches} 1605a6962d72SJoe Perches 16068905a67cSAndy Whitcroftsub ctx_statement_block { 16078905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 16088905a67cSAndy Whitcroft my $line = $linenr - 1; 16098905a67cSAndy Whitcroft my $blk = ''; 16108905a67cSAndy Whitcroft my $soff = $off; 16118905a67cSAndy Whitcroft my $coff = $off - 1; 1612773647a0SAndy Whitcroft my $coff_set = 0; 16138905a67cSAndy Whitcroft 161413214adfSAndy Whitcroft my $loff = 0; 161513214adfSAndy Whitcroft 16168905a67cSAndy Whitcroft my $type = ''; 16178905a67cSAndy Whitcroft my $level = 0; 1618a2750645SAndy Whitcroft my @stack = (); 1619cf655043SAndy Whitcroft my $p; 16208905a67cSAndy Whitcroft my $c; 16218905a67cSAndy Whitcroft my $len = 0; 162213214adfSAndy Whitcroft 162313214adfSAndy Whitcroft my $remainder; 16248905a67cSAndy Whitcroft while (1) { 1625a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1626a2750645SAndy Whitcroft 1627773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 16288905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 16298905a67cSAndy Whitcroft # context. 16308905a67cSAndy Whitcroft if ($off >= $len) { 16318905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1632dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1633c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 16348905a67cSAndy Whitcroft $remain--; 163513214adfSAndy Whitcroft $loff = $len; 1636c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 16378905a67cSAndy Whitcroft $len = length($blk); 16388905a67cSAndy Whitcroft $line++; 16398905a67cSAndy Whitcroft last; 16408905a67cSAndy Whitcroft } 16418905a67cSAndy Whitcroft # Bail if there is no further context. 16428905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 164313214adfSAndy Whitcroft if ($off >= $len) { 16448905a67cSAndy Whitcroft last; 16458905a67cSAndy Whitcroft } 1646f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1647f74bd194SAndy Whitcroft $level++; 1648f74bd194SAndy Whitcroft $type = '#'; 1649f74bd194SAndy Whitcroft } 16508905a67cSAndy Whitcroft } 1651cf655043SAndy Whitcroft $p = $c; 16528905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 165313214adfSAndy Whitcroft $remainder = substr($blk, $off); 16548905a67cSAndy Whitcroft 1655773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 16564635f4fbSAndy Whitcroft 16574635f4fbSAndy Whitcroft # Handle nested #if/#else. 16584635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 16594635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 16604635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 16614635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 16624635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 16634635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 16644635f4fbSAndy Whitcroft } 16654635f4fbSAndy Whitcroft 16668905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 16678905a67cSAndy Whitcroft # outermost level. 16688905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 16698905a67cSAndy Whitcroft last; 16708905a67cSAndy Whitcroft } 16718905a67cSAndy Whitcroft 167213214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1673773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1674773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1675773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1676773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1677773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1678773647a0SAndy Whitcroft $coff_set = 1; 1679773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1680773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 168113214adfSAndy Whitcroft } 168213214adfSAndy Whitcroft 16838905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 16848905a67cSAndy Whitcroft $level++; 16858905a67cSAndy Whitcroft $type = '('; 16868905a67cSAndy Whitcroft } 16878905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 16888905a67cSAndy Whitcroft $level--; 16898905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 16908905a67cSAndy Whitcroft 16918905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 16928905a67cSAndy Whitcroft $coff = $off; 1693773647a0SAndy Whitcroft $coff_set = 1; 1694773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 16958905a67cSAndy Whitcroft } 16968905a67cSAndy Whitcroft } 16978905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 16988905a67cSAndy Whitcroft $level++; 16998905a67cSAndy Whitcroft $type = '{'; 17008905a67cSAndy Whitcroft } 17018905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 17028905a67cSAndy Whitcroft $level--; 17038905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 17048905a67cSAndy Whitcroft 17058905a67cSAndy Whitcroft if ($level == 0) { 1706b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1707b998e001SPatrick Pannuto $off++; 1708b998e001SPatrick Pannuto } 17098905a67cSAndy Whitcroft last; 17108905a67cSAndy Whitcroft } 17118905a67cSAndy Whitcroft } 1712f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1713f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1714f74bd194SAndy Whitcroft $level--; 1715f74bd194SAndy Whitcroft $type = ''; 1716f74bd194SAndy Whitcroft $off++; 1717f74bd194SAndy Whitcroft last; 1718f74bd194SAndy Whitcroft } 17198905a67cSAndy Whitcroft $off++; 17208905a67cSAndy Whitcroft } 1721a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 172213214adfSAndy Whitcroft if ($off == $len) { 1723a3bb97a7SAndy Whitcroft $loff = $len + 1; 172413214adfSAndy Whitcroft $line++; 172513214adfSAndy Whitcroft $remain--; 172613214adfSAndy Whitcroft } 17278905a67cSAndy Whitcroft 17288905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 17298905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 17308905a67cSAndy Whitcroft 17318905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 17328905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 17338905a67cSAndy Whitcroft 1734773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 173513214adfSAndy Whitcroft 173613214adfSAndy Whitcroft return ($statement, $condition, 173713214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 173813214adfSAndy Whitcroft} 173913214adfSAndy Whitcroft 1740cf655043SAndy Whitcroftsub statement_lines { 1741cf655043SAndy Whitcroft my ($stmt) = @_; 1742cf655043SAndy Whitcroft 1743cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1744cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1745cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1746cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1747cf655043SAndy Whitcroft 1748cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1749cf655043SAndy Whitcroft 1750cf655043SAndy Whitcroft return $#stmt_lines + 2; 1751cf655043SAndy Whitcroft} 1752cf655043SAndy Whitcroft 1753cf655043SAndy Whitcroftsub statement_rawlines { 1754cf655043SAndy Whitcroft my ($stmt) = @_; 1755cf655043SAndy Whitcroft 1756cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1757cf655043SAndy Whitcroft 1758cf655043SAndy Whitcroft return $#stmt_lines + 2; 1759cf655043SAndy Whitcroft} 1760cf655043SAndy Whitcroft 1761cf655043SAndy Whitcroftsub statement_block_size { 1762cf655043SAndy Whitcroft my ($stmt) = @_; 1763cf655043SAndy Whitcroft 1764cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1765cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1766cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1767cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1768cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1769cf655043SAndy Whitcroft 1770cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1771cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1772cf655043SAndy Whitcroft 1773cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1774cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1775cf655043SAndy Whitcroft 1776cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1777cf655043SAndy Whitcroft return $stmt_lines; 1778cf655043SAndy Whitcroft } else { 1779cf655043SAndy Whitcroft return $stmt_statements; 1780cf655043SAndy Whitcroft } 1781cf655043SAndy Whitcroft} 1782cf655043SAndy Whitcroft 178313214adfSAndy Whitcroftsub ctx_statement_full { 178413214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 178513214adfSAndy Whitcroft my ($statement, $condition, $level); 178613214adfSAndy Whitcroft 178713214adfSAndy Whitcroft my (@chunks); 178813214adfSAndy Whitcroft 1789cf655043SAndy Whitcroft # Grab the first conditional/block pair. 179013214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 179113214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1792773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 179313214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1794cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1795cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1796cf655043SAndy Whitcroft } 1797cf655043SAndy Whitcroft 1798cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1799cf655043SAndy Whitcroft # could continue the statement. 1800cf655043SAndy Whitcroft for (;;) { 180113214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 180213214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1803cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1804773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1805cf655043SAndy Whitcroft #print "C: push\n"; 1806cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 180713214adfSAndy Whitcroft } 180813214adfSAndy Whitcroft 180913214adfSAndy Whitcroft return ($level, $linenr, @chunks); 18108905a67cSAndy Whitcroft} 18118905a67cSAndy Whitcroft 18124a0df2efSAndy Whitcroftsub ctx_block_get { 1813f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 18144a0df2efSAndy Whitcroft my $line; 18154a0df2efSAndy Whitcroft my $start = $linenr - 1; 18164a0df2efSAndy Whitcroft my $blk = ''; 18174a0df2efSAndy Whitcroft my @o; 18184a0df2efSAndy Whitcroft my @c; 18194a0df2efSAndy Whitcroft my @res = (); 18204a0df2efSAndy Whitcroft 1821f0a594c1SAndy Whitcroft my $level = 0; 18224635f4fbSAndy Whitcroft my @stack = ($level); 182300df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 182400df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 182500df344fSAndy Whitcroft $remain--; 182600df344fSAndy Whitcroft 182700df344fSAndy Whitcroft $blk .= $rawlines[$line]; 18284635f4fbSAndy Whitcroft 18294635f4fbSAndy Whitcroft # Handle nested #if/#else. 183001464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 18314635f4fbSAndy Whitcroft push(@stack, $level); 183201464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 18334635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 183401464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 18354635f4fbSAndy Whitcroft $level = pop(@stack); 18364635f4fbSAndy Whitcroft } 18374635f4fbSAndy Whitcroft 183801464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1839f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1840f0a594c1SAndy Whitcroft if ($off > 0) { 1841f0a594c1SAndy Whitcroft $off--; 1842f0a594c1SAndy Whitcroft next; 1843f0a594c1SAndy Whitcroft } 18444a0df2efSAndy Whitcroft 1845f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1846f0a594c1SAndy Whitcroft $level--; 1847f0a594c1SAndy Whitcroft last if ($level == 0); 1848f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1849f0a594c1SAndy Whitcroft $level++; 1850f0a594c1SAndy Whitcroft } 1851f0a594c1SAndy Whitcroft } 18524a0df2efSAndy Whitcroft 1853f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 185400df344fSAndy Whitcroft push(@res, $rawlines[$line]); 18554a0df2efSAndy Whitcroft } 18564a0df2efSAndy Whitcroft 1857f0a594c1SAndy Whitcroft last if ($level == 0); 18584a0df2efSAndy Whitcroft } 18594a0df2efSAndy Whitcroft 1860f0a594c1SAndy Whitcroft return ($level, @res); 18614a0df2efSAndy Whitcroft} 18624a0df2efSAndy Whitcroftsub ctx_block_outer { 18634a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 18644a0df2efSAndy Whitcroft 1865f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1866f0a594c1SAndy Whitcroft return @r; 18674a0df2efSAndy Whitcroft} 18684a0df2efSAndy Whitcroftsub ctx_block { 18694a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 18704a0df2efSAndy Whitcroft 1871f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1872f0a594c1SAndy Whitcroft return @r; 1873653d4876SAndy Whitcroft} 1874653d4876SAndy Whitcroftsub ctx_statement { 1875f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1876f0a594c1SAndy Whitcroft 1877f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1878f0a594c1SAndy Whitcroft return @r; 1879f0a594c1SAndy Whitcroft} 1880f0a594c1SAndy Whitcroftsub ctx_block_level { 1881653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1882653d4876SAndy Whitcroft 1883f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 18844a0df2efSAndy Whitcroft} 18859c0ca6f9SAndy Whitcroftsub ctx_statement_level { 18869c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 18879c0ca6f9SAndy Whitcroft 18889c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 18899c0ca6f9SAndy Whitcroft} 18904a0df2efSAndy Whitcroft 18914a0df2efSAndy Whitcroftsub ctx_locate_comment { 18924a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 18934a0df2efSAndy Whitcroft 1894a55ee0ccSJoe Perches # If c99 comment on the current line, or the line before or after 1895a55ee0ccSJoe Perches my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); 1896a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1897a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); 1898a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1899a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); 1900a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1901a55ee0ccSJoe Perches 19024a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1903a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 19044a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 19054a0df2efSAndy Whitcroft 19064a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 19074a0df2efSAndy Whitcroft # comment. 19084a0df2efSAndy Whitcroft my $in_comment = 0; 19094a0df2efSAndy Whitcroft $current_comment = ''; 19104a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 191100df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 191200df344fSAndy Whitcroft #warn " $line\n"; 19134a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 19144a0df2efSAndy Whitcroft $in_comment = 1; 19154a0df2efSAndy Whitcroft } 19164a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 19174a0df2efSAndy Whitcroft $in_comment = 1; 19184a0df2efSAndy Whitcroft } 19194a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 19204a0df2efSAndy Whitcroft $current_comment = ''; 19214a0df2efSAndy Whitcroft } 19224a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 19234a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 19244a0df2efSAndy Whitcroft $in_comment = 0; 19254a0df2efSAndy Whitcroft } 19264a0df2efSAndy Whitcroft } 19274a0df2efSAndy Whitcroft 19284a0df2efSAndy Whitcroft chomp($current_comment); 19294a0df2efSAndy Whitcroft return($current_comment); 19304a0df2efSAndy Whitcroft} 19314a0df2efSAndy Whitcroftsub ctx_has_comment { 19324a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 19334a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 19344a0df2efSAndy Whitcroft 193500df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 19364a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 19374a0df2efSAndy Whitcroft 19384a0df2efSAndy Whitcroft return ($cmt ne ''); 19394a0df2efSAndy Whitcroft} 19404a0df2efSAndy Whitcroft 19414d001e4dSAndy Whitcroftsub raw_line { 19424d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 19434d001e4dSAndy Whitcroft 19444d001e4dSAndy Whitcroft my $offset = $linenr - 1; 19454d001e4dSAndy Whitcroft $cnt++; 19464d001e4dSAndy Whitcroft 19474d001e4dSAndy Whitcroft my $line; 19484d001e4dSAndy Whitcroft while ($cnt) { 19494d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 19504d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 19514d001e4dSAndy Whitcroft $cnt--; 19524d001e4dSAndy Whitcroft } 19534d001e4dSAndy Whitcroft 19544d001e4dSAndy Whitcroft return $line; 19554d001e4dSAndy Whitcroft} 19564d001e4dSAndy Whitcroft 19572a9f9d85STobin C. Hardingsub get_stat_real { 19582a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 19592a9f9d85STobin C. Harding 19602a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 19612a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 19622a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 19632a9f9d85STobin C. Harding } 19642a9f9d85STobin C. Harding 19652a9f9d85STobin C. Harding return $stat_real; 19662a9f9d85STobin C. Harding} 19672a9f9d85STobin C. Harding 1968e3d95a2aSTobin C. Hardingsub get_stat_here { 1969e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 1970e3d95a2aSTobin C. Harding 1971e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 1972e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 1973e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 1974e3d95a2aSTobin C. Harding } 1975e3d95a2aSTobin C. Harding 1976e3d95a2aSTobin C. Harding return $herectx; 1977e3d95a2aSTobin C. Harding} 1978e3d95a2aSTobin C. Harding 19790a920b5bSAndy Whitcroftsub cat_vet { 19800a920b5bSAndy Whitcroft my ($vet) = @_; 19819c0ca6f9SAndy Whitcroft my ($res, $coded); 19820a920b5bSAndy Whitcroft 19839c0ca6f9SAndy Whitcroft $res = ''; 19846c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 19856c72ffaaSAndy Whitcroft $res .= $1; 19866c72ffaaSAndy Whitcroft if ($2 ne '') { 19879c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 19886c72ffaaSAndy Whitcroft $res .= $coded; 19896c72ffaaSAndy Whitcroft } 19909c0ca6f9SAndy Whitcroft } 19919c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 19920a920b5bSAndy Whitcroft 19939c0ca6f9SAndy Whitcroft return $res; 19940a920b5bSAndy Whitcroft} 19950a920b5bSAndy Whitcroft 1996c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1997cf655043SAndy Whitcroftmy $av_pending; 1998c2fdda0dSAndy Whitcroftmy @av_paren_type; 19991f65f947SAndy Whitcroftmy $av_pend_colon; 2000c2fdda0dSAndy Whitcroft 2001c2fdda0dSAndy Whitcroftsub annotate_reset { 2002c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 2003cf655043SAndy Whitcroft $av_pending = '_'; 2004cf655043SAndy Whitcroft @av_paren_type = ('E'); 20051f65f947SAndy Whitcroft $av_pend_colon = 'O'; 2006c2fdda0dSAndy Whitcroft} 2007c2fdda0dSAndy Whitcroft 20086c72ffaaSAndy Whitcroftsub annotate_values { 20096c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 20106c72ffaaSAndy Whitcroft 20116c72ffaaSAndy Whitcroft my $res; 20121f65f947SAndy Whitcroft my $var = '_' x length($stream); 20136c72ffaaSAndy Whitcroft my $cur = $stream; 20146c72ffaaSAndy Whitcroft 2015c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 20166c72ffaaSAndy Whitcroft 20176c72ffaaSAndy Whitcroft while (length($cur)) { 2018773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 2019cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 2020171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 20216c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 2022c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 2023c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 2024cf655043SAndy Whitcroft $type = pop(@av_paren_type); 2025c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 20266c72ffaaSAndy Whitcroft } 20276c72ffaaSAndy Whitcroft 2028c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 20299446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 20309446ef56SAndy Whitcroft push(@av_paren_type, $type); 2031addcdceaSAndy Whitcroft $type = 'c'; 20329446ef56SAndy Whitcroft 2033e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 2034c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 20356c72ffaaSAndy Whitcroft $type = 'T'; 20366c72ffaaSAndy Whitcroft 2037389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 2038389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 2039389a2fe5SAndy Whitcroft $type = 'T'; 2040389a2fe5SAndy Whitcroft 2041c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 2042171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 2043c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2044171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 2045171ae1a4SAndy Whitcroft if ($2 ne '') { 2046cf655043SAndy Whitcroft $av_pending = 'N'; 2047171ae1a4SAndy Whitcroft } 2048171ae1a4SAndy Whitcroft $type = 'E'; 2049171ae1a4SAndy Whitcroft 2050c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 2051171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 2052171ae1a4SAndy Whitcroft $av_preprocessor = 1; 2053171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 20546c72ffaaSAndy Whitcroft 2055c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 2056cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 2057c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2058cf655043SAndy Whitcroft 2059cf655043SAndy Whitcroft push(@av_paren_type, $type); 2060cf655043SAndy Whitcroft push(@av_paren_type, $type); 2061171ae1a4SAndy Whitcroft $type = 'E'; 2062cf655043SAndy Whitcroft 2063c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 2064cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 2065cf655043SAndy Whitcroft $av_preprocessor = 1; 2066cf655043SAndy Whitcroft 2067cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 2068cf655043SAndy Whitcroft 2069171ae1a4SAndy Whitcroft $type = 'E'; 2070cf655043SAndy Whitcroft 2071c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 2072cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 2073cf655043SAndy Whitcroft 2074cf655043SAndy Whitcroft $av_preprocessor = 1; 2075cf655043SAndy Whitcroft 2076cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 2077cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 2078cf655043SAndy Whitcroft pop(@av_paren_type); 2079cf655043SAndy Whitcroft push(@av_paren_type, $type); 2080171ae1a4SAndy Whitcroft $type = 'E'; 20816c72ffaaSAndy Whitcroft 20826c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 2083c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 20846c72ffaaSAndy Whitcroft 2085171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 2086171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 2087171ae1a4SAndy Whitcroft $av_pending = $type; 2088171ae1a4SAndy Whitcroft $type = 'N'; 2089171ae1a4SAndy Whitcroft 20906c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 2091c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 20926c72ffaaSAndy Whitcroft if (defined $2) { 2093cf655043SAndy Whitcroft $av_pending = 'V'; 20946c72ffaaSAndy Whitcroft } 20956c72ffaaSAndy Whitcroft $type = 'N'; 20966c72ffaaSAndy Whitcroft 209714b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 2098c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 209914b111c1SAndy Whitcroft $av_pending = 'E'; 21006c72ffaaSAndy Whitcroft $type = 'N'; 21016c72ffaaSAndy Whitcroft 21021f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 21031f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 21041f65f947SAndy Whitcroft $av_pend_colon = 'C'; 21051f65f947SAndy Whitcroft $type = 'N'; 21061f65f947SAndy Whitcroft 210714b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 2108c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 21096c72ffaaSAndy Whitcroft $type = 'N'; 21106c72ffaaSAndy Whitcroft 21116c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 2112c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 2113cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 2114cf655043SAndy Whitcroft $av_pending = '_'; 21156c72ffaaSAndy Whitcroft $type = 'N'; 21166c72ffaaSAndy Whitcroft 21176c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 2118cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 2119cf655043SAndy Whitcroft if ($new_type ne '_') { 2120cf655043SAndy Whitcroft $type = $new_type; 2121c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 2122c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 21236c72ffaaSAndy Whitcroft } else { 2124c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 21256c72ffaaSAndy Whitcroft } 21266c72ffaaSAndy Whitcroft 2127c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 2128c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 2129c8cb2ca3SAndy Whitcroft $type = 'V'; 2130cf655043SAndy Whitcroft $av_pending = 'V'; 21316c72ffaaSAndy Whitcroft 21328e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 21338e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 21341f65f947SAndy Whitcroft $av_pend_colon = 'B'; 21358e761b04SAndy Whitcroft } elsif ($type eq 'E') { 21368e761b04SAndy Whitcroft $av_pend_colon = 'L'; 21371f65f947SAndy Whitcroft } 21381f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 21391f65f947SAndy Whitcroft $type = 'V'; 21401f65f947SAndy Whitcroft 21416c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 2142c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 21436c72ffaaSAndy Whitcroft $type = 'V'; 21446c72ffaaSAndy Whitcroft 21456c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 2146c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 21476c72ffaaSAndy Whitcroft $type = 'N'; 21486c72ffaaSAndy Whitcroft 2149cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 2150c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 215113214adfSAndy Whitcroft $type = 'E'; 21521f65f947SAndy Whitcroft $av_pend_colon = 'O'; 215313214adfSAndy Whitcroft 21548e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 21558e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 21568e761b04SAndy Whitcroft $type = 'C'; 21578e761b04SAndy Whitcroft 21581f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 21591f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 21601f65f947SAndy Whitcroft $type = 'N'; 21611f65f947SAndy Whitcroft 21621f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 21631f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 21641f65f947SAndy Whitcroft 21651f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 21661f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 21671f65f947SAndy Whitcroft $type = 'E'; 21681f65f947SAndy Whitcroft } else { 21691f65f947SAndy Whitcroft $type = 'N'; 21701f65f947SAndy Whitcroft } 21711f65f947SAndy Whitcroft $av_pend_colon = 'O'; 21721f65f947SAndy Whitcroft 21738e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 217413214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 21756c72ffaaSAndy Whitcroft $type = 'N'; 21766c72ffaaSAndy Whitcroft 21770d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 217874048ed8SAndy Whitcroft my $variant; 217974048ed8SAndy Whitcroft 218074048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 218174048ed8SAndy Whitcroft if ($type eq 'V') { 218274048ed8SAndy Whitcroft $variant = 'B'; 218374048ed8SAndy Whitcroft } else { 218474048ed8SAndy Whitcroft $variant = 'U'; 218574048ed8SAndy Whitcroft } 218674048ed8SAndy Whitcroft 218774048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 218874048ed8SAndy Whitcroft $type = 'N'; 218974048ed8SAndy Whitcroft 21906c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 2191c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 21926c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 21936c72ffaaSAndy Whitcroft $type = 'N'; 21946c72ffaaSAndy Whitcroft } 21956c72ffaaSAndy Whitcroft 21966c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 2197c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 21986c72ffaaSAndy Whitcroft } 21996c72ffaaSAndy Whitcroft if (defined $1) { 22006c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 22016c72ffaaSAndy Whitcroft $res .= $type x length($1); 22026c72ffaaSAndy Whitcroft } 22036c72ffaaSAndy Whitcroft } 22046c72ffaaSAndy Whitcroft 22051f65f947SAndy Whitcroft return ($res, $var); 22066c72ffaaSAndy Whitcroft} 22076c72ffaaSAndy Whitcroft 22088905a67cSAndy Whitcroftsub possible { 220913214adfSAndy Whitcroft my ($possible, $line) = @_; 22109a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 22110776e594SAndy Whitcroft ^(?: 22120776e594SAndy Whitcroft $Modifier| 22130776e594SAndy Whitcroft $Storage| 22140776e594SAndy Whitcroft $Type| 22159a974fdbSAndy Whitcroft DEFINE_\S+ 22169a974fdbSAndy Whitcroft )$| 22179a974fdbSAndy Whitcroft ^(?: 22180776e594SAndy Whitcroft goto| 22190776e594SAndy Whitcroft return| 22200776e594SAndy Whitcroft case| 22210776e594SAndy Whitcroft else| 22220776e594SAndy Whitcroft asm|__asm__| 222389a88353SAndy Whitcroft do| 222489a88353SAndy Whitcroft \#| 222589a88353SAndy Whitcroft \#\#| 22269a974fdbSAndy Whitcroft )(?:\s|$)| 22270776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 22289a974fdbSAndy Whitcroft )}x; 22299a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 22309a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 2231c45dcabdSAndy Whitcroft # Check for modifiers. 2232c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 2233c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 2234c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 2235c45dcabdSAndy Whitcroft 2236c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 2237c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 2238d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 22399a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 2240d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 2241485ff23eSAlex Dowad push(@modifierListFile, $modifier); 2242d2506586SAndy Whitcroft } 22439a974fdbSAndy Whitcroft } 2244c45dcabdSAndy Whitcroft 2245c45dcabdSAndy Whitcroft } else { 224613214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 2247485ff23eSAlex Dowad push(@typeListFile, $possible); 2248c45dcabdSAndy Whitcroft } 22498905a67cSAndy Whitcroft build_types(); 22500776e594SAndy Whitcroft } else { 22510776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 22528905a67cSAndy Whitcroft } 22538905a67cSAndy Whitcroft} 22548905a67cSAndy Whitcroft 22556c72ffaaSAndy Whitcroftmy $prefix = ''; 22566c72ffaaSAndy Whitcroft 2257000d1cc1SJoe Perchessub show_type { 2258cbec18afSJoe Perches my ($type) = @_; 225991bfe484SJoe Perches 2260522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2261522b837cSAlexey Dobriyan 2262cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2263cbec18afSJoe Perches 2264cbec18afSJoe Perches return !defined $ignore_type{$type}; 2265000d1cc1SJoe Perches} 2266000d1cc1SJoe Perches 2267f0a594c1SAndy Whitcroftsub report { 2268cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2269cbec18afSJoe Perches 2270cbec18afSJoe Perches if (!show_type($type) || 2271cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2272773647a0SAndy Whitcroft return 0; 2273773647a0SAndy Whitcroft } 227457230297SJoe Perches my $output = ''; 2275737c0767SJohn Brooks if ($color) { 227657230297SJoe Perches if ($level eq 'ERROR') { 227757230297SJoe Perches $output .= RED; 227857230297SJoe Perches } elsif ($level eq 'WARNING') { 227957230297SJoe Perches $output .= YELLOW; 2280000d1cc1SJoe Perches } else { 228157230297SJoe Perches $output .= GREEN; 2282000d1cc1SJoe Perches } 228357230297SJoe Perches } 228457230297SJoe Perches $output .= $prefix . $level . ':'; 228557230297SJoe Perches if ($show_types) { 2286737c0767SJohn Brooks $output .= BLUE if ($color); 228757230297SJoe Perches $output .= "$type:"; 228857230297SJoe Perches } 2289737c0767SJohn Brooks $output .= RESET if ($color); 229057230297SJoe Perches $output .= ' ' . $msg . "\n"; 229134d8815fSJoe Perches 229234d8815fSJoe Perches if ($showfile) { 229334d8815fSJoe Perches my @lines = split("\n", $output, -1); 229434d8815fSJoe Perches splice(@lines, 1, 1); 229534d8815fSJoe Perches $output = join("\n", @lines); 229634d8815fSJoe Perches } 229752178ce0SDwaipayan Ray 229852178ce0SDwaipayan Ray if ($terse) { 229952178ce0SDwaipayan Ray $output = (split('\n', $output))[0] . "\n"; 230052178ce0SDwaipayan Ray } 230152178ce0SDwaipayan Ray 230252178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$type}) && 230352178ce0SDwaipayan Ray !exists($verbose_emitted{$type})) { 230452178ce0SDwaipayan Ray $output .= $verbose_messages{$type} . "\n\n"; 230552178ce0SDwaipayan Ray $verbose_emitted{$type} = 1; 230652178ce0SDwaipayan Ray } 23078905a67cSAndy Whitcroft 230857230297SJoe Perches push(our @report, $output); 2309773647a0SAndy Whitcroft 2310773647a0SAndy Whitcroft return 1; 2311f0a594c1SAndy Whitcroft} 2312cbec18afSJoe Perches 2313f0a594c1SAndy Whitcroftsub report_dump { 231413214adfSAndy Whitcroft our @report; 2315f0a594c1SAndy Whitcroft} 2316000d1cc1SJoe Perches 2317d752fcc8SJoe Perchessub fixup_current_range { 2318d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2319d752fcc8SJoe Perches 2320d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2321d752fcc8SJoe Perches my $o = $1; 2322d752fcc8SJoe Perches my $l = $2; 2323d752fcc8SJoe Perches my $no = $o + $offset; 2324d752fcc8SJoe Perches my $nl = $l + $length; 2325d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2326d752fcc8SJoe Perches } 2327d752fcc8SJoe Perches} 2328d752fcc8SJoe Perches 2329d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2330d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2331d752fcc8SJoe Perches 2332d752fcc8SJoe Perches my $range_last_linenr = 0; 2333d752fcc8SJoe Perches my $delta_offset = 0; 2334d752fcc8SJoe Perches 2335d752fcc8SJoe Perches my $old_linenr = 0; 2336d752fcc8SJoe Perches my $new_linenr = 0; 2337d752fcc8SJoe Perches 2338d752fcc8SJoe Perches my $next_insert = 0; 2339d752fcc8SJoe Perches my $next_delete = 0; 2340d752fcc8SJoe Perches 2341d752fcc8SJoe Perches my @lines = (); 2342d752fcc8SJoe Perches 2343d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2344d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2345d752fcc8SJoe Perches 2346d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2347d752fcc8SJoe Perches my $save_line = 1; 2348d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2349323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2350d752fcc8SJoe Perches $delta_offset = 0; 2351d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2352d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2353d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2354d752fcc8SJoe Perches } 2355d752fcc8SJoe Perches 2356d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2357d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2358d752fcc8SJoe Perches $save_line = 0; 2359d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2360d752fcc8SJoe Perches } 2361d752fcc8SJoe Perches 2362d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2363d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2364d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2365d752fcc8SJoe Perches $new_linenr++; 2366d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2367d752fcc8SJoe Perches } 2368d752fcc8SJoe Perches 2369d752fcc8SJoe Perches if ($save_line) { 2370d752fcc8SJoe Perches push(@lines, $line); 2371d752fcc8SJoe Perches $new_linenr++; 2372d752fcc8SJoe Perches } 2373d752fcc8SJoe Perches 2374d752fcc8SJoe Perches $old_linenr++; 2375d752fcc8SJoe Perches } 2376d752fcc8SJoe Perches 2377d752fcc8SJoe Perches return @lines; 2378d752fcc8SJoe Perches} 2379d752fcc8SJoe Perches 2380f2d7e4d4SJoe Perchessub fix_insert_line { 2381f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2382f2d7e4d4SJoe Perches 2383f2d7e4d4SJoe Perches my $inserted = { 2384f2d7e4d4SJoe Perches LINENR => $linenr, 2385f2d7e4d4SJoe Perches LINE => $line, 2386f2d7e4d4SJoe Perches }; 2387f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2388f2d7e4d4SJoe Perches} 2389f2d7e4d4SJoe Perches 2390f2d7e4d4SJoe Perchessub fix_delete_line { 2391f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2392f2d7e4d4SJoe Perches 2393f2d7e4d4SJoe Perches my $deleted = { 2394f2d7e4d4SJoe Perches LINENR => $linenr, 2395f2d7e4d4SJoe Perches LINE => $line, 2396f2d7e4d4SJoe Perches }; 2397f2d7e4d4SJoe Perches 2398f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2399f2d7e4d4SJoe Perches} 2400f2d7e4d4SJoe Perches 2401de7d4f0eSAndy Whitcroftsub ERROR { 2402cbec18afSJoe Perches my ($type, $msg) = @_; 2403cbec18afSJoe Perches 2404cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2405de7d4f0eSAndy Whitcroft our $clean = 0; 24066c72ffaaSAndy Whitcroft our $cnt_error++; 24073705ce5bSJoe Perches return 1; 2408de7d4f0eSAndy Whitcroft } 24093705ce5bSJoe Perches return 0; 2410773647a0SAndy Whitcroft} 2411de7d4f0eSAndy Whitcroftsub WARN { 2412cbec18afSJoe Perches my ($type, $msg) = @_; 2413cbec18afSJoe Perches 2414cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2415de7d4f0eSAndy Whitcroft our $clean = 0; 24166c72ffaaSAndy Whitcroft our $cnt_warn++; 24173705ce5bSJoe Perches return 1; 2418de7d4f0eSAndy Whitcroft } 24193705ce5bSJoe Perches return 0; 2420773647a0SAndy Whitcroft} 2421de7d4f0eSAndy Whitcroftsub CHK { 2422cbec18afSJoe Perches my ($type, $msg) = @_; 2423cbec18afSJoe Perches 2424cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2425de7d4f0eSAndy Whitcroft our $clean = 0; 24266c72ffaaSAndy Whitcroft our $cnt_chk++; 24273705ce5bSJoe Perches return 1; 24286c72ffaaSAndy Whitcroft } 24293705ce5bSJoe Perches return 0; 2430de7d4f0eSAndy Whitcroft} 2431de7d4f0eSAndy Whitcroft 24326ecd9674SAndy Whitcroftsub check_absolute_file { 24336ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 24346ecd9674SAndy Whitcroft my $file = $absolute; 24356ecd9674SAndy Whitcroft 24366ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 24376ecd9674SAndy Whitcroft 24386ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 24396ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 24406ecd9674SAndy Whitcroft if (-f "$root/$file") { 24416ecd9674SAndy Whitcroft ##print "file<$file>\n"; 24426ecd9674SAndy Whitcroft last; 24436ecd9674SAndy Whitcroft } 24446ecd9674SAndy Whitcroft } 24456ecd9674SAndy Whitcroft if (! -f _) { 24466ecd9674SAndy Whitcroft return 0; 24476ecd9674SAndy Whitcroft } 24486ecd9674SAndy Whitcroft 24496ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 24506ecd9674SAndy Whitcroft my $prefix = $absolute; 24516ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 24526ecd9674SAndy Whitcroft 24536ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 24546ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2455000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2456000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 24576ecd9674SAndy Whitcroft } 24586ecd9674SAndy Whitcroft} 24596ecd9674SAndy Whitcroft 24603705ce5bSJoe Perchessub trim { 24613705ce5bSJoe Perches my ($string) = @_; 24623705ce5bSJoe Perches 2463b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2464b34c648bSJoe Perches 2465b34c648bSJoe Perches return $string; 2466b34c648bSJoe Perches} 2467b34c648bSJoe Perches 2468b34c648bSJoe Perchessub ltrim { 2469b34c648bSJoe Perches my ($string) = @_; 2470b34c648bSJoe Perches 2471b34c648bSJoe Perches $string =~ s/^\s+//; 2472b34c648bSJoe Perches 2473b34c648bSJoe Perches return $string; 2474b34c648bSJoe Perches} 2475b34c648bSJoe Perches 2476b34c648bSJoe Perchessub rtrim { 2477b34c648bSJoe Perches my ($string) = @_; 2478b34c648bSJoe Perches 2479b34c648bSJoe Perches $string =~ s/\s+$//; 24803705ce5bSJoe Perches 24813705ce5bSJoe Perches return $string; 24823705ce5bSJoe Perches} 24833705ce5bSJoe Perches 248452ea8506SJoe Perchessub string_find_replace { 248552ea8506SJoe Perches my ($string, $find, $replace) = @_; 248652ea8506SJoe Perches 248752ea8506SJoe Perches $string =~ s/$find/$replace/g; 248852ea8506SJoe Perches 248952ea8506SJoe Perches return $string; 249052ea8506SJoe Perches} 249152ea8506SJoe Perches 24923705ce5bSJoe Perchessub tabify { 24933705ce5bSJoe Perches my ($leading) = @_; 24943705ce5bSJoe Perches 2495713a09deSAntonio Borneo my $source_indent = $tabsize; 24963705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 24973705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 24983705ce5bSJoe Perches 24993705ce5bSJoe Perches #convert leading spaces to tabs 25003705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 25013705ce5bSJoe Perches #Remove spaces before a tab 25023705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 25033705ce5bSJoe Perches 25043705ce5bSJoe Perches return "$leading"; 25053705ce5bSJoe Perches} 25063705ce5bSJoe Perches 2507d1fe9c09SJoe Perchessub pos_last_openparen { 2508d1fe9c09SJoe Perches my ($line) = @_; 2509d1fe9c09SJoe Perches 2510d1fe9c09SJoe Perches my $pos = 0; 2511d1fe9c09SJoe Perches 2512d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2513d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2514d1fe9c09SJoe Perches 2515d1fe9c09SJoe Perches my $last_openparen = 0; 2516d1fe9c09SJoe Perches 2517d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2518d1fe9c09SJoe Perches return -1; 2519d1fe9c09SJoe Perches } 2520d1fe9c09SJoe Perches 2521d1fe9c09SJoe Perches my $len = length($line); 2522d1fe9c09SJoe Perches 2523d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2524d1fe9c09SJoe Perches my $string = substr($line, $pos); 2525d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2526d1fe9c09SJoe Perches $pos += length($1) - 1; 2527d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2528d1fe9c09SJoe Perches $last_openparen = $pos; 2529d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2530d1fe9c09SJoe Perches last; 2531d1fe9c09SJoe Perches } 2532d1fe9c09SJoe Perches } 2533d1fe9c09SJoe Perches 253491cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2535d1fe9c09SJoe Perches} 2536d1fe9c09SJoe Perches 2537f36d3eb8SJoe Perchessub get_raw_comment { 2538f36d3eb8SJoe Perches my ($line, $rawline) = @_; 2539f36d3eb8SJoe Perches my $comment = ''; 2540f36d3eb8SJoe Perches 2541f36d3eb8SJoe Perches for my $i (0 .. (length($line) - 1)) { 2542f36d3eb8SJoe Perches if (substr($line, $i, 1) eq "$;") { 2543f36d3eb8SJoe Perches $comment .= substr($rawline, $i, 1); 2544f36d3eb8SJoe Perches } 2545f36d3eb8SJoe Perches } 2546f36d3eb8SJoe Perches 2547f36d3eb8SJoe Perches return $comment; 2548f36d3eb8SJoe Perches} 2549f36d3eb8SJoe Perches 25505b8f82e1SSong Liusub exclude_global_initialisers { 25515b8f82e1SSong Liu my ($realfile) = @_; 25525b8f82e1SSong Liu 25535b8f82e1SSong Liu # Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c). 25545b8f82e1SSong Liu return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ || 25555b8f82e1SSong Liu $realfile =~ m@^samples/bpf/.*_kern\.c$@ || 25565b8f82e1SSong Liu $realfile =~ m@/bpf/.*\.bpf\.c$@; 25575b8f82e1SSong Liu} 25585b8f82e1SSong Liu 25590a920b5bSAndy Whitcroftsub process { 25600a920b5bSAndy Whitcroft my $filename = shift; 25610a920b5bSAndy Whitcroft 25620a920b5bSAndy Whitcroft my $linenr=0; 25630a920b5bSAndy Whitcroft my $prevline=""; 2564c2fdda0dSAndy Whitcroft my $prevrawline=""; 25650a920b5bSAndy Whitcroft my $stashline=""; 2566c2fdda0dSAndy Whitcroft my $stashrawline=""; 25670a920b5bSAndy Whitcroft 25684a0df2efSAndy Whitcroft my $length; 25690a920b5bSAndy Whitcroft my $indent; 25700a920b5bSAndy Whitcroft my $previndent=0; 25710a920b5bSAndy Whitcroft my $stashindent=0; 25720a920b5bSAndy Whitcroft 2573de7d4f0eSAndy Whitcroft our $clean = 1; 25740a920b5bSAndy Whitcroft my $signoff = 0; 2575cd261496SGeert Uytterhoeven my $author = ''; 2576cd261496SGeert Uytterhoeven my $authorsignoff = 0; 257748ca2d8aSDwaipayan Ray my $author_sob = ''; 25780a920b5bSAndy Whitcroft my $is_patch = 0; 2579133712a2SRob Herring my $is_binding_patch = -1; 258029ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 258115662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 258244d303ebSJoe Perches my $has_patch_separator = 0; #Found a --- line 2583ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2584490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2585bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 25862a076f40SJoe Perches my $commit_log_long_line = 0; 2587e518e9a5SJoe Perches my $commit_log_has_diff = 0; 258813f1937eSJoe Perches my $reported_maintainer_file = 0; 2589fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2590fa64205dSPasi Savanainen 2591*4ce9f970SJoe Perches my $last_git_commit_id_linenr = -1; 2592*4ce9f970SJoe Perches 2593365dd4eaSJoe Perches my $last_blank_line = 0; 25945e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2595365dd4eaSJoe Perches 259613214adfSAndy Whitcroft our @report = (); 25976c72ffaaSAndy Whitcroft our $cnt_lines = 0; 25986c72ffaaSAndy Whitcroft our $cnt_error = 0; 25996c72ffaaSAndy Whitcroft our $cnt_warn = 0; 26006c72ffaaSAndy Whitcroft our $cnt_chk = 0; 26016c72ffaaSAndy Whitcroft 26020a920b5bSAndy Whitcroft # Trace the real file/line as we go. 26030a920b5bSAndy Whitcroft my $realfile = ''; 26040a920b5bSAndy Whitcroft my $realline = 0; 26050a920b5bSAndy Whitcroft my $realcnt = 0; 26060a920b5bSAndy Whitcroft my $here = ''; 260777cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 26080a920b5bSAndy Whitcroft my $in_comment = 0; 2609c2fdda0dSAndy Whitcroft my $comment_edge = 0; 26100a920b5bSAndy Whitcroft my $first_line = 0; 26111e855726SWolfram Sang my $p1_prefix = ''; 26120a920b5bSAndy Whitcroft 261313214adfSAndy Whitcroft my $prev_values = 'E'; 261413214adfSAndy Whitcroft 261513214adfSAndy Whitcroft # suppression flags 2616773647a0SAndy Whitcroft my %suppress_ifbraces; 2617170d3a22SAndy Whitcroft my %suppress_whiletrailers; 26182b474a1aSAndy Whitcroft my %suppress_export; 26193e469cdcSAndy Whitcroft my $suppress_statement = 0; 2620653d4876SAndy Whitcroft 26217e51f197SJoe Perches my %signatures = (); 2622323c1260SJoe Perches 2623c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2624de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2625c2fdda0dSAndy Whitcroft # 2626de7d4f0eSAndy Whitcroft my @setup_docs = (); 2627de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2628773647a0SAndy Whitcroft 2629d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2630d8b07710SJoe Perches 26319f3a8992SRob Herring my $checklicenseline = 1; 26329f3a8992SRob Herring 2633773647a0SAndy Whitcroft sanitise_line_reset(); 2634c2fdda0dSAndy Whitcroft my $line; 2635c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2636773647a0SAndy Whitcroft $linenr++; 2637773647a0SAndy Whitcroft $line = $rawline; 2638c2fdda0dSAndy Whitcroft 26393705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 26403705ce5bSJoe Perches 2641773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2642de7d4f0eSAndy Whitcroft $setup_docs = 0; 26432581ac7cSTim Froidcoeur if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { 2644de7d4f0eSAndy Whitcroft $setup_docs = 1; 2645de7d4f0eSAndy Whitcroft } 2646773647a0SAndy Whitcroft #next; 2647de7d4f0eSAndy Whitcroft } 264874fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2649773647a0SAndy Whitcroft $realline=$1-1; 2650773647a0SAndy Whitcroft if (defined $2) { 2651773647a0SAndy Whitcroft $realcnt=$3+1; 2652773647a0SAndy Whitcroft } else { 2653773647a0SAndy Whitcroft $realcnt=1+1; 2654773647a0SAndy Whitcroft } 2655c45dcabdSAndy Whitcroft $in_comment = 0; 2656773647a0SAndy Whitcroft 2657773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2658773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2659773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2660773647a0SAndy Whitcroft # at context start. 2661773647a0SAndy Whitcroft my $edge; 266201fa9147SAndy Whitcroft my $cnt = $realcnt; 266301fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 266401fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 266501fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 266601fa9147SAndy Whitcroft $cnt--; 266701fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2668721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2669fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2670fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2671fae17daeSAndy Whitcroft ($edge) = $1; 2672fae17daeSAndy Whitcroft last; 2673fae17daeSAndy Whitcroft } 2674773647a0SAndy Whitcroft } 2675773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2676773647a0SAndy Whitcroft $in_comment = 1; 2677773647a0SAndy Whitcroft } 2678773647a0SAndy Whitcroft 2679773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2680773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2681773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2682773647a0SAndy Whitcroft if (!defined $edge && 268383242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2684773647a0SAndy Whitcroft { 2685773647a0SAndy Whitcroft $in_comment = 1; 2686773647a0SAndy Whitcroft } 2687773647a0SAndy Whitcroft 2688773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2689773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2690773647a0SAndy Whitcroft 2691171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2692773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2693171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2694773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2695773647a0SAndy Whitcroft } 2696773647a0SAndy Whitcroft push(@lines, $line); 2697773647a0SAndy Whitcroft 2698773647a0SAndy Whitcroft if ($realcnt > 1) { 2699773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2700773647a0SAndy Whitcroft } else { 2701773647a0SAndy Whitcroft $realcnt = 0; 2702773647a0SAndy Whitcroft } 2703773647a0SAndy Whitcroft 2704773647a0SAndy Whitcroft #print "==>$rawline\n"; 2705773647a0SAndy Whitcroft #print "-->$line\n"; 2706de7d4f0eSAndy Whitcroft 2707de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2708de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2709de7d4f0eSAndy Whitcroft } 2710de7d4f0eSAndy Whitcroft } 2711de7d4f0eSAndy Whitcroft 27126c72ffaaSAndy Whitcroft $prefix = ''; 27136c72ffaaSAndy Whitcroft 2714773647a0SAndy Whitcroft $realcnt = 0; 2715773647a0SAndy Whitcroft $linenr = 0; 2716194f66fcSJoe Perches $fixlinenr = -1; 27170a920b5bSAndy Whitcroft foreach my $line (@lines) { 27180a920b5bSAndy Whitcroft $linenr++; 2719194f66fcSJoe Perches $fixlinenr++; 27201b5539b1SJoe Perches my $sline = $line; #copy of $line 27211b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 27220a920b5bSAndy Whitcroft 2723c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 2724f36d3eb8SJoe Perches my $raw_comment = get_raw_comment($line, $rawline); 27256c72ffaaSAndy Whitcroft 272612c253abSJoe Perches# check if it's a mode change, rename or start of a patch 272712c253abSJoe Perches if (!$in_commit_log && 272812c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 272912c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 273012c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 273112c253abSJoe Perches $is_patch = 1; 273212c253abSJoe Perches } 273312c253abSJoe Perches 27340a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2735e518e9a5SJoe Perches if (!$in_commit_log && 273674fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 273774fd4f34SJoe Perches my $context = $4; 27380a920b5bSAndy Whitcroft $is_patch = 1; 27394a0df2efSAndy Whitcroft $first_line = $linenr + 1; 27400a920b5bSAndy Whitcroft $realline=$1-1; 27410a920b5bSAndy Whitcroft if (defined $2) { 27420a920b5bSAndy Whitcroft $realcnt=$3+1; 27430a920b5bSAndy Whitcroft } else { 27440a920b5bSAndy Whitcroft $realcnt=1+1; 27450a920b5bSAndy Whitcroft } 2746c2fdda0dSAndy Whitcroft annotate_reset(); 274713214adfSAndy Whitcroft $prev_values = 'E'; 274813214adfSAndy Whitcroft 2749773647a0SAndy Whitcroft %suppress_ifbraces = (); 2750170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 27512b474a1aSAndy Whitcroft %suppress_export = (); 27523e469cdcSAndy Whitcroft $suppress_statement = 0; 275374fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 275474fd4f34SJoe Perches $context_function = $1; 275574fd4f34SJoe Perches } else { 275674fd4f34SJoe Perches undef $context_function; 275774fd4f34SJoe Perches } 27580a920b5bSAndy Whitcroft next; 27590a920b5bSAndy Whitcroft 27604a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 27614a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 27624a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2763773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 27640a920b5bSAndy Whitcroft $realline++; 2765d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 27660a920b5bSAndy Whitcroft 27674a0df2efSAndy Whitcroft # Measure the line length and indent. 2768c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 27690a920b5bSAndy Whitcroft 27700a920b5bSAndy Whitcroft # Track the previous line. 27710a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 27720a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2773c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2774c2fdda0dSAndy Whitcroft 2775773647a0SAndy Whitcroft #warn "line<$line>\n"; 27766c72ffaaSAndy Whitcroft 2777d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2778d8aaf121SAndy Whitcroft $realcnt--; 27790a920b5bSAndy Whitcroft } 27800a920b5bSAndy Whitcroft 2781cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2782cc77cdcaSAndy Whitcroft 27836c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 27846c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2785773647a0SAndy Whitcroft 27862ac73b4fSJoe Perches my $found_file = 0; 2787773647a0SAndy Whitcroft # extract the filename as it passes 27883bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 27893bf9a009SRabin Vincent $realfile = $1; 27902b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2791270c49a0SJoe Perches $in_commit_log = 0; 27922ac73b4fSJoe Perches $found_file = 1; 27933bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2794773647a0SAndy Whitcroft $realfile = $1; 27952b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2796270c49a0SJoe Perches $in_commit_log = 0; 27971e855726SWolfram Sang 27981e855726SWolfram Sang $p1_prefix = $1; 2799e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2800e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2801000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2802000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 28031e855726SWolfram Sang } 2804773647a0SAndy Whitcroft 2805c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2806000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2807000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2808773647a0SAndy Whitcroft } 28092ac73b4fSJoe Perches $found_file = 1; 28102ac73b4fSJoe Perches } 28112ac73b4fSJoe Perches 281234d8815fSJoe Perches#make up the handle for any error we report on this line 281334d8815fSJoe Perches if ($showfile) { 281434d8815fSJoe Perches $prefix = "$realfile:$realline: " 281534d8815fSJoe Perches } elsif ($emacs) { 28167d3a9f67SJoe Perches if ($file) { 28177d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 28187d3a9f67SJoe Perches } else { 281934d8815fSJoe Perches $prefix = "$filename:$linenr: "; 282034d8815fSJoe Perches } 28217d3a9f67SJoe Perches } 282234d8815fSJoe Perches 28232ac73b4fSJoe Perches if ($found_file) { 282485b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 282585b0ee18SJoe Perches WARN("OBSOLETE", 282685b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 282785b0ee18SJoe Perches } 28287bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 28292ac73b4fSJoe Perches $check = 1; 28302ac73b4fSJoe Perches } else { 28312ac73b4fSJoe Perches $check = $check_orig; 28322ac73b4fSJoe Perches } 28339f3a8992SRob Herring $checklicenseline = 1; 2834133712a2SRob Herring 2835133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2836133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2837133712a2SRob Herring 2838133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2839133712a2SRob Herring 2840133712a2SRob Herring if (($last_binding_patch != -1) && 2841133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2842133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2843858e6845SMauro Carvalho Chehab "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); 2844133712a2SRob Herring } 2845133712a2SRob Herring } 2846133712a2SRob Herring 2847773647a0SAndy Whitcroft next; 2848773647a0SAndy Whitcroft } 2849773647a0SAndy Whitcroft 2850389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 28510a920b5bSAndy Whitcroft 2852c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2853c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2854c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 28550a920b5bSAndy Whitcroft 28566c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 28576c72ffaaSAndy Whitcroft 2858490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2859490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2860490b292cSJoe Perches if ($in_commit_log) { 2861490b292cSJoe Perches if ($line !~ /^\s*$/) { 2862490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2863490b292cSJoe Perches } 2864490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2865490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2866490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2867490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2868490b292cSJoe Perches } 2869490b292cSJoe Perches 2870e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2871e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 287213e45417SMrinal Pandey (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && 287313e45417SMrinal Pandey $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || 2874e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2875e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2876e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2877e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2878e518e9a5SJoe Perches $commit_log_has_diff = 1; 2879e518e9a5SJoe Perches } 2880e518e9a5SJoe Perches 28813bf9a009SRabin Vincent# Check for incorrect file permissions 28823bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 28833bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 288404db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 288504db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2886000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2887000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 28883bf9a009SRabin Vincent } 28893bf9a009SRabin Vincent } 28903bf9a009SRabin Vincent 2891cd261496SGeert Uytterhoeven# Check the patch for a From: 2892cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2893cd261496SGeert Uytterhoeven $author = $1; 2894e7f929f3SDwaipayan Ray my $curline = $linenr; 2895e7f929f3SDwaipayan Ray while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { 2896e7f929f3SDwaipayan Ray $author .= $1; 2897e7f929f3SDwaipayan Ray } 2898cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2899cd261496SGeert Uytterhoeven $author =~ s/"//g; 2900dfa05c28SJoe Perches $author = reformat_email($author); 2901cd261496SGeert Uytterhoeven } 2902cd261496SGeert Uytterhoeven 290320112475SJoe Perches# Check the patch for a signoff: 2904dfa05c28SJoe Perches if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { 29054a0df2efSAndy Whitcroft $signoff++; 290615662b3eSJoe Perches $in_commit_log = 0; 290748ca2d8aSDwaipayan Ray if ($author ne '' && $authorsignoff != 1) { 2908fccaebf0SDwaipayan Ray if (same_email_addresses($1, $author)) { 2909cd261496SGeert Uytterhoeven $authorsignoff = 1; 291048ca2d8aSDwaipayan Ray } else { 291148ca2d8aSDwaipayan Ray my $ctx = $1; 291248ca2d8aSDwaipayan Ray my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); 291348ca2d8aSDwaipayan Ray my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); 291448ca2d8aSDwaipayan Ray 2915046fc741SMimi Zohar if (lc $email_address eq lc $author_address && $email_name eq $author_name) { 291648ca2d8aSDwaipayan Ray $author_sob = $ctx; 291748ca2d8aSDwaipayan Ray $authorsignoff = 2; 2918046fc741SMimi Zohar } elsif (lc $email_address eq lc $author_address) { 291948ca2d8aSDwaipayan Ray $author_sob = $ctx; 292048ca2d8aSDwaipayan Ray $authorsignoff = 3; 292148ca2d8aSDwaipayan Ray } elsif ($email_name eq $author_name) { 292248ca2d8aSDwaipayan Ray $author_sob = $ctx; 292348ca2d8aSDwaipayan Ray $authorsignoff = 4; 292448ca2d8aSDwaipayan Ray 292548ca2d8aSDwaipayan Ray my $address1 = $email_address; 292648ca2d8aSDwaipayan Ray my $address2 = $author_address; 292748ca2d8aSDwaipayan Ray 292848ca2d8aSDwaipayan Ray if ($address1 =~ /(\S+)\+\S+(\@.*)/) { 292948ca2d8aSDwaipayan Ray $address1 = "$1$2"; 293048ca2d8aSDwaipayan Ray } 293148ca2d8aSDwaipayan Ray if ($address2 =~ /(\S+)\+\S+(\@.*)/) { 293248ca2d8aSDwaipayan Ray $address2 = "$1$2"; 293348ca2d8aSDwaipayan Ray } 293448ca2d8aSDwaipayan Ray if ($address1 eq $address2) { 293548ca2d8aSDwaipayan Ray $authorsignoff = 5; 293648ca2d8aSDwaipayan Ray } 293748ca2d8aSDwaipayan Ray } 2938cd261496SGeert Uytterhoeven } 2939cd261496SGeert Uytterhoeven } 29400a920b5bSAndy Whitcroft } 294120112475SJoe Perches 294244d303ebSJoe Perches# Check for patch separator 294344d303ebSJoe Perches if ($line =~ /^---$/) { 294444d303ebSJoe Perches $has_patch_separator = 1; 294544d303ebSJoe Perches $in_commit_log = 0; 294644d303ebSJoe Perches } 294744d303ebSJoe Perches 2948e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2949e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2950e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2951e0d975b1SJoe Perches $reported_maintainer_file = 1; 2952e0d975b1SJoe Perches } 2953e0d975b1SJoe Perches 295420112475SJoe Perches# Check signature styles 2955270c49a0SJoe Perches if (!$in_header_lines && 2956ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 295720112475SJoe Perches my $space_before = $1; 295820112475SJoe Perches my $sign_off = $2; 295920112475SJoe Perches my $space_after = $3; 296020112475SJoe Perches my $email = $4; 296120112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 296220112475SJoe Perches 2963ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2964831242abSAditya Srivastava my $suggested_signature = find_standard_signature($sign_off); 2965831242abSAditya Srivastava if ($suggested_signature eq "") { 2966ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2967ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2968831242abSAditya Srivastava } else { 2969831242abSAditya Srivastava if (WARN("BAD_SIGN_OFF", 2970831242abSAditya Srivastava "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && 2971831242abSAditya Srivastava $fix) { 2972831242abSAditya Srivastava $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; 2973831242abSAditya Srivastava } 2974831242abSAditya Srivastava } 2975ce0338dfSJoe Perches } 297620112475SJoe Perches if (defined $space_before && $space_before ne "") { 29773705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 29783705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 29793705ce5bSJoe Perches $fix) { 2980194f66fcSJoe Perches $fixed[$fixlinenr] = 29813705ce5bSJoe Perches "$ucfirst_sign_off $email"; 29823705ce5bSJoe Perches } 298320112475SJoe Perches } 298420112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 29853705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 29863705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 29873705ce5bSJoe Perches $fix) { 2988194f66fcSJoe Perches $fixed[$fixlinenr] = 29893705ce5bSJoe Perches "$ucfirst_sign_off $email"; 29903705ce5bSJoe Perches } 29913705ce5bSJoe Perches 299220112475SJoe Perches } 299320112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 29943705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 29953705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 29963705ce5bSJoe Perches $fix) { 2997194f66fcSJoe Perches $fixed[$fixlinenr] = 29983705ce5bSJoe Perches "$ucfirst_sign_off $email"; 29993705ce5bSJoe Perches } 300020112475SJoe Perches } 300120112475SJoe Perches 3002dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 300348ca2d8aSDwaipayan Ray my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); 300420112475SJoe Perches if ($suggested_email eq "") { 3005000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 3006000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 300720112475SJoe Perches } else { 300820112475SJoe Perches my $dequoted = $suggested_email; 300920112475SJoe Perches $dequoted =~ s/^"//; 301020112475SJoe Perches $dequoted =~ s/" </ </; 301120112475SJoe Perches # Don't force email to have quotes 301220112475SJoe Perches # Allow just an angle bracketed address 3013fccaebf0SDwaipayan Ray if (!same_email_addresses($email, $suggested_email)) { 3014fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3015fccaebf0SDwaipayan Ray "email address '$email' might be better as '$suggested_email'\n" . $herecurr) && 3016fccaebf0SDwaipayan Ray $fix) { 3017fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/; 3018fccaebf0SDwaipayan Ray } 3019fccaebf0SDwaipayan Ray } 3020fccaebf0SDwaipayan Ray 3021fccaebf0SDwaipayan Ray # Address part shouldn't have comments 3022fccaebf0SDwaipayan Ray my $stripped_address = $email_address; 3023fccaebf0SDwaipayan Ray $stripped_address =~ s/\([^\(\)]*\)//g; 3024fccaebf0SDwaipayan Ray if ($email_address ne $stripped_address) { 3025fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3026fccaebf0SDwaipayan Ray "address part of email should not have comments: '$email_address'\n" . $herecurr) && 3027fccaebf0SDwaipayan Ray $fix) { 3028fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/; 3029fccaebf0SDwaipayan Ray } 3030fccaebf0SDwaipayan Ray } 3031fccaebf0SDwaipayan Ray 3032fccaebf0SDwaipayan Ray # Only one name comment should be allowed 3033fccaebf0SDwaipayan Ray my $comment_count = () = $name_comment =~ /\([^\)]+\)/g; 3034fccaebf0SDwaipayan Ray if ($comment_count > 1) { 3035000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 3036fccaebf0SDwaipayan Ray "Use a single name comment in email: '$email'\n" . $herecurr); 3037fccaebf0SDwaipayan Ray } 3038fccaebf0SDwaipayan Ray 3039fccaebf0SDwaipayan Ray 3040fccaebf0SDwaipayan Ray # [email protected] or [email protected] shouldn't 3041e73d2715SDwaipayan Ray # have an email name. In addition comments should strictly 3042fccaebf0SDwaipayan Ray # begin with a # 3043fccaebf0SDwaipayan Ray if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { 3044fccaebf0SDwaipayan Ray if (($comment ne "" && $comment !~ /^#.+/) || 3045fccaebf0SDwaipayan Ray ($email_name ne "")) { 3046fccaebf0SDwaipayan Ray my $cur_name = $email_name; 3047fccaebf0SDwaipayan Ray my $new_comment = $comment; 3048fccaebf0SDwaipayan Ray $cur_name =~ s/[a-zA-Z\s\-\"]+//g; 3049fccaebf0SDwaipayan Ray 3050fccaebf0SDwaipayan Ray # Remove brackets enclosing comment text 3051fccaebf0SDwaipayan Ray # and # from start of comments to get comment text 3052fccaebf0SDwaipayan Ray $new_comment =~ s/^\((.*)\)$/$1/; 3053fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3054fccaebf0SDwaipayan Ray $new_comment =~ s/^[\s\#]+|\s+$//g; 3055fccaebf0SDwaipayan Ray 3056fccaebf0SDwaipayan Ray $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); 3057fccaebf0SDwaipayan Ray $new_comment = " # $new_comment" if ($new_comment ne ""); 3058fccaebf0SDwaipayan Ray my $new_email = "$email_address$new_comment"; 3059fccaebf0SDwaipayan Ray 3060fccaebf0SDwaipayan Ray if (WARN("BAD_STABLE_ADDRESS_STYLE", 3061fccaebf0SDwaipayan Ray "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && 3062fccaebf0SDwaipayan Ray $fix) { 3063fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3064fccaebf0SDwaipayan Ray } 3065fccaebf0SDwaipayan Ray } 3066fccaebf0SDwaipayan Ray } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { 3067fccaebf0SDwaipayan Ray my $new_comment = $comment; 3068fccaebf0SDwaipayan Ray 3069fccaebf0SDwaipayan Ray # Extract comment text from within brackets or 3070fccaebf0SDwaipayan Ray # c89 style /*...*/ comments 3071fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3072fccaebf0SDwaipayan Ray $new_comment =~ s/^\/\*(.*)\*\/$/$1/; 3073fccaebf0SDwaipayan Ray 3074fccaebf0SDwaipayan Ray $new_comment = trim($new_comment); 3075fccaebf0SDwaipayan Ray $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo 3076fccaebf0SDwaipayan Ray $new_comment = "($new_comment)" if ($new_comment ne ""); 3077fccaebf0SDwaipayan Ray my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); 3078fccaebf0SDwaipayan Ray 3079fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3080fccaebf0SDwaipayan Ray "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && 3081fccaebf0SDwaipayan Ray $fix) { 3082fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3083fccaebf0SDwaipayan Ray } 308420112475SJoe Perches } 30850a920b5bSAndy Whitcroft } 30867e51f197SJoe Perches 30877e51f197SJoe Perches# Check for duplicate signatures 30887e51f197SJoe Perches my $sig_nospace = $line; 30897e51f197SJoe Perches $sig_nospace =~ s/\s//g; 30907e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 30917e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 30927e51f197SJoe Perches WARN("BAD_SIGN_OFF", 30937e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 30947e51f197SJoe Perches } else { 30957e51f197SJoe Perches $signatures{$sig_nospace} = 1; 30967e51f197SJoe Perches } 30976c5d24eeSSean Christopherson 30986c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 30996c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 31006c5d24eeSSean Christopherson if ($email eq $author) { 31016c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31026c5d24eeSSean Christopherson "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); 31036c5d24eeSSean Christopherson } 31046c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 31056c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31066c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); 31076c5d24eeSSean Christopherson } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { 31086c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31096c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 31106c5d24eeSSean Christopherson } elsif ($1 ne $email) { 31116c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31126c5d24eeSSean Christopherson "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 31136c5d24eeSSean Christopherson } 31146c5d24eeSSean Christopherson } 31150a920b5bSAndy Whitcroft } 31160a920b5bSAndy Whitcroft 3117a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 3118a2fe16b9SJoe Perches if ($in_header_lines && 3119a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 3120a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 3121a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 3122a2fe16b9SJoe Perches } 3123a2fe16b9SJoe Perches 312444d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context 312544d303ebSJoe Perches if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { 31267580c5b9SAditya Srivastava if (ERROR("GERRIT_CHANGE_ID", 31277580c5b9SAditya Srivastava "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && 31287580c5b9SAditya Srivastava $fix) { 31297580c5b9SAditya Srivastava fix_delete_line($fixlinenr, $rawline); 31307580c5b9SAditya Srivastava } 31317ebd05efSChristopher Covington } 31327ebd05efSChristopher Covington 3133369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 3134369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3135369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 3136369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 3137369c8dd3SJoe Perches # timestamp 3138634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 3139634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 3140634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 3141634cffccSJoe Perches # stack dump address styles 3142369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 3143369c8dd3SJoe Perches } 3144369c8dd3SJoe Perches 31452a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 31462a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 3147bf4daf12SJoe Perches length($line) > 75 && 3148bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 3149bf4daf12SJoe Perches # file delta changes 3150bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 3151bf4daf12SJoe Perches # filename then : 315227b379afSAditya Srivastava $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i || 315327b379afSAditya Srivastava # A Fixes: or Link: line or signature tag line 3154bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 31552a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 31562a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 31572a076f40SJoe Perches $commit_log_long_line = 1; 31582a076f40SJoe Perches } 31592a076f40SJoe Perches 3160bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 3161bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 3162bf4daf12SJoe Perches $line =~ /^\s*$/) { 3163bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 3164bf4daf12SJoe Perches } 3165bf4daf12SJoe Perches 3166084a617aSDwaipayan Ray# Check for lines starting with a # 3167084a617aSDwaipayan Ray if ($in_commit_log && $line =~ /^#/) { 3168084a617aSDwaipayan Ray if (WARN("COMMIT_COMMENT_SYMBOL", 3169084a617aSDwaipayan Ray "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && 3170084a617aSDwaipayan Ray $fix) { 3171084a617aSDwaipayan Ray $fixed[$fixlinenr] =~ s/^/ /; 3172084a617aSDwaipayan Ray } 3173084a617aSDwaipayan Ray } 3174084a617aSDwaipayan Ray 31750d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 3176*4ce9f970SJoe Perches# A correctly formed commit description is: 3177*4ce9f970SJoe Perches# commit <SHA-1 hash length 12+ chars> ("Complete commit subject") 3178*4ce9f970SJoe Perches# with the commit subject '("' prefix and '")' suffix 3179*4ce9f970SJoe Perches# This is a fairly compilicated block as it tests for what appears to be 3180*4ce9f970SJoe Perches# bare SHA-1 hash with minimum length of 5. It also avoids several types of 3181*4ce9f970SJoe Perches# possible SHA-1 matches. 3182*4ce9f970SJoe Perches# A commit match can span multiple lines so this block attempts to find a 3183*4ce9f970SJoe Perches# complete typical commit on a maximum of 3 lines 3184*4ce9f970SJoe Perches if ($perl_version_ok && 3185*4ce9f970SJoe Perches $in_commit_log && !$commit_log_possible_stack_dump && 3186a8972573SJohn Hubbard $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && 3187e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 3188*4ce9f970SJoe Perches (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 3189*4ce9f970SJoe Perches ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) || 3190aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 3191369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 3192bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 3193fe043ea1SJoe Perches my $init_char = "c"; 3194fe043ea1SJoe Perches my $orig_commit = ""; 31950d7835fcSJoe Perches my $short = 1; 31960d7835fcSJoe Perches my $long = 0; 31970d7835fcSJoe Perches my $case = 1; 31980d7835fcSJoe Perches my $space = 1; 31990d7835fcSJoe Perches my $id = '0123456789ab'; 32000d7835fcSJoe Perches my $orig_desc = "commit description"; 32010d7835fcSJoe Perches my $description = ""; 3202*4ce9f970SJoe Perches my $herectx = $herecurr; 3203*4ce9f970SJoe Perches my $has_parens = 0; 3204*4ce9f970SJoe Perches my $has_quotes = 0; 32050d7835fcSJoe Perches 3206*4ce9f970SJoe Perches my $input = $line; 3207*4ce9f970SJoe Perches if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) { 3208*4ce9f970SJoe Perches for (my $n = 0; $n < 2; $n++) { 3209*4ce9f970SJoe Perches if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) { 3210*4ce9f970SJoe Perches $orig_desc = $1; 3211*4ce9f970SJoe Perches $has_parens = 1; 3212*4ce9f970SJoe Perches # Always strip leading/trailing parens then double quotes if existing 3213*4ce9f970SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 3214*4ce9f970SJoe Perches if ($orig_desc =~ /^".*"$/) { 3215*4ce9f970SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 3216*4ce9f970SJoe Perches $has_quotes = 1; 3217*4ce9f970SJoe Perches } 3218*4ce9f970SJoe Perches last; 3219*4ce9f970SJoe Perches } 3220*4ce9f970SJoe Perches last if ($#lines < $linenr + $n); 3221*4ce9f970SJoe Perches $input .= " " . trim($rawlines[$linenr + $n]); 3222*4ce9f970SJoe Perches $herectx .= "$rawlines[$linenr + $n]\n"; 3223*4ce9f970SJoe Perches } 3224*4ce9f970SJoe Perches $herectx = $herecurr if (!$has_parens); 3225fe043ea1SJoe Perches } 3226fe043ea1SJoe Perches 3227*4ce9f970SJoe Perches if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 3228*4ce9f970SJoe Perches $init_char = $1; 3229*4ce9f970SJoe Perches $orig_commit = lc($2); 3230*4ce9f970SJoe Perches $short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i); 3231*4ce9f970SJoe Perches $long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i); 3232*4ce9f970SJoe Perches $space = 0 if ($input =~ /\bcommit [0-9a-f]/i); 3233*4ce9f970SJoe Perches $case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 3234*4ce9f970SJoe Perches } elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) { 3235*4ce9f970SJoe Perches $orig_commit = lc($1); 32360d7835fcSJoe Perches } 32370d7835fcSJoe Perches 32380d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 32390d7835fcSJoe Perches $id, $orig_desc); 32400d7835fcSJoe Perches 3241948b133aSHeinrich Schuchardt if (defined($id) && 3242*4ce9f970SJoe Perches ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) && 3243*4ce9f970SJoe Perches $last_git_commit_id_linenr != $linenr - 1) { 3244d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 3245*4ce9f970SJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx); 32460d7835fcSJoe Perches } 3247*4ce9f970SJoe Perches #don't report the next line if this line ends in commit and the sha1 hash is the next line 3248*4ce9f970SJoe Perches $last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i); 3249d311cd44SJoe Perches } 3250d311cd44SJoe Perches 325113f1937eSJoe Perches# Check for added, moved or deleted files 325213f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 325313f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 325413f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 325513f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 325613f1937eSJoe Perches (defined($1) || defined($2))))) { 3257a82603a8SAndrew Jeffery $is_patch = 1; 325813f1937eSJoe Perches $reported_maintainer_file = 1; 325913f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 326013f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 326113f1937eSJoe Perches } 326213f1937eSJoe Perches 3263e400edb1SRob Herring# Check for adding new DT bindings not in schema format 3264e400edb1SRob Herring if (!$in_commit_log && 3265e400edb1SRob Herring ($line =~ /^new file mode\s*\d+\s*$/) && 3266e400edb1SRob Herring ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { 3267e400edb1SRob Herring WARN("DT_SCHEMA_BINDING_PATCH", 326856ddc4cdSMauro Carvalho Chehab "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n"); 3269e400edb1SRob Herring } 3270e400edb1SRob Herring 327100df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 32728905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 3273000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 3274000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 32756c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 3276de7d4f0eSAndy Whitcroft } 3277de7d4f0eSAndy Whitcroft 3278de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 3279de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 3280171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 3281171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 3282171ae1a4SAndy Whitcroft 3283171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 3284171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 3285171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 3286171ae1a4SAndy Whitcroft 328734d99219SJoe Perches CHK("INVALID_UTF8", 3288000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 328900df344fSAndy Whitcroft } 32900a920b5bSAndy Whitcroft 329115662b3eSJoe Perches# Check if it's the start of a commit log 329215662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 329315662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 3294eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 3295eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 329615662b3eSJoe Perches $in_header_lines = 0; 329715662b3eSJoe Perches $in_commit_log = 1; 3298ed43c4e5SAllen Hubbe $has_commit_log = 1; 329915662b3eSJoe Perches } 330015662b3eSJoe Perches 3301fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 3302fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 3303fa64205dSPasi Savanainen if ($in_header_lines && 3304fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 3305fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 3306fa64205dSPasi Savanainen $non_utf8_charset = 1; 3307fa64205dSPasi Savanainen } 3308fa64205dSPasi Savanainen 3309fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 331015662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 3311fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 331215662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 331315662b3eSJoe Perches } 331415662b3eSJoe Perches 3315d6430f71SJoe Perches# Check for absolute kernel paths in commit message 3316d6430f71SJoe Perches if ($tree && $in_commit_log) { 3317d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 3318d6430f71SJoe Perches my $file = $1; 3319d6430f71SJoe Perches 3320d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 3321d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 3322d6430f71SJoe Perches # 3323d6430f71SJoe Perches } else { 3324d6430f71SJoe Perches check_absolute_file($file, $herecurr); 3325d6430f71SJoe Perches } 3326d6430f71SJoe Perches } 3327d6430f71SJoe Perches } 3328d6430f71SJoe Perches 332966b47b4aSKees Cook# Check for various typo / spelling mistakes 333066d7a382SJoe Perches if (defined($misspellings) && 333166d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 33327da07c31SDwaipayan Ray while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { 333366b47b4aSKees Cook my $typo = $1; 33347da07c31SDwaipayan Ray my $blank = copy_spacing($rawline); 33357da07c31SDwaipayan Ray my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); 33367da07c31SDwaipayan Ray my $hereptr = "$hereline$ptr\n"; 333766b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 333866b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 333966b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 33400675a8fbSJean Delvare my $msg_level = \&WARN; 33410675a8fbSJean Delvare $msg_level = \&CHK if ($file); 33420675a8fbSJean Delvare if (&{$msg_level}("TYPO_SPELLING", 33437da07c31SDwaipayan Ray "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && 334466b47b4aSKees Cook $fix) { 334566b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 334666b47b4aSKees Cook } 334766b47b4aSKees Cook } 334866b47b4aSKees Cook } 334966b47b4aSKees Cook 3350a8dd86bfSMatteo Croce# check for invalid commit id 3351a8dd86bfSMatteo Croce if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 3352a8dd86bfSMatteo Croce my $id; 3353a8dd86bfSMatteo Croce my $description; 3354a8dd86bfSMatteo Croce ($id, $description) = git_commit_info($2, undef, undef); 3355a8dd86bfSMatteo Croce if (!defined($id)) { 3356a8dd86bfSMatteo Croce WARN("UNKNOWN_COMMIT_ID", 3357a8dd86bfSMatteo Croce "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 3358a8dd86bfSMatteo Croce } 3359a8dd86bfSMatteo Croce } 3360a8dd86bfSMatteo Croce 3361310cd06bSJoe Perches# check for repeated words separated by a single space 33628d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root' 33638d0325ccSAditya Srivastava if (($rawline =~ /^\+/ || $in_commit_log) && 33648d0325ccSAditya Srivastava $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { 33651db81a68SDwaipayan Ray pos($rawline) = 1 if (!$in_commit_log); 3366310cd06bSJoe Perches while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { 3367310cd06bSJoe Perches 3368310cd06bSJoe Perches my $first = $1; 3369310cd06bSJoe Perches my $second = $2; 33701db81a68SDwaipayan Ray my $start_pos = $-[1]; 33711db81a68SDwaipayan Ray my $end_pos = $+[2]; 3372310cd06bSJoe Perches if ($first =~ /(?:struct|union|enum)/) { 3373310cd06bSJoe Perches pos($rawline) += length($first) + length($second) + 1; 3374310cd06bSJoe Perches next; 3375310cd06bSJoe Perches } 3376310cd06bSJoe Perches 33771db81a68SDwaipayan Ray next if (lc($first) ne lc($second)); 3378310cd06bSJoe Perches next if ($first eq 'long'); 3379310cd06bSJoe Perches 33801db81a68SDwaipayan Ray # check for character before and after the word matches 33811db81a68SDwaipayan Ray my $start_char = ''; 33821db81a68SDwaipayan Ray my $end_char = ''; 33831db81a68SDwaipayan Ray $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); 33841db81a68SDwaipayan Ray $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); 33851db81a68SDwaipayan Ray 33861db81a68SDwaipayan Ray next if ($start_char =~ /^\S$/); 33871db81a68SDwaipayan Ray next if (index(" \t.,;?!", $end_char) == -1); 33881db81a68SDwaipayan Ray 33898d0325ccSAditya Srivastava # avoid repeating hex occurrences like 'ff ff fe 09 ...' 33908d0325ccSAditya Srivastava if ($first =~ /\b[0-9a-f]{2,}\b/i) { 33918d0325ccSAditya Srivastava next if (!exists($allow_repeated_words{lc($first)})); 33928d0325ccSAditya Srivastava } 33938d0325ccSAditya Srivastava 3394310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3395310cd06bSJoe Perches "Possible repeated word: '$first'\n" . $herecurr) && 3396310cd06bSJoe Perches $fix) { 3397310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; 3398310cd06bSJoe Perches } 3399310cd06bSJoe Perches } 3400310cd06bSJoe Perches 3401310cd06bSJoe Perches # if it's a repeated word on consecutive lines in a comment block 3402310cd06bSJoe Perches if ($prevline =~ /$;+\s*$/ && 3403310cd06bSJoe Perches $prevrawline =~ /($word_pattern)\s*$/) { 3404310cd06bSJoe Perches my $last_word = $1; 3405310cd06bSJoe Perches if ($rawline =~ /^\+\s*\*\s*$last_word /) { 3406310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3407310cd06bSJoe Perches "Possible repeated word: '$last_word'\n" . $hereprev) && 3408310cd06bSJoe Perches $fix) { 3409310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; 3410310cd06bSJoe Perches } 3411310cd06bSJoe Perches } 3412310cd06bSJoe Perches } 3413310cd06bSJoe Perches } 3414310cd06bSJoe Perches 341530670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 341630670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 341700df344fSAndy Whitcroft 34180a920b5bSAndy Whitcroft#trailing whitespace 34199c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 3420c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3421d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 3422d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 3423d5e616fcSJoe Perches $fix) { 3424194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 3425d5e616fcSJoe Perches } 3426c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 3427c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 34283705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 34293705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 34303705ce5bSJoe Perches $fix) { 3431194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 34323705ce5bSJoe Perches } 34333705ce5bSJoe Perches 3434d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 34350a920b5bSAndy Whitcroft } 34365368df20SAndy Whitcroft 34374783f894SJosh Triplett# Check for FSF mailing addresses. 3438109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 34391bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 34403e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 34413e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 34424783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 34430675a8fbSJean Delvare my $msg_level = \&ERROR; 34440675a8fbSJean Delvare $msg_level = \&CHK if ($file); 34450675a8fbSJean Delvare &{$msg_level}("FSF_MAILING_ADDRESS", 34464783f894SJosh 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) 34474783f894SJosh Triplett } 34484783f894SJosh Triplett 34493354957aSAndi Kleen# check for Kconfig help text having a real description 34509fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 34519fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 34523354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 3453678ae162SUlf Magnusson # 'choice' is usually the last thing on the line (though 3454678ae162SUlf Magnusson # Kconfig supports named choices), so use a word boundary 3455678ae162SUlf Magnusson # (\b) rather than a whitespace character (\s) 3456678ae162SUlf Magnusson $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 34573354957aSAndi Kleen my $length = 0; 34589fe287d7SAndy Whitcroft my $cnt = $realcnt; 34599fe287d7SAndy Whitcroft my $ln = $linenr + 1; 34609fe287d7SAndy Whitcroft my $f; 3461a1385803SAndy Whitcroft my $is_start = 0; 34629fe287d7SAndy Whitcroft my $is_end = 0; 3463a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 34649fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 34659fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 34669fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 34679fe287d7SAndy Whitcroft 34689fe287d7SAndy Whitcroft next if ($f =~ /^-/); 34698d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 3470a1385803SAndy Whitcroft 347186adf1a0SUlf Magnusson if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 3472a1385803SAndy Whitcroft $is_start = 1; 347322a4ac02SMasahiro Yamada } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 3474a1385803SAndy Whitcroft $length = -1; 3475a1385803SAndy Whitcroft } 3476a1385803SAndy Whitcroft 34779fe287d7SAndy Whitcroft $f =~ s/^.//; 34783354957aSAndi Kleen $f =~ s/#.*//; 34793354957aSAndi Kleen $f =~ s/^\s+//; 34803354957aSAndi Kleen next if ($f =~ /^$/); 3481678ae162SUlf Magnusson 3482678ae162SUlf Magnusson # This only checks context lines in the patch 3483678ae162SUlf Magnusson # and so hopefully shouldn't trigger false 3484678ae162SUlf Magnusson # positives, even though some of these are 3485678ae162SUlf Magnusson # common words in help texts 3486678ae162SUlf Magnusson if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| 3487678ae162SUlf Magnusson if|endif|menu|endmenu|source)\b/x) { 34889fe287d7SAndy Whitcroft $is_end = 1; 34899fe287d7SAndy Whitcroft last; 34909fe287d7SAndy Whitcroft } 34913354957aSAndi Kleen $length++; 34923354957aSAndi Kleen } 349356193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 3494000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 349556193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 349656193274SVadim Bendebury } 3497a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 34983354957aSAndi Kleen } 34993354957aSAndi Kleen 35007ccf41a8SJoe Perches# check MAINTAINERS entries 35017ccf41a8SJoe Perches if ($realfile =~ /^MAINTAINERS$/) { 35027ccf41a8SJoe Perches# check MAINTAINERS entries for the right form 35037ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 3504628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3505628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3506628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3507628f91a2SJoe Perches $fix) { 3508628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3509628f91a2SJoe Perches } 3510628f91a2SJoe Perches } 35117ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too 35127ccf41a8SJoe Perches my $preferred_order = 'MRLSWQBCPTFXNK'; 35137ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 35147ccf41a8SJoe Perches $prevrawline =~ /^[\+ ][A-Z]:/) { 35157ccf41a8SJoe Perches $rawline =~ /^\+([A-Z]):\s*(.*)/; 35167ccf41a8SJoe Perches my $cur = $1; 35177ccf41a8SJoe Perches my $curval = $2; 35187ccf41a8SJoe Perches $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; 35197ccf41a8SJoe Perches my $prev = $1; 35207ccf41a8SJoe Perches my $prevval = $2; 35217ccf41a8SJoe Perches my $curindex = index($preferred_order, $cur); 35227ccf41a8SJoe Perches my $previndex = index($preferred_order, $prev); 35237ccf41a8SJoe Perches if ($curindex < 0) { 35247ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 35257ccf41a8SJoe Perches "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); 35267ccf41a8SJoe Perches } else { 35277ccf41a8SJoe Perches if ($previndex >= 0 && $curindex < $previndex) { 35287ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 35297ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); 35307ccf41a8SJoe Perches } elsif ((($prev eq 'F' && $cur eq 'F') || 35317ccf41a8SJoe Perches ($prev eq 'X' && $cur eq 'X')) && 35327ccf41a8SJoe Perches ($prevval cmp $curval) > 0) { 35337ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 35347ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); 35357ccf41a8SJoe Perches } 35367ccf41a8SJoe Perches } 35377ccf41a8SJoe Perches } 35387ccf41a8SJoe Perches } 3539628f91a2SJoe Perches 3540c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3541c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3542c68e5878SArnaud Lacombe my $flag = $1; 3543c68e5878SArnaud Lacombe my $replacement = { 3544c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 3545c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 3546c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 3547c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 3548c68e5878SArnaud Lacombe }; 3549c68e5878SArnaud Lacombe 3550c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 3551c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3552c68e5878SArnaud Lacombe } 3553c68e5878SArnaud Lacombe 3554bff5da43SRob Herring# check for DT compatible documentation 35557dd05b38SFlorian Vaussard if (defined $root && 35567dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 35577dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 35587dd05b38SFlorian Vaussard 3559bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3560bff5da43SRob Herring 3561cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3562852d095dSRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3563cc93319bSFlorian Vaussard 3564bff5da43SRob Herring foreach my $compat (@compats) { 3565bff5da43SRob Herring my $compat2 = $compat; 3566185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3567185d566bSRob Herring my $compat3 = $compat; 3568185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3569185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3570bff5da43SRob Herring if ( $? >> 8 ) { 3571bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3572bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3573bff5da43SRob Herring } 3574bff5da43SRob Herring 35754fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 35764fbf32a6SFlorian Vaussard my $vendor = $1; 3577852d095dSRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3578bff5da43SRob Herring if ( $? >> 8 ) { 3579bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3580cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3581bff5da43SRob Herring } 3582bff5da43SRob Herring } 3583bff5da43SRob Herring } 3584bff5da43SRob Herring 35859f3a8992SRob Herring# check for using SPDX license tag at beginning of files 35869f3a8992SRob Herring if ($realline == $checklicenseline) { 35879f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 35889f3a8992SRob Herring $checklicenseline = 2; 35899f3a8992SRob Herring } elsif ($rawline =~ /^\+/) { 35909f3a8992SRob Herring my $comment = ""; 35919f3a8992SRob Herring if ($realfile =~ /\.(h|s|S)$/) { 35929f3a8992SRob Herring $comment = '/*'; 35939f3a8992SRob Herring } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { 35949f3a8992SRob Herring $comment = '//'; 3595c8df0ab6SLubomir Rintel } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 35969f3a8992SRob Herring $comment = '#'; 35979f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 35989f3a8992SRob Herring $comment = '..'; 35999f3a8992SRob Herring } 36009f3a8992SRob Herring 3601fdf13693SJoe Perches# check SPDX comment style for .[chsS] files 3602fdf13693SJoe Perches if ($realfile =~ /\.[chsS]$/ && 3603fdf13693SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 3604ffbce897SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 3605fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3606fdf13693SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3607fdf13693SJoe Perches } 3608fdf13693SJoe Perches 36099f3a8992SRob Herring if ($comment !~ /^$/ && 3610ffbce897SJoe Perches $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 36119f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 36129f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 36133b6e8ac9SJoe Perches } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 36143b6e8ac9SJoe Perches my $spdx_license = $1; 36153b6e8ac9SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 36163b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 36173b6e8ac9SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 36183b6e8ac9SJoe Perches } 361950c92900SLubomir Rintel if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 362050c92900SLubomir Rintel not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { 362150c92900SLubomir Rintel my $msg_level = \&WARN; 362250c92900SLubomir Rintel $msg_level = \&CHK if ($file); 362350c92900SLubomir Rintel if (&{$msg_level}("SPDX_LICENSE_TAG", 362450c92900SLubomir Rintel 362550c92900SLubomir Rintel "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 362650c92900SLubomir Rintel $fix) { 362750c92900SLubomir Rintel $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 362850c92900SLubomir Rintel } 362950c92900SLubomir Rintel } 36309f3a8992SRob Herring } 36319f3a8992SRob Herring } 36329f3a8992SRob Herring } 36339f3a8992SRob Herring 3634a0154cdbSJoe Perches# check for embedded filenames 3635a0154cdbSJoe Perches if ($rawline =~ /^\+.*\Q$realfile\E/) { 3636a0154cdbSJoe Perches WARN("EMBEDDED_FILENAME", 3637a0154cdbSJoe Perches "It's generally not useful to have the filename in the file\n" . $herecurr); 3638a0154cdbSJoe Perches } 3639a0154cdbSJoe Perches 36405368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 3641d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 36425368df20SAndy Whitcroft 3643a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3644a8da38a9SJoe Perches if ($realline != $checklicenseline && 3645a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3646a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3647a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3648a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3649a8da38a9SJoe Perches } 3650a8da38a9SJoe Perches 365147e0c88bSJoe Perches# line length limit (with some exclusions) 365247e0c88bSJoe Perches# 365347e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 365447e0c88bSJoe Perches# logging functions like pr_info that end in a string 365547e0c88bSJoe Perches# lines with a single string 365647e0c88bSJoe Perches# #defines that are a single string 36572e4bbbc5SAndreas Brauchli# lines with an RFC3986 like URL 365847e0c88bSJoe Perches# 365947e0c88bSJoe Perches# There are 3 different line length message types: 3660ab1ecabfSJean Delvare# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 366147e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 366247e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 366347e0c88bSJoe Perches# 366447e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 366547e0c88bSJoe Perches# 366647e0c88bSJoe Perches 3667b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 366847e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 366947e0c88bSJoe Perches 367047e0c88bSJoe Perches # Check the allowed long line types first 367147e0c88bSJoe Perches 367247e0c88bSJoe Perches # logging functions that end in a string that starts 367347e0c88bSJoe Perches # before $max_line_length 367447e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 367547e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 367647e0c88bSJoe Perches $msg_type = ""; 367747e0c88bSJoe Perches 367847e0c88bSJoe Perches # lines with only strings (w/ possible termination) 367947e0c88bSJoe Perches # #defines with only strings 368047e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 368147e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 368247e0c88bSJoe Perches $msg_type = ""; 368347e0c88bSJoe Perches 3684cc147506SJoe Perches # More special cases 3685cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3686cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3687d560a5f8SJoe Perches $msg_type = ""; 3688d560a5f8SJoe Perches 36892e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 36902e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 36912e4bbbc5SAndreas Brauchli $msg_type = ""; 36922e4bbbc5SAndreas Brauchli 369347e0c88bSJoe Perches # Otherwise set the alternate message types 369447e0c88bSJoe Perches 369547e0c88bSJoe Perches # a comment starts before $max_line_length 369647e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 369747e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 369847e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 369947e0c88bSJoe Perches 370047e0c88bSJoe Perches # a quoted string starts before $max_line_length 370147e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 370247e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 370347e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 370447e0c88bSJoe Perches } 370547e0c88bSJoe Perches 370647e0c88bSJoe Perches if ($msg_type ne "" && 370747e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 3708bdc48fa1SJoe Perches my $msg_level = \&WARN; 3709bdc48fa1SJoe Perches $msg_level = \&CHK if ($file); 3710bdc48fa1SJoe Perches &{$msg_level}($msg_type, 3711bdc48fa1SJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 37120a920b5bSAndy Whitcroft } 371347e0c88bSJoe Perches } 37140a920b5bSAndy Whitcroft 37158905a67cSAndy Whitcroft# check for adding lines without a newline. 37168905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 371747ca69b8STom Rix if (WARN("MISSING_EOF_NEWLINE", 371847ca69b8STom Rix "adding a line without newline at end of file\n" . $herecurr) && 371947ca69b8STom Rix $fix) { 372047ca69b8STom Rix fix_delete_line($fixlinenr+1, "No newline at end of file"); 372147ca69b8STom Rix } 37228905a67cSAndy Whitcroft } 37238905a67cSAndy Whitcroft 3724de93245cSAditya Srivastava# check for .L prefix local symbols in .S files 3725de93245cSAditya Srivastava if ($realfile =~ /\.S$/ && 3726de93245cSAditya Srivastava $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { 3727de93245cSAditya Srivastava WARN("AVOID_L_PREFIX", 3728de93245cSAditya 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); 3729de93245cSAditya Srivastava } 3730de93245cSAditya Srivastava 3731b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3732de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 37330a920b5bSAndy Whitcroft 37340a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 3735713a09deSAntonio Borneo# more than $tabsize must use tabs. 3736c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3737c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3738c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3739d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 37403705ce5bSJoe Perches if (ERROR("CODE_INDENT", 37413705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 37423705ce5bSJoe Perches $fix) { 3743194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 37443705ce5bSJoe Perches } 37450a920b5bSAndy Whitcroft } 37460a920b5bSAndy Whitcroft 374708e44365SAlberto Panizzo# check for space before tabs. 374808e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 374908e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 37503705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 37513705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 37523705ce5bSJoe Perches $fix) { 3753194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3754713a09deSAntonio Borneo s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 3755194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3756c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 37573705ce5bSJoe Perches } 375808e44365SAlberto Panizzo } 375908e44365SAlberto Panizzo 37606a487211SJoe Perches# check for assignments on the start of a line 37616a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 3762da7355abSAditya Srivastava my $operator = $1; 3763da7355abSAditya Srivastava if (CHK("ASSIGNMENT_CONTINUATIONS", 3764da7355abSAditya Srivastava "Assignment operator '$1' should be on the previous line\n" . $hereprev) && 3765da7355abSAditya Srivastava $fix && $prevrawline =~ /^\+/) { 3766da7355abSAditya Srivastava # add assignment operator to the previous line, remove from current line 3767da7355abSAditya Srivastava $fixed[$fixlinenr - 1] .= " $operator"; 3768da7355abSAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 3769da7355abSAditya Srivastava } 37706a487211SJoe Perches } 37716a487211SJoe Perches 3772d1fe9c09SJoe Perches# check for && or || at the start of a line 3773d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 37748e08f076SAditya Srivastava my $operator = $1; 37758e08f076SAditya Srivastava if (CHK("LOGICAL_CONTINUATIONS", 37768e08f076SAditya Srivastava "Logical continuations should be on the previous line\n" . $hereprev) && 37778e08f076SAditya Srivastava $fix && $prevrawline =~ /^\+/) { 37788e08f076SAditya Srivastava # insert logical operator at last non-comment, non-whitepsace char on previous line 37798e08f076SAditya Srivastava $prevline =~ /[\s$;]*$/; 37808e08f076SAditya Srivastava my $line_end = substr($prevrawline, $-[0]); 37818e08f076SAditya Srivastava $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; 37828e08f076SAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 37838e08f076SAditya Srivastava } 3784d1fe9c09SJoe Perches } 3785d1fe9c09SJoe Perches 3786a91e8994SJoe Perches# check indentation starts on a tab stop 37875b57980dSJoe Perches if ($perl_version_ok && 3788bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3789a91e8994SJoe Perches my $indent = length($1); 3790713a09deSAntonio Borneo if ($indent % $tabsize) { 3791a91e8994SJoe Perches if (WARN("TABSTOP", 3792a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3793a91e8994SJoe Perches $fix) { 3794713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 3795a91e8994SJoe Perches } 3796a91e8994SJoe Perches } 3797a91e8994SJoe Perches } 3798a91e8994SJoe Perches 3799d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 38005b57980dSJoe Perches if ($perl_version_ok && 3801fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3802d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3803d1fe9c09SJoe Perches my $oldindent = $1; 3804d1fe9c09SJoe Perches my $rest = $2; 3805d1fe9c09SJoe Perches 3806d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3807d1fe9c09SJoe Perches if ($pos >= 0) { 3808b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3809b34a26f3SJoe Perches my $newindent = $2; 3810d1fe9c09SJoe Perches 3811d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3812713a09deSAntonio Borneo "\t" x ($pos / $tabsize) . 3813713a09deSAntonio Borneo " " x ($pos % $tabsize); 3814d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3815d1fe9c09SJoe Perches 3816d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3817d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 38183705ce5bSJoe Perches 38193705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 38203705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 38213705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3822194f66fcSJoe Perches $fixed[$fixlinenr] =~ 38233705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 38243705ce5bSJoe Perches } 3825d1fe9c09SJoe Perches } 3826d1fe9c09SJoe Perches } 3827d1fe9c09SJoe Perches } 3828d1fe9c09SJoe Perches 38296ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 38306ab3a970SJoe Perches# avoid checking a few false positives: 38316ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 38326ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 38336ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 38346ab3a970SJoe Perches# multiline macros that define functions 38356ab3a970SJoe Perches# known attributes or the __attribute__ keyword 38366ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 38376ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 38383705ce5bSJoe Perches if (CHK("SPACING", 3839f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 38403705ce5bSJoe Perches $fix) { 3841194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3842f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 38433705ce5bSJoe Perches } 3844aad4f614SJoe Perches } 3845aad4f614SJoe Perches 384686406b1cSJoe Perches# Block comment styles 384786406b1cSJoe Perches# Networking with an initial /* 384805880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3849fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 385085ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 3851c70735c2SŁukasz Stelmach $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier 385205880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 385305880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 385405880600SJoe Perches } 385505880600SJoe Perches 385686406b1cSJoe Perches# Block comments use * on subsequent lines 385786406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 385886406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3859a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 386061135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3861a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 386286406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 386386406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3864a605e32eSJoe Perches } 3865a605e32eSJoe Perches 386686406b1cSJoe Perches# Block comments use */ on trailing lines 386786406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3868c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3869c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3870c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 387186406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 387286406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 387305880600SJoe Perches } 387405880600SJoe Perches 387508eb9b80SJoe Perches# Block comment * alignment 387608eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3877af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3878af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3879af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 388008eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3881af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3882af207524SJoe Perches my $oldindent; 388308eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3884af207524SJoe Perches if (defined($1)) { 3885af207524SJoe Perches $oldindent = expand_tabs($1); 3886af207524SJoe Perches } else { 3887af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3888af207524SJoe Perches $oldindent = expand_tabs($1); 3889af207524SJoe Perches } 389008eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 389108eb9b80SJoe Perches my $newindent = $1; 389208eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3893af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 389408eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 389508eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 389608eb9b80SJoe Perches } 389708eb9b80SJoe Perches } 389808eb9b80SJoe Perches 38997f619191SJoe Perches# check for missing blank lines after struct/union declarations 39007f619191SJoe Perches# with exceptions for various attributes and macros 39017f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 39027f619191SJoe Perches $line =~ /^\+/ && 39037f619191SJoe Perches !($line =~ /^\+\s*$/ || 39047f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 39057f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 39067f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 39077f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 39087f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 39097f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 39100bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 39117f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3912d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3913d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3914d752fcc8SJoe Perches $fix) { 3915f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3916d752fcc8SJoe Perches } 39177f619191SJoe Perches } 39187f619191SJoe Perches 3919365dd4eaSJoe Perches# check for multiple consecutive blank lines 3920365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3921365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3922365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3923d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3924d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3925d752fcc8SJoe Perches $fix) { 3926f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3927d752fcc8SJoe Perches } 3928d752fcc8SJoe Perches 3929365dd4eaSJoe Perches $last_blank_line = $linenr; 3930365dd4eaSJoe Perches } 3931365dd4eaSJoe Perches 39323b617e3bSJoe Perches# check for missing blank lines after declarations 3933b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line) 3934b5e8736aSJoe Perches if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) { 3935b5e8736aSJoe Perches # use temporaries 3936b5e8736aSJoe Perches my $sl = $sline; 3937b5e8736aSJoe Perches my $pl = $prevline; 3938b5e8736aSJoe Perches # remove $Attribute/$Sparse uses to simplify comparisons 3939b5e8736aSJoe Perches $sl =~ s/\b(?:$Attribute|$Sparse)\b//g; 3940b5e8736aSJoe Perches $pl =~ s/\b(?:$Attribute|$Sparse)\b//g; 3941b5e8736aSJoe Perches if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 39425a4e1fd3SJoe Perches # function pointer declarations 3943b5e8736aSJoe Perches $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 39443f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 3945b5e8736aSJoe Perches $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 39463f7bac03SJoe Perches # known declaration macros 3947b5e8736aSJoe Perches $pl =~ /^\+\s+$declaration_macros/) && 39483f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 3949b5e8736aSJoe Perches !($pl =~ /^\+\s+$c90_Keywords\b/ || 39503f7bac03SJoe Perches # other possible extensions of declaration lines 3951b5e8736aSJoe Perches $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 39523f7bac03SJoe Perches # not starting a section or a macro "\" extended line 3953b5e8736aSJoe Perches $pl =~ /(?:\{\s*|\\)$/) && 39543f7bac03SJoe Perches # looks like a declaration 3955b5e8736aSJoe Perches !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 39565a4e1fd3SJoe Perches # function pointer declarations 3957b5e8736aSJoe Perches $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 39583f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 3959b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 39603f7bac03SJoe Perches # known declaration macros 3961b5e8736aSJoe Perches $sl =~ /^\+\s+$declaration_macros/ || 39623f7bac03SJoe Perches # start of struct or union or enum 3963b5e8736aSJoe Perches $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 39643f7bac03SJoe Perches # start or end of block or continuation of declaration 3965b5e8736aSJoe Perches $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 39663f7bac03SJoe Perches # bitfield continuation 3967b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 39683f7bac03SJoe Perches # other possible extensions of declaration lines 3969b5e8736aSJoe Perches $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) { 3970d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3971d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3972d752fcc8SJoe Perches $fix) { 3973f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3974d752fcc8SJoe Perches } 39753b617e3bSJoe Perches } 3976b5e8736aSJoe Perches } 39773b617e3bSJoe Perches 39785f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 39796b4c5bebSAndy Whitcroft# Exceptions: 39806b4c5bebSAndy Whitcroft# 1) within comments 39816b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 39826b4c5bebSAndy Whitcroft# 3) hanging labels 39833705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 39845f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 39853705ce5bSJoe Perches if (WARN("LEADING_SPACE", 39863705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 39873705ce5bSJoe Perches $fix) { 3988194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 39893705ce5bSJoe Perches } 39905f7ddae6SRaffaele Recalcati } 39915f7ddae6SRaffaele Recalcati 3992b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3993b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3994b9ea10d6SAndy Whitcroft 39955751a24eSJoe Perches# check for unusual line ending [ or ( 39965751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 39975751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 39985751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 39995751a24eSJoe Perches } 40005751a24eSJoe Perches 40014dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 40024dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 40034dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 40044dbed76fSJoe Perches $context_function = $1; 40054dbed76fSJoe Perches } 40064dbed76fSJoe Perches 40074dbed76fSJoe Perches# check if this appears to be the end of function declaration 40084dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 40094dbed76fSJoe Perches undef $context_function; 40104dbed76fSJoe Perches } 40114dbed76fSJoe Perches 4012032a4c0fSJoe Perches# check indentation of any line with a bare else 4013840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 4014032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 4015032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 4016032a4c0fSJoe Perches my $tabs = length($1) + 1; 4017840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 4018840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 4019840080a0SJoe Perches defined $lines[$linenr] && 4020840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 4021032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 4022032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 4023032a4c0fSJoe Perches } 4024032a4c0fSJoe Perches } 4025032a4c0fSJoe Perches 4026c00df19aSJoe Perches# check indentation of a line with a break; 4027dc58bc55SJoe Perches# if the previous line is a goto, return or break 4028dc58bc55SJoe Perches# and is indented the same # of tabs 4029c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 4030c00df19aSJoe Perches my $tabs = $1; 4031dc58bc55SJoe Perches if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { 4032dc58bc55SJoe Perches if (WARN("UNNECESSARY_BREAK", 4033dc58bc55SJoe Perches "break is not useful after a $1\n" . $hereprev) && 4034dc58bc55SJoe Perches $fix) { 4035dc58bc55SJoe Perches fix_delete_line($fixlinenr, $rawline); 4036dc58bc55SJoe Perches } 4037c00df19aSJoe Perches } 4038c00df19aSJoe Perches } 4039c00df19aSJoe Perches 4040c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 4041cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 4042000d1cc1SJoe Perches WARN("CVS_KEYWORD", 4043000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 4044c2fdda0dSAndy Whitcroft } 404522f2a2efSAndy Whitcroft 404656e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 404756e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 404856e77d70SJoe Perches WARN("HOTPLUG_SECTION", 404956e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 405056e77d70SJoe Perches } 405156e77d70SJoe Perches 40529c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 40532b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 40542b474a1aSAndy Whitcroft $realline_next); 40553e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 4056ca819864SJoe Perches if ($linenr > $suppress_statement && 40571b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 4058170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 4059f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4060171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 4061171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 4062171ae1a4SAndy Whitcroft 40633e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 40643e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 40653e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 40663e469cdcSAndy Whitcroft # until we hit end of it. 40673e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 40683e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 40693e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 40703e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 40713e469cdcSAndy Whitcroft } 4072f74bd194SAndy Whitcroft 40732b474a1aSAndy Whitcroft # Find the real next line. 40742b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 40752b474a1aSAndy Whitcroft if (defined $realline_next && 40762b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 40772b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 40782b474a1aSAndy Whitcroft $realline_next++; 40792b474a1aSAndy Whitcroft } 40802b474a1aSAndy Whitcroft 4081171ae1a4SAndy Whitcroft my $s = $stat; 4082171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 4083cf655043SAndy Whitcroft 4084c2fdda0dSAndy Whitcroft # Ignore goto labels. 4085171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 4086c2fdda0dSAndy Whitcroft 4087c2fdda0dSAndy Whitcroft # Ignore functions being called 4088171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 4089c2fdda0dSAndy Whitcroft 4090463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 4091463f2864SAndy Whitcroft 4092c45dcabdSAndy Whitcroft # declarations always start with types 4093d2506586SAndy 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) { 4094c45dcabdSAndy Whitcroft my $type = $1; 4095c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 4096c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 4097c45dcabdSAndy Whitcroft 40986c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 4099a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 4100c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 4101c2fdda0dSAndy Whitcroft } 41028905a67cSAndy Whitcroft 41036c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 410465863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 4105c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 41069c0ca6f9SAndy Whitcroft } 41078905a67cSAndy Whitcroft 41088905a67cSAndy Whitcroft # Check for any sort of function declaration. 41098905a67cSAndy Whitcroft # int foo(something bar, other baz); 41108905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 4111171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 41128905a67cSAndy Whitcroft my ($name_len) = length($1); 41138905a67cSAndy Whitcroft 4114cf655043SAndy Whitcroft my $ctx = $s; 4115773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 41168905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 4117cf655043SAndy Whitcroft 41188905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 4119c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 41208905a67cSAndy Whitcroft 4121c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 41228905a67cSAndy Whitcroft } 41238905a67cSAndy Whitcroft } 41248905a67cSAndy Whitcroft } 41258905a67cSAndy Whitcroft 41269c0ca6f9SAndy Whitcroft } 41279c0ca6f9SAndy Whitcroft 412800df344fSAndy Whitcroft# 412900df344fSAndy Whitcroft# Checks which may be anchored in the context. 413000df344fSAndy Whitcroft# 413100df344fSAndy Whitcroft 413200df344fSAndy Whitcroft# Check for switch () and associated case and default 413300df344fSAndy Whitcroft# statements should be at the same indent. 413400df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 413500df344fSAndy Whitcroft my $err = ''; 413600df344fSAndy Whitcroft my $sep = ''; 413700df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 413800df344fSAndy Whitcroft shift(@ctx); 413900df344fSAndy Whitcroft for my $ctx (@ctx) { 414000df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 414100df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 414200df344fSAndy Whitcroft $indent != $cindent) { 414300df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 414400df344fSAndy Whitcroft $sep = ''; 414500df344fSAndy Whitcroft } else { 414600df344fSAndy Whitcroft $sep = "[...]\n"; 414700df344fSAndy Whitcroft } 414800df344fSAndy Whitcroft } 414900df344fSAndy Whitcroft if ($err ne '') { 4150000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 4151000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 4152de7d4f0eSAndy Whitcroft } 4153de7d4f0eSAndy Whitcroft } 4154de7d4f0eSAndy Whitcroft 4155de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 4156de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 41570fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 4158773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 4159773647a0SAndy Whitcroft 41609c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 41618eef05ddSJoe Perches 41628eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 41638eef05ddSJoe Perches WARN("DEEP_INDENTATION", 41648eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 41658eef05ddSJoe Perches } 41668eef05ddSJoe Perches 4167de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 4168de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 4169de7d4f0eSAndy Whitcroft 4170548596d5SAndy Whitcroft my $ctx_ln = $linenr; 4171548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 4172de7d4f0eSAndy Whitcroft 4173548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 4174548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 4175548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 4176548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 4177548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 4178773647a0SAndy Whitcroft $ctx_ln++; 4179773647a0SAndy Whitcroft } 4180548596d5SAndy Whitcroft 418153210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 418253210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 4183773647a0SAndy Whitcroft 4184773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 4185000d1cc1SJoe Perches ERROR("OPEN_BRACE", 4186000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 418701464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 418800df344fSAndy Whitcroft } 4189773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 4190773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 4191773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 4192773647a0SAndy Whitcroft { 41939c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 41949c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 4195000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 4196000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 419701464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 41989c0ca6f9SAndy Whitcroft } 41999c0ca6f9SAndy Whitcroft } 420000df344fSAndy Whitcroft } 420100df344fSAndy Whitcroft 42024d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 4203f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 42043e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 42053e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 42063e469cdcSAndy Whitcroft if (!defined $stat); 42074d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 42084d001e4dSAndy Whitcroft 42094d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 42104d001e4dSAndy Whitcroft 42119f5af480SJoe Perches # remove inline comments 42129f5af480SJoe Perches $s =~ s/$;/ /g; 42139f5af480SJoe Perches $c =~ s/$;/ /g; 42144d001e4dSAndy Whitcroft 42154d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 42166f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 42176f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 42184d001e4dSAndy Whitcroft 42199f5af480SJoe Perches # Make sure we remove the line prefixes as we have 42209f5af480SJoe Perches # none on the first line, and are going to readd them 42219f5af480SJoe Perches # where necessary. 42229f5af480SJoe Perches $s =~ s/\n./\n/gs; 42239f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 42249f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 42259f5af480SJoe Perches } 42269f5af480SJoe Perches 42274d001e4dSAndy Whitcroft # We want to check the first line inside the block 42284d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 42294d001e4dSAndy Whitcroft # 1) any blank line termination 42304d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 42314d001e4dSAndy Whitcroft # 3) any do (...) { 42324d001e4dSAndy Whitcroft my $continuation = 0; 42334d001e4dSAndy Whitcroft my $check = 0; 42344d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 42354d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 42364d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 42374d001e4dSAndy Whitcroft $continuation = 1; 42384d001e4dSAndy Whitcroft } 42399bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 42404d001e4dSAndy Whitcroft $check = 1; 42414d001e4dSAndy Whitcroft $cond_lines++; 42424d001e4dSAndy Whitcroft } 42434d001e4dSAndy Whitcroft 42444d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 42454d001e4dSAndy Whitcroft # preprocessor statement. 42464d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 42474d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 42484d001e4dSAndy Whitcroft $check = 0; 42494d001e4dSAndy Whitcroft } 42504d001e4dSAndy Whitcroft 42519bd49efeSAndy Whitcroft my $cond_ptr = -1; 4252740504c6SAndy Whitcroft $continuation = 0; 42539bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 42549bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 42554d001e4dSAndy Whitcroft 4256f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 4257f16fa28fSAndy Whitcroft # is not linear. 4258f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 4259f16fa28fSAndy Whitcroft $check = 0; 4260f16fa28fSAndy Whitcroft } 4261f16fa28fSAndy Whitcroft 42629bd49efeSAndy Whitcroft # Ignore: 42639bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 42649bd49efeSAndy Whitcroft # 2) preprocessor lines, and 42659bd49efeSAndy Whitcroft # 3) labels. 4266740504c6SAndy Whitcroft if ($continuation || 4267740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 42689bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 42699bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 4270740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 427130dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 42729bd49efeSAndy Whitcroft $cond_lines++; 42739bd49efeSAndy Whitcroft } 42744d001e4dSAndy Whitcroft } 427530dad6ebSAndy Whitcroft } 42764d001e4dSAndy Whitcroft 42774d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 42784d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 42794d001e4dSAndy Whitcroft 42804d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 42814d001e4dSAndy Whitcroft # this is not this patch's fault. 42824d001e4dSAndy Whitcroft if (!defined($stat_real) || 42834d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 42844d001e4dSAndy Whitcroft $check = 0; 42854d001e4dSAndy Whitcroft } 42864d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 42874d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 42884d001e4dSAndy Whitcroft } 42894d001e4dSAndy Whitcroft 42909bd49efeSAndy 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"; 42914d001e4dSAndy Whitcroft 42929f5af480SJoe Perches if ($check && $s ne '' && 4293713a09deSAntonio Borneo (($sindent % $tabsize) != 0 || 42949f5af480SJoe Perches ($sindent < $indent) || 4295f6950a73SJoe Perches ($sindent == $indent && 4296f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 4297713a09deSAntonio Borneo ($sindent > $indent + $tabsize))) { 4298000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 4299000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 43004d001e4dSAndy Whitcroft } 43014d001e4dSAndy Whitcroft } 43024d001e4dSAndy Whitcroft 43036c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 43046c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 43051f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 43061f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 43076c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 4308c2fdda0dSAndy Whitcroft if ($dbg_values) { 4309c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 4310cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 4311cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 43121f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 4313c2fdda0dSAndy Whitcroft } 43146c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 43156c72ffaaSAndy Whitcroft 431600df344fSAndy Whitcroft#ignore lines not being added 43173705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 431800df344fSAndy Whitcroft 431999ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings 432099ca38c2SJoe Perches# e.g.: int foo = foo, *bar = NULL; 432199ca38c2SJoe Perches# struct foo bar = *(&(bar)); 432299ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { 432399ca38c2SJoe Perches my $var = $1; 432499ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { 432599ca38c2SJoe Perches WARN("SELF_ASSIGNMENT", 432699ca38c2SJoe Perches "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); 432799ca38c2SJoe Perches } 432899ca38c2SJoe Perches } 432999ca38c2SJoe Perches 433011ca40a0SJoe Perches# check for dereferences that span multiple lines 433111ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 433211ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 433311ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 433411ca40a0SJoe Perches my $ref = $1; 433511ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 433611ca40a0SJoe Perches $ref .= $1; 433711ca40a0SJoe Perches $ref =~ s/\s//g; 433811ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 433911ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 434011ca40a0SJoe Perches } 434111ca40a0SJoe Perches 4342a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 4343c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 4344a1ce18e4SJoe Perches my $type = $1; 4345a1ce18e4SJoe Perches my $var = $2; 4346207a8e84SJoe Perches $var = "" if (!defined $var); 4347207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 4348a1ce18e4SJoe Perches my $sign = $1; 4349a1ce18e4SJoe Perches my $pointer = $2; 4350a1ce18e4SJoe Perches 4351a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 4352a1ce18e4SJoe Perches 4353a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 4354a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 4355a1ce18e4SJoe Perches $fix) { 4356a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 4357207a8e84SJoe Perches my $comp_pointer = $pointer; 4358207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 4359207a8e84SJoe Perches $decl .= $comp_pointer; 4360207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 4361207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 4362a1ce18e4SJoe Perches } 4363a1ce18e4SJoe Perches } 4364a1ce18e4SJoe Perches } 4365a1ce18e4SJoe Perches 4366653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 43677429c690SAndy Whitcroft if ($dbg_type) { 43687429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 4369000d1cc1SJoe Perches ERROR("TEST_TYPE", 4370000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 43717429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 4372000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 4373000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 43747429c690SAndy Whitcroft } 4375653d4876SAndy Whitcroft next; 4376653d4876SAndy Whitcroft } 4377a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 4378a1ef277eSAndy Whitcroft if ($dbg_attr) { 43799360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 4380000d1cc1SJoe Perches ERROR("TEST_ATTR", 4381000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 43829360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 4383000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 4384000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 4385a1ef277eSAndy Whitcroft } 4386a1ef277eSAndy Whitcroft next; 4387a1ef277eSAndy Whitcroft } 4388653d4876SAndy Whitcroft 4389f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 439099423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 439199423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 4392d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 4393d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 4394f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 4395f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 4396f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 4397d752fcc8SJoe Perches my $fixedline = $prevrawline; 4398d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 4399f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4400d752fcc8SJoe Perches $fixedline = $line; 44018d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 4402f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4403d752fcc8SJoe Perches } 4404f0a594c1SAndy Whitcroft } 4405f0a594c1SAndy Whitcroft 440600df344fSAndy Whitcroft# 440700df344fSAndy Whitcroft# Checks which are anchored on the added line. 440800df344fSAndy Whitcroft# 440900df344fSAndy Whitcroft 4410653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 4411c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 4412653d4876SAndy Whitcroft my $path = $1; 4413653d4876SAndy Whitcroft if ($path =~ m{//}) { 4414000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 4415495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 4416495e9d84SJoe Perches } 4417495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 4418495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 4419495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 4420653d4876SAndy Whitcroft } 4421653d4876SAndy Whitcroft } 4422653d4876SAndy Whitcroft 442300df344fSAndy Whitcroft# no C99 // comments 442400df344fSAndy Whitcroft if ($line =~ m{//}) { 44253705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 44263705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 44273705ce5bSJoe Perches $fix) { 4428194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 44293705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 44303705ce5bSJoe Perches my $comment = trim($1); 4431194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 44323705ce5bSJoe Perches } 44333705ce5bSJoe Perches } 443400df344fSAndy Whitcroft } 443500df344fSAndy Whitcroft # Remove C99 comments. 44360a920b5bSAndy Whitcroft $line =~ s@//.*@@; 44376c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 44380a920b5bSAndy Whitcroft 44392b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 44402b474a1aSAndy Whitcroft# the whole statement. 44412b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 44422b474a1aSAndy Whitcroft if (defined $realline_next && 44432b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 44442b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 444536794822SChristoph Hellwig ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 44463cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 44473cbf62dfSAndy Whitcroft # a prefix: 44483cbf62dfSAndy Whitcroft # XXX(foo); 44493cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 4450653d4876SAndy Whitcroft my $name = $1; 445187a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 44523cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 44533cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 44543cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 44553cbf62dfSAndy Whitcroft 44563cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 44572b474a1aSAndy Whitcroft \n.}\s*$| 445848012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 445948012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 446048012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 44612b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 44622b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 446348012058SAndy Whitcroft )/x) { 44642b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 44652b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 44662b474a1aSAndy Whitcroft } else { 44672b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 44680a920b5bSAndy Whitcroft } 44690a920b5bSAndy Whitcroft } 44702b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 44712b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 447236794822SChristoph Hellwig ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 44732b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 44742b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 44752b474a1aSAndy Whitcroft } 44762b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 44772b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 4478000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 4479000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 44802b474a1aSAndy Whitcroft } 44810a920b5bSAndy Whitcroft 44825150bda4SJoe Eloff# check for global initialisers. 44835b8f82e1SSong Liu if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ && 44845b8f82e1SSong Liu !exclude_global_initialisers($realfile)) { 4485d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 44866d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 4487d5e616fcSJoe Perches $fix) { 44886d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 4489d5e616fcSJoe Perches } 4490f0a594c1SAndy Whitcroft } 44910a920b5bSAndy Whitcroft# check for static initialisers. 44926d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 4493d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 44946d32f7a3SJoe Perches "do not initialise statics to $1\n" . 4495d5e616fcSJoe Perches $herecurr) && 4496d5e616fcSJoe Perches $fix) { 44976d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 4498d5e616fcSJoe Perches } 44990a920b5bSAndy Whitcroft } 45000a920b5bSAndy Whitcroft 45011813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 45021813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 45031813087dSJoe Perches my $tmp = trim($1); 45041813087dSJoe Perches WARN("MISORDERED_TYPE", 45051813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 45061813087dSJoe Perches } 45071813087dSJoe Perches 4508809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4509809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4510809e082eSJoe Perches my $type = trim($1); 4511809e082eSJoe Perches next if ($type !~ /\bint\b/); 4512809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 4513809e082eSJoe Perches my $new_type = $type; 4514809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 4515809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 4516809e082eSJoe Perches $new_type =~ s/^const\s+//; 4517809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 4518809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 4519809e082eSJoe Perches $new_type =~ s/\s+/ /g; 4520809e082eSJoe Perches $new_type = trim($new_type); 4521809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 4522809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4523809e082eSJoe Perches $fix) { 4524809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4525809e082eSJoe Perches } 4526809e082eSJoe Perches } 4527809e082eSJoe Perches 4528cb710ecaSJoe Perches# check for static const char * arrays. 4529cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4530000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4531000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 4532cb710ecaSJoe Perches $herecurr); 4533cb710ecaSJoe Perches } 4534cb710ecaSJoe Perches 453577b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 453677b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 453777b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 453877b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 453977b8c0a8SJoe Perches $fix) { 454077b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 454177b8c0a8SJoe Perches } 454277b8c0a8SJoe Perches } 454377b8c0a8SJoe Perches 4544cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 4545cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4546000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4547000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 4548cb710ecaSJoe Perches $herecurr); 4549cb710ecaSJoe Perches } 4550cb710ecaSJoe Perches 4551ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 4552ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 4553ab7e23f3SJoe Perches my $found = $1; 4554ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 4555ab7e23f3SJoe Perches WARN("CONST_CONST", 4556ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 4557ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4558ab7e23f3SJoe Perches WARN("CONST_CONST", 4559ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4560ab7e23f3SJoe Perches } 4561ab7e23f3SJoe Perches } 4562ab7e23f3SJoe Perches 456373169765SJoe Perches# check for const static or static <non ptr type> const declarations 456473169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const' 456573169765SJoe Perches if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || 456673169765SJoe Perches $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { 456773169765SJoe Perches if (WARN("STATIC_CONST", 456873169765SJoe Perches "Move const after static - use 'static const $1'\n" . $herecurr) && 456973169765SJoe Perches $fix) { 457073169765SJoe Perches $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; 457173169765SJoe Perches $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; 457273169765SJoe Perches } 457373169765SJoe Perches } 457473169765SJoe Perches 45759b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 45769b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 45779b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 45789b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 45799b0fa60dSJoe Perches $herecurr); 45809b0fa60dSJoe Perches } 45819b0fa60dSJoe Perches 4582b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 4583b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 4584b598b670SJoe Perches my $array = $1; 4585b598b670SJoe 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*\))@) { 4586b598b670SJoe Perches my $array_div = $1; 4587b598b670SJoe Perches if (WARN("ARRAY_SIZE", 4588b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 4589b598b670SJoe Perches $fix) { 4590b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4591b598b670SJoe Perches } 4592b598b670SJoe Perches } 4593b598b670SJoe Perches } 4594b598b670SJoe Perches 4595b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 459616b7f3c8SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4597b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4598b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4599b36190c5SJoe Perches $fix) { 4600194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4601b36190c5SJoe Perches } 4602b36190c5SJoe Perches } 4603b36190c5SJoe Perches 4604653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4605653d4876SAndy Whitcroft# make sense. 4606653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 46078054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4608c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 46098ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 461046d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4611000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4612000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 46130a920b5bSAndy Whitcroft } 46140a920b5bSAndy Whitcroft 46150a920b5bSAndy Whitcroft# * goes on variable not on type 461665863862SAndy Whitcroft # (char*[ const]) 4617bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4618bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 46193705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4620d8aaf121SAndy Whitcroft 462165863862SAndy Whitcroft # Should start with a space. 462265863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 462365863862SAndy Whitcroft # Should not end with a space. 462465863862SAndy Whitcroft $to =~ s/\s+$//; 462565863862SAndy Whitcroft # '*'s should not have spaces between. 4626f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 462765863862SAndy Whitcroft } 4628d8aaf121SAndy Whitcroft 46293705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 463065863862SAndy Whitcroft if ($from ne $to) { 46313705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 46323705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 46333705ce5bSJoe Perches $fix) { 46343705ce5bSJoe Perches my $sub_from = $ident; 46353705ce5bSJoe Perches my $sub_to = $ident; 46363705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4637194f66fcSJoe Perches $fixed[$fixlinenr] =~ 46383705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 46393705ce5bSJoe Perches } 464065863862SAndy Whitcroft } 4641bfcb2cc7SAndy Whitcroft } 4642bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4643bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 46443705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4645d8aaf121SAndy Whitcroft 464665863862SAndy Whitcroft # Should start with a space. 464765863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 464865863862SAndy Whitcroft # Should not end with a space. 464965863862SAndy Whitcroft $to =~ s/\s+$//; 465065863862SAndy Whitcroft # '*'s should not have spaces between. 4651f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 465265863862SAndy Whitcroft } 465365863862SAndy Whitcroft # Modifiers should have spaces. 465465863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 465565863862SAndy Whitcroft 46563705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4657667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 46583705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 46593705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 46603705ce5bSJoe Perches $fix) { 46613705ce5bSJoe Perches 46623705ce5bSJoe Perches my $sub_from = $match; 46633705ce5bSJoe Perches my $sub_to = $match; 46643705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4665194f66fcSJoe Perches $fixed[$fixlinenr] =~ 46663705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 46673705ce5bSJoe Perches } 466865863862SAndy Whitcroft } 46690a920b5bSAndy Whitcroft } 46700a920b5bSAndy Whitcroft 46719d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 46729d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 46730675a8fbSJean Delvare my $msg_level = \&WARN; 46740675a8fbSJean Delvare $msg_level = \&CHK if ($file); 46750675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 46769d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 46779d3e3c70SJoe Perches } 46780a920b5bSAndy Whitcroft 46799d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 46808905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4681000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4682000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 46838905a67cSAndy Whitcroft } 46848905a67cSAndy Whitcroft 468517441227SJoe Perches# check for uses of printk_ratelimit 468617441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4687000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4688000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 468917441227SJoe Perches } 469017441227SJoe Perches 4691eeef5733SJoe Perches# printk should use KERN_* levels 4692eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4693000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4694eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 469500df344fSAndy Whitcroft } 46960a920b5bSAndy Whitcroft 4697f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL> 4698f5eea3b0SJoe Perches if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { 4699f5eea3b0SJoe Perches my $printk = $1; 4700f5eea3b0SJoe Perches my $modifier = $2; 4701f5eea3b0SJoe Perches my $orig = $3; 4702f5eea3b0SJoe Perches $modifier = "" if (!defined($modifier)); 4703243f3803SJoe Perches my $level = lc($orig); 4704243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 47058f26b837SJoe Perches my $level2 = $level; 47068f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4707f5eea3b0SJoe Perches $level .= $modifier; 4708f5eea3b0SJoe Perches $level2 .= $modifier; 4709243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4710f5eea3b0SJoe Perches "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); 4711243f3803SJoe Perches } 4712243f3803SJoe Perches 4713f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL> 4714dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4715dc139313SJoe Perches my $orig = $1; 4716dc139313SJoe Perches my $level = lc($orig); 4717dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4718dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4719dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4720dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4721dc139313SJoe Perches } 4722dc139313SJoe Perches 47238020b253SNicolas Boichat# trace_printk should not be used in production code. 47248020b253SNicolas Boichat if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { 47258020b253SNicolas Boichat WARN("TRACE_PRINTK", 47268020b253SNicolas Boichat "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); 47278020b253SNicolas Boichat } 47288020b253SNicolas Boichat 472991c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 473091c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 473191c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 473291c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 473391c9afafSAndy Lutomirski WARN("ENOSYS", 473491c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 473591c9afafSAndy Lutomirski } 473691c9afafSAndy Lutomirski 47376b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches. 47386b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. 47396b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected. 47406b9ea5ffSJakub Kicinski if (!$file && $line =~ /\bENOTSUPP\b/) { 47416b9ea5ffSJakub Kicinski if (WARN("ENOTSUPP", 47426b9ea5ffSJakub Kicinski "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && 47436b9ea5ffSJakub Kicinski $fix) { 47446b9ea5ffSJakub Kicinski $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; 47456b9ea5ffSJakub Kicinski } 47466b9ea5ffSJakub Kicinski } 47476b9ea5ffSJakub Kicinski 4748653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4749653d4876SAndy Whitcroft# or if closed on same line 47505b57980dSJoe Perches if ($perl_version_ok && 47512d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 47522d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 47532d453e3bSJoe Perches $sline !~ /}/) { 47548d182478SJoe Perches if (ERROR("OPEN_BRACE", 47552d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 47568d182478SJoe Perches $fix) { 47578d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 47588d182478SJoe Perches my $fixed_line = $rawline; 475903f49351SDwaipayan Ray $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; 47608d182478SJoe Perches my $line1 = $1; 47618d182478SJoe Perches my $line2 = $2; 47628d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 47638d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 47648d182478SJoe Perches if ($line2 !~ /^\s*$/) { 47658d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 47668d182478SJoe Perches } 47678d182478SJoe Perches } 47680a920b5bSAndy Whitcroft } 4769653d4876SAndy Whitcroft 47708905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 47718905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 47728905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 47738d182478SJoe Perches if (ERROR("OPEN_BRACE", 47748d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 47758d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 47768d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 47778d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 47788d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 47798d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47808d182478SJoe Perches $fixedline = $rawline; 47818d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 47828d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 47838d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47848d182478SJoe Perches } 47858d182478SJoe Perches } 47868905a67cSAndy Whitcroft } 47878905a67cSAndy Whitcroft 47880c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 47893705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 47903705ce5bSJoe Perches if (WARN("SPACING", 47913705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 47923705ce5bSJoe Perches $fix) { 4793194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47943705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 47953705ce5bSJoe Perches } 47960c73b4ebSAndy Whitcroft } 47970c73b4ebSAndy Whitcroft 479831070b5dSJoe Perches# Function pointer declarations 479931070b5dSJoe Perches# check spacing between type, funcptr, and args 480031070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 480191f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 480231070b5dSJoe Perches my $declare = $1; 480331070b5dSJoe Perches my $pre_pointer_space = $2; 480431070b5dSJoe Perches my $post_pointer_space = $3; 480531070b5dSJoe Perches my $funcname = $4; 480631070b5dSJoe Perches my $post_funcname_space = $5; 480731070b5dSJoe Perches my $pre_args_space = $6; 480831070b5dSJoe Perches 480991f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 481091f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 481191f72e9cSJoe Perches# don't need a space so don't warn for those. 481291f72e9cSJoe Perches my $post_declare_space = ""; 481391f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 481491f72e9cSJoe Perches $post_declare_space = $1; 481591f72e9cSJoe Perches $declare = rtrim($declare); 481691f72e9cSJoe Perches } 481791f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 481831070b5dSJoe Perches WARN("SPACING", 481931070b5dSJoe Perches "missing space after return type\n" . $herecurr); 482091f72e9cSJoe Perches $post_declare_space = " "; 482131070b5dSJoe Perches } 482231070b5dSJoe Perches 482331070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 482491f72e9cSJoe Perches# This test is not currently implemented because these declarations are 482591f72e9cSJoe Perches# equivalent to 482691f72e9cSJoe Perches# int foo(int bar, ...) 482791f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 482891f72e9cSJoe Perches# 482991f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 483091f72e9cSJoe Perches# WARN("SPACING", 483191f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 483291f72e9cSJoe Perches# } 483331070b5dSJoe Perches 483431070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 483531070b5dSJoe Perches if (defined $pre_pointer_space && 483631070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 483731070b5dSJoe Perches WARN("SPACING", 483831070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 483931070b5dSJoe Perches } 484031070b5dSJoe Perches 484131070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 484231070b5dSJoe Perches if (defined $post_pointer_space && 484331070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 484431070b5dSJoe Perches WARN("SPACING", 484531070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 484631070b5dSJoe Perches } 484731070b5dSJoe Perches 484831070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 484931070b5dSJoe Perches if (defined $post_funcname_space && 485031070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 485131070b5dSJoe Perches WARN("SPACING", 485231070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 485331070b5dSJoe Perches } 485431070b5dSJoe Perches 485531070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 485631070b5dSJoe Perches if (defined $pre_args_space && 485731070b5dSJoe Perches $pre_args_space =~ /^\s/) { 485831070b5dSJoe Perches WARN("SPACING", 485931070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 486031070b5dSJoe Perches } 486131070b5dSJoe Perches 486231070b5dSJoe Perches if (show_type("SPACING") && $fix) { 4863194f66fcSJoe Perches $fixed[$fixlinenr] =~ 486491f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 486531070b5dSJoe Perches } 486631070b5dSJoe Perches } 486731070b5dSJoe Perches 48688d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 48698d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 4870fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4871fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 48728d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 48738d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 48748d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 4875fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 487638dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 48773705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 48783705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 48793705ce5bSJoe Perches $fix) { 4880194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48813705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 48823705ce5bSJoe Perches } 48838d31cfceSAndy Whitcroft } 48848d31cfceSAndy Whitcroft } 48858d31cfceSAndy Whitcroft 4886f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 48876c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4888c2fdda0dSAndy Whitcroft my $name = $1; 4889773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4890773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4891c2fdda0dSAndy Whitcroft 4892c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4893773647a0SAndy Whitcroft if ($name =~ /^(?: 4894773647a0SAndy Whitcroft if|for|while|switch|return|case| 4895773647a0SAndy Whitcroft volatile|__volatile__| 4896773647a0SAndy Whitcroft __attribute__|format|__extension__| 4897773647a0SAndy Whitcroft asm|__asm__)$/x) 4898773647a0SAndy Whitcroft { 4899c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4900c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4901c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4902c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4903773647a0SAndy Whitcroft 4904773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4905c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4906c2fdda0dSAndy Whitcroft 4907c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4908c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4909773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4910c2fdda0dSAndy Whitcroft 4911c2fdda0dSAndy Whitcroft } else { 49123705ce5bSJoe Perches if (WARN("SPACING", 49133705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 49143705ce5bSJoe Perches $fix) { 4915194f66fcSJoe Perches $fixed[$fixlinenr] =~ 49163705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 49173705ce5bSJoe Perches } 4918f0a594c1SAndy Whitcroft } 49196c72ffaaSAndy Whitcroft } 49209a4cad4eSEric Nelson 4921653d4876SAndy Whitcroft# Check operator spacing. 49220a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 49233705ce5bSJoe Perches my $fixed_line = ""; 49243705ce5bSJoe Perches my $line_fixed = 0; 49253705ce5bSJoe Perches 49269c0ca6f9SAndy Whitcroft my $ops = qr{ 49279c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 49289c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 49299c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 49301f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 493184731623SJoe Perches \?:|\?|: 49329c0ca6f9SAndy Whitcroft }x; 4933cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 49343705ce5bSJoe Perches 49353705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 49363705ce5bSJoe Perches## foreach my $el (@elements) { 49373705ce5bSJoe Perches## print("el: <$el>\n"); 49383705ce5bSJoe Perches## } 49393705ce5bSJoe Perches 49403705ce5bSJoe Perches my @fix_elements = (); 494100df344fSAndy Whitcroft my $off = 0; 49426c72ffaaSAndy Whitcroft 49433705ce5bSJoe Perches foreach my $el (@elements) { 49443705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 49453705ce5bSJoe Perches $off += length($el); 49463705ce5bSJoe Perches } 49473705ce5bSJoe Perches 49483705ce5bSJoe Perches $off = 0; 49493705ce5bSJoe Perches 49506c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4951b34c648bSJoe Perches my $last_after = -1; 49526c72ffaaSAndy Whitcroft 49530a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 49543705ce5bSJoe Perches 49553705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 49563705ce5bSJoe Perches 49573705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 49583705ce5bSJoe Perches 49594a0df2efSAndy Whitcroft $off += length($elements[$n]); 49604a0df2efSAndy Whitcroft 496125985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4962773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4963773647a0SAndy Whitcroft my $cc = ''; 4964773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4965773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4966773647a0SAndy Whitcroft } 4967773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4968773647a0SAndy Whitcroft 49694a0df2efSAndy Whitcroft my $a = ''; 49704a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 49714a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4972cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 49734a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 49744a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4975773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 49764a0df2efSAndy Whitcroft 49770a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 49784a0df2efSAndy Whitcroft 49794a0df2efSAndy Whitcroft my $c = ''; 49800a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 49814a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 49824a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4983cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 49844a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 49854a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 49868b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 49874a0df2efSAndy Whitcroft } else { 49884a0df2efSAndy Whitcroft $c = 'E'; 49890a920b5bSAndy Whitcroft } 49900a920b5bSAndy Whitcroft 49914a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 49924a0df2efSAndy Whitcroft 49934a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 49944a0df2efSAndy Whitcroft 49956c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4996de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 49970a920b5bSAndy Whitcroft 499874048ed8SAndy Whitcroft # Pull out the value of this operator. 49996c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 50000a920b5bSAndy Whitcroft 50011f65f947SAndy Whitcroft # Get the full operator variant. 50021f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 50031f65f947SAndy Whitcroft 500413214adfSAndy Whitcroft # Ignore operators passed as parameters. 500513214adfSAndy Whitcroft if ($op_type ne 'V' && 5006d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 500713214adfSAndy Whitcroft 5008cf655043SAndy Whitcroft# # Ignore comments 5009cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 501013214adfSAndy Whitcroft 5011d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 501213214adfSAndy Whitcroft } elsif ($op eq ';') { 5013cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 5014cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 50153705ce5bSJoe Perches if (ERROR("SPACING", 50163705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 5017b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 50183705ce5bSJoe Perches $line_fixed = 1; 50193705ce5bSJoe Perches } 5020d8aaf121SAndy Whitcroft } 5021d8aaf121SAndy Whitcroft 5022d8aaf121SAndy Whitcroft # // is a comment 5023d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 50240a920b5bSAndy Whitcroft 5025b00e4814SJoe Perches # : when part of a bitfield 5026b00e4814SJoe Perches } elsif ($opv eq ':B') { 5027b00e4814SJoe Perches # skip the bitfield test for now 5028b00e4814SJoe Perches 50291f65f947SAndy Whitcroft # No spaces for: 50301f65f947SAndy Whitcroft # -> 5031b00e4814SJoe Perches } elsif ($op eq '->') { 50324a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 50333705ce5bSJoe Perches if (ERROR("SPACING", 50343705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 5035b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 50363705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 50373705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 50383705ce5bSJoe Perches } 5039b34c648bSJoe Perches $line_fixed = 1; 50403705ce5bSJoe Perches } 50410a920b5bSAndy Whitcroft } 50420a920b5bSAndy Whitcroft 50432381097bSJoe Perches # , must not have a space before and must have a space on the right. 50440a920b5bSAndy Whitcroft } elsif ($op eq ',') { 50452381097bSJoe Perches my $rtrim_before = 0; 50462381097bSJoe Perches my $space_after = 0; 50472381097bSJoe Perches if ($ctx =~ /Wx./) { 50482381097bSJoe Perches if (ERROR("SPACING", 50492381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 50502381097bSJoe Perches $line_fixed = 1; 50512381097bSJoe Perches $rtrim_before = 1; 50522381097bSJoe Perches } 50532381097bSJoe Perches } 5054cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 50553705ce5bSJoe Perches if (ERROR("SPACING", 50563705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 50573705ce5bSJoe Perches $line_fixed = 1; 5058b34c648bSJoe Perches $last_after = $n; 50592381097bSJoe Perches $space_after = 1; 50602381097bSJoe Perches } 50612381097bSJoe Perches } 50622381097bSJoe Perches if ($rtrim_before || $space_after) { 50632381097bSJoe Perches if ($rtrim_before) { 50642381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 50652381097bSJoe Perches } else { 50662381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 50672381097bSJoe Perches } 50682381097bSJoe Perches if ($space_after) { 50692381097bSJoe Perches $good .= " "; 50703705ce5bSJoe Perches } 50710a920b5bSAndy Whitcroft } 50720a920b5bSAndy Whitcroft 50739c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 507474048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 50759c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 50769c0ca6f9SAndy Whitcroft 50779c0ca6f9SAndy Whitcroft # unary operators should have a space before and 50789c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 50799c0ca6f9SAndy Whitcroft # unary operator, or a cast 50809c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 508174048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 50820d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 5083cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 50843705ce5bSJoe Perches if (ERROR("SPACING", 50853705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 5086b34c648bSJoe Perches if ($n != $last_after + 2) { 5087b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 50883705ce5bSJoe Perches $line_fixed = 1; 50893705ce5bSJoe Perches } 50900a920b5bSAndy Whitcroft } 5091b34c648bSJoe Perches } 5092a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 5093171ae1a4SAndy Whitcroft # A unary '*' may be const 5094171ae1a4SAndy Whitcroft 5095171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 50963705ce5bSJoe Perches if (ERROR("SPACING", 50973705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5098b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 50993705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 51003705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 51013705ce5bSJoe Perches } 5102b34c648bSJoe Perches $line_fixed = 1; 51033705ce5bSJoe Perches } 51040a920b5bSAndy Whitcroft } 51050a920b5bSAndy Whitcroft 51060a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 51070a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 5108773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 51093705ce5bSJoe Perches if (ERROR("SPACING", 51103705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 5111b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 51123705ce5bSJoe Perches $line_fixed = 1; 51133705ce5bSJoe Perches } 51140a920b5bSAndy Whitcroft } 5115773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 5116773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 51173705ce5bSJoe Perches if (ERROR("SPACING", 51183705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5119b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 51203705ce5bSJoe Perches $line_fixed = 1; 51213705ce5bSJoe Perches } 5122653d4876SAndy Whitcroft } 5123773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 51243705ce5bSJoe Perches if (ERROR("SPACING", 51253705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5126b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 51273705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 51283705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5129773647a0SAndy Whitcroft } 5130b34c648bSJoe Perches $line_fixed = 1; 51313705ce5bSJoe Perches } 51323705ce5bSJoe Perches } 51330a920b5bSAndy Whitcroft 51340a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 51359c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 51369c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 51379c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 5138c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 5139c2fdda0dSAndy Whitcroft $op eq '%') 51400a920b5bSAndy Whitcroft { 5141d2e025f3SJoe Perches if ($check) { 5142d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 5143d2e025f3SJoe Perches if (CHK("SPACING", 5144d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 5145d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5146d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5147d2e025f3SJoe Perches $line_fixed = 1; 5148d2e025f3SJoe Perches } 5149d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 5150d2e025f3SJoe Perches if (CHK("SPACING", 5151d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 5152d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 5153d2e025f3SJoe Perches $line_fixed = 1; 5154d2e025f3SJoe Perches } 5155d2e025f3SJoe Perches } 5156d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 51573705ce5bSJoe Perches if (ERROR("SPACING", 51583705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 5159b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5160b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5161b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5162b34c648bSJoe Perches } 51633705ce5bSJoe Perches $line_fixed = 1; 51643705ce5bSJoe Perches } 51650a920b5bSAndy Whitcroft } 51660a920b5bSAndy Whitcroft 51671f65f947SAndy Whitcroft # A colon needs no spaces before when it is 51681f65f947SAndy Whitcroft # terminating a case value or a label. 51691f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 5170263afd39SChris Down if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) { 51713705ce5bSJoe Perches if (ERROR("SPACING", 51723705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5173b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 51743705ce5bSJoe Perches $line_fixed = 1; 51753705ce5bSJoe Perches } 51761f65f947SAndy Whitcroft } 51771f65f947SAndy Whitcroft 51780a920b5bSAndy Whitcroft # All the others need spaces both sides. 5179cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 51801f65f947SAndy Whitcroft my $ok = 0; 51811f65f947SAndy Whitcroft 518222f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 51831f65f947SAndy Whitcroft if (($op eq '<' && 51841f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 51851f65f947SAndy Whitcroft ($op eq '>' && 51861f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 51871f65f947SAndy Whitcroft { 51881f65f947SAndy Whitcroft $ok = 1; 51891f65f947SAndy Whitcroft } 51901f65f947SAndy Whitcroft 5191e0df7e1fSJoe Perches # for asm volatile statements 5192e0df7e1fSJoe Perches # ignore a colon with another 5193e0df7e1fSJoe Perches # colon immediately before or after 5194e0df7e1fSJoe Perches if (($op eq ':') && 5195e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 5196e0df7e1fSJoe Perches $ok = 1; 5197e0df7e1fSJoe Perches } 5198e0df7e1fSJoe Perches 519984731623SJoe Perches # messages are ERROR, but ?: are CHK 52001f65f947SAndy Whitcroft if ($ok == 0) { 52010675a8fbSJean Delvare my $msg_level = \&ERROR; 52020675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 520384731623SJoe Perches 52040675a8fbSJean Delvare if (&{$msg_level}("SPACING", 52053705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 5206b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5207b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5208b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5209b34c648bSJoe Perches } 52103705ce5bSJoe Perches $line_fixed = 1; 52113705ce5bSJoe Perches } 52120a920b5bSAndy Whitcroft } 521322f2a2efSAndy Whitcroft } 52144a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 52153705ce5bSJoe Perches 52163705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 52173705ce5bSJoe Perches 52183705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 52190a920b5bSAndy Whitcroft } 52203705ce5bSJoe Perches 52213705ce5bSJoe Perches if (($#elements % 2) == 0) { 52223705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 52233705ce5bSJoe Perches } 52243705ce5bSJoe Perches 5225194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 5226194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 52273705ce5bSJoe Perches } 52283705ce5bSJoe Perches 52293705ce5bSJoe Perches 52300a920b5bSAndy Whitcroft } 52310a920b5bSAndy Whitcroft 5232786b6326SJoe Perches# check for whitespace before a non-naked semicolon 5233d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 5234786b6326SJoe Perches if (WARN("SPACING", 5235786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 5236786b6326SJoe Perches $fix) { 5237194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 5238786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 5239786b6326SJoe Perches } 5240786b6326SJoe Perches } 5241786b6326SJoe Perches 5242f0a594c1SAndy Whitcroft# check for multiple assignments 5243f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 5244000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 5245000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 5246f0a594c1SAndy Whitcroft } 5247f0a594c1SAndy Whitcroft 524822f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 524922f2a2efSAndy Whitcroft## # continuation. 525022f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 525122f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 525222f2a2efSAndy Whitcroft## 525322f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 5254e73d2715SDwaipayan Ray## # falsely report the parameters of functions. 525522f2a2efSAndy Whitcroft## my $ln = $line; 525622f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 525722f2a2efSAndy Whitcroft## } 525822f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 5259000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 5260000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 526122f2a2efSAndy Whitcroft## } 526222f2a2efSAndy Whitcroft## } 5263f0a594c1SAndy Whitcroft 52640a920b5bSAndy Whitcroft#need space before brace following if, while, etc 52656b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 52666ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 52673705ce5bSJoe Perches if (ERROR("SPACING", 52683705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 52693705ce5bSJoe Perches $fix) { 52706ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 52713705ce5bSJoe Perches } 5272de7d4f0eSAndy Whitcroft } 5273de7d4f0eSAndy Whitcroft 5274c4a62ef9SJoe Perches## # check for blank lines before declarations 5275c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 5276c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 5277c4a62ef9SJoe Perches## WARN("SPACING", 5278c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 5279c4a62ef9SJoe Perches## } 5280c4a62ef9SJoe Perches## 5281c4a62ef9SJoe Perches 5282de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 5283de7d4f0eSAndy Whitcroft# on the line 528494fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 5285d5e616fcSJoe Perches if (ERROR("SPACING", 5286d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 5287d5e616fcSJoe Perches $fix) { 5288194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5289d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 5290d5e616fcSJoe Perches } 52910a920b5bSAndy Whitcroft } 52920a920b5bSAndy Whitcroft 529322f2a2efSAndy Whitcroft# check spacing on square brackets 529422f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 52953705ce5bSJoe Perches if (ERROR("SPACING", 52963705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 52973705ce5bSJoe Perches $fix) { 5298194f66fcSJoe Perches $fixed[$fixlinenr] =~ 52993705ce5bSJoe Perches s/\[\s+/\[/; 53003705ce5bSJoe Perches } 530122f2a2efSAndy Whitcroft } 530222f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 53033705ce5bSJoe Perches if (ERROR("SPACING", 53043705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 53053705ce5bSJoe Perches $fix) { 5306194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53073705ce5bSJoe Perches s/\s+\]/\]/; 53083705ce5bSJoe Perches } 530922f2a2efSAndy Whitcroft } 531022f2a2efSAndy Whitcroft 5311c45dcabdSAndy Whitcroft# check spacing on parentheses 53129c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 53139c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 53143705ce5bSJoe Perches if (ERROR("SPACING", 53153705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 53163705ce5bSJoe Perches $fix) { 5317194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53183705ce5bSJoe Perches s/\(\s+/\(/; 53193705ce5bSJoe Perches } 532022f2a2efSAndy Whitcroft } 532113214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 5322c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 5323c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 53243705ce5bSJoe Perches if (ERROR("SPACING", 53253705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 53263705ce5bSJoe Perches $fix) { 5327194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53283705ce5bSJoe Perches s/\s+\)/\)/; 53293705ce5bSJoe Perches } 533022f2a2efSAndy Whitcroft } 533122f2a2efSAndy Whitcroft 5332e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 5333e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 5334e2826fd0SJoe Perches 5335e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 5336ea4acbb1SJoe Perches my $var = $1; 5337ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5338ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 5339ea4acbb1SJoe Perches $fix) { 5340ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 5341ea4acbb1SJoe Perches } 5342ea4acbb1SJoe Perches } 5343ea4acbb1SJoe Perches 5344ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 5345ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 5346ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 5347ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 5348ea4acbb1SJoe Perches my $var = $2; 5349ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5350ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 5351ea4acbb1SJoe Perches $fix) { 5352ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 5353ea4acbb1SJoe Perches $var2 =~ s/\s//g; 5354ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 5355ea4acbb1SJoe Perches } 5356e2826fd0SJoe Perches } 5357e2826fd0SJoe Perches 535863b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 5359a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 5360a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 53615b57980dSJoe Perches $perl_version_ok && defined($stat) && 536263b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 536363b7c73eSJoe Perches my $if_stat = $1; 536463b7c73eSJoe Perches my $test = substr($2, 1, -1); 536563b7c73eSJoe Perches my $herectx; 536663b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 536763b7c73eSJoe Perches my $match = $1; 536863b7c73eSJoe Perches # avoid parentheses around potential macro args 536963b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 537063b7c73eSJoe Perches if (!defined($herectx)) { 537163b7c73eSJoe Perches $herectx = $here . "\n"; 537263b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 537363b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 537463b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 537563b7c73eSJoe Perches $herectx .= $rl . "\n"; 537663b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 537763b7c73eSJoe Perches } 537863b7c73eSJoe Perches } 537963b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 538063b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 538163b7c73eSJoe Perches } 538263b7c73eSJoe Perches } 538363b7c73eSJoe Perches 538469078651SJoe Perches# check that goto labels aren't indented (allow a single space indentation) 538569078651SJoe Perches# and ignore bitfield definitions like foo:1 538669078651SJoe Perches# Strictly, labels can have whitespace after the identifier and before the : 538769078651SJoe Perches# but this is not allowed here as many ?: uses would appear to be labels 538869078651SJoe Perches if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ && 538969078651SJoe Perches $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ && 539069078651SJoe Perches $sline !~ /^.\s+default:/) { 53913705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 53923705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 53933705ce5bSJoe Perches $fix) { 5394194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53953705ce5bSJoe Perches s/^(.)\s+/$1/; 53963705ce5bSJoe Perches } 53970a920b5bSAndy Whitcroft } 53980a920b5bSAndy Whitcroft 539940873abaSJoe Perches# check if a statement with a comma should be two statements like: 540040873abaSJoe Perches# foo = bar(), /* comma should be semicolon */ 540140873abaSJoe Perches# bar = baz(); 540240873abaSJoe Perches if (defined($stat) && 540340873abaSJoe Perches $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { 540440873abaSJoe Perches my $cnt = statement_rawlines($stat); 540540873abaSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 540640873abaSJoe Perches WARN("SUSPECT_COMMA_SEMICOLON", 540740873abaSJoe Perches "Possible comma where semicolon could be used\n" . $herectx); 540840873abaSJoe Perches } 540940873abaSJoe Perches 54105b9553abSJoe Perches# return is not a function 5411507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 5412c45dcabdSAndy Whitcroft my $spacing = $1; 54135b57980dSJoe Perches if ($perl_version_ok && 54145b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 54155b9553abSJoe Perches my $value = $1; 54165b9553abSJoe Perches $value = deparenthesize($value); 54175b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 5418000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 5419000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 54205b9553abSJoe Perches } 5421c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 5422000d1cc1SJoe Perches ERROR("SPACING", 5423000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 5424c45dcabdSAndy Whitcroft } 5425c45dcabdSAndy Whitcroft } 5426507e5141SJoe Perches 5427b43ae21bSJoe Perches# unnecessary return in a void function 5428b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 5429b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 5430b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 5431b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 5432b43ae21bSJoe Perches $linenr >= 3 && 5433b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 5434b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 54359819cf25SJoe Perches WARN("RETURN_VOID", 5436b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 54379819cf25SJoe Perches } 54389819cf25SJoe Perches 5439189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 54405b57980dSJoe Perches if ($perl_version_ok && 5441189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 5442189248d8SJoe Perches my $openparens = $1; 5443189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 5444189248d8SJoe Perches my $msg = ""; 5445189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 5446189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 5447189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 5448189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 5449189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 5450189248d8SJoe Perches } 5451189248d8SJoe Perches } 5452189248d8SJoe Perches 5453c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 5454c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 5455c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 5456c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 54575b57980dSJoe Perches if ($perl_version_ok && 5458c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 5459c5595fa2SJoe Perches my $lead = $1; 5460c5595fa2SJoe Perches my $const = $2; 5461c5595fa2SJoe Perches my $comp = $3; 5462c5595fa2SJoe Perches my $to = $4; 5463c5595fa2SJoe Perches my $newcomp = $comp; 5464f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 5465c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 5466c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 5467c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 5468c5595fa2SJoe Perches $fix) { 5469c5595fa2SJoe Perches if ($comp eq "<") { 5470c5595fa2SJoe Perches $newcomp = ">"; 5471c5595fa2SJoe Perches } elsif ($comp eq "<=") { 5472c5595fa2SJoe Perches $newcomp = ">="; 5473c5595fa2SJoe Perches } elsif ($comp eq ">") { 5474c5595fa2SJoe Perches $newcomp = "<"; 5475c5595fa2SJoe Perches } elsif ($comp eq ">=") { 5476c5595fa2SJoe Perches $newcomp = "<="; 5477c5595fa2SJoe Perches } 5478c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 5479c5595fa2SJoe Perches } 5480c5595fa2SJoe Perches } 5481c5595fa2SJoe Perches 5482f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 5483f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 548453a3c448SAndy Whitcroft my $name = $1; 548546b85bf9SGuenter Roeck if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) { 5486000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 5487f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 548853a3c448SAndy Whitcroft } 548953a3c448SAndy Whitcroft } 5490c45dcabdSAndy Whitcroft 54910a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 54924a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 54933705ce5bSJoe Perches if (ERROR("SPACING", 54943705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 54953705ce5bSJoe Perches $fix) { 5496194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54973705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 54983705ce5bSJoe Perches } 54990a920b5bSAndy Whitcroft } 55000a920b5bSAndy Whitcroft 5501f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 5502f5fe35ddSAndy Whitcroft# statements after the conditional. 5503170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 55043e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 55053e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 55063e469cdcSAndy Whitcroft if (!defined $stat); 5507170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 5508170d3a22SAndy Whitcroft $remain_next, $off_next); 5509170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 5510170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 5511170d3a22SAndy Whitcroft 5512170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 5513170d3a22SAndy Whitcroft # If the statement carries leading newlines, 5514170d3a22SAndy Whitcroft # then count those as offsets. 5515170d3a22SAndy Whitcroft my ($whitespace) = 5516170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 5517170d3a22SAndy Whitcroft my $offset = 5518170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 5519170d3a22SAndy Whitcroft 5520170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 5521170d3a22SAndy Whitcroft $offset} = 1; 5522170d3a22SAndy Whitcroft } 5523170d3a22SAndy Whitcroft } 5524170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 5525c11230f4SJoe Perches defined($stat) && defined($cond) && 5526170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 5527171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 55288905a67cSAndy Whitcroft 5529b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 553065b64b3bSJoe Perches if (ERROR("ASSIGN_IN_IF", 553165b64b3bSJoe Perches "do not use assignment in if condition\n" . $herecurr) && 553265b64b3bSJoe Perches $fix && $perl_version_ok) { 553365b64b3bSJoe Perches if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { 553465b64b3bSJoe Perches my $space = $1; 553565b64b3bSJoe Perches my $not = $2; 553665b64b3bSJoe Perches my $statement = $3; 553765b64b3bSJoe Perches my $assigned = $4; 553865b64b3bSJoe Perches my $test = $8; 553965b64b3bSJoe Perches my $against = $9; 554065b64b3bSJoe Perches my $brace = $15; 554165b64b3bSJoe Perches fix_delete_line($fixlinenr, $rawline); 554265b64b3bSJoe Perches fix_insert_line($fixlinenr, "$space$statement;"); 554365b64b3bSJoe Perches my $newline = "${space}if ("; 554465b64b3bSJoe Perches $newline .= '!' if defined($not); 554565b64b3bSJoe Perches $newline .= '(' if (defined $not && defined($test) && defined($against)); 554665b64b3bSJoe Perches $newline .= "$assigned"; 554765b64b3bSJoe Perches $newline .= " $test $against" if (defined($test) && defined($against)); 554865b64b3bSJoe Perches $newline .= ')' if (defined $not && defined($test) && defined($against)); 554965b64b3bSJoe Perches $newline .= ')'; 555065b64b3bSJoe Perches $newline .= " {" if (defined($brace)); 555165b64b3bSJoe Perches fix_insert_line($fixlinenr + 1, $newline); 555265b64b3bSJoe Perches } 555365b64b3bSJoe Perches } 55548905a67cSAndy Whitcroft } 55558905a67cSAndy Whitcroft 55568905a67cSAndy Whitcroft # Find out what is on the end of the line after the 55578905a67cSAndy Whitcroft # conditional. 5558773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 55598905a67cSAndy Whitcroft $s =~ s/\n.*//g; 556013214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 556153210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 556253210168SAndy Whitcroft $c !~ /}\s*while\s*/) 5563773647a0SAndy Whitcroft { 5564bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 5565bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 5566bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 556742bdf74cSHidetoshi Seto my $stat_real = ''; 5568bb44ad39SAndy Whitcroft 556942bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 557042bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 5571bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 5572bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 5573bb44ad39SAndy Whitcroft } 5574bb44ad39SAndy Whitcroft 5575000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5576000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 55778905a67cSAndy Whitcroft } 55788905a67cSAndy Whitcroft } 55798905a67cSAndy Whitcroft 558013214adfSAndy Whitcroft# Check for bitwise tests written as boolean 558113214adfSAndy Whitcroft if ($line =~ / 558213214adfSAndy Whitcroft (?: 558313214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 558413214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 558513214adfSAndy Whitcroft (?:\&\&|\|\|) 558613214adfSAndy Whitcroft | 558713214adfSAndy Whitcroft (?:\&\&|\|\|) 558813214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 558913214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 559013214adfSAndy Whitcroft )/x) 559113214adfSAndy Whitcroft { 5592000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 5593000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 559413214adfSAndy Whitcroft } 559513214adfSAndy Whitcroft 55968905a67cSAndy Whitcroft# if and else should not have general statements after it 559713214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 559813214adfSAndy Whitcroft my $s = $1; 559913214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 560013214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 5601000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5602000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 56030a920b5bSAndy Whitcroft } 560413214adfSAndy Whitcroft } 560539667782SAndy Whitcroft# if should not continue a brace 560639667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 5607000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5608048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 560939667782SAndy Whitcroft $herecurr); 561039667782SAndy Whitcroft } 5611a1080bf8SAndy Whitcroft# case and default should not have general statements after them 5612a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 5613a1080bf8SAndy Whitcroft $line !~ /\G(?: 56143fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5615a1080bf8SAndy Whitcroft \s*return\s+ 5616a1080bf8SAndy Whitcroft )/xg) 5617a1080bf8SAndy Whitcroft { 5618000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5619000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 5620a1080bf8SAndy Whitcroft } 56210a920b5bSAndy Whitcroft 56220a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 56230a920b5bSAndy Whitcroft # indent level to be relevant to each other. 56248b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 56250a920b5bSAndy Whitcroft $previndent == $indent) { 56268b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 56278b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 56288b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 56298b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 56308b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 56318b8856f4SJoe Perches my $fixedline = $prevrawline; 56328b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 56338b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 56348b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 56358b8856f4SJoe Perches } 56368b8856f4SJoe Perches $fixedline = $rawline; 56378b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 56388b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 56398b8856f4SJoe Perches } 56400a920b5bSAndy Whitcroft } 56410a920b5bSAndy Whitcroft 56428b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5643c2fdda0dSAndy Whitcroft $previndent == $indent) { 5644c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5645c2fdda0dSAndy Whitcroft 5646c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5647c2fdda0dSAndy Whitcroft # conditional. 5648773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5649c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5650c2fdda0dSAndy Whitcroft 5651c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 56528b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 56538b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 56548b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 56558b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 56568b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 56578b8856f4SJoe Perches my $fixedline = $prevrawline; 56588b8856f4SJoe Perches my $trailing = $rawline; 56598b8856f4SJoe Perches $trailing =~ s/^\+//; 56608b8856f4SJoe Perches $trailing = trim($trailing); 56618b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 56628b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 56638b8856f4SJoe Perches } 5664c2fdda0dSAndy Whitcroft } 5665c2fdda0dSAndy Whitcroft } 5666c2fdda0dSAndy Whitcroft 566795e2c602SJoe Perches#Specific variable tests 5668323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5669323c1260SJoe Perches my $var = $1; 567095e2c602SJoe Perches 567195e2c602SJoe Perches#CamelCase 5672807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5673be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 56744104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values 56754104a206SŁukasz Stelmach $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && 567622735ce8SJoe Perches#Ignore Page<foo> variants 5677807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5678d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB 5679d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 5680d439e6a5SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5681f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5682f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 56837e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 56847e781f67SJoe Perches my $word = $1; 56857e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5686d8b07710SJoe Perches if ($check) { 5687d8b07710SJoe Perches seed_camelcase_includes(); 5688d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5689d8b07710SJoe Perches seed_camelcase_file($realfile); 5690d8b07710SJoe Perches $camelcase_file_seeded = 1; 5691d8b07710SJoe Perches } 5692d8b07710SJoe Perches } 56937e781f67SJoe Perches if (!defined $camelcase{$word}) { 56947e781f67SJoe Perches $camelcase{$word} = 1; 5695be79794bSJoe Perches CHK("CAMELCASE", 56967e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 56977e781f67SJoe Perches } 5698323c1260SJoe Perches } 5699323c1260SJoe Perches } 57003445686aSJoe Perches } 57010a920b5bSAndy Whitcroft 57020a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5703d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5704d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5705d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5706d5e616fcSJoe Perches $fix) { 5707194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5708d5e616fcSJoe Perches } 57090a920b5bSAndy Whitcroft } 57100a920b5bSAndy Whitcroft 57110e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 57120e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5713c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5714e09dec48SAndy Whitcroft my $file = "$1.h"; 5715e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5716e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5717e09dec48SAndy Whitcroft $realfile ne $checkfile && 57187840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5719c45dcabdSAndy Whitcroft { 57200e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 57210e212e0aSFabian Frederick if ($asminclude > 0) { 5722e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5723000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5724000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5725e09dec48SAndy Whitcroft } else { 5726000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5727000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5728e09dec48SAndy Whitcroft } 57290a920b5bSAndy Whitcroft } 57300a920b5bSAndy Whitcroft } 57310e212e0aSFabian Frederick } 57320a920b5bSAndy Whitcroft 5733653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5734653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5735cf655043SAndy Whitcroft# in a known good container 5736b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5737b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5738d8aaf121SAndy Whitcroft my $ln = $linenr; 5739d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5740c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5741c45dcabdSAndy Whitcroft my $ctx = ''; 574208a2843eSJoe Perches my $has_flow_statement = 0; 574308a2843eSJoe Perches my $has_arg_concat = 0; 5744c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5745f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5746f74bd194SAndy Whitcroft $ctx = $dstat; 5747c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5748a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5749c45dcabdSAndy Whitcroft 575008a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 575162e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 575208a2843eSJoe Perches 5753f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5754f59b64bfSJoe Perches my $define_args = $1; 5755f59b64bfSJoe Perches my $define_stmt = $dstat; 5756f59b64bfSJoe Perches my @def_args = (); 5757f59b64bfSJoe Perches 5758f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5759f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5760f59b64bfSJoe Perches $define_args =~ s/\s*//g; 57618c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5762f59b64bfSJoe Perches @def_args = split(",", $define_args); 5763f59b64bfSJoe Perches } 5764f59b64bfSJoe Perches 5765292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5766c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5767c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5768c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5769c45dcabdSAndy Whitcroft 5770c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 57712e44e803SDwaipayan Ray while ($dstat =~ s/\([^\(\)]*\)/1u/ || 57722e44e803SDwaipayan Ray $dstat =~ s/\{[^\{\}]*\}/1u/ || 57732e44e803SDwaipayan Ray $dstat =~ s/.\[[^\[\]]*\]/1u/) 5774bf30d6edSAndy Whitcroft { 5775c45dcabdSAndy Whitcroft } 5776c45dcabdSAndy Whitcroft 5777342d3d2fSAntonio Borneo # Flatten any obvious string concatenation. 577833acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 577933acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5780e45bab8eSAndy Whitcroft { 5781e45bab8eSAndy Whitcroft } 5782e45bab8eSAndy Whitcroft 578342e15293SJoe Perches # Make asm volatile uses seem like a generic function 578442e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 578542e15293SJoe Perches 5786c45dcabdSAndy Whitcroft my $exceptions = qr{ 5787c45dcabdSAndy Whitcroft $Declare| 5788c45dcabdSAndy Whitcroft module_param_named| 5789a0a0a7a9SKees Cook MODULE_PARM_DESC| 5790c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5791c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5792383099fdSAndy Whitcroft __typeof__\(| 579322fd2d3eSStefani Seibold union| 579422fd2d3eSStefani Seibold struct| 5795ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 57966b10df42SVladimir Zapolskiy ^\"|\"$| 57976b10df42SVladimir Zapolskiy ^\[ 5798c45dcabdSAndy Whitcroft }x; 57995eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5800f59b64bfSJoe Perches 5801f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5802f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5803e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5804f59b64bfSJoe Perches 5805f74bd194SAndy Whitcroft if ($dstat ne '' && 5806f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5807f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 58083cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5809356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5810f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5811f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5812e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 581372f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 58142e44e803SDwaipayan Ray $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} 5815f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5816f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5817f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 58184e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5819f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5820c45dcabdSAndy Whitcroft { 5821e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5822e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5823e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5824e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5825f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5826f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5827f74bd194SAndy Whitcroft } else { 5828000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 5829388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5830d8aaf121SAndy Whitcroft } 5831f59b64bfSJoe Perches 5832f59b64bfSJoe Perches } 58335207649bSJoe Perches 58345207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 58355207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 58365207649bSJoe Perches my $first = 1; 58375207649bSJoe Perches $define_stmt = ""; 58385207649bSJoe Perches foreach my $l (@stmt_array) { 58395207649bSJoe Perches $l =~ s/\\$//; 58405207649bSJoe Perches if ($first) { 58415207649bSJoe Perches $define_stmt = $l; 58425207649bSJoe Perches $first = 0; 58435207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 58445207649bSJoe Perches $define_stmt .= substr($l, 1); 58455207649bSJoe Perches } 58465207649bSJoe Perches } 58475207649bSJoe Perches $define_stmt =~ s/$;//g; 58485207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 58495207649bSJoe Perches $define_stmt = trim($define_stmt); 58505207649bSJoe Perches 5851f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 5852f59b64bfSJoe Perches foreach my $arg (@def_args) { 5853f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 58549192d41aSJoe Perches next if ($arg =~ /^type$/i); 58557fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 58567b844345SVincent 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; 58577fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 58587fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5859d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 5860f59b64bfSJoe Perches if ($use_cnt > 1) { 5861f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 5862f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5863f59b64bfSJoe Perches } 58649192d41aSJoe Perches# check if any macro arguments may have other precedence issues 58657fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 58669192d41aSJoe Perches ((defined($1) && $1 ne ',') || 58679192d41aSJoe Perches (defined($2) && $2 ne ','))) { 58689192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 58699192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 58709192d41aSJoe Perches } 58710a920b5bSAndy Whitcroft } 58725023d347SJoe Perches 587308a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 587408a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 587508a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 587608a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 5877e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 587808a2843eSJoe Perches 587908a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 588008a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 588108a2843eSJoe Perches } 588208a2843eSJoe Perches 5883481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 58845023d347SJoe Perches 58855023d347SJoe Perches } else { 58865023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 5887481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 5888481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 58895023d347SJoe Perches $line =~ /^\+.*\\$/) { 58905023d347SJoe Perches WARN("LINE_CONTINUATIONS", 58915023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 58925023d347SJoe Perches } 5893653d4876SAndy Whitcroft } 58940a920b5bSAndy Whitcroft 5895b13edf7fSJoe Perches# do {} while (0) macro tests: 5896b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 5897b13edf7fSJoe Perches# macro should not end with a semicolon 58985b57980dSJoe Perches if ($perl_version_ok && 5899b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 5900b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5901b13edf7fSJoe Perches my $ln = $linenr; 5902b13edf7fSJoe Perches my $cnt = $realcnt; 5903b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 5904b13edf7fSJoe Perches my $ctx = ''; 5905b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 5906b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 5907b13edf7fSJoe Perches $ctx = $dstat; 5908b13edf7fSJoe Perches 5909b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 59101b36b201SJoe Perches $dstat =~ s/$;/ /g; 5911b13edf7fSJoe Perches 5912b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 5913b13edf7fSJoe Perches my $stmts = $2; 5914b13edf7fSJoe Perches my $semis = $3; 5915b13edf7fSJoe Perches 5916b13edf7fSJoe Perches $ctx =~ s/\n*$//; 5917b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 5918e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5919b13edf7fSJoe Perches 5920ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 5921ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 5922b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 5923b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 5924b13edf7fSJoe Perches } 5925b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 5926b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 5927b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5928b13edf7fSJoe Perches } 5929f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5930f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5931f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5932e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5933f5ef95b1SJoe Perches 5934f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5935f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5936b13edf7fSJoe Perches } 5937b13edf7fSJoe Perches } 5938b13edf7fSJoe Perches 5939f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 594013214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 594113214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5942cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 594313214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5944cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5945cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5946aad4f614SJoe Perches my @allowed = (); 5947aad4f614SJoe Perches my $allow = 0; 594813214adfSAndy Whitcroft my $seen = 0; 5949773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5950cf655043SAndy Whitcroft my $ln = $linenr - 1; 595113214adfSAndy Whitcroft for my $chunk (@chunks) { 595213214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 595313214adfSAndy Whitcroft 5954773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5955773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5956773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5957773647a0SAndy Whitcroft 5958aad4f614SJoe Perches $allowed[$allow] = 0; 5959773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5960773647a0SAndy Whitcroft 5961773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5962773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5963773647a0SAndy Whitcroft 5964773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5965cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5966cf655043SAndy Whitcroft 5967773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 596813214adfSAndy Whitcroft 596913214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 597013214adfSAndy Whitcroft 5971aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5972cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5973cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5974aad4f614SJoe Perches $allowed[$allow] = 1; 597513214adfSAndy Whitcroft } 597613214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5977cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5978aad4f614SJoe Perches $allowed[$allow] = 1; 597913214adfSAndy Whitcroft } 5980cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5981cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5982aad4f614SJoe Perches $allowed[$allow] = 1; 598313214adfSAndy Whitcroft } 5984aad4f614SJoe Perches $allow++; 598513214adfSAndy Whitcroft } 5986aad4f614SJoe Perches if ($seen) { 5987aad4f614SJoe Perches my $sum_allowed = 0; 5988aad4f614SJoe Perches foreach (@allowed) { 5989aad4f614SJoe Perches $sum_allowed += $_; 5990aad4f614SJoe Perches } 5991aad4f614SJoe Perches if ($sum_allowed == 0) { 5992000d1cc1SJoe Perches WARN("BRACES", 5993000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5994aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5995aad4f614SJoe Perches $seen != $allow) { 5996aad4f614SJoe Perches CHK("BRACES", 5997aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5998aad4f614SJoe Perches } 599913214adfSAndy Whitcroft } 600013214adfSAndy Whitcroft } 600113214adfSAndy Whitcroft } 6002773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 600313214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 6004cf655043SAndy Whitcroft my $allowed = 0; 6005f0a594c1SAndy Whitcroft 6006cf655043SAndy Whitcroft # Check the pre-context. 6007cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 6008cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 6009cf655043SAndy Whitcroft $allowed = 1; 6010f0a594c1SAndy Whitcroft } 6011773647a0SAndy Whitcroft 6012773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 6013773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 6014773647a0SAndy Whitcroft 6015cf655043SAndy Whitcroft # Check the condition. 6016cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 6017773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 6018cf655043SAndy Whitcroft if (defined $cond) { 6019773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 6020cf655043SAndy Whitcroft } 6021cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 6022cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 6023cf655043SAndy Whitcroft $allowed = 1; 6024cf655043SAndy Whitcroft } 6025cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 6026cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 6027cf655043SAndy Whitcroft $allowed = 1; 6028cf655043SAndy Whitcroft } 6029cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 6030cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 6031cf655043SAndy Whitcroft $allowed = 1; 6032cf655043SAndy Whitcroft } 6033cf655043SAndy Whitcroft # Check the post-context. 6034cf655043SAndy Whitcroft if (defined $chunks[1]) { 6035cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 6036cf655043SAndy Whitcroft if (defined $cond) { 6037773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 6038cf655043SAndy Whitcroft } 6039cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 6040cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 6041cf655043SAndy Whitcroft $allowed = 1; 6042cf655043SAndy Whitcroft } 6043cf655043SAndy Whitcroft } 6044cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 6045f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 6046e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6047cf655043SAndy Whitcroft 6048000d1cc1SJoe Perches WARN("BRACES", 6049000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 6050f0a594c1SAndy Whitcroft } 6051f0a594c1SAndy Whitcroft } 6052f0a594c1SAndy Whitcroft 6053e4c5babdSJoe Perches# check for single line unbalanced braces 605495330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 605595330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 6056e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 6057e4c5babdSJoe Perches } 6058e4c5babdSJoe Perches 60590979ae66SJoe Perches# check for unnecessary blank lines around braces 606077b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 6061f8e58219SJoe Perches if (CHK("BRACES", 6062f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 6063f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 6064f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6065f8e58219SJoe Perches } 60660979ae66SJoe Perches } 606777b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 6068f8e58219SJoe Perches if (CHK("BRACES", 6069f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 6070f8e58219SJoe Perches $fix) { 6071f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 6072f8e58219SJoe Perches } 60730979ae66SJoe Perches } 60740979ae66SJoe Perches 60754a0df2efSAndy Whitcroft# no volatiles please 60766c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 60776c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 6078000d1cc1SJoe Perches WARN("VOLATILE", 60798c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 60804a0df2efSAndy Whitcroft } 60814a0df2efSAndy Whitcroft 60825e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 60835e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 60845e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 60855e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 608633acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 60875e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 60885e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 60895e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 60905e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 60915e4f6ba5SJoe Perches $fix && 60925e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 60935e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 60945e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 60955e4f6ba5SJoe Perches my $comma_close = ""; 60965e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 60975e4f6ba5SJoe Perches $comma_close = $1; 60985e4f6ba5SJoe Perches } 60995e4f6ba5SJoe Perches 61005e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 61015e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 61025e4f6ba5SJoe Perches my $fixedline = $prevrawline; 61035e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 61045e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 61055e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 61065e4f6ba5SJoe Perches $fixedline = $rawline; 61075e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 61085e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 61095e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 61105e4f6ba5SJoe Perches } 61115e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 61125e4f6ba5SJoe Perches } 61135e4f6ba5SJoe Perches } 61145e4f6ba5SJoe Perches 61155e4f6ba5SJoe Perches# check for missing a space in a string concatenation 61165e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 61175e4f6ba5SJoe Perches WARN('MISSING_SPACE', 61185e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 61195e4f6ba5SJoe Perches } 61205e4f6ba5SJoe Perches 612177cb8546SJoe Perches# check for an embedded function name in a string when the function is known 6122e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 6123e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 6124e4b7d309SJoe Perches# function declarations 612577cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 612677cb8546SJoe Perches defined($context_function) && 6127e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 6128e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 612977cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 6130e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 613177cb8546SJoe Perches } 613277cb8546SJoe Perches 6133adb2da82SJoe Perches# check for unnecessary function tracing like uses 6134adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like 6135adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions 6136adb2da82SJoe Perches if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) { 6137adb2da82SJoe Perches if (WARN("TRACING_LOGGING", 6138adb2da82SJoe Perches "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) && 6139adb2da82SJoe Perches $fix) { 6140adb2da82SJoe Perches fix_delete_line($fixlinenr, $rawline); 6141adb2da82SJoe Perches } 6142adb2da82SJoe Perches } 6143adb2da82SJoe Perches 61445e4f6ba5SJoe Perches# check for spaces before a quoted newline 61455e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 61465e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 61475e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 61485e4f6ba5SJoe Perches $fix) { 61495e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 61505e4f6ba5SJoe Perches } 61515e4f6ba5SJoe Perches 61525e4f6ba5SJoe Perches } 61535e4f6ba5SJoe Perches 6154f17dba4fSJoe Perches# concatenated string without spaces between elements 6155d2af5aa6SJoe Perches if ($line =~ /$String[A-Z_]/ || 6156d2af5aa6SJoe Perches ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) { 615779682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 615879682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 615979682c0cSJoe Perches $fix) { 616079682c0cSJoe Perches while ($line =~ /($String)/g) { 616179682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 616279682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 616379682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 616479682c0cSJoe Perches } 616579682c0cSJoe Perches } 6166f17dba4fSJoe Perches } 6167f17dba4fSJoe Perches 616890ad30e5SJoe Perches# uncoalesced string fragments 6169d2af5aa6SJoe Perches if ($line =~ /$String\s*[Lu]?"/) { 617079682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 617179682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 617279682c0cSJoe Perches $fix) { 617379682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 617479682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 617579682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 617679682c0cSJoe Perches } 617779682c0cSJoe Perches } 617890ad30e5SJoe Perches } 617990ad30e5SJoe Perches 6180522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 6181522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 6182522b837cSAlexey Dobriyan my $show_Z = 1; 61835e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 6184522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 61855e4f6ba5SJoe Perches $string =~ s/%%/__/g; 6186522b837cSAlexey Dobriyan # check for %L 6187522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 61885e4f6ba5SJoe Perches WARN("PRINTF_L", 6189522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 6190522b837cSAlexey Dobriyan $show_L = 0; 61915e4f6ba5SJoe Perches } 6192522b837cSAlexey Dobriyan # check for %Z 6193522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 6194522b837cSAlexey Dobriyan WARN("PRINTF_Z", 6195522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 6196522b837cSAlexey Dobriyan $show_Z = 0; 6197522b837cSAlexey Dobriyan } 6198522b837cSAlexey Dobriyan # check for 0x<decimal> 6199522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 6200522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 62016e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 62026e300757SJoe Perches } 62035e4f6ba5SJoe Perches } 62045e4f6ba5SJoe Perches 62055e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 62063f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 62075e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 62085e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 62095e4f6ba5SJoe Perches } 62105e4f6ba5SJoe Perches 621100df344fSAndy Whitcroft# warn about #if 0 6212c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 621360f89010SPrakruthi Deepak Heragu WARN("IF_0", 621460f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 621560f89010SPrakruthi Deepak Heragu } 621660f89010SPrakruthi Deepak Heragu 621760f89010SPrakruthi Deepak Heragu# warn about #if 1 621860f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 621960f89010SPrakruthi Deepak Heragu WARN("IF_1", 622060f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 62214a0df2efSAndy Whitcroft } 62224a0df2efSAndy Whitcroft 622303df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 622403df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 6225100425deSJoe Perches my $tested = quotemeta($1); 6226100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 6227100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 6228100425deSJoe Perches my $func = $1; 6229100425deSJoe Perches if (WARN('NEEDLESS_IF', 6230100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 6231100425deSJoe Perches $fix) { 6232100425deSJoe Perches my $do_fix = 1; 6233100425deSJoe Perches my $leading_tabs = ""; 6234100425deSJoe Perches my $new_leading_tabs = ""; 6235100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 6236100425deSJoe Perches $leading_tabs = $1; 6237100425deSJoe Perches } else { 6238100425deSJoe Perches $do_fix = 0; 6239100425deSJoe Perches } 6240100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 6241100425deSJoe Perches $new_leading_tabs = $1; 6242100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 6243100425deSJoe Perches $do_fix = 0; 6244100425deSJoe Perches } 6245100425deSJoe Perches } else { 6246100425deSJoe Perches $do_fix = 0; 6247100425deSJoe Perches } 6248100425deSJoe Perches if ($do_fix) { 6249100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6250100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 6251100425deSJoe Perches } 6252100425deSJoe Perches } 62534c432a8fSGreg Kroah-Hartman } 62544c432a8fSGreg Kroah-Hartman } 6255f0a594c1SAndy Whitcroft 6256ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 6257ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 6258ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 6259ebfdc409SJoe Perches (defined $1 || defined $3) && 6260ebfdc409SJoe Perches $linenr > 3) { 6261ebfdc409SJoe Perches my $testval = $2; 6262ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 6263ebfdc409SJoe Perches 6264ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 6265ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 6266ebfdc409SJoe Perches 6267e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 6268e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 6269ebfdc409SJoe Perches WARN("OOM_MESSAGE", 6270ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 6271ebfdc409SJoe Perches } 6272ebfdc409SJoe Perches } 6273ebfdc409SJoe Perches 6274f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 6275dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 6276f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 6277f78d98f6SJoe Perches my $level = $1; 6278f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 6279f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 6280f78d98f6SJoe Perches $fix) { 6281f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 6282f78d98f6SJoe Perches } 6283f78d98f6SJoe Perches } 6284f78d98f6SJoe Perches 628545c55e92SJoe Perches# check for logging continuations 628645c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 628745c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 628845c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 628945c55e92SJoe Perches } 629045c55e92SJoe Perches 629170eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions 629270eb2275SDwaipayan Ray if (defined $stat && 629370eb2275SDwaipayan Ray $line =~ /\b$logFunctions\s*\(/ && 629470eb2275SDwaipayan Ray index($stat, '"') >= 0) { 629570eb2275SDwaipayan Ray my $lc = $stat =~ tr@\n@@; 629670eb2275SDwaipayan Ray $lc = $lc + $linenr; 629770eb2275SDwaipayan Ray my $stat_real = get_stat_real($linenr, $lc); 629870eb2275SDwaipayan Ray pos($stat_real) = index($stat_real, '"'); 629970eb2275SDwaipayan Ray while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { 630070eb2275SDwaipayan Ray my $pspec = $1; 630170eb2275SDwaipayan Ray my $h = $2; 630270eb2275SDwaipayan Ray my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; 630370eb2275SDwaipayan Ray if (WARN("UNNECESSARY_MODIFIER", 630470eb2275SDwaipayan Ray "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && 630570eb2275SDwaipayan Ray $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { 630670eb2275SDwaipayan Ray my $nspec = $pspec; 630770eb2275SDwaipayan Ray $nspec =~ s/h//g; 630870eb2275SDwaipayan Ray $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; 630970eb2275SDwaipayan Ray } 631070eb2275SDwaipayan Ray } 631170eb2275SDwaipayan Ray } 631270eb2275SDwaipayan Ray 6313abb08a53SJoe Perches# check for mask then right shift without a parentheses 63145b57980dSJoe Perches if ($perl_version_ok && 6315abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 6316abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 6317abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 6318abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 6319abb08a53SJoe Perches } 6320abb08a53SJoe Perches 6321b75ac618SJoe Perches# check for pointer comparisons to NULL 63225b57980dSJoe Perches if ($perl_version_ok) { 6323b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 6324b75ac618SJoe Perches my $val = $1; 6325b75ac618SJoe Perches my $equal = "!"; 6326b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 6327b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 6328b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 6329b75ac618SJoe Perches $fix) { 6330b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 6331b75ac618SJoe Perches } 6332b75ac618SJoe Perches } 6333b75ac618SJoe Perches } 6334b75ac618SJoe Perches 63358716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 63368716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 63378716de38SJoe Perches my $attr = $1; 63388716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 63398716de38SJoe Perches my $ptr = $1; 63408716de38SJoe Perches my $var = $2; 63418716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 63428716de38SJoe Perches ERROR("MISPLACED_INIT", 63438716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 63448716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 63458716de38SJoe Perches WARN("MISPLACED_INIT", 63468716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 63478716de38SJoe Perches $fix) { 6348194f66fcSJoe 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; 63498716de38SJoe Perches } 63508716de38SJoe Perches } 63518716de38SJoe Perches } 63528716de38SJoe Perches 6353e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 6354e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 6355e970b884SJoe Perches my $attr = $1; 6356e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 6357e970b884SJoe Perches my $attr_prefix = $1; 6358e970b884SJoe Perches my $attr_type = $2; 6359e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6360e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 6361e970b884SJoe Perches $fix) { 6362194f66fcSJoe Perches $fixed[$fixlinenr] =~ 6363e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 6364e970b884SJoe Perches } 6365e970b884SJoe Perches } 6366e970b884SJoe Perches 6367e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 6368e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 6369e970b884SJoe Perches my $attr = $1; 6370e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6371e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 6372e970b884SJoe Perches $fix) { 6373194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 6374e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 6375e970b884SJoe Perches $lead = rtrim($1); 6376e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 6377e970b884SJoe Perches $lead = "${lead}const "; 6378194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 6379e970b884SJoe Perches } 6380e970b884SJoe Perches } 6381e970b884SJoe Perches 6382c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 6383c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 6384c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 6385c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 6386c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 6387c17893c7SJoe Perches $fix) { 6388c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 6389c17893c7SJoe Perches } 6390c17893c7SJoe Perches } 6391c17893c7SJoe Perches 6392fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 6393fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 6394fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 6395fbdb8138SJoe Perches my $constant_func = $1; 6396fbdb8138SJoe Perches my $func = $constant_func; 6397fbdb8138SJoe Perches $func =~ s/^__constant_//; 6398fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 6399fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 6400fbdb8138SJoe Perches $fix) { 6401194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 6402fbdb8138SJoe Perches } 6403fbdb8138SJoe Perches } 6404fbdb8138SJoe Perches 64051a15a250SPatrick Pannuto# prefer usleep_range over udelay 640637581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 640743c1d77cSJoe Perches my $delay = $1; 64081a15a250SPatrick Pannuto # ignore udelay's < 10, however 640943c1d77cSJoe Perches if (! ($delay < 10) ) { 6410000d1cc1SJoe Perches CHK("USLEEP_RANGE", 6411458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 641243c1d77cSJoe Perches } 641343c1d77cSJoe Perches if ($delay > 2000) { 641443c1d77cSJoe Perches WARN("LONG_UDELAY", 641543c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 64161a15a250SPatrick Pannuto } 64171a15a250SPatrick Pannuto } 64181a15a250SPatrick Pannuto 641909ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 642009ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 642109ef8725SPatrick Pannuto if ($1 < 20) { 6422000d1cc1SJoe Perches WARN("MSLEEP", 6423458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 642409ef8725SPatrick Pannuto } 642509ef8725SPatrick Pannuto } 642609ef8725SPatrick Pannuto 642736ec1939SJoe Perches# check for comparisons of jiffies 642836ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 642936ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 643036ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 643136ec1939SJoe Perches } 643236ec1939SJoe Perches 64339d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 64349d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 64359d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 64369d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 64379d7a34a5SJoe Perches } 64389d7a34a5SJoe Perches 643900df344fSAndy Whitcroft# warn about #ifdefs in C files 6440c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 644100df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 644200df344fSAndy Whitcroft# print "$herecurr"; 644300df344fSAndy Whitcroft# $clean = 0; 644400df344fSAndy Whitcroft# } 644500df344fSAndy Whitcroft 644622f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 6447c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 64483705ce5bSJoe Perches if (ERROR("SPACING", 64493705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 64503705ce5bSJoe Perches $fix) { 6451194f66fcSJoe Perches $fixed[$fixlinenr] =~ 64523705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 64533705ce5bSJoe Perches } 64543705ce5bSJoe Perches 645522f2a2efSAndy Whitcroft } 645622f2a2efSAndy Whitcroft 64574a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 6458171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 6459171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 64604a0df2efSAndy Whitcroft my $which = $1; 64614a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6462000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 6463000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 64644a0df2efSAndy Whitcroft } 64654a0df2efSAndy Whitcroft } 64664a0df2efSAndy Whitcroft# check for memory barriers without a comment. 6467402c2553SMichael S. Tsirkin 6468402c2553SMichael S. Tsirkin my $barriers = qr{ 6469402c2553SMichael S. Tsirkin mb| 6470402c2553SMichael S. Tsirkin rmb| 6471ad83ec6cSWill Deacon wmb 6472402c2553SMichael S. Tsirkin }x; 6473402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 6474402c2553SMichael S. Tsirkin mb__before_atomic| 6475402c2553SMichael S. Tsirkin mb__after_atomic| 6476402c2553SMichael S. Tsirkin store_release| 6477402c2553SMichael S. Tsirkin load_acquire| 6478402c2553SMichael S. Tsirkin store_mb| 6479402c2553SMichael S. Tsirkin (?:$barriers) 6480402c2553SMichael S. Tsirkin }x; 6481402c2553SMichael S. Tsirkin my $all_barriers = qr{ 6482402c2553SMichael S. Tsirkin (?:$barriers)| 648343e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 648443e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 6485402c2553SMichael S. Tsirkin }x; 6486402c2553SMichael S. Tsirkin 6487402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 64884a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6489c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 6490000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 64914a0df2efSAndy Whitcroft } 64924a0df2efSAndy Whitcroft } 64933ad81779SPaul E. McKenney 6494f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 6495f4073b0fSMichael S. Tsirkin 6496f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 6497f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 6498f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 6499f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 6500f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 6501f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 6502f4073b0fSMichael S. Tsirkin } 6503f4073b0fSMichael S. Tsirkin 6504cb426e99SJoe Perches# check for waitqueue_active without a comment. 6505cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 6506cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 6507cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 6508cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 6509cb426e99SJoe Perches } 6510cb426e99SJoe Perches } 65113ad81779SPaul E. McKenney 65125099a722SMarco Elver# check for data_race without a comment. 65135099a722SMarco Elver if ($line =~ /\bdata_race\s*\(/) { 65145099a722SMarco Elver if (!ctx_has_comment($first_line, $linenr)) { 65155099a722SMarco Elver WARN("DATA_RACE", 65165099a722SMarco Elver "data_race without comment\n" . $herecurr); 65175099a722SMarco Elver } 65185099a722SMarco Elver } 65195099a722SMarco Elver 65204a0df2efSAndy Whitcroft# check of hardware specific defines 6521c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 6522000d1cc1SJoe Perches CHK("ARCH_DEFINES", 6523000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 65240a920b5bSAndy Whitcroft } 6525653d4876SAndy Whitcroft 6526596ed45bSJoe Perches# check that the storage class is not after a type 6527596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 6528000d1cc1SJoe Perches WARN("STORAGE_CLASS", 6529596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 6530596ed45bSJoe Perches } 6531596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 6532596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 6533596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 6534596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 6535596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 6536596ed45bSJoe Perches WARN("STORAGE_CLASS", 6537596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 6538d4977c78STobias Klauser } 6539d4977c78STobias Klauser 6540de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 6541de7d4f0eSAndy Whitcroft# storage class and type. 65429c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 65439c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 6544000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 6545000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 6546de7d4f0eSAndy Whitcroft } 6547de7d4f0eSAndy Whitcroft 65488905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 65492b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 65502b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 6551d5e616fcSJoe Perches if (WARN("INLINE", 6552d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 6553d5e616fcSJoe Perches $fix) { 6554194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 6555d5e616fcSJoe Perches 6556d5e616fcSJoe Perches } 65578905a67cSAndy Whitcroft } 65588905a67cSAndy Whitcroft 65597ebe1d17SDwaipayan Ray# Check for compiler attributes 65602b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 65617ebe1d17SDwaipayan Ray $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { 65627ebe1d17SDwaipayan Ray my $attr = $1; 65637ebe1d17SDwaipayan Ray $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; 65647ebe1d17SDwaipayan Ray 65657ebe1d17SDwaipayan Ray my %attr_list = ( 65660830aab0SJoe Perches "alias" => "__alias", 65677ebe1d17SDwaipayan Ray "aligned" => "__aligned", 65687ebe1d17SDwaipayan Ray "always_inline" => "__always_inline", 65697ebe1d17SDwaipayan Ray "assume_aligned" => "__assume_aligned", 65707ebe1d17SDwaipayan Ray "cold" => "__cold", 65717ebe1d17SDwaipayan Ray "const" => "__attribute_const__", 65727ebe1d17SDwaipayan Ray "copy" => "__copy", 65737ebe1d17SDwaipayan Ray "designated_init" => "__designated_init", 65747ebe1d17SDwaipayan Ray "externally_visible" => "__visible", 65757ebe1d17SDwaipayan Ray "format" => "printf|scanf", 65767ebe1d17SDwaipayan Ray "gnu_inline" => "__gnu_inline", 65777ebe1d17SDwaipayan Ray "malloc" => "__malloc", 65787ebe1d17SDwaipayan Ray "mode" => "__mode", 65797ebe1d17SDwaipayan Ray "no_caller_saved_registers" => "__no_caller_saved_registers", 65807ebe1d17SDwaipayan Ray "noclone" => "__noclone", 65817ebe1d17SDwaipayan Ray "noinline" => "noinline", 65827ebe1d17SDwaipayan Ray "nonstring" => "__nonstring", 65837ebe1d17SDwaipayan Ray "noreturn" => "__noreturn", 65847ebe1d17SDwaipayan Ray "packed" => "__packed", 65857ebe1d17SDwaipayan Ray "pure" => "__pure", 6586339f29d9SJoe Perches "section" => "__section", 65870830aab0SJoe Perches "used" => "__used", 65880830aab0SJoe Perches "weak" => "__weak" 65897ebe1d17SDwaipayan Ray ); 65907ebe1d17SDwaipayan Ray 65917ebe1d17SDwaipayan Ray while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { 6592339f29d9SJoe Perches my $orig_attr = $1; 65937ebe1d17SDwaipayan Ray my $params = ''; 65947ebe1d17SDwaipayan Ray $params = $2 if defined($2); 6595339f29d9SJoe Perches my $curr_attr = $orig_attr; 65967ebe1d17SDwaipayan Ray $curr_attr =~ s/^[\s_]+|[\s_]+$//g; 65977ebe1d17SDwaipayan Ray if (exists($attr_list{$curr_attr})) { 6598339f29d9SJoe Perches my $new = $attr_list{$curr_attr}; 65997ebe1d17SDwaipayan Ray if ($curr_attr eq "format" && $params) { 66007ebe1d17SDwaipayan Ray $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; 6601339f29d9SJoe Perches $new = "__$1\($2"; 66027ebe1d17SDwaipayan Ray } else { 6603339f29d9SJoe Perches $new = "$new$params"; 66047ebe1d17SDwaipayan Ray } 66057ebe1d17SDwaipayan Ray if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 6606339f29d9SJoe Perches "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && 66077ebe1d17SDwaipayan Ray $fix) { 6608339f29d9SJoe Perches my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; 6609339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/$remove//; 6610339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; 6611339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; 6612339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; 66137ebe1d17SDwaipayan Ray } 661439b7e287SJoe Perches } 6615462811d9SJoe Perches } 6616462811d9SJoe Perches 66177ebe1d17SDwaipayan Ray # Check for __attribute__ unused, prefer __always_unused or __maybe_unused 66187ebe1d17SDwaipayan Ray if ($attr =~ /^_*unused/) { 66197ebe1d17SDwaipayan Ray WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 66207ebe1d17SDwaipayan Ray "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); 6621d5e616fcSJoe Perches } 66226061d949SJoe Perches } 66236061d949SJoe Perches 6624619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 66255b57980dSJoe Perches if ($perl_version_ok && 6626619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 6627619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 6628619a908aSJoe Perches $line =~ /\b__weak\b/)) { 6629619a908aSJoe Perches ERROR("WEAK_DECLARATION", 6630619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 6631619a908aSJoe Perches } 6632619a908aSJoe Perches 6633fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 6634e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6635fd39f904STomas Winkler $realfile !~ m@\btools/@ && 6636e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 6637e6176fa4SJoe Perches my $type = $1; 6638e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 6639e6176fa4SJoe Perches $type = $1; 6640e6176fa4SJoe Perches my $kernel_type = 'u'; 6641e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6642e6176fa4SJoe Perches $type =~ /(\d+)/; 6643e6176fa4SJoe Perches $kernel_type .= $1; 6644e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6645e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6646e6176fa4SJoe Perches $fix) { 6647e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6648e6176fa4SJoe Perches } 6649e6176fa4SJoe Perches } 6650e6176fa4SJoe Perches } 6651e6176fa4SJoe Perches 6652938224b5SJoe Perches# check for cast of C90 native int or longer types constants 6653938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6654938224b5SJoe Perches my $cast = $1; 6655938224b5SJoe Perches my $const = $2; 6656938224b5SJoe Perches my $suffix = ""; 6657938224b5SJoe Perches my $newconst = $const; 6658938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 6659938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6660938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6661938224b5SJoe Perches $suffix .= 'LL'; 6662938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 6663938224b5SJoe Perches $suffix .= 'L'; 6664938224b5SJoe Perches } 66650972b8bfSJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 66660972b8bfSJoe Perches "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) && 66670972b8bfSJoe Perches $fix) { 6668938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6669938224b5SJoe Perches } 6670938224b5SJoe Perches } 6671938224b5SJoe Perches 66728f53a9b8SJoe Perches# check for sizeof(&) 66738f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6674000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 6675000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 66768f53a9b8SJoe Perches } 66778f53a9b8SJoe Perches 667866c80b60SJoe Perches# check for sizeof without parenthesis 667966c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 6680d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 6681d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6682d5e616fcSJoe Perches $fix) { 6683194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6684d5e616fcSJoe Perches } 668566c80b60SJoe Perches } 668666c80b60SJoe Perches 668788982feaSJoe Perches# check for struct spinlock declarations 668888982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 668988982feaSJoe Perches WARN("USE_SPINLOCK_T", 669088982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 669188982feaSJoe Perches } 669288982feaSJoe Perches 6693a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 669406668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6695a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 6696caac1d5fSHeba Aamer $fmt =~ s/%%//g; 6697caac1d5fSHeba Aamer if ($fmt !~ /%/) { 6698d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 6699d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6700d5e616fcSJoe Perches $fix) { 6701194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6702d5e616fcSJoe Perches } 6703a6962d72SJoe Perches } 6704a6962d72SJoe Perches } 6705a6962d72SJoe Perches 67060b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 67075b57980dSJoe Perches if ($perl_version_ok && 67080b523769SJoe Perches defined $stat && 67090b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 67100b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6711e3c6bc95STobin C. Harding my $stat_real; 6712e3c6bc95STobin C. Harding 67130b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 67140b523769SJoe Perches $lc = $lc + $linenr; 67150b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6716ffe07513SJoe Perches my $specifier; 6717ffe07513SJoe Perches my $extension; 67183bd32d6aSSakari Ailus my $qualifier; 6719ffe07513SJoe Perches my $bad_specifier = ""; 67200b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 67210b523769SJoe Perches $fmt =~ s/%%//g; 6722e3c6bc95STobin C. Harding 67233bd32d6aSSakari Ailus while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 6724e3c6bc95STobin C. Harding $specifier = $1; 6725e3c6bc95STobin C. Harding $extension = $2; 67263bd32d6aSSakari Ailus $qualifier = $3; 6727af612e43SSakari Ailus if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 67283bd32d6aSSakari Ailus ($extension eq "f" && 6729af612e43SSakari Ailus defined $qualifier && $qualifier !~ /^w/) || 6730af612e43SSakari Ailus ($extension eq "4" && 6731af612e43SSakari Ailus defined $qualifier && $qualifier !~ /^cc/)) { 6732e3c6bc95STobin C. Harding $bad_specifier = $specifier; 67330b523769SJoe Perches last; 67340b523769SJoe Perches } 6735e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6736e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6737e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 67380b523769SJoe Perches } 6739e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6740e3c6bc95STobin 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"); 6741e3c6bc95STobin C. Harding } 6742e3c6bc95STobin C. Harding } 6743e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 67442a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 67451df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 67461df7338aSSergey Senozhatsky my $use = ""; 6747e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 67481df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6749e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 67501df7338aSSergey Senozhatsky } 67512a9f9d85STobin C. Harding 67520b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 6753e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6754e3c6bc95STobin C. Harding } 67550b523769SJoe Perches } 67560b523769SJoe Perches } 67570b523769SJoe Perches 6758554e165cSAndy Whitcroft# Check for misused memsets 67595b57980dSJoe Perches if ($perl_version_ok && 6760d1fe9c09SJoe Perches defined $stat && 67619e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6762554e165cSAndy Whitcroft 6763d7c76ba7SJoe Perches my $ms_addr = $2; 6764d1fe9c09SJoe Perches my $ms_val = $7; 6765d1fe9c09SJoe Perches my $ms_size = $12; 6766d7c76ba7SJoe Perches 6767554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6768554e165cSAndy Whitcroft ERROR("MEMSET", 6769d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6770554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6771554e165cSAndy Whitcroft WARN("MEMSET", 6772d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6773d7c76ba7SJoe Perches } 6774d7c76ba7SJoe Perches } 6775d7c76ba7SJoe Perches 677698a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 67775b57980dSJoe Perches# if ($perl_version_ok && 6778f333195dSJoe Perches# defined $stat && 6779f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6780f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6781f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6782f333195dSJoe Perches# $fix) { 6783f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6784f333195dSJoe Perches# } 6785f333195dSJoe Perches# } 678698a9bba5SJoe Perches 6787b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 67885b57980dSJoe Perches# if ($perl_version_ok && 6789f333195dSJoe Perches# defined $stat && 6790f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6791f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6792f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6793f333195dSJoe Perches# } 6794b6117d17SMateusz Kulikowski 67958617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 67968617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 67975b57980dSJoe Perches# if ($perl_version_ok && 6798f333195dSJoe Perches# defined $stat && 6799f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6800f333195dSJoe Perches# 6801f333195dSJoe Perches# my $ms_val = $7; 6802f333195dSJoe Perches# 6803f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6804f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6805f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6806f333195dSJoe Perches# $fix) { 6807f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6808f333195dSJoe Perches# } 6809f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6810f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6811f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6812f333195dSJoe Perches# $fix) { 6813f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6814f333195dSJoe Perches# } 6815f333195dSJoe Perches# } 6816f333195dSJoe Perches# } 68178617cd09SMateusz Kulikowski 68185dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy 68195dbdb2d8SJoe Perches if ($line =~ /\bstrlcpy\s*\(/) { 68205dbdb2d8SJoe Perches WARN("STRLCPY", 68215dbdb2d8SJoe Perches "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr); 68225dbdb2d8SJoe Perches } 68235dbdb2d8SJoe Perches 6824d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 68255b57980dSJoe Perches if ($perl_version_ok && 6826d1fe9c09SJoe Perches defined $stat && 6827d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6828d1fe9c09SJoe Perches if (defined $2 || defined $7) { 6829d7c76ba7SJoe Perches my $call = $1; 6830d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 6831d7c76ba7SJoe Perches my $arg1 = $3; 6832d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 6833d1fe9c09SJoe Perches my $arg2 = $8; 6834d7c76ba7SJoe Perches my $cast; 6835d7c76ba7SJoe Perches 6836d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 6837d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 6838d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 6839d7c76ba7SJoe Perches $cast = $cast1; 6840d7c76ba7SJoe Perches } else { 6841d7c76ba7SJoe Perches $cast = $cast2; 6842d7c76ba7SJoe Perches } 6843d7c76ba7SJoe Perches WARN("MINMAX", 6844d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 6845554e165cSAndy Whitcroft } 6846554e165cSAndy Whitcroft } 6847554e165cSAndy Whitcroft 68484a273195SJoe Perches# check usleep_range arguments 68495b57980dSJoe Perches if ($perl_version_ok && 68504a273195SJoe Perches defined $stat && 68514a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 68524a273195SJoe Perches my $min = $1; 68534a273195SJoe Perches my $max = $7; 68544a273195SJoe Perches if ($min eq $max) { 68554a273195SJoe Perches WARN("USLEEP_RANGE", 6856458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 68574a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 68584a273195SJoe Perches $min > $max) { 68594a273195SJoe Perches WARN("USLEEP_RANGE", 6860458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 68614a273195SJoe Perches } 68624a273195SJoe Perches } 68634a273195SJoe Perches 6864823b794cSJoe Perches# check for naked sscanf 68655b57980dSJoe Perches if ($perl_version_ok && 6866823b794cSJoe Perches defined $stat && 68676c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 6868823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6869823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 6870823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6871823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 6872823b794cSJoe Perches $lc = $lc + $linenr; 68732a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6874823b794cSJoe Perches WARN("NAKED_SSCANF", 6875823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6876823b794cSJoe Perches } 6877823b794cSJoe Perches 6878afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 68795b57980dSJoe Perches if ($perl_version_ok && 6880afc819abSJoe Perches defined $stat && 6881afc819abSJoe Perches $line =~ /\bsscanf\b/) { 6882afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 6883afc819abSJoe Perches $lc = $lc + $linenr; 68842a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6885afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6886afc819abSJoe Perches my $format = $6; 6887afc819abSJoe Perches my $count = $format =~ tr@%@%@; 6888afc819abSJoe Perches if ($count == 1 && 6889afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 6890afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 6891afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 6892afc819abSJoe Perches } 6893afc819abSJoe Perches } 6894afc819abSJoe Perches } 6895afc819abSJoe Perches 689670dc8a48SJoe Perches# check for new externs in .h files. 689770dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 689870dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 6899d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 690070dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 690170dc8a48SJoe Perches $fix) { 6902194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 690370dc8a48SJoe Perches } 690470dc8a48SJoe Perches } 690570dc8a48SJoe Perches 6906de7d4f0eSAndy Whitcroft# check for new externs in .c files. 6907171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 6908c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 6909171ae1a4SAndy Whitcroft { 6910c45dcabdSAndy Whitcroft my $function_name = $1; 6911c45dcabdSAndy Whitcroft my $paren_space = $2; 6912171ae1a4SAndy Whitcroft 6913171ae1a4SAndy Whitcroft my $s = $stat; 6914171ae1a4SAndy Whitcroft if (defined $cond) { 6915171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 6916171ae1a4SAndy Whitcroft } 6917d8b44b58SKees Cook if ($s =~ /^\s*;/) 6918c45dcabdSAndy Whitcroft { 6919000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6920000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6921de7d4f0eSAndy Whitcroft } 6922de7d4f0eSAndy Whitcroft 6923171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 6924000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 6925000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 6926171ae1a4SAndy Whitcroft } 69279c9ba34eSAndy Whitcroft 69289c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 69299c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 69309c9ba34eSAndy Whitcroft { 6931000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6932000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6933171ae1a4SAndy Whitcroft } 6934171ae1a4SAndy Whitcroft 6935a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 6936a0ad7596SJoe Perches if (defined $stat && 6937d8b44b58SKees Cook $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 6938d8b44b58SKees Cook $1 ne "void") { 6939d8b44b58SKees Cook my $args = trim($1); 6940ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 6941ca0d8929SJoe Perches my $arg = trim($1); 6942d8b44b58SKees Cook if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 6943ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 6944ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 6945ca0d8929SJoe Perches } 6946ca0d8929SJoe Perches } 6947ca0d8929SJoe Perches } 6948ca0d8929SJoe Perches 6949a0ad7596SJoe Perches# check for function definitions 69505b57980dSJoe Perches if ($perl_version_ok && 6951a0ad7596SJoe Perches defined $stat && 6952a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 6953a0ad7596SJoe Perches $context_function = $1; 6954a0ad7596SJoe Perches 6955a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 6956a0ad7596SJoe Perches my $ok = 0; 6957a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 6958a0ad7596SJoe Perches my $herectx = $here . "\n"; 6959a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6960a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 6961a0ad7596SJoe Perches $herectx .= $rl . "\n"; 6962a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 6963a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 6964a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 6965a0ad7596SJoe Perches } 6966a0ad7596SJoe Perches if (!$ok) { 6967a0ad7596SJoe Perches ERROR("OPEN_BRACE", 6968a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 6969a0ad7596SJoe Perches } 6970a0ad7596SJoe Perches } 6971a0ad7596SJoe Perches 6972de7d4f0eSAndy Whitcroft# checks for new __setup's 6973de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 6974de7d4f0eSAndy Whitcroft my $name = $1; 6975de7d4f0eSAndy Whitcroft 6976de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 6977000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 69782581ac7cSTim Froidcoeur "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); 6979de7d4f0eSAndy Whitcroft } 6980653d4876SAndy Whitcroft } 69819c0ca6f9SAndy Whitcroft 6982e29a70f1SJoe Perches# check for pointless casting of alloc functions 6983e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 6984000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 6985000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 69869c0ca6f9SAndy Whitcroft } 698713214adfSAndy Whitcroft 6988a640d25cSJoe Perches# alloc style 6989a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 69905b57980dSJoe Perches if ($perl_version_ok && 6991e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 6992a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 6993a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 6994a640d25cSJoe Perches } 6995a640d25cSJoe Perches 699660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 69975b57980dSJoe Perches if ($perl_version_ok && 69981b4a2ed4SJoe Perches defined $stat && 69991b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 700060a55369SJoe Perches my $oldfunc = $3; 700160a55369SJoe Perches my $a1 = $4; 700260a55369SJoe Perches my $a2 = $10; 700360a55369SJoe Perches my $newfunc = "kmalloc_array"; 700460a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 700560a55369SJoe Perches my $r1 = $a1; 700660a55369SJoe Perches my $r2 = $a2; 700760a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 700860a55369SJoe Perches $r1 = $a2; 700960a55369SJoe Perches $r2 = $a1; 701060a55369SJoe Perches } 7011e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 7012e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 70131b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 7014e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 7015e3d95a2aSTobin C. Harding 7016e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 70171b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 70181b4a2ed4SJoe Perches $cnt == 1 && 7019e367455aSJoe Perches $fix) { 7020194f66fcSJoe 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; 702160a55369SJoe Perches } 702260a55369SJoe Perches } 702360a55369SJoe Perches } 702460a55369SJoe Perches 7025972fdea2SJoe Perches# check for krealloc arg reuse 70265b57980dSJoe Perches if ($perl_version_ok && 70274cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 70284cab63ceSJoe Perches $1 eq $3) { 7029972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 7030972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 7031972fdea2SJoe Perches } 7032972fdea2SJoe Perches 70335ce59ae0SJoe Perches# check for alloc argument mismatch 70347e6cdd7fSChristophe JAILLET if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) { 70355ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 70365ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 70375ce59ae0SJoe Perches } 70385ce59ae0SJoe Perches 7039caf2a54fSJoe Perches# check for multiple semicolons 7040caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 7041d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 7042d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 7043d5e616fcSJoe Perches $fix) { 7044194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 7045d5e616fcSJoe Perches } 7046d1e2ad07SJoe Perches } 7047d1e2ad07SJoe Perches 7048cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 7049cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 7050cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 70510ab90191SJoe Perches my $ull = ""; 70520ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 70530ab90191SJoe Perches if (CHK("BIT_MACRO", 70540ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 70550ab90191SJoe Perches $fix) { 70560ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 70570ab90191SJoe Perches } 70580ab90191SJoe Perches } 70590ab90191SJoe Perches 706050161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) 70613e89ad85SJerome Forissier if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { 706250161266SJoe Perches WARN("IS_ENABLED_CONFIG", 70633e89ad85SJerome Forissier "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); 706450161266SJoe Perches } 706550161266SJoe Perches 70662d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 70673e89ad85SJerome 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*$/) { 70682d632745SJoe Perches my $config = $1; 70692d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 70703e89ad85SJerome Forissier "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && 70712d632745SJoe Perches $fix) { 70722d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 70732d632745SJoe Perches } 70742d632745SJoe Perches } 70752d632745SJoe Perches 7076f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 7077f36d3eb8SJoe Perches my @fallthroughs = ( 7078f36d3eb8SJoe Perches 'fallthrough', 7079f36d3eb8SJoe Perches '@fallthrough@', 7080f36d3eb8SJoe Perches 'lint -fallthrough[ \t]*', 7081f36d3eb8SJoe Perches 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 7082f36d3eb8SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 7083f36d3eb8SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 7084f36d3eb8SJoe Perches 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 7085f36d3eb8SJoe Perches ); 7086f36d3eb8SJoe Perches if ($raw_comment ne '') { 7087f36d3eb8SJoe Perches foreach my $ft (@fallthroughs) { 7088f36d3eb8SJoe Perches if ($raw_comment =~ /$ft/) { 7089f36d3eb8SJoe Perches my $msg_level = \&WARN; 7090f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 7091f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 7092f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 7093f36d3eb8SJoe Perches last; 7094f36d3eb8SJoe Perches } 7095f36d3eb8SJoe Perches } 7096f36d3eb8SJoe Perches } 7097f36d3eb8SJoe Perches 7098d1e2ad07SJoe Perches# check for switch/default statements without a break; 70995b57980dSJoe Perches if ($perl_version_ok && 7100d1e2ad07SJoe Perches defined $stat && 7101d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 7102d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 7103e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 7104e3d95a2aSTobin C. Harding 7105d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 7106d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 7107caf2a54fSJoe Perches } 7108caf2a54fSJoe Perches 710913214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 7110d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 7111d5e616fcSJoe Perches if (WARN("USE_FUNC", 7112d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 7113d5e616fcSJoe Perches $fix) { 7114194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 7115d5e616fcSJoe Perches } 711613214adfSAndy Whitcroft } 7117773647a0SAndy Whitcroft 711862ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 711962ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 712062ec818fSJoe Perches ERROR("DATE_TIME", 712162ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 712262ec818fSJoe Perches } 712362ec818fSJoe Perches 71242c92488aSJoe Perches# check for use of yield() 71252c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 71262c92488aSJoe Perches WARN("YIELD", 71272c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 71282c92488aSJoe Perches } 71292c92488aSJoe Perches 7130179f8f40SJoe Perches# check for comparisons against true and false 7131179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 7132179f8f40SJoe Perches my $lead = $1; 7133179f8f40SJoe Perches my $arg = $2; 7134179f8f40SJoe Perches my $test = $3; 7135179f8f40SJoe Perches my $otype = $4; 7136179f8f40SJoe Perches my $trail = $5; 7137179f8f40SJoe Perches my $op = "!"; 7138179f8f40SJoe Perches 7139179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 7140179f8f40SJoe Perches 7141179f8f40SJoe Perches my $type = lc($otype); 7142179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 7143179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 7144179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 7145179f8f40SJoe Perches $op = ""; 7146179f8f40SJoe Perches } 7147179f8f40SJoe Perches 7148179f8f40SJoe Perches CHK("BOOL_COMPARISON", 7149179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 7150179f8f40SJoe Perches 7151179f8f40SJoe Perches## maybe suggesting a correct construct would better 7152179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 7153179f8f40SJoe Perches 7154179f8f40SJoe Perches } 7155179f8f40SJoe Perches } 7156179f8f40SJoe Perches 71574882720bSThomas Gleixner# check for semaphores initialized locked 71584882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 7159000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 7160000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 7161773647a0SAndy Whitcroft } 71626712d858SJoe Perches 716367d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 716467d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 7165000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 716667d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 7167773647a0SAndy Whitcroft } 71686712d858SJoe Perches 7169ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 7170f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 7171000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 7172ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 7173f3db6639SMichael Ellerman } 71746712d858SJoe Perches 71753d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 71763d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 71773d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 71783d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 71793d709ab5SPaul E. McKenney } 71803d709ab5SPaul E. McKenney 71819189c7e7SJoe Perches# check for deprecated apis 71829189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 71839189c7e7SJoe Perches my $deprecated_api = $1; 71849189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 71859189c7e7SJoe Perches WARN("DEPRECATED_API", 71869189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 71879189c7e7SJoe Perches } 71889189c7e7SJoe Perches 71890f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 7190d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 7191ced69da1SQuentin Monnet if (defined($const_structs) && 7192ced69da1SQuentin Monnet $line !~ /\bconst\b/ && 7193d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 7194000d1cc1SJoe Perches WARN("CONST_STRUCT", 7195d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 71962b6db5cbSAndy Whitcroft } 7197773647a0SAndy Whitcroft 7198773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 7199773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 720035cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS 7201773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 7202c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 7203c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 7204171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 7205171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 720635cdcbfcSPeng Wang $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ && 720735cdcbfcSPeng Wang $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/) 7208773647a0SAndy Whitcroft { 7209000d1cc1SJoe Perches WARN("NR_CPUS", 7210000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 7211773647a0SAndy Whitcroft } 72129c9ba34eSAndy Whitcroft 721352ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 721452ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 721552ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 721652ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 721752ea8506SJoe Perches } 721852ea8506SJoe Perches 7219acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 72205b57980dSJoe Perches if ($perl_version_ok && 7221acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 7222acd9362cSJoe Perches WARN("LIKELY_MISUSE", 7223acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 7224acd9362cSJoe Perches } 7225acd9362cSJoe Perches 7226fbe74541SJoe Perches# return sysfs_emit(foo, fmt, ...) fmt without newline 7227fbe74541SJoe Perches if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ && 7228fbe74541SJoe Perches substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) { 7229fbe74541SJoe Perches my $offset = $+[6] - 1; 7230fbe74541SJoe Perches if (WARN("SYSFS_EMIT", 7231fbe74541SJoe Perches "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) && 7232fbe74541SJoe Perches $fix) { 7233fbe74541SJoe Perches substr($fixed[$fixlinenr], $offset, 0) = '\\n'; 7234fbe74541SJoe Perches } 7235fbe74541SJoe Perches } 7236fbe74541SJoe Perches 7237de3f186fSDenis Efremov# nested likely/unlikely calls 7238de3f186fSDenis Efremov if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 7239de3f186fSDenis Efremov WARN("LIKELY_MISUSE", 7240de3f186fSDenis Efremov "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 7241de3f186fSDenis Efremov } 7242de3f186fSDenis Efremov 7243691d77b6SAndy Whitcroft# whine mightly about in_atomic 7244691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 7245691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 7246000d1cc1SJoe Perches ERROR("IN_ATOMIC", 7247000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 7248f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 7249000d1cc1SJoe Perches WARN("IN_ATOMIC", 7250000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 7251691d77b6SAndy Whitcroft } 7252691d77b6SAndy Whitcroft } 72531704f47bSPeter Zijlstra 72541704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 72551704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 72561704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 72571704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 72581704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 72591704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 7260000d1cc1SJoe Perches ERROR("LOCKDEP", 7261000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 72621704f47bSPeter Zijlstra } 72631704f47bSPeter Zijlstra } 726488f8831cSDave Jones 7265b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 7266b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 7267000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 7268000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 726988f8831cSDave Jones } 72702435880fSJoe Perches 727100180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 727200180468SJoe Perches# and whether or not function naming is typical and if 727300180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 72745b57980dSJoe Perches if ($perl_version_ok && 727500180468SJoe Perches defined $stat && 727600180468SJoe 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*\)/) { 727700180468SJoe Perches my $var = $1; 727800180468SJoe Perches my $perms = $2; 727900180468SJoe Perches my $show = $3; 728000180468SJoe Perches my $store = $4; 728100180468SJoe Perches my $octal_perms = perms_to_octal($perms); 728200180468SJoe Perches if ($show =~ /^${var}_show$/ && 728300180468SJoe Perches $store =~ /^${var}_store$/ && 728400180468SJoe Perches $octal_perms eq "0644") { 728500180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 728600180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 728700180468SJoe Perches $fix) { 728800180468SJoe 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})/; 728900180468SJoe Perches } 729000180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 729100180468SJoe Perches $store =~ /^NULL$/ && 729200180468SJoe Perches $octal_perms eq "0444") { 729300180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 729400180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 729500180468SJoe Perches $fix) { 729600180468SJoe 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})/; 729700180468SJoe Perches } 729800180468SJoe Perches } elsif ($show =~ /^NULL$/ && 729900180468SJoe Perches $store =~ /^${var}_store$/ && 730000180468SJoe Perches $octal_perms eq "0200") { 730100180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 730200180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 730300180468SJoe Perches $fix) { 730400180468SJoe 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})/; 730500180468SJoe Perches } 730600180468SJoe Perches } elsif ($octal_perms eq "0644" || 730700180468SJoe Perches $octal_perms eq "0444" || 730800180468SJoe Perches $octal_perms eq "0200") { 730900180468SJoe Perches my $newshow = "$show"; 731000180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 731100180468SJoe Perches my $newstore = $store; 731200180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 731300180468SJoe Perches my $rename = ""; 731400180468SJoe Perches if ($show ne $newshow) { 731500180468SJoe Perches $rename .= " '$show' to '$newshow'"; 731600180468SJoe Perches } 731700180468SJoe Perches if ($store ne $newstore) { 731800180468SJoe Perches $rename .= " '$store' to '$newstore'"; 731900180468SJoe Perches } 732000180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 732100180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 732200180468SJoe Perches } else { 732300180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 732400180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 732500180468SJoe Perches } 732600180468SJoe Perches } 732700180468SJoe Perches 7328515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 7329515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 733073121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 733173121534SJoe Perches# specific definition of not visible in sysfs. 733273121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 733373121534SJoe Perches# use the default permissions 73345b57980dSJoe Perches if ($perl_version_ok && 7335459cf0aeSJoe Perches defined $stat && 7336515a235eSJoe Perches $line =~ /$mode_perms_search/) { 73372435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 73382435880fSJoe Perches my $func = $entry->[0]; 73392435880fSJoe Perches my $arg_pos = $entry->[1]; 73402435880fSJoe Perches 7341459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 7342459cf0aeSJoe Perches $lc = $lc + $linenr; 73432a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 7344459cf0aeSJoe Perches 73452435880fSJoe Perches my $skip_args = ""; 73462435880fSJoe Perches if ($arg_pos > 1) { 73472435880fSJoe Perches $arg_pos--; 73482435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 73492435880fSJoe Perches } 7350f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 7351459cf0aeSJoe Perches if ($stat =~ /$test/) { 73522435880fSJoe Perches my $val = $1; 73532435880fSJoe Perches $val = $6 if ($skip_args ne ""); 735473121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 735573121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 735673121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 73572435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 7358459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 7359f90774e1SJoe Perches } 7360f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 7361c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 7362459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 73632435880fSJoe Perches } 7364459cf0aeSJoe Perches } 7365459cf0aeSJoe Perches } 7366459cf0aeSJoe Perches } 7367459cf0aeSJoe Perches 7368459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 7369bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 737000180468SJoe Perches my $oval = $1; 737100180468SJoe Perches my $octal = perms_to_octal($oval); 7372f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 7373459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 7374f90774e1SJoe Perches $fix) { 737500180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 73762435880fSJoe Perches } 737713214adfSAndy Whitcroft } 73785a6d20ceSBjorn Andersson 73795a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 73805a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 73815a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 73825a6d20ceSBjorn Andersson my $valid_licenses = qr{ 73835a6d20ceSBjorn Andersson GPL| 73845a6d20ceSBjorn Andersson GPL\ v2| 73855a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 73865a6d20ceSBjorn Andersson Dual\ BSD/GPL| 73875a6d20ceSBjorn Andersson Dual\ MIT/GPL| 73885a6d20ceSBjorn Andersson Dual\ MPL/GPL| 73895a6d20ceSBjorn Andersson Proprietary 73905a6d20ceSBjorn Andersson }x; 73915a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 73925a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 73935a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 73945a6d20ceSBjorn Andersson } 73955a6d20ceSBjorn Andersson } 73966a8d76cbSMatteo Croce 73976a8d76cbSMatteo Croce# check for sysctl duplicate constants 73986a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 73996a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 74006a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 74016a8d76cbSMatteo Croce } 7402515a235eSJoe Perches } 740313214adfSAndy Whitcroft 740413214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 740513214adfSAndy Whitcroft # so just keep quiet. 740613214adfSAndy Whitcroft if ($#rawlines == -1) { 740713214adfSAndy Whitcroft exit(0); 74080a920b5bSAndy Whitcroft } 74090a920b5bSAndy Whitcroft 74108905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 74118905a67cSAndy Whitcroft # things that appear to be patches. 74128905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 74138905a67cSAndy Whitcroft exit(0); 74148905a67cSAndy Whitcroft } 74158905a67cSAndy Whitcroft 7416e73d2715SDwaipayan Ray # This is not a patch, and we are in 'no-patch' mode so 74178905a67cSAndy Whitcroft # just keep quiet. 74188905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 74198905a67cSAndy Whitcroft exit(0); 74208905a67cSAndy Whitcroft } 74218905a67cSAndy Whitcroft 7422a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 7423000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 7424000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 74250a920b5bSAndy Whitcroft } 7426cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 7427cd261496SGeert Uytterhoeven if ($signoff == 0) { 7428000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 7429000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 743048ca2d8aSDwaipayan Ray } elsif ($authorsignoff != 1) { 743148ca2d8aSDwaipayan Ray # authorsignoff values: 743248ca2d8aSDwaipayan Ray # 0 -> missing sign off 743348ca2d8aSDwaipayan Ray # 1 -> sign off identical 743448ca2d8aSDwaipayan Ray # 2 -> names and addresses match, comments mismatch 743548ca2d8aSDwaipayan Ray # 3 -> addresses match, names different 743648ca2d8aSDwaipayan Ray # 4 -> names match, addresses different 743748ca2d8aSDwaipayan Ray # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match 743848ca2d8aSDwaipayan Ray 743948ca2d8aSDwaipayan Ray my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; 744048ca2d8aSDwaipayan Ray 744148ca2d8aSDwaipayan Ray if ($authorsignoff == 0) { 744248ca2d8aSDwaipayan Ray ERROR("NO_AUTHOR_SIGN_OFF", 7443cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 744448ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 2) { 744548ca2d8aSDwaipayan Ray CHK("FROM_SIGN_OFF_MISMATCH", 744648ca2d8aSDwaipayan Ray "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); 744748ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 3) { 744848ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 744948ca2d8aSDwaipayan Ray "From:/Signed-off-by: email name mismatch: $sob_msg\n"); 745048ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 4) { 745148ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 745248ca2d8aSDwaipayan Ray "From:/Signed-off-by: email address mismatch: $sob_msg\n"); 745348ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 5) { 745448ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 745548ca2d8aSDwaipayan Ray "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); 745648ca2d8aSDwaipayan Ray } 7457cd261496SGeert Uytterhoeven } 74580a920b5bSAndy Whitcroft } 74590a920b5bSAndy Whitcroft 7460f0a594c1SAndy Whitcroft print report_dump(); 746113214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 746213214adfSAndy Whitcroft print "$filename " if ($summary_file); 74636c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 74646c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 74656c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 74666c72ffaaSAndy Whitcroft } 74678905a67cSAndy Whitcroft 7468d2c0a235SAndy Whitcroft if ($quiet == 0) { 7469ef212196SJoe Perches # If there were any defects found and not already fixing them 7470ef212196SJoe Perches if (!$clean and !$fix) { 7471ef212196SJoe Perches print << "EOM" 7472ef212196SJoe Perches 7473ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 7474ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 7475ef212196SJoe PerchesEOM 7476ef212196SJoe Perches } 7477d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 7478d2c0a235SAndy Whitcroft # then suggest that. 7479d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 7480b0781216SMike Frysinger $rpt_cleaners = 0; 7481d8469f16SJoe Perches print << "EOM" 7482d8469f16SJoe Perches 7483d8469f16SJoe PerchesNOTE: Whitespace errors detected. 7484d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 7485d8469f16SJoe PerchesEOM 7486d2c0a235SAndy Whitcroft } 7487d2c0a235SAndy Whitcroft } 7488d2c0a235SAndy Whitcroft 7489d752fcc8SJoe Perches if ($clean == 0 && $fix && 7490d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 7491d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 74929624b8d6SJoe Perches my $newfile = $filename; 74939624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 74943705ce5bSJoe Perches my $linecount = 0; 74953705ce5bSJoe Perches my $f; 74963705ce5bSJoe Perches 7497d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 7498d752fcc8SJoe Perches 74993705ce5bSJoe Perches open($f, '>', $newfile) 75003705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 75013705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 75023705ce5bSJoe Perches $linecount++; 75033705ce5bSJoe Perches if ($file) { 75043705ce5bSJoe Perches if ($linecount > 3) { 75053705ce5bSJoe Perches $fixed_line =~ s/^\+//; 75063705ce5bSJoe Perches print $f $fixed_line . "\n"; 75073705ce5bSJoe Perches } 75083705ce5bSJoe Perches } else { 75093705ce5bSJoe Perches print $f $fixed_line . "\n"; 75103705ce5bSJoe Perches } 75113705ce5bSJoe Perches } 75123705ce5bSJoe Perches close($f); 75133705ce5bSJoe Perches 75143705ce5bSJoe Perches if (!$quiet) { 75153705ce5bSJoe Perches print << "EOM"; 7516d8469f16SJoe Perches 75173705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 75183705ce5bSJoe Perches 75193705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 75203705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 75213705ce5bSJoe Perches 75223705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 75233705ce5bSJoe PerchesNo warranties, expressed or implied... 75243705ce5bSJoe PerchesEOM 75253705ce5bSJoe Perches } 75263705ce5bSJoe Perches } 75273705ce5bSJoe Perches 7528d8469f16SJoe Perches if ($quiet == 0) { 7529d8469f16SJoe Perches print "\n"; 7530d8469f16SJoe Perches if ($clean == 1) { 7531d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 7532d8469f16SJoe Perches } else { 7533d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 75340a920b5bSAndy Whitcroft } 75350a920b5bSAndy Whitcroft } 75360a920b5bSAndy Whitcroft return $clean; 75370a920b5bSAndy Whitcroft} 7538