1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl 2882ea1d6SJoe Perches# SPDX-License-Identifier: GPL-2.0 3882ea1d6SJoe Perches# 4dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit) 500df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 62a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite) 7015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]> 8882ea1d6SJoe Perches# (c) 2010-2018 Joe Perches <[email protected]> 90a920b5bSAndy Whitcroft 100a920b5bSAndy Whitcroftuse strict; 11cb77f0d6SKamil Rytarowskiuse warnings; 12c707a81dSJoe Perchesuse POSIX; 1336061e38SJoe Perchesuse File::Basename; 1436061e38SJoe Perchesuse Cwd 'abs_path'; 1557230297SJoe Perchesuse Term::ANSIColor qw(:constants); 16cd261496SGeert Uytterhoevenuse Encode qw(decode encode); 170a920b5bSAndy Whitcroft 180a920b5bSAndy Whitcroftmy $P = $0; 1936061e38SJoe Perchesmy $D = dirname(abs_path($P)); 200a920b5bSAndy Whitcroft 21000d1cc1SJoe Perchesmy $V = '0.32'; 220a920b5bSAndy Whitcroft 230a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 240a920b5bSAndy Whitcroft 250a920b5bSAndy Whitcroftmy $quiet = 0; 2652178ce0SDwaipayan Raymy $verbose = 0; 2752178ce0SDwaipayan Raymy %verbose_messages = (); 2852178ce0SDwaipayan Raymy %verbose_emitted = (); 290a920b5bSAndy Whitcroftmy $tree = 1; 300a920b5bSAndy Whitcroftmy $chk_signoff = 1; 310a920b5bSAndy Whitcroftmy $chk_patch = 1; 32773647a0SAndy Whitcroftmy $tst_only; 336c72ffaaSAndy Whitcroftmy $emacs = 0; 348905a67cSAndy Whitcroftmy $terse = 0; 3534d8815fSJoe Perchesmy $showfile = 0; 366c72ffaaSAndy Whitcroftmy $file = 0; 374a593c34SDu, Changbinmy $git = 0; 380dea9f1eSJoe Perchesmy %git_commits = (); 396c72ffaaSAndy Whitcroftmy $check = 0; 402ac73b4fSJoe Perchesmy $check_orig = 0; 418905a67cSAndy Whitcroftmy $summary = 1; 428905a67cSAndy Whitcroftmy $mailback = 0; 4313214adfSAndy Whitcroftmy $summary_file = 0; 44000d1cc1SJoe Perchesmy $show_types = 0; 453beb42ecSJoe Perchesmy $list_types = 0; 463705ce5bSJoe Perchesmy $fix = 0; 479624b8d6SJoe Perchesmy $fix_inplace = 0; 486c72ffaaSAndy Whitcroftmy $root; 490f7f635bSJoe Perchesmy $gitroot = $ENV{'GIT_DIR'}; 500f7f635bSJoe Perches$gitroot = ".git" if !defined($gitroot); 51c2fdda0dSAndy Whitcroftmy %debug; 523445686aSJoe Perchesmy %camelcase = (); 5391bfe484SJoe Perchesmy %use_type = (); 5491bfe484SJoe Perchesmy @use = (); 5591bfe484SJoe Perchesmy %ignore_type = (); 56000d1cc1SJoe Perchesmy @ignore = (); 5777f5b10aSHannes Edermy $help = 0; 58000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 59bdc48fa1SJoe Perchesmy $max_line_length = 100; 60d62a201fSDave Hansenmy $ignore_perl_version = 0; 61d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 6256193274SVadim Bendeburymy $min_conf_desc_length = 4; 6366b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 64ebfd7d62SJoe Perchesmy $codespell = 0; 65f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt"; 660ee3e7b8SPeter Ujfalusimy $user_codespellfile = ""; 67bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 6852178ce0SDwaipayan Raymy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst"; 69ced69da1SQuentin Monnetmy $typedefsfile; 70737c0767SJohn Brooksmy $color = "auto"; 7198005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE 72dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE 73dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git'; 74713a09deSAntonio Borneomy $tabsize = 8; 753e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_"; 7677f5b10aSHannes Eder 775b2c7334SJim Cromiemy %maybe_linker_symbol; # for externs in c exceptions, when seen in *vmlinux.lds.h 785b2c7334SJim Cromie 7977f5b10aSHannes Edersub help { 8077f5b10aSHannes Eder my ($exitcode) = @_; 8177f5b10aSHannes Eder 8277f5b10aSHannes Eder print << "EOM"; 8377f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 8477f5b10aSHannes EderVersion: $V 8577f5b10aSHannes Eder 8677f5b10aSHannes EderOptions: 8777f5b10aSHannes Eder -q, --quiet quiet 8852178ce0SDwaipayan Ray -v, --verbose verbose mode 8977f5b10aSHannes Eder --no-tree run without a kernel tree 9077f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 9177f5b10aSHannes Eder --patch treat FILE as patchfile (default) 9277f5b10aSHannes Eder --emacs emacs compile window format 9377f5b10aSHannes Eder --terse one line per report 9434d8815fSJoe Perches --showfile emit diffed file position, not input file position 954a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 964a593c34SDu, Changbin single git commit with: 974a593c34SDu, Changbin <rev> 984a593c34SDu, Changbin <rev>^ 994a593c34SDu, Changbin <rev>~n 1004a593c34SDu, Changbin multiple git commits with: 1014a593c34SDu, Changbin <rev1>..<rev2> 1024a593c34SDu, Changbin <rev1>...<rev2> 1034a593c34SDu, Changbin <rev>-<count> 1044a593c34SDu, Changbin git merges are ignored 10577f5b10aSHannes Eder -f, --file treat FILE as regular source file 10677f5b10aSHannes Eder --subjective, --strict enable more subjective tests 1073beb42ecSJoe Perches --list-types list the possible message types 10891bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 109000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 1103beb42ecSJoe Perches --show-types show the specific message type in the output 111bdc48fa1SJoe Perches --max-line-length=n set the maximum line length, (default $max_line_length) 112bdc48fa1SJoe Perches if exceeded, warn on patches 113bdc48fa1SJoe Perches requires --strict for use with --file 11456193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 115bdc48fa1SJoe Perches --tab-size=n set the number of spaces for tab (default $tabsize) 11677f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 11777f5b10aSHannes Eder --no-summary suppress the per-file summary 11877f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 11977f5b10aSHannes Eder --summary-file include the filename in summary 12077f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 12177f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 12277f5b10aSHannes Eder is all off) 12377f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 12477f5b10aSHannes Eder literally 1253705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1263705ce5bSJoe Perches If correctable single-line errors exist, create 1273705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1283705ce5bSJoe Perches with potential errors corrected to the preferred 1293705ce5bSJoe Perches checkpatch style 1309624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1319624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1329624b8d6SJoe Perches file. It's your fault if there's no backup or git 133d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 134d62a201fSDave Hansen runtime errors. 135ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 1360ee3e7b8SPeter Ujfalusi (default:$codespellfile) 137ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 13875ad8c57SJerome Forissier --typedefsfile Read additional types from this file 139737c0767SJohn Brooks --color[=WHEN] Use colors 'always', 'never', or only when output 140737c0767SJohn Brooks is a terminal ('auto'). Default is 'auto'. 1413e89ad85SJerome Forissier --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default 1423e89ad85SJerome Forissier ${CONFIG_}) 14377f5b10aSHannes Eder -h, --help, --version display this help and exit 14477f5b10aSHannes Eder 14577f5b10aSHannes EderWhen FILE is - read standard input. 14677f5b10aSHannes EderEOM 14777f5b10aSHannes Eder 14877f5b10aSHannes Eder exit($exitcode); 14977f5b10aSHannes Eder} 15077f5b10aSHannes Eder 1513beb42ecSJoe Perchessub uniq { 1523beb42ecSJoe Perches my %seen; 1533beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1543beb42ecSJoe Perches} 1553beb42ecSJoe Perches 1563beb42ecSJoe Perchessub list_types { 1573beb42ecSJoe Perches my ($exitcode) = @_; 1583beb42ecSJoe Perches 1593beb42ecSJoe Perches my $count = 0; 1603beb42ecSJoe Perches 1613beb42ecSJoe Perches local $/ = undef; 1623beb42ecSJoe Perches 1633beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1643beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1653beb42ecSJoe Perches 1663beb42ecSJoe Perches my $text = <$script>; 1673beb42ecSJoe Perches close($script); 1683beb42ecSJoe Perches 16952178ce0SDwaipayan Ray my %types = (); 1700547fa58SJean Delvare # Also catch when type or level is passed through a variable 17152178ce0SDwaipayan Ray while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { 17252178ce0SDwaipayan Ray if (defined($1)) { 17352178ce0SDwaipayan Ray if (exists($types{$2})) { 17452178ce0SDwaipayan Ray $types{$2} .= ",$1" if ($types{$2} ne $1); 17552178ce0SDwaipayan Ray } else { 17652178ce0SDwaipayan Ray $types{$2} = $1; 1773beb42ecSJoe Perches } 17852178ce0SDwaipayan Ray } else { 17952178ce0SDwaipayan Ray $types{$2} = "UNDETERMINED"; 18052178ce0SDwaipayan Ray } 18152178ce0SDwaipayan Ray } 18252178ce0SDwaipayan Ray 1833beb42ecSJoe Perches print("#\tMessage type\n\n"); 18452178ce0SDwaipayan Ray if ($color) { 18552178ce0SDwaipayan Ray print(" ( Color coding: "); 18652178ce0SDwaipayan Ray print(RED . "ERROR" . RESET); 18752178ce0SDwaipayan Ray print(" | "); 18852178ce0SDwaipayan Ray print(YELLOW . "WARNING" . RESET); 18952178ce0SDwaipayan Ray print(" | "); 19052178ce0SDwaipayan Ray print(GREEN . "CHECK" . RESET); 19152178ce0SDwaipayan Ray print(" | "); 19252178ce0SDwaipayan Ray print("Multiple levels / Undetermined"); 19352178ce0SDwaipayan Ray print(" )\n\n"); 19452178ce0SDwaipayan Ray } 19552178ce0SDwaipayan Ray 19652178ce0SDwaipayan Ray foreach my $type (sort keys %types) { 19752178ce0SDwaipayan Ray my $orig_type = $type; 19852178ce0SDwaipayan Ray if ($color) { 19952178ce0SDwaipayan Ray my $level = $types{$type}; 20052178ce0SDwaipayan Ray if ($level eq "ERROR") { 20152178ce0SDwaipayan Ray $type = RED . $type . RESET; 20252178ce0SDwaipayan Ray } elsif ($level eq "WARN") { 20352178ce0SDwaipayan Ray $type = YELLOW . $type . RESET; 20452178ce0SDwaipayan Ray } elsif ($level eq "CHK") { 20552178ce0SDwaipayan Ray $type = GREEN . $type . RESET; 20652178ce0SDwaipayan Ray } 20752178ce0SDwaipayan Ray } 2083beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 20952178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$orig_type})) { 21052178ce0SDwaipayan Ray my $message = $verbose_messages{$orig_type}; 21152178ce0SDwaipayan Ray $message =~ s/\n/\n\t/g; 21252178ce0SDwaipayan Ray print("\t" . $message . "\n\n"); 21352178ce0SDwaipayan Ray } 2143beb42ecSJoe Perches } 2153beb42ecSJoe Perches 2163beb42ecSJoe Perches exit($exitcode); 2173beb42ecSJoe Perches} 2183beb42ecSJoe Perches 219000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 220000d1cc1SJoe Perchesif (-f $conf) { 221000d1cc1SJoe Perches my @conf_args; 222000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 223000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 224000d1cc1SJoe Perches 225000d1cc1SJoe Perches while (<$conffile>) { 226000d1cc1SJoe Perches my $line = $_; 227000d1cc1SJoe Perches 228000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 229000d1cc1SJoe Perches $line =~ s/^\s*//g; 230000d1cc1SJoe Perches $line =~ s/\s+/ /g; 231000d1cc1SJoe Perches 232000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 233000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 234000d1cc1SJoe Perches 235000d1cc1SJoe Perches my @words = split(" ", $line); 236000d1cc1SJoe Perches foreach my $word (@words) { 237000d1cc1SJoe Perches last if ($word =~ m/^#/); 238000d1cc1SJoe Perches push (@conf_args, $word); 239000d1cc1SJoe Perches } 240000d1cc1SJoe Perches } 241000d1cc1SJoe Perches close($conffile); 242000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 243000d1cc1SJoe Perches} 244000d1cc1SJoe Perches 24552178ce0SDwaipayan Raysub load_docs { 24652178ce0SDwaipayan Ray open(my $docs, '<', "$docsfile") 24752178ce0SDwaipayan Ray or warn "$P: Can't read the documentation file $docsfile $!\n"; 24852178ce0SDwaipayan Ray 24952178ce0SDwaipayan Ray my $type = ''; 25052178ce0SDwaipayan Ray my $desc = ''; 25152178ce0SDwaipayan Ray my $in_desc = 0; 25252178ce0SDwaipayan Ray 25352178ce0SDwaipayan Ray while (<$docs>) { 25452178ce0SDwaipayan Ray chomp; 25552178ce0SDwaipayan Ray my $line = $_; 25652178ce0SDwaipayan Ray $line =~ s/\s+$//; 25752178ce0SDwaipayan Ray 25852178ce0SDwaipayan Ray if ($line =~ /^\s*\*\*(.+)\*\*$/) { 25952178ce0SDwaipayan Ray if ($desc ne '') { 26052178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 26152178ce0SDwaipayan Ray } 26252178ce0SDwaipayan Ray $type = $1; 26352178ce0SDwaipayan Ray $desc = ''; 26452178ce0SDwaipayan Ray $in_desc = 1; 26552178ce0SDwaipayan Ray } elsif ($in_desc) { 26652178ce0SDwaipayan Ray if ($line =~ /^(?:\s{4,}|$)/) { 26752178ce0SDwaipayan Ray $line =~ s/^\s{4}//; 26852178ce0SDwaipayan Ray $desc .= $line; 26952178ce0SDwaipayan Ray $desc .= "\n"; 27052178ce0SDwaipayan Ray } else { 27152178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 27252178ce0SDwaipayan Ray $type = ''; 27352178ce0SDwaipayan Ray $desc = ''; 27452178ce0SDwaipayan Ray $in_desc = 0; 27552178ce0SDwaipayan Ray } 27652178ce0SDwaipayan Ray } 27752178ce0SDwaipayan Ray } 27852178ce0SDwaipayan Ray 27952178ce0SDwaipayan Ray if ($desc ne '') { 28052178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 28152178ce0SDwaipayan Ray } 28252178ce0SDwaipayan Ray close($docs); 28352178ce0SDwaipayan Ray} 28452178ce0SDwaipayan Ray 285737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space. 286737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments 287737c0767SJohn Brooksforeach (@ARGV) { 288737c0767SJohn Brooks if ($_ eq "--color" || $_ eq "-color") { 289737c0767SJohn Brooks $_ = "--color=$color"; 290737c0767SJohn Brooks } 291737c0767SJohn Brooks} 292737c0767SJohn Brooks 2930a920b5bSAndy WhitcroftGetOptions( 2946c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 29552178ce0SDwaipayan Ray 'v|verbose!' => \$verbose, 2960a920b5bSAndy Whitcroft 'tree!' => \$tree, 2970a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 2980a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 2996c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 3008905a67cSAndy Whitcroft 'terse!' => \$terse, 30134d8815fSJoe Perches 'showfile!' => \$showfile, 30277f5b10aSHannes Eder 'f|file!' => \$file, 3034a593c34SDu, Changbin 'g|git!' => \$git, 3046c72ffaaSAndy Whitcroft 'subjective!' => \$check, 3056c72ffaaSAndy Whitcroft 'strict!' => \$check, 306000d1cc1SJoe Perches 'ignore=s' => \@ignore, 30791bfe484SJoe Perches 'types=s' => \@use, 308000d1cc1SJoe Perches 'show-types!' => \$show_types, 3093beb42ecSJoe Perches 'list-types!' => \$list_types, 3106cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 31156193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 312713a09deSAntonio Borneo 'tab-size=i' => \$tabsize, 3136c72ffaaSAndy Whitcroft 'root=s' => \$root, 3148905a67cSAndy Whitcroft 'summary!' => \$summary, 3158905a67cSAndy Whitcroft 'mailback!' => \$mailback, 31613214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 3173705ce5bSJoe Perches 'fix!' => \$fix, 3189624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 319d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 320c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 321773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 322ebfd7d62SJoe Perches 'codespell!' => \$codespell, 3230ee3e7b8SPeter Ujfalusi 'codespellfile=s' => \$user_codespellfile, 32475ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 325737c0767SJohn Brooks 'color=s' => \$color, 326737c0767SJohn Brooks 'no-color' => \$color, #keep old behaviors of -nocolor 327737c0767SJohn Brooks 'nocolor' => \$color, #keep old behaviors of -nocolor 3283e89ad85SJerome Forissier 'kconfig-prefix=s' => \${CONFIG_}, 32977f5b10aSHannes Eder 'h|help' => \$help, 33077f5b10aSHannes Eder 'version' => \$help 3310ee3e7b8SPeter Ujfalusi) or $help = 2; 33277f5b10aSHannes Eder 3330ee3e7b8SPeter Ujfalusiif ($user_codespellfile) { 3340ee3e7b8SPeter Ujfalusi # Use the user provided codespell file unconditionally 3350ee3e7b8SPeter Ujfalusi $codespellfile = $user_codespellfile; 3360ee3e7b8SPeter Ujfalusi} elsif (!(-f $codespellfile)) { 3370ee3e7b8SPeter Ujfalusi # If /usr/share/codespell/dictionary.txt is not present, try to find it 3380ee3e7b8SPeter Ujfalusi # under codespell's install directory: <codespell_root>/data/dictionary.txt 339c882c6b1SSagar Patel if (($codespell || $help) && which("python3") ne "") { 3400ee3e7b8SPeter Ujfalusi my $python_codespell_dict = << "EOF"; 3410ee3e7b8SPeter Ujfalusi 3420ee3e7b8SPeter Ujfalusiimport os.path as op 3430ee3e7b8SPeter Ujfalusiimport codespell_lib 3440ee3e7b8SPeter Ujfalusicodespell_dir = op.dirname(codespell_lib.__file__) 3450ee3e7b8SPeter Ujfalusicodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt') 3460ee3e7b8SPeter Ujfalusiprint(codespell_file, end='') 3470ee3e7b8SPeter UjfalusiEOF 3480ee3e7b8SPeter Ujfalusi 349c882c6b1SSagar Patel my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`; 3500ee3e7b8SPeter Ujfalusi $codespellfile = $codespell_dict if (-f $codespell_dict); 3510ee3e7b8SPeter Ujfalusi } 3520ee3e7b8SPeter Ujfalusi} 3530ee3e7b8SPeter Ujfalusi 3540ee3e7b8SPeter Ujfalusi# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0 3550ee3e7b8SPeter Ujfalusi# $help is 2 if invalid option is passed - exitcode: 1 3560ee3e7b8SPeter Ujfalusihelp($help - 1) if ($help); 3570a920b5bSAndy Whitcroft 35852178ce0SDwaipayan Raydie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); 35952178ce0SDwaipayan Raydie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse); 36052178ce0SDwaipayan Ray 36152178ce0SDwaipayan Rayif ($color =~ /^[01]$/) { 36252178ce0SDwaipayan Ray $color = !$color; 36352178ce0SDwaipayan Ray} elsif ($color =~ /^always$/i) { 36452178ce0SDwaipayan Ray $color = 1; 36552178ce0SDwaipayan Ray} elsif ($color =~ /^never$/i) { 36652178ce0SDwaipayan Ray $color = 0; 36752178ce0SDwaipayan Ray} elsif ($color =~ /^auto$/i) { 36852178ce0SDwaipayan Ray $color = (-t STDOUT); 36952178ce0SDwaipayan Ray} else { 37052178ce0SDwaipayan Ray die "$P: Invalid color mode: $color\n"; 37152178ce0SDwaipayan Ray} 37252178ce0SDwaipayan Ray 37352178ce0SDwaipayan Rayload_docs() if ($verbose); 3743beb42ecSJoe Percheslist_types(0) if ($list_types); 3753beb42ecSJoe Perches 3769624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 3772ac73b4fSJoe Perches$check_orig = $check; 3789624b8d6SJoe Perches 3790a920b5bSAndy Whitcroftmy $exit = 0; 3800a920b5bSAndy Whitcroft 3815b57980dSJoe Perchesmy $perl_version_ok = 1; 382d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 3835b57980dSJoe Perches $perl_version_ok = 0; 384d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 3855b57980dSJoe Perches exit(1) if (!$ignore_perl_version); 386d62a201fSDave Hansen} 387d62a201fSDave Hansen 38845107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 3890a920b5bSAndy Whitcroftif ($#ARGV < 0) { 39045107ff6SAllen Hubbe push(@ARGV, '-'); 3910a920b5bSAndy Whitcroft} 3920a920b5bSAndy Whitcroft 393713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1 39432f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); 395713a09deSAntonio Borneo 39691bfe484SJoe Perchessub hash_save_array_words { 39791bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 39891bfe484SJoe Perches 39991bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 40091bfe484SJoe Perches foreach my $word (@array) { 401000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 402000d1cc1SJoe Perches $word =~ s/^\s*//g; 403000d1cc1SJoe Perches $word =~ s/\s+/ /g; 404000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 405000d1cc1SJoe Perches 406000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 407000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 408000d1cc1SJoe Perches 40991bfe484SJoe Perches $hashRef->{$word}++; 410000d1cc1SJoe Perches } 41191bfe484SJoe Perches} 41291bfe484SJoe Perches 41391bfe484SJoe Perchessub hash_show_words { 41491bfe484SJoe Perches my ($hashRef, $prefix) = @_; 41591bfe484SJoe Perches 4163c816e49SJoe Perches if (keys %$hashRef) { 417d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 41858cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 41991bfe484SJoe Perches print " $word"; 42091bfe484SJoe Perches } 421d8469f16SJoe Perches print "\n"; 42291bfe484SJoe Perches } 42391bfe484SJoe Perches} 42491bfe484SJoe Perches 42591bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 42691bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 427000d1cc1SJoe Perches 428c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 429c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 4307429c690SAndy Whitcroftmy $dbg_type = 0; 431a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 432c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 43321caa13cSAndy Whitcroft ## no critic 43421caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 43521caa13cSAndy Whitcroft die "$@" if ($@); 436c2fdda0dSAndy Whitcroft} 437c2fdda0dSAndy Whitcroft 438d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 439d2c0a235SAndy Whitcroft 4408905a67cSAndy Whitcroftif ($terse) { 4418905a67cSAndy Whitcroft $emacs = 1; 4428905a67cSAndy Whitcroft $quiet++; 4438905a67cSAndy Whitcroft} 4448905a67cSAndy Whitcroft 4456c72ffaaSAndy Whitcroftif ($tree) { 4466c72ffaaSAndy Whitcroft if (defined $root) { 4476c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 4486c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 4496c72ffaaSAndy Whitcroft } 4506c72ffaaSAndy Whitcroft } else { 4516c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 4526c72ffaaSAndy Whitcroft $root = '.'; 4536c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 4546c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 4556c72ffaaSAndy Whitcroft $root = $1; 4566c72ffaaSAndy Whitcroft } 4576c72ffaaSAndy Whitcroft } 4586c72ffaaSAndy Whitcroft 4596c72ffaaSAndy Whitcroft if (!defined $root) { 4600a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 4610a920b5bSAndy Whitcroft exit(2); 4620a920b5bSAndy Whitcroft } 4636c72ffaaSAndy Whitcroft} 4646c72ffaaSAndy Whitcroft 4656c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 4666c72ffaaSAndy Whitcroft 4672ceb532bSAndy Whitcroftour $Ident = qr{ 4682ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 4692ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 4702ceb532bSAndy Whitcroft }x; 4716c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 4726c72ffaaSAndy Whitcroftour $Sparse = qr{ 4736c72ffaaSAndy Whitcroft __user| 4746c72ffaaSAndy Whitcroft __kernel| 4756c72ffaaSAndy Whitcroft __force| 4766c72ffaaSAndy Whitcroft __iomem| 4776c72ffaaSAndy Whitcroft __must_check| 478417495edSAndy Whitcroft __kprobes| 479165e72a6SSven Eckelmann __ref| 48033aa4597SGeert Uytterhoeven __refconst| 48133aa4597SGeert Uytterhoeven __refdata| 482ad315455SBoqun Feng __rcu| 483ad315455SBoqun Feng __private 4846c72ffaaSAndy Whitcroft }x; 485e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 486e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 487e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 488e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 489e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 4908716de38SJoe Perches 49152131292SWolfram Sang# Notes to $Attribute: 49252131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 4936c72ffaaSAndy Whitcroftour $Attribute = qr{ 4946c72ffaaSAndy Whitcroft const| 495b5e8736aSJoe Perches volatile| 49603f1df7dSJoe Perches __percpu| 49703f1df7dSJoe Perches __nocast| 49803f1df7dSJoe Perches __safe| 49946d832f5SMichael S. Tsirkin __bitwise| 50003f1df7dSJoe Perches __packed__| 50103f1df7dSJoe Perches __packed2__| 50203f1df7dSJoe Perches __naked| 50303f1df7dSJoe Perches __maybe_unused| 50403f1df7dSJoe Perches __always_unused| 50503f1df7dSJoe Perches __noreturn| 50603f1df7dSJoe Perches __used| 50703f1df7dSJoe Perches __cold| 508e23ef1f3SJoe Perches __pure| 50903f1df7dSJoe Perches __noclone| 51003f1df7dSJoe Perches __deprecated| 5116c72ffaaSAndy Whitcroft __read_mostly| 512c5967e98SJoe Perches __ro_after_init| 5136c72ffaaSAndy Whitcroft __kprobes| 5148716de38SJoe Perches $InitAttribute| 515*2f9dadbaSMarcelo Schmitt __aligned\s*\(.*\)| 51624e1d81aSAndy Whitcroft ____cacheline_aligned| 51724e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 5185fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 51986cffecdSKees Cook __weak| 52086cffecdSKees Cook __alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) 5216c72ffaaSAndy Whitcroft }x; 522c45dcabdSAndy Whitcroftour $Modifier; 52391cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 5246c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 5256c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 5266c72ffaaSAndy Whitcroft 52795e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 52895e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 52995e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 53095e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 5312435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 532d2af5aa6SJoe Perchesour $String = qr{(?:\b[Lu])?"[X\t]*"}; 533326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 534326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 535326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 53674349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 5372435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 538326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 539447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 54023f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 5416c72ffaaSAndy Whitcroftour $Operators = qr{ 5426c72ffaaSAndy Whitcroft <=|>=|==|!=| 5436c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 54423f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 5456c72ffaaSAndy Whitcroft }x; 5466c72ffaaSAndy Whitcroft 54791cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 54891cb5195SJoe Perches 549ab7e23f3SJoe Perchesour $BasicType; 5508905a67cSAndy Whitcroftour $NonptrType; 5511813087dSJoe Perchesour $NonptrTypeMisordered; 5528716de38SJoe Perchesour $NonptrTypeWithAttr; 5538905a67cSAndy Whitcroftour $Type; 5541813087dSJoe Perchesour $TypeMisordered; 5558905a67cSAndy Whitcroftour $Declare; 5561813087dSJoe Perchesour $DeclareMisordered; 5578905a67cSAndy Whitcroft 55815662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 55915662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 560171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 561171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 562171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 563171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 564171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 565171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 566171ae1a4SAndy Whitcroft}x; 567171ae1a4SAndy Whitcroft 56815662b3eSJoe Perchesour $UTF8 = qr{ 56915662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 57015662b3eSJoe Perches | $NON_ASCII_UTF8 57115662b3eSJoe Perches}x; 57215662b3eSJoe Perches 573e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 574021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 575021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 576021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 577021158b4SJoe Perches)}; 578e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 579fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 5808ed22cadSAndy Whitcroft atomic_t 5818ed22cadSAndy Whitcroft)}; 5828ea0114eSMickaël Salaünour $typeStdioTypedefs = qr{(?x: 5838ea0114eSMickaël Salaün FILE 5848ea0114eSMickaël Salaün)}; 585e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 586e6176fa4SJoe Perches $typeC99Typedefs\b| 587e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 5888ea0114eSMickaël Salaün $typeKernelTypedefs\b| 5898ea0114eSMickaël Salaün $typeStdioTypedefs\b 590e6176fa4SJoe Perches)}; 5918ed22cadSAndy Whitcroft 5926d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 5936d32f7a3SJoe Perches 594691e669bSJoe Perchesour $logFunctions = qr{(?x: 595758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 5967d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 59787bd499aSJoe Perches TP_printk| 5986e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 599b0531722SJoe Perches panic| 60006668727SJoe Perches MODULE_[A-Z_]+| 60106668727SJoe Perches seq_vprintf|seq_printf|seq_puts 602691e669bSJoe Perches)}; 603691e669bSJoe Perches 604e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 605e29a70f1SJoe Perches (?:(?:devm_)? 60658f02267SJoe Perches (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? | 607e29a70f1SJoe Perches kstrdup(?:_const)? | 608e29a70f1SJoe Perches kmemdup(?:_nul)?) | 609461e1565SChristophe JAILLET (?:\w+)?alloc_skb(?:_ip_align)? | 610e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 611e29a70f1SJoe Perches dma_alloc_coherent 612e29a70f1SJoe Perches)}; 613e29a70f1SJoe Perches 61420112475SJoe Perchesour $signature_tags = qr{(?xi: 61520112475SJoe Perches Signed-off-by:| 616d499480cSJorge Ramirez-Ortiz Co-developed-by:| 61720112475SJoe Perches Acked-by:| 61820112475SJoe Perches Tested-by:| 61920112475SJoe Perches Reviewed-by:| 62020112475SJoe Perches Reported-by:| 6218543ae12SMugunthan V N Suggested-by:| 62220112475SJoe Perches To:| 62320112475SJoe Perches Cc: 62420112475SJoe Perches)}; 62520112475SJoe Perches 62644c31888SMatthieu Baertsour @link_tags = qw(Link Closes); 627f94e40eaSMatthieu Baerts 628f94e40eaSMatthieu Baerts#Create a search and print patterns for all these strings to be used directly below 629f94e40eaSMatthieu Baertsour $link_tags_search = ""; 630f94e40eaSMatthieu Baertsour $link_tags_print = ""; 631f94e40eaSMatthieu Baertsforeach my $entry (@link_tags) { 632f94e40eaSMatthieu Baerts if ($link_tags_search ne "") { 633f94e40eaSMatthieu Baerts $link_tags_search .= '|'; 634f94e40eaSMatthieu Baerts $link_tags_print .= ' or '; 635f94e40eaSMatthieu Baerts } 636f94e40eaSMatthieu Baerts $entry .= ':'; 637f94e40eaSMatthieu Baerts $link_tags_search .= $entry; 638f94e40eaSMatthieu Baerts $link_tags_print .= "'$entry'"; 639f94e40eaSMatthieu Baerts} 640f94e40eaSMatthieu Baerts$link_tags_search = "(?:${link_tags_search})"; 641f94e40eaSMatthieu Baerts 642adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi: 643adb2da82SJoe Perches [=-]*> | 644adb2da82SJoe Perches <[=-]* | 645adb2da82SJoe Perches \[ | 646adb2da82SJoe Perches \] | 647adb2da82SJoe Perches start | 648adb2da82SJoe Perches called | 649adb2da82SJoe Perches entered | 650adb2da82SJoe Perches entry | 651adb2da82SJoe Perches enter | 652adb2da82SJoe Perches in | 653adb2da82SJoe Perches inside | 654adb2da82SJoe Perches here | 655adb2da82SJoe Perches begin | 656adb2da82SJoe Perches exit | 657adb2da82SJoe Perches end | 658adb2da82SJoe Perches done | 659adb2da82SJoe Perches leave | 660adb2da82SJoe Perches completed | 661adb2da82SJoe Perches out | 662adb2da82SJoe Perches return | 663adb2da82SJoe Perches [\.\!:\s]* 664adb2da82SJoe Perches)}; 665adb2da82SJoe Perches 666831242abSAditya Srivastavasub edit_distance_min { 667831242abSAditya Srivastava my (@arr) = @_; 668831242abSAditya Srivastava my $len = scalar @arr; 669831242abSAditya Srivastava if ((scalar @arr) < 1) { 670831242abSAditya Srivastava # if underflow, return 671831242abSAditya Srivastava return; 672831242abSAditya Srivastava } 673831242abSAditya Srivastava my $min = $arr[0]; 674831242abSAditya Srivastava for my $i (0 .. ($len-1)) { 675831242abSAditya Srivastava if ($arr[$i] < $min) { 676831242abSAditya Srivastava $min = $arr[$i]; 677831242abSAditya Srivastava } 678831242abSAditya Srivastava } 679831242abSAditya Srivastava return $min; 680831242abSAditya Srivastava} 681831242abSAditya Srivastava 682831242abSAditya Srivastavasub get_edit_distance { 683831242abSAditya Srivastava my ($str1, $str2) = @_; 684831242abSAditya Srivastava $str1 = lc($str1); 685831242abSAditya Srivastava $str2 = lc($str2); 686831242abSAditya Srivastava $str1 =~ s/-//g; 687831242abSAditya Srivastava $str2 =~ s/-//g; 688831242abSAditya Srivastava my $len1 = length($str1); 689831242abSAditya Srivastava my $len2 = length($str2); 690831242abSAditya Srivastava # two dimensional array storing minimum edit distance 691831242abSAditya Srivastava my @distance; 692831242abSAditya Srivastava for my $i (0 .. $len1) { 693831242abSAditya Srivastava for my $j (0 .. $len2) { 694831242abSAditya Srivastava if ($i == 0) { 695831242abSAditya Srivastava $distance[$i][$j] = $j; 696831242abSAditya Srivastava } elsif ($j == 0) { 697831242abSAditya Srivastava $distance[$i][$j] = $i; 698831242abSAditya Srivastava } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { 699831242abSAditya Srivastava $distance[$i][$j] = $distance[$i - 1][$j - 1]; 700831242abSAditya Srivastava } else { 701831242abSAditya Srivastava my $dist1 = $distance[$i][$j - 1]; #insert distance 702831242abSAditya Srivastava my $dist2 = $distance[$i - 1][$j]; # remove 703831242abSAditya Srivastava my $dist3 = $distance[$i - 1][$j - 1]; #replace 704831242abSAditya Srivastava $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); 705831242abSAditya Srivastava } 706831242abSAditya Srivastava } 707831242abSAditya Srivastava } 708831242abSAditya Srivastava return $distance[$len1][$len2]; 709831242abSAditya Srivastava} 710831242abSAditya Srivastava 711831242abSAditya Srivastavasub find_standard_signature { 712831242abSAditya Srivastava my ($sign_off) = @_; 713831242abSAditya Srivastava my @standard_signature_tags = ( 714831242abSAditya Srivastava 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', 715831242abSAditya Srivastava 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' 716831242abSAditya Srivastava ); 717831242abSAditya Srivastava foreach my $signature (@standard_signature_tags) { 718831242abSAditya Srivastava return $signature if (get_edit_distance($sign_off, $signature) <= 2); 719831242abSAditya Srivastava } 720831242abSAditya Srivastava 721831242abSAditya Srivastava return ""; 722831242abSAditya Srivastava} 723831242abSAditya Srivastava 7249b71f79fSBjorn Helgaasour $obsolete_archives = qr{(?xi: 7259b71f79fSBjorn Helgaas \Qfreedesktop.org/archives/dri-devel\E | 7269b71f79fSBjorn Helgaas \Qlists.infradead.org\E | 7279b71f79fSBjorn Helgaas \Qlkml.org\E | 7289b71f79fSBjorn Helgaas \Qmail-archive.com\E | 7299b71f79fSBjorn Helgaas \Qmailman.alsa-project.org/pipermail\E | 7309b71f79fSBjorn Helgaas \Qmarc.info\E | 7319b71f79fSBjorn Helgaas \Qozlabs.org/pipermail\E | 7329b71f79fSBjorn Helgaas \Qspinics.net\E 7339b71f79fSBjorn Helgaas)}; 7349b71f79fSBjorn Helgaas 7351813087dSJoe Perchesour @typeListMisordered = ( 7361813087dSJoe Perches qr{char\s+(?:un)?signed}, 7371813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 7381813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 7391813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 7401813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 7411813087dSJoe Perches qr{short\s+(?:un)?signed}, 7421813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 7431813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 7441813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 7451813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 7461813087dSJoe Perches qr{int\s+(?:un)?signed}, 7471813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 7481813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 7491813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 7501813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 7511813087dSJoe Perches qr{long\s+(?:un)?signed}, 7521813087dSJoe Perches); 7531813087dSJoe Perches 7548905a67cSAndy Whitcroftour @typeList = ( 7558905a67cSAndy Whitcroft qr{void}, 7560c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 7570c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 7580c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 7590c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 7600c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 7610c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 7620c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 7630c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 7640c773d9dSJoe Perches qr{(?:un)?signed}, 7658905a67cSAndy Whitcroft qr{float}, 7668905a67cSAndy Whitcroft qr{double}, 7678905a67cSAndy Whitcroft qr{bool}, 7688905a67cSAndy Whitcroft qr{struct\s+$Ident}, 7698905a67cSAndy Whitcroft qr{union\s+$Ident}, 7708905a67cSAndy Whitcroft qr{enum\s+$Ident}, 7718905a67cSAndy Whitcroft qr{${Ident}_t}, 7728905a67cSAndy Whitcroft qr{${Ident}_handler}, 7738905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 7741813087dSJoe Perches @typeListMisordered, 7758905a67cSAndy Whitcroft); 776938224b5SJoe Perches 777938224b5SJoe Perchesour $C90_int_types = qr{(?x: 778938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 779938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 780938224b5SJoe Perches long\s+long\s+(?:un)?signed| 781938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 782938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 783938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 784938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 785938224b5SJoe Perches 786938224b5SJoe Perches long\s+int\s+(?:un)?signed| 787938224b5SJoe Perches long\s+(?:un)?signed\s+int| 788938224b5SJoe Perches long\s+(?:un)?signed| 789938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 790938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 791938224b5SJoe Perches int\s+long\s+(?:un)?signed| 792938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 793938224b5SJoe Perches 794938224b5SJoe Perches int\s+(?:un)?signed| 795938224b5SJoe Perches (?:(?:un)?signed\s+)?int 796938224b5SJoe Perches)}; 797938224b5SJoe Perches 798485ff23eSAlex Dowadour @typeListFile = (); 7998716de38SJoe Perchesour @typeListWithAttr = ( 8008716de38SJoe Perches @typeList, 8018716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 8028716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 8038716de38SJoe Perches); 8048716de38SJoe Perches 805c45dcabdSAndy Whitcroftour @modifierList = ( 806c45dcabdSAndy Whitcroft qr{fastcall}, 807c45dcabdSAndy Whitcroft); 808485ff23eSAlex Dowadour @modifierListFile = (); 8098905a67cSAndy Whitcroft 8102435880fSJoe Perchesour @mode_permission_funcs = ( 8112435880fSJoe Perches ["module_param", 3], 8122435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 8132435880fSJoe Perches ["module_param_array_named", 5], 8142435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 8152435880fSJoe Perches ["proc_create(?:_data|)", 2], 816459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 817459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 818459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 819459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 820459cf0aeSJoe Perches ["__ATTR", 2], 8212435880fSJoe Perches); 8222435880fSJoe Perches 8231a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; 8241a3dcf2eSJoe Perches 825515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 826515a235eSJoe Perchesour $mode_perms_search = ""; 827515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 828515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 829515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 830515a235eSJoe Perches} 83100180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 832515a235eSJoe Perches 8339189c7e7SJoe Perchesour %deprecated_apis = ( 8349189c7e7SJoe Perches "synchronize_rcu_bh" => "synchronize_rcu", 8359189c7e7SJoe Perches "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 8369189c7e7SJoe Perches "call_rcu_bh" => "call_rcu", 8379189c7e7SJoe Perches "rcu_barrier_bh" => "rcu_barrier", 8389189c7e7SJoe Perches "synchronize_sched" => "synchronize_rcu", 8399189c7e7SJoe Perches "synchronize_sched_expedited" => "synchronize_rcu_expedited", 8409189c7e7SJoe Perches "call_rcu_sched" => "call_rcu", 8419189c7e7SJoe Perches "rcu_barrier_sched" => "rcu_barrier", 8429189c7e7SJoe Perches "get_state_synchronize_sched" => "get_state_synchronize_rcu", 8439189c7e7SJoe Perches "cond_synchronize_sched" => "cond_synchronize_rcu", 844defdaff1SIra Weiny "kmap" => "kmap_local_page", 845a3ea42ffSIra Weiny "kunmap" => "kunmap_local", 846defdaff1SIra Weiny "kmap_atomic" => "kmap_local_page", 847a3ea42ffSIra Weiny "kunmap_atomic" => "kunmap_local", 8489189c7e7SJoe Perches); 8499189c7e7SJoe Perches 8509189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 8519189c7e7SJoe Perchesour $deprecated_apis_search = ""; 8529189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 8539189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 8549189c7e7SJoe Perches $deprecated_apis_search .= $entry; 8559189c7e7SJoe Perches} 8569189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 8579189c7e7SJoe Perches 858b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 859b392c64fSJoe Perches S_IWUGO | 860b392c64fSJoe Perches S_IWOTH | 861b392c64fSJoe Perches S_IRWXUGO | 862b392c64fSJoe Perches S_IALLUGO | 863b392c64fSJoe Perches 0[0-7][0-7][2367] 864b392c64fSJoe Perches}x; 865b392c64fSJoe Perches 866f90774e1SJoe Perchesour %mode_permission_string_types = ( 867f90774e1SJoe Perches "S_IRWXU" => 0700, 868f90774e1SJoe Perches "S_IRUSR" => 0400, 869f90774e1SJoe Perches "S_IWUSR" => 0200, 870f90774e1SJoe Perches "S_IXUSR" => 0100, 871f90774e1SJoe Perches "S_IRWXG" => 0070, 872f90774e1SJoe Perches "S_IRGRP" => 0040, 873f90774e1SJoe Perches "S_IWGRP" => 0020, 874f90774e1SJoe Perches "S_IXGRP" => 0010, 875f90774e1SJoe Perches "S_IRWXO" => 0007, 876f90774e1SJoe Perches "S_IROTH" => 0004, 877f90774e1SJoe Perches "S_IWOTH" => 0002, 878f90774e1SJoe Perches "S_IXOTH" => 0001, 879f90774e1SJoe Perches "S_IRWXUGO" => 0777, 880f90774e1SJoe Perches "S_IRUGO" => 0444, 881f90774e1SJoe Perches "S_IWUGO" => 0222, 882f90774e1SJoe Perches "S_IXUGO" => 0111, 883f90774e1SJoe Perches); 884f90774e1SJoe Perches 885f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 886f90774e1SJoe Perchesour $mode_perms_string_search = ""; 887f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 888f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 889f90774e1SJoe Perches $mode_perms_string_search .= $entry; 890f90774e1SJoe Perches} 89100180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 89200180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 89300180468SJoe Perches ${single_mode_perms_string_search} 89400180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 89500180468SJoe Perches}x; 89600180468SJoe Perches 89700180468SJoe Perchessub perms_to_octal { 89800180468SJoe Perches my ($string) = @_; 89900180468SJoe Perches 90000180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 90100180468SJoe Perches 90200180468SJoe Perches my $val = ""; 90300180468SJoe Perches my $oval = ""; 90400180468SJoe Perches my $to = 0; 90500180468SJoe Perches my $curpos = 0; 90600180468SJoe Perches my $lastpos = 0; 90700180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 90800180468SJoe Perches $curpos = pos($string); 90900180468SJoe Perches my $match = $2; 91000180468SJoe Perches my $omatch = $1; 91100180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 91200180468SJoe Perches $lastpos = $curpos; 91300180468SJoe Perches $to |= $mode_permission_string_types{$match}; 91400180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 91500180468SJoe Perches $val .= $match; 91600180468SJoe Perches $oval .= $omatch; 91700180468SJoe Perches } 91800180468SJoe Perches $oval =~ s/^\s*\|\s*//; 91900180468SJoe Perches $oval =~ s/\s*\|\s*$//; 92000180468SJoe Perches return sprintf("%04o", $to); 92100180468SJoe Perches} 922f90774e1SJoe Perches 9237840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 9247840a94cSWolfram Sang irq| 925cdcee686SSergey Ryazanov memory| 926cdcee686SSergey Ryazanov time| 927cdcee686SSergey Ryazanov reboot 9287840a94cSWolfram Sang)}; 9297840a94cSWolfram Sang# memory.h: ARM has a custom one 9307840a94cSWolfram Sang 93166b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 93266b47b4aSKees Cookmy $misspellings; 93366b47b4aSKees Cookmy %spelling_fix; 93436061e38SJoe Perches 93536061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 93666b47b4aSKees Cook while (<$spelling>) { 93766b47b4aSKees Cook my $line = $_; 93866b47b4aSKees Cook 93966b47b4aSKees Cook $line =~ s/\s*\n?$//g; 94066b47b4aSKees Cook $line =~ s/^\s*//g; 94166b47b4aSKees Cook 94266b47b4aSKees Cook next if ($line =~ m/^\s*#/); 94366b47b4aSKees Cook next if ($line =~ m/^\s*$/); 94466b47b4aSKees Cook 94566b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 94666b47b4aSKees Cook 94766b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 94866b47b4aSKees Cook } 94966b47b4aSKees Cook close($spelling); 95036061e38SJoe Perches} else { 95136061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 95236061e38SJoe Perches} 95366b47b4aSKees Cook 954ebfd7d62SJoe Perchesif ($codespell) { 955ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 956ebfd7d62SJoe Perches while (<$spelling>) { 957ebfd7d62SJoe Perches my $line = $_; 958ebfd7d62SJoe Perches 959ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 960ebfd7d62SJoe Perches $line =~ s/^\s*//g; 961ebfd7d62SJoe Perches 962ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 963ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 964ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 965ebfd7d62SJoe Perches 966ebfd7d62SJoe Perches $line =~ s/,.*$//; 967ebfd7d62SJoe Perches 968ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 969ebfd7d62SJoe Perches 970ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 971ebfd7d62SJoe Perches } 972ebfd7d62SJoe Perches close($spelling); 973ebfd7d62SJoe Perches } else { 974ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 975ebfd7d62SJoe Perches } 976ebfd7d62SJoe Perches} 977ebfd7d62SJoe Perches 978ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 979ebfd7d62SJoe Perches 98075ad8c57SJerome Forissiersub read_words { 98175ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 98275ad8c57SJerome Forissier 98375ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 98475ad8c57SJerome Forissier while (<$words>) { 985bf1fa1daSJoe Perches my $line = $_; 986bf1fa1daSJoe Perches 987bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 988bf1fa1daSJoe Perches $line =~ s/^\s*//g; 989bf1fa1daSJoe Perches 990bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 991bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 992bf1fa1daSJoe Perches if ($line =~ /\s/) { 99375ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 994bf1fa1daSJoe Perches next; 995bf1fa1daSJoe Perches } 996bf1fa1daSJoe Perches 997ced69da1SQuentin Monnet $$wordsRef .= '|' if (defined $$wordsRef); 99875ad8c57SJerome Forissier $$wordsRef .= $line; 999bf1fa1daSJoe Perches } 100075ad8c57SJerome Forissier close($file); 100175ad8c57SJerome Forissier return 1; 1002bf1fa1daSJoe Perches } 1003bf1fa1daSJoe Perches 100475ad8c57SJerome Forissier return 0; 100575ad8c57SJerome Forissier} 100675ad8c57SJerome Forissier 1007ced69da1SQuentin Monnetmy $const_structs; 1008ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) { 100975ad8c57SJerome Forissier read_words(\$const_structs, $conststructsfile) 101075ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 1011ced69da1SQuentin Monnet} 101275ad8c57SJerome Forissier 1013ced69da1SQuentin Monnetif (defined($typedefsfile)) { 1014ced69da1SQuentin Monnet my $typeOtherTypedefs; 101575ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 101675ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 1017ced69da1SQuentin Monnet $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); 101875ad8c57SJerome Forissier} 101975ad8c57SJerome Forissier 10208905a67cSAndy Whitcroftsub build_types { 1021485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 1022485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 10231813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 10248716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 1025c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 1026ab7e23f3SJoe Perches $BasicType = qr{ 1027ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 1028ab7e23f3SJoe Perches (?:${all}\b) 1029ab7e23f3SJoe Perches }x; 10308905a67cSAndy Whitcroft $NonptrType = qr{ 1031d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 1032cf655043SAndy Whitcroft (?: 10336b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 10348ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 1035c45dcabdSAndy Whitcroft (?:${all}\b) 1036cf655043SAndy Whitcroft ) 1037c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 10388905a67cSAndy Whitcroft }x; 10391813087dSJoe Perches $NonptrTypeMisordered = qr{ 10401813087dSJoe Perches (?:$Modifier\s+|const\s+)* 10411813087dSJoe Perches (?: 10421813087dSJoe Perches (?:${Misordered}\b) 10431813087dSJoe Perches ) 10441813087dSJoe Perches (?:\s+$Modifier|\s+const)* 10451813087dSJoe Perches }x; 10468716de38SJoe Perches $NonptrTypeWithAttr = qr{ 10478716de38SJoe Perches (?:$Modifier\s+|const\s+)* 10488716de38SJoe Perches (?: 10498716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 10508716de38SJoe Perches (?:$typeTypedefs\b)| 10518716de38SJoe Perches (?:${allWithAttr}\b) 10528716de38SJoe Perches ) 10538716de38SJoe Perches (?:\s+$Modifier|\s+const)* 10548716de38SJoe Perches }x; 10558905a67cSAndy Whitcroft $Type = qr{ 1056c45dcabdSAndy Whitcroft $NonptrType 10577b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 1058c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 10598905a67cSAndy Whitcroft }x; 10601813087dSJoe Perches $TypeMisordered = qr{ 10611813087dSJoe Perches $NonptrTypeMisordered 10627b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 10631813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 10641813087dSJoe Perches }x; 106591cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 10661813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 10678905a67cSAndy Whitcroft} 10688905a67cSAndy Whitcroftbuild_types(); 10696c72ffaaSAndy Whitcroft 10707d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 1071d1fe9c09SJoe Perches 1072d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 1073d1fe9c09SJoe Perches# requires at least perl version v5.10.0 1074d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 1075d1fe9c09SJoe Perches 1076d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 10772435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 1078c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 10797d2367afSJoe Perches 1080f8422308SJoe Perchesour $declaration_macros = qr{(?x: 10813e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 1082fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 1083dcea7964SJoe Perches (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(| 1084dcea7964SJoe Perches (?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\( 1085f8422308SJoe Perches)}; 1086f8422308SJoe Perches 10878d0325ccSAditya Srivastavaour %allow_repeated_words = ( 10888d0325ccSAditya Srivastava add => '', 10898d0325ccSAditya Srivastava added => '', 10908d0325ccSAditya Srivastava bad => '', 10918d0325ccSAditya Srivastava be => '', 10928d0325ccSAditya Srivastava); 10938d0325ccSAditya Srivastava 10947d2367afSJoe Perchessub deparenthesize { 10957d2367afSJoe Perches my ($string) = @_; 10967d2367afSJoe Perches return "" if (!defined($string)); 10975b9553abSJoe Perches 10985b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 10995b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 11005b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 11015b9553abSJoe Perches } 11025b9553abSJoe Perches 11037d2367afSJoe Perches $string =~ s@\s+@ @g; 11045b9553abSJoe Perches 11057d2367afSJoe Perches return $string; 11067d2367afSJoe Perches} 11077d2367afSJoe Perches 11083445686aSJoe Perchessub seed_camelcase_file { 11093445686aSJoe Perches my ($file) = @_; 11103445686aSJoe Perches 11113445686aSJoe Perches return if (!(-f $file)); 11123445686aSJoe Perches 11133445686aSJoe Perches local $/; 11143445686aSJoe Perches 11153445686aSJoe Perches open(my $include_file, '<', "$file") 11163445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 11173445686aSJoe Perches my $text = <$include_file>; 11183445686aSJoe Perches close($include_file); 11193445686aSJoe Perches 11203445686aSJoe Perches my @lines = split('\n', $text); 11213445686aSJoe Perches 11223445686aSJoe Perches foreach my $line (@lines) { 11233445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 11243445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 11253445686aSJoe Perches $camelcase{$1} = 1; 112611ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 112711ea516aSJoe Perches $camelcase{$1} = 1; 112811ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 11293445686aSJoe Perches $camelcase{$1} = 1; 11303445686aSJoe Perches } 11313445686aSJoe Perches } 11323445686aSJoe Perches} 11333445686aSJoe Perches 1134cd28b119SJoe Perchesour %maintained_status = (); 1135cd28b119SJoe Perches 113685b0ee18SJoe Perchessub is_maintained_obsolete { 113785b0ee18SJoe Perches my ($filename) = @_; 113885b0ee18SJoe Perches 1139f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 114085b0ee18SJoe Perches 1141cd28b119SJoe Perches if (!exists($maintained_status{$filename})) { 1142cd28b119SJoe Perches $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 1143cd28b119SJoe Perches } 114485b0ee18SJoe Perches 1145cd28b119SJoe Perches return $maintained_status{$filename} =~ /obsolete/i; 114685b0ee18SJoe Perches} 114785b0ee18SJoe Perches 11483b6e8ac9SJoe Perchessub is_SPDX_License_valid { 11493b6e8ac9SJoe Perches my ($license) = @_; 11503b6e8ac9SJoe Perches 1151f9363b31SGuenter Roeck return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); 11523b6e8ac9SJoe Perches 115356294112SJoe Perches my $root_path = abs_path($root); 1154f9363b31SGuenter Roeck my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`; 11553b6e8ac9SJoe Perches return 0 if ($status ne ""); 11563b6e8ac9SJoe Perches return 1; 11573b6e8ac9SJoe Perches} 11583b6e8ac9SJoe Perches 11593445686aSJoe Perchesmy $camelcase_seeded = 0; 11603445686aSJoe Perchessub seed_camelcase_includes { 11613445686aSJoe Perches return if ($camelcase_seeded); 11623445686aSJoe Perches 11633445686aSJoe Perches my $files; 1164c707a81dSJoe Perches my $camelcase_cache = ""; 1165c707a81dSJoe Perches my @include_files = (); 1166c707a81dSJoe Perches 1167c707a81dSJoe Perches $camelcase_seeded = 1; 1168351b2a1fSJoe Perches 11690f7f635bSJoe Perches if (-e "$gitroot") { 1170dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 1171351b2a1fSJoe Perches chomp $git_last_include_commit; 1172c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 1173c707a81dSJoe Perches } else { 1174c707a81dSJoe Perches my $last_mod_date = 0; 1175c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 1176c707a81dSJoe Perches @include_files = split('\n', $files); 1177c707a81dSJoe Perches foreach my $file (@include_files) { 1178c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 1179c707a81dSJoe Perches localtime((stat $file)[9])); 1180c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 1181c707a81dSJoe Perches } 1182c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 1183c707a81dSJoe Perches } 1184c707a81dSJoe Perches 1185c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 1186c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 1187c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 1188351b2a1fSJoe Perches while (<$camelcase_file>) { 1189351b2a1fSJoe Perches chomp; 1190351b2a1fSJoe Perches $camelcase{$_} = 1; 1191351b2a1fSJoe Perches } 1192351b2a1fSJoe Perches close($camelcase_file); 1193351b2a1fSJoe Perches 1194351b2a1fSJoe Perches return; 1195351b2a1fSJoe Perches } 1196c707a81dSJoe Perches 11970f7f635bSJoe Perches if (-e "$gitroot") { 1198dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 1199c707a81dSJoe Perches @include_files = split('\n', $files); 12003445686aSJoe Perches } 1201c707a81dSJoe Perches 12023445686aSJoe Perches foreach my $file (@include_files) { 12033445686aSJoe Perches seed_camelcase_file($file); 12043445686aSJoe Perches } 1205351b2a1fSJoe Perches 1206c707a81dSJoe Perches if ($camelcase_cache ne "") { 1207351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 1208c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 1209c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 1210351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 1211351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 1212351b2a1fSJoe Perches } 1213351b2a1fSJoe Perches close($camelcase_file); 1214351b2a1fSJoe Perches } 12153445686aSJoe Perches} 12163445686aSJoe Perches 1217f5f61325SJoe Perchessub git_is_single_file { 1218f5f61325SJoe Perches my ($filename) = @_; 1219f5f61325SJoe Perches 1220f5f61325SJoe Perches return 0 if ((which("git") eq "") || !(-e "$gitroot")); 1221f5f61325SJoe Perches 1222f5f61325SJoe Perches my $output = `${git_command} ls-files -- $filename 2>/dev/null`; 1223f5f61325SJoe Perches my $count = $output =~ tr/\n//; 1224f5f61325SJoe Perches return $count eq 1 && $output =~ m{^${filename}$}; 1225f5f61325SJoe Perches} 1226f5f61325SJoe Perches 1227d311cd44SJoe Perchessub git_commit_info { 1228d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 1229d311cd44SJoe Perches 12300f7f635bSJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); 1231d311cd44SJoe Perches 1232dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 1233d311cd44SJoe Perches $output =~ s/^\s*//gm; 1234d311cd44SJoe Perches my @lines = split("\n", $output); 1235d311cd44SJoe Perches 12360d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 12370d7835fcSJoe Perches 12385a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 1239d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 1240d311cd44SJoe Perches# all matching commit ids, but it's very slow... 1241d311cd44SJoe Perches# 1242d311cd44SJoe Perches# echo "checking commits $1..." 1243d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 1244d311cd44SJoe Perches# while read line ; do 1245d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 1246d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 1247d311cd44SJoe Perches# done 12484ce9f970SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ || 12494ce9f970SJoe Perches $lines[0] =~ /^fatal: bad object $commit/) { 1250948b133aSHeinrich Schuchardt $id = undef; 1251d311cd44SJoe Perches } else { 1252d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 1253d311cd44SJoe Perches $desc = substr($lines[0], 41); 1254d311cd44SJoe Perches } 1255d311cd44SJoe Perches 1256d311cd44SJoe Perches return ($id, $desc); 1257d311cd44SJoe Perches} 1258d311cd44SJoe Perches 12596c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 12600a920b5bSAndy Whitcroft 126100df344fSAndy Whitcroftmy @rawlines = (); 1262c2fdda0dSAndy Whitcroftmy @lines = (); 12633705ce5bSJoe Perchesmy @fixed = (); 1264d752fcc8SJoe Perchesmy @fixed_inserted = (); 1265d752fcc8SJoe Perchesmy @fixed_deleted = (); 1266194f66fcSJoe Perchesmy $fixlinenr = -1; 1267194f66fcSJoe Perches 12684a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 12694a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 12700f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot"); 12714a593c34SDu, Changbin 12724a593c34SDu, Changbinif ($git) { 12734a593c34SDu, Changbin my @commits = (); 12740dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 12754a593c34SDu, Changbin my $git_range; 127628898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 127728898fd1SJoe Perches $git_range = "-$2 $1"; 12784a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 12794a593c34SDu, Changbin $git_range = "$commit_expr"; 12804a593c34SDu, Changbin } else { 12810dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 12820dea9f1eSJoe Perches } 1283dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 12840dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 128528898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 128628898fd1SJoe Perches next if (!defined($1) || !defined($2)); 12870dea9f1eSJoe Perches my $sha1 = $1; 12880dea9f1eSJoe Perches my $subject = $2; 12890dea9f1eSJoe Perches unshift(@commits, $sha1); 12900dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 12914a593c34SDu, Changbin } 12924a593c34SDu, Changbin } 12934a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 12944a593c34SDu, Changbin @ARGV = @commits; 12954a593c34SDu, Changbin} 12964a593c34SDu, Changbin 1297c2fdda0dSAndy Whitcroftmy $vname; 129898005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 12996c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 130021caa13cSAndy Whitcroft my $FILE; 1301f5f61325SJoe Perches my $is_git_file = git_is_single_file($filename); 1302f5f61325SJoe Perches my $oldfile = $file; 1303f5f61325SJoe Perches $file = 1 if ($is_git_file); 13044a593c34SDu, Changbin if ($git) { 13054a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 13064a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 13074a593c34SDu, Changbin } elsif ($file) { 130821caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 13096c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 131021caa13cSAndy Whitcroft } elsif ($filename eq '-') { 131121caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 13126c72ffaaSAndy Whitcroft } else { 131321caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 13146c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 13156c72ffaaSAndy Whitcroft } 1316c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1317c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 13184a593c34SDu, Changbin } elsif ($git) { 13190dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1320c2fdda0dSAndy Whitcroft } else { 1321c2fdda0dSAndy Whitcroft $vname = $filename; 1322c2fdda0dSAndy Whitcroft } 132321caa13cSAndy Whitcroft while (<$FILE>) { 13240a920b5bSAndy Whitcroft chomp; 132500df344fSAndy Whitcroft push(@rawlines, $_); 1326c7f574d0SGeert Uytterhoeven $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); 13276c72ffaaSAndy Whitcroft } 132821caa13cSAndy Whitcroft close($FILE); 1329d8469f16SJoe Perches 1330d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1331d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1332d8469f16SJoe Perches print "$vname\n"; 1333d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1334d8469f16SJoe Perches } 1335d8469f16SJoe Perches 1336c2fdda0dSAndy Whitcroft if (!process($filename)) { 13370a920b5bSAndy Whitcroft $exit = 1; 13380a920b5bSAndy Whitcroft } 133900df344fSAndy Whitcroft @rawlines = (); 134013214adfSAndy Whitcroft @lines = (); 13413705ce5bSJoe Perches @fixed = (); 1342d752fcc8SJoe Perches @fixed_inserted = (); 1343d752fcc8SJoe Perches @fixed_deleted = (); 1344194f66fcSJoe Perches $fixlinenr = -1; 1345485ff23eSAlex Dowad @modifierListFile = (); 1346485ff23eSAlex Dowad @typeListFile = (); 1347485ff23eSAlex Dowad build_types(); 1348f5f61325SJoe Perches $file = $oldfile if ($is_git_file); 13490a920b5bSAndy Whitcroft} 13500a920b5bSAndy Whitcroft 1351d8469f16SJoe Perchesif (!$quiet) { 13523c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 13533c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 13543c816e49SJoe Perches 13555b57980dSJoe Perches if (!$perl_version_ok) { 1356d8469f16SJoe Perches print << "EOM" 1357d8469f16SJoe Perches 1358d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 13595b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1360d8469f16SJoe PerchesEOM 1361d8469f16SJoe Perches } 1362d8469f16SJoe Perches if ($exit) { 1363d8469f16SJoe Perches print << "EOM" 1364d8469f16SJoe Perches 1365d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1366d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1367d8469f16SJoe PerchesEOM 1368d8469f16SJoe Perches } 1369d8469f16SJoe Perches} 1370d8469f16SJoe Perches 13710a920b5bSAndy Whitcroftexit($exit); 13720a920b5bSAndy Whitcroft 13730a920b5bSAndy Whitcroftsub top_of_kernel_tree { 13746c72ffaaSAndy Whitcroft my ($root) = @_; 13756c72ffaaSAndy Whitcroft 13766c72ffaaSAndy Whitcroft my @tree_check = ( 13776c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 13786c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 13796c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 13806c72ffaaSAndy Whitcroft ); 13816c72ffaaSAndy Whitcroft 13826c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 13836c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 13840a920b5bSAndy Whitcroft return 0; 13850a920b5bSAndy Whitcroft } 13866c72ffaaSAndy Whitcroft } 13876c72ffaaSAndy Whitcroft return 1; 13886c72ffaaSAndy Whitcroft} 13890a920b5bSAndy Whitcroft 139020112475SJoe Perchessub parse_email { 139120112475SJoe Perches my ($formatted_email) = @_; 139220112475SJoe Perches 139320112475SJoe Perches my $name = ""; 1394fccaebf0SDwaipayan Ray my $quoted = ""; 1395dfa05c28SJoe Perches my $name_comment = ""; 139620112475SJoe Perches my $address = ""; 139720112475SJoe Perches my $comment = ""; 139820112475SJoe Perches 139920112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 140020112475SJoe Perches $name = $1; 140120112475SJoe Perches $address = $2; 140220112475SJoe Perches $comment = $3 if defined $3; 140320112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 140420112475SJoe Perches $address = $1; 140520112475SJoe Perches $comment = $2 if defined $2; 140620112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 140720112475SJoe Perches $address = $1; 140820112475SJoe Perches $comment = $2 if defined $2; 140985e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 141020112475SJoe Perches $name = $formatted_email; 14113705ce5bSJoe Perches $name = trim($name); 141220112475SJoe Perches $name =~ s/^\"|\"$//g; 141320112475SJoe Perches # If there's a name left after stripping spaces and 141420112475SJoe Perches # leading quotes, and the address doesn't have both 141520112475SJoe Perches # leading and trailing angle brackets, the address 141620112475SJoe Perches # is invalid. ie: 141720112475SJoe Perches # "joe smith [email protected]" bad 141820112475SJoe Perches # "joe smith <[email protected]" bad 141920112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 142020112475SJoe Perches $name = ""; 142120112475SJoe Perches $address = ""; 142220112475SJoe Perches $comment = ""; 142320112475SJoe Perches } 142420112475SJoe Perches } 142520112475SJoe Perches 1426fccaebf0SDwaipayan Ray # Extract comments from names excluding quoted parts 1427fccaebf0SDwaipayan Ray # "John D. (Doe)" - Do not extract 1428fccaebf0SDwaipayan Ray if ($name =~ s/\"(.+)\"//) { 1429fccaebf0SDwaipayan Ray $quoted = $1; 1430dfa05c28SJoe Perches } 1431fccaebf0SDwaipayan Ray while ($name =~ s/\s*($balanced_parens)\s*/ /) { 1432fccaebf0SDwaipayan Ray $name_comment .= trim($1); 1433fccaebf0SDwaipayan Ray } 1434fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 1435fccaebf0SDwaipayan Ray $name = trim("$quoted $name"); 1436fccaebf0SDwaipayan Ray 14373705ce5bSJoe Perches $address = trim($address); 143820112475SJoe Perches $address =~ s/^\<|\>$//g; 1439fccaebf0SDwaipayan Ray $comment = trim($comment); 144020112475SJoe Perches 144120112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 144220112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 144320112475SJoe Perches $name = "\"$name\""; 144420112475SJoe Perches } 144520112475SJoe Perches 1446dfa05c28SJoe Perches return ($name, $name_comment, $address, $comment); 144720112475SJoe Perches} 144820112475SJoe Perches 144920112475SJoe Perchessub format_email { 145048ca2d8aSDwaipayan Ray my ($name, $name_comment, $address, $comment) = @_; 145120112475SJoe Perches 145220112475SJoe Perches my $formatted_email; 145320112475SJoe Perches 1454fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 14553705ce5bSJoe Perches $address = trim($address); 1456fccaebf0SDwaipayan Ray $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes 145720112475SJoe Perches 145820112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 145920112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 146020112475SJoe Perches $name = "\"$name\""; 146120112475SJoe Perches } 146220112475SJoe Perches 1463fccaebf0SDwaipayan Ray $name_comment = trim($name_comment); 1464fccaebf0SDwaipayan Ray $name_comment = " $name_comment" if ($name_comment ne ""); 1465fccaebf0SDwaipayan Ray $comment = trim($comment); 1466fccaebf0SDwaipayan Ray $comment = " $comment" if ($comment ne ""); 1467fccaebf0SDwaipayan Ray 146820112475SJoe Perches if ("$name" eq "") { 146920112475SJoe Perches $formatted_email = "$address"; 147020112475SJoe Perches } else { 147148ca2d8aSDwaipayan Ray $formatted_email = "$name$name_comment <$address>"; 147220112475SJoe Perches } 147348ca2d8aSDwaipayan Ray $formatted_email .= "$comment"; 147420112475SJoe Perches return $formatted_email; 147520112475SJoe Perches} 147620112475SJoe Perches 1477dfa05c28SJoe Perchessub reformat_email { 1478dfa05c28SJoe Perches my ($email) = @_; 1479dfa05c28SJoe Perches 1480dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 148148ca2d8aSDwaipayan Ray return format_email($email_name, $name_comment, $email_address, $comment); 1482dfa05c28SJoe Perches} 1483dfa05c28SJoe Perches 1484dfa05c28SJoe Perchessub same_email_addresses { 1485fccaebf0SDwaipayan Ray my ($email1, $email2) = @_; 1486dfa05c28SJoe Perches 1487dfa05c28SJoe Perches my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); 1488dfa05c28SJoe Perches my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); 1489dfa05c28SJoe Perches 149048ca2d8aSDwaipayan Ray return $email1_name eq $email2_name && 149148ca2d8aSDwaipayan Ray $email1_address eq $email2_address && 149248ca2d8aSDwaipayan Ray $name1_comment eq $name2_comment && 149348ca2d8aSDwaipayan Ray $comment1 eq $comment2; 149448ca2d8aSDwaipayan Ray} 1495dfa05c28SJoe Perches 1496d311cd44SJoe Perchessub which { 1497d311cd44SJoe Perches my ($bin) = @_; 1498d311cd44SJoe Perches 1499d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1500d311cd44SJoe Perches if (-e "$path/$bin") { 1501d311cd44SJoe Perches return "$path/$bin"; 1502d311cd44SJoe Perches } 1503d311cd44SJoe Perches } 1504d311cd44SJoe Perches 1505d311cd44SJoe Perches return ""; 1506d311cd44SJoe Perches} 1507d311cd44SJoe Perches 1508000d1cc1SJoe Perchessub which_conf { 1509000d1cc1SJoe Perches my ($conf) = @_; 1510000d1cc1SJoe Perches 1511000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1512000d1cc1SJoe Perches if (-e "$path/$conf") { 1513000d1cc1SJoe Perches return "$path/$conf"; 1514000d1cc1SJoe Perches } 1515000d1cc1SJoe Perches } 1516000d1cc1SJoe Perches 1517000d1cc1SJoe Perches return ""; 1518000d1cc1SJoe Perches} 1519000d1cc1SJoe Perches 15200a920b5bSAndy Whitcroftsub expand_tabs { 15210a920b5bSAndy Whitcroft my ($str) = @_; 15220a920b5bSAndy Whitcroft 15230a920b5bSAndy Whitcroft my $res = ''; 15240a920b5bSAndy Whitcroft my $n = 0; 15250a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 15260a920b5bSAndy Whitcroft if ($c eq "\t") { 15270a920b5bSAndy Whitcroft $res .= ' '; 15280a920b5bSAndy Whitcroft $n++; 1529713a09deSAntonio Borneo for (; ($n % $tabsize) != 0; $n++) { 15300a920b5bSAndy Whitcroft $res .= ' '; 15310a920b5bSAndy Whitcroft } 15320a920b5bSAndy Whitcroft next; 15330a920b5bSAndy Whitcroft } 15340a920b5bSAndy Whitcroft $res .= $c; 15350a920b5bSAndy Whitcroft $n++; 15360a920b5bSAndy Whitcroft } 15370a920b5bSAndy Whitcroft 15380a920b5bSAndy Whitcroft return $res; 15390a920b5bSAndy Whitcroft} 15406c72ffaaSAndy Whitcroftsub copy_spacing { 1541773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 15426c72ffaaSAndy Whitcroft return $res; 15436c72ffaaSAndy Whitcroft} 15440a920b5bSAndy Whitcroft 15454a0df2efSAndy Whitcroftsub line_stats { 15464a0df2efSAndy Whitcroft my ($line) = @_; 15474a0df2efSAndy Whitcroft 15484a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 15494a0df2efSAndy Whitcroft $line =~ s/^.//; 15504a0df2efSAndy Whitcroft $line = expand_tabs($line); 15514a0df2efSAndy Whitcroft 15524a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 15534a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 15544a0df2efSAndy Whitcroft 15554a0df2efSAndy Whitcroft return (length($line), length($white)); 15564a0df2efSAndy Whitcroft} 15574a0df2efSAndy Whitcroft 1558773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1559773647a0SAndy Whitcroft 1560773647a0SAndy Whitcroftsub sanitise_line_reset { 1561773647a0SAndy Whitcroft my ($in_comment) = @_; 1562773647a0SAndy Whitcroft 1563773647a0SAndy Whitcroft if ($in_comment) { 1564773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1565773647a0SAndy Whitcroft } else { 1566773647a0SAndy Whitcroft $sanitise_quote = ''; 1567773647a0SAndy Whitcroft } 1568773647a0SAndy Whitcroft} 156900df344fSAndy Whitcroftsub sanitise_line { 157000df344fSAndy Whitcroft my ($line) = @_; 157100df344fSAndy Whitcroft 157200df344fSAndy Whitcroft my $res = ''; 157300df344fSAndy Whitcroft my $l = ''; 157400df344fSAndy Whitcroft 1575c2fdda0dSAndy Whitcroft my $qlen = 0; 1576773647a0SAndy Whitcroft my $off = 0; 1577773647a0SAndy Whitcroft my $c; 157800df344fSAndy Whitcroft 1579773647a0SAndy Whitcroft # Always copy over the diff marker. 1580773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1581773647a0SAndy Whitcroft 1582773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1583773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1584773647a0SAndy Whitcroft 15858d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1586773647a0SAndy Whitcroft # and end, all to $;. 1587773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1588773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1589773647a0SAndy Whitcroft 1590773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1591773647a0SAndy Whitcroft $off++; 159200df344fSAndy Whitcroft next; 1593773647a0SAndy Whitcroft } 159481bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1595773647a0SAndy Whitcroft $sanitise_quote = ''; 1596773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1597773647a0SAndy Whitcroft $off++; 1598773647a0SAndy Whitcroft next; 1599773647a0SAndy Whitcroft } 1600113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1601113f04a8SDaniel Walker $sanitise_quote = '//'; 1602113f04a8SDaniel Walker 1603113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1604113f04a8SDaniel Walker $off++; 1605113f04a8SDaniel Walker next; 1606113f04a8SDaniel Walker } 1607773647a0SAndy Whitcroft 1608773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1609773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1610773647a0SAndy Whitcroft $c eq "\\") { 1611773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1612773647a0SAndy Whitcroft $off++; 1613773647a0SAndy Whitcroft next; 1614773647a0SAndy Whitcroft } 1615773647a0SAndy Whitcroft # Regular quotes. 1616773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1617773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1618773647a0SAndy Whitcroft $sanitise_quote = $c; 1619773647a0SAndy Whitcroft 1620773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1621773647a0SAndy Whitcroft next; 1622773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1623773647a0SAndy Whitcroft $sanitise_quote = ''; 162400df344fSAndy Whitcroft } 162500df344fSAndy Whitcroft } 1626773647a0SAndy Whitcroft 1627fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1628773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1629773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1630113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1631113f04a8SDaniel Walker substr($res, $off, 1, $;); 1632773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1633773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 163400df344fSAndy Whitcroft } else { 1635773647a0SAndy Whitcroft substr($res, $off, 1, $c); 163600df344fSAndy Whitcroft } 1637c2fdda0dSAndy Whitcroft } 1638c2fdda0dSAndy Whitcroft 1639113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1640113f04a8SDaniel Walker $sanitise_quote = ''; 1641113f04a8SDaniel Walker } 1642113f04a8SDaniel Walker 1643c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1644c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1645c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1646c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1647c2fdda0dSAndy Whitcroft 1648c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1649c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1650c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1651c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1652c2fdda0dSAndy Whitcroft } 1653c2fdda0dSAndy Whitcroft 1654dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1655dadf680dSJoe Perches my $match = $1; 1656dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1657dadf680dSJoe Perches } 1658dadf680dSJoe Perches 165900df344fSAndy Whitcroft return $res; 166000df344fSAndy Whitcroft} 166100df344fSAndy Whitcroft 1662a6962d72SJoe Perchessub get_quoted_string { 1663a6962d72SJoe Perches my ($line, $rawline) = @_; 1664a6962d72SJoe Perches 1665478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 166633acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1667a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1668a6962d72SJoe Perches} 1669a6962d72SJoe Perches 16708905a67cSAndy Whitcroftsub ctx_statement_block { 16718905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 16728905a67cSAndy Whitcroft my $line = $linenr - 1; 16738905a67cSAndy Whitcroft my $blk = ''; 16748905a67cSAndy Whitcroft my $soff = $off; 16758905a67cSAndy Whitcroft my $coff = $off - 1; 1676773647a0SAndy Whitcroft my $coff_set = 0; 16778905a67cSAndy Whitcroft 167813214adfSAndy Whitcroft my $loff = 0; 167913214adfSAndy Whitcroft 16808905a67cSAndy Whitcroft my $type = ''; 16818905a67cSAndy Whitcroft my $level = 0; 1682a2750645SAndy Whitcroft my @stack = (); 1683cf655043SAndy Whitcroft my $p; 16848905a67cSAndy Whitcroft my $c; 16858905a67cSAndy Whitcroft my $len = 0; 168613214adfSAndy Whitcroft 168713214adfSAndy Whitcroft my $remainder; 16888905a67cSAndy Whitcroft while (1) { 1689a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1690a2750645SAndy Whitcroft 1691773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 16928905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 16938905a67cSAndy Whitcroft # context. 16948905a67cSAndy Whitcroft if ($off >= $len) { 16958905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1696dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1697c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 16988905a67cSAndy Whitcroft $remain--; 169913214adfSAndy Whitcroft $loff = $len; 1700c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 17018905a67cSAndy Whitcroft $len = length($blk); 17028905a67cSAndy Whitcroft $line++; 17038905a67cSAndy Whitcroft last; 17048905a67cSAndy Whitcroft } 17058905a67cSAndy Whitcroft # Bail if there is no further context. 17068905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 170713214adfSAndy Whitcroft if ($off >= $len) { 17088905a67cSAndy Whitcroft last; 17098905a67cSAndy Whitcroft } 1710f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1711f74bd194SAndy Whitcroft $level++; 1712f74bd194SAndy Whitcroft $type = '#'; 1713f74bd194SAndy Whitcroft } 17148905a67cSAndy Whitcroft } 1715cf655043SAndy Whitcroft $p = $c; 17168905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 171713214adfSAndy Whitcroft $remainder = substr($blk, $off); 17188905a67cSAndy Whitcroft 1719773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 17204635f4fbSAndy Whitcroft 17214635f4fbSAndy Whitcroft # Handle nested #if/#else. 17224635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 17234635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 17244635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 17254635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 17264635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 17274635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 17284635f4fbSAndy Whitcroft } 17294635f4fbSAndy Whitcroft 17308905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 17318905a67cSAndy Whitcroft # outermost level. 17328905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 17338905a67cSAndy Whitcroft last; 17348905a67cSAndy Whitcroft } 17358905a67cSAndy Whitcroft 173613214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1737773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1738773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1739773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1740773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1741773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1742773647a0SAndy Whitcroft $coff_set = 1; 1743773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1744773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 174513214adfSAndy Whitcroft } 174613214adfSAndy Whitcroft 17478905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 17488905a67cSAndy Whitcroft $level++; 17498905a67cSAndy Whitcroft $type = '('; 17508905a67cSAndy Whitcroft } 17518905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 17528905a67cSAndy Whitcroft $level--; 17538905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 17548905a67cSAndy Whitcroft 17558905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 17568905a67cSAndy Whitcroft $coff = $off; 1757773647a0SAndy Whitcroft $coff_set = 1; 1758773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 17598905a67cSAndy Whitcroft } 17608905a67cSAndy Whitcroft } 17618905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 17628905a67cSAndy Whitcroft $level++; 17638905a67cSAndy Whitcroft $type = '{'; 17648905a67cSAndy Whitcroft } 17658905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 17668905a67cSAndy Whitcroft $level--; 17678905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 17688905a67cSAndy Whitcroft 17698905a67cSAndy Whitcroft if ($level == 0) { 1770b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1771b998e001SPatrick Pannuto $off++; 1772b998e001SPatrick Pannuto } 17738905a67cSAndy Whitcroft last; 17748905a67cSAndy Whitcroft } 17758905a67cSAndy Whitcroft } 1776f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1777f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1778f74bd194SAndy Whitcroft $level--; 1779f74bd194SAndy Whitcroft $type = ''; 1780f74bd194SAndy Whitcroft $off++; 1781f74bd194SAndy Whitcroft last; 1782f74bd194SAndy Whitcroft } 17838905a67cSAndy Whitcroft $off++; 17848905a67cSAndy Whitcroft } 1785a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 178613214adfSAndy Whitcroft if ($off == $len) { 1787a3bb97a7SAndy Whitcroft $loff = $len + 1; 178813214adfSAndy Whitcroft $line++; 178913214adfSAndy Whitcroft $remain--; 179013214adfSAndy Whitcroft } 17918905a67cSAndy Whitcroft 17928905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 17938905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 17948905a67cSAndy Whitcroft 17958905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 17968905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 17978905a67cSAndy Whitcroft 1798773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 179913214adfSAndy Whitcroft 180013214adfSAndy Whitcroft return ($statement, $condition, 180113214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 180213214adfSAndy Whitcroft} 180313214adfSAndy Whitcroft 1804cf655043SAndy Whitcroftsub statement_lines { 1805cf655043SAndy Whitcroft my ($stmt) = @_; 1806cf655043SAndy Whitcroft 1807cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1808cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1809cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1810cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1811cf655043SAndy Whitcroft 1812cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1813cf655043SAndy Whitcroft 1814cf655043SAndy Whitcroft return $#stmt_lines + 2; 1815cf655043SAndy Whitcroft} 1816cf655043SAndy Whitcroft 1817cf655043SAndy Whitcroftsub statement_rawlines { 1818cf655043SAndy Whitcroft my ($stmt) = @_; 1819cf655043SAndy Whitcroft 1820cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1821cf655043SAndy Whitcroft 1822cf655043SAndy Whitcroft return $#stmt_lines + 2; 1823cf655043SAndy Whitcroft} 1824cf655043SAndy Whitcroft 1825cf655043SAndy Whitcroftsub statement_block_size { 1826cf655043SAndy Whitcroft my ($stmt) = @_; 1827cf655043SAndy Whitcroft 1828cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1829cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1830cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1831cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1832cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1833cf655043SAndy Whitcroft 1834cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1835cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1836cf655043SAndy Whitcroft 1837cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1838cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1839cf655043SAndy Whitcroft 1840cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1841cf655043SAndy Whitcroft return $stmt_lines; 1842cf655043SAndy Whitcroft } else { 1843cf655043SAndy Whitcroft return $stmt_statements; 1844cf655043SAndy Whitcroft } 1845cf655043SAndy Whitcroft} 1846cf655043SAndy Whitcroft 184713214adfSAndy Whitcroftsub ctx_statement_full { 184813214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 184913214adfSAndy Whitcroft my ($statement, $condition, $level); 185013214adfSAndy Whitcroft 185113214adfSAndy Whitcroft my (@chunks); 185213214adfSAndy Whitcroft 1853cf655043SAndy Whitcroft # Grab the first conditional/block pair. 185413214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 185513214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1856773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 185713214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1858cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1859cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1860cf655043SAndy Whitcroft } 1861cf655043SAndy Whitcroft 1862cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1863cf655043SAndy Whitcroft # could continue the statement. 1864cf655043SAndy Whitcroft for (;;) { 186513214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 186613214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1867cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1868773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1869cf655043SAndy Whitcroft #print "C: push\n"; 1870cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 187113214adfSAndy Whitcroft } 187213214adfSAndy Whitcroft 187313214adfSAndy Whitcroft return ($level, $linenr, @chunks); 18748905a67cSAndy Whitcroft} 18758905a67cSAndy Whitcroft 18764a0df2efSAndy Whitcroftsub ctx_block_get { 1877f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 18784a0df2efSAndy Whitcroft my $line; 18794a0df2efSAndy Whitcroft my $start = $linenr - 1; 18804a0df2efSAndy Whitcroft my $blk = ''; 18814a0df2efSAndy Whitcroft my @o; 18824a0df2efSAndy Whitcroft my @c; 18834a0df2efSAndy Whitcroft my @res = (); 18844a0df2efSAndy Whitcroft 1885f0a594c1SAndy Whitcroft my $level = 0; 18864635f4fbSAndy Whitcroft my @stack = ($level); 188700df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 188800df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 188900df344fSAndy Whitcroft $remain--; 189000df344fSAndy Whitcroft 189100df344fSAndy Whitcroft $blk .= $rawlines[$line]; 18924635f4fbSAndy Whitcroft 18934635f4fbSAndy Whitcroft # Handle nested #if/#else. 189401464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 18954635f4fbSAndy Whitcroft push(@stack, $level); 189601464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 18974635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 189801464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 18994635f4fbSAndy Whitcroft $level = pop(@stack); 19004635f4fbSAndy Whitcroft } 19014635f4fbSAndy Whitcroft 190201464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1903f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1904f0a594c1SAndy Whitcroft if ($off > 0) { 1905f0a594c1SAndy Whitcroft $off--; 1906f0a594c1SAndy Whitcroft next; 1907f0a594c1SAndy Whitcroft } 19084a0df2efSAndy Whitcroft 1909f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1910f0a594c1SAndy Whitcroft $level--; 1911f0a594c1SAndy Whitcroft last if ($level == 0); 1912f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1913f0a594c1SAndy Whitcroft $level++; 1914f0a594c1SAndy Whitcroft } 1915f0a594c1SAndy Whitcroft } 19164a0df2efSAndy Whitcroft 1917f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 191800df344fSAndy Whitcroft push(@res, $rawlines[$line]); 19194a0df2efSAndy Whitcroft } 19204a0df2efSAndy Whitcroft 1921f0a594c1SAndy Whitcroft last if ($level == 0); 19224a0df2efSAndy Whitcroft } 19234a0df2efSAndy Whitcroft 1924f0a594c1SAndy Whitcroft return ($level, @res); 19254a0df2efSAndy Whitcroft} 19264a0df2efSAndy Whitcroftsub ctx_block_outer { 19274a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 19284a0df2efSAndy Whitcroft 1929f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1930f0a594c1SAndy Whitcroft return @r; 19314a0df2efSAndy Whitcroft} 19324a0df2efSAndy Whitcroftsub ctx_block { 19334a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 19344a0df2efSAndy Whitcroft 1935f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1936f0a594c1SAndy Whitcroft return @r; 1937653d4876SAndy Whitcroft} 1938653d4876SAndy Whitcroftsub ctx_statement { 1939f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1940f0a594c1SAndy Whitcroft 1941f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1942f0a594c1SAndy Whitcroft return @r; 1943f0a594c1SAndy Whitcroft} 1944f0a594c1SAndy Whitcroftsub ctx_block_level { 1945653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1946653d4876SAndy Whitcroft 1947f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 19484a0df2efSAndy Whitcroft} 19499c0ca6f9SAndy Whitcroftsub ctx_statement_level { 19509c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 19519c0ca6f9SAndy Whitcroft 19529c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 19539c0ca6f9SAndy Whitcroft} 19544a0df2efSAndy Whitcroft 19554a0df2efSAndy Whitcroftsub ctx_locate_comment { 19564a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 19574a0df2efSAndy Whitcroft 1958a55ee0ccSJoe Perches # If c99 comment on the current line, or the line before or after 1959a55ee0ccSJoe Perches my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); 1960a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1961a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); 1962a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1963a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); 1964a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1965a55ee0ccSJoe Perches 19664a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1967a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 19684a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 19694a0df2efSAndy Whitcroft 19704a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 19714a0df2efSAndy Whitcroft # comment. 19724a0df2efSAndy Whitcroft my $in_comment = 0; 19734a0df2efSAndy Whitcroft $current_comment = ''; 19744a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 197500df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 197600df344fSAndy Whitcroft #warn " $line\n"; 19774a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 19784a0df2efSAndy Whitcroft $in_comment = 1; 19794a0df2efSAndy Whitcroft } 19804a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 19814a0df2efSAndy Whitcroft $in_comment = 1; 19824a0df2efSAndy Whitcroft } 19834a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 19844a0df2efSAndy Whitcroft $current_comment = ''; 19854a0df2efSAndy Whitcroft } 19864a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 19874a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 19884a0df2efSAndy Whitcroft $in_comment = 0; 19894a0df2efSAndy Whitcroft } 19904a0df2efSAndy Whitcroft } 19914a0df2efSAndy Whitcroft 19924a0df2efSAndy Whitcroft chomp($current_comment); 19934a0df2efSAndy Whitcroft return($current_comment); 19944a0df2efSAndy Whitcroft} 19954a0df2efSAndy Whitcroftsub ctx_has_comment { 19964a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 19974a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 19984a0df2efSAndy Whitcroft 199900df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 20004a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 20014a0df2efSAndy Whitcroft 20024a0df2efSAndy Whitcroft return ($cmt ne ''); 20034a0df2efSAndy Whitcroft} 20044a0df2efSAndy Whitcroft 20054d001e4dSAndy Whitcroftsub raw_line { 20064d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 20074d001e4dSAndy Whitcroft 20084d001e4dSAndy Whitcroft my $offset = $linenr - 1; 20094d001e4dSAndy Whitcroft $cnt++; 20104d001e4dSAndy Whitcroft 20114d001e4dSAndy Whitcroft my $line; 20124d001e4dSAndy Whitcroft while ($cnt) { 20134d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 20144d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 20154d001e4dSAndy Whitcroft $cnt--; 20164d001e4dSAndy Whitcroft } 20174d001e4dSAndy Whitcroft 20184d001e4dSAndy Whitcroft return $line; 20194d001e4dSAndy Whitcroft} 20204d001e4dSAndy Whitcroft 20212a9f9d85STobin C. Hardingsub get_stat_real { 20222a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 20232a9f9d85STobin C. Harding 20242a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 20252a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 20262a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 20272a9f9d85STobin C. Harding } 20282a9f9d85STobin C. Harding 20292a9f9d85STobin C. Harding return $stat_real; 20302a9f9d85STobin C. Harding} 20312a9f9d85STobin C. Harding 2032e3d95a2aSTobin C. Hardingsub get_stat_here { 2033e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 2034e3d95a2aSTobin C. Harding 2035e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 2036e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 2037e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 2038e3d95a2aSTobin C. Harding } 2039e3d95a2aSTobin C. Harding 2040e3d95a2aSTobin C. Harding return $herectx; 2041e3d95a2aSTobin C. Harding} 2042e3d95a2aSTobin C. Harding 20430a920b5bSAndy Whitcroftsub cat_vet { 20440a920b5bSAndy Whitcroft my ($vet) = @_; 20459c0ca6f9SAndy Whitcroft my ($res, $coded); 20460a920b5bSAndy Whitcroft 20479c0ca6f9SAndy Whitcroft $res = ''; 20486c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 20496c72ffaaSAndy Whitcroft $res .= $1; 20506c72ffaaSAndy Whitcroft if ($2 ne '') { 20519c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 20526c72ffaaSAndy Whitcroft $res .= $coded; 20536c72ffaaSAndy Whitcroft } 20549c0ca6f9SAndy Whitcroft } 20559c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 20560a920b5bSAndy Whitcroft 20579c0ca6f9SAndy Whitcroft return $res; 20580a920b5bSAndy Whitcroft} 20590a920b5bSAndy Whitcroft 2060c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 2061cf655043SAndy Whitcroftmy $av_pending; 2062c2fdda0dSAndy Whitcroftmy @av_paren_type; 20631f65f947SAndy Whitcroftmy $av_pend_colon; 2064c2fdda0dSAndy Whitcroft 2065c2fdda0dSAndy Whitcroftsub annotate_reset { 2066c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 2067cf655043SAndy Whitcroft $av_pending = '_'; 2068cf655043SAndy Whitcroft @av_paren_type = ('E'); 20691f65f947SAndy Whitcroft $av_pend_colon = 'O'; 2070c2fdda0dSAndy Whitcroft} 2071c2fdda0dSAndy Whitcroft 20726c72ffaaSAndy Whitcroftsub annotate_values { 20736c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 20746c72ffaaSAndy Whitcroft 20756c72ffaaSAndy Whitcroft my $res; 20761f65f947SAndy Whitcroft my $var = '_' x length($stream); 20776c72ffaaSAndy Whitcroft my $cur = $stream; 20786c72ffaaSAndy Whitcroft 2079c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 20806c72ffaaSAndy Whitcroft 20816c72ffaaSAndy Whitcroft while (length($cur)) { 2082773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 2083cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 2084171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 20856c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 2086c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 2087c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 2088cf655043SAndy Whitcroft $type = pop(@av_paren_type); 2089c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 20906c72ffaaSAndy Whitcroft } 20916c72ffaaSAndy Whitcroft 2092c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 20939446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 20949446ef56SAndy Whitcroft push(@av_paren_type, $type); 2095addcdceaSAndy Whitcroft $type = 'c'; 20969446ef56SAndy Whitcroft 2097e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 2098c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 20996c72ffaaSAndy Whitcroft $type = 'T'; 21006c72ffaaSAndy Whitcroft 2101389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 2102389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 2103389a2fe5SAndy Whitcroft $type = 'T'; 2104389a2fe5SAndy Whitcroft 2105c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 2106171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 2107c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2108171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 2109171ae1a4SAndy Whitcroft if ($2 ne '') { 2110cf655043SAndy Whitcroft $av_pending = 'N'; 2111171ae1a4SAndy Whitcroft } 2112171ae1a4SAndy Whitcroft $type = 'E'; 2113171ae1a4SAndy Whitcroft 2114c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 2115171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 2116171ae1a4SAndy Whitcroft $av_preprocessor = 1; 2117171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 21186c72ffaaSAndy Whitcroft 2119c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 2120cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 2121c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2122cf655043SAndy Whitcroft 2123cf655043SAndy Whitcroft push(@av_paren_type, $type); 2124cf655043SAndy Whitcroft push(@av_paren_type, $type); 2125171ae1a4SAndy Whitcroft $type = 'E'; 2126cf655043SAndy Whitcroft 2127c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 2128cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 2129cf655043SAndy Whitcroft $av_preprocessor = 1; 2130cf655043SAndy Whitcroft 2131cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 2132cf655043SAndy Whitcroft 2133171ae1a4SAndy Whitcroft $type = 'E'; 2134cf655043SAndy Whitcroft 2135c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 2136cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 2137cf655043SAndy Whitcroft 2138cf655043SAndy Whitcroft $av_preprocessor = 1; 2139cf655043SAndy Whitcroft 2140cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 2141cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 2142cf655043SAndy Whitcroft pop(@av_paren_type); 2143cf655043SAndy Whitcroft push(@av_paren_type, $type); 2144171ae1a4SAndy Whitcroft $type = 'E'; 21456c72ffaaSAndy Whitcroft 21466c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 2147c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 21486c72ffaaSAndy Whitcroft 2149171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 2150171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 2151171ae1a4SAndy Whitcroft $av_pending = $type; 2152171ae1a4SAndy Whitcroft $type = 'N'; 2153171ae1a4SAndy Whitcroft 21546c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 2155c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 21566c72ffaaSAndy Whitcroft if (defined $2) { 2157cf655043SAndy Whitcroft $av_pending = 'V'; 21586c72ffaaSAndy Whitcroft } 21596c72ffaaSAndy Whitcroft $type = 'N'; 21606c72ffaaSAndy Whitcroft 216114b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 2162c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 216314b111c1SAndy Whitcroft $av_pending = 'E'; 21646c72ffaaSAndy Whitcroft $type = 'N'; 21656c72ffaaSAndy Whitcroft 21661f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 21671f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 21681f65f947SAndy Whitcroft $av_pend_colon = 'C'; 21691f65f947SAndy Whitcroft $type = 'N'; 21701f65f947SAndy Whitcroft 217114b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 2172c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 21736c72ffaaSAndy Whitcroft $type = 'N'; 21746c72ffaaSAndy Whitcroft 21756c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 2176c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 2177cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 2178cf655043SAndy Whitcroft $av_pending = '_'; 21796c72ffaaSAndy Whitcroft $type = 'N'; 21806c72ffaaSAndy Whitcroft 21816c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 2182cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 2183cf655043SAndy Whitcroft if ($new_type ne '_') { 2184cf655043SAndy Whitcroft $type = $new_type; 2185c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 2186c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 21876c72ffaaSAndy Whitcroft } else { 2188c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 21896c72ffaaSAndy Whitcroft } 21906c72ffaaSAndy Whitcroft 2191c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 2192c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 2193c8cb2ca3SAndy Whitcroft $type = 'V'; 2194cf655043SAndy Whitcroft $av_pending = 'V'; 21956c72ffaaSAndy Whitcroft 21968e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 21978e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 21981f65f947SAndy Whitcroft $av_pend_colon = 'B'; 21998e761b04SAndy Whitcroft } elsif ($type eq 'E') { 22008e761b04SAndy Whitcroft $av_pend_colon = 'L'; 22011f65f947SAndy Whitcroft } 22021f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 22031f65f947SAndy Whitcroft $type = 'V'; 22041f65f947SAndy Whitcroft 22056c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 2206c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 22076c72ffaaSAndy Whitcroft $type = 'V'; 22086c72ffaaSAndy Whitcroft 22096c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 2210c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 22116c72ffaaSAndy Whitcroft $type = 'N'; 22126c72ffaaSAndy Whitcroft 2213cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 2214c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 221513214adfSAndy Whitcroft $type = 'E'; 22161f65f947SAndy Whitcroft $av_pend_colon = 'O'; 221713214adfSAndy Whitcroft 22188e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 22198e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 22208e761b04SAndy Whitcroft $type = 'C'; 22218e761b04SAndy Whitcroft 22221f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 22231f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 22241f65f947SAndy Whitcroft $type = 'N'; 22251f65f947SAndy Whitcroft 22261f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 22271f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 22281f65f947SAndy Whitcroft 22291f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 22301f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 22311f65f947SAndy Whitcroft $type = 'E'; 22321f65f947SAndy Whitcroft } else { 22331f65f947SAndy Whitcroft $type = 'N'; 22341f65f947SAndy Whitcroft } 22351f65f947SAndy Whitcroft $av_pend_colon = 'O'; 22361f65f947SAndy Whitcroft 22378e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 223813214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 22396c72ffaaSAndy Whitcroft $type = 'N'; 22406c72ffaaSAndy Whitcroft 22410d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 224274048ed8SAndy Whitcroft my $variant; 224374048ed8SAndy Whitcroft 224474048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 224574048ed8SAndy Whitcroft if ($type eq 'V') { 224674048ed8SAndy Whitcroft $variant = 'B'; 224774048ed8SAndy Whitcroft } else { 224874048ed8SAndy Whitcroft $variant = 'U'; 224974048ed8SAndy Whitcroft } 225074048ed8SAndy Whitcroft 225174048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 225274048ed8SAndy Whitcroft $type = 'N'; 225374048ed8SAndy Whitcroft 22546c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 2255c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 22566c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 22576c72ffaaSAndy Whitcroft $type = 'N'; 22586c72ffaaSAndy Whitcroft } 22596c72ffaaSAndy Whitcroft 22606c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 2261c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 22626c72ffaaSAndy Whitcroft } 22636c72ffaaSAndy Whitcroft if (defined $1) { 22646c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 22656c72ffaaSAndy Whitcroft $res .= $type x length($1); 22666c72ffaaSAndy Whitcroft } 22676c72ffaaSAndy Whitcroft } 22686c72ffaaSAndy Whitcroft 22691f65f947SAndy Whitcroft return ($res, $var); 22706c72ffaaSAndy Whitcroft} 22716c72ffaaSAndy Whitcroft 22728905a67cSAndy Whitcroftsub possible { 227313214adfSAndy Whitcroft my ($possible, $line) = @_; 22749a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 22750776e594SAndy Whitcroft ^(?: 22760776e594SAndy Whitcroft $Modifier| 22770776e594SAndy Whitcroft $Storage| 22780776e594SAndy Whitcroft $Type| 22799a974fdbSAndy Whitcroft DEFINE_\S+ 22809a974fdbSAndy Whitcroft )$| 22819a974fdbSAndy Whitcroft ^(?: 22820776e594SAndy Whitcroft goto| 22830776e594SAndy Whitcroft return| 22840776e594SAndy Whitcroft case| 22850776e594SAndy Whitcroft else| 22860776e594SAndy Whitcroft asm|__asm__| 228789a88353SAndy Whitcroft do| 228889a88353SAndy Whitcroft \#| 228989a88353SAndy Whitcroft \#\#| 22909a974fdbSAndy Whitcroft )(?:\s|$)| 22910776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 22929a974fdbSAndy Whitcroft )}x; 22939a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 22949a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 2295c45dcabdSAndy Whitcroft # Check for modifiers. 2296c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 2297c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 2298c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 2299c45dcabdSAndy Whitcroft 2300c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 2301c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 2302d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 23039a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 2304d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 2305485ff23eSAlex Dowad push(@modifierListFile, $modifier); 2306d2506586SAndy Whitcroft } 23079a974fdbSAndy Whitcroft } 2308c45dcabdSAndy Whitcroft 2309c45dcabdSAndy Whitcroft } else { 231013214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 2311485ff23eSAlex Dowad push(@typeListFile, $possible); 2312c45dcabdSAndy Whitcroft } 23138905a67cSAndy Whitcroft build_types(); 23140776e594SAndy Whitcroft } else { 23150776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 23168905a67cSAndy Whitcroft } 23178905a67cSAndy Whitcroft} 23188905a67cSAndy Whitcroft 23196c72ffaaSAndy Whitcroftmy $prefix = ''; 23206c72ffaaSAndy Whitcroft 2321000d1cc1SJoe Perchessub show_type { 2322cbec18afSJoe Perches my ($type) = @_; 232391bfe484SJoe Perches 2324522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2325522b837cSAlexey Dobriyan 2326cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2327cbec18afSJoe Perches 2328cbec18afSJoe Perches return !defined $ignore_type{$type}; 2329000d1cc1SJoe Perches} 2330000d1cc1SJoe Perches 2331f0a594c1SAndy Whitcroftsub report { 2332cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2333cbec18afSJoe Perches 2334cbec18afSJoe Perches if (!show_type($type) || 2335cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2336773647a0SAndy Whitcroft return 0; 2337773647a0SAndy Whitcroft } 233857230297SJoe Perches my $output = ''; 2339737c0767SJohn Brooks if ($color) { 234057230297SJoe Perches if ($level eq 'ERROR') { 234157230297SJoe Perches $output .= RED; 234257230297SJoe Perches } elsif ($level eq 'WARNING') { 234357230297SJoe Perches $output .= YELLOW; 2344000d1cc1SJoe Perches } else { 234557230297SJoe Perches $output .= GREEN; 2346000d1cc1SJoe Perches } 234757230297SJoe Perches } 234857230297SJoe Perches $output .= $prefix . $level . ':'; 234957230297SJoe Perches if ($show_types) { 2350737c0767SJohn Brooks $output .= BLUE if ($color); 235157230297SJoe Perches $output .= "$type:"; 235257230297SJoe Perches } 2353737c0767SJohn Brooks $output .= RESET if ($color); 235457230297SJoe Perches $output .= ' ' . $msg . "\n"; 235534d8815fSJoe Perches 235634d8815fSJoe Perches if ($showfile) { 235734d8815fSJoe Perches my @lines = split("\n", $output, -1); 235834d8815fSJoe Perches splice(@lines, 1, 1); 235934d8815fSJoe Perches $output = join("\n", @lines); 236034d8815fSJoe Perches } 236152178ce0SDwaipayan Ray 236252178ce0SDwaipayan Ray if ($terse) { 236352178ce0SDwaipayan Ray $output = (split('\n', $output))[0] . "\n"; 236452178ce0SDwaipayan Ray } 236552178ce0SDwaipayan Ray 236652178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$type}) && 236752178ce0SDwaipayan Ray !exists($verbose_emitted{$type})) { 236852178ce0SDwaipayan Ray $output .= $verbose_messages{$type} . "\n\n"; 236952178ce0SDwaipayan Ray $verbose_emitted{$type} = 1; 237052178ce0SDwaipayan Ray } 23718905a67cSAndy Whitcroft 237257230297SJoe Perches push(our @report, $output); 2373773647a0SAndy Whitcroft 2374773647a0SAndy Whitcroft return 1; 2375f0a594c1SAndy Whitcroft} 2376cbec18afSJoe Perches 2377f0a594c1SAndy Whitcroftsub report_dump { 237813214adfSAndy Whitcroft our @report; 2379f0a594c1SAndy Whitcroft} 2380000d1cc1SJoe Perches 2381d752fcc8SJoe Perchessub fixup_current_range { 2382d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2383d752fcc8SJoe Perches 2384d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2385d752fcc8SJoe Perches my $o = $1; 2386d752fcc8SJoe Perches my $l = $2; 2387d752fcc8SJoe Perches my $no = $o + $offset; 2388d752fcc8SJoe Perches my $nl = $l + $length; 2389d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2390d752fcc8SJoe Perches } 2391d752fcc8SJoe Perches} 2392d752fcc8SJoe Perches 2393d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2394d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2395d752fcc8SJoe Perches 2396d752fcc8SJoe Perches my $range_last_linenr = 0; 2397d752fcc8SJoe Perches my $delta_offset = 0; 2398d752fcc8SJoe Perches 2399d752fcc8SJoe Perches my $old_linenr = 0; 2400d752fcc8SJoe Perches my $new_linenr = 0; 2401d752fcc8SJoe Perches 2402d752fcc8SJoe Perches my $next_insert = 0; 2403d752fcc8SJoe Perches my $next_delete = 0; 2404d752fcc8SJoe Perches 2405d752fcc8SJoe Perches my @lines = (); 2406d752fcc8SJoe Perches 2407d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2408d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2409d752fcc8SJoe Perches 2410d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2411d752fcc8SJoe Perches my $save_line = 1; 2412d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2413323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2414d752fcc8SJoe Perches $delta_offset = 0; 2415d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2416d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2417d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2418d752fcc8SJoe Perches } 2419d752fcc8SJoe Perches 2420d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2421d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2422d752fcc8SJoe Perches $save_line = 0; 2423d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2424d752fcc8SJoe Perches } 2425d752fcc8SJoe Perches 2426d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2427d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2428d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2429d752fcc8SJoe Perches $new_linenr++; 2430d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2431d752fcc8SJoe Perches } 2432d752fcc8SJoe Perches 2433d752fcc8SJoe Perches if ($save_line) { 2434d752fcc8SJoe Perches push(@lines, $line); 2435d752fcc8SJoe Perches $new_linenr++; 2436d752fcc8SJoe Perches } 2437d752fcc8SJoe Perches 2438d752fcc8SJoe Perches $old_linenr++; 2439d752fcc8SJoe Perches } 2440d752fcc8SJoe Perches 2441d752fcc8SJoe Perches return @lines; 2442d752fcc8SJoe Perches} 2443d752fcc8SJoe Perches 2444f2d7e4d4SJoe Perchessub fix_insert_line { 2445f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2446f2d7e4d4SJoe Perches 2447f2d7e4d4SJoe Perches my $inserted = { 2448f2d7e4d4SJoe Perches LINENR => $linenr, 2449f2d7e4d4SJoe Perches LINE => $line, 2450f2d7e4d4SJoe Perches }; 2451f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2452f2d7e4d4SJoe Perches} 2453f2d7e4d4SJoe Perches 2454f2d7e4d4SJoe Perchessub fix_delete_line { 2455f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2456f2d7e4d4SJoe Perches 2457f2d7e4d4SJoe Perches my $deleted = { 2458f2d7e4d4SJoe Perches LINENR => $linenr, 2459f2d7e4d4SJoe Perches LINE => $line, 2460f2d7e4d4SJoe Perches }; 2461f2d7e4d4SJoe Perches 2462f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2463f2d7e4d4SJoe Perches} 2464f2d7e4d4SJoe Perches 2465de7d4f0eSAndy Whitcroftsub ERROR { 2466cbec18afSJoe Perches my ($type, $msg) = @_; 2467cbec18afSJoe Perches 2468cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2469de7d4f0eSAndy Whitcroft our $clean = 0; 24706c72ffaaSAndy Whitcroft our $cnt_error++; 24713705ce5bSJoe Perches return 1; 2472de7d4f0eSAndy Whitcroft } 24733705ce5bSJoe Perches return 0; 2474773647a0SAndy Whitcroft} 2475de7d4f0eSAndy Whitcroftsub WARN { 2476cbec18afSJoe Perches my ($type, $msg) = @_; 2477cbec18afSJoe Perches 2478cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2479de7d4f0eSAndy Whitcroft our $clean = 0; 24806c72ffaaSAndy Whitcroft our $cnt_warn++; 24813705ce5bSJoe Perches return 1; 2482de7d4f0eSAndy Whitcroft } 24833705ce5bSJoe Perches return 0; 2484773647a0SAndy Whitcroft} 2485de7d4f0eSAndy Whitcroftsub CHK { 2486cbec18afSJoe Perches my ($type, $msg) = @_; 2487cbec18afSJoe Perches 2488cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2489de7d4f0eSAndy Whitcroft our $clean = 0; 24906c72ffaaSAndy Whitcroft our $cnt_chk++; 24913705ce5bSJoe Perches return 1; 24926c72ffaaSAndy Whitcroft } 24933705ce5bSJoe Perches return 0; 2494de7d4f0eSAndy Whitcroft} 2495de7d4f0eSAndy Whitcroft 24966ecd9674SAndy Whitcroftsub check_absolute_file { 24976ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 24986ecd9674SAndy Whitcroft my $file = $absolute; 24996ecd9674SAndy Whitcroft 25006ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 25016ecd9674SAndy Whitcroft 25026ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 25036ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 25046ecd9674SAndy Whitcroft if (-f "$root/$file") { 25056ecd9674SAndy Whitcroft ##print "file<$file>\n"; 25066ecd9674SAndy Whitcroft last; 25076ecd9674SAndy Whitcroft } 25086ecd9674SAndy Whitcroft } 25096ecd9674SAndy Whitcroft if (! -f _) { 25106ecd9674SAndy Whitcroft return 0; 25116ecd9674SAndy Whitcroft } 25126ecd9674SAndy Whitcroft 25136ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 25146ecd9674SAndy Whitcroft my $prefix = $absolute; 25156ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 25166ecd9674SAndy Whitcroft 25176ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 25186ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2519000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2520000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 25216ecd9674SAndy Whitcroft } 25226ecd9674SAndy Whitcroft} 25236ecd9674SAndy Whitcroft 25243705ce5bSJoe Perchessub trim { 25253705ce5bSJoe Perches my ($string) = @_; 25263705ce5bSJoe Perches 2527b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2528b34c648bSJoe Perches 2529b34c648bSJoe Perches return $string; 2530b34c648bSJoe Perches} 2531b34c648bSJoe Perches 2532b34c648bSJoe Perchessub ltrim { 2533b34c648bSJoe Perches my ($string) = @_; 2534b34c648bSJoe Perches 2535b34c648bSJoe Perches $string =~ s/^\s+//; 2536b34c648bSJoe Perches 2537b34c648bSJoe Perches return $string; 2538b34c648bSJoe Perches} 2539b34c648bSJoe Perches 2540b34c648bSJoe Perchessub rtrim { 2541b34c648bSJoe Perches my ($string) = @_; 2542b34c648bSJoe Perches 2543b34c648bSJoe Perches $string =~ s/\s+$//; 25443705ce5bSJoe Perches 25453705ce5bSJoe Perches return $string; 25463705ce5bSJoe Perches} 25473705ce5bSJoe Perches 254852ea8506SJoe Perchessub string_find_replace { 254952ea8506SJoe Perches my ($string, $find, $replace) = @_; 255052ea8506SJoe Perches 255152ea8506SJoe Perches $string =~ s/$find/$replace/g; 255252ea8506SJoe Perches 255352ea8506SJoe Perches return $string; 255452ea8506SJoe Perches} 255552ea8506SJoe Perches 25563705ce5bSJoe Perchessub tabify { 25573705ce5bSJoe Perches my ($leading) = @_; 25583705ce5bSJoe Perches 2559713a09deSAntonio Borneo my $source_indent = $tabsize; 25603705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 25613705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 25623705ce5bSJoe Perches 25633705ce5bSJoe Perches #convert leading spaces to tabs 25643705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 25653705ce5bSJoe Perches #Remove spaces before a tab 25663705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 25673705ce5bSJoe Perches 25683705ce5bSJoe Perches return "$leading"; 25693705ce5bSJoe Perches} 25703705ce5bSJoe Perches 2571d1fe9c09SJoe Perchessub pos_last_openparen { 2572d1fe9c09SJoe Perches my ($line) = @_; 2573d1fe9c09SJoe Perches 2574d1fe9c09SJoe Perches my $pos = 0; 2575d1fe9c09SJoe Perches 2576d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2577d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2578d1fe9c09SJoe Perches 2579d1fe9c09SJoe Perches my $last_openparen = 0; 2580d1fe9c09SJoe Perches 2581d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2582d1fe9c09SJoe Perches return -1; 2583d1fe9c09SJoe Perches } 2584d1fe9c09SJoe Perches 2585d1fe9c09SJoe Perches my $len = length($line); 2586d1fe9c09SJoe Perches 2587d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2588d1fe9c09SJoe Perches my $string = substr($line, $pos); 2589d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2590d1fe9c09SJoe Perches $pos += length($1) - 1; 2591d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2592d1fe9c09SJoe Perches $last_openparen = $pos; 2593d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2594d1fe9c09SJoe Perches last; 2595d1fe9c09SJoe Perches } 2596d1fe9c09SJoe Perches } 2597d1fe9c09SJoe Perches 259891cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2599d1fe9c09SJoe Perches} 2600d1fe9c09SJoe Perches 2601f36d3eb8SJoe Perchessub get_raw_comment { 2602f36d3eb8SJoe Perches my ($line, $rawline) = @_; 2603f36d3eb8SJoe Perches my $comment = ''; 2604f36d3eb8SJoe Perches 2605f36d3eb8SJoe Perches for my $i (0 .. (length($line) - 1)) { 2606f36d3eb8SJoe Perches if (substr($line, $i, 1) eq "$;") { 2607f36d3eb8SJoe Perches $comment .= substr($rawline, $i, 1); 2608f36d3eb8SJoe Perches } 2609f36d3eb8SJoe Perches } 2610f36d3eb8SJoe Perches 2611f36d3eb8SJoe Perches return $comment; 2612f36d3eb8SJoe Perches} 2613f36d3eb8SJoe Perches 26145b8f82e1SSong Liusub exclude_global_initialisers { 26155b8f82e1SSong Liu my ($realfile) = @_; 26165b8f82e1SSong Liu 26175b8f82e1SSong Liu # Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c). 26185b8f82e1SSong Liu return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ || 26195b8f82e1SSong Liu $realfile =~ m@^samples/bpf/.*_kern\.c$@ || 26205b8f82e1SSong Liu $realfile =~ m@/bpf/.*\.bpf\.c$@; 26215b8f82e1SSong Liu} 26225b8f82e1SSong Liu 26230a920b5bSAndy Whitcroftsub process { 26240a920b5bSAndy Whitcroft my $filename = shift; 26250a920b5bSAndy Whitcroft 26260a920b5bSAndy Whitcroft my $linenr=0; 26270a920b5bSAndy Whitcroft my $prevline=""; 2628c2fdda0dSAndy Whitcroft my $prevrawline=""; 26290a920b5bSAndy Whitcroft my $stashline=""; 2630c2fdda0dSAndy Whitcroft my $stashrawline=""; 26310a920b5bSAndy Whitcroft 26324a0df2efSAndy Whitcroft my $length; 26330a920b5bSAndy Whitcroft my $indent; 26340a920b5bSAndy Whitcroft my $previndent=0; 26350a920b5bSAndy Whitcroft my $stashindent=0; 26360a920b5bSAndy Whitcroft 2637de7d4f0eSAndy Whitcroft our $clean = 1; 26380a920b5bSAndy Whitcroft my $signoff = 0; 2639cd261496SGeert Uytterhoeven my $author = ''; 2640cd261496SGeert Uytterhoeven my $authorsignoff = 0; 264148ca2d8aSDwaipayan Ray my $author_sob = ''; 26420a920b5bSAndy Whitcroft my $is_patch = 0; 2643133712a2SRob Herring my $is_binding_patch = -1; 264429ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 264515662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 264644d303ebSJoe Perches my $has_patch_separator = 0; #Found a --- line 2647ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2648490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2649bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 26502a076f40SJoe Perches my $commit_log_long_line = 0; 2651e518e9a5SJoe Perches my $commit_log_has_diff = 0; 265213f1937eSJoe Perches my $reported_maintainer_file = 0; 2653fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2654fa64205dSPasi Savanainen 26554ce9f970SJoe Perches my $last_git_commit_id_linenr = -1; 26564ce9f970SJoe Perches 2657365dd4eaSJoe Perches my $last_blank_line = 0; 26585e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2659365dd4eaSJoe Perches 266013214adfSAndy Whitcroft our @report = (); 26616c72ffaaSAndy Whitcroft our $cnt_lines = 0; 26626c72ffaaSAndy Whitcroft our $cnt_error = 0; 26636c72ffaaSAndy Whitcroft our $cnt_warn = 0; 26646c72ffaaSAndy Whitcroft our $cnt_chk = 0; 26656c72ffaaSAndy Whitcroft 26660a920b5bSAndy Whitcroft # Trace the real file/line as we go. 26670a920b5bSAndy Whitcroft my $realfile = ''; 26680a920b5bSAndy Whitcroft my $realline = 0; 26690a920b5bSAndy Whitcroft my $realcnt = 0; 26700a920b5bSAndy Whitcroft my $here = ''; 267177cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 26720a920b5bSAndy Whitcroft my $in_comment = 0; 2673c2fdda0dSAndy Whitcroft my $comment_edge = 0; 26740a920b5bSAndy Whitcroft my $first_line = 0; 26751e855726SWolfram Sang my $p1_prefix = ''; 26760a920b5bSAndy Whitcroft 267713214adfSAndy Whitcroft my $prev_values = 'E'; 267813214adfSAndy Whitcroft 267913214adfSAndy Whitcroft # suppression flags 2680773647a0SAndy Whitcroft my %suppress_ifbraces; 2681170d3a22SAndy Whitcroft my %suppress_whiletrailers; 26822b474a1aSAndy Whitcroft my %suppress_export; 26833e469cdcSAndy Whitcroft my $suppress_statement = 0; 2684653d4876SAndy Whitcroft 26857e51f197SJoe Perches my %signatures = (); 2686323c1260SJoe Perches 2687c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2688de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2689c2fdda0dSAndy Whitcroft # 2690de7d4f0eSAndy Whitcroft my @setup_docs = (); 2691de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2692773647a0SAndy Whitcroft 2693d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2694d8b07710SJoe Perches 26959f3a8992SRob Herring my $checklicenseline = 1; 26969f3a8992SRob Herring 2697773647a0SAndy Whitcroft sanitise_line_reset(); 2698c2fdda0dSAndy Whitcroft my $line; 2699c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2700773647a0SAndy Whitcroft $linenr++; 2701773647a0SAndy Whitcroft $line = $rawline; 2702c2fdda0dSAndy Whitcroft 27033705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 27043705ce5bSJoe Perches 2705773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2706de7d4f0eSAndy Whitcroft $setup_docs = 0; 27072581ac7cSTim Froidcoeur if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { 2708de7d4f0eSAndy Whitcroft $setup_docs = 1; 2709de7d4f0eSAndy Whitcroft } 2710773647a0SAndy Whitcroft #next; 2711de7d4f0eSAndy Whitcroft } 271274fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2713773647a0SAndy Whitcroft $realline=$1-1; 2714773647a0SAndy Whitcroft if (defined $2) { 2715773647a0SAndy Whitcroft $realcnt=$3+1; 2716773647a0SAndy Whitcroft } else { 2717773647a0SAndy Whitcroft $realcnt=1+1; 2718773647a0SAndy Whitcroft } 2719c45dcabdSAndy Whitcroft $in_comment = 0; 2720773647a0SAndy Whitcroft 2721773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2722773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2723773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2724773647a0SAndy Whitcroft # at context start. 2725773647a0SAndy Whitcroft my $edge; 272601fa9147SAndy Whitcroft my $cnt = $realcnt; 272701fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 272801fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 272901fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 273001fa9147SAndy Whitcroft $cnt--; 273101fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2732721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2733fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2734fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2735fae17daeSAndy Whitcroft ($edge) = $1; 2736fae17daeSAndy Whitcroft last; 2737fae17daeSAndy Whitcroft } 2738773647a0SAndy Whitcroft } 2739773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2740773647a0SAndy Whitcroft $in_comment = 1; 2741773647a0SAndy Whitcroft } 2742773647a0SAndy Whitcroft 2743773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2744773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2745773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2746773647a0SAndy Whitcroft if (!defined $edge && 274783242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2748773647a0SAndy Whitcroft { 2749773647a0SAndy Whitcroft $in_comment = 1; 2750773647a0SAndy Whitcroft } 2751773647a0SAndy Whitcroft 2752773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2753773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2754773647a0SAndy Whitcroft 2755171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2756773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2757171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2758773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2759773647a0SAndy Whitcroft } 2760773647a0SAndy Whitcroft push(@lines, $line); 2761773647a0SAndy Whitcroft 2762773647a0SAndy Whitcroft if ($realcnt > 1) { 2763773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2764773647a0SAndy Whitcroft } else { 2765773647a0SAndy Whitcroft $realcnt = 0; 2766773647a0SAndy Whitcroft } 2767773647a0SAndy Whitcroft 2768773647a0SAndy Whitcroft #print "==>$rawline\n"; 2769773647a0SAndy Whitcroft #print "-->$line\n"; 2770de7d4f0eSAndy Whitcroft 2771de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2772de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2773de7d4f0eSAndy Whitcroft } 2774de7d4f0eSAndy Whitcroft } 2775de7d4f0eSAndy Whitcroft 27766c72ffaaSAndy Whitcroft $prefix = ''; 27776c72ffaaSAndy Whitcroft 2778773647a0SAndy Whitcroft $realcnt = 0; 2779773647a0SAndy Whitcroft $linenr = 0; 2780194f66fcSJoe Perches $fixlinenr = -1; 27810a920b5bSAndy Whitcroft foreach my $line (@lines) { 27820a920b5bSAndy Whitcroft $linenr++; 2783194f66fcSJoe Perches $fixlinenr++; 27841b5539b1SJoe Perches my $sline = $line; #copy of $line 27851b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 27860a920b5bSAndy Whitcroft 2787c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 2788f36d3eb8SJoe Perches my $raw_comment = get_raw_comment($line, $rawline); 27896c72ffaaSAndy Whitcroft 279012c253abSJoe Perches# check if it's a mode change, rename or start of a patch 279112c253abSJoe Perches if (!$in_commit_log && 279212c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 279312c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 279412c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 279512c253abSJoe Perches $is_patch = 1; 279612c253abSJoe Perches } 279712c253abSJoe Perches 27980a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2799e518e9a5SJoe Perches if (!$in_commit_log && 280074fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 280174fd4f34SJoe Perches my $context = $4; 28020a920b5bSAndy Whitcroft $is_patch = 1; 28034a0df2efSAndy Whitcroft $first_line = $linenr + 1; 28040a920b5bSAndy Whitcroft $realline=$1-1; 28050a920b5bSAndy Whitcroft if (defined $2) { 28060a920b5bSAndy Whitcroft $realcnt=$3+1; 28070a920b5bSAndy Whitcroft } else { 28080a920b5bSAndy Whitcroft $realcnt=1+1; 28090a920b5bSAndy Whitcroft } 2810c2fdda0dSAndy Whitcroft annotate_reset(); 281113214adfSAndy Whitcroft $prev_values = 'E'; 281213214adfSAndy Whitcroft 2813773647a0SAndy Whitcroft %suppress_ifbraces = (); 2814170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 28152b474a1aSAndy Whitcroft %suppress_export = (); 28163e469cdcSAndy Whitcroft $suppress_statement = 0; 281774fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 281874fd4f34SJoe Perches $context_function = $1; 281974fd4f34SJoe Perches } else { 282074fd4f34SJoe Perches undef $context_function; 282174fd4f34SJoe Perches } 28220a920b5bSAndy Whitcroft next; 28230a920b5bSAndy Whitcroft 28244a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 28254a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 28264a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2827773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 28280a920b5bSAndy Whitcroft $realline++; 2829d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 28300a920b5bSAndy Whitcroft 28314a0df2efSAndy Whitcroft # Measure the line length and indent. 2832c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 28330a920b5bSAndy Whitcroft 28340a920b5bSAndy Whitcroft # Track the previous line. 28350a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 28360a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2837c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2838c2fdda0dSAndy Whitcroft 2839773647a0SAndy Whitcroft #warn "line<$line>\n"; 28406c72ffaaSAndy Whitcroft 2841d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2842d8aaf121SAndy Whitcroft $realcnt--; 28430a920b5bSAndy Whitcroft } 28440a920b5bSAndy Whitcroft 2845cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2846cc77cdcaSAndy Whitcroft 28476c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 28486c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2849773647a0SAndy Whitcroft 28502ac73b4fSJoe Perches my $found_file = 0; 2851773647a0SAndy Whitcroft # extract the filename as it passes 28523bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 28533bf9a009SRabin Vincent $realfile = $1; 28542b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2855270c49a0SJoe Perches $in_commit_log = 0; 28562ac73b4fSJoe Perches $found_file = 1; 28573bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2858773647a0SAndy Whitcroft $realfile = $1; 28592b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2860270c49a0SJoe Perches $in_commit_log = 0; 28611e855726SWolfram Sang 28621e855726SWolfram Sang $p1_prefix = $1; 2863e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2864e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2865000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2866000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 28671e855726SWolfram Sang } 2868773647a0SAndy Whitcroft 2869c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2870000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2871000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2872773647a0SAndy Whitcroft } 28732ac73b4fSJoe Perches $found_file = 1; 28742ac73b4fSJoe Perches } 28752ac73b4fSJoe Perches 287634d8815fSJoe Perches#make up the handle for any error we report on this line 287734d8815fSJoe Perches if ($showfile) { 287834d8815fSJoe Perches $prefix = "$realfile:$realline: " 287934d8815fSJoe Perches } elsif ($emacs) { 28807d3a9f67SJoe Perches if ($file) { 28817d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 28827d3a9f67SJoe Perches } else { 288334d8815fSJoe Perches $prefix = "$filename:$linenr: "; 288434d8815fSJoe Perches } 28857d3a9f67SJoe Perches } 288634d8815fSJoe Perches 28872ac73b4fSJoe Perches if ($found_file) { 288885b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 288985b0ee18SJoe Perches WARN("OBSOLETE", 289085b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 289185b0ee18SJoe Perches } 28927bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 28932ac73b4fSJoe Perches $check = 1; 28942ac73b4fSJoe Perches } else { 28952ac73b4fSJoe Perches $check = $check_orig; 28962ac73b4fSJoe Perches } 28979f3a8992SRob Herring $checklicenseline = 1; 2898133712a2SRob Herring 2899133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2900133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2901133712a2SRob Herring 2902133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2903133712a2SRob Herring 2904133712a2SRob Herring if (($last_binding_patch != -1) && 2905133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2906133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2907858e6845SMauro Carvalho Chehab "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); 2908133712a2SRob Herring } 2909133712a2SRob Herring } 2910133712a2SRob Herring 2911773647a0SAndy Whitcroft next; 2912773647a0SAndy Whitcroft } 2913773647a0SAndy Whitcroft 2914389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 29150a920b5bSAndy Whitcroft 2916c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2917c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2918c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 29190a920b5bSAndy Whitcroft 29206c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 29216c72ffaaSAndy Whitcroft 2922490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2923490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2924490b292cSJoe Perches if ($in_commit_log) { 2925490b292cSJoe Perches if ($line !~ /^\s*$/) { 2926490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2927490b292cSJoe Perches } 2928490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2929490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2930490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2931490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2932490b292cSJoe Perches } 2933490b292cSJoe Perches 2934e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2935e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 293613e45417SMrinal Pandey (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && 293713e45417SMrinal Pandey $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || 2938e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2939e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2940e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2941e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2942e518e9a5SJoe Perches $commit_log_has_diff = 1; 2943e518e9a5SJoe Perches } 2944e518e9a5SJoe Perches 29453bf9a009SRabin Vincent# Check for incorrect file permissions 29463bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 29473bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 294804db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 294904db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2950000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2951000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 29523bf9a009SRabin Vincent } 29533bf9a009SRabin Vincent } 29543bf9a009SRabin Vincent 2955cd261496SGeert Uytterhoeven# Check the patch for a From: 2956cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2957cd261496SGeert Uytterhoeven $author = $1; 2958e7f929f3SDwaipayan Ray my $curline = $linenr; 2959e7f929f3SDwaipayan Ray while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { 2960e7f929f3SDwaipayan Ray $author .= $1; 2961e7f929f3SDwaipayan Ray } 2962cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2963cd261496SGeert Uytterhoeven $author =~ s/"//g; 2964dfa05c28SJoe Perches $author = reformat_email($author); 2965cd261496SGeert Uytterhoeven } 2966cd261496SGeert Uytterhoeven 296720112475SJoe Perches# Check the patch for a signoff: 2968dfa05c28SJoe Perches if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { 29694a0df2efSAndy Whitcroft $signoff++; 297015662b3eSJoe Perches $in_commit_log = 0; 297148ca2d8aSDwaipayan Ray if ($author ne '' && $authorsignoff != 1) { 2972fccaebf0SDwaipayan Ray if (same_email_addresses($1, $author)) { 2973cd261496SGeert Uytterhoeven $authorsignoff = 1; 297448ca2d8aSDwaipayan Ray } else { 297548ca2d8aSDwaipayan Ray my $ctx = $1; 297648ca2d8aSDwaipayan Ray my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); 297748ca2d8aSDwaipayan Ray my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); 297848ca2d8aSDwaipayan Ray 2979046fc741SMimi Zohar if (lc $email_address eq lc $author_address && $email_name eq $author_name) { 298048ca2d8aSDwaipayan Ray $author_sob = $ctx; 298148ca2d8aSDwaipayan Ray $authorsignoff = 2; 2982046fc741SMimi Zohar } elsif (lc $email_address eq lc $author_address) { 298348ca2d8aSDwaipayan Ray $author_sob = $ctx; 298448ca2d8aSDwaipayan Ray $authorsignoff = 3; 298548ca2d8aSDwaipayan Ray } elsif ($email_name eq $author_name) { 298648ca2d8aSDwaipayan Ray $author_sob = $ctx; 298748ca2d8aSDwaipayan Ray $authorsignoff = 4; 298848ca2d8aSDwaipayan Ray 298948ca2d8aSDwaipayan Ray my $address1 = $email_address; 299048ca2d8aSDwaipayan Ray my $address2 = $author_address; 299148ca2d8aSDwaipayan Ray 299248ca2d8aSDwaipayan Ray if ($address1 =~ /(\S+)\+\S+(\@.*)/) { 299348ca2d8aSDwaipayan Ray $address1 = "$1$2"; 299448ca2d8aSDwaipayan Ray } 299548ca2d8aSDwaipayan Ray if ($address2 =~ /(\S+)\+\S+(\@.*)/) { 299648ca2d8aSDwaipayan Ray $address2 = "$1$2"; 299748ca2d8aSDwaipayan Ray } 299848ca2d8aSDwaipayan Ray if ($address1 eq $address2) { 299948ca2d8aSDwaipayan Ray $authorsignoff = 5; 300048ca2d8aSDwaipayan Ray } 300148ca2d8aSDwaipayan Ray } 3002cd261496SGeert Uytterhoeven } 3003cd261496SGeert Uytterhoeven } 30040a920b5bSAndy Whitcroft } 300520112475SJoe Perches 300644d303ebSJoe Perches# Check for patch separator 300744d303ebSJoe Perches if ($line =~ /^---$/) { 300844d303ebSJoe Perches $has_patch_separator = 1; 300944d303ebSJoe Perches $in_commit_log = 0; 301044d303ebSJoe Perches } 301144d303ebSJoe Perches 3012e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 3013e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 3014e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 3015e0d975b1SJoe Perches $reported_maintainer_file = 1; 3016e0d975b1SJoe Perches } 3017e0d975b1SJoe Perches 301820112475SJoe Perches# Check signature styles 3019270c49a0SJoe Perches if (!$in_header_lines && 3020ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 302120112475SJoe Perches my $space_before = $1; 302220112475SJoe Perches my $sign_off = $2; 302320112475SJoe Perches my $space_after = $3; 302420112475SJoe Perches my $email = $4; 302520112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 302620112475SJoe Perches 3027ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 3028831242abSAditya Srivastava my $suggested_signature = find_standard_signature($sign_off); 3029831242abSAditya Srivastava if ($suggested_signature eq "") { 3030ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 3031ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 3032831242abSAditya Srivastava } else { 3033831242abSAditya Srivastava if (WARN("BAD_SIGN_OFF", 3034831242abSAditya Srivastava "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && 3035831242abSAditya Srivastava $fix) { 3036831242abSAditya Srivastava $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; 3037831242abSAditya Srivastava } 3038831242abSAditya Srivastava } 3039ce0338dfSJoe Perches } 304020112475SJoe Perches if (defined $space_before && $space_before ne "") { 30413705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30423705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 30433705ce5bSJoe Perches $fix) { 3044194f66fcSJoe Perches $fixed[$fixlinenr] = 30453705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30463705ce5bSJoe Perches } 304720112475SJoe Perches } 304820112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 30493705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30503705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 30513705ce5bSJoe Perches $fix) { 3052194f66fcSJoe Perches $fixed[$fixlinenr] = 30533705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30543705ce5bSJoe Perches } 30553705ce5bSJoe Perches 305620112475SJoe Perches } 305720112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 30583705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30593705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 30603705ce5bSJoe Perches $fix) { 3061194f66fcSJoe Perches $fixed[$fixlinenr] = 30623705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30633705ce5bSJoe Perches } 306420112475SJoe Perches } 306520112475SJoe Perches 3066dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 306748ca2d8aSDwaipayan Ray my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); 306820112475SJoe Perches if ($suggested_email eq "") { 3069000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 3070000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 307120112475SJoe Perches } else { 307220112475SJoe Perches my $dequoted = $suggested_email; 307320112475SJoe Perches $dequoted =~ s/^"//; 307420112475SJoe Perches $dequoted =~ s/" </ </; 307520112475SJoe Perches # Don't force email to have quotes 307620112475SJoe Perches # Allow just an angle bracketed address 3077fccaebf0SDwaipayan Ray if (!same_email_addresses($email, $suggested_email)) { 3078fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3079fccaebf0SDwaipayan Ray "email address '$email' might be better as '$suggested_email'\n" . $herecurr) && 3080fccaebf0SDwaipayan Ray $fix) { 3081fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/; 3082fccaebf0SDwaipayan Ray } 3083fccaebf0SDwaipayan Ray } 3084fccaebf0SDwaipayan Ray 3085fccaebf0SDwaipayan Ray # Address part shouldn't have comments 3086fccaebf0SDwaipayan Ray my $stripped_address = $email_address; 3087fccaebf0SDwaipayan Ray $stripped_address =~ s/\([^\(\)]*\)//g; 3088fccaebf0SDwaipayan Ray if ($email_address ne $stripped_address) { 3089fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3090fccaebf0SDwaipayan Ray "address part of email should not have comments: '$email_address'\n" . $herecurr) && 3091fccaebf0SDwaipayan Ray $fix) { 3092fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/; 3093fccaebf0SDwaipayan Ray } 3094fccaebf0SDwaipayan Ray } 3095fccaebf0SDwaipayan Ray 3096fccaebf0SDwaipayan Ray # Only one name comment should be allowed 3097fccaebf0SDwaipayan Ray my $comment_count = () = $name_comment =~ /\([^\)]+\)/g; 3098fccaebf0SDwaipayan Ray if ($comment_count > 1) { 3099000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 3100fccaebf0SDwaipayan Ray "Use a single name comment in email: '$email'\n" . $herecurr); 3101fccaebf0SDwaipayan Ray } 3102fccaebf0SDwaipayan Ray 3103fccaebf0SDwaipayan Ray 3104fccaebf0SDwaipayan Ray # [email protected] or [email protected] shouldn't 3105e73d2715SDwaipayan Ray # have an email name. In addition comments should strictly 3106fccaebf0SDwaipayan Ray # begin with a # 3107fccaebf0SDwaipayan Ray if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { 3108fccaebf0SDwaipayan Ray if (($comment ne "" && $comment !~ /^#.+/) || 3109fccaebf0SDwaipayan Ray ($email_name ne "")) { 3110fccaebf0SDwaipayan Ray my $cur_name = $email_name; 3111fccaebf0SDwaipayan Ray my $new_comment = $comment; 3112fccaebf0SDwaipayan Ray $cur_name =~ s/[a-zA-Z\s\-\"]+//g; 3113fccaebf0SDwaipayan Ray 3114fccaebf0SDwaipayan Ray # Remove brackets enclosing comment text 3115fccaebf0SDwaipayan Ray # and # from start of comments to get comment text 3116fccaebf0SDwaipayan Ray $new_comment =~ s/^\((.*)\)$/$1/; 3117fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3118fccaebf0SDwaipayan Ray $new_comment =~ s/^[\s\#]+|\s+$//g; 3119fccaebf0SDwaipayan Ray 3120fccaebf0SDwaipayan Ray $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); 3121fccaebf0SDwaipayan Ray $new_comment = " # $new_comment" if ($new_comment ne ""); 3122fccaebf0SDwaipayan Ray my $new_email = "$email_address$new_comment"; 3123fccaebf0SDwaipayan Ray 3124fccaebf0SDwaipayan Ray if (WARN("BAD_STABLE_ADDRESS_STYLE", 3125fccaebf0SDwaipayan Ray "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && 3126fccaebf0SDwaipayan Ray $fix) { 3127fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3128fccaebf0SDwaipayan Ray } 3129fccaebf0SDwaipayan Ray } 3130fccaebf0SDwaipayan Ray } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { 3131fccaebf0SDwaipayan Ray my $new_comment = $comment; 3132fccaebf0SDwaipayan Ray 3133fccaebf0SDwaipayan Ray # Extract comment text from within brackets or 3134fccaebf0SDwaipayan Ray # c89 style /*...*/ comments 3135fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3136fccaebf0SDwaipayan Ray $new_comment =~ s/^\/\*(.*)\*\/$/$1/; 3137fccaebf0SDwaipayan Ray 3138fccaebf0SDwaipayan Ray $new_comment = trim($new_comment); 3139fccaebf0SDwaipayan Ray $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo 3140fccaebf0SDwaipayan Ray $new_comment = "($new_comment)" if ($new_comment ne ""); 3141fccaebf0SDwaipayan Ray my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); 3142fccaebf0SDwaipayan Ray 3143fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3144fccaebf0SDwaipayan Ray "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && 3145fccaebf0SDwaipayan Ray $fix) { 3146fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3147fccaebf0SDwaipayan Ray } 314820112475SJoe Perches } 31490a920b5bSAndy Whitcroft } 31507e51f197SJoe Perches 31517e51f197SJoe Perches# Check for duplicate signatures 31527e51f197SJoe Perches my $sig_nospace = $line; 31537e51f197SJoe Perches $sig_nospace =~ s/\s//g; 31547e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 31557e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 31567e51f197SJoe Perches WARN("BAD_SIGN_OFF", 31577e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 31587e51f197SJoe Perches } else { 31597e51f197SJoe Perches $signatures{$sig_nospace} = 1; 31607e51f197SJoe Perches } 31616c5d24eeSSean Christopherson 31626c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 31636c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 31646c5d24eeSSean Christopherson if ($email eq $author) { 31656c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31661916f777SThorsten Leemhuis "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . $herecurr); 31676c5d24eeSSean Christopherson } 31686c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 31696c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31701916f777SThorsten Leemhuis "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr); 31711916f777SThorsten Leemhuis } elsif ($rawlines[$linenr] !~ /^signed-off-by:\s*(.*)/i) { 31726c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31731916f777SThorsten Leemhuis "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr . $rawlines[$linenr] . "\n"); 31746c5d24eeSSean Christopherson } elsif ($1 ne $email) { 31756c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31761916f777SThorsten Leemhuis "Co-developed-by and Signed-off-by: name/email do not match\n" . $herecurr . $rawlines[$linenr] . "\n"); 31776c5d24eeSSean Christopherson } 31786c5d24eeSSean Christopherson } 3179d7f1d71eSKai Wasserbäch 318044c31888SMatthieu Baerts# check if Reported-by: is followed by a Closes: tag 3181d7f1d71eSKai Wasserbäch if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) { 3182d7f1d71eSKai Wasserbäch if (!defined $lines[$linenr]) { 3183d7f1d71eSKai Wasserbäch WARN("BAD_REPORTED_BY_LINK", 318444c31888SMatthieu Baerts "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . "\n"); 3185d6ccdd67SMatthieu Baerts } elsif ($rawlines[$linenr] !~ /^closes:\s*/i) { 3186d7f1d71eSKai Wasserbäch WARN("BAD_REPORTED_BY_LINK", 318744c31888SMatthieu Baerts "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n"); 31880a920b5bSAndy Whitcroft } 3189d7f1d71eSKai Wasserbäch } 3190d7f1d71eSKai Wasserbäch } 3191d7f1d71eSKai Wasserbäch 31920a920b5bSAndy Whitcroft 3193bd17e036SNiklas Söderlund# Check Fixes: styles is correct 3194bd17e036SNiklas Söderlund if (!$in_header_lines && 3195bd17e036SNiklas Söderlund $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) { 3196bd17e036SNiklas Söderlund my $orig_commit = ""; 3197bd17e036SNiklas Söderlund my $id = "0123456789ab"; 3198bd17e036SNiklas Söderlund my $title = "commit title"; 3199bd17e036SNiklas Söderlund my $tag_case = 1; 3200bd17e036SNiklas Söderlund my $tag_space = 1; 3201bd17e036SNiklas Söderlund my $id_length = 1; 3202bd17e036SNiklas Söderlund my $id_case = 1; 3203bd17e036SNiklas Söderlund my $title_has_quotes = 0; 3204bd17e036SNiklas Söderlund 3205bd17e036SNiklas Söderlund if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) { 3206bd17e036SNiklas Söderlund my $tag = $1; 3207bd17e036SNiklas Söderlund $orig_commit = $2; 3208bd17e036SNiklas Söderlund $title = $3; 3209bd17e036SNiklas Söderlund 3210bd17e036SNiklas Söderlund $tag_case = 0 if $tag eq "Fixes:"; 3211bd17e036SNiklas Söderlund $tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i); 3212bd17e036SNiklas Söderlund 3213bd17e036SNiklas Söderlund $id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i); 3214bd17e036SNiklas Söderlund $id_case = 0 if ($orig_commit !~ /[A-F]/); 3215bd17e036SNiklas Söderlund 3216bd17e036SNiklas Söderlund # Always strip leading/trailing parens then double quotes if existing 3217bd17e036SNiklas Söderlund $title = substr($title, 1, -1); 3218bd17e036SNiklas Söderlund if ($title =~ /^".*"$/) { 3219bd17e036SNiklas Söderlund $title = substr($title, 1, -1); 3220bd17e036SNiklas Söderlund $title_has_quotes = 1; 3221bd17e036SNiklas Söderlund } 3222bd17e036SNiklas Söderlund } 3223bd17e036SNiklas Söderlund 3224bd17e036SNiklas Söderlund my ($cid, $ctitle) = git_commit_info($orig_commit, $id, 3225bd17e036SNiklas Söderlund $title); 3226bd17e036SNiklas Söderlund 3227bd17e036SNiklas Söderlund if ($ctitle ne $title || $tag_case || $tag_space || 3228bd17e036SNiklas Söderlund $id_length || $id_case || !$title_has_quotes) { 3229bd17e036SNiklas Söderlund if (WARN("BAD_FIXES_TAG", 3230bd17e036SNiklas Söderlund "Please use correct Fixes: style 'Fixes: <12 chars of sha1> (\"<title line>\")' - ie: 'Fixes: $cid (\"$ctitle\")'\n" . $herecurr) && 3231bd17e036SNiklas Söderlund $fix) { 3232bd17e036SNiklas Söderlund $fixed[$fixlinenr] = "Fixes: $cid (\"$ctitle\")"; 3233bd17e036SNiklas Söderlund } 3234bd17e036SNiklas Söderlund } 3235bd17e036SNiklas Söderlund } 3236bd17e036SNiklas Söderlund 3237a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 3238a2fe16b9SJoe Perches if ($in_header_lines && 3239a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 3240a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 3241a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 3242a2fe16b9SJoe Perches } 3243a2fe16b9SJoe Perches 324444d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context 324544d303ebSJoe Perches if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { 32467580c5b9SAditya Srivastava if (ERROR("GERRIT_CHANGE_ID", 32477580c5b9SAditya Srivastava "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && 32487580c5b9SAditya Srivastava $fix) { 32497580c5b9SAditya Srivastava fix_delete_line($fixlinenr, $rawline); 32507580c5b9SAditya Srivastava } 32517ebd05efSChristopher Covington } 32527ebd05efSChristopher Covington 3253369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 3254369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3255369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 3256369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 3257369c8dd3SJoe Perches # timestamp 3258634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 3259634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 3260634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 3261634cffccSJoe Perches # stack dump address styles 3262369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 3263369c8dd3SJoe Perches } 3264369c8dd3SJoe Perches 32652a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 32662a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 3267bf4daf12SJoe Perches length($line) > 75 && 3268bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 3269bf4daf12SJoe Perches # file delta changes 327036f8b348SJerome Forissier $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ || 3271bf4daf12SJoe Perches # filename then : 3272f94e40eaSMatthieu Baerts $line =~ /^\s*(?:Fixes:|$link_tags_search|$signature_tags)/i || 3273f94e40eaSMatthieu Baerts # A Fixes:, link or signature tag line 3274bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 32752a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 32768e7b7ffbSJim Cromie "Prefer a maximum 75 chars per line (possible unwrapped commit description?)\n" . $herecurr); 32772a076f40SJoe Perches $commit_log_long_line = 1; 32782a076f40SJoe Perches } 32792a076f40SJoe Perches 3280bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 3281bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 3282bf4daf12SJoe Perches $line =~ /^\s*$/) { 3283bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 3284bf4daf12SJoe Perches } 3285bf4daf12SJoe Perches 328676f381bbSKai Wasserbäch# Check for odd tags before a URI/URL 328776f381bbSKai Wasserbäch if ($in_commit_log && 3288f94e40eaSMatthieu Baerts $line =~ /^\s*(\w+:)\s*http/ && $1 !~ /^$link_tags_search$/) { 328976f381bbSKai Wasserbäch if ($1 =~ /^v(?:ersion)?\d+/i) { 329076f381bbSKai Wasserbäch WARN("COMMIT_LOG_VERSIONING", 329176f381bbSKai Wasserbäch "Patch version information should be after the --- line\n" . $herecurr); 329276f381bbSKai Wasserbäch } else { 329376f381bbSKai Wasserbäch WARN("COMMIT_LOG_USE_LINK", 3294f94e40eaSMatthieu Baerts "Unknown link reference '$1', use $link_tags_print instead\n" . $herecurr); 329576f381bbSKai Wasserbäch } 329676f381bbSKai Wasserbäch } 329776f381bbSKai Wasserbäch 3298d6ccdd67SMatthieu Baerts# Check for misuse of the link tags 3299d6ccdd67SMatthieu Baerts if ($in_commit_log && 3300d6ccdd67SMatthieu Baerts $line =~ /^\s*(\w+:)\s*(\S+)/) { 3301d6ccdd67SMatthieu Baerts my $tag = $1; 3302d6ccdd67SMatthieu Baerts my $value = $2; 3303d6ccdd67SMatthieu Baerts if ($tag =~ /^$link_tags_search$/ && $value !~ m{^https?://}) { 3304d6ccdd67SMatthieu Baerts WARN("COMMIT_LOG_WRONG_LINK", 3305d6ccdd67SMatthieu Baerts "'$tag' should be followed by a public http(s) link\n" . $herecurr); 33060d7835fcSJoe Perches } 33074ce9f970SJoe Perches } 33084ce9f970SJoe Perches 33094ce9f970SJoe Perches# Check for lines starting with a # 33104ce9f970SJoe Perches if ($in_commit_log && $line =~ /^#/) { 33114ce9f970SJoe Perches if (WARN("COMMIT_COMMENT_SYMBOL", 33124ce9f970SJoe Perches "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && 33134ce9f970SJoe Perches $fix) { 33144ce9f970SJoe Perches $fixed[$fixlinenr] =~ s/^/ /; 33154ce9f970SJoe Perches } 33164ce9f970SJoe Perches } 3317a8972573SJohn Hubbard 3318e882dbfcSWei Wang# Check for git id commit length and improperly formed commit descriptions 33194ce9f970SJoe Perches# A correctly formed commit description is: 33204ce9f970SJoe Perches# commit <SHA-1 hash length 12+ chars> ("Complete commit subject") 3321aab38f51SJoe Perches# with the commit subject '("' prefix and '")' suffix 3322369c8dd3SJoe Perches# This is a fairly compilicated block as it tests for what appears to be 3323bf4daf12SJoe Perches# bare SHA-1 hash with minimum length of 5. It also avoids several types of 3324fe043ea1SJoe Perches# possible SHA-1 matches. 3325fe043ea1SJoe Perches# A commit match can span multiple lines so this block attempts to find a 33260d7835fcSJoe Perches# complete typical commit on a maximum of 3 lines 33270d7835fcSJoe Perches if ($perl_version_ok && 33280d7835fcSJoe Perches $in_commit_log && !$commit_log_possible_stack_dump && 33290d7835fcSJoe Perches $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && 33300d7835fcSJoe Perches $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 33310d7835fcSJoe Perches (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 33320d7835fcSJoe Perches ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) || 33334ce9f970SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 33344ce9f970SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 33354ce9f970SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 33360d7835fcSJoe Perches my $init_char = "c"; 33374ce9f970SJoe Perches my $orig_commit = ""; 33384ce9f970SJoe Perches my $short = 1; 33394ce9f970SJoe Perches my $long = 0; 33404ce9f970SJoe Perches my $case = 1; 33414ce9f970SJoe Perches my $space = 1; 33424ce9f970SJoe Perches my $id = '0123456789ab'; 33434ce9f970SJoe Perches my $orig_desc = "commit description"; 33444ce9f970SJoe Perches my $description = ""; 33454ce9f970SJoe Perches my $herectx = $herecurr; 33464ce9f970SJoe Perches my $has_parens = 0; 33474ce9f970SJoe Perches my $has_quotes = 0; 33484ce9f970SJoe Perches 33494ce9f970SJoe Perches my $input = $line; 33504ce9f970SJoe Perches if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) { 33514ce9f970SJoe Perches for (my $n = 0; $n < 2; $n++) { 33524ce9f970SJoe Perches if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) { 33534ce9f970SJoe Perches $orig_desc = $1; 33544ce9f970SJoe Perches $has_parens = 1; 33554ce9f970SJoe Perches # Always strip leading/trailing parens then double quotes if existing 3356fe043ea1SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 3357fe043ea1SJoe Perches if ($orig_desc =~ /^".*"$/) { 33584ce9f970SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 33594ce9f970SJoe Perches $has_quotes = 1; 33604ce9f970SJoe Perches } 33614ce9f970SJoe Perches last; 33624ce9f970SJoe Perches } 33634ce9f970SJoe Perches last if ($#lines < $linenr + $n); 33644ce9f970SJoe Perches $input .= " " . trim($rawlines[$linenr + $n]); 33654ce9f970SJoe Perches $herectx .= "$rawlines[$linenr + $n]\n"; 33664ce9f970SJoe Perches } 33670d7835fcSJoe Perches $herectx = $herecurr if (!$has_parens); 33680d7835fcSJoe Perches } 33690d7835fcSJoe Perches 33700d7835fcSJoe Perches if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 33710d7835fcSJoe Perches $init_char = $1; 3372948b133aSHeinrich Schuchardt $orig_commit = lc($2); 33734ce9f970SJoe Perches $short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i); 33744ce9f970SJoe Perches $long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i); 3375d311cd44SJoe Perches $space = 0 if ($input =~ /\bcommit [0-9a-f]/i); 33764ce9f970SJoe Perches $case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 33770d7835fcSJoe Perches } elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) { 33784ce9f970SJoe Perches $orig_commit = lc($1); 33794ce9f970SJoe Perches } 3380d311cd44SJoe Perches 3381d311cd44SJoe Perches ($id, $description) = git_commit_info($orig_commit, 33829b71f79fSBjorn Helgaas $id, $orig_desc); 33839b71f79fSBjorn Helgaas 33849b71f79fSBjorn Helgaas if (defined($id) && 33859b71f79fSBjorn Helgaas ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) && 33869b71f79fSBjorn Helgaas $last_git_commit_id_linenr != $linenr - 1) { 33879b71f79fSBjorn Helgaas ERROR("GIT_COMMIT_ID", 338813f1937eSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx); 338913f1937eSJoe Perches } 339013f1937eSJoe Perches #don't report the next line if this line ends in commit and the sha1 hash is the next line 339113f1937eSJoe Perches $last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i); 339213f1937eSJoe Perches } 339313f1937eSJoe Perches 3394a82603a8SAndrew Jeffery# Check for mailing list archives other than lore.kernel.org 339513f1937eSJoe Perches if ($rawline =~ m{http.*\b$obsolete_archives}) { 339613f1937eSJoe Perches WARN("PREFER_LORE_ARCHIVE", 339713f1937eSJoe Perches "Use lore.kernel.org archive links when possible - see https://lore.kernel.org/lists.html\n" . $herecurr); 339813f1937eSJoe Perches } 339913f1937eSJoe Perches 3400e400edb1SRob Herring# Check for added, moved or deleted files 3401e400edb1SRob Herring if (!$reported_maintainer_file && !$in_commit_log && 3402e400edb1SRob Herring ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 3403e400edb1SRob Herring $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 3404e400edb1SRob Herring ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 340556ddc4cdSMauro Carvalho Chehab (defined($1) || defined($2))))) { 3406e400edb1SRob Herring $is_patch = 1; 3407e400edb1SRob Herring $reported_maintainer_file = 1; 340800df344fSAndy Whitcroft WARN("FILE_PATH_CHANGES", 34098905a67cSAndy Whitcroft "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 3410000d1cc1SJoe Perches } 3411000d1cc1SJoe Perches 34126c72ffaaSAndy Whitcroft# Check for adding new DT bindings not in schema format 3413de7d4f0eSAndy Whitcroft if (!$in_commit_log && 3414de7d4f0eSAndy Whitcroft ($line =~ /^new file mode\s*\d+\s*$/) && 3415de7d4f0eSAndy Whitcroft ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { 3416de7d4f0eSAndy Whitcroft WARN("DT_SCHEMA_BINDING_PATCH", 3417171ae1a4SAndy Whitcroft "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n"); 3418171ae1a4SAndy Whitcroft } 3419171ae1a4SAndy Whitcroft 3420171ae1a4SAndy Whitcroft# Check for wrappage within a valid hunk of the file 3421171ae1a4SAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 3422171ae1a4SAndy Whitcroft ERROR("CORRUPTED_PATCH", 3423171ae1a4SAndy Whitcroft "patch seems to be corrupt (line wrapped?)\n" . 342434d99219SJoe Perches $herecurr) if (!$emitted_corrupt++); 3425000d1cc1SJoe Perches } 342600df344fSAndy Whitcroft 34270a920b5bSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 342815662b3eSJoe Perches if (($realfile =~ /^$/ || $line =~ /^\+/) && 342915662b3eSJoe Perches $rawline !~ m/^$UTF8*$/) { 343015662b3eSJoe Perches my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 3431eb3a58deSJoe Perches 3432eb3a58deSJoe Perches my $blank = copy_spacing($rawline); 343315662b3eSJoe Perches my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 343415662b3eSJoe Perches my $hereptr = "$hereline$ptr\n"; 3435ed43c4e5SAllen Hubbe 343615662b3eSJoe Perches CHK("INVALID_UTF8", 343715662b3eSJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 3438fa64205dSPasi Savanainen } 3439fa64205dSPasi Savanainen 3440fa64205dSPasi Savanainen# Check if it's the start of a commit log 3441fa64205dSPasi Savanainen# (not a header line and we haven't seen the patch filename) 3442fa64205dSPasi Savanainen if ($in_header_lines && $realfile =~ /^$/ && 3443fa64205dSPasi Savanainen !($rawline =~ /^\s+(?:\S|$)/ || 3444fa64205dSPasi Savanainen $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 3445fa64205dSPasi Savanainen $in_header_lines = 0; 3446fa64205dSPasi Savanainen $in_commit_log = 1; 344715662b3eSJoe Perches $has_commit_log = 1; 3448fa64205dSPasi Savanainen } 344915662b3eSJoe Perches 345015662b3eSJoe Perches# Check if there is UTF-8 in a commit log when a mail header has explicitly 345115662b3eSJoe Perches# declined it, i.e defined some charset where it is missing. 3452d6430f71SJoe Perches if ($in_header_lines && 3453d6430f71SJoe Perches $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 3454d6430f71SJoe Perches $1 !~ /utf-8/i) { 3455d6430f71SJoe Perches $non_utf8_charset = 1; 3456d6430f71SJoe Perches } 3457d6430f71SJoe Perches 3458d6430f71SJoe Perches if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 3459d6430f71SJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 3460d6430f71SJoe Perches WARN("UTF8_BEFORE_PATCH", 3461d6430f71SJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 3462d6430f71SJoe Perches } 3463d6430f71SJoe Perches 3464d6430f71SJoe Perches# Check for absolute kernel paths in commit message 3465d6430f71SJoe Perches if ($tree && $in_commit_log) { 346666b47b4aSKees Cook while ($line =~ m{(?:^|\s)(/\S*)}g) { 346766d7a382SJoe Perches my $file = $1; 346866d7a382SJoe Perches 34697da07c31SDwaipayan Ray if ($file =~ m{^(.*?)(?::\d+)+:?$} && 347066b47b4aSKees Cook check_absolute_file($1, $herecurr)) { 34717da07c31SDwaipayan Ray # 34727da07c31SDwaipayan Ray } else { 34737da07c31SDwaipayan Ray check_absolute_file($file, $herecurr); 347466b47b4aSKees Cook } 347566b47b4aSKees Cook } 347666b47b4aSKees Cook } 34770675a8fbSJean Delvare 34780675a8fbSJean Delvare# Check for various typo / spelling mistakes 34790675a8fbSJean Delvare if (defined($misspellings) && 34807da07c31SDwaipayan Ray ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 348166b47b4aSKees Cook while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { 348266b47b4aSKees Cook my $typo = $1; 348366b47b4aSKees Cook my $blank = copy_spacing($rawline); 348466b47b4aSKees Cook my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); 348566b47b4aSKees Cook my $hereptr = "$hereline$ptr\n"; 348666b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 3487a8dd86bfSMatteo Croce $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 3488a8dd86bfSMatteo Croce $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 3489a8dd86bfSMatteo Croce my $msg_level = \&WARN; 3490a8dd86bfSMatteo Croce $msg_level = \&CHK if ($file); 3491a8dd86bfSMatteo Croce if (&{$msg_level}("TYPO_SPELLING", 3492a8dd86bfSMatteo Croce "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && 3493a8dd86bfSMatteo Croce $fix) { 3494a8dd86bfSMatteo Croce $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 3495a8dd86bfSMatteo Croce } 3496a8dd86bfSMatteo Croce } 3497a8dd86bfSMatteo Croce } 3498310cd06bSJoe Perches 34998d0325ccSAditya Srivastava# check for invalid commit id 35008d0325ccSAditya Srivastava if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 35018d0325ccSAditya Srivastava my $id; 35021db81a68SDwaipayan Ray my $description; 3503310cd06bSJoe Perches ($id, $description) = git_commit_info($2, undef, undef); 3504310cd06bSJoe Perches if (!defined($id)) { 3505310cd06bSJoe Perches WARN("UNKNOWN_COMMIT_ID", 3506310cd06bSJoe Perches "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 35071db81a68SDwaipayan Ray } 35081db81a68SDwaipayan Ray } 3509310cd06bSJoe Perches 3510310cd06bSJoe Perches# check for repeated words separated by a single space 3511310cd06bSJoe Perches# avoid false positive from list command eg, '-rw-r--r-- 1 root root' 3512310cd06bSJoe Perches if (($rawline =~ /^\+/ || $in_commit_log) && 3513310cd06bSJoe Perches $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { 35141db81a68SDwaipayan Ray pos($rawline) = 1 if (!$in_commit_log); 3515310cd06bSJoe Perches while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { 3516310cd06bSJoe Perches 35171db81a68SDwaipayan Ray my $first = $1; 35181db81a68SDwaipayan Ray my $second = $2; 35191db81a68SDwaipayan Ray my $start_pos = $-[1]; 35201db81a68SDwaipayan Ray my $end_pos = $+[2]; 35211db81a68SDwaipayan Ray if ($first =~ /(?:struct|union|enum)/) { 35221db81a68SDwaipayan Ray pos($rawline) += length($first) + length($second) + 1; 35231db81a68SDwaipayan Ray next; 35241db81a68SDwaipayan Ray } 35251db81a68SDwaipayan Ray 35268d0325ccSAditya Srivastava next if (lc($first) ne lc($second)); 35278d0325ccSAditya Srivastava next if ($first eq 'long'); 35288d0325ccSAditya Srivastava 35298d0325ccSAditya Srivastava # check for character before and after the word matches 35308d0325ccSAditya Srivastava my $start_char = ''; 3531310cd06bSJoe Perches my $end_char = ''; 3532310cd06bSJoe Perches $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); 3533310cd06bSJoe Perches $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); 3534310cd06bSJoe Perches 3535310cd06bSJoe Perches next if ($start_char =~ /^\S$/); 3536310cd06bSJoe Perches next if (index(" \t.,;?!", $end_char) == -1); 3537310cd06bSJoe Perches 3538310cd06bSJoe Perches # avoid repeating hex occurrences like 'ff ff fe 09 ...' 3539310cd06bSJoe Perches if ($first =~ /\b[0-9a-f]{2,}\b/i) { 3540310cd06bSJoe Perches next if (!exists($allow_repeated_words{lc($first)})); 3541310cd06bSJoe Perches } 3542310cd06bSJoe Perches 3543310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3544310cd06bSJoe Perches "Possible repeated word: '$first'\n" . $herecurr) && 3545310cd06bSJoe Perches $fix) { 3546310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; 3547310cd06bSJoe Perches } 3548310cd06bSJoe Perches } 3549310cd06bSJoe Perches 3550310cd06bSJoe Perches # if it's a repeated word on consecutive lines in a comment block 3551310cd06bSJoe Perches if ($prevline =~ /$;+\s*$/ && 355230670854SAndy Whitcroft $prevrawline =~ /($word_pattern)\s*$/) { 355330670854SAndy Whitcroft my $last_word = $1; 355400df344fSAndy Whitcroft if ($rawline =~ /^\+\s*\*\s*$last_word /) { 35550a920b5bSAndy Whitcroft if (WARN("REPEATED_WORD", 35569c0ca6f9SAndy Whitcroft "Possible repeated word: '$last_word'\n" . $hereprev) && 3557c2fdda0dSAndy Whitcroft $fix) { 3558d5e616fcSJoe Perches $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; 3559d5e616fcSJoe Perches } 3560d5e616fcSJoe Perches } 3561194f66fcSJoe Perches } 3562d5e616fcSJoe Perches } 3563c2fdda0dSAndy Whitcroft 3564c2fdda0dSAndy Whitcroft# ignore non-hunk lines and lines being removed 35653705ce5bSJoe Perches next if (!$hunk_line || $line =~ /^-/); 35663705ce5bSJoe Perches 35673705ce5bSJoe Perches#trailing whitespace 3568194f66fcSJoe Perches if ($line =~ /^\+.*\015/) { 35693705ce5bSJoe Perches my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 35703705ce5bSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 3571d2c0a235SAndy Whitcroft "DOS line endings\n" . $herevet) && 35720a920b5bSAndy Whitcroft $fix) { 35735368df20SAndy Whitcroft $fixed[$fixlinenr] =~ s/[\s\015]+$//; 35744783f894SJosh Triplett } 3575109d8cb2SAlexander Duyck } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 35761bde561eSMatthew Wilcox my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 35773e2232f2SJoe Perches if (ERROR("TRAILING_WHITESPACE", 35783e2232f2SJoe Perches "trailing whitespace\n" . $herevet) && 35794783f894SJosh Triplett $fix) { 35800675a8fbSJean Delvare $fixed[$fixlinenr] =~ s/\s+$//; 35810675a8fbSJean Delvare } 35820675a8fbSJean Delvare 35834783f894SJosh Triplett $rpt_cleaners = 1; 35844783f894SJosh Triplett } 35854783f894SJosh Triplett 35863354957aSAndi Kleen# Check for FSF mailing addresses. 35879fe287d7SAndy Whitcroft if ($rawline =~ /\bwrite to the Free/i || 35889fe287d7SAndy Whitcroft $rawline =~ /\b675\s+Mass\s+Ave/i || 35893354957aSAndi Kleen $rawline =~ /\b59\s+Temple\s+Pl/i || 3590678ae162SUlf Magnusson $rawline =~ /\b51\s+Franklin\s+St/i) { 3591678ae162SUlf Magnusson my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3592678ae162SUlf Magnusson my $msg_level = \&ERROR; 3593678ae162SUlf Magnusson $msg_level = \&CHK if ($file); 3594b8709bceSJoe Perches &{$msg_level}("FSF_MAILING_ADDRESS", 3595b8709bceSJoe Perches "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) 3596b8709bceSJoe Perches } 3597b8709bceSJoe Perches 3598b8709bceSJoe Perches# check for Kconfig help text having a real description 3599b8709bceSJoe Perches# Only applies when adding the entry originally, after that we do not have 36009fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 36019fe287d7SAndy Whitcroft if ($realfile =~ /Kconfig/ && 3602b8709bceSJoe Perches # 'choice' is usually the last thing on the line (though 3603a1385803SAndy Whitcroft # Kconfig supports named choices), so use a word boundary 3604b8709bceSJoe Perches # (\b) rather than a whitespace character (\s) 3605b8709bceSJoe Perches $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 3606b8709bceSJoe Perches my $ln = $linenr; 3607b8709bceSJoe Perches my $needs_help = 0; 3608b8709bceSJoe Perches my $has_help = 0; 3609b8709bceSJoe Perches my $help_length = 0; 3610b8709bceSJoe Perches while (defined $lines[$ln]) { 3611a1385803SAndy Whitcroft my $f = $lines[$ln++]; 3612a1385803SAndy Whitcroft 3613b8709bceSJoe Perches next if ($f =~ /^-/); 3614b8709bceSJoe Perches last if ($f !~ /^[\+ ]/); # !patch context 3615b8709bceSJoe Perches 3616b8709bceSJoe Perches if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 3617678ae162SUlf Magnusson $needs_help = 1; 3618b8709bceSJoe Perches next; 3619678ae162SUlf Magnusson } 3620678ae162SUlf Magnusson if ($f =~ /^\+\s*help\s*$/) { 3621678ae162SUlf Magnusson $has_help = 1; 3622678ae162SUlf Magnusson next; 3623b8709bceSJoe Perches } 3624678ae162SUlf Magnusson 36259fe287d7SAndy Whitcroft $f =~ s/^.//; # strip patch context [+ ] 36269fe287d7SAndy Whitcroft $f =~ s/#.*//; # strip # directives 3627b8709bceSJoe Perches $f =~ s/^\s+//; # strip leading blanks 36283354957aSAndi Kleen next if ($f =~ /^$/); # skip blank lines 3629b8709bceSJoe Perches 3630b8709bceSJoe Perches # At the end of this Kconfig block: 3631b8709bceSJoe Perches # This only checks context lines in the patch 3632000d1cc1SJoe Perches # and so hopefully shouldn't trigger false 3633b8709bceSJoe Perches # positives, even though some of these are 363456193274SVadim Bendebury # common words in help texts 36353354957aSAndi Kleen if ($f =~ /^(?:config|menuconfig|choice|endchoice| 36363354957aSAndi Kleen if|endif|menu|endmenu|source)\b/x) { 36377ccf41a8SJoe Perches last; 36387ccf41a8SJoe Perches } 36397ccf41a8SJoe Perches $help_length++ if ($has_help); 36407ccf41a8SJoe Perches } 3641628f91a2SJoe Perches if ($needs_help && 3642628f91a2SJoe Perches $help_length < $min_conf_desc_length) { 3643628f91a2SJoe Perches my $stat_real = get_stat_real($linenr, $ln - 1); 3644628f91a2SJoe Perches WARN("CONFIG_DESCRIPTION", 3645628f91a2SJoe Perches "please write a help paragraph that fully describes the config symbol\n" . "$here\n$stat_real\n"); 3646628f91a2SJoe Perches } 3647628f91a2SJoe Perches } 36487ccf41a8SJoe Perches 36497ccf41a8SJoe Perches# check MAINTAINERS entries 36507ccf41a8SJoe Perches if ($realfile =~ /^MAINTAINERS$/) { 36517ccf41a8SJoe Perches# check MAINTAINERS entries for the right form 36527ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 36537ccf41a8SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 36547ccf41a8SJoe Perches if (WARN("MAINTAINERS_STYLE", 36557ccf41a8SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 36567ccf41a8SJoe Perches $fix) { 36577ccf41a8SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 36587ccf41a8SJoe Perches } 36597ccf41a8SJoe Perches } 36607ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too 36617ccf41a8SJoe Perches my $preferred_order = 'MRLSWQBCPTFXNK'; 36627ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 36637ccf41a8SJoe Perches $prevrawline =~ /^[\+ ][A-Z]:/) { 36647ccf41a8SJoe Perches $rawline =~ /^\+([A-Z]):\s*(.*)/; 36657ccf41a8SJoe Perches my $cur = $1; 36667ccf41a8SJoe Perches my $curval = $2; 36677ccf41a8SJoe Perches $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; 36687ccf41a8SJoe Perches my $prev = $1; 36697ccf41a8SJoe Perches my $prevval = $2; 36707ccf41a8SJoe Perches my $curindex = index($preferred_order, $cur); 36717ccf41a8SJoe Perches my $previndex = index($preferred_order, $prev); 36727ccf41a8SJoe Perches if ($curindex < 0) { 36737ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 36747ccf41a8SJoe Perches "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); 36757ccf41a8SJoe Perches } else { 3676628f91a2SJoe Perches if ($previndex >= 0 && $curindex < $previndex) { 3677c68e5878SArnaud Lacombe WARN("MAINTAINERS_STYLE", 3678c68e5878SArnaud Lacombe "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); 3679c68e5878SArnaud Lacombe } elsif ((($prev eq 'F' && $cur eq 'F') || 3680c68e5878SArnaud Lacombe ($prev eq 'X' && $cur eq 'X')) && 3681c68e5878SArnaud Lacombe ($prevval cmp $curval) > 0) { 3682c68e5878SArnaud Lacombe WARN("MAINTAINERS_STYLE", 3683c68e5878SArnaud Lacombe "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); 3684c68e5878SArnaud Lacombe } 3685c68e5878SArnaud Lacombe } 3686c68e5878SArnaud Lacombe } 3687c68e5878SArnaud Lacombe } 3688c68e5878SArnaud Lacombe 3689c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3690c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3691bff5da43SRob Herring my $flag = $1; 36927dd05b38SFlorian Vaussard my $replacement = { 36937dd05b38SFlorian Vaussard 'EXTRA_AFLAGS' => 'asflags-y', 36947dd05b38SFlorian Vaussard 'EXTRA_CFLAGS' => 'ccflags-y', 36957dd05b38SFlorian Vaussard 'EXTRA_CPPFLAGS' => 'cppflags-y', 3696bff5da43SRob Herring 'EXTRA_LDFLAGS' => 'ldflags-y', 3697bff5da43SRob Herring }; 3698cc93319bSFlorian Vaussard 3699852d095dSRob Herring WARN("DEPRECATED_VARIABLE", 3700cc93319bSFlorian Vaussard "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3701bff5da43SRob Herring } 3702bff5da43SRob Herring 3703185d566bSRob Herring# check for DT compatible documentation 3704185d566bSRob Herring if (defined $root && 3705185d566bSRob Herring (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 3706185d566bSRob Herring ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 3707bff5da43SRob Herring 3708bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3709bff5da43SRob Herring 3710bff5da43SRob Herring my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3711bff5da43SRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 37124fbf32a6SFlorian Vaussard 37134fbf32a6SFlorian Vaussard foreach my $compat (@compats) { 3714852d095dSRob Herring my $compat2 = $compat; 3715bff5da43SRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3716bff5da43SRob Herring my $compat3 = $compat; 3717cc93319bSFlorian Vaussard $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3718bff5da43SRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3719bff5da43SRob Herring if ( $? >> 8 ) { 3720bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3721bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 37229f3a8992SRob Herring } 37239f3a8992SRob Herring 37249f3a8992SRob Herring next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 37259f3a8992SRob Herring my $vendor = $1; 37269f3a8992SRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 37279f3a8992SRob Herring if ( $? >> 8 ) { 37289f3a8992SRob Herring WARN("UNDOCUMENTED_DT_STRING", 37299f3a8992SRob Herring "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3730d1d84b5fSMiguel Ojeda } 37319f3a8992SRob Herring } 3732c8df0ab6SLubomir Rintel } 37339f3a8992SRob Herring 37349f3a8992SRob Herring# check for using SPDX license tag at beginning of files 37359f3a8992SRob Herring if ($realline == $checklicenseline) { 37369f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 37379f3a8992SRob Herring $checklicenseline = 2; 3738fdf13693SJoe Perches } elsif ($rawline =~ /^\+/) { 3739fdf13693SJoe Perches my $comment = ""; 3740fdf13693SJoe Perches if ($realfile =~ /\.(h|s|S)$/) { 3741ffbce897SJoe Perches $comment = '/*'; 3742fdf13693SJoe Perches } elsif ($realfile =~ /\.(c|rs|dts|dtsi)$/) { 3743fdf13693SJoe Perches $comment = '//'; 3744fdf13693SJoe Perches } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 3745fdf13693SJoe Perches $comment = '#'; 37469f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 3747ffbce897SJoe Perches $comment = '..'; 37489f3a8992SRob Herring } 37499f3a8992SRob Herring 37503b6e8ac9SJoe Perches# check SPDX comment style for .[chsS] files 37513b6e8ac9SJoe Perches if ($realfile =~ /\.[chsS]$/ && 37523b6e8ac9SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 37533b6e8ac9SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 37543b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 37553b6e8ac9SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 375650c92900SLubomir Rintel } 375750c92900SLubomir Rintel 375850c92900SLubomir Rintel if ($comment !~ /^$/ && 375950c92900SLubomir Rintel $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 376050c92900SLubomir Rintel WARN("SPDX_LICENSE_TAG", 376150c92900SLubomir Rintel "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 376250c92900SLubomir Rintel } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 376350c92900SLubomir Rintel my $spdx_license = $1; 376450c92900SLubomir Rintel if (!is_SPDX_License_valid($spdx_license)) { 376550c92900SLubomir Rintel WARN("SPDX_LICENSE_TAG", 376650c92900SLubomir Rintel "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 37679f3a8992SRob Herring } 37689f3a8992SRob Herring if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 3769a04bb4c2SDmitry Rokosov $spdx_license !~ /GPL-2\.0(?:-only)? OR BSD-2-Clause/) { 37709f3a8992SRob Herring my $msg_level = \&WARN; 37719f3a8992SRob Herring $msg_level = \&CHK if ($file); 37725368df20SAndy Whitcroft if (&{$msg_level}("SPDX_LICENSE_TAG", 3773d6430f71SJoe Perches 37745368df20SAndy Whitcroft "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 3775a8da38a9SJoe Perches $fix) { 3776a8da38a9SJoe Perches $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 3777a8da38a9SJoe Perches } 3778a8da38a9SJoe Perches } 3779a04bb4c2SDmitry Rokosov if ($realfile =~ m@^include/dt-bindings/@ && 3780a04bb4c2SDmitry Rokosov $spdx_license !~ /GPL-2\.0(?:-only)? OR \S+/) { 3781a04bb4c2SDmitry Rokosov WARN("SPDX_LICENSE_TAG", 3782a04bb4c2SDmitry Rokosov "DT binding headers should be licensed (GPL-2.0-only OR .*)\n" . $herecurr); 3783a04bb4c2SDmitry Rokosov } 378447e0c88bSJoe Perches } 378547e0c88bSJoe Perches } 378647e0c88bSJoe Perches } 378747e0c88bSJoe Perches 3788a0154cdbSJoe Perches# check for embedded filenames 378936217357SJoe Perches if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) { 3790a0154cdbSJoe Perches WARN("EMBEDDED_FILENAME", 3791a0154cdbSJoe Perches "It's generally not useful to have the filename in the file\n" . $herecurr); 3792a0154cdbSJoe Perches } 3793a0154cdbSJoe Perches 37945e79d96eSJoe Perches# check we are in a valid source file if not then ignore this hunk 3795d1d84b5fSMiguel Ojeda next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/); 37960a920b5bSAndy Whitcroft 3797a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3798a8da38a9SJoe Perches if ($realline != $checklicenseline && 3799a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3800a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3801a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3802a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3803a8da38a9SJoe Perches } 3804a8da38a9SJoe Perches 3805c45dcabdSAndy Whitcroft# line length limit (with some exclusions) 380647e0c88bSJoe Perches# 380747e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 380847e0c88bSJoe Perches# logging functions like pr_info that end in a string 380947e0c88bSJoe Perches# lines with a single string 381047e0c88bSJoe Perches# #defines that are a single string 381147e0c88bSJoe Perches# lines with an RFC3986 like URL 381247e0c88bSJoe Perches# 381347e0c88bSJoe Perches# There are 3 different line length message types: 381447e0c88bSJoe Perches# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 381547e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 381647e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 381747e0c88bSJoe Perches# 381847e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 381947e0c88bSJoe Perches# 382047e0c88bSJoe Perches 382147e0c88bSJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 382247e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 382347e0c88bSJoe Perches 382447e0c88bSJoe Perches # Check the allowed long line types first 382547e0c88bSJoe Perches 382647e0c88bSJoe Perches # logging functions that end in a string that starts 382747e0c88bSJoe Perches # before $max_line_length 382847e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 382947e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 383047e0c88bSJoe Perches $msg_type = ""; 383147e0c88bSJoe Perches 383247e0c88bSJoe Perches # lines with only strings (w/ possible termination) 383347e0c88bSJoe Perches # #defines with only strings 383447e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 383547e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 383647e0c88bSJoe Perches $msg_type = ""; 383747e0c88bSJoe Perches 3838cc147506SJoe Perches # More special cases 3839cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3840cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3841d560a5f8SJoe Perches $msg_type = ""; 3842d560a5f8SJoe Perches 38432e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 38442e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 38452e4bbbc5SAndreas Brauchli $msg_type = ""; 38462e4bbbc5SAndreas Brauchli 384747e0c88bSJoe Perches # Otherwise set the alternate message types 384847e0c88bSJoe Perches 384947e0c88bSJoe Perches # a comment starts before $max_line_length 385047e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 385147e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 385247e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 385347e0c88bSJoe Perches 385447e0c88bSJoe Perches # a quoted string starts before $max_line_length 385547e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 385647e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 385747e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 385847e0c88bSJoe Perches } 385947e0c88bSJoe Perches 386047e0c88bSJoe Perches if ($msg_type ne "" && 386147e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 3862bdc48fa1SJoe Perches my $msg_level = \&WARN; 3863bdc48fa1SJoe Perches $msg_level = \&CHK if ($file); 3864bdc48fa1SJoe Perches &{$msg_level}($msg_type, 3865bdc48fa1SJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 38660a920b5bSAndy Whitcroft } 386747e0c88bSJoe Perches } 38680a920b5bSAndy Whitcroft 38698905a67cSAndy Whitcroft# check for adding lines without a newline. 38708905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 387147ca69b8STom Rix if (WARN("MISSING_EOF_NEWLINE", 387247ca69b8STom Rix "adding a line without newline at end of file\n" . $herecurr) && 387347ca69b8STom Rix $fix) { 387447ca69b8STom Rix fix_delete_line($fixlinenr+1, "No newline at end of file"); 387547ca69b8STom Rix } 38768905a67cSAndy Whitcroft } 38778905a67cSAndy Whitcroft 3878de93245cSAditya Srivastava# check for .L prefix local symbols in .S files 3879de93245cSAditya Srivastava if ($realfile =~ /\.S$/ && 3880de93245cSAditya Srivastava $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { 3881de93245cSAditya Srivastava WARN("AVOID_L_PREFIX", 3882f4bf1cd4SJonathan Corbet "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/core-api/asm-annotations.rst\n" . $herecurr); 3883de93245cSAditya Srivastava } 3884de93245cSAditya Srivastava 3885b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3886de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 38870a920b5bSAndy Whitcroft 38880a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 3889713a09deSAntonio Borneo# more than $tabsize must use tabs. 3890c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3891c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3892c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3893d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 38943705ce5bSJoe Perches if (ERROR("CODE_INDENT", 38953705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 38963705ce5bSJoe Perches $fix) { 3897194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 38983705ce5bSJoe Perches } 38990a920b5bSAndy Whitcroft } 39000a920b5bSAndy Whitcroft 390108e44365SAlberto Panizzo# check for space before tabs. 390208e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 390308e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 39043705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 39053705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 39063705ce5bSJoe Perches $fix) { 3907194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3908713a09deSAntonio Borneo s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 3909194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3910c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 39113705ce5bSJoe Perches } 391208e44365SAlberto Panizzo } 391308e44365SAlberto Panizzo 39146a487211SJoe Perches# check for assignments on the start of a line 39156a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 3916da7355abSAditya Srivastava my $operator = $1; 3917da7355abSAditya Srivastava if (CHK("ASSIGNMENT_CONTINUATIONS", 3918da7355abSAditya Srivastava "Assignment operator '$1' should be on the previous line\n" . $hereprev) && 3919da7355abSAditya Srivastava $fix && $prevrawline =~ /^\+/) { 3920da7355abSAditya Srivastava # add assignment operator to the previous line, remove from current line 3921da7355abSAditya Srivastava $fixed[$fixlinenr - 1] .= " $operator"; 3922da7355abSAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 3923da7355abSAditya Srivastava } 39246a487211SJoe Perches } 39256a487211SJoe Perches 3926d1fe9c09SJoe Perches# check for && or || at the start of a line 3927d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 39288e08f076SAditya Srivastava my $operator = $1; 39298e08f076SAditya Srivastava if (CHK("LOGICAL_CONTINUATIONS", 39308e08f076SAditya Srivastava "Logical continuations should be on the previous line\n" . $hereprev) && 39318e08f076SAditya Srivastava $fix && $prevrawline =~ /^\+/) { 39328e08f076SAditya Srivastava # insert logical operator at last non-comment, non-whitepsace char on previous line 39338e08f076SAditya Srivastava $prevline =~ /[\s$;]*$/; 39348e08f076SAditya Srivastava my $line_end = substr($prevrawline, $-[0]); 39358e08f076SAditya Srivastava $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; 39368e08f076SAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 39378e08f076SAditya Srivastava } 3938d1fe9c09SJoe Perches } 3939d1fe9c09SJoe Perches 3940a91e8994SJoe Perches# check indentation starts on a tab stop 39415b57980dSJoe Perches if ($perl_version_ok && 3942bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3943a91e8994SJoe Perches my $indent = length($1); 3944713a09deSAntonio Borneo if ($indent % $tabsize) { 3945a91e8994SJoe Perches if (WARN("TABSTOP", 3946a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3947a91e8994SJoe Perches $fix) { 3948713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 3949a91e8994SJoe Perches } 3950a91e8994SJoe Perches } 3951a91e8994SJoe Perches } 3952a91e8994SJoe Perches 3953d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 39545b57980dSJoe Perches if ($perl_version_ok && 3955fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3956d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3957d1fe9c09SJoe Perches my $oldindent = $1; 3958d1fe9c09SJoe Perches my $rest = $2; 3959d1fe9c09SJoe Perches 3960d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3961d1fe9c09SJoe Perches if ($pos >= 0) { 3962b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3963b34a26f3SJoe Perches my $newindent = $2; 3964d1fe9c09SJoe Perches 3965d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3966713a09deSAntonio Borneo "\t" x ($pos / $tabsize) . 3967713a09deSAntonio Borneo " " x ($pos % $tabsize); 3968d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3969d1fe9c09SJoe Perches 3970d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3971d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 39723705ce5bSJoe Perches 39733705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 39743705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 39753705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3976194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39773705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 39783705ce5bSJoe Perches } 3979d1fe9c09SJoe Perches } 3980d1fe9c09SJoe Perches } 3981d1fe9c09SJoe Perches } 3982d1fe9c09SJoe Perches 39836ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 39846ab3a970SJoe Perches# avoid checking a few false positives: 39856ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 39866ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 39876ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 39886ab3a970SJoe Perches# multiline macros that define functions 39896ab3a970SJoe Perches# known attributes or the __attribute__ keyword 39906ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 39916ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 39923705ce5bSJoe Perches if (CHK("SPACING", 3993f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 39943705ce5bSJoe Perches $fix) { 3995194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3996f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 39973705ce5bSJoe Perches } 3998aad4f614SJoe Perches } 3999aad4f614SJoe Perches 400086406b1cSJoe Perches# Block comment styles 400186406b1cSJoe Perches# Networking with an initial /* 400205880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 4003fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 400485ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 4005c70735c2SŁukasz Stelmach $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier 400605880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 400705880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 400805880600SJoe Perches } 400905880600SJoe Perches 401086406b1cSJoe Perches# Block comments use * on subsequent lines 401186406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 401286406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 4013a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 401461135e96SJoe Perches $rawline =~ /^\+/ && #line is new 4015a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 401686406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 401786406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 4018a605e32eSJoe Perches } 4019a605e32eSJoe Perches 402086406b1cSJoe Perches# Block comments use */ on trailing lines 402186406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 4022c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 4023c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 4024c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 402586406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 402686406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 402705880600SJoe Perches } 402805880600SJoe Perches 402908eb9b80SJoe Perches# Block comment * alignment 403008eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 4031af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 4032af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 4033af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 403408eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 4035af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 4036af207524SJoe Perches my $oldindent; 403708eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 4038af207524SJoe Perches if (defined($1)) { 4039af207524SJoe Perches $oldindent = expand_tabs($1); 4040af207524SJoe Perches } else { 4041af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 4042af207524SJoe Perches $oldindent = expand_tabs($1); 4043af207524SJoe Perches } 404408eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 404508eb9b80SJoe Perches my $newindent = $1; 404608eb9b80SJoe Perches $newindent = expand_tabs($newindent); 4047af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 404808eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 404908eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 405008eb9b80SJoe Perches } 405108eb9b80SJoe Perches } 405208eb9b80SJoe Perches 40537f619191SJoe Perches# check for missing blank lines after struct/union declarations 40547f619191SJoe Perches# with exceptions for various attributes and macros 40557f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 40567f619191SJoe Perches $line =~ /^\+/ && 40577f619191SJoe Perches !($line =~ /^\+\s*$/ || 405805dc40e6SJoe Perches $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param)/ || 40597f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 40607f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 40617f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 40627f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 40637f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 40640bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 40657f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 4066d752fcc8SJoe Perches if (CHK("LINE_SPACING", 4067d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 4068d752fcc8SJoe Perches $fix) { 4069f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 4070d752fcc8SJoe Perches } 40717f619191SJoe Perches } 40727f619191SJoe Perches 4073365dd4eaSJoe Perches# check for multiple consecutive blank lines 4074365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 4075365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 4076365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 4077d752fcc8SJoe Perches if (CHK("LINE_SPACING", 4078d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 4079d752fcc8SJoe Perches $fix) { 4080f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 4081d752fcc8SJoe Perches } 4082d752fcc8SJoe Perches 4083365dd4eaSJoe Perches $last_blank_line = $linenr; 4084365dd4eaSJoe Perches } 4085365dd4eaSJoe Perches 40863b617e3bSJoe Perches# check for missing blank lines after declarations 4087b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line) 4088b5e8736aSJoe Perches if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) { 4089b5e8736aSJoe Perches # use temporaries 4090b5e8736aSJoe Perches my $sl = $sline; 4091b5e8736aSJoe Perches my $pl = $prevline; 4092b5e8736aSJoe Perches # remove $Attribute/$Sparse uses to simplify comparisons 4093b5e8736aSJoe Perches $sl =~ s/\b(?:$Attribute|$Sparse)\b//g; 4094b5e8736aSJoe Perches $pl =~ s/\b(?:$Attribute|$Sparse)\b//g; 4095b5e8736aSJoe Perches if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 40965a4e1fd3SJoe Perches # function pointer declarations 4097b5e8736aSJoe Perches $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 40983f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 4099b5e8736aSJoe Perches $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 41003f7bac03SJoe Perches # known declaration macros 4101b5e8736aSJoe Perches $pl =~ /^\+\s+$declaration_macros/) && 41023f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 4103b5e8736aSJoe Perches !($pl =~ /^\+\s+$c90_Keywords\b/ || 41043f7bac03SJoe Perches # other possible extensions of declaration lines 4105b5e8736aSJoe Perches $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 41063f7bac03SJoe Perches # not starting a section or a macro "\" extended line 4107b5e8736aSJoe Perches $pl =~ /(?:\{\s*|\\)$/) && 41083f7bac03SJoe Perches # looks like a declaration 4109b5e8736aSJoe Perches !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 41105a4e1fd3SJoe Perches # function pointer declarations 4111b5e8736aSJoe Perches $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 41123f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 4113b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 41143f7bac03SJoe Perches # known declaration macros 4115b5e8736aSJoe Perches $sl =~ /^\+\s+$declaration_macros/ || 41163f7bac03SJoe Perches # start of struct or union or enum 4117b5e8736aSJoe Perches $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 41183f7bac03SJoe Perches # start or end of block or continuation of declaration 4119b5e8736aSJoe Perches $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 41203f7bac03SJoe Perches # bitfield continuation 4121b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 41223f7bac03SJoe Perches # other possible extensions of declaration lines 4123b5e8736aSJoe Perches $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) { 4124d752fcc8SJoe Perches if (WARN("LINE_SPACING", 4125d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 4126d752fcc8SJoe Perches $fix) { 4127f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 4128d752fcc8SJoe Perches } 41293b617e3bSJoe Perches } 4130b5e8736aSJoe Perches } 41313b617e3bSJoe Perches 41325f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 41336b4c5bebSAndy Whitcroft# Exceptions: 41346b4c5bebSAndy Whitcroft# 1) within comments 41356b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 41366b4c5bebSAndy Whitcroft# 3) hanging labels 41373705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 41385f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 41393705ce5bSJoe Perches if (WARN("LEADING_SPACE", 41403705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 41413705ce5bSJoe Perches $fix) { 4142194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 41433705ce5bSJoe Perches } 41445f7ddae6SRaffaele Recalcati } 41455f7ddae6SRaffaele Recalcati 4146b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 4147b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 4148b9ea10d6SAndy Whitcroft 41495751a24eSJoe Perches# check for unusual line ending [ or ( 41505751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 41515751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 41525751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 41535751a24eSJoe Perches } 41545751a24eSJoe Perches 41554dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 41564dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 41574dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 41584dbed76fSJoe Perches $context_function = $1; 41594dbed76fSJoe Perches } 41604dbed76fSJoe Perches 41614dbed76fSJoe Perches# check if this appears to be the end of function declaration 41624dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 41634dbed76fSJoe Perches undef $context_function; 41644dbed76fSJoe Perches } 41654dbed76fSJoe Perches 4166032a4c0fSJoe Perches# check indentation of any line with a bare else 4167840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 4168032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 4169032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 4170032a4c0fSJoe Perches my $tabs = length($1) + 1; 4171840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 4172840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 4173840080a0SJoe Perches defined $lines[$linenr] && 4174840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 4175032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 4176032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 4177032a4c0fSJoe Perches } 4178032a4c0fSJoe Perches } 4179032a4c0fSJoe Perches 4180c00df19aSJoe Perches# check indentation of a line with a break; 4181dc58bc55SJoe Perches# if the previous line is a goto, return or break 4182dc58bc55SJoe Perches# and is indented the same # of tabs 4183c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 4184c00df19aSJoe Perches my $tabs = $1; 4185dc58bc55SJoe Perches if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { 4186dc58bc55SJoe Perches if (WARN("UNNECESSARY_BREAK", 4187dc58bc55SJoe Perches "break is not useful after a $1\n" . $hereprev) && 4188dc58bc55SJoe Perches $fix) { 4189dc58bc55SJoe Perches fix_delete_line($fixlinenr, $rawline); 4190dc58bc55SJoe Perches } 4191c00df19aSJoe Perches } 4192c00df19aSJoe Perches } 4193c00df19aSJoe Perches 4194c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 4195cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 4196000d1cc1SJoe Perches WARN("CVS_KEYWORD", 4197000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 4198c2fdda0dSAndy Whitcroft } 419922f2a2efSAndy Whitcroft 420056e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 420156e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 420256e77d70SJoe Perches WARN("HOTPLUG_SECTION", 420356e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 420456e77d70SJoe Perches } 420556e77d70SJoe Perches 42069c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 42072b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 42082b474a1aSAndy Whitcroft $realline_next); 42093e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 4210ca819864SJoe Perches if ($linenr > $suppress_statement && 42111b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 4212170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 4213f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4214171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 4215171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 4216171ae1a4SAndy Whitcroft 42173e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 42183e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 42193e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 42203e469cdcSAndy Whitcroft # until we hit end of it. 42213e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 42223e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 42233e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 42243e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 42253e469cdcSAndy Whitcroft } 4226f74bd194SAndy Whitcroft 42272b474a1aSAndy Whitcroft # Find the real next line. 42282b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 42292b474a1aSAndy Whitcroft if (defined $realline_next && 42302b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 42312b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 42322b474a1aSAndy Whitcroft $realline_next++; 42332b474a1aSAndy Whitcroft } 42342b474a1aSAndy Whitcroft 4235171ae1a4SAndy Whitcroft my $s = $stat; 4236171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 4237cf655043SAndy Whitcroft 4238c2fdda0dSAndy Whitcroft # Ignore goto labels. 4239171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 4240c2fdda0dSAndy Whitcroft 4241c2fdda0dSAndy Whitcroft # Ignore functions being called 4242171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 4243c2fdda0dSAndy Whitcroft 4244463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 4245463f2864SAndy Whitcroft 4246c45dcabdSAndy Whitcroft # declarations always start with types 4247d2506586SAndy 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) { 4248c45dcabdSAndy Whitcroft my $type = $1; 4249c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 4250c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 4251c45dcabdSAndy Whitcroft 42526c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 4253a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 4254c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 4255c2fdda0dSAndy Whitcroft } 42568905a67cSAndy Whitcroft 42576c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 425865863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 4259c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 42609c0ca6f9SAndy Whitcroft } 42618905a67cSAndy Whitcroft 42628905a67cSAndy Whitcroft # Check for any sort of function declaration. 42638905a67cSAndy Whitcroft # int foo(something bar, other baz); 42648905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 4265171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 42668905a67cSAndy Whitcroft my ($name_len) = length($1); 42678905a67cSAndy Whitcroft 4268cf655043SAndy Whitcroft my $ctx = $s; 4269773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 42708905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 4271cf655043SAndy Whitcroft 42728905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 4273c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 42748905a67cSAndy Whitcroft 4275c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 42768905a67cSAndy Whitcroft } 42778905a67cSAndy Whitcroft } 42788905a67cSAndy Whitcroft } 42798905a67cSAndy Whitcroft 42809c0ca6f9SAndy Whitcroft } 42819c0ca6f9SAndy Whitcroft 428200df344fSAndy Whitcroft# 428300df344fSAndy Whitcroft# Checks which may be anchored in the context. 428400df344fSAndy Whitcroft# 428500df344fSAndy Whitcroft 428600df344fSAndy Whitcroft# Check for switch () and associated case and default 428700df344fSAndy Whitcroft# statements should be at the same indent. 428800df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 428900df344fSAndy Whitcroft my $err = ''; 429000df344fSAndy Whitcroft my $sep = ''; 429100df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 429200df344fSAndy Whitcroft shift(@ctx); 429300df344fSAndy Whitcroft for my $ctx (@ctx) { 429400df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 429500df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 429600df344fSAndy Whitcroft $indent != $cindent) { 429700df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 429800df344fSAndy Whitcroft $sep = ''; 429900df344fSAndy Whitcroft } else { 430000df344fSAndy Whitcroft $sep = "[...]\n"; 430100df344fSAndy Whitcroft } 430200df344fSAndy Whitcroft } 430300df344fSAndy Whitcroft if ($err ne '') { 4304000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 4305000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 4306de7d4f0eSAndy Whitcroft } 4307de7d4f0eSAndy Whitcroft } 4308de7d4f0eSAndy Whitcroft 4309de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 4310de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 43110fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 4312773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 4313773647a0SAndy Whitcroft 43149c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 43158eef05ddSJoe Perches 43168eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 43178eef05ddSJoe Perches WARN("DEEP_INDENTATION", 43188eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 43198eef05ddSJoe Perches } 43208eef05ddSJoe Perches 4321de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 4322de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 4323de7d4f0eSAndy Whitcroft 4324548596d5SAndy Whitcroft my $ctx_ln = $linenr; 4325548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 4326de7d4f0eSAndy Whitcroft 4327548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 4328548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 4329548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 4330548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 4331548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 4332773647a0SAndy Whitcroft $ctx_ln++; 4333773647a0SAndy Whitcroft } 4334548596d5SAndy Whitcroft 433553210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 433653210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 4337773647a0SAndy Whitcroft 4338773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 4339000d1cc1SJoe Perches ERROR("OPEN_BRACE", 4340000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 434101464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 434200df344fSAndy Whitcroft } 4343773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 4344773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 4345773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 4346773647a0SAndy Whitcroft { 43479c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 43489c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 4349000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 4350000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 435101464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 43529c0ca6f9SAndy Whitcroft } 43539c0ca6f9SAndy Whitcroft } 435400df344fSAndy Whitcroft } 435500df344fSAndy Whitcroft 43564d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 4357f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 43583e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 43593e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 43603e469cdcSAndy Whitcroft if (!defined $stat); 43614d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 43624d001e4dSAndy Whitcroft 43634d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 43644d001e4dSAndy Whitcroft 43659f5af480SJoe Perches # remove inline comments 43669f5af480SJoe Perches $s =~ s/$;/ /g; 43679f5af480SJoe Perches $c =~ s/$;/ /g; 43684d001e4dSAndy Whitcroft 43694d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 43706f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 43716f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 43724d001e4dSAndy Whitcroft 43739f5af480SJoe Perches # Make sure we remove the line prefixes as we have 43749f5af480SJoe Perches # none on the first line, and are going to readd them 43759f5af480SJoe Perches # where necessary. 43769f5af480SJoe Perches $s =~ s/\n./\n/gs; 43779f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 43789f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 43799f5af480SJoe Perches } 43809f5af480SJoe Perches 43814d001e4dSAndy Whitcroft # We want to check the first line inside the block 43824d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 43834d001e4dSAndy Whitcroft # 1) any blank line termination 43844d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 43854d001e4dSAndy Whitcroft # 3) any do (...) { 43864d001e4dSAndy Whitcroft my $continuation = 0; 43874d001e4dSAndy Whitcroft my $check = 0; 43884d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 43894d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 43904d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 43914d001e4dSAndy Whitcroft $continuation = 1; 43924d001e4dSAndy Whitcroft } 43939bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 43944d001e4dSAndy Whitcroft $check = 1; 43954d001e4dSAndy Whitcroft $cond_lines++; 43964d001e4dSAndy Whitcroft } 43974d001e4dSAndy Whitcroft 43984d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 43994d001e4dSAndy Whitcroft # preprocessor statement. 44004d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 44014d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 44024d001e4dSAndy Whitcroft $check = 0; 44034d001e4dSAndy Whitcroft } 44044d001e4dSAndy Whitcroft 44059bd49efeSAndy Whitcroft my $cond_ptr = -1; 4406740504c6SAndy Whitcroft $continuation = 0; 44079bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 44089bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 44094d001e4dSAndy Whitcroft 4410f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 4411f16fa28fSAndy Whitcroft # is not linear. 4412f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 4413f16fa28fSAndy Whitcroft $check = 0; 4414f16fa28fSAndy Whitcroft } 4415f16fa28fSAndy Whitcroft 44169bd49efeSAndy Whitcroft # Ignore: 44179bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 44189bd49efeSAndy Whitcroft # 2) preprocessor lines, and 44199bd49efeSAndy Whitcroft # 3) labels. 4420740504c6SAndy Whitcroft if ($continuation || 4421740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 44229bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 44239bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 4424740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 442530dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 44269bd49efeSAndy Whitcroft $cond_lines++; 44279bd49efeSAndy Whitcroft } 44284d001e4dSAndy Whitcroft } 442930dad6ebSAndy Whitcroft } 44304d001e4dSAndy Whitcroft 44314d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 44324d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 44334d001e4dSAndy Whitcroft 44344d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 44354d001e4dSAndy Whitcroft # this is not this patch's fault. 44364d001e4dSAndy Whitcroft if (!defined($stat_real) || 44374d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 44384d001e4dSAndy Whitcroft $check = 0; 44394d001e4dSAndy Whitcroft } 44404d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 44414d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 44424d001e4dSAndy Whitcroft } 44434d001e4dSAndy Whitcroft 44449bd49efeSAndy 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"; 44454d001e4dSAndy Whitcroft 44469f5af480SJoe Perches if ($check && $s ne '' && 4447713a09deSAntonio Borneo (($sindent % $tabsize) != 0 || 44489f5af480SJoe Perches ($sindent < $indent) || 4449f6950a73SJoe Perches ($sindent == $indent && 4450f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 4451713a09deSAntonio Borneo ($sindent > $indent + $tabsize))) { 4452000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 4453000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 44544d001e4dSAndy Whitcroft } 44554d001e4dSAndy Whitcroft } 44564d001e4dSAndy Whitcroft 44576c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 44586c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 44591f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 44601f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 44616c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 4462c2fdda0dSAndy Whitcroft if ($dbg_values) { 4463c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 4464cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 4465cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 44661f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 4467c2fdda0dSAndy Whitcroft } 44686c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 44696c72ffaaSAndy Whitcroft 447000df344fSAndy Whitcroft#ignore lines not being added 44713705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 447200df344fSAndy Whitcroft 447399ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings 447499ca38c2SJoe Perches# e.g.: int foo = foo, *bar = NULL; 447599ca38c2SJoe Perches# struct foo bar = *(&(bar)); 447699ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { 447799ca38c2SJoe Perches my $var = $1; 447899ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { 447999ca38c2SJoe Perches WARN("SELF_ASSIGNMENT", 448099ca38c2SJoe Perches "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); 448199ca38c2SJoe Perches } 448299ca38c2SJoe Perches } 448399ca38c2SJoe Perches 448411ca40a0SJoe Perches# check for dereferences that span multiple lines 448511ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 448611ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 448711ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 448811ca40a0SJoe Perches my $ref = $1; 448911ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 449011ca40a0SJoe Perches $ref .= $1; 449111ca40a0SJoe Perches $ref =~ s/\s//g; 449211ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 449311ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 449411ca40a0SJoe Perches } 449511ca40a0SJoe Perches 4496a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 4497c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 4498a1ce18e4SJoe Perches my $type = $1; 4499a1ce18e4SJoe Perches my $var = $2; 4500207a8e84SJoe Perches $var = "" if (!defined $var); 4501207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 4502a1ce18e4SJoe Perches my $sign = $1; 4503a1ce18e4SJoe Perches my $pointer = $2; 4504a1ce18e4SJoe Perches 4505a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 4506a1ce18e4SJoe Perches 4507a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 4508a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 4509a1ce18e4SJoe Perches $fix) { 4510a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 4511207a8e84SJoe Perches my $comp_pointer = $pointer; 4512207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 4513207a8e84SJoe Perches $decl .= $comp_pointer; 4514207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 4515207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 4516a1ce18e4SJoe Perches } 4517a1ce18e4SJoe Perches } 4518a1ce18e4SJoe Perches } 4519a1ce18e4SJoe Perches 4520653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 45217429c690SAndy Whitcroft if ($dbg_type) { 45227429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 4523000d1cc1SJoe Perches ERROR("TEST_TYPE", 4524000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 45257429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 4526000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 4527000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 45287429c690SAndy Whitcroft } 4529653d4876SAndy Whitcroft next; 4530653d4876SAndy Whitcroft } 4531a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 4532a1ef277eSAndy Whitcroft if ($dbg_attr) { 45339360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 4534000d1cc1SJoe Perches ERROR("TEST_ATTR", 4535000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 45369360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 4537000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 4538000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 4539a1ef277eSAndy Whitcroft } 4540a1ef277eSAndy Whitcroft next; 4541a1ef277eSAndy Whitcroft } 4542653d4876SAndy Whitcroft 4543f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 454499423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 454599423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 4546d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 4547d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 4548f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 4549f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 4550f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 4551d752fcc8SJoe Perches my $fixedline = $prevrawline; 4552d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 4553f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4554d752fcc8SJoe Perches $fixedline = $line; 45558d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 4556f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4557d752fcc8SJoe Perches } 4558f0a594c1SAndy Whitcroft } 4559f0a594c1SAndy Whitcroft 456000df344fSAndy Whitcroft# 456100df344fSAndy Whitcroft# Checks which are anchored on the added line. 456200df344fSAndy Whitcroft# 456300df344fSAndy Whitcroft 4564653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 4565c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 4566653d4876SAndy Whitcroft my $path = $1; 4567653d4876SAndy Whitcroft if ($path =~ m{//}) { 4568000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 4569495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 4570495e9d84SJoe Perches } 4571495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 4572495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 4573495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 4574653d4876SAndy Whitcroft } 4575653d4876SAndy Whitcroft } 4576653d4876SAndy Whitcroft 457700df344fSAndy Whitcroft# no C99 // comments 457800df344fSAndy Whitcroft if ($line =~ m{//}) { 45793705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 45803705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 45813705ce5bSJoe Perches $fix) { 4582194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 45833705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 45843705ce5bSJoe Perches my $comment = trim($1); 4585194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 45863705ce5bSJoe Perches } 45873705ce5bSJoe Perches } 458800df344fSAndy Whitcroft } 458900df344fSAndy Whitcroft # Remove C99 comments. 45900a920b5bSAndy Whitcroft $line =~ s@//.*@@; 45916c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 45920a920b5bSAndy Whitcroft 45932b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 45942b474a1aSAndy Whitcroft# the whole statement. 45952b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 45962b474a1aSAndy Whitcroft if (defined $realline_next && 45972b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 45982b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 459936794822SChristoph Hellwig ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 46003cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 46013cbf62dfSAndy Whitcroft # a prefix: 46023cbf62dfSAndy Whitcroft # XXX(foo); 46033cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 4604653d4876SAndy Whitcroft my $name = $1; 460570a11659SJoe Perches $name =~ s/^\s*($Ident).*/$1/; 460687a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 46073cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 46083cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 46093cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 46103cbf62dfSAndy Whitcroft 46113cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 46122b474a1aSAndy Whitcroft \n.}\s*$| 461348012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 461448012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 461548012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 46162b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 46172b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 461848012058SAndy Whitcroft )/x) { 46192b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 46202b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 46212b474a1aSAndy Whitcroft } else { 46222b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 46230a920b5bSAndy Whitcroft } 46240a920b5bSAndy Whitcroft } 46252b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 46262b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 462736794822SChristoph Hellwig ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 46282b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 46292b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 46302b474a1aSAndy Whitcroft } 46312b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 46322b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 4633000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 4634000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 46352b474a1aSAndy Whitcroft } 46360a920b5bSAndy Whitcroft 46375150bda4SJoe Eloff# check for global initialisers. 46385b8f82e1SSong Liu if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ && 46395b8f82e1SSong Liu !exclude_global_initialisers($realfile)) { 4640d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 46416d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 4642d5e616fcSJoe Perches $fix) { 46436d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 4644d5e616fcSJoe Perches } 4645f0a594c1SAndy Whitcroft } 46460a920b5bSAndy Whitcroft# check for static initialisers. 46476d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 4648d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 46496d32f7a3SJoe Perches "do not initialise statics to $1\n" . 4650d5e616fcSJoe Perches $herecurr) && 4651d5e616fcSJoe Perches $fix) { 46526d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 4653d5e616fcSJoe Perches } 46540a920b5bSAndy Whitcroft } 46550a920b5bSAndy Whitcroft 46561813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 46571813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 46581813087dSJoe Perches my $tmp = trim($1); 46591813087dSJoe Perches WARN("MISORDERED_TYPE", 46601813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 46611813087dSJoe Perches } 46621813087dSJoe Perches 4663809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4664809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4665809e082eSJoe Perches my $type = trim($1); 4666809e082eSJoe Perches next if ($type !~ /\bint\b/); 4667809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 4668809e082eSJoe Perches my $new_type = $type; 4669809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 4670809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 4671809e082eSJoe Perches $new_type =~ s/^const\s+//; 4672809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 4673809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 4674809e082eSJoe Perches $new_type =~ s/\s+/ /g; 4675809e082eSJoe Perches $new_type = trim($new_type); 4676809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 4677809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4678809e082eSJoe Perches $fix) { 4679809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4680809e082eSJoe Perches } 4681809e082eSJoe Perches } 4682809e082eSJoe Perches 4683cb710ecaSJoe Perches# check for static const char * arrays. 4684cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4685000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4686000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 4687cb710ecaSJoe Perches $herecurr); 4688cb710ecaSJoe Perches } 4689cb710ecaSJoe Perches 469077b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 469177b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 469277b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 469377b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 469477b8c0a8SJoe Perches $fix) { 469577b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 469677b8c0a8SJoe Perches } 469777b8c0a8SJoe Perches } 469877b8c0a8SJoe Perches 4699cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 4700cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4701000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4702000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 4703cb710ecaSJoe Perches $herecurr); 4704cb710ecaSJoe Perches } 4705cb710ecaSJoe Perches 4706ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 4707ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 4708ab7e23f3SJoe Perches my $found = $1; 4709ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 4710ab7e23f3SJoe Perches WARN("CONST_CONST", 4711ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 4712ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4713ab7e23f3SJoe Perches WARN("CONST_CONST", 4714ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4715ab7e23f3SJoe Perches } 4716ab7e23f3SJoe Perches } 4717ab7e23f3SJoe Perches 471873169765SJoe Perches# check for const static or static <non ptr type> const declarations 471973169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const' 472073169765SJoe Perches if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || 472173169765SJoe Perches $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { 472273169765SJoe Perches if (WARN("STATIC_CONST", 472373169765SJoe Perches "Move const after static - use 'static const $1'\n" . $herecurr) && 472473169765SJoe Perches $fix) { 472573169765SJoe Perches $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; 472673169765SJoe Perches $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; 472773169765SJoe Perches } 472873169765SJoe Perches } 472973169765SJoe Perches 47309b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 47319b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 47329b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 47339b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 47349b0fa60dSJoe Perches $herecurr); 47359b0fa60dSJoe Perches } 47369b0fa60dSJoe Perches 4737b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 4738b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 4739b598b670SJoe Perches my $array = $1; 4740b598b670SJoe 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*\))@) { 4741b598b670SJoe Perches my $array_div = $1; 4742b598b670SJoe Perches if (WARN("ARRAY_SIZE", 4743b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 4744b598b670SJoe Perches $fix) { 4745b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4746b598b670SJoe Perches } 4747b598b670SJoe Perches } 4748b598b670SJoe Perches } 4749b598b670SJoe Perches 4750b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 475116b7f3c8SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4752b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4753b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4754b36190c5SJoe Perches $fix) { 4755194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4756b36190c5SJoe Perches } 4757b36190c5SJoe Perches } 4758b36190c5SJoe Perches 4759653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4760653d4876SAndy Whitcroft# make sense. 4761653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 47628054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4763c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 47648ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 476546d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4766000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4767000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 47680a920b5bSAndy Whitcroft } 47690a920b5bSAndy Whitcroft 47700a920b5bSAndy Whitcroft# * goes on variable not on type 477165863862SAndy Whitcroft # (char*[ const]) 4772bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4773bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 47743705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4775d8aaf121SAndy Whitcroft 477665863862SAndy Whitcroft # Should start with a space. 477765863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 477865863862SAndy Whitcroft # Should not end with a space. 477965863862SAndy Whitcroft $to =~ s/\s+$//; 478065863862SAndy Whitcroft # '*'s should not have spaces between. 4781f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 478265863862SAndy Whitcroft } 4783d8aaf121SAndy Whitcroft 47843705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 478565863862SAndy Whitcroft if ($from ne $to) { 47863705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 47873705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 47883705ce5bSJoe Perches $fix) { 47893705ce5bSJoe Perches my $sub_from = $ident; 47903705ce5bSJoe Perches my $sub_to = $ident; 47913705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4792194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47933705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 47943705ce5bSJoe Perches } 479565863862SAndy Whitcroft } 4796bfcb2cc7SAndy Whitcroft } 4797bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4798bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 47993705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4800d8aaf121SAndy Whitcroft 480165863862SAndy Whitcroft # Should start with a space. 480265863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 480365863862SAndy Whitcroft # Should not end with a space. 480465863862SAndy Whitcroft $to =~ s/\s+$//; 480565863862SAndy Whitcroft # '*'s should not have spaces between. 4806f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 480765863862SAndy Whitcroft } 480865863862SAndy Whitcroft # Modifiers should have spaces. 480965863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 481065863862SAndy Whitcroft 48113705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4812667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 48133705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 48143705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 48153705ce5bSJoe Perches $fix) { 48163705ce5bSJoe Perches 48173705ce5bSJoe Perches my $sub_from = $match; 48183705ce5bSJoe Perches my $sub_to = $match; 48193705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4820194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48213705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 48223705ce5bSJoe Perches } 482365863862SAndy Whitcroft } 48240a920b5bSAndy Whitcroft } 48250a920b5bSAndy Whitcroft 482669d517e6SDavid Hildenbrand# do not use BUG() or variants 482769d517e6SDavid Hildenbrand if ($line =~ /\b(?!AA_|BUILD_|DCCP_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) { 48280675a8fbSJean Delvare my $msg_level = \&WARN; 48290675a8fbSJean Delvare $msg_level = \&CHK if ($file); 48300675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 483169d517e6SDavid Hildenbrand "Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants\n" . $herecurr); 48329d3e3c70SJoe Perches } 48330a920b5bSAndy Whitcroft 48349d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 48358905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4836000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4837000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 48388905a67cSAndy Whitcroft } 48398905a67cSAndy Whitcroft 484017441227SJoe Perches# check for uses of printk_ratelimit 484117441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4842000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4843000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 484417441227SJoe Perches } 484517441227SJoe Perches 4846eeef5733SJoe Perches# printk should use KERN_* levels 4847eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4848000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4849eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 485000df344fSAndy Whitcroft } 48510a920b5bSAndy Whitcroft 4852f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL> 4853f5eea3b0SJoe Perches if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { 4854f5eea3b0SJoe Perches my $printk = $1; 4855f5eea3b0SJoe Perches my $modifier = $2; 4856f5eea3b0SJoe Perches my $orig = $3; 4857f5eea3b0SJoe Perches $modifier = "" if (!defined($modifier)); 4858243f3803SJoe Perches my $level = lc($orig); 4859243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 48608f26b837SJoe Perches my $level2 = $level; 48618f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4862f5eea3b0SJoe Perches $level .= $modifier; 4863f5eea3b0SJoe Perches $level2 .= $modifier; 4864243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4865f5eea3b0SJoe Perches "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); 4866243f3803SJoe Perches } 4867243f3803SJoe Perches 4868f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL> 4869dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4870dc139313SJoe Perches my $orig = $1; 4871dc139313SJoe Perches my $level = lc($orig); 4872dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4873dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4874dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4875dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4876dc139313SJoe Perches } 4877dc139313SJoe Perches 48788020b253SNicolas Boichat# trace_printk should not be used in production code. 48798020b253SNicolas Boichat if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { 48808020b253SNicolas Boichat WARN("TRACE_PRINTK", 48818020b253SNicolas Boichat "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); 48828020b253SNicolas Boichat } 48838020b253SNicolas Boichat 488491c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 488591c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 488691c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 488791c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 488891c9afafSAndy Lutomirski WARN("ENOSYS", 488991c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 489091c9afafSAndy Lutomirski } 489191c9afafSAndy Lutomirski 48926b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches. 48936b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. 48946b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected. 48956b9ea5ffSJakub Kicinski if (!$file && $line =~ /\bENOTSUPP\b/) { 48966b9ea5ffSJakub Kicinski if (WARN("ENOTSUPP", 48976b9ea5ffSJakub Kicinski "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && 48986b9ea5ffSJakub Kicinski $fix) { 48996b9ea5ffSJakub Kicinski $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; 49006b9ea5ffSJakub Kicinski } 49016b9ea5ffSJakub Kicinski } 49026b9ea5ffSJakub Kicinski 4903653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4904653d4876SAndy Whitcroft# or if closed on same line 49055b57980dSJoe Perches if ($perl_version_ok && 49062d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 49072d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 49082d453e3bSJoe Perches $sline !~ /}/) { 49098d182478SJoe Perches if (ERROR("OPEN_BRACE", 49102d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 49118d182478SJoe Perches $fix) { 49128d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 49138d182478SJoe Perches my $fixed_line = $rawline; 491403f49351SDwaipayan Ray $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; 49158d182478SJoe Perches my $line1 = $1; 49168d182478SJoe Perches my $line2 = $2; 49178d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 49188d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 49198d182478SJoe Perches if ($line2 !~ /^\s*$/) { 49208d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 49218d182478SJoe Perches } 49228d182478SJoe Perches } 49230a920b5bSAndy Whitcroft } 4924653d4876SAndy Whitcroft 49258905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 49268905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 49278905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 49288d182478SJoe Perches if (ERROR("OPEN_BRACE", 49298d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 49308d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 49318d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 49328d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 49338d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 49348d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 49358d182478SJoe Perches $fixedline = $rawline; 49368d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 49378d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 49388d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 49398d182478SJoe Perches } 49408d182478SJoe Perches } 49418905a67cSAndy Whitcroft } 49428905a67cSAndy Whitcroft 49430c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 49443705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 49453705ce5bSJoe Perches if (WARN("SPACING", 49463705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 49473705ce5bSJoe Perches $fix) { 4948194f66fcSJoe Perches $fixed[$fixlinenr] =~ 49493705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 49503705ce5bSJoe Perches } 49510c73b4ebSAndy Whitcroft } 49520c73b4ebSAndy Whitcroft 495331070b5dSJoe Perches# Function pointer declarations 495431070b5dSJoe Perches# check spacing between type, funcptr, and args 495531070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 495691f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 495731070b5dSJoe Perches my $declare = $1; 495831070b5dSJoe Perches my $pre_pointer_space = $2; 495931070b5dSJoe Perches my $post_pointer_space = $3; 496031070b5dSJoe Perches my $funcname = $4; 496131070b5dSJoe Perches my $post_funcname_space = $5; 496231070b5dSJoe Perches my $pre_args_space = $6; 496331070b5dSJoe Perches 496491f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 496591f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 496691f72e9cSJoe Perches# don't need a space so don't warn for those. 496791f72e9cSJoe Perches my $post_declare_space = ""; 496891f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 496991f72e9cSJoe Perches $post_declare_space = $1; 497091f72e9cSJoe Perches $declare = rtrim($declare); 497191f72e9cSJoe Perches } 497291f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 497331070b5dSJoe Perches WARN("SPACING", 497431070b5dSJoe Perches "missing space after return type\n" . $herecurr); 497591f72e9cSJoe Perches $post_declare_space = " "; 497631070b5dSJoe Perches } 497731070b5dSJoe Perches 497831070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 497991f72e9cSJoe Perches# This test is not currently implemented because these declarations are 498091f72e9cSJoe Perches# equivalent to 498191f72e9cSJoe Perches# int foo(int bar, ...) 498291f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 498391f72e9cSJoe Perches# 498491f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 498591f72e9cSJoe Perches# WARN("SPACING", 498691f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 498791f72e9cSJoe Perches# } 498831070b5dSJoe Perches 498931070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 499031070b5dSJoe Perches if (defined $pre_pointer_space && 499131070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 499231070b5dSJoe Perches WARN("SPACING", 499331070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 499431070b5dSJoe Perches } 499531070b5dSJoe Perches 499631070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 499731070b5dSJoe Perches if (defined $post_pointer_space && 499831070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 499931070b5dSJoe Perches WARN("SPACING", 500031070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 500131070b5dSJoe Perches } 500231070b5dSJoe Perches 500331070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 500431070b5dSJoe Perches if (defined $post_funcname_space && 500531070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 500631070b5dSJoe Perches WARN("SPACING", 500731070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 500831070b5dSJoe Perches } 500931070b5dSJoe Perches 501031070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 501131070b5dSJoe Perches if (defined $pre_args_space && 501231070b5dSJoe Perches $pre_args_space =~ /^\s/) { 501331070b5dSJoe Perches WARN("SPACING", 501431070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 501531070b5dSJoe Perches } 501631070b5dSJoe Perches 501731070b5dSJoe Perches if (show_type("SPACING") && $fix) { 5018194f66fcSJoe Perches $fixed[$fixlinenr] =~ 501991f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 502031070b5dSJoe Perches } 502131070b5dSJoe Perches } 502231070b5dSJoe Perches 50238d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 50248d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 5025fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 5026fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 50278d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 50288d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 50298d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 5030fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 503138dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 50323705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 50333705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 50343705ce5bSJoe Perches $fix) { 5035194f66fcSJoe Perches $fixed[$fixlinenr] =~ 50363705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 50373705ce5bSJoe Perches } 50388d31cfceSAndy Whitcroft } 50398d31cfceSAndy Whitcroft } 50408d31cfceSAndy Whitcroft 5041f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 50426c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 5043c2fdda0dSAndy Whitcroft my $name = $1; 5044773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 5045773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 5046c2fdda0dSAndy Whitcroft 5047c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 5048773647a0SAndy Whitcroft if ($name =~ /^(?: 5049773647a0SAndy Whitcroft if|for|while|switch|return|case| 5050773647a0SAndy Whitcroft volatile|__volatile__| 5051773647a0SAndy Whitcroft __attribute__|format|__extension__| 505254da6a09SPeter Zijlstra asm|__asm__|scoped_guard)$/x) 5053773647a0SAndy Whitcroft { 5054c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 5055c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 5056c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 5057c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 5058773647a0SAndy Whitcroft 5059773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 5060c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 5061c2fdda0dSAndy Whitcroft 5062c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 5063c2fdda0dSAndy Whitcroft # likely a typedef for a function. 5064773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 5065c2fdda0dSAndy Whitcroft 5066c2fdda0dSAndy Whitcroft } else { 50673705ce5bSJoe Perches if (WARN("SPACING", 50683705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 50693705ce5bSJoe Perches $fix) { 5070194f66fcSJoe Perches $fixed[$fixlinenr] =~ 50713705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 50723705ce5bSJoe Perches } 5073f0a594c1SAndy Whitcroft } 50746c72ffaaSAndy Whitcroft } 50759a4cad4eSEric Nelson 5076653d4876SAndy Whitcroft# Check operator spacing. 50770a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 50783705ce5bSJoe Perches my $fixed_line = ""; 50793705ce5bSJoe Perches my $line_fixed = 0; 50803705ce5bSJoe Perches 50819c0ca6f9SAndy Whitcroft my $ops = qr{ 50829c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 50839c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 50849c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 50851f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 508684731623SJoe Perches \?:|\?|: 50879c0ca6f9SAndy Whitcroft }x; 5088cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 50893705ce5bSJoe Perches 50903705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 50913705ce5bSJoe Perches## foreach my $el (@elements) { 50923705ce5bSJoe Perches## print("el: <$el>\n"); 50933705ce5bSJoe Perches## } 50943705ce5bSJoe Perches 50953705ce5bSJoe Perches my @fix_elements = (); 509600df344fSAndy Whitcroft my $off = 0; 50976c72ffaaSAndy Whitcroft 50983705ce5bSJoe Perches foreach my $el (@elements) { 50993705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 51003705ce5bSJoe Perches $off += length($el); 51013705ce5bSJoe Perches } 51023705ce5bSJoe Perches 51033705ce5bSJoe Perches $off = 0; 51043705ce5bSJoe Perches 51056c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 5106b34c648bSJoe Perches my $last_after = -1; 51076c72ffaaSAndy Whitcroft 51080a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 51093705ce5bSJoe Perches 51103705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 51113705ce5bSJoe Perches 51123705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 51133705ce5bSJoe Perches 51144a0df2efSAndy Whitcroft $off += length($elements[$n]); 51154a0df2efSAndy Whitcroft 511625985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 5117773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 5118773647a0SAndy Whitcroft my $cc = ''; 5119773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 5120773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 5121773647a0SAndy Whitcroft } 5122773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 5123773647a0SAndy Whitcroft 51244a0df2efSAndy Whitcroft my $a = ''; 51254a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 51264a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 5127cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 51284a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 51294a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 5130773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 51314a0df2efSAndy Whitcroft 51320a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 51334a0df2efSAndy Whitcroft 51344a0df2efSAndy Whitcroft my $c = ''; 51350a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 51364a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 51374a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 5138cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 51394a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 51404a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 51418b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 51424a0df2efSAndy Whitcroft } else { 51434a0df2efSAndy Whitcroft $c = 'E'; 51440a920b5bSAndy Whitcroft } 51450a920b5bSAndy Whitcroft 51464a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 51474a0df2efSAndy Whitcroft 51484a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 51494a0df2efSAndy Whitcroft 51506c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 5151de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 51520a920b5bSAndy Whitcroft 515374048ed8SAndy Whitcroft # Pull out the value of this operator. 51546c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 51550a920b5bSAndy Whitcroft 51561f65f947SAndy Whitcroft # Get the full operator variant. 51571f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 51581f65f947SAndy Whitcroft 515913214adfSAndy Whitcroft # Ignore operators passed as parameters. 516013214adfSAndy Whitcroft if ($op_type ne 'V' && 5161d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 516213214adfSAndy Whitcroft 5163cf655043SAndy Whitcroft# # Ignore comments 5164cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 516513214adfSAndy Whitcroft 5166d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 516713214adfSAndy Whitcroft } elsif ($op eq ';') { 5168cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 5169cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 51703705ce5bSJoe Perches if (ERROR("SPACING", 51713705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 5172b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 51733705ce5bSJoe Perches $line_fixed = 1; 51743705ce5bSJoe Perches } 5175d8aaf121SAndy Whitcroft } 5176d8aaf121SAndy Whitcroft 5177d8aaf121SAndy Whitcroft # // is a comment 5178d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 51790a920b5bSAndy Whitcroft 5180b00e4814SJoe Perches # : when part of a bitfield 5181b00e4814SJoe Perches } elsif ($opv eq ':B') { 5182b00e4814SJoe Perches # skip the bitfield test for now 5183b00e4814SJoe Perches 51841f65f947SAndy Whitcroft # No spaces for: 51851f65f947SAndy Whitcroft # -> 5186b00e4814SJoe Perches } elsif ($op eq '->') { 51874a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 51883705ce5bSJoe Perches if (ERROR("SPACING", 51893705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 5190b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 51913705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 51923705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 51933705ce5bSJoe Perches } 5194b34c648bSJoe Perches $line_fixed = 1; 51953705ce5bSJoe Perches } 51960a920b5bSAndy Whitcroft } 51970a920b5bSAndy Whitcroft 51982381097bSJoe Perches # , must not have a space before and must have a space on the right. 51990a920b5bSAndy Whitcroft } elsif ($op eq ',') { 52002381097bSJoe Perches my $rtrim_before = 0; 52012381097bSJoe Perches my $space_after = 0; 52022381097bSJoe Perches if ($ctx =~ /Wx./) { 52032381097bSJoe Perches if (ERROR("SPACING", 52042381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 52052381097bSJoe Perches $line_fixed = 1; 52062381097bSJoe Perches $rtrim_before = 1; 52072381097bSJoe Perches } 52082381097bSJoe Perches } 5209cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 52103705ce5bSJoe Perches if (ERROR("SPACING", 52113705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 52123705ce5bSJoe Perches $line_fixed = 1; 5213b34c648bSJoe Perches $last_after = $n; 52142381097bSJoe Perches $space_after = 1; 52152381097bSJoe Perches } 52162381097bSJoe Perches } 52172381097bSJoe Perches if ($rtrim_before || $space_after) { 52182381097bSJoe Perches if ($rtrim_before) { 52192381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 52202381097bSJoe Perches } else { 52212381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 52222381097bSJoe Perches } 52232381097bSJoe Perches if ($space_after) { 52242381097bSJoe Perches $good .= " "; 52253705ce5bSJoe Perches } 52260a920b5bSAndy Whitcroft } 52270a920b5bSAndy Whitcroft 52289c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 522974048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 52309c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 52319c0ca6f9SAndy Whitcroft 52329c0ca6f9SAndy Whitcroft # unary operators should have a space before and 52339c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 52349c0ca6f9SAndy Whitcroft # unary operator, or a cast 52359c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 523674048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 52370d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 5238cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 52393705ce5bSJoe Perches if (ERROR("SPACING", 52403705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 5241b34c648bSJoe Perches if ($n != $last_after + 2) { 5242b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 52433705ce5bSJoe Perches $line_fixed = 1; 52443705ce5bSJoe Perches } 52450a920b5bSAndy Whitcroft } 5246b34c648bSJoe Perches } 5247a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 5248171ae1a4SAndy Whitcroft # A unary '*' may be const 5249171ae1a4SAndy Whitcroft 5250171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 52513705ce5bSJoe Perches if (ERROR("SPACING", 52523705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5253b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 52543705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 52553705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 52563705ce5bSJoe Perches } 5257b34c648bSJoe Perches $line_fixed = 1; 52583705ce5bSJoe Perches } 52590a920b5bSAndy Whitcroft } 52600a920b5bSAndy Whitcroft 52610a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 52620a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 5263773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 52643705ce5bSJoe Perches if (ERROR("SPACING", 52653705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 5266b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 52673705ce5bSJoe Perches $line_fixed = 1; 52683705ce5bSJoe Perches } 52690a920b5bSAndy Whitcroft } 5270773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 5271773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 52723705ce5bSJoe Perches if (ERROR("SPACING", 52733705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5274b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 52753705ce5bSJoe Perches $line_fixed = 1; 52763705ce5bSJoe Perches } 5277653d4876SAndy Whitcroft } 5278773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 52793705ce5bSJoe Perches if (ERROR("SPACING", 52803705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5281b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 52823705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 52833705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5284773647a0SAndy Whitcroft } 5285b34c648bSJoe Perches $line_fixed = 1; 52863705ce5bSJoe Perches } 52873705ce5bSJoe Perches } 52880a920b5bSAndy Whitcroft 52890a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 52909c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 52919c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 52929c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 5293c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 5294c2fdda0dSAndy Whitcroft $op eq '%') 52950a920b5bSAndy Whitcroft { 5296d2e025f3SJoe Perches if ($check) { 5297d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 5298d2e025f3SJoe Perches if (CHK("SPACING", 5299d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 5300d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5301d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5302d2e025f3SJoe Perches $line_fixed = 1; 5303d2e025f3SJoe Perches } 5304d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 5305d2e025f3SJoe Perches if (CHK("SPACING", 5306d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 5307d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 5308d2e025f3SJoe Perches $line_fixed = 1; 5309d2e025f3SJoe Perches } 5310d2e025f3SJoe Perches } 5311d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 53123705ce5bSJoe Perches if (ERROR("SPACING", 53133705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 5314b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5315b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5316b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5317b34c648bSJoe Perches } 53183705ce5bSJoe Perches $line_fixed = 1; 53193705ce5bSJoe Perches } 53200a920b5bSAndy Whitcroft } 53210a920b5bSAndy Whitcroft 53221f65f947SAndy Whitcroft # A colon needs no spaces before when it is 53231f65f947SAndy Whitcroft # terminating a case value or a label. 53241f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 5325263afd39SChris Down if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) { 53263705ce5bSJoe Perches if (ERROR("SPACING", 53273705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5328b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 53293705ce5bSJoe Perches $line_fixed = 1; 53303705ce5bSJoe Perches } 53311f65f947SAndy Whitcroft } 53321f65f947SAndy Whitcroft 53330a920b5bSAndy Whitcroft # All the others need spaces both sides. 5334cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 53351f65f947SAndy Whitcroft my $ok = 0; 53361f65f947SAndy Whitcroft 533722f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 53381f65f947SAndy Whitcroft if (($op eq '<' && 53391f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 53401f65f947SAndy Whitcroft ($op eq '>' && 53411f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 53421f65f947SAndy Whitcroft { 53431f65f947SAndy Whitcroft $ok = 1; 53441f65f947SAndy Whitcroft } 53451f65f947SAndy Whitcroft 5346e0df7e1fSJoe Perches # for asm volatile statements 5347e0df7e1fSJoe Perches # ignore a colon with another 5348e0df7e1fSJoe Perches # colon immediately before or after 5349e0df7e1fSJoe Perches if (($op eq ':') && 5350e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 5351e0df7e1fSJoe Perches $ok = 1; 5352e0df7e1fSJoe Perches } 5353e0df7e1fSJoe Perches 535484731623SJoe Perches # messages are ERROR, but ?: are CHK 53551f65f947SAndy Whitcroft if ($ok == 0) { 53560675a8fbSJean Delvare my $msg_level = \&ERROR; 53570675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 535884731623SJoe Perches 53590675a8fbSJean Delvare if (&{$msg_level}("SPACING", 53603705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 5361b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5362b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5363b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5364b34c648bSJoe Perches } 53653705ce5bSJoe Perches $line_fixed = 1; 53663705ce5bSJoe Perches } 53670a920b5bSAndy Whitcroft } 536822f2a2efSAndy Whitcroft } 53694a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 53703705ce5bSJoe Perches 53713705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 53723705ce5bSJoe Perches 53733705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 53740a920b5bSAndy Whitcroft } 53753705ce5bSJoe Perches 53763705ce5bSJoe Perches if (($#elements % 2) == 0) { 53773705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 53783705ce5bSJoe Perches } 53793705ce5bSJoe Perches 5380194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 5381194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 53823705ce5bSJoe Perches } 53833705ce5bSJoe Perches 53843705ce5bSJoe Perches 53850a920b5bSAndy Whitcroft } 53860a920b5bSAndy Whitcroft 5387786b6326SJoe Perches# check for whitespace before a non-naked semicolon 5388d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 5389786b6326SJoe Perches if (WARN("SPACING", 5390786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 5391786b6326SJoe Perches $fix) { 5392194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 5393786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 5394786b6326SJoe Perches } 5395786b6326SJoe Perches } 5396786b6326SJoe Perches 5397f0a594c1SAndy Whitcroft# check for multiple assignments 5398f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 5399000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 5400000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 5401f0a594c1SAndy Whitcroft } 5402f0a594c1SAndy Whitcroft 540322f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 540422f2a2efSAndy Whitcroft## # continuation. 540522f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 540622f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 540722f2a2efSAndy Whitcroft## 540822f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 5409e73d2715SDwaipayan Ray## # falsely report the parameters of functions. 541022f2a2efSAndy Whitcroft## my $ln = $line; 541122f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 541222f2a2efSAndy Whitcroft## } 541322f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 5414000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 5415000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 541622f2a2efSAndy Whitcroft## } 541722f2a2efSAndy Whitcroft## } 5418f0a594c1SAndy Whitcroft 54190a920b5bSAndy Whitcroft#need space before brace following if, while, etc 54206b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 54216ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 54223705ce5bSJoe Perches if (ERROR("SPACING", 54233705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 54243705ce5bSJoe Perches $fix) { 54256ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 54263705ce5bSJoe Perches } 5427de7d4f0eSAndy Whitcroft } 5428de7d4f0eSAndy Whitcroft 5429c4a62ef9SJoe Perches## # check for blank lines before declarations 5430c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 5431c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 5432c4a62ef9SJoe Perches## WARN("SPACING", 5433c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 5434c4a62ef9SJoe Perches## } 5435c4a62ef9SJoe Perches## 5436c4a62ef9SJoe Perches 5437de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 5438de7d4f0eSAndy Whitcroft# on the line 543994fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 5440d5e616fcSJoe Perches if (ERROR("SPACING", 5441d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 5442d5e616fcSJoe Perches $fix) { 5443194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5444d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 5445d5e616fcSJoe Perches } 54460a920b5bSAndy Whitcroft } 54470a920b5bSAndy Whitcroft 544822f2a2efSAndy Whitcroft# check spacing on square brackets 544922f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 54503705ce5bSJoe Perches if (ERROR("SPACING", 54513705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 54523705ce5bSJoe Perches $fix) { 5453194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54543705ce5bSJoe Perches s/\[\s+/\[/; 54553705ce5bSJoe Perches } 545622f2a2efSAndy Whitcroft } 545722f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 54583705ce5bSJoe Perches if (ERROR("SPACING", 54593705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 54603705ce5bSJoe Perches $fix) { 5461194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54623705ce5bSJoe Perches s/\s+\]/\]/; 54633705ce5bSJoe Perches } 546422f2a2efSAndy Whitcroft } 546522f2a2efSAndy Whitcroft 5466c45dcabdSAndy Whitcroft# check spacing on parentheses 54679c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 54689c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 54693705ce5bSJoe Perches if (ERROR("SPACING", 54703705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 54713705ce5bSJoe Perches $fix) { 5472194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54733705ce5bSJoe Perches s/\(\s+/\(/; 54743705ce5bSJoe Perches } 547522f2a2efSAndy Whitcroft } 547613214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 5477c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 5478c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 54793705ce5bSJoe Perches if (ERROR("SPACING", 54803705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 54813705ce5bSJoe Perches $fix) { 5482194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54833705ce5bSJoe Perches s/\s+\)/\)/; 54843705ce5bSJoe Perches } 548522f2a2efSAndy Whitcroft } 548622f2a2efSAndy Whitcroft 5487e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 5488e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 5489e2826fd0SJoe Perches 5490e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 5491ea4acbb1SJoe Perches my $var = $1; 5492ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5493ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 5494ea4acbb1SJoe Perches $fix) { 5495ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 5496ea4acbb1SJoe Perches } 5497ea4acbb1SJoe Perches } 5498ea4acbb1SJoe Perches 5499ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 5500ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 5501ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 5502ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 5503ea4acbb1SJoe Perches my $var = $2; 5504ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5505ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 5506ea4acbb1SJoe Perches $fix) { 5507ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 5508ea4acbb1SJoe Perches $var2 =~ s/\s//g; 5509ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 5510ea4acbb1SJoe Perches } 5511e2826fd0SJoe Perches } 5512e2826fd0SJoe Perches 551363b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 5514a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 5515a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 55165b57980dSJoe Perches $perl_version_ok && defined($stat) && 551763b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 551863b7c73eSJoe Perches my $if_stat = $1; 551963b7c73eSJoe Perches my $test = substr($2, 1, -1); 552063b7c73eSJoe Perches my $herectx; 552163b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 552263b7c73eSJoe Perches my $match = $1; 552363b7c73eSJoe Perches # avoid parentheses around potential macro args 552463b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 552563b7c73eSJoe Perches if (!defined($herectx)) { 552663b7c73eSJoe Perches $herectx = $here . "\n"; 552763b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 552863b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 552963b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 553063b7c73eSJoe Perches $herectx .= $rl . "\n"; 553163b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 553263b7c73eSJoe Perches } 553363b7c73eSJoe Perches } 553463b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 553563b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 553663b7c73eSJoe Perches } 553763b7c73eSJoe Perches } 553863b7c73eSJoe Perches 553969078651SJoe Perches# check that goto labels aren't indented (allow a single space indentation) 554069078651SJoe Perches# and ignore bitfield definitions like foo:1 554169078651SJoe Perches# Strictly, labels can have whitespace after the identifier and before the : 554269078651SJoe Perches# but this is not allowed here as many ?: uses would appear to be labels 554369078651SJoe Perches if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ && 554469078651SJoe Perches $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ && 554569078651SJoe Perches $sline !~ /^.\s+default:/) { 55463705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 55473705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 55483705ce5bSJoe Perches $fix) { 5549194f66fcSJoe Perches $fixed[$fixlinenr] =~ 55503705ce5bSJoe Perches s/^(.)\s+/$1/; 55513705ce5bSJoe Perches } 55520a920b5bSAndy Whitcroft } 55530a920b5bSAndy Whitcroft 555440873abaSJoe Perches# check if a statement with a comma should be two statements like: 555540873abaSJoe Perches# foo = bar(), /* comma should be semicolon */ 555640873abaSJoe Perches# bar = baz(); 555740873abaSJoe Perches if (defined($stat) && 555840873abaSJoe Perches $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { 555940873abaSJoe Perches my $cnt = statement_rawlines($stat); 556040873abaSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 556140873abaSJoe Perches WARN("SUSPECT_COMMA_SEMICOLON", 556240873abaSJoe Perches "Possible comma where semicolon could be used\n" . $herectx); 556340873abaSJoe Perches } 556440873abaSJoe Perches 55655b9553abSJoe Perches# return is not a function 5566507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 5567c45dcabdSAndy Whitcroft my $spacing = $1; 55685b57980dSJoe Perches if ($perl_version_ok && 55695b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 55705b9553abSJoe Perches my $value = $1; 55715b9553abSJoe Perches $value = deparenthesize($value); 55725b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 5573000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 5574000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 55755b9553abSJoe Perches } 5576c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 5577000d1cc1SJoe Perches ERROR("SPACING", 5578000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 5579c45dcabdSAndy Whitcroft } 5580c45dcabdSAndy Whitcroft } 5581507e5141SJoe Perches 5582b43ae21bSJoe Perches# unnecessary return in a void function 5583b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 5584b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 5585b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 5586b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 5587b43ae21bSJoe Perches $linenr >= 3 && 5588b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 5589b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 55909819cf25SJoe Perches WARN("RETURN_VOID", 5591b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 55929819cf25SJoe Perches } 55939819cf25SJoe Perches 5594189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 55955b57980dSJoe Perches if ($perl_version_ok && 5596189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 5597189248d8SJoe Perches my $openparens = $1; 5598189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 5599189248d8SJoe Perches my $msg = ""; 5600189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 5601189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 5602189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 5603189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 5604189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 5605189248d8SJoe Perches } 5606189248d8SJoe Perches } 5607189248d8SJoe Perches 5608c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 5609c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 5610c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 5611c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 56125b57980dSJoe Perches if ($perl_version_ok && 5613c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 5614c5595fa2SJoe Perches my $lead = $1; 5615c5595fa2SJoe Perches my $const = $2; 5616c5595fa2SJoe Perches my $comp = $3; 5617c5595fa2SJoe Perches my $to = $4; 5618c5595fa2SJoe Perches my $newcomp = $comp; 5619f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 5620c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 5621c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 5622c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 5623c5595fa2SJoe Perches $fix) { 5624c5595fa2SJoe Perches if ($comp eq "<") { 5625c5595fa2SJoe Perches $newcomp = ">"; 5626c5595fa2SJoe Perches } elsif ($comp eq "<=") { 5627c5595fa2SJoe Perches $newcomp = ">="; 5628c5595fa2SJoe Perches } elsif ($comp eq ">") { 5629c5595fa2SJoe Perches $newcomp = "<"; 5630c5595fa2SJoe Perches } elsif ($comp eq ">=") { 5631c5595fa2SJoe Perches $newcomp = "<="; 5632c5595fa2SJoe Perches } 5633c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 5634c5595fa2SJoe Perches } 5635c5595fa2SJoe Perches } 5636c5595fa2SJoe Perches 5637f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 5638f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 563953a3c448SAndy Whitcroft my $name = $1; 564046b85bf9SGuenter Roeck if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) { 5641000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 5642f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 564353a3c448SAndy Whitcroft } 564453a3c448SAndy Whitcroft } 5645c45dcabdSAndy Whitcroft 56460a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 56474a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 56483705ce5bSJoe Perches if (ERROR("SPACING", 56493705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 56503705ce5bSJoe Perches $fix) { 5651194f66fcSJoe Perches $fixed[$fixlinenr] =~ 56523705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 56533705ce5bSJoe Perches } 56540a920b5bSAndy Whitcroft } 56550a920b5bSAndy Whitcroft 5656f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 5657f5fe35ddSAndy Whitcroft# statements after the conditional. 5658170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 56593e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 56603e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 56613e469cdcSAndy Whitcroft if (!defined $stat); 5662170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 5663170d3a22SAndy Whitcroft $remain_next, $off_next); 5664170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 5665170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 5666170d3a22SAndy Whitcroft 5667170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 5668170d3a22SAndy Whitcroft # If the statement carries leading newlines, 5669170d3a22SAndy Whitcroft # then count those as offsets. 5670170d3a22SAndy Whitcroft my ($whitespace) = 5671170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 5672170d3a22SAndy Whitcroft my $offset = 5673170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 5674170d3a22SAndy Whitcroft 5675170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 5676170d3a22SAndy Whitcroft $offset} = 1; 5677170d3a22SAndy Whitcroft } 5678170d3a22SAndy Whitcroft } 5679170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 5680c11230f4SJoe Perches defined($stat) && defined($cond) && 5681170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 5682171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 5683481efd7bSJoe Perches my $fixed_assign_in_if = 0; 56848905a67cSAndy Whitcroft 5685b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 568665b64b3bSJoe Perches if (ERROR("ASSIGN_IN_IF", 568765b64b3bSJoe Perches "do not use assignment in if condition\n" . $herecurr) && 568865b64b3bSJoe Perches $fix && $perl_version_ok) { 568965b64b3bSJoe Perches if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { 569065b64b3bSJoe Perches my $space = $1; 569165b64b3bSJoe Perches my $not = $2; 569265b64b3bSJoe Perches my $statement = $3; 569365b64b3bSJoe Perches my $assigned = $4; 569465b64b3bSJoe Perches my $test = $8; 569565b64b3bSJoe Perches my $against = $9; 569665b64b3bSJoe Perches my $brace = $15; 569765b64b3bSJoe Perches fix_delete_line($fixlinenr, $rawline); 569865b64b3bSJoe Perches fix_insert_line($fixlinenr, "$space$statement;"); 569965b64b3bSJoe Perches my $newline = "${space}if ("; 570065b64b3bSJoe Perches $newline .= '!' if defined($not); 570165b64b3bSJoe Perches $newline .= '(' if (defined $not && defined($test) && defined($against)); 570265b64b3bSJoe Perches $newline .= "$assigned"; 570365b64b3bSJoe Perches $newline .= " $test $against" if (defined($test) && defined($against)); 570465b64b3bSJoe Perches $newline .= ')' if (defined $not && defined($test) && defined($against)); 570565b64b3bSJoe Perches $newline .= ')'; 570665b64b3bSJoe Perches $newline .= " {" if (defined($brace)); 570765b64b3bSJoe Perches fix_insert_line($fixlinenr + 1, $newline); 5708481efd7bSJoe Perches $fixed_assign_in_if = 1; 570965b64b3bSJoe Perches } 571065b64b3bSJoe Perches } 57118905a67cSAndy Whitcroft } 57128905a67cSAndy Whitcroft 57138905a67cSAndy Whitcroft # Find out what is on the end of the line after the 57148905a67cSAndy Whitcroft # conditional. 5715773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 57168905a67cSAndy Whitcroft $s =~ s/\n.*//g; 571713214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 571853210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 571953210168SAndy Whitcroft $c !~ /}\s*while\s*/) 5720773647a0SAndy Whitcroft { 5721bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 5722bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 5723bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 572442bdf74cSHidetoshi Seto my $stat_real = ''; 5725bb44ad39SAndy Whitcroft 572642bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 572742bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 5728bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 5729bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 5730bb44ad39SAndy Whitcroft } 5731bb44ad39SAndy Whitcroft 5732481efd7bSJoe Perches if (ERROR("TRAILING_STATEMENTS", 5733481efd7bSJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real) && 5734481efd7bSJoe Perches !$fixed_assign_in_if && 5735481efd7bSJoe Perches $cond_lines == 0 && 5736481efd7bSJoe Perches $fix && $perl_version_ok && 5737481efd7bSJoe Perches $fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) { 5738481efd7bSJoe Perches my $indent = $1; 5739481efd7bSJoe Perches my $test = $2; 5740481efd7bSJoe Perches my $rest = rtrim($4); 5741481efd7bSJoe Perches if ($rest =~ /;$/) { 5742481efd7bSJoe Perches $fixed[$fixlinenr] = "\+$indent$test"; 5743481efd7bSJoe Perches fix_insert_line($fixlinenr + 1, "$indent\t$rest"); 5744481efd7bSJoe Perches } 5745481efd7bSJoe Perches } 57468905a67cSAndy Whitcroft } 57478905a67cSAndy Whitcroft } 57488905a67cSAndy Whitcroft 574913214adfSAndy Whitcroft# Check for bitwise tests written as boolean 575013214adfSAndy Whitcroft if ($line =~ / 575113214adfSAndy Whitcroft (?: 575213214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 575313214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 575413214adfSAndy Whitcroft (?:\&\&|\|\|) 575513214adfSAndy Whitcroft | 575613214adfSAndy Whitcroft (?:\&\&|\|\|) 575713214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 575813214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 575913214adfSAndy Whitcroft )/x) 576013214adfSAndy Whitcroft { 5761000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 5762000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 576313214adfSAndy Whitcroft } 576413214adfSAndy Whitcroft 57658905a67cSAndy Whitcroft# if and else should not have general statements after it 576613214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 576713214adfSAndy Whitcroft my $s = $1; 576813214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 576913214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 5770000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5771000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 57720a920b5bSAndy Whitcroft } 577313214adfSAndy Whitcroft } 577439667782SAndy Whitcroft# if should not continue a brace 577539667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 5776000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5777048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 577839667782SAndy Whitcroft $herecurr); 577939667782SAndy Whitcroft } 5780a1080bf8SAndy Whitcroft# case and default should not have general statements after them 5781a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 5782a1080bf8SAndy Whitcroft $line !~ /\G(?: 57833fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5784a1080bf8SAndy Whitcroft \s*return\s+ 5785a1080bf8SAndy Whitcroft )/xg) 5786a1080bf8SAndy Whitcroft { 5787000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5788000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 5789a1080bf8SAndy Whitcroft } 57900a920b5bSAndy Whitcroft 57910a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 57920a920b5bSAndy Whitcroft # indent level to be relevant to each other. 57938b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 57940a920b5bSAndy Whitcroft $previndent == $indent) { 57958b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 57968b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 57978b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 57988b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 57998b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 58008b8856f4SJoe Perches my $fixedline = $prevrawline; 58018b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 58028b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 58038b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 58048b8856f4SJoe Perches } 58058b8856f4SJoe Perches $fixedline = $rawline; 58068b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 58078b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 58088b8856f4SJoe Perches } 58090a920b5bSAndy Whitcroft } 58100a920b5bSAndy Whitcroft 58118b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5812c2fdda0dSAndy Whitcroft $previndent == $indent) { 5813c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5814c2fdda0dSAndy Whitcroft 5815c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5816c2fdda0dSAndy Whitcroft # conditional. 5817773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5818c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5819c2fdda0dSAndy Whitcroft 5820c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 58218b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 58228b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 58238b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 58248b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 58258b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 58268b8856f4SJoe Perches my $fixedline = $prevrawline; 58278b8856f4SJoe Perches my $trailing = $rawline; 58288b8856f4SJoe Perches $trailing =~ s/^\+//; 58298b8856f4SJoe Perches $trailing = trim($trailing); 58308b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 58318b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 58328b8856f4SJoe Perches } 5833c2fdda0dSAndy Whitcroft } 5834c2fdda0dSAndy Whitcroft } 5835c2fdda0dSAndy Whitcroft 583695e2c602SJoe Perches#Specific variable tests 5837323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5838323c1260SJoe Perches my $var = $1; 583995e2c602SJoe Perches 584095e2c602SJoe Perches#CamelCase 5841807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5842be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 58434104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values 58444104a206SŁukasz Stelmach $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && 584522735ce8SJoe Perches#Ignore Page<foo> variants 5846807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5847d99a4158SGerhard Engleder#Ignore ETHTOOL_LINK_MODE_<foo> variants 5848d99a4158SGerhard Engleder $var !~ /^ETHTOOL_LINK_MODE_/ && 5849d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB 5850d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 5851d439e6a5SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5852f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5853f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 5854f858e23aSAntonio Borneo while ($var =~ m{\b($Ident)}g) { 58557e781f67SJoe Perches my $word = $1; 58567e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5857d8b07710SJoe Perches if ($check) { 5858d8b07710SJoe Perches seed_camelcase_includes(); 5859d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5860d8b07710SJoe Perches seed_camelcase_file($realfile); 5861d8b07710SJoe Perches $camelcase_file_seeded = 1; 5862d8b07710SJoe Perches } 5863d8b07710SJoe Perches } 58647e781f67SJoe Perches if (!defined $camelcase{$word}) { 58657e781f67SJoe Perches $camelcase{$word} = 1; 5866be79794bSJoe Perches CHK("CAMELCASE", 58677e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 58687e781f67SJoe Perches } 5869323c1260SJoe Perches } 5870323c1260SJoe Perches } 58713445686aSJoe Perches } 58720a920b5bSAndy Whitcroft 58730a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5874d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5875d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5876d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5877d5e616fcSJoe Perches $fix) { 5878194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5879d5e616fcSJoe Perches } 58800a920b5bSAndy Whitcroft } 58810a920b5bSAndy Whitcroft 58820e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 58830e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5884c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5885e09dec48SAndy Whitcroft my $file = "$1.h"; 5886e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5887e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5888e09dec48SAndy Whitcroft $realfile ne $checkfile && 58897840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5890c45dcabdSAndy Whitcroft { 58910e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 58920e212e0aSFabian Frederick if ($asminclude > 0) { 5893e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5894000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5895000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5896e09dec48SAndy Whitcroft } else { 5897000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5898000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5899e09dec48SAndy Whitcroft } 59000a920b5bSAndy Whitcroft } 59010a920b5bSAndy Whitcroft } 59020e212e0aSFabian Frederick } 59030a920b5bSAndy Whitcroft 5904653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5905653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5906cf655043SAndy Whitcroft# in a known good container 5907b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5908b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5909d8aaf121SAndy Whitcroft my $ln = $linenr; 5910d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5911c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5912c45dcabdSAndy Whitcroft my $ctx = ''; 591308a2843eSJoe Perches my $has_flow_statement = 0; 591408a2843eSJoe Perches my $has_arg_concat = 0; 5915c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5916f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5917f74bd194SAndy Whitcroft $ctx = $dstat; 5918c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5919a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5920c45dcabdSAndy Whitcroft 592108a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 592262e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 592308a2843eSJoe Perches 5924f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5925f59b64bfSJoe Perches my $define_args = $1; 5926f59b64bfSJoe Perches my $define_stmt = $dstat; 5927f59b64bfSJoe Perches my @def_args = (); 5928f59b64bfSJoe Perches 5929f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5930f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5931f59b64bfSJoe Perches $define_args =~ s/\s*//g; 59328c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5933f59b64bfSJoe Perches @def_args = split(",", $define_args); 5934f59b64bfSJoe Perches } 5935f59b64bfSJoe Perches 5936292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5937c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5938c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5939c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5940c45dcabdSAndy Whitcroft 5941c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 59422e44e803SDwaipayan Ray while ($dstat =~ s/\([^\(\)]*\)/1u/ || 59432e44e803SDwaipayan Ray $dstat =~ s/\{[^\{\}]*\}/1u/ || 59442e44e803SDwaipayan Ray $dstat =~ s/.\[[^\[\]]*\]/1u/) 5945bf30d6edSAndy Whitcroft { 5946c45dcabdSAndy Whitcroft } 5947c45dcabdSAndy Whitcroft 5948342d3d2fSAntonio Borneo # Flatten any obvious string concatenation. 594933acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 595033acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5951e45bab8eSAndy Whitcroft { 5952e45bab8eSAndy Whitcroft } 5953e45bab8eSAndy Whitcroft 595442e15293SJoe Perches # Make asm volatile uses seem like a generic function 595542e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 595642e15293SJoe Perches 5957c45dcabdSAndy Whitcroft my $exceptions = qr{ 5958c45dcabdSAndy Whitcroft $Declare| 5959c45dcabdSAndy Whitcroft module_param_named| 5960a0a0a7a9SKees Cook MODULE_PARM_DESC| 5961c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5962c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5963383099fdSAndy Whitcroft __typeof__\(| 596422fd2d3eSStefani Seibold union| 596522fd2d3eSStefani Seibold struct| 5966ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 59676b10df42SVladimir Zapolskiy ^\"|\"$| 59686b10df42SVladimir Zapolskiy ^\[ 5969c45dcabdSAndy Whitcroft }x; 59705eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5971f59b64bfSJoe Perches 5972f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5973f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5974e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5975f59b64bfSJoe Perches 5976f74bd194SAndy Whitcroft if ($dstat ne '' && 5977f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5978f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 59793cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5980356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5981f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5982f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5983e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 5984dc3f4deeSStanislaw Gruszka $dstat !~ /^case\b/ && # case ... 598572f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 59862e44e803SDwaipayan Ray $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} 5987f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5988f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5989f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 59904e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5991f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5992c45dcabdSAndy Whitcroft { 5993e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5994e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5995e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5996e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5997f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5998f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5999f74bd194SAndy Whitcroft } else { 6000000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 6001388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 6002d8aaf121SAndy Whitcroft } 6003f59b64bfSJoe Perches 6004f59b64bfSJoe Perches } 60055207649bSJoe Perches 60065207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 60075207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 60085207649bSJoe Perches my $first = 1; 60095207649bSJoe Perches $define_stmt = ""; 60105207649bSJoe Perches foreach my $l (@stmt_array) { 60115207649bSJoe Perches $l =~ s/\\$//; 60125207649bSJoe Perches if ($first) { 60135207649bSJoe Perches $define_stmt = $l; 60145207649bSJoe Perches $first = 0; 60155207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 60165207649bSJoe Perches $define_stmt .= substr($l, 1); 60175207649bSJoe Perches } 60185207649bSJoe Perches } 60195207649bSJoe Perches $define_stmt =~ s/$;//g; 60205207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 60215207649bSJoe Perches $define_stmt = trim($define_stmt); 60225207649bSJoe Perches 6023f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 6024f59b64bfSJoe Perches foreach my $arg (@def_args) { 6025f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 60269192d41aSJoe Perches next if ($arg =~ /^type$/i); 60277fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 60287b844345SVincent 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; 60297fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 60307fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 6031d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 6032f59b64bfSJoe Perches if ($use_cnt > 1) { 6033f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 6034f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 6035f59b64bfSJoe Perches } 60369192d41aSJoe Perches# check if any macro arguments may have other precedence issues 60377fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 60389192d41aSJoe Perches ((defined($1) && $1 ne ',') || 60399192d41aSJoe Perches (defined($2) && $2 ne ','))) { 60409192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 60419192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 60429192d41aSJoe Perches } 60430a920b5bSAndy Whitcroft } 60445023d347SJoe Perches 604508a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 604608a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 604708a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 604808a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 6049e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 605008a2843eSJoe Perches 605108a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 605208a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 605308a2843eSJoe Perches } 605408a2843eSJoe Perches 6055481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 60565023d347SJoe Perches 60575b2c7334SJim Cromie } elsif ($realfile =~ m@/vmlinux.lds.h$@) { 60585b2c7334SJim Cromie $line =~ s/(\w+)/$maybe_linker_symbol{$1}++/ge; 60595b2c7334SJim Cromie #print "REAL: $realfile\nln: $line\nkeys:", sort keys %maybe_linker_symbol; 60605023d347SJoe Perches } else { 60615023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 6062481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 6063481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 60645023d347SJoe Perches $line =~ /^\+.*\\$/) { 60655023d347SJoe Perches WARN("LINE_CONTINUATIONS", 60665023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 60675023d347SJoe Perches } 6068653d4876SAndy Whitcroft } 60690a920b5bSAndy Whitcroft 6070b13edf7fSJoe Perches# do {} while (0) macro tests: 6071b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 6072b13edf7fSJoe Perches# macro should not end with a semicolon 60735b57980dSJoe Perches if ($perl_version_ok && 6074b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 6075b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 6076b13edf7fSJoe Perches my $ln = $linenr; 6077b13edf7fSJoe Perches my $cnt = $realcnt; 6078b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 6079b13edf7fSJoe Perches my $ctx = ''; 6080b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 6081b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 6082b13edf7fSJoe Perches $ctx = $dstat; 6083b13edf7fSJoe Perches 6084b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 60851b36b201SJoe Perches $dstat =~ s/$;/ /g; 6086b13edf7fSJoe Perches 6087b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 6088b13edf7fSJoe Perches my $stmts = $2; 6089b13edf7fSJoe Perches my $semis = $3; 6090b13edf7fSJoe Perches 6091b13edf7fSJoe Perches $ctx =~ s/\n*$//; 6092b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 6093e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6094b13edf7fSJoe Perches 6095ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 6096ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 6097b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 6098b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 6099b13edf7fSJoe Perches } 6100b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 6101b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 6102b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 6103b13edf7fSJoe Perches } 6104f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 6105f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 6106f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 6107e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6108f5ef95b1SJoe Perches 6109f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 6110f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 6111b13edf7fSJoe Perches } 6112b13edf7fSJoe Perches } 6113b13edf7fSJoe Perches 6114f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 611513214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 611613214adfSAndy Whitcroft my ($level, $endln, @chunks) = 6117cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 611813214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 6119cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 6120cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 6121aad4f614SJoe Perches my @allowed = (); 6122aad4f614SJoe Perches my $allow = 0; 612313214adfSAndy Whitcroft my $seen = 0; 6124773647a0SAndy Whitcroft my $herectx = $here . "\n"; 6125cf655043SAndy Whitcroft my $ln = $linenr - 1; 612613214adfSAndy Whitcroft for my $chunk (@chunks) { 612713214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 612813214adfSAndy Whitcroft 6129773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 6130773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 6131773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 6132773647a0SAndy Whitcroft 6133aad4f614SJoe Perches $allowed[$allow] = 0; 6134773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 6135773647a0SAndy Whitcroft 6136773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 6137773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 6138773647a0SAndy Whitcroft 6139773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 6140cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 6141cf655043SAndy Whitcroft 6142773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 614313214adfSAndy Whitcroft 614413214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 614513214adfSAndy Whitcroft 6146aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 6147cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 6148cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 6149aad4f614SJoe Perches $allowed[$allow] = 1; 615013214adfSAndy Whitcroft } 615113214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 6152cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 6153aad4f614SJoe Perches $allowed[$allow] = 1; 615413214adfSAndy Whitcroft } 6155cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 6156cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 6157aad4f614SJoe Perches $allowed[$allow] = 1; 615813214adfSAndy Whitcroft } 6159aad4f614SJoe Perches $allow++; 616013214adfSAndy Whitcroft } 6161aad4f614SJoe Perches if ($seen) { 6162aad4f614SJoe Perches my $sum_allowed = 0; 6163aad4f614SJoe Perches foreach (@allowed) { 6164aad4f614SJoe Perches $sum_allowed += $_; 6165aad4f614SJoe Perches } 6166aad4f614SJoe Perches if ($sum_allowed == 0) { 6167000d1cc1SJoe Perches WARN("BRACES", 6168000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 6169aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 6170aad4f614SJoe Perches $seen != $allow) { 6171aad4f614SJoe Perches CHK("BRACES", 6172aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 6173aad4f614SJoe Perches } 617413214adfSAndy Whitcroft } 617513214adfSAndy Whitcroft } 617613214adfSAndy Whitcroft } 6177773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 617813214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 6179cf655043SAndy Whitcroft my $allowed = 0; 6180f0a594c1SAndy Whitcroft 6181cf655043SAndy Whitcroft # Check the pre-context. 6182cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 6183cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 6184cf655043SAndy Whitcroft $allowed = 1; 6185f0a594c1SAndy Whitcroft } 6186773647a0SAndy Whitcroft 6187773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 6188773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 6189773647a0SAndy Whitcroft 6190cf655043SAndy Whitcroft # Check the condition. 6191cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 6192773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 6193cf655043SAndy Whitcroft if (defined $cond) { 6194773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 6195cf655043SAndy Whitcroft } 6196cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 6197cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 6198cf655043SAndy Whitcroft $allowed = 1; 6199cf655043SAndy Whitcroft } 6200cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 6201cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 6202cf655043SAndy Whitcroft $allowed = 1; 6203cf655043SAndy Whitcroft } 6204cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 6205cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 6206cf655043SAndy Whitcroft $allowed = 1; 6207cf655043SAndy Whitcroft } 6208cf655043SAndy Whitcroft # Check the post-context. 6209cf655043SAndy Whitcroft if (defined $chunks[1]) { 6210cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 6211cf655043SAndy Whitcroft if (defined $cond) { 6212773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 6213cf655043SAndy Whitcroft } 6214cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 6215cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 6216cf655043SAndy Whitcroft $allowed = 1; 6217cf655043SAndy Whitcroft } 6218cf655043SAndy Whitcroft } 6219cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 6220f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 6221e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6222cf655043SAndy Whitcroft 6223000d1cc1SJoe Perches WARN("BRACES", 6224000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 6225f0a594c1SAndy Whitcroft } 6226f0a594c1SAndy Whitcroft } 6227f0a594c1SAndy Whitcroft 6228e4c5babdSJoe Perches# check for single line unbalanced braces 622995330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 623095330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 6231e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 6232e4c5babdSJoe Perches } 6233e4c5babdSJoe Perches 62340979ae66SJoe Perches# check for unnecessary blank lines around braces 623577b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 6236f8e58219SJoe Perches if (CHK("BRACES", 6237f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 6238f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 6239f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6240f8e58219SJoe Perches } 62410979ae66SJoe Perches } 624277b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 6243f8e58219SJoe Perches if (CHK("BRACES", 6244f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 6245f8e58219SJoe Perches $fix) { 6246f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 6247f8e58219SJoe Perches } 62480979ae66SJoe Perches } 62490979ae66SJoe Perches 62504a0df2efSAndy Whitcroft# no volatiles please 62516c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 62526c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 6253000d1cc1SJoe Perches WARN("VOLATILE", 62548c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 62554a0df2efSAndy Whitcroft } 62564a0df2efSAndy Whitcroft 62575e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 62585e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 62595e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 62605e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 626133acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 62625e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 62635e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 62645e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 62655e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 62665e4f6ba5SJoe Perches $fix && 62675e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 62685e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 62695e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 62705e4f6ba5SJoe Perches my $comma_close = ""; 62715e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 62725e4f6ba5SJoe Perches $comma_close = $1; 62735e4f6ba5SJoe Perches } 62745e4f6ba5SJoe Perches 62755e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 62765e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 62775e4f6ba5SJoe Perches my $fixedline = $prevrawline; 62785e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 62795e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 62805e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 62815e4f6ba5SJoe Perches $fixedline = $rawline; 62825e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 62835e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 62845e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 62855e4f6ba5SJoe Perches } 62865e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 62875e4f6ba5SJoe Perches } 62885e4f6ba5SJoe Perches } 62895e4f6ba5SJoe Perches 62905e4f6ba5SJoe Perches# check for missing a space in a string concatenation 62915e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 62925e4f6ba5SJoe Perches WARN('MISSING_SPACE', 62935e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 62945e4f6ba5SJoe Perches } 62955e4f6ba5SJoe Perches 629677cb8546SJoe Perches# check for an embedded function name in a string when the function is known 6297e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 6298e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 6299e4b7d309SJoe Perches# function declarations 630077cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 630177cb8546SJoe Perches defined($context_function) && 6302e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 6303e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 630477cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 6305e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 630677cb8546SJoe Perches } 630777cb8546SJoe Perches 6308adb2da82SJoe Perches# check for unnecessary function tracing like uses 6309adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like 6310adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions 6311adb2da82SJoe Perches if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) { 6312adb2da82SJoe Perches if (WARN("TRACING_LOGGING", 6313adb2da82SJoe Perches "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) && 6314adb2da82SJoe Perches $fix) { 6315adb2da82SJoe Perches fix_delete_line($fixlinenr, $rawline); 6316adb2da82SJoe Perches } 6317adb2da82SJoe Perches } 6318adb2da82SJoe Perches 63195e4f6ba5SJoe Perches# check for spaces before a quoted newline 63205e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 63215e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 63225e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 63235e4f6ba5SJoe Perches $fix) { 63245e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 63255e4f6ba5SJoe Perches } 63265e4f6ba5SJoe Perches 63275e4f6ba5SJoe Perches } 63285e4f6ba5SJoe Perches 6329f17dba4fSJoe Perches# concatenated string without spaces between elements 6330d2af5aa6SJoe Perches if ($line =~ /$String[A-Z_]/ || 6331d2af5aa6SJoe Perches ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) { 633279682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 633379682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 633479682c0cSJoe Perches $fix) { 633579682c0cSJoe Perches while ($line =~ /($String)/g) { 633679682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 633779682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 633879682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 633979682c0cSJoe Perches } 634079682c0cSJoe Perches } 6341f17dba4fSJoe Perches } 6342f17dba4fSJoe Perches 634390ad30e5SJoe Perches# uncoalesced string fragments 6344d2af5aa6SJoe Perches if ($line =~ /$String\s*[Lu]?"/) { 634579682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 634679682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 634779682c0cSJoe Perches $fix) { 634879682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 634979682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 635079682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 635179682c0cSJoe Perches } 635279682c0cSJoe Perches } 635390ad30e5SJoe Perches } 635490ad30e5SJoe Perches 6355522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 6356522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 6357522b837cSAlexey Dobriyan my $show_Z = 1; 63585e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 6359522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 63605e4f6ba5SJoe Perches $string =~ s/%%/__/g; 6361522b837cSAlexey Dobriyan # check for %L 6362522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 63635e4f6ba5SJoe Perches WARN("PRINTF_L", 6364522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 6365522b837cSAlexey Dobriyan $show_L = 0; 63665e4f6ba5SJoe Perches } 6367522b837cSAlexey Dobriyan # check for %Z 6368522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 6369522b837cSAlexey Dobriyan WARN("PRINTF_Z", 6370522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 6371522b837cSAlexey Dobriyan $show_Z = 0; 6372522b837cSAlexey Dobriyan } 6373522b837cSAlexey Dobriyan # check for 0x<decimal> 6374522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 6375522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 63766e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 63776e300757SJoe Perches } 63785e4f6ba5SJoe Perches } 63795e4f6ba5SJoe Perches 63805e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 63813f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 63825e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 63835e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 63845e4f6ba5SJoe Perches } 63855e4f6ba5SJoe Perches 638600df344fSAndy Whitcroft# warn about #if 0 6387c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 638860f89010SPrakruthi Deepak Heragu WARN("IF_0", 638960f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 639060f89010SPrakruthi Deepak Heragu } 639160f89010SPrakruthi Deepak Heragu 639260f89010SPrakruthi Deepak Heragu# warn about #if 1 639360f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 639460f89010SPrakruthi Deepak Heragu WARN("IF_1", 639560f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 63964a0df2efSAndy Whitcroft } 63974a0df2efSAndy Whitcroft 639803df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 639903df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 6400100425deSJoe Perches my $tested = quotemeta($1); 6401100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 6402100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 6403100425deSJoe Perches my $func = $1; 6404100425deSJoe Perches if (WARN('NEEDLESS_IF', 6405100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 6406100425deSJoe Perches $fix) { 6407100425deSJoe Perches my $do_fix = 1; 6408100425deSJoe Perches my $leading_tabs = ""; 6409100425deSJoe Perches my $new_leading_tabs = ""; 6410100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 6411100425deSJoe Perches $leading_tabs = $1; 6412100425deSJoe Perches } else { 6413100425deSJoe Perches $do_fix = 0; 6414100425deSJoe Perches } 6415100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 6416100425deSJoe Perches $new_leading_tabs = $1; 6417100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 6418100425deSJoe Perches $do_fix = 0; 6419100425deSJoe Perches } 6420100425deSJoe Perches } else { 6421100425deSJoe Perches $do_fix = 0; 6422100425deSJoe Perches } 6423100425deSJoe Perches if ($do_fix) { 6424100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6425100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 6426100425deSJoe Perches } 6427100425deSJoe Perches } 64284c432a8fSGreg Kroah-Hartman } 64294c432a8fSGreg Kroah-Hartman } 6430f0a594c1SAndy Whitcroft 6431ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 6432ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 6433ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 6434ebfdc409SJoe Perches (defined $1 || defined $3) && 6435ebfdc409SJoe Perches $linenr > 3) { 6436ebfdc409SJoe Perches my $testval = $2; 6437ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 6438ebfdc409SJoe Perches 6439ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 6440ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 6441ebfdc409SJoe Perches 6442e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 6443e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 6444ebfdc409SJoe Perches WARN("OOM_MESSAGE", 6445ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 6446ebfdc409SJoe Perches } 6447ebfdc409SJoe Perches } 6448ebfdc409SJoe Perches 6449f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 6450dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 6451f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 6452f78d98f6SJoe Perches my $level = $1; 6453f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 6454f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 6455f78d98f6SJoe Perches $fix) { 6456f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 6457f78d98f6SJoe Perches } 6458f78d98f6SJoe Perches } 6459f78d98f6SJoe Perches 646045c55e92SJoe Perches# check for logging continuations 646145c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 646245c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 646345c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 646445c55e92SJoe Perches } 646545c55e92SJoe Perches 646670eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions 646770eb2275SDwaipayan Ray if (defined $stat && 646870eb2275SDwaipayan Ray $line =~ /\b$logFunctions\s*\(/ && 646970eb2275SDwaipayan Ray index($stat, '"') >= 0) { 647070eb2275SDwaipayan Ray my $lc = $stat =~ tr@\n@@; 647170eb2275SDwaipayan Ray $lc = $lc + $linenr; 647270eb2275SDwaipayan Ray my $stat_real = get_stat_real($linenr, $lc); 647370eb2275SDwaipayan Ray pos($stat_real) = index($stat_real, '"'); 647470eb2275SDwaipayan Ray while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { 647570eb2275SDwaipayan Ray my $pspec = $1; 647670eb2275SDwaipayan Ray my $h = $2; 647770eb2275SDwaipayan Ray my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; 647870eb2275SDwaipayan Ray if (WARN("UNNECESSARY_MODIFIER", 647970eb2275SDwaipayan Ray "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && 648070eb2275SDwaipayan Ray $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { 648170eb2275SDwaipayan Ray my $nspec = $pspec; 648270eb2275SDwaipayan Ray $nspec =~ s/h//g; 648370eb2275SDwaipayan Ray $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; 648470eb2275SDwaipayan Ray } 648570eb2275SDwaipayan Ray } 648670eb2275SDwaipayan Ray } 648770eb2275SDwaipayan Ray 6488abb08a53SJoe Perches# check for mask then right shift without a parentheses 64895b57980dSJoe Perches if ($perl_version_ok && 6490abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 6491abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 6492abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 6493abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 6494abb08a53SJoe Perches } 6495abb08a53SJoe Perches 6496b75ac618SJoe Perches# check for pointer comparisons to NULL 64975b57980dSJoe Perches if ($perl_version_ok) { 6498b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 6499b75ac618SJoe Perches my $val = $1; 6500b75ac618SJoe Perches my $equal = "!"; 6501b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 6502b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 6503b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 6504b75ac618SJoe Perches $fix) { 6505b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 6506b75ac618SJoe Perches } 6507b75ac618SJoe Perches } 6508b75ac618SJoe Perches } 6509b75ac618SJoe Perches 65108716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 65118716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 65128716de38SJoe Perches my $attr = $1; 65138716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 65148716de38SJoe Perches my $ptr = $1; 65158716de38SJoe Perches my $var = $2; 65168716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 65178716de38SJoe Perches ERROR("MISPLACED_INIT", 65188716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 65198716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 65208716de38SJoe Perches WARN("MISPLACED_INIT", 65218716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 65228716de38SJoe Perches $fix) { 6523194f66fcSJoe 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; 65248716de38SJoe Perches } 65258716de38SJoe Perches } 65268716de38SJoe Perches } 65278716de38SJoe Perches 6528e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 6529e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 6530e970b884SJoe Perches my $attr = $1; 6531e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 6532e970b884SJoe Perches my $attr_prefix = $1; 6533e970b884SJoe Perches my $attr_type = $2; 6534e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6535e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 6536e970b884SJoe Perches $fix) { 6537194f66fcSJoe Perches $fixed[$fixlinenr] =~ 6538e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 6539e970b884SJoe Perches } 6540e970b884SJoe Perches } 6541e970b884SJoe Perches 6542e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 6543e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 6544e970b884SJoe Perches my $attr = $1; 6545e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6546e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 6547e970b884SJoe Perches $fix) { 6548194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 6549e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 6550e970b884SJoe Perches $lead = rtrim($1); 6551e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 6552e970b884SJoe Perches $lead = "${lead}const "; 6553194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 6554e970b884SJoe Perches } 6555e970b884SJoe Perches } 6556e970b884SJoe Perches 6557c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 6558c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 6559c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 6560c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 6561c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 6562c17893c7SJoe Perches $fix) { 6563c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 6564c17893c7SJoe Perches } 6565c17893c7SJoe Perches } 6566c17893c7SJoe Perches 6567fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 6568fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 6569fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 6570fbdb8138SJoe Perches my $constant_func = $1; 6571fbdb8138SJoe Perches my $func = $constant_func; 6572fbdb8138SJoe Perches $func =~ s/^__constant_//; 6573fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 6574fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 6575fbdb8138SJoe Perches $fix) { 6576194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 6577fbdb8138SJoe Perches } 6578fbdb8138SJoe Perches } 6579fbdb8138SJoe Perches 65801a15a250SPatrick Pannuto# prefer usleep_range over udelay 658137581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 658243c1d77cSJoe Perches my $delay = $1; 65831a15a250SPatrick Pannuto # ignore udelay's < 10, however 658443c1d77cSJoe Perches if (! ($delay < 10) ) { 6585000d1cc1SJoe Perches CHK("USLEEP_RANGE", 6586458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 658743c1d77cSJoe Perches } 658843c1d77cSJoe Perches if ($delay > 2000) { 658943c1d77cSJoe Perches WARN("LONG_UDELAY", 659043c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 65911a15a250SPatrick Pannuto } 65921a15a250SPatrick Pannuto } 65931a15a250SPatrick Pannuto 659409ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 659509ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 659609ef8725SPatrick Pannuto if ($1 < 20) { 6597000d1cc1SJoe Perches WARN("MSLEEP", 6598458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 659909ef8725SPatrick Pannuto } 660009ef8725SPatrick Pannuto } 660109ef8725SPatrick Pannuto 660236ec1939SJoe Perches# check for comparisons of jiffies 660336ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 660436ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 660536ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 660636ec1939SJoe Perches } 660736ec1939SJoe Perches 66089d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 66099d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 66109d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 66119d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 66129d7a34a5SJoe Perches } 66139d7a34a5SJoe Perches 661400df344fSAndy Whitcroft# warn about #ifdefs in C files 6615c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 661600df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 661700df344fSAndy Whitcroft# print "$herecurr"; 661800df344fSAndy Whitcroft# $clean = 0; 661900df344fSAndy Whitcroft# } 662000df344fSAndy Whitcroft 662122f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 6622c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 66233705ce5bSJoe Perches if (ERROR("SPACING", 66243705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 66253705ce5bSJoe Perches $fix) { 6626194f66fcSJoe Perches $fixed[$fixlinenr] =~ 66273705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 66283705ce5bSJoe Perches } 66293705ce5bSJoe Perches 663022f2a2efSAndy Whitcroft } 663122f2a2efSAndy Whitcroft 66324a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 6633171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 6634171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 66354a0df2efSAndy Whitcroft my $which = $1; 66364a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6637000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 6638000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 66394a0df2efSAndy Whitcroft } 66404a0df2efSAndy Whitcroft } 66414a0df2efSAndy Whitcroft# check for memory barriers without a comment. 6642402c2553SMichael S. Tsirkin 6643402c2553SMichael S. Tsirkin my $barriers = qr{ 6644402c2553SMichael S. Tsirkin mb| 6645402c2553SMichael S. Tsirkin rmb| 6646ad83ec6cSWill Deacon wmb 6647402c2553SMichael S. Tsirkin }x; 6648402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 6649402c2553SMichael S. Tsirkin mb__before_atomic| 6650402c2553SMichael S. Tsirkin mb__after_atomic| 6651402c2553SMichael S. Tsirkin store_release| 6652402c2553SMichael S. Tsirkin load_acquire| 6653402c2553SMichael S. Tsirkin store_mb| 6654402c2553SMichael S. Tsirkin (?:$barriers) 6655402c2553SMichael S. Tsirkin }x; 6656402c2553SMichael S. Tsirkin my $all_barriers = qr{ 6657402c2553SMichael S. Tsirkin (?:$barriers)| 665843e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 665943e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 6660402c2553SMichael S. Tsirkin }x; 6661402c2553SMichael S. Tsirkin 6662402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 66634a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6664c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 6665000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 66664a0df2efSAndy Whitcroft } 66674a0df2efSAndy Whitcroft } 66683ad81779SPaul E. McKenney 6669f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 6670f4073b0fSMichael S. Tsirkin 6671f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 6672f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 6673f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 6674f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 6675f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 6676f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 6677f4073b0fSMichael S. Tsirkin } 6678f4073b0fSMichael S. Tsirkin 6679cb426e99SJoe Perches# check for waitqueue_active without a comment. 6680cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 6681cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 6682cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 6683cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 6684cb426e99SJoe Perches } 6685cb426e99SJoe Perches } 66863ad81779SPaul E. McKenney 66875099a722SMarco Elver# check for data_race without a comment. 66885099a722SMarco Elver if ($line =~ /\bdata_race\s*\(/) { 66895099a722SMarco Elver if (!ctx_has_comment($first_line, $linenr)) { 66905099a722SMarco Elver WARN("DATA_RACE", 66915099a722SMarco Elver "data_race without comment\n" . $herecurr); 66925099a722SMarco Elver } 66935099a722SMarco Elver } 66945099a722SMarco Elver 66954a0df2efSAndy Whitcroft# check of hardware specific defines 6696c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 6697000d1cc1SJoe Perches CHK("ARCH_DEFINES", 6698000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 66990a920b5bSAndy Whitcroft } 6700653d4876SAndy Whitcroft 6701596ed45bSJoe Perches# check that the storage class is not after a type 6702596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 6703000d1cc1SJoe Perches WARN("STORAGE_CLASS", 6704596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 6705596ed45bSJoe Perches } 6706596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 6707596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 6708596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 6709596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 6710596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 6711596ed45bSJoe Perches WARN("STORAGE_CLASS", 6712596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 6713d4977c78STobias Klauser } 6714d4977c78STobias Klauser 6715de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 6716de7d4f0eSAndy Whitcroft# storage class and type. 67179c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 67189c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 6719000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 6720000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 6721de7d4f0eSAndy Whitcroft } 6722de7d4f0eSAndy Whitcroft 67238905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 67242b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 67252b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 6726d5e616fcSJoe Perches if (WARN("INLINE", 6727d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 6728d5e616fcSJoe Perches $fix) { 6729194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 6730d5e616fcSJoe Perches 6731d5e616fcSJoe Perches } 67328905a67cSAndy Whitcroft } 67338905a67cSAndy Whitcroft 67347ebe1d17SDwaipayan Ray# Check for compiler attributes 67352b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 67367ebe1d17SDwaipayan Ray $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { 67377ebe1d17SDwaipayan Ray my $attr = $1; 67387ebe1d17SDwaipayan Ray $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; 67397ebe1d17SDwaipayan Ray 67407ebe1d17SDwaipayan Ray my %attr_list = ( 67410830aab0SJoe Perches "alias" => "__alias", 67427ebe1d17SDwaipayan Ray "aligned" => "__aligned", 67437ebe1d17SDwaipayan Ray "always_inline" => "__always_inline", 67447ebe1d17SDwaipayan Ray "assume_aligned" => "__assume_aligned", 67457ebe1d17SDwaipayan Ray "cold" => "__cold", 67467ebe1d17SDwaipayan Ray "const" => "__attribute_const__", 67477ebe1d17SDwaipayan Ray "copy" => "__copy", 67487ebe1d17SDwaipayan Ray "designated_init" => "__designated_init", 67497ebe1d17SDwaipayan Ray "externally_visible" => "__visible", 67507ebe1d17SDwaipayan Ray "format" => "printf|scanf", 67517ebe1d17SDwaipayan Ray "gnu_inline" => "__gnu_inline", 67527ebe1d17SDwaipayan Ray "malloc" => "__malloc", 67537ebe1d17SDwaipayan Ray "mode" => "__mode", 67547ebe1d17SDwaipayan Ray "no_caller_saved_registers" => "__no_caller_saved_registers", 67557ebe1d17SDwaipayan Ray "noclone" => "__noclone", 67567ebe1d17SDwaipayan Ray "noinline" => "noinline", 67577ebe1d17SDwaipayan Ray "nonstring" => "__nonstring", 67587ebe1d17SDwaipayan Ray "noreturn" => "__noreturn", 67597ebe1d17SDwaipayan Ray "packed" => "__packed", 67607ebe1d17SDwaipayan Ray "pure" => "__pure", 6761339f29d9SJoe Perches "section" => "__section", 67620830aab0SJoe Perches "used" => "__used", 67630830aab0SJoe Perches "weak" => "__weak" 67647ebe1d17SDwaipayan Ray ); 67657ebe1d17SDwaipayan Ray 67667ebe1d17SDwaipayan Ray while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { 6767339f29d9SJoe Perches my $orig_attr = $1; 67687ebe1d17SDwaipayan Ray my $params = ''; 67697ebe1d17SDwaipayan Ray $params = $2 if defined($2); 6770339f29d9SJoe Perches my $curr_attr = $orig_attr; 67717ebe1d17SDwaipayan Ray $curr_attr =~ s/^[\s_]+|[\s_]+$//g; 67727ebe1d17SDwaipayan Ray if (exists($attr_list{$curr_attr})) { 6773339f29d9SJoe Perches my $new = $attr_list{$curr_attr}; 67747ebe1d17SDwaipayan Ray if ($curr_attr eq "format" && $params) { 67757ebe1d17SDwaipayan Ray $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; 6776339f29d9SJoe Perches $new = "__$1\($2"; 67777ebe1d17SDwaipayan Ray } else { 6778339f29d9SJoe Perches $new = "$new$params"; 67797ebe1d17SDwaipayan Ray } 67807ebe1d17SDwaipayan Ray if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 6781339f29d9SJoe Perches "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && 67827ebe1d17SDwaipayan Ray $fix) { 6783339f29d9SJoe Perches my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; 6784339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/$remove//; 6785339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; 6786339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; 6787339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; 67887ebe1d17SDwaipayan Ray } 678939b7e287SJoe Perches } 6790462811d9SJoe Perches } 6791462811d9SJoe Perches 67927ebe1d17SDwaipayan Ray # Check for __attribute__ unused, prefer __always_unused or __maybe_unused 67937ebe1d17SDwaipayan Ray if ($attr =~ /^_*unused/) { 67947ebe1d17SDwaipayan Ray WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 67957ebe1d17SDwaipayan Ray "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); 6796d5e616fcSJoe Perches } 67976061d949SJoe Perches } 67986061d949SJoe Perches 6799619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 68005b57980dSJoe Perches if ($perl_version_ok && 6801619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 6802619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 6803619a908aSJoe Perches $line =~ /\b__weak\b/)) { 6804619a908aSJoe Perches ERROR("WEAK_DECLARATION", 6805619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 6806619a908aSJoe Perches } 6807619a908aSJoe Perches 6808fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 6809e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6810fd39f904STomas Winkler $realfile !~ m@\btools/@ && 6811e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 6812e6176fa4SJoe Perches my $type = $1; 6813e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 6814e6176fa4SJoe Perches $type = $1; 6815e6176fa4SJoe Perches my $kernel_type = 'u'; 6816e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6817e6176fa4SJoe Perches $type =~ /(\d+)/; 6818e6176fa4SJoe Perches $kernel_type .= $1; 6819e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6820e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6821e6176fa4SJoe Perches $fix) { 6822e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6823e6176fa4SJoe Perches } 6824e6176fa4SJoe Perches } 6825e6176fa4SJoe Perches } 6826e6176fa4SJoe Perches 6827938224b5SJoe Perches# check for cast of C90 native int or longer types constants 6828938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6829938224b5SJoe Perches my $cast = $1; 6830938224b5SJoe Perches my $const = $2; 6831938224b5SJoe Perches my $suffix = ""; 6832938224b5SJoe Perches my $newconst = $const; 6833938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 6834938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6835938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6836938224b5SJoe Perches $suffix .= 'LL'; 6837938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 6838938224b5SJoe Perches $suffix .= 'L'; 6839938224b5SJoe Perches } 68400972b8bfSJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 68410972b8bfSJoe Perches "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) && 68420972b8bfSJoe Perches $fix) { 6843938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6844938224b5SJoe Perches } 6845938224b5SJoe Perches } 6846938224b5SJoe Perches 68478f53a9b8SJoe Perches# check for sizeof(&) 68488f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6849000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 6850000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 68518f53a9b8SJoe Perches } 68528f53a9b8SJoe Perches 685366c80b60SJoe Perches# check for sizeof without parenthesis 685466c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 6855d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 6856d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6857d5e616fcSJoe Perches $fix) { 6858194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6859d5e616fcSJoe Perches } 686066c80b60SJoe Perches } 686166c80b60SJoe Perches 686288982feaSJoe Perches# check for struct spinlock declarations 686388982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 686488982feaSJoe Perches WARN("USE_SPINLOCK_T", 686588982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 686688982feaSJoe Perches } 686788982feaSJoe Perches 6868a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 686906668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6870a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 6871caac1d5fSHeba Aamer $fmt =~ s/%%//g; 6872caac1d5fSHeba Aamer if ($fmt !~ /%/) { 6873d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 6874d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6875d5e616fcSJoe Perches $fix) { 6876194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6877d5e616fcSJoe Perches } 6878a6962d72SJoe Perches } 6879a6962d72SJoe Perches } 6880a6962d72SJoe Perches 68810b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 68825b57980dSJoe Perches if ($perl_version_ok && 68830b523769SJoe Perches defined $stat && 68840b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 68850b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6886e3c6bc95STobin C. Harding my $stat_real; 6887e3c6bc95STobin C. Harding 68880b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 68890b523769SJoe Perches $lc = $lc + $linenr; 68900b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6891ffe07513SJoe Perches my $specifier; 6892ffe07513SJoe Perches my $extension; 68933bd32d6aSSakari Ailus my $qualifier; 6894ffe07513SJoe Perches my $bad_specifier = ""; 68950b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 68960b523769SJoe Perches $fmt =~ s/%%//g; 6897e3c6bc95STobin C. Harding 68983bd32d6aSSakari Ailus while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 6899e3c6bc95STobin C. Harding $specifier = $1; 6900e3c6bc95STobin C. Harding $extension = $2; 69013bd32d6aSSakari Ailus $qualifier = $3; 6902af612e43SSakari Ailus if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 69033bd32d6aSSakari Ailus ($extension eq "f" && 6904af612e43SSakari Ailus defined $qualifier && $qualifier !~ /^w/) || 6905af612e43SSakari Ailus ($extension eq "4" && 6906af612e43SSakari Ailus defined $qualifier && $qualifier !~ /^cc/)) { 6907e3c6bc95STobin C. Harding $bad_specifier = $specifier; 69080b523769SJoe Perches last; 69090b523769SJoe Perches } 6910e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6911e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6912e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 69130b523769SJoe Perches } 6914e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6915e3c6bc95STobin 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"); 6916e3c6bc95STobin C. Harding } 6917e3c6bc95STobin C. Harding } 6918e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 69192a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6920de48fa1aSMiguel Ojeda my $msg_level = \&WARN; 69211df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 69221df7338aSSergey Senozhatsky my $use = ""; 6923e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 69241df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6925e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 6926de48fa1aSMiguel Ojeda } elsif ($bad_specifier =~ /pA/) { 6927de48fa1aSMiguel Ojeda $use = " - '%pA' is only intended to be used from Rust code"; 6928de48fa1aSMiguel Ojeda $msg_level = \&ERROR; 69291df7338aSSergey Senozhatsky } 69302a9f9d85STobin C. Harding 6931de48fa1aSMiguel Ojeda &{$msg_level}("VSPRINTF_POINTER_EXTENSION", 6932e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6933e3c6bc95STobin C. Harding } 69340b523769SJoe Perches } 69350b523769SJoe Perches } 69360b523769SJoe Perches 6937554e165cSAndy Whitcroft# Check for misused memsets 69385b57980dSJoe Perches if ($perl_version_ok && 6939d1fe9c09SJoe Perches defined $stat && 69409e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6941554e165cSAndy Whitcroft 6942d7c76ba7SJoe Perches my $ms_addr = $2; 6943d1fe9c09SJoe Perches my $ms_val = $7; 6944d1fe9c09SJoe Perches my $ms_size = $12; 6945d7c76ba7SJoe Perches 6946554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6947554e165cSAndy Whitcroft ERROR("MEMSET", 6948d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6949554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6950554e165cSAndy Whitcroft WARN("MEMSET", 6951d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6952d7c76ba7SJoe Perches } 6953d7c76ba7SJoe Perches } 6954d7c76ba7SJoe Perches 695598a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 69565b57980dSJoe Perches# if ($perl_version_ok && 6957f333195dSJoe Perches# defined $stat && 6958f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6959f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6960f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6961f333195dSJoe Perches# $fix) { 6962f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6963f333195dSJoe Perches# } 6964f333195dSJoe Perches# } 696598a9bba5SJoe Perches 6966b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 69675b57980dSJoe Perches# if ($perl_version_ok && 6968f333195dSJoe Perches# defined $stat && 6969f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6970f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6971f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6972f333195dSJoe Perches# } 6973b6117d17SMateusz Kulikowski 69748617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 69758617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 69765b57980dSJoe Perches# if ($perl_version_ok && 6977f333195dSJoe Perches# defined $stat && 6978f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6979f333195dSJoe Perches# 6980f333195dSJoe Perches# my $ms_val = $7; 6981f333195dSJoe Perches# 6982f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6983f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6984f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6985f333195dSJoe Perches# $fix) { 6986f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6987f333195dSJoe Perches# } 6988f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6989f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6990f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6991f333195dSJoe Perches# $fix) { 6992f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6993f333195dSJoe Perches# } 6994f333195dSJoe Perches# } 6995f333195dSJoe Perches# } 69968617cd09SMateusz Kulikowski 6997d0f90841SKees Cook# strcpy uses that should likely be strscpy 6998d0f90841SKees Cook if ($line =~ /\bstrcpy\s*\(/) { 6999d0f90841SKees Cook WARN("STRCPY", 7000d0f90841SKees Cook "Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88\n" . $herecurr); 7001d0f90841SKees Cook } 7002d0f90841SKees Cook 70035dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy 70045dbdb2d8SJoe Perches if ($line =~ /\bstrlcpy\s*\(/) { 70055dbdb2d8SJoe Perches WARN("STRLCPY", 7006d0f90841SKees Cook "Prefer strscpy over strlcpy - see: https://github.com/KSPP/linux/issues/89\n" . $herecurr); 7007d0f90841SKees Cook } 7008d0f90841SKees Cook 7009d0f90841SKees Cook# strncpy uses that should likely be strscpy or strscpy_pad 7010d0f90841SKees Cook if ($line =~ /\bstrncpy\s*\(/) { 7011d0f90841SKees Cook WARN("STRNCPY", 7012d0f90841SKees Cook "Prefer strscpy, strscpy_pad, or __nonstring over strncpy - see: https://github.com/KSPP/linux/issues/90\n" . $herecurr); 70135dbdb2d8SJoe Perches } 70145dbdb2d8SJoe Perches 7015d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 70165b57980dSJoe Perches if ($perl_version_ok && 7017d1fe9c09SJoe Perches defined $stat && 7018d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 7019d1fe9c09SJoe Perches if (defined $2 || defined $7) { 7020d7c76ba7SJoe Perches my $call = $1; 7021d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 7022d7c76ba7SJoe Perches my $arg1 = $3; 7023d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 7024d1fe9c09SJoe Perches my $arg2 = $8; 7025d7c76ba7SJoe Perches my $cast; 7026d7c76ba7SJoe Perches 7027d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 7028d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 7029d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 7030d7c76ba7SJoe Perches $cast = $cast1; 7031d7c76ba7SJoe Perches } else { 7032d7c76ba7SJoe Perches $cast = $cast2; 7033d7c76ba7SJoe Perches } 7034d7c76ba7SJoe Perches WARN("MINMAX", 7035d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 7036554e165cSAndy Whitcroft } 7037554e165cSAndy Whitcroft } 7038554e165cSAndy Whitcroft 70394a273195SJoe Perches# check usleep_range arguments 70405b57980dSJoe Perches if ($perl_version_ok && 70414a273195SJoe Perches defined $stat && 70424a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 70434a273195SJoe Perches my $min = $1; 70444a273195SJoe Perches my $max = $7; 70454a273195SJoe Perches if ($min eq $max) { 70464a273195SJoe Perches WARN("USLEEP_RANGE", 7047458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 70484a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 70494a273195SJoe Perches $min > $max) { 70504a273195SJoe Perches WARN("USLEEP_RANGE", 7051458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 70524a273195SJoe Perches } 70534a273195SJoe Perches } 70544a273195SJoe Perches 7055823b794cSJoe Perches# check for naked sscanf 70565b57980dSJoe Perches if ($perl_version_ok && 7057823b794cSJoe Perches defined $stat && 70586c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 7059823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 7060823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 7061823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 7062823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 7063823b794cSJoe Perches $lc = $lc + $linenr; 70642a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 7065823b794cSJoe Perches WARN("NAKED_SSCANF", 7066823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 7067823b794cSJoe Perches } 7068823b794cSJoe Perches 7069afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 70705b57980dSJoe Perches if ($perl_version_ok && 7071afc819abSJoe Perches defined $stat && 7072afc819abSJoe Perches $line =~ /\bsscanf\b/) { 7073afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 7074afc819abSJoe Perches $lc = $lc + $linenr; 70752a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 7076afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 7077afc819abSJoe Perches my $format = $6; 7078afc819abSJoe Perches my $count = $format =~ tr@%@%@; 7079afc819abSJoe Perches if ($count == 1 && 7080afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 7081afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 7082afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 7083afc819abSJoe Perches } 7084afc819abSJoe Perches } 7085afc819abSJoe Perches } 7086afc819abSJoe Perches 708770dc8a48SJoe Perches# check for new externs in .h files. 708870dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 708970dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 7090d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 709170dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 709270dc8a48SJoe Perches $fix) { 7093194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 709470dc8a48SJoe Perches } 709570dc8a48SJoe Perches } 709670dc8a48SJoe Perches 7097de7d4f0eSAndy Whitcroft# check for new externs in .c files. 7098171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 7099c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 7100171ae1a4SAndy Whitcroft { 7101c45dcabdSAndy Whitcroft my $function_name = $1; 7102c45dcabdSAndy Whitcroft my $paren_space = $2; 7103171ae1a4SAndy Whitcroft 7104171ae1a4SAndy Whitcroft my $s = $stat; 7105171ae1a4SAndy Whitcroft if (defined $cond) { 7106171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 7107171ae1a4SAndy Whitcroft } 7108d8b44b58SKees Cook if ($s =~ /^\s*;/) 7109c45dcabdSAndy Whitcroft { 7110000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 7111000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 7112de7d4f0eSAndy Whitcroft } 7113de7d4f0eSAndy Whitcroft 7114171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 7115000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 7116000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 7117171ae1a4SAndy Whitcroft } 71189c9ba34eSAndy Whitcroft 71199c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 71205b2c7334SJim Cromie $stat =~ /^\+extern struct\s+(\w+)\s+(\w+)\[\];/) 71215b2c7334SJim Cromie { 71225b2c7334SJim Cromie my ($st_type, $st_name) = ($1, $2); 71235b2c7334SJim Cromie 71245b2c7334SJim Cromie for my $s (keys %maybe_linker_symbol) { 71255b2c7334SJim Cromie #print "Linker symbol? $st_name : $s\n"; 71265b2c7334SJim Cromie goto LIKELY_LINKER_SYMBOL 71275b2c7334SJim Cromie if $st_name =~ /$s/; 71285b2c7334SJim Cromie } 71295b2c7334SJim Cromie WARN("AVOID_EXTERNS", 71305b2c7334SJim Cromie "found a file-scoped extern type:$st_type name:$st_name in .c file\n" 71315b2c7334SJim Cromie . "is this a linker symbol ?\n" . $herecurr); 71325b2c7334SJim Cromie LIKELY_LINKER_SYMBOL: 71335b2c7334SJim Cromie 71345b2c7334SJim Cromie } elsif ($realfile =~ /\.c$/ && defined $stat && 71359c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 71369c9ba34eSAndy Whitcroft { 7137000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 7138000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 7139171ae1a4SAndy Whitcroft } 7140171ae1a4SAndy Whitcroft 7141a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 7142a0ad7596SJoe Perches if (defined $stat && 7143d8b44b58SKees Cook $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 7144d8b44b58SKees Cook $1 ne "void") { 7145d8b44b58SKees Cook my $args = trim($1); 7146ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 7147ca0d8929SJoe Perches my $arg = trim($1); 7148d8b44b58SKees Cook if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 7149ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 7150ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 7151ca0d8929SJoe Perches } 7152ca0d8929SJoe Perches } 7153ca0d8929SJoe Perches } 7154ca0d8929SJoe Perches 7155a0ad7596SJoe Perches# check for function definitions 71565b57980dSJoe Perches if ($perl_version_ok && 7157a0ad7596SJoe Perches defined $stat && 7158a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 7159a0ad7596SJoe Perches $context_function = $1; 7160a0ad7596SJoe Perches 7161a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 7162a0ad7596SJoe Perches my $ok = 0; 7163a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 7164a0ad7596SJoe Perches my $herectx = $here . "\n"; 7165a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 7166a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 7167a0ad7596SJoe Perches $herectx .= $rl . "\n"; 7168a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 7169a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 7170a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 7171a0ad7596SJoe Perches } 7172a0ad7596SJoe Perches if (!$ok) { 7173a0ad7596SJoe Perches ERROR("OPEN_BRACE", 7174a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 7175a0ad7596SJoe Perches } 7176a0ad7596SJoe Perches } 7177a0ad7596SJoe Perches 7178de7d4f0eSAndy Whitcroft# checks for new __setup's 7179de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 7180de7d4f0eSAndy Whitcroft my $name = $1; 7181de7d4f0eSAndy Whitcroft 7182de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 7183000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 71842581ac7cSTim Froidcoeur "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); 7185de7d4f0eSAndy Whitcroft } 7186653d4876SAndy Whitcroft } 71879c0ca6f9SAndy Whitcroft 7188e29a70f1SJoe Perches# check for pointless casting of alloc functions 7189e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 7190000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 7191000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 71929c0ca6f9SAndy Whitcroft } 719313214adfSAndy Whitcroft 7194a640d25cSJoe Perches# alloc style 7195a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 71965b57980dSJoe Perches if ($perl_version_ok && 7197e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 7198a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 7199a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 7200a640d25cSJoe Perches } 7201a640d25cSJoe Perches 720273f1d07eSGustavo A. R. Silva# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc 72035b57980dSJoe Perches if ($perl_version_ok && 72041b4a2ed4SJoe Perches defined $stat && 720573f1d07eSGustavo A. R. Silva $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 720660a55369SJoe Perches my $oldfunc = $3; 720760a55369SJoe Perches my $a1 = $4; 720860a55369SJoe Perches my $a2 = $10; 720960a55369SJoe Perches my $newfunc = "kmalloc_array"; 721073f1d07eSGustavo A. R. Silva $newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc"); 721173f1d07eSGustavo A. R. Silva $newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc"); 721260a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 721360a55369SJoe Perches my $r1 = $a1; 721460a55369SJoe Perches my $r2 = $a2; 721560a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 721660a55369SJoe Perches $r1 = $a2; 721760a55369SJoe Perches $r2 = $a1; 721860a55369SJoe Perches } 7219e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 7220e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 72211b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 7222e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 7223e3d95a2aSTobin C. Harding 7224e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 72251b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 72261b4a2ed4SJoe Perches $cnt == 1 && 7227e367455aSJoe Perches $fix) { 722873f1d07eSGustavo A. R. Silva $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; 722960a55369SJoe Perches } 723060a55369SJoe Perches } 723160a55369SJoe Perches } 723260a55369SJoe Perches 7233972fdea2SJoe Perches# check for krealloc arg reuse 72345b57980dSJoe Perches if ($perl_version_ok && 72354cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 72364cab63ceSJoe Perches $1 eq $3) { 7237972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 7238972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 7239972fdea2SJoe Perches } 7240972fdea2SJoe Perches 72415ce59ae0SJoe Perches# check for alloc argument mismatch 72423965292aSLiao Chang if ($line =~ /\b((?:devm_)?((?:k|kv)?(calloc|malloc_array)(?:_node)?))\s*\(\s*sizeof\b/) { 72435ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 72445ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 72455ce59ae0SJoe Perches } 72465ce59ae0SJoe Perches 7247caf2a54fSJoe Perches# check for multiple semicolons 7248caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 7249d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 7250d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 7251d5e616fcSJoe Perches $fix) { 7252194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 7253d5e616fcSJoe Perches } 7254d1e2ad07SJoe Perches } 7255d1e2ad07SJoe Perches 7256cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 7257cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 7258cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 72590ab90191SJoe Perches my $ull = ""; 72600ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 72610ab90191SJoe Perches if (CHK("BIT_MACRO", 72620ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 72630ab90191SJoe Perches $fix) { 72640ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 72650ab90191SJoe Perches } 72660ab90191SJoe Perches } 72670ab90191SJoe Perches 726850161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) 72693e89ad85SJerome Forissier if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { 727050161266SJoe Perches WARN("IS_ENABLED_CONFIG", 72713e89ad85SJerome Forissier "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); 727250161266SJoe Perches } 727350161266SJoe Perches 72742d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 72753e89ad85SJerome 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*$/) { 72762d632745SJoe Perches my $config = $1; 72772d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 72783e89ad85SJerome Forissier "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && 72792d632745SJoe Perches $fix) { 72802d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 72812d632745SJoe Perches } 72822d632745SJoe Perches } 72832d632745SJoe Perches 7284f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 7285f36d3eb8SJoe Perches my @fallthroughs = ( 7286f36d3eb8SJoe Perches 'fallthrough', 7287f36d3eb8SJoe Perches '@fallthrough@', 7288f36d3eb8SJoe Perches 'lint -fallthrough[ \t]*', 7289f36d3eb8SJoe Perches 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 7290f36d3eb8SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 7291f36d3eb8SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 7292f36d3eb8SJoe Perches 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 7293f36d3eb8SJoe Perches ); 7294f36d3eb8SJoe Perches if ($raw_comment ne '') { 7295f36d3eb8SJoe Perches foreach my $ft (@fallthroughs) { 7296f36d3eb8SJoe Perches if ($raw_comment =~ /$ft/) { 7297f36d3eb8SJoe Perches my $msg_level = \&WARN; 7298f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 7299f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 7300f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 7301f36d3eb8SJoe Perches last; 7302f36d3eb8SJoe Perches } 7303f36d3eb8SJoe Perches } 7304f36d3eb8SJoe Perches } 7305f36d3eb8SJoe Perches 7306d1e2ad07SJoe Perches# check for switch/default statements without a break; 73075b57980dSJoe Perches if ($perl_version_ok && 7308d1e2ad07SJoe Perches defined $stat && 7309d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 7310d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 7311e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 7312e3d95a2aSTobin C. Harding 7313d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 7314d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 7315caf2a54fSJoe Perches } 7316caf2a54fSJoe Perches 731713214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 7318d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 7319d5e616fcSJoe Perches if (WARN("USE_FUNC", 7320d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 7321d5e616fcSJoe Perches $fix) { 7322194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 7323d5e616fcSJoe Perches } 732413214adfSAndy Whitcroft } 7325773647a0SAndy Whitcroft 732662ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 732762ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 732862ec818fSJoe Perches ERROR("DATE_TIME", 732962ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 733062ec818fSJoe Perches } 733162ec818fSJoe Perches 73322c92488aSJoe Perches# check for use of yield() 73332c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 73342c92488aSJoe Perches WARN("YIELD", 73352c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 73362c92488aSJoe Perches } 73372c92488aSJoe Perches 7338179f8f40SJoe Perches# check for comparisons against true and false 7339179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 7340179f8f40SJoe Perches my $lead = $1; 7341179f8f40SJoe Perches my $arg = $2; 7342179f8f40SJoe Perches my $test = $3; 7343179f8f40SJoe Perches my $otype = $4; 7344179f8f40SJoe Perches my $trail = $5; 7345179f8f40SJoe Perches my $op = "!"; 7346179f8f40SJoe Perches 7347179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 7348179f8f40SJoe Perches 7349179f8f40SJoe Perches my $type = lc($otype); 7350179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 7351179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 7352179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 7353179f8f40SJoe Perches $op = ""; 7354179f8f40SJoe Perches } 7355179f8f40SJoe Perches 7356179f8f40SJoe Perches CHK("BOOL_COMPARISON", 7357179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 7358179f8f40SJoe Perches 7359179f8f40SJoe Perches## maybe suggesting a correct construct would better 7360179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 7361179f8f40SJoe Perches 7362179f8f40SJoe Perches } 7363179f8f40SJoe Perches } 7364179f8f40SJoe Perches 73654882720bSThomas Gleixner# check for semaphores initialized locked 73664882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 7367000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 7368000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 7369773647a0SAndy Whitcroft } 73706712d858SJoe Perches 737167d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 737267d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 7373000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 737467d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 7375773647a0SAndy Whitcroft } 73766712d858SJoe Perches 7377ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 7378f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 7379000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 7380ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 7381f3db6639SMichael Ellerman } 73826712d858SJoe Perches 73833d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 73843d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 73853d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 73863d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 73873d709ab5SPaul E. McKenney } 73883d709ab5SPaul E. McKenney 73899189c7e7SJoe Perches# check for deprecated apis 73909189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 73919189c7e7SJoe Perches my $deprecated_api = $1; 73929189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 73939189c7e7SJoe Perches WARN("DEPRECATED_API", 73949189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 73959189c7e7SJoe Perches } 73969189c7e7SJoe Perches 73970f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 7398d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 7399ced69da1SQuentin Monnet if (defined($const_structs) && 7400ced69da1SQuentin Monnet $line !~ /\bconst\b/ && 7401d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 7402000d1cc1SJoe Perches WARN("CONST_STRUCT", 7403d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 74042b6db5cbSAndy Whitcroft } 7405773647a0SAndy Whitcroft 7406773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 7407773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 740835cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS 7409773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 7410c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 7411c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 7412171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 7413171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 741435cdcbfcSPeng Wang $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ && 741535cdcbfcSPeng Wang $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/) 7416773647a0SAndy Whitcroft { 7417000d1cc1SJoe Perches WARN("NR_CPUS", 7418000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 7419773647a0SAndy Whitcroft } 74209c9ba34eSAndy Whitcroft 742152ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 742252ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 742352ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 742452ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 742552ea8506SJoe Perches } 742652ea8506SJoe Perches 7427acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 74285b57980dSJoe Perches if ($perl_version_ok && 7429acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 7430acd9362cSJoe Perches WARN("LIKELY_MISUSE", 7431acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 7432acd9362cSJoe Perches } 7433acd9362cSJoe Perches 7434fbe74541SJoe Perches# return sysfs_emit(foo, fmt, ...) fmt without newline 7435fbe74541SJoe Perches if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ && 7436fbe74541SJoe Perches substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) { 7437fbe74541SJoe Perches my $offset = $+[6] - 1; 7438fbe74541SJoe Perches if (WARN("SYSFS_EMIT", 7439fbe74541SJoe Perches "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) && 7440fbe74541SJoe Perches $fix) { 7441fbe74541SJoe Perches substr($fixed[$fixlinenr], $offset, 0) = '\\n'; 7442fbe74541SJoe Perches } 7443fbe74541SJoe Perches } 7444fbe74541SJoe Perches 74458515e4a7SKees Cook# check for array definition/declarations that should use flexible arrays instead 74468515e4a7SKees Cook if ($sline =~ /^[\+ ]\s*\}(?:\s*__packed)?\s*;\s*$/ && 74478515e4a7SKees Cook $prevline =~ /^\+\s*(?:\}(?:\s*__packed\s*)?|$Type)\s*$Ident\s*\[\s*(0|1)\s*\]\s*;\s*$/) { 74488515e4a7SKees Cook if (ERROR("FLEXIBLE_ARRAY", 74498515e4a7SKees Cook "Use C99 flexible arrays - see https://docs.kernel.org/process/deprecated.html#zero-length-and-one-element-arrays\n" . $hereprev) && 74508515e4a7SKees Cook $1 == '0' && $fix) { 74518515e4a7SKees Cook $fixed[$fixlinenr - 1] =~ s/\[\s*0\s*\]/[]/; 74528515e4a7SKees Cook } 74538515e4a7SKees Cook } 74548515e4a7SKees Cook 7455de3f186fSDenis Efremov# nested likely/unlikely calls 7456de3f186fSDenis Efremov if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 7457de3f186fSDenis Efremov WARN("LIKELY_MISUSE", 7458de3f186fSDenis Efremov "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 7459de3f186fSDenis Efremov } 7460de3f186fSDenis Efremov 7461691d77b6SAndy Whitcroft# whine mightly about in_atomic 7462691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 7463691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 7464000d1cc1SJoe Perches ERROR("IN_ATOMIC", 7465000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 7466f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 7467000d1cc1SJoe Perches WARN("IN_ATOMIC", 7468000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 7469691d77b6SAndy Whitcroft } 7470691d77b6SAndy Whitcroft } 74711704f47bSPeter Zijlstra 747284dd7f19SPaul E. McKenney# Complain about RCU Tasks Trace used outside of BPF (and of course, RCU). 747384dd7f19SPaul E. McKenney our $rcu_trace_funcs = qr{(?x: 747484dd7f19SPaul E. McKenney rcu_read_lock_trace | 747584dd7f19SPaul E. McKenney rcu_read_lock_trace_held | 747684dd7f19SPaul E. McKenney rcu_read_unlock_trace | 747784dd7f19SPaul E. McKenney call_rcu_tasks_trace | 747884dd7f19SPaul E. McKenney synchronize_rcu_tasks_trace | 747984dd7f19SPaul E. McKenney rcu_barrier_tasks_trace | 748084dd7f19SPaul E. McKenney rcu_request_urgent_qs_task 748184dd7f19SPaul E. McKenney )}; 748284dd7f19SPaul E. McKenney our $rcu_trace_paths = qr{(?x: 748384dd7f19SPaul E. McKenney kernel/bpf/ | 748484dd7f19SPaul E. McKenney include/linux/bpf | 748584dd7f19SPaul E. McKenney net/bpf/ | 748684dd7f19SPaul E. McKenney kernel/rcu/ | 748784dd7f19SPaul E. McKenney include/linux/rcu 748884dd7f19SPaul E. McKenney )}; 748984dd7f19SPaul E. McKenney if ($line =~ /\b($rcu_trace_funcs)\s*\(/) { 749084dd7f19SPaul E. McKenney if ($realfile !~ m{^$rcu_trace_paths}) { 749184dd7f19SPaul E. McKenney WARN("RCU_TASKS_TRACE", 749284dd7f19SPaul E. McKenney "use of RCU tasks trace is incorrect outside BPF or core RCU code\n" . $herecurr); 749384dd7f19SPaul E. McKenney } 749484dd7f19SPaul E. McKenney } 749584dd7f19SPaul E. McKenney 74961704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 74971704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 74981704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 74991704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 75001704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 75011704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 7502000d1cc1SJoe Perches ERROR("LOCKDEP", 7503000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 75041704f47bSPeter Zijlstra } 75051704f47bSPeter Zijlstra } 750688f8831cSDave Jones 7507b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 7508b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 7509000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 7510000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 751188f8831cSDave Jones } 75122435880fSJoe Perches 751300180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 751400180468SJoe Perches# and whether or not function naming is typical and if 751500180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 75165b57980dSJoe Perches if ($perl_version_ok && 751700180468SJoe Perches defined $stat && 751800180468SJoe 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*\)/) { 751900180468SJoe Perches my $var = $1; 752000180468SJoe Perches my $perms = $2; 752100180468SJoe Perches my $show = $3; 752200180468SJoe Perches my $store = $4; 752300180468SJoe Perches my $octal_perms = perms_to_octal($perms); 752400180468SJoe Perches if ($show =~ /^${var}_show$/ && 752500180468SJoe Perches $store =~ /^${var}_store$/ && 752600180468SJoe Perches $octal_perms eq "0644") { 752700180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 752800180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 752900180468SJoe Perches $fix) { 753000180468SJoe 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})/; 753100180468SJoe Perches } 753200180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 753300180468SJoe Perches $store =~ /^NULL$/ && 753400180468SJoe Perches $octal_perms eq "0444") { 753500180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 753600180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 753700180468SJoe Perches $fix) { 753800180468SJoe 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})/; 753900180468SJoe Perches } 754000180468SJoe Perches } elsif ($show =~ /^NULL$/ && 754100180468SJoe Perches $store =~ /^${var}_store$/ && 754200180468SJoe Perches $octal_perms eq "0200") { 754300180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 754400180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 754500180468SJoe Perches $fix) { 754600180468SJoe 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})/; 754700180468SJoe Perches } 754800180468SJoe Perches } elsif ($octal_perms eq "0644" || 754900180468SJoe Perches $octal_perms eq "0444" || 755000180468SJoe Perches $octal_perms eq "0200") { 755100180468SJoe Perches my $newshow = "$show"; 755200180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 755300180468SJoe Perches my $newstore = $store; 755400180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 755500180468SJoe Perches my $rename = ""; 755600180468SJoe Perches if ($show ne $newshow) { 755700180468SJoe Perches $rename .= " '$show' to '$newshow'"; 755800180468SJoe Perches } 755900180468SJoe Perches if ($store ne $newstore) { 756000180468SJoe Perches $rename .= " '$store' to '$newstore'"; 756100180468SJoe Perches } 756200180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 756300180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 756400180468SJoe Perches } else { 756500180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 756600180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 756700180468SJoe Perches } 756800180468SJoe Perches } 756900180468SJoe Perches 7570515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 7571515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 757273121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 757373121534SJoe Perches# specific definition of not visible in sysfs. 757473121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 757573121534SJoe Perches# use the default permissions 75765b57980dSJoe Perches if ($perl_version_ok && 7577459cf0aeSJoe Perches defined $stat && 7578515a235eSJoe Perches $line =~ /$mode_perms_search/) { 75792435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 75802435880fSJoe Perches my $func = $entry->[0]; 75812435880fSJoe Perches my $arg_pos = $entry->[1]; 75822435880fSJoe Perches 7583459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 7584459cf0aeSJoe Perches $lc = $lc + $linenr; 75852a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 7586459cf0aeSJoe Perches 75872435880fSJoe Perches my $skip_args = ""; 75882435880fSJoe Perches if ($arg_pos > 1) { 75892435880fSJoe Perches $arg_pos--; 75902435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 75912435880fSJoe Perches } 7592f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 7593459cf0aeSJoe Perches if ($stat =~ /$test/) { 75942435880fSJoe Perches my $val = $1; 75952435880fSJoe Perches $val = $6 if ($skip_args ne ""); 759673121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 759773121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 759873121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 75992435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 7600459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 7601f90774e1SJoe Perches } 7602f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 7603c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 7604459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 76052435880fSJoe Perches } 7606459cf0aeSJoe Perches } 7607459cf0aeSJoe Perches } 7608459cf0aeSJoe Perches } 7609459cf0aeSJoe Perches 7610459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 7611bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 761200180468SJoe Perches my $oval = $1; 761300180468SJoe Perches my $octal = perms_to_octal($oval); 7614f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 7615459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 7616f90774e1SJoe Perches $fix) { 761700180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 76182435880fSJoe Perches } 761913214adfSAndy Whitcroft } 76205a6d20ceSBjorn Andersson 76215a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 76225a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 76235a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 76245a6d20ceSBjorn Andersson my $valid_licenses = qr{ 76255a6d20ceSBjorn Andersson GPL| 76265a6d20ceSBjorn Andersson GPL\ v2| 76275a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 76285a6d20ceSBjorn Andersson Dual\ BSD/GPL| 76295a6d20ceSBjorn Andersson Dual\ MIT/GPL| 76305a6d20ceSBjorn Andersson Dual\ MPL/GPL| 76315a6d20ceSBjorn Andersson Proprietary 76325a6d20ceSBjorn Andersson }x; 76335a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 76345a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 76355a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 76365a6d20ceSBjorn Andersson } 76376e8f42dcSJoe Perches if (!$file && $extracted_string eq '"GPL v2"') { 76386e8f42dcSJoe Perches if (WARN("MODULE_LICENSE", 76396e8f42dcSJoe Perches "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) && 76406e8f42dcSJoe Perches $fix) { 76416e8f42dcSJoe Perches $fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/; 76426e8f42dcSJoe Perches } 76436e8f42dcSJoe Perches } 76445a6d20ceSBjorn Andersson } 76456a8d76cbSMatteo Croce 76466a8d76cbSMatteo Croce# check for sysctl duplicate constants 76476a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 76486a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 76496a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 76506a8d76cbSMatteo Croce } 7651515a235eSJoe Perches } 765213214adfSAndy Whitcroft 765313214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 765413214adfSAndy Whitcroft # so just keep quiet. 765513214adfSAndy Whitcroft if ($#rawlines == -1) { 765613214adfSAndy Whitcroft exit(0); 76570a920b5bSAndy Whitcroft } 76580a920b5bSAndy Whitcroft 76598905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 76608905a67cSAndy Whitcroft # things that appear to be patches. 76618905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 76628905a67cSAndy Whitcroft exit(0); 76638905a67cSAndy Whitcroft } 76648905a67cSAndy Whitcroft 7665e73d2715SDwaipayan Ray # This is not a patch, and we are in 'no-patch' mode so 76668905a67cSAndy Whitcroft # just keep quiet. 76678905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 76688905a67cSAndy Whitcroft exit(0); 76698905a67cSAndy Whitcroft } 76708905a67cSAndy Whitcroft 7671a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 7672000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 7673000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 76740a920b5bSAndy Whitcroft } 7675cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 7676cd261496SGeert Uytterhoeven if ($signoff == 0) { 7677000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 7678000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 767948ca2d8aSDwaipayan Ray } elsif ($authorsignoff != 1) { 768048ca2d8aSDwaipayan Ray # authorsignoff values: 768148ca2d8aSDwaipayan Ray # 0 -> missing sign off 768248ca2d8aSDwaipayan Ray # 1 -> sign off identical 768348ca2d8aSDwaipayan Ray # 2 -> names and addresses match, comments mismatch 768448ca2d8aSDwaipayan Ray # 3 -> addresses match, names different 768548ca2d8aSDwaipayan Ray # 4 -> names match, addresses different 768648ca2d8aSDwaipayan Ray # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match 768748ca2d8aSDwaipayan Ray 768848ca2d8aSDwaipayan Ray my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; 768948ca2d8aSDwaipayan Ray 769048ca2d8aSDwaipayan Ray if ($authorsignoff == 0) { 769148ca2d8aSDwaipayan Ray ERROR("NO_AUTHOR_SIGN_OFF", 7692cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 769348ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 2) { 769448ca2d8aSDwaipayan Ray CHK("FROM_SIGN_OFF_MISMATCH", 769548ca2d8aSDwaipayan Ray "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); 769648ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 3) { 769748ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 769848ca2d8aSDwaipayan Ray "From:/Signed-off-by: email name mismatch: $sob_msg\n"); 769948ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 4) { 770048ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 770148ca2d8aSDwaipayan Ray "From:/Signed-off-by: email address mismatch: $sob_msg\n"); 770248ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 5) { 770348ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 770448ca2d8aSDwaipayan Ray "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); 770548ca2d8aSDwaipayan Ray } 7706cd261496SGeert Uytterhoeven } 77070a920b5bSAndy Whitcroft } 77080a920b5bSAndy Whitcroft 7709f0a594c1SAndy Whitcroft print report_dump(); 771013214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 771113214adfSAndy Whitcroft print "$filename " if ($summary_file); 77126c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 77136c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 77146c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 77156c72ffaaSAndy Whitcroft } 77168905a67cSAndy Whitcroft 7717d2c0a235SAndy Whitcroft if ($quiet == 0) { 7718ef212196SJoe Perches # If there were any defects found and not already fixing them 7719ef212196SJoe Perches if (!$clean and !$fix) { 7720ef212196SJoe Perches print << "EOM" 7721ef212196SJoe Perches 7722ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 7723ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 7724ef212196SJoe PerchesEOM 7725ef212196SJoe Perches } 7726d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 7727d2c0a235SAndy Whitcroft # then suggest that. 7728d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 7729b0781216SMike Frysinger $rpt_cleaners = 0; 7730d8469f16SJoe Perches print << "EOM" 7731d8469f16SJoe Perches 7732d8469f16SJoe PerchesNOTE: Whitespace errors detected. 7733d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 7734d8469f16SJoe PerchesEOM 7735d2c0a235SAndy Whitcroft } 7736d2c0a235SAndy Whitcroft } 7737d2c0a235SAndy Whitcroft 7738d752fcc8SJoe Perches if ($clean == 0 && $fix && 7739d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 7740d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 77419624b8d6SJoe Perches my $newfile = $filename; 77429624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 77433705ce5bSJoe Perches my $linecount = 0; 77443705ce5bSJoe Perches my $f; 77453705ce5bSJoe Perches 7746d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 7747d752fcc8SJoe Perches 77483705ce5bSJoe Perches open($f, '>', $newfile) 77493705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 77503705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 77513705ce5bSJoe Perches $linecount++; 77523705ce5bSJoe Perches if ($file) { 77533705ce5bSJoe Perches if ($linecount > 3) { 77543705ce5bSJoe Perches $fixed_line =~ s/^\+//; 77553705ce5bSJoe Perches print $f $fixed_line . "\n"; 77563705ce5bSJoe Perches } 77573705ce5bSJoe Perches } else { 77583705ce5bSJoe Perches print $f $fixed_line . "\n"; 77593705ce5bSJoe Perches } 77603705ce5bSJoe Perches } 77613705ce5bSJoe Perches close($f); 77623705ce5bSJoe Perches 77633705ce5bSJoe Perches if (!$quiet) { 77643705ce5bSJoe Perches print << "EOM"; 7765d8469f16SJoe Perches 77663705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 77673705ce5bSJoe Perches 77683705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 77693705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 77703705ce5bSJoe Perches 77713705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 77723705ce5bSJoe PerchesNo warranties, expressed or implied... 77733705ce5bSJoe PerchesEOM 77743705ce5bSJoe Perches } 77753705ce5bSJoe Perches } 77763705ce5bSJoe Perches 7777d8469f16SJoe Perches if ($quiet == 0) { 7778d8469f16SJoe Perches print "\n"; 7779d8469f16SJoe Perches if ($clean == 1) { 7780d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 7781d8469f16SJoe Perches } else { 7782d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 77830a920b5bSAndy Whitcroft } 77840a920b5bSAndy Whitcroft } 77850a920b5bSAndy Whitcroft return $clean; 77860a920b5bSAndy Whitcroft} 7787