1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl 2882ea1d6SJoe Perches# SPDX-License-Identifier: GPL-2.0 3882ea1d6SJoe Perches# 4dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit) 500df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 62a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite) 7015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]> 8882ea1d6SJoe Perches# (c) 2010-2018 Joe Perches <[email protected]> 90a920b5bSAndy Whitcroft 100a920b5bSAndy Whitcroftuse strict; 11cb77f0d6SKamil Rytarowskiuse warnings; 12c707a81dSJoe Perchesuse POSIX; 1336061e38SJoe Perchesuse File::Basename; 1436061e38SJoe Perchesuse Cwd 'abs_path'; 1557230297SJoe Perchesuse Term::ANSIColor qw(:constants); 16cd261496SGeert Uytterhoevenuse Encode qw(decode encode); 170a920b5bSAndy Whitcroft 180a920b5bSAndy Whitcroftmy $P = $0; 1936061e38SJoe Perchesmy $D = dirname(abs_path($P)); 200a920b5bSAndy Whitcroft 21000d1cc1SJoe Perchesmy $V = '0.32'; 220a920b5bSAndy Whitcroft 230a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 240a920b5bSAndy Whitcroft 250a920b5bSAndy Whitcroftmy $quiet = 0; 260a920b5bSAndy Whitcroftmy $tree = 1; 270a920b5bSAndy Whitcroftmy $chk_signoff = 1; 280a920b5bSAndy Whitcroftmy $chk_patch = 1; 29773647a0SAndy Whitcroftmy $tst_only; 306c72ffaaSAndy Whitcroftmy $emacs = 0; 318905a67cSAndy Whitcroftmy $terse = 0; 3234d8815fSJoe Perchesmy $showfile = 0; 336c72ffaaSAndy Whitcroftmy $file = 0; 344a593c34SDu, Changbinmy $git = 0; 350dea9f1eSJoe Perchesmy %git_commits = (); 366c72ffaaSAndy Whitcroftmy $check = 0; 372ac73b4fSJoe Perchesmy $check_orig = 0; 388905a67cSAndy Whitcroftmy $summary = 1; 398905a67cSAndy Whitcroftmy $mailback = 0; 4013214adfSAndy Whitcroftmy $summary_file = 0; 41000d1cc1SJoe Perchesmy $show_types = 0; 423beb42ecSJoe Perchesmy $list_types = 0; 433705ce5bSJoe Perchesmy $fix = 0; 449624b8d6SJoe Perchesmy $fix_inplace = 0; 456c72ffaaSAndy Whitcroftmy $root; 460f7f635bSJoe Perchesmy $gitroot = $ENV{'GIT_DIR'}; 470f7f635bSJoe Perches$gitroot = ".git" if !defined($gitroot); 48c2fdda0dSAndy Whitcroftmy %debug; 493445686aSJoe Perchesmy %camelcase = (); 5091bfe484SJoe Perchesmy %use_type = (); 5191bfe484SJoe Perchesmy @use = (); 5291bfe484SJoe Perchesmy %ignore_type = (); 53000d1cc1SJoe Perchesmy @ignore = (); 5477f5b10aSHannes Edermy $help = 0; 55000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 56bdc48fa1SJoe Perchesmy $max_line_length = 100; 57d62a201fSDave Hansenmy $ignore_perl_version = 0; 58d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 5956193274SVadim Bendeburymy $min_conf_desc_length = 4; 6066b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 61ebfd7d62SJoe Perchesmy $codespell = 0; 62f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt"; 63bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 64ced69da1SQuentin Monnetmy $typedefsfile; 65737c0767SJohn Brooksmy $color = "auto"; 6698005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE 67dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE 68dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git'; 69713a09deSAntonio Borneomy $tabsize = 8; 703e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_"; 7177f5b10aSHannes Eder 7277f5b10aSHannes Edersub help { 7377f5b10aSHannes Eder my ($exitcode) = @_; 7477f5b10aSHannes Eder 7577f5b10aSHannes Eder print << "EOM"; 7677f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 7777f5b10aSHannes EderVersion: $V 7877f5b10aSHannes Eder 7977f5b10aSHannes EderOptions: 8077f5b10aSHannes Eder -q, --quiet quiet 8177f5b10aSHannes Eder --no-tree run without a kernel tree 8277f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 8377f5b10aSHannes Eder --patch treat FILE as patchfile (default) 8477f5b10aSHannes Eder --emacs emacs compile window format 8577f5b10aSHannes Eder --terse one line per report 8634d8815fSJoe Perches --showfile emit diffed file position, not input file position 874a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 884a593c34SDu, Changbin single git commit with: 894a593c34SDu, Changbin <rev> 904a593c34SDu, Changbin <rev>^ 914a593c34SDu, Changbin <rev>~n 924a593c34SDu, Changbin multiple git commits with: 934a593c34SDu, Changbin <rev1>..<rev2> 944a593c34SDu, Changbin <rev1>...<rev2> 954a593c34SDu, Changbin <rev>-<count> 964a593c34SDu, Changbin git merges are ignored 9777f5b10aSHannes Eder -f, --file treat FILE as regular source file 9877f5b10aSHannes Eder --subjective, --strict enable more subjective tests 993beb42ecSJoe Perches --list-types list the possible message types 10091bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 101000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 1023beb42ecSJoe Perches --show-types show the specific message type in the output 103bdc48fa1SJoe Perches --max-line-length=n set the maximum line length, (default $max_line_length) 104bdc48fa1SJoe Perches if exceeded, warn on patches 105bdc48fa1SJoe Perches requires --strict for use with --file 10656193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 107bdc48fa1SJoe Perches --tab-size=n set the number of spaces for tab (default $tabsize) 10877f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 10977f5b10aSHannes Eder --no-summary suppress the per-file summary 11077f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 11177f5b10aSHannes Eder --summary-file include the filename in summary 11277f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 11377f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 11477f5b10aSHannes Eder is all off) 11577f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 11677f5b10aSHannes Eder literally 1173705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1183705ce5bSJoe Perches If correctable single-line errors exist, create 1193705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1203705ce5bSJoe Perches with potential errors corrected to the preferred 1213705ce5bSJoe Perches checkpatch style 1229624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1239624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1249624b8d6SJoe Perches file. It's your fault if there's no backup or git 125d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 126d62a201fSDave Hansen runtime errors. 127ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 128f1a63678SMaxim Uvarov (default:/usr/share/codespell/dictionary.txt) 129ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 13075ad8c57SJerome Forissier --typedefsfile Read additional types from this file 131737c0767SJohn Brooks --color[=WHEN] Use colors 'always', 'never', or only when output 132737c0767SJohn Brooks is a terminal ('auto'). Default is 'auto'. 1333e89ad85SJerome Forissier --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default 1343e89ad85SJerome Forissier ${CONFIG_}) 13577f5b10aSHannes Eder -h, --help, --version display this help and exit 13677f5b10aSHannes Eder 13777f5b10aSHannes EderWhen FILE is - read standard input. 13877f5b10aSHannes EderEOM 13977f5b10aSHannes Eder 14077f5b10aSHannes Eder exit($exitcode); 14177f5b10aSHannes Eder} 14277f5b10aSHannes Eder 1433beb42ecSJoe Perchessub uniq { 1443beb42ecSJoe Perches my %seen; 1453beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1463beb42ecSJoe Perches} 1473beb42ecSJoe Perches 1483beb42ecSJoe Perchessub list_types { 1493beb42ecSJoe Perches my ($exitcode) = @_; 1503beb42ecSJoe Perches 1513beb42ecSJoe Perches my $count = 0; 1523beb42ecSJoe Perches 1533beb42ecSJoe Perches local $/ = undef; 1543beb42ecSJoe Perches 1553beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1563beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1573beb42ecSJoe Perches 1583beb42ecSJoe Perches my $text = <$script>; 1593beb42ecSJoe Perches close($script); 1603beb42ecSJoe Perches 1613beb42ecSJoe Perches my @types = (); 1620547fa58SJean Delvare # Also catch when type or level is passed through a variable 1630547fa58SJean Delvare for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { 1643beb42ecSJoe Perches push (@types, $_); 1653beb42ecSJoe Perches } 1663beb42ecSJoe Perches @types = sort(uniq(@types)); 1673beb42ecSJoe Perches print("#\tMessage type\n\n"); 1683beb42ecSJoe Perches foreach my $type (@types) { 1693beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 1703beb42ecSJoe Perches } 1713beb42ecSJoe Perches 1723beb42ecSJoe Perches exit($exitcode); 1733beb42ecSJoe Perches} 1743beb42ecSJoe Perches 175000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 176000d1cc1SJoe Perchesif (-f $conf) { 177000d1cc1SJoe Perches my @conf_args; 178000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 179000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 180000d1cc1SJoe Perches 181000d1cc1SJoe Perches while (<$conffile>) { 182000d1cc1SJoe Perches my $line = $_; 183000d1cc1SJoe Perches 184000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 185000d1cc1SJoe Perches $line =~ s/^\s*//g; 186000d1cc1SJoe Perches $line =~ s/\s+/ /g; 187000d1cc1SJoe Perches 188000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 189000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 190000d1cc1SJoe Perches 191000d1cc1SJoe Perches my @words = split(" ", $line); 192000d1cc1SJoe Perches foreach my $word (@words) { 193000d1cc1SJoe Perches last if ($word =~ m/^#/); 194000d1cc1SJoe Perches push (@conf_args, $word); 195000d1cc1SJoe Perches } 196000d1cc1SJoe Perches } 197000d1cc1SJoe Perches close($conffile); 198000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 199000d1cc1SJoe Perches} 200000d1cc1SJoe Perches 201737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space. 202737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments 203737c0767SJohn Brooksforeach (@ARGV) { 204737c0767SJohn Brooks if ($_ eq "--color" || $_ eq "-color") { 205737c0767SJohn Brooks $_ = "--color=$color"; 206737c0767SJohn Brooks } 207737c0767SJohn Brooks} 208737c0767SJohn Brooks 2090a920b5bSAndy WhitcroftGetOptions( 2106c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 2110a920b5bSAndy Whitcroft 'tree!' => \$tree, 2120a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 2130a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 2146c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 2158905a67cSAndy Whitcroft 'terse!' => \$terse, 21634d8815fSJoe Perches 'showfile!' => \$showfile, 21777f5b10aSHannes Eder 'f|file!' => \$file, 2184a593c34SDu, Changbin 'g|git!' => \$git, 2196c72ffaaSAndy Whitcroft 'subjective!' => \$check, 2206c72ffaaSAndy Whitcroft 'strict!' => \$check, 221000d1cc1SJoe Perches 'ignore=s' => \@ignore, 22291bfe484SJoe Perches 'types=s' => \@use, 223000d1cc1SJoe Perches 'show-types!' => \$show_types, 2243beb42ecSJoe Perches 'list-types!' => \$list_types, 2256cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 22656193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 227713a09deSAntonio Borneo 'tab-size=i' => \$tabsize, 2286c72ffaaSAndy Whitcroft 'root=s' => \$root, 2298905a67cSAndy Whitcroft 'summary!' => \$summary, 2308905a67cSAndy Whitcroft 'mailback!' => \$mailback, 23113214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 2323705ce5bSJoe Perches 'fix!' => \$fix, 2339624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 234d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 235c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 236773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 237ebfd7d62SJoe Perches 'codespell!' => \$codespell, 238ebfd7d62SJoe Perches 'codespellfile=s' => \$codespellfile, 23975ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 240737c0767SJohn Brooks 'color=s' => \$color, 241737c0767SJohn Brooks 'no-color' => \$color, #keep old behaviors of -nocolor 242737c0767SJohn Brooks 'nocolor' => \$color, #keep old behaviors of -nocolor 2433e89ad85SJerome Forissier 'kconfig-prefix=s' => \${CONFIG_}, 24477f5b10aSHannes Eder 'h|help' => \$help, 24577f5b10aSHannes Eder 'version' => \$help 24677f5b10aSHannes Eder) or help(1); 24777f5b10aSHannes Eder 24877f5b10aSHannes Ederhelp(0) if ($help); 2490a920b5bSAndy Whitcroft 2503beb42ecSJoe Percheslist_types(0) if ($list_types); 2513beb42ecSJoe Perches 2529624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 2532ac73b4fSJoe Perches$check_orig = $check; 2549624b8d6SJoe Perches 25532f30ca9SJoe Perchesdie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); 25632f30ca9SJoe Perches 2570a920b5bSAndy Whitcroftmy $exit = 0; 2580a920b5bSAndy Whitcroft 2595b57980dSJoe Perchesmy $perl_version_ok = 1; 260d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 2615b57980dSJoe Perches $perl_version_ok = 0; 262d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 2635b57980dSJoe Perches exit(1) if (!$ignore_perl_version); 264d62a201fSDave Hansen} 265d62a201fSDave Hansen 26645107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 2670a920b5bSAndy Whitcroftif ($#ARGV < 0) { 26845107ff6SAllen Hubbe push(@ARGV, '-'); 2690a920b5bSAndy Whitcroft} 2700a920b5bSAndy Whitcroft 271737c0767SJohn Brooksif ($color =~ /^[01]$/) { 272737c0767SJohn Brooks $color = !$color; 273737c0767SJohn Brooks} elsif ($color =~ /^always$/i) { 274737c0767SJohn Brooks $color = 1; 275737c0767SJohn Brooks} elsif ($color =~ /^never$/i) { 276737c0767SJohn Brooks $color = 0; 277737c0767SJohn Brooks} elsif ($color =~ /^auto$/i) { 278737c0767SJohn Brooks $color = (-t STDOUT); 279737c0767SJohn Brooks} else { 28032f30ca9SJoe Perches die "$P: Invalid color mode: $color\n"; 281737c0767SJohn Brooks} 282737c0767SJohn Brooks 283713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1 28432f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); 285713a09deSAntonio Borneo 28691bfe484SJoe Perchessub hash_save_array_words { 28791bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 28891bfe484SJoe Perches 28991bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 29091bfe484SJoe Perches foreach my $word (@array) { 291000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 292000d1cc1SJoe Perches $word =~ s/^\s*//g; 293000d1cc1SJoe Perches $word =~ s/\s+/ /g; 294000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 295000d1cc1SJoe Perches 296000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 297000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 298000d1cc1SJoe Perches 29991bfe484SJoe Perches $hashRef->{$word}++; 300000d1cc1SJoe Perches } 30191bfe484SJoe Perches} 30291bfe484SJoe Perches 30391bfe484SJoe Perchessub hash_show_words { 30491bfe484SJoe Perches my ($hashRef, $prefix) = @_; 30591bfe484SJoe Perches 3063c816e49SJoe Perches if (keys %$hashRef) { 307d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 30858cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 30991bfe484SJoe Perches print " $word"; 31091bfe484SJoe Perches } 311d8469f16SJoe Perches print "\n"; 31291bfe484SJoe Perches } 31391bfe484SJoe Perches} 31491bfe484SJoe Perches 31591bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 31691bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 317000d1cc1SJoe Perches 318c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 319c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 3207429c690SAndy Whitcroftmy $dbg_type = 0; 321a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 322c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 32321caa13cSAndy Whitcroft ## no critic 32421caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 32521caa13cSAndy Whitcroft die "$@" if ($@); 326c2fdda0dSAndy Whitcroft} 327c2fdda0dSAndy Whitcroft 328d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 329d2c0a235SAndy Whitcroft 3308905a67cSAndy Whitcroftif ($terse) { 3318905a67cSAndy Whitcroft $emacs = 1; 3328905a67cSAndy Whitcroft $quiet++; 3338905a67cSAndy Whitcroft} 3348905a67cSAndy Whitcroft 3356c72ffaaSAndy Whitcroftif ($tree) { 3366c72ffaaSAndy Whitcroft if (defined $root) { 3376c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 3386c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 3396c72ffaaSAndy Whitcroft } 3406c72ffaaSAndy Whitcroft } else { 3416c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 3426c72ffaaSAndy Whitcroft $root = '.'; 3436c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 3446c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 3456c72ffaaSAndy Whitcroft $root = $1; 3466c72ffaaSAndy Whitcroft } 3476c72ffaaSAndy Whitcroft } 3486c72ffaaSAndy Whitcroft 3496c72ffaaSAndy Whitcroft if (!defined $root) { 3500a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 3510a920b5bSAndy Whitcroft exit(2); 3520a920b5bSAndy Whitcroft } 3536c72ffaaSAndy Whitcroft} 3546c72ffaaSAndy Whitcroft 3556c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 3566c72ffaaSAndy Whitcroft 3572ceb532bSAndy Whitcroftour $Ident = qr{ 3582ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 3592ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 3602ceb532bSAndy Whitcroft }x; 3616c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 3626c72ffaaSAndy Whitcroftour $Sparse = qr{ 3636c72ffaaSAndy Whitcroft __user| 3646c72ffaaSAndy Whitcroft __kernel| 3656c72ffaaSAndy Whitcroft __force| 3666c72ffaaSAndy Whitcroft __iomem| 3676c72ffaaSAndy Whitcroft __must_check| 368417495edSAndy Whitcroft __kprobes| 369165e72a6SSven Eckelmann __ref| 37033aa4597SGeert Uytterhoeven __refconst| 37133aa4597SGeert Uytterhoeven __refdata| 372ad315455SBoqun Feng __rcu| 373ad315455SBoqun Feng __private 3746c72ffaaSAndy Whitcroft }x; 375e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 376e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 377e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 378e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 379e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 3808716de38SJoe Perches 38152131292SWolfram Sang# Notes to $Attribute: 38252131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 3836c72ffaaSAndy Whitcroftour $Attribute = qr{ 3846c72ffaaSAndy Whitcroft const| 385b5e8736aSJoe Perches volatile| 38603f1df7dSJoe Perches __percpu| 38703f1df7dSJoe Perches __nocast| 38803f1df7dSJoe Perches __safe| 38946d832f5SMichael S. Tsirkin __bitwise| 39003f1df7dSJoe Perches __packed__| 39103f1df7dSJoe Perches __packed2__| 39203f1df7dSJoe Perches __naked| 39303f1df7dSJoe Perches __maybe_unused| 39403f1df7dSJoe Perches __always_unused| 39503f1df7dSJoe Perches __noreturn| 39603f1df7dSJoe Perches __used| 39703f1df7dSJoe Perches __cold| 398e23ef1f3SJoe Perches __pure| 39903f1df7dSJoe Perches __noclone| 40003f1df7dSJoe Perches __deprecated| 4016c72ffaaSAndy Whitcroft __read_mostly| 402c5967e98SJoe Perches __ro_after_init| 4036c72ffaaSAndy Whitcroft __kprobes| 4048716de38SJoe Perches $InitAttribute| 40524e1d81aSAndy Whitcroft ____cacheline_aligned| 40624e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 4075fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 4085fe3af11SAndy Whitcroft __weak 4096c72ffaaSAndy Whitcroft }x; 410c45dcabdSAndy Whitcroftour $Modifier; 41191cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 4126c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 4136c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 4146c72ffaaSAndy Whitcroft 41595e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 41695e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 41795e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 41895e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 4192435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 420c0a5c898SJoe Perchesour $String = qr{"[X\t]*"}; 421326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 422326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 423326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 42474349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 4252435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 426326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 427447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 42823f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 4296c72ffaaSAndy Whitcroftour $Operators = qr{ 4306c72ffaaSAndy Whitcroft <=|>=|==|!=| 4316c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 43223f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 4336c72ffaaSAndy Whitcroft }x; 4346c72ffaaSAndy Whitcroft 43591cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 43691cb5195SJoe Perches 437ab7e23f3SJoe Perchesour $BasicType; 4388905a67cSAndy Whitcroftour $NonptrType; 4391813087dSJoe Perchesour $NonptrTypeMisordered; 4408716de38SJoe Perchesour $NonptrTypeWithAttr; 4418905a67cSAndy Whitcroftour $Type; 4421813087dSJoe Perchesour $TypeMisordered; 4438905a67cSAndy Whitcroftour $Declare; 4441813087dSJoe Perchesour $DeclareMisordered; 4458905a67cSAndy Whitcroft 44615662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 44715662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 448171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 449171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 450171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 451171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 452171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 453171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 454171ae1a4SAndy Whitcroft}x; 455171ae1a4SAndy Whitcroft 45615662b3eSJoe Perchesour $UTF8 = qr{ 45715662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 45815662b3eSJoe Perches | $NON_ASCII_UTF8 45915662b3eSJoe Perches}x; 46015662b3eSJoe Perches 461e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 462021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 463021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 464021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 465021158b4SJoe Perches)}; 466e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 467fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 4688ed22cadSAndy Whitcroft atomic_t 4698ed22cadSAndy Whitcroft)}; 470e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 471e6176fa4SJoe Perches $typeC99Typedefs\b| 472e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 473e6176fa4SJoe Perches $typeKernelTypedefs\b 474e6176fa4SJoe Perches)}; 4758ed22cadSAndy Whitcroft 4766d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 4776d32f7a3SJoe Perches 478691e669bSJoe Perchesour $logFunctions = qr{(?x: 479758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 4807d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 48187bd499aSJoe Perches TP_printk| 4826e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 483b0531722SJoe Perches panic| 48406668727SJoe Perches MODULE_[A-Z_]+| 48506668727SJoe Perches seq_vprintf|seq_printf|seq_puts 486691e669bSJoe Perches)}; 487691e669bSJoe Perches 488e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 489e29a70f1SJoe Perches (?:(?:devm_)? 49058f02267SJoe Perches (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? | 491e29a70f1SJoe Perches kstrdup(?:_const)? | 492e29a70f1SJoe Perches kmemdup(?:_nul)?) | 493461e1565SChristophe JAILLET (?:\w+)?alloc_skb(?:_ip_align)? | 494e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 495e29a70f1SJoe Perches dma_alloc_coherent 496e29a70f1SJoe Perches)}; 497e29a70f1SJoe Perches 49820112475SJoe Perchesour $signature_tags = qr{(?xi: 49920112475SJoe Perches Signed-off-by:| 500d499480cSJorge Ramirez-Ortiz Co-developed-by:| 50120112475SJoe Perches Acked-by:| 50220112475SJoe Perches Tested-by:| 50320112475SJoe Perches Reviewed-by:| 50420112475SJoe Perches Reported-by:| 5058543ae12SMugunthan V N Suggested-by:| 50620112475SJoe Perches To:| 50720112475SJoe Perches Cc: 50820112475SJoe Perches)}; 50920112475SJoe Perches 510adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi: 511adb2da82SJoe Perches [=-]*> | 512adb2da82SJoe Perches <[=-]* | 513adb2da82SJoe Perches \[ | 514adb2da82SJoe Perches \] | 515adb2da82SJoe Perches start | 516adb2da82SJoe Perches called | 517adb2da82SJoe Perches entered | 518adb2da82SJoe Perches entry | 519adb2da82SJoe Perches enter | 520adb2da82SJoe Perches in | 521adb2da82SJoe Perches inside | 522adb2da82SJoe Perches here | 523adb2da82SJoe Perches begin | 524adb2da82SJoe Perches exit | 525adb2da82SJoe Perches end | 526adb2da82SJoe Perches done | 527adb2da82SJoe Perches leave | 528adb2da82SJoe Perches completed | 529adb2da82SJoe Perches out | 530adb2da82SJoe Perches return | 531adb2da82SJoe Perches [\.\!:\s]* 532adb2da82SJoe Perches)}; 533adb2da82SJoe Perches 534831242abSAditya Srivastavasub edit_distance_min { 535831242abSAditya Srivastava my (@arr) = @_; 536831242abSAditya Srivastava my $len = scalar @arr; 537831242abSAditya Srivastava if ((scalar @arr) < 1) { 538831242abSAditya Srivastava # if underflow, return 539831242abSAditya Srivastava return; 540831242abSAditya Srivastava } 541831242abSAditya Srivastava my $min = $arr[0]; 542831242abSAditya Srivastava for my $i (0 .. ($len-1)) { 543831242abSAditya Srivastava if ($arr[$i] < $min) { 544831242abSAditya Srivastava $min = $arr[$i]; 545831242abSAditya Srivastava } 546831242abSAditya Srivastava } 547831242abSAditya Srivastava return $min; 548831242abSAditya Srivastava} 549831242abSAditya Srivastava 550831242abSAditya Srivastavasub get_edit_distance { 551831242abSAditya Srivastava my ($str1, $str2) = @_; 552831242abSAditya Srivastava $str1 = lc($str1); 553831242abSAditya Srivastava $str2 = lc($str2); 554831242abSAditya Srivastava $str1 =~ s/-//g; 555831242abSAditya Srivastava $str2 =~ s/-//g; 556831242abSAditya Srivastava my $len1 = length($str1); 557831242abSAditya Srivastava my $len2 = length($str2); 558831242abSAditya Srivastava # two dimensional array storing minimum edit distance 559831242abSAditya Srivastava my @distance; 560831242abSAditya Srivastava for my $i (0 .. $len1) { 561831242abSAditya Srivastava for my $j (0 .. $len2) { 562831242abSAditya Srivastava if ($i == 0) { 563831242abSAditya Srivastava $distance[$i][$j] = $j; 564831242abSAditya Srivastava } elsif ($j == 0) { 565831242abSAditya Srivastava $distance[$i][$j] = $i; 566831242abSAditya Srivastava } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { 567831242abSAditya Srivastava $distance[$i][$j] = $distance[$i - 1][$j - 1]; 568831242abSAditya Srivastava } else { 569831242abSAditya Srivastava my $dist1 = $distance[$i][$j - 1]; #insert distance 570831242abSAditya Srivastava my $dist2 = $distance[$i - 1][$j]; # remove 571831242abSAditya Srivastava my $dist3 = $distance[$i - 1][$j - 1]; #replace 572831242abSAditya Srivastava $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); 573831242abSAditya Srivastava } 574831242abSAditya Srivastava } 575831242abSAditya Srivastava } 576831242abSAditya Srivastava return $distance[$len1][$len2]; 577831242abSAditya Srivastava} 578831242abSAditya Srivastava 579831242abSAditya Srivastavasub find_standard_signature { 580831242abSAditya Srivastava my ($sign_off) = @_; 581831242abSAditya Srivastava my @standard_signature_tags = ( 582831242abSAditya Srivastava 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', 583831242abSAditya Srivastava 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' 584831242abSAditya Srivastava ); 585831242abSAditya Srivastava foreach my $signature (@standard_signature_tags) { 586831242abSAditya Srivastava return $signature if (get_edit_distance($sign_off, $signature) <= 2); 587831242abSAditya Srivastava } 588831242abSAditya Srivastava 589831242abSAditya Srivastava return ""; 590831242abSAditya Srivastava} 591831242abSAditya Srivastava 5921813087dSJoe Perchesour @typeListMisordered = ( 5931813087dSJoe Perches qr{char\s+(?:un)?signed}, 5941813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 5951813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 5961813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 5971813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 5981813087dSJoe Perches qr{short\s+(?:un)?signed}, 5991813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 6001813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 6011813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 6021813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 6031813087dSJoe Perches qr{int\s+(?:un)?signed}, 6041813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 6051813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 6061813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 6071813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 6081813087dSJoe Perches qr{long\s+(?:un)?signed}, 6091813087dSJoe Perches); 6101813087dSJoe Perches 6118905a67cSAndy Whitcroftour @typeList = ( 6128905a67cSAndy Whitcroft qr{void}, 6130c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 6140c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 6150c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 6160c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 6170c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 6180c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 6190c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 6200c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 6210c773d9dSJoe Perches qr{(?:un)?signed}, 6228905a67cSAndy Whitcroft qr{float}, 6238905a67cSAndy Whitcroft qr{double}, 6248905a67cSAndy Whitcroft qr{bool}, 6258905a67cSAndy Whitcroft qr{struct\s+$Ident}, 6268905a67cSAndy Whitcroft qr{union\s+$Ident}, 6278905a67cSAndy Whitcroft qr{enum\s+$Ident}, 6288905a67cSAndy Whitcroft qr{${Ident}_t}, 6298905a67cSAndy Whitcroft qr{${Ident}_handler}, 6308905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 6311813087dSJoe Perches @typeListMisordered, 6328905a67cSAndy Whitcroft); 633938224b5SJoe Perches 634938224b5SJoe Perchesour $C90_int_types = qr{(?x: 635938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 636938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 637938224b5SJoe Perches long\s+long\s+(?:un)?signed| 638938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 639938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 640938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 641938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 642938224b5SJoe Perches 643938224b5SJoe Perches long\s+int\s+(?:un)?signed| 644938224b5SJoe Perches long\s+(?:un)?signed\s+int| 645938224b5SJoe Perches long\s+(?:un)?signed| 646938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 647938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 648938224b5SJoe Perches int\s+long\s+(?:un)?signed| 649938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 650938224b5SJoe Perches 651938224b5SJoe Perches int\s+(?:un)?signed| 652938224b5SJoe Perches (?:(?:un)?signed\s+)?int 653938224b5SJoe Perches)}; 654938224b5SJoe Perches 655485ff23eSAlex Dowadour @typeListFile = (); 6568716de38SJoe Perchesour @typeListWithAttr = ( 6578716de38SJoe Perches @typeList, 6588716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 6598716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 6608716de38SJoe Perches); 6618716de38SJoe Perches 662c45dcabdSAndy Whitcroftour @modifierList = ( 663c45dcabdSAndy Whitcroft qr{fastcall}, 664c45dcabdSAndy Whitcroft); 665485ff23eSAlex Dowadour @modifierListFile = (); 6668905a67cSAndy Whitcroft 6672435880fSJoe Perchesour @mode_permission_funcs = ( 6682435880fSJoe Perches ["module_param", 3], 6692435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 6702435880fSJoe Perches ["module_param_array_named", 5], 6712435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 6722435880fSJoe Perches ["proc_create(?:_data|)", 2], 673459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 674459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 675459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 676459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 677459cf0aeSJoe Perches ["__ATTR", 2], 6782435880fSJoe Perches); 6792435880fSJoe Perches 6801a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; 6811a3dcf2eSJoe Perches 682515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 683515a235eSJoe Perchesour $mode_perms_search = ""; 684515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 685515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 686515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 687515a235eSJoe Perches} 68800180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 689515a235eSJoe Perches 6909189c7e7SJoe Perchesour %deprecated_apis = ( 6919189c7e7SJoe Perches "synchronize_rcu_bh" => "synchronize_rcu", 6929189c7e7SJoe Perches "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 6939189c7e7SJoe Perches "call_rcu_bh" => "call_rcu", 6949189c7e7SJoe Perches "rcu_barrier_bh" => "rcu_barrier", 6959189c7e7SJoe Perches "synchronize_sched" => "synchronize_rcu", 6969189c7e7SJoe Perches "synchronize_sched_expedited" => "synchronize_rcu_expedited", 6979189c7e7SJoe Perches "call_rcu_sched" => "call_rcu", 6989189c7e7SJoe Perches "rcu_barrier_sched" => "rcu_barrier", 6999189c7e7SJoe Perches "get_state_synchronize_sched" => "get_state_synchronize_rcu", 7009189c7e7SJoe Perches "cond_synchronize_sched" => "cond_synchronize_rcu", 7019189c7e7SJoe Perches); 7029189c7e7SJoe Perches 7039189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 7049189c7e7SJoe Perchesour $deprecated_apis_search = ""; 7059189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 7069189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 7079189c7e7SJoe Perches $deprecated_apis_search .= $entry; 7089189c7e7SJoe Perches} 7099189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 7109189c7e7SJoe Perches 711b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 712b392c64fSJoe Perches S_IWUGO | 713b392c64fSJoe Perches S_IWOTH | 714b392c64fSJoe Perches S_IRWXUGO | 715b392c64fSJoe Perches S_IALLUGO | 716b392c64fSJoe Perches 0[0-7][0-7][2367] 717b392c64fSJoe Perches}x; 718b392c64fSJoe Perches 719f90774e1SJoe Perchesour %mode_permission_string_types = ( 720f90774e1SJoe Perches "S_IRWXU" => 0700, 721f90774e1SJoe Perches "S_IRUSR" => 0400, 722f90774e1SJoe Perches "S_IWUSR" => 0200, 723f90774e1SJoe Perches "S_IXUSR" => 0100, 724f90774e1SJoe Perches "S_IRWXG" => 0070, 725f90774e1SJoe Perches "S_IRGRP" => 0040, 726f90774e1SJoe Perches "S_IWGRP" => 0020, 727f90774e1SJoe Perches "S_IXGRP" => 0010, 728f90774e1SJoe Perches "S_IRWXO" => 0007, 729f90774e1SJoe Perches "S_IROTH" => 0004, 730f90774e1SJoe Perches "S_IWOTH" => 0002, 731f90774e1SJoe Perches "S_IXOTH" => 0001, 732f90774e1SJoe Perches "S_IRWXUGO" => 0777, 733f90774e1SJoe Perches "S_IRUGO" => 0444, 734f90774e1SJoe Perches "S_IWUGO" => 0222, 735f90774e1SJoe Perches "S_IXUGO" => 0111, 736f90774e1SJoe Perches); 737f90774e1SJoe Perches 738f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 739f90774e1SJoe Perchesour $mode_perms_string_search = ""; 740f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 741f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 742f90774e1SJoe Perches $mode_perms_string_search .= $entry; 743f90774e1SJoe Perches} 74400180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 74500180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 74600180468SJoe Perches ${single_mode_perms_string_search} 74700180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 74800180468SJoe Perches}x; 74900180468SJoe Perches 75000180468SJoe Perchessub perms_to_octal { 75100180468SJoe Perches my ($string) = @_; 75200180468SJoe Perches 75300180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 75400180468SJoe Perches 75500180468SJoe Perches my $val = ""; 75600180468SJoe Perches my $oval = ""; 75700180468SJoe Perches my $to = 0; 75800180468SJoe Perches my $curpos = 0; 75900180468SJoe Perches my $lastpos = 0; 76000180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 76100180468SJoe Perches $curpos = pos($string); 76200180468SJoe Perches my $match = $2; 76300180468SJoe Perches my $omatch = $1; 76400180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 76500180468SJoe Perches $lastpos = $curpos; 76600180468SJoe Perches $to |= $mode_permission_string_types{$match}; 76700180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 76800180468SJoe Perches $val .= $match; 76900180468SJoe Perches $oval .= $omatch; 77000180468SJoe Perches } 77100180468SJoe Perches $oval =~ s/^\s*\|\s*//; 77200180468SJoe Perches $oval =~ s/\s*\|\s*$//; 77300180468SJoe Perches return sprintf("%04o", $to); 77400180468SJoe Perches} 775f90774e1SJoe Perches 7767840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 7777840a94cSWolfram Sang irq| 778cdcee686SSergey Ryazanov memory| 779cdcee686SSergey Ryazanov time| 780cdcee686SSergey Ryazanov reboot 7817840a94cSWolfram Sang)}; 7827840a94cSWolfram Sang# memory.h: ARM has a custom one 7837840a94cSWolfram Sang 78466b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 78566b47b4aSKees Cookmy $misspellings; 78666b47b4aSKees Cookmy %spelling_fix; 78736061e38SJoe Perches 78836061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 78966b47b4aSKees Cook while (<$spelling>) { 79066b47b4aSKees Cook my $line = $_; 79166b47b4aSKees Cook 79266b47b4aSKees Cook $line =~ s/\s*\n?$//g; 79366b47b4aSKees Cook $line =~ s/^\s*//g; 79466b47b4aSKees Cook 79566b47b4aSKees Cook next if ($line =~ m/^\s*#/); 79666b47b4aSKees Cook next if ($line =~ m/^\s*$/); 79766b47b4aSKees Cook 79866b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 79966b47b4aSKees Cook 80066b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 80166b47b4aSKees Cook } 80266b47b4aSKees Cook close($spelling); 80336061e38SJoe Perches} else { 80436061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 80536061e38SJoe Perches} 80666b47b4aSKees Cook 807ebfd7d62SJoe Perchesif ($codespell) { 808ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 809ebfd7d62SJoe Perches while (<$spelling>) { 810ebfd7d62SJoe Perches my $line = $_; 811ebfd7d62SJoe Perches 812ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 813ebfd7d62SJoe Perches $line =~ s/^\s*//g; 814ebfd7d62SJoe Perches 815ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 816ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 817ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 818ebfd7d62SJoe Perches 819ebfd7d62SJoe Perches $line =~ s/,.*$//; 820ebfd7d62SJoe Perches 821ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 822ebfd7d62SJoe Perches 823ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 824ebfd7d62SJoe Perches } 825ebfd7d62SJoe Perches close($spelling); 826ebfd7d62SJoe Perches } else { 827ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 828ebfd7d62SJoe Perches } 829ebfd7d62SJoe Perches} 830ebfd7d62SJoe Perches 831ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 832ebfd7d62SJoe Perches 83375ad8c57SJerome Forissiersub read_words { 83475ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 83575ad8c57SJerome Forissier 83675ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 83775ad8c57SJerome Forissier while (<$words>) { 838bf1fa1daSJoe Perches my $line = $_; 839bf1fa1daSJoe Perches 840bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 841bf1fa1daSJoe Perches $line =~ s/^\s*//g; 842bf1fa1daSJoe Perches 843bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 844bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 845bf1fa1daSJoe Perches if ($line =~ /\s/) { 84675ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 847bf1fa1daSJoe Perches next; 848bf1fa1daSJoe Perches } 849bf1fa1daSJoe Perches 850ced69da1SQuentin Monnet $$wordsRef .= '|' if (defined $$wordsRef); 85175ad8c57SJerome Forissier $$wordsRef .= $line; 852bf1fa1daSJoe Perches } 85375ad8c57SJerome Forissier close($file); 85475ad8c57SJerome Forissier return 1; 855bf1fa1daSJoe Perches } 856bf1fa1daSJoe Perches 85775ad8c57SJerome Forissier return 0; 85875ad8c57SJerome Forissier} 85975ad8c57SJerome Forissier 860ced69da1SQuentin Monnetmy $const_structs; 861ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) { 86275ad8c57SJerome Forissier read_words(\$const_structs, $conststructsfile) 86375ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 864ced69da1SQuentin Monnet} 86575ad8c57SJerome Forissier 866ced69da1SQuentin Monnetif (defined($typedefsfile)) { 867ced69da1SQuentin Monnet my $typeOtherTypedefs; 86875ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 86975ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 870ced69da1SQuentin Monnet $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); 87175ad8c57SJerome Forissier} 87275ad8c57SJerome Forissier 8738905a67cSAndy Whitcroftsub build_types { 874485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 875485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 8761813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 8778716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 878c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 879ab7e23f3SJoe Perches $BasicType = qr{ 880ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 881ab7e23f3SJoe Perches (?:${all}\b) 882ab7e23f3SJoe Perches }x; 8838905a67cSAndy Whitcroft $NonptrType = qr{ 884d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 885cf655043SAndy Whitcroft (?: 8866b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 8878ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 888c45dcabdSAndy Whitcroft (?:${all}\b) 889cf655043SAndy Whitcroft ) 890c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 8918905a67cSAndy Whitcroft }x; 8921813087dSJoe Perches $NonptrTypeMisordered = qr{ 8931813087dSJoe Perches (?:$Modifier\s+|const\s+)* 8941813087dSJoe Perches (?: 8951813087dSJoe Perches (?:${Misordered}\b) 8961813087dSJoe Perches ) 8971813087dSJoe Perches (?:\s+$Modifier|\s+const)* 8981813087dSJoe Perches }x; 8998716de38SJoe Perches $NonptrTypeWithAttr = qr{ 9008716de38SJoe Perches (?:$Modifier\s+|const\s+)* 9018716de38SJoe Perches (?: 9028716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 9038716de38SJoe Perches (?:$typeTypedefs\b)| 9048716de38SJoe Perches (?:${allWithAttr}\b) 9058716de38SJoe Perches ) 9068716de38SJoe Perches (?:\s+$Modifier|\s+const)* 9078716de38SJoe Perches }x; 9088905a67cSAndy Whitcroft $Type = qr{ 909c45dcabdSAndy Whitcroft $NonptrType 9107b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 911c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 9128905a67cSAndy Whitcroft }x; 9131813087dSJoe Perches $TypeMisordered = qr{ 9141813087dSJoe Perches $NonptrTypeMisordered 9157b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 9161813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 9171813087dSJoe Perches }x; 91891cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 9191813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 9208905a67cSAndy Whitcroft} 9218905a67cSAndy Whitcroftbuild_types(); 9226c72ffaaSAndy Whitcroft 9237d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 924d1fe9c09SJoe Perches 925d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 926d1fe9c09SJoe Perches# requires at least perl version v5.10.0 927d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 928d1fe9c09SJoe Perches 929d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 9302435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 931c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 9327d2367afSJoe Perches 933f8422308SJoe Perchesour $declaration_macros = qr{(?x: 9343e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 935fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 9363d102fc0SGilad Ben-Yossef (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( 937f8422308SJoe Perches)}; 938f8422308SJoe Perches 9398d0325ccSAditya Srivastavaour %allow_repeated_words = ( 9408d0325ccSAditya Srivastava add => '', 9418d0325ccSAditya Srivastava added => '', 9428d0325ccSAditya Srivastava bad => '', 9438d0325ccSAditya Srivastava be => '', 9448d0325ccSAditya Srivastava); 9458d0325ccSAditya Srivastava 9467d2367afSJoe Perchessub deparenthesize { 9477d2367afSJoe Perches my ($string) = @_; 9487d2367afSJoe Perches return "" if (!defined($string)); 9495b9553abSJoe Perches 9505b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 9515b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 9525b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 9535b9553abSJoe Perches } 9545b9553abSJoe Perches 9557d2367afSJoe Perches $string =~ s@\s+@ @g; 9565b9553abSJoe Perches 9577d2367afSJoe Perches return $string; 9587d2367afSJoe Perches} 9597d2367afSJoe Perches 9603445686aSJoe Perchessub seed_camelcase_file { 9613445686aSJoe Perches my ($file) = @_; 9623445686aSJoe Perches 9633445686aSJoe Perches return if (!(-f $file)); 9643445686aSJoe Perches 9653445686aSJoe Perches local $/; 9663445686aSJoe Perches 9673445686aSJoe Perches open(my $include_file, '<', "$file") 9683445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 9693445686aSJoe Perches my $text = <$include_file>; 9703445686aSJoe Perches close($include_file); 9713445686aSJoe Perches 9723445686aSJoe Perches my @lines = split('\n', $text); 9733445686aSJoe Perches 9743445686aSJoe Perches foreach my $line (@lines) { 9753445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 9763445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 9773445686aSJoe Perches $camelcase{$1} = 1; 97811ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 97911ea516aSJoe Perches $camelcase{$1} = 1; 98011ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 9813445686aSJoe Perches $camelcase{$1} = 1; 9823445686aSJoe Perches } 9833445686aSJoe Perches } 9843445686aSJoe Perches} 9853445686aSJoe Perches 986cd28b119SJoe Perchesour %maintained_status = (); 987cd28b119SJoe Perches 98885b0ee18SJoe Perchessub is_maintained_obsolete { 98985b0ee18SJoe Perches my ($filename) = @_; 99085b0ee18SJoe Perches 991f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 99285b0ee18SJoe Perches 993cd28b119SJoe Perches if (!exists($maintained_status{$filename})) { 994cd28b119SJoe Perches $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 995cd28b119SJoe Perches } 99685b0ee18SJoe Perches 997cd28b119SJoe Perches return $maintained_status{$filename} =~ /obsolete/i; 99885b0ee18SJoe Perches} 99985b0ee18SJoe Perches 10003b6e8ac9SJoe Perchessub is_SPDX_License_valid { 10013b6e8ac9SJoe Perches my ($license) = @_; 10023b6e8ac9SJoe Perches 10030f7f635bSJoe Perches return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); 10043b6e8ac9SJoe Perches 100556294112SJoe Perches my $root_path = abs_path($root); 100656294112SJoe Perches my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`; 10073b6e8ac9SJoe Perches return 0 if ($status ne ""); 10083b6e8ac9SJoe Perches return 1; 10093b6e8ac9SJoe Perches} 10103b6e8ac9SJoe Perches 10113445686aSJoe Perchesmy $camelcase_seeded = 0; 10123445686aSJoe Perchessub seed_camelcase_includes { 10133445686aSJoe Perches return if ($camelcase_seeded); 10143445686aSJoe Perches 10153445686aSJoe Perches my $files; 1016c707a81dSJoe Perches my $camelcase_cache = ""; 1017c707a81dSJoe Perches my @include_files = (); 1018c707a81dSJoe Perches 1019c707a81dSJoe Perches $camelcase_seeded = 1; 1020351b2a1fSJoe Perches 10210f7f635bSJoe Perches if (-e "$gitroot") { 1022dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 1023351b2a1fSJoe Perches chomp $git_last_include_commit; 1024c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 1025c707a81dSJoe Perches } else { 1026c707a81dSJoe Perches my $last_mod_date = 0; 1027c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 1028c707a81dSJoe Perches @include_files = split('\n', $files); 1029c707a81dSJoe Perches foreach my $file (@include_files) { 1030c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 1031c707a81dSJoe Perches localtime((stat $file)[9])); 1032c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 1033c707a81dSJoe Perches } 1034c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 1035c707a81dSJoe Perches } 1036c707a81dSJoe Perches 1037c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 1038c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 1039c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 1040351b2a1fSJoe Perches while (<$camelcase_file>) { 1041351b2a1fSJoe Perches chomp; 1042351b2a1fSJoe Perches $camelcase{$_} = 1; 1043351b2a1fSJoe Perches } 1044351b2a1fSJoe Perches close($camelcase_file); 1045351b2a1fSJoe Perches 1046351b2a1fSJoe Perches return; 1047351b2a1fSJoe Perches } 1048c707a81dSJoe Perches 10490f7f635bSJoe Perches if (-e "$gitroot") { 1050dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 1051c707a81dSJoe Perches @include_files = split('\n', $files); 10523445686aSJoe Perches } 1053c707a81dSJoe Perches 10543445686aSJoe Perches foreach my $file (@include_files) { 10553445686aSJoe Perches seed_camelcase_file($file); 10563445686aSJoe Perches } 1057351b2a1fSJoe Perches 1058c707a81dSJoe Perches if ($camelcase_cache ne "") { 1059351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 1060c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 1061c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 1062351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 1063351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 1064351b2a1fSJoe Perches } 1065351b2a1fSJoe Perches close($camelcase_file); 1066351b2a1fSJoe Perches } 10673445686aSJoe Perches} 10683445686aSJoe Perches 1069f5f61325SJoe Perchessub git_is_single_file { 1070f5f61325SJoe Perches my ($filename) = @_; 1071f5f61325SJoe Perches 1072f5f61325SJoe Perches return 0 if ((which("git") eq "") || !(-e "$gitroot")); 1073f5f61325SJoe Perches 1074f5f61325SJoe Perches my $output = `${git_command} ls-files -- $filename 2>/dev/null`; 1075f5f61325SJoe Perches my $count = $output =~ tr/\n//; 1076f5f61325SJoe Perches return $count eq 1 && $output =~ m{^${filename}$}; 1077f5f61325SJoe Perches} 1078f5f61325SJoe Perches 1079d311cd44SJoe Perchessub git_commit_info { 1080d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 1081d311cd44SJoe Perches 10820f7f635bSJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); 1083d311cd44SJoe Perches 1084dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 1085d311cd44SJoe Perches $output =~ s/^\s*//gm; 1086d311cd44SJoe Perches my @lines = split("\n", $output); 1087d311cd44SJoe Perches 10880d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 10890d7835fcSJoe Perches 10905a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 1091d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 1092d311cd44SJoe Perches# all matching commit ids, but it's very slow... 1093d311cd44SJoe Perches# 1094d311cd44SJoe Perches# echo "checking commits $1..." 1095d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 1096d311cd44SJoe Perches# while read line ; do 1097d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 1098d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 1099d311cd44SJoe Perches# done 1100d311cd44SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { 1101948b133aSHeinrich Schuchardt $id = undef; 1102d311cd44SJoe Perches } else { 1103d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 1104d311cd44SJoe Perches $desc = substr($lines[0], 41); 1105d311cd44SJoe Perches } 1106d311cd44SJoe Perches 1107d311cd44SJoe Perches return ($id, $desc); 1108d311cd44SJoe Perches} 1109d311cd44SJoe Perches 11106c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 11110a920b5bSAndy Whitcroft 111200df344fSAndy Whitcroftmy @rawlines = (); 1113c2fdda0dSAndy Whitcroftmy @lines = (); 11143705ce5bSJoe Perchesmy @fixed = (); 1115d752fcc8SJoe Perchesmy @fixed_inserted = (); 1116d752fcc8SJoe Perchesmy @fixed_deleted = (); 1117194f66fcSJoe Perchesmy $fixlinenr = -1; 1118194f66fcSJoe Perches 11194a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 11204a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 11210f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot"); 11224a593c34SDu, Changbin 11234a593c34SDu, Changbinif ($git) { 11244a593c34SDu, Changbin my @commits = (); 11250dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 11264a593c34SDu, Changbin my $git_range; 112728898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 112828898fd1SJoe Perches $git_range = "-$2 $1"; 11294a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 11304a593c34SDu, Changbin $git_range = "$commit_expr"; 11314a593c34SDu, Changbin } else { 11320dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 11330dea9f1eSJoe Perches } 1134dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 11350dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 113628898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 113728898fd1SJoe Perches next if (!defined($1) || !defined($2)); 11380dea9f1eSJoe Perches my $sha1 = $1; 11390dea9f1eSJoe Perches my $subject = $2; 11400dea9f1eSJoe Perches unshift(@commits, $sha1); 11410dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 11424a593c34SDu, Changbin } 11434a593c34SDu, Changbin } 11444a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 11454a593c34SDu, Changbin @ARGV = @commits; 11464a593c34SDu, Changbin} 11474a593c34SDu, Changbin 1148c2fdda0dSAndy Whitcroftmy $vname; 114998005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 11506c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 115121caa13cSAndy Whitcroft my $FILE; 1152f5f61325SJoe Perches my $is_git_file = git_is_single_file($filename); 1153f5f61325SJoe Perches my $oldfile = $file; 1154f5f61325SJoe Perches $file = 1 if ($is_git_file); 11554a593c34SDu, Changbin if ($git) { 11564a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 11574a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 11584a593c34SDu, Changbin } elsif ($file) { 115921caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 11606c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 116121caa13cSAndy Whitcroft } elsif ($filename eq '-') { 116221caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 11636c72ffaaSAndy Whitcroft } else { 116421caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 11656c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 11666c72ffaaSAndy Whitcroft } 1167c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1168c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 11694a593c34SDu, Changbin } elsif ($git) { 11700dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1171c2fdda0dSAndy Whitcroft } else { 1172c2fdda0dSAndy Whitcroft $vname = $filename; 1173c2fdda0dSAndy Whitcroft } 117421caa13cSAndy Whitcroft while (<$FILE>) { 11750a920b5bSAndy Whitcroft chomp; 117600df344fSAndy Whitcroft push(@rawlines, $_); 1177c7f574d0SGeert Uytterhoeven $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); 11786c72ffaaSAndy Whitcroft } 117921caa13cSAndy Whitcroft close($FILE); 1180d8469f16SJoe Perches 1181d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1182d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1183d8469f16SJoe Perches print "$vname\n"; 1184d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1185d8469f16SJoe Perches } 1186d8469f16SJoe Perches 1187c2fdda0dSAndy Whitcroft if (!process($filename)) { 11880a920b5bSAndy Whitcroft $exit = 1; 11890a920b5bSAndy Whitcroft } 119000df344fSAndy Whitcroft @rawlines = (); 119113214adfSAndy Whitcroft @lines = (); 11923705ce5bSJoe Perches @fixed = (); 1193d752fcc8SJoe Perches @fixed_inserted = (); 1194d752fcc8SJoe Perches @fixed_deleted = (); 1195194f66fcSJoe Perches $fixlinenr = -1; 1196485ff23eSAlex Dowad @modifierListFile = (); 1197485ff23eSAlex Dowad @typeListFile = (); 1198485ff23eSAlex Dowad build_types(); 1199f5f61325SJoe Perches $file = $oldfile if ($is_git_file); 12000a920b5bSAndy Whitcroft} 12010a920b5bSAndy Whitcroft 1202d8469f16SJoe Perchesif (!$quiet) { 12033c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 12043c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 12053c816e49SJoe Perches 12065b57980dSJoe Perches if (!$perl_version_ok) { 1207d8469f16SJoe Perches print << "EOM" 1208d8469f16SJoe Perches 1209d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 12105b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1211d8469f16SJoe PerchesEOM 1212d8469f16SJoe Perches } 1213d8469f16SJoe Perches if ($exit) { 1214d8469f16SJoe Perches print << "EOM" 1215d8469f16SJoe Perches 1216d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1217d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1218d8469f16SJoe PerchesEOM 1219d8469f16SJoe Perches } 1220d8469f16SJoe Perches} 1221d8469f16SJoe Perches 12220a920b5bSAndy Whitcroftexit($exit); 12230a920b5bSAndy Whitcroft 12240a920b5bSAndy Whitcroftsub top_of_kernel_tree { 12256c72ffaaSAndy Whitcroft my ($root) = @_; 12266c72ffaaSAndy Whitcroft 12276c72ffaaSAndy Whitcroft my @tree_check = ( 12286c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 12296c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 12306c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 12316c72ffaaSAndy Whitcroft ); 12326c72ffaaSAndy Whitcroft 12336c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 12346c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 12350a920b5bSAndy Whitcroft return 0; 12360a920b5bSAndy Whitcroft } 12376c72ffaaSAndy Whitcroft } 12386c72ffaaSAndy Whitcroft return 1; 12396c72ffaaSAndy Whitcroft} 12400a920b5bSAndy Whitcroft 124120112475SJoe Perchessub parse_email { 124220112475SJoe Perches my ($formatted_email) = @_; 124320112475SJoe Perches 124420112475SJoe Perches my $name = ""; 1245fccaebf0SDwaipayan Ray my $quoted = ""; 1246dfa05c28SJoe Perches my $name_comment = ""; 124720112475SJoe Perches my $address = ""; 124820112475SJoe Perches my $comment = ""; 124920112475SJoe Perches 125020112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 125120112475SJoe Perches $name = $1; 125220112475SJoe Perches $address = $2; 125320112475SJoe Perches $comment = $3 if defined $3; 125420112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 125520112475SJoe Perches $address = $1; 125620112475SJoe Perches $comment = $2 if defined $2; 125720112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 125820112475SJoe Perches $address = $1; 125920112475SJoe Perches $comment = $2 if defined $2; 126085e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 126120112475SJoe Perches $name = $formatted_email; 12623705ce5bSJoe Perches $name = trim($name); 126320112475SJoe Perches $name =~ s/^\"|\"$//g; 126420112475SJoe Perches # If there's a name left after stripping spaces and 126520112475SJoe Perches # leading quotes, and the address doesn't have both 126620112475SJoe Perches # leading and trailing angle brackets, the address 126720112475SJoe Perches # is invalid. ie: 126820112475SJoe Perches # "joe smith [email protected]" bad 126920112475SJoe Perches # "joe smith <[email protected]" bad 127020112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 127120112475SJoe Perches $name = ""; 127220112475SJoe Perches $address = ""; 127320112475SJoe Perches $comment = ""; 127420112475SJoe Perches } 127520112475SJoe Perches } 127620112475SJoe Perches 1277fccaebf0SDwaipayan Ray # Extract comments from names excluding quoted parts 1278fccaebf0SDwaipayan Ray # "John D. (Doe)" - Do not extract 1279fccaebf0SDwaipayan Ray if ($name =~ s/\"(.+)\"//) { 1280fccaebf0SDwaipayan Ray $quoted = $1; 1281dfa05c28SJoe Perches } 1282fccaebf0SDwaipayan Ray while ($name =~ s/\s*($balanced_parens)\s*/ /) { 1283fccaebf0SDwaipayan Ray $name_comment .= trim($1); 1284fccaebf0SDwaipayan Ray } 1285fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 1286fccaebf0SDwaipayan Ray $name = trim("$quoted $name"); 1287fccaebf0SDwaipayan Ray 12883705ce5bSJoe Perches $address = trim($address); 128920112475SJoe Perches $address =~ s/^\<|\>$//g; 1290fccaebf0SDwaipayan Ray $comment = trim($comment); 129120112475SJoe Perches 129220112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 129320112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 129420112475SJoe Perches $name = "\"$name\""; 129520112475SJoe Perches } 129620112475SJoe Perches 1297dfa05c28SJoe Perches return ($name, $name_comment, $address, $comment); 129820112475SJoe Perches} 129920112475SJoe Perches 130020112475SJoe Perchessub format_email { 130148ca2d8aSDwaipayan Ray my ($name, $name_comment, $address, $comment) = @_; 130220112475SJoe Perches 130320112475SJoe Perches my $formatted_email; 130420112475SJoe Perches 1305fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 13063705ce5bSJoe Perches $address = trim($address); 1307fccaebf0SDwaipayan Ray $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes 130820112475SJoe Perches 130920112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 131020112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 131120112475SJoe Perches $name = "\"$name\""; 131220112475SJoe Perches } 131320112475SJoe Perches 1314fccaebf0SDwaipayan Ray $name_comment = trim($name_comment); 1315fccaebf0SDwaipayan Ray $name_comment = " $name_comment" if ($name_comment ne ""); 1316fccaebf0SDwaipayan Ray $comment = trim($comment); 1317fccaebf0SDwaipayan Ray $comment = " $comment" if ($comment ne ""); 1318fccaebf0SDwaipayan Ray 131920112475SJoe Perches if ("$name" eq "") { 132020112475SJoe Perches $formatted_email = "$address"; 132120112475SJoe Perches } else { 132248ca2d8aSDwaipayan Ray $formatted_email = "$name$name_comment <$address>"; 132320112475SJoe Perches } 132448ca2d8aSDwaipayan Ray $formatted_email .= "$comment"; 132520112475SJoe Perches return $formatted_email; 132620112475SJoe Perches} 132720112475SJoe Perches 1328dfa05c28SJoe Perchessub reformat_email { 1329dfa05c28SJoe Perches my ($email) = @_; 1330dfa05c28SJoe Perches 1331dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 133248ca2d8aSDwaipayan Ray return format_email($email_name, $name_comment, $email_address, $comment); 1333dfa05c28SJoe Perches} 1334dfa05c28SJoe Perches 1335dfa05c28SJoe Perchessub same_email_addresses { 1336fccaebf0SDwaipayan Ray my ($email1, $email2) = @_; 1337dfa05c28SJoe Perches 1338dfa05c28SJoe Perches my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); 1339dfa05c28SJoe Perches my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); 1340dfa05c28SJoe Perches 134148ca2d8aSDwaipayan Ray return $email1_name eq $email2_name && 134248ca2d8aSDwaipayan Ray $email1_address eq $email2_address && 134348ca2d8aSDwaipayan Ray $name1_comment eq $name2_comment && 134448ca2d8aSDwaipayan Ray $comment1 eq $comment2; 134548ca2d8aSDwaipayan Ray} 1346dfa05c28SJoe Perches 1347d311cd44SJoe Perchessub which { 1348d311cd44SJoe Perches my ($bin) = @_; 1349d311cd44SJoe Perches 1350d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1351d311cd44SJoe Perches if (-e "$path/$bin") { 1352d311cd44SJoe Perches return "$path/$bin"; 1353d311cd44SJoe Perches } 1354d311cd44SJoe Perches } 1355d311cd44SJoe Perches 1356d311cd44SJoe Perches return ""; 1357d311cd44SJoe Perches} 1358d311cd44SJoe Perches 1359000d1cc1SJoe Perchessub which_conf { 1360000d1cc1SJoe Perches my ($conf) = @_; 1361000d1cc1SJoe Perches 1362000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1363000d1cc1SJoe Perches if (-e "$path/$conf") { 1364000d1cc1SJoe Perches return "$path/$conf"; 1365000d1cc1SJoe Perches } 1366000d1cc1SJoe Perches } 1367000d1cc1SJoe Perches 1368000d1cc1SJoe Perches return ""; 1369000d1cc1SJoe Perches} 1370000d1cc1SJoe Perches 13710a920b5bSAndy Whitcroftsub expand_tabs { 13720a920b5bSAndy Whitcroft my ($str) = @_; 13730a920b5bSAndy Whitcroft 13740a920b5bSAndy Whitcroft my $res = ''; 13750a920b5bSAndy Whitcroft my $n = 0; 13760a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 13770a920b5bSAndy Whitcroft if ($c eq "\t") { 13780a920b5bSAndy Whitcroft $res .= ' '; 13790a920b5bSAndy Whitcroft $n++; 1380713a09deSAntonio Borneo for (; ($n % $tabsize) != 0; $n++) { 13810a920b5bSAndy Whitcroft $res .= ' '; 13820a920b5bSAndy Whitcroft } 13830a920b5bSAndy Whitcroft next; 13840a920b5bSAndy Whitcroft } 13850a920b5bSAndy Whitcroft $res .= $c; 13860a920b5bSAndy Whitcroft $n++; 13870a920b5bSAndy Whitcroft } 13880a920b5bSAndy Whitcroft 13890a920b5bSAndy Whitcroft return $res; 13900a920b5bSAndy Whitcroft} 13916c72ffaaSAndy Whitcroftsub copy_spacing { 1392773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 13936c72ffaaSAndy Whitcroft return $res; 13946c72ffaaSAndy Whitcroft} 13950a920b5bSAndy Whitcroft 13964a0df2efSAndy Whitcroftsub line_stats { 13974a0df2efSAndy Whitcroft my ($line) = @_; 13984a0df2efSAndy Whitcroft 13994a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 14004a0df2efSAndy Whitcroft $line =~ s/^.//; 14014a0df2efSAndy Whitcroft $line = expand_tabs($line); 14024a0df2efSAndy Whitcroft 14034a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 14044a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 14054a0df2efSAndy Whitcroft 14064a0df2efSAndy Whitcroft return (length($line), length($white)); 14074a0df2efSAndy Whitcroft} 14084a0df2efSAndy Whitcroft 1409773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1410773647a0SAndy Whitcroft 1411773647a0SAndy Whitcroftsub sanitise_line_reset { 1412773647a0SAndy Whitcroft my ($in_comment) = @_; 1413773647a0SAndy Whitcroft 1414773647a0SAndy Whitcroft if ($in_comment) { 1415773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1416773647a0SAndy Whitcroft } else { 1417773647a0SAndy Whitcroft $sanitise_quote = ''; 1418773647a0SAndy Whitcroft } 1419773647a0SAndy Whitcroft} 142000df344fSAndy Whitcroftsub sanitise_line { 142100df344fSAndy Whitcroft my ($line) = @_; 142200df344fSAndy Whitcroft 142300df344fSAndy Whitcroft my $res = ''; 142400df344fSAndy Whitcroft my $l = ''; 142500df344fSAndy Whitcroft 1426c2fdda0dSAndy Whitcroft my $qlen = 0; 1427773647a0SAndy Whitcroft my $off = 0; 1428773647a0SAndy Whitcroft my $c; 142900df344fSAndy Whitcroft 1430773647a0SAndy Whitcroft # Always copy over the diff marker. 1431773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1432773647a0SAndy Whitcroft 1433773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1434773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1435773647a0SAndy Whitcroft 14368d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1437773647a0SAndy Whitcroft # and end, all to $;. 1438773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1439773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1440773647a0SAndy Whitcroft 1441773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1442773647a0SAndy Whitcroft $off++; 144300df344fSAndy Whitcroft next; 1444773647a0SAndy Whitcroft } 144581bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1446773647a0SAndy Whitcroft $sanitise_quote = ''; 1447773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1448773647a0SAndy Whitcroft $off++; 1449773647a0SAndy Whitcroft next; 1450773647a0SAndy Whitcroft } 1451113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1452113f04a8SDaniel Walker $sanitise_quote = '//'; 1453113f04a8SDaniel Walker 1454113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1455113f04a8SDaniel Walker $off++; 1456113f04a8SDaniel Walker next; 1457113f04a8SDaniel Walker } 1458773647a0SAndy Whitcroft 1459773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1460773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1461773647a0SAndy Whitcroft $c eq "\\") { 1462773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1463773647a0SAndy Whitcroft $off++; 1464773647a0SAndy Whitcroft next; 1465773647a0SAndy Whitcroft } 1466773647a0SAndy Whitcroft # Regular quotes. 1467773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1468773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1469773647a0SAndy Whitcroft $sanitise_quote = $c; 1470773647a0SAndy Whitcroft 1471773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1472773647a0SAndy Whitcroft next; 1473773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1474773647a0SAndy Whitcroft $sanitise_quote = ''; 147500df344fSAndy Whitcroft } 147600df344fSAndy Whitcroft } 1477773647a0SAndy Whitcroft 1478fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1479773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1480773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1481113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1482113f04a8SDaniel Walker substr($res, $off, 1, $;); 1483773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1484773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 148500df344fSAndy Whitcroft } else { 1486773647a0SAndy Whitcroft substr($res, $off, 1, $c); 148700df344fSAndy Whitcroft } 1488c2fdda0dSAndy Whitcroft } 1489c2fdda0dSAndy Whitcroft 1490113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1491113f04a8SDaniel Walker $sanitise_quote = ''; 1492113f04a8SDaniel Walker } 1493113f04a8SDaniel Walker 1494c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1495c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1496c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1497c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1498c2fdda0dSAndy Whitcroft 1499c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1500c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1501c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1502c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1503c2fdda0dSAndy Whitcroft } 1504c2fdda0dSAndy Whitcroft 1505dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1506dadf680dSJoe Perches my $match = $1; 1507dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1508dadf680dSJoe Perches } 1509dadf680dSJoe Perches 151000df344fSAndy Whitcroft return $res; 151100df344fSAndy Whitcroft} 151200df344fSAndy Whitcroft 1513a6962d72SJoe Perchessub get_quoted_string { 1514a6962d72SJoe Perches my ($line, $rawline) = @_; 1515a6962d72SJoe Perches 1516478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 151733acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1518a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1519a6962d72SJoe Perches} 1520a6962d72SJoe Perches 15218905a67cSAndy Whitcroftsub ctx_statement_block { 15228905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 15238905a67cSAndy Whitcroft my $line = $linenr - 1; 15248905a67cSAndy Whitcroft my $blk = ''; 15258905a67cSAndy Whitcroft my $soff = $off; 15268905a67cSAndy Whitcroft my $coff = $off - 1; 1527773647a0SAndy Whitcroft my $coff_set = 0; 15288905a67cSAndy Whitcroft 152913214adfSAndy Whitcroft my $loff = 0; 153013214adfSAndy Whitcroft 15318905a67cSAndy Whitcroft my $type = ''; 15328905a67cSAndy Whitcroft my $level = 0; 1533a2750645SAndy Whitcroft my @stack = (); 1534cf655043SAndy Whitcroft my $p; 15358905a67cSAndy Whitcroft my $c; 15368905a67cSAndy Whitcroft my $len = 0; 153713214adfSAndy Whitcroft 153813214adfSAndy Whitcroft my $remainder; 15398905a67cSAndy Whitcroft while (1) { 1540a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1541a2750645SAndy Whitcroft 1542773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 15438905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 15448905a67cSAndy Whitcroft # context. 15458905a67cSAndy Whitcroft if ($off >= $len) { 15468905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1547dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1548c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 15498905a67cSAndy Whitcroft $remain--; 155013214adfSAndy Whitcroft $loff = $len; 1551c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 15528905a67cSAndy Whitcroft $len = length($blk); 15538905a67cSAndy Whitcroft $line++; 15548905a67cSAndy Whitcroft last; 15558905a67cSAndy Whitcroft } 15568905a67cSAndy Whitcroft # Bail if there is no further context. 15578905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 155813214adfSAndy Whitcroft if ($off >= $len) { 15598905a67cSAndy Whitcroft last; 15608905a67cSAndy Whitcroft } 1561f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1562f74bd194SAndy Whitcroft $level++; 1563f74bd194SAndy Whitcroft $type = '#'; 1564f74bd194SAndy Whitcroft } 15658905a67cSAndy Whitcroft } 1566cf655043SAndy Whitcroft $p = $c; 15678905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 156813214adfSAndy Whitcroft $remainder = substr($blk, $off); 15698905a67cSAndy Whitcroft 1570773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 15714635f4fbSAndy Whitcroft 15724635f4fbSAndy Whitcroft # Handle nested #if/#else. 15734635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 15744635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 15754635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 15764635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 15774635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 15784635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 15794635f4fbSAndy Whitcroft } 15804635f4fbSAndy Whitcroft 15818905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 15828905a67cSAndy Whitcroft # outermost level. 15838905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 15848905a67cSAndy Whitcroft last; 15858905a67cSAndy Whitcroft } 15868905a67cSAndy Whitcroft 158713214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1588773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1589773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1590773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1591773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1592773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1593773647a0SAndy Whitcroft $coff_set = 1; 1594773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1595773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 159613214adfSAndy Whitcroft } 159713214adfSAndy Whitcroft 15988905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 15998905a67cSAndy Whitcroft $level++; 16008905a67cSAndy Whitcroft $type = '('; 16018905a67cSAndy Whitcroft } 16028905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 16038905a67cSAndy Whitcroft $level--; 16048905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 16058905a67cSAndy Whitcroft 16068905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 16078905a67cSAndy Whitcroft $coff = $off; 1608773647a0SAndy Whitcroft $coff_set = 1; 1609773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 16108905a67cSAndy Whitcroft } 16118905a67cSAndy Whitcroft } 16128905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 16138905a67cSAndy Whitcroft $level++; 16148905a67cSAndy Whitcroft $type = '{'; 16158905a67cSAndy Whitcroft } 16168905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 16178905a67cSAndy Whitcroft $level--; 16188905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 16198905a67cSAndy Whitcroft 16208905a67cSAndy Whitcroft if ($level == 0) { 1621b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1622b998e001SPatrick Pannuto $off++; 1623b998e001SPatrick Pannuto } 16248905a67cSAndy Whitcroft last; 16258905a67cSAndy Whitcroft } 16268905a67cSAndy Whitcroft } 1627f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1628f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1629f74bd194SAndy Whitcroft $level--; 1630f74bd194SAndy Whitcroft $type = ''; 1631f74bd194SAndy Whitcroft $off++; 1632f74bd194SAndy Whitcroft last; 1633f74bd194SAndy Whitcroft } 16348905a67cSAndy Whitcroft $off++; 16358905a67cSAndy Whitcroft } 1636a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 163713214adfSAndy Whitcroft if ($off == $len) { 1638a3bb97a7SAndy Whitcroft $loff = $len + 1; 163913214adfSAndy Whitcroft $line++; 164013214adfSAndy Whitcroft $remain--; 164113214adfSAndy Whitcroft } 16428905a67cSAndy Whitcroft 16438905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 16448905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 16458905a67cSAndy Whitcroft 16468905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 16478905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 16488905a67cSAndy Whitcroft 1649773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 165013214adfSAndy Whitcroft 165113214adfSAndy Whitcroft return ($statement, $condition, 165213214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 165313214adfSAndy Whitcroft} 165413214adfSAndy Whitcroft 1655cf655043SAndy Whitcroftsub statement_lines { 1656cf655043SAndy Whitcroft my ($stmt) = @_; 1657cf655043SAndy Whitcroft 1658cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1659cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1660cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1661cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1662cf655043SAndy Whitcroft 1663cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1664cf655043SAndy Whitcroft 1665cf655043SAndy Whitcroft return $#stmt_lines + 2; 1666cf655043SAndy Whitcroft} 1667cf655043SAndy Whitcroft 1668cf655043SAndy Whitcroftsub statement_rawlines { 1669cf655043SAndy Whitcroft my ($stmt) = @_; 1670cf655043SAndy Whitcroft 1671cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1672cf655043SAndy Whitcroft 1673cf655043SAndy Whitcroft return $#stmt_lines + 2; 1674cf655043SAndy Whitcroft} 1675cf655043SAndy Whitcroft 1676cf655043SAndy Whitcroftsub statement_block_size { 1677cf655043SAndy Whitcroft my ($stmt) = @_; 1678cf655043SAndy Whitcroft 1679cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1680cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1681cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1682cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1683cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1684cf655043SAndy Whitcroft 1685cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1686cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1687cf655043SAndy Whitcroft 1688cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1689cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1690cf655043SAndy Whitcroft 1691cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1692cf655043SAndy Whitcroft return $stmt_lines; 1693cf655043SAndy Whitcroft } else { 1694cf655043SAndy Whitcroft return $stmt_statements; 1695cf655043SAndy Whitcroft } 1696cf655043SAndy Whitcroft} 1697cf655043SAndy Whitcroft 169813214adfSAndy Whitcroftsub ctx_statement_full { 169913214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 170013214adfSAndy Whitcroft my ($statement, $condition, $level); 170113214adfSAndy Whitcroft 170213214adfSAndy Whitcroft my (@chunks); 170313214adfSAndy Whitcroft 1704cf655043SAndy Whitcroft # Grab the first conditional/block pair. 170513214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 170613214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1707773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 170813214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1709cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1710cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1711cf655043SAndy Whitcroft } 1712cf655043SAndy Whitcroft 1713cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1714cf655043SAndy Whitcroft # could continue the statement. 1715cf655043SAndy Whitcroft for (;;) { 171613214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 171713214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1718cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1719773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1720cf655043SAndy Whitcroft #print "C: push\n"; 1721cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 172213214adfSAndy Whitcroft } 172313214adfSAndy Whitcroft 172413214adfSAndy Whitcroft return ($level, $linenr, @chunks); 17258905a67cSAndy Whitcroft} 17268905a67cSAndy Whitcroft 17274a0df2efSAndy Whitcroftsub ctx_block_get { 1728f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 17294a0df2efSAndy Whitcroft my $line; 17304a0df2efSAndy Whitcroft my $start = $linenr - 1; 17314a0df2efSAndy Whitcroft my $blk = ''; 17324a0df2efSAndy Whitcroft my @o; 17334a0df2efSAndy Whitcroft my @c; 17344a0df2efSAndy Whitcroft my @res = (); 17354a0df2efSAndy Whitcroft 1736f0a594c1SAndy Whitcroft my $level = 0; 17374635f4fbSAndy Whitcroft my @stack = ($level); 173800df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 173900df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 174000df344fSAndy Whitcroft $remain--; 174100df344fSAndy Whitcroft 174200df344fSAndy Whitcroft $blk .= $rawlines[$line]; 17434635f4fbSAndy Whitcroft 17444635f4fbSAndy Whitcroft # Handle nested #if/#else. 174501464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 17464635f4fbSAndy Whitcroft push(@stack, $level); 174701464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 17484635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 174901464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 17504635f4fbSAndy Whitcroft $level = pop(@stack); 17514635f4fbSAndy Whitcroft } 17524635f4fbSAndy Whitcroft 175301464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1754f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1755f0a594c1SAndy Whitcroft if ($off > 0) { 1756f0a594c1SAndy Whitcroft $off--; 1757f0a594c1SAndy Whitcroft next; 1758f0a594c1SAndy Whitcroft } 17594a0df2efSAndy Whitcroft 1760f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1761f0a594c1SAndy Whitcroft $level--; 1762f0a594c1SAndy Whitcroft last if ($level == 0); 1763f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1764f0a594c1SAndy Whitcroft $level++; 1765f0a594c1SAndy Whitcroft } 1766f0a594c1SAndy Whitcroft } 17674a0df2efSAndy Whitcroft 1768f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 176900df344fSAndy Whitcroft push(@res, $rawlines[$line]); 17704a0df2efSAndy Whitcroft } 17714a0df2efSAndy Whitcroft 1772f0a594c1SAndy Whitcroft last if ($level == 0); 17734a0df2efSAndy Whitcroft } 17744a0df2efSAndy Whitcroft 1775f0a594c1SAndy Whitcroft return ($level, @res); 17764a0df2efSAndy Whitcroft} 17774a0df2efSAndy Whitcroftsub ctx_block_outer { 17784a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 17794a0df2efSAndy Whitcroft 1780f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1781f0a594c1SAndy Whitcroft return @r; 17824a0df2efSAndy Whitcroft} 17834a0df2efSAndy Whitcroftsub ctx_block { 17844a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 17854a0df2efSAndy Whitcroft 1786f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1787f0a594c1SAndy Whitcroft return @r; 1788653d4876SAndy Whitcroft} 1789653d4876SAndy Whitcroftsub ctx_statement { 1790f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1791f0a594c1SAndy Whitcroft 1792f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1793f0a594c1SAndy Whitcroft return @r; 1794f0a594c1SAndy Whitcroft} 1795f0a594c1SAndy Whitcroftsub ctx_block_level { 1796653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1797653d4876SAndy Whitcroft 1798f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 17994a0df2efSAndy Whitcroft} 18009c0ca6f9SAndy Whitcroftsub ctx_statement_level { 18019c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 18029c0ca6f9SAndy Whitcroft 18039c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 18049c0ca6f9SAndy Whitcroft} 18054a0df2efSAndy Whitcroft 18064a0df2efSAndy Whitcroftsub ctx_locate_comment { 18074a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 18084a0df2efSAndy Whitcroft 1809a55ee0ccSJoe Perches # If c99 comment on the current line, or the line before or after 1810a55ee0ccSJoe Perches my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); 1811a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1812a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); 1813a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1814a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); 1815a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1816a55ee0ccSJoe Perches 18174a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1818a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 18194a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 18204a0df2efSAndy Whitcroft 18214a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 18224a0df2efSAndy Whitcroft # comment. 18234a0df2efSAndy Whitcroft my $in_comment = 0; 18244a0df2efSAndy Whitcroft $current_comment = ''; 18254a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 182600df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 182700df344fSAndy Whitcroft #warn " $line\n"; 18284a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 18294a0df2efSAndy Whitcroft $in_comment = 1; 18304a0df2efSAndy Whitcroft } 18314a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 18324a0df2efSAndy Whitcroft $in_comment = 1; 18334a0df2efSAndy Whitcroft } 18344a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 18354a0df2efSAndy Whitcroft $current_comment = ''; 18364a0df2efSAndy Whitcroft } 18374a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 18384a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 18394a0df2efSAndy Whitcroft $in_comment = 0; 18404a0df2efSAndy Whitcroft } 18414a0df2efSAndy Whitcroft } 18424a0df2efSAndy Whitcroft 18434a0df2efSAndy Whitcroft chomp($current_comment); 18444a0df2efSAndy Whitcroft return($current_comment); 18454a0df2efSAndy Whitcroft} 18464a0df2efSAndy Whitcroftsub ctx_has_comment { 18474a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 18484a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 18494a0df2efSAndy Whitcroft 185000df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 18514a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 18524a0df2efSAndy Whitcroft 18534a0df2efSAndy Whitcroft return ($cmt ne ''); 18544a0df2efSAndy Whitcroft} 18554a0df2efSAndy Whitcroft 18564d001e4dSAndy Whitcroftsub raw_line { 18574d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 18584d001e4dSAndy Whitcroft 18594d001e4dSAndy Whitcroft my $offset = $linenr - 1; 18604d001e4dSAndy Whitcroft $cnt++; 18614d001e4dSAndy Whitcroft 18624d001e4dSAndy Whitcroft my $line; 18634d001e4dSAndy Whitcroft while ($cnt) { 18644d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 18654d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 18664d001e4dSAndy Whitcroft $cnt--; 18674d001e4dSAndy Whitcroft } 18684d001e4dSAndy Whitcroft 18694d001e4dSAndy Whitcroft return $line; 18704d001e4dSAndy Whitcroft} 18714d001e4dSAndy Whitcroft 18722a9f9d85STobin C. Hardingsub get_stat_real { 18732a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 18742a9f9d85STobin C. Harding 18752a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 18762a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 18772a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 18782a9f9d85STobin C. Harding } 18792a9f9d85STobin C. Harding 18802a9f9d85STobin C. Harding return $stat_real; 18812a9f9d85STobin C. Harding} 18822a9f9d85STobin C. Harding 1883e3d95a2aSTobin C. Hardingsub get_stat_here { 1884e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 1885e3d95a2aSTobin C. Harding 1886e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 1887e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 1888e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 1889e3d95a2aSTobin C. Harding } 1890e3d95a2aSTobin C. Harding 1891e3d95a2aSTobin C. Harding return $herectx; 1892e3d95a2aSTobin C. Harding} 1893e3d95a2aSTobin C. Harding 18940a920b5bSAndy Whitcroftsub cat_vet { 18950a920b5bSAndy Whitcroft my ($vet) = @_; 18969c0ca6f9SAndy Whitcroft my ($res, $coded); 18970a920b5bSAndy Whitcroft 18989c0ca6f9SAndy Whitcroft $res = ''; 18996c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 19006c72ffaaSAndy Whitcroft $res .= $1; 19016c72ffaaSAndy Whitcroft if ($2 ne '') { 19029c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 19036c72ffaaSAndy Whitcroft $res .= $coded; 19046c72ffaaSAndy Whitcroft } 19059c0ca6f9SAndy Whitcroft } 19069c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 19070a920b5bSAndy Whitcroft 19089c0ca6f9SAndy Whitcroft return $res; 19090a920b5bSAndy Whitcroft} 19100a920b5bSAndy Whitcroft 1911c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1912cf655043SAndy Whitcroftmy $av_pending; 1913c2fdda0dSAndy Whitcroftmy @av_paren_type; 19141f65f947SAndy Whitcroftmy $av_pend_colon; 1915c2fdda0dSAndy Whitcroft 1916c2fdda0dSAndy Whitcroftsub annotate_reset { 1917c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1918cf655043SAndy Whitcroft $av_pending = '_'; 1919cf655043SAndy Whitcroft @av_paren_type = ('E'); 19201f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1921c2fdda0dSAndy Whitcroft} 1922c2fdda0dSAndy Whitcroft 19236c72ffaaSAndy Whitcroftsub annotate_values { 19246c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 19256c72ffaaSAndy Whitcroft 19266c72ffaaSAndy Whitcroft my $res; 19271f65f947SAndy Whitcroft my $var = '_' x length($stream); 19286c72ffaaSAndy Whitcroft my $cur = $stream; 19296c72ffaaSAndy Whitcroft 1930c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 19316c72ffaaSAndy Whitcroft 19326c72ffaaSAndy Whitcroft while (length($cur)) { 1933773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1934cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1935171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 19366c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1937c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1938c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1939cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1940c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 19416c72ffaaSAndy Whitcroft } 19426c72ffaaSAndy Whitcroft 1943c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 19449446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 19459446ef56SAndy Whitcroft push(@av_paren_type, $type); 1946addcdceaSAndy Whitcroft $type = 'c'; 19479446ef56SAndy Whitcroft 1948e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1949c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 19506c72ffaaSAndy Whitcroft $type = 'T'; 19516c72ffaaSAndy Whitcroft 1952389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1953389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1954389a2fe5SAndy Whitcroft $type = 'T'; 1955389a2fe5SAndy Whitcroft 1956c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1957171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1958c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1959171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1960171ae1a4SAndy Whitcroft if ($2 ne '') { 1961cf655043SAndy Whitcroft $av_pending = 'N'; 1962171ae1a4SAndy Whitcroft } 1963171ae1a4SAndy Whitcroft $type = 'E'; 1964171ae1a4SAndy Whitcroft 1965c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1966171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1967171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1968171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 19696c72ffaaSAndy Whitcroft 1970c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1971cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1972c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1973cf655043SAndy Whitcroft 1974cf655043SAndy Whitcroft push(@av_paren_type, $type); 1975cf655043SAndy Whitcroft push(@av_paren_type, $type); 1976171ae1a4SAndy Whitcroft $type = 'E'; 1977cf655043SAndy Whitcroft 1978c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1979cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1980cf655043SAndy Whitcroft $av_preprocessor = 1; 1981cf655043SAndy Whitcroft 1982cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1983cf655043SAndy Whitcroft 1984171ae1a4SAndy Whitcroft $type = 'E'; 1985cf655043SAndy Whitcroft 1986c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1987cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1988cf655043SAndy Whitcroft 1989cf655043SAndy Whitcroft $av_preprocessor = 1; 1990cf655043SAndy Whitcroft 1991cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1992cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1993cf655043SAndy Whitcroft pop(@av_paren_type); 1994cf655043SAndy Whitcroft push(@av_paren_type, $type); 1995171ae1a4SAndy Whitcroft $type = 'E'; 19966c72ffaaSAndy Whitcroft 19976c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1998c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 19996c72ffaaSAndy Whitcroft 2000171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 2001171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 2002171ae1a4SAndy Whitcroft $av_pending = $type; 2003171ae1a4SAndy Whitcroft $type = 'N'; 2004171ae1a4SAndy Whitcroft 20056c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 2006c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 20076c72ffaaSAndy Whitcroft if (defined $2) { 2008cf655043SAndy Whitcroft $av_pending = 'V'; 20096c72ffaaSAndy Whitcroft } 20106c72ffaaSAndy Whitcroft $type = 'N'; 20116c72ffaaSAndy Whitcroft 201214b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 2013c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 201414b111c1SAndy Whitcroft $av_pending = 'E'; 20156c72ffaaSAndy Whitcroft $type = 'N'; 20166c72ffaaSAndy Whitcroft 20171f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 20181f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 20191f65f947SAndy Whitcroft $av_pend_colon = 'C'; 20201f65f947SAndy Whitcroft $type = 'N'; 20211f65f947SAndy Whitcroft 202214b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 2023c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 20246c72ffaaSAndy Whitcroft $type = 'N'; 20256c72ffaaSAndy Whitcroft 20266c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 2027c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 2028cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 2029cf655043SAndy Whitcroft $av_pending = '_'; 20306c72ffaaSAndy Whitcroft $type = 'N'; 20316c72ffaaSAndy Whitcroft 20326c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 2033cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 2034cf655043SAndy Whitcroft if ($new_type ne '_') { 2035cf655043SAndy Whitcroft $type = $new_type; 2036c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 2037c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 20386c72ffaaSAndy Whitcroft } else { 2039c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 20406c72ffaaSAndy Whitcroft } 20416c72ffaaSAndy Whitcroft 2042c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 2043c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 2044c8cb2ca3SAndy Whitcroft $type = 'V'; 2045cf655043SAndy Whitcroft $av_pending = 'V'; 20466c72ffaaSAndy Whitcroft 20478e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 20488e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 20491f65f947SAndy Whitcroft $av_pend_colon = 'B'; 20508e761b04SAndy Whitcroft } elsif ($type eq 'E') { 20518e761b04SAndy Whitcroft $av_pend_colon = 'L'; 20521f65f947SAndy Whitcroft } 20531f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 20541f65f947SAndy Whitcroft $type = 'V'; 20551f65f947SAndy Whitcroft 20566c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 2057c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 20586c72ffaaSAndy Whitcroft $type = 'V'; 20596c72ffaaSAndy Whitcroft 20606c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 2061c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 20626c72ffaaSAndy Whitcroft $type = 'N'; 20636c72ffaaSAndy Whitcroft 2064cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 2065c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 206613214adfSAndy Whitcroft $type = 'E'; 20671f65f947SAndy Whitcroft $av_pend_colon = 'O'; 206813214adfSAndy Whitcroft 20698e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 20708e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 20718e761b04SAndy Whitcroft $type = 'C'; 20728e761b04SAndy Whitcroft 20731f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 20741f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 20751f65f947SAndy Whitcroft $type = 'N'; 20761f65f947SAndy Whitcroft 20771f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 20781f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 20791f65f947SAndy Whitcroft 20801f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 20811f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 20821f65f947SAndy Whitcroft $type = 'E'; 20831f65f947SAndy Whitcroft } else { 20841f65f947SAndy Whitcroft $type = 'N'; 20851f65f947SAndy Whitcroft } 20861f65f947SAndy Whitcroft $av_pend_colon = 'O'; 20871f65f947SAndy Whitcroft 20888e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 208913214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 20906c72ffaaSAndy Whitcroft $type = 'N'; 20916c72ffaaSAndy Whitcroft 20920d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 209374048ed8SAndy Whitcroft my $variant; 209474048ed8SAndy Whitcroft 209574048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 209674048ed8SAndy Whitcroft if ($type eq 'V') { 209774048ed8SAndy Whitcroft $variant = 'B'; 209874048ed8SAndy Whitcroft } else { 209974048ed8SAndy Whitcroft $variant = 'U'; 210074048ed8SAndy Whitcroft } 210174048ed8SAndy Whitcroft 210274048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 210374048ed8SAndy Whitcroft $type = 'N'; 210474048ed8SAndy Whitcroft 21056c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 2106c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 21076c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 21086c72ffaaSAndy Whitcroft $type = 'N'; 21096c72ffaaSAndy Whitcroft } 21106c72ffaaSAndy Whitcroft 21116c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 2112c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 21136c72ffaaSAndy Whitcroft } 21146c72ffaaSAndy Whitcroft if (defined $1) { 21156c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 21166c72ffaaSAndy Whitcroft $res .= $type x length($1); 21176c72ffaaSAndy Whitcroft } 21186c72ffaaSAndy Whitcroft } 21196c72ffaaSAndy Whitcroft 21201f65f947SAndy Whitcroft return ($res, $var); 21216c72ffaaSAndy Whitcroft} 21226c72ffaaSAndy Whitcroft 21238905a67cSAndy Whitcroftsub possible { 212413214adfSAndy Whitcroft my ($possible, $line) = @_; 21259a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 21260776e594SAndy Whitcroft ^(?: 21270776e594SAndy Whitcroft $Modifier| 21280776e594SAndy Whitcroft $Storage| 21290776e594SAndy Whitcroft $Type| 21309a974fdbSAndy Whitcroft DEFINE_\S+ 21319a974fdbSAndy Whitcroft )$| 21329a974fdbSAndy Whitcroft ^(?: 21330776e594SAndy Whitcroft goto| 21340776e594SAndy Whitcroft return| 21350776e594SAndy Whitcroft case| 21360776e594SAndy Whitcroft else| 21370776e594SAndy Whitcroft asm|__asm__| 213889a88353SAndy Whitcroft do| 213989a88353SAndy Whitcroft \#| 214089a88353SAndy Whitcroft \#\#| 21419a974fdbSAndy Whitcroft )(?:\s|$)| 21420776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 21439a974fdbSAndy Whitcroft )}x; 21449a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 21459a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 2146c45dcabdSAndy Whitcroft # Check for modifiers. 2147c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 2148c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 2149c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 2150c45dcabdSAndy Whitcroft 2151c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 2152c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 2153d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 21549a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 2155d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 2156485ff23eSAlex Dowad push(@modifierListFile, $modifier); 2157d2506586SAndy Whitcroft } 21589a974fdbSAndy Whitcroft } 2159c45dcabdSAndy Whitcroft 2160c45dcabdSAndy Whitcroft } else { 216113214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 2162485ff23eSAlex Dowad push(@typeListFile, $possible); 2163c45dcabdSAndy Whitcroft } 21648905a67cSAndy Whitcroft build_types(); 21650776e594SAndy Whitcroft } else { 21660776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 21678905a67cSAndy Whitcroft } 21688905a67cSAndy Whitcroft} 21698905a67cSAndy Whitcroft 21706c72ffaaSAndy Whitcroftmy $prefix = ''; 21716c72ffaaSAndy Whitcroft 2172000d1cc1SJoe Perchessub show_type { 2173cbec18afSJoe Perches my ($type) = @_; 217491bfe484SJoe Perches 2175522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2176522b837cSAlexey Dobriyan 2177cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2178cbec18afSJoe Perches 2179cbec18afSJoe Perches return !defined $ignore_type{$type}; 2180000d1cc1SJoe Perches} 2181000d1cc1SJoe Perches 2182f0a594c1SAndy Whitcroftsub report { 2183cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2184cbec18afSJoe Perches 2185cbec18afSJoe Perches if (!show_type($type) || 2186cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2187773647a0SAndy Whitcroft return 0; 2188773647a0SAndy Whitcroft } 218957230297SJoe Perches my $output = ''; 2190737c0767SJohn Brooks if ($color) { 219157230297SJoe Perches if ($level eq 'ERROR') { 219257230297SJoe Perches $output .= RED; 219357230297SJoe Perches } elsif ($level eq 'WARNING') { 219457230297SJoe Perches $output .= YELLOW; 2195000d1cc1SJoe Perches } else { 219657230297SJoe Perches $output .= GREEN; 2197000d1cc1SJoe Perches } 219857230297SJoe Perches } 219957230297SJoe Perches $output .= $prefix . $level . ':'; 220057230297SJoe Perches if ($show_types) { 2201737c0767SJohn Brooks $output .= BLUE if ($color); 220257230297SJoe Perches $output .= "$type:"; 220357230297SJoe Perches } 2204737c0767SJohn Brooks $output .= RESET if ($color); 220557230297SJoe Perches $output .= ' ' . $msg . "\n"; 220634d8815fSJoe Perches 220734d8815fSJoe Perches if ($showfile) { 220834d8815fSJoe Perches my @lines = split("\n", $output, -1); 220934d8815fSJoe Perches splice(@lines, 1, 1); 221034d8815fSJoe Perches $output = join("\n", @lines); 221134d8815fSJoe Perches } 221257230297SJoe Perches $output = (split('\n', $output))[0] . "\n" if ($terse); 22138905a67cSAndy Whitcroft 221457230297SJoe Perches push(our @report, $output); 2215773647a0SAndy Whitcroft 2216773647a0SAndy Whitcroft return 1; 2217f0a594c1SAndy Whitcroft} 2218cbec18afSJoe Perches 2219f0a594c1SAndy Whitcroftsub report_dump { 222013214adfSAndy Whitcroft our @report; 2221f0a594c1SAndy Whitcroft} 2222000d1cc1SJoe Perches 2223d752fcc8SJoe Perchessub fixup_current_range { 2224d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2225d752fcc8SJoe Perches 2226d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2227d752fcc8SJoe Perches my $o = $1; 2228d752fcc8SJoe Perches my $l = $2; 2229d752fcc8SJoe Perches my $no = $o + $offset; 2230d752fcc8SJoe Perches my $nl = $l + $length; 2231d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2232d752fcc8SJoe Perches } 2233d752fcc8SJoe Perches} 2234d752fcc8SJoe Perches 2235d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2236d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2237d752fcc8SJoe Perches 2238d752fcc8SJoe Perches my $range_last_linenr = 0; 2239d752fcc8SJoe Perches my $delta_offset = 0; 2240d752fcc8SJoe Perches 2241d752fcc8SJoe Perches my $old_linenr = 0; 2242d752fcc8SJoe Perches my $new_linenr = 0; 2243d752fcc8SJoe Perches 2244d752fcc8SJoe Perches my $next_insert = 0; 2245d752fcc8SJoe Perches my $next_delete = 0; 2246d752fcc8SJoe Perches 2247d752fcc8SJoe Perches my @lines = (); 2248d752fcc8SJoe Perches 2249d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2250d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2251d752fcc8SJoe Perches 2252d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2253d752fcc8SJoe Perches my $save_line = 1; 2254d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2255323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2256d752fcc8SJoe Perches $delta_offset = 0; 2257d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2258d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2259d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2260d752fcc8SJoe Perches } 2261d752fcc8SJoe Perches 2262d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2263d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2264d752fcc8SJoe Perches $save_line = 0; 2265d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2266d752fcc8SJoe Perches } 2267d752fcc8SJoe Perches 2268d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2269d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2270d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2271d752fcc8SJoe Perches $new_linenr++; 2272d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2273d752fcc8SJoe Perches } 2274d752fcc8SJoe Perches 2275d752fcc8SJoe Perches if ($save_line) { 2276d752fcc8SJoe Perches push(@lines, $line); 2277d752fcc8SJoe Perches $new_linenr++; 2278d752fcc8SJoe Perches } 2279d752fcc8SJoe Perches 2280d752fcc8SJoe Perches $old_linenr++; 2281d752fcc8SJoe Perches } 2282d752fcc8SJoe Perches 2283d752fcc8SJoe Perches return @lines; 2284d752fcc8SJoe Perches} 2285d752fcc8SJoe Perches 2286f2d7e4d4SJoe Perchessub fix_insert_line { 2287f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2288f2d7e4d4SJoe Perches 2289f2d7e4d4SJoe Perches my $inserted = { 2290f2d7e4d4SJoe Perches LINENR => $linenr, 2291f2d7e4d4SJoe Perches LINE => $line, 2292f2d7e4d4SJoe Perches }; 2293f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2294f2d7e4d4SJoe Perches} 2295f2d7e4d4SJoe Perches 2296f2d7e4d4SJoe Perchessub fix_delete_line { 2297f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2298f2d7e4d4SJoe Perches 2299f2d7e4d4SJoe Perches my $deleted = { 2300f2d7e4d4SJoe Perches LINENR => $linenr, 2301f2d7e4d4SJoe Perches LINE => $line, 2302f2d7e4d4SJoe Perches }; 2303f2d7e4d4SJoe Perches 2304f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2305f2d7e4d4SJoe Perches} 2306f2d7e4d4SJoe Perches 2307de7d4f0eSAndy Whitcroftsub ERROR { 2308cbec18afSJoe Perches my ($type, $msg) = @_; 2309cbec18afSJoe Perches 2310cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2311de7d4f0eSAndy Whitcroft our $clean = 0; 23126c72ffaaSAndy Whitcroft our $cnt_error++; 23133705ce5bSJoe Perches return 1; 2314de7d4f0eSAndy Whitcroft } 23153705ce5bSJoe Perches return 0; 2316773647a0SAndy Whitcroft} 2317de7d4f0eSAndy Whitcroftsub WARN { 2318cbec18afSJoe Perches my ($type, $msg) = @_; 2319cbec18afSJoe Perches 2320cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2321de7d4f0eSAndy Whitcroft our $clean = 0; 23226c72ffaaSAndy Whitcroft our $cnt_warn++; 23233705ce5bSJoe Perches return 1; 2324de7d4f0eSAndy Whitcroft } 23253705ce5bSJoe Perches return 0; 2326773647a0SAndy Whitcroft} 2327de7d4f0eSAndy Whitcroftsub CHK { 2328cbec18afSJoe Perches my ($type, $msg) = @_; 2329cbec18afSJoe Perches 2330cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2331de7d4f0eSAndy Whitcroft our $clean = 0; 23326c72ffaaSAndy Whitcroft our $cnt_chk++; 23333705ce5bSJoe Perches return 1; 23346c72ffaaSAndy Whitcroft } 23353705ce5bSJoe Perches return 0; 2336de7d4f0eSAndy Whitcroft} 2337de7d4f0eSAndy Whitcroft 23386ecd9674SAndy Whitcroftsub check_absolute_file { 23396ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 23406ecd9674SAndy Whitcroft my $file = $absolute; 23416ecd9674SAndy Whitcroft 23426ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 23436ecd9674SAndy Whitcroft 23446ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 23456ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 23466ecd9674SAndy Whitcroft if (-f "$root/$file") { 23476ecd9674SAndy Whitcroft ##print "file<$file>\n"; 23486ecd9674SAndy Whitcroft last; 23496ecd9674SAndy Whitcroft } 23506ecd9674SAndy Whitcroft } 23516ecd9674SAndy Whitcroft if (! -f _) { 23526ecd9674SAndy Whitcroft return 0; 23536ecd9674SAndy Whitcroft } 23546ecd9674SAndy Whitcroft 23556ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 23566ecd9674SAndy Whitcroft my $prefix = $absolute; 23576ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 23586ecd9674SAndy Whitcroft 23596ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 23606ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2361000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2362000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 23636ecd9674SAndy Whitcroft } 23646ecd9674SAndy Whitcroft} 23656ecd9674SAndy Whitcroft 23663705ce5bSJoe Perchessub trim { 23673705ce5bSJoe Perches my ($string) = @_; 23683705ce5bSJoe Perches 2369b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2370b34c648bSJoe Perches 2371b34c648bSJoe Perches return $string; 2372b34c648bSJoe Perches} 2373b34c648bSJoe Perches 2374b34c648bSJoe Perchessub ltrim { 2375b34c648bSJoe Perches my ($string) = @_; 2376b34c648bSJoe Perches 2377b34c648bSJoe Perches $string =~ s/^\s+//; 2378b34c648bSJoe Perches 2379b34c648bSJoe Perches return $string; 2380b34c648bSJoe Perches} 2381b34c648bSJoe Perches 2382b34c648bSJoe Perchessub rtrim { 2383b34c648bSJoe Perches my ($string) = @_; 2384b34c648bSJoe Perches 2385b34c648bSJoe Perches $string =~ s/\s+$//; 23863705ce5bSJoe Perches 23873705ce5bSJoe Perches return $string; 23883705ce5bSJoe Perches} 23893705ce5bSJoe Perches 239052ea8506SJoe Perchessub string_find_replace { 239152ea8506SJoe Perches my ($string, $find, $replace) = @_; 239252ea8506SJoe Perches 239352ea8506SJoe Perches $string =~ s/$find/$replace/g; 239452ea8506SJoe Perches 239552ea8506SJoe Perches return $string; 239652ea8506SJoe Perches} 239752ea8506SJoe Perches 23983705ce5bSJoe Perchessub tabify { 23993705ce5bSJoe Perches my ($leading) = @_; 24003705ce5bSJoe Perches 2401713a09deSAntonio Borneo my $source_indent = $tabsize; 24023705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 24033705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 24043705ce5bSJoe Perches 24053705ce5bSJoe Perches #convert leading spaces to tabs 24063705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 24073705ce5bSJoe Perches #Remove spaces before a tab 24083705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 24093705ce5bSJoe Perches 24103705ce5bSJoe Perches return "$leading"; 24113705ce5bSJoe Perches} 24123705ce5bSJoe Perches 2413d1fe9c09SJoe Perchessub pos_last_openparen { 2414d1fe9c09SJoe Perches my ($line) = @_; 2415d1fe9c09SJoe Perches 2416d1fe9c09SJoe Perches my $pos = 0; 2417d1fe9c09SJoe Perches 2418d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2419d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2420d1fe9c09SJoe Perches 2421d1fe9c09SJoe Perches my $last_openparen = 0; 2422d1fe9c09SJoe Perches 2423d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2424d1fe9c09SJoe Perches return -1; 2425d1fe9c09SJoe Perches } 2426d1fe9c09SJoe Perches 2427d1fe9c09SJoe Perches my $len = length($line); 2428d1fe9c09SJoe Perches 2429d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2430d1fe9c09SJoe Perches my $string = substr($line, $pos); 2431d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2432d1fe9c09SJoe Perches $pos += length($1) - 1; 2433d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2434d1fe9c09SJoe Perches $last_openparen = $pos; 2435d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2436d1fe9c09SJoe Perches last; 2437d1fe9c09SJoe Perches } 2438d1fe9c09SJoe Perches } 2439d1fe9c09SJoe Perches 244091cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2441d1fe9c09SJoe Perches} 2442d1fe9c09SJoe Perches 2443f36d3eb8SJoe Perchessub get_raw_comment { 2444f36d3eb8SJoe Perches my ($line, $rawline) = @_; 2445f36d3eb8SJoe Perches my $comment = ''; 2446f36d3eb8SJoe Perches 2447f36d3eb8SJoe Perches for my $i (0 .. (length($line) - 1)) { 2448f36d3eb8SJoe Perches if (substr($line, $i, 1) eq "$;") { 2449f36d3eb8SJoe Perches $comment .= substr($rawline, $i, 1); 2450f36d3eb8SJoe Perches } 2451f36d3eb8SJoe Perches } 2452f36d3eb8SJoe Perches 2453f36d3eb8SJoe Perches return $comment; 2454f36d3eb8SJoe Perches} 2455f36d3eb8SJoe Perches 24560a920b5bSAndy Whitcroftsub process { 24570a920b5bSAndy Whitcroft my $filename = shift; 24580a920b5bSAndy Whitcroft 24590a920b5bSAndy Whitcroft my $linenr=0; 24600a920b5bSAndy Whitcroft my $prevline=""; 2461c2fdda0dSAndy Whitcroft my $prevrawline=""; 24620a920b5bSAndy Whitcroft my $stashline=""; 2463c2fdda0dSAndy Whitcroft my $stashrawline=""; 24640a920b5bSAndy Whitcroft 24654a0df2efSAndy Whitcroft my $length; 24660a920b5bSAndy Whitcroft my $indent; 24670a920b5bSAndy Whitcroft my $previndent=0; 24680a920b5bSAndy Whitcroft my $stashindent=0; 24690a920b5bSAndy Whitcroft 2470de7d4f0eSAndy Whitcroft our $clean = 1; 24710a920b5bSAndy Whitcroft my $signoff = 0; 2472cd261496SGeert Uytterhoeven my $author = ''; 2473cd261496SGeert Uytterhoeven my $authorsignoff = 0; 247448ca2d8aSDwaipayan Ray my $author_sob = ''; 24750a920b5bSAndy Whitcroft my $is_patch = 0; 2476133712a2SRob Herring my $is_binding_patch = -1; 247729ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 247815662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 247944d303ebSJoe Perches my $has_patch_separator = 0; #Found a --- line 2480ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2481490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2482bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 24832a076f40SJoe Perches my $commit_log_long_line = 0; 2484e518e9a5SJoe Perches my $commit_log_has_diff = 0; 248513f1937eSJoe Perches my $reported_maintainer_file = 0; 2486fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2487fa64205dSPasi Savanainen 2488365dd4eaSJoe Perches my $last_blank_line = 0; 24895e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2490365dd4eaSJoe Perches 249113214adfSAndy Whitcroft our @report = (); 24926c72ffaaSAndy Whitcroft our $cnt_lines = 0; 24936c72ffaaSAndy Whitcroft our $cnt_error = 0; 24946c72ffaaSAndy Whitcroft our $cnt_warn = 0; 24956c72ffaaSAndy Whitcroft our $cnt_chk = 0; 24966c72ffaaSAndy Whitcroft 24970a920b5bSAndy Whitcroft # Trace the real file/line as we go. 24980a920b5bSAndy Whitcroft my $realfile = ''; 24990a920b5bSAndy Whitcroft my $realline = 0; 25000a920b5bSAndy Whitcroft my $realcnt = 0; 25010a920b5bSAndy Whitcroft my $here = ''; 250277cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 25030a920b5bSAndy Whitcroft my $in_comment = 0; 2504c2fdda0dSAndy Whitcroft my $comment_edge = 0; 25050a920b5bSAndy Whitcroft my $first_line = 0; 25061e855726SWolfram Sang my $p1_prefix = ''; 25070a920b5bSAndy Whitcroft 250813214adfSAndy Whitcroft my $prev_values = 'E'; 250913214adfSAndy Whitcroft 251013214adfSAndy Whitcroft # suppression flags 2511773647a0SAndy Whitcroft my %suppress_ifbraces; 2512170d3a22SAndy Whitcroft my %suppress_whiletrailers; 25132b474a1aSAndy Whitcroft my %suppress_export; 25143e469cdcSAndy Whitcroft my $suppress_statement = 0; 2515653d4876SAndy Whitcroft 25167e51f197SJoe Perches my %signatures = (); 2517323c1260SJoe Perches 2518c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2519de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2520c2fdda0dSAndy Whitcroft # 2521de7d4f0eSAndy Whitcroft my @setup_docs = (); 2522de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2523773647a0SAndy Whitcroft 2524d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2525d8b07710SJoe Perches 25269f3a8992SRob Herring my $checklicenseline = 1; 25279f3a8992SRob Herring 2528773647a0SAndy Whitcroft sanitise_line_reset(); 2529c2fdda0dSAndy Whitcroft my $line; 2530c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2531773647a0SAndy Whitcroft $linenr++; 2532773647a0SAndy Whitcroft $line = $rawline; 2533c2fdda0dSAndy Whitcroft 25343705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 25353705ce5bSJoe Perches 2536773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2537de7d4f0eSAndy Whitcroft $setup_docs = 0; 25382581ac7cSTim Froidcoeur if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { 2539de7d4f0eSAndy Whitcroft $setup_docs = 1; 2540de7d4f0eSAndy Whitcroft } 2541773647a0SAndy Whitcroft #next; 2542de7d4f0eSAndy Whitcroft } 254374fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2544773647a0SAndy Whitcroft $realline=$1-1; 2545773647a0SAndy Whitcroft if (defined $2) { 2546773647a0SAndy Whitcroft $realcnt=$3+1; 2547773647a0SAndy Whitcroft } else { 2548773647a0SAndy Whitcroft $realcnt=1+1; 2549773647a0SAndy Whitcroft } 2550c45dcabdSAndy Whitcroft $in_comment = 0; 2551773647a0SAndy Whitcroft 2552773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2553773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2554773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2555773647a0SAndy Whitcroft # at context start. 2556773647a0SAndy Whitcroft my $edge; 255701fa9147SAndy Whitcroft my $cnt = $realcnt; 255801fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 255901fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 256001fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 256101fa9147SAndy Whitcroft $cnt--; 256201fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2563721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2564fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2565fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2566fae17daeSAndy Whitcroft ($edge) = $1; 2567fae17daeSAndy Whitcroft last; 2568fae17daeSAndy Whitcroft } 2569773647a0SAndy Whitcroft } 2570773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2571773647a0SAndy Whitcroft $in_comment = 1; 2572773647a0SAndy Whitcroft } 2573773647a0SAndy Whitcroft 2574773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2575773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2576773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2577773647a0SAndy Whitcroft if (!defined $edge && 257883242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2579773647a0SAndy Whitcroft { 2580773647a0SAndy Whitcroft $in_comment = 1; 2581773647a0SAndy Whitcroft } 2582773647a0SAndy Whitcroft 2583773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2584773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2585773647a0SAndy Whitcroft 2586171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2587773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2588171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2589773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2590773647a0SAndy Whitcroft } 2591773647a0SAndy Whitcroft push(@lines, $line); 2592773647a0SAndy Whitcroft 2593773647a0SAndy Whitcroft if ($realcnt > 1) { 2594773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2595773647a0SAndy Whitcroft } else { 2596773647a0SAndy Whitcroft $realcnt = 0; 2597773647a0SAndy Whitcroft } 2598773647a0SAndy Whitcroft 2599773647a0SAndy Whitcroft #print "==>$rawline\n"; 2600773647a0SAndy Whitcroft #print "-->$line\n"; 2601de7d4f0eSAndy Whitcroft 2602de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2603de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2604de7d4f0eSAndy Whitcroft } 2605de7d4f0eSAndy Whitcroft } 2606de7d4f0eSAndy Whitcroft 26076c72ffaaSAndy Whitcroft $prefix = ''; 26086c72ffaaSAndy Whitcroft 2609773647a0SAndy Whitcroft $realcnt = 0; 2610773647a0SAndy Whitcroft $linenr = 0; 2611194f66fcSJoe Perches $fixlinenr = -1; 26120a920b5bSAndy Whitcroft foreach my $line (@lines) { 26130a920b5bSAndy Whitcroft $linenr++; 2614194f66fcSJoe Perches $fixlinenr++; 26151b5539b1SJoe Perches my $sline = $line; #copy of $line 26161b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 26170a920b5bSAndy Whitcroft 2618c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 2619f36d3eb8SJoe Perches my $raw_comment = get_raw_comment($line, $rawline); 26206c72ffaaSAndy Whitcroft 262112c253abSJoe Perches# check if it's a mode change, rename or start of a patch 262212c253abSJoe Perches if (!$in_commit_log && 262312c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 262412c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 262512c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 262612c253abSJoe Perches $is_patch = 1; 262712c253abSJoe Perches } 262812c253abSJoe Perches 26290a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2630e518e9a5SJoe Perches if (!$in_commit_log && 263174fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 263274fd4f34SJoe Perches my $context = $4; 26330a920b5bSAndy Whitcroft $is_patch = 1; 26344a0df2efSAndy Whitcroft $first_line = $linenr + 1; 26350a920b5bSAndy Whitcroft $realline=$1-1; 26360a920b5bSAndy Whitcroft if (defined $2) { 26370a920b5bSAndy Whitcroft $realcnt=$3+1; 26380a920b5bSAndy Whitcroft } else { 26390a920b5bSAndy Whitcroft $realcnt=1+1; 26400a920b5bSAndy Whitcroft } 2641c2fdda0dSAndy Whitcroft annotate_reset(); 264213214adfSAndy Whitcroft $prev_values = 'E'; 264313214adfSAndy Whitcroft 2644773647a0SAndy Whitcroft %suppress_ifbraces = (); 2645170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 26462b474a1aSAndy Whitcroft %suppress_export = (); 26473e469cdcSAndy Whitcroft $suppress_statement = 0; 264874fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 264974fd4f34SJoe Perches $context_function = $1; 265074fd4f34SJoe Perches } else { 265174fd4f34SJoe Perches undef $context_function; 265274fd4f34SJoe Perches } 26530a920b5bSAndy Whitcroft next; 26540a920b5bSAndy Whitcroft 26554a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 26564a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 26574a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2658773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 26590a920b5bSAndy Whitcroft $realline++; 2660d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 26610a920b5bSAndy Whitcroft 26624a0df2efSAndy Whitcroft # Measure the line length and indent. 2663c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 26640a920b5bSAndy Whitcroft 26650a920b5bSAndy Whitcroft # Track the previous line. 26660a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 26670a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2668c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2669c2fdda0dSAndy Whitcroft 2670773647a0SAndy Whitcroft #warn "line<$line>\n"; 26716c72ffaaSAndy Whitcroft 2672d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2673d8aaf121SAndy Whitcroft $realcnt--; 26740a920b5bSAndy Whitcroft } 26750a920b5bSAndy Whitcroft 2676cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2677cc77cdcaSAndy Whitcroft 26786c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 26796c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2680773647a0SAndy Whitcroft 26812ac73b4fSJoe Perches my $found_file = 0; 2682773647a0SAndy Whitcroft # extract the filename as it passes 26833bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 26843bf9a009SRabin Vincent $realfile = $1; 26852b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2686270c49a0SJoe Perches $in_commit_log = 0; 26872ac73b4fSJoe Perches $found_file = 1; 26883bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2689773647a0SAndy Whitcroft $realfile = $1; 26902b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2691270c49a0SJoe Perches $in_commit_log = 0; 26921e855726SWolfram Sang 26931e855726SWolfram Sang $p1_prefix = $1; 2694e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2695e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2696000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2697000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 26981e855726SWolfram Sang } 2699773647a0SAndy Whitcroft 2700c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2701000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2702000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2703773647a0SAndy Whitcroft } 27042ac73b4fSJoe Perches $found_file = 1; 27052ac73b4fSJoe Perches } 27062ac73b4fSJoe Perches 270734d8815fSJoe Perches#make up the handle for any error we report on this line 270834d8815fSJoe Perches if ($showfile) { 270934d8815fSJoe Perches $prefix = "$realfile:$realline: " 271034d8815fSJoe Perches } elsif ($emacs) { 27117d3a9f67SJoe Perches if ($file) { 27127d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 27137d3a9f67SJoe Perches } else { 271434d8815fSJoe Perches $prefix = "$filename:$linenr: "; 271534d8815fSJoe Perches } 27167d3a9f67SJoe Perches } 271734d8815fSJoe Perches 27182ac73b4fSJoe Perches if ($found_file) { 271985b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 272085b0ee18SJoe Perches WARN("OBSOLETE", 272185b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 272285b0ee18SJoe Perches } 27237bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 27242ac73b4fSJoe Perches $check = 1; 27252ac73b4fSJoe Perches } else { 27262ac73b4fSJoe Perches $check = $check_orig; 27272ac73b4fSJoe Perches } 27289f3a8992SRob Herring $checklicenseline = 1; 2729133712a2SRob Herring 2730133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2731133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2732133712a2SRob Herring 2733133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2734133712a2SRob Herring 2735133712a2SRob Herring if (($last_binding_patch != -1) && 2736133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2737133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2738858e6845SMauro Carvalho Chehab "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); 2739133712a2SRob Herring } 2740133712a2SRob Herring } 2741133712a2SRob Herring 2742773647a0SAndy Whitcroft next; 2743773647a0SAndy Whitcroft } 2744773647a0SAndy Whitcroft 2745389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 27460a920b5bSAndy Whitcroft 2747c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2748c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2749c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 27500a920b5bSAndy Whitcroft 27516c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 27526c72ffaaSAndy Whitcroft 2753490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2754490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2755490b292cSJoe Perches if ($in_commit_log) { 2756490b292cSJoe Perches if ($line !~ /^\s*$/) { 2757490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2758490b292cSJoe Perches } 2759490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2760490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2761490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2762490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2763490b292cSJoe Perches } 2764490b292cSJoe Perches 2765e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2766e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 276713e45417SMrinal Pandey (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && 276813e45417SMrinal Pandey $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || 2769e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2770e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2771e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2772e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2773e518e9a5SJoe Perches $commit_log_has_diff = 1; 2774e518e9a5SJoe Perches } 2775e518e9a5SJoe Perches 27763bf9a009SRabin Vincent# Check for incorrect file permissions 27773bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 27783bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 277904db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 278004db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2781000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2782000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 27833bf9a009SRabin Vincent } 27843bf9a009SRabin Vincent } 27853bf9a009SRabin Vincent 2786cd261496SGeert Uytterhoeven# Check the patch for a From: 2787cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2788cd261496SGeert Uytterhoeven $author = $1; 2789e7f929f3SDwaipayan Ray my $curline = $linenr; 2790e7f929f3SDwaipayan Ray while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { 2791e7f929f3SDwaipayan Ray $author .= $1; 2792e7f929f3SDwaipayan Ray } 2793cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2794cd261496SGeert Uytterhoeven $author =~ s/"//g; 2795dfa05c28SJoe Perches $author = reformat_email($author); 2796cd261496SGeert Uytterhoeven } 2797cd261496SGeert Uytterhoeven 279820112475SJoe Perches# Check the patch for a signoff: 2799dfa05c28SJoe Perches if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { 28004a0df2efSAndy Whitcroft $signoff++; 280115662b3eSJoe Perches $in_commit_log = 0; 280248ca2d8aSDwaipayan Ray if ($author ne '' && $authorsignoff != 1) { 2803fccaebf0SDwaipayan Ray if (same_email_addresses($1, $author)) { 2804cd261496SGeert Uytterhoeven $authorsignoff = 1; 280548ca2d8aSDwaipayan Ray } else { 280648ca2d8aSDwaipayan Ray my $ctx = $1; 280748ca2d8aSDwaipayan Ray my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); 280848ca2d8aSDwaipayan Ray my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); 280948ca2d8aSDwaipayan Ray 281048ca2d8aSDwaipayan Ray if ($email_address eq $author_address && $email_name eq $author_name) { 281148ca2d8aSDwaipayan Ray $author_sob = $ctx; 281248ca2d8aSDwaipayan Ray $authorsignoff = 2; 281348ca2d8aSDwaipayan Ray } elsif ($email_address eq $author_address) { 281448ca2d8aSDwaipayan Ray $author_sob = $ctx; 281548ca2d8aSDwaipayan Ray $authorsignoff = 3; 281648ca2d8aSDwaipayan Ray } elsif ($email_name eq $author_name) { 281748ca2d8aSDwaipayan Ray $author_sob = $ctx; 281848ca2d8aSDwaipayan Ray $authorsignoff = 4; 281948ca2d8aSDwaipayan Ray 282048ca2d8aSDwaipayan Ray my $address1 = $email_address; 282148ca2d8aSDwaipayan Ray my $address2 = $author_address; 282248ca2d8aSDwaipayan Ray 282348ca2d8aSDwaipayan Ray if ($address1 =~ /(\S+)\+\S+(\@.*)/) { 282448ca2d8aSDwaipayan Ray $address1 = "$1$2"; 282548ca2d8aSDwaipayan Ray } 282648ca2d8aSDwaipayan Ray if ($address2 =~ /(\S+)\+\S+(\@.*)/) { 282748ca2d8aSDwaipayan Ray $address2 = "$1$2"; 282848ca2d8aSDwaipayan Ray } 282948ca2d8aSDwaipayan Ray if ($address1 eq $address2) { 283048ca2d8aSDwaipayan Ray $authorsignoff = 5; 283148ca2d8aSDwaipayan Ray } 283248ca2d8aSDwaipayan Ray } 2833cd261496SGeert Uytterhoeven } 2834cd261496SGeert Uytterhoeven } 28350a920b5bSAndy Whitcroft } 283620112475SJoe Perches 283744d303ebSJoe Perches# Check for patch separator 283844d303ebSJoe Perches if ($line =~ /^---$/) { 283944d303ebSJoe Perches $has_patch_separator = 1; 284044d303ebSJoe Perches $in_commit_log = 0; 284144d303ebSJoe Perches } 284244d303ebSJoe Perches 2843e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2844e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2845e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2846e0d975b1SJoe Perches $reported_maintainer_file = 1; 2847e0d975b1SJoe Perches } 2848e0d975b1SJoe Perches 284920112475SJoe Perches# Check signature styles 2850270c49a0SJoe Perches if (!$in_header_lines && 2851ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 285220112475SJoe Perches my $space_before = $1; 285320112475SJoe Perches my $sign_off = $2; 285420112475SJoe Perches my $space_after = $3; 285520112475SJoe Perches my $email = $4; 285620112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 285720112475SJoe Perches 2858ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2859831242abSAditya Srivastava my $suggested_signature = find_standard_signature($sign_off); 2860831242abSAditya Srivastava if ($suggested_signature eq "") { 2861ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2862ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2863831242abSAditya Srivastava } else { 2864831242abSAditya Srivastava if (WARN("BAD_SIGN_OFF", 2865831242abSAditya Srivastava "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && 2866831242abSAditya Srivastava $fix) { 2867831242abSAditya Srivastava $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; 2868831242abSAditya Srivastava } 2869831242abSAditya Srivastava } 2870ce0338dfSJoe Perches } 287120112475SJoe Perches if (defined $space_before && $space_before ne "") { 28723705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 28733705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 28743705ce5bSJoe Perches $fix) { 2875194f66fcSJoe Perches $fixed[$fixlinenr] = 28763705ce5bSJoe Perches "$ucfirst_sign_off $email"; 28773705ce5bSJoe Perches } 287820112475SJoe Perches } 287920112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 28803705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 28813705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 28823705ce5bSJoe Perches $fix) { 2883194f66fcSJoe Perches $fixed[$fixlinenr] = 28843705ce5bSJoe Perches "$ucfirst_sign_off $email"; 28853705ce5bSJoe Perches } 28863705ce5bSJoe Perches 288720112475SJoe Perches } 288820112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 28893705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 28903705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 28913705ce5bSJoe Perches $fix) { 2892194f66fcSJoe Perches $fixed[$fixlinenr] = 28933705ce5bSJoe Perches "$ucfirst_sign_off $email"; 28943705ce5bSJoe Perches } 289520112475SJoe Perches } 289620112475SJoe Perches 2897dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 289848ca2d8aSDwaipayan Ray my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); 289920112475SJoe Perches if ($suggested_email eq "") { 2900000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 2901000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 290220112475SJoe Perches } else { 290320112475SJoe Perches my $dequoted = $suggested_email; 290420112475SJoe Perches $dequoted =~ s/^"//; 290520112475SJoe Perches $dequoted =~ s/" </ </; 290620112475SJoe Perches # Don't force email to have quotes 290720112475SJoe Perches # Allow just an angle bracketed address 2908fccaebf0SDwaipayan Ray if (!same_email_addresses($email, $suggested_email)) { 2909fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 2910fccaebf0SDwaipayan Ray "email address '$email' might be better as '$suggested_email'\n" . $herecurr) && 2911fccaebf0SDwaipayan Ray $fix) { 2912fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/; 2913fccaebf0SDwaipayan Ray } 2914fccaebf0SDwaipayan Ray } 2915fccaebf0SDwaipayan Ray 2916fccaebf0SDwaipayan Ray # Address part shouldn't have comments 2917fccaebf0SDwaipayan Ray my $stripped_address = $email_address; 2918fccaebf0SDwaipayan Ray $stripped_address =~ s/\([^\(\)]*\)//g; 2919fccaebf0SDwaipayan Ray if ($email_address ne $stripped_address) { 2920fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 2921fccaebf0SDwaipayan Ray "address part of email should not have comments: '$email_address'\n" . $herecurr) && 2922fccaebf0SDwaipayan Ray $fix) { 2923fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/; 2924fccaebf0SDwaipayan Ray } 2925fccaebf0SDwaipayan Ray } 2926fccaebf0SDwaipayan Ray 2927fccaebf0SDwaipayan Ray # Only one name comment should be allowed 2928fccaebf0SDwaipayan Ray my $comment_count = () = $name_comment =~ /\([^\)]+\)/g; 2929fccaebf0SDwaipayan Ray if ($comment_count > 1) { 2930000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 2931fccaebf0SDwaipayan Ray "Use a single name comment in email: '$email'\n" . $herecurr); 2932fccaebf0SDwaipayan Ray } 2933fccaebf0SDwaipayan Ray 2934fccaebf0SDwaipayan Ray 2935fccaebf0SDwaipayan Ray # [email protected] or [email protected] shouldn't 2936e73d2715SDwaipayan Ray # have an email name. In addition comments should strictly 2937fccaebf0SDwaipayan Ray # begin with a # 2938fccaebf0SDwaipayan Ray if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { 2939fccaebf0SDwaipayan Ray if (($comment ne "" && $comment !~ /^#.+/) || 2940fccaebf0SDwaipayan Ray ($email_name ne "")) { 2941fccaebf0SDwaipayan Ray my $cur_name = $email_name; 2942fccaebf0SDwaipayan Ray my $new_comment = $comment; 2943fccaebf0SDwaipayan Ray $cur_name =~ s/[a-zA-Z\s\-\"]+//g; 2944fccaebf0SDwaipayan Ray 2945fccaebf0SDwaipayan Ray # Remove brackets enclosing comment text 2946fccaebf0SDwaipayan Ray # and # from start of comments to get comment text 2947fccaebf0SDwaipayan Ray $new_comment =~ s/^\((.*)\)$/$1/; 2948fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 2949fccaebf0SDwaipayan Ray $new_comment =~ s/^[\s\#]+|\s+$//g; 2950fccaebf0SDwaipayan Ray 2951fccaebf0SDwaipayan Ray $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); 2952fccaebf0SDwaipayan Ray $new_comment = " # $new_comment" if ($new_comment ne ""); 2953fccaebf0SDwaipayan Ray my $new_email = "$email_address$new_comment"; 2954fccaebf0SDwaipayan Ray 2955fccaebf0SDwaipayan Ray if (WARN("BAD_STABLE_ADDRESS_STYLE", 2956fccaebf0SDwaipayan Ray "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && 2957fccaebf0SDwaipayan Ray $fix) { 2958fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 2959fccaebf0SDwaipayan Ray } 2960fccaebf0SDwaipayan Ray } 2961fccaebf0SDwaipayan Ray } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { 2962fccaebf0SDwaipayan Ray my $new_comment = $comment; 2963fccaebf0SDwaipayan Ray 2964fccaebf0SDwaipayan Ray # Extract comment text from within brackets or 2965fccaebf0SDwaipayan Ray # c89 style /*...*/ comments 2966fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 2967fccaebf0SDwaipayan Ray $new_comment =~ s/^\/\*(.*)\*\/$/$1/; 2968fccaebf0SDwaipayan Ray 2969fccaebf0SDwaipayan Ray $new_comment = trim($new_comment); 2970fccaebf0SDwaipayan Ray $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo 2971fccaebf0SDwaipayan Ray $new_comment = "($new_comment)" if ($new_comment ne ""); 2972fccaebf0SDwaipayan Ray my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); 2973fccaebf0SDwaipayan Ray 2974fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 2975fccaebf0SDwaipayan Ray "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && 2976fccaebf0SDwaipayan Ray $fix) { 2977fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 2978fccaebf0SDwaipayan Ray } 297920112475SJoe Perches } 29800a920b5bSAndy Whitcroft } 29817e51f197SJoe Perches 29827e51f197SJoe Perches# Check for duplicate signatures 29837e51f197SJoe Perches my $sig_nospace = $line; 29847e51f197SJoe Perches $sig_nospace =~ s/\s//g; 29857e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 29867e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 29877e51f197SJoe Perches WARN("BAD_SIGN_OFF", 29887e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 29897e51f197SJoe Perches } else { 29907e51f197SJoe Perches $signatures{$sig_nospace} = 1; 29917e51f197SJoe Perches } 29926c5d24eeSSean Christopherson 29936c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 29946c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 29956c5d24eeSSean Christopherson if ($email eq $author) { 29966c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 29976c5d24eeSSean Christopherson "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); 29986c5d24eeSSean Christopherson } 29996c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 30006c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 30016c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); 30026c5d24eeSSean Christopherson } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { 30036c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 30046c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 30056c5d24eeSSean Christopherson } elsif ($1 ne $email) { 30066c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 30076c5d24eeSSean Christopherson "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 30086c5d24eeSSean Christopherson } 30096c5d24eeSSean Christopherson } 30100a920b5bSAndy Whitcroft } 30110a920b5bSAndy Whitcroft 3012a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 3013a2fe16b9SJoe Perches if ($in_header_lines && 3014a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 3015a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 3016a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 3017a2fe16b9SJoe Perches } 3018a2fe16b9SJoe Perches 301944d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context 302044d303ebSJoe Perches if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { 30217580c5b9SAditya Srivastava if (ERROR("GERRIT_CHANGE_ID", 30227580c5b9SAditya Srivastava "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && 30237580c5b9SAditya Srivastava $fix) { 30247580c5b9SAditya Srivastava fix_delete_line($fixlinenr, $rawline); 30257580c5b9SAditya Srivastava } 30267ebd05efSChristopher Covington } 30277ebd05efSChristopher Covington 3028369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 3029369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3030369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 3031369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 3032369c8dd3SJoe Perches # timestamp 3033634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 3034634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 3035634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 3036634cffccSJoe Perches # stack dump address styles 3037369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 3038369c8dd3SJoe Perches } 3039369c8dd3SJoe Perches 30402a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 30412a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 3042bf4daf12SJoe Perches length($line) > 75 && 3043bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 3044bf4daf12SJoe Perches # file delta changes 3045bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 3046bf4daf12SJoe Perches # filename then : 304727b379afSAditya Srivastava $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i || 304827b379afSAditya Srivastava # A Fixes: or Link: line or signature tag line 3049bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 30502a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 30512a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 30522a076f40SJoe Perches $commit_log_long_line = 1; 30532a076f40SJoe Perches } 30542a076f40SJoe Perches 3055bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 3056bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 3057bf4daf12SJoe Perches $line =~ /^\s*$/) { 3058bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 3059bf4daf12SJoe Perches } 3060bf4daf12SJoe Perches 3061084a617aSDwaipayan Ray# Check for lines starting with a # 3062084a617aSDwaipayan Ray if ($in_commit_log && $line =~ /^#/) { 3063084a617aSDwaipayan Ray if (WARN("COMMIT_COMMENT_SYMBOL", 3064084a617aSDwaipayan Ray "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && 3065084a617aSDwaipayan Ray $fix) { 3066084a617aSDwaipayan Ray $fixed[$fixlinenr] =~ s/^/ /; 3067084a617aSDwaipayan Ray } 3068084a617aSDwaipayan Ray } 3069084a617aSDwaipayan Ray 30700d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 3071369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3072a8972573SJohn Hubbard $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && 3073e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 3074fe043ea1SJoe Perches ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 3075aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 3076369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 3077bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 3078fe043ea1SJoe Perches my $init_char = "c"; 3079fe043ea1SJoe Perches my $orig_commit = ""; 30800d7835fcSJoe Perches my $short = 1; 30810d7835fcSJoe Perches my $long = 0; 30820d7835fcSJoe Perches my $case = 1; 30830d7835fcSJoe Perches my $space = 1; 30840d7835fcSJoe Perches my $hasdesc = 0; 308519c146a6SJoe Perches my $hasparens = 0; 30860d7835fcSJoe Perches my $id = '0123456789ab'; 30870d7835fcSJoe Perches my $orig_desc = "commit description"; 30880d7835fcSJoe Perches my $description = ""; 30890d7835fcSJoe Perches 3090fe043ea1SJoe Perches if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 3091fe043ea1SJoe Perches $init_char = $1; 3092fe043ea1SJoe Perches $orig_commit = lc($2); 3093fe043ea1SJoe Perches } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { 3094fe043ea1SJoe Perches $orig_commit = lc($1); 3095fe043ea1SJoe Perches } 3096fe043ea1SJoe Perches 30970d7835fcSJoe Perches $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 30980d7835fcSJoe Perches $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 30990d7835fcSJoe Perches $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 31000d7835fcSJoe Perches $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 31010d7835fcSJoe Perches if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 31020d7835fcSJoe Perches $orig_desc = $1; 310319c146a6SJoe Perches $hasparens = 1; 31040d7835fcSJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 31050d7835fcSJoe Perches defined $rawlines[$linenr] && 31060d7835fcSJoe Perches $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 31070d7835fcSJoe Perches $orig_desc = $1; 310819c146a6SJoe Perches $hasparens = 1; 3109b671fde0SJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 3110b671fde0SJoe Perches defined $rawlines[$linenr] && 3111b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 3112b671fde0SJoe Perches $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 3113b671fde0SJoe Perches $orig_desc = $1; 3114b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 3115b671fde0SJoe Perches $orig_desc .= " " . $1; 311619c146a6SJoe Perches $hasparens = 1; 31170d7835fcSJoe Perches } 31180d7835fcSJoe Perches 31190d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 31200d7835fcSJoe Perches $id, $orig_desc); 31210d7835fcSJoe Perches 3122948b133aSHeinrich Schuchardt if (defined($id) && 3123948b133aSHeinrich Schuchardt ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { 3124d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 31250d7835fcSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 31260d7835fcSJoe Perches } 3127d311cd44SJoe Perches } 3128d311cd44SJoe Perches 312913f1937eSJoe Perches# Check for added, moved or deleted files 313013f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 313113f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 313213f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 313313f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 313413f1937eSJoe Perches (defined($1) || defined($2))))) { 3135a82603a8SAndrew Jeffery $is_patch = 1; 313613f1937eSJoe Perches $reported_maintainer_file = 1; 313713f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 313813f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 313913f1937eSJoe Perches } 314013f1937eSJoe Perches 3141e400edb1SRob Herring# Check for adding new DT bindings not in schema format 3142e400edb1SRob Herring if (!$in_commit_log && 3143e400edb1SRob Herring ($line =~ /^new file mode\s*\d+\s*$/) && 3144e400edb1SRob Herring ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { 3145e400edb1SRob Herring WARN("DT_SCHEMA_BINDING_PATCH", 3146e400edb1SRob Herring "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n"); 3147e400edb1SRob Herring } 3148e400edb1SRob Herring 314900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 31508905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 3151000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 3152000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 31536c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 3154de7d4f0eSAndy Whitcroft } 3155de7d4f0eSAndy Whitcroft 3156de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 3157de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 3158171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 3159171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 3160171ae1a4SAndy Whitcroft 3161171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 3162171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 3163171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 3164171ae1a4SAndy Whitcroft 316534d99219SJoe Perches CHK("INVALID_UTF8", 3166000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 316700df344fSAndy Whitcroft } 31680a920b5bSAndy Whitcroft 316915662b3eSJoe Perches# Check if it's the start of a commit log 317015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 317115662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 3172eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 3173eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 317415662b3eSJoe Perches $in_header_lines = 0; 317515662b3eSJoe Perches $in_commit_log = 1; 3176ed43c4e5SAllen Hubbe $has_commit_log = 1; 317715662b3eSJoe Perches } 317815662b3eSJoe Perches 3179fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 3180fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 3181fa64205dSPasi Savanainen if ($in_header_lines && 3182fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 3183fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 3184fa64205dSPasi Savanainen $non_utf8_charset = 1; 3185fa64205dSPasi Savanainen } 3186fa64205dSPasi Savanainen 3187fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 318815662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 3189fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 319015662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 319115662b3eSJoe Perches } 319215662b3eSJoe Perches 3193d6430f71SJoe Perches# Check for absolute kernel paths in commit message 3194d6430f71SJoe Perches if ($tree && $in_commit_log) { 3195d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 3196d6430f71SJoe Perches my $file = $1; 3197d6430f71SJoe Perches 3198d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 3199d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 3200d6430f71SJoe Perches # 3201d6430f71SJoe Perches } else { 3202d6430f71SJoe Perches check_absolute_file($file, $herecurr); 3203d6430f71SJoe Perches } 3204d6430f71SJoe Perches } 3205d6430f71SJoe Perches } 3206d6430f71SJoe Perches 320766b47b4aSKees Cook# Check for various typo / spelling mistakes 320866d7a382SJoe Perches if (defined($misspellings) && 320966d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 32107da07c31SDwaipayan Ray while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { 321166b47b4aSKees Cook my $typo = $1; 32127da07c31SDwaipayan Ray my $blank = copy_spacing($rawline); 32137da07c31SDwaipayan Ray my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); 32147da07c31SDwaipayan Ray my $hereptr = "$hereline$ptr\n"; 321566b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 321666b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 321766b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 32180675a8fbSJean Delvare my $msg_level = \&WARN; 32190675a8fbSJean Delvare $msg_level = \&CHK if ($file); 32200675a8fbSJean Delvare if (&{$msg_level}("TYPO_SPELLING", 32217da07c31SDwaipayan Ray "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && 322266b47b4aSKees Cook $fix) { 322366b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 322466b47b4aSKees Cook } 322566b47b4aSKees Cook } 322666b47b4aSKees Cook } 322766b47b4aSKees Cook 3228a8dd86bfSMatteo Croce# check for invalid commit id 3229a8dd86bfSMatteo Croce if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 3230a8dd86bfSMatteo Croce my $id; 3231a8dd86bfSMatteo Croce my $description; 3232a8dd86bfSMatteo Croce ($id, $description) = git_commit_info($2, undef, undef); 3233a8dd86bfSMatteo Croce if (!defined($id)) { 3234a8dd86bfSMatteo Croce WARN("UNKNOWN_COMMIT_ID", 3235a8dd86bfSMatteo Croce "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 3236a8dd86bfSMatteo Croce } 3237a8dd86bfSMatteo Croce } 3238a8dd86bfSMatteo Croce 3239310cd06bSJoe Perches# check for repeated words separated by a single space 32408d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root' 32418d0325ccSAditya Srivastava if (($rawline =~ /^\+/ || $in_commit_log) && 32428d0325ccSAditya Srivastava $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { 32431db81a68SDwaipayan Ray pos($rawline) = 1 if (!$in_commit_log); 3244310cd06bSJoe Perches while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { 3245310cd06bSJoe Perches 3246310cd06bSJoe Perches my $first = $1; 3247310cd06bSJoe Perches my $second = $2; 32481db81a68SDwaipayan Ray my $start_pos = $-[1]; 32491db81a68SDwaipayan Ray my $end_pos = $+[2]; 3250310cd06bSJoe Perches if ($first =~ /(?:struct|union|enum)/) { 3251310cd06bSJoe Perches pos($rawline) += length($first) + length($second) + 1; 3252310cd06bSJoe Perches next; 3253310cd06bSJoe Perches } 3254310cd06bSJoe Perches 32551db81a68SDwaipayan Ray next if (lc($first) ne lc($second)); 3256310cd06bSJoe Perches next if ($first eq 'long'); 3257310cd06bSJoe Perches 32581db81a68SDwaipayan Ray # check for character before and after the word matches 32591db81a68SDwaipayan Ray my $start_char = ''; 32601db81a68SDwaipayan Ray my $end_char = ''; 32611db81a68SDwaipayan Ray $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); 32621db81a68SDwaipayan Ray $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); 32631db81a68SDwaipayan Ray 32641db81a68SDwaipayan Ray next if ($start_char =~ /^\S$/); 32651db81a68SDwaipayan Ray next if (index(" \t.,;?!", $end_char) == -1); 32661db81a68SDwaipayan Ray 32678d0325ccSAditya Srivastava # avoid repeating hex occurrences like 'ff ff fe 09 ...' 32688d0325ccSAditya Srivastava if ($first =~ /\b[0-9a-f]{2,}\b/i) { 32698d0325ccSAditya Srivastava next if (!exists($allow_repeated_words{lc($first)})); 32708d0325ccSAditya Srivastava } 32718d0325ccSAditya Srivastava 3272310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3273310cd06bSJoe Perches "Possible repeated word: '$first'\n" . $herecurr) && 3274310cd06bSJoe Perches $fix) { 3275310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; 3276310cd06bSJoe Perches } 3277310cd06bSJoe Perches } 3278310cd06bSJoe Perches 3279310cd06bSJoe Perches # if it's a repeated word on consecutive lines in a comment block 3280310cd06bSJoe Perches if ($prevline =~ /$;+\s*$/ && 3281310cd06bSJoe Perches $prevrawline =~ /($word_pattern)\s*$/) { 3282310cd06bSJoe Perches my $last_word = $1; 3283310cd06bSJoe Perches if ($rawline =~ /^\+\s*\*\s*$last_word /) { 3284310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3285310cd06bSJoe Perches "Possible repeated word: '$last_word'\n" . $hereprev) && 3286310cd06bSJoe Perches $fix) { 3287310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; 3288310cd06bSJoe Perches } 3289310cd06bSJoe Perches } 3290310cd06bSJoe Perches } 3291310cd06bSJoe Perches } 3292310cd06bSJoe Perches 329330670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 329430670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 329500df344fSAndy Whitcroft 32960a920b5bSAndy Whitcroft#trailing whitespace 32979c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 3298c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3299d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 3300d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 3301d5e616fcSJoe Perches $fix) { 3302194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 3303d5e616fcSJoe Perches } 3304c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 3305c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 33063705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 33073705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 33083705ce5bSJoe Perches $fix) { 3309194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 33103705ce5bSJoe Perches } 33113705ce5bSJoe Perches 3312d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 33130a920b5bSAndy Whitcroft } 33145368df20SAndy Whitcroft 33154783f894SJosh Triplett# Check for FSF mailing addresses. 3316109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 33171bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 33183e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 33193e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 33204783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 33210675a8fbSJean Delvare my $msg_level = \&ERROR; 33220675a8fbSJean Delvare $msg_level = \&CHK if ($file); 33230675a8fbSJean Delvare &{$msg_level}("FSF_MAILING_ADDRESS", 33244783f894SJosh Triplett "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) 33254783f894SJosh Triplett } 33264783f894SJosh Triplett 33273354957aSAndi Kleen# check for Kconfig help text having a real description 33289fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 33299fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 33303354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 3331678ae162SUlf Magnusson # 'choice' is usually the last thing on the line (though 3332678ae162SUlf Magnusson # Kconfig supports named choices), so use a word boundary 3333678ae162SUlf Magnusson # (\b) rather than a whitespace character (\s) 3334678ae162SUlf Magnusson $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 33353354957aSAndi Kleen my $length = 0; 33369fe287d7SAndy Whitcroft my $cnt = $realcnt; 33379fe287d7SAndy Whitcroft my $ln = $linenr + 1; 33389fe287d7SAndy Whitcroft my $f; 3339a1385803SAndy Whitcroft my $is_start = 0; 33409fe287d7SAndy Whitcroft my $is_end = 0; 3341a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 33429fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 33439fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 33449fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 33459fe287d7SAndy Whitcroft 33469fe287d7SAndy Whitcroft next if ($f =~ /^-/); 33478d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 3348a1385803SAndy Whitcroft 334986adf1a0SUlf Magnusson if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 3350a1385803SAndy Whitcroft $is_start = 1; 335122a4ac02SMasahiro Yamada } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 3352a1385803SAndy Whitcroft $length = -1; 3353a1385803SAndy Whitcroft } 3354a1385803SAndy Whitcroft 33559fe287d7SAndy Whitcroft $f =~ s/^.//; 33563354957aSAndi Kleen $f =~ s/#.*//; 33573354957aSAndi Kleen $f =~ s/^\s+//; 33583354957aSAndi Kleen next if ($f =~ /^$/); 3359678ae162SUlf Magnusson 3360678ae162SUlf Magnusson # This only checks context lines in the patch 3361678ae162SUlf Magnusson # and so hopefully shouldn't trigger false 3362678ae162SUlf Magnusson # positives, even though some of these are 3363678ae162SUlf Magnusson # common words in help texts 3364678ae162SUlf Magnusson if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| 3365678ae162SUlf Magnusson if|endif|menu|endmenu|source)\b/x) { 33669fe287d7SAndy Whitcroft $is_end = 1; 33679fe287d7SAndy Whitcroft last; 33689fe287d7SAndy Whitcroft } 33693354957aSAndi Kleen $length++; 33703354957aSAndi Kleen } 337156193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 3372000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 337356193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 337456193274SVadim Bendebury } 3375a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 33763354957aSAndi Kleen } 33773354957aSAndi Kleen 33787ccf41a8SJoe Perches# check MAINTAINERS entries 33797ccf41a8SJoe Perches if ($realfile =~ /^MAINTAINERS$/) { 33807ccf41a8SJoe Perches# check MAINTAINERS entries for the right form 33817ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 3382628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3383628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3384628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3385628f91a2SJoe Perches $fix) { 3386628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3387628f91a2SJoe Perches } 3388628f91a2SJoe Perches } 33897ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too 33907ccf41a8SJoe Perches my $preferred_order = 'MRLSWQBCPTFXNK'; 33917ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 33927ccf41a8SJoe Perches $prevrawline =~ /^[\+ ][A-Z]:/) { 33937ccf41a8SJoe Perches $rawline =~ /^\+([A-Z]):\s*(.*)/; 33947ccf41a8SJoe Perches my $cur = $1; 33957ccf41a8SJoe Perches my $curval = $2; 33967ccf41a8SJoe Perches $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; 33977ccf41a8SJoe Perches my $prev = $1; 33987ccf41a8SJoe Perches my $prevval = $2; 33997ccf41a8SJoe Perches my $curindex = index($preferred_order, $cur); 34007ccf41a8SJoe Perches my $previndex = index($preferred_order, $prev); 34017ccf41a8SJoe Perches if ($curindex < 0) { 34027ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 34037ccf41a8SJoe Perches "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); 34047ccf41a8SJoe Perches } else { 34057ccf41a8SJoe Perches if ($previndex >= 0 && $curindex < $previndex) { 34067ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 34077ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); 34087ccf41a8SJoe Perches } elsif ((($prev eq 'F' && $cur eq 'F') || 34097ccf41a8SJoe Perches ($prev eq 'X' && $cur eq 'X')) && 34107ccf41a8SJoe Perches ($prevval cmp $curval) > 0) { 34117ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 34127ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); 34137ccf41a8SJoe Perches } 34147ccf41a8SJoe Perches } 34157ccf41a8SJoe Perches } 34167ccf41a8SJoe Perches } 3417628f91a2SJoe Perches 3418c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3419c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3420c68e5878SArnaud Lacombe my $flag = $1; 3421c68e5878SArnaud Lacombe my $replacement = { 3422c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 3423c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 3424c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 3425c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 3426c68e5878SArnaud Lacombe }; 3427c68e5878SArnaud Lacombe 3428c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 3429c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3430c68e5878SArnaud Lacombe } 3431c68e5878SArnaud Lacombe 3432bff5da43SRob Herring# check for DT compatible documentation 34337dd05b38SFlorian Vaussard if (defined $root && 34347dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 34357dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 34367dd05b38SFlorian Vaussard 3437bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3438bff5da43SRob Herring 3439cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3440852d095dSRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3441cc93319bSFlorian Vaussard 3442bff5da43SRob Herring foreach my $compat (@compats) { 3443bff5da43SRob Herring my $compat2 = $compat; 3444185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3445185d566bSRob Herring my $compat3 = $compat; 3446185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3447185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3448bff5da43SRob Herring if ( $? >> 8 ) { 3449bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3450bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3451bff5da43SRob Herring } 3452bff5da43SRob Herring 34534fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 34544fbf32a6SFlorian Vaussard my $vendor = $1; 3455852d095dSRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3456bff5da43SRob Herring if ( $? >> 8 ) { 3457bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3458cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3459bff5da43SRob Herring } 3460bff5da43SRob Herring } 3461bff5da43SRob Herring } 3462bff5da43SRob Herring 34639f3a8992SRob Herring# check for using SPDX license tag at beginning of files 34649f3a8992SRob Herring if ($realline == $checklicenseline) { 34659f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 34669f3a8992SRob Herring $checklicenseline = 2; 34679f3a8992SRob Herring } elsif ($rawline =~ /^\+/) { 34689f3a8992SRob Herring my $comment = ""; 34699f3a8992SRob Herring if ($realfile =~ /\.(h|s|S)$/) { 34709f3a8992SRob Herring $comment = '/*'; 34719f3a8992SRob Herring } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { 34729f3a8992SRob Herring $comment = '//'; 3473c8df0ab6SLubomir Rintel } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 34749f3a8992SRob Herring $comment = '#'; 34759f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 34769f3a8992SRob Herring $comment = '..'; 34779f3a8992SRob Herring } 34789f3a8992SRob Herring 3479fdf13693SJoe Perches# check SPDX comment style for .[chsS] files 3480fdf13693SJoe Perches if ($realfile =~ /\.[chsS]$/ && 3481fdf13693SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 3482ffbce897SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 3483fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3484fdf13693SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3485fdf13693SJoe Perches } 3486fdf13693SJoe Perches 34879f3a8992SRob Herring if ($comment !~ /^$/ && 3488ffbce897SJoe Perches $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 34899f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 34909f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 34913b6e8ac9SJoe Perches } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 34923b6e8ac9SJoe Perches my $spdx_license = $1; 34933b6e8ac9SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 34943b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 34953b6e8ac9SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 34963b6e8ac9SJoe Perches } 349750c92900SLubomir Rintel if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 349850c92900SLubomir Rintel not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { 349950c92900SLubomir Rintel my $msg_level = \&WARN; 350050c92900SLubomir Rintel $msg_level = \&CHK if ($file); 350150c92900SLubomir Rintel if (&{$msg_level}("SPDX_LICENSE_TAG", 350250c92900SLubomir Rintel 350350c92900SLubomir Rintel "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 350450c92900SLubomir Rintel $fix) { 350550c92900SLubomir Rintel $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 350650c92900SLubomir Rintel } 350750c92900SLubomir Rintel } 35089f3a8992SRob Herring } 35099f3a8992SRob Herring } 35109f3a8992SRob Herring } 35119f3a8992SRob Herring 3512a0154cdbSJoe Perches# check for embedded filenames 3513a0154cdbSJoe Perches if ($rawline =~ /^\+.*\Q$realfile\E/) { 3514a0154cdbSJoe Perches WARN("EMBEDDED_FILENAME", 3515a0154cdbSJoe Perches "It's generally not useful to have the filename in the file\n" . $herecurr); 3516a0154cdbSJoe Perches } 3517a0154cdbSJoe Perches 35185368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 3519d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 35205368df20SAndy Whitcroft 3521a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3522a8da38a9SJoe Perches if ($realline != $checklicenseline && 3523a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3524a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3525a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3526a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3527a8da38a9SJoe Perches } 3528a8da38a9SJoe Perches 352947e0c88bSJoe Perches# line length limit (with some exclusions) 353047e0c88bSJoe Perches# 353147e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 353247e0c88bSJoe Perches# logging functions like pr_info that end in a string 353347e0c88bSJoe Perches# lines with a single string 353447e0c88bSJoe Perches# #defines that are a single string 35352e4bbbc5SAndreas Brauchli# lines with an RFC3986 like URL 353647e0c88bSJoe Perches# 353747e0c88bSJoe Perches# There are 3 different line length message types: 3538ab1ecabfSJean Delvare# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 353947e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 354047e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 354147e0c88bSJoe Perches# 354247e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 354347e0c88bSJoe Perches# 354447e0c88bSJoe Perches 3545b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 354647e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 354747e0c88bSJoe Perches 354847e0c88bSJoe Perches # Check the allowed long line types first 354947e0c88bSJoe Perches 355047e0c88bSJoe Perches # logging functions that end in a string that starts 355147e0c88bSJoe Perches # before $max_line_length 355247e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 355347e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 355447e0c88bSJoe Perches $msg_type = ""; 355547e0c88bSJoe Perches 355647e0c88bSJoe Perches # lines with only strings (w/ possible termination) 355747e0c88bSJoe Perches # #defines with only strings 355847e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 355947e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 356047e0c88bSJoe Perches $msg_type = ""; 356147e0c88bSJoe Perches 3562cc147506SJoe Perches # More special cases 3563cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3564cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3565d560a5f8SJoe Perches $msg_type = ""; 3566d560a5f8SJoe Perches 35672e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 35682e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 35692e4bbbc5SAndreas Brauchli $msg_type = ""; 35702e4bbbc5SAndreas Brauchli 357147e0c88bSJoe Perches # Otherwise set the alternate message types 357247e0c88bSJoe Perches 357347e0c88bSJoe Perches # a comment starts before $max_line_length 357447e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 357547e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 357647e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 357747e0c88bSJoe Perches 357847e0c88bSJoe Perches # a quoted string starts before $max_line_length 357947e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 358047e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 358147e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 358247e0c88bSJoe Perches } 358347e0c88bSJoe Perches 358447e0c88bSJoe Perches if ($msg_type ne "" && 358547e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 3586bdc48fa1SJoe Perches my $msg_level = \&WARN; 3587bdc48fa1SJoe Perches $msg_level = \&CHK if ($file); 3588bdc48fa1SJoe Perches &{$msg_level}($msg_type, 3589bdc48fa1SJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 35900a920b5bSAndy Whitcroft } 359147e0c88bSJoe Perches } 35920a920b5bSAndy Whitcroft 35938905a67cSAndy Whitcroft# check for adding lines without a newline. 35948905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 359547ca69b8STom Rix if (WARN("MISSING_EOF_NEWLINE", 359647ca69b8STom Rix "adding a line without newline at end of file\n" . $herecurr) && 359747ca69b8STom Rix $fix) { 359847ca69b8STom Rix fix_delete_line($fixlinenr+1, "No newline at end of file"); 359947ca69b8STom Rix } 36008905a67cSAndy Whitcroft } 36018905a67cSAndy Whitcroft 3602de93245cSAditya Srivastava# check for .L prefix local symbols in .S files 3603de93245cSAditya Srivastava if ($realfile =~ /\.S$/ && 3604de93245cSAditya Srivastava $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { 3605de93245cSAditya Srivastava WARN("AVOID_L_PREFIX", 3606de93245cSAditya Srivastava "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\n" . $herecurr); 3607de93245cSAditya Srivastava } 3608de93245cSAditya Srivastava 3609b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3610de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 36110a920b5bSAndy Whitcroft 36120a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 3613713a09deSAntonio Borneo# more than $tabsize must use tabs. 3614c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3615c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3616c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3617d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 36183705ce5bSJoe Perches if (ERROR("CODE_INDENT", 36193705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 36203705ce5bSJoe Perches $fix) { 3621194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 36223705ce5bSJoe Perches } 36230a920b5bSAndy Whitcroft } 36240a920b5bSAndy Whitcroft 362508e44365SAlberto Panizzo# check for space before tabs. 362608e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 362708e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 36283705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 36293705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 36303705ce5bSJoe Perches $fix) { 3631194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3632713a09deSAntonio Borneo s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 3633194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3634c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 36353705ce5bSJoe Perches } 363608e44365SAlberto Panizzo } 363708e44365SAlberto Panizzo 36386a487211SJoe Perches# check for assignments on the start of a line 36396a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 3640da7355abSAditya Srivastava my $operator = $1; 3641da7355abSAditya Srivastava if (CHK("ASSIGNMENT_CONTINUATIONS", 3642da7355abSAditya Srivastava "Assignment operator '$1' should be on the previous line\n" . $hereprev) && 3643da7355abSAditya Srivastava $fix && $prevrawline =~ /^\+/) { 3644da7355abSAditya Srivastava # add assignment operator to the previous line, remove from current line 3645da7355abSAditya Srivastava $fixed[$fixlinenr - 1] .= " $operator"; 3646da7355abSAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 3647da7355abSAditya Srivastava } 36486a487211SJoe Perches } 36496a487211SJoe Perches 3650d1fe9c09SJoe Perches# check for && or || at the start of a line 3651d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 36528e08f076SAditya Srivastava my $operator = $1; 36538e08f076SAditya Srivastava if (CHK("LOGICAL_CONTINUATIONS", 36548e08f076SAditya Srivastava "Logical continuations should be on the previous line\n" . $hereprev) && 36558e08f076SAditya Srivastava $fix && $prevrawline =~ /^\+/) { 36568e08f076SAditya Srivastava # insert logical operator at last non-comment, non-whitepsace char on previous line 36578e08f076SAditya Srivastava $prevline =~ /[\s$;]*$/; 36588e08f076SAditya Srivastava my $line_end = substr($prevrawline, $-[0]); 36598e08f076SAditya Srivastava $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; 36608e08f076SAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 36618e08f076SAditya Srivastava } 3662d1fe9c09SJoe Perches } 3663d1fe9c09SJoe Perches 3664a91e8994SJoe Perches# check indentation starts on a tab stop 36655b57980dSJoe Perches if ($perl_version_ok && 3666bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3667a91e8994SJoe Perches my $indent = length($1); 3668713a09deSAntonio Borneo if ($indent % $tabsize) { 3669a91e8994SJoe Perches if (WARN("TABSTOP", 3670a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3671a91e8994SJoe Perches $fix) { 3672713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 3673a91e8994SJoe Perches } 3674a91e8994SJoe Perches } 3675a91e8994SJoe Perches } 3676a91e8994SJoe Perches 3677d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 36785b57980dSJoe Perches if ($perl_version_ok && 3679fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3680d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3681d1fe9c09SJoe Perches my $oldindent = $1; 3682d1fe9c09SJoe Perches my $rest = $2; 3683d1fe9c09SJoe Perches 3684d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3685d1fe9c09SJoe Perches if ($pos >= 0) { 3686b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3687b34a26f3SJoe Perches my $newindent = $2; 3688d1fe9c09SJoe Perches 3689d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3690713a09deSAntonio Borneo "\t" x ($pos / $tabsize) . 3691713a09deSAntonio Borneo " " x ($pos % $tabsize); 3692d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3693d1fe9c09SJoe Perches 3694d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3695d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 36963705ce5bSJoe Perches 36973705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 36983705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 36993705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3700194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37013705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 37023705ce5bSJoe Perches } 3703d1fe9c09SJoe Perches } 3704d1fe9c09SJoe Perches } 3705d1fe9c09SJoe Perches } 3706d1fe9c09SJoe Perches 37076ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 37086ab3a970SJoe Perches# avoid checking a few false positives: 37096ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 37106ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 37116ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 37126ab3a970SJoe Perches# multiline macros that define functions 37136ab3a970SJoe Perches# known attributes or the __attribute__ keyword 37146ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 37156ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 37163705ce5bSJoe Perches if (CHK("SPACING", 3717f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 37183705ce5bSJoe Perches $fix) { 3719194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3720f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 37213705ce5bSJoe Perches } 3722aad4f614SJoe Perches } 3723aad4f614SJoe Perches 372486406b1cSJoe Perches# Block comment styles 372586406b1cSJoe Perches# Networking with an initial /* 372605880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3727fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 372885ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 3729c70735c2SŁukasz Stelmach $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier 373005880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 373105880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 373205880600SJoe Perches } 373305880600SJoe Perches 373486406b1cSJoe Perches# Block comments use * on subsequent lines 373586406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 373686406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3737a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 373861135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3739a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 374086406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 374186406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3742a605e32eSJoe Perches } 3743a605e32eSJoe Perches 374486406b1cSJoe Perches# Block comments use */ on trailing lines 374586406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3746c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3747c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3748c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 374986406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 375086406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 375105880600SJoe Perches } 375205880600SJoe Perches 375308eb9b80SJoe Perches# Block comment * alignment 375408eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3755af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3756af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3757af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 375808eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3759af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3760af207524SJoe Perches my $oldindent; 376108eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3762af207524SJoe Perches if (defined($1)) { 3763af207524SJoe Perches $oldindent = expand_tabs($1); 3764af207524SJoe Perches } else { 3765af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3766af207524SJoe Perches $oldindent = expand_tabs($1); 3767af207524SJoe Perches } 376808eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 376908eb9b80SJoe Perches my $newindent = $1; 377008eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3771af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 377208eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 377308eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 377408eb9b80SJoe Perches } 377508eb9b80SJoe Perches } 377608eb9b80SJoe Perches 37777f619191SJoe Perches# check for missing blank lines after struct/union declarations 37787f619191SJoe Perches# with exceptions for various attributes and macros 37797f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 37807f619191SJoe Perches $line =~ /^\+/ && 37817f619191SJoe Perches !($line =~ /^\+\s*$/ || 37827f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 37837f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 37847f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 37857f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 37867f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 37877f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 37880bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 37897f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3790d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3791d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3792d752fcc8SJoe Perches $fix) { 3793f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3794d752fcc8SJoe Perches } 37957f619191SJoe Perches } 37967f619191SJoe Perches 3797365dd4eaSJoe Perches# check for multiple consecutive blank lines 3798365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3799365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3800365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3801d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3802d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3803d752fcc8SJoe Perches $fix) { 3804f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3805d752fcc8SJoe Perches } 3806d752fcc8SJoe Perches 3807365dd4eaSJoe Perches $last_blank_line = $linenr; 3808365dd4eaSJoe Perches } 3809365dd4eaSJoe Perches 38103b617e3bSJoe Perches# check for missing blank lines after declarations 3811b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line) 3812b5e8736aSJoe Perches if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) { 3813b5e8736aSJoe Perches # use temporaries 3814b5e8736aSJoe Perches my $sl = $sline; 3815b5e8736aSJoe Perches my $pl = $prevline; 3816b5e8736aSJoe Perches # remove $Attribute/$Sparse uses to simplify comparisons 3817b5e8736aSJoe Perches $sl =~ s/\b(?:$Attribute|$Sparse)\b//g; 3818b5e8736aSJoe Perches $pl =~ s/\b(?:$Attribute|$Sparse)\b//g; 3819b5e8736aSJoe Perches if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 38205a4e1fd3SJoe Perches # function pointer declarations 3821b5e8736aSJoe Perches $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 38223f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 3823b5e8736aSJoe Perches $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 38243f7bac03SJoe Perches # known declaration macros 3825b5e8736aSJoe Perches $pl =~ /^\+\s+$declaration_macros/) && 38263f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 3827b5e8736aSJoe Perches !($pl =~ /^\+\s+$c90_Keywords\b/ || 38283f7bac03SJoe Perches # other possible extensions of declaration lines 3829b5e8736aSJoe Perches $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 38303f7bac03SJoe Perches # not starting a section or a macro "\" extended line 3831b5e8736aSJoe Perches $pl =~ /(?:\{\s*|\\)$/) && 38323f7bac03SJoe Perches # looks like a declaration 3833b5e8736aSJoe Perches !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 38345a4e1fd3SJoe Perches # function pointer declarations 3835b5e8736aSJoe Perches $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 38363f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 3837b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 38383f7bac03SJoe Perches # known declaration macros 3839b5e8736aSJoe Perches $sl =~ /^\+\s+$declaration_macros/ || 38403f7bac03SJoe Perches # start of struct or union or enum 3841b5e8736aSJoe Perches $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 38423f7bac03SJoe Perches # start or end of block or continuation of declaration 3843b5e8736aSJoe Perches $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 38443f7bac03SJoe Perches # bitfield continuation 3845b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 38463f7bac03SJoe Perches # other possible extensions of declaration lines 3847b5e8736aSJoe Perches $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) { 3848d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3849d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3850d752fcc8SJoe Perches $fix) { 3851f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3852d752fcc8SJoe Perches } 38533b617e3bSJoe Perches } 3854b5e8736aSJoe Perches } 38553b617e3bSJoe Perches 38565f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 38576b4c5bebSAndy Whitcroft# Exceptions: 38586b4c5bebSAndy Whitcroft# 1) within comments 38596b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 38606b4c5bebSAndy Whitcroft# 3) hanging labels 38613705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 38625f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 38633705ce5bSJoe Perches if (WARN("LEADING_SPACE", 38643705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 38653705ce5bSJoe Perches $fix) { 3866194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 38673705ce5bSJoe Perches } 38685f7ddae6SRaffaele Recalcati } 38695f7ddae6SRaffaele Recalcati 3870b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3871b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3872b9ea10d6SAndy Whitcroft 38735751a24eSJoe Perches# check for unusual line ending [ or ( 38745751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 38755751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 38765751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 38775751a24eSJoe Perches } 38785751a24eSJoe Perches 38794dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 38804dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 38814dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 38824dbed76fSJoe Perches $context_function = $1; 38834dbed76fSJoe Perches } 38844dbed76fSJoe Perches 38854dbed76fSJoe Perches# check if this appears to be the end of function declaration 38864dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 38874dbed76fSJoe Perches undef $context_function; 38884dbed76fSJoe Perches } 38894dbed76fSJoe Perches 3890032a4c0fSJoe Perches# check indentation of any line with a bare else 3891840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3892032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3893032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3894032a4c0fSJoe Perches my $tabs = length($1) + 1; 3895840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3896840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3897840080a0SJoe Perches defined $lines[$linenr] && 3898840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3899032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3900032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3901032a4c0fSJoe Perches } 3902032a4c0fSJoe Perches } 3903032a4c0fSJoe Perches 3904c00df19aSJoe Perches# check indentation of a line with a break; 3905dc58bc55SJoe Perches# if the previous line is a goto, return or break 3906dc58bc55SJoe Perches# and is indented the same # of tabs 3907c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3908c00df19aSJoe Perches my $tabs = $1; 3909dc58bc55SJoe Perches if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { 3910dc58bc55SJoe Perches if (WARN("UNNECESSARY_BREAK", 3911dc58bc55SJoe Perches "break is not useful after a $1\n" . $hereprev) && 3912dc58bc55SJoe Perches $fix) { 3913dc58bc55SJoe Perches fix_delete_line($fixlinenr, $rawline); 3914dc58bc55SJoe Perches } 3915c00df19aSJoe Perches } 3916c00df19aSJoe Perches } 3917c00df19aSJoe Perches 3918c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3919cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3920000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3921000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3922c2fdda0dSAndy Whitcroft } 392322f2a2efSAndy Whitcroft 392456e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 392556e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 392656e77d70SJoe Perches WARN("HOTPLUG_SECTION", 392756e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 392856e77d70SJoe Perches } 392956e77d70SJoe Perches 39309c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 39312b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 39322b474a1aSAndy Whitcroft $realline_next); 39333e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 3934ca819864SJoe Perches if ($linenr > $suppress_statement && 39351b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3936170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3937f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3938171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3939171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3940171ae1a4SAndy Whitcroft 39413e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 39423e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 39433e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 39443e469cdcSAndy Whitcroft # until we hit end of it. 39453e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 39463e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 39473e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 39483e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 39493e469cdcSAndy Whitcroft } 3950f74bd194SAndy Whitcroft 39512b474a1aSAndy Whitcroft # Find the real next line. 39522b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 39532b474a1aSAndy Whitcroft if (defined $realline_next && 39542b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 39552b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 39562b474a1aSAndy Whitcroft $realline_next++; 39572b474a1aSAndy Whitcroft } 39582b474a1aSAndy Whitcroft 3959171ae1a4SAndy Whitcroft my $s = $stat; 3960171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3961cf655043SAndy Whitcroft 3962c2fdda0dSAndy Whitcroft # Ignore goto labels. 3963171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3964c2fdda0dSAndy Whitcroft 3965c2fdda0dSAndy Whitcroft # Ignore functions being called 3966171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3967c2fdda0dSAndy Whitcroft 3968463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3969463f2864SAndy Whitcroft 3970c45dcabdSAndy Whitcroft # declarations always start with types 3971d2506586SAndy 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) { 3972c45dcabdSAndy Whitcroft my $type = $1; 3973c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3974c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3975c45dcabdSAndy Whitcroft 39766c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3977a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3978c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3979c2fdda0dSAndy Whitcroft } 39808905a67cSAndy Whitcroft 39816c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 398265863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3983c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 39849c0ca6f9SAndy Whitcroft } 39858905a67cSAndy Whitcroft 39868905a67cSAndy Whitcroft # Check for any sort of function declaration. 39878905a67cSAndy Whitcroft # int foo(something bar, other baz); 39888905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3989171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 39908905a67cSAndy Whitcroft my ($name_len) = length($1); 39918905a67cSAndy Whitcroft 3992cf655043SAndy Whitcroft my $ctx = $s; 3993773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 39948905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 3995cf655043SAndy Whitcroft 39968905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 3997c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 39988905a67cSAndy Whitcroft 3999c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 40008905a67cSAndy Whitcroft } 40018905a67cSAndy Whitcroft } 40028905a67cSAndy Whitcroft } 40038905a67cSAndy Whitcroft 40049c0ca6f9SAndy Whitcroft } 40059c0ca6f9SAndy Whitcroft 400600df344fSAndy Whitcroft# 400700df344fSAndy Whitcroft# Checks which may be anchored in the context. 400800df344fSAndy Whitcroft# 400900df344fSAndy Whitcroft 401000df344fSAndy Whitcroft# Check for switch () and associated case and default 401100df344fSAndy Whitcroft# statements should be at the same indent. 401200df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 401300df344fSAndy Whitcroft my $err = ''; 401400df344fSAndy Whitcroft my $sep = ''; 401500df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 401600df344fSAndy Whitcroft shift(@ctx); 401700df344fSAndy Whitcroft for my $ctx (@ctx) { 401800df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 401900df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 402000df344fSAndy Whitcroft $indent != $cindent) { 402100df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 402200df344fSAndy Whitcroft $sep = ''; 402300df344fSAndy Whitcroft } else { 402400df344fSAndy Whitcroft $sep = "[...]\n"; 402500df344fSAndy Whitcroft } 402600df344fSAndy Whitcroft } 402700df344fSAndy Whitcroft if ($err ne '') { 4028000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 4029000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 4030de7d4f0eSAndy Whitcroft } 4031de7d4f0eSAndy Whitcroft } 4032de7d4f0eSAndy Whitcroft 4033de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 4034de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 40350fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 4036773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 4037773647a0SAndy Whitcroft 40389c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 40398eef05ddSJoe Perches 40408eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 40418eef05ddSJoe Perches WARN("DEEP_INDENTATION", 40428eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 40438eef05ddSJoe Perches } 40448eef05ddSJoe Perches 4045de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 4046de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 4047de7d4f0eSAndy Whitcroft 4048548596d5SAndy Whitcroft my $ctx_ln = $linenr; 4049548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 4050de7d4f0eSAndy Whitcroft 4051548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 4052548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 4053548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 4054548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 4055548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 4056773647a0SAndy Whitcroft $ctx_ln++; 4057773647a0SAndy Whitcroft } 4058548596d5SAndy Whitcroft 405953210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 406053210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 4061773647a0SAndy Whitcroft 4062773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 4063000d1cc1SJoe Perches ERROR("OPEN_BRACE", 4064000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 406501464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 406600df344fSAndy Whitcroft } 4067773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 4068773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 4069773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 4070773647a0SAndy Whitcroft { 40719c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 40729c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 4073000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 4074000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 407501464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 40769c0ca6f9SAndy Whitcroft } 40779c0ca6f9SAndy Whitcroft } 407800df344fSAndy Whitcroft } 407900df344fSAndy Whitcroft 40804d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 4081f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 40823e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 40833e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 40843e469cdcSAndy Whitcroft if (!defined $stat); 40854d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 40864d001e4dSAndy Whitcroft 40874d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 40884d001e4dSAndy Whitcroft 40899f5af480SJoe Perches # remove inline comments 40909f5af480SJoe Perches $s =~ s/$;/ /g; 40919f5af480SJoe Perches $c =~ s/$;/ /g; 40924d001e4dSAndy Whitcroft 40934d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 40946f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 40956f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 40964d001e4dSAndy Whitcroft 40979f5af480SJoe Perches # Make sure we remove the line prefixes as we have 40989f5af480SJoe Perches # none on the first line, and are going to readd them 40999f5af480SJoe Perches # where necessary. 41009f5af480SJoe Perches $s =~ s/\n./\n/gs; 41019f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 41029f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 41039f5af480SJoe Perches } 41049f5af480SJoe Perches 41054d001e4dSAndy Whitcroft # We want to check the first line inside the block 41064d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 41074d001e4dSAndy Whitcroft # 1) any blank line termination 41084d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 41094d001e4dSAndy Whitcroft # 3) any do (...) { 41104d001e4dSAndy Whitcroft my $continuation = 0; 41114d001e4dSAndy Whitcroft my $check = 0; 41124d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 41134d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 41144d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 41154d001e4dSAndy Whitcroft $continuation = 1; 41164d001e4dSAndy Whitcroft } 41179bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 41184d001e4dSAndy Whitcroft $check = 1; 41194d001e4dSAndy Whitcroft $cond_lines++; 41204d001e4dSAndy Whitcroft } 41214d001e4dSAndy Whitcroft 41224d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 41234d001e4dSAndy Whitcroft # preprocessor statement. 41244d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 41254d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 41264d001e4dSAndy Whitcroft $check = 0; 41274d001e4dSAndy Whitcroft } 41284d001e4dSAndy Whitcroft 41299bd49efeSAndy Whitcroft my $cond_ptr = -1; 4130740504c6SAndy Whitcroft $continuation = 0; 41319bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 41329bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 41334d001e4dSAndy Whitcroft 4134f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 4135f16fa28fSAndy Whitcroft # is not linear. 4136f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 4137f16fa28fSAndy Whitcroft $check = 0; 4138f16fa28fSAndy Whitcroft } 4139f16fa28fSAndy Whitcroft 41409bd49efeSAndy Whitcroft # Ignore: 41419bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 41429bd49efeSAndy Whitcroft # 2) preprocessor lines, and 41439bd49efeSAndy Whitcroft # 3) labels. 4144740504c6SAndy Whitcroft if ($continuation || 4145740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 41469bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 41479bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 4148740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 414930dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 41509bd49efeSAndy Whitcroft $cond_lines++; 41519bd49efeSAndy Whitcroft } 41524d001e4dSAndy Whitcroft } 415330dad6ebSAndy Whitcroft } 41544d001e4dSAndy Whitcroft 41554d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 41564d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 41574d001e4dSAndy Whitcroft 41584d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 41594d001e4dSAndy Whitcroft # this is not this patch's fault. 41604d001e4dSAndy Whitcroft if (!defined($stat_real) || 41614d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 41624d001e4dSAndy Whitcroft $check = 0; 41634d001e4dSAndy Whitcroft } 41644d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 41654d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 41664d001e4dSAndy Whitcroft } 41674d001e4dSAndy Whitcroft 41689bd49efeSAndy 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"; 41694d001e4dSAndy Whitcroft 41709f5af480SJoe Perches if ($check && $s ne '' && 4171713a09deSAntonio Borneo (($sindent % $tabsize) != 0 || 41729f5af480SJoe Perches ($sindent < $indent) || 4173f6950a73SJoe Perches ($sindent == $indent && 4174f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 4175713a09deSAntonio Borneo ($sindent > $indent + $tabsize))) { 4176000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 4177000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 41784d001e4dSAndy Whitcroft } 41794d001e4dSAndy Whitcroft } 41804d001e4dSAndy Whitcroft 41816c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 41826c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 41831f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 41841f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 41856c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 4186c2fdda0dSAndy Whitcroft if ($dbg_values) { 4187c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 4188cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 4189cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 41901f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 4191c2fdda0dSAndy Whitcroft } 41926c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 41936c72ffaaSAndy Whitcroft 419400df344fSAndy Whitcroft#ignore lines not being added 41953705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 419600df344fSAndy Whitcroft 419799ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings 419899ca38c2SJoe Perches# e.g.: int foo = foo, *bar = NULL; 419999ca38c2SJoe Perches# struct foo bar = *(&(bar)); 420099ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { 420199ca38c2SJoe Perches my $var = $1; 420299ca38c2SJoe Perches if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { 420399ca38c2SJoe Perches WARN("SELF_ASSIGNMENT", 420499ca38c2SJoe Perches "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); 420599ca38c2SJoe Perches } 420699ca38c2SJoe Perches } 420799ca38c2SJoe Perches 420811ca40a0SJoe Perches# check for dereferences that span multiple lines 420911ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 421011ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 421111ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 421211ca40a0SJoe Perches my $ref = $1; 421311ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 421411ca40a0SJoe Perches $ref .= $1; 421511ca40a0SJoe Perches $ref =~ s/\s//g; 421611ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 421711ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 421811ca40a0SJoe Perches } 421911ca40a0SJoe Perches 4220a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 4221c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 4222a1ce18e4SJoe Perches my $type = $1; 4223a1ce18e4SJoe Perches my $var = $2; 4224207a8e84SJoe Perches $var = "" if (!defined $var); 4225207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 4226a1ce18e4SJoe Perches my $sign = $1; 4227a1ce18e4SJoe Perches my $pointer = $2; 4228a1ce18e4SJoe Perches 4229a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 4230a1ce18e4SJoe Perches 4231a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 4232a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 4233a1ce18e4SJoe Perches $fix) { 4234a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 4235207a8e84SJoe Perches my $comp_pointer = $pointer; 4236207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 4237207a8e84SJoe Perches $decl .= $comp_pointer; 4238207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 4239207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 4240a1ce18e4SJoe Perches } 4241a1ce18e4SJoe Perches } 4242a1ce18e4SJoe Perches } 4243a1ce18e4SJoe Perches 4244653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 42457429c690SAndy Whitcroft if ($dbg_type) { 42467429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 4247000d1cc1SJoe Perches ERROR("TEST_TYPE", 4248000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 42497429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 4250000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 4251000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 42527429c690SAndy Whitcroft } 4253653d4876SAndy Whitcroft next; 4254653d4876SAndy Whitcroft } 4255a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 4256a1ef277eSAndy Whitcroft if ($dbg_attr) { 42579360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 4258000d1cc1SJoe Perches ERROR("TEST_ATTR", 4259000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 42609360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 4261000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 4262000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 4263a1ef277eSAndy Whitcroft } 4264a1ef277eSAndy Whitcroft next; 4265a1ef277eSAndy Whitcroft } 4266653d4876SAndy Whitcroft 4267f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 426899423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 426999423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 4270d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 4271d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 4272f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 4273f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 4274f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 4275d752fcc8SJoe Perches my $fixedline = $prevrawline; 4276d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 4277f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4278d752fcc8SJoe Perches $fixedline = $line; 42798d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 4280f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 4281d752fcc8SJoe Perches } 4282f0a594c1SAndy Whitcroft } 4283f0a594c1SAndy Whitcroft 428400df344fSAndy Whitcroft# 428500df344fSAndy Whitcroft# Checks which are anchored on the added line. 428600df344fSAndy Whitcroft# 428700df344fSAndy Whitcroft 4288653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 4289c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 4290653d4876SAndy Whitcroft my $path = $1; 4291653d4876SAndy Whitcroft if ($path =~ m{//}) { 4292000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 4293495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 4294495e9d84SJoe Perches } 4295495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 4296495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 4297495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 4298653d4876SAndy Whitcroft } 4299653d4876SAndy Whitcroft } 4300653d4876SAndy Whitcroft 430100df344fSAndy Whitcroft# no C99 // comments 430200df344fSAndy Whitcroft if ($line =~ m{//}) { 43033705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 43043705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 43053705ce5bSJoe Perches $fix) { 4306194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 43073705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 43083705ce5bSJoe Perches my $comment = trim($1); 4309194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 43103705ce5bSJoe Perches } 43113705ce5bSJoe Perches } 431200df344fSAndy Whitcroft } 431300df344fSAndy Whitcroft # Remove C99 comments. 43140a920b5bSAndy Whitcroft $line =~ s@//.*@@; 43156c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 43160a920b5bSAndy Whitcroft 43172b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 43182b474a1aSAndy Whitcroft# the whole statement. 43192b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 43202b474a1aSAndy Whitcroft if (defined $realline_next && 43212b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 43222b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 432336794822SChristoph Hellwig ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 43243cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 43253cbf62dfSAndy Whitcroft # a prefix: 43263cbf62dfSAndy Whitcroft # XXX(foo); 43273cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 4328653d4876SAndy Whitcroft my $name = $1; 432987a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 43303cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 43313cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 43323cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 43333cbf62dfSAndy Whitcroft 43343cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 43352b474a1aSAndy Whitcroft \n.}\s*$| 433648012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 433748012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 433848012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 43392b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 43402b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 434148012058SAndy Whitcroft )/x) { 43422b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 43432b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 43442b474a1aSAndy Whitcroft } else { 43452b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 43460a920b5bSAndy Whitcroft } 43470a920b5bSAndy Whitcroft } 43482b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 43492b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 435036794822SChristoph Hellwig ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 43512b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 43522b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 43532b474a1aSAndy Whitcroft } 43542b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 43552b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 4356000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 4357000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 43582b474a1aSAndy Whitcroft } 43590a920b5bSAndy Whitcroft 43605150bda4SJoe Eloff# check for global initialisers. 43616d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 4362d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 43636d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 4364d5e616fcSJoe Perches $fix) { 43656d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 4366d5e616fcSJoe Perches } 4367f0a594c1SAndy Whitcroft } 43680a920b5bSAndy Whitcroft# check for static initialisers. 43696d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 4370d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 43716d32f7a3SJoe Perches "do not initialise statics to $1\n" . 4372d5e616fcSJoe Perches $herecurr) && 4373d5e616fcSJoe Perches $fix) { 43746d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 4375d5e616fcSJoe Perches } 43760a920b5bSAndy Whitcroft } 43770a920b5bSAndy Whitcroft 43781813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 43791813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 43801813087dSJoe Perches my $tmp = trim($1); 43811813087dSJoe Perches WARN("MISORDERED_TYPE", 43821813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 43831813087dSJoe Perches } 43841813087dSJoe Perches 4385809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4386809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4387809e082eSJoe Perches my $type = trim($1); 4388809e082eSJoe Perches next if ($type !~ /\bint\b/); 4389809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 4390809e082eSJoe Perches my $new_type = $type; 4391809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 4392809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 4393809e082eSJoe Perches $new_type =~ s/^const\s+//; 4394809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 4395809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 4396809e082eSJoe Perches $new_type =~ s/\s+/ /g; 4397809e082eSJoe Perches $new_type = trim($new_type); 4398809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 4399809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4400809e082eSJoe Perches $fix) { 4401809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4402809e082eSJoe Perches } 4403809e082eSJoe Perches } 4404809e082eSJoe Perches 4405cb710ecaSJoe Perches# check for static const char * arrays. 4406cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4407000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4408000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 4409cb710ecaSJoe Perches $herecurr); 4410cb710ecaSJoe Perches } 4411cb710ecaSJoe Perches 441277b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 441377b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 441477b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 441577b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 441677b8c0a8SJoe Perches $fix) { 441777b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 441877b8c0a8SJoe Perches } 441977b8c0a8SJoe Perches } 442077b8c0a8SJoe Perches 4421cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 4422cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4423000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4424000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 4425cb710ecaSJoe Perches $herecurr); 4426cb710ecaSJoe Perches } 4427cb710ecaSJoe Perches 4428ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 4429ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 4430ab7e23f3SJoe Perches my $found = $1; 4431ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 4432ab7e23f3SJoe Perches WARN("CONST_CONST", 4433ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 4434ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4435ab7e23f3SJoe Perches WARN("CONST_CONST", 4436ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4437ab7e23f3SJoe Perches } 4438ab7e23f3SJoe Perches } 4439ab7e23f3SJoe Perches 444073169765SJoe Perches# check for const static or static <non ptr type> const declarations 444173169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const' 444273169765SJoe Perches if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || 444373169765SJoe Perches $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { 444473169765SJoe Perches if (WARN("STATIC_CONST", 444573169765SJoe Perches "Move const after static - use 'static const $1'\n" . $herecurr) && 444673169765SJoe Perches $fix) { 444773169765SJoe Perches $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; 444873169765SJoe Perches $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; 444973169765SJoe Perches } 445073169765SJoe Perches } 445173169765SJoe Perches 44529b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 44539b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 44549b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 44559b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 44569b0fa60dSJoe Perches $herecurr); 44579b0fa60dSJoe Perches } 44589b0fa60dSJoe Perches 4459b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 4460b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 4461b598b670SJoe Perches my $array = $1; 4462b598b670SJoe 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*\))@) { 4463b598b670SJoe Perches my $array_div = $1; 4464b598b670SJoe Perches if (WARN("ARRAY_SIZE", 4465b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 4466b598b670SJoe Perches $fix) { 4467b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4468b598b670SJoe Perches } 4469b598b670SJoe Perches } 4470b598b670SJoe Perches } 4471b598b670SJoe Perches 4472b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 447316b7f3c8SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4474b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4475b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4476b36190c5SJoe Perches $fix) { 4477194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4478b36190c5SJoe Perches } 4479b36190c5SJoe Perches } 4480b36190c5SJoe Perches 4481653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4482653d4876SAndy Whitcroft# make sense. 4483653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 44848054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4485c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 44868ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 448746d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4488000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4489000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 44900a920b5bSAndy Whitcroft } 44910a920b5bSAndy Whitcroft 44920a920b5bSAndy Whitcroft# * goes on variable not on type 449365863862SAndy Whitcroft # (char*[ const]) 4494bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4495bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 44963705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4497d8aaf121SAndy Whitcroft 449865863862SAndy Whitcroft # Should start with a space. 449965863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 450065863862SAndy Whitcroft # Should not end with a space. 450165863862SAndy Whitcroft $to =~ s/\s+$//; 450265863862SAndy Whitcroft # '*'s should not have spaces between. 4503f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 450465863862SAndy Whitcroft } 4505d8aaf121SAndy Whitcroft 45063705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 450765863862SAndy Whitcroft if ($from ne $to) { 45083705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 45093705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 45103705ce5bSJoe Perches $fix) { 45113705ce5bSJoe Perches my $sub_from = $ident; 45123705ce5bSJoe Perches my $sub_to = $ident; 45133705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4514194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45153705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 45163705ce5bSJoe Perches } 451765863862SAndy Whitcroft } 4518bfcb2cc7SAndy Whitcroft } 4519bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4520bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 45213705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4522d8aaf121SAndy Whitcroft 452365863862SAndy Whitcroft # Should start with a space. 452465863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 452565863862SAndy Whitcroft # Should not end with a space. 452665863862SAndy Whitcroft $to =~ s/\s+$//; 452765863862SAndy Whitcroft # '*'s should not have spaces between. 4528f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 452965863862SAndy Whitcroft } 453065863862SAndy Whitcroft # Modifiers should have spaces. 453165863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 453265863862SAndy Whitcroft 45333705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4534667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 45353705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 45363705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 45373705ce5bSJoe Perches $fix) { 45383705ce5bSJoe Perches 45393705ce5bSJoe Perches my $sub_from = $match; 45403705ce5bSJoe Perches my $sub_to = $match; 45413705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4542194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45433705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 45443705ce5bSJoe Perches } 454565863862SAndy Whitcroft } 45460a920b5bSAndy Whitcroft } 45470a920b5bSAndy Whitcroft 45489d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 45499d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 45500675a8fbSJean Delvare my $msg_level = \&WARN; 45510675a8fbSJean Delvare $msg_level = \&CHK if ($file); 45520675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 45539d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 45549d3e3c70SJoe Perches } 45550a920b5bSAndy Whitcroft 45569d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 45578905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4558000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4559000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 45608905a67cSAndy Whitcroft } 45618905a67cSAndy Whitcroft 456217441227SJoe Perches# check for uses of printk_ratelimit 456317441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4564000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4565000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 456617441227SJoe Perches } 456717441227SJoe Perches 4568eeef5733SJoe Perches# printk should use KERN_* levels 4569eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4570000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4571eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 457200df344fSAndy Whitcroft } 45730a920b5bSAndy Whitcroft 4574f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL> 4575f5eea3b0SJoe Perches if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { 4576f5eea3b0SJoe Perches my $printk = $1; 4577f5eea3b0SJoe Perches my $modifier = $2; 4578f5eea3b0SJoe Perches my $orig = $3; 4579f5eea3b0SJoe Perches $modifier = "" if (!defined($modifier)); 4580243f3803SJoe Perches my $level = lc($orig); 4581243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 45828f26b837SJoe Perches my $level2 = $level; 45838f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4584f5eea3b0SJoe Perches $level .= $modifier; 4585f5eea3b0SJoe Perches $level2 .= $modifier; 4586243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4587f5eea3b0SJoe Perches "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); 4588243f3803SJoe Perches } 4589243f3803SJoe Perches 4590f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL> 4591dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4592dc139313SJoe Perches my $orig = $1; 4593dc139313SJoe Perches my $level = lc($orig); 4594dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4595dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4596dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4597dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4598dc139313SJoe Perches } 4599dc139313SJoe Perches 46008020b253SNicolas Boichat# trace_printk should not be used in production code. 46018020b253SNicolas Boichat if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { 46028020b253SNicolas Boichat WARN("TRACE_PRINTK", 46038020b253SNicolas Boichat "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); 46048020b253SNicolas Boichat } 46058020b253SNicolas Boichat 460691c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 460791c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 460891c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 460991c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 461091c9afafSAndy Lutomirski WARN("ENOSYS", 461191c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 461291c9afafSAndy Lutomirski } 461391c9afafSAndy Lutomirski 46146b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches. 46156b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. 46166b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected. 46176b9ea5ffSJakub Kicinski if (!$file && $line =~ /\bENOTSUPP\b/) { 46186b9ea5ffSJakub Kicinski if (WARN("ENOTSUPP", 46196b9ea5ffSJakub Kicinski "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && 46206b9ea5ffSJakub Kicinski $fix) { 46216b9ea5ffSJakub Kicinski $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; 46226b9ea5ffSJakub Kicinski } 46236b9ea5ffSJakub Kicinski } 46246b9ea5ffSJakub Kicinski 4625653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4626653d4876SAndy Whitcroft# or if closed on same line 46275b57980dSJoe Perches if ($perl_version_ok && 46282d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 46292d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 46302d453e3bSJoe Perches $sline !~ /}/) { 46318d182478SJoe Perches if (ERROR("OPEN_BRACE", 46322d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 46338d182478SJoe Perches $fix) { 46348d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 46358d182478SJoe Perches my $fixed_line = $rawline; 463603f49351SDwaipayan Ray $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; 46378d182478SJoe Perches my $line1 = $1; 46388d182478SJoe Perches my $line2 = $2; 46398d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 46408d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 46418d182478SJoe Perches if ($line2 !~ /^\s*$/) { 46428d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 46438d182478SJoe Perches } 46448d182478SJoe Perches } 46450a920b5bSAndy Whitcroft } 4646653d4876SAndy Whitcroft 46478905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 46488905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 46498905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 46508d182478SJoe Perches if (ERROR("OPEN_BRACE", 46518d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 46528d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46538d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46548d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 46558d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 46568d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46578d182478SJoe Perches $fixedline = $rawline; 46588d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 46598d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 46608d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46618d182478SJoe Perches } 46628d182478SJoe Perches } 46638905a67cSAndy Whitcroft } 46648905a67cSAndy Whitcroft 46650c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 46663705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 46673705ce5bSJoe Perches if (WARN("SPACING", 46683705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 46693705ce5bSJoe Perches $fix) { 4670194f66fcSJoe Perches $fixed[$fixlinenr] =~ 46713705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 46723705ce5bSJoe Perches } 46730c73b4ebSAndy Whitcroft } 46740c73b4ebSAndy Whitcroft 467531070b5dSJoe Perches# Function pointer declarations 467631070b5dSJoe Perches# check spacing between type, funcptr, and args 467731070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 467891f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 467931070b5dSJoe Perches my $declare = $1; 468031070b5dSJoe Perches my $pre_pointer_space = $2; 468131070b5dSJoe Perches my $post_pointer_space = $3; 468231070b5dSJoe Perches my $funcname = $4; 468331070b5dSJoe Perches my $post_funcname_space = $5; 468431070b5dSJoe Perches my $pre_args_space = $6; 468531070b5dSJoe Perches 468691f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 468791f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 468891f72e9cSJoe Perches# don't need a space so don't warn for those. 468991f72e9cSJoe Perches my $post_declare_space = ""; 469091f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 469191f72e9cSJoe Perches $post_declare_space = $1; 469291f72e9cSJoe Perches $declare = rtrim($declare); 469391f72e9cSJoe Perches } 469491f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 469531070b5dSJoe Perches WARN("SPACING", 469631070b5dSJoe Perches "missing space after return type\n" . $herecurr); 469791f72e9cSJoe Perches $post_declare_space = " "; 469831070b5dSJoe Perches } 469931070b5dSJoe Perches 470031070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 470191f72e9cSJoe Perches# This test is not currently implemented because these declarations are 470291f72e9cSJoe Perches# equivalent to 470391f72e9cSJoe Perches# int foo(int bar, ...) 470491f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 470591f72e9cSJoe Perches# 470691f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 470791f72e9cSJoe Perches# WARN("SPACING", 470891f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 470991f72e9cSJoe Perches# } 471031070b5dSJoe Perches 471131070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 471231070b5dSJoe Perches if (defined $pre_pointer_space && 471331070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 471431070b5dSJoe Perches WARN("SPACING", 471531070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 471631070b5dSJoe Perches } 471731070b5dSJoe Perches 471831070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 471931070b5dSJoe Perches if (defined $post_pointer_space && 472031070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 472131070b5dSJoe Perches WARN("SPACING", 472231070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 472331070b5dSJoe Perches } 472431070b5dSJoe Perches 472531070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 472631070b5dSJoe Perches if (defined $post_funcname_space && 472731070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 472831070b5dSJoe Perches WARN("SPACING", 472931070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 473031070b5dSJoe Perches } 473131070b5dSJoe Perches 473231070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 473331070b5dSJoe Perches if (defined $pre_args_space && 473431070b5dSJoe Perches $pre_args_space =~ /^\s/) { 473531070b5dSJoe Perches WARN("SPACING", 473631070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 473731070b5dSJoe Perches } 473831070b5dSJoe Perches 473931070b5dSJoe Perches if (show_type("SPACING") && $fix) { 4740194f66fcSJoe Perches $fixed[$fixlinenr] =~ 474191f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 474231070b5dSJoe Perches } 474331070b5dSJoe Perches } 474431070b5dSJoe Perches 47458d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 47468d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 4747fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4748fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 47498d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 47508d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 47518d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 4752fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 475338dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 47543705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 47553705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 47563705ce5bSJoe Perches $fix) { 4757194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47583705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 47593705ce5bSJoe Perches } 47608d31cfceSAndy Whitcroft } 47618d31cfceSAndy Whitcroft } 47628d31cfceSAndy Whitcroft 4763f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 47646c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4765c2fdda0dSAndy Whitcroft my $name = $1; 4766773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4767773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4768c2fdda0dSAndy Whitcroft 4769c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4770773647a0SAndy Whitcroft if ($name =~ /^(?: 4771773647a0SAndy Whitcroft if|for|while|switch|return|case| 4772773647a0SAndy Whitcroft volatile|__volatile__| 4773773647a0SAndy Whitcroft __attribute__|format|__extension__| 4774773647a0SAndy Whitcroft asm|__asm__)$/x) 4775773647a0SAndy Whitcroft { 4776c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4777c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4778c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4779c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4780773647a0SAndy Whitcroft 4781773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4782c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4783c2fdda0dSAndy Whitcroft 4784c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4785c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4786773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4787c2fdda0dSAndy Whitcroft 4788c2fdda0dSAndy Whitcroft } else { 47893705ce5bSJoe Perches if (WARN("SPACING", 47903705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 47913705ce5bSJoe Perches $fix) { 4792194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47933705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 47943705ce5bSJoe Perches } 4795f0a594c1SAndy Whitcroft } 47966c72ffaaSAndy Whitcroft } 47979a4cad4eSEric Nelson 4798653d4876SAndy Whitcroft# Check operator spacing. 47990a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 48003705ce5bSJoe Perches my $fixed_line = ""; 48013705ce5bSJoe Perches my $line_fixed = 0; 48023705ce5bSJoe Perches 48039c0ca6f9SAndy Whitcroft my $ops = qr{ 48049c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 48059c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 48069c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 48071f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 480884731623SJoe Perches \?:|\?|: 48099c0ca6f9SAndy Whitcroft }x; 4810cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 48113705ce5bSJoe Perches 48123705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 48133705ce5bSJoe Perches## foreach my $el (@elements) { 48143705ce5bSJoe Perches## print("el: <$el>\n"); 48153705ce5bSJoe Perches## } 48163705ce5bSJoe Perches 48173705ce5bSJoe Perches my @fix_elements = (); 481800df344fSAndy Whitcroft my $off = 0; 48196c72ffaaSAndy Whitcroft 48203705ce5bSJoe Perches foreach my $el (@elements) { 48213705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 48223705ce5bSJoe Perches $off += length($el); 48233705ce5bSJoe Perches } 48243705ce5bSJoe Perches 48253705ce5bSJoe Perches $off = 0; 48263705ce5bSJoe Perches 48276c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4828b34c648bSJoe Perches my $last_after = -1; 48296c72ffaaSAndy Whitcroft 48300a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 48313705ce5bSJoe Perches 48323705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 48333705ce5bSJoe Perches 48343705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 48353705ce5bSJoe Perches 48364a0df2efSAndy Whitcroft $off += length($elements[$n]); 48374a0df2efSAndy Whitcroft 483825985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4839773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4840773647a0SAndy Whitcroft my $cc = ''; 4841773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4842773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4843773647a0SAndy Whitcroft } 4844773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4845773647a0SAndy Whitcroft 48464a0df2efSAndy Whitcroft my $a = ''; 48474a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 48484a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4849cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 48504a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 48514a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4852773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 48534a0df2efSAndy Whitcroft 48540a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 48554a0df2efSAndy Whitcroft 48564a0df2efSAndy Whitcroft my $c = ''; 48570a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 48584a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 48594a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4860cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 48614a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 48624a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 48638b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 48644a0df2efSAndy Whitcroft } else { 48654a0df2efSAndy Whitcroft $c = 'E'; 48660a920b5bSAndy Whitcroft } 48670a920b5bSAndy Whitcroft 48684a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 48694a0df2efSAndy Whitcroft 48704a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 48714a0df2efSAndy Whitcroft 48726c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4873de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 48740a920b5bSAndy Whitcroft 487574048ed8SAndy Whitcroft # Pull out the value of this operator. 48766c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 48770a920b5bSAndy Whitcroft 48781f65f947SAndy Whitcroft # Get the full operator variant. 48791f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 48801f65f947SAndy Whitcroft 488113214adfSAndy Whitcroft # Ignore operators passed as parameters. 488213214adfSAndy Whitcroft if ($op_type ne 'V' && 4883d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 488413214adfSAndy Whitcroft 4885cf655043SAndy Whitcroft# # Ignore comments 4886cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 488713214adfSAndy Whitcroft 4888d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 488913214adfSAndy Whitcroft } elsif ($op eq ';') { 4890cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4891cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 48923705ce5bSJoe Perches if (ERROR("SPACING", 48933705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4894b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 48953705ce5bSJoe Perches $line_fixed = 1; 48963705ce5bSJoe Perches } 4897d8aaf121SAndy Whitcroft } 4898d8aaf121SAndy Whitcroft 4899d8aaf121SAndy Whitcroft # // is a comment 4900d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 49010a920b5bSAndy Whitcroft 4902b00e4814SJoe Perches # : when part of a bitfield 4903b00e4814SJoe Perches } elsif ($opv eq ':B') { 4904b00e4814SJoe Perches # skip the bitfield test for now 4905b00e4814SJoe Perches 49061f65f947SAndy Whitcroft # No spaces for: 49071f65f947SAndy Whitcroft # -> 4908b00e4814SJoe Perches } elsif ($op eq '->') { 49094a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 49103705ce5bSJoe Perches if (ERROR("SPACING", 49113705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4912b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 49133705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 49143705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 49153705ce5bSJoe Perches } 4916b34c648bSJoe Perches $line_fixed = 1; 49173705ce5bSJoe Perches } 49180a920b5bSAndy Whitcroft } 49190a920b5bSAndy Whitcroft 49202381097bSJoe Perches # , must not have a space before and must have a space on the right. 49210a920b5bSAndy Whitcroft } elsif ($op eq ',') { 49222381097bSJoe Perches my $rtrim_before = 0; 49232381097bSJoe Perches my $space_after = 0; 49242381097bSJoe Perches if ($ctx =~ /Wx./) { 49252381097bSJoe Perches if (ERROR("SPACING", 49262381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 49272381097bSJoe Perches $line_fixed = 1; 49282381097bSJoe Perches $rtrim_before = 1; 49292381097bSJoe Perches } 49302381097bSJoe Perches } 4931cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 49323705ce5bSJoe Perches if (ERROR("SPACING", 49333705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 49343705ce5bSJoe Perches $line_fixed = 1; 4935b34c648bSJoe Perches $last_after = $n; 49362381097bSJoe Perches $space_after = 1; 49372381097bSJoe Perches } 49382381097bSJoe Perches } 49392381097bSJoe Perches if ($rtrim_before || $space_after) { 49402381097bSJoe Perches if ($rtrim_before) { 49412381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 49422381097bSJoe Perches } else { 49432381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 49442381097bSJoe Perches } 49452381097bSJoe Perches if ($space_after) { 49462381097bSJoe Perches $good .= " "; 49473705ce5bSJoe Perches } 49480a920b5bSAndy Whitcroft } 49490a920b5bSAndy Whitcroft 49509c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 495174048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 49529c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 49539c0ca6f9SAndy Whitcroft 49549c0ca6f9SAndy Whitcroft # unary operators should have a space before and 49559c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 49569c0ca6f9SAndy Whitcroft # unary operator, or a cast 49579c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 495874048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 49590d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4960cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 49613705ce5bSJoe Perches if (ERROR("SPACING", 49623705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4963b34c648bSJoe Perches if ($n != $last_after + 2) { 4964b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 49653705ce5bSJoe Perches $line_fixed = 1; 49663705ce5bSJoe Perches } 49670a920b5bSAndy Whitcroft } 4968b34c648bSJoe Perches } 4969a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4970171ae1a4SAndy Whitcroft # A unary '*' may be const 4971171ae1a4SAndy Whitcroft 4972171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 49733705ce5bSJoe Perches if (ERROR("SPACING", 49743705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4975b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 49763705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 49773705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 49783705ce5bSJoe Perches } 4979b34c648bSJoe Perches $line_fixed = 1; 49803705ce5bSJoe Perches } 49810a920b5bSAndy Whitcroft } 49820a920b5bSAndy Whitcroft 49830a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 49840a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4985773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 49863705ce5bSJoe Perches if (ERROR("SPACING", 49873705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4988b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 49893705ce5bSJoe Perches $line_fixed = 1; 49903705ce5bSJoe Perches } 49910a920b5bSAndy Whitcroft } 4992773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4993773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 49943705ce5bSJoe Perches if (ERROR("SPACING", 49953705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4996b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 49973705ce5bSJoe Perches $line_fixed = 1; 49983705ce5bSJoe Perches } 4999653d4876SAndy Whitcroft } 5000773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 50013705ce5bSJoe Perches if (ERROR("SPACING", 50023705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 5003b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 50043705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 50053705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5006773647a0SAndy Whitcroft } 5007b34c648bSJoe Perches $line_fixed = 1; 50083705ce5bSJoe Perches } 50093705ce5bSJoe Perches } 50100a920b5bSAndy Whitcroft 50110a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 50129c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 50139c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 50149c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 5015c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 5016c2fdda0dSAndy Whitcroft $op eq '%') 50170a920b5bSAndy Whitcroft { 5018d2e025f3SJoe Perches if ($check) { 5019d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 5020d2e025f3SJoe Perches if (CHK("SPACING", 5021d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 5022d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5023d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5024d2e025f3SJoe Perches $line_fixed = 1; 5025d2e025f3SJoe Perches } 5026d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 5027d2e025f3SJoe Perches if (CHK("SPACING", 5028d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 5029d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 5030d2e025f3SJoe Perches $line_fixed = 1; 5031d2e025f3SJoe Perches } 5032d2e025f3SJoe Perches } 5033d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 50343705ce5bSJoe Perches if (ERROR("SPACING", 50353705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 5036b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5037b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5038b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5039b34c648bSJoe Perches } 50403705ce5bSJoe Perches $line_fixed = 1; 50413705ce5bSJoe Perches } 50420a920b5bSAndy Whitcroft } 50430a920b5bSAndy Whitcroft 50441f65f947SAndy Whitcroft # A colon needs no spaces before when it is 50451f65f947SAndy Whitcroft # terminating a case value or a label. 50461f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 5047*263afd39SChris Down if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) { 50483705ce5bSJoe Perches if (ERROR("SPACING", 50493705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5050b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 50513705ce5bSJoe Perches $line_fixed = 1; 50523705ce5bSJoe Perches } 50531f65f947SAndy Whitcroft } 50541f65f947SAndy Whitcroft 50550a920b5bSAndy Whitcroft # All the others need spaces both sides. 5056cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 50571f65f947SAndy Whitcroft my $ok = 0; 50581f65f947SAndy Whitcroft 505922f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 50601f65f947SAndy Whitcroft if (($op eq '<' && 50611f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 50621f65f947SAndy Whitcroft ($op eq '>' && 50631f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 50641f65f947SAndy Whitcroft { 50651f65f947SAndy Whitcroft $ok = 1; 50661f65f947SAndy Whitcroft } 50671f65f947SAndy Whitcroft 5068e0df7e1fSJoe Perches # for asm volatile statements 5069e0df7e1fSJoe Perches # ignore a colon with another 5070e0df7e1fSJoe Perches # colon immediately before or after 5071e0df7e1fSJoe Perches if (($op eq ':') && 5072e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 5073e0df7e1fSJoe Perches $ok = 1; 5074e0df7e1fSJoe Perches } 5075e0df7e1fSJoe Perches 507684731623SJoe Perches # messages are ERROR, but ?: are CHK 50771f65f947SAndy Whitcroft if ($ok == 0) { 50780675a8fbSJean Delvare my $msg_level = \&ERROR; 50790675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 508084731623SJoe Perches 50810675a8fbSJean Delvare if (&{$msg_level}("SPACING", 50823705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 5083b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5084b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 5085b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5086b34c648bSJoe Perches } 50873705ce5bSJoe Perches $line_fixed = 1; 50883705ce5bSJoe Perches } 50890a920b5bSAndy Whitcroft } 509022f2a2efSAndy Whitcroft } 50914a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 50923705ce5bSJoe Perches 50933705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 50943705ce5bSJoe Perches 50953705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 50960a920b5bSAndy Whitcroft } 50973705ce5bSJoe Perches 50983705ce5bSJoe Perches if (($#elements % 2) == 0) { 50993705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 51003705ce5bSJoe Perches } 51013705ce5bSJoe Perches 5102194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 5103194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 51043705ce5bSJoe Perches } 51053705ce5bSJoe Perches 51063705ce5bSJoe Perches 51070a920b5bSAndy Whitcroft } 51080a920b5bSAndy Whitcroft 5109786b6326SJoe Perches# check for whitespace before a non-naked semicolon 5110d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 5111786b6326SJoe Perches if (WARN("SPACING", 5112786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 5113786b6326SJoe Perches $fix) { 5114194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 5115786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 5116786b6326SJoe Perches } 5117786b6326SJoe Perches } 5118786b6326SJoe Perches 5119f0a594c1SAndy Whitcroft# check for multiple assignments 5120f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 5121000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 5122000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 5123f0a594c1SAndy Whitcroft } 5124f0a594c1SAndy Whitcroft 512522f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 512622f2a2efSAndy Whitcroft## # continuation. 512722f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 512822f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 512922f2a2efSAndy Whitcroft## 513022f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 5131e73d2715SDwaipayan Ray## # falsely report the parameters of functions. 513222f2a2efSAndy Whitcroft## my $ln = $line; 513322f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 513422f2a2efSAndy Whitcroft## } 513522f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 5136000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 5137000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 513822f2a2efSAndy Whitcroft## } 513922f2a2efSAndy Whitcroft## } 5140f0a594c1SAndy Whitcroft 51410a920b5bSAndy Whitcroft#need space before brace following if, while, etc 51426b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 51436ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 51443705ce5bSJoe Perches if (ERROR("SPACING", 51453705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 51463705ce5bSJoe Perches $fix) { 51476ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 51483705ce5bSJoe Perches } 5149de7d4f0eSAndy Whitcroft } 5150de7d4f0eSAndy Whitcroft 5151c4a62ef9SJoe Perches## # check for blank lines before declarations 5152c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 5153c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 5154c4a62ef9SJoe Perches## WARN("SPACING", 5155c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 5156c4a62ef9SJoe Perches## } 5157c4a62ef9SJoe Perches## 5158c4a62ef9SJoe Perches 5159de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 5160de7d4f0eSAndy Whitcroft# on the line 516194fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 5162d5e616fcSJoe Perches if (ERROR("SPACING", 5163d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 5164d5e616fcSJoe Perches $fix) { 5165194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5166d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 5167d5e616fcSJoe Perches } 51680a920b5bSAndy Whitcroft } 51690a920b5bSAndy Whitcroft 517022f2a2efSAndy Whitcroft# check spacing on square brackets 517122f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 51723705ce5bSJoe Perches if (ERROR("SPACING", 51733705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 51743705ce5bSJoe Perches $fix) { 5175194f66fcSJoe Perches $fixed[$fixlinenr] =~ 51763705ce5bSJoe Perches s/\[\s+/\[/; 51773705ce5bSJoe Perches } 517822f2a2efSAndy Whitcroft } 517922f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 51803705ce5bSJoe Perches if (ERROR("SPACING", 51813705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 51823705ce5bSJoe Perches $fix) { 5183194f66fcSJoe Perches $fixed[$fixlinenr] =~ 51843705ce5bSJoe Perches s/\s+\]/\]/; 51853705ce5bSJoe Perches } 518622f2a2efSAndy Whitcroft } 518722f2a2efSAndy Whitcroft 5188c45dcabdSAndy Whitcroft# check spacing on parentheses 51899c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 51909c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 51913705ce5bSJoe Perches if (ERROR("SPACING", 51923705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 51933705ce5bSJoe Perches $fix) { 5194194f66fcSJoe Perches $fixed[$fixlinenr] =~ 51953705ce5bSJoe Perches s/\(\s+/\(/; 51963705ce5bSJoe Perches } 519722f2a2efSAndy Whitcroft } 519813214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 5199c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 5200c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 52013705ce5bSJoe Perches if (ERROR("SPACING", 52023705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 52033705ce5bSJoe Perches $fix) { 5204194f66fcSJoe Perches $fixed[$fixlinenr] =~ 52053705ce5bSJoe Perches s/\s+\)/\)/; 52063705ce5bSJoe Perches } 520722f2a2efSAndy Whitcroft } 520822f2a2efSAndy Whitcroft 5209e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 5210e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 5211e2826fd0SJoe Perches 5212e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 5213ea4acbb1SJoe Perches my $var = $1; 5214ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5215ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 5216ea4acbb1SJoe Perches $fix) { 5217ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 5218ea4acbb1SJoe Perches } 5219ea4acbb1SJoe Perches } 5220ea4acbb1SJoe Perches 5221ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 5222ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 5223ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 5224ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 5225ea4acbb1SJoe Perches my $var = $2; 5226ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5227ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 5228ea4acbb1SJoe Perches $fix) { 5229ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 5230ea4acbb1SJoe Perches $var2 =~ s/\s//g; 5231ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 5232ea4acbb1SJoe Perches } 5233e2826fd0SJoe Perches } 5234e2826fd0SJoe Perches 523563b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 5236a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 5237a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 52385b57980dSJoe Perches $perl_version_ok && defined($stat) && 523963b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 524063b7c73eSJoe Perches my $if_stat = $1; 524163b7c73eSJoe Perches my $test = substr($2, 1, -1); 524263b7c73eSJoe Perches my $herectx; 524363b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 524463b7c73eSJoe Perches my $match = $1; 524563b7c73eSJoe Perches # avoid parentheses around potential macro args 524663b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 524763b7c73eSJoe Perches if (!defined($herectx)) { 524863b7c73eSJoe Perches $herectx = $here . "\n"; 524963b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 525063b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 525163b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 525263b7c73eSJoe Perches $herectx .= $rl . "\n"; 525363b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 525463b7c73eSJoe Perches } 525563b7c73eSJoe Perches } 525663b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 525763b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 525863b7c73eSJoe Perches } 525963b7c73eSJoe Perches } 526063b7c73eSJoe Perches 52610a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 52624a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 52630a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 52643705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 52653705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 52663705ce5bSJoe Perches $fix) { 5267194f66fcSJoe Perches $fixed[$fixlinenr] =~ 52683705ce5bSJoe Perches s/^(.)\s+/$1/; 52693705ce5bSJoe Perches } 52700a920b5bSAndy Whitcroft } 52710a920b5bSAndy Whitcroft 527240873abaSJoe Perches# check if a statement with a comma should be two statements like: 527340873abaSJoe Perches# foo = bar(), /* comma should be semicolon */ 527440873abaSJoe Perches# bar = baz(); 527540873abaSJoe Perches if (defined($stat) && 527640873abaSJoe Perches $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { 527740873abaSJoe Perches my $cnt = statement_rawlines($stat); 527840873abaSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 527940873abaSJoe Perches WARN("SUSPECT_COMMA_SEMICOLON", 528040873abaSJoe Perches "Possible comma where semicolon could be used\n" . $herectx); 528140873abaSJoe Perches } 528240873abaSJoe Perches 52835b9553abSJoe Perches# return is not a function 5284507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 5285c45dcabdSAndy Whitcroft my $spacing = $1; 52865b57980dSJoe Perches if ($perl_version_ok && 52875b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 52885b9553abSJoe Perches my $value = $1; 52895b9553abSJoe Perches $value = deparenthesize($value); 52905b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 5291000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 5292000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 52935b9553abSJoe Perches } 5294c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 5295000d1cc1SJoe Perches ERROR("SPACING", 5296000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 5297c45dcabdSAndy Whitcroft } 5298c45dcabdSAndy Whitcroft } 5299507e5141SJoe Perches 5300b43ae21bSJoe Perches# unnecessary return in a void function 5301b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 5302b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 5303b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 5304b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 5305b43ae21bSJoe Perches $linenr >= 3 && 5306b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 5307b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 53089819cf25SJoe Perches WARN("RETURN_VOID", 5309b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 53109819cf25SJoe Perches } 53119819cf25SJoe Perches 5312189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 53135b57980dSJoe Perches if ($perl_version_ok && 5314189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 5315189248d8SJoe Perches my $openparens = $1; 5316189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 5317189248d8SJoe Perches my $msg = ""; 5318189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 5319189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 5320189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 5321189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 5322189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 5323189248d8SJoe Perches } 5324189248d8SJoe Perches } 5325189248d8SJoe Perches 5326c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 5327c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 5328c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 5329c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 53305b57980dSJoe Perches if ($perl_version_ok && 5331c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 5332c5595fa2SJoe Perches my $lead = $1; 5333c5595fa2SJoe Perches my $const = $2; 5334c5595fa2SJoe Perches my $comp = $3; 5335c5595fa2SJoe Perches my $to = $4; 5336c5595fa2SJoe Perches my $newcomp = $comp; 5337f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 5338c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 5339c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 5340c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 5341c5595fa2SJoe Perches $fix) { 5342c5595fa2SJoe Perches if ($comp eq "<") { 5343c5595fa2SJoe Perches $newcomp = ">"; 5344c5595fa2SJoe Perches } elsif ($comp eq "<=") { 5345c5595fa2SJoe Perches $newcomp = ">="; 5346c5595fa2SJoe Perches } elsif ($comp eq ">") { 5347c5595fa2SJoe Perches $newcomp = "<"; 5348c5595fa2SJoe Perches } elsif ($comp eq ">=") { 5349c5595fa2SJoe Perches $newcomp = "<="; 5350c5595fa2SJoe Perches } 5351c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 5352c5595fa2SJoe Perches } 5353c5595fa2SJoe Perches } 5354c5595fa2SJoe Perches 5355f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 5356f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 535753a3c448SAndy Whitcroft my $name = $1; 535853a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 5359000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 5360f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 536153a3c448SAndy Whitcroft } 536253a3c448SAndy Whitcroft } 5363c45dcabdSAndy Whitcroft 53640a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 53654a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 53663705ce5bSJoe Perches if (ERROR("SPACING", 53673705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 53683705ce5bSJoe Perches $fix) { 5369194f66fcSJoe Perches $fixed[$fixlinenr] =~ 53703705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 53713705ce5bSJoe Perches } 53720a920b5bSAndy Whitcroft } 53730a920b5bSAndy Whitcroft 5374f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 5375f5fe35ddSAndy Whitcroft# statements after the conditional. 5376170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 53773e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 53783e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 53793e469cdcSAndy Whitcroft if (!defined $stat); 5380170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 5381170d3a22SAndy Whitcroft $remain_next, $off_next); 5382170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 5383170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 5384170d3a22SAndy Whitcroft 5385170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 5386170d3a22SAndy Whitcroft # If the statement carries leading newlines, 5387170d3a22SAndy Whitcroft # then count those as offsets. 5388170d3a22SAndy Whitcroft my ($whitespace) = 5389170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 5390170d3a22SAndy Whitcroft my $offset = 5391170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 5392170d3a22SAndy Whitcroft 5393170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 5394170d3a22SAndy Whitcroft $offset} = 1; 5395170d3a22SAndy Whitcroft } 5396170d3a22SAndy Whitcroft } 5397170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 5398c11230f4SJoe Perches defined($stat) && defined($cond) && 5399170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 5400171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 54018905a67cSAndy Whitcroft 5402b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 540365b64b3bSJoe Perches if (ERROR("ASSIGN_IN_IF", 540465b64b3bSJoe Perches "do not use assignment in if condition\n" . $herecurr) && 540565b64b3bSJoe Perches $fix && $perl_version_ok) { 540665b64b3bSJoe Perches if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { 540765b64b3bSJoe Perches my $space = $1; 540865b64b3bSJoe Perches my $not = $2; 540965b64b3bSJoe Perches my $statement = $3; 541065b64b3bSJoe Perches my $assigned = $4; 541165b64b3bSJoe Perches my $test = $8; 541265b64b3bSJoe Perches my $against = $9; 541365b64b3bSJoe Perches my $brace = $15; 541465b64b3bSJoe Perches fix_delete_line($fixlinenr, $rawline); 541565b64b3bSJoe Perches fix_insert_line($fixlinenr, "$space$statement;"); 541665b64b3bSJoe Perches my $newline = "${space}if ("; 541765b64b3bSJoe Perches $newline .= '!' if defined($not); 541865b64b3bSJoe Perches $newline .= '(' if (defined $not && defined($test) && defined($against)); 541965b64b3bSJoe Perches $newline .= "$assigned"; 542065b64b3bSJoe Perches $newline .= " $test $against" if (defined($test) && defined($against)); 542165b64b3bSJoe Perches $newline .= ')' if (defined $not && defined($test) && defined($against)); 542265b64b3bSJoe Perches $newline .= ')'; 542365b64b3bSJoe Perches $newline .= " {" if (defined($brace)); 542465b64b3bSJoe Perches fix_insert_line($fixlinenr + 1, $newline); 542565b64b3bSJoe Perches } 542665b64b3bSJoe Perches } 54278905a67cSAndy Whitcroft } 54288905a67cSAndy Whitcroft 54298905a67cSAndy Whitcroft # Find out what is on the end of the line after the 54308905a67cSAndy Whitcroft # conditional. 5431773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 54328905a67cSAndy Whitcroft $s =~ s/\n.*//g; 543313214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 543453210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 543553210168SAndy Whitcroft $c !~ /}\s*while\s*/) 5436773647a0SAndy Whitcroft { 5437bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 5438bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 5439bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 544042bdf74cSHidetoshi Seto my $stat_real = ''; 5441bb44ad39SAndy Whitcroft 544242bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 544342bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 5444bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 5445bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 5446bb44ad39SAndy Whitcroft } 5447bb44ad39SAndy Whitcroft 5448000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5449000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 54508905a67cSAndy Whitcroft } 54518905a67cSAndy Whitcroft } 54528905a67cSAndy Whitcroft 545313214adfSAndy Whitcroft# Check for bitwise tests written as boolean 545413214adfSAndy Whitcroft if ($line =~ / 545513214adfSAndy Whitcroft (?: 545613214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 545713214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 545813214adfSAndy Whitcroft (?:\&\&|\|\|) 545913214adfSAndy Whitcroft | 546013214adfSAndy Whitcroft (?:\&\&|\|\|) 546113214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 546213214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 546313214adfSAndy Whitcroft )/x) 546413214adfSAndy Whitcroft { 5465000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 5466000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 546713214adfSAndy Whitcroft } 546813214adfSAndy Whitcroft 54698905a67cSAndy Whitcroft# if and else should not have general statements after it 547013214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 547113214adfSAndy Whitcroft my $s = $1; 547213214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 547313214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 5474000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5475000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 54760a920b5bSAndy Whitcroft } 547713214adfSAndy Whitcroft } 547839667782SAndy Whitcroft# if should not continue a brace 547939667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 5480000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5481048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 548239667782SAndy Whitcroft $herecurr); 548339667782SAndy Whitcroft } 5484a1080bf8SAndy Whitcroft# case and default should not have general statements after them 5485a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 5486a1080bf8SAndy Whitcroft $line !~ /\G(?: 54873fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5488a1080bf8SAndy Whitcroft \s*return\s+ 5489a1080bf8SAndy Whitcroft )/xg) 5490a1080bf8SAndy Whitcroft { 5491000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5492000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 5493a1080bf8SAndy Whitcroft } 54940a920b5bSAndy Whitcroft 54950a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 54960a920b5bSAndy Whitcroft # indent level to be relevant to each other. 54978b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 54980a920b5bSAndy Whitcroft $previndent == $indent) { 54998b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 55008b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 55018b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 55028b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 55038b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 55048b8856f4SJoe Perches my $fixedline = $prevrawline; 55058b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 55068b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 55078b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 55088b8856f4SJoe Perches } 55098b8856f4SJoe Perches $fixedline = $rawline; 55108b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 55118b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 55128b8856f4SJoe Perches } 55130a920b5bSAndy Whitcroft } 55140a920b5bSAndy Whitcroft 55158b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5516c2fdda0dSAndy Whitcroft $previndent == $indent) { 5517c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5518c2fdda0dSAndy Whitcroft 5519c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5520c2fdda0dSAndy Whitcroft # conditional. 5521773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5522c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5523c2fdda0dSAndy Whitcroft 5524c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 55258b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 55268b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 55278b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 55288b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 55298b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 55308b8856f4SJoe Perches my $fixedline = $prevrawline; 55318b8856f4SJoe Perches my $trailing = $rawline; 55328b8856f4SJoe Perches $trailing =~ s/^\+//; 55338b8856f4SJoe Perches $trailing = trim($trailing); 55348b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 55358b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 55368b8856f4SJoe Perches } 5537c2fdda0dSAndy Whitcroft } 5538c2fdda0dSAndy Whitcroft } 5539c2fdda0dSAndy Whitcroft 554095e2c602SJoe Perches#Specific variable tests 5541323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5542323c1260SJoe Perches my $var = $1; 554395e2c602SJoe Perches 554495e2c602SJoe Perches#CamelCase 5545807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5546be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 55474104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values 55484104a206SŁukasz Stelmach $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && 554922735ce8SJoe Perches#Ignore Page<foo> variants 5550807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5551d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB 5552d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 5553d439e6a5SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5554f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5555f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 55567e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 55577e781f67SJoe Perches my $word = $1; 55587e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5559d8b07710SJoe Perches if ($check) { 5560d8b07710SJoe Perches seed_camelcase_includes(); 5561d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5562d8b07710SJoe Perches seed_camelcase_file($realfile); 5563d8b07710SJoe Perches $camelcase_file_seeded = 1; 5564d8b07710SJoe Perches } 5565d8b07710SJoe Perches } 55667e781f67SJoe Perches if (!defined $camelcase{$word}) { 55677e781f67SJoe Perches $camelcase{$word} = 1; 5568be79794bSJoe Perches CHK("CAMELCASE", 55697e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 55707e781f67SJoe Perches } 5571323c1260SJoe Perches } 5572323c1260SJoe Perches } 55733445686aSJoe Perches } 55740a920b5bSAndy Whitcroft 55750a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5576d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5577d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5578d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5579d5e616fcSJoe Perches $fix) { 5580194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5581d5e616fcSJoe Perches } 55820a920b5bSAndy Whitcroft } 55830a920b5bSAndy Whitcroft 55840e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 55850e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5586c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5587e09dec48SAndy Whitcroft my $file = "$1.h"; 5588e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5589e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5590e09dec48SAndy Whitcroft $realfile ne $checkfile && 55917840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5592c45dcabdSAndy Whitcroft { 55930e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 55940e212e0aSFabian Frederick if ($asminclude > 0) { 5595e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5596000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5597000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5598e09dec48SAndy Whitcroft } else { 5599000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5600000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5601e09dec48SAndy Whitcroft } 56020a920b5bSAndy Whitcroft } 56030a920b5bSAndy Whitcroft } 56040e212e0aSFabian Frederick } 56050a920b5bSAndy Whitcroft 5606653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5607653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5608cf655043SAndy Whitcroft# in a known good container 5609b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5610b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5611d8aaf121SAndy Whitcroft my $ln = $linenr; 5612d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5613c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5614c45dcabdSAndy Whitcroft my $ctx = ''; 561508a2843eSJoe Perches my $has_flow_statement = 0; 561608a2843eSJoe Perches my $has_arg_concat = 0; 5617c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5618f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5619f74bd194SAndy Whitcroft $ctx = $dstat; 5620c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5621a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5622c45dcabdSAndy Whitcroft 562308a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 562462e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 562508a2843eSJoe Perches 5626f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5627f59b64bfSJoe Perches my $define_args = $1; 5628f59b64bfSJoe Perches my $define_stmt = $dstat; 5629f59b64bfSJoe Perches my @def_args = (); 5630f59b64bfSJoe Perches 5631f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5632f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5633f59b64bfSJoe Perches $define_args =~ s/\s*//g; 56348c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5635f59b64bfSJoe Perches @def_args = split(",", $define_args); 5636f59b64bfSJoe Perches } 5637f59b64bfSJoe Perches 5638292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5639c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5640c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5641c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5642c45dcabdSAndy Whitcroft 5643c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 56442e44e803SDwaipayan Ray while ($dstat =~ s/\([^\(\)]*\)/1u/ || 56452e44e803SDwaipayan Ray $dstat =~ s/\{[^\{\}]*\}/1u/ || 56462e44e803SDwaipayan Ray $dstat =~ s/.\[[^\[\]]*\]/1u/) 5647bf30d6edSAndy Whitcroft { 5648c45dcabdSAndy Whitcroft } 5649c45dcabdSAndy Whitcroft 5650342d3d2fSAntonio Borneo # Flatten any obvious string concatenation. 565133acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 565233acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5653e45bab8eSAndy Whitcroft { 5654e45bab8eSAndy Whitcroft } 5655e45bab8eSAndy Whitcroft 565642e15293SJoe Perches # Make asm volatile uses seem like a generic function 565742e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 565842e15293SJoe Perches 5659c45dcabdSAndy Whitcroft my $exceptions = qr{ 5660c45dcabdSAndy Whitcroft $Declare| 5661c45dcabdSAndy Whitcroft module_param_named| 5662a0a0a7a9SKees Cook MODULE_PARM_DESC| 5663c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5664c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5665383099fdSAndy Whitcroft __typeof__\(| 566622fd2d3eSStefani Seibold union| 566722fd2d3eSStefani Seibold struct| 5668ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 56696b10df42SVladimir Zapolskiy ^\"|\"$| 56706b10df42SVladimir Zapolskiy ^\[ 5671c45dcabdSAndy Whitcroft }x; 56725eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5673f59b64bfSJoe Perches 5674f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5675f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5676e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5677f59b64bfSJoe Perches 5678f74bd194SAndy Whitcroft if ($dstat ne '' && 5679f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5680f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 56813cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5682356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5683f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5684f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5685e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 568672f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 56872e44e803SDwaipayan Ray $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} 5688f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5689f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5690f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 56914e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5692f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5693c45dcabdSAndy Whitcroft { 5694e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5695e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5696e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5697e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5698f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5699f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5700f74bd194SAndy Whitcroft } else { 5701000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 5702388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5703d8aaf121SAndy Whitcroft } 5704f59b64bfSJoe Perches 5705f59b64bfSJoe Perches } 57065207649bSJoe Perches 57075207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 57085207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 57095207649bSJoe Perches my $first = 1; 57105207649bSJoe Perches $define_stmt = ""; 57115207649bSJoe Perches foreach my $l (@stmt_array) { 57125207649bSJoe Perches $l =~ s/\\$//; 57135207649bSJoe Perches if ($first) { 57145207649bSJoe Perches $define_stmt = $l; 57155207649bSJoe Perches $first = 0; 57165207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 57175207649bSJoe Perches $define_stmt .= substr($l, 1); 57185207649bSJoe Perches } 57195207649bSJoe Perches } 57205207649bSJoe Perches $define_stmt =~ s/$;//g; 57215207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 57225207649bSJoe Perches $define_stmt = trim($define_stmt); 57235207649bSJoe Perches 5724f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 5725f59b64bfSJoe Perches foreach my $arg (@def_args) { 5726f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 57279192d41aSJoe Perches next if ($arg =~ /^type$/i); 57287fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 57296dba824eSBrendan Jackman $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 57307fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 57317fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5732d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 5733f59b64bfSJoe Perches if ($use_cnt > 1) { 5734f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 5735f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5736f59b64bfSJoe Perches } 57379192d41aSJoe Perches# check if any macro arguments may have other precedence issues 57387fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 57399192d41aSJoe Perches ((defined($1) && $1 ne ',') || 57409192d41aSJoe Perches (defined($2) && $2 ne ','))) { 57419192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 57429192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 57439192d41aSJoe Perches } 57440a920b5bSAndy Whitcroft } 57455023d347SJoe Perches 574608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 574708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 574808a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 574908a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 5750e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 575108a2843eSJoe Perches 575208a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 575308a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 575408a2843eSJoe Perches } 575508a2843eSJoe Perches 5756481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 57575023d347SJoe Perches 57585023d347SJoe Perches } else { 57595023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 5760481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 5761481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 57625023d347SJoe Perches $line =~ /^\+.*\\$/) { 57635023d347SJoe Perches WARN("LINE_CONTINUATIONS", 57645023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 57655023d347SJoe Perches } 5766653d4876SAndy Whitcroft } 57670a920b5bSAndy Whitcroft 5768b13edf7fSJoe Perches# do {} while (0) macro tests: 5769b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 5770b13edf7fSJoe Perches# macro should not end with a semicolon 57715b57980dSJoe Perches if ($perl_version_ok && 5772b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 5773b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5774b13edf7fSJoe Perches my $ln = $linenr; 5775b13edf7fSJoe Perches my $cnt = $realcnt; 5776b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 5777b13edf7fSJoe Perches my $ctx = ''; 5778b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 5779b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 5780b13edf7fSJoe Perches $ctx = $dstat; 5781b13edf7fSJoe Perches 5782b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 57831b36b201SJoe Perches $dstat =~ s/$;/ /g; 5784b13edf7fSJoe Perches 5785b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 5786b13edf7fSJoe Perches my $stmts = $2; 5787b13edf7fSJoe Perches my $semis = $3; 5788b13edf7fSJoe Perches 5789b13edf7fSJoe Perches $ctx =~ s/\n*$//; 5790b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 5791e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5792b13edf7fSJoe Perches 5793ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 5794ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 5795b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 5796b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 5797b13edf7fSJoe Perches } 5798b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 5799b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 5800b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5801b13edf7fSJoe Perches } 5802f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5803f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5804f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5805e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5806f5ef95b1SJoe Perches 5807f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5808f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5809b13edf7fSJoe Perches } 5810b13edf7fSJoe Perches } 5811b13edf7fSJoe Perches 5812f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 581313214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 581413214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5815cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 581613214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5817cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5818cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5819aad4f614SJoe Perches my @allowed = (); 5820aad4f614SJoe Perches my $allow = 0; 582113214adfSAndy Whitcroft my $seen = 0; 5822773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5823cf655043SAndy Whitcroft my $ln = $linenr - 1; 582413214adfSAndy Whitcroft for my $chunk (@chunks) { 582513214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 582613214adfSAndy Whitcroft 5827773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5828773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5829773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5830773647a0SAndy Whitcroft 5831aad4f614SJoe Perches $allowed[$allow] = 0; 5832773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5833773647a0SAndy Whitcroft 5834773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5835773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5836773647a0SAndy Whitcroft 5837773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5838cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5839cf655043SAndy Whitcroft 5840773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 584113214adfSAndy Whitcroft 584213214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 584313214adfSAndy Whitcroft 5844aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5845cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5846cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5847aad4f614SJoe Perches $allowed[$allow] = 1; 584813214adfSAndy Whitcroft } 584913214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5850cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5851aad4f614SJoe Perches $allowed[$allow] = 1; 585213214adfSAndy Whitcroft } 5853cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5854cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5855aad4f614SJoe Perches $allowed[$allow] = 1; 585613214adfSAndy Whitcroft } 5857aad4f614SJoe Perches $allow++; 585813214adfSAndy Whitcroft } 5859aad4f614SJoe Perches if ($seen) { 5860aad4f614SJoe Perches my $sum_allowed = 0; 5861aad4f614SJoe Perches foreach (@allowed) { 5862aad4f614SJoe Perches $sum_allowed += $_; 5863aad4f614SJoe Perches } 5864aad4f614SJoe Perches if ($sum_allowed == 0) { 5865000d1cc1SJoe Perches WARN("BRACES", 5866000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5867aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5868aad4f614SJoe Perches $seen != $allow) { 5869aad4f614SJoe Perches CHK("BRACES", 5870aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5871aad4f614SJoe Perches } 587213214adfSAndy Whitcroft } 587313214adfSAndy Whitcroft } 587413214adfSAndy Whitcroft } 5875773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 587613214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5877cf655043SAndy Whitcroft my $allowed = 0; 5878f0a594c1SAndy Whitcroft 5879cf655043SAndy Whitcroft # Check the pre-context. 5880cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5881cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5882cf655043SAndy Whitcroft $allowed = 1; 5883f0a594c1SAndy Whitcroft } 5884773647a0SAndy Whitcroft 5885773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5886773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5887773647a0SAndy Whitcroft 5888cf655043SAndy Whitcroft # Check the condition. 5889cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5890773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5891cf655043SAndy Whitcroft if (defined $cond) { 5892773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5893cf655043SAndy Whitcroft } 5894cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5895cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5896cf655043SAndy Whitcroft $allowed = 1; 5897cf655043SAndy Whitcroft } 5898cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5899cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5900cf655043SAndy Whitcroft $allowed = 1; 5901cf655043SAndy Whitcroft } 5902cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5903cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5904cf655043SAndy Whitcroft $allowed = 1; 5905cf655043SAndy Whitcroft } 5906cf655043SAndy Whitcroft # Check the post-context. 5907cf655043SAndy Whitcroft if (defined $chunks[1]) { 5908cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5909cf655043SAndy Whitcroft if (defined $cond) { 5910773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5911cf655043SAndy Whitcroft } 5912cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5913cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5914cf655043SAndy Whitcroft $allowed = 1; 5915cf655043SAndy Whitcroft } 5916cf655043SAndy Whitcroft } 5917cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 5918f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5919e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5920cf655043SAndy Whitcroft 5921000d1cc1SJoe Perches WARN("BRACES", 5922000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5923f0a594c1SAndy Whitcroft } 5924f0a594c1SAndy Whitcroft } 5925f0a594c1SAndy Whitcroft 5926e4c5babdSJoe Perches# check for single line unbalanced braces 592795330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 592895330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5929e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5930e4c5babdSJoe Perches } 5931e4c5babdSJoe Perches 59320979ae66SJoe Perches# check for unnecessary blank lines around braces 593377b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5934f8e58219SJoe Perches if (CHK("BRACES", 5935f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5936f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5937f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5938f8e58219SJoe Perches } 59390979ae66SJoe Perches } 594077b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5941f8e58219SJoe Perches if (CHK("BRACES", 5942f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5943f8e58219SJoe Perches $fix) { 5944f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5945f8e58219SJoe Perches } 59460979ae66SJoe Perches } 59470979ae66SJoe Perches 59484a0df2efSAndy Whitcroft# no volatiles please 59496c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 59506c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5951000d1cc1SJoe Perches WARN("VOLATILE", 59528c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 59534a0df2efSAndy Whitcroft } 59544a0df2efSAndy Whitcroft 59555e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 59565e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 59575e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 59585e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 595933acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 59605e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 59615e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 59625e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 59635e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 59645e4f6ba5SJoe Perches $fix && 59655e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 59665e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 59675e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 59685e4f6ba5SJoe Perches my $comma_close = ""; 59695e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 59705e4f6ba5SJoe Perches $comma_close = $1; 59715e4f6ba5SJoe Perches } 59725e4f6ba5SJoe Perches 59735e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 59745e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 59755e4f6ba5SJoe Perches my $fixedline = $prevrawline; 59765e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 59775e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 59785e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 59795e4f6ba5SJoe Perches $fixedline = $rawline; 59805e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 59815e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 59825e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 59835e4f6ba5SJoe Perches } 59845e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 59855e4f6ba5SJoe Perches } 59865e4f6ba5SJoe Perches } 59875e4f6ba5SJoe Perches 59885e4f6ba5SJoe Perches# check for missing a space in a string concatenation 59895e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 59905e4f6ba5SJoe Perches WARN('MISSING_SPACE', 59915e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 59925e4f6ba5SJoe Perches } 59935e4f6ba5SJoe Perches 599477cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5995e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5996e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5997e4b7d309SJoe Perches# function declarations 599877cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 599977cb8546SJoe Perches defined($context_function) && 6000e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 6001e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 600277cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 6003e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 600477cb8546SJoe Perches } 600577cb8546SJoe Perches 6006adb2da82SJoe Perches# check for unnecessary function tracing like uses 6007adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like 6008adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions 6009adb2da82SJoe Perches if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) { 6010adb2da82SJoe Perches if (WARN("TRACING_LOGGING", 6011adb2da82SJoe Perches "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) && 6012adb2da82SJoe Perches $fix) { 6013adb2da82SJoe Perches fix_delete_line($fixlinenr, $rawline); 6014adb2da82SJoe Perches } 6015adb2da82SJoe Perches } 6016adb2da82SJoe Perches 60175e4f6ba5SJoe Perches# check for spaces before a quoted newline 60185e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 60195e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 60205e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 60215e4f6ba5SJoe Perches $fix) { 60225e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 60235e4f6ba5SJoe Perches } 60245e4f6ba5SJoe Perches 60255e4f6ba5SJoe Perches } 60265e4f6ba5SJoe Perches 6027f17dba4fSJoe Perches# concatenated string without spaces between elements 602879682c0cSJoe Perches if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) { 602979682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 603079682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 603179682c0cSJoe Perches $fix) { 603279682c0cSJoe Perches while ($line =~ /($String)/g) { 603379682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 603479682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 603579682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 603679682c0cSJoe Perches } 603779682c0cSJoe Perches } 6038f17dba4fSJoe Perches } 6039f17dba4fSJoe Perches 604090ad30e5SJoe Perches# uncoalesced string fragments 604133acb54aSJoe Perches if ($line =~ /$String\s*"/) { 604279682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 604379682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 604479682c0cSJoe Perches $fix) { 604579682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 604679682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 604779682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 604879682c0cSJoe Perches } 604979682c0cSJoe Perches } 605090ad30e5SJoe Perches } 605190ad30e5SJoe Perches 6052522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 6053522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 6054522b837cSAlexey Dobriyan my $show_Z = 1; 60555e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 6056522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 60575e4f6ba5SJoe Perches $string =~ s/%%/__/g; 6058522b837cSAlexey Dobriyan # check for %L 6059522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 60605e4f6ba5SJoe Perches WARN("PRINTF_L", 6061522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 6062522b837cSAlexey Dobriyan $show_L = 0; 60635e4f6ba5SJoe Perches } 6064522b837cSAlexey Dobriyan # check for %Z 6065522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 6066522b837cSAlexey Dobriyan WARN("PRINTF_Z", 6067522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 6068522b837cSAlexey Dobriyan $show_Z = 0; 6069522b837cSAlexey Dobriyan } 6070522b837cSAlexey Dobriyan # check for 0x<decimal> 6071522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 6072522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 60736e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 60746e300757SJoe Perches } 60755e4f6ba5SJoe Perches } 60765e4f6ba5SJoe Perches 60775e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 60783f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 60795e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 60805e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 60815e4f6ba5SJoe Perches } 60825e4f6ba5SJoe Perches 608300df344fSAndy Whitcroft# warn about #if 0 6084c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 608560f89010SPrakruthi Deepak Heragu WARN("IF_0", 608660f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 608760f89010SPrakruthi Deepak Heragu } 608860f89010SPrakruthi Deepak Heragu 608960f89010SPrakruthi Deepak Heragu# warn about #if 1 609060f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 609160f89010SPrakruthi Deepak Heragu WARN("IF_1", 609260f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 60934a0df2efSAndy Whitcroft } 60944a0df2efSAndy Whitcroft 609503df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 609603df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 6097100425deSJoe Perches my $tested = quotemeta($1); 6098100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 6099100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 6100100425deSJoe Perches my $func = $1; 6101100425deSJoe Perches if (WARN('NEEDLESS_IF', 6102100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 6103100425deSJoe Perches $fix) { 6104100425deSJoe Perches my $do_fix = 1; 6105100425deSJoe Perches my $leading_tabs = ""; 6106100425deSJoe Perches my $new_leading_tabs = ""; 6107100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 6108100425deSJoe Perches $leading_tabs = $1; 6109100425deSJoe Perches } else { 6110100425deSJoe Perches $do_fix = 0; 6111100425deSJoe Perches } 6112100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 6113100425deSJoe Perches $new_leading_tabs = $1; 6114100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 6115100425deSJoe Perches $do_fix = 0; 6116100425deSJoe Perches } 6117100425deSJoe Perches } else { 6118100425deSJoe Perches $do_fix = 0; 6119100425deSJoe Perches } 6120100425deSJoe Perches if ($do_fix) { 6121100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6122100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 6123100425deSJoe Perches } 6124100425deSJoe Perches } 61254c432a8fSGreg Kroah-Hartman } 61264c432a8fSGreg Kroah-Hartman } 6127f0a594c1SAndy Whitcroft 6128ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 6129ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 6130ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 6131ebfdc409SJoe Perches (defined $1 || defined $3) && 6132ebfdc409SJoe Perches $linenr > 3) { 6133ebfdc409SJoe Perches my $testval = $2; 6134ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 6135ebfdc409SJoe Perches 6136ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 6137ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 6138ebfdc409SJoe Perches 6139e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 6140e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 6141ebfdc409SJoe Perches WARN("OOM_MESSAGE", 6142ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 6143ebfdc409SJoe Perches } 6144ebfdc409SJoe Perches } 6145ebfdc409SJoe Perches 6146f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 6147dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 6148f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 6149f78d98f6SJoe Perches my $level = $1; 6150f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 6151f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 6152f78d98f6SJoe Perches $fix) { 6153f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 6154f78d98f6SJoe Perches } 6155f78d98f6SJoe Perches } 6156f78d98f6SJoe Perches 615745c55e92SJoe Perches# check for logging continuations 615845c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 615945c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 616045c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 616145c55e92SJoe Perches } 616245c55e92SJoe Perches 616370eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions 616470eb2275SDwaipayan Ray if (defined $stat && 616570eb2275SDwaipayan Ray $line =~ /\b$logFunctions\s*\(/ && 616670eb2275SDwaipayan Ray index($stat, '"') >= 0) { 616770eb2275SDwaipayan Ray my $lc = $stat =~ tr@\n@@; 616870eb2275SDwaipayan Ray $lc = $lc + $linenr; 616970eb2275SDwaipayan Ray my $stat_real = get_stat_real($linenr, $lc); 617070eb2275SDwaipayan Ray pos($stat_real) = index($stat_real, '"'); 617170eb2275SDwaipayan Ray while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { 617270eb2275SDwaipayan Ray my $pspec = $1; 617370eb2275SDwaipayan Ray my $h = $2; 617470eb2275SDwaipayan Ray my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; 617570eb2275SDwaipayan Ray if (WARN("UNNECESSARY_MODIFIER", 617670eb2275SDwaipayan Ray "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && 617770eb2275SDwaipayan Ray $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { 617870eb2275SDwaipayan Ray my $nspec = $pspec; 617970eb2275SDwaipayan Ray $nspec =~ s/h//g; 618070eb2275SDwaipayan Ray $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; 618170eb2275SDwaipayan Ray } 618270eb2275SDwaipayan Ray } 618370eb2275SDwaipayan Ray } 618470eb2275SDwaipayan Ray 6185abb08a53SJoe Perches# check for mask then right shift without a parentheses 61865b57980dSJoe Perches if ($perl_version_ok && 6187abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 6188abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 6189abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 6190abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 6191abb08a53SJoe Perches } 6192abb08a53SJoe Perches 6193b75ac618SJoe Perches# check for pointer comparisons to NULL 61945b57980dSJoe Perches if ($perl_version_ok) { 6195b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 6196b75ac618SJoe Perches my $val = $1; 6197b75ac618SJoe Perches my $equal = "!"; 6198b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 6199b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 6200b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 6201b75ac618SJoe Perches $fix) { 6202b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 6203b75ac618SJoe Perches } 6204b75ac618SJoe Perches } 6205b75ac618SJoe Perches } 6206b75ac618SJoe Perches 62078716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 62088716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 62098716de38SJoe Perches my $attr = $1; 62108716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 62118716de38SJoe Perches my $ptr = $1; 62128716de38SJoe Perches my $var = $2; 62138716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 62148716de38SJoe Perches ERROR("MISPLACED_INIT", 62158716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 62168716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 62178716de38SJoe Perches WARN("MISPLACED_INIT", 62188716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 62198716de38SJoe Perches $fix) { 6220194f66fcSJoe 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; 62218716de38SJoe Perches } 62228716de38SJoe Perches } 62238716de38SJoe Perches } 62248716de38SJoe Perches 6225e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 6226e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 6227e970b884SJoe Perches my $attr = $1; 6228e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 6229e970b884SJoe Perches my $attr_prefix = $1; 6230e970b884SJoe Perches my $attr_type = $2; 6231e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6232e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 6233e970b884SJoe Perches $fix) { 6234194f66fcSJoe Perches $fixed[$fixlinenr] =~ 6235e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 6236e970b884SJoe Perches } 6237e970b884SJoe Perches } 6238e970b884SJoe Perches 6239e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 6240e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 6241e970b884SJoe Perches my $attr = $1; 6242e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6243e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 6244e970b884SJoe Perches $fix) { 6245194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 6246e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 6247e970b884SJoe Perches $lead = rtrim($1); 6248e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 6249e970b884SJoe Perches $lead = "${lead}const "; 6250194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 6251e970b884SJoe Perches } 6252e970b884SJoe Perches } 6253e970b884SJoe Perches 6254c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 6255c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 6256c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 6257c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 6258c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 6259c17893c7SJoe Perches $fix) { 6260c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 6261c17893c7SJoe Perches } 6262c17893c7SJoe Perches } 6263c17893c7SJoe Perches 6264fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 6265fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 6266fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 6267fbdb8138SJoe Perches my $constant_func = $1; 6268fbdb8138SJoe Perches my $func = $constant_func; 6269fbdb8138SJoe Perches $func =~ s/^__constant_//; 6270fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 6271fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 6272fbdb8138SJoe Perches $fix) { 6273194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 6274fbdb8138SJoe Perches } 6275fbdb8138SJoe Perches } 6276fbdb8138SJoe Perches 62771a15a250SPatrick Pannuto# prefer usleep_range over udelay 627837581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 627943c1d77cSJoe Perches my $delay = $1; 62801a15a250SPatrick Pannuto # ignore udelay's < 10, however 628143c1d77cSJoe Perches if (! ($delay < 10) ) { 6282000d1cc1SJoe Perches CHK("USLEEP_RANGE", 6283458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 628443c1d77cSJoe Perches } 628543c1d77cSJoe Perches if ($delay > 2000) { 628643c1d77cSJoe Perches WARN("LONG_UDELAY", 628743c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 62881a15a250SPatrick Pannuto } 62891a15a250SPatrick Pannuto } 62901a15a250SPatrick Pannuto 629109ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 629209ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 629309ef8725SPatrick Pannuto if ($1 < 20) { 6294000d1cc1SJoe Perches WARN("MSLEEP", 6295458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 629609ef8725SPatrick Pannuto } 629709ef8725SPatrick Pannuto } 629809ef8725SPatrick Pannuto 629936ec1939SJoe Perches# check for comparisons of jiffies 630036ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 630136ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 630236ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 630336ec1939SJoe Perches } 630436ec1939SJoe Perches 63059d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 63069d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 63079d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 63089d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 63099d7a34a5SJoe Perches } 63109d7a34a5SJoe Perches 631100df344fSAndy Whitcroft# warn about #ifdefs in C files 6312c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 631300df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 631400df344fSAndy Whitcroft# print "$herecurr"; 631500df344fSAndy Whitcroft# $clean = 0; 631600df344fSAndy Whitcroft# } 631700df344fSAndy Whitcroft 631822f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 6319c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 63203705ce5bSJoe Perches if (ERROR("SPACING", 63213705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 63223705ce5bSJoe Perches $fix) { 6323194f66fcSJoe Perches $fixed[$fixlinenr] =~ 63243705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 63253705ce5bSJoe Perches } 63263705ce5bSJoe Perches 632722f2a2efSAndy Whitcroft } 632822f2a2efSAndy Whitcroft 63294a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 6330171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 6331171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 63324a0df2efSAndy Whitcroft my $which = $1; 63334a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6334000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 6335000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 63364a0df2efSAndy Whitcroft } 63374a0df2efSAndy Whitcroft } 63384a0df2efSAndy Whitcroft# check for memory barriers without a comment. 6339402c2553SMichael S. Tsirkin 6340402c2553SMichael S. Tsirkin my $barriers = qr{ 6341402c2553SMichael S. Tsirkin mb| 6342402c2553SMichael S. Tsirkin rmb| 6343ad83ec6cSWill Deacon wmb 6344402c2553SMichael S. Tsirkin }x; 6345402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 6346402c2553SMichael S. Tsirkin mb__before_atomic| 6347402c2553SMichael S. Tsirkin mb__after_atomic| 6348402c2553SMichael S. Tsirkin store_release| 6349402c2553SMichael S. Tsirkin load_acquire| 6350402c2553SMichael S. Tsirkin store_mb| 6351402c2553SMichael S. Tsirkin (?:$barriers) 6352402c2553SMichael S. Tsirkin }x; 6353402c2553SMichael S. Tsirkin my $all_barriers = qr{ 6354402c2553SMichael S. Tsirkin (?:$barriers)| 635543e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 635643e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 6357402c2553SMichael S. Tsirkin }x; 6358402c2553SMichael S. Tsirkin 6359402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 63604a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 6361c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 6362000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 63634a0df2efSAndy Whitcroft } 63644a0df2efSAndy Whitcroft } 63653ad81779SPaul E. McKenney 6366f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 6367f4073b0fSMichael S. Tsirkin 6368f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 6369f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 6370f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 6371f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 6372f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 6373f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 6374f4073b0fSMichael S. Tsirkin } 6375f4073b0fSMichael S. Tsirkin 6376cb426e99SJoe Perches# check for waitqueue_active without a comment. 6377cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 6378cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 6379cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 6380cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 6381cb426e99SJoe Perches } 6382cb426e99SJoe Perches } 63833ad81779SPaul E. McKenney 63845099a722SMarco Elver# check for data_race without a comment. 63855099a722SMarco Elver if ($line =~ /\bdata_race\s*\(/) { 63865099a722SMarco Elver if (!ctx_has_comment($first_line, $linenr)) { 63875099a722SMarco Elver WARN("DATA_RACE", 63885099a722SMarco Elver "data_race without comment\n" . $herecurr); 63895099a722SMarco Elver } 63905099a722SMarco Elver } 63915099a722SMarco Elver 63924a0df2efSAndy Whitcroft# check of hardware specific defines 6393c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 6394000d1cc1SJoe Perches CHK("ARCH_DEFINES", 6395000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 63960a920b5bSAndy Whitcroft } 6397653d4876SAndy Whitcroft 6398596ed45bSJoe Perches# check that the storage class is not after a type 6399596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 6400000d1cc1SJoe Perches WARN("STORAGE_CLASS", 6401596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 6402596ed45bSJoe Perches } 6403596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 6404596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 6405596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 6406596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 6407596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 6408596ed45bSJoe Perches WARN("STORAGE_CLASS", 6409596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 6410d4977c78STobias Klauser } 6411d4977c78STobias Klauser 6412de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 6413de7d4f0eSAndy Whitcroft# storage class and type. 64149c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 64159c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 6416000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 6417000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 6418de7d4f0eSAndy Whitcroft } 6419de7d4f0eSAndy Whitcroft 64208905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 64212b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 64222b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 6423d5e616fcSJoe Perches if (WARN("INLINE", 6424d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 6425d5e616fcSJoe Perches $fix) { 6426194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 6427d5e616fcSJoe Perches 6428d5e616fcSJoe Perches } 64298905a67cSAndy Whitcroft } 64308905a67cSAndy Whitcroft 64317ebe1d17SDwaipayan Ray# Check for compiler attributes 64322b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 64337ebe1d17SDwaipayan Ray $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { 64347ebe1d17SDwaipayan Ray my $attr = $1; 64357ebe1d17SDwaipayan Ray $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; 64367ebe1d17SDwaipayan Ray 64377ebe1d17SDwaipayan Ray my %attr_list = ( 64380830aab0SJoe Perches "alias" => "__alias", 64397ebe1d17SDwaipayan Ray "aligned" => "__aligned", 64407ebe1d17SDwaipayan Ray "always_inline" => "__always_inline", 64417ebe1d17SDwaipayan Ray "assume_aligned" => "__assume_aligned", 64427ebe1d17SDwaipayan Ray "cold" => "__cold", 64437ebe1d17SDwaipayan Ray "const" => "__attribute_const__", 64447ebe1d17SDwaipayan Ray "copy" => "__copy", 64457ebe1d17SDwaipayan Ray "designated_init" => "__designated_init", 64467ebe1d17SDwaipayan Ray "externally_visible" => "__visible", 64477ebe1d17SDwaipayan Ray "format" => "printf|scanf", 64487ebe1d17SDwaipayan Ray "gnu_inline" => "__gnu_inline", 64497ebe1d17SDwaipayan Ray "malloc" => "__malloc", 64507ebe1d17SDwaipayan Ray "mode" => "__mode", 64517ebe1d17SDwaipayan Ray "no_caller_saved_registers" => "__no_caller_saved_registers", 64527ebe1d17SDwaipayan Ray "noclone" => "__noclone", 64537ebe1d17SDwaipayan Ray "noinline" => "noinline", 64547ebe1d17SDwaipayan Ray "nonstring" => "__nonstring", 64557ebe1d17SDwaipayan Ray "noreturn" => "__noreturn", 64567ebe1d17SDwaipayan Ray "packed" => "__packed", 64577ebe1d17SDwaipayan Ray "pure" => "__pure", 6458339f29d9SJoe Perches "section" => "__section", 64590830aab0SJoe Perches "used" => "__used", 64600830aab0SJoe Perches "weak" => "__weak" 64617ebe1d17SDwaipayan Ray ); 64627ebe1d17SDwaipayan Ray 64637ebe1d17SDwaipayan Ray while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { 6464339f29d9SJoe Perches my $orig_attr = $1; 64657ebe1d17SDwaipayan Ray my $params = ''; 64667ebe1d17SDwaipayan Ray $params = $2 if defined($2); 6467339f29d9SJoe Perches my $curr_attr = $orig_attr; 64687ebe1d17SDwaipayan Ray $curr_attr =~ s/^[\s_]+|[\s_]+$//g; 64697ebe1d17SDwaipayan Ray if (exists($attr_list{$curr_attr})) { 6470339f29d9SJoe Perches my $new = $attr_list{$curr_attr}; 64717ebe1d17SDwaipayan Ray if ($curr_attr eq "format" && $params) { 64727ebe1d17SDwaipayan Ray $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; 6473339f29d9SJoe Perches $new = "__$1\($2"; 64747ebe1d17SDwaipayan Ray } else { 6475339f29d9SJoe Perches $new = "$new$params"; 64767ebe1d17SDwaipayan Ray } 64777ebe1d17SDwaipayan Ray if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 6478339f29d9SJoe Perches "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && 64797ebe1d17SDwaipayan Ray $fix) { 6480339f29d9SJoe Perches my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; 6481339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/$remove//; 6482339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; 6483339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; 6484339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; 64857ebe1d17SDwaipayan Ray } 648639b7e287SJoe Perches } 6487462811d9SJoe Perches } 6488462811d9SJoe Perches 64897ebe1d17SDwaipayan Ray # Check for __attribute__ unused, prefer __always_unused or __maybe_unused 64907ebe1d17SDwaipayan Ray if ($attr =~ /^_*unused/) { 64917ebe1d17SDwaipayan Ray WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 64927ebe1d17SDwaipayan Ray "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); 6493d5e616fcSJoe Perches } 64946061d949SJoe Perches } 64956061d949SJoe Perches 6496619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 64975b57980dSJoe Perches if ($perl_version_ok && 6498619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 6499619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 6500619a908aSJoe Perches $line =~ /\b__weak\b/)) { 6501619a908aSJoe Perches ERROR("WEAK_DECLARATION", 6502619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 6503619a908aSJoe Perches } 6504619a908aSJoe Perches 6505fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 6506e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6507fd39f904STomas Winkler $realfile !~ m@\btools/@ && 6508e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 6509e6176fa4SJoe Perches my $type = $1; 6510e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 6511e6176fa4SJoe Perches $type = $1; 6512e6176fa4SJoe Perches my $kernel_type = 'u'; 6513e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6514e6176fa4SJoe Perches $type =~ /(\d+)/; 6515e6176fa4SJoe Perches $kernel_type .= $1; 6516e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6517e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6518e6176fa4SJoe Perches $fix) { 6519e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6520e6176fa4SJoe Perches } 6521e6176fa4SJoe Perches } 6522e6176fa4SJoe Perches } 6523e6176fa4SJoe Perches 6524938224b5SJoe Perches# check for cast of C90 native int or longer types constants 6525938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6526938224b5SJoe Perches my $cast = $1; 6527938224b5SJoe Perches my $const = $2; 6528938224b5SJoe Perches my $suffix = ""; 6529938224b5SJoe Perches my $newconst = $const; 6530938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 6531938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6532938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6533938224b5SJoe Perches $suffix .= 'LL'; 6534938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 6535938224b5SJoe Perches $suffix .= 'L'; 6536938224b5SJoe Perches } 65370972b8bfSJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 65380972b8bfSJoe Perches "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) && 65390972b8bfSJoe Perches $fix) { 6540938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6541938224b5SJoe Perches } 6542938224b5SJoe Perches } 6543938224b5SJoe Perches 65448f53a9b8SJoe Perches# check for sizeof(&) 65458f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6546000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 6547000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 65488f53a9b8SJoe Perches } 65498f53a9b8SJoe Perches 655066c80b60SJoe Perches# check for sizeof without parenthesis 655166c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 6552d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 6553d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6554d5e616fcSJoe Perches $fix) { 6555194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6556d5e616fcSJoe Perches } 655766c80b60SJoe Perches } 655866c80b60SJoe Perches 655988982feaSJoe Perches# check for struct spinlock declarations 656088982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 656188982feaSJoe Perches WARN("USE_SPINLOCK_T", 656288982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 656388982feaSJoe Perches } 656488982feaSJoe Perches 6565a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 656606668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6567a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 6568caac1d5fSHeba Aamer $fmt =~ s/%%//g; 6569caac1d5fSHeba Aamer if ($fmt !~ /%/) { 6570d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 6571d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6572d5e616fcSJoe Perches $fix) { 6573194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6574d5e616fcSJoe Perches } 6575a6962d72SJoe Perches } 6576a6962d72SJoe Perches } 6577a6962d72SJoe Perches 65780b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 65795b57980dSJoe Perches if ($perl_version_ok && 65800b523769SJoe Perches defined $stat && 65810b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 65820b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6583e3c6bc95STobin C. Harding my $stat_real; 6584e3c6bc95STobin C. Harding 65850b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 65860b523769SJoe Perches $lc = $lc + $linenr; 65870b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6588ffe07513SJoe Perches my $specifier; 6589ffe07513SJoe Perches my $extension; 65903bd32d6aSSakari Ailus my $qualifier; 6591ffe07513SJoe Perches my $bad_specifier = ""; 65920b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 65930b523769SJoe Perches $fmt =~ s/%%//g; 6594e3c6bc95STobin C. Harding 65953bd32d6aSSakari Ailus while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 6596e3c6bc95STobin C. Harding $specifier = $1; 6597e3c6bc95STobin C. Harding $extension = $2; 65983bd32d6aSSakari Ailus $qualifier = $3; 6599361b0d28SLinus Torvalds if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 66003bd32d6aSSakari Ailus ($extension eq "f" && 66013bd32d6aSSakari Ailus defined $qualifier && $qualifier !~ /^w/)) { 6602e3c6bc95STobin C. Harding $bad_specifier = $specifier; 66030b523769SJoe Perches last; 66040b523769SJoe Perches } 6605e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6606e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6607e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 66080b523769SJoe Perches } 6609e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6610e3c6bc95STobin 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"); 6611e3c6bc95STobin C. Harding } 6612e3c6bc95STobin C. Harding } 6613e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 66142a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 66151df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 66161df7338aSSergey Senozhatsky my $use = ""; 6617e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 66181df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6619e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 66201df7338aSSergey Senozhatsky } 66212a9f9d85STobin C. Harding 66220b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 6623e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6624e3c6bc95STobin C. Harding } 66250b523769SJoe Perches } 66260b523769SJoe Perches } 66270b523769SJoe Perches 6628554e165cSAndy Whitcroft# Check for misused memsets 66295b57980dSJoe Perches if ($perl_version_ok && 6630d1fe9c09SJoe Perches defined $stat && 66319e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6632554e165cSAndy Whitcroft 6633d7c76ba7SJoe Perches my $ms_addr = $2; 6634d1fe9c09SJoe Perches my $ms_val = $7; 6635d1fe9c09SJoe Perches my $ms_size = $12; 6636d7c76ba7SJoe Perches 6637554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6638554e165cSAndy Whitcroft ERROR("MEMSET", 6639d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6640554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6641554e165cSAndy Whitcroft WARN("MEMSET", 6642d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6643d7c76ba7SJoe Perches } 6644d7c76ba7SJoe Perches } 6645d7c76ba7SJoe Perches 664698a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 66475b57980dSJoe Perches# if ($perl_version_ok && 6648f333195dSJoe Perches# defined $stat && 6649f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6650f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6651f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6652f333195dSJoe Perches# $fix) { 6653f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6654f333195dSJoe Perches# } 6655f333195dSJoe Perches# } 665698a9bba5SJoe Perches 6657b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 66585b57980dSJoe Perches# if ($perl_version_ok && 6659f333195dSJoe Perches# defined $stat && 6660f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6661f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6662f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6663f333195dSJoe Perches# } 6664b6117d17SMateusz Kulikowski 66658617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 66668617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 66675b57980dSJoe Perches# if ($perl_version_ok && 6668f333195dSJoe Perches# defined $stat && 6669f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6670f333195dSJoe Perches# 6671f333195dSJoe Perches# my $ms_val = $7; 6672f333195dSJoe Perches# 6673f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6674f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6675f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6676f333195dSJoe Perches# $fix) { 6677f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6678f333195dSJoe Perches# } 6679f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6680f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6681f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6682f333195dSJoe Perches# $fix) { 6683f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6684f333195dSJoe Perches# } 6685f333195dSJoe Perches# } 6686f333195dSJoe Perches# } 66878617cd09SMateusz Kulikowski 66885dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy 66895dbdb2d8SJoe Perches if ($line =~ /\bstrlcpy\s*\(/) { 66905dbdb2d8SJoe Perches WARN("STRLCPY", 66915dbdb2d8SJoe Perches "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr); 66925dbdb2d8SJoe Perches } 66935dbdb2d8SJoe Perches 6694d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 66955b57980dSJoe Perches if ($perl_version_ok && 6696d1fe9c09SJoe Perches defined $stat && 6697d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6698d1fe9c09SJoe Perches if (defined $2 || defined $7) { 6699d7c76ba7SJoe Perches my $call = $1; 6700d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 6701d7c76ba7SJoe Perches my $arg1 = $3; 6702d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 6703d1fe9c09SJoe Perches my $arg2 = $8; 6704d7c76ba7SJoe Perches my $cast; 6705d7c76ba7SJoe Perches 6706d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 6707d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 6708d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 6709d7c76ba7SJoe Perches $cast = $cast1; 6710d7c76ba7SJoe Perches } else { 6711d7c76ba7SJoe Perches $cast = $cast2; 6712d7c76ba7SJoe Perches } 6713d7c76ba7SJoe Perches WARN("MINMAX", 6714d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 6715554e165cSAndy Whitcroft } 6716554e165cSAndy Whitcroft } 6717554e165cSAndy Whitcroft 67184a273195SJoe Perches# check usleep_range arguments 67195b57980dSJoe Perches if ($perl_version_ok && 67204a273195SJoe Perches defined $stat && 67214a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 67224a273195SJoe Perches my $min = $1; 67234a273195SJoe Perches my $max = $7; 67244a273195SJoe Perches if ($min eq $max) { 67254a273195SJoe Perches WARN("USLEEP_RANGE", 6726458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 67274a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 67284a273195SJoe Perches $min > $max) { 67294a273195SJoe Perches WARN("USLEEP_RANGE", 6730458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 67314a273195SJoe Perches } 67324a273195SJoe Perches } 67334a273195SJoe Perches 6734823b794cSJoe Perches# check for naked sscanf 67355b57980dSJoe Perches if ($perl_version_ok && 6736823b794cSJoe Perches defined $stat && 67376c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 6738823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6739823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 6740823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6741823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 6742823b794cSJoe Perches $lc = $lc + $linenr; 67432a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6744823b794cSJoe Perches WARN("NAKED_SSCANF", 6745823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6746823b794cSJoe Perches } 6747823b794cSJoe Perches 6748afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 67495b57980dSJoe Perches if ($perl_version_ok && 6750afc819abSJoe Perches defined $stat && 6751afc819abSJoe Perches $line =~ /\bsscanf\b/) { 6752afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 6753afc819abSJoe Perches $lc = $lc + $linenr; 67542a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6755afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6756afc819abSJoe Perches my $format = $6; 6757afc819abSJoe Perches my $count = $format =~ tr@%@%@; 6758afc819abSJoe Perches if ($count == 1 && 6759afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 6760afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 6761afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 6762afc819abSJoe Perches } 6763afc819abSJoe Perches } 6764afc819abSJoe Perches } 6765afc819abSJoe Perches 676670dc8a48SJoe Perches# check for new externs in .h files. 676770dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 676870dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 6769d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 677070dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 677170dc8a48SJoe Perches $fix) { 6772194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 677370dc8a48SJoe Perches } 677470dc8a48SJoe Perches } 677570dc8a48SJoe Perches 6776de7d4f0eSAndy Whitcroft# check for new externs in .c files. 6777171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 6778c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 6779171ae1a4SAndy Whitcroft { 6780c45dcabdSAndy Whitcroft my $function_name = $1; 6781c45dcabdSAndy Whitcroft my $paren_space = $2; 6782171ae1a4SAndy Whitcroft 6783171ae1a4SAndy Whitcroft my $s = $stat; 6784171ae1a4SAndy Whitcroft if (defined $cond) { 6785171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 6786171ae1a4SAndy Whitcroft } 6787d8b44b58SKees Cook if ($s =~ /^\s*;/) 6788c45dcabdSAndy Whitcroft { 6789000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6790000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6791de7d4f0eSAndy Whitcroft } 6792de7d4f0eSAndy Whitcroft 6793171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 6794000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 6795000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 6796171ae1a4SAndy Whitcroft } 67979c9ba34eSAndy Whitcroft 67989c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 67999c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 68009c9ba34eSAndy Whitcroft { 6801000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6802000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6803171ae1a4SAndy Whitcroft } 6804171ae1a4SAndy Whitcroft 6805a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 6806a0ad7596SJoe Perches if (defined $stat && 6807d8b44b58SKees Cook $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 6808d8b44b58SKees Cook $1 ne "void") { 6809d8b44b58SKees Cook my $args = trim($1); 6810ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 6811ca0d8929SJoe Perches my $arg = trim($1); 6812d8b44b58SKees Cook if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 6813ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 6814ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 6815ca0d8929SJoe Perches } 6816ca0d8929SJoe Perches } 6817ca0d8929SJoe Perches } 6818ca0d8929SJoe Perches 6819a0ad7596SJoe Perches# check for function definitions 68205b57980dSJoe Perches if ($perl_version_ok && 6821a0ad7596SJoe Perches defined $stat && 6822a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 6823a0ad7596SJoe Perches $context_function = $1; 6824a0ad7596SJoe Perches 6825a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 6826a0ad7596SJoe Perches my $ok = 0; 6827a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 6828a0ad7596SJoe Perches my $herectx = $here . "\n"; 6829a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6830a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 6831a0ad7596SJoe Perches $herectx .= $rl . "\n"; 6832a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 6833a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 6834a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 6835a0ad7596SJoe Perches } 6836a0ad7596SJoe Perches if (!$ok) { 6837a0ad7596SJoe Perches ERROR("OPEN_BRACE", 6838a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 6839a0ad7596SJoe Perches } 6840a0ad7596SJoe Perches } 6841a0ad7596SJoe Perches 6842de7d4f0eSAndy Whitcroft# checks for new __setup's 6843de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 6844de7d4f0eSAndy Whitcroft my $name = $1; 6845de7d4f0eSAndy Whitcroft 6846de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 6847000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 68482581ac7cSTim Froidcoeur "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); 6849de7d4f0eSAndy Whitcroft } 6850653d4876SAndy Whitcroft } 68519c0ca6f9SAndy Whitcroft 6852e29a70f1SJoe Perches# check for pointless casting of alloc functions 6853e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 6854000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 6855000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 68569c0ca6f9SAndy Whitcroft } 685713214adfSAndy Whitcroft 6858a640d25cSJoe Perches# alloc style 6859a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 68605b57980dSJoe Perches if ($perl_version_ok && 6861e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 6862a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 6863a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 6864a640d25cSJoe Perches } 6865a640d25cSJoe Perches 686660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 68675b57980dSJoe Perches if ($perl_version_ok && 68681b4a2ed4SJoe Perches defined $stat && 68691b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 687060a55369SJoe Perches my $oldfunc = $3; 687160a55369SJoe Perches my $a1 = $4; 687260a55369SJoe Perches my $a2 = $10; 687360a55369SJoe Perches my $newfunc = "kmalloc_array"; 687460a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 687560a55369SJoe Perches my $r1 = $a1; 687660a55369SJoe Perches my $r2 = $a2; 687760a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 687860a55369SJoe Perches $r1 = $a2; 687960a55369SJoe Perches $r2 = $a1; 688060a55369SJoe Perches } 6881e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 6882e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 68831b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 6884e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6885e3d95a2aSTobin C. Harding 6886e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 68871b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 68881b4a2ed4SJoe Perches $cnt == 1 && 6889e367455aSJoe Perches $fix) { 6890194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; 689160a55369SJoe Perches } 689260a55369SJoe Perches } 689360a55369SJoe Perches } 689460a55369SJoe Perches 6895972fdea2SJoe Perches# check for krealloc arg reuse 68965b57980dSJoe Perches if ($perl_version_ok && 68974cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 68984cab63ceSJoe Perches $1 eq $3) { 6899972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 6900972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 6901972fdea2SJoe Perches } 6902972fdea2SJoe Perches 69035ce59ae0SJoe Perches# check for alloc argument mismatch 69045ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 69055ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 69065ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 69075ce59ae0SJoe Perches } 69085ce59ae0SJoe Perches 6909caf2a54fSJoe Perches# check for multiple semicolons 6910caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 6911d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 6912d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 6913d5e616fcSJoe Perches $fix) { 6914194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 6915d5e616fcSJoe Perches } 6916d1e2ad07SJoe Perches } 6917d1e2ad07SJoe Perches 6918cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 6919cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 6920cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 69210ab90191SJoe Perches my $ull = ""; 69220ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 69230ab90191SJoe Perches if (CHK("BIT_MACRO", 69240ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 69250ab90191SJoe Perches $fix) { 69260ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 69270ab90191SJoe Perches } 69280ab90191SJoe Perches } 69290ab90191SJoe Perches 693050161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) 69313e89ad85SJerome Forissier if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { 693250161266SJoe Perches WARN("IS_ENABLED_CONFIG", 69333e89ad85SJerome Forissier "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); 693450161266SJoe Perches } 693550161266SJoe Perches 69362d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 69373e89ad85SJerome 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*$/) { 69382d632745SJoe Perches my $config = $1; 69392d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 69403e89ad85SJerome Forissier "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && 69412d632745SJoe Perches $fix) { 69422d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 69432d632745SJoe Perches } 69442d632745SJoe Perches } 69452d632745SJoe Perches 6946f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 6947f36d3eb8SJoe Perches my @fallthroughs = ( 6948f36d3eb8SJoe Perches 'fallthrough', 6949f36d3eb8SJoe Perches '@fallthrough@', 6950f36d3eb8SJoe Perches 'lint -fallthrough[ \t]*', 6951f36d3eb8SJoe Perches 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 6952f36d3eb8SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 6953f36d3eb8SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 6954f36d3eb8SJoe Perches 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 6955f36d3eb8SJoe Perches ); 6956f36d3eb8SJoe Perches if ($raw_comment ne '') { 6957f36d3eb8SJoe Perches foreach my $ft (@fallthroughs) { 6958f36d3eb8SJoe Perches if ($raw_comment =~ /$ft/) { 6959f36d3eb8SJoe Perches my $msg_level = \&WARN; 6960f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 6961f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 6962f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 6963f36d3eb8SJoe Perches last; 6964f36d3eb8SJoe Perches } 6965f36d3eb8SJoe Perches } 6966f36d3eb8SJoe Perches } 6967f36d3eb8SJoe Perches 6968d1e2ad07SJoe Perches# check for switch/default statements without a break; 69695b57980dSJoe Perches if ($perl_version_ok && 6970d1e2ad07SJoe Perches defined $stat && 6971d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6972d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6973e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6974e3d95a2aSTobin C. Harding 6975d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6976d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6977caf2a54fSJoe Perches } 6978caf2a54fSJoe Perches 697913214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6980d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6981d5e616fcSJoe Perches if (WARN("USE_FUNC", 6982d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6983d5e616fcSJoe Perches $fix) { 6984194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6985d5e616fcSJoe Perches } 698613214adfSAndy Whitcroft } 6987773647a0SAndy Whitcroft 698862ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 698962ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 699062ec818fSJoe Perches ERROR("DATE_TIME", 699162ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 699262ec818fSJoe Perches } 699362ec818fSJoe Perches 69942c92488aSJoe Perches# check for use of yield() 69952c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 69962c92488aSJoe Perches WARN("YIELD", 69972c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 69982c92488aSJoe Perches } 69992c92488aSJoe Perches 7000179f8f40SJoe Perches# check for comparisons against true and false 7001179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 7002179f8f40SJoe Perches my $lead = $1; 7003179f8f40SJoe Perches my $arg = $2; 7004179f8f40SJoe Perches my $test = $3; 7005179f8f40SJoe Perches my $otype = $4; 7006179f8f40SJoe Perches my $trail = $5; 7007179f8f40SJoe Perches my $op = "!"; 7008179f8f40SJoe Perches 7009179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 7010179f8f40SJoe Perches 7011179f8f40SJoe Perches my $type = lc($otype); 7012179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 7013179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 7014179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 7015179f8f40SJoe Perches $op = ""; 7016179f8f40SJoe Perches } 7017179f8f40SJoe Perches 7018179f8f40SJoe Perches CHK("BOOL_COMPARISON", 7019179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 7020179f8f40SJoe Perches 7021179f8f40SJoe Perches## maybe suggesting a correct construct would better 7022179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 7023179f8f40SJoe Perches 7024179f8f40SJoe Perches } 7025179f8f40SJoe Perches } 7026179f8f40SJoe Perches 70274882720bSThomas Gleixner# check for semaphores initialized locked 70284882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 7029000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 7030000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 7031773647a0SAndy Whitcroft } 70326712d858SJoe Perches 703367d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 703467d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 7035000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 703667d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 7037773647a0SAndy Whitcroft } 70386712d858SJoe Perches 7039ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 7040f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 7041000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 7042ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 7043f3db6639SMichael Ellerman } 70446712d858SJoe Perches 70453d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 70463d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 70473d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 70483d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 70493d709ab5SPaul E. McKenney } 70503d709ab5SPaul E. McKenney 70519189c7e7SJoe Perches# check for deprecated apis 70529189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 70539189c7e7SJoe Perches my $deprecated_api = $1; 70549189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 70559189c7e7SJoe Perches WARN("DEPRECATED_API", 70569189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 70579189c7e7SJoe Perches } 70589189c7e7SJoe Perches 70590f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 7060d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 7061ced69da1SQuentin Monnet if (defined($const_structs) && 7062ced69da1SQuentin Monnet $line !~ /\bconst\b/ && 7063d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 7064000d1cc1SJoe Perches WARN("CONST_STRUCT", 7065d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 70662b6db5cbSAndy Whitcroft } 7067773647a0SAndy Whitcroft 7068773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 7069773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 707035cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS 7071773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 7072c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 7073c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 7074171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 7075171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 707635cdcbfcSPeng Wang $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ && 707735cdcbfcSPeng Wang $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/) 7078773647a0SAndy Whitcroft { 7079000d1cc1SJoe Perches WARN("NR_CPUS", 7080000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 7081773647a0SAndy Whitcroft } 70829c9ba34eSAndy Whitcroft 708352ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 708452ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 708552ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 708652ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 708752ea8506SJoe Perches } 708852ea8506SJoe Perches 7089acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 70905b57980dSJoe Perches if ($perl_version_ok && 7091acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 7092acd9362cSJoe Perches WARN("LIKELY_MISUSE", 7093acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 7094acd9362cSJoe Perches } 7095acd9362cSJoe Perches 7096de3f186fSDenis Efremov# nested likely/unlikely calls 7097de3f186fSDenis Efremov if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 7098de3f186fSDenis Efremov WARN("LIKELY_MISUSE", 7099de3f186fSDenis Efremov "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 7100de3f186fSDenis Efremov } 7101de3f186fSDenis Efremov 7102691d77b6SAndy Whitcroft# whine mightly about in_atomic 7103691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 7104691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 7105000d1cc1SJoe Perches ERROR("IN_ATOMIC", 7106000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 7107f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 7108000d1cc1SJoe Perches WARN("IN_ATOMIC", 7109000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 7110691d77b6SAndy Whitcroft } 7111691d77b6SAndy Whitcroft } 71121704f47bSPeter Zijlstra 71131704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 71141704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 71151704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 71161704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 71171704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 71181704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 7119000d1cc1SJoe Perches ERROR("LOCKDEP", 7120000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 71211704f47bSPeter Zijlstra } 71221704f47bSPeter Zijlstra } 712388f8831cSDave Jones 7124b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 7125b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 7126000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 7127000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 712888f8831cSDave Jones } 71292435880fSJoe Perches 713000180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 713100180468SJoe Perches# and whether or not function naming is typical and if 713200180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 71335b57980dSJoe Perches if ($perl_version_ok && 713400180468SJoe Perches defined $stat && 713500180468SJoe 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*\)/) { 713600180468SJoe Perches my $var = $1; 713700180468SJoe Perches my $perms = $2; 713800180468SJoe Perches my $show = $3; 713900180468SJoe Perches my $store = $4; 714000180468SJoe Perches my $octal_perms = perms_to_octal($perms); 714100180468SJoe Perches if ($show =~ /^${var}_show$/ && 714200180468SJoe Perches $store =~ /^${var}_store$/ && 714300180468SJoe Perches $octal_perms eq "0644") { 714400180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 714500180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 714600180468SJoe Perches $fix) { 714700180468SJoe 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})/; 714800180468SJoe Perches } 714900180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 715000180468SJoe Perches $store =~ /^NULL$/ && 715100180468SJoe Perches $octal_perms eq "0444") { 715200180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 715300180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 715400180468SJoe Perches $fix) { 715500180468SJoe 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})/; 715600180468SJoe Perches } 715700180468SJoe Perches } elsif ($show =~ /^NULL$/ && 715800180468SJoe Perches $store =~ /^${var}_store$/ && 715900180468SJoe Perches $octal_perms eq "0200") { 716000180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 716100180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 716200180468SJoe Perches $fix) { 716300180468SJoe 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})/; 716400180468SJoe Perches } 716500180468SJoe Perches } elsif ($octal_perms eq "0644" || 716600180468SJoe Perches $octal_perms eq "0444" || 716700180468SJoe Perches $octal_perms eq "0200") { 716800180468SJoe Perches my $newshow = "$show"; 716900180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 717000180468SJoe Perches my $newstore = $store; 717100180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 717200180468SJoe Perches my $rename = ""; 717300180468SJoe Perches if ($show ne $newshow) { 717400180468SJoe Perches $rename .= " '$show' to '$newshow'"; 717500180468SJoe Perches } 717600180468SJoe Perches if ($store ne $newstore) { 717700180468SJoe Perches $rename .= " '$store' to '$newstore'"; 717800180468SJoe Perches } 717900180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 718000180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 718100180468SJoe Perches } else { 718200180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 718300180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 718400180468SJoe Perches } 718500180468SJoe Perches } 718600180468SJoe Perches 7187515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 7188515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 718973121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 719073121534SJoe Perches# specific definition of not visible in sysfs. 719173121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 719273121534SJoe Perches# use the default permissions 71935b57980dSJoe Perches if ($perl_version_ok && 7194459cf0aeSJoe Perches defined $stat && 7195515a235eSJoe Perches $line =~ /$mode_perms_search/) { 71962435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 71972435880fSJoe Perches my $func = $entry->[0]; 71982435880fSJoe Perches my $arg_pos = $entry->[1]; 71992435880fSJoe Perches 7200459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 7201459cf0aeSJoe Perches $lc = $lc + $linenr; 72022a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 7203459cf0aeSJoe Perches 72042435880fSJoe Perches my $skip_args = ""; 72052435880fSJoe Perches if ($arg_pos > 1) { 72062435880fSJoe Perches $arg_pos--; 72072435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 72082435880fSJoe Perches } 7209f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 7210459cf0aeSJoe Perches if ($stat =~ /$test/) { 72112435880fSJoe Perches my $val = $1; 72122435880fSJoe Perches $val = $6 if ($skip_args ne ""); 721373121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 721473121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 721573121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 72162435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 7217459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 7218f90774e1SJoe Perches } 7219f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 7220c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 7221459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 72222435880fSJoe Perches } 7223459cf0aeSJoe Perches } 7224459cf0aeSJoe Perches } 7225459cf0aeSJoe Perches } 7226459cf0aeSJoe Perches 7227459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 7228bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 722900180468SJoe Perches my $oval = $1; 723000180468SJoe Perches my $octal = perms_to_octal($oval); 7231f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 7232459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 7233f90774e1SJoe Perches $fix) { 723400180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 72352435880fSJoe Perches } 723613214adfSAndy Whitcroft } 72375a6d20ceSBjorn Andersson 72385a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 72395a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 72405a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 72415a6d20ceSBjorn Andersson my $valid_licenses = qr{ 72425a6d20ceSBjorn Andersson GPL| 72435a6d20ceSBjorn Andersson GPL\ v2| 72445a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 72455a6d20ceSBjorn Andersson Dual\ BSD/GPL| 72465a6d20ceSBjorn Andersson Dual\ MIT/GPL| 72475a6d20ceSBjorn Andersson Dual\ MPL/GPL| 72485a6d20ceSBjorn Andersson Proprietary 72495a6d20ceSBjorn Andersson }x; 72505a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 72515a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 72525a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 72535a6d20ceSBjorn Andersson } 72545a6d20ceSBjorn Andersson } 72556a8d76cbSMatteo Croce 72566a8d76cbSMatteo Croce# check for sysctl duplicate constants 72576a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 72586a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 72596a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 72606a8d76cbSMatteo Croce } 7261515a235eSJoe Perches } 726213214adfSAndy Whitcroft 726313214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 726413214adfSAndy Whitcroft # so just keep quiet. 726513214adfSAndy Whitcroft if ($#rawlines == -1) { 726613214adfSAndy Whitcroft exit(0); 72670a920b5bSAndy Whitcroft } 72680a920b5bSAndy Whitcroft 72698905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 72708905a67cSAndy Whitcroft # things that appear to be patches. 72718905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 72728905a67cSAndy Whitcroft exit(0); 72738905a67cSAndy Whitcroft } 72748905a67cSAndy Whitcroft 7275e73d2715SDwaipayan Ray # This is not a patch, and we are in 'no-patch' mode so 72768905a67cSAndy Whitcroft # just keep quiet. 72778905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 72788905a67cSAndy Whitcroft exit(0); 72798905a67cSAndy Whitcroft } 72808905a67cSAndy Whitcroft 7281a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 7282000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 7283000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 72840a920b5bSAndy Whitcroft } 7285cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 7286cd261496SGeert Uytterhoeven if ($signoff == 0) { 7287000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 7288000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 728948ca2d8aSDwaipayan Ray } elsif ($authorsignoff != 1) { 729048ca2d8aSDwaipayan Ray # authorsignoff values: 729148ca2d8aSDwaipayan Ray # 0 -> missing sign off 729248ca2d8aSDwaipayan Ray # 1 -> sign off identical 729348ca2d8aSDwaipayan Ray # 2 -> names and addresses match, comments mismatch 729448ca2d8aSDwaipayan Ray # 3 -> addresses match, names different 729548ca2d8aSDwaipayan Ray # 4 -> names match, addresses different 729648ca2d8aSDwaipayan Ray # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match 729748ca2d8aSDwaipayan Ray 729848ca2d8aSDwaipayan Ray my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; 729948ca2d8aSDwaipayan Ray 730048ca2d8aSDwaipayan Ray if ($authorsignoff == 0) { 730148ca2d8aSDwaipayan Ray ERROR("NO_AUTHOR_SIGN_OFF", 7302cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 730348ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 2) { 730448ca2d8aSDwaipayan Ray CHK("FROM_SIGN_OFF_MISMATCH", 730548ca2d8aSDwaipayan Ray "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); 730648ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 3) { 730748ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 730848ca2d8aSDwaipayan Ray "From:/Signed-off-by: email name mismatch: $sob_msg\n"); 730948ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 4) { 731048ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 731148ca2d8aSDwaipayan Ray "From:/Signed-off-by: email address mismatch: $sob_msg\n"); 731248ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 5) { 731348ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 731448ca2d8aSDwaipayan Ray "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); 731548ca2d8aSDwaipayan Ray } 7316cd261496SGeert Uytterhoeven } 73170a920b5bSAndy Whitcroft } 73180a920b5bSAndy Whitcroft 7319f0a594c1SAndy Whitcroft print report_dump(); 732013214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 732113214adfSAndy Whitcroft print "$filename " if ($summary_file); 73226c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 73236c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 73246c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 73256c72ffaaSAndy Whitcroft } 73268905a67cSAndy Whitcroft 7327d2c0a235SAndy Whitcroft if ($quiet == 0) { 7328ef212196SJoe Perches # If there were any defects found and not already fixing them 7329ef212196SJoe Perches if (!$clean and !$fix) { 7330ef212196SJoe Perches print << "EOM" 7331ef212196SJoe Perches 7332ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 7333ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 7334ef212196SJoe PerchesEOM 7335ef212196SJoe Perches } 7336d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 7337d2c0a235SAndy Whitcroft # then suggest that. 7338d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 7339b0781216SMike Frysinger $rpt_cleaners = 0; 7340d8469f16SJoe Perches print << "EOM" 7341d8469f16SJoe Perches 7342d8469f16SJoe PerchesNOTE: Whitespace errors detected. 7343d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 7344d8469f16SJoe PerchesEOM 7345d2c0a235SAndy Whitcroft } 7346d2c0a235SAndy Whitcroft } 7347d2c0a235SAndy Whitcroft 7348d752fcc8SJoe Perches if ($clean == 0 && $fix && 7349d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 7350d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 73519624b8d6SJoe Perches my $newfile = $filename; 73529624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 73533705ce5bSJoe Perches my $linecount = 0; 73543705ce5bSJoe Perches my $f; 73553705ce5bSJoe Perches 7356d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 7357d752fcc8SJoe Perches 73583705ce5bSJoe Perches open($f, '>', $newfile) 73593705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 73603705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 73613705ce5bSJoe Perches $linecount++; 73623705ce5bSJoe Perches if ($file) { 73633705ce5bSJoe Perches if ($linecount > 3) { 73643705ce5bSJoe Perches $fixed_line =~ s/^\+//; 73653705ce5bSJoe Perches print $f $fixed_line . "\n"; 73663705ce5bSJoe Perches } 73673705ce5bSJoe Perches } else { 73683705ce5bSJoe Perches print $f $fixed_line . "\n"; 73693705ce5bSJoe Perches } 73703705ce5bSJoe Perches } 73713705ce5bSJoe Perches close($f); 73723705ce5bSJoe Perches 73733705ce5bSJoe Perches if (!$quiet) { 73743705ce5bSJoe Perches print << "EOM"; 7375d8469f16SJoe Perches 73763705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 73773705ce5bSJoe Perches 73783705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 73793705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 73803705ce5bSJoe Perches 73813705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 73823705ce5bSJoe PerchesNo warranties, expressed or implied... 73833705ce5bSJoe PerchesEOM 73843705ce5bSJoe Perches } 73853705ce5bSJoe Perches } 73863705ce5bSJoe Perches 7387d8469f16SJoe Perches if ($quiet == 0) { 7388d8469f16SJoe Perches print "\n"; 7389d8469f16SJoe Perches if ($clean == 1) { 7390d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 7391d8469f16SJoe Perches } else { 7392d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 73930a920b5bSAndy Whitcroft } 73940a920b5bSAndy Whitcroft } 73950a920b5bSAndy Whitcroft return $clean; 73960a920b5bSAndy Whitcroft} 7397