1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl 2882ea1d6SJoe Perches# SPDX-License-Identifier: GPL-2.0 3882ea1d6SJoe Perches# 4dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit) 500df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 62a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite) 7015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]> 8882ea1d6SJoe Perches# (c) 2010-2018 Joe Perches <[email protected]> 90a920b5bSAndy Whitcroft 100a920b5bSAndy Whitcroftuse strict; 11cb77f0d6SKamil Rytarowskiuse warnings; 12c707a81dSJoe Perchesuse POSIX; 1336061e38SJoe Perchesuse File::Basename; 1436061e38SJoe Perchesuse Cwd 'abs_path'; 1557230297SJoe Perchesuse Term::ANSIColor qw(:constants); 16cd261496SGeert Uytterhoevenuse Encode qw(decode encode); 170a920b5bSAndy Whitcroft 180a920b5bSAndy Whitcroftmy $P = $0; 1936061e38SJoe Perchesmy $D = dirname(abs_path($P)); 200a920b5bSAndy Whitcroft 21000d1cc1SJoe Perchesmy $V = '0.32'; 220a920b5bSAndy Whitcroft 230a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 240a920b5bSAndy Whitcroft 250a920b5bSAndy Whitcroftmy $quiet = 0; 2652178ce0SDwaipayan Raymy $verbose = 0; 2752178ce0SDwaipayan Raymy %verbose_messages = (); 2852178ce0SDwaipayan Raymy %verbose_emitted = (); 290a920b5bSAndy Whitcroftmy $tree = 1; 300a920b5bSAndy Whitcroftmy $chk_signoff = 1; 31d5d6281aSDan Carpentermy $chk_fixes_tag = 1; 320a920b5bSAndy Whitcroftmy $chk_patch = 1; 33773647a0SAndy Whitcroftmy $tst_only; 346c72ffaaSAndy Whitcroftmy $emacs = 0; 358905a67cSAndy Whitcroftmy $terse = 0; 3634d8815fSJoe Perchesmy $showfile = 0; 376c72ffaaSAndy Whitcroftmy $file = 0; 384a593c34SDu, Changbinmy $git = 0; 390dea9f1eSJoe Perchesmy %git_commits = (); 406c72ffaaSAndy Whitcroftmy $check = 0; 412ac73b4fSJoe Perchesmy $check_orig = 0; 428905a67cSAndy Whitcroftmy $summary = 1; 438905a67cSAndy Whitcroftmy $mailback = 0; 4413214adfSAndy Whitcroftmy $summary_file = 0; 45000d1cc1SJoe Perchesmy $show_types = 0; 463beb42ecSJoe Perchesmy $list_types = 0; 473705ce5bSJoe Perchesmy $fix = 0; 489624b8d6SJoe Perchesmy $fix_inplace = 0; 496c72ffaaSAndy Whitcroftmy $root; 500f7f635bSJoe Perchesmy $gitroot = $ENV{'GIT_DIR'}; 510f7f635bSJoe Perches$gitroot = ".git" if !defined($gitroot); 52c2fdda0dSAndy Whitcroftmy %debug; 533445686aSJoe Perchesmy %camelcase = (); 5491bfe484SJoe Perchesmy %use_type = (); 5591bfe484SJoe Perchesmy @use = (); 5691bfe484SJoe Perchesmy %ignore_type = (); 57000d1cc1SJoe Perchesmy @ignore = (); 5877f5b10aSHannes Edermy $help = 0; 59000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 60bdc48fa1SJoe Perchesmy $max_line_length = 100; 61d62a201fSDave Hansenmy $ignore_perl_version = 0; 62d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 6356193274SVadim Bendeburymy $min_conf_desc_length = 4; 6466b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 65ebfd7d62SJoe Perchesmy $codespell = 0; 66f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt"; 670ee3e7b8SPeter Ujfalusimy $user_codespellfile = ""; 68bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 6952178ce0SDwaipayan Raymy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst"; 70ced69da1SQuentin Monnetmy $typedefsfile; 71737c0767SJohn Brooksmy $color = "auto"; 7298005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE 73dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE 74dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git'; 75713a09deSAntonio Borneomy $tabsize = 8; 763e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_"; 7777f5b10aSHannes Eder 785b2c7334SJim Cromiemy %maybe_linker_symbol; # for externs in c exceptions, when seen in *vmlinux.lds.h 795b2c7334SJim Cromie 8077f5b10aSHannes Edersub help { 8177f5b10aSHannes Eder my ($exitcode) = @_; 8277f5b10aSHannes Eder 8377f5b10aSHannes Eder print << "EOM"; 8477f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 8577f5b10aSHannes EderVersion: $V 8677f5b10aSHannes Eder 8777f5b10aSHannes EderOptions: 8877f5b10aSHannes Eder -q, --quiet quiet 8952178ce0SDwaipayan Ray -v, --verbose verbose mode 9077f5b10aSHannes Eder --no-tree run without a kernel tree 9177f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 92d5d6281aSDan Carpenter --no-fixes-tag do not check for 'Fixes:' tag 9377f5b10aSHannes Eder --patch treat FILE as patchfile (default) 9477f5b10aSHannes Eder --emacs emacs compile window format 9577f5b10aSHannes Eder --terse one line per report 9634d8815fSJoe Perches --showfile emit diffed file position, not input file position 974a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 984a593c34SDu, Changbin single git commit with: 994a593c34SDu, Changbin <rev> 1004a593c34SDu, Changbin <rev>^ 1014a593c34SDu, Changbin <rev>~n 1024a593c34SDu, Changbin multiple git commits with: 1034a593c34SDu, Changbin <rev1>..<rev2> 1044a593c34SDu, Changbin <rev1>...<rev2> 1054a593c34SDu, Changbin <rev>-<count> 1064a593c34SDu, Changbin git merges are ignored 10777f5b10aSHannes Eder -f, --file treat FILE as regular source file 10877f5b10aSHannes Eder --subjective, --strict enable more subjective tests 1093beb42ecSJoe Perches --list-types list the possible message types 11091bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 111000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 1123beb42ecSJoe Perches --show-types show the specific message type in the output 113bdc48fa1SJoe Perches --max-line-length=n set the maximum line length, (default $max_line_length) 114bdc48fa1SJoe Perches if exceeded, warn on patches 115bdc48fa1SJoe Perches requires --strict for use with --file 116*bc2f19d6SPhilipp Hahn --min-conf-desc-length=n set the minimum description length for config symbols 117*bc2f19d6SPhilipp Hahn in lines, if shorter, warn (default $min_conf_desc_length) 118bdc48fa1SJoe Perches --tab-size=n set the number of spaces for tab (default $tabsize) 11977f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 12077f5b10aSHannes Eder --no-summary suppress the per-file summary 12177f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 12277f5b10aSHannes Eder --summary-file include the filename in summary 12377f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 12477f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 12577f5b10aSHannes Eder is all off) 12677f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 12777f5b10aSHannes Eder literally 1283705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1293705ce5bSJoe Perches If correctable single-line errors exist, create 1303705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1313705ce5bSJoe Perches with potential errors corrected to the preferred 1323705ce5bSJoe Perches checkpatch style 1339624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1349624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1359624b8d6SJoe Perches file. It's your fault if there's no backup or git 136d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 137d62a201fSDave Hansen runtime errors. 138ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 1390ee3e7b8SPeter Ujfalusi (default:$codespellfile) 140ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 14175ad8c57SJerome Forissier --typedefsfile Read additional types from this file 142737c0767SJohn Brooks --color[=WHEN] Use colors 'always', 'never', or only when output 143737c0767SJohn Brooks is a terminal ('auto'). Default is 'auto'. 1443e89ad85SJerome Forissier --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default 1453e89ad85SJerome Forissier ${CONFIG_}) 14677f5b10aSHannes Eder -h, --help, --version display this help and exit 14777f5b10aSHannes Eder 14877f5b10aSHannes EderWhen FILE is - read standard input. 14977f5b10aSHannes EderEOM 15077f5b10aSHannes Eder 15177f5b10aSHannes Eder exit($exitcode); 15277f5b10aSHannes Eder} 15377f5b10aSHannes Eder 1543beb42ecSJoe Perchessub uniq { 1553beb42ecSJoe Perches my %seen; 1563beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1573beb42ecSJoe Perches} 1583beb42ecSJoe Perches 1593beb42ecSJoe Perchessub list_types { 1603beb42ecSJoe Perches my ($exitcode) = @_; 1613beb42ecSJoe Perches 1623beb42ecSJoe Perches my $count = 0; 1633beb42ecSJoe Perches 1643beb42ecSJoe Perches local $/ = undef; 1653beb42ecSJoe Perches 1663beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1673beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1683beb42ecSJoe Perches 1693beb42ecSJoe Perches my $text = <$script>; 1703beb42ecSJoe Perches close($script); 1713beb42ecSJoe Perches 17252178ce0SDwaipayan Ray my %types = (); 1730547fa58SJean Delvare # Also catch when type or level is passed through a variable 17452178ce0SDwaipayan Ray while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { 17552178ce0SDwaipayan Ray if (defined($1)) { 17652178ce0SDwaipayan Ray if (exists($types{$2})) { 17752178ce0SDwaipayan Ray $types{$2} .= ",$1" if ($types{$2} ne $1); 17852178ce0SDwaipayan Ray } else { 17952178ce0SDwaipayan Ray $types{$2} = $1; 1803beb42ecSJoe Perches } 18152178ce0SDwaipayan Ray } else { 18252178ce0SDwaipayan Ray $types{$2} = "UNDETERMINED"; 18352178ce0SDwaipayan Ray } 18452178ce0SDwaipayan Ray } 18552178ce0SDwaipayan Ray 1863beb42ecSJoe Perches print("#\tMessage type\n\n"); 18752178ce0SDwaipayan Ray if ($color) { 18852178ce0SDwaipayan Ray print(" ( Color coding: "); 18952178ce0SDwaipayan Ray print(RED . "ERROR" . RESET); 19052178ce0SDwaipayan Ray print(" | "); 19152178ce0SDwaipayan Ray print(YELLOW . "WARNING" . RESET); 19252178ce0SDwaipayan Ray print(" | "); 19352178ce0SDwaipayan Ray print(GREEN . "CHECK" . RESET); 19452178ce0SDwaipayan Ray print(" | "); 19552178ce0SDwaipayan Ray print("Multiple levels / Undetermined"); 19652178ce0SDwaipayan Ray print(" )\n\n"); 19752178ce0SDwaipayan Ray } 19852178ce0SDwaipayan Ray 19952178ce0SDwaipayan Ray foreach my $type (sort keys %types) { 20052178ce0SDwaipayan Ray my $orig_type = $type; 20152178ce0SDwaipayan Ray if ($color) { 20252178ce0SDwaipayan Ray my $level = $types{$type}; 20352178ce0SDwaipayan Ray if ($level eq "ERROR") { 20452178ce0SDwaipayan Ray $type = RED . $type . RESET; 20552178ce0SDwaipayan Ray } elsif ($level eq "WARN") { 20652178ce0SDwaipayan Ray $type = YELLOW . $type . RESET; 20752178ce0SDwaipayan Ray } elsif ($level eq "CHK") { 20852178ce0SDwaipayan Ray $type = GREEN . $type . RESET; 20952178ce0SDwaipayan Ray } 21052178ce0SDwaipayan Ray } 2113beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 21252178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$orig_type})) { 21352178ce0SDwaipayan Ray my $message = $verbose_messages{$orig_type}; 21452178ce0SDwaipayan Ray $message =~ s/\n/\n\t/g; 21552178ce0SDwaipayan Ray print("\t" . $message . "\n\n"); 21652178ce0SDwaipayan Ray } 2173beb42ecSJoe Perches } 2183beb42ecSJoe Perches 2193beb42ecSJoe Perches exit($exitcode); 2203beb42ecSJoe Perches} 2213beb42ecSJoe Perches 222000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 223000d1cc1SJoe Perchesif (-f $conf) { 224000d1cc1SJoe Perches my @conf_args; 225000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 226000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 227000d1cc1SJoe Perches 228000d1cc1SJoe Perches while (<$conffile>) { 229000d1cc1SJoe Perches my $line = $_; 230000d1cc1SJoe Perches 231000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 232000d1cc1SJoe Perches $line =~ s/^\s*//g; 233000d1cc1SJoe Perches $line =~ s/\s+/ /g; 234000d1cc1SJoe Perches 235000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 236000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 237000d1cc1SJoe Perches 238000d1cc1SJoe Perches my @words = split(" ", $line); 239000d1cc1SJoe Perches foreach my $word (@words) { 240000d1cc1SJoe Perches last if ($word =~ m/^#/); 241000d1cc1SJoe Perches push (@conf_args, $word); 242000d1cc1SJoe Perches } 243000d1cc1SJoe Perches } 244000d1cc1SJoe Perches close($conffile); 245000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 246000d1cc1SJoe Perches} 247000d1cc1SJoe Perches 24852178ce0SDwaipayan Raysub load_docs { 24952178ce0SDwaipayan Ray open(my $docs, '<', "$docsfile") 25052178ce0SDwaipayan Ray or warn "$P: Can't read the documentation file $docsfile $!\n"; 25152178ce0SDwaipayan Ray 25252178ce0SDwaipayan Ray my $type = ''; 25352178ce0SDwaipayan Ray my $desc = ''; 25452178ce0SDwaipayan Ray my $in_desc = 0; 25552178ce0SDwaipayan Ray 25652178ce0SDwaipayan Ray while (<$docs>) { 25752178ce0SDwaipayan Ray chomp; 25852178ce0SDwaipayan Ray my $line = $_; 25952178ce0SDwaipayan Ray $line =~ s/\s+$//; 26052178ce0SDwaipayan Ray 26152178ce0SDwaipayan Ray if ($line =~ /^\s*\*\*(.+)\*\*$/) { 26252178ce0SDwaipayan Ray if ($desc ne '') { 26352178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 26452178ce0SDwaipayan Ray } 26552178ce0SDwaipayan Ray $type = $1; 26652178ce0SDwaipayan Ray $desc = ''; 26752178ce0SDwaipayan Ray $in_desc = 1; 26852178ce0SDwaipayan Ray } elsif ($in_desc) { 26952178ce0SDwaipayan Ray if ($line =~ /^(?:\s{4,}|$)/) { 27052178ce0SDwaipayan Ray $line =~ s/^\s{4}//; 27152178ce0SDwaipayan Ray $desc .= $line; 27252178ce0SDwaipayan Ray $desc .= "\n"; 27352178ce0SDwaipayan Ray } else { 27452178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 27552178ce0SDwaipayan Ray $type = ''; 27652178ce0SDwaipayan Ray $desc = ''; 27752178ce0SDwaipayan Ray $in_desc = 0; 27852178ce0SDwaipayan Ray } 27952178ce0SDwaipayan Ray } 28052178ce0SDwaipayan Ray } 28152178ce0SDwaipayan Ray 28252178ce0SDwaipayan Ray if ($desc ne '') { 28352178ce0SDwaipayan Ray $verbose_messages{$type} = trim($desc); 28452178ce0SDwaipayan Ray } 28552178ce0SDwaipayan Ray close($docs); 28652178ce0SDwaipayan Ray} 28752178ce0SDwaipayan Ray 288737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space. 289737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments 290737c0767SJohn Brooksforeach (@ARGV) { 291737c0767SJohn Brooks if ($_ eq "--color" || $_ eq "-color") { 292737c0767SJohn Brooks $_ = "--color=$color"; 293737c0767SJohn Brooks } 294737c0767SJohn Brooks} 295737c0767SJohn Brooks 2960a920b5bSAndy WhitcroftGetOptions( 2976c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 29852178ce0SDwaipayan Ray 'v|verbose!' => \$verbose, 2990a920b5bSAndy Whitcroft 'tree!' => \$tree, 3000a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 301d5d6281aSDan Carpenter 'fixes-tag!' => \$chk_fixes_tag, 3020a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 3036c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 3048905a67cSAndy Whitcroft 'terse!' => \$terse, 30534d8815fSJoe Perches 'showfile!' => \$showfile, 30677f5b10aSHannes Eder 'f|file!' => \$file, 3074a593c34SDu, Changbin 'g|git!' => \$git, 3086c72ffaaSAndy Whitcroft 'subjective!' => \$check, 3096c72ffaaSAndy Whitcroft 'strict!' => \$check, 310000d1cc1SJoe Perches 'ignore=s' => \@ignore, 31191bfe484SJoe Perches 'types=s' => \@use, 312000d1cc1SJoe Perches 'show-types!' => \$show_types, 3133beb42ecSJoe Perches 'list-types!' => \$list_types, 3146cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 31556193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 316713a09deSAntonio Borneo 'tab-size=i' => \$tabsize, 3176c72ffaaSAndy Whitcroft 'root=s' => \$root, 3188905a67cSAndy Whitcroft 'summary!' => \$summary, 3198905a67cSAndy Whitcroft 'mailback!' => \$mailback, 32013214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 3213705ce5bSJoe Perches 'fix!' => \$fix, 3229624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 323d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 324c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 325773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 326ebfd7d62SJoe Perches 'codespell!' => \$codespell, 3270ee3e7b8SPeter Ujfalusi 'codespellfile=s' => \$user_codespellfile, 32875ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 329737c0767SJohn Brooks 'color=s' => \$color, 330737c0767SJohn Brooks 'no-color' => \$color, #keep old behaviors of -nocolor 331737c0767SJohn Brooks 'nocolor' => \$color, #keep old behaviors of -nocolor 3323e89ad85SJerome Forissier 'kconfig-prefix=s' => \${CONFIG_}, 33377f5b10aSHannes Eder 'h|help' => \$help, 33477f5b10aSHannes Eder 'version' => \$help 3350ee3e7b8SPeter Ujfalusi) or $help = 2; 33677f5b10aSHannes Eder 3370ee3e7b8SPeter Ujfalusiif ($user_codespellfile) { 3380ee3e7b8SPeter Ujfalusi # Use the user provided codespell file unconditionally 3390ee3e7b8SPeter Ujfalusi $codespellfile = $user_codespellfile; 3400ee3e7b8SPeter Ujfalusi} elsif (!(-f $codespellfile)) { 3410ee3e7b8SPeter Ujfalusi # If /usr/share/codespell/dictionary.txt is not present, try to find it 3420ee3e7b8SPeter Ujfalusi # under codespell's install directory: <codespell_root>/data/dictionary.txt 343c882c6b1SSagar Patel if (($codespell || $help) && which("python3") ne "") { 3440ee3e7b8SPeter Ujfalusi my $python_codespell_dict = << "EOF"; 3450ee3e7b8SPeter Ujfalusi 3460ee3e7b8SPeter Ujfalusiimport os.path as op 3470ee3e7b8SPeter Ujfalusiimport codespell_lib 3480ee3e7b8SPeter Ujfalusicodespell_dir = op.dirname(codespell_lib.__file__) 3490ee3e7b8SPeter Ujfalusicodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt') 3500ee3e7b8SPeter Ujfalusiprint(codespell_file, end='') 3510ee3e7b8SPeter UjfalusiEOF 3520ee3e7b8SPeter Ujfalusi 353c882c6b1SSagar Patel my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`; 3540ee3e7b8SPeter Ujfalusi $codespellfile = $codespell_dict if (-f $codespell_dict); 3550ee3e7b8SPeter Ujfalusi } 3560ee3e7b8SPeter Ujfalusi} 3570ee3e7b8SPeter Ujfalusi 3580ee3e7b8SPeter Ujfalusi# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0 3590ee3e7b8SPeter Ujfalusi# $help is 2 if invalid option is passed - exitcode: 1 3600ee3e7b8SPeter Ujfalusihelp($help - 1) if ($help); 3610a920b5bSAndy Whitcroft 36252178ce0SDwaipayan Raydie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); 36352178ce0SDwaipayan Raydie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse); 36452178ce0SDwaipayan Ray 36552178ce0SDwaipayan Rayif ($color =~ /^[01]$/) { 36652178ce0SDwaipayan Ray $color = !$color; 36752178ce0SDwaipayan Ray} elsif ($color =~ /^always$/i) { 36852178ce0SDwaipayan Ray $color = 1; 36952178ce0SDwaipayan Ray} elsif ($color =~ /^never$/i) { 37052178ce0SDwaipayan Ray $color = 0; 37152178ce0SDwaipayan Ray} elsif ($color =~ /^auto$/i) { 37252178ce0SDwaipayan Ray $color = (-t STDOUT); 37352178ce0SDwaipayan Ray} else { 37452178ce0SDwaipayan Ray die "$P: Invalid color mode: $color\n"; 37552178ce0SDwaipayan Ray} 37652178ce0SDwaipayan Ray 37752178ce0SDwaipayan Rayload_docs() if ($verbose); 3783beb42ecSJoe Percheslist_types(0) if ($list_types); 3793beb42ecSJoe Perches 3809624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 3812ac73b4fSJoe Perches$check_orig = $check; 3829624b8d6SJoe Perches 3830a920b5bSAndy Whitcroftmy $exit = 0; 3840a920b5bSAndy Whitcroft 3855b57980dSJoe Perchesmy $perl_version_ok = 1; 386d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 3875b57980dSJoe Perches $perl_version_ok = 0; 388d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 3895b57980dSJoe Perches exit(1) if (!$ignore_perl_version); 390d62a201fSDave Hansen} 391d62a201fSDave Hansen 39245107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 3930a920b5bSAndy Whitcroftif ($#ARGV < 0) { 39445107ff6SAllen Hubbe push(@ARGV, '-'); 3950a920b5bSAndy Whitcroft} 3960a920b5bSAndy Whitcroft 397713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1 39832f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); 399713a09deSAntonio Borneo 40091bfe484SJoe Perchessub hash_save_array_words { 40191bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 40291bfe484SJoe Perches 40391bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 40491bfe484SJoe Perches foreach my $word (@array) { 405000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 406000d1cc1SJoe Perches $word =~ s/^\s*//g; 407000d1cc1SJoe Perches $word =~ s/\s+/ /g; 408000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 409000d1cc1SJoe Perches 410000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 411000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 412000d1cc1SJoe Perches 41391bfe484SJoe Perches $hashRef->{$word}++; 414000d1cc1SJoe Perches } 41591bfe484SJoe Perches} 41691bfe484SJoe Perches 41791bfe484SJoe Perchessub hash_show_words { 41891bfe484SJoe Perches my ($hashRef, $prefix) = @_; 41991bfe484SJoe Perches 4203c816e49SJoe Perches if (keys %$hashRef) { 421d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 42258cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 42391bfe484SJoe Perches print " $word"; 42491bfe484SJoe Perches } 425d8469f16SJoe Perches print "\n"; 42691bfe484SJoe Perches } 42791bfe484SJoe Perches} 42891bfe484SJoe Perches 42991bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 43091bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 431000d1cc1SJoe Perches 432c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 433c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 4347429c690SAndy Whitcroftmy $dbg_type = 0; 435a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 436c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 43721caa13cSAndy Whitcroft ## no critic 43821caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 43921caa13cSAndy Whitcroft die "$@" if ($@); 440c2fdda0dSAndy Whitcroft} 441c2fdda0dSAndy Whitcroft 442d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 443d2c0a235SAndy Whitcroft 4448905a67cSAndy Whitcroftif ($terse) { 4458905a67cSAndy Whitcroft $emacs = 1; 4468905a67cSAndy Whitcroft $quiet++; 4478905a67cSAndy Whitcroft} 4488905a67cSAndy Whitcroft 4496c72ffaaSAndy Whitcroftif ($tree) { 4506c72ffaaSAndy Whitcroft if (defined $root) { 4516c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 4526c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 4536c72ffaaSAndy Whitcroft } 4546c72ffaaSAndy Whitcroft } else { 4556c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 4566c72ffaaSAndy Whitcroft $root = '.'; 4576c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 4586c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 4596c72ffaaSAndy Whitcroft $root = $1; 4606c72ffaaSAndy Whitcroft } 4616c72ffaaSAndy Whitcroft } 4626c72ffaaSAndy Whitcroft 4636c72ffaaSAndy Whitcroft if (!defined $root) { 4640a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 4650a920b5bSAndy Whitcroft exit(2); 4660a920b5bSAndy Whitcroft } 4676c72ffaaSAndy Whitcroft} 4686c72ffaaSAndy Whitcroft 4696c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 4706c72ffaaSAndy Whitcroft 4712ceb532bSAndy Whitcroftour $Ident = qr{ 4722ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 4732ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 4742ceb532bSAndy Whitcroft }x; 4756c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 4766c72ffaaSAndy Whitcroftour $Sparse = qr{ 4776c72ffaaSAndy Whitcroft __user| 4786c72ffaaSAndy Whitcroft __kernel| 4796c72ffaaSAndy Whitcroft __force| 4806c72ffaaSAndy Whitcroft __iomem| 4816c72ffaaSAndy Whitcroft __must_check| 482417495edSAndy Whitcroft __kprobes| 483165e72a6SSven Eckelmann __ref| 48433aa4597SGeert Uytterhoeven __refconst| 48533aa4597SGeert Uytterhoeven __refdata| 486ad315455SBoqun Feng __rcu| 487ad315455SBoqun Feng __private 4886c72ffaaSAndy Whitcroft }x; 489e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 490e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 491e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 492e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 493e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 4948716de38SJoe Perches 49552131292SWolfram Sang# Notes to $Attribute: 49652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 4976c72ffaaSAndy Whitcroftour $Attribute = qr{ 4986c72ffaaSAndy Whitcroft const| 499b5e8736aSJoe Perches volatile| 50003f1df7dSJoe Perches __percpu| 50103f1df7dSJoe Perches __nocast| 50203f1df7dSJoe Perches __safe| 50346d832f5SMichael S. Tsirkin __bitwise| 50403f1df7dSJoe Perches __packed__| 50503f1df7dSJoe Perches __packed2__| 50603f1df7dSJoe Perches __naked| 50703f1df7dSJoe Perches __maybe_unused| 50803f1df7dSJoe Perches __always_unused| 50903f1df7dSJoe Perches __noreturn| 51003f1df7dSJoe Perches __used| 51103f1df7dSJoe Perches __cold| 512e23ef1f3SJoe Perches __pure| 51303f1df7dSJoe Perches __noclone| 51403f1df7dSJoe Perches __deprecated| 5156c72ffaaSAndy Whitcroft __read_mostly| 516c5967e98SJoe Perches __ro_after_init| 5176c72ffaaSAndy Whitcroft __kprobes| 5188716de38SJoe Perches $InitAttribute| 5192f9dadbaSMarcelo Schmitt __aligned\s*\(.*\)| 52024e1d81aSAndy Whitcroft ____cacheline_aligned| 52124e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 5225fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 52386cffecdSKees Cook __weak| 52486cffecdSKees Cook __alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) 5256c72ffaaSAndy Whitcroft }x; 526c45dcabdSAndy Whitcroftour $Modifier; 52791cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 5286c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 5296c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 5306c72ffaaSAndy Whitcroft 53195e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 53295e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 53395e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 53495e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 5352435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 536d2af5aa6SJoe Perchesour $String = qr{(?:\b[Lu])?"[X\t]*"}; 537326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 538326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 539326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 54074349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 5412435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 542326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 543447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 54423f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 5456c72ffaaSAndy Whitcroftour $Operators = qr{ 5466c72ffaaSAndy Whitcroft <=|>=|==|!=| 5476c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 54823f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 5496c72ffaaSAndy Whitcroft }x; 5506c72ffaaSAndy Whitcroft 55191cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 55291cb5195SJoe Perches 553ab7e23f3SJoe Perchesour $BasicType; 5548905a67cSAndy Whitcroftour $NonptrType; 5551813087dSJoe Perchesour $NonptrTypeMisordered; 5568716de38SJoe Perchesour $NonptrTypeWithAttr; 5578905a67cSAndy Whitcroftour $Type; 5581813087dSJoe Perchesour $TypeMisordered; 5598905a67cSAndy Whitcroftour $Declare; 5601813087dSJoe Perchesour $DeclareMisordered; 5618905a67cSAndy Whitcroft 56215662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 56315662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 564171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 565171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 566171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 567171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 568171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 569171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 570171ae1a4SAndy Whitcroft}x; 571171ae1a4SAndy Whitcroft 57215662b3eSJoe Perchesour $UTF8 = qr{ 57315662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 57415662b3eSJoe Perches | $NON_ASCII_UTF8 57515662b3eSJoe Perches}x; 57615662b3eSJoe Perches 577e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 578021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 579021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 580021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 581021158b4SJoe Perches)}; 582e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 583fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 5848ed22cadSAndy Whitcroft atomic_t 5858ed22cadSAndy Whitcroft)}; 5868ea0114eSMickaël Salaünour $typeStdioTypedefs = qr{(?x: 5878ea0114eSMickaël Salaün FILE 5888ea0114eSMickaël Salaün)}; 589e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 590e6176fa4SJoe Perches $typeC99Typedefs\b| 591e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 5928ea0114eSMickaël Salaün $typeKernelTypedefs\b| 5938ea0114eSMickaël Salaün $typeStdioTypedefs\b 594e6176fa4SJoe Perches)}; 5958ed22cadSAndy Whitcroft 5966d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 5976d32f7a3SJoe Perches 598691e669bSJoe Perchesour $logFunctions = qr{(?x: 599758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 6007d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 60187bd499aSJoe Perches TP_printk| 6026e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 603b0531722SJoe Perches panic| 60406668727SJoe Perches MODULE_[A-Z_]+| 60506668727SJoe Perches seq_vprintf|seq_printf|seq_puts 606691e669bSJoe Perches)}; 607691e669bSJoe Perches 608e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 609e29a70f1SJoe Perches (?:(?:devm_)? 61058f02267SJoe Perches (?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? | 611e29a70f1SJoe Perches kstrdup(?:_const)? | 612e29a70f1SJoe Perches kmemdup(?:_nul)?) | 613461e1565SChristophe JAILLET (?:\w+)?alloc_skb(?:_ip_align)? | 614e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 615e29a70f1SJoe Perches dma_alloc_coherent 616e29a70f1SJoe Perches)}; 617e29a70f1SJoe Perches 61820112475SJoe Perchesour $signature_tags = qr{(?xi: 61920112475SJoe Perches Signed-off-by:| 620d499480cSJorge Ramirez-Ortiz Co-developed-by:| 62120112475SJoe Perches Acked-by:| 62220112475SJoe Perches Tested-by:| 62320112475SJoe Perches Reviewed-by:| 62420112475SJoe Perches Reported-by:| 6258543ae12SMugunthan V N Suggested-by:| 62620112475SJoe Perches To:| 62720112475SJoe Perches Cc: 62820112475SJoe Perches)}; 62920112475SJoe Perches 63044c31888SMatthieu Baertsour @link_tags = qw(Link Closes); 631f94e40eaSMatthieu Baerts 632f94e40eaSMatthieu Baerts#Create a search and print patterns for all these strings to be used directly below 633f94e40eaSMatthieu Baertsour $link_tags_search = ""; 634f94e40eaSMatthieu Baertsour $link_tags_print = ""; 635f94e40eaSMatthieu Baertsforeach my $entry (@link_tags) { 636f94e40eaSMatthieu Baerts if ($link_tags_search ne "") { 637f94e40eaSMatthieu Baerts $link_tags_search .= '|'; 638f94e40eaSMatthieu Baerts $link_tags_print .= ' or '; 639f94e40eaSMatthieu Baerts } 640f94e40eaSMatthieu Baerts $entry .= ':'; 641f94e40eaSMatthieu Baerts $link_tags_search .= $entry; 642f94e40eaSMatthieu Baerts $link_tags_print .= "'$entry'"; 643f94e40eaSMatthieu Baerts} 644f94e40eaSMatthieu Baerts$link_tags_search = "(?:${link_tags_search})"; 645f94e40eaSMatthieu Baerts 646adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi: 647adb2da82SJoe Perches [=-]*> | 648adb2da82SJoe Perches <[=-]* | 649adb2da82SJoe Perches \[ | 650adb2da82SJoe Perches \] | 651adb2da82SJoe Perches start | 652adb2da82SJoe Perches called | 653adb2da82SJoe Perches entered | 654adb2da82SJoe Perches entry | 655adb2da82SJoe Perches enter | 656adb2da82SJoe Perches in | 657adb2da82SJoe Perches inside | 658adb2da82SJoe Perches here | 659adb2da82SJoe Perches begin | 660adb2da82SJoe Perches exit | 661adb2da82SJoe Perches end | 662adb2da82SJoe Perches done | 663adb2da82SJoe Perches leave | 664adb2da82SJoe Perches completed | 665adb2da82SJoe Perches out | 666adb2da82SJoe Perches return | 667adb2da82SJoe Perches [\.\!:\s]* 668adb2da82SJoe Perches)}; 669adb2da82SJoe Perches 670831242abSAditya Srivastavasub edit_distance_min { 671831242abSAditya Srivastava my (@arr) = @_; 672831242abSAditya Srivastava my $len = scalar @arr; 673831242abSAditya Srivastava if ((scalar @arr) < 1) { 674831242abSAditya Srivastava # if underflow, return 675831242abSAditya Srivastava return; 676831242abSAditya Srivastava } 677831242abSAditya Srivastava my $min = $arr[0]; 678831242abSAditya Srivastava for my $i (0 .. ($len-1)) { 679831242abSAditya Srivastava if ($arr[$i] < $min) { 680831242abSAditya Srivastava $min = $arr[$i]; 681831242abSAditya Srivastava } 682831242abSAditya Srivastava } 683831242abSAditya Srivastava return $min; 684831242abSAditya Srivastava} 685831242abSAditya Srivastava 686831242abSAditya Srivastavasub get_edit_distance { 687831242abSAditya Srivastava my ($str1, $str2) = @_; 688831242abSAditya Srivastava $str1 = lc($str1); 689831242abSAditya Srivastava $str2 = lc($str2); 690831242abSAditya Srivastava $str1 =~ s/-//g; 691831242abSAditya Srivastava $str2 =~ s/-//g; 692831242abSAditya Srivastava my $len1 = length($str1); 693831242abSAditya Srivastava my $len2 = length($str2); 694831242abSAditya Srivastava # two dimensional array storing minimum edit distance 695831242abSAditya Srivastava my @distance; 696831242abSAditya Srivastava for my $i (0 .. $len1) { 697831242abSAditya Srivastava for my $j (0 .. $len2) { 698831242abSAditya Srivastava if ($i == 0) { 699831242abSAditya Srivastava $distance[$i][$j] = $j; 700831242abSAditya Srivastava } elsif ($j == 0) { 701831242abSAditya Srivastava $distance[$i][$j] = $i; 702831242abSAditya Srivastava } elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) { 703831242abSAditya Srivastava $distance[$i][$j] = $distance[$i - 1][$j - 1]; 704831242abSAditya Srivastava } else { 705831242abSAditya Srivastava my $dist1 = $distance[$i][$j - 1]; #insert distance 706831242abSAditya Srivastava my $dist2 = $distance[$i - 1][$j]; # remove 707831242abSAditya Srivastava my $dist3 = $distance[$i - 1][$j - 1]; #replace 708831242abSAditya Srivastava $distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3); 709831242abSAditya Srivastava } 710831242abSAditya Srivastava } 711831242abSAditya Srivastava } 712831242abSAditya Srivastava return $distance[$len1][$len2]; 713831242abSAditya Srivastava} 714831242abSAditya Srivastava 715831242abSAditya Srivastavasub find_standard_signature { 716831242abSAditya Srivastava my ($sign_off) = @_; 717831242abSAditya Srivastava my @standard_signature_tags = ( 718831242abSAditya Srivastava 'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:', 719831242abSAditya Srivastava 'Reviewed-by:', 'Reported-by:', 'Suggested-by:' 720831242abSAditya Srivastava ); 721831242abSAditya Srivastava foreach my $signature (@standard_signature_tags) { 722831242abSAditya Srivastava return $signature if (get_edit_distance($sign_off, $signature) <= 2); 723831242abSAditya Srivastava } 724831242abSAditya Srivastava 725831242abSAditya Srivastava return ""; 726831242abSAditya Srivastava} 727831242abSAditya Srivastava 7289b71f79fSBjorn Helgaasour $obsolete_archives = qr{(?xi: 7299b71f79fSBjorn Helgaas \Qfreedesktop.org/archives/dri-devel\E | 7309b71f79fSBjorn Helgaas \Qlists.infradead.org\E | 7319b71f79fSBjorn Helgaas \Qlkml.org\E | 7329b71f79fSBjorn Helgaas \Qmail-archive.com\E | 7339b71f79fSBjorn Helgaas \Qmailman.alsa-project.org/pipermail\E | 7349b71f79fSBjorn Helgaas \Qmarc.info\E | 7359b71f79fSBjorn Helgaas \Qozlabs.org/pipermail\E | 7369b71f79fSBjorn Helgaas \Qspinics.net\E 7379b71f79fSBjorn Helgaas)}; 7389b71f79fSBjorn Helgaas 7391813087dSJoe Perchesour @typeListMisordered = ( 7401813087dSJoe Perches qr{char\s+(?:un)?signed}, 7411813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 7421813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 7431813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 7441813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 7451813087dSJoe Perches qr{short\s+(?:un)?signed}, 7461813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 7471813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 7481813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 7491813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 7501813087dSJoe Perches qr{int\s+(?:un)?signed}, 7511813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 7521813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 7531813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 7541813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 7551813087dSJoe Perches qr{long\s+(?:un)?signed}, 7561813087dSJoe Perches); 7571813087dSJoe Perches 7588905a67cSAndy Whitcroftour @typeList = ( 7598905a67cSAndy Whitcroft qr{void}, 7600c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 7610c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 7620c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 7630c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 7640c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 7650c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 7660c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 7670c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 7680c773d9dSJoe Perches qr{(?:un)?signed}, 7698905a67cSAndy Whitcroft qr{float}, 7708905a67cSAndy Whitcroft qr{double}, 7718905a67cSAndy Whitcroft qr{bool}, 7728905a67cSAndy Whitcroft qr{struct\s+$Ident}, 7738905a67cSAndy Whitcroft qr{union\s+$Ident}, 7748905a67cSAndy Whitcroft qr{enum\s+$Ident}, 7758905a67cSAndy Whitcroft qr{${Ident}_t}, 7768905a67cSAndy Whitcroft qr{${Ident}_handler}, 7778905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 7781813087dSJoe Perches @typeListMisordered, 7798905a67cSAndy Whitcroft); 780938224b5SJoe Perches 781938224b5SJoe Perchesour $C90_int_types = qr{(?x: 782938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 783938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 784938224b5SJoe Perches long\s+long\s+(?:un)?signed| 785938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 786938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 787938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 788938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 789938224b5SJoe Perches 790938224b5SJoe Perches long\s+int\s+(?:un)?signed| 791938224b5SJoe Perches long\s+(?:un)?signed\s+int| 792938224b5SJoe Perches long\s+(?:un)?signed| 793938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 794938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 795938224b5SJoe Perches int\s+long\s+(?:un)?signed| 796938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 797938224b5SJoe Perches 798938224b5SJoe Perches int\s+(?:un)?signed| 799938224b5SJoe Perches (?:(?:un)?signed\s+)?int 800938224b5SJoe Perches)}; 801938224b5SJoe Perches 802485ff23eSAlex Dowadour @typeListFile = (); 8038716de38SJoe Perchesour @typeListWithAttr = ( 8048716de38SJoe Perches @typeList, 8058716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 8068716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 8078716de38SJoe Perches); 8088716de38SJoe Perches 809c45dcabdSAndy Whitcroftour @modifierList = ( 810c45dcabdSAndy Whitcroft qr{fastcall}, 811c45dcabdSAndy Whitcroft); 812485ff23eSAlex Dowadour @modifierListFile = (); 8138905a67cSAndy Whitcroft 8142435880fSJoe Perchesour @mode_permission_funcs = ( 8152435880fSJoe Perches ["module_param", 3], 8162435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 8172435880fSJoe Perches ["module_param_array_named", 5], 8182435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 8192435880fSJoe Perches ["proc_create(?:_data|)", 2], 820459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 821459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 822459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 823459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 824459cf0aeSJoe Perches ["__ATTR", 2], 8252435880fSJoe Perches); 8262435880fSJoe Perches 8271a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; 8281a3dcf2eSJoe Perches 829515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 830515a235eSJoe Perchesour $mode_perms_search = ""; 831515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 832515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 833515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 834515a235eSJoe Perches} 83500180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 836515a235eSJoe Perches 8379189c7e7SJoe Perchesour %deprecated_apis = ( 838defdaff1SIra Weiny "kmap" => "kmap_local_page", 839a3ea42ffSIra Weiny "kunmap" => "kunmap_local", 840defdaff1SIra Weiny "kmap_atomic" => "kmap_local_page", 841a3ea42ffSIra Weiny "kunmap_atomic" => "kunmap_local", 8429189c7e7SJoe Perches); 8439189c7e7SJoe Perches 8449189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 8459189c7e7SJoe Perchesour $deprecated_apis_search = ""; 8469189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 8479189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 8489189c7e7SJoe Perches $deprecated_apis_search .= $entry; 8499189c7e7SJoe Perches} 8509189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 8519189c7e7SJoe Perches 852b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 853b392c64fSJoe Perches S_IWUGO | 854b392c64fSJoe Perches S_IWOTH | 855b392c64fSJoe Perches S_IRWXUGO | 856b392c64fSJoe Perches S_IALLUGO | 857b392c64fSJoe Perches 0[0-7][0-7][2367] 858b392c64fSJoe Perches}x; 859b392c64fSJoe Perches 860f90774e1SJoe Perchesour %mode_permission_string_types = ( 861f90774e1SJoe Perches "S_IRWXU" => 0700, 862f90774e1SJoe Perches "S_IRUSR" => 0400, 863f90774e1SJoe Perches "S_IWUSR" => 0200, 864f90774e1SJoe Perches "S_IXUSR" => 0100, 865f90774e1SJoe Perches "S_IRWXG" => 0070, 866f90774e1SJoe Perches "S_IRGRP" => 0040, 867f90774e1SJoe Perches "S_IWGRP" => 0020, 868f90774e1SJoe Perches "S_IXGRP" => 0010, 869f90774e1SJoe Perches "S_IRWXO" => 0007, 870f90774e1SJoe Perches "S_IROTH" => 0004, 871f90774e1SJoe Perches "S_IWOTH" => 0002, 872f90774e1SJoe Perches "S_IXOTH" => 0001, 873f90774e1SJoe Perches "S_IRWXUGO" => 0777, 874f90774e1SJoe Perches "S_IRUGO" => 0444, 875f90774e1SJoe Perches "S_IWUGO" => 0222, 876f90774e1SJoe Perches "S_IXUGO" => 0111, 877f90774e1SJoe Perches); 878f90774e1SJoe Perches 879f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 880f90774e1SJoe Perchesour $mode_perms_string_search = ""; 881f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 882f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 883f90774e1SJoe Perches $mode_perms_string_search .= $entry; 884f90774e1SJoe Perches} 88500180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 88600180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 88700180468SJoe Perches ${single_mode_perms_string_search} 88800180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 88900180468SJoe Perches}x; 89000180468SJoe Perches 89100180468SJoe Perchessub perms_to_octal { 89200180468SJoe Perches my ($string) = @_; 89300180468SJoe Perches 89400180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 89500180468SJoe Perches 89600180468SJoe Perches my $val = ""; 89700180468SJoe Perches my $oval = ""; 89800180468SJoe Perches my $to = 0; 89900180468SJoe Perches my $curpos = 0; 90000180468SJoe Perches my $lastpos = 0; 90100180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 90200180468SJoe Perches $curpos = pos($string); 90300180468SJoe Perches my $match = $2; 90400180468SJoe Perches my $omatch = $1; 90500180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 90600180468SJoe Perches $lastpos = $curpos; 90700180468SJoe Perches $to |= $mode_permission_string_types{$match}; 90800180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 90900180468SJoe Perches $val .= $match; 91000180468SJoe Perches $oval .= $omatch; 91100180468SJoe Perches } 91200180468SJoe Perches $oval =~ s/^\s*\|\s*//; 91300180468SJoe Perches $oval =~ s/\s*\|\s*$//; 91400180468SJoe Perches return sprintf("%04o", $to); 91500180468SJoe Perches} 916f90774e1SJoe Perches 9177840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 9187840a94cSWolfram Sang irq| 919cdcee686SSergey Ryazanov memory| 920cdcee686SSergey Ryazanov time| 921cdcee686SSergey Ryazanov reboot 9227840a94cSWolfram Sang)}; 9237840a94cSWolfram Sang# memory.h: ARM has a custom one 9247840a94cSWolfram Sang 92566b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 92666b47b4aSKees Cookmy $misspellings; 92766b47b4aSKees Cookmy %spelling_fix; 92836061e38SJoe Perches 92936061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 93066b47b4aSKees Cook while (<$spelling>) { 93166b47b4aSKees Cook my $line = $_; 93266b47b4aSKees Cook 93366b47b4aSKees Cook $line =~ s/\s*\n?$//g; 93466b47b4aSKees Cook $line =~ s/^\s*//g; 93566b47b4aSKees Cook 93666b47b4aSKees Cook next if ($line =~ m/^\s*#/); 93766b47b4aSKees Cook next if ($line =~ m/^\s*$/); 93866b47b4aSKees Cook 93966b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 94066b47b4aSKees Cook 94166b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 94266b47b4aSKees Cook } 94366b47b4aSKees Cook close($spelling); 94436061e38SJoe Perches} else { 94536061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 94636061e38SJoe Perches} 94766b47b4aSKees Cook 948ebfd7d62SJoe Perchesif ($codespell) { 949ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 950ebfd7d62SJoe Perches while (<$spelling>) { 951ebfd7d62SJoe Perches my $line = $_; 952ebfd7d62SJoe Perches 953ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 954ebfd7d62SJoe Perches $line =~ s/^\s*//g; 955ebfd7d62SJoe Perches 956ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 957ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 958ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 959ebfd7d62SJoe Perches 960ebfd7d62SJoe Perches $line =~ s/,.*$//; 961ebfd7d62SJoe Perches 962ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 963ebfd7d62SJoe Perches 964ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 965ebfd7d62SJoe Perches } 966ebfd7d62SJoe Perches close($spelling); 967ebfd7d62SJoe Perches } else { 968ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 969ebfd7d62SJoe Perches } 970ebfd7d62SJoe Perches} 971ebfd7d62SJoe Perches 972ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 973ebfd7d62SJoe Perches 97475ad8c57SJerome Forissiersub read_words { 97575ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 97675ad8c57SJerome Forissier 97775ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 97875ad8c57SJerome Forissier while (<$words>) { 979bf1fa1daSJoe Perches my $line = $_; 980bf1fa1daSJoe Perches 981bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 982bf1fa1daSJoe Perches $line =~ s/^\s*//g; 983bf1fa1daSJoe Perches 984bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 985bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 986bf1fa1daSJoe Perches if ($line =~ /\s/) { 98775ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 988bf1fa1daSJoe Perches next; 989bf1fa1daSJoe Perches } 990bf1fa1daSJoe Perches 991ced69da1SQuentin Monnet $$wordsRef .= '|' if (defined $$wordsRef); 99275ad8c57SJerome Forissier $$wordsRef .= $line; 993bf1fa1daSJoe Perches } 99475ad8c57SJerome Forissier close($file); 99575ad8c57SJerome Forissier return 1; 996bf1fa1daSJoe Perches } 997bf1fa1daSJoe Perches 99875ad8c57SJerome Forissier return 0; 99975ad8c57SJerome Forissier} 100075ad8c57SJerome Forissier 1001ced69da1SQuentin Monnetmy $const_structs; 1002ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) { 100375ad8c57SJerome Forissier read_words(\$const_structs, $conststructsfile) 100475ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 1005ced69da1SQuentin Monnet} 100675ad8c57SJerome Forissier 1007ced69da1SQuentin Monnetif (defined($typedefsfile)) { 1008ced69da1SQuentin Monnet my $typeOtherTypedefs; 100975ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 101075ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 1011ced69da1SQuentin Monnet $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); 101275ad8c57SJerome Forissier} 101375ad8c57SJerome Forissier 10148905a67cSAndy Whitcroftsub build_types { 1015485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 1016485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 10171813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 10188716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 1019c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 1020ab7e23f3SJoe Perches $BasicType = qr{ 1021ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 1022ab7e23f3SJoe Perches (?:${all}\b) 1023ab7e23f3SJoe Perches }x; 10248905a67cSAndy Whitcroft $NonptrType = qr{ 1025d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 1026cf655043SAndy Whitcroft (?: 10276b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 10288ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 1029c45dcabdSAndy Whitcroft (?:${all}\b) 1030cf655043SAndy Whitcroft ) 1031c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 10328905a67cSAndy Whitcroft }x; 10331813087dSJoe Perches $NonptrTypeMisordered = qr{ 10341813087dSJoe Perches (?:$Modifier\s+|const\s+)* 10351813087dSJoe Perches (?: 10361813087dSJoe Perches (?:${Misordered}\b) 10371813087dSJoe Perches ) 10381813087dSJoe Perches (?:\s+$Modifier|\s+const)* 10391813087dSJoe Perches }x; 10408716de38SJoe Perches $NonptrTypeWithAttr = qr{ 10418716de38SJoe Perches (?:$Modifier\s+|const\s+)* 10428716de38SJoe Perches (?: 10438716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 10448716de38SJoe Perches (?:$typeTypedefs\b)| 10458716de38SJoe Perches (?:${allWithAttr}\b) 10468716de38SJoe Perches ) 10478716de38SJoe Perches (?:\s+$Modifier|\s+const)* 10488716de38SJoe Perches }x; 10498905a67cSAndy Whitcroft $Type = qr{ 1050c45dcabdSAndy Whitcroft $NonptrType 10517b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 1052c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 10538905a67cSAndy Whitcroft }x; 10541813087dSJoe Perches $TypeMisordered = qr{ 10551813087dSJoe Perches $NonptrTypeMisordered 10567b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 10571813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 10581813087dSJoe Perches }x; 105991cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 10601813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 10618905a67cSAndy Whitcroft} 10628905a67cSAndy Whitcroftbuild_types(); 10636c72ffaaSAndy Whitcroft 10647d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 1065d1fe9c09SJoe Perches 1066d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 1067d1fe9c09SJoe Perches# requires at least perl version v5.10.0 1068d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 1069d1fe9c09SJoe Perches 1070d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 10712435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 1072c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 10737d2367afSJoe Perches 1074f8422308SJoe Perchesour $declaration_macros = qr{(?x: 10753e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 1076fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 1077dcea7964SJoe Perches (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(| 1078dcea7964SJoe Perches (?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\( 1079f8422308SJoe Perches)}; 1080f8422308SJoe Perches 10818d0325ccSAditya Srivastavaour %allow_repeated_words = ( 10828d0325ccSAditya Srivastava add => '', 10838d0325ccSAditya Srivastava added => '', 10848d0325ccSAditya Srivastava bad => '', 10858d0325ccSAditya Srivastava be => '', 10868d0325ccSAditya Srivastava); 10878d0325ccSAditya Srivastava 10887d2367afSJoe Perchessub deparenthesize { 10897d2367afSJoe Perches my ($string) = @_; 10907d2367afSJoe Perches return "" if (!defined($string)); 10915b9553abSJoe Perches 10925b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 10935b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 10945b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 10955b9553abSJoe Perches } 10965b9553abSJoe Perches 10977d2367afSJoe Perches $string =~ s@\s+@ @g; 10985b9553abSJoe Perches 10997d2367afSJoe Perches return $string; 11007d2367afSJoe Perches} 11017d2367afSJoe Perches 11023445686aSJoe Perchessub seed_camelcase_file { 11033445686aSJoe Perches my ($file) = @_; 11043445686aSJoe Perches 11053445686aSJoe Perches return if (!(-f $file)); 11063445686aSJoe Perches 11073445686aSJoe Perches local $/; 11083445686aSJoe Perches 11093445686aSJoe Perches open(my $include_file, '<', "$file") 11103445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 11113445686aSJoe Perches my $text = <$include_file>; 11123445686aSJoe Perches close($include_file); 11133445686aSJoe Perches 11143445686aSJoe Perches my @lines = split('\n', $text); 11153445686aSJoe Perches 11163445686aSJoe Perches foreach my $line (@lines) { 11173445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 11183445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 11193445686aSJoe Perches $camelcase{$1} = 1; 112011ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 112111ea516aSJoe Perches $camelcase{$1} = 1; 112211ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 11233445686aSJoe Perches $camelcase{$1} = 1; 11243445686aSJoe Perches } 11253445686aSJoe Perches } 11263445686aSJoe Perches} 11273445686aSJoe Perches 1128cd28b119SJoe Perchesour %maintained_status = (); 1129cd28b119SJoe Perches 113085b0ee18SJoe Perchessub is_maintained_obsolete { 113185b0ee18SJoe Perches my ($filename) = @_; 113285b0ee18SJoe Perches 1133f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 113485b0ee18SJoe Perches 1135cd28b119SJoe Perches if (!exists($maintained_status{$filename})) { 1136cd28b119SJoe Perches $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 1137cd28b119SJoe Perches } 113885b0ee18SJoe Perches 1139cd28b119SJoe Perches return $maintained_status{$filename} =~ /obsolete/i; 114085b0ee18SJoe Perches} 114185b0ee18SJoe Perches 11423b6e8ac9SJoe Perchessub is_SPDX_License_valid { 11433b6e8ac9SJoe Perches my ($license) = @_; 11443b6e8ac9SJoe Perches 1145f9363b31SGuenter Roeck return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); 11463b6e8ac9SJoe Perches 114756294112SJoe Perches my $root_path = abs_path($root); 1148f9363b31SGuenter Roeck my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`; 11493b6e8ac9SJoe Perches return 0 if ($status ne ""); 11503b6e8ac9SJoe Perches return 1; 11513b6e8ac9SJoe Perches} 11523b6e8ac9SJoe Perches 11533445686aSJoe Perchesmy $camelcase_seeded = 0; 11543445686aSJoe Perchessub seed_camelcase_includes { 11553445686aSJoe Perches return if ($camelcase_seeded); 11563445686aSJoe Perches 11573445686aSJoe Perches my $files; 1158c707a81dSJoe Perches my $camelcase_cache = ""; 1159c707a81dSJoe Perches my @include_files = (); 1160c707a81dSJoe Perches 1161c707a81dSJoe Perches $camelcase_seeded = 1; 1162351b2a1fSJoe Perches 11630f7f635bSJoe Perches if (-e "$gitroot") { 1164dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 1165351b2a1fSJoe Perches chomp $git_last_include_commit; 1166c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 1167c707a81dSJoe Perches } else { 1168c707a81dSJoe Perches my $last_mod_date = 0; 1169c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 1170c707a81dSJoe Perches @include_files = split('\n', $files); 1171c707a81dSJoe Perches foreach my $file (@include_files) { 1172c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 1173c707a81dSJoe Perches localtime((stat $file)[9])); 1174c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 1175c707a81dSJoe Perches } 1176c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 1177c707a81dSJoe Perches } 1178c707a81dSJoe Perches 1179c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 1180c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 1181c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 1182351b2a1fSJoe Perches while (<$camelcase_file>) { 1183351b2a1fSJoe Perches chomp; 1184351b2a1fSJoe Perches $camelcase{$_} = 1; 1185351b2a1fSJoe Perches } 1186351b2a1fSJoe Perches close($camelcase_file); 1187351b2a1fSJoe Perches 1188351b2a1fSJoe Perches return; 1189351b2a1fSJoe Perches } 1190c707a81dSJoe Perches 11910f7f635bSJoe Perches if (-e "$gitroot") { 1192dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 1193c707a81dSJoe Perches @include_files = split('\n', $files); 11943445686aSJoe Perches } 1195c707a81dSJoe Perches 11963445686aSJoe Perches foreach my $file (@include_files) { 11973445686aSJoe Perches seed_camelcase_file($file); 11983445686aSJoe Perches } 1199351b2a1fSJoe Perches 1200c707a81dSJoe Perches if ($camelcase_cache ne "") { 1201351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 1202c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 1203c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 1204351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 1205351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 1206351b2a1fSJoe Perches } 1207351b2a1fSJoe Perches close($camelcase_file); 1208351b2a1fSJoe Perches } 12093445686aSJoe Perches} 12103445686aSJoe Perches 1211f5f61325SJoe Perchessub git_is_single_file { 1212f5f61325SJoe Perches my ($filename) = @_; 1213f5f61325SJoe Perches 1214f5f61325SJoe Perches return 0 if ((which("git") eq "") || !(-e "$gitroot")); 1215f5f61325SJoe Perches 1216f5f61325SJoe Perches my $output = `${git_command} ls-files -- $filename 2>/dev/null`; 1217f5f61325SJoe Perches my $count = $output =~ tr/\n//; 1218f5f61325SJoe Perches return $count eq 1 && $output =~ m{^${filename}$}; 1219f5f61325SJoe Perches} 1220f5f61325SJoe Perches 1221d311cd44SJoe Perchessub git_commit_info { 1222d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 1223d311cd44SJoe Perches 12240f7f635bSJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); 1225d311cd44SJoe Perches 1226dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 1227d311cd44SJoe Perches $output =~ s/^\s*//gm; 1228d311cd44SJoe Perches my @lines = split("\n", $output); 1229d311cd44SJoe Perches 12300d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 12310d7835fcSJoe Perches 12325a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 1233d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 1234d311cd44SJoe Perches# all matching commit ids, but it's very slow... 1235d311cd44SJoe Perches# 1236d311cd44SJoe Perches# echo "checking commits $1..." 1237d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 1238d311cd44SJoe Perches# while read line ; do 1239d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 1240d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 1241d311cd44SJoe Perches# done 12424ce9f970SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ || 12434ce9f970SJoe Perches $lines[0] =~ /^fatal: bad object $commit/) { 1244948b133aSHeinrich Schuchardt $id = undef; 1245d311cd44SJoe Perches } else { 1246d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 1247d311cd44SJoe Perches $desc = substr($lines[0], 41); 1248d311cd44SJoe Perches } 1249d311cd44SJoe Perches 1250d311cd44SJoe Perches return ($id, $desc); 1251d311cd44SJoe Perches} 1252d311cd44SJoe Perches 12536c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 1254d5d6281aSDan Carpenter$chk_fixes_tag = 0 if ($file); 12550a920b5bSAndy Whitcroft 125600df344fSAndy Whitcroftmy @rawlines = (); 1257c2fdda0dSAndy Whitcroftmy @lines = (); 12583705ce5bSJoe Perchesmy @fixed = (); 1259d752fcc8SJoe Perchesmy @fixed_inserted = (); 1260d752fcc8SJoe Perchesmy @fixed_deleted = (); 1261194f66fcSJoe Perchesmy $fixlinenr = -1; 1262194f66fcSJoe Perches 12634a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 12644a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 12650f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot"); 12664a593c34SDu, Changbin 12674a593c34SDu, Changbinif ($git) { 12684a593c34SDu, Changbin my @commits = (); 12690dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 12704a593c34SDu, Changbin my $git_range; 127128898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 127228898fd1SJoe Perches $git_range = "-$2 $1"; 12734a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 12744a593c34SDu, Changbin $git_range = "$commit_expr"; 12754a593c34SDu, Changbin } else { 12760dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 12770dea9f1eSJoe Perches } 1278dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 12790dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 128028898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 128128898fd1SJoe Perches next if (!defined($1) || !defined($2)); 12820dea9f1eSJoe Perches my $sha1 = $1; 12830dea9f1eSJoe Perches my $subject = $2; 12840dea9f1eSJoe Perches unshift(@commits, $sha1); 12850dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 12864a593c34SDu, Changbin } 12874a593c34SDu, Changbin } 12884a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 12894a593c34SDu, Changbin @ARGV = @commits; 12904a593c34SDu, Changbin} 12914a593c34SDu, Changbin 1292c2fdda0dSAndy Whitcroftmy $vname; 129398005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 12946c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 129521caa13cSAndy Whitcroft my $FILE; 1296f5f61325SJoe Perches my $is_git_file = git_is_single_file($filename); 1297f5f61325SJoe Perches my $oldfile = $file; 1298f5f61325SJoe Perches $file = 1 if ($is_git_file); 12994a593c34SDu, Changbin if ($git) { 13004a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 13014a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 13024a593c34SDu, Changbin } elsif ($file) { 130321caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 13046c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 130521caa13cSAndy Whitcroft } elsif ($filename eq '-') { 130621caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 13076c72ffaaSAndy Whitcroft } else { 130821caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 13096c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 13106c72ffaaSAndy Whitcroft } 1311c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1312c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 13134a593c34SDu, Changbin } elsif ($git) { 13140dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1315c2fdda0dSAndy Whitcroft } else { 1316c2fdda0dSAndy Whitcroft $vname = $filename; 1317c2fdda0dSAndy Whitcroft } 131821caa13cSAndy Whitcroft while (<$FILE>) { 13190a920b5bSAndy Whitcroft chomp; 132000df344fSAndy Whitcroft push(@rawlines, $_); 1321c7f574d0SGeert Uytterhoeven $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); 13226c72ffaaSAndy Whitcroft } 132321caa13cSAndy Whitcroft close($FILE); 1324d8469f16SJoe Perches 1325d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1326d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1327d8469f16SJoe Perches print "$vname\n"; 1328d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1329d8469f16SJoe Perches } 1330d8469f16SJoe Perches 1331c2fdda0dSAndy Whitcroft if (!process($filename)) { 13320a920b5bSAndy Whitcroft $exit = 1; 13330a920b5bSAndy Whitcroft } 133400df344fSAndy Whitcroft @rawlines = (); 133513214adfSAndy Whitcroft @lines = (); 13363705ce5bSJoe Perches @fixed = (); 1337d752fcc8SJoe Perches @fixed_inserted = (); 1338d752fcc8SJoe Perches @fixed_deleted = (); 1339194f66fcSJoe Perches $fixlinenr = -1; 1340485ff23eSAlex Dowad @modifierListFile = (); 1341485ff23eSAlex Dowad @typeListFile = (); 1342485ff23eSAlex Dowad build_types(); 1343f5f61325SJoe Perches $file = $oldfile if ($is_git_file); 13440a920b5bSAndy Whitcroft} 13450a920b5bSAndy Whitcroft 1346d8469f16SJoe Perchesif (!$quiet) { 13473c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 13483c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 13493c816e49SJoe Perches 13505b57980dSJoe Perches if (!$perl_version_ok) { 1351d8469f16SJoe Perches print << "EOM" 1352d8469f16SJoe Perches 1353d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 13545b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1355d8469f16SJoe PerchesEOM 1356d8469f16SJoe Perches } 1357d8469f16SJoe Perches if ($exit) { 1358d8469f16SJoe Perches print << "EOM" 1359d8469f16SJoe Perches 1360d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1361d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1362d8469f16SJoe PerchesEOM 1363d8469f16SJoe Perches } 1364d8469f16SJoe Perches} 1365d8469f16SJoe Perches 13660a920b5bSAndy Whitcroftexit($exit); 13670a920b5bSAndy Whitcroft 13680a920b5bSAndy Whitcroftsub top_of_kernel_tree { 13696c72ffaaSAndy Whitcroft my ($root) = @_; 13706c72ffaaSAndy Whitcroft 13716c72ffaaSAndy Whitcroft my @tree_check = ( 13726c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 13736c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 13746c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 13756c72ffaaSAndy Whitcroft ); 13766c72ffaaSAndy Whitcroft 13776c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 13786c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 13790a920b5bSAndy Whitcroft return 0; 13800a920b5bSAndy Whitcroft } 13816c72ffaaSAndy Whitcroft } 13826c72ffaaSAndy Whitcroft return 1; 13836c72ffaaSAndy Whitcroft} 13840a920b5bSAndy Whitcroft 138520112475SJoe Perchessub parse_email { 138620112475SJoe Perches my ($formatted_email) = @_; 138720112475SJoe Perches 138820112475SJoe Perches my $name = ""; 1389fccaebf0SDwaipayan Ray my $quoted = ""; 1390dfa05c28SJoe Perches my $name_comment = ""; 139120112475SJoe Perches my $address = ""; 139220112475SJoe Perches my $comment = ""; 139320112475SJoe Perches 139420112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 139520112475SJoe Perches $name = $1; 139620112475SJoe Perches $address = $2; 139720112475SJoe Perches $comment = $3 if defined $3; 139820112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 139920112475SJoe Perches $address = $1; 140020112475SJoe Perches $comment = $2 if defined $2; 140120112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 140220112475SJoe Perches $address = $1; 140320112475SJoe Perches $comment = $2 if defined $2; 140485e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 140520112475SJoe Perches $name = $formatted_email; 14063705ce5bSJoe Perches $name = trim($name); 140720112475SJoe Perches $name =~ s/^\"|\"$//g; 140820112475SJoe Perches # If there's a name left after stripping spaces and 140920112475SJoe Perches # leading quotes, and the address doesn't have both 141020112475SJoe Perches # leading and trailing angle brackets, the address 141120112475SJoe Perches # is invalid. ie: 141220112475SJoe Perches # "joe smith [email protected]" bad 141320112475SJoe Perches # "joe smith <[email protected]" bad 141420112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 141520112475SJoe Perches $name = ""; 141620112475SJoe Perches $address = ""; 141720112475SJoe Perches $comment = ""; 141820112475SJoe Perches } 141920112475SJoe Perches } 142020112475SJoe Perches 1421fccaebf0SDwaipayan Ray # Extract comments from names excluding quoted parts 1422fccaebf0SDwaipayan Ray # "John D. (Doe)" - Do not extract 1423fccaebf0SDwaipayan Ray if ($name =~ s/\"(.+)\"//) { 1424fccaebf0SDwaipayan Ray $quoted = $1; 1425dfa05c28SJoe Perches } 1426fccaebf0SDwaipayan Ray while ($name =~ s/\s*($balanced_parens)\s*/ /) { 1427fccaebf0SDwaipayan Ray $name_comment .= trim($1); 1428fccaebf0SDwaipayan Ray } 1429fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 1430fccaebf0SDwaipayan Ray $name = trim("$quoted $name"); 1431fccaebf0SDwaipayan Ray 14323705ce5bSJoe Perches $address = trim($address); 143320112475SJoe Perches $address =~ s/^\<|\>$//g; 1434fccaebf0SDwaipayan Ray $comment = trim($comment); 143520112475SJoe Perches 143620112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 143720112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 143820112475SJoe Perches $name = "\"$name\""; 143920112475SJoe Perches } 144020112475SJoe Perches 1441dfa05c28SJoe Perches return ($name, $name_comment, $address, $comment); 144220112475SJoe Perches} 144320112475SJoe Perches 144420112475SJoe Perchessub format_email { 144548ca2d8aSDwaipayan Ray my ($name, $name_comment, $address, $comment) = @_; 144620112475SJoe Perches 144720112475SJoe Perches my $formatted_email; 144820112475SJoe Perches 1449fccaebf0SDwaipayan Ray $name =~ s/^[ \"]+|[ \"]+$//g; 14503705ce5bSJoe Perches $address = trim($address); 1451fccaebf0SDwaipayan Ray $address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes 145220112475SJoe Perches 145320112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 145420112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 145520112475SJoe Perches $name = "\"$name\""; 145620112475SJoe Perches } 145720112475SJoe Perches 1458fccaebf0SDwaipayan Ray $name_comment = trim($name_comment); 1459fccaebf0SDwaipayan Ray $name_comment = " $name_comment" if ($name_comment ne ""); 1460fccaebf0SDwaipayan Ray $comment = trim($comment); 1461fccaebf0SDwaipayan Ray $comment = " $comment" if ($comment ne ""); 1462fccaebf0SDwaipayan Ray 146320112475SJoe Perches if ("$name" eq "") { 146420112475SJoe Perches $formatted_email = "$address"; 146520112475SJoe Perches } else { 146648ca2d8aSDwaipayan Ray $formatted_email = "$name$name_comment <$address>"; 146720112475SJoe Perches } 146848ca2d8aSDwaipayan Ray $formatted_email .= "$comment"; 146920112475SJoe Perches return $formatted_email; 147020112475SJoe Perches} 147120112475SJoe Perches 1472dfa05c28SJoe Perchessub reformat_email { 1473dfa05c28SJoe Perches my ($email) = @_; 1474dfa05c28SJoe Perches 1475dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 147648ca2d8aSDwaipayan Ray return format_email($email_name, $name_comment, $email_address, $comment); 1477dfa05c28SJoe Perches} 1478dfa05c28SJoe Perches 1479dfa05c28SJoe Perchessub same_email_addresses { 1480fccaebf0SDwaipayan Ray my ($email1, $email2) = @_; 1481dfa05c28SJoe Perches 1482dfa05c28SJoe Perches my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); 1483dfa05c28SJoe Perches my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); 1484dfa05c28SJoe Perches 148548ca2d8aSDwaipayan Ray return $email1_name eq $email2_name && 148648ca2d8aSDwaipayan Ray $email1_address eq $email2_address && 148748ca2d8aSDwaipayan Ray $name1_comment eq $name2_comment && 148848ca2d8aSDwaipayan Ray $comment1 eq $comment2; 148948ca2d8aSDwaipayan Ray} 1490dfa05c28SJoe Perches 1491d311cd44SJoe Perchessub which { 1492d311cd44SJoe Perches my ($bin) = @_; 1493d311cd44SJoe Perches 1494d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1495d311cd44SJoe Perches if (-e "$path/$bin") { 1496d311cd44SJoe Perches return "$path/$bin"; 1497d311cd44SJoe Perches } 1498d311cd44SJoe Perches } 1499d311cd44SJoe Perches 1500d311cd44SJoe Perches return ""; 1501d311cd44SJoe Perches} 1502d311cd44SJoe Perches 1503000d1cc1SJoe Perchessub which_conf { 1504000d1cc1SJoe Perches my ($conf) = @_; 1505000d1cc1SJoe Perches 1506000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1507000d1cc1SJoe Perches if (-e "$path/$conf") { 1508000d1cc1SJoe Perches return "$path/$conf"; 1509000d1cc1SJoe Perches } 1510000d1cc1SJoe Perches } 1511000d1cc1SJoe Perches 1512000d1cc1SJoe Perches return ""; 1513000d1cc1SJoe Perches} 1514000d1cc1SJoe Perches 15150a920b5bSAndy Whitcroftsub expand_tabs { 15160a920b5bSAndy Whitcroft my ($str) = @_; 15170a920b5bSAndy Whitcroft 15180a920b5bSAndy Whitcroft my $res = ''; 15190a920b5bSAndy Whitcroft my $n = 0; 15200a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 15210a920b5bSAndy Whitcroft if ($c eq "\t") { 15220a920b5bSAndy Whitcroft $res .= ' '; 15230a920b5bSAndy Whitcroft $n++; 1524713a09deSAntonio Borneo for (; ($n % $tabsize) != 0; $n++) { 15250a920b5bSAndy Whitcroft $res .= ' '; 15260a920b5bSAndy Whitcroft } 15270a920b5bSAndy Whitcroft next; 15280a920b5bSAndy Whitcroft } 15290a920b5bSAndy Whitcroft $res .= $c; 15300a920b5bSAndy Whitcroft $n++; 15310a920b5bSAndy Whitcroft } 15320a920b5bSAndy Whitcroft 15330a920b5bSAndy Whitcroft return $res; 15340a920b5bSAndy Whitcroft} 15356c72ffaaSAndy Whitcroftsub copy_spacing { 1536773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 15376c72ffaaSAndy Whitcroft return $res; 15386c72ffaaSAndy Whitcroft} 15390a920b5bSAndy Whitcroft 15404a0df2efSAndy Whitcroftsub line_stats { 15414a0df2efSAndy Whitcroft my ($line) = @_; 15424a0df2efSAndy Whitcroft 15434a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 15444a0df2efSAndy Whitcroft $line =~ s/^.//; 15454a0df2efSAndy Whitcroft $line = expand_tabs($line); 15464a0df2efSAndy Whitcroft 15474a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 15484a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 15494a0df2efSAndy Whitcroft 15504a0df2efSAndy Whitcroft return (length($line), length($white)); 15514a0df2efSAndy Whitcroft} 15524a0df2efSAndy Whitcroft 1553773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1554773647a0SAndy Whitcroft 1555773647a0SAndy Whitcroftsub sanitise_line_reset { 1556773647a0SAndy Whitcroft my ($in_comment) = @_; 1557773647a0SAndy Whitcroft 1558773647a0SAndy Whitcroft if ($in_comment) { 1559773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1560773647a0SAndy Whitcroft } else { 1561773647a0SAndy Whitcroft $sanitise_quote = ''; 1562773647a0SAndy Whitcroft } 1563773647a0SAndy Whitcroft} 156400df344fSAndy Whitcroftsub sanitise_line { 156500df344fSAndy Whitcroft my ($line) = @_; 156600df344fSAndy Whitcroft 156700df344fSAndy Whitcroft my $res = ''; 156800df344fSAndy Whitcroft my $l = ''; 156900df344fSAndy Whitcroft 1570c2fdda0dSAndy Whitcroft my $qlen = 0; 1571773647a0SAndy Whitcroft my $off = 0; 1572773647a0SAndy Whitcroft my $c; 157300df344fSAndy Whitcroft 1574773647a0SAndy Whitcroft # Always copy over the diff marker. 1575773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1576773647a0SAndy Whitcroft 1577773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1578773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1579773647a0SAndy Whitcroft 15808d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1581773647a0SAndy Whitcroft # and end, all to $;. 1582773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1583773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1584773647a0SAndy Whitcroft 1585773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1586773647a0SAndy Whitcroft $off++; 158700df344fSAndy Whitcroft next; 1588773647a0SAndy Whitcroft } 158981bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1590773647a0SAndy Whitcroft $sanitise_quote = ''; 1591773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1592773647a0SAndy Whitcroft $off++; 1593773647a0SAndy Whitcroft next; 1594773647a0SAndy Whitcroft } 1595113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1596113f04a8SDaniel Walker $sanitise_quote = '//'; 1597113f04a8SDaniel Walker 1598113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1599113f04a8SDaniel Walker $off++; 1600113f04a8SDaniel Walker next; 1601113f04a8SDaniel Walker } 1602773647a0SAndy Whitcroft 1603773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1604773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1605773647a0SAndy Whitcroft $c eq "\\") { 1606773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1607773647a0SAndy Whitcroft $off++; 1608773647a0SAndy Whitcroft next; 1609773647a0SAndy Whitcroft } 1610773647a0SAndy Whitcroft # Regular quotes. 1611773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1612773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1613773647a0SAndy Whitcroft $sanitise_quote = $c; 1614773647a0SAndy Whitcroft 1615773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1616773647a0SAndy Whitcroft next; 1617773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1618773647a0SAndy Whitcroft $sanitise_quote = ''; 161900df344fSAndy Whitcroft } 162000df344fSAndy Whitcroft } 1621773647a0SAndy Whitcroft 1622fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1623773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1624773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1625113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1626113f04a8SDaniel Walker substr($res, $off, 1, $;); 1627773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1628773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 162900df344fSAndy Whitcroft } else { 1630773647a0SAndy Whitcroft substr($res, $off, 1, $c); 163100df344fSAndy Whitcroft } 1632c2fdda0dSAndy Whitcroft } 1633c2fdda0dSAndy Whitcroft 1634113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1635113f04a8SDaniel Walker $sanitise_quote = ''; 1636113f04a8SDaniel Walker } 1637113f04a8SDaniel Walker 1638c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1639c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1640c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1641c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1642c2fdda0dSAndy Whitcroft 1643c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1644c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1645c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1646c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1647c2fdda0dSAndy Whitcroft } 1648c2fdda0dSAndy Whitcroft 1649dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1650dadf680dSJoe Perches my $match = $1; 1651dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1652dadf680dSJoe Perches } 1653dadf680dSJoe Perches 165400df344fSAndy Whitcroft return $res; 165500df344fSAndy Whitcroft} 165600df344fSAndy Whitcroft 1657a6962d72SJoe Perchessub get_quoted_string { 1658a6962d72SJoe Perches my ($line, $rawline) = @_; 1659a6962d72SJoe Perches 1660478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 166133acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1662a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1663a6962d72SJoe Perches} 1664a6962d72SJoe Perches 16658905a67cSAndy Whitcroftsub ctx_statement_block { 16668905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 16678905a67cSAndy Whitcroft my $line = $linenr - 1; 16688905a67cSAndy Whitcroft my $blk = ''; 16698905a67cSAndy Whitcroft my $soff = $off; 16708905a67cSAndy Whitcroft my $coff = $off - 1; 1671773647a0SAndy Whitcroft my $coff_set = 0; 16728905a67cSAndy Whitcroft 167313214adfSAndy Whitcroft my $loff = 0; 167413214adfSAndy Whitcroft 16758905a67cSAndy Whitcroft my $type = ''; 16768905a67cSAndy Whitcroft my $level = 0; 1677a2750645SAndy Whitcroft my @stack = (); 1678cf655043SAndy Whitcroft my $p; 16798905a67cSAndy Whitcroft my $c; 16808905a67cSAndy Whitcroft my $len = 0; 168113214adfSAndy Whitcroft 168213214adfSAndy Whitcroft my $remainder; 16838905a67cSAndy Whitcroft while (1) { 1684a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1685a2750645SAndy Whitcroft 1686773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 16878905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 16888905a67cSAndy Whitcroft # context. 16898905a67cSAndy Whitcroft if ($off >= $len) { 16908905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1691dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1692c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 16938905a67cSAndy Whitcroft $remain--; 169413214adfSAndy Whitcroft $loff = $len; 1695c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 16968905a67cSAndy Whitcroft $len = length($blk); 16978905a67cSAndy Whitcroft $line++; 16988905a67cSAndy Whitcroft last; 16998905a67cSAndy Whitcroft } 17008905a67cSAndy Whitcroft # Bail if there is no further context. 17018905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 170213214adfSAndy Whitcroft if ($off >= $len) { 17038905a67cSAndy Whitcroft last; 17048905a67cSAndy Whitcroft } 1705f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1706f74bd194SAndy Whitcroft $level++; 1707f74bd194SAndy Whitcroft $type = '#'; 1708f74bd194SAndy Whitcroft } 17098905a67cSAndy Whitcroft } 1710cf655043SAndy Whitcroft $p = $c; 17118905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 171213214adfSAndy Whitcroft $remainder = substr($blk, $off); 17138905a67cSAndy Whitcroft 1714773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 17154635f4fbSAndy Whitcroft 17164635f4fbSAndy Whitcroft # Handle nested #if/#else. 17174635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 17184635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 17194635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 17204635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 17214635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 17224635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 17234635f4fbSAndy Whitcroft } 17244635f4fbSAndy Whitcroft 17258905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 17268905a67cSAndy Whitcroft # outermost level. 17278905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 17288905a67cSAndy Whitcroft last; 17298905a67cSAndy Whitcroft } 17308905a67cSAndy Whitcroft 173113214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1732773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1733773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1734773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1735773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1736773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1737773647a0SAndy Whitcroft $coff_set = 1; 1738773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1739773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 174013214adfSAndy Whitcroft } 174113214adfSAndy Whitcroft 17428905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 17438905a67cSAndy Whitcroft $level++; 17448905a67cSAndy Whitcroft $type = '('; 17458905a67cSAndy Whitcroft } 17468905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 17478905a67cSAndy Whitcroft $level--; 17488905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 17498905a67cSAndy Whitcroft 17508905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 17518905a67cSAndy Whitcroft $coff = $off; 1752773647a0SAndy Whitcroft $coff_set = 1; 1753773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 17548905a67cSAndy Whitcroft } 17558905a67cSAndy Whitcroft } 17568905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 17578905a67cSAndy Whitcroft $level++; 17588905a67cSAndy Whitcroft $type = '{'; 17598905a67cSAndy Whitcroft } 17608905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 17618905a67cSAndy Whitcroft $level--; 17628905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 17638905a67cSAndy Whitcroft 17648905a67cSAndy Whitcroft if ($level == 0) { 1765b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1766b998e001SPatrick Pannuto $off++; 1767b998e001SPatrick Pannuto } 17688905a67cSAndy Whitcroft last; 17698905a67cSAndy Whitcroft } 17708905a67cSAndy Whitcroft } 1771f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1772f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1773f74bd194SAndy Whitcroft $level--; 1774f74bd194SAndy Whitcroft $type = ''; 1775f74bd194SAndy Whitcroft $off++; 1776f74bd194SAndy Whitcroft last; 1777f74bd194SAndy Whitcroft } 17788905a67cSAndy Whitcroft $off++; 17798905a67cSAndy Whitcroft } 1780a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 178113214adfSAndy Whitcroft if ($off == $len) { 1782a3bb97a7SAndy Whitcroft $loff = $len + 1; 178313214adfSAndy Whitcroft $line++; 178413214adfSAndy Whitcroft $remain--; 178513214adfSAndy Whitcroft } 17868905a67cSAndy Whitcroft 17878905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 17888905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 17898905a67cSAndy Whitcroft 17908905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 17918905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 17928905a67cSAndy Whitcroft 1793773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 179413214adfSAndy Whitcroft 179513214adfSAndy Whitcroft return ($statement, $condition, 179613214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 179713214adfSAndy Whitcroft} 179813214adfSAndy Whitcroft 1799cf655043SAndy Whitcroftsub statement_lines { 1800cf655043SAndy Whitcroft my ($stmt) = @_; 1801cf655043SAndy Whitcroft 1802cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1803cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1804cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1805cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1806cf655043SAndy Whitcroft 1807cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1808cf655043SAndy Whitcroft 1809cf655043SAndy Whitcroft return $#stmt_lines + 2; 1810cf655043SAndy Whitcroft} 1811cf655043SAndy Whitcroft 1812cf655043SAndy Whitcroftsub statement_rawlines { 1813cf655043SAndy Whitcroft my ($stmt) = @_; 1814cf655043SAndy Whitcroft 1815cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1816cf655043SAndy Whitcroft 1817cf655043SAndy Whitcroft return $#stmt_lines + 2; 1818cf655043SAndy Whitcroft} 1819cf655043SAndy Whitcroft 1820cf655043SAndy Whitcroftsub statement_block_size { 1821cf655043SAndy Whitcroft my ($stmt) = @_; 1822cf655043SAndy Whitcroft 1823cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1824cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1825cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1826cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1827cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1828cf655043SAndy Whitcroft 1829cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1830cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1831cf655043SAndy Whitcroft 1832cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1833cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1834cf655043SAndy Whitcroft 1835cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1836cf655043SAndy Whitcroft return $stmt_lines; 1837cf655043SAndy Whitcroft } else { 1838cf655043SAndy Whitcroft return $stmt_statements; 1839cf655043SAndy Whitcroft } 1840cf655043SAndy Whitcroft} 1841cf655043SAndy Whitcroft 184213214adfSAndy Whitcroftsub ctx_statement_full { 184313214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 184413214adfSAndy Whitcroft my ($statement, $condition, $level); 184513214adfSAndy Whitcroft 184613214adfSAndy Whitcroft my (@chunks); 184713214adfSAndy Whitcroft 1848cf655043SAndy Whitcroft # Grab the first conditional/block pair. 184913214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 185013214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1851773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 185213214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1853cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1854cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1855cf655043SAndy Whitcroft } 1856cf655043SAndy Whitcroft 1857cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1858cf655043SAndy Whitcroft # could continue the statement. 1859cf655043SAndy Whitcroft for (;;) { 186013214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 186113214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1862cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1863773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1864cf655043SAndy Whitcroft #print "C: push\n"; 1865cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 186613214adfSAndy Whitcroft } 186713214adfSAndy Whitcroft 186813214adfSAndy Whitcroft return ($level, $linenr, @chunks); 18698905a67cSAndy Whitcroft} 18708905a67cSAndy Whitcroft 18714a0df2efSAndy Whitcroftsub ctx_block_get { 1872f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 18734a0df2efSAndy Whitcroft my $line; 18744a0df2efSAndy Whitcroft my $start = $linenr - 1; 18754a0df2efSAndy Whitcroft my $blk = ''; 18764a0df2efSAndy Whitcroft my @o; 18774a0df2efSAndy Whitcroft my @c; 18784a0df2efSAndy Whitcroft my @res = (); 18794a0df2efSAndy Whitcroft 1880f0a594c1SAndy Whitcroft my $level = 0; 18814635f4fbSAndy Whitcroft my @stack = ($level); 188200df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 188300df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 188400df344fSAndy Whitcroft $remain--; 188500df344fSAndy Whitcroft 188600df344fSAndy Whitcroft $blk .= $rawlines[$line]; 18874635f4fbSAndy Whitcroft 18884635f4fbSAndy Whitcroft # Handle nested #if/#else. 188901464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 18904635f4fbSAndy Whitcroft push(@stack, $level); 189101464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 18924635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 189301464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 18944635f4fbSAndy Whitcroft $level = pop(@stack); 18954635f4fbSAndy Whitcroft } 18964635f4fbSAndy Whitcroft 189701464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1898f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1899f0a594c1SAndy Whitcroft if ($off > 0) { 1900f0a594c1SAndy Whitcroft $off--; 1901f0a594c1SAndy Whitcroft next; 1902f0a594c1SAndy Whitcroft } 19034a0df2efSAndy Whitcroft 1904f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1905f0a594c1SAndy Whitcroft $level--; 1906f0a594c1SAndy Whitcroft last if ($level == 0); 1907f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1908f0a594c1SAndy Whitcroft $level++; 1909f0a594c1SAndy Whitcroft } 1910f0a594c1SAndy Whitcroft } 19114a0df2efSAndy Whitcroft 1912f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 191300df344fSAndy Whitcroft push(@res, $rawlines[$line]); 19144a0df2efSAndy Whitcroft } 19154a0df2efSAndy Whitcroft 1916f0a594c1SAndy Whitcroft last if ($level == 0); 19174a0df2efSAndy Whitcroft } 19184a0df2efSAndy Whitcroft 1919f0a594c1SAndy Whitcroft return ($level, @res); 19204a0df2efSAndy Whitcroft} 19214a0df2efSAndy Whitcroftsub ctx_block_outer { 19224a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 19234a0df2efSAndy Whitcroft 1924f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1925f0a594c1SAndy Whitcroft return @r; 19264a0df2efSAndy Whitcroft} 19274a0df2efSAndy Whitcroftsub ctx_block { 19284a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 19294a0df2efSAndy Whitcroft 1930f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1931f0a594c1SAndy Whitcroft return @r; 1932653d4876SAndy Whitcroft} 1933653d4876SAndy Whitcroftsub ctx_statement { 1934f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1935f0a594c1SAndy Whitcroft 1936f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1937f0a594c1SAndy Whitcroft return @r; 1938f0a594c1SAndy Whitcroft} 1939f0a594c1SAndy Whitcroftsub ctx_block_level { 1940653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1941653d4876SAndy Whitcroft 1942f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 19434a0df2efSAndy Whitcroft} 19449c0ca6f9SAndy Whitcroftsub ctx_statement_level { 19459c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 19469c0ca6f9SAndy Whitcroft 19479c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 19489c0ca6f9SAndy Whitcroft} 19494a0df2efSAndy Whitcroft 19504a0df2efSAndy Whitcroftsub ctx_locate_comment { 19514a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 19524a0df2efSAndy Whitcroft 1953a55ee0ccSJoe Perches # If c99 comment on the current line, or the line before or after 1954a55ee0ccSJoe Perches my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); 1955a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1956a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); 1957a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1958a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); 1959a55ee0ccSJoe Perches return $current_comment if (defined $current_comment); 1960a55ee0ccSJoe Perches 19614a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1962a55ee0ccSJoe Perches ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 19634a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 19644a0df2efSAndy Whitcroft 19654a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 19664a0df2efSAndy Whitcroft # comment. 19674a0df2efSAndy Whitcroft my $in_comment = 0; 19684a0df2efSAndy Whitcroft $current_comment = ''; 19694a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 197000df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 197100df344fSAndy Whitcroft #warn " $line\n"; 19724a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 19734a0df2efSAndy Whitcroft $in_comment = 1; 19744a0df2efSAndy Whitcroft } 19754a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 19764a0df2efSAndy Whitcroft $in_comment = 1; 19774a0df2efSAndy Whitcroft } 19784a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 19794a0df2efSAndy Whitcroft $current_comment = ''; 19804a0df2efSAndy Whitcroft } 19814a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 19824a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 19834a0df2efSAndy Whitcroft $in_comment = 0; 19844a0df2efSAndy Whitcroft } 19854a0df2efSAndy Whitcroft } 19864a0df2efSAndy Whitcroft 19874a0df2efSAndy Whitcroft chomp($current_comment); 19884a0df2efSAndy Whitcroft return($current_comment); 19894a0df2efSAndy Whitcroft} 19904a0df2efSAndy Whitcroftsub ctx_has_comment { 19914a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 19924a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 19934a0df2efSAndy Whitcroft 199400df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 19954a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 19964a0df2efSAndy Whitcroft 19974a0df2efSAndy Whitcroft return ($cmt ne ''); 19984a0df2efSAndy Whitcroft} 19994a0df2efSAndy Whitcroft 20004d001e4dSAndy Whitcroftsub raw_line { 20014d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 20024d001e4dSAndy Whitcroft 20034d001e4dSAndy Whitcroft my $offset = $linenr - 1; 20044d001e4dSAndy Whitcroft $cnt++; 20054d001e4dSAndy Whitcroft 20064d001e4dSAndy Whitcroft my $line; 20074d001e4dSAndy Whitcroft while ($cnt) { 20084d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 20094d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 20104d001e4dSAndy Whitcroft $cnt--; 20114d001e4dSAndy Whitcroft } 20124d001e4dSAndy Whitcroft 20134d001e4dSAndy Whitcroft return $line; 20144d001e4dSAndy Whitcroft} 20154d001e4dSAndy Whitcroft 20162a9f9d85STobin C. Hardingsub get_stat_real { 20172a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 20182a9f9d85STobin C. Harding 20192a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 20202a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 20212a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 20222a9f9d85STobin C. Harding } 20232a9f9d85STobin C. Harding 20242a9f9d85STobin C. Harding return $stat_real; 20252a9f9d85STobin C. Harding} 20262a9f9d85STobin C. Harding 2027e3d95a2aSTobin C. Hardingsub get_stat_here { 2028e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 2029e3d95a2aSTobin C. Harding 2030e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 2031e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 2032e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 2033e3d95a2aSTobin C. Harding } 2034e3d95a2aSTobin C. Harding 2035e3d95a2aSTobin C. Harding return $herectx; 2036e3d95a2aSTobin C. Harding} 2037e3d95a2aSTobin C. Harding 20380a920b5bSAndy Whitcroftsub cat_vet { 20390a920b5bSAndy Whitcroft my ($vet) = @_; 20409c0ca6f9SAndy Whitcroft my ($res, $coded); 20410a920b5bSAndy Whitcroft 20429c0ca6f9SAndy Whitcroft $res = ''; 20436c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 20446c72ffaaSAndy Whitcroft $res .= $1; 20456c72ffaaSAndy Whitcroft if ($2 ne '') { 20469c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 20476c72ffaaSAndy Whitcroft $res .= $coded; 20486c72ffaaSAndy Whitcroft } 20499c0ca6f9SAndy Whitcroft } 20509c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 20510a920b5bSAndy Whitcroft 20529c0ca6f9SAndy Whitcroft return $res; 20530a920b5bSAndy Whitcroft} 20540a920b5bSAndy Whitcroft 2055c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 2056cf655043SAndy Whitcroftmy $av_pending; 2057c2fdda0dSAndy Whitcroftmy @av_paren_type; 20581f65f947SAndy Whitcroftmy $av_pend_colon; 2059c2fdda0dSAndy Whitcroft 2060c2fdda0dSAndy Whitcroftsub annotate_reset { 2061c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 2062cf655043SAndy Whitcroft $av_pending = '_'; 2063cf655043SAndy Whitcroft @av_paren_type = ('E'); 20641f65f947SAndy Whitcroft $av_pend_colon = 'O'; 2065c2fdda0dSAndy Whitcroft} 2066c2fdda0dSAndy Whitcroft 20676c72ffaaSAndy Whitcroftsub annotate_values { 20686c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 20696c72ffaaSAndy Whitcroft 20706c72ffaaSAndy Whitcroft my $res; 20711f65f947SAndy Whitcroft my $var = '_' x length($stream); 20726c72ffaaSAndy Whitcroft my $cur = $stream; 20736c72ffaaSAndy Whitcroft 2074c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 20756c72ffaaSAndy Whitcroft 20766c72ffaaSAndy Whitcroft while (length($cur)) { 2077773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 2078cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 2079171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 20806c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 2081c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 2082c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 2083cf655043SAndy Whitcroft $type = pop(@av_paren_type); 2084c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 20856c72ffaaSAndy Whitcroft } 20866c72ffaaSAndy Whitcroft 2087c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 20889446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 20899446ef56SAndy Whitcroft push(@av_paren_type, $type); 2090addcdceaSAndy Whitcroft $type = 'c'; 20919446ef56SAndy Whitcroft 2092e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 2093c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 20946c72ffaaSAndy Whitcroft $type = 'T'; 20956c72ffaaSAndy Whitcroft 2096389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 2097389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 2098389a2fe5SAndy Whitcroft $type = 'T'; 2099389a2fe5SAndy Whitcroft 2100c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 2101171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 2102c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2103171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 2104171ae1a4SAndy Whitcroft if ($2 ne '') { 2105cf655043SAndy Whitcroft $av_pending = 'N'; 2106171ae1a4SAndy Whitcroft } 2107171ae1a4SAndy Whitcroft $type = 'E'; 2108171ae1a4SAndy Whitcroft 2109c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 2110171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 2111171ae1a4SAndy Whitcroft $av_preprocessor = 1; 2112171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 21136c72ffaaSAndy Whitcroft 2114c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 2115cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 2116c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 2117cf655043SAndy Whitcroft 2118cf655043SAndy Whitcroft push(@av_paren_type, $type); 2119cf655043SAndy Whitcroft push(@av_paren_type, $type); 2120171ae1a4SAndy Whitcroft $type = 'E'; 2121cf655043SAndy Whitcroft 2122c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 2123cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 2124cf655043SAndy Whitcroft $av_preprocessor = 1; 2125cf655043SAndy Whitcroft 2126cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 2127cf655043SAndy Whitcroft 2128171ae1a4SAndy Whitcroft $type = 'E'; 2129cf655043SAndy Whitcroft 2130c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 2131cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 2132cf655043SAndy Whitcroft 2133cf655043SAndy Whitcroft $av_preprocessor = 1; 2134cf655043SAndy Whitcroft 2135cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 2136cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 2137cf655043SAndy Whitcroft pop(@av_paren_type); 2138cf655043SAndy Whitcroft push(@av_paren_type, $type); 2139171ae1a4SAndy Whitcroft $type = 'E'; 21406c72ffaaSAndy Whitcroft 21416c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 2142c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 21436c72ffaaSAndy Whitcroft 2144171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 2145171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 2146171ae1a4SAndy Whitcroft $av_pending = $type; 2147171ae1a4SAndy Whitcroft $type = 'N'; 2148171ae1a4SAndy Whitcroft 21496c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 2150c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 21516c72ffaaSAndy Whitcroft if (defined $2) { 2152cf655043SAndy Whitcroft $av_pending = 'V'; 21536c72ffaaSAndy Whitcroft } 21546c72ffaaSAndy Whitcroft $type = 'N'; 21556c72ffaaSAndy Whitcroft 215614b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 2157c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 215814b111c1SAndy Whitcroft $av_pending = 'E'; 21596c72ffaaSAndy Whitcroft $type = 'N'; 21606c72ffaaSAndy Whitcroft 21611f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 21621f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 21631f65f947SAndy Whitcroft $av_pend_colon = 'C'; 21641f65f947SAndy Whitcroft $type = 'N'; 21651f65f947SAndy Whitcroft 216614b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 2167c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 21686c72ffaaSAndy Whitcroft $type = 'N'; 21696c72ffaaSAndy Whitcroft 21706c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 2171c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 2172cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 2173cf655043SAndy Whitcroft $av_pending = '_'; 21746c72ffaaSAndy Whitcroft $type = 'N'; 21756c72ffaaSAndy Whitcroft 21766c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 2177cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 2178cf655043SAndy Whitcroft if ($new_type ne '_') { 2179cf655043SAndy Whitcroft $type = $new_type; 2180c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 2181c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 21826c72ffaaSAndy Whitcroft } else { 2183c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 21846c72ffaaSAndy Whitcroft } 21856c72ffaaSAndy Whitcroft 2186c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 2187c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 2188c8cb2ca3SAndy Whitcroft $type = 'V'; 2189cf655043SAndy Whitcroft $av_pending = 'V'; 21906c72ffaaSAndy Whitcroft 21918e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 21928e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 21931f65f947SAndy Whitcroft $av_pend_colon = 'B'; 21948e761b04SAndy Whitcroft } elsif ($type eq 'E') { 21958e761b04SAndy Whitcroft $av_pend_colon = 'L'; 21961f65f947SAndy Whitcroft } 21971f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 21981f65f947SAndy Whitcroft $type = 'V'; 21991f65f947SAndy Whitcroft 22006c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 2201c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 22026c72ffaaSAndy Whitcroft $type = 'V'; 22036c72ffaaSAndy Whitcroft 22046c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 2205c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 22066c72ffaaSAndy Whitcroft $type = 'N'; 22076c72ffaaSAndy Whitcroft 2208cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 2209c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 221013214adfSAndy Whitcroft $type = 'E'; 22111f65f947SAndy Whitcroft $av_pend_colon = 'O'; 221213214adfSAndy Whitcroft 22138e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 22148e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 22158e761b04SAndy Whitcroft $type = 'C'; 22168e761b04SAndy Whitcroft 22171f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 22181f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 22191f65f947SAndy Whitcroft $type = 'N'; 22201f65f947SAndy Whitcroft 22211f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 22221f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 22231f65f947SAndy Whitcroft 22241f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 22251f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 22261f65f947SAndy Whitcroft $type = 'E'; 22271f65f947SAndy Whitcroft } else { 22281f65f947SAndy Whitcroft $type = 'N'; 22291f65f947SAndy Whitcroft } 22301f65f947SAndy Whitcroft $av_pend_colon = 'O'; 22311f65f947SAndy Whitcroft 22328e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 223313214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 22346c72ffaaSAndy Whitcroft $type = 'N'; 22356c72ffaaSAndy Whitcroft 22360d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 223774048ed8SAndy Whitcroft my $variant; 223874048ed8SAndy Whitcroft 223974048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 224074048ed8SAndy Whitcroft if ($type eq 'V') { 224174048ed8SAndy Whitcroft $variant = 'B'; 224274048ed8SAndy Whitcroft } else { 224374048ed8SAndy Whitcroft $variant = 'U'; 224474048ed8SAndy Whitcroft } 224574048ed8SAndy Whitcroft 224674048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 224774048ed8SAndy Whitcroft $type = 'N'; 224874048ed8SAndy Whitcroft 22496c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 2250c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 22516c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 22526c72ffaaSAndy Whitcroft $type = 'N'; 22536c72ffaaSAndy Whitcroft } 22546c72ffaaSAndy Whitcroft 22556c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 2256c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 22576c72ffaaSAndy Whitcroft } 22586c72ffaaSAndy Whitcroft if (defined $1) { 22596c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 22606c72ffaaSAndy Whitcroft $res .= $type x length($1); 22616c72ffaaSAndy Whitcroft } 22626c72ffaaSAndy Whitcroft } 22636c72ffaaSAndy Whitcroft 22641f65f947SAndy Whitcroft return ($res, $var); 22656c72ffaaSAndy Whitcroft} 22666c72ffaaSAndy Whitcroft 22678905a67cSAndy Whitcroftsub possible { 226813214adfSAndy Whitcroft my ($possible, $line) = @_; 22699a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 22700776e594SAndy Whitcroft ^(?: 22710776e594SAndy Whitcroft $Modifier| 22720776e594SAndy Whitcroft $Storage| 22730776e594SAndy Whitcroft $Type| 22749a974fdbSAndy Whitcroft DEFINE_\S+ 22759a974fdbSAndy Whitcroft )$| 22769a974fdbSAndy Whitcroft ^(?: 22770776e594SAndy Whitcroft goto| 22780776e594SAndy Whitcroft return| 22790776e594SAndy Whitcroft case| 22800776e594SAndy Whitcroft else| 22810776e594SAndy Whitcroft asm|__asm__| 228289a88353SAndy Whitcroft do| 228389a88353SAndy Whitcroft \#| 228489a88353SAndy Whitcroft \#\#| 22859a974fdbSAndy Whitcroft )(?:\s|$)| 22860776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 22879a974fdbSAndy Whitcroft )}x; 22889a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 22899a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 2290c45dcabdSAndy Whitcroft # Check for modifiers. 2291c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 2292c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 2293c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 2294c45dcabdSAndy Whitcroft 2295c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 2296c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 2297d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 22989a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 2299d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 2300485ff23eSAlex Dowad push(@modifierListFile, $modifier); 2301d2506586SAndy Whitcroft } 23029a974fdbSAndy Whitcroft } 2303c45dcabdSAndy Whitcroft 2304c45dcabdSAndy Whitcroft } else { 230513214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 2306485ff23eSAlex Dowad push(@typeListFile, $possible); 2307c45dcabdSAndy Whitcroft } 23088905a67cSAndy Whitcroft build_types(); 23090776e594SAndy Whitcroft } else { 23100776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 23118905a67cSAndy Whitcroft } 23128905a67cSAndy Whitcroft} 23138905a67cSAndy Whitcroft 23146c72ffaaSAndy Whitcroftmy $prefix = ''; 23156c72ffaaSAndy Whitcroft 2316000d1cc1SJoe Perchessub show_type { 2317cbec18afSJoe Perches my ($type) = @_; 231891bfe484SJoe Perches 2319522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2320522b837cSAlexey Dobriyan 2321cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2322cbec18afSJoe Perches 2323cbec18afSJoe Perches return !defined $ignore_type{$type}; 2324000d1cc1SJoe Perches} 2325000d1cc1SJoe Perches 2326f0a594c1SAndy Whitcroftsub report { 2327cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2328cbec18afSJoe Perches 2329cbec18afSJoe Perches if (!show_type($type) || 2330cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2331773647a0SAndy Whitcroft return 0; 2332773647a0SAndy Whitcroft } 233357230297SJoe Perches my $output = ''; 2334737c0767SJohn Brooks if ($color) { 233557230297SJoe Perches if ($level eq 'ERROR') { 233657230297SJoe Perches $output .= RED; 233757230297SJoe Perches } elsif ($level eq 'WARNING') { 233857230297SJoe Perches $output .= YELLOW; 2339000d1cc1SJoe Perches } else { 234057230297SJoe Perches $output .= GREEN; 2341000d1cc1SJoe Perches } 234257230297SJoe Perches } 234357230297SJoe Perches $output .= $prefix . $level . ':'; 234457230297SJoe Perches if ($show_types) { 2345737c0767SJohn Brooks $output .= BLUE if ($color); 234657230297SJoe Perches $output .= "$type:"; 234757230297SJoe Perches } 2348737c0767SJohn Brooks $output .= RESET if ($color); 234957230297SJoe Perches $output .= ' ' . $msg . "\n"; 235034d8815fSJoe Perches 235134d8815fSJoe Perches if ($showfile) { 235234d8815fSJoe Perches my @lines = split("\n", $output, -1); 235334d8815fSJoe Perches splice(@lines, 1, 1); 235434d8815fSJoe Perches $output = join("\n", @lines); 235534d8815fSJoe Perches } 235652178ce0SDwaipayan Ray 235752178ce0SDwaipayan Ray if ($terse) { 235852178ce0SDwaipayan Ray $output = (split('\n', $output))[0] . "\n"; 235952178ce0SDwaipayan Ray } 236052178ce0SDwaipayan Ray 236152178ce0SDwaipayan Ray if ($verbose && exists($verbose_messages{$type}) && 236252178ce0SDwaipayan Ray !exists($verbose_emitted{$type})) { 236352178ce0SDwaipayan Ray $output .= $verbose_messages{$type} . "\n\n"; 236452178ce0SDwaipayan Ray $verbose_emitted{$type} = 1; 236552178ce0SDwaipayan Ray } 23668905a67cSAndy Whitcroft 236757230297SJoe Perches push(our @report, $output); 2368773647a0SAndy Whitcroft 2369773647a0SAndy Whitcroft return 1; 2370f0a594c1SAndy Whitcroft} 2371cbec18afSJoe Perches 2372f0a594c1SAndy Whitcroftsub report_dump { 237313214adfSAndy Whitcroft our @report; 2374f0a594c1SAndy Whitcroft} 2375000d1cc1SJoe Perches 2376d752fcc8SJoe Perchessub fixup_current_range { 2377d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2378d752fcc8SJoe Perches 2379d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2380d752fcc8SJoe Perches my $o = $1; 2381d752fcc8SJoe Perches my $l = $2; 2382d752fcc8SJoe Perches my $no = $o + $offset; 2383d752fcc8SJoe Perches my $nl = $l + $length; 2384d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2385d752fcc8SJoe Perches } 2386d752fcc8SJoe Perches} 2387d752fcc8SJoe Perches 2388d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2389d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2390d752fcc8SJoe Perches 2391d752fcc8SJoe Perches my $range_last_linenr = 0; 2392d752fcc8SJoe Perches my $delta_offset = 0; 2393d752fcc8SJoe Perches 2394d752fcc8SJoe Perches my $old_linenr = 0; 2395d752fcc8SJoe Perches my $new_linenr = 0; 2396d752fcc8SJoe Perches 2397d752fcc8SJoe Perches my $next_insert = 0; 2398d752fcc8SJoe Perches my $next_delete = 0; 2399d752fcc8SJoe Perches 2400d752fcc8SJoe Perches my @lines = (); 2401d752fcc8SJoe Perches 2402d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2403d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2404d752fcc8SJoe Perches 2405d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2406d752fcc8SJoe Perches my $save_line = 1; 2407d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2408323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2409d752fcc8SJoe Perches $delta_offset = 0; 2410d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2411d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2412d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2413d752fcc8SJoe Perches } 2414d752fcc8SJoe Perches 2415d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2416d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2417d752fcc8SJoe Perches $save_line = 0; 2418d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2419d752fcc8SJoe Perches } 2420d752fcc8SJoe Perches 2421d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2422d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2423d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2424d752fcc8SJoe Perches $new_linenr++; 2425d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2426d752fcc8SJoe Perches } 2427d752fcc8SJoe Perches 2428d752fcc8SJoe Perches if ($save_line) { 2429d752fcc8SJoe Perches push(@lines, $line); 2430d752fcc8SJoe Perches $new_linenr++; 2431d752fcc8SJoe Perches } 2432d752fcc8SJoe Perches 2433d752fcc8SJoe Perches $old_linenr++; 2434d752fcc8SJoe Perches } 2435d752fcc8SJoe Perches 2436d752fcc8SJoe Perches return @lines; 2437d752fcc8SJoe Perches} 2438d752fcc8SJoe Perches 2439f2d7e4d4SJoe Perchessub fix_insert_line { 2440f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2441f2d7e4d4SJoe Perches 2442f2d7e4d4SJoe Perches my $inserted = { 2443f2d7e4d4SJoe Perches LINENR => $linenr, 2444f2d7e4d4SJoe Perches LINE => $line, 2445f2d7e4d4SJoe Perches }; 2446f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2447f2d7e4d4SJoe Perches} 2448f2d7e4d4SJoe Perches 2449f2d7e4d4SJoe Perchessub fix_delete_line { 2450f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2451f2d7e4d4SJoe Perches 2452f2d7e4d4SJoe Perches my $deleted = { 2453f2d7e4d4SJoe Perches LINENR => $linenr, 2454f2d7e4d4SJoe Perches LINE => $line, 2455f2d7e4d4SJoe Perches }; 2456f2d7e4d4SJoe Perches 2457f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2458f2d7e4d4SJoe Perches} 2459f2d7e4d4SJoe Perches 2460de7d4f0eSAndy Whitcroftsub ERROR { 2461cbec18afSJoe Perches my ($type, $msg) = @_; 2462cbec18afSJoe Perches 2463cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2464de7d4f0eSAndy Whitcroft our $clean = 0; 24656c72ffaaSAndy Whitcroft our $cnt_error++; 24663705ce5bSJoe Perches return 1; 2467de7d4f0eSAndy Whitcroft } 24683705ce5bSJoe Perches return 0; 2469773647a0SAndy Whitcroft} 2470de7d4f0eSAndy Whitcroftsub WARN { 2471cbec18afSJoe Perches my ($type, $msg) = @_; 2472cbec18afSJoe Perches 2473cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2474de7d4f0eSAndy Whitcroft our $clean = 0; 24756c72ffaaSAndy Whitcroft our $cnt_warn++; 24763705ce5bSJoe Perches return 1; 2477de7d4f0eSAndy Whitcroft } 24783705ce5bSJoe Perches return 0; 2479773647a0SAndy Whitcroft} 2480de7d4f0eSAndy Whitcroftsub CHK { 2481cbec18afSJoe Perches my ($type, $msg) = @_; 2482cbec18afSJoe Perches 2483cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2484de7d4f0eSAndy Whitcroft our $clean = 0; 24856c72ffaaSAndy Whitcroft our $cnt_chk++; 24863705ce5bSJoe Perches return 1; 24876c72ffaaSAndy Whitcroft } 24883705ce5bSJoe Perches return 0; 2489de7d4f0eSAndy Whitcroft} 2490de7d4f0eSAndy Whitcroft 24916ecd9674SAndy Whitcroftsub check_absolute_file { 24926ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 24936ecd9674SAndy Whitcroft my $file = $absolute; 24946ecd9674SAndy Whitcroft 24956ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 24966ecd9674SAndy Whitcroft 24976ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 24986ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 24996ecd9674SAndy Whitcroft if (-f "$root/$file") { 25006ecd9674SAndy Whitcroft ##print "file<$file>\n"; 25016ecd9674SAndy Whitcroft last; 25026ecd9674SAndy Whitcroft } 25036ecd9674SAndy Whitcroft } 25046ecd9674SAndy Whitcroft if (! -f _) { 25056ecd9674SAndy Whitcroft return 0; 25066ecd9674SAndy Whitcroft } 25076ecd9674SAndy Whitcroft 25086ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 25096ecd9674SAndy Whitcroft my $prefix = $absolute; 25106ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 25116ecd9674SAndy Whitcroft 25126ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 25136ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2514000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2515000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 25166ecd9674SAndy Whitcroft } 25176ecd9674SAndy Whitcroft} 25186ecd9674SAndy Whitcroft 25193705ce5bSJoe Perchessub trim { 25203705ce5bSJoe Perches my ($string) = @_; 25213705ce5bSJoe Perches 2522b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2523b34c648bSJoe Perches 2524b34c648bSJoe Perches return $string; 2525b34c648bSJoe Perches} 2526b34c648bSJoe Perches 2527b34c648bSJoe Perchessub ltrim { 2528b34c648bSJoe Perches my ($string) = @_; 2529b34c648bSJoe Perches 2530b34c648bSJoe Perches $string =~ s/^\s+//; 2531b34c648bSJoe Perches 2532b34c648bSJoe Perches return $string; 2533b34c648bSJoe Perches} 2534b34c648bSJoe Perches 2535b34c648bSJoe Perchessub rtrim { 2536b34c648bSJoe Perches my ($string) = @_; 2537b34c648bSJoe Perches 2538b34c648bSJoe Perches $string =~ s/\s+$//; 25393705ce5bSJoe Perches 25403705ce5bSJoe Perches return $string; 25413705ce5bSJoe Perches} 25423705ce5bSJoe Perches 254352ea8506SJoe Perchessub string_find_replace { 254452ea8506SJoe Perches my ($string, $find, $replace) = @_; 254552ea8506SJoe Perches 254652ea8506SJoe Perches $string =~ s/$find/$replace/g; 254752ea8506SJoe Perches 254852ea8506SJoe Perches return $string; 254952ea8506SJoe Perches} 255052ea8506SJoe Perches 25513705ce5bSJoe Perchessub tabify { 25523705ce5bSJoe Perches my ($leading) = @_; 25533705ce5bSJoe Perches 2554713a09deSAntonio Borneo my $source_indent = $tabsize; 25553705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 25563705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 25573705ce5bSJoe Perches 25583705ce5bSJoe Perches #convert leading spaces to tabs 25593705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 25603705ce5bSJoe Perches #Remove spaces before a tab 25613705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 25623705ce5bSJoe Perches 25633705ce5bSJoe Perches return "$leading"; 25643705ce5bSJoe Perches} 25653705ce5bSJoe Perches 2566d1fe9c09SJoe Perchessub pos_last_openparen { 2567d1fe9c09SJoe Perches my ($line) = @_; 2568d1fe9c09SJoe Perches 2569d1fe9c09SJoe Perches my $pos = 0; 2570d1fe9c09SJoe Perches 2571d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2572d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2573d1fe9c09SJoe Perches 2574d1fe9c09SJoe Perches my $last_openparen = 0; 2575d1fe9c09SJoe Perches 2576d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2577d1fe9c09SJoe Perches return -1; 2578d1fe9c09SJoe Perches } 2579d1fe9c09SJoe Perches 2580d1fe9c09SJoe Perches my $len = length($line); 2581d1fe9c09SJoe Perches 2582d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2583d1fe9c09SJoe Perches my $string = substr($line, $pos); 2584d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2585d1fe9c09SJoe Perches $pos += length($1) - 1; 2586d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2587d1fe9c09SJoe Perches $last_openparen = $pos; 2588d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2589d1fe9c09SJoe Perches last; 2590d1fe9c09SJoe Perches } 2591d1fe9c09SJoe Perches } 2592d1fe9c09SJoe Perches 259391cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2594d1fe9c09SJoe Perches} 2595d1fe9c09SJoe Perches 2596f36d3eb8SJoe Perchessub get_raw_comment { 2597f36d3eb8SJoe Perches my ($line, $rawline) = @_; 2598f36d3eb8SJoe Perches my $comment = ''; 2599f36d3eb8SJoe Perches 2600f36d3eb8SJoe Perches for my $i (0 .. (length($line) - 1)) { 2601f36d3eb8SJoe Perches if (substr($line, $i, 1) eq "$;") { 2602f36d3eb8SJoe Perches $comment .= substr($rawline, $i, 1); 2603f36d3eb8SJoe Perches } 2604f36d3eb8SJoe Perches } 2605f36d3eb8SJoe Perches 2606f36d3eb8SJoe Perches return $comment; 2607f36d3eb8SJoe Perches} 2608f36d3eb8SJoe Perches 26095b8f82e1SSong Liusub exclude_global_initialisers { 26105b8f82e1SSong Liu my ($realfile) = @_; 26115b8f82e1SSong Liu 26125b8f82e1SSong Liu # Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c). 26135b8f82e1SSong Liu return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ || 26145b8f82e1SSong Liu $realfile =~ m@^samples/bpf/.*_kern\.c$@ || 26155b8f82e1SSong Liu $realfile =~ m@/bpf/.*\.bpf\.c$@; 26165b8f82e1SSong Liu} 26175b8f82e1SSong Liu 26180a920b5bSAndy Whitcroftsub process { 26190a920b5bSAndy Whitcroft my $filename = shift; 26200a920b5bSAndy Whitcroft 26210a920b5bSAndy Whitcroft my $linenr=0; 26220a920b5bSAndy Whitcroft my $prevline=""; 2623c2fdda0dSAndy Whitcroft my $prevrawline=""; 26240a920b5bSAndy Whitcroft my $stashline=""; 2625c2fdda0dSAndy Whitcroft my $stashrawline=""; 26260a920b5bSAndy Whitcroft 26274a0df2efSAndy Whitcroft my $length; 26280a920b5bSAndy Whitcroft my $indent; 26290a920b5bSAndy Whitcroft my $previndent=0; 26300a920b5bSAndy Whitcroft my $stashindent=0; 26310a920b5bSAndy Whitcroft 2632de7d4f0eSAndy Whitcroft our $clean = 1; 26330a920b5bSAndy Whitcroft my $signoff = 0; 2634d5d6281aSDan Carpenter my $fixes_tag = 0; 2635d5d6281aSDan Carpenter my $is_revert = 0; 2636d5d6281aSDan Carpenter my $needs_fixes_tag = ""; 2637cd261496SGeert Uytterhoeven my $author = ''; 2638cd261496SGeert Uytterhoeven my $authorsignoff = 0; 263948ca2d8aSDwaipayan Ray my $author_sob = ''; 26400a920b5bSAndy Whitcroft my $is_patch = 0; 2641133712a2SRob Herring my $is_binding_patch = -1; 264229ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 264315662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 264444d303ebSJoe Perches my $has_patch_separator = 0; #Found a --- line 2645ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2646490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2647bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 26482a076f40SJoe Perches my $commit_log_long_line = 0; 2649e518e9a5SJoe Perches my $commit_log_has_diff = 0; 265013f1937eSJoe Perches my $reported_maintainer_file = 0; 2651fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2652fa64205dSPasi Savanainen 26534ce9f970SJoe Perches my $last_git_commit_id_linenr = -1; 26544ce9f970SJoe Perches 2655365dd4eaSJoe Perches my $last_blank_line = 0; 26565e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2657365dd4eaSJoe Perches 265813214adfSAndy Whitcroft our @report = (); 26596c72ffaaSAndy Whitcroft our $cnt_lines = 0; 26606c72ffaaSAndy Whitcroft our $cnt_error = 0; 26616c72ffaaSAndy Whitcroft our $cnt_warn = 0; 26626c72ffaaSAndy Whitcroft our $cnt_chk = 0; 26636c72ffaaSAndy Whitcroft 26640a920b5bSAndy Whitcroft # Trace the real file/line as we go. 26650a920b5bSAndy Whitcroft my $realfile = ''; 26660a920b5bSAndy Whitcroft my $realline = 0; 26670a920b5bSAndy Whitcroft my $realcnt = 0; 26680a920b5bSAndy Whitcroft my $here = ''; 266977cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 26700a920b5bSAndy Whitcroft my $in_comment = 0; 2671c2fdda0dSAndy Whitcroft my $comment_edge = 0; 26720a920b5bSAndy Whitcroft my $first_line = 0; 26731e855726SWolfram Sang my $p1_prefix = ''; 26740a920b5bSAndy Whitcroft 267513214adfSAndy Whitcroft my $prev_values = 'E'; 267613214adfSAndy Whitcroft 267713214adfSAndy Whitcroft # suppression flags 2678773647a0SAndy Whitcroft my %suppress_ifbraces; 2679170d3a22SAndy Whitcroft my %suppress_whiletrailers; 26802b474a1aSAndy Whitcroft my %suppress_export; 26813e469cdcSAndy Whitcroft my $suppress_statement = 0; 2682653d4876SAndy Whitcroft 26837e51f197SJoe Perches my %signatures = (); 2684323c1260SJoe Perches 2685c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2686de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2687c2fdda0dSAndy Whitcroft # 2688de7d4f0eSAndy Whitcroft my @setup_docs = (); 2689de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2690773647a0SAndy Whitcroft 2691d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2692d8b07710SJoe Perches 26939f3a8992SRob Herring my $checklicenseline = 1; 26949f3a8992SRob Herring 2695773647a0SAndy Whitcroft sanitise_line_reset(); 2696c2fdda0dSAndy Whitcroft my $line; 2697c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2698773647a0SAndy Whitcroft $linenr++; 2699773647a0SAndy Whitcroft $line = $rawline; 2700c2fdda0dSAndy Whitcroft 27013705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 27023705ce5bSJoe Perches 2703773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2704de7d4f0eSAndy Whitcroft $setup_docs = 0; 27052581ac7cSTim Froidcoeur if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { 2706de7d4f0eSAndy Whitcroft $setup_docs = 1; 2707de7d4f0eSAndy Whitcroft } 2708773647a0SAndy Whitcroft #next; 2709de7d4f0eSAndy Whitcroft } 271074fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2711773647a0SAndy Whitcroft $realline=$1-1; 2712773647a0SAndy Whitcroft if (defined $2) { 2713773647a0SAndy Whitcroft $realcnt=$3+1; 2714773647a0SAndy Whitcroft } else { 2715773647a0SAndy Whitcroft $realcnt=1+1; 2716773647a0SAndy Whitcroft } 2717c45dcabdSAndy Whitcroft $in_comment = 0; 2718773647a0SAndy Whitcroft 2719773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2720773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2721773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2722773647a0SAndy Whitcroft # at context start. 2723773647a0SAndy Whitcroft my $edge; 272401fa9147SAndy Whitcroft my $cnt = $realcnt; 272501fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 272601fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 272701fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 272801fa9147SAndy Whitcroft $cnt--; 272901fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2730721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2731fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2732fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2733fae17daeSAndy Whitcroft ($edge) = $1; 2734fae17daeSAndy Whitcroft last; 2735fae17daeSAndy Whitcroft } 2736773647a0SAndy Whitcroft } 2737773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2738773647a0SAndy Whitcroft $in_comment = 1; 2739773647a0SAndy Whitcroft } 2740773647a0SAndy Whitcroft 2741773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2742773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2743773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2744773647a0SAndy Whitcroft if (!defined $edge && 274583242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2746773647a0SAndy Whitcroft { 2747773647a0SAndy Whitcroft $in_comment = 1; 2748773647a0SAndy Whitcroft } 2749773647a0SAndy Whitcroft 2750773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2751773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2752773647a0SAndy Whitcroft 2753171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2754773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2755171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2756773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2757773647a0SAndy Whitcroft } 2758773647a0SAndy Whitcroft push(@lines, $line); 2759773647a0SAndy Whitcroft 2760773647a0SAndy Whitcroft if ($realcnt > 1) { 2761773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2762773647a0SAndy Whitcroft } else { 2763773647a0SAndy Whitcroft $realcnt = 0; 2764773647a0SAndy Whitcroft } 2765773647a0SAndy Whitcroft 2766773647a0SAndy Whitcroft #print "==>$rawline\n"; 2767773647a0SAndy Whitcroft #print "-->$line\n"; 2768de7d4f0eSAndy Whitcroft 2769de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2770de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2771de7d4f0eSAndy Whitcroft } 2772de7d4f0eSAndy Whitcroft } 2773de7d4f0eSAndy Whitcroft 27746c72ffaaSAndy Whitcroft $prefix = ''; 27756c72ffaaSAndy Whitcroft 2776773647a0SAndy Whitcroft $realcnt = 0; 2777773647a0SAndy Whitcroft $linenr = 0; 2778194f66fcSJoe Perches $fixlinenr = -1; 27790a920b5bSAndy Whitcroft foreach my $line (@lines) { 27800a920b5bSAndy Whitcroft $linenr++; 2781194f66fcSJoe Perches $fixlinenr++; 27821b5539b1SJoe Perches my $sline = $line; #copy of $line 27831b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 27840a920b5bSAndy Whitcroft 2785c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 2786f36d3eb8SJoe Perches my $raw_comment = get_raw_comment($line, $rawline); 27876c72ffaaSAndy Whitcroft 278812c253abSJoe Perches# check if it's a mode change, rename or start of a patch 278912c253abSJoe Perches if (!$in_commit_log && 279012c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 279112c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 279212c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 279312c253abSJoe Perches $is_patch = 1; 279412c253abSJoe Perches } 279512c253abSJoe Perches 27960a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2797e518e9a5SJoe Perches if (!$in_commit_log && 279874fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 279974fd4f34SJoe Perches my $context = $4; 28000a920b5bSAndy Whitcroft $is_patch = 1; 28014a0df2efSAndy Whitcroft $first_line = $linenr + 1; 28020a920b5bSAndy Whitcroft $realline=$1-1; 28030a920b5bSAndy Whitcroft if (defined $2) { 28040a920b5bSAndy Whitcroft $realcnt=$3+1; 28050a920b5bSAndy Whitcroft } else { 28060a920b5bSAndy Whitcroft $realcnt=1+1; 28070a920b5bSAndy Whitcroft } 2808c2fdda0dSAndy Whitcroft annotate_reset(); 280913214adfSAndy Whitcroft $prev_values = 'E'; 281013214adfSAndy Whitcroft 2811773647a0SAndy Whitcroft %suppress_ifbraces = (); 2812170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 28132b474a1aSAndy Whitcroft %suppress_export = (); 28143e469cdcSAndy Whitcroft $suppress_statement = 0; 281574fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 281674fd4f34SJoe Perches $context_function = $1; 281774fd4f34SJoe Perches } else { 281874fd4f34SJoe Perches undef $context_function; 281974fd4f34SJoe Perches } 28200a920b5bSAndy Whitcroft next; 28210a920b5bSAndy Whitcroft 28224a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 28234a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 28244a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2825773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 28260a920b5bSAndy Whitcroft $realline++; 2827d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 28280a920b5bSAndy Whitcroft 28294a0df2efSAndy Whitcroft # Measure the line length and indent. 2830c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 28310a920b5bSAndy Whitcroft 28320a920b5bSAndy Whitcroft # Track the previous line. 28330a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 28340a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2835c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2836c2fdda0dSAndy Whitcroft 2837773647a0SAndy Whitcroft #warn "line<$line>\n"; 28386c72ffaaSAndy Whitcroft 2839d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2840d8aaf121SAndy Whitcroft $realcnt--; 28410a920b5bSAndy Whitcroft } 28420a920b5bSAndy Whitcroft 2843cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2844cc77cdcaSAndy Whitcroft 28456c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 28466c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2847773647a0SAndy Whitcroft 28482ac73b4fSJoe Perches my $found_file = 0; 2849773647a0SAndy Whitcroft # extract the filename as it passes 28503bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 28513bf9a009SRabin Vincent $realfile = $1; 28522b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2853270c49a0SJoe Perches $in_commit_log = 0; 28542ac73b4fSJoe Perches $found_file = 1; 28553bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2856773647a0SAndy Whitcroft $realfile = $1; 28572b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2858270c49a0SJoe Perches $in_commit_log = 0; 28591e855726SWolfram Sang 28601e855726SWolfram Sang $p1_prefix = $1; 2861e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2862e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2863000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2864000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 28651e855726SWolfram Sang } 2866773647a0SAndy Whitcroft 2867c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2868000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 286910d27111SGeert Uytterhoeven "do not modify files in include/asm, change architecture specific files in arch/<architecture>/include/asm\n" . "$here$rawline\n"); 2870773647a0SAndy Whitcroft } 28712ac73b4fSJoe Perches $found_file = 1; 28722ac73b4fSJoe Perches } 28732ac73b4fSJoe Perches 287434d8815fSJoe Perches#make up the handle for any error we report on this line 287534d8815fSJoe Perches if ($showfile) { 287634d8815fSJoe Perches $prefix = "$realfile:$realline: " 287734d8815fSJoe Perches } elsif ($emacs) { 28787d3a9f67SJoe Perches if ($file) { 28797d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 28807d3a9f67SJoe Perches } else { 288134d8815fSJoe Perches $prefix = "$filename:$linenr: "; 288234d8815fSJoe Perches } 28837d3a9f67SJoe Perches } 288434d8815fSJoe Perches 28852ac73b4fSJoe Perches if ($found_file) { 288685b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 288785b0ee18SJoe Perches WARN("OBSOLETE", 288885b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 288985b0ee18SJoe Perches } 28907bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 28912ac73b4fSJoe Perches $check = 1; 28922ac73b4fSJoe Perches } else { 28932ac73b4fSJoe Perches $check = $check_orig; 28942ac73b4fSJoe Perches } 28959f3a8992SRob Herring $checklicenseline = 1; 2896133712a2SRob Herring 2897133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2898133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2899133712a2SRob Herring 2900133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2901133712a2SRob Herring 2902133712a2SRob Herring if (($last_binding_patch != -1) && 2903133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2904133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2905858e6845SMauro Carvalho Chehab "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); 2906133712a2SRob Herring } 2907133712a2SRob Herring } 2908133712a2SRob Herring 2909773647a0SAndy Whitcroft next; 2910773647a0SAndy Whitcroft } 2911773647a0SAndy Whitcroft 2912389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 29130a920b5bSAndy Whitcroft 2914c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2915c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2916c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 29170a920b5bSAndy Whitcroft 29186c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 29196c72ffaaSAndy Whitcroft 2920490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2921490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2922490b292cSJoe Perches if ($in_commit_log) { 2923490b292cSJoe Perches if ($line !~ /^\s*$/) { 2924490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2925490b292cSJoe Perches } 2926490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2927490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2928490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2929490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2930490b292cSJoe Perches } 2931490b292cSJoe Perches 2932e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2933e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 293413e45417SMrinal Pandey (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && 293513e45417SMrinal Pandey $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || 2936e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2937e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2938e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2939e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2940e518e9a5SJoe Perches $commit_log_has_diff = 1; 2941e518e9a5SJoe Perches } 2942e518e9a5SJoe Perches 29433bf9a009SRabin Vincent# Check for incorrect file permissions 29443bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 29453bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 294604db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 294704db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2948000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2949000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 29503bf9a009SRabin Vincent } 29513bf9a009SRabin Vincent } 29523bf9a009SRabin Vincent 2953cd261496SGeert Uytterhoeven# Check the patch for a From: 2954cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2955cd261496SGeert Uytterhoeven $author = $1; 2956e7f929f3SDwaipayan Ray my $curline = $linenr; 2957e7f929f3SDwaipayan Ray while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { 2958e7f929f3SDwaipayan Ray $author .= $1; 2959e7f929f3SDwaipayan Ray } 2960cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2961cd261496SGeert Uytterhoeven $author =~ s/"//g; 2962dfa05c28SJoe Perches $author = reformat_email($author); 2963cd261496SGeert Uytterhoeven } 2964cd261496SGeert Uytterhoeven 296520112475SJoe Perches# Check the patch for a signoff: 2966dfa05c28SJoe Perches if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { 29674a0df2efSAndy Whitcroft $signoff++; 296815662b3eSJoe Perches $in_commit_log = 0; 296948ca2d8aSDwaipayan Ray if ($author ne '' && $authorsignoff != 1) { 2970fccaebf0SDwaipayan Ray if (same_email_addresses($1, $author)) { 2971cd261496SGeert Uytterhoeven $authorsignoff = 1; 297248ca2d8aSDwaipayan Ray } else { 297348ca2d8aSDwaipayan Ray my $ctx = $1; 297448ca2d8aSDwaipayan Ray my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); 297548ca2d8aSDwaipayan Ray my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); 297648ca2d8aSDwaipayan Ray 2977046fc741SMimi Zohar if (lc $email_address eq lc $author_address && $email_name eq $author_name) { 297848ca2d8aSDwaipayan Ray $author_sob = $ctx; 297948ca2d8aSDwaipayan Ray $authorsignoff = 2; 2980046fc741SMimi Zohar } elsif (lc $email_address eq lc $author_address) { 298148ca2d8aSDwaipayan Ray $author_sob = $ctx; 298248ca2d8aSDwaipayan Ray $authorsignoff = 3; 298348ca2d8aSDwaipayan Ray } elsif ($email_name eq $author_name) { 298448ca2d8aSDwaipayan Ray $author_sob = $ctx; 298548ca2d8aSDwaipayan Ray $authorsignoff = 4; 298648ca2d8aSDwaipayan Ray 298748ca2d8aSDwaipayan Ray my $address1 = $email_address; 298848ca2d8aSDwaipayan Ray my $address2 = $author_address; 298948ca2d8aSDwaipayan Ray 299048ca2d8aSDwaipayan Ray if ($address1 =~ /(\S+)\+\S+(\@.*)/) { 299148ca2d8aSDwaipayan Ray $address1 = "$1$2"; 299248ca2d8aSDwaipayan Ray } 299348ca2d8aSDwaipayan Ray if ($address2 =~ /(\S+)\+\S+(\@.*)/) { 299448ca2d8aSDwaipayan Ray $address2 = "$1$2"; 299548ca2d8aSDwaipayan Ray } 299648ca2d8aSDwaipayan Ray if ($address1 eq $address2) { 299748ca2d8aSDwaipayan Ray $authorsignoff = 5; 299848ca2d8aSDwaipayan Ray } 299948ca2d8aSDwaipayan Ray } 3000cd261496SGeert Uytterhoeven } 3001cd261496SGeert Uytterhoeven } 30020a920b5bSAndy Whitcroft } 300320112475SJoe Perches 300444d303ebSJoe Perches# Check for patch separator 300544d303ebSJoe Perches if ($line =~ /^---$/) { 300644d303ebSJoe Perches $has_patch_separator = 1; 300744d303ebSJoe Perches $in_commit_log = 0; 300844d303ebSJoe Perches } 300944d303ebSJoe Perches 3010e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 3011e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 3012e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 3013e0d975b1SJoe Perches $reported_maintainer_file = 1; 3014e0d975b1SJoe Perches } 3015e0d975b1SJoe Perches 301620112475SJoe Perches# Check signature styles 3017270c49a0SJoe Perches if (!$in_header_lines && 3018ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 301920112475SJoe Perches my $space_before = $1; 302020112475SJoe Perches my $sign_off = $2; 302120112475SJoe Perches my $space_after = $3; 302220112475SJoe Perches my $email = $4; 302320112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 302420112475SJoe Perches 3025ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 3026831242abSAditya Srivastava my $suggested_signature = find_standard_signature($sign_off); 3027831242abSAditya Srivastava if ($suggested_signature eq "") { 3028ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 3029ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 3030831242abSAditya Srivastava } else { 3031831242abSAditya Srivastava if (WARN("BAD_SIGN_OFF", 3032831242abSAditya Srivastava "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) && 3033831242abSAditya Srivastava $fix) { 3034831242abSAditya Srivastava $fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/; 3035831242abSAditya Srivastava } 3036831242abSAditya Srivastava } 3037ce0338dfSJoe Perches } 303820112475SJoe Perches if (defined $space_before && $space_before ne "") { 30393705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30403705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 30413705ce5bSJoe Perches $fix) { 3042194f66fcSJoe Perches $fixed[$fixlinenr] = 30433705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30443705ce5bSJoe Perches } 304520112475SJoe Perches } 304620112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 30473705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30483705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 30493705ce5bSJoe Perches $fix) { 3050194f66fcSJoe Perches $fixed[$fixlinenr] = 30513705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30523705ce5bSJoe Perches } 30533705ce5bSJoe Perches 305420112475SJoe Perches } 305520112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 30563705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 30573705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 30583705ce5bSJoe Perches $fix) { 3059194f66fcSJoe Perches $fixed[$fixlinenr] = 30603705ce5bSJoe Perches "$ucfirst_sign_off $email"; 30613705ce5bSJoe Perches } 306220112475SJoe Perches } 306320112475SJoe Perches 3064dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 306548ca2d8aSDwaipayan Ray my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); 306620112475SJoe Perches if ($suggested_email eq "") { 3067000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 3068000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 306920112475SJoe Perches } else { 307020112475SJoe Perches my $dequoted = $suggested_email; 307120112475SJoe Perches $dequoted =~ s/^"//; 307220112475SJoe Perches $dequoted =~ s/" </ </; 307320112475SJoe Perches # Don't force email to have quotes 307420112475SJoe Perches # Allow just an angle bracketed address 3075fccaebf0SDwaipayan Ray if (!same_email_addresses($email, $suggested_email)) { 3076fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3077fccaebf0SDwaipayan Ray "email address '$email' might be better as '$suggested_email'\n" . $herecurr) && 3078fccaebf0SDwaipayan Ray $fix) { 3079fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/; 3080fccaebf0SDwaipayan Ray } 3081fccaebf0SDwaipayan Ray } 3082fccaebf0SDwaipayan Ray 3083fccaebf0SDwaipayan Ray # Address part shouldn't have comments 3084fccaebf0SDwaipayan Ray my $stripped_address = $email_address; 3085fccaebf0SDwaipayan Ray $stripped_address =~ s/\([^\(\)]*\)//g; 3086fccaebf0SDwaipayan Ray if ($email_address ne $stripped_address) { 3087fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3088fccaebf0SDwaipayan Ray "address part of email should not have comments: '$email_address'\n" . $herecurr) && 3089fccaebf0SDwaipayan Ray $fix) { 3090fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/; 3091fccaebf0SDwaipayan Ray } 3092fccaebf0SDwaipayan Ray } 3093fccaebf0SDwaipayan Ray 3094fccaebf0SDwaipayan Ray # Only one name comment should be allowed 3095fccaebf0SDwaipayan Ray my $comment_count = () = $name_comment =~ /\([^\)]+\)/g; 3096fccaebf0SDwaipayan Ray if ($comment_count > 1) { 3097000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 3098fccaebf0SDwaipayan Ray "Use a single name comment in email: '$email'\n" . $herecurr); 3099fccaebf0SDwaipayan Ray } 3100fccaebf0SDwaipayan Ray 3101fccaebf0SDwaipayan Ray 3102fccaebf0SDwaipayan Ray # [email protected] or [email protected] shouldn't 3103e73d2715SDwaipayan Ray # have an email name. In addition comments should strictly 3104fccaebf0SDwaipayan Ray # begin with a # 3105fccaebf0SDwaipayan Ray if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) { 3106fccaebf0SDwaipayan Ray if (($comment ne "" && $comment !~ /^#.+/) || 3107fccaebf0SDwaipayan Ray ($email_name ne "")) { 3108fccaebf0SDwaipayan Ray my $cur_name = $email_name; 3109fccaebf0SDwaipayan Ray my $new_comment = $comment; 3110fccaebf0SDwaipayan Ray $cur_name =~ s/[a-zA-Z\s\-\"]+//g; 3111fccaebf0SDwaipayan Ray 3112fccaebf0SDwaipayan Ray # Remove brackets enclosing comment text 3113fccaebf0SDwaipayan Ray # and # from start of comments to get comment text 3114fccaebf0SDwaipayan Ray $new_comment =~ s/^\((.*)\)$/$1/; 3115fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3116fccaebf0SDwaipayan Ray $new_comment =~ s/^[\s\#]+|\s+$//g; 3117fccaebf0SDwaipayan Ray 3118fccaebf0SDwaipayan Ray $new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment); 3119fccaebf0SDwaipayan Ray $new_comment = " # $new_comment" if ($new_comment ne ""); 3120fccaebf0SDwaipayan Ray my $new_email = "$email_address$new_comment"; 3121fccaebf0SDwaipayan Ray 3122fccaebf0SDwaipayan Ray if (WARN("BAD_STABLE_ADDRESS_STYLE", 3123fccaebf0SDwaipayan Ray "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) && 3124fccaebf0SDwaipayan Ray $fix) { 3125fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3126fccaebf0SDwaipayan Ray } 3127fccaebf0SDwaipayan Ray } 3128fccaebf0SDwaipayan Ray } elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) { 3129fccaebf0SDwaipayan Ray my $new_comment = $comment; 3130fccaebf0SDwaipayan Ray 3131fccaebf0SDwaipayan Ray # Extract comment text from within brackets or 3132fccaebf0SDwaipayan Ray # c89 style /*...*/ comments 3133fccaebf0SDwaipayan Ray $new_comment =~ s/^\[(.*)\]$/$1/; 3134fccaebf0SDwaipayan Ray $new_comment =~ s/^\/\*(.*)\*\/$/$1/; 3135fccaebf0SDwaipayan Ray 3136fccaebf0SDwaipayan Ray $new_comment = trim($new_comment); 3137fccaebf0SDwaipayan Ray $new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo 3138fccaebf0SDwaipayan Ray $new_comment = "($new_comment)" if ($new_comment ne ""); 3139fccaebf0SDwaipayan Ray my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); 3140fccaebf0SDwaipayan Ray 3141fccaebf0SDwaipayan Ray if (WARN("BAD_SIGN_OFF", 3142fccaebf0SDwaipayan Ray "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) && 3143fccaebf0SDwaipayan Ray $fix) { 3144fccaebf0SDwaipayan Ray $fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/; 3145fccaebf0SDwaipayan Ray } 314620112475SJoe Perches } 31470a920b5bSAndy Whitcroft } 31487e51f197SJoe Perches 31497e51f197SJoe Perches# Check for duplicate signatures 31507e51f197SJoe Perches my $sig_nospace = $line; 31517e51f197SJoe Perches $sig_nospace =~ s/\s//g; 31527e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 31537e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 31547e51f197SJoe Perches WARN("BAD_SIGN_OFF", 31557e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 31567e51f197SJoe Perches } else { 31577e51f197SJoe Perches $signatures{$sig_nospace} = 1; 31587e51f197SJoe Perches } 31596c5d24eeSSean Christopherson 31606c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 31616c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 31626c5d24eeSSean Christopherson if ($email eq $author) { 31636c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31641916f777SThorsten Leemhuis "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . $herecurr); 31656c5d24eeSSean Christopherson } 31666c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 31676c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31681916f777SThorsten Leemhuis "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr); 31691916f777SThorsten Leemhuis } elsif ($rawlines[$linenr] !~ /^signed-off-by:\s*(.*)/i) { 31706c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31711916f777SThorsten Leemhuis "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr . $rawlines[$linenr] . "\n"); 31726c5d24eeSSean Christopherson } elsif ($1 ne $email) { 31736c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 31741916f777SThorsten Leemhuis "Co-developed-by and Signed-off-by: name/email do not match\n" . $herecurr . $rawlines[$linenr] . "\n"); 31756c5d24eeSSean Christopherson } 31766c5d24eeSSean Christopherson } 3177d7f1d71eSKai Wasserbäch 317844c31888SMatthieu Baerts# check if Reported-by: is followed by a Closes: tag 3179d7f1d71eSKai Wasserbäch if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) { 3180d7f1d71eSKai Wasserbäch if (!defined $lines[$linenr]) { 3181d7f1d71eSKai Wasserbäch WARN("BAD_REPORTED_BY_LINK", 318244c31888SMatthieu Baerts "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . "\n"); 3183d6ccdd67SMatthieu Baerts } elsif ($rawlines[$linenr] !~ /^closes:\s*/i) { 3184d7f1d71eSKai Wasserbäch WARN("BAD_REPORTED_BY_LINK", 318544c31888SMatthieu Baerts "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n"); 31860a920b5bSAndy Whitcroft } 3187d7f1d71eSKai Wasserbäch } 3188d7f1d71eSKai Wasserbäch } 3189d7f1d71eSKai Wasserbäch 3190d5d6281aSDan Carpenter# These indicate a bug fix 3191d5d6281aSDan Carpenter if (!$in_header_lines && !$is_patch && 3192d5d6281aSDan Carpenter $line =~ /^This reverts commit/) { 3193d5d6281aSDan Carpenter $is_revert = 1; 3194d5d6281aSDan Carpenter } 3195d5d6281aSDan Carpenter 3196d5d6281aSDan Carpenter if (!$in_header_lines && !$is_patch && 3197d5d6281aSDan Carpenter $line =~ /((?:(?:BUG: K.|UB)SAN: |Call Trace:|stable\@|syzkaller))/) { 3198d5d6281aSDan Carpenter $needs_fixes_tag = $1; 3199d5d6281aSDan Carpenter } 32000a920b5bSAndy Whitcroft 3201bd17e036SNiklas Söderlund# Check Fixes: styles is correct 3202bd17e036SNiklas Söderlund if (!$in_header_lines && 32032f07b652STamir Duberstein $line =~ /^\s*(fixes:?)\s*(?:commit\s*)?([0-9a-f]{5,40})(?:\s*($balanced_parens))?/i) { 32042f07b652STamir Duberstein my $tag = $1; 32052f07b652STamir Duberstein my $orig_commit = $2; 32062f07b652STamir Duberstein my $title; 3207bd17e036SNiklas Söderlund my $title_has_quotes = 0; 3208d5d6281aSDan Carpenter $fixes_tag = 1; 32092f07b652STamir Duberstein if (defined $3) { 3210bd17e036SNiklas Söderlund # Always strip leading/trailing parens then double quotes if existing 32112f07b652STamir Duberstein $title = substr($3, 1, -1); 3212bd17e036SNiklas Söderlund if ($title =~ /^".*"$/) { 3213bd17e036SNiklas Söderlund $title = substr($title, 1, -1); 3214bd17e036SNiklas Söderlund $title_has_quotes = 1; 3215bd17e036SNiklas Söderlund } 32162f07b652STamir Duberstein } else { 32172f07b652STamir Duberstein $title = "commit title" 3218bd17e036SNiklas Söderlund } 3219bd17e036SNiklas Söderlund 32202f07b652STamir Duberstein 32212f07b652STamir Duberstein my $tag_case = not ($tag eq "Fixes:"); 32222f07b652STamir Duberstein my $tag_space = not ($line =~ /^fixes:? [0-9a-f]{5,40} ($balanced_parens)/i); 32232f07b652STamir Duberstein 32246356f18fSGeert Uytterhoeven my $id_length = not ($orig_commit =~ /^[0-9a-f]{12,40}$/i); 32252f07b652STamir Duberstein my $id_case = not ($orig_commit !~ /[A-F]/); 32262f07b652STamir Duberstein 32272f07b652STamir Duberstein my $id = "0123456789ab"; 3228bd17e036SNiklas Söderlund my ($cid, $ctitle) = git_commit_info($orig_commit, $id, 3229bd17e036SNiklas Söderlund $title); 3230bd17e036SNiklas Söderlund 32313735c522STamir Duberstein if (defined($cid) && ($ctitle ne $title || $tag_case || $tag_space || $id_length || $id_case || !$title_has_quotes)) { 32323735c522STamir Duberstein my $fixed = "Fixes: $cid (\"$ctitle\")"; 3233bd17e036SNiklas Söderlund if (WARN("BAD_FIXES_TAG", 32343735c522STamir Duberstein "Please use correct Fixes: style 'Fixes: <12+ chars of sha1> (\"<title line>\")' - ie: '$fixed'\n" . $herecurr) && 3235bd17e036SNiklas Söderlund $fix) { 32363735c522STamir Duberstein $fixed[$fixlinenr] = $fixed; 3237bd17e036SNiklas Söderlund } 3238bd17e036SNiklas Söderlund } 3239bd17e036SNiklas Söderlund } 3240bd17e036SNiklas Söderlund 3241a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 3242a2fe16b9SJoe Perches if ($in_header_lines && 3243a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 3244a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 3245a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 3246a2fe16b9SJoe Perches } 3247a2fe16b9SJoe Perches 324844d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context 324944d303ebSJoe Perches if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { 32507580c5b9SAditya Srivastava if (ERROR("GERRIT_CHANGE_ID", 32517580c5b9SAditya Srivastava "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) && 32527580c5b9SAditya Srivastava $fix) { 32537580c5b9SAditya Srivastava fix_delete_line($fixlinenr, $rawline); 32547580c5b9SAditya Srivastava } 32557ebd05efSChristopher Covington } 32567ebd05efSChristopher Covington 3257369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 3258369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 3259369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 3260369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 3261369c8dd3SJoe Perches # timestamp 3262634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 3263634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 3264634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 3265634cffccSJoe Perches # stack dump address styles 3266369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 3267369c8dd3SJoe Perches } 3268369c8dd3SJoe Perches 32692a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 32702a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 3271bf4daf12SJoe Perches length($line) > 75 && 3272bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 3273bf4daf12SJoe Perches # file delta changes 327436f8b348SJerome Forissier $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ || 3275bf4daf12SJoe Perches # filename then : 3276f94e40eaSMatthieu Baerts $line =~ /^\s*(?:Fixes:|$link_tags_search|$signature_tags)/i || 3277f94e40eaSMatthieu Baerts # A Fixes:, link or signature tag line 3278bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 32792a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 32808e7b7ffbSJim Cromie "Prefer a maximum 75 chars per line (possible unwrapped commit description?)\n" . $herecurr); 32812a076f40SJoe Perches $commit_log_long_line = 1; 32822a076f40SJoe Perches } 32832a076f40SJoe Perches 3284bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 3285bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 3286bf4daf12SJoe Perches $line =~ /^\s*$/) { 3287bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 3288bf4daf12SJoe Perches } 3289bf4daf12SJoe Perches 329076f381bbSKai Wasserbäch# Check for odd tags before a URI/URL 329176f381bbSKai Wasserbäch if ($in_commit_log && 3292f94e40eaSMatthieu Baerts $line =~ /^\s*(\w+:)\s*http/ && $1 !~ /^$link_tags_search$/) { 329376f381bbSKai Wasserbäch if ($1 =~ /^v(?:ersion)?\d+/i) { 329476f381bbSKai Wasserbäch WARN("COMMIT_LOG_VERSIONING", 329576f381bbSKai Wasserbäch "Patch version information should be after the --- line\n" . $herecurr); 329676f381bbSKai Wasserbäch } else { 329776f381bbSKai Wasserbäch WARN("COMMIT_LOG_USE_LINK", 3298f94e40eaSMatthieu Baerts "Unknown link reference '$1', use $link_tags_print instead\n" . $herecurr); 329976f381bbSKai Wasserbäch } 330076f381bbSKai Wasserbäch } 330176f381bbSKai Wasserbäch 3302d6ccdd67SMatthieu Baerts# Check for misuse of the link tags 3303d6ccdd67SMatthieu Baerts if ($in_commit_log && 3304d6ccdd67SMatthieu Baerts $line =~ /^\s*(\w+:)\s*(\S+)/) { 3305d6ccdd67SMatthieu Baerts my $tag = $1; 3306d6ccdd67SMatthieu Baerts my $value = $2; 3307d6ccdd67SMatthieu Baerts if ($tag =~ /^$link_tags_search$/ && $value !~ m{^https?://}) { 3308d6ccdd67SMatthieu Baerts WARN("COMMIT_LOG_WRONG_LINK", 3309d6ccdd67SMatthieu Baerts "'$tag' should be followed by a public http(s) link\n" . $herecurr); 33100d7835fcSJoe Perches } 33114ce9f970SJoe Perches } 33124ce9f970SJoe Perches 33134ce9f970SJoe Perches# Check for lines starting with a # 33144ce9f970SJoe Perches if ($in_commit_log && $line =~ /^#/) { 33154ce9f970SJoe Perches if (WARN("COMMIT_COMMENT_SYMBOL", 33164ce9f970SJoe Perches "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) && 33174ce9f970SJoe Perches $fix) { 33184ce9f970SJoe Perches $fixed[$fixlinenr] =~ s/^/ /; 33194ce9f970SJoe Perches } 33204ce9f970SJoe Perches } 3321a8972573SJohn Hubbard 3322e882dbfcSWei Wang# Check for git id commit length and improperly formed commit descriptions 33234ce9f970SJoe Perches# A correctly formed commit description is: 33244ce9f970SJoe Perches# commit <SHA-1 hash length 12+ chars> ("Complete commit subject") 3325aab38f51SJoe Perches# with the commit subject '("' prefix and '")' suffix 3326369c8dd3SJoe Perches# This is a fairly compilicated block as it tests for what appears to be 3327bf4daf12SJoe Perches# bare SHA-1 hash with minimum length of 5. It also avoids several types of 3328fe043ea1SJoe Perches# possible SHA-1 matches. 3329fe043ea1SJoe Perches# A commit match can span multiple lines so this block attempts to find a 33300d7835fcSJoe Perches# complete typical commit on a maximum of 3 lines 33310d7835fcSJoe Perches if ($perl_version_ok && 33320d7835fcSJoe Perches $in_commit_log && !$commit_log_possible_stack_dump && 33330d7835fcSJoe Perches $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && 33340d7835fcSJoe Perches $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 33350d7835fcSJoe Perches (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 33360d7835fcSJoe Perches ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) || 33374ce9f970SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 33384ce9f970SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 33394ce9f970SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 33400d7835fcSJoe Perches my $init_char = "c"; 33414ce9f970SJoe Perches my $orig_commit = ""; 33424ce9f970SJoe Perches my $short = 1; 33434ce9f970SJoe Perches my $long = 0; 33444ce9f970SJoe Perches my $case = 1; 33454ce9f970SJoe Perches my $space = 1; 33464ce9f970SJoe Perches my $id = '0123456789ab'; 33474ce9f970SJoe Perches my $orig_desc = "commit description"; 33484ce9f970SJoe Perches my $description = ""; 33494ce9f970SJoe Perches my $herectx = $herecurr; 33504ce9f970SJoe Perches my $has_parens = 0; 33514ce9f970SJoe Perches my $has_quotes = 0; 33524ce9f970SJoe Perches 33534ce9f970SJoe Perches my $input = $line; 33544ce9f970SJoe Perches if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) { 33554ce9f970SJoe Perches for (my $n = 0; $n < 2; $n++) { 33564ce9f970SJoe Perches if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) { 33574ce9f970SJoe Perches $orig_desc = $1; 33584ce9f970SJoe Perches $has_parens = 1; 33594ce9f970SJoe Perches # Always strip leading/trailing parens then double quotes if existing 3360fe043ea1SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 3361fe043ea1SJoe Perches if ($orig_desc =~ /^".*"$/) { 33624ce9f970SJoe Perches $orig_desc = substr($orig_desc, 1, -1); 33634ce9f970SJoe Perches $has_quotes = 1; 33644ce9f970SJoe Perches } 33654ce9f970SJoe Perches last; 33664ce9f970SJoe Perches } 33674ce9f970SJoe Perches last if ($#lines < $linenr + $n); 33684ce9f970SJoe Perches $input .= " " . trim($rawlines[$linenr + $n]); 33694ce9f970SJoe Perches $herectx .= "$rawlines[$linenr + $n]\n"; 33704ce9f970SJoe Perches } 33710d7835fcSJoe Perches $herectx = $herecurr if (!$has_parens); 33720d7835fcSJoe Perches } 33730d7835fcSJoe Perches 33740d7835fcSJoe Perches if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 33750d7835fcSJoe Perches $init_char = $1; 3376948b133aSHeinrich Schuchardt $orig_commit = lc($2); 33774ce9f970SJoe Perches $short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i); 33784ce9f970SJoe Perches $long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i); 3379d311cd44SJoe Perches $space = 0 if ($input =~ /\bcommit [0-9a-f]/i); 33804ce9f970SJoe Perches $case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 33810d7835fcSJoe Perches } elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) { 33824ce9f970SJoe Perches $orig_commit = lc($1); 33834ce9f970SJoe Perches } 3384d311cd44SJoe Perches 3385d311cd44SJoe Perches ($id, $description) = git_commit_info($orig_commit, 33869b71f79fSBjorn Helgaas $id, $orig_desc); 33879b71f79fSBjorn Helgaas 33889b71f79fSBjorn Helgaas if (defined($id) && 33899b71f79fSBjorn Helgaas ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) && 33909b71f79fSBjorn Helgaas $last_git_commit_id_linenr != $linenr - 1) { 33919b71f79fSBjorn Helgaas ERROR("GIT_COMMIT_ID", 339213f1937eSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx); 339313f1937eSJoe Perches } 339413f1937eSJoe Perches #don't report the next line if this line ends in commit and the sha1 hash is the next line 339513f1937eSJoe Perches $last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i); 339613f1937eSJoe Perches } 339713f1937eSJoe Perches 3398a82603a8SAndrew Jeffery# Check for mailing list archives other than lore.kernel.org 339913f1937eSJoe Perches if ($rawline =~ m{http.*\b$obsolete_archives}) { 340013f1937eSJoe Perches WARN("PREFER_LORE_ARCHIVE", 340113f1937eSJoe Perches "Use lore.kernel.org archive links when possible - see https://lore.kernel.org/lists.html\n" . $herecurr); 340213f1937eSJoe Perches } 340313f1937eSJoe Perches 3404e400edb1SRob Herring# Check for added, moved or deleted files 3405e400edb1SRob Herring if (!$reported_maintainer_file && !$in_commit_log && 3406e400edb1SRob Herring ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 3407e400edb1SRob Herring $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 3408e400edb1SRob Herring ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 340956ddc4cdSMauro Carvalho Chehab (defined($1) || defined($2))))) { 3410e400edb1SRob Herring $is_patch = 1; 3411e400edb1SRob Herring $reported_maintainer_file = 1; 341200df344fSAndy Whitcroft WARN("FILE_PATH_CHANGES", 34138905a67cSAndy Whitcroft "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 3414000d1cc1SJoe Perches } 3415000d1cc1SJoe Perches 34166c72ffaaSAndy Whitcroft# Check for adding new DT bindings not in schema format 3417de7d4f0eSAndy Whitcroft if (!$in_commit_log && 3418de7d4f0eSAndy Whitcroft ($line =~ /^new file mode\s*\d+\s*$/) && 3419de7d4f0eSAndy Whitcroft ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { 3420de7d4f0eSAndy Whitcroft WARN("DT_SCHEMA_BINDING_PATCH", 3421171ae1a4SAndy Whitcroft "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n"); 3422171ae1a4SAndy Whitcroft } 3423171ae1a4SAndy Whitcroft 3424171ae1a4SAndy Whitcroft# Check for wrappage within a valid hunk of the file 3425171ae1a4SAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 3426171ae1a4SAndy Whitcroft ERROR("CORRUPTED_PATCH", 3427171ae1a4SAndy Whitcroft "patch seems to be corrupt (line wrapped?)\n" . 342834d99219SJoe Perches $herecurr) if (!$emitted_corrupt++); 3429000d1cc1SJoe Perches } 343000df344fSAndy Whitcroft 34310a920b5bSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 343215662b3eSJoe Perches if (($realfile =~ /^$/ || $line =~ /^\+/) && 343315662b3eSJoe Perches $rawline !~ m/^$UTF8*$/) { 343415662b3eSJoe Perches my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 3435eb3a58deSJoe Perches 3436eb3a58deSJoe Perches my $blank = copy_spacing($rawline); 343715662b3eSJoe Perches my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 343815662b3eSJoe Perches my $hereptr = "$hereline$ptr\n"; 3439ed43c4e5SAllen Hubbe 344015662b3eSJoe Perches CHK("INVALID_UTF8", 344115662b3eSJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 3442fa64205dSPasi Savanainen } 3443fa64205dSPasi Savanainen 3444fa64205dSPasi Savanainen# Check if it's the start of a commit log 3445fa64205dSPasi Savanainen# (not a header line and we haven't seen the patch filename) 3446fa64205dSPasi Savanainen if ($in_header_lines && $realfile =~ /^$/ && 3447fa64205dSPasi Savanainen !($rawline =~ /^\s+(?:\S|$)/ || 3448fa64205dSPasi Savanainen $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 3449fa64205dSPasi Savanainen $in_header_lines = 0; 3450fa64205dSPasi Savanainen $in_commit_log = 1; 345115662b3eSJoe Perches $has_commit_log = 1; 3452fa64205dSPasi Savanainen } 345315662b3eSJoe Perches 345415662b3eSJoe Perches# Check if there is UTF-8 in a commit log when a mail header has explicitly 345515662b3eSJoe Perches# declined it, i.e defined some charset where it is missing. 3456d6430f71SJoe Perches if ($in_header_lines && 3457d6430f71SJoe Perches $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 3458d6430f71SJoe Perches $1 !~ /utf-8/i) { 3459d6430f71SJoe Perches $non_utf8_charset = 1; 3460d6430f71SJoe Perches } 3461d6430f71SJoe Perches 3462d6430f71SJoe Perches if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 3463d6430f71SJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 3464d6430f71SJoe Perches WARN("UTF8_BEFORE_PATCH", 3465d6430f71SJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 3466d6430f71SJoe Perches } 3467d6430f71SJoe Perches 3468d6430f71SJoe Perches# Check for absolute kernel paths in commit message 3469d6430f71SJoe Perches if ($tree && $in_commit_log) { 347066b47b4aSKees Cook while ($line =~ m{(?:^|\s)(/\S*)}g) { 347166d7a382SJoe Perches my $file = $1; 347266d7a382SJoe Perches 34737da07c31SDwaipayan Ray if ($file =~ m{^(.*?)(?::\d+)+:?$} && 347466b47b4aSKees Cook check_absolute_file($1, $herecurr)) { 34757da07c31SDwaipayan Ray # 34767da07c31SDwaipayan Ray } else { 34777da07c31SDwaipayan Ray check_absolute_file($file, $herecurr); 347866b47b4aSKees Cook } 347966b47b4aSKees Cook } 348066b47b4aSKees Cook } 34810675a8fbSJean Delvare 34820675a8fbSJean Delvare# Check for various typo / spelling mistakes 34830675a8fbSJean Delvare if (defined($misspellings) && 34847da07c31SDwaipayan Ray ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 348566b47b4aSKees Cook while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) { 348666b47b4aSKees Cook my $typo = $1; 348766b47b4aSKees Cook my $blank = copy_spacing($rawline); 348866b47b4aSKees Cook my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo); 348966b47b4aSKees Cook my $hereptr = "$hereline$ptr\n"; 349066b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 3491a8dd86bfSMatteo Croce $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 3492a8dd86bfSMatteo Croce $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 3493a8dd86bfSMatteo Croce my $msg_level = \&WARN; 3494a8dd86bfSMatteo Croce $msg_level = \&CHK if ($file); 3495a8dd86bfSMatteo Croce if (&{$msg_level}("TYPO_SPELLING", 3496a8dd86bfSMatteo Croce "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) && 3497a8dd86bfSMatteo Croce $fix) { 3498a8dd86bfSMatteo Croce $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 3499a8dd86bfSMatteo Croce } 3500a8dd86bfSMatteo Croce } 3501a8dd86bfSMatteo Croce } 3502310cd06bSJoe Perches 35038d0325ccSAditya Srivastava# check for invalid commit id 35048d0325ccSAditya Srivastava if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 35058d0325ccSAditya Srivastava my $id; 35061db81a68SDwaipayan Ray my $description; 3507310cd06bSJoe Perches ($id, $description) = git_commit_info($2, undef, undef); 3508310cd06bSJoe Perches if (!defined($id)) { 3509310cd06bSJoe Perches WARN("UNKNOWN_COMMIT_ID", 3510310cd06bSJoe Perches "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 35111db81a68SDwaipayan Ray } 35121db81a68SDwaipayan Ray } 3513310cd06bSJoe Perches 3514310cd06bSJoe Perches# check for repeated words separated by a single space 3515310cd06bSJoe Perches# avoid false positive from list command eg, '-rw-r--r-- 1 root root' 3516310cd06bSJoe Perches if (($rawline =~ /^\+/ || $in_commit_log) && 3517310cd06bSJoe Perches $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) { 35181db81a68SDwaipayan Ray pos($rawline) = 1 if (!$in_commit_log); 3519310cd06bSJoe Perches while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { 3520310cd06bSJoe Perches 35211db81a68SDwaipayan Ray my $first = $1; 35221db81a68SDwaipayan Ray my $second = $2; 35231db81a68SDwaipayan Ray my $start_pos = $-[1]; 35241db81a68SDwaipayan Ray my $end_pos = $+[2]; 35251db81a68SDwaipayan Ray if ($first =~ /(?:struct|union|enum)/) { 35261db81a68SDwaipayan Ray pos($rawline) += length($first) + length($second) + 1; 35271db81a68SDwaipayan Ray next; 35281db81a68SDwaipayan Ray } 35291db81a68SDwaipayan Ray 35308d0325ccSAditya Srivastava next if (lc($first) ne lc($second)); 35318d0325ccSAditya Srivastava next if ($first eq 'long'); 35328d0325ccSAditya Srivastava 35338d0325ccSAditya Srivastava # check for character before and after the word matches 35348d0325ccSAditya Srivastava my $start_char = ''; 3535310cd06bSJoe Perches my $end_char = ''; 3536310cd06bSJoe Perches $start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1)); 3537310cd06bSJoe Perches $end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); 3538310cd06bSJoe Perches 3539310cd06bSJoe Perches next if ($start_char =~ /^\S$/); 3540310cd06bSJoe Perches next if (index(" \t.,;?!", $end_char) == -1); 3541310cd06bSJoe Perches 3542310cd06bSJoe Perches # avoid repeating hex occurrences like 'ff ff fe 09 ...' 3543310cd06bSJoe Perches if ($first =~ /\b[0-9a-f]{2,}\b/i) { 3544310cd06bSJoe Perches next if (!exists($allow_repeated_words{lc($first)})); 3545310cd06bSJoe Perches } 3546310cd06bSJoe Perches 3547310cd06bSJoe Perches if (WARN("REPEATED_WORD", 3548310cd06bSJoe Perches "Possible repeated word: '$first'\n" . $herecurr) && 3549310cd06bSJoe Perches $fix) { 3550310cd06bSJoe Perches $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; 3551310cd06bSJoe Perches } 3552310cd06bSJoe Perches } 3553310cd06bSJoe Perches 3554310cd06bSJoe Perches # if it's a repeated word on consecutive lines in a comment block 3555310cd06bSJoe Perches if ($prevline =~ /$;+\s*$/ && 355630670854SAndy Whitcroft $prevrawline =~ /($word_pattern)\s*$/) { 355730670854SAndy Whitcroft my $last_word = $1; 355800df344fSAndy Whitcroft if ($rawline =~ /^\+\s*\*\s*$last_word /) { 35590a920b5bSAndy Whitcroft if (WARN("REPEATED_WORD", 35609c0ca6f9SAndy Whitcroft "Possible repeated word: '$last_word'\n" . $hereprev) && 3561c2fdda0dSAndy Whitcroft $fix) { 3562d5e616fcSJoe Perches $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; 3563d5e616fcSJoe Perches } 3564d5e616fcSJoe Perches } 3565194f66fcSJoe Perches } 3566d5e616fcSJoe Perches } 3567c2fdda0dSAndy Whitcroft 3568c2fdda0dSAndy Whitcroft# ignore non-hunk lines and lines being removed 35693705ce5bSJoe Perches next if (!$hunk_line || $line =~ /^-/); 35703705ce5bSJoe Perches 35713705ce5bSJoe Perches#trailing whitespace 3572194f66fcSJoe Perches if ($line =~ /^\+.*\015/) { 35733705ce5bSJoe Perches my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 35743705ce5bSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 3575d2c0a235SAndy Whitcroft "DOS line endings\n" . $herevet) && 35760a920b5bSAndy Whitcroft $fix) { 35775368df20SAndy Whitcroft $fixed[$fixlinenr] =~ s/[\s\015]+$//; 35784783f894SJosh Triplett } 3579109d8cb2SAlexander Duyck } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 35801bde561eSMatthew Wilcox my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 35813e2232f2SJoe Perches if (ERROR("TRAILING_WHITESPACE", 35823e2232f2SJoe Perches "trailing whitespace\n" . $herevet) && 35834783f894SJosh Triplett $fix) { 35840675a8fbSJean Delvare $fixed[$fixlinenr] =~ s/\s+$//; 35850675a8fbSJean Delvare } 35860675a8fbSJean Delvare 35874783f894SJosh Triplett $rpt_cleaners = 1; 35884783f894SJosh Triplett } 35894783f894SJosh Triplett 35903354957aSAndi Kleen# Check for FSF mailing addresses. 35919fe287d7SAndy Whitcroft if ($rawline =~ /\bwrite to the Free/i || 35929fe287d7SAndy Whitcroft $rawline =~ /\b675\s+Mass\s+Ave/i || 35933354957aSAndi Kleen $rawline =~ /\b59\s+Temple\s+Pl/i || 3594678ae162SUlf Magnusson $rawline =~ /\b51\s+Franklin\s+St/i) { 3595678ae162SUlf Magnusson my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3596678ae162SUlf Magnusson my $msg_level = \&ERROR; 3597678ae162SUlf Magnusson $msg_level = \&CHK if ($file); 3598b8709bceSJoe Perches &{$msg_level}("FSF_MAILING_ADDRESS", 3599b8709bceSJoe Perches "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) 3600b8709bceSJoe Perches } 3601b8709bceSJoe Perches 3602b8709bceSJoe Perches# check for Kconfig help text having a real description 3603b8709bceSJoe Perches# Only applies when adding the entry originally, after that we do not have 36049fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 36059fe287d7SAndy Whitcroft if ($realfile =~ /Kconfig/ && 3606b8709bceSJoe Perches # 'choice' is usually the last thing on the line (though 3607a1385803SAndy Whitcroft # Kconfig supports named choices), so use a word boundary 3608b8709bceSJoe Perches # (\b) rather than a whitespace character (\s) 3609b8709bceSJoe Perches $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 3610b8709bceSJoe Perches my $ln = $linenr; 3611b8709bceSJoe Perches my $needs_help = 0; 3612b8709bceSJoe Perches my $has_help = 0; 3613b8709bceSJoe Perches my $help_length = 0; 3614b8709bceSJoe Perches while (defined $lines[$ln]) { 3615a1385803SAndy Whitcroft my $f = $lines[$ln++]; 3616a1385803SAndy Whitcroft 3617b8709bceSJoe Perches next if ($f =~ /^-/); 3618b8709bceSJoe Perches last if ($f !~ /^[\+ ]/); # !patch context 3619b8709bceSJoe Perches 3620b8709bceSJoe Perches if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 3621678ae162SUlf Magnusson $needs_help = 1; 3622b8709bceSJoe Perches next; 3623678ae162SUlf Magnusson } 3624678ae162SUlf Magnusson if ($f =~ /^\+\s*help\s*$/) { 3625678ae162SUlf Magnusson $has_help = 1; 3626678ae162SUlf Magnusson next; 3627b8709bceSJoe Perches } 3628678ae162SUlf Magnusson 36299fe287d7SAndy Whitcroft $f =~ s/^.//; # strip patch context [+ ] 36309fe287d7SAndy Whitcroft $f =~ s/#.*//; # strip # directives 3631b8709bceSJoe Perches $f =~ s/^\s+//; # strip leading blanks 36323354957aSAndi Kleen next if ($f =~ /^$/); # skip blank lines 3633b8709bceSJoe Perches 3634b8709bceSJoe Perches # At the end of this Kconfig block: 3635b8709bceSJoe Perches # This only checks context lines in the patch 3636000d1cc1SJoe Perches # and so hopefully shouldn't trigger false 3637b8709bceSJoe Perches # positives, even though some of these are 363856193274SVadim Bendebury # common words in help texts 36393354957aSAndi Kleen if ($f =~ /^(?:config|menuconfig|choice|endchoice| 36403354957aSAndi Kleen if|endif|menu|endmenu|source)\b/x) { 36417ccf41a8SJoe Perches last; 36427ccf41a8SJoe Perches } 36437ccf41a8SJoe Perches $help_length++ if ($has_help); 36447ccf41a8SJoe Perches } 3645628f91a2SJoe Perches if ($needs_help && 3646628f91a2SJoe Perches $help_length < $min_conf_desc_length) { 3647628f91a2SJoe Perches my $stat_real = get_stat_real($linenr, $ln - 1); 3648628f91a2SJoe Perches WARN("CONFIG_DESCRIPTION", 3649*bc2f19d6SPhilipp Hahn "please write a help paragraph that fully describes the config symbol with at least $min_conf_desc_length lines\n" . "$here\n$stat_real\n"); 36501ba8dfd1SKees Cook } 36511ba8dfd1SKees Cook } 36521ba8dfd1SKees Cook 36531ba8dfd1SKees Cook# check MAINTAINERS entries 3654628f91a2SJoe Perches if ($realfile =~ /^MAINTAINERS$/) { 3655628f91a2SJoe Perches# check MAINTAINERS entries for the right form 3656628f91a2SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 3657628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3658628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3659628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3660628f91a2SJoe Perches $fix) { 3661628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3662628f91a2SJoe Perches } 3663628f91a2SJoe Perches } 36647ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too 36657ccf41a8SJoe Perches my $preferred_order = 'MRLSWQBCPTFXNK'; 36667ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 36677ccf41a8SJoe Perches $prevrawline =~ /^[\+ ][A-Z]:/) { 36687ccf41a8SJoe Perches $rawline =~ /^\+([A-Z]):\s*(.*)/; 36697ccf41a8SJoe Perches my $cur = $1; 36707ccf41a8SJoe Perches my $curval = $2; 36717ccf41a8SJoe Perches $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; 36727ccf41a8SJoe Perches my $prev = $1; 36737ccf41a8SJoe Perches my $prevval = $2; 36747ccf41a8SJoe Perches my $curindex = index($preferred_order, $cur); 36757ccf41a8SJoe Perches my $previndex = index($preferred_order, $prev); 36767ccf41a8SJoe Perches if ($curindex < 0) { 36777ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 36787ccf41a8SJoe Perches "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); 36797ccf41a8SJoe Perches } else { 36807ccf41a8SJoe Perches if ($previndex >= 0 && $curindex < $previndex) { 36817ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 36827ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); 36837ccf41a8SJoe Perches } elsif ((($prev eq 'F' && $cur eq 'F') || 36847ccf41a8SJoe Perches ($prev eq 'X' && $cur eq 'X')) && 36857ccf41a8SJoe Perches ($prevval cmp $curval) > 0) { 36867ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 36877ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); 36887ccf41a8SJoe Perches } 36897ccf41a8SJoe Perches } 36907ccf41a8SJoe Perches } 36917ccf41a8SJoe Perches } 3692628f91a2SJoe Perches 3693c68e5878SArnaud Lacombe# check for DT compatible documentation 3694c68e5878SArnaud Lacombe if (defined $root && 3695c68e5878SArnaud Lacombe (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 3696c68e5878SArnaud Lacombe ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 3697c68e5878SArnaud Lacombe 3698c68e5878SArnaud Lacombe my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3699c68e5878SArnaud Lacombe 3700c68e5878SArnaud Lacombe my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3701c68e5878SArnaud Lacombe my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3702c68e5878SArnaud Lacombe 3703c68e5878SArnaud Lacombe foreach my $compat (@compats) { 3704c68e5878SArnaud Lacombe my $compat2 = $compat; 3705c68e5878SArnaud Lacombe $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3706c68e5878SArnaud Lacombe my $compat3 = $compat; 3707bff5da43SRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 37087dd05b38SFlorian Vaussard `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 37097dd05b38SFlorian Vaussard if ( $? >> 8 ) { 37107dd05b38SFlorian Vaussard WARN("UNDOCUMENTED_DT_STRING", 37117dd05b38SFlorian Vaussard "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3712bff5da43SRob Herring } 3713bff5da43SRob Herring 3714cc93319bSFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 3715852d095dSRob Herring my $vendor = $1; 3716cc93319bSFlorian Vaussard `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3717bff5da43SRob Herring if ( $? >> 8 ) { 3718bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3719185d566bSRob Herring "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3720185d566bSRob Herring } 3721185d566bSRob Herring } 3722185d566bSRob Herring } 3723bff5da43SRob Herring 3724bff5da43SRob Herring# check for using SPDX license tag at beginning of files 3725bff5da43SRob Herring if ($realline == $checklicenseline) { 3726bff5da43SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 3727bff5da43SRob Herring $checklicenseline = 2; 37284fbf32a6SFlorian Vaussard } elsif ($rawline =~ /^\+/) { 37294fbf32a6SFlorian Vaussard my $comment = ""; 3730852d095dSRob Herring if ($realfile =~ /\.(h|s|S)$/) { 3731bff5da43SRob Herring $comment = '/*'; 3732bff5da43SRob Herring } elsif ($realfile =~ /\.(c|rs|dts|dtsi)$/) { 3733cc93319bSFlorian Vaussard $comment = '//'; 3734bff5da43SRob Herring } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 3735bff5da43SRob Herring $comment = '#'; 3736bff5da43SRob Herring } elsif ($realfile =~ /\.rst$/) { 3737bff5da43SRob Herring $comment = '..'; 37389f3a8992SRob Herring } 37399f3a8992SRob Herring 37409f3a8992SRob Herring# check SPDX comment style for .[chsS] files 37419f3a8992SRob Herring if ($realfile =~ /\.[chsS]$/ && 37429f3a8992SRob Herring $rawline =~ /SPDX-License-Identifier:/ && 37439f3a8992SRob Herring $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 37449f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 37459f3a8992SRob Herring "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3746d1d84b5fSMiguel Ojeda } 37479f3a8992SRob Herring 3748c8df0ab6SLubomir Rintel if ($comment !~ /^$/ && 37499f3a8992SRob Herring $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 37509f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 37519f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 37529f3a8992SRob Herring } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 37539f3a8992SRob Herring my $spdx_license = $1; 3754fdf13693SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 3755fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3756fdf13693SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 3757ffbce897SJoe Perches } 3758fdf13693SJoe Perches if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 3759fdf13693SJoe Perches $spdx_license !~ /GPL-2\.0(?:-only)? OR BSD-2-Clause/) { 3760fdf13693SJoe Perches my $msg_level = \&WARN; 3761fdf13693SJoe Perches $msg_level = \&CHK if ($file); 37629f3a8992SRob Herring if (&{$msg_level}("SPDX_LICENSE_TAG", 3763ffbce897SJoe Perches 37649f3a8992SRob Herring "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 37659f3a8992SRob Herring $fix) { 37663b6e8ac9SJoe Perches $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 37673b6e8ac9SJoe Perches } 37683b6e8ac9SJoe Perches } 37693b6e8ac9SJoe Perches if ($realfile =~ m@^include/dt-bindings/@ && 37703b6e8ac9SJoe Perches $spdx_license !~ /GPL-2\.0(?:-only)? OR \S+/) { 37713b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 377250c92900SLubomir Rintel "DT binding headers should be licensed (GPL-2.0-only OR .*)\n" . $herecurr); 3773a04bb4c2SDmitry Rokosov } 377450c92900SLubomir Rintel } 377550c92900SLubomir Rintel } 377650c92900SLubomir Rintel } 377750c92900SLubomir Rintel 377850c92900SLubomir Rintel# check for embedded filenames 377950c92900SLubomir Rintel if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) { 378050c92900SLubomir Rintel WARN("EMBEDDED_FILENAME", 378150c92900SLubomir Rintel "It's generally not useful to have the filename in the file\n" . $herecurr); 378250c92900SLubomir Rintel } 3783a04bb4c2SDmitry Rokosov 3784a04bb4c2SDmitry Rokosov# check we are in a valid source file if not then ignore this hunk 3785a04bb4c2SDmitry Rokosov next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/); 3786a04bb4c2SDmitry Rokosov 3787a04bb4c2SDmitry Rokosov# check for using SPDX-License-Identifier on the wrong line number 37889f3a8992SRob Herring if ($realline != $checklicenseline && 37899f3a8992SRob Herring $rawline =~ /\bSPDX-License-Identifier:/ && 37909f3a8992SRob Herring substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 37919f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 3792a0154cdbSJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 379336217357SJoe Perches } 3794a0154cdbSJoe Perches 3795a0154cdbSJoe Perches# line length limit (with some exclusions) 3796a0154cdbSJoe Perches# 3797a0154cdbSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 37985368df20SAndy Whitcroft# logging functions like pr_info that end in a string 3799d1d84b5fSMiguel Ojeda# lines with a single string 38005368df20SAndy Whitcroft# #defines that are a single string 3801a8da38a9SJoe Perches# lines with an RFC3986 like URL 3802a8da38a9SJoe Perches# 3803a8da38a9SJoe Perches# There are 3 different line length message types: 3804a8da38a9SJoe Perches# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 3805a8da38a9SJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 3806a8da38a9SJoe Perches# LONG_LINE all other lines longer than $max_line_length 3807a8da38a9SJoe Perches# 3808a8da38a9SJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 380947e0c88bSJoe Perches# 381047e0c88bSJoe Perches 381147e0c88bSJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 381247e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 381347e0c88bSJoe Perches 381447e0c88bSJoe Perches # Check the allowed long line types first 38152e4bbbc5SAndreas Brauchli 381647e0c88bSJoe Perches # logging functions that end in a string that starts 381747e0c88bSJoe Perches # before $max_line_length 3818ab1ecabfSJean Delvare if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 381947e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 382047e0c88bSJoe Perches $msg_type = ""; 382147e0c88bSJoe Perches 382247e0c88bSJoe Perches # lines with only strings (w/ possible termination) 382347e0c88bSJoe Perches # #defines with only strings 382447e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 3825b4749e96SJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 382647e0c88bSJoe Perches $msg_type = ""; 382747e0c88bSJoe Perches 382847e0c88bSJoe Perches # More special cases 382947e0c88bSJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 383047e0c88bSJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 383147e0c88bSJoe Perches $msg_type = ""; 383247e0c88bSJoe Perches 383347e0c88bSJoe Perches # URL ($rawline is used in case the URL is in a comment) 383447e0c88bSJoe Perches } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 383547e0c88bSJoe Perches $msg_type = ""; 383647e0c88bSJoe Perches 383747e0c88bSJoe Perches # Otherwise set the alternate message types 383847e0c88bSJoe Perches 383947e0c88bSJoe Perches # a comment starts before $max_line_length 384047e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 384147e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 3842cc147506SJoe Perches $msg_type = "LONG_LINE_COMMENT" 3843cc147506SJoe Perches 3844cc147506SJoe Perches # a quoted string starts before $max_line_length 3845d560a5f8SJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 3846d560a5f8SJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 38472e4bbbc5SAndreas Brauchli $msg_type = "LONG_LINE_STRING" 38482e4bbbc5SAndreas Brauchli } 38492e4bbbc5SAndreas Brauchli 38502e4bbbc5SAndreas Brauchli if ($msg_type ne "" && 385147e0c88bSJoe Perches show_type("LONG_LINE") && show_type($msg_type)) { 385247e0c88bSJoe Perches my $msg_level = \&WARN; 385347e0c88bSJoe Perches $msg_level = \&CHK if ($file); 385447e0c88bSJoe Perches &{$msg_level}($msg_type, 385547e0c88bSJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 385647e0c88bSJoe Perches } 385747e0c88bSJoe Perches } 385847e0c88bSJoe Perches 385947e0c88bSJoe Perches# check for adding lines without a newline. 386047e0c88bSJoe Perches if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 386147e0c88bSJoe Perches if (WARN("MISSING_EOF_NEWLINE", 386247e0c88bSJoe Perches "adding a line without newline at end of file\n" . $herecurr) && 386347e0c88bSJoe Perches $fix) { 386447e0c88bSJoe Perches fix_delete_line($fixlinenr+1, "No newline at end of file"); 3865d6bb3951SWolfram Sang } 3866bdc48fa1SJoe Perches } 3867bdc48fa1SJoe Perches 3868bdc48fa1SJoe Perches# check for .L prefix local symbols in .S files 3869bdc48fa1SJoe Perches if ($realfile =~ /\.S$/ && 38700a920b5bSAndy Whitcroft $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { 387147e0c88bSJoe Perches WARN("AVOID_L_PREFIX", 38720a920b5bSAndy Whitcroft "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/core-api/asm-annotations.rst\n" . $herecurr); 38738905a67cSAndy Whitcroft } 38748905a67cSAndy Whitcroft 387547ca69b8STom Rix# check we are in a valid source file C or perl if not then ignore this hunk 387647ca69b8STom Rix next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 387747ca69b8STom Rix 387847ca69b8STom Rix# at the beginning of a line any tabs must come first and anything 387947ca69b8STom Rix# more than $tabsize must use tabs. 38808905a67cSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 38818905a67cSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3882de93245cSAditya Srivastava my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3883de93245cSAditya Srivastava $rpt_cleaners = 1; 3884de93245cSAditya Srivastava if (ERROR("CODE_INDENT", 3885de93245cSAditya Srivastava "code indent should use tabs where possible\n" . $herevet) && 3886f4bf1cd4SJonathan Corbet $fix) { 3887de93245cSAditya Srivastava $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 3888de93245cSAditya Srivastava } 3889b9ea10d6SAndy Whitcroft } 3890de4c924cSGeert Uytterhoeven 38910a920b5bSAndy Whitcroft# check for space before tabs. 38920a920b5bSAndy Whitcroft if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 3893713a09deSAntonio Borneo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3894c2fdda0dSAndy Whitcroft if (WARN("SPACE_BEFORE_TAB", 3895c2fdda0dSAndy Whitcroft "please, no space before tabs\n" . $herevet) && 3896c2fdda0dSAndy Whitcroft $fix) { 3897d2c0a235SAndy Whitcroft while ($fixed[$fixlinenr] =~ 38983705ce5bSJoe Perches s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 38993705ce5bSJoe Perches while ($fixed[$fixlinenr] =~ 39003705ce5bSJoe Perches s/(^\+.*) +\t/$1\t/) {} 3901194f66fcSJoe Perches } 39023705ce5bSJoe Perches } 39030a920b5bSAndy Whitcroft 39040a920b5bSAndy Whitcroft# check for assignments on the start of a line 390508e44365SAlberto Panizzo if ($sline =~ /^\+\s+($Assignment)[^=]/) { 390608e44365SAlberto Panizzo my $operator = $1; 390708e44365SAlberto Panizzo if (CHK("ASSIGNMENT_CONTINUATIONS", 39083705ce5bSJoe Perches "Assignment operator '$1' should be on the previous line\n" . $hereprev) && 39093705ce5bSJoe Perches $fix && $prevrawline =~ /^\+/) { 39103705ce5bSJoe Perches # add assignment operator to the previous line, remove from current line 3911194f66fcSJoe Perches $fixed[$fixlinenr - 1] .= " $operator"; 3912713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 3913194f66fcSJoe Perches } 3914c76f4cb3SJoe Perches } 39153705ce5bSJoe Perches 391608e44365SAlberto Panizzo# check for && or || at the start of a line 391708e44365SAlberto Panizzo if ($rawline =~ /^\+\s*(&&|\|\|)/) { 39186a487211SJoe Perches my $operator = $1; 39196a487211SJoe Perches if (CHK("LOGICAL_CONTINUATIONS", 3920da7355abSAditya Srivastava "Logical continuations should be on the previous line\n" . $hereprev) && 3921da7355abSAditya Srivastava $fix && $prevrawline =~ /^\+/) { 3922da7355abSAditya Srivastava # insert logical operator at last non-comment, non-whitepsace char on previous line 3923da7355abSAditya Srivastava $prevline =~ /[\s$;]*$/; 3924da7355abSAditya Srivastava my $line_end = substr($prevrawline, $-[0]); 3925da7355abSAditya Srivastava $fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/; 3926da7355abSAditya Srivastava $fixed[$fixlinenr] =~ s/\Q$operator\E\s*//; 3927da7355abSAditya Srivastava } 39286a487211SJoe Perches } 39296a487211SJoe Perches 3930d1fe9c09SJoe Perches# check indentation starts on a tab stop 3931d1fe9c09SJoe Perches if ($perl_version_ok && 39328e08f076SAditya Srivastava $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 39338e08f076SAditya Srivastava my $indent = length($1); 39348e08f076SAditya Srivastava if ($indent % $tabsize) { 39358e08f076SAditya Srivastava if (WARN("TABSTOP", 39368e08f076SAditya Srivastava "Statements should start on a tabstop\n" . $herecurr) && 39378e08f076SAditya Srivastava $fix) { 39388e08f076SAditya Srivastava $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 39398e08f076SAditya Srivastava } 39408e08f076SAditya Srivastava } 39418e08f076SAditya Srivastava } 3942d1fe9c09SJoe Perches 3943d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 3944a91e8994SJoe Perches if ($perl_version_ok && 39455b57980dSJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3946bd49111fSJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3947a91e8994SJoe Perches my $oldindent = $1; 3948713a09deSAntonio Borneo my $rest = $2; 3949a91e8994SJoe Perches 3950a91e8994SJoe Perches my $pos = pos_last_openparen($rest); 3951a91e8994SJoe Perches if ($pos >= 0) { 3952713a09deSAntonio Borneo $line =~ /^(\+| )([ \t]*)/; 3953a91e8994SJoe Perches my $newindent = $2; 3954a91e8994SJoe Perches 3955a91e8994SJoe Perches my $goodtabindent = $oldindent . 3956a91e8994SJoe Perches "\t" x ($pos / $tabsize) . 3957d1fe9c09SJoe Perches " " x ($pos % $tabsize); 39585b57980dSJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3959fd71f632SJoe Perches 3960d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3961d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 3962d1fe9c09SJoe Perches 3963d1fe9c09SJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 3964d1fe9c09SJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 3965d1fe9c09SJoe Perches $fix && $line =~ /^\+/) { 3966b34a26f3SJoe Perches $fixed[$fixlinenr] =~ 3967b34a26f3SJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 3968d1fe9c09SJoe Perches } 3969d1fe9c09SJoe Perches } 3970713a09deSAntonio Borneo } 3971713a09deSAntonio Borneo } 3972d1fe9c09SJoe Perches 3973d1fe9c09SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 3974d1fe9c09SJoe Perches# avoid checking a few false positives: 3975d1fe9c09SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 39763705ce5bSJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 39773705ce5bSJoe Perches# structure definitions like "(struct foo) { 0 };" 39783705ce5bSJoe Perches# multiline macros that define functions 39793705ce5bSJoe Perches# known attributes or the __attribute__ keyword 3980194f66fcSJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 39813705ce5bSJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 39823705ce5bSJoe Perches if (CHK("SPACING", 3983d1fe9c09SJoe Perches "No space is necessary after a cast\n" . $herecurr) && 3984d1fe9c09SJoe Perches $fix) { 3985d1fe9c09SJoe Perches $fixed[$fixlinenr] =~ 3986d1fe9c09SJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 39876ab3a970SJoe Perches } 39886ab3a970SJoe Perches } 39896ab3a970SJoe Perches 39906ab3a970SJoe Perches# Block comments use * on subsequent lines 39916ab3a970SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 39926ab3a970SJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 39936ab3a970SJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 39946ab3a970SJoe Perches $rawline =~ /^\+/ && #line is new 39956ab3a970SJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 39963705ce5bSJoe Perches WARN("BLOCK_COMMENT_STYLE", 3997f27c95dbSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 39983705ce5bSJoe Perches } 3999194f66fcSJoe Perches 4000f27c95dbSJoe Perches# Block comments use */ on trailing lines 40013705ce5bSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 4002aad4f614SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 4003aad4f614SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 400486406b1cSJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 400586406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 400686406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 4007a605e32eSJoe Perches } 400861135e96SJoe Perches 4009a605e32eSJoe Perches# Block comment * alignment 401086406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 401186406b1cSJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 4012a605e32eSJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 4013a605e32eSJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 401486406b1cSJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 401586406b1cSJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 4016c24f9f19SJoe Perches my $oldindent; 4017c24f9f19SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 4018c24f9f19SJoe Perches if (defined($1)) { 401986406b1cSJoe Perches $oldindent = expand_tabs($1); 402086406b1cSJoe Perches } else { 402105880600SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 402205880600SJoe Perches $oldindent = expand_tabs($1); 402308eb9b80SJoe Perches } 402408eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 4025af207524SJoe Perches my $newindent = $1; 4026af207524SJoe Perches $newindent = expand_tabs($newindent); 4027af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 402808eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 4029af207524SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 4030af207524SJoe Perches } 403108eb9b80SJoe Perches } 4032af207524SJoe Perches 4033af207524SJoe Perches# check for missing blank lines after struct/union declarations 4034af207524SJoe Perches# with exceptions for various attributes and macros 4035af207524SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 4036af207524SJoe Perches $line =~ /^\+/ && 4037af207524SJoe Perches !($line =~ /^\+\s*$/ || 403808eb9b80SJoe Perches $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param|ALLOW_ERROR_INJECTION)/ || 403908eb9b80SJoe Perches $line =~ /^\+\s*MODULE_/i || 404008eb9b80SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 4041af207524SJoe Perches $line =~ /^\+[a-z_]*init/ || 404208eb9b80SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 404308eb9b80SJoe Perches $line =~ /^\+\s*DECLARE/ || 404408eb9b80SJoe Perches $line =~ /^\+\s*builtin_[\w_]*driver/ || 404508eb9b80SJoe Perches $line =~ /^\+\s*__setup/)) { 404608eb9b80SJoe Perches if (CHK("LINE_SPACING", 40477f619191SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 40487f619191SJoe Perches $fix) { 40497f619191SJoe Perches fix_insert_line($fixlinenr, "\+"); 40507f619191SJoe Perches } 40517f619191SJoe Perches } 405271aa3419SSergey Senozhatsky 40537f619191SJoe Perches# check for multiple consecutive blank lines 40547f619191SJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 40557f619191SJoe Perches $line =~ /^\+\s*$/ && 40567f619191SJoe Perches $last_blank_line != ($linenr - 1)) { 40577f619191SJoe Perches if (CHK("LINE_SPACING", 40580bc989ffSMasahiro Yamada "Please don't use multiple blank lines\n" . $hereprev) && 40597f619191SJoe Perches $fix) { 4060d752fcc8SJoe Perches fix_delete_line($fixlinenr, $rawline); 4061d752fcc8SJoe Perches } 4062d752fcc8SJoe Perches 4063f2d7e4d4SJoe Perches $last_blank_line = $linenr; 4064d752fcc8SJoe Perches } 40657f619191SJoe Perches 40667f619191SJoe Perches# check for missing blank lines after declarations 4067365dd4eaSJoe Perches# (declarations must have the same indentation and not be at the start of line) 4068365dd4eaSJoe Perches if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) { 4069365dd4eaSJoe Perches # use temporaries 4070365dd4eaSJoe Perches my $sl = $sline; 4071d752fcc8SJoe Perches my $pl = $prevline; 4072d752fcc8SJoe Perches # remove $Attribute/$Sparse uses to simplify comparisons 4073d752fcc8SJoe Perches $sl =~ s/\b(?:$Attribute|$Sparse)\b//g; 4074f2d7e4d4SJoe Perches $pl =~ s/\b(?:$Attribute|$Sparse)\b//g; 4075d752fcc8SJoe Perches if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 4076d752fcc8SJoe Perches # function pointer declarations 4077365dd4eaSJoe Perches $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 4078365dd4eaSJoe Perches # foo bar; where foo is some local typedef or #define 4079365dd4eaSJoe Perches $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 40803b617e3bSJoe Perches # known declaration macros 4081b5e8736aSJoe Perches $pl =~ /^\+\s+$declaration_macros/) && 4082b5e8736aSJoe Perches # for "else if" which can look like "$Ident $Ident" 4083b5e8736aSJoe Perches !($pl =~ /^\+\s+$c90_Keywords\b/ || 4084b5e8736aSJoe Perches # other possible extensions of declaration lines 4085b5e8736aSJoe Perches $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 4086b5e8736aSJoe Perches # not starting a section or a macro "\" extended line 4087b5e8736aSJoe Perches $pl =~ /(?:\{\s*|\\)$/) && 4088b5e8736aSJoe Perches # looks like a declaration 4089b5e8736aSJoe Perches !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 40905a4e1fd3SJoe Perches # function pointer declarations 4091b5e8736aSJoe Perches $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 40923f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 4093b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 40943f7bac03SJoe Perches # known declaration macros 4095b5e8736aSJoe Perches $sl =~ /^\+\s+$declaration_macros/ || 40963f7bac03SJoe Perches # start of struct or union or enum 4097b5e8736aSJoe Perches $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 40983f7bac03SJoe Perches # start or end of block or continuation of declaration 4099b5e8736aSJoe Perches $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 41003f7bac03SJoe Perches # bitfield continuation 4101b5e8736aSJoe Perches $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 41023f7bac03SJoe Perches # other possible extensions of declaration lines 4103b5e8736aSJoe Perches $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) { 41045a4e1fd3SJoe Perches if (WARN("LINE_SPACING", 4105b5e8736aSJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 41063f7bac03SJoe Perches $fix) { 4107b5e8736aSJoe Perches fix_insert_line($fixlinenr, "\+"); 41083f7bac03SJoe Perches } 4109b5e8736aSJoe Perches } 41103f7bac03SJoe Perches } 4111b5e8736aSJoe Perches 41123f7bac03SJoe Perches# check for spaces at the beginning of a line. 4113b5e8736aSJoe Perches# Exceptions: 41143f7bac03SJoe Perches# 1) within comments 4115b5e8736aSJoe Perches# 2) indented preprocessor commands 41163f7bac03SJoe Perches# 3) hanging labels 4117b5e8736aSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 4118d752fcc8SJoe Perches my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 4119d752fcc8SJoe Perches if (WARN("LEADING_SPACE", 4120d752fcc8SJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 4121f2d7e4d4SJoe Perches $fix) { 4122d752fcc8SJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 41233b617e3bSJoe Perches } 4124b5e8736aSJoe Perches } 41253b617e3bSJoe Perches 41265f7ddae6SRaffaele Recalcati# check we are in a valid C source file if not then ignore this hunk 41276b4c5bebSAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 41286b4c5bebSAndy Whitcroft 41296b4c5bebSAndy Whitcroft# check for unusual line ending [ or ( 41306b4c5bebSAndy Whitcroft if ($line =~ /^\+.*([\[\(])\s*$/) { 41313705ce5bSJoe Perches CHK("OPEN_ENDED_LINE", 41325f7ddae6SRaffaele Recalcati "Lines should not end with a '$1'\n" . $herecurr); 41333705ce5bSJoe Perches } 41343705ce5bSJoe Perches 41353705ce5bSJoe Perches# check if this appears to be the start function declaration, save the name 4136194f66fcSJoe Perches if ($sline =~ /^\+\{\s*$/ && 41373705ce5bSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 41385f7ddae6SRaffaele Recalcati $context_function = $1; 41395f7ddae6SRaffaele Recalcati } 4140b9ea10d6SAndy Whitcroft 4141b9ea10d6SAndy Whitcroft# check if this appears to be the end of function declaration 4142b9ea10d6SAndy Whitcroft if ($sline =~ /^\+\}\s*$/) { 41435751a24eSJoe Perches undef $context_function; 41445751a24eSJoe Perches } 41455751a24eSJoe Perches 41465751a24eSJoe Perches# check indentation of any line with a bare else 41475751a24eSJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 41485751a24eSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 41494dbed76fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 41504dbed76fSJoe Perches my $tabs = length($1) + 1; 41514dbed76fSJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 41524dbed76fSJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 41534dbed76fSJoe Perches defined $lines[$linenr] && 41544dbed76fSJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 41554dbed76fSJoe Perches WARN("UNNECESSARY_ELSE", 41564dbed76fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 41574dbed76fSJoe Perches } 41584dbed76fSJoe Perches } 41594dbed76fSJoe Perches 4160032a4c0fSJoe Perches# check indentation of a line with a break; 4161840080a0SJoe Perches# if the previous line is a goto, return or break 4162032a4c0fSJoe Perches# and is indented the same # of tabs 4163032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 4164032a4c0fSJoe Perches my $tabs = $1; 4165840080a0SJoe Perches if ($prevline =~ /^\+$tabs(goto|return|break)\b/) { 4166840080a0SJoe Perches if (WARN("UNNECESSARY_BREAK", 4167840080a0SJoe Perches "break is not useful after a $1\n" . $hereprev) && 4168840080a0SJoe Perches $fix) { 4169032a4c0fSJoe Perches fix_delete_line($fixlinenr, $rawline); 4170032a4c0fSJoe Perches } 4171032a4c0fSJoe Perches } 4172032a4c0fSJoe Perches } 4173032a4c0fSJoe Perches 4174c00df19aSJoe Perches# check for RCS/CVS revision markers 4175dc58bc55SJoe Perches if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 4176dc58bc55SJoe Perches WARN("CVS_KEYWORD", 4177c00df19aSJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 4178c00df19aSJoe Perches } 4179dc58bc55SJoe Perches 4180dc58bc55SJoe Perches# check for old HOTPLUG __dev<foo> section markings 4181dc58bc55SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 4182dc58bc55SJoe Perches WARN("HOTPLUG_SECTION", 4183dc58bc55SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 4184dc58bc55SJoe Perches } 4185c00df19aSJoe Perches 4186c00df19aSJoe Perches# Check for potential 'bare' types 4187c00df19aSJoe Perches my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 4188c2fdda0dSAndy Whitcroft $realline_next); 4189cf655043SAndy Whitcroft#print "LINE<$line>\n"; 4190000d1cc1SJoe Perches if ($linenr > $suppress_statement && 4191000d1cc1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 4192c2fdda0dSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 419322f2a2efSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 419456e77d70SJoe Perches $stat =~ s/\n./\n /g; 419556e77d70SJoe Perches $cond =~ s/\n./\n /g; 419656e77d70SJoe Perches 419756e77d70SJoe Perches#print "linenr<$linenr> <$stat>\n"; 419856e77d70SJoe Perches # If this statement has no statement boundaries within 419956e77d70SJoe Perches # it there is no point in retrying a statement scan 42009c0ca6f9SAndy Whitcroft # until we hit end of it. 42012b474a1aSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 42022b474a1aSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 42033e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 4204ca819864SJoe Perches $suppress_statement = $line_nr_next; 42051b5539b1SJoe Perches } 4206170d3a22SAndy Whitcroft 4207f5fe35ddSAndy Whitcroft # Find the real next line. 4208171ae1a4SAndy Whitcroft $realline_next = $line_nr_next; 4209171ae1a4SAndy Whitcroft if (defined $realline_next && 4210171ae1a4SAndy Whitcroft (!defined $lines[$realline_next - 1] || 42113e469cdcSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 42123e469cdcSAndy Whitcroft $realline_next++; 42133e469cdcSAndy Whitcroft } 42143e469cdcSAndy Whitcroft 42153e469cdcSAndy Whitcroft my $s = $stat; 42163e469cdcSAndy Whitcroft $s =~ s/{.*$//s; 42173e469cdcSAndy Whitcroft 42183e469cdcSAndy Whitcroft # Ignore goto labels. 42193e469cdcSAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 4220f74bd194SAndy Whitcroft 42212b474a1aSAndy Whitcroft # Ignore functions being called 42222b474a1aSAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 42232b474a1aSAndy Whitcroft 42242b474a1aSAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 42252b474a1aSAndy Whitcroft 42262b474a1aSAndy Whitcroft # declarations always start with types 42272b474a1aSAndy 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) { 42282b474a1aSAndy Whitcroft my $type = $1; 4229171ae1a4SAndy Whitcroft $type =~ s/\s+/ /g; 4230171ae1a4SAndy Whitcroft possible($type, "A:" . $s); 4231cf655043SAndy Whitcroft 4232c2fdda0dSAndy Whitcroft # definitions in global scope can only start with types 4233171ae1a4SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 4234c2fdda0dSAndy Whitcroft possible($1, "B:" . $s); 4235c2fdda0dSAndy Whitcroft } 4236171ae1a4SAndy Whitcroft 4237c2fdda0dSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 4238463f2864SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 4239463f2864SAndy Whitcroft possible($1, "C:" . $s); 4240c45dcabdSAndy Whitcroft } 4241d2506586SAndy Whitcroft 4242c45dcabdSAndy Whitcroft # Check for any sort of function declaration. 4243c45dcabdSAndy Whitcroft # int foo(something bar, other baz); 4244c45dcabdSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 4245c45dcabdSAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 42466c72ffaaSAndy Whitcroft my ($name_len) = length($1); 4247a6a84062SAndy Whitcroft 4248c45dcabdSAndy Whitcroft my $ctx = $s; 4249c2fdda0dSAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 42508905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 42516c72ffaaSAndy Whitcroft 425265863862SAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 4253c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 42549c0ca6f9SAndy Whitcroft 42558905a67cSAndy Whitcroft possible($1, "D:" . $s); 42568905a67cSAndy Whitcroft } 42578905a67cSAndy Whitcroft } 42588905a67cSAndy Whitcroft } 4259171ae1a4SAndy Whitcroft 42608905a67cSAndy Whitcroft } 42618905a67cSAndy Whitcroft 4262cf655043SAndy Whitcroft# 4263773647a0SAndy Whitcroft# Checks which may be anchored in the context. 42648905a67cSAndy Whitcroft# 4265cf655043SAndy Whitcroft 42668905a67cSAndy Whitcroft# Check for switch () and associated case and default 4267c45dcabdSAndy Whitcroft# statements should be at the same indent. 42688905a67cSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 4269c45dcabdSAndy Whitcroft my $err = ''; 42708905a67cSAndy Whitcroft my $sep = ''; 42718905a67cSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 42728905a67cSAndy Whitcroft shift(@ctx); 42738905a67cSAndy Whitcroft for my $ctx (@ctx) { 42749c0ca6f9SAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 42759c0ca6f9SAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 427600df344fSAndy Whitcroft $indent != $cindent) { 427700df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 427800df344fSAndy Whitcroft $sep = ''; 427900df344fSAndy Whitcroft } else { 428000df344fSAndy Whitcroft $sep = "[...]\n"; 428100df344fSAndy Whitcroft } 428200df344fSAndy Whitcroft } 428300df344fSAndy Whitcroft if ($err ne '') { 428400df344fSAndy Whitcroft ERROR("SWITCH_CASE_INDENT_LEVEL", 428500df344fSAndy Whitcroft "switch and case should be at the same indent\n$hereline$err"); 428600df344fSAndy Whitcroft } 428700df344fSAndy Whitcroft } 428800df344fSAndy Whitcroft 428900df344fSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 429000df344fSAndy Whitcroft# or if that brace on the next line is for something else 429100df344fSAndy Whitcroft if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 429200df344fSAndy Whitcroft my $pre_ctx = "$1$2"; 429300df344fSAndy Whitcroft 429400df344fSAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 429500df344fSAndy Whitcroft 429600df344fSAndy Whitcroft if ($line =~ /^\+\t{6,}/) { 429700df344fSAndy Whitcroft WARN("DEEP_INDENTATION", 4298000d1cc1SJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 4299000d1cc1SJoe Perches } 4300de7d4f0eSAndy Whitcroft 4301de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 4302de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 4303de7d4f0eSAndy Whitcroft 4304de7d4f0eSAndy Whitcroft my $ctx_ln = $linenr; 43050fe3dc2bSJoe Perches my $ctx_skip = $realcnt; 4306773647a0SAndy Whitcroft 4307773647a0SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 43089c0ca6f9SAndy Whitcroft defined $lines[$ctx_ln - 1] && 43098eef05ddSJoe Perches $lines[$ctx_ln - 1] =~ /^-/)) { 43108eef05ddSJoe Perches ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 43118eef05ddSJoe Perches $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 43128eef05ddSJoe Perches $ctx_ln++; 43138eef05ddSJoe Perches } 43148eef05ddSJoe Perches 4315de7d4f0eSAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 4316de7d4f0eSAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 4317de7d4f0eSAndy Whitcroft 4318548596d5SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 4319548596d5SAndy Whitcroft ERROR("OPEN_BRACE", 4320de7d4f0eSAndy Whitcroft "that open brace { should be on the previous line\n" . 4321548596d5SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 4322548596d5SAndy Whitcroft } 4323548596d5SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 4324548596d5SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 4325548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1]) 4326773647a0SAndy Whitcroft { 4327773647a0SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 4328548596d5SAndy Whitcroft if ($nindent > $indent) { 432953210168SAndy Whitcroft WARN("TRAILING_SEMICOLON", 433053210168SAndy Whitcroft "trailing semicolon indicates no statements, indent implies otherwise\n" . 4331773647a0SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 4332773647a0SAndy Whitcroft } 4333000d1cc1SJoe Perches } 4334000d1cc1SJoe Perches } 433501464f30SAndy Whitcroft 433600df344fSAndy Whitcroft# Check relative indent for conditionals and blocks. 4337773647a0SAndy Whitcroft if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 4338773647a0SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 4339773647a0SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 4340773647a0SAndy Whitcroft if (!defined $stat); 43419c0ca6f9SAndy Whitcroft my ($s, $c) = ($stat, $cond); 43429c0ca6f9SAndy Whitcroft 4343000d1cc1SJoe Perches substr($s, 0, length($c), ''); 4344000d1cc1SJoe Perches 434501464f30SAndy Whitcroft # remove inline comments 43469c0ca6f9SAndy Whitcroft $s =~ s/$;/ /g; 43479c0ca6f9SAndy Whitcroft $c =~ s/$;/ /g; 434800df344fSAndy Whitcroft 434900df344fSAndy Whitcroft # Find out how long the conditional actually is. 43504d001e4dSAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4351f6950a73SJoe Perches my $cond_lines = 1 + $#newlines; 43523e469cdcSAndy Whitcroft 43533e469cdcSAndy Whitcroft # Make sure we remove the line prefixes as we have 43543e469cdcSAndy Whitcroft # none on the first line, and are going to readd them 43554d001e4dSAndy Whitcroft # where necessary. 43564d001e4dSAndy Whitcroft $s =~ s/\n./\n/gs; 43574d001e4dSAndy Whitcroft while ($s =~ /\n\s+\\\n/) { 43584d001e4dSAndy Whitcroft $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 43599f5af480SJoe Perches } 43609f5af480SJoe Perches 43619f5af480SJoe Perches # We want to check the first line inside the block 43624d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 43634d001e4dSAndy Whitcroft # 1) any blank line termination 43646f779c18SAndy Whitcroft # 2) any opening brace { on end of the line 43656f779c18SAndy Whitcroft # 3) any do (...) { 43664d001e4dSAndy Whitcroft my $continuation = 0; 43679f5af480SJoe Perches my $check = 0; 43689f5af480SJoe Perches $s =~ s/^.*\bdo\b//; 43699f5af480SJoe Perches $s =~ s/^\s*{//; 43709f5af480SJoe Perches if ($s =~ s/^\s*\\//) { 43719f5af480SJoe Perches $continuation = 1; 43729f5af480SJoe Perches } 43739f5af480SJoe Perches if ($s =~ s/^\s*?\n//) { 43749f5af480SJoe Perches $check = 1; 43754d001e4dSAndy Whitcroft $cond_lines++; 43764d001e4dSAndy Whitcroft } 43774d001e4dSAndy Whitcroft 43784d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 43794d001e4dSAndy Whitcroft # preprocessor statement. 43804d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 43814d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 43824d001e4dSAndy Whitcroft $check = 0; 43834d001e4dSAndy Whitcroft } 43844d001e4dSAndy Whitcroft 43854d001e4dSAndy Whitcroft my $cond_ptr = -1; 43864d001e4dSAndy Whitcroft $continuation = 0; 43879bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 43884d001e4dSAndy Whitcroft $cond_ptr = $cond_lines; 43894d001e4dSAndy Whitcroft 43904d001e4dSAndy Whitcroft # If we see an #else/#elif then the code 43914d001e4dSAndy Whitcroft # is not linear. 43924d001e4dSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 43934d001e4dSAndy Whitcroft $check = 0; 43944d001e4dSAndy Whitcroft } 43954d001e4dSAndy Whitcroft 43964d001e4dSAndy Whitcroft # Ignore: 43974d001e4dSAndy Whitcroft # 1) blank lines, they should be at 0, 43984d001e4dSAndy Whitcroft # 2) preprocessor lines, and 43999bd49efeSAndy Whitcroft # 3) labels. 4400740504c6SAndy Whitcroft if ($continuation || 44019bd49efeSAndy Whitcroft $s =~ /^\s*?\n/ || 44029bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 44034d001e4dSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 4404f16fa28fSAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 4405f16fa28fSAndy Whitcroft if ($s =~ s/^.*?\n//) { 4406f16fa28fSAndy Whitcroft $cond_lines++; 4407f16fa28fSAndy Whitcroft } 4408f16fa28fSAndy Whitcroft } 4409f16fa28fSAndy Whitcroft } 44109bd49efeSAndy Whitcroft 44119bd49efeSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 44129bd49efeSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 44139bd49efeSAndy Whitcroft 4414740504c6SAndy Whitcroft # Check if either of these lines are modified, else 4415740504c6SAndy Whitcroft # this is not this patch's fault. 44169bd49efeSAndy Whitcroft if (!defined($stat_real) || 44179bd49efeSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 4418740504c6SAndy Whitcroft $check = 0; 441930dad6ebSAndy Whitcroft } 44209bd49efeSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 44219bd49efeSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 44224d001e4dSAndy Whitcroft } 442330dad6ebSAndy Whitcroft 44244d001e4dSAndy 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"; 44254d001e4dSAndy Whitcroft 44264d001e4dSAndy Whitcroft if ($check && $s ne '' && 44274d001e4dSAndy Whitcroft (($sindent % $tabsize) != 0 || 44284d001e4dSAndy Whitcroft ($sindent < $indent) || 44294d001e4dSAndy Whitcroft ($sindent == $indent && 44304d001e4dSAndy Whitcroft ($s !~ /^\s*(?:\}|\{|else\b)/)) || 44314d001e4dSAndy Whitcroft ($sindent > $indent + $tabsize))) { 44324d001e4dSAndy Whitcroft WARN("SUSPECT_CODE_INDENT", 44334d001e4dSAndy Whitcroft "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 44344d001e4dSAndy Whitcroft } 44354d001e4dSAndy Whitcroft } 44364d001e4dSAndy Whitcroft 44374d001e4dSAndy Whitcroft # Track the 'values' across context and added lines. 44389bd49efeSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 44394d001e4dSAndy Whitcroft my ($curr_values, $curr_vars) = 44409f5af480SJoe Perches annotate_values($opline . "\n", $prev_values); 4441713a09deSAntonio Borneo $curr_values = $prev_values . $curr_values; 44429f5af480SJoe Perches if ($dbg_values) { 4443f6950a73SJoe Perches my $outline = $opline; $outline =~ s/\t/ /g; 4444f6950a73SJoe Perches print "$linenr > .$outline\n"; 4445713a09deSAntonio Borneo print "$linenr > $curr_values\n"; 4446000d1cc1SJoe Perches print "$linenr > $curr_vars\n"; 4447000d1cc1SJoe Perches } 44484d001e4dSAndy Whitcroft $prev_values = substr($curr_values, -1); 44494d001e4dSAndy Whitcroft 44504d001e4dSAndy Whitcroft#ignore lines not being added 44516c72ffaaSAndy Whitcroft next if ($line =~ /^[^\+]/); 44526c72ffaaSAndy Whitcroft 44531f65f947SAndy Whitcroft# check for self assignments used to avoid compiler warnings 44541f65f947SAndy Whitcroft# e.g.: int foo = foo, *bar = NULL; 44556c72ffaaSAndy Whitcroft# struct foo bar = *(&(bar)); 4456c2fdda0dSAndy Whitcroft if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { 4457c2fdda0dSAndy Whitcroft my $var = $1; 4458cf655043SAndy Whitcroft if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { 4459cf655043SAndy Whitcroft WARN("SELF_ASSIGNMENT", 44601f65f947SAndy Whitcroft "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); 4461c2fdda0dSAndy Whitcroft } 44626c72ffaaSAndy Whitcroft } 44636c72ffaaSAndy Whitcroft 446400df344fSAndy Whitcroft# check for dereferences that span multiple lines 44653705ce5bSJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 446600df344fSAndy Whitcroft $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 446799ca38c2SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 446899ca38c2SJoe Perches my $ref = $1; 446999ca38c2SJoe Perches $line =~ /^.\s*($Lval)/; 447099ca38c2SJoe Perches $ref .= $1; 447199ca38c2SJoe Perches $ref =~ s/\s//g; 447299ca38c2SJoe Perches WARN("MULTILINE_DEREFERENCE", 447399ca38c2SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 447499ca38c2SJoe Perches } 447599ca38c2SJoe Perches 447699ca38c2SJoe Perches# check for declarations of signed or unsigned without int 447799ca38c2SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 447811ca40a0SJoe Perches my $type = $1; 447911ca40a0SJoe Perches my $var = $2; 448011ca40a0SJoe Perches $var = "" if (!defined $var); 448111ca40a0SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 448211ca40a0SJoe Perches my $sign = $1; 448311ca40a0SJoe Perches my $pointer = $2; 448411ca40a0SJoe Perches 448511ca40a0SJoe Perches $pointer = "" if (!defined $pointer); 448611ca40a0SJoe Perches 448711ca40a0SJoe Perches if (WARN("UNSPECIFIED_INT", 448811ca40a0SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 448911ca40a0SJoe Perches $fix) { 4490a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 4491c8447115SJoe Perches my $comp_pointer = $pointer; 4492a1ce18e4SJoe Perches $comp_pointer =~ s/\s//g; 4493a1ce18e4SJoe Perches $decl .= $comp_pointer; 4494207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 4495207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 4496a1ce18e4SJoe Perches } 4497a1ce18e4SJoe Perches } 4498a1ce18e4SJoe Perches } 4499a1ce18e4SJoe Perches 4500a1ce18e4SJoe Perches# TEST: allow direct testing of the type matcher. 4501a1ce18e4SJoe Perches if ($dbg_type) { 4502a1ce18e4SJoe Perches if ($line =~ /^.\s*$Declare\s*$/) { 4503a1ce18e4SJoe Perches ERROR("TEST_TYPE", 4504a1ce18e4SJoe Perches "TEST: is type\n" . $herecurr); 4505207a8e84SJoe Perches } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 4506207a8e84SJoe Perches ERROR("TEST_NOT_TYPE", 4507207a8e84SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 4508207a8e84SJoe Perches } 4509207a8e84SJoe Perches next; 4510a1ce18e4SJoe Perches } 4511a1ce18e4SJoe Perches# TEST: allow direct testing of the attribute matcher. 4512a1ce18e4SJoe Perches if ($dbg_attr) { 4513a1ce18e4SJoe Perches if ($line =~ /^.\s*$Modifier\s*$/) { 4514653d4876SAndy Whitcroft ERROR("TEST_ATTR", 45157429c690SAndy Whitcroft "TEST: is attr\n" . $herecurr); 45167429c690SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 4517000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 4518000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 45197429c690SAndy Whitcroft } 4520000d1cc1SJoe Perches next; 4521000d1cc1SJoe Perches } 45227429c690SAndy Whitcroft 4523653d4876SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 4524653d4876SAndy Whitcroft if ($line =~ /^.\s*{/ && 4525a1ef277eSAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 4526a1ef277eSAndy Whitcroft if (ERROR("OPEN_BRACE", 45279360b0e5SAndy Whitcroft "that open brace { should be on the previous line\n" . $hereprev) && 4528000d1cc1SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 4529000d1cc1SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 45309360b0e5SAndy Whitcroft fix_delete_line($fixlinenr, $rawline); 4531000d1cc1SJoe Perches my $fixedline = $prevrawline; 4532000d1cc1SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 4533a1ef277eSAndy Whitcroft fix_insert_line($fixlinenr, $fixedline); 4534a1ef277eSAndy Whitcroft $fixedline = $line; 4535a1ef277eSAndy Whitcroft $fixedline =~ s/^(.\s*)\{\s*/$1/; 4536653d4876SAndy Whitcroft fix_insert_line($fixlinenr, $fixedline); 4537f0a594c1SAndy Whitcroft } 453899423c20SAndy Whitcroft } 453999423c20SAndy Whitcroft 4540d752fcc8SJoe Perches# 4541d752fcc8SJoe Perches# Checks which are anchored on the added line. 4542f2d7e4d4SJoe Perches# 4543f2d7e4d4SJoe Perches 4544f2d7e4d4SJoe Perches# check for malformed paths in #include statements (uses RAW line) 4545d752fcc8SJoe Perches if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 4546d752fcc8SJoe Perches my $path = $1; 4547f2d7e4d4SJoe Perches if ($path =~ m{//}) { 4548d752fcc8SJoe Perches ERROR("MALFORMED_INCLUDE", 45498d81ae05SCyril Bur "malformed #include filename\n" . $herecurr); 4550f2d7e4d4SJoe Perches } 4551d752fcc8SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 4552f0a594c1SAndy Whitcroft ERROR("UAPI_INCLUDE", 4553f0a594c1SAndy Whitcroft "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 455400df344fSAndy Whitcroft } 455500df344fSAndy Whitcroft } 455600df344fSAndy Whitcroft 455700df344fSAndy Whitcroft# no C99 // comments 4558653d4876SAndy Whitcroft if ($line =~ m{//}) { 4559c45dcabdSAndy Whitcroft if (ERROR("C99_COMMENTS", 4560653d4876SAndy Whitcroft "do not use C99 // comments\n" . $herecurr) && 4561653d4876SAndy Whitcroft $fix) { 4562000d1cc1SJoe Perches my $line = $fixed[$fixlinenr]; 4563495e9d84SJoe Perches if ($line =~ /\/\/(.*)$/) { 4564495e9d84SJoe Perches my $comment = trim($1); 4565495e9d84SJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 4566495e9d84SJoe Perches } 4567495e9d84SJoe Perches } 4568653d4876SAndy Whitcroft } 4569653d4876SAndy Whitcroft # Remove C99 comments. 4570653d4876SAndy Whitcroft $line =~ s@//.*@@; 457100df344fSAndy Whitcroft $opline =~ s@//.*@@; 457200df344fSAndy Whitcroft 45733705ce5bSJoe Perches# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 45743705ce5bSJoe Perches# the whole statement. 45753705ce5bSJoe Perches#print "APW <$lines[$realline_next - 1]>\n"; 4576194f66fcSJoe Perches if (defined $realline_next && 45773705ce5bSJoe Perches exists $lines[$realline_next - 1] && 45783705ce5bSJoe Perches !defined $suppress_export{$realline_next} && 4579194f66fcSJoe Perches ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 45803705ce5bSJoe Perches # Handle definitions which produce identifiers with 45813705ce5bSJoe Perches # a prefix: 458200df344fSAndy Whitcroft # XXX(foo); 458300df344fSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 45840a920b5bSAndy Whitcroft my $name = $1; 45856c72ffaaSAndy Whitcroft $name =~ s/^\s*($Ident).*/$1/; 45860a920b5bSAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 45872b474a1aSAndy Whitcroft $name =~ /^${Ident}_$2/) { 45882b474a1aSAndy Whitcroft#print "FOO C name<$name>\n"; 45892b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 45902b474a1aSAndy Whitcroft 45912b474a1aSAndy Whitcroft } elsif ($stat !~ /(?: 45922b474a1aSAndy Whitcroft \n.}\s*$| 459336794822SChristoph Hellwig ^.DEFINE_$Ident\(\Q$name\E\)| 45943cbf62dfSAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 45953cbf62dfSAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 45963cbf62dfSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 45973cbf62dfSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 4598653d4876SAndy Whitcroft )/x) { 459970a11659SJoe Perches#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 460087a53877SAndy Whitcroft $suppress_export{$realline_next} = 2; 46013cbf62dfSAndy Whitcroft } else { 46023cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 46033cbf62dfSAndy Whitcroft } 46043cbf62dfSAndy Whitcroft } 46053cbf62dfSAndy Whitcroft if (!defined $suppress_export{$linenr} && 46062b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 460748012058SAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { 460848012058SAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 460948012058SAndy Whitcroft $suppress_export{$linenr} = 2; 46102b474a1aSAndy Whitcroft } 46112b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 461248012058SAndy Whitcroft $suppress_export{$linenr} == 2) { 46132b474a1aSAndy Whitcroft WARN("EXPORT_SYMBOL", 46142b474a1aSAndy Whitcroft "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 46152b474a1aSAndy Whitcroft } 46162b474a1aSAndy Whitcroft 46170a920b5bSAndy Whitcroft# check for global initialisers. 46180a920b5bSAndy Whitcroft if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ && 46192b474a1aSAndy Whitcroft !exclude_global_initialisers($realfile)) { 46202b474a1aSAndy Whitcroft if (ERROR("GLOBAL_INITIALISERS", 462136794822SChristoph Hellwig "do not initialise globals to $1\n" . $herecurr) && 46222b474a1aSAndy Whitcroft $fix) { 46232b474a1aSAndy Whitcroft $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 46242b474a1aSAndy Whitcroft } 46252b474a1aSAndy Whitcroft } 46262b474a1aSAndy Whitcroft# check for static initialisers. 4627000d1cc1SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 4628000d1cc1SJoe Perches if (ERROR("INITIALISED_STATIC", 46292b474a1aSAndy Whitcroft "do not initialise statics to $1\n" . 46300a920b5bSAndy Whitcroft $herecurr) && 46315150bda4SJoe Eloff $fix) { 46325b8f82e1SSong Liu $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 46335b8f82e1SSong Liu } 4634d5e616fcSJoe Perches } 46356d32f7a3SJoe Perches 4636d5e616fcSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 46376d32f7a3SJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 4638d5e616fcSJoe Perches my $tmp = trim($1); 4639f0a594c1SAndy Whitcroft WARN("MISORDERED_TYPE", 46400a920b5bSAndy Whitcroft "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 46416d32f7a3SJoe Perches } 4642d5e616fcSJoe Perches 46436d32f7a3SJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4644d5e616fcSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4645d5e616fcSJoe Perches my $type = trim($1); 46466d32f7a3SJoe Perches next if ($type !~ /\bint\b/); 4647d5e616fcSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 46480a920b5bSAndy Whitcroft my $new_type = $type; 46490a920b5bSAndy Whitcroft $new_type =~ s/\b\s*int\s*\b/ /; 46501813087dSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 46511813087dSJoe Perches $new_type =~ s/^const\s+//; 46521813087dSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 46531813087dSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 46541813087dSJoe Perches $new_type =~ s/\s+/ /g; 46551813087dSJoe Perches $new_type = trim($new_type); 46561813087dSJoe Perches if (WARN("UNNECESSARY_INT", 4657809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4658809e082eSJoe Perches $fix) { 4659809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4660809e082eSJoe Perches } 4661809e082eSJoe Perches } 4662809e082eSJoe Perches 4663809e082eSJoe Perches# check for static const char * arrays. 4664809e082eSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4665809e082eSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4666809e082eSJoe Perches "static const char * array should probably be static const char * const\n" . 4667809e082eSJoe Perches $herecurr); 4668809e082eSJoe Perches } 4669809e082eSJoe Perches 4670809e082eSJoe Perches# check for initialized const char arrays that should be static const 4671809e082eSJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 4672809e082eSJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 4673809e082eSJoe Perches "const array should probably be static const\n" . $herecurr) && 4674809e082eSJoe Perches $fix) { 4675809e082eSJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 4676809e082eSJoe Perches } 4677cb710ecaSJoe Perches } 4678cb710ecaSJoe Perches 4679000d1cc1SJoe Perches# check for static char foo[] = "bar" declarations. 4680000d1cc1SJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4681cb710ecaSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4682cb710ecaSJoe Perches "static char array declaration should probably be static const char\n" . 4683cb710ecaSJoe Perches $herecurr); 468477b8c0a8SJoe Perches } 468577b8c0a8SJoe Perches 468677b8c0a8SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 468777b8c0a8SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 468877b8c0a8SJoe Perches my $found = $1; 468977b8c0a8SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 469077b8c0a8SJoe Perches WARN("CONST_CONST", 469177b8c0a8SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 469277b8c0a8SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4693cb710ecaSJoe Perches WARN("CONST_CONST", 4694cb710ecaSJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4695000d1cc1SJoe Perches } 4696000d1cc1SJoe Perches } 4697cb710ecaSJoe Perches 4698cb710ecaSJoe Perches# check for const static or static <non ptr type> const declarations 4699cb710ecaSJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const' 4700ab7e23f3SJoe Perches if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ || 4701ab7e23f3SJoe Perches $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) { 4702ab7e23f3SJoe Perches if (WARN("STATIC_CONST", 4703ab7e23f3SJoe Perches "Move const after static - use 'static const $1'\n" . $herecurr) && 4704ab7e23f3SJoe Perches $fix) { 4705ab7e23f3SJoe Perches $fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/; 4706ab7e23f3SJoe Perches $fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/; 4707ab7e23f3SJoe Perches } 4708ab7e23f3SJoe Perches } 4709ab7e23f3SJoe Perches 4710ab7e23f3SJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 4711ab7e23f3SJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 471273169765SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 471373169765SJoe Perches "char * array declaration might be better as static const\n" . 471473169765SJoe Perches $herecurr); 471573169765SJoe Perches } 471673169765SJoe Perches 471773169765SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 471873169765SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 471973169765SJoe Perches my $array = $1; 472073169765SJoe 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*\))@) { 472173169765SJoe Perches my $array_div = $1; 472273169765SJoe Perches if (WARN("ARRAY_SIZE", 472373169765SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 47249b0fa60dSJoe Perches $fix) { 47259b0fa60dSJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 47269b0fa60dSJoe Perches } 47279b0fa60dSJoe Perches } 47289b0fa60dSJoe Perches } 47299b0fa60dSJoe Perches 47309b0fa60dSJoe Perches# check for function declarations without arguments like "int foo()" 4731b598b670SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4732b598b670SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4733b598b670SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4734b598b670SJoe Perches $fix) { 4735b598b670SJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4736b598b670SJoe Perches } 4737b598b670SJoe Perches } 4738b598b670SJoe Perches 4739b598b670SJoe Perches# check for new typedefs, only function parameters and sparse annotations 4740b598b670SJoe Perches# make sense. 4741b598b670SJoe Perches if ($line =~ /\btypedef\s/ && 4742b598b670SJoe Perches $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4743b598b670SJoe Perches $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 4744b36190c5SJoe Perches $line !~ /\b$typeTypedefs\b/ && 474516b7f3c8SJoe Perches $line !~ /\b__bitwise\b/) { 4746b36190c5SJoe Perches WARN("NEW_TYPEDEFS", 4747b36190c5SJoe Perches "do not add new typedefs\n" . $herecurr); 4748b36190c5SJoe Perches } 4749194f66fcSJoe Perches 4750b36190c5SJoe Perches# * goes on variable not on type 4751b36190c5SJoe Perches # (char*[ const]) 4752b36190c5SJoe Perches while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4753653d4876SAndy Whitcroft #print "AA<$1>\n"; 4754653d4876SAndy Whitcroft my ($ident, $from, $to) = ($1, $2, $2); 4755653d4876SAndy Whitcroft 47568054576dSAndy Whitcroft # Should start with a space. 4757c45dcabdSAndy Whitcroft $to =~ s/^(\S)/ $1/; 47588ed22cadSAndy Whitcroft # Should not end with a space. 475946d832f5SMichael S. Tsirkin $to =~ s/\s+$//; 4760000d1cc1SJoe Perches # '*'s should not have spaces between. 4761000d1cc1SJoe Perches while ($to =~ s/\*\s+\*/\*\*/) { 47620a920b5bSAndy Whitcroft } 47630a920b5bSAndy Whitcroft 47640a920b5bSAndy Whitcroft## print "1: from<$from> to<$to> ident<$ident>\n"; 476565863862SAndy Whitcroft if ($from ne $to) { 4766bfcb2cc7SAndy Whitcroft if (ERROR("POINTER_LOCATION", 4767bfcb2cc7SAndy Whitcroft "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 47683705ce5bSJoe Perches $fix) { 4769d8aaf121SAndy Whitcroft my $sub_from = $ident; 477065863862SAndy Whitcroft my $sub_to = $ident; 477165863862SAndy Whitcroft $sub_to =~ s/\Q$from\E/$to/; 477265863862SAndy Whitcroft $fixed[$fixlinenr] =~ 477365863862SAndy Whitcroft s@\Q$sub_from\E@$sub_to@; 477465863862SAndy Whitcroft } 4775f9a0b3d1SAndy Whitcroft } 477665863862SAndy Whitcroft } 4777d8aaf121SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 47783705ce5bSJoe Perches #print "BB<$1>\n"; 477965863862SAndy Whitcroft my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 47803705ce5bSJoe Perches 47813705ce5bSJoe Perches # Should start with a space. 47823705ce5bSJoe Perches $to =~ s/^(\S)/ $1/; 47833705ce5bSJoe Perches # Should not end with a space. 47843705ce5bSJoe Perches $to =~ s/\s+$//; 47853705ce5bSJoe Perches # '*'s should not have spaces between. 4786194f66fcSJoe Perches while ($to =~ s/\*\s+\*/\*\*/) { 47873705ce5bSJoe Perches } 47883705ce5bSJoe Perches # Modifiers should have spaces. 478965863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 4790bfcb2cc7SAndy Whitcroft 4791bfcb2cc7SAndy Whitcroft## print "2: from<$from> to<$to> ident<$ident>\n"; 4792bfcb2cc7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 47933705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 4794d8aaf121SAndy Whitcroft "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 479565863862SAndy Whitcroft $fix) { 479665863862SAndy Whitcroft 479765863862SAndy Whitcroft my $sub_from = $match; 479865863862SAndy Whitcroft my $sub_to = $match; 479965863862SAndy Whitcroft $sub_to =~ s/\Q$from\E/$to/; 4800f9a0b3d1SAndy Whitcroft $fixed[$fixlinenr] =~ 480165863862SAndy Whitcroft s@\Q$sub_from\E@$sub_to@; 480265863862SAndy Whitcroft } 480365863862SAndy Whitcroft } 480465863862SAndy Whitcroft } 48053705ce5bSJoe Perches 4806667026e7SAndy Whitcroft# do not use BUG() or variants 48073705ce5bSJoe Perches if ($line =~ /\b(?!AA_|BUILD_|DCCP_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) { 48083705ce5bSJoe Perches my $msg_level = \&WARN; 48093705ce5bSJoe Perches $msg_level = \&CHK if ($file); 48103705ce5bSJoe Perches &{$msg_level}("AVOID_BUG", 48113705ce5bSJoe Perches "Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants\n" . $herecurr); 48123705ce5bSJoe Perches } 48133705ce5bSJoe Perches 4814194f66fcSJoe Perches# avoid LINUX_VERSION_CODE 48153705ce5bSJoe Perches if ($line =~ /\bLINUX_VERSION_CODE\b/) { 48163705ce5bSJoe Perches WARN("LINUX_VERSION_CODE", 481765863862SAndy Whitcroft "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 48180a920b5bSAndy Whitcroft } 48190a920b5bSAndy Whitcroft 482069d517e6SDavid Hildenbrand# check for uses of printk_ratelimit 482169d517e6SDavid Hildenbrand if ($line =~ /\bprintk_ratelimit\s*\(/) { 48220675a8fbSJean Delvare WARN("PRINTK_RATELIMITED", 48230675a8fbSJean Delvare "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 48240675a8fbSJean Delvare } 482569d517e6SDavid Hildenbrand 48269d3e3c70SJoe Perches# printk should use KERN_* levels 48270a920b5bSAndy Whitcroft if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 48289d3e3c70SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 48298905a67cSAndy Whitcroft "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 4830000d1cc1SJoe Perches } 4831000d1cc1SJoe Perches 48328905a67cSAndy Whitcroft# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL> 48338905a67cSAndy Whitcroft if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) { 483417441227SJoe Perches my $printk = $1; 483517441227SJoe Perches my $modifier = $2; 4836000d1cc1SJoe Perches my $orig = $3; 4837000d1cc1SJoe Perches $modifier = "" if (!defined($modifier)); 483817441227SJoe Perches my $level = lc($orig); 483917441227SJoe Perches $level = "warn" if ($level eq "warning"); 4840eeef5733SJoe Perches my $level2 = $level; 4841eeef5733SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4842000d1cc1SJoe Perches $level .= $modifier; 4843eeef5733SJoe Perches $level2 .= $modifier; 484400df344fSAndy Whitcroft WARN("PREFER_PR_LEVEL", 48450a920b5bSAndy Whitcroft "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to $printk(KERN_$orig ...\n" . $herecurr); 4846f5eea3b0SJoe Perches } 4847f5eea3b0SJoe Perches 4848f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL> 4849f5eea3b0SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4850f5eea3b0SJoe Perches my $orig = $1; 4851f5eea3b0SJoe Perches my $level = lc($orig); 4852243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 4853243f3803SJoe Perches $level = "dbg" if ($level eq "debug"); 48548f26b837SJoe Perches WARN("PREFER_DEV_LEVEL", 48558f26b837SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4856f5eea3b0SJoe Perches } 4857f5eea3b0SJoe Perches 4858243f3803SJoe Perches# trace_printk should not be used in production code. 4859f5eea3b0SJoe Perches if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { 4860243f3803SJoe Perches WARN("TRACE_PRINTK", 4861243f3803SJoe Perches "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); 4862f5eea3b0SJoe Perches } 4863dc139313SJoe Perches 4864dc139313SJoe Perches# ENOSYS means "bad syscall nr" and nothing else. This will have a small 4865dc139313SJoe Perches# number of false positives, but assembly files are not checked, so at 4866dc139313SJoe Perches# least the arch entry code will not trigger this warning. 4867dc139313SJoe Perches if ($line =~ /\bENOSYS\b/) { 4868dc139313SJoe Perches WARN("ENOSYS", 4869dc139313SJoe Perches "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 4870dc139313SJoe Perches } 4871dc139313SJoe Perches 48728020b253SNicolas Boichat# ENOTSUPP is not a standard error code and should be avoided in new patches. 48738020b253SNicolas Boichat# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. 48748020b253SNicolas Boichat# Similarly to ENOSYS warning a small number of false positives is expected. 48758020b253SNicolas Boichat if (!$file && $line =~ /\bENOTSUPP\b/) { 48768020b253SNicolas Boichat if (WARN("ENOTSUPP", 48778020b253SNicolas Boichat "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && 487891c9afafSAndy Lutomirski $fix) { 487991c9afafSAndy Lutomirski $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; 488091c9afafSAndy Lutomirski } 488191c9afafSAndy Lutomirski } 488291c9afafSAndy Lutomirski 488391c9afafSAndy Lutomirski# function brace can't be on same line, except for #defines of do while, 488491c9afafSAndy Lutomirski# or if closed on same line 488591c9afafSAndy Lutomirski if ($perl_version_ok && 48866b9ea5ffSJakub Kicinski $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 48876b9ea5ffSJakub Kicinski $sline !~ /\#\s*define\b.*do\s*\{/ && 48886b9ea5ffSJakub Kicinski $sline !~ /}/) { 48896b9ea5ffSJakub Kicinski if (ERROR("OPEN_BRACE", 48906b9ea5ffSJakub Kicinski "open brace '{' following function definitions go on the next line\n" . $herecurr) && 48916b9ea5ffSJakub Kicinski $fix) { 48926b9ea5ffSJakub Kicinski fix_delete_line($fixlinenr, $rawline); 48936b9ea5ffSJakub Kicinski my $fixed_line = $rawline; 48946b9ea5ffSJakub Kicinski $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; 48956b9ea5ffSJakub Kicinski my $line1 = $1; 48966b9ea5ffSJakub Kicinski my $line2 = $2; 4897653d4876SAndy Whitcroft fix_insert_line($fixlinenr, ltrim($line1)); 4898653d4876SAndy Whitcroft fix_insert_line($fixlinenr, "\+{"); 48995b57980dSJoe Perches if ($line2 !~ /^\s*$/) { 49002d453e3bSJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 49012d453e3bSJoe Perches } 49022d453e3bSJoe Perches } 49038d182478SJoe Perches } 49042d453e3bSJoe Perches 49058d182478SJoe Perches# open braces for enum, union and struct go on the same line. 49068d182478SJoe Perches if ($line =~ /^.\s*{/ && 49078d182478SJoe Perches $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 490803f49351SDwaipayan Ray if (ERROR("OPEN_BRACE", 49098d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 49108d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 49118d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 49128d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 49138d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 49148d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 49158d182478SJoe Perches $fixedline = $rawline; 49168d182478SJoe Perches $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 49170a920b5bSAndy Whitcroft if ($fixedline !~ /^\+\s*$/) { 4918653d4876SAndy Whitcroft fix_insert_line($fixlinenr, $fixedline); 49198905a67cSAndy Whitcroft } 49208905a67cSAndy Whitcroft } 49218905a67cSAndy Whitcroft } 49228d182478SJoe Perches 49238d182478SJoe Perches# missing space after union, struct or enum definition 49248d182478SJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 49258d182478SJoe Perches if (WARN("SPACING", 49268d182478SJoe Perches "missing space after $1 definition\n" . $herecurr) && 49278d182478SJoe Perches $fix) { 49288d182478SJoe Perches $fixed[$fixlinenr] =~ 49298d182478SJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 49308d81ae05SCyril Bur } 49318d182478SJoe Perches } 49328d182478SJoe Perches 49338d182478SJoe Perches# Function pointer declarations 49348d182478SJoe Perches# check spacing between type, funcptr, and args 49358905a67cSAndy Whitcroft# canonical declaration is "type (*funcptr)(args...)" 49368905a67cSAndy Whitcroft if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 49370c73b4ebSAndy Whitcroft my $declare = $1; 49383705ce5bSJoe Perches my $pre_pointer_space = $2; 49393705ce5bSJoe Perches my $post_pointer_space = $3; 49403705ce5bSJoe Perches my $funcname = $4; 49413705ce5bSJoe Perches my $post_funcname_space = $5; 4942194f66fcSJoe Perches my $pre_args_space = $6; 49433705ce5bSJoe Perches 49443705ce5bSJoe Perches# the $Declare variable will capture all spaces after the type 49450c73b4ebSAndy Whitcroft# so check it for a missing trailing missing space but pointer return types 49460c73b4ebSAndy Whitcroft# don't need a space so don't warn for those. 494731070b5dSJoe Perches my $post_declare_space = ""; 494831070b5dSJoe Perches if ($declare =~ /(\s+)$/) { 494931070b5dSJoe Perches $post_declare_space = $1; 495091f72e9cSJoe Perches $declare = rtrim($declare); 495131070b5dSJoe Perches } 495231070b5dSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 495331070b5dSJoe Perches WARN("SPACING", 495431070b5dSJoe Perches "missing space after return type\n" . $herecurr); 495531070b5dSJoe Perches $post_declare_space = " "; 495631070b5dSJoe Perches } 495731070b5dSJoe Perches 495891f72e9cSJoe Perches# unnecessary space "type (*funcptr)(args...)" 495991f72e9cSJoe Perches# This test is not currently implemented because these declarations are 496091f72e9cSJoe Perches# equivalent to 496191f72e9cSJoe Perches# int foo(int bar, ...) 496291f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 496391f72e9cSJoe Perches# 496491f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 496591f72e9cSJoe Perches# WARN("SPACING", 496691f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 496731070b5dSJoe Perches# } 496831070b5dSJoe Perches 496991f72e9cSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 497031070b5dSJoe Perches if (defined $pre_pointer_space && 497131070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 497231070b5dSJoe Perches WARN("SPACING", 497391f72e9cSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 497491f72e9cSJoe Perches } 497591f72e9cSJoe Perches 497691f72e9cSJoe Perches# unnecessary space "type (* funcptr)(args...)" 497791f72e9cSJoe Perches if (defined $post_pointer_space && 497891f72e9cSJoe Perches $post_pointer_space =~ /^\s/) { 497991f72e9cSJoe Perches WARN("SPACING", 498091f72e9cSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 498191f72e9cSJoe Perches } 498231070b5dSJoe Perches 498331070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 498431070b5dSJoe Perches if (defined $post_funcname_space && 498531070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 498631070b5dSJoe Perches WARN("SPACING", 498731070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 498831070b5dSJoe Perches } 498931070b5dSJoe Perches 499031070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 499131070b5dSJoe Perches if (defined $pre_args_space && 499231070b5dSJoe Perches $pre_args_space =~ /^\s/) { 499331070b5dSJoe Perches WARN("SPACING", 499431070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 499531070b5dSJoe Perches } 499631070b5dSJoe Perches 499731070b5dSJoe Perches if (show_type("SPACING") && $fix) { 499831070b5dSJoe Perches $fixed[$fixlinenr] =~ 499931070b5dSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 500031070b5dSJoe Perches } 500131070b5dSJoe Perches } 500231070b5dSJoe Perches 500331070b5dSJoe Perches# check for spacing round square brackets; allowed: 500431070b5dSJoe Perches# 1. with a type on the left -- int [] a; 500531070b5dSJoe Perches# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 500631070b5dSJoe Perches# 3. inside a curly brace -- = { [0...10] = 5 } 500731070b5dSJoe Perches while ($line =~ /(.*?\s)\[/g) { 500831070b5dSJoe Perches my ($where, $prefix) = ($-[1], $1); 500931070b5dSJoe Perches if ($prefix !~ /$Type\s+$/ && 501031070b5dSJoe Perches ($where != 0 || $prefix !~ /^.\s+$/) && 501131070b5dSJoe Perches $prefix !~ /[{,:]\s+$/) { 5012194f66fcSJoe Perches if (ERROR("BRACKET_SPACE", 501391f72e9cSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 501431070b5dSJoe Perches $fix) { 501531070b5dSJoe Perches $fixed[$fixlinenr] =~ 501631070b5dSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 50178d31cfceSAndy Whitcroft } 50188d31cfceSAndy Whitcroft } 5019fe2a7dbcSAndy Whitcroft } 5020fe2a7dbcSAndy Whitcroft 50218d31cfceSAndy Whitcroft# check for spaces between functions and their parentheses. 50228d31cfceSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 50238d31cfceSAndy Whitcroft my $name = $1; 5024fe2a7dbcSAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 502538dca988SHeinrich Schuchardt my $ctx = "$ctx_before$name"; 50263705ce5bSJoe Perches 50273705ce5bSJoe Perches # Ignore those directives where spaces _are_ permitted. 50283705ce5bSJoe Perches if ($name =~ /^(?: 5029194f66fcSJoe Perches if|for|while|switch|return|case| 50303705ce5bSJoe Perches volatile|__volatile__| 50313705ce5bSJoe Perches __attribute__|format|__extension__| 50328d31cfceSAndy Whitcroft asm|__asm__|scoped_guard)$/x) 50338d31cfceSAndy Whitcroft { 50348d31cfceSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 5035f0a594c1SAndy Whitcroft # if there is a space between the name and the open 50366c72ffaaSAndy Whitcroft # parenthesis it is simply not a parameter group. 5037c2fdda0dSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 5038773647a0SAndy Whitcroft 5039773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 5040c2fdda0dSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 5041c2fdda0dSAndy Whitcroft 5042773647a0SAndy Whitcroft # If this whole things ends with a type its most 5043773647a0SAndy Whitcroft # likely a typedef for a function. 5044773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 5045773647a0SAndy Whitcroft 504654da6a09SPeter Zijlstra } else { 5047773647a0SAndy Whitcroft if (WARN("SPACING", 5048c2fdda0dSAndy Whitcroft "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 5049c2fdda0dSAndy Whitcroft $fix) { 5050c2fdda0dSAndy Whitcroft $fixed[$fixlinenr] =~ 5051c45dcabdSAndy Whitcroft s/\b$name\s+\(/$name\(/; 5052773647a0SAndy Whitcroft } 5053773647a0SAndy Whitcroft } 5054c45dcabdSAndy Whitcroft } 5055c2fdda0dSAndy Whitcroft 5056c2fdda0dSAndy Whitcroft# Check operator spacing. 5057c2fdda0dSAndy Whitcroft if (!($line=~/\#\s*include/)) { 5058773647a0SAndy Whitcroft my $fixed_line = ""; 5059c2fdda0dSAndy Whitcroft my $line_fixed = 0; 5060c2fdda0dSAndy Whitcroft 50613705ce5bSJoe Perches my $ops = qr{ 50623705ce5bSJoe Perches <<=|>>=|<=|>=|==|!=| 50633705ce5bSJoe Perches \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 5064194f66fcSJoe Perches =>|->|<<|>>|<|>|=|!|~| 50653705ce5bSJoe Perches &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 50663705ce5bSJoe Perches \?:|\?|: 5067f0a594c1SAndy Whitcroft }x; 50686c72ffaaSAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 50699a4cad4eSEric Nelson 5070653d4876SAndy Whitcroft## print("element count: <" . $#elements . ">\n"); 50710a920b5bSAndy Whitcroft## foreach my $el (@elements) { 50723705ce5bSJoe Perches## print("el: <$el>\n"); 50733705ce5bSJoe Perches## } 50743705ce5bSJoe Perches 50759c0ca6f9SAndy Whitcroft my @fix_elements = (); 50769c0ca6f9SAndy Whitcroft my $off = 0; 50779c0ca6f9SAndy Whitcroft 50789c0ca6f9SAndy Whitcroft foreach my $el (@elements) { 50791f65f947SAndy Whitcroft push(@fix_elements, substr($rawline, $off, length($el))); 508084731623SJoe Perches $off += length($el); 50819c0ca6f9SAndy Whitcroft } 5082cf655043SAndy Whitcroft 50833705ce5bSJoe Perches $off = 0; 50843705ce5bSJoe Perches 50853705ce5bSJoe Perches my $blank = copy_spacing($opline); 50863705ce5bSJoe Perches my $last_after = -1; 50873705ce5bSJoe Perches 50883705ce5bSJoe Perches for (my $n = 0; $n < $#elements; $n += 2) { 50893705ce5bSJoe Perches 509000df344fSAndy Whitcroft my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 50916c72ffaaSAndy Whitcroft 50923705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 50933705ce5bSJoe Perches 50943705ce5bSJoe Perches $off += length($elements[$n]); 50953705ce5bSJoe Perches 50963705ce5bSJoe Perches # Pick up the preceding and succeeding characters. 50973705ce5bSJoe Perches my $ca = substr($opline, 0, $off); 50983705ce5bSJoe Perches my $cc = ''; 50996c72ffaaSAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 5100b34c648bSJoe Perches $cc = substr($opline, $off + length($elements[$n + 1])); 51016c72ffaaSAndy Whitcroft } 51020a920b5bSAndy Whitcroft my $cb = "$ca$;$cc"; 51033705ce5bSJoe Perches 51043705ce5bSJoe Perches my $a = ''; 51053705ce5bSJoe Perches $a = 'V' if ($elements[$n] ne ''); 51063705ce5bSJoe Perches $a = 'W' if ($elements[$n] =~ /\s$/); 51073705ce5bSJoe Perches $a = 'C' if ($elements[$n] =~ /$;$/); 51084a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 51094a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 511025985edcSLucas De Marchi $a = 'E' if ($ca =~ /^\s*$/); 5111773647a0SAndy Whitcroft 5112773647a0SAndy Whitcroft my $op = $elements[$n + 1]; 5113773647a0SAndy Whitcroft 5114773647a0SAndy Whitcroft my $c = ''; 5115773647a0SAndy Whitcroft if (defined $elements[$n + 2]) { 5116773647a0SAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 5117773647a0SAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 51184a0df2efSAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 51194a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 51204a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 5121cf655043SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 51224a0df2efSAndy Whitcroft } else { 51234a0df2efSAndy Whitcroft $c = 'E'; 5124773647a0SAndy Whitcroft } 51254a0df2efSAndy Whitcroft 51260a920b5bSAndy Whitcroft my $ctx = "${a}x${c}"; 51274a0df2efSAndy Whitcroft 51284a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 51290a920b5bSAndy Whitcroft 51304a0df2efSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 51314a0df2efSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 5132cf655043SAndy Whitcroft 51334a0df2efSAndy Whitcroft # Pull out the value of this operator. 51344a0df2efSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 51358b1b3378SAndy Whitcroft 51364a0df2efSAndy Whitcroft # Get the full operator variant. 51374a0df2efSAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 51380a920b5bSAndy Whitcroft 51390a920b5bSAndy Whitcroft # Ignore operators passed as parameters. 51404a0df2efSAndy Whitcroft if ($op_type ne 'V' && 51414a0df2efSAndy Whitcroft $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 51424a0df2efSAndy Whitcroft 51434a0df2efSAndy Whitcroft# # Ignore comments 51446c72ffaaSAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 5145de7d4f0eSAndy Whitcroft 51460a920b5bSAndy Whitcroft # ; should have either the end of line or a space or \ after it 514774048ed8SAndy Whitcroft } elsif ($op eq ';') { 51486c72ffaaSAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 51490a920b5bSAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 51501f65f947SAndy Whitcroft if (ERROR("SPACING", 51511f65f947SAndy Whitcroft "space required after that '$op' $at\n" . $hereptr)) { 51521f65f947SAndy Whitcroft $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 515313214adfSAndy Whitcroft $line_fixed = 1; 515413214adfSAndy Whitcroft } 5155d7fe8065SSam Bobroff } 515613214adfSAndy Whitcroft 5157cf655043SAndy Whitcroft # // is a comment 5158cf655043SAndy Whitcroft } elsif ($op eq '//') { 515913214adfSAndy Whitcroft 5160d8aaf121SAndy Whitcroft # : when part of a bitfield 516113214adfSAndy Whitcroft } elsif ($opv eq ':B') { 5162cf655043SAndy Whitcroft # skip the bitfield test for now 5163cf655043SAndy Whitcroft 51643705ce5bSJoe Perches # No spaces for: 51653705ce5bSJoe Perches # -> 5166b34c648bSJoe Perches } elsif ($op eq '->') { 51673705ce5bSJoe Perches if ($ctx =~ /Wx.|.xW/) { 51683705ce5bSJoe Perches if (ERROR("SPACING", 5169d8aaf121SAndy Whitcroft "spaces prohibited around that '$op' $at\n" . $hereptr)) { 5170d8aaf121SAndy Whitcroft $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 5171d8aaf121SAndy Whitcroft if (defined $fix_elements[$n + 2]) { 5172d8aaf121SAndy Whitcroft $fix_elements[$n + 2] =~ s/^\s+//; 51730a920b5bSAndy Whitcroft } 5174b00e4814SJoe Perches $line_fixed = 1; 5175b00e4814SJoe Perches } 5176b00e4814SJoe Perches } 5177b00e4814SJoe Perches 51781f65f947SAndy Whitcroft # , must not have a space before and must have a space on the right. 51791f65f947SAndy Whitcroft } elsif ($op eq ',') { 5180b00e4814SJoe Perches my $rtrim_before = 0; 51814a0df2efSAndy Whitcroft my $space_after = 0; 51823705ce5bSJoe Perches if ($ctx =~ /Wx./) { 51833705ce5bSJoe Perches if (ERROR("SPACING", 5184b34c648bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 51853705ce5bSJoe Perches $line_fixed = 1; 51863705ce5bSJoe Perches $rtrim_before = 1; 51873705ce5bSJoe Perches } 5188b34c648bSJoe Perches } 51893705ce5bSJoe Perches if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 51900a920b5bSAndy Whitcroft if (ERROR("SPACING", 51910a920b5bSAndy Whitcroft "space required after that '$op' $at\n" . $hereptr)) { 51922381097bSJoe Perches $line_fixed = 1; 51930a920b5bSAndy Whitcroft $last_after = $n; 51942381097bSJoe Perches $space_after = 1; 51952381097bSJoe Perches } 51962381097bSJoe Perches } 51972381097bSJoe Perches if ($rtrim_before || $space_after) { 51982381097bSJoe Perches if ($rtrim_before) { 51992381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 52002381097bSJoe Perches } else { 52012381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 52022381097bSJoe Perches } 5203cf655043SAndy Whitcroft if ($space_after) { 52043705ce5bSJoe Perches $good .= " "; 52053705ce5bSJoe Perches } 52063705ce5bSJoe Perches } 5207b34c648bSJoe Perches 52082381097bSJoe Perches # '*' as part of a type definition -- reported already. 52092381097bSJoe Perches } elsif ($opv eq '*_') { 52102381097bSJoe Perches #warn "'*' is part of type\n"; 52112381097bSJoe Perches 52122381097bSJoe Perches # unary operators should have a space before and 52132381097bSJoe Perches # none after. May be left adjacent to another 52142381097bSJoe Perches # unary operator, or a cast 52152381097bSJoe Perches } elsif ($op eq '!' || $op eq '~' || 52162381097bSJoe Perches $opv eq '*U' || $opv eq '-U' || 52172381097bSJoe Perches $opv eq '&U' || $opv eq '&&U') { 52182381097bSJoe Perches if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 52193705ce5bSJoe Perches if (ERROR("SPACING", 52200a920b5bSAndy Whitcroft "space required before that '$op' $at\n" . $hereptr)) { 52210a920b5bSAndy Whitcroft if ($n != $last_after + 2) { 52229c0ca6f9SAndy Whitcroft $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 522374048ed8SAndy Whitcroft $line_fixed = 1; 52249c0ca6f9SAndy Whitcroft } 52259c0ca6f9SAndy Whitcroft } 52269c0ca6f9SAndy Whitcroft } 52279c0ca6f9SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 52289c0ca6f9SAndy Whitcroft # A unary '*' may be const 52299c0ca6f9SAndy Whitcroft 523074048ed8SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 52310d413866SAndy Whitcroft if (ERROR("SPACING", 5232cf655043SAndy Whitcroft "space prohibited after that '$op' $at\n" . $hereptr)) { 52333705ce5bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 52343705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 5235b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5236b34c648bSJoe Perches } 52373705ce5bSJoe Perches $line_fixed = 1; 52383705ce5bSJoe Perches } 52390a920b5bSAndy Whitcroft } 5240b34c648bSJoe Perches 5241a3340b35SAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 5242171ae1a4SAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 5243171ae1a4SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 5244171ae1a4SAndy Whitcroft if (ERROR("SPACING", 52453705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 52463705ce5bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 5247b34c648bSJoe Perches $line_fixed = 1; 52483705ce5bSJoe Perches } 52493705ce5bSJoe Perches } 52503705ce5bSJoe Perches if ($ctx =~ /Wx[BE]/ || 5251b34c648bSJoe Perches ($ctx =~ /Wx./ && $cc =~ /^;/)) { 52523705ce5bSJoe Perches if (ERROR("SPACING", 52530a920b5bSAndy Whitcroft "space prohibited before that '$op' $at\n" . $hereptr)) { 52540a920b5bSAndy Whitcroft $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 52550a920b5bSAndy Whitcroft $line_fixed = 1; 52560a920b5bSAndy Whitcroft } 5257773647a0SAndy Whitcroft } 52583705ce5bSJoe Perches if ($ctx =~ /ExW/) { 52593705ce5bSJoe Perches if (ERROR("SPACING", 5260b34c648bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 52613705ce5bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 52623705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 52630a920b5bSAndy Whitcroft $fix_elements[$n + 2] =~ s/^\s+//; 5264773647a0SAndy Whitcroft } 5265773647a0SAndy Whitcroft $line_fixed = 1; 52663705ce5bSJoe Perches } 52673705ce5bSJoe Perches } 5268b34c648bSJoe Perches 52693705ce5bSJoe Perches # << and >> may either have or not have spaces both sides 52703705ce5bSJoe Perches } elsif ($op eq '<<' or $op eq '>>' or 5271653d4876SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 5272773647a0SAndy Whitcroft $op eq '+' or $op eq '-' or 52733705ce5bSJoe Perches $op eq '*' or $op eq '/' or 52743705ce5bSJoe Perches $op eq '%') 5275b34c648bSJoe Perches { 52763705ce5bSJoe Perches if ($check) { 52773705ce5bSJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 5278773647a0SAndy Whitcroft if (CHK("SPACING", 5279b34c648bSJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 52803705ce5bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 52813705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 52820a920b5bSAndy Whitcroft $line_fixed = 1; 52830a920b5bSAndy Whitcroft } 52849c0ca6f9SAndy Whitcroft } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 52859c0ca6f9SAndy Whitcroft if (CHK("SPACING", 52869c0ca6f9SAndy Whitcroft "space preferred before that '$op' $at\n" . $hereptr)) { 5287c2fdda0dSAndy Whitcroft $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 5288c2fdda0dSAndy Whitcroft $line_fixed = 1; 52890a920b5bSAndy Whitcroft } 5290d2e025f3SJoe Perches } 5291d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 5292d2e025f3SJoe Perches if (ERROR("SPACING", 5293d2e025f3SJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 5294d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5295d2e025f3SJoe Perches if (defined $fix_elements[$n + 2]) { 5296d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5297d2e025f3SJoe Perches } 5298d2e025f3SJoe Perches $line_fixed = 1; 5299d2e025f3SJoe Perches } 5300d2e025f3SJoe Perches } 5301d2e025f3SJoe Perches 5302d2e025f3SJoe Perches # A colon needs no spaces before when it is 5303d2e025f3SJoe Perches # terminating a case value or a label. 5304d2e025f3SJoe Perches } elsif ($opv eq ':C' || $opv eq ':L') { 5305d2e025f3SJoe Perches if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) { 53063705ce5bSJoe Perches if (ERROR("SPACING", 53073705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 5308b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 5309b34c648bSJoe Perches $line_fixed = 1; 5310b34c648bSJoe Perches } 5311b34c648bSJoe Perches } 53123705ce5bSJoe Perches 53133705ce5bSJoe Perches # All the others need spaces both sides. 53140a920b5bSAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 53150a920b5bSAndy Whitcroft my $ok = 0; 53161f65f947SAndy Whitcroft 53171f65f947SAndy Whitcroft # Ignore email addresses <foo@bar> 53181f65f947SAndy Whitcroft if (($op eq '<' && 5319263afd39SChris Down $cc =~ /^\S+\@\S+>/) || 53203705ce5bSJoe Perches ($op eq '>' && 53213705ce5bSJoe Perches $ca =~ /<\S+\@\S+$/)) 5322b34c648bSJoe Perches { 53233705ce5bSJoe Perches $ok = 1; 53243705ce5bSJoe Perches } 53251f65f947SAndy Whitcroft 53261f65f947SAndy Whitcroft # for asm volatile statements 53270a920b5bSAndy Whitcroft # ignore a colon with another 5328cf655043SAndy Whitcroft # colon immediately before or after 53291f65f947SAndy Whitcroft if (($op eq ':') && 53301f65f947SAndy Whitcroft ($ca =~ /:$/ || $cc =~ /^:/)) { 533122f2a2efSAndy Whitcroft $ok = 1; 53321f65f947SAndy Whitcroft } 53331f65f947SAndy Whitcroft 53341f65f947SAndy Whitcroft # messages are ERROR, but ?: are CHK 53351f65f947SAndy Whitcroft if ($ok == 0) { 53361f65f947SAndy Whitcroft my $msg_level = \&ERROR; 53371f65f947SAndy Whitcroft $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 53381f65f947SAndy Whitcroft 53391f65f947SAndy Whitcroft if (&{$msg_level}("SPACING", 5340e0df7e1fSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 5341e0df7e1fSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 5342e0df7e1fSJoe Perches if (defined $fix_elements[$n + 2]) { 5343e0df7e1fSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 5344e0df7e1fSJoe Perches } 5345e0df7e1fSJoe Perches $line_fixed = 1; 5346e0df7e1fSJoe Perches } 5347e0df7e1fSJoe Perches } 534884731623SJoe Perches } 53491f65f947SAndy Whitcroft $off += length($elements[$n + 1]); 53500675a8fbSJean Delvare 53510675a8fbSJean Delvare## print("n: <$n> GOOD: <$good>\n"); 535284731623SJoe Perches 53530675a8fbSJean Delvare $fixed_line = $fixed_line . $good; 53543705ce5bSJoe Perches } 5355b34c648bSJoe Perches 5356b34c648bSJoe Perches if (($#elements % 2) == 0) { 5357b34c648bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 5358b34c648bSJoe Perches } 53593705ce5bSJoe Perches 53603705ce5bSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 53610a920b5bSAndy Whitcroft $fixed[$fixlinenr] = $fixed_line; 536222f2a2efSAndy Whitcroft } 53634a0df2efSAndy Whitcroft 53643705ce5bSJoe Perches 53653705ce5bSJoe Perches } 53663705ce5bSJoe Perches 53673705ce5bSJoe Perches# check for whitespace before a non-naked semicolon 53680a920b5bSAndy Whitcroft if ($line =~ /^\+.*\S\s+;\s*$/) { 53693705ce5bSJoe Perches if (WARN("SPACING", 53703705ce5bSJoe Perches "space prohibited before semicolon\n" . $herecurr) && 53713705ce5bSJoe Perches $fix) { 53723705ce5bSJoe Perches 1 while $fixed[$fixlinenr] =~ 53733705ce5bSJoe Perches s/^(\+.*\S)\s+;/$1;/; 5374194f66fcSJoe Perches } 5375194f66fcSJoe Perches } 53763705ce5bSJoe Perches 53773705ce5bSJoe Perches# check for multiple assignments 53783705ce5bSJoe Perches if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 53790a920b5bSAndy Whitcroft CHK("MULTIPLE_ASSIGNMENTS", 53800a920b5bSAndy Whitcroft "multiple assignments should be avoided\n" . $herecurr); 5381786b6326SJoe Perches } 5382d2e248e7SJoe Perches 5383786b6326SJoe Perches## # check for multiple declarations, allowing for a function declaration 5384786b6326SJoe Perches## # continuation. 5385786b6326SJoe Perches## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 5386194f66fcSJoe Perches## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 5387786b6326SJoe Perches## 5388786b6326SJoe Perches## # Remove any bracketed sections to ensure we do not 5389786b6326SJoe Perches## # falsely report the parameters of functions. 5390786b6326SJoe Perches## my $ln = $line; 5391f0a594c1SAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 5392f0a594c1SAndy Whitcroft## } 5393000d1cc1SJoe Perches## if ($ln =~ /,/) { 5394000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 5395f0a594c1SAndy Whitcroft## "declaring multiple variables together should be avoided\n" . $herecurr); 5396f0a594c1SAndy Whitcroft## } 539722f2a2efSAndy Whitcroft## } 539822f2a2efSAndy Whitcroft 539922f2a2efSAndy Whitcroft#need space before brace following if, while, etc 540022f2a2efSAndy Whitcroft if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 540122f2a2efSAndy Whitcroft $line =~ /\b(?:else|do)\{/) { 540222f2a2efSAndy Whitcroft if (ERROR("SPACING", 5403e73d2715SDwaipayan Ray "space required before the open brace '{'\n" . $herecurr) && 540422f2a2efSAndy Whitcroft $fix) { 540522f2a2efSAndy Whitcroft $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 540622f2a2efSAndy Whitcroft } 540722f2a2efSAndy Whitcroft } 5408000d1cc1SJoe Perches 5409000d1cc1SJoe Perches## # check for blank lines before declarations 541022f2a2efSAndy Whitcroft## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 541122f2a2efSAndy Whitcroft## $prevrawline =~ /^.\s*$/) { 5412f0a594c1SAndy Whitcroft## WARN("SPACING", 54130a920b5bSAndy Whitcroft## "No blank lines before declarations\n" . $hereprev); 54146b8c69e4SGeyslan G. Bem## } 54156ad724e2SMichal Zylowski## 54163705ce5bSJoe Perches 54173705ce5bSJoe Perches# closing brace should have a space following it when it has anything 54183705ce5bSJoe Perches# on the line 54196ad724e2SMichal Zylowski if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 54203705ce5bSJoe Perches if (ERROR("SPACING", 5421de7d4f0eSAndy Whitcroft "space required after that close brace '}'\n" . $herecurr) && 5422de7d4f0eSAndy Whitcroft $fix) { 5423c4a62ef9SJoe Perches $fixed[$fixlinenr] =~ 5424c4a62ef9SJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 5425c4a62ef9SJoe Perches } 5426c4a62ef9SJoe Perches } 5427c4a62ef9SJoe Perches 5428c4a62ef9SJoe Perches# check spacing on square brackets 5429c4a62ef9SJoe Perches if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 5430c4a62ef9SJoe Perches if (ERROR("SPACING", 5431de7d4f0eSAndy Whitcroft "space prohibited after that open square bracket '['\n" . $herecurr) && 5432de7d4f0eSAndy Whitcroft $fix) { 543394fb9845SJoe Perches $fixed[$fixlinenr] =~ 5434d5e616fcSJoe Perches s/\[\s+/\[/; 5435d5e616fcSJoe Perches } 5436d5e616fcSJoe Perches } 5437194f66fcSJoe Perches if ($line =~ /\s\]/) { 5438d5e616fcSJoe Perches if (ERROR("SPACING", 5439d5e616fcSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 54400a920b5bSAndy Whitcroft $fix) { 54410a920b5bSAndy Whitcroft $fixed[$fixlinenr] =~ 544222f2a2efSAndy Whitcroft s/\s+\]/\]/; 544322f2a2efSAndy Whitcroft } 54443705ce5bSJoe Perches } 54453705ce5bSJoe Perches 54463705ce5bSJoe Perches# check spacing on parentheses 5447194f66fcSJoe Perches if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 54483705ce5bSJoe Perches $line !~ /for\s*\(\s+;/) { 54493705ce5bSJoe Perches if (ERROR("SPACING", 545022f2a2efSAndy Whitcroft "space prohibited after that open parenthesis '('\n" . $herecurr) && 545122f2a2efSAndy Whitcroft $fix) { 54523705ce5bSJoe Perches $fixed[$fixlinenr] =~ 54533705ce5bSJoe Perches s/\(\s+/\(/; 54543705ce5bSJoe Perches } 5455194f66fcSJoe Perches } 54563705ce5bSJoe Perches if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 54573705ce5bSJoe Perches $line !~ /for\s*\(.*;\s+\)/ && 545822f2a2efSAndy Whitcroft $line !~ /:\s+\)/) { 545922f2a2efSAndy Whitcroft if (ERROR("SPACING", 5460c45dcabdSAndy Whitcroft "space prohibited before that close parenthesis ')'\n" . $herecurr) && 54619c0ca6f9SAndy Whitcroft $fix) { 54629c0ca6f9SAndy Whitcroft $fixed[$fixlinenr] =~ 54633705ce5bSJoe Perches s/\s+\)/\)/; 54643705ce5bSJoe Perches } 54653705ce5bSJoe Perches } 5466194f66fcSJoe Perches 54673705ce5bSJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 54683705ce5bSJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 546922f2a2efSAndy Whitcroft 547013214adfSAndy Whitcroft while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 5471c45dcabdSAndy Whitcroft my $var = $1; 5472c45dcabdSAndy Whitcroft if (CHK("UNNECESSARY_PARENTHESES", 54733705ce5bSJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 54743705ce5bSJoe Perches $fix) { 54753705ce5bSJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 5476194f66fcSJoe Perches } 54773705ce5bSJoe Perches } 54783705ce5bSJoe Perches 547922f2a2efSAndy Whitcroft# check for unnecessary parentheses around function pointer uses 548022f2a2efSAndy Whitcroft# ie: (foo->bar)(); should be foo->bar(); 5481e2826fd0SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 5482e2826fd0SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 5483e2826fd0SJoe Perches my $var = $2; 5484e2826fd0SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 5485ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 5486ea4acbb1SJoe Perches $fix) { 5487ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 5488ea4acbb1SJoe Perches $var2 =~ s/\s//g; 5489ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 5490ea4acbb1SJoe Perches } 5491ea4acbb1SJoe Perches } 5492ea4acbb1SJoe Perches 5493ea4acbb1SJoe Perches# check for unnecessary parentheses around comparisons 5494ea4acbb1SJoe Perches# except in drivers/staging 5495ea4acbb1SJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@) && 5496ea4acbb1SJoe Perches $perl_version_ok && defined($stat) && 5497ea4acbb1SJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 5498ea4acbb1SJoe Perches my $if_stat = $1; 5499ea4acbb1SJoe Perches my $test = substr($2, 1, -1); 5500ea4acbb1SJoe Perches my $herectx; 5501ea4acbb1SJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 5502ea4acbb1SJoe Perches my $match = $1; 5503ea4acbb1SJoe Perches # avoid parentheses around potential macro args 5504ea4acbb1SJoe Perches next if ($match =~ /^\s*\w+\s*$/); 5505e2826fd0SJoe Perches if (!defined($herectx)) { 5506e2826fd0SJoe Perches $herectx = $here . "\n"; 5507d22feb5bSDan Carpenter my $cnt = statement_rawlines($if_stat); 5508d22feb5bSDan Carpenter for (my $n = 0; $n < $cnt; $n++) { 5509d22feb5bSDan Carpenter my $rl = raw_line($linenr, $n); 55105b57980dSJoe Perches $herectx .= $rl . "\n"; 551163b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 551263b7c73eSJoe Perches } 551363b7c73eSJoe Perches } 551463b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 551563b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 551663b7c73eSJoe Perches } 551763b7c73eSJoe Perches } 551863b7c73eSJoe Perches 551963b7c73eSJoe Perches# check that goto labels aren't indented (allow a single space indentation) 552063b7c73eSJoe Perches# and ignore bitfield definitions like foo:1 552163b7c73eSJoe Perches# Strictly, labels can have whitespace after the identifier and before the : 552263b7c73eSJoe Perches# but this is not allowed here as many ?: uses would appear to be labels 552363b7c73eSJoe Perches if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ && 552463b7c73eSJoe Perches $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ && 552563b7c73eSJoe Perches $sline !~ /^.\s+default:/) { 552663b7c73eSJoe Perches if (WARN("INDENTED_LABEL", 552763b7c73eSJoe Perches "labels should not be indented\n" . $herecurr) && 552863b7c73eSJoe Perches $fix) { 552963b7c73eSJoe Perches $fixed[$fixlinenr] =~ 553063b7c73eSJoe Perches s/^(.)\s+/$1/; 553163b7c73eSJoe Perches } 553263b7c73eSJoe Perches } 553369078651SJoe Perches 553469078651SJoe Perches# check if a statement with a comma should be two statements like: 553569078651SJoe Perches# foo = bar(), /* comma should be semicolon */ 553669078651SJoe Perches# bar = baz(); 553769078651SJoe Perches if (defined($stat) && 553869078651SJoe Perches $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { 553969078651SJoe Perches my $cnt = statement_rawlines($stat); 55403705ce5bSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 55413705ce5bSJoe Perches WARN("SUSPECT_COMMA_SEMICOLON", 55423705ce5bSJoe Perches "Possible comma where semicolon could be used\n" . $herectx); 5543194f66fcSJoe Perches } 55443705ce5bSJoe Perches 55453705ce5bSJoe Perches# return is not a function 55460a920b5bSAndy Whitcroft if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 55470a920b5bSAndy Whitcroft my $spacing = $1; 554840873abaSJoe Perches if ($perl_version_ok && 554940873abaSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 555040873abaSJoe Perches my $value = $1; 555140873abaSJoe Perches $value = deparenthesize($value); 555240873abaSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 555340873abaSJoe Perches ERROR("RETURN_PARENTHESES", 555440873abaSJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 555540873abaSJoe Perches } 555640873abaSJoe Perches } elsif ($spacing !~ /\s+/) { 555740873abaSJoe Perches ERROR("SPACING", 555840873abaSJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 55595b9553abSJoe Perches } 5560507e5141SJoe Perches } 5561c45dcabdSAndy Whitcroft 55625b57980dSJoe Perches# unnecessary return in a void function 55635b9553abSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 55645b9553abSJoe Perches# and the line before that not a goto label target like "out:" 55655b9553abSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 55665b9553abSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 5567000d1cc1SJoe Perches $linenr >= 3 && 5568000d1cc1SJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 55695b9553abSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 5570c45dcabdSAndy Whitcroft WARN("RETURN_VOID", 5571000d1cc1SJoe Perches "void function return statements are not generally useful\n" . $hereprev); 5572000d1cc1SJoe Perches } 5573c45dcabdSAndy Whitcroft 5574c45dcabdSAndy Whitcroft# if statements using unnecessary parentheses - ie: if ((foo == bar)) 5575507e5141SJoe Perches if ($perl_version_ok && 5576b43ae21bSJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 5577b43ae21bSJoe Perches my $openparens = $1; 5578b43ae21bSJoe Perches my $count = $openparens =~ tr@\(@\(@; 5579b43ae21bSJoe Perches my $msg = ""; 5580b43ae21bSJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 5581b43ae21bSJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 5582b43ae21bSJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 5583b43ae21bSJoe Perches WARN("UNNECESSARY_PARENTHESES", 55849819cf25SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 5585b43ae21bSJoe Perches } 55869819cf25SJoe Perches } 55879819cf25SJoe Perches 5588189248d8SJoe Perches# comparisons with a constant or upper case identifier on the left 55895b57980dSJoe Perches# avoid cases like "foo + BAR < baz" 5590189248d8SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 5591189248d8SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 5592189248d8SJoe Perches if ($perl_version_ok && 5593189248d8SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 5594189248d8SJoe Perches my $lead = $1; 5595189248d8SJoe Perches my $const = $2; 5596189248d8SJoe Perches my $comp = $3; 5597189248d8SJoe Perches my $to = $4; 5598189248d8SJoe Perches my $newcomp = $comp; 5599189248d8SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 5600189248d8SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 5601189248d8SJoe Perches WARN("CONSTANT_COMPARISON", 5602c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 5603c5595fa2SJoe Perches $fix) { 5604c5595fa2SJoe Perches if ($comp eq "<") { 5605c5595fa2SJoe Perches $newcomp = ">"; 56065b57980dSJoe Perches } elsif ($comp eq "<=") { 5607c5595fa2SJoe Perches $newcomp = ">="; 5608c5595fa2SJoe Perches } elsif ($comp eq ">") { 5609c5595fa2SJoe Perches $newcomp = "<"; 5610c5595fa2SJoe Perches } elsif ($comp eq ">=") { 5611c5595fa2SJoe Perches $newcomp = "<="; 5612c5595fa2SJoe Perches } 5613f39e1769SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 5614c5595fa2SJoe Perches } 5615c5595fa2SJoe Perches } 5616c5595fa2SJoe Perches 5617c5595fa2SJoe Perches# Return of what appears to be an errno should normally be negative 5618c5595fa2SJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 5619c5595fa2SJoe Perches my $name = $1; 5620c5595fa2SJoe Perches if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) { 5621c5595fa2SJoe Perches WARN("USE_NEGATIVE_ERRNO", 5622c5595fa2SJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 5623c5595fa2SJoe Perches } 5624c5595fa2SJoe Perches } 5625c5595fa2SJoe Perches 5626c5595fa2SJoe Perches# Need a space before open parenthesis after if, while etc 5627c5595fa2SJoe Perches if ($line =~ /\b(if|while|for|switch)\(/) { 5628c5595fa2SJoe Perches if (ERROR("SPACING", 5629c5595fa2SJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 5630c5595fa2SJoe Perches $fix) { 5631f34e4a4fSJoe Perches $fixed[$fixlinenr] =~ 5632f34e4a4fSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 563353a3c448SAndy Whitcroft } 563446b85bf9SGuenter Roeck } 5635000d1cc1SJoe Perches 5636f34e4a4fSJoe Perches# Check for illegal assignment in if conditional -- and check for trailing 563753a3c448SAndy Whitcroft# statements after the conditional. 563853a3c448SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 5639c45dcabdSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 56400a920b5bSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 56414a0df2efSAndy Whitcroft if (!defined $stat); 56423705ce5bSJoe Perches my ($stat_next) = ctx_statement_block($line_nr_next, 56433705ce5bSJoe Perches $remain_next, $off_next); 56443705ce5bSJoe Perches $stat_next =~ s/\n./\n /g; 5645194f66fcSJoe Perches ##print "stat<$stat> stat_next<$stat_next>\n"; 56463705ce5bSJoe Perches 56473705ce5bSJoe Perches if ($stat_next =~ /^\s*while\b/) { 56480a920b5bSAndy Whitcroft # If the statement carries leading newlines, 56490a920b5bSAndy Whitcroft # then count those as offsets. 5650f5fe35ddSAndy Whitcroft my ($whitespace) = 5651f5fe35ddSAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 5652170d3a22SAndy Whitcroft my $offset = 56533e469cdcSAndy Whitcroft statement_rawlines($whitespace) - 1; 56543e469cdcSAndy Whitcroft 56553e469cdcSAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 5656170d3a22SAndy Whitcroft $offset} = 1; 5657170d3a22SAndy Whitcroft } 5658170d3a22SAndy Whitcroft } 5659170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 5660170d3a22SAndy Whitcroft defined($stat) && defined($cond) && 5661170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 5662170d3a22SAndy Whitcroft my ($s, $c) = ($stat, $cond); 5663170d3a22SAndy Whitcroft my $fixed_assign_in_if = 0; 5664170d3a22SAndy Whitcroft 5665170d3a22SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 5666170d3a22SAndy Whitcroft if (ERROR("ASSIGN_IN_IF", 5667170d3a22SAndy Whitcroft "do not use assignment in if condition\n" . $herecurr) && 5668170d3a22SAndy Whitcroft $fix && $perl_version_ok) { 5669170d3a22SAndy Whitcroft if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { 5670170d3a22SAndy Whitcroft my $space = $1; 5671170d3a22SAndy Whitcroft my $not = $2; 5672170d3a22SAndy Whitcroft my $statement = $3; 5673170d3a22SAndy Whitcroft my $assigned = $4; 5674c11230f4SJoe Perches my $test = $8; 5675170d3a22SAndy Whitcroft my $against = $9; 5676171ae1a4SAndy Whitcroft my $brace = $15; 5677481efd7bSJoe Perches fix_delete_line($fixlinenr, $rawline); 56788905a67cSAndy Whitcroft fix_insert_line($fixlinenr, "$space$statement;"); 5679b53c8e10SAndy Whitcroft my $newline = "${space}if ("; 568065b64b3bSJoe Perches $newline .= '!' if defined($not); 568165b64b3bSJoe Perches $newline .= '(' if (defined $not && defined($test) && defined($against)); 568265b64b3bSJoe Perches $newline .= "$assigned"; 568365b64b3bSJoe Perches $newline .= " $test $against" if (defined($test) && defined($against)); 568465b64b3bSJoe Perches $newline .= ')' if (defined $not && defined($test) && defined($against)); 568565b64b3bSJoe Perches $newline .= ')'; 568665b64b3bSJoe Perches $newline .= " {" if (defined($brace)); 568765b64b3bSJoe Perches fix_insert_line($fixlinenr + 1, $newline); 568865b64b3bSJoe Perches $fixed_assign_in_if = 1; 568965b64b3bSJoe Perches } 569065b64b3bSJoe Perches } 569165b64b3bSJoe Perches } 569265b64b3bSJoe Perches 569365b64b3bSJoe Perches # Find out what is on the end of the line after the 569465b64b3bSJoe Perches # conditional. 569565b64b3bSJoe Perches substr($s, 0, length($c), ''); 569665b64b3bSJoe Perches $s =~ s/\n.*//g; 569765b64b3bSJoe Perches $s =~ s/$;//g; # Remove any comments 569865b64b3bSJoe Perches if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 569965b64b3bSJoe Perches $c !~ /}\s*while\s*/) 570065b64b3bSJoe Perches { 570165b64b3bSJoe Perches # Find out how long the conditional actually is. 5702481efd7bSJoe Perches my @newlines = ($c =~ /\n/gs); 570365b64b3bSJoe Perches my $cond_lines = 1 + $#newlines; 570465b64b3bSJoe Perches my $stat_real = ''; 57058905a67cSAndy Whitcroft 57068905a67cSAndy Whitcroft $stat_real = raw_line($linenr, $cond_lines) 57078905a67cSAndy Whitcroft . "\n" if ($cond_lines); 57088905a67cSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 5709773647a0SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 57108905a67cSAndy Whitcroft } 571113214adfSAndy Whitcroft 571253210168SAndy Whitcroft if (ERROR("TRAILING_STATEMENTS", 571353210168SAndy Whitcroft "trailing statements should be on next line\n" . $herecurr . $stat_real) && 5714773647a0SAndy Whitcroft !$fixed_assign_in_if && 5715bb44ad39SAndy Whitcroft $cond_lines == 0 && 5716bb44ad39SAndy Whitcroft $fix && $perl_version_ok && 5717bb44ad39SAndy Whitcroft $fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) { 571842bdf74cSHidetoshi Seto my $indent = $1; 5719bb44ad39SAndy Whitcroft my $test = $2; 572042bdf74cSHidetoshi Seto my $rest = rtrim($4); 572142bdf74cSHidetoshi Seto if ($rest =~ /;$/) { 5722bb44ad39SAndy Whitcroft $fixed[$fixlinenr] = "\+$indent$test"; 5723bb44ad39SAndy Whitcroft fix_insert_line($fixlinenr + 1, "$indent\t$rest"); 5724bb44ad39SAndy Whitcroft } 5725bb44ad39SAndy Whitcroft } 5726481efd7bSJoe Perches } 5727481efd7bSJoe Perches } 5728481efd7bSJoe Perches 5729481efd7bSJoe Perches# Check for bitwise tests written as boolean 5730481efd7bSJoe Perches if ($line =~ / 5731481efd7bSJoe Perches (?: 5732481efd7bSJoe Perches (?:\[|\(|\&\&|\|\|) 5733481efd7bSJoe Perches \s*0[xX][0-9]+\s* 5734481efd7bSJoe Perches (?:\&\&|\|\|) 5735481efd7bSJoe Perches | 5736481efd7bSJoe Perches (?:\&\&|\|\|) 5737481efd7bSJoe Perches \s*0[xX][0-9]+\s* 5738481efd7bSJoe Perches (?:\&\&|\|\||\)|\]) 5739481efd7bSJoe Perches )/x) 57408905a67cSAndy Whitcroft { 57418905a67cSAndy Whitcroft WARN("HEXADECIMAL_BOOLEAN_TEST", 57428905a67cSAndy Whitcroft "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 574313214adfSAndy Whitcroft } 574413214adfSAndy Whitcroft 574513214adfSAndy Whitcroft# if and else should not have general statements after it 574613214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 574713214adfSAndy Whitcroft my $s = $1; 574813214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 574913214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 575013214adfSAndy Whitcroft ERROR("TRAILING_STATEMENTS", 575113214adfSAndy Whitcroft "trailing statements should be on next line\n" . $herecurr); 575213214adfSAndy Whitcroft } 575313214adfSAndy Whitcroft } 575413214adfSAndy Whitcroft# if should not continue a brace 5755000d1cc1SJoe Perches if ($line =~ /}\s*if\b/) { 5756000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 575713214adfSAndy Whitcroft "trailing statements should be on next line (or did you mean 'else if'?)\n" . 575813214adfSAndy Whitcroft $herecurr); 57598905a67cSAndy Whitcroft } 576013214adfSAndy Whitcroft# case and default should not have general statements after them 576113214adfSAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 576213214adfSAndy Whitcroft $line !~ /\G(?: 576313214adfSAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5764000d1cc1SJoe Perches \s*return\s+ 5765000d1cc1SJoe Perches )/xg) 57660a920b5bSAndy Whitcroft { 576713214adfSAndy Whitcroft ERROR("TRAILING_STATEMENTS", 576839667782SAndy Whitcroft "trailing statements should be on next line\n" . $herecurr); 576939667782SAndy Whitcroft } 5770000d1cc1SJoe Perches 5771048b123fSRasmus Villemoes # Check for }<nl>else {, these must be at the same 577239667782SAndy Whitcroft # indent level to be relevant to each other. 577339667782SAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 5774a1080bf8SAndy Whitcroft $previndent == $indent) { 5775a1080bf8SAndy Whitcroft if (ERROR("ELSE_AFTER_BRACE", 5776a1080bf8SAndy Whitcroft "else should follow close brace '}'\n" . $hereprev) && 57773fef12d6SAndy Whitcroft $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 5778a1080bf8SAndy Whitcroft fix_delete_line($fixlinenr - 1, $prevrawline); 5779a1080bf8SAndy Whitcroft fix_delete_line($fixlinenr, $rawline); 5780a1080bf8SAndy Whitcroft my $fixedline = $prevrawline; 5781000d1cc1SJoe Perches $fixedline =~ s/}\s*$//; 5782000d1cc1SJoe Perches if ($fixedline !~ /^\+\s*$/) { 5783a1080bf8SAndy Whitcroft fix_insert_line($fixlinenr, $fixedline); 57840a920b5bSAndy Whitcroft } 57850a920b5bSAndy Whitcroft $fixedline = $rawline; 57860a920b5bSAndy Whitcroft $fixedline =~ s/^(.\s*)else/$1} else/; 57878b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 57880a920b5bSAndy Whitcroft } 57898b8856f4SJoe Perches } 57908b8856f4SJoe Perches 57918b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 57928b8856f4SJoe Perches $previndent == $indent) { 57938b8856f4SJoe Perches my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 57948b8856f4SJoe Perches 57958b8856f4SJoe Perches # Find out what is on the end of the line after the 57968b8856f4SJoe Perches # conditional. 57978b8856f4SJoe Perches substr($s, 0, length($c), ''); 57988b8856f4SJoe Perches $s =~ s/\n.*//g; 57998b8856f4SJoe Perches 58008b8856f4SJoe Perches if ($s =~ /^\s*;/) { 58018b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 58028b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 58030a920b5bSAndy Whitcroft $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 58040a920b5bSAndy Whitcroft fix_delete_line($fixlinenr - 1, $prevrawline); 58058b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 5806c2fdda0dSAndy Whitcroft my $fixedline = $prevrawline; 5807c2fdda0dSAndy Whitcroft my $trailing = $rawline; 5808c2fdda0dSAndy Whitcroft $trailing =~ s/^\+//; 5809c2fdda0dSAndy Whitcroft $trailing = trim($trailing); 5810c2fdda0dSAndy Whitcroft $fixedline =~ s/}\s*$/} $trailing/; 5811773647a0SAndy Whitcroft fix_insert_line($fixlinenr, $fixedline); 5812c2fdda0dSAndy Whitcroft } 5813c2fdda0dSAndy Whitcroft } 5814c2fdda0dSAndy Whitcroft } 58158b8856f4SJoe Perches 58168b8856f4SJoe Perches#Specific variable tests 58178b8856f4SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 58188b8856f4SJoe Perches my $var = $1; 58198b8856f4SJoe Perches 58208b8856f4SJoe Perches#CamelCase 58218b8856f4SJoe Perches if ($var !~ /^$Constant$/ && 58228b8856f4SJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 58238b8856f4SJoe Perches#Ignore C keywords 58248b8856f4SJoe Perches $var !~ /^_Generic$/ && 58258b8856f4SJoe Perches#Ignore some autogenerated defines and enum values 58268b8856f4SJoe Perches $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && 5827c2fdda0dSAndy Whitcroft#Ignore Page<foo> variants 5828c2fdda0dSAndy Whitcroft $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5829c2fdda0dSAndy Whitcroft#Ignore ETHTOOL_LINK_MODE_<foo> variants 583095e2c602SJoe Perches $var !~ /^ETHTOOL_LINK_MODE_/ && 5831323c1260SJoe Perches#Ignore SI style variants like nS, mV and dB 5832323c1260SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 583395e2c602SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 583495e2c602SJoe Perches#Ignore some three character SI units explicitly, like MiB and KHz 5835807bd26cSJoe Perches $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 5836be79794bSJoe Perches while ($var =~ m{\b($Ident)}g) { 583720d00cfaSPrzemek Kitszel my $word = $1; 583820d00cfaSPrzemek Kitszel next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 58394104a206SŁukasz Stelmach if ($check) { 58404104a206SŁukasz Stelmach seed_camelcase_includes(); 584122735ce8SJoe Perches if (!$file && !$camelcase_file_seeded) { 5842807bd26cSJoe Perches seed_camelcase_file($realfile); 5843d99a4158SGerhard Engleder $camelcase_file_seeded = 1; 5844d99a4158SGerhard Engleder } 5845d439e6a5SJoe Perches } 5846d439e6a5SJoe Perches if (!defined $camelcase{$word}) { 5847d439e6a5SJoe Perches $camelcase{$word} = 1; 5848f5123576SJulius Werner CHK("CAMELCASE", 5849f5123576SJulius Werner "Avoid CamelCase: <$word>\n" . $herecurr); 5850f858e23aSAntonio Borneo } 58517e781f67SJoe Perches } 58527e781f67SJoe Perches } 5853d8b07710SJoe Perches } 5854d8b07710SJoe Perches 5855d8b07710SJoe Perches#no spaces allowed after \ in define 5856d8b07710SJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5857d8b07710SJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5858d8b07710SJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5859d8b07710SJoe Perches $fix) { 58607e781f67SJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 58617e781f67SJoe Perches } 5862be79794bSJoe Perches } 58637e781f67SJoe Perches 58647e781f67SJoe Perches# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 5865323c1260SJoe Perches# itself <asm/foo.h> (uses RAW line) 5866323c1260SJoe Perches if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 58673445686aSJoe Perches my $file = "$1.h"; 58680a920b5bSAndy Whitcroft my $checkfile = "include/linux/$file"; 58690a920b5bSAndy Whitcroft if (-f "$root/$checkfile" && 5870d5e616fcSJoe Perches $realfile ne $checkfile && 5871d5e616fcSJoe Perches $1 !~ /$allowed_asm_includes/) 5872d5e616fcSJoe Perches { 5873d5e616fcSJoe Perches my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 5874194f66fcSJoe Perches if ($asminclude > 0) { 5875d5e616fcSJoe Perches if ($realfile =~ m{^arch/}) { 58760a920b5bSAndy Whitcroft CHK("ARCH_INCLUDE_LINUX", 58770a920b5bSAndy Whitcroft "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 58780e212e0aSFabian Frederick } else { 58790e212e0aSFabian Frederick WARN("INCLUDE_LINUX", 5880c45dcabdSAndy Whitcroft "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5881e09dec48SAndy Whitcroft } 5882e09dec48SAndy Whitcroft } 5883e09dec48SAndy Whitcroft } 5884e09dec48SAndy Whitcroft } 58857840a94cSWolfram Sang 5886c45dcabdSAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 58870e212e0aSFabian Frederick# first statement and ensure its the whole macro if its not enclosed 58880e212e0aSFabian Frederick# in a known good container 5889e09dec48SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5890000d1cc1SJoe Perches $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5891000d1cc1SJoe Perches my $ln = $linenr; 5892e09dec48SAndy Whitcroft my $cnt = $realcnt; 5893000d1cc1SJoe Perches my ($off, $dstat, $dcond, $rest); 5894000d1cc1SJoe Perches my $ctx = ''; 5895e09dec48SAndy Whitcroft my $has_flow_statement = 0; 58960a920b5bSAndy Whitcroft my $has_arg_concat = 0; 58970a920b5bSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 58980e212e0aSFabian Frederick ctx_statement_block($linenr, $realcnt, 0); 58990a920b5bSAndy Whitcroft $ctx = $dstat; 5900653d4876SAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5901653d4876SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5902cf655043SAndy Whitcroft 5903b8f96a31SAndy Whitcroft $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 5904b8f96a31SAndy Whitcroft $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 5905d8aaf121SAndy Whitcroft 5906d8aaf121SAndy Whitcroft $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5907c45dcabdSAndy Whitcroft my $define_args = $1; 5908c45dcabdSAndy Whitcroft my $define_stmt = $dstat; 590908a2843eSJoe Perches my @def_args = (); 591008a2843eSJoe Perches 5911c45dcabdSAndy Whitcroft if (defined $define_args && $define_args ne "") { 5912f74bd194SAndy Whitcroft $define_args = substr($define_args, 1, length($define_args) - 2); 5913f74bd194SAndy Whitcroft $define_args =~ s/\s*//g; 5914c45dcabdSAndy Whitcroft $define_args =~ s/\\\+?//g; 5915a3bb97a7SAndy Whitcroft @def_args = split(",", $define_args); 5916c45dcabdSAndy Whitcroft } 591708a2843eSJoe Perches 591862e15a6dSJoe Perches $dstat =~ s/$;//g; 591908a2843eSJoe Perches $dstat =~ s/\\\n.//g; 5920f59b64bfSJoe Perches $dstat =~ s/^\s*//s; 5921f59b64bfSJoe Perches $dstat =~ s/\s*$//s; 5922f59b64bfSJoe Perches 5923f59b64bfSJoe Perches # Flatten any parentheses and braces 5924f59b64bfSJoe Perches while ($dstat =~ s/\([^\(\)]*\)/1u/ || 5925f59b64bfSJoe Perches $dstat =~ s/\{[^\{\}]*\}/1u/ || 5926f59b64bfSJoe Perches $dstat =~ s/.\[[^\[\]]*\]/1u/) 5927f59b64bfSJoe Perches { 59288c8c45cfSJoe Perches } 5929f59b64bfSJoe Perches 5930f59b64bfSJoe Perches # Flatten any obvious string concatenation. 5931f59b64bfSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 5932292f1a9bSAndy Whitcroft $dstat =~ s/$Ident\s*($String)/$1/) 5933c45dcabdSAndy Whitcroft { 5934c45dcabdSAndy Whitcroft } 5935c45dcabdSAndy Whitcroft 5936c45dcabdSAndy Whitcroft # Make asm volatile uses seem like a generic function 5937c45dcabdSAndy Whitcroft $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 59382e44e803SDwaipayan Ray 59392e44e803SDwaipayan Ray my $exceptions = qr{ 59402e44e803SDwaipayan Ray $Declare| 5941bf30d6edSAndy Whitcroft module_param_named| 5942c45dcabdSAndy Whitcroft MODULE_PARM_DESC| 5943c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5944342d3d2fSAntonio Borneo DEFINE_PER_CPU| 594533acb54aSJoe Perches __typeof__\(| 594633acb54aSJoe Perches union| 5947e45bab8eSAndy Whitcroft struct| 5948e45bab8eSAndy Whitcroft \.$Ident\s*=\s*| 5949e45bab8eSAndy Whitcroft ^\"|\"$| 595042e15293SJoe Perches ^\[ 595142e15293SJoe Perches }x; 595242e15293SJoe Perches #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5953c45dcabdSAndy Whitcroft 5954c45dcabdSAndy Whitcroft $ctx =~ s/\n*$//; 5955c45dcabdSAndy Whitcroft my $stmt_cnt = statement_rawlines($ctx); 5956a0a0a7a9SKees Cook my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5957c45dcabdSAndy Whitcroft 5958c45dcabdSAndy Whitcroft if ($dstat ne '' && 5959383099fdSAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 596022fd2d3eSStefani Seibold $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 596122fd2d3eSStefani Seibold $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5962ea71a0a0SAndy Whitcroft $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 59636b10df42SVladimir Zapolskiy $dstat !~ /$exceptions/ && 59646b10df42SVladimir Zapolskiy $dstat !~ /^\.$Ident\s*=/ && # .foo = 5965c45dcabdSAndy Whitcroft $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 59665eaa20b9SAndy Whitcroft $dstat !~ /^case\b/ && # case ... 5967f59b64bfSJoe Perches $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 5968f59b64bfSJoe Perches $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} 5969f59b64bfSJoe Perches $dstat !~ /^for\s*$Constant$/ && # for (...) 5970e3d95a2aSTobin C. Harding $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5971f59b64bfSJoe Perches $dstat !~ /^do\s*{/ && # do {... 5972f74bd194SAndy Whitcroft $dstat !~ /^\(\{/ && # ({... 5973f74bd194SAndy Whitcroft $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5974f74bd194SAndy Whitcroft { 59753cc4b1c3SJoe Perches if ($dstat =~ /^\s*if\b/) { 5976356fd398SJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5977f74bd194SAndy Whitcroft "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5978f74bd194SAndy Whitcroft } elsif ($dstat =~ /;/) { 5979e942e2c3SJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5980dc3f4deeSStanislaw Gruszka "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 598172f115f9SAndy Whitcroft } else { 59822e44e803SDwaipayan Ray ERROR("COMPLEX_MACRO", 5983f74bd194SAndy Whitcroft "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5984f74bd194SAndy Whitcroft } 5985f74bd194SAndy Whitcroft 59864e5d56bdSEddie Kovsky } 5987f95a7e6aSJoe Perches 5988c45dcabdSAndy Whitcroft # Make $define_stmt single line, comment-free, etc 5989e795556aSJoe Perches my @stmt_array = split('\n', $define_stmt); 5990e795556aSJoe Perches my $first = 1; 5991e795556aSJoe Perches $define_stmt = ""; 5992e795556aSJoe Perches foreach my $l (@stmt_array) { 5993f74bd194SAndy Whitcroft $l =~ s/\\$//; 5994f74bd194SAndy Whitcroft if ($first) { 5995f74bd194SAndy Whitcroft $define_stmt = $l; 5996000d1cc1SJoe Perches $first = 0; 5997388982b5SAndrew Morton } elsif ($l =~ /^[\+ ]/) { 5998d8aaf121SAndy Whitcroft $define_stmt .= substr($l, 1); 5999f59b64bfSJoe Perches } 6000f59b64bfSJoe Perches } 60015207649bSJoe Perches $define_stmt =~ s/$;//g; 60025207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 60035207649bSJoe Perches $define_stmt = trim($define_stmt); 60045207649bSJoe Perches 60055207649bSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 60065207649bSJoe Perches foreach my $arg (@def_args) { 60075207649bSJoe Perches next if ($arg =~ /\.\.\./); 60085207649bSJoe Perches next if ($arg =~ /^type$/i); 60095207649bSJoe Perches my $tmp_stmt = $define_stmt; 60105207649bSJoe Perches $tmp_stmt =~ s/\b(__must_be_array|offsetof|sizeof|sizeof_field|__stringify|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 60115207649bSJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 60125207649bSJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 60135207649bSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 60145207649bSJoe Perches if ($use_cnt > 1) { 60155207649bSJoe Perches CHK("MACRO_ARG_REUSE", 60165207649bSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 60175207649bSJoe Perches } 60185207649bSJoe Perches# check if any macro arguments may have other precedence issues 6019f59b64bfSJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 6020f59b64bfSJoe Perches ((defined($1) && $1 ne ',') || 6021f59b64bfSJoe Perches (defined($2) && $2 ne ','))) { 60229192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 60237fe528a2SJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 60247b844345SVincent Mailhol } 60257fe528a2SJoe Perches 60267fe528a2SJoe Perches# check if this is an unused argument 6027d41362edSJoe Perches if ($define_stmt !~ /\b$arg\b/) { 6028f59b64bfSJoe Perches WARN("MACRO_ARG_UNUSED", 6029f59b64bfSJoe Perches "Argument '$arg' is not used in function-like macro\n" . "$herectx"); 6030f59b64bfSJoe Perches } 6031f59b64bfSJoe Perches } 60329192d41aSJoe Perches 60337fe528a2SJoe Perches# check for macros with flow control, but without ## concatenation 60349192d41aSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 60359192d41aSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 60369192d41aSJoe Perches my $cnt = statement_rawlines($ctx); 60379192d41aSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 60389192d41aSJoe Perches 6039b1be5844SXining Xu WARN("MACRO_WITH_FLOW_CONTROL", 6040b1be5844SXining Xu "Macros with flow control statements should be avoided\n" . "$herectx"); 6041b1be5844SXining Xu } 6042b1be5844SXining Xu 6043b1be5844SXining Xu# check for line continuations outside of #defines, preprocessor #, and asm 6044b1be5844SXining Xu 60450a920b5bSAndy Whitcroft } elsif ($realfile =~ m@/vmlinux.lds.h$@) { 60465023d347SJoe Perches $line =~ s/(\w+)/$maybe_linker_symbol{$1}++/ge; 604708a2843eSJoe Perches #print "REAL: $realfile\nln: $line\nkeys:", sort keys %maybe_linker_symbol; 604808a2843eSJoe Perches } else { 604908a2843eSJoe Perches if ($prevline !~ /^..*\\$/ && 605008a2843eSJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 6051e3d95a2aSTobin C. Harding $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 605208a2843eSJoe Perches $line =~ /^\+.*\\$/) { 605308a2843eSJoe Perches WARN("LINE_CONTINUATIONS", 605408a2843eSJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 605508a2843eSJoe Perches } 605608a2843eSJoe Perches } 6057481eb486SJoe Perches 60585023d347SJoe Perches# do {} while (0) macro tests: 60595b2c7334SJim Cromie# single-statement macros do not need to be enclosed in do while (0) loop, 60605b2c7334SJim Cromie# macro should not end with a semicolon 60615b2c7334SJim Cromie if ($perl_version_ok && 60625023d347SJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 60635023d347SJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 6064481eb486SJoe Perches my $ln = $linenr; 6065481eb486SJoe Perches my $cnt = $realcnt; 60665023d347SJoe Perches my ($off, $dstat, $dcond, $rest); 60675023d347SJoe Perches my $ctx = ''; 60685023d347SJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 60695023d347SJoe Perches ctx_statement_block($linenr, $realcnt, 0); 6070653d4876SAndy Whitcroft $ctx = $dstat; 60710a920b5bSAndy Whitcroft 6072b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 6073b13edf7fSJoe Perches $dstat =~ s/$;/ /g; 6074b13edf7fSJoe Perches 60755b57980dSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 6076b13edf7fSJoe Perches my $stmts = $2; 6077b13edf7fSJoe Perches my $semis = $3; 6078b13edf7fSJoe Perches 6079b13edf7fSJoe Perches $ctx =~ s/\n*$//; 6080b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 6081b13edf7fSJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 6082b13edf7fSJoe Perches 6083b13edf7fSJoe Perches if (($stmts =~ tr/;/;/) == 1 && 6084b13edf7fSJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 6085b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 6086b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 60871b36b201SJoe Perches } 6088b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 6089b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 6090b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 6091b13edf7fSJoe Perches } 6092b13edf7fSJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 6093b13edf7fSJoe Perches $ctx =~ s/\n*$//; 6094b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 6095e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6096b13edf7fSJoe Perches 6097ac8e97f8SJoe Perches WARN("TRAILING_SEMICOLON", 6098ac8e97f8SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 6099b13edf7fSJoe Perches } 6100b13edf7fSJoe Perches } 6101b13edf7fSJoe Perches 6102b13edf7fSJoe Perches# check for redundant bracing round if etc 6103b13edf7fSJoe Perches if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 6104b13edf7fSJoe Perches my ($level, $endln, @chunks) = 6105b13edf7fSJoe Perches ctx_statement_full($linenr, $realcnt, 1); 6106f5ef95b1SJoe Perches #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 6107f5ef95b1SJoe Perches #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 6108f5ef95b1SJoe Perches if ($#chunks > 0 && $level == 0) { 6109e3d95a2aSTobin C. Harding my @allowed = (); 6110f5ef95b1SJoe Perches my $allow = 0; 6111f5ef95b1SJoe Perches my $seen = 0; 6112f5ef95b1SJoe Perches my $herectx = $here . "\n"; 6113b13edf7fSJoe Perches my $ln = $linenr - 1; 6114b13edf7fSJoe Perches for my $chunk (@chunks) { 6115b13edf7fSJoe Perches my ($cond, $block) = @{$chunk}; 6116f0a594c1SAndy Whitcroft 611713214adfSAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 611813214adfSAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 6119cf655043SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 612013214adfSAndy Whitcroft 6121cf655043SAndy Whitcroft $allowed[$allow] = 0; 6122cf655043SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 6123aad4f614SJoe Perches 6124aad4f614SJoe Perches # We have looked at and allowed this specific line. 612513214adfSAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 6126773647a0SAndy Whitcroft 6127cf655043SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 612813214adfSAndy Whitcroft $ln += statement_rawlines($block) - 1; 612913214adfSAndy Whitcroft 613013214adfSAndy Whitcroft substr($block, 0, length($cond), ''); 6131773647a0SAndy Whitcroft 6132773647a0SAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 6133773647a0SAndy Whitcroft 6134773647a0SAndy Whitcroft #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 6135aad4f614SJoe Perches if (statement_lines($cond) > 1) { 6136773647a0SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 6137773647a0SAndy Whitcroft $allowed[$allow] = 1; 6138773647a0SAndy Whitcroft } 6139773647a0SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 6140773647a0SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 6141773647a0SAndy Whitcroft $allowed[$allow] = 1; 6142cf655043SAndy Whitcroft } 6143cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 6144773647a0SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 614513214adfSAndy Whitcroft $allowed[$allow] = 1; 614613214adfSAndy Whitcroft } 614713214adfSAndy Whitcroft $allow++; 6148aad4f614SJoe Perches } 6149cf655043SAndy Whitcroft if ($seen) { 6150cf655043SAndy Whitcroft my $sum_allowed = 0; 6151aad4f614SJoe Perches foreach (@allowed) { 615213214adfSAndy Whitcroft $sum_allowed += $_; 615313214adfSAndy Whitcroft } 6154cf655043SAndy Whitcroft if ($sum_allowed == 0) { 6155aad4f614SJoe Perches WARN("BRACES", 615613214adfSAndy Whitcroft "braces {} are not necessary for any arm of this statement\n" . $herectx); 6157cf655043SAndy Whitcroft } elsif ($sum_allowed != $allow && 6158cf655043SAndy Whitcroft $seen != $allow) { 6159aad4f614SJoe Perches CHK("BRACES", 616013214adfSAndy Whitcroft "braces {} should be used on all arms of this statement\n" . $herectx); 6161aad4f614SJoe Perches } 616213214adfSAndy Whitcroft } 6163aad4f614SJoe Perches } 6164aad4f614SJoe Perches } 6165aad4f614SJoe Perches if (!defined $suppress_ifbraces{$linenr - 1} && 6166aad4f614SJoe Perches $line =~ /\b(if|while|for|else)\b/) { 6167aad4f614SJoe Perches my $allowed = 0; 6168aad4f614SJoe Perches 6169000d1cc1SJoe Perches # Check the pre-context. 6170000d1cc1SJoe Perches if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 6171aad4f614SJoe Perches #print "APW: ALLOWED: pre<$1>\n"; 6172aad4f614SJoe Perches $allowed = 1; 6173aad4f614SJoe Perches } 6174aad4f614SJoe Perches 6175aad4f614SJoe Perches my ($level, $endln, @chunks) = 617613214adfSAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 617713214adfSAndy Whitcroft 617813214adfSAndy Whitcroft # Check the condition. 6179773647a0SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 618013214adfSAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 6181cf655043SAndy Whitcroft if (defined $cond) { 6182f0a594c1SAndy Whitcroft substr($block, 0, length($cond), ''); 6183cf655043SAndy Whitcroft } 6184cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 6185cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 6186cf655043SAndy Whitcroft $allowed = 1; 6187f0a594c1SAndy Whitcroft } 6188773647a0SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 6189773647a0SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 6190773647a0SAndy Whitcroft $allowed = 1; 6191773647a0SAndy Whitcroft } 6192cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 6193cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 6194773647a0SAndy Whitcroft $allowed = 1; 6195cf655043SAndy Whitcroft } 6196773647a0SAndy Whitcroft # Check the post-context. 6197cf655043SAndy Whitcroft if (defined $chunks[1]) { 6198cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 6199cf655043SAndy Whitcroft if (defined $cond) { 6200cf655043SAndy Whitcroft substr($block, 0, length($cond), ''); 6201cf655043SAndy Whitcroft } 6202cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 6203cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 6204cf655043SAndy Whitcroft $allowed = 1; 6205cf655043SAndy Whitcroft } 6206cf655043SAndy Whitcroft } 6207cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 6208cf655043SAndy Whitcroft my $cnt = statement_rawlines($block); 6209cf655043SAndy Whitcroft my $herectx = get_stat_here($linenr, $cnt, $here); 6210cf655043SAndy Whitcroft 6211cf655043SAndy Whitcroft WARN("BRACES", 6212cf655043SAndy Whitcroft "braces {} are not necessary for single statement blocks\n" . $herectx); 6213cf655043SAndy Whitcroft } 6214773647a0SAndy Whitcroft } 6215cf655043SAndy Whitcroft 6216cf655043SAndy Whitcroft# check for single line unbalanced braces 6217cf655043SAndy Whitcroft if ($sline =~ /^.\s*\}\s*else\s*$/ || 6218cf655043SAndy Whitcroft $sline =~ /^.\s*else\s*\{\s*$/) { 6219cf655043SAndy Whitcroft CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 6220cf655043SAndy Whitcroft } 6221cf655043SAndy Whitcroft 6222f055663cSAndy Whitcroft# check for unnecessary blank lines around braces 6223e3d95a2aSTobin C. Harding if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 6224cf655043SAndy Whitcroft if (CHK("BRACES", 6225000d1cc1SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 6226000d1cc1SJoe Perches $fix && $prevrawline =~ /^\+/) { 6227f0a594c1SAndy Whitcroft fix_delete_line($fixlinenr - 1, $prevrawline); 6228f0a594c1SAndy Whitcroft } 6229f0a594c1SAndy Whitcroft } 6230e4c5babdSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 623195330473SSven Eckelmann if (CHK("BRACES", 623295330473SSven Eckelmann "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 6233e4c5babdSJoe Perches $fix) { 6234e4c5babdSJoe Perches fix_delete_line($fixlinenr, $rawline); 6235e4c5babdSJoe Perches } 62360979ae66SJoe Perches } 623777b9a53aSJoe Perches 6238f8e58219SJoe Perches# no volatiles please 6239f8e58219SJoe Perches my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 6240f8e58219SJoe Perches if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 6241f8e58219SJoe Perches WARN("VOLATILE", 6242f8e58219SJoe Perches "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 62430979ae66SJoe Perches } 624477b9a53aSJoe Perches 6245f8e58219SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 6246f8e58219SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 6247f8e58219SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 6248f8e58219SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 6249f8e58219SJoe Perches if ($line =~ /^\+\s*$String/ && 62500979ae66SJoe Perches $prevline =~ /"\s*$/ && 62510979ae66SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 62524a0df2efSAndy Whitcroft if (WARN("SPLIT_STRING", 62536c72ffaaSAndy Whitcroft "quoted string split across lines\n" . $hereprev) && 62546c72ffaaSAndy Whitcroft $fix && 6255000d1cc1SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 62568c27ceffSMauro Carvalho Chehab $last_coalesced_string_linenr != $linenr - 1) { 62574a0df2efSAndy Whitcroft my $extracted_string = get_quoted_string($line, $rawline); 62584a0df2efSAndy Whitcroft my $comma_close = ""; 62595e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 62605e4f6ba5SJoe Perches $comma_close = $1; 62615e4f6ba5SJoe Perches } 62625e4f6ba5SJoe Perches 626333acb54aSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 62645e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 62655e4f6ba5SJoe Perches my $fixedline = $prevrawline; 62665e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 62675e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 62685e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 62695e4f6ba5SJoe Perches $fixedline = $rawline; 62705e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 62715e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 62725e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 62735e4f6ba5SJoe Perches } 62745e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 62755e4f6ba5SJoe Perches } 62765e4f6ba5SJoe Perches } 62775e4f6ba5SJoe Perches 62785e4f6ba5SJoe Perches# check for missing a space in a string concatenation 62795e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 62805e4f6ba5SJoe Perches WARN('MISSING_SPACE', 62815e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 62825e4f6ba5SJoe Perches } 62835e4f6ba5SJoe Perches 62845e4f6ba5SJoe Perches# check for an embedded function name in a string when the function is known 62855e4f6ba5SJoe Perches# This does not work very well for -f --file checking as it depends on patch 62865e4f6ba5SJoe Perches# context providing the function name or a single line form for in-file 62875e4f6ba5SJoe Perches# function declarations 62885e4f6ba5SJoe Perches if ($line =~ /^\+.*$String/ && 62895e4f6ba5SJoe Perches defined($context_function) && 62905e4f6ba5SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 62915e4f6ba5SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 62925e4f6ba5SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 62935e4f6ba5SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 62945e4f6ba5SJoe Perches } 62955e4f6ba5SJoe Perches 62965e4f6ba5SJoe Perches# check for unnecessary function tracing like uses 62975e4f6ba5SJoe Perches# This does not use $logFunctions because there are many instances like 629877cb8546SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions 6299e4b7d309SJoe Perches if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) { 6300e4b7d309SJoe Perches if (WARN("TRACING_LOGGING", 6301e4b7d309SJoe Perches "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) && 630277cb8546SJoe Perches $fix) { 630377cb8546SJoe Perches fix_delete_line($fixlinenr, $rawline); 6304e4b7d309SJoe Perches } 6305e4b7d309SJoe Perches } 630677cb8546SJoe Perches 6307e4b7d309SJoe Perches# check for spaces before a quoted newline 630877cb8546SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 630977cb8546SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 6310adb2da82SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 6311adb2da82SJoe Perches $fix) { 6312adb2da82SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 6313adb2da82SJoe Perches } 6314adb2da82SJoe Perches 6315adb2da82SJoe Perches } 6316adb2da82SJoe Perches 6317adb2da82SJoe Perches# concatenated string without spaces between elements 6318adb2da82SJoe Perches if ($line =~ /$String[A-Z_]/ || 6319adb2da82SJoe Perches ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) { 6320adb2da82SJoe Perches if (CHK("CONCATENATED_STRING", 63215e4f6ba5SJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 63225e4f6ba5SJoe Perches $fix) { 63235e4f6ba5SJoe Perches while ($line =~ /($String)/g) { 63245e4f6ba5SJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 63255e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 63265e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 63275e4f6ba5SJoe Perches } 63285e4f6ba5SJoe Perches } 63295e4f6ba5SJoe Perches } 63305e4f6ba5SJoe Perches 6331f17dba4fSJoe Perches# uncoalesced string fragments 6332d2af5aa6SJoe Perches if ($line =~ /$String\s*[Lu]?"/) { 6333d2af5aa6SJoe Perches if (WARN("STRING_FRAGMENTS", 633479682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 633579682c0cSJoe Perches $fix) { 633679682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 633779682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 633879682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 633979682c0cSJoe Perches } 634079682c0cSJoe Perches } 634179682c0cSJoe Perches } 634279682c0cSJoe Perches 6343f17dba4fSJoe Perches# check for non-standard and hex prefixed decimal printf formats 6344f17dba4fSJoe Perches my $show_L = 1; #don't show the same defect twice 634590ad30e5SJoe Perches my $show_Z = 1; 6346d2af5aa6SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 634779682c0cSJoe Perches my $string = substr($rawline, $-[1], $+[1] - $-[1]); 634879682c0cSJoe Perches $string =~ s/%%/__/g; 634979682c0cSJoe Perches # check for %L 635079682c0cSJoe Perches if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 635179682c0cSJoe Perches WARN("PRINTF_L", 635279682c0cSJoe Perches "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 635379682c0cSJoe Perches $show_L = 0; 635479682c0cSJoe Perches } 635590ad30e5SJoe Perches # check for %Z 635690ad30e5SJoe Perches if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 6357522b837cSAlexey Dobriyan WARN("PRINTF_Z", 6358522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 6359522b837cSAlexey Dobriyan $show_Z = 0; 63605e4f6ba5SJoe Perches } 6361522b837cSAlexey Dobriyan # check for 0x<decimal> 63625e4f6ba5SJoe Perches if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 6363522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 6364522b837cSAlexey Dobriyan "Prefixing 0x with decimal output is defective\n" . $herecurr); 63655e4f6ba5SJoe Perches } 6366522b837cSAlexey Dobriyan } 6367522b837cSAlexey Dobriyan 63685e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 6369522b837cSAlexey Dobriyan if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 6370522b837cSAlexey Dobriyan WARN("LINE_CONTINUATIONS", 6371522b837cSAlexey Dobriyan "Avoid line continuations in quoted strings\n" . $herecurr); 6372522b837cSAlexey Dobriyan } 6373522b837cSAlexey Dobriyan 6374522b837cSAlexey Dobriyan# warn about #if 0 6375522b837cSAlexey Dobriyan if ($line =~ /^.\s*\#\s*if\s+0\b/) { 6376522b837cSAlexey Dobriyan WARN("IF_0", 6377522b837cSAlexey Dobriyan "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 63786e300757SJoe Perches } 63796e300757SJoe Perches 63805e4f6ba5SJoe Perches# warn about #if 1 63815e4f6ba5SJoe Perches if ($line =~ /^.\s*\#\s*if\s+1\b/) { 63825e4f6ba5SJoe Perches WARN("IF_1", 63833f7f335dSJoe Perches "Consider removing the #if 1 and its #endif\n" . $herecurr); 63845e4f6ba5SJoe Perches } 63855e4f6ba5SJoe Perches 63865e4f6ba5SJoe Perches# check for needless "if (<foo>) fn(<foo>)" uses 63875e4f6ba5SJoe Perches if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 638800df344fSAndy Whitcroft my $tested = quotemeta($1); 6389c45dcabdSAndy Whitcroft my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 639060f89010SPrakruthi Deepak Heragu if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 639160f89010SPrakruthi Deepak Heragu my $func = $1; 639260f89010SPrakruthi Deepak Heragu if (WARN('NEEDLESS_IF', 639360f89010SPrakruthi Deepak Heragu "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 639460f89010SPrakruthi Deepak Heragu $fix) { 639560f89010SPrakruthi Deepak Heragu my $do_fix = 1; 639660f89010SPrakruthi Deepak Heragu my $leading_tabs = ""; 639760f89010SPrakruthi Deepak Heragu my $new_leading_tabs = ""; 63984a0df2efSAndy Whitcroft if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 63994a0df2efSAndy Whitcroft $leading_tabs = $1; 640003df4b51SAndy Whitcroft } else { 640103df4b51SAndy Whitcroft $do_fix = 0; 6402100425deSJoe Perches } 6403100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 6404100425deSJoe Perches $new_leading_tabs = $1; 6405100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 6406100425deSJoe Perches $do_fix = 0; 6407100425deSJoe Perches } 6408100425deSJoe Perches } else { 6409100425deSJoe Perches $do_fix = 0; 6410100425deSJoe Perches } 6411100425deSJoe Perches if ($do_fix) { 6412100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 6413100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 6414100425deSJoe Perches } 6415100425deSJoe Perches } 6416100425deSJoe Perches } 6417100425deSJoe Perches } 6418100425deSJoe Perches 6419100425deSJoe Perches# check for unnecessary "Out of Memory" messages 6420100425deSJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 6421100425deSJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 6422100425deSJoe Perches (defined $1 || defined $3) && 6423100425deSJoe Perches $linenr > 3) { 6424100425deSJoe Perches my $testval = $2; 6425100425deSJoe Perches my $testline = $lines[$linenr - 3]; 6426100425deSJoe Perches 6427100425deSJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 6428100425deSJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 6429100425deSJoe Perches 64304c432a8fSGreg Kroah-Hartman if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 64314c432a8fSGreg Kroah-Hartman $s !~ /\b__GFP_NOWARN\b/ ) { 6432f0a594c1SAndy Whitcroft WARN("OOM_MESSAGE", 6433ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 6434ebfdc409SJoe Perches } 6435ebfdc409SJoe Perches } 6436ebfdc409SJoe Perches 6437ebfdc409SJoe Perches# check for logging functions with KERN_<LEVEL> 6438ebfdc409SJoe Perches if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 6439ebfdc409SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 6440ebfdc409SJoe Perches my $level = $1; 6441ebfdc409SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 6442ebfdc409SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 6443ebfdc409SJoe Perches $fix) { 6444e29a70f1SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 6445e29a70f1SJoe Perches } 6446ebfdc409SJoe Perches } 6447ebfdc409SJoe Perches 6448ebfdc409SJoe Perches# check for logging continuations 6449ebfdc409SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 6450ebfdc409SJoe Perches WARN("LOGGING_CONTINUATION", 6451f78d98f6SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 6452dcaf1123SPaolo Bonzini } 6453f78d98f6SJoe Perches 6454f78d98f6SJoe Perches# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions 6455f78d98f6SJoe Perches if (defined $stat && 6456f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(/ && 6457f78d98f6SJoe Perches index($stat, '"') >= 0) { 6458f78d98f6SJoe Perches my $lc = $stat =~ tr@\n@@; 6459f78d98f6SJoe Perches $lc = $lc + $linenr; 6460f78d98f6SJoe Perches my $stat_real = get_stat_real($linenr, $lc); 6461f78d98f6SJoe Perches pos($stat_real) = index($stat_real, '"'); 646245c55e92SJoe Perches while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) { 646345c55e92SJoe Perches my $pspec = $1; 646445c55e92SJoe Perches my $h = $2; 646545c55e92SJoe Perches my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@; 646645c55e92SJoe Perches if (WARN("UNNECESSARY_MODIFIER", 646745c55e92SJoe Perches "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") && 646870eb2275SDwaipayan Ray $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) { 646970eb2275SDwaipayan Ray my $nspec = $pspec; 647070eb2275SDwaipayan Ray $nspec =~ s/h//g; 647170eb2275SDwaipayan Ray $fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/; 647270eb2275SDwaipayan Ray } 647370eb2275SDwaipayan Ray } 647470eb2275SDwaipayan Ray } 647570eb2275SDwaipayan Ray 647670eb2275SDwaipayan Ray# check for mask then right shift without a parentheses 647770eb2275SDwaipayan Ray if ($perl_version_ok && 647870eb2275SDwaipayan Ray $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 647970eb2275SDwaipayan Ray $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 648070eb2275SDwaipayan Ray WARN("MASK_THEN_SHIFT", 648170eb2275SDwaipayan Ray "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 648270eb2275SDwaipayan Ray } 648370eb2275SDwaipayan Ray 648470eb2275SDwaipayan Ray# check for pointer comparisons to NULL 648570eb2275SDwaipayan Ray if ($perl_version_ok) { 648670eb2275SDwaipayan Ray while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 648770eb2275SDwaipayan Ray my $val = $1; 648870eb2275SDwaipayan Ray my $equal = "!"; 648970eb2275SDwaipayan Ray $equal = "" if ($4 eq "!="); 6490abb08a53SJoe Perches if (CHK("COMPARISON_TO_NULL", 64915b57980dSJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 6492abb08a53SJoe Perches $fix) { 6493abb08a53SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 6494abb08a53SJoe Perches } 6495abb08a53SJoe Perches } 6496abb08a53SJoe Perches } 6497abb08a53SJoe Perches 6498b75ac618SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 64995b57980dSJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 6500b75ac618SJoe Perches my $attr = $1; 6501b75ac618SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 6502b75ac618SJoe Perches my $ptr = $1; 6503b75ac618SJoe Perches my $var = $2; 6504b75ac618SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 6505b75ac618SJoe Perches ERROR("MISPLACED_INIT", 6506b75ac618SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 6507b75ac618SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 6508b75ac618SJoe Perches WARN("MISPLACED_INIT", 6509b75ac618SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 6510b75ac618SJoe Perches $fix) { 6511b75ac618SJoe 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; 65128716de38SJoe Perches } 65138716de38SJoe Perches } 65148716de38SJoe Perches } 65158716de38SJoe Perches 65168716de38SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 65178716de38SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 65188716de38SJoe Perches my $attr = $1; 65198716de38SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 65208716de38SJoe Perches my $attr_prefix = $1; 65218716de38SJoe Perches my $attr_type = $2; 65228716de38SJoe Perches if (ERROR("INIT_ATTRIBUTE", 65238716de38SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 65248716de38SJoe Perches $fix) { 6525194f66fcSJoe Perches $fixed[$fixlinenr] =~ 65268716de38SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 65278716de38SJoe Perches } 65288716de38SJoe Perches } 65298716de38SJoe Perches 6530e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 6531e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 6532e970b884SJoe Perches my $attr = $1; 6533e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 6534e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 6535e970b884SJoe Perches $fix) { 6536e970b884SJoe Perches my $lead = $fixed[$fixlinenr] =~ 6537e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 6538e970b884SJoe Perches $lead = rtrim($1); 6539194f66fcSJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 6540e970b884SJoe Perches $lead = "${lead}const "; 6541e970b884SJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 6542e970b884SJoe Perches } 6543e970b884SJoe Perches } 6544e970b884SJoe Perches 6545e970b884SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 6546e970b884SJoe Perches if ($line =~ /\b__read_mostly\b/ && 6547e970b884SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 6548e970b884SJoe Perches if (ERROR("CONST_READ_MOSTLY", 6549e970b884SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 6550194f66fcSJoe Perches $fix) { 6551e970b884SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 6552e970b884SJoe Perches } 6553e970b884SJoe Perches } 6554e970b884SJoe Perches 6555194f66fcSJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 6556e970b884SJoe Perches if ($realfile !~ m@^include/uapi/@ && 6557e970b884SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 6558e970b884SJoe Perches my $constant_func = $1; 6559c17893c7SJoe Perches my $func = $constant_func; 6560c17893c7SJoe Perches $func =~ s/^__constant_//; 6561c17893c7SJoe Perches if (WARN("CONSTANT_CONVERSION", 6562c17893c7SJoe Perches "$constant_func should be $func\n" . $herecurr) && 6563c17893c7SJoe Perches $fix) { 6564c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 6565c17893c7SJoe Perches } 6566c17893c7SJoe Perches } 6567c17893c7SJoe Perches 6568c17893c7SJoe Perches# prefer usleep_range over udelay 6569fbdb8138SJoe Perches if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 6570fbdb8138SJoe Perches my $delay = $1; 6571fbdb8138SJoe Perches # ignore udelay's < 10, however 6572fbdb8138SJoe Perches if (! ($delay < 10) ) { 6573fbdb8138SJoe Perches CHK("USLEEP_RANGE", 6574fbdb8138SJoe Perches "usleep_range is preferred over udelay; see function description of usleep_range() and udelay().\n" . $herecurr); 6575fbdb8138SJoe Perches } 6576fbdb8138SJoe Perches if ($delay > 2000) { 6577fbdb8138SJoe Perches WARN("LONG_UDELAY", 6578194f66fcSJoe Perches "long udelay - prefer mdelay; see function description of mdelay().\n" . $herecurr); 6579fbdb8138SJoe Perches } 6580fbdb8138SJoe Perches } 6581fbdb8138SJoe Perches 65821a15a250SPatrick Pannuto# warn about unexpectedly long msleep's 658337581c28SBruce Allan if ($line =~ /\bmsleep\s*\((\d+)\);/) { 658443c1d77cSJoe Perches if ($1 < 20) { 65851a15a250SPatrick Pannuto WARN("MSLEEP", 658643c1d77cSJoe Perches "msleep < 20ms can sleep for up to 20ms; see function description of msleep().\n" . $herecurr); 6587000d1cc1SJoe Perches } 65886534086aSAnna-Maria Behnsen } 658943c1d77cSJoe Perches 659043c1d77cSJoe Perches# check for comparisons of jiffies 659143c1d77cSJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 65926534086aSAnna-Maria Behnsen WARN("JIFFIES_COMPARISON", 65931a15a250SPatrick Pannuto "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 65941a15a250SPatrick Pannuto } 65951a15a250SPatrick Pannuto 659609ef8725SPatrick Pannuto# check for comparisons of get_jiffies_64() 659709ef8725SPatrick Pannuto if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 659809ef8725SPatrick Pannuto WARN("JIFFIES_COMPARISON", 6599000d1cc1SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 66006534086aSAnna-Maria Behnsen } 660109ef8725SPatrick Pannuto 660209ef8725SPatrick Pannuto# warn about #ifdefs in C files 660309ef8725SPatrick Pannuto# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 660436ec1939SJoe Perches# print "#ifdef in C files should be avoided\n"; 660536ec1939SJoe Perches# print "$herecurr"; 660636ec1939SJoe Perches# $clean = 0; 660736ec1939SJoe Perches# } 660836ec1939SJoe Perches 660936ec1939SJoe Perches# warn about spacing in #ifdefs 66109d7a34a5SJoe Perches if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 66119d7a34a5SJoe Perches if (ERROR("SPACING", 66129d7a34a5SJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 66139d7a34a5SJoe Perches $fix) { 66149d7a34a5SJoe Perches $fixed[$fixlinenr] =~ 66159d7a34a5SJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 661600df344fSAndy Whitcroft } 6617c45dcabdSAndy Whitcroft 661800df344fSAndy Whitcroft } 661900df344fSAndy Whitcroft 662000df344fSAndy Whitcroft# check for spinlock_t definitions without a comment. 662100df344fSAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 662200df344fSAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 662322f2a2efSAndy Whitcroft my $which = $1; 6624c45dcabdSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 66253705ce5bSJoe Perches CHK("UNCOMMENTED_DEFINITION", 66263705ce5bSJoe Perches "$1 definition without comment\n" . $herecurr); 66273705ce5bSJoe Perches } 6628194f66fcSJoe Perches } 66293705ce5bSJoe Perches# check for memory barriers without a comment. 66303705ce5bSJoe Perches 66313705ce5bSJoe Perches my $barriers = qr{ 663222f2a2efSAndy Whitcroft mb| 663322f2a2efSAndy Whitcroft rmb| 66344a0df2efSAndy Whitcroft wmb 6635171ae1a4SAndy Whitcroft }x; 6636171ae1a4SAndy Whitcroft my $barrier_stems = qr{ 66374a0df2efSAndy Whitcroft mb__before_atomic| 66384a0df2efSAndy Whitcroft mb__after_atomic| 6639000d1cc1SJoe Perches store_release| 6640000d1cc1SJoe Perches load_acquire| 66414a0df2efSAndy Whitcroft store_mb| 66424a0df2efSAndy Whitcroft (?:$barriers) 66434a0df2efSAndy Whitcroft }x; 6644402c2553SMichael S. Tsirkin my $all_barriers = qr{ 6645402c2553SMichael S. Tsirkin (?:$barriers)| 6646402c2553SMichael S. Tsirkin smp_(?:$barrier_stems)| 6647402c2553SMichael S. Tsirkin virt_(?:$barrier_stems) 6648ad83ec6cSWill Deacon }x; 6649402c2553SMichael S. Tsirkin 6650402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 6651402c2553SMichael S. Tsirkin if (!ctx_has_comment($first_line, $linenr)) { 6652402c2553SMichael S. Tsirkin WARN("MEMORY_BARRIER", 6653402c2553SMichael S. Tsirkin "memory barrier without comment\n" . $herecurr); 6654402c2553SMichael S. Tsirkin } 6655402c2553SMichael S. Tsirkin } 6656402c2553SMichael S. Tsirkin 6657402c2553SMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 6658402c2553SMichael S. Tsirkin 6659402c2553SMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 666043e361f2SMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 666143e361f2SMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 6662402c2553SMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 6663402c2553SMichael S. Tsirkin WARN("MEMORY_BARRIER", 6664402c2553SMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 66654a0df2efSAndy Whitcroft } 6666c1fd7bb9SJoe Perches 6667000d1cc1SJoe Perches# check for waitqueue_active without a comment. 66684a0df2efSAndy Whitcroft if ($line =~ /\bwaitqueue_active\s*\(/) { 66694a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 66703ad81779SPaul E. McKenney WARN("WAITQUEUE_ACTIVE", 6671f4073b0fSMichael S. Tsirkin "waitqueue_active without comment\n" . $herecurr); 6672f4073b0fSMichael S. Tsirkin } 6673f4073b0fSMichael S. Tsirkin } 6674f4073b0fSMichael S. Tsirkin 6675f4073b0fSMichael S. Tsirkin# check for data_race without a comment. 6676f4073b0fSMichael S. Tsirkin if ($line =~ /\bdata_race\s*\(/) { 6677f4073b0fSMichael S. Tsirkin if (!ctx_has_comment($first_line, $linenr)) { 6678f4073b0fSMichael S. Tsirkin WARN("DATA_RACE", 6679f4073b0fSMichael S. Tsirkin "data_race without comment\n" . $herecurr); 6680f4073b0fSMichael S. Tsirkin } 6681cb426e99SJoe Perches } 6682cb426e99SJoe Perches 6683cb426e99SJoe Perches# check of hardware specific defines 6684cb426e99SJoe Perches if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 6685cb426e99SJoe Perches CHK("ARCH_DEFINES", 6686cb426e99SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 6687cb426e99SJoe Perches } 66883ad81779SPaul E. McKenney 66895099a722SMarco Elver# check that the storage class is not after a type 66905099a722SMarco Elver if ($line =~ /\b($Type)\s+($Storage)\b/) { 66915099a722SMarco Elver WARN("STORAGE_CLASS", 66925099a722SMarco Elver "storage class '$2' should be located before type '$1'\n" . $herecurr); 66935099a722SMarco Elver } 66945099a722SMarco Elver# Check that the storage class is at the beginning of a declaration 66955099a722SMarco Elver if ($line =~ /\b$Storage\b/ && 66965099a722SMarco Elver $line !~ /^.\s*$Storage/ && 66974a0df2efSAndy Whitcroft $line =~ /^.\s*(.+?)\$Storage\s/ && 6698c45dcabdSAndy Whitcroft $1 !~ /[\,\)]\s*$/) { 6699000d1cc1SJoe Perches WARN("STORAGE_CLASS", 6700000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 67010a920b5bSAndy Whitcroft } 6702653d4876SAndy Whitcroft 6703596ed45bSJoe Perches# check the location of the inline attribute, that it is between 6704596ed45bSJoe Perches# storage class and type. 6705000d1cc1SJoe Perches if ($line =~ /\b$Type\s+$Inline\b/ || 6706596ed45bSJoe Perches $line =~ /\b$Inline\s+$Storage\b/) { 6707596ed45bSJoe Perches ERROR("INLINE_LOCATION", 6708596ed45bSJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 6709596ed45bSJoe Perches } 6710596ed45bSJoe Perches 6711596ed45bSJoe Perches# Check for __inline__ and __inline, prefer inline 6712596ed45bSJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6713596ed45bSJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 6714596ed45bSJoe Perches if (WARN("INLINE", 6715d4977c78STobias Klauser "plain inline is preferred over $1\n" . $herecurr) && 6716d4977c78STobias Klauser $fix) { 6717de7d4f0eSAndy Whitcroft $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 6718de7d4f0eSAndy Whitcroft 67199c0ca6f9SAndy Whitcroft } 67209c0ca6f9SAndy Whitcroft } 6721000d1cc1SJoe Perches 6722000d1cc1SJoe Perches# Check for compiler attributes 6723de7d4f0eSAndy Whitcroft if ($realfile !~ m@\binclude/uapi/@ && 6724de7d4f0eSAndy Whitcroft $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) { 67258905a67cSAndy Whitcroft my $attr = $1; 67262b7ab453SJoe Perches $attr =~ s/\s*\(\s*(.*)\)\s*/$1/; 67272b7ab453SJoe Perches 6728d5e616fcSJoe Perches my %attr_list = ( 6729d5e616fcSJoe Perches "alias" => "__alias", 6730d5e616fcSJoe Perches "aligned" => "__aligned", 6731194f66fcSJoe Perches "always_inline" => "__always_inline", 6732d5e616fcSJoe Perches "assume_aligned" => "__assume_aligned", 6733d5e616fcSJoe Perches "cold" => "__cold", 67348905a67cSAndy Whitcroft "const" => "__attribute_const__", 67358905a67cSAndy Whitcroft "copy" => "__copy", 67367ebe1d17SDwaipayan Ray "designated_init" => "__designated_init", 67372b7ab453SJoe Perches "externally_visible" => "__visible", 67387ebe1d17SDwaipayan Ray "format" => "printf|scanf", 67397ebe1d17SDwaipayan Ray "gnu_inline" => "__gnu_inline", 67407ebe1d17SDwaipayan Ray "malloc" => "__malloc", 67417ebe1d17SDwaipayan Ray "mode" => "__mode", 67427ebe1d17SDwaipayan Ray "no_caller_saved_registers" => "__no_caller_saved_registers", 67430830aab0SJoe Perches "noclone" => "__noclone", 67447ebe1d17SDwaipayan Ray "noinline" => "noinline", 67457ebe1d17SDwaipayan Ray "nonstring" => "__nonstring", 67467ebe1d17SDwaipayan Ray "noreturn" => "__noreturn", 67477ebe1d17SDwaipayan Ray "packed" => "__packed", 67487ebe1d17SDwaipayan Ray "pure" => "__pure", 67497ebe1d17SDwaipayan Ray "section" => "__section", 67507ebe1d17SDwaipayan Ray "used" => "__used", 67517ebe1d17SDwaipayan Ray "weak" => "__weak" 67527ebe1d17SDwaipayan Ray ); 67537ebe1d17SDwaipayan Ray 67547ebe1d17SDwaipayan Ray while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) { 67557ebe1d17SDwaipayan Ray my $orig_attr = $1; 67567ebe1d17SDwaipayan Ray my $params = ''; 67577ebe1d17SDwaipayan Ray $params = $2 if defined($2); 67587ebe1d17SDwaipayan Ray my $curr_attr = $orig_attr; 67597ebe1d17SDwaipayan Ray $curr_attr =~ s/^[\s_]+|[\s_]+$//g; 67607ebe1d17SDwaipayan Ray if (exists($attr_list{$curr_attr})) { 67617ebe1d17SDwaipayan Ray my $new = $attr_list{$curr_attr}; 67627ebe1d17SDwaipayan Ray if ($curr_attr eq "format" && $params) { 6763339f29d9SJoe Perches $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/; 67640830aab0SJoe Perches $new = "__$1\($2"; 67650830aab0SJoe Perches } else { 67667ebe1d17SDwaipayan Ray $new = "$new$params"; 67677ebe1d17SDwaipayan Ray } 67687ebe1d17SDwaipayan Ray if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 6769339f29d9SJoe Perches "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) && 67707ebe1d17SDwaipayan Ray $fix) { 67717ebe1d17SDwaipayan Ray my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?'; 6772339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/$remove//; 67737ebe1d17SDwaipayan Ray $fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/; 67747ebe1d17SDwaipayan Ray $fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/; 6775339f29d9SJoe Perches $fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//; 67767ebe1d17SDwaipayan Ray } 67777ebe1d17SDwaipayan Ray } 6778339f29d9SJoe Perches } 67797ebe1d17SDwaipayan Ray 6780339f29d9SJoe Perches # Check for __attribute__ unused, prefer __always_unused or __maybe_unused 67817ebe1d17SDwaipayan Ray if ($attr =~ /^_*unused/) { 67827ebe1d17SDwaipayan Ray WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", 6783339f29d9SJoe Perches "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); 67847ebe1d17SDwaipayan Ray } 6785339f29d9SJoe Perches } 6786339f29d9SJoe Perches 6787339f29d9SJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 6788339f29d9SJoe Perches if ($perl_version_ok && 6789339f29d9SJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 67907ebe1d17SDwaipayan Ray ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 679139b7e287SJoe Perches $line =~ /\b__weak\b/)) { 6792462811d9SJoe Perches ERROR("WEAK_DECLARATION", 6793462811d9SJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 67947ebe1d17SDwaipayan Ray } 67957ebe1d17SDwaipayan Ray 67967ebe1d17SDwaipayan Ray# check for c99 types like uint8_t used outside of uapi/ and tools/ 67977ebe1d17SDwaipayan Ray if ($realfile !~ m@\binclude/uapi/@ && 6798d5e616fcSJoe Perches $realfile !~ m@\btools/@ && 67996061d949SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 68006061d949SJoe Perches my $type = $1; 6801619a908aSJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 68025b57980dSJoe Perches $type = $1; 6803619a908aSJoe Perches my $kernel_type = 'u'; 6804619a908aSJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6805619a908aSJoe Perches $type =~ /(\d+)/; 6806619a908aSJoe Perches $kernel_type .= $1; 6807619a908aSJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6808619a908aSJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6809619a908aSJoe Perches $fix) { 6810fd39f904STomas Winkler $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6811e6176fa4SJoe Perches } 6812fd39f904STomas Winkler } 6813e6176fa4SJoe Perches } 6814e6176fa4SJoe Perches 6815e6176fa4SJoe Perches# check for cast of C90 native int or longer types constants 6816e6176fa4SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6817e6176fa4SJoe Perches my $cast = $1; 6818e6176fa4SJoe Perches my $const = $2; 6819e6176fa4SJoe Perches my $suffix = ""; 6820e6176fa4SJoe Perches my $newconst = $const; 6821e6176fa4SJoe Perches $newconst =~ s/${Int_type}$//; 6822e6176fa4SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6823e6176fa4SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6824e6176fa4SJoe Perches $suffix .= 'LL'; 6825e6176fa4SJoe Perches } elsif ($cast =~ /\blong\b/) { 6826e6176fa4SJoe Perches $suffix .= 'L'; 6827e6176fa4SJoe Perches } 6828e6176fa4SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 6829938224b5SJoe Perches "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) && 6830938224b5SJoe Perches $fix) { 6831938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6832938224b5SJoe Perches } 6833938224b5SJoe Perches } 6834938224b5SJoe Perches 6835938224b5SJoe Perches# check for sizeof(&) 6836938224b5SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6837938224b5SJoe Perches WARN("SIZEOF_ADDRESS", 6838938224b5SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 6839938224b5SJoe Perches } 6840938224b5SJoe Perches 6841938224b5SJoe Perches# check for sizeof without parenthesis 68420972b8bfSJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 68430972b8bfSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 68440972b8bfSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6845938224b5SJoe Perches $fix) { 6846938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6847938224b5SJoe Perches } 6848938224b5SJoe Perches } 68498f53a9b8SJoe Perches 68508f53a9b8SJoe Perches# check for struct spinlock declarations 6851000d1cc1SJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 6852000d1cc1SJoe Perches WARN("USE_SPINLOCK_T", 68538f53a9b8SJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 68548f53a9b8SJoe Perches } 685566c80b60SJoe Perches 685666c80b60SJoe Perches# check for seq_printf uses that could be seq_puts 6857d5e616fcSJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6858d5e616fcSJoe Perches my $fmt = get_quoted_string($line, $rawline); 6859d5e616fcSJoe Perches $fmt =~ s/%%//g; 6860194f66fcSJoe Perches if ($fmt !~ /%/) { 6861d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 686266c80b60SJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 686366c80b60SJoe Perches $fix) { 686488982feaSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 686588982feaSJoe Perches } 686688982feaSJoe Perches } 686788982feaSJoe Perches } 686888982feaSJoe Perches 686988982feaSJoe Perches# check for vsprintf extension %p<foo> misuses 6870a6962d72SJoe Perches if ($perl_version_ok && 687106668727SJoe Perches defined $stat && 6872a6962d72SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 6873caac1d5fSHeba Aamer $1 !~ /^_*volatile_*$/) { 6874caac1d5fSHeba Aamer my $stat_real; 6875d5e616fcSJoe Perches 6876d5e616fcSJoe Perches my $lc = $stat =~ tr@\n@@; 6877d5e616fcSJoe Perches $lc = $lc + $linenr; 6878194f66fcSJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6879d5e616fcSJoe Perches my $specifier; 6880a6962d72SJoe Perches my $extension; 6881a6962d72SJoe Perches my $qualifier; 6882a6962d72SJoe Perches my $bad_specifier = ""; 68830b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 68845b57980dSJoe Perches $fmt =~ s/%%//g; 68850b523769SJoe Perches 68860b523769SJoe Perches while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 68870b523769SJoe Perches $specifier = $1; 6888e3c6bc95STobin C. Harding $extension = $2; 6889e3c6bc95STobin C. Harding $qualifier = $3; 68900b523769SJoe Perches if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 68910b523769SJoe Perches ($extension eq "f" && 68920b523769SJoe Perches defined $qualifier && $qualifier !~ /^w/) || 6893ffe07513SJoe Perches ($extension eq "4" && 6894ffe07513SJoe Perches defined $qualifier && $qualifier !~ /^cc/)) { 68953bd32d6aSSakari Ailus $bad_specifier = $specifier; 6896ffe07513SJoe Perches last; 68970b523769SJoe Perches } 68980b523769SJoe Perches if ($extension eq "x" && !defined($stat_real)) { 6899e3c6bc95STobin C. Harding if (!defined($stat_real)) { 69003bd32d6aSSakari Ailus $stat_real = get_stat_real($linenr, $lc); 6901e3c6bc95STobin C. Harding } 6902e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 69033bd32d6aSSakari Ailus "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"); 6904af612e43SSakari Ailus } 69053bd32d6aSSakari Ailus } 6906af612e43SSakari Ailus if ($bad_specifier ne "") { 6907af612e43SSakari Ailus my $stat_real = get_stat_real($linenr, $lc); 6908af612e43SSakari Ailus my $msg_level = \&WARN; 6909e3c6bc95STobin C. Harding my $ext_type = "Invalid"; 69100b523769SJoe Perches my $use = ""; 69110b523769SJoe Perches if ($bad_specifier =~ /p[Ff]/) { 6912e3c6bc95STobin C. Harding $use = " - use %pS instead"; 6913e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 6914e3c6bc95STobin C. Harding } elsif ($bad_specifier =~ /pA/) { 69150b523769SJoe Perches $use = " - '%pA' is only intended to be used from Rust code"; 6916e3c6bc95STobin C. Harding $msg_level = \&ERROR; 6917e3c6bc95STobin C. Harding } 6918e3c6bc95STobin C. Harding 6919e3c6bc95STobin C. Harding &{$msg_level}("VSPRINTF_POINTER_EXTENSION", 6920e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 69212a9f9d85STobin C. Harding } 6922de48fa1aSMiguel Ojeda } 69231df7338aSSergey Senozhatsky } 69241df7338aSSergey Senozhatsky 6925e3c6bc95STobin C. Harding# Check for misused memsets 69261df7338aSSergey Senozhatsky if ($perl_version_ok && 6927e3c6bc95STobin C. Harding defined $stat && 6928de48fa1aSMiguel Ojeda $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6929de48fa1aSMiguel Ojeda 6930de48fa1aSMiguel Ojeda my $ms_addr = $2; 69311df7338aSSergey Senozhatsky my $ms_val = $7; 69322a9f9d85STobin C. Harding my $ms_size = $12; 6933de48fa1aSMiguel Ojeda 6934e3c6bc95STobin C. Harding if ($ms_size =~ /^(0x|)0$/i) { 6935e3c6bc95STobin C. Harding ERROR("MEMSET", 69360b523769SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 69370b523769SJoe Perches } elsif ($ms_size =~ /^(0x|)1$/i) { 69380b523769SJoe Perches WARN("MEMSET", 6939554e165cSAndy Whitcroft "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 69405b57980dSJoe Perches } 6941d1fe9c09SJoe Perches } 69429e20a853SMateusz Kulikowski 6943554e165cSAndy Whitcroft# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 6944d7c76ba7SJoe Perches# if ($perl_version_ok && 6945d1fe9c09SJoe Perches# defined $stat && 6946d1fe9c09SJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6947d7c76ba7SJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6948554e165cSAndy Whitcroft# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6949554e165cSAndy Whitcroft# $fix) { 6950d7c76ba7SJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6951554e165cSAndy Whitcroft# } 6952554e165cSAndy Whitcroft# } 6953d7c76ba7SJoe Perches 6954d7c76ba7SJoe Perches# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 6955d7c76ba7SJoe Perches# if ($perl_version_ok && 6956d7c76ba7SJoe Perches# defined $stat && 695798a9bba5SJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 69585b57980dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6959f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6960f333195dSJoe Perches# } 6961f333195dSJoe Perches 6962f333195dSJoe Perches# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 6963f333195dSJoe Perches# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 6964f333195dSJoe Perches# if ($perl_version_ok && 6965f333195dSJoe Perches# defined $stat && 6966f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 696798a9bba5SJoe Perches# 6968b6117d17SMateusz Kulikowski# my $ms_val = $7; 69695b57980dSJoe Perches# 6970f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6971f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6972f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6973f333195dSJoe Perches# $fix) { 6974f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6975b6117d17SMateusz Kulikowski# } 69768617cd09SMateusz Kulikowski# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 69778617cd09SMateusz Kulikowski# if (WARN("PREFER_ETH_BROADCAST_ADDR", 69785b57980dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6979f333195dSJoe Perches# $fix) { 6980f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6981f333195dSJoe Perches# } 6982f333195dSJoe Perches# } 6983f333195dSJoe Perches# } 6984f333195dSJoe Perches 6985f333195dSJoe Perches# strcpy uses that should likely be strscpy 6986f333195dSJoe Perches if ($line =~ /\bstrcpy\s*\(/) { 6987f333195dSJoe Perches WARN("STRCPY", 6988f333195dSJoe Perches "Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88\n" . $herecurr); 6989f333195dSJoe Perches } 6990f333195dSJoe Perches 6991f333195dSJoe Perches# strlcpy uses that should likely be strscpy 6992f333195dSJoe Perches if ($line =~ /\bstrlcpy\s*\(/) { 6993f333195dSJoe Perches WARN("STRLCPY", 6994f333195dSJoe Perches "Prefer strscpy over strlcpy - see: https://github.com/KSPP/linux/issues/89\n" . $herecurr); 6995f333195dSJoe Perches } 6996f333195dSJoe Perches 6997f333195dSJoe Perches# strncpy uses that should likely be strscpy or strscpy_pad 69988617cd09SMateusz Kulikowski if ($line =~ /\bstrncpy\s*\(/) { 6999d0f90841SKees Cook WARN("STRNCPY", 7000d0f90841SKees Cook "Prefer strscpy, strscpy_pad, or __nonstring over strncpy - see: https://github.com/KSPP/linux/issues/90\n" . $herecurr); 7001d0f90841SKees Cook } 7002d0f90841SKees Cook 7003d0f90841SKees Cook# ethtool_sprintf uses that should likely be ethtool_puts 7004d0f90841SKees Cook if ($line =~ /\bethtool_sprintf\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 70055dbdb2d8SJoe Perches if (WARN("PREFER_ETHTOOL_PUTS", 70065dbdb2d8SJoe Perches "Prefer ethtool_puts over ethtool_sprintf with only two arguments\n" . $herecurr) && 70075dbdb2d8SJoe Perches $fix) { 7008d0f90841SKees Cook $fixed[$fixlinenr] =~ s/\bethtool_sprintf\s*\(\s*($FuncArg)\s*,\s*($FuncArg)/ethtool_puts($1, $7)/; 7009d0f90841SKees Cook } 7010d0f90841SKees Cook } 7011d0f90841SKees Cook 7012d0f90841SKees Cook # use $rawline because $line loses %s via sanitization and thus we can't match against it. 7013d0f90841SKees Cook if ($rawline =~ /\bethtool_sprintf\s*\(\s*$FuncArg\s*,\s*\"\%s\"\s*,\s*$FuncArg\s*\)/) { 7014d0f90841SKees Cook if (WARN("PREFER_ETHTOOL_PUTS", 70155dbdb2d8SJoe Perches "Prefer ethtool_puts over ethtool_sprintf with standalone \"%s\" specifier\n" . $herecurr) && 70165dbdb2d8SJoe Perches $fix) { 70179b5f621cS[email protected] $fixed[$fixlinenr] =~ s/\bethtool_sprintf\s*\(\s*($FuncArg)\s*,\s*"\%s"\s*,\s*($FuncArg)/ethtool_puts($1, $7)/; 70189b5f621cS[email protected] } 70199b5f621cS[email protected] } 70209b5f621cS[email protected] 70219b5f621cS[email protected] 70229b5f621cS[email protected]# typecasts on min/max could be min_t/max_t 70239b5f621cS[email protected] if ($perl_version_ok && 70249b5f621cS[email protected] defined $stat && 70259b5f621cS[email protected] $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 70269b5f621cS[email protected] if (defined $2 || defined $7) { 70279b5f621cS[email protected] my $call = $1; 70289b5f621cS[email protected] my $cast1 = deparenthesize($2); 70299b5f621cS[email protected] my $arg1 = $3; 70309b5f621cS[email protected] my $cast2 = deparenthesize($7); 70319b5f621cS[email protected] my $arg2 = $8; 70329b5f621cS[email protected] my $cast; 70339b5f621cS[email protected] 70349b5f621cS[email protected] if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 70359b5f621cS[email protected] $cast = "$cast1 or $cast2"; 7036d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 70375b57980dSJoe Perches $cast = $cast1; 7038d1fe9c09SJoe Perches } else { 7039d7c76ba7SJoe Perches $cast = $cast2; 7040d1fe9c09SJoe Perches } 7041d7c76ba7SJoe Perches WARN("MINMAX", 7042d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 7043d7c76ba7SJoe Perches } 7044d1fe9c09SJoe Perches } 7045d1fe9c09SJoe Perches 7046d7c76ba7SJoe Perches# check usleep_range arguments 7047d7c76ba7SJoe Perches if ($perl_version_ok && 7048d1fe9c09SJoe Perches defined $stat && 7049d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 7050d7c76ba7SJoe Perches my $min = $1; 7051d7c76ba7SJoe Perches my $max = $7; 7052d7c76ba7SJoe Perches if ($min eq $max) { 7053d7c76ba7SJoe Perches WARN("USLEEP_RANGE", 7054d7c76ba7SJoe Perches "usleep_range should not use min == max args; see function description of usleep_range().\n" . "$here\n$stat\n"); 7055d7c76ba7SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 7056d7c76ba7SJoe Perches $min > $max) { 7057554e165cSAndy Whitcroft WARN("USLEEP_RANGE", 7058554e165cSAndy Whitcroft "usleep_range args reversed, use min then max; see function description of usleep_range().\n" . "$here\n$stat\n"); 7059554e165cSAndy Whitcroft } 70604a273195SJoe Perches } 70615b57980dSJoe Perches 70624a273195SJoe Perches# check for naked sscanf 70634a273195SJoe Perches if ($perl_version_ok && 70644a273195SJoe Perches defined $stat && 70654a273195SJoe Perches $line =~ /\bsscanf\b/ && 70664a273195SJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 70674a273195SJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 70686534086aSAnna-Maria Behnsen $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 70694a273195SJoe Perches my $lc = $stat =~ tr@\n@@; 70704a273195SJoe Perches $lc = $lc + $linenr; 70714a273195SJoe Perches my $stat_real = get_stat_real($linenr, $lc); 70726534086aSAnna-Maria Behnsen WARN("NAKED_SSCANF", 70734a273195SJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 70744a273195SJoe Perches } 70754a273195SJoe Perches 7076823b794cSJoe Perches# check for simple sscanf that should be kstrto<foo> 70775b57980dSJoe Perches if ($perl_version_ok && 7078823b794cSJoe Perches defined $stat && 70796c8bd707SJoe Perches $line =~ /\bsscanf\b/) { 7080823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 7081823b794cSJoe Perches $lc = $lc + $linenr; 7082823b794cSJoe Perches my $stat_real = get_stat_real($linenr, $lc); 7083823b794cSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 7084823b794cSJoe Perches my $format = $6; 70852a9f9d85STobin C. Harding my $count = $format =~ tr@%@%@; 7086823b794cSJoe Perches if ($count == 1 && 7087823b794cSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 7088823b794cSJoe Perches WARN("SSCANF_TO_KSTRTO", 7089823b794cSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 7090afc819abSJoe Perches } 70915b57980dSJoe Perches } 7092afc819abSJoe Perches } 7093afc819abSJoe Perches 7094afc819abSJoe Perches# check for new externs in .h files. 7095afc819abSJoe Perches if ($realfile =~ /\.h$/ && 70962a9f9d85STobin C. Harding $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 7097afc819abSJoe Perches if (CHK("AVOID_EXTERNS", 7098afc819abSJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 7099afc819abSJoe Perches $fix) { 7100afc819abSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 7101afc819abSJoe Perches } 7102afc819abSJoe Perches } 7103afc819abSJoe Perches 7104afc819abSJoe Perches# check for new externs in .c files. 7105afc819abSJoe Perches if ($realfile =~ /\.c$/ && defined $stat && 7106afc819abSJoe Perches $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 7107afc819abSJoe Perches { 710870dc8a48SJoe Perches my $function_name = $1; 710970dc8a48SJoe Perches my $paren_space = $2; 711070dc8a48SJoe Perches 7111d1d85780SJoe Perches my $s = $stat; 711270dc8a48SJoe Perches if (defined $cond) { 711370dc8a48SJoe Perches substr($s, 0, length($cond), ''); 7114194f66fcSJoe Perches } 711570dc8a48SJoe Perches if ($s =~ /^\s*;/) 711670dc8a48SJoe Perches { 711770dc8a48SJoe Perches WARN("AVOID_EXTERNS", 7118de7d4f0eSAndy Whitcroft "externs should be avoided in .c files\n" . $herecurr); 7119171ae1a4SAndy Whitcroft } 7120c45dcabdSAndy Whitcroft 7121171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 7122c45dcabdSAndy Whitcroft WARN("FUNCTION_ARGUMENTS", 7123c45dcabdSAndy Whitcroft "arguments for function declarations should follow identifier\n" . $herecurr); 7124171ae1a4SAndy Whitcroft } 7125171ae1a4SAndy Whitcroft 7126171ae1a4SAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 7127171ae1a4SAndy Whitcroft $stat =~ /^\+extern struct\s+(\w+)\s+(\w+)\[\];/) 7128171ae1a4SAndy Whitcroft { 7129d8b44b58SKees Cook my ($st_type, $st_name) = ($1, $2); 7130c45dcabdSAndy Whitcroft 7131000d1cc1SJoe Perches for my $s (keys %maybe_linker_symbol) { 7132000d1cc1SJoe Perches #print "Linker symbol? $st_name : $s\n"; 7133de7d4f0eSAndy Whitcroft goto LIKELY_LINKER_SYMBOL 7134de7d4f0eSAndy Whitcroft if $st_name =~ /$s/; 7135171ae1a4SAndy Whitcroft } 7136000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 7137000d1cc1SJoe Perches "found a file-scoped extern type:$st_type name:$st_name in .c file\n" 7138171ae1a4SAndy Whitcroft . "is this a linker symbol ?\n" . $herecurr); 71399c9ba34eSAndy Whitcroft LIKELY_LINKER_SYMBOL: 71409c9ba34eSAndy Whitcroft 71415b2c7334SJim Cromie } elsif ($realfile =~ /\.c$/ && defined $stat && 71425b2c7334SJim Cromie $stat =~ /^.\s*extern\s+/) 71435b2c7334SJim Cromie { 71445b2c7334SJim Cromie WARN("AVOID_EXTERNS", 71455b2c7334SJim Cromie "externs should be avoided in .c files\n" . $herecurr); 71465b2c7334SJim Cromie } 71475b2c7334SJim Cromie 71485b2c7334SJim Cromie# check for function declarations that have arguments without identifier names 71495b2c7334SJim Cromie if (defined $stat && 71505b2c7334SJim Cromie $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 71515b2c7334SJim Cromie $1 ne "void") { 71525b2c7334SJim Cromie my $args = trim($1); 71535b2c7334SJim Cromie while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 71545b2c7334SJim Cromie my $arg = trim($1); 71555b2c7334SJim Cromie if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 71569c9ba34eSAndy Whitcroft WARN("FUNCTION_ARGUMENTS", 71579c9ba34eSAndy Whitcroft "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 7158000d1cc1SJoe Perches } 7159000d1cc1SJoe Perches } 7160171ae1a4SAndy Whitcroft } 7161171ae1a4SAndy Whitcroft 7162a0ad7596SJoe Perches# check for function definitions 7163a0ad7596SJoe Perches if ($perl_version_ok && 7164d8b44b58SKees Cook defined $stat && 7165d8b44b58SKees Cook $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 7166d8b44b58SKees Cook $context_function = $1; 7167ca0d8929SJoe Perches 7168ca0d8929SJoe Perches# check for multiline function definition with misplaced open brace 7169d8b44b58SKees Cook my $ok = 0; 7170ca0d8929SJoe Perches my $cnt = statement_rawlines($stat); 7171ca0d8929SJoe Perches my $herectx = $here . "\n"; 7172ca0d8929SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 7173ca0d8929SJoe Perches my $rl = raw_line($linenr, $n); 7174ca0d8929SJoe Perches $herectx .= $rl . "\n"; 7175ca0d8929SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 7176a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 71775b57980dSJoe Perches last if $rl =~ /^[ \+].*\{/; 7178a0ad7596SJoe Perches } 7179a0ad7596SJoe Perches if (!$ok) { 7180a0ad7596SJoe Perches ERROR("OPEN_BRACE", 7181a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 7182a0ad7596SJoe Perches } 7183a0ad7596SJoe Perches } 7184a0ad7596SJoe Perches 7185a0ad7596SJoe Perches# checks for new __setup's 7186a0ad7596SJoe Perches if ($rawline =~ /\b__setup\("([^"]*)"/) { 7187a0ad7596SJoe Perches my $name = $1; 7188a0ad7596SJoe Perches 7189a0ad7596SJoe Perches if (!grep(/$name/, @setup_docs)) { 7190a0ad7596SJoe Perches CHK("UNDOCUMENTED_SETUP", 7191a0ad7596SJoe Perches "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); 7192a0ad7596SJoe Perches } 7193a0ad7596SJoe Perches } 7194a0ad7596SJoe Perches 7195a0ad7596SJoe Perches# check for pointless casting of alloc functions 7196a0ad7596SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 7197a0ad7596SJoe Perches WARN("UNNECESSARY_CASTS", 7198a0ad7596SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 7199de7d4f0eSAndy Whitcroft } 7200de7d4f0eSAndy Whitcroft 7201de7d4f0eSAndy Whitcroft# alloc style 7202de7d4f0eSAndy Whitcroft# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 7203de7d4f0eSAndy Whitcroft if ($perl_version_ok && 7204000d1cc1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 72052581ac7cSTim Froidcoeur CHK("ALLOC_SIZEOF_STRUCT", 7206de7d4f0eSAndy Whitcroft "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 7207653d4876SAndy Whitcroft } 72089c0ca6f9SAndy Whitcroft 7209e29a70f1SJoe Perches# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc 7210e29a70f1SJoe Perches if ($perl_version_ok && 7211000d1cc1SJoe Perches defined $stat && 7212000d1cc1SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 72139c0ca6f9SAndy Whitcroft my $oldfunc = $3; 721413214adfSAndy Whitcroft my $a1 = $4; 7215a640d25cSJoe Perches my $a2 = $10; 7216a640d25cSJoe Perches my $newfunc = "kmalloc_array"; 72175b57980dSJoe Perches $newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc"); 7218e29a70f1SJoe Perches $newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc"); 7219a640d25cSJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 7220a640d25cSJoe Perches my $r1 = $a1; 7221a640d25cSJoe Perches my $r2 = $a2; 7222a640d25cSJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 722373f1d07eSGustavo A. R. Silva $r1 = $a2; 72245b57980dSJoe Perches $r2 = $a1; 72251b4a2ed4SJoe Perches } 722673f1d07eSGustavo A. R. Silva if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 722760a55369SJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 722860a55369SJoe Perches my $cnt = statement_rawlines($stat); 722960a55369SJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 723060a55369SJoe Perches 723173f1d07eSGustavo A. R. Silva if (WARN("ALLOC_WITH_MULTIPLY", 723273f1d07eSGustavo A. R. Silva "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 723360a55369SJoe Perches $cnt == 1 && 723460a55369SJoe Perches $fix) { 723560a55369SJoe Perches $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; 723660a55369SJoe Perches } 723760a55369SJoe Perches } 723860a55369SJoe Perches } 723960a55369SJoe Perches 7240e367455aSJoe Perches# check for krealloc arg reuse 7241e367455aSJoe Perches if ($perl_version_ok && 72421b4a2ed4SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 7243e3d95a2aSTobin C. Harding $1 eq $3) { 7244e3d95a2aSTobin C. Harding WARN("KREALLOC_ARG_REUSE", 7245e367455aSJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 72461b4a2ed4SJoe Perches } 72471b4a2ed4SJoe Perches 7248e367455aSJoe Perches# check for alloc argument mismatch 724973f1d07eSGustavo A. R. Silva if ($line =~ /\b((?:devm_)?((?:k|kv)?(calloc|malloc_array)(?:_node)?))\s*\(\s*sizeof\b/) { 725060a55369SJoe Perches WARN("ALLOC_ARRAY_ARGS", 725160a55369SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 725260a55369SJoe Perches } 725360a55369SJoe Perches 7254972fdea2SJoe Perches# check for multiple semicolons 72555b57980dSJoe Perches if ($line =~ /;\s*;\s*$/) { 72564cab63ceSJoe Perches if (WARN("ONE_SEMICOLON", 72574cab63ceSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 7258972fdea2SJoe Perches $fix) { 7259972fdea2SJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 7260972fdea2SJoe Perches } 7261972fdea2SJoe Perches } 72625ce59ae0SJoe Perches 72633965292aSLiao Chang# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 72645ce59ae0SJoe Perches if ($realfile !~ m@^include/uapi/@ && 72655ce59ae0SJoe Perches $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 72665ce59ae0SJoe Perches my $ull = ""; 72675ce59ae0SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 7268caf2a54fSJoe Perches if (CHK("BIT_MACRO", 7269caf2a54fSJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 7270d5e616fcSJoe Perches $fix) { 7271d5e616fcSJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 7272d5e616fcSJoe Perches } 7273194f66fcSJoe Perches } 7274d5e616fcSJoe Perches 7275d1e2ad07SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) 7276d1e2ad07SJoe Perches if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { 7277cec3aaa5STomas Winkler WARN("IS_ENABLED_CONFIG", 7278cec3aaa5STomas Winkler "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); 7279cec3aaa5STomas Winkler } 72800ab90191SJoe Perches 72810ab90191SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 72820ab90191SJoe Perches if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { 72830ab90191SJoe Perches my $config = $1; 72840ab90191SJoe Perches if (WARN("PREFER_IS_ENABLED", 72850ab90191SJoe Perches "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && 72860ab90191SJoe Perches $fix) { 72870ab90191SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 72880ab90191SJoe Perches } 728950161266SJoe Perches } 72903e89ad85SJerome Forissier 729150161266SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 72923e89ad85SJerome Forissier my @fallthroughs = ( 729350161266SJoe Perches 'fallthrough', 729450161266SJoe Perches '@fallthrough@', 72952d632745SJoe Perches 'lint -fallthrough[ \t]*', 72963e89ad85SJerome Forissier 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 72972d632745SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 72982d632745SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 72993e89ad85SJerome Forissier 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 73002d632745SJoe Perches ); 73012d632745SJoe Perches if ($raw_comment ne '') { 73022d632745SJoe Perches foreach my $ft (@fallthroughs) { 73032d632745SJoe Perches if ($raw_comment =~ /$ft/) { 73042d632745SJoe Perches my $msg_level = \&WARN; 7305f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 7306f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 7307f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 7308f36d3eb8SJoe Perches last; 7309f36d3eb8SJoe Perches } 7310f36d3eb8SJoe Perches } 7311f36d3eb8SJoe Perches } 7312f36d3eb8SJoe Perches 7313f36d3eb8SJoe Perches# check for switch/default statements without a break; 7314f36d3eb8SJoe Perches if ($perl_version_ok && 7315f36d3eb8SJoe Perches defined $stat && 7316f36d3eb8SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 7317f36d3eb8SJoe Perches my $cnt = statement_rawlines($stat); 7318f36d3eb8SJoe Perches my $herectx = get_stat_here($linenr, $cnt, $here); 7319f36d3eb8SJoe Perches 7320f36d3eb8SJoe Perches WARN("DEFAULT_NO_BREAK", 7321f36d3eb8SJoe Perches "switch default: should use break\n" . $herectx); 7322f36d3eb8SJoe Perches } 7323f36d3eb8SJoe Perches 7324f36d3eb8SJoe Perches# check for gcc specific __FUNCTION__ 7325f36d3eb8SJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 7326f36d3eb8SJoe Perches if (WARN("USE_FUNC", 7327d1e2ad07SJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 73285b57980dSJoe Perches $fix) { 7329d1e2ad07SJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 7330d1e2ad07SJoe Perches } 7331d1e2ad07SJoe Perches } 7332e3d95a2aSTobin C. Harding 7333e3d95a2aSTobin C. Harding# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 7334d1e2ad07SJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 7335d1e2ad07SJoe Perches ERROR("DATE_TIME", 7336caf2a54fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 7337caf2a54fSJoe Perches } 733813214adfSAndy Whitcroft 7339d5e616fcSJoe Perches# check for use of yield() 7340d5e616fcSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 7341d5e616fcSJoe Perches WARN("YIELD", 7342d5e616fcSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 7343194f66fcSJoe Perches } 7344d5e616fcSJoe Perches 734513214adfSAndy Whitcroft# check for comparisons against true and false 7346773647a0SAndy Whitcroft if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 734762ec818fSJoe Perches my $lead = $1; 734862ec818fSJoe Perches my $arg = $2; 734962ec818fSJoe Perches my $test = $3; 735062ec818fSJoe Perches my $otype = $4; 735162ec818fSJoe Perches my $trail = $5; 735262ec818fSJoe Perches my $op = "!"; 73532c92488aSJoe Perches 73542c92488aSJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 73552c92488aSJoe Perches 73562c92488aSJoe Perches my $type = lc($otype); 73572c92488aSJoe Perches if ($type =~ /^(?:true|false)$/) { 73582c92488aSJoe Perches if (("$test" eq "==" && "$type" eq "true") || 7359179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 7360179f8f40SJoe Perches $op = ""; 7361179f8f40SJoe Perches } 7362179f8f40SJoe Perches 7363179f8f40SJoe Perches CHK("BOOL_COMPARISON", 7364179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 7365179f8f40SJoe Perches 7366179f8f40SJoe Perches## maybe suggesting a correct construct would better 7367179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 7368179f8f40SJoe Perches 7369179f8f40SJoe Perches } 7370179f8f40SJoe Perches } 7371179f8f40SJoe Perches 7372179f8f40SJoe Perches# check for semaphores initialized locked 7373179f8f40SJoe Perches if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 7374179f8f40SJoe Perches WARN("CONSIDER_COMPLETION", 7375179f8f40SJoe Perches "consider using a completion\n" . $herecurr); 7376179f8f40SJoe Perches } 7377179f8f40SJoe Perches 7378179f8f40SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 7379179f8f40SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 7380179f8f40SJoe Perches WARN("CONSIDER_KSTRTO", 7381179f8f40SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 7382179f8f40SJoe Perches } 7383179f8f40SJoe Perches 7384179f8f40SJoe Perches# check for __initcall(), use device_initcall() explicitly or more appropriate function please 7385179f8f40SJoe Perches if ($line =~ /^.\s*__initcall\s*\(/) { 73864882720bSThomas Gleixner WARN("USE_DEVICE_INITCALL", 73874882720bSThomas Gleixner "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 7388000d1cc1SJoe Perches } 7389000d1cc1SJoe Perches 7390773647a0SAndy Whitcroft# check for spin_is_locked(), suggest lockdep instead 73916712d858SJoe Perches if ($line =~ /\bspin_is_locked\(/) { 739267d0a075SJoe Perches WARN("USE_LOCKDEP", 739367d0a075SJoe Perches "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 7394000d1cc1SJoe Perches } 739567d0a075SJoe Perches 7396773647a0SAndy Whitcroft# check for deprecated apis 73976712d858SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 7398ae3ccc46SFabian Frederick my $deprecated_api = $1; 7399f3db6639SMichael Ellerman my $new_api = $deprecated_apis{$deprecated_api}; 7400000d1cc1SJoe Perches WARN("DEPRECATED_API", 7401ae3ccc46SFabian Frederick "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 7402f3db6639SMichael Ellerman } 74036712d858SJoe Perches 74043d709ab5SPaul E. McKenney# check for various structs that are normally const (ops, kgdb, device_tree) 74053d709ab5SPaul E. McKenney# and avoid what seem like struct definitions 'struct foo {' 74063d709ab5SPaul E. McKenney if (defined($const_structs) && 74073d709ab5SPaul E. McKenney $line !~ /\bconst\b/ && 74083d709ab5SPaul E. McKenney $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 74093d709ab5SPaul E. McKenney WARN("CONST_STRUCT", 74109189c7e7SJoe Perches "struct $1 should normally be const\n" . $herecurr); 74119189c7e7SJoe Perches } 74129189c7e7SJoe Perches 74139189c7e7SJoe Perches# use of NR_CPUS is usually wrong 74149189c7e7SJoe Perches# ignore definitions of NR_CPUS and usage to define arrays as likely right 74159189c7e7SJoe Perches# ignore designated initializers using NR_CPUS 74169189c7e7SJoe Perches if ($line =~ /\bNR_CPUS\b/ && 74179189c7e7SJoe Perches $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 74180f3c5aabSJoe Perches $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 7419d9190e4eSJoe Perches $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 7420ced69da1SQuentin Monnet $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 7421ced69da1SQuentin Monnet $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ && 7422d9190e4eSJoe Perches $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/) 7423000d1cc1SJoe Perches { 7424d9190e4eSJoe Perches WARN("NR_CPUS", 74252b6db5cbSAndy Whitcroft "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 7426773647a0SAndy Whitcroft } 7427773647a0SAndy Whitcroft 7428773647a0SAndy Whitcroft# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 742935cdcbfcSPeng Wang if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 7430773647a0SAndy Whitcroft ERROR("DEFINE_ARCH_HAS", 7431c45dcabdSAndy Whitcroft "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 7432c45dcabdSAndy Whitcroft } 7433171ae1a4SAndy Whitcroft 7434171ae1a4SAndy Whitcroft# likely/unlikely comparisons similar to "(likely(foo) > 0)" 743535cdcbfcSPeng Wang if ($perl_version_ok && 743635cdcbfcSPeng Wang $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 7437773647a0SAndy Whitcroft WARN("LIKELY_MISUSE", 7438000d1cc1SJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 7439000d1cc1SJoe Perches } 7440773647a0SAndy Whitcroft 74419c9ba34eSAndy Whitcroft# return sysfs_emit(foo, fmt, ...) fmt without newline 744252ea8506SJoe Perches if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ && 744352ea8506SJoe Perches substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) { 744452ea8506SJoe Perches my $offset = $+[6] - 1; 744552ea8506SJoe Perches if (WARN("SYSFS_EMIT", 744652ea8506SJoe Perches "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) && 744752ea8506SJoe Perches $fix) { 7448acd9362cSJoe Perches substr($fixed[$fixlinenr], $offset, 0) = '\\n'; 74495b57980dSJoe Perches } 7450acd9362cSJoe Perches } 7451acd9362cSJoe Perches 7452acd9362cSJoe Perches# check for array definition/declarations that should use flexible arrays instead 7453acd9362cSJoe Perches if ($sline =~ /^[\+ ]\s*\}(?:\s*__packed)?\s*;\s*$/ && 7454acd9362cSJoe Perches $prevline =~ /^\+\s*(?:\}(?:\s*__packed\s*)?|$Type)\s*$Ident\s*\[\s*(0|1)\s*\]\s*;\s*$/) { 7455fbe74541SJoe Perches if (ERROR("FLEXIBLE_ARRAY", 7456fbe74541SJoe Perches "Use C99 flexible arrays - see https://docs.kernel.org/process/deprecated.html#zero-length-and-one-element-arrays\n" . $hereprev) && 7457fbe74541SJoe Perches $1 == '0' && $fix) { 7458fbe74541SJoe Perches $fixed[$fixlinenr - 1] =~ s/\[\s*0\s*\]/[]/; 7459fbe74541SJoe Perches } 7460fbe74541SJoe Perches } 7461fbe74541SJoe Perches 7462fbe74541SJoe Perches# nested likely/unlikely calls 7463fbe74541SJoe Perches if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 7464fbe74541SJoe Perches WARN("LIKELY_MISUSE", 7465fbe74541SJoe Perches "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 74668515e4a7SKees Cook } 74678515e4a7SKees Cook 74688515e4a7SKees Cook# whine mightly about in_atomic 74698515e4a7SKees Cook if ($line =~ /\bin_atomic\s*\(/) { 74708515e4a7SKees Cook if ($realfile =~ m@^drivers/@) { 74718515e4a7SKees Cook ERROR("IN_ATOMIC", 74728515e4a7SKees Cook "do not use in_atomic in drivers\n" . $herecurr); 74738515e4a7SKees Cook } elsif ($realfile !~ m@^kernel/@) { 74748515e4a7SKees Cook WARN("IN_ATOMIC", 74758515e4a7SKees Cook "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 7476de3f186fSDenis Efremov } 7477de3f186fSDenis Efremov } 7478de3f186fSDenis Efremov 7479de3f186fSDenis Efremov# Complain about RCU Tasks Trace used outside of BPF (and of course, RCU). 7480de3f186fSDenis Efremov our $rcu_trace_funcs = qr{(?x: 7481de3f186fSDenis Efremov rcu_read_lock_trace | 7482691d77b6SAndy Whitcroft rcu_read_lock_trace_held | 7483691d77b6SAndy Whitcroft rcu_read_unlock_trace | 7484691d77b6SAndy Whitcroft call_rcu_tasks_trace | 7485000d1cc1SJoe Perches synchronize_rcu_tasks_trace | 7486000d1cc1SJoe Perches rcu_barrier_tasks_trace | 7487f4a87736SAndy Whitcroft rcu_request_urgent_qs_task 7488000d1cc1SJoe Perches )}; 7489000d1cc1SJoe Perches our $rcu_trace_paths = qr{(?x: 7490691d77b6SAndy Whitcroft kernel/bpf/ | 7491691d77b6SAndy Whitcroft include/linux/bpf | 74921704f47bSPeter Zijlstra net/bpf/ | 749384dd7f19SPaul E. McKenney kernel/rcu/ | 749484dd7f19SPaul E. McKenney include/linux/rcu 749584dd7f19SPaul E. McKenney )}; 749684dd7f19SPaul E. McKenney if ($line =~ /\b($rcu_trace_funcs)\s*\(/) { 749784dd7f19SPaul E. McKenney if ($realfile !~ m{^$rcu_trace_paths}) { 749884dd7f19SPaul E. McKenney WARN("RCU_TASKS_TRACE", 749984dd7f19SPaul E. McKenney "use of RCU tasks trace is incorrect outside BPF or core RCU code\n" . $herecurr); 750084dd7f19SPaul E. McKenney } 750184dd7f19SPaul E. McKenney } 750284dd7f19SPaul E. McKenney 750384dd7f19SPaul E. McKenney# check for lockdep_set_novalidate_class 750484dd7f19SPaul E. McKenney if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 750584dd7f19SPaul E. McKenney $line =~ /__lockdep_no_validate__\s*\)/ ) { 750684dd7f19SPaul E. McKenney if ($realfile !~ m@^kernel/lockdep@ && 750784dd7f19SPaul E. McKenney $realfile !~ m@^include/linux/lockdep@ && 750884dd7f19SPaul E. McKenney $realfile !~ m@^drivers/base/core@) { 750984dd7f19SPaul E. McKenney ERROR("LOCKDEP", 751084dd7f19SPaul E. McKenney "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 751184dd7f19SPaul E. McKenney } 751284dd7f19SPaul E. McKenney } 751384dd7f19SPaul E. McKenney 751484dd7f19SPaul E. McKenney if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 751584dd7f19SPaul E. McKenney $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 751684dd7f19SPaul E. McKenney WARN("EXPORTED_WORLD_WRITABLE", 75171704f47bSPeter Zijlstra "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 75181704f47bSPeter Zijlstra } 75191704f47bSPeter Zijlstra 75201704f47bSPeter Zijlstra# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 75211704f47bSPeter Zijlstra# and whether or not function naming is typical and if 75221704f47bSPeter Zijlstra# DEVICE_ATTR permissions uses are unusual too 7523000d1cc1SJoe Perches if ($perl_version_ok && 7524000d1cc1SJoe Perches defined $stat && 75251704f47bSPeter Zijlstra $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*\)/) { 75261704f47bSPeter Zijlstra my $var = $1; 752788f8831cSDave Jones my $perms = $2; 7528b392c64fSJoe Perches my $show = $3; 7529b392c64fSJoe Perches my $store = $4; 7530000d1cc1SJoe Perches my $octal_perms = perms_to_octal($perms); 7531000d1cc1SJoe Perches if ($show =~ /^${var}_show$/ && 753288f8831cSDave Jones $store =~ /^${var}_store$/ && 75332435880fSJoe Perches $octal_perms eq "0644") { 753400180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 753500180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 753600180468SJoe Perches $fix) { 75375b57980dSJoe 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})/; 753800180468SJoe Perches } 753900180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 754000180468SJoe Perches $store =~ /^NULL$/ && 754100180468SJoe Perches $octal_perms eq "0444") { 754200180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 754300180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 754400180468SJoe Perches $fix) { 754500180468SJoe 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})/; 754600180468SJoe Perches } 754700180468SJoe Perches } elsif ($show =~ /^NULL$/ && 754800180468SJoe Perches $store =~ /^${var}_store$/ && 754900180468SJoe Perches $octal_perms eq "0200") { 755000180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 755100180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 755200180468SJoe Perches $fix) { 755300180468SJoe 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})/; 755400180468SJoe Perches } 755500180468SJoe Perches } elsif ($octal_perms eq "0644" || 755600180468SJoe Perches $octal_perms eq "0444" || 755700180468SJoe Perches $octal_perms eq "0200") { 755800180468SJoe Perches my $newshow = "$show"; 755900180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 756000180468SJoe Perches my $newstore = $store; 756100180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 756200180468SJoe Perches my $rename = ""; 756300180468SJoe Perches if ($show ne $newshow) { 756400180468SJoe Perches $rename .= " '$show' to '$newshow'"; 756500180468SJoe Perches } 756600180468SJoe Perches if ($store ne $newstore) { 756700180468SJoe Perches $rename .= " '$store' to '$newstore'"; 756800180468SJoe Perches } 756900180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 757000180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 757100180468SJoe Perches } else { 757200180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 757300180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 757400180468SJoe Perches } 757500180468SJoe Perches } 757600180468SJoe Perches 757700180468SJoe Perches# Mode permission misuses where it seems decimal should be octal 757800180468SJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 757900180468SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 758000180468SJoe Perches# specific definition of not visible in sysfs. 758100180468SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 758200180468SJoe Perches# use the default permissions 758300180468SJoe Perches if ($perl_version_ok && 758400180468SJoe Perches defined $stat && 758500180468SJoe Perches $line =~ /$mode_perms_search/) { 758600180468SJoe Perches foreach my $entry (@mode_permission_funcs) { 758700180468SJoe Perches my $func = $entry->[0]; 758800180468SJoe Perches my $arg_pos = $entry->[1]; 758900180468SJoe Perches 759000180468SJoe Perches my $lc = $stat =~ tr@\n@@; 7591515a235eSJoe Perches $lc = $lc + $linenr; 7592515a235eSJoe Perches my $stat_real = get_stat_real($linenr, $lc); 759373121534SJoe Perches 759473121534SJoe Perches my $skip_args = ""; 759573121534SJoe Perches if ($arg_pos > 1) { 759673121534SJoe Perches $arg_pos--; 75975b57980dSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 7598459cf0aeSJoe Perches } 7599515a235eSJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 76002435880fSJoe Perches if ($stat =~ /$test/) { 76012435880fSJoe Perches my $val = $1; 76022435880fSJoe Perches $val = $6 if ($skip_args ne ""); 76032435880fSJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 7604459cf0aeSJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 7605459cf0aeSJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 76062a9f9d85STobin C. Harding ERROR("NON_OCTAL_PERMISSIONS", 7607459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 76082435880fSJoe Perches } 76092435880fSJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 76102435880fSJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 76112435880fSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 76122435880fSJoe Perches } 7613f90774e1SJoe Perches } 7614459cf0aeSJoe Perches } 76152435880fSJoe Perches } 76162435880fSJoe Perches 761773121534SJoe Perches# check for uses of S_<PERMS> that could be octal for readability 761873121534SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 761973121534SJoe Perches my $oval = $1; 76202435880fSJoe Perches my $octal = perms_to_octal($oval); 7621459cf0aeSJoe Perches if (WARN("SYMBOLIC_PERMS", 7622f90774e1SJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 7623f90774e1SJoe Perches $fix) { 7624c0a5c898SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 7625459cf0aeSJoe Perches } 76262435880fSJoe Perches } 7627459cf0aeSJoe Perches 7628459cf0aeSJoe Perches# validate content of MODULE_LICENSE against list from include/linux/module.h 7629459cf0aeSJoe Perches if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 7630459cf0aeSJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 7631459cf0aeSJoe Perches my $valid_licenses = qr{ 7632bc22d9a7SJoe Perches GPL| 763300180468SJoe Perches GPL\ v2| 763400180468SJoe Perches GPL\ and\ additional\ rights| 7635f90774e1SJoe Perches Dual\ BSD/GPL| 7636459cf0aeSJoe Perches Dual\ MIT/GPL| 7637f90774e1SJoe Perches Dual\ MPL/GPL| 763800180468SJoe Perches Proprietary 76392435880fSJoe Perches }x; 764013214adfSAndy Whitcroft if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 76415a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 76425a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 76435a6d20ceSBjorn Andersson } 76445a6d20ceSBjorn Andersson if (!$file && $extracted_string eq '"GPL v2"') { 76455a6d20ceSBjorn Andersson if (WARN("MODULE_LICENSE", 76465a6d20ceSBjorn Andersson "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) && 76475a6d20ceSBjorn Andersson $fix) { 76485a6d20ceSBjorn Andersson $fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/; 76495a6d20ceSBjorn Andersson } 76505a6d20ceSBjorn Andersson } 76515a6d20ceSBjorn Andersson } 76525a6d20ceSBjorn Andersson 76535a6d20ceSBjorn Andersson# check for sysctl duplicate constants 76545a6d20ceSBjorn Andersson if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 76555a6d20ceSBjorn Andersson WARN("DUPLICATED_SYSCTL_CONST", 76565a6d20ceSBjorn Andersson "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 76575a6d20ceSBjorn Andersson } 76586e8f42dcSJoe Perches } 76596e8f42dcSJoe Perches 76606e8f42dcSJoe Perches # If we have no input at all, then there is nothing to report on 76616e8f42dcSJoe Perches # so just keep quiet. 76626e8f42dcSJoe Perches if ($#rawlines == -1) { 76636e8f42dcSJoe Perches exit(0); 76646e8f42dcSJoe Perches } 76655a6d20ceSBjorn Andersson 76666a8d76cbSMatteo Croce # In mailback mode only produce a report in the negative, for 76676a8d76cbSMatteo Croce # things that appear to be patches. 76686a8d76cbSMatteo Croce if ($mailback && ($clean == 1 || !$is_patch)) { 76696a8d76cbSMatteo Croce exit(0); 76706a8d76cbSMatteo Croce } 76716a8d76cbSMatteo Croce 7672515a235eSJoe Perches # This is not a patch, and we are in 'no-patch' mode so 767313214adfSAndy Whitcroft # just keep quiet. 767413214adfSAndy Whitcroft if (!$chk_patch && !$is_patch) { 767513214adfSAndy Whitcroft exit(0); 767613214adfSAndy Whitcroft } 767713214adfSAndy Whitcroft 76780a920b5bSAndy Whitcroft if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 76790a920b5bSAndy Whitcroft ERROR("NOT_UNIFIED_DIFF", 76808905a67cSAndy Whitcroft "Does not appear to be a unified-diff format patch\n"); 76818905a67cSAndy Whitcroft } 76828905a67cSAndy Whitcroft if ($is_patch && $has_commit_log && $chk_fixes_tag) { 76838905a67cSAndy Whitcroft if ($needs_fixes_tag ne "" && !$is_revert && !$fixes_tag) { 76848905a67cSAndy Whitcroft WARN("MISSING_FIXES_TAG", 76858905a67cSAndy Whitcroft "The commit message has '$needs_fixes_tag', perhaps it also needs a 'Fixes:' tag?\n"); 7686e73d2715SDwaipayan Ray } 76878905a67cSAndy Whitcroft } 76888905a67cSAndy Whitcroft if ($is_patch && $has_commit_log && $chk_signoff) { 76898905a67cSAndy Whitcroft if ($signoff == 0) { 76908905a67cSAndy Whitcroft ERROR("MISSING_SIGN_OFF", 76918905a67cSAndy Whitcroft "Missing Signed-off-by: line(s)\n"); 7692a08ffbefSStafford Horne } elsif ($authorsignoff != 1) { 7693000d1cc1SJoe Perches # authorsignoff values: 7694000d1cc1SJoe Perches # 0 -> missing sign off 76950a920b5bSAndy Whitcroft # 1 -> sign off identical 7696d5d6281aSDan Carpenter # 2 -> names and addresses match, comments mismatch 7697d5d6281aSDan Carpenter # 3 -> addresses match, names different 7698d5d6281aSDan Carpenter # 4 -> names match, addresses different 7699d5d6281aSDan Carpenter # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match 7700d5d6281aSDan Carpenter 7701d5d6281aSDan Carpenter my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; 7702cd261496SGeert Uytterhoeven 7703cd261496SGeert Uytterhoeven if ($authorsignoff == 0) { 7704000d1cc1SJoe Perches ERROR("NO_AUTHOR_SIGN_OFF", 7705000d1cc1SJoe Perches "Missing Signed-off-by: line by nominal patch author '$author'\n"); 770648ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 2) { 770748ca2d8aSDwaipayan Ray CHK("FROM_SIGN_OFF_MISMATCH", 770848ca2d8aSDwaipayan Ray "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); 770948ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 3) { 771048ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 771148ca2d8aSDwaipayan Ray "From:/Signed-off-by: email name mismatch: $sob_msg\n"); 771248ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 4) { 771348ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 771448ca2d8aSDwaipayan Ray "From:/Signed-off-by: email address mismatch: $sob_msg\n"); 771548ca2d8aSDwaipayan Ray } elsif ($authorsignoff == 5) { 771648ca2d8aSDwaipayan Ray WARN("FROM_SIGN_OFF_MISMATCH", 771748ca2d8aSDwaipayan Ray "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); 771848ca2d8aSDwaipayan Ray } 7719cd261496SGeert Uytterhoeven } 772048ca2d8aSDwaipayan Ray } 772148ca2d8aSDwaipayan Ray 772248ca2d8aSDwaipayan Ray print report_dump(); 772348ca2d8aSDwaipayan Ray if ($summary && !($clean == 1 && $quiet == 1)) { 772448ca2d8aSDwaipayan Ray print "$filename " if ($summary_file); 772548ca2d8aSDwaipayan Ray print "total: $cnt_error errors, $cnt_warn warnings, " . 772648ca2d8aSDwaipayan Ray (($check)? "$cnt_chk checks, " : "") . 772748ca2d8aSDwaipayan Ray "$cnt_lines lines checked\n"; 772848ca2d8aSDwaipayan Ray } 772948ca2d8aSDwaipayan Ray 773048ca2d8aSDwaipayan Ray if ($quiet == 0) { 773148ca2d8aSDwaipayan Ray # If there were any defects found and not already fixing them 773248ca2d8aSDwaipayan Ray if (!$clean and !$fix) { 7733cd261496SGeert Uytterhoeven print << "EOM" 77340a920b5bSAndy Whitcroft 77350a920b5bSAndy WhitcroftNOTE: For some of the reported defects, checkpatch may be able to 7736f0a594c1SAndy Whitcroft mechanically convert to the typical style using --fix or --fix-inplace. 773713214adfSAndy WhitcroftEOM 773813214adfSAndy Whitcroft } 77396c72ffaaSAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 77406c72ffaaSAndy Whitcroft # then suggest that. 77416c72ffaaSAndy Whitcroft if ($rpt_cleaners) { 77426c72ffaaSAndy Whitcroft $rpt_cleaners = 0; 77438905a67cSAndy Whitcroft print << "EOM" 7744d2c0a235SAndy Whitcroft 7745ef212196SJoe PerchesNOTE: Whitespace errors detected. 7746ef212196SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 7747ef212196SJoe PerchesEOM 7748ef212196SJoe Perches } 7749ef212196SJoe Perches } 7750ef212196SJoe Perches 7751ef212196SJoe Perches if ($clean == 0 && $fix && 7752ef212196SJoe Perches ("@rawlines" ne "@fixed" || 7753d2c0a235SAndy Whitcroft $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 7754d2c0a235SAndy Whitcroft my $newfile = $filename; 7755d2c0a235SAndy Whitcroft $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 7756b0781216SMike Frysinger my $linecount = 0; 7757d8469f16SJoe Perches my $f; 7758d8469f16SJoe Perches 7759d8469f16SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 7760d8469f16SJoe Perches 7761d8469f16SJoe Perches open($f, '>', $newfile) 7762d2c0a235SAndy Whitcroft or die "$P: Can't open $newfile for write\n"; 7763d2c0a235SAndy Whitcroft foreach my $fixed_line (@fixed) { 7764d2c0a235SAndy Whitcroft $linecount++; 7765d752fcc8SJoe Perches if ($file) { 7766d752fcc8SJoe Perches if ($linecount > 3) { 7767d752fcc8SJoe Perches $fixed_line =~ s/^\+//; 77689624b8d6SJoe Perches print $f $fixed_line . "\n"; 77699624b8d6SJoe Perches } 77703705ce5bSJoe Perches } else { 77713705ce5bSJoe Perches print $f $fixed_line . "\n"; 77723705ce5bSJoe Perches } 7773d752fcc8SJoe Perches } 7774d752fcc8SJoe Perches close($f); 77753705ce5bSJoe Perches 77763705ce5bSJoe Perches if (!$quiet) { 77773705ce5bSJoe Perches print << "EOM"; 77783705ce5bSJoe Perches 77793705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 77803705ce5bSJoe Perches 77813705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 77823705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 77833705ce5bSJoe Perches 77843705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 77853705ce5bSJoe PerchesNo warranties, expressed or implied... 77863705ce5bSJoe PerchesEOM 77873705ce5bSJoe Perches } 77883705ce5bSJoe Perches } 77893705ce5bSJoe Perches 77903705ce5bSJoe Perches if ($quiet == 0) { 77913705ce5bSJoe Perches print "\n"; 7792d8469f16SJoe Perches if ($clean == 1) { 77933705ce5bSJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 77943705ce5bSJoe Perches } else { 77953705ce5bSJoe Perches print "$vname has style problems, please review.\n"; 77963705ce5bSJoe Perches } 77973705ce5bSJoe Perches } 77983705ce5bSJoe Perches return $clean; 77993705ce5bSJoe Perches} 78003705ce5bSJoe Perches