1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl 2882ea1d6SJoe Perches# SPDX-License-Identifier: GPL-2.0 3882ea1d6SJoe Perches# 4dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit) 500df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 62a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite) 7015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]> 8882ea1d6SJoe Perches# (c) 2010-2018 Joe Perches <[email protected]> 90a920b5bSAndy Whitcroft 100a920b5bSAndy Whitcroftuse strict; 11cb77f0d6SKamil Rytarowskiuse warnings; 12c707a81dSJoe Perchesuse POSIX; 1336061e38SJoe Perchesuse File::Basename; 1436061e38SJoe Perchesuse Cwd 'abs_path'; 1557230297SJoe Perchesuse Term::ANSIColor qw(:constants); 16cd261496SGeert Uytterhoevenuse Encode qw(decode encode); 170a920b5bSAndy Whitcroft 180a920b5bSAndy Whitcroftmy $P = $0; 1936061e38SJoe Perchesmy $D = dirname(abs_path($P)); 200a920b5bSAndy Whitcroft 21000d1cc1SJoe Perchesmy $V = '0.32'; 220a920b5bSAndy Whitcroft 230a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 240a920b5bSAndy Whitcroft 250a920b5bSAndy Whitcroftmy $quiet = 0; 260a920b5bSAndy Whitcroftmy $tree = 1; 270a920b5bSAndy Whitcroftmy $chk_signoff = 1; 280a920b5bSAndy Whitcroftmy $chk_patch = 1; 29773647a0SAndy Whitcroftmy $tst_only; 306c72ffaaSAndy Whitcroftmy $emacs = 0; 318905a67cSAndy Whitcroftmy $terse = 0; 3234d8815fSJoe Perchesmy $showfile = 0; 336c72ffaaSAndy Whitcroftmy $file = 0; 344a593c34SDu, Changbinmy $git = 0; 350dea9f1eSJoe Perchesmy %git_commits = (); 366c72ffaaSAndy Whitcroftmy $check = 0; 372ac73b4fSJoe Perchesmy $check_orig = 0; 388905a67cSAndy Whitcroftmy $summary = 1; 398905a67cSAndy Whitcroftmy $mailback = 0; 4013214adfSAndy Whitcroftmy $summary_file = 0; 41000d1cc1SJoe Perchesmy $show_types = 0; 423beb42ecSJoe Perchesmy $list_types = 0; 433705ce5bSJoe Perchesmy $fix = 0; 449624b8d6SJoe Perchesmy $fix_inplace = 0; 456c72ffaaSAndy Whitcroftmy $root; 46c2fdda0dSAndy Whitcroftmy %debug; 473445686aSJoe Perchesmy %camelcase = (); 4891bfe484SJoe Perchesmy %use_type = (); 4991bfe484SJoe Perchesmy @use = (); 5091bfe484SJoe Perchesmy %ignore_type = (); 51000d1cc1SJoe Perchesmy @ignore = (); 5277f5b10aSHannes Edermy $help = 0; 53000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 54*bdc48fa1SJoe Perchesmy $max_line_length = 100; 55d62a201fSDave Hansenmy $ignore_perl_version = 0; 56d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 5756193274SVadim Bendeburymy $min_conf_desc_length = 4; 5866b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 59ebfd7d62SJoe Perchesmy $codespell = 0; 60f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt"; 61bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 6275ad8c57SJerome Forissiermy $typedefsfile = ""; 63737c0767SJohn Brooksmy $color = "auto"; 6498005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE 65dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE 66dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git'; 67713a09deSAntonio Borneomy $tabsize = 8; 6877f5b10aSHannes Eder 6977f5b10aSHannes Edersub help { 7077f5b10aSHannes Eder my ($exitcode) = @_; 7177f5b10aSHannes Eder 7277f5b10aSHannes Eder print << "EOM"; 7377f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 7477f5b10aSHannes EderVersion: $V 7577f5b10aSHannes Eder 7677f5b10aSHannes EderOptions: 7777f5b10aSHannes Eder -q, --quiet quiet 7877f5b10aSHannes Eder --no-tree run without a kernel tree 7977f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 8077f5b10aSHannes Eder --patch treat FILE as patchfile (default) 8177f5b10aSHannes Eder --emacs emacs compile window format 8277f5b10aSHannes Eder --terse one line per report 8334d8815fSJoe Perches --showfile emit diffed file position, not input file position 844a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 854a593c34SDu, Changbin single git commit with: 864a593c34SDu, Changbin <rev> 874a593c34SDu, Changbin <rev>^ 884a593c34SDu, Changbin <rev>~n 894a593c34SDu, Changbin multiple git commits with: 904a593c34SDu, Changbin <rev1>..<rev2> 914a593c34SDu, Changbin <rev1>...<rev2> 924a593c34SDu, Changbin <rev>-<count> 934a593c34SDu, Changbin git merges are ignored 9477f5b10aSHannes Eder -f, --file treat FILE as regular source file 9577f5b10aSHannes Eder --subjective, --strict enable more subjective tests 963beb42ecSJoe Perches --list-types list the possible message types 9791bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 98000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 993beb42ecSJoe Perches --show-types show the specific message type in the output 100*bdc48fa1SJoe Perches --max-line-length=n set the maximum line length, (default $max_line_length) 101*bdc48fa1SJoe Perches if exceeded, warn on patches 102*bdc48fa1SJoe Perches requires --strict for use with --file 10356193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 104*bdc48fa1SJoe Perches --tab-size=n set the number of spaces for tab (default $tabsize) 10577f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 10677f5b10aSHannes Eder --no-summary suppress the per-file summary 10777f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 10877f5b10aSHannes Eder --summary-file include the filename in summary 10977f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 11077f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 11177f5b10aSHannes Eder is all off) 11277f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 11377f5b10aSHannes Eder literally 1143705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1153705ce5bSJoe Perches If correctable single-line errors exist, create 1163705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1173705ce5bSJoe Perches with potential errors corrected to the preferred 1183705ce5bSJoe Perches checkpatch style 1199624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1209624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1219624b8d6SJoe Perches file. It's your fault if there's no backup or git 122d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 123d62a201fSDave Hansen runtime errors. 124ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 125f1a63678SMaxim Uvarov (default:/usr/share/codespell/dictionary.txt) 126ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 12775ad8c57SJerome Forissier --typedefsfile Read additional types from this file 128737c0767SJohn Brooks --color[=WHEN] Use colors 'always', 'never', or only when output 129737c0767SJohn Brooks is a terminal ('auto'). Default is 'auto'. 13077f5b10aSHannes Eder -h, --help, --version display this help and exit 13177f5b10aSHannes Eder 13277f5b10aSHannes EderWhen FILE is - read standard input. 13377f5b10aSHannes EderEOM 13477f5b10aSHannes Eder 13577f5b10aSHannes Eder exit($exitcode); 13677f5b10aSHannes Eder} 13777f5b10aSHannes Eder 1383beb42ecSJoe Perchessub uniq { 1393beb42ecSJoe Perches my %seen; 1403beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1413beb42ecSJoe Perches} 1423beb42ecSJoe Perches 1433beb42ecSJoe Perchessub list_types { 1443beb42ecSJoe Perches my ($exitcode) = @_; 1453beb42ecSJoe Perches 1463beb42ecSJoe Perches my $count = 0; 1473beb42ecSJoe Perches 1483beb42ecSJoe Perches local $/ = undef; 1493beb42ecSJoe Perches 1503beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1513beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1523beb42ecSJoe Perches 1533beb42ecSJoe Perches my $text = <$script>; 1543beb42ecSJoe Perches close($script); 1553beb42ecSJoe Perches 1563beb42ecSJoe Perches my @types = (); 1570547fa58SJean Delvare # Also catch when type or level is passed through a variable 1580547fa58SJean Delvare for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { 1593beb42ecSJoe Perches push (@types, $_); 1603beb42ecSJoe Perches } 1613beb42ecSJoe Perches @types = sort(uniq(@types)); 1623beb42ecSJoe Perches print("#\tMessage type\n\n"); 1633beb42ecSJoe Perches foreach my $type (@types) { 1643beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 1653beb42ecSJoe Perches } 1663beb42ecSJoe Perches 1673beb42ecSJoe Perches exit($exitcode); 1683beb42ecSJoe Perches} 1693beb42ecSJoe Perches 170000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 171000d1cc1SJoe Perchesif (-f $conf) { 172000d1cc1SJoe Perches my @conf_args; 173000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 174000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 175000d1cc1SJoe Perches 176000d1cc1SJoe Perches while (<$conffile>) { 177000d1cc1SJoe Perches my $line = $_; 178000d1cc1SJoe Perches 179000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 180000d1cc1SJoe Perches $line =~ s/^\s*//g; 181000d1cc1SJoe Perches $line =~ s/\s+/ /g; 182000d1cc1SJoe Perches 183000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 184000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 185000d1cc1SJoe Perches 186000d1cc1SJoe Perches my @words = split(" ", $line); 187000d1cc1SJoe Perches foreach my $word (@words) { 188000d1cc1SJoe Perches last if ($word =~ m/^#/); 189000d1cc1SJoe Perches push (@conf_args, $word); 190000d1cc1SJoe Perches } 191000d1cc1SJoe Perches } 192000d1cc1SJoe Perches close($conffile); 193000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 194000d1cc1SJoe Perches} 195000d1cc1SJoe Perches 196737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space. 197737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments 198737c0767SJohn Brooksforeach (@ARGV) { 199737c0767SJohn Brooks if ($_ eq "--color" || $_ eq "-color") { 200737c0767SJohn Brooks $_ = "--color=$color"; 201737c0767SJohn Brooks } 202737c0767SJohn Brooks} 203737c0767SJohn Brooks 2040a920b5bSAndy WhitcroftGetOptions( 2056c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 2060a920b5bSAndy Whitcroft 'tree!' => \$tree, 2070a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 2080a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 2096c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 2108905a67cSAndy Whitcroft 'terse!' => \$terse, 21134d8815fSJoe Perches 'showfile!' => \$showfile, 21277f5b10aSHannes Eder 'f|file!' => \$file, 2134a593c34SDu, Changbin 'g|git!' => \$git, 2146c72ffaaSAndy Whitcroft 'subjective!' => \$check, 2156c72ffaaSAndy Whitcroft 'strict!' => \$check, 216000d1cc1SJoe Perches 'ignore=s' => \@ignore, 21791bfe484SJoe Perches 'types=s' => \@use, 218000d1cc1SJoe Perches 'show-types!' => \$show_types, 2193beb42ecSJoe Perches 'list-types!' => \$list_types, 2206cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 22156193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 222713a09deSAntonio Borneo 'tab-size=i' => \$tabsize, 2236c72ffaaSAndy Whitcroft 'root=s' => \$root, 2248905a67cSAndy Whitcroft 'summary!' => \$summary, 2258905a67cSAndy Whitcroft 'mailback!' => \$mailback, 22613214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 2273705ce5bSJoe Perches 'fix!' => \$fix, 2289624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 229d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 230c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 231773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 232ebfd7d62SJoe Perches 'codespell!' => \$codespell, 233ebfd7d62SJoe Perches 'codespellfile=s' => \$codespellfile, 23475ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 235737c0767SJohn Brooks 'color=s' => \$color, 236737c0767SJohn Brooks 'no-color' => \$color, #keep old behaviors of -nocolor 237737c0767SJohn Brooks 'nocolor' => \$color, #keep old behaviors of -nocolor 23877f5b10aSHannes Eder 'h|help' => \$help, 23977f5b10aSHannes Eder 'version' => \$help 24077f5b10aSHannes Eder) or help(1); 24177f5b10aSHannes Eder 24277f5b10aSHannes Ederhelp(0) if ($help); 2430a920b5bSAndy Whitcroft 2443beb42ecSJoe Percheslist_types(0) if ($list_types); 2453beb42ecSJoe Perches 2469624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 2472ac73b4fSJoe Perches$check_orig = $check; 2489624b8d6SJoe Perches 2490a920b5bSAndy Whitcroftmy $exit = 0; 2500a920b5bSAndy Whitcroft 2515b57980dSJoe Perchesmy $perl_version_ok = 1; 252d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 2535b57980dSJoe Perches $perl_version_ok = 0; 254d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 2555b57980dSJoe Perches exit(1) if (!$ignore_perl_version); 256d62a201fSDave Hansen} 257d62a201fSDave Hansen 25845107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 2590a920b5bSAndy Whitcroftif ($#ARGV < 0) { 26045107ff6SAllen Hubbe push(@ARGV, '-'); 2610a920b5bSAndy Whitcroft} 2620a920b5bSAndy Whitcroft 263737c0767SJohn Brooksif ($color =~ /^[01]$/) { 264737c0767SJohn Brooks $color = !$color; 265737c0767SJohn Brooks} elsif ($color =~ /^always$/i) { 266737c0767SJohn Brooks $color = 1; 267737c0767SJohn Brooks} elsif ($color =~ /^never$/i) { 268737c0767SJohn Brooks $color = 0; 269737c0767SJohn Brooks} elsif ($color =~ /^auto$/i) { 270737c0767SJohn Brooks $color = (-t STDOUT); 271737c0767SJohn Brooks} else { 272737c0767SJohn Brooks die "Invalid color mode: $color\n"; 273737c0767SJohn Brooks} 274737c0767SJohn Brooks 275713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1 276713a09deSAntonio Borneodie "Invalid TAB size: $tabsize\n" if ($tabsize < 2); 277713a09deSAntonio Borneo 27891bfe484SJoe Perchessub hash_save_array_words { 27991bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 28091bfe484SJoe Perches 28191bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 28291bfe484SJoe Perches foreach my $word (@array) { 283000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 284000d1cc1SJoe Perches $word =~ s/^\s*//g; 285000d1cc1SJoe Perches $word =~ s/\s+/ /g; 286000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 287000d1cc1SJoe Perches 288000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 289000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 290000d1cc1SJoe Perches 29191bfe484SJoe Perches $hashRef->{$word}++; 292000d1cc1SJoe Perches } 29391bfe484SJoe Perches} 29491bfe484SJoe Perches 29591bfe484SJoe Perchessub hash_show_words { 29691bfe484SJoe Perches my ($hashRef, $prefix) = @_; 29791bfe484SJoe Perches 2983c816e49SJoe Perches if (keys %$hashRef) { 299d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 30058cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 30191bfe484SJoe Perches print " $word"; 30291bfe484SJoe Perches } 303d8469f16SJoe Perches print "\n"; 30491bfe484SJoe Perches } 30591bfe484SJoe Perches} 30691bfe484SJoe Perches 30791bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 30891bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 309000d1cc1SJoe Perches 310c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 311c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 3127429c690SAndy Whitcroftmy $dbg_type = 0; 313a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 314c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 31521caa13cSAndy Whitcroft ## no critic 31621caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 31721caa13cSAndy Whitcroft die "$@" if ($@); 318c2fdda0dSAndy Whitcroft} 319c2fdda0dSAndy Whitcroft 320d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 321d2c0a235SAndy Whitcroft 3228905a67cSAndy Whitcroftif ($terse) { 3238905a67cSAndy Whitcroft $emacs = 1; 3248905a67cSAndy Whitcroft $quiet++; 3258905a67cSAndy Whitcroft} 3268905a67cSAndy Whitcroft 3276c72ffaaSAndy Whitcroftif ($tree) { 3286c72ffaaSAndy Whitcroft if (defined $root) { 3296c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 3306c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 3316c72ffaaSAndy Whitcroft } 3326c72ffaaSAndy Whitcroft } else { 3336c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 3346c72ffaaSAndy Whitcroft $root = '.'; 3356c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 3366c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 3376c72ffaaSAndy Whitcroft $root = $1; 3386c72ffaaSAndy Whitcroft } 3396c72ffaaSAndy Whitcroft } 3406c72ffaaSAndy Whitcroft 3416c72ffaaSAndy Whitcroft if (!defined $root) { 3420a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 3430a920b5bSAndy Whitcroft exit(2); 3440a920b5bSAndy Whitcroft } 3456c72ffaaSAndy Whitcroft} 3466c72ffaaSAndy Whitcroft 3476c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 3486c72ffaaSAndy Whitcroft 3492ceb532bSAndy Whitcroftour $Ident = qr{ 3502ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 3512ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 3522ceb532bSAndy Whitcroft }x; 3536c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 3546c72ffaaSAndy Whitcroftour $Sparse = qr{ 3556c72ffaaSAndy Whitcroft __user| 3566c72ffaaSAndy Whitcroft __kernel| 3576c72ffaaSAndy Whitcroft __force| 3586c72ffaaSAndy Whitcroft __iomem| 3596c72ffaaSAndy Whitcroft __must_check| 360417495edSAndy Whitcroft __kprobes| 361165e72a6SSven Eckelmann __ref| 36233aa4597SGeert Uytterhoeven __refconst| 36333aa4597SGeert Uytterhoeven __refdata| 364ad315455SBoqun Feng __rcu| 365ad315455SBoqun Feng __private 3666c72ffaaSAndy Whitcroft }x; 367e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 368e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 369e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 370e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 371e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 3728716de38SJoe Perches 37352131292SWolfram Sang# Notes to $Attribute: 37452131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 3756c72ffaaSAndy Whitcroftour $Attribute = qr{ 3766c72ffaaSAndy Whitcroft const| 37703f1df7dSJoe Perches __percpu| 37803f1df7dSJoe Perches __nocast| 37903f1df7dSJoe Perches __safe| 38046d832f5SMichael S. Tsirkin __bitwise| 38103f1df7dSJoe Perches __packed__| 38203f1df7dSJoe Perches __packed2__| 38303f1df7dSJoe Perches __naked| 38403f1df7dSJoe Perches __maybe_unused| 38503f1df7dSJoe Perches __always_unused| 38603f1df7dSJoe Perches __noreturn| 38703f1df7dSJoe Perches __used| 38803f1df7dSJoe Perches __cold| 389e23ef1f3SJoe Perches __pure| 39003f1df7dSJoe Perches __noclone| 39103f1df7dSJoe Perches __deprecated| 3926c72ffaaSAndy Whitcroft __read_mostly| 393c5967e98SJoe Perches __ro_after_init| 3946c72ffaaSAndy Whitcroft __kprobes| 3958716de38SJoe Perches $InitAttribute| 39624e1d81aSAndy Whitcroft ____cacheline_aligned| 39724e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 3985fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 3995fe3af11SAndy Whitcroft __weak 4006c72ffaaSAndy Whitcroft }x; 401c45dcabdSAndy Whitcroftour $Modifier; 40291cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 4036c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 4046c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 4056c72ffaaSAndy Whitcroft 40695e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 40795e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 40895e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 40995e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 4102435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 411c0a5c898SJoe Perchesour $String = qr{"[X\t]*"}; 412326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 413326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 414326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 41574349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 4162435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 417326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 418447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 41923f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 4206c72ffaaSAndy Whitcroftour $Operators = qr{ 4216c72ffaaSAndy Whitcroft <=|>=|==|!=| 4226c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 42323f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 4246c72ffaaSAndy Whitcroft }x; 4256c72ffaaSAndy Whitcroft 42691cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 42791cb5195SJoe Perches 428ab7e23f3SJoe Perchesour $BasicType; 4298905a67cSAndy Whitcroftour $NonptrType; 4301813087dSJoe Perchesour $NonptrTypeMisordered; 4318716de38SJoe Perchesour $NonptrTypeWithAttr; 4328905a67cSAndy Whitcroftour $Type; 4331813087dSJoe Perchesour $TypeMisordered; 4348905a67cSAndy Whitcroftour $Declare; 4351813087dSJoe Perchesour $DeclareMisordered; 4368905a67cSAndy Whitcroft 43715662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 43815662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 439171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 440171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 441171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 442171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 443171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 444171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 445171ae1a4SAndy Whitcroft}x; 446171ae1a4SAndy Whitcroft 44715662b3eSJoe Perchesour $UTF8 = qr{ 44815662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 44915662b3eSJoe Perches | $NON_ASCII_UTF8 45015662b3eSJoe Perches}x; 45115662b3eSJoe Perches 452e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 453021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 454021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 455021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 456021158b4SJoe Perches)}; 457e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 458fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 4598ed22cadSAndy Whitcroft atomic_t 4608ed22cadSAndy Whitcroft)}; 461e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 462e6176fa4SJoe Perches $typeC99Typedefs\b| 463e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 464e6176fa4SJoe Perches $typeKernelTypedefs\b 465e6176fa4SJoe Perches)}; 4668ed22cadSAndy Whitcroft 4676d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 4686d32f7a3SJoe Perches 469691e669bSJoe Perchesour $logFunctions = qr{(?x: 470758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 4717d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 47287bd499aSJoe Perches TP_printk| 4736e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 474b0531722SJoe Perches panic| 47506668727SJoe Perches MODULE_[A-Z_]+| 47606668727SJoe Perches seq_vprintf|seq_printf|seq_puts 477691e669bSJoe Perches)}; 478691e669bSJoe Perches 479e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 480e29a70f1SJoe Perches (?:(?:devm_)? 481e29a70f1SJoe Perches (?:kv|k|v)[czm]alloc(?:_node|_array)? | 482e29a70f1SJoe Perches kstrdup(?:_const)? | 483e29a70f1SJoe Perches kmemdup(?:_nul)?) | 484461e1565SChristophe JAILLET (?:\w+)?alloc_skb(?:_ip_align)? | 485e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 486e29a70f1SJoe Perches dma_alloc_coherent 487e29a70f1SJoe Perches)}; 488e29a70f1SJoe Perches 48920112475SJoe Perchesour $signature_tags = qr{(?xi: 49020112475SJoe Perches Signed-off-by:| 491d499480cSJorge Ramirez-Ortiz Co-developed-by:| 49220112475SJoe Perches Acked-by:| 49320112475SJoe Perches Tested-by:| 49420112475SJoe Perches Reviewed-by:| 49520112475SJoe Perches Reported-by:| 4968543ae12SMugunthan V N Suggested-by:| 49720112475SJoe Perches To:| 49820112475SJoe Perches Cc: 49920112475SJoe Perches)}; 50020112475SJoe Perches 5011813087dSJoe Perchesour @typeListMisordered = ( 5021813087dSJoe Perches qr{char\s+(?:un)?signed}, 5031813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 5041813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 5051813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 5061813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 5071813087dSJoe Perches qr{short\s+(?:un)?signed}, 5081813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 5091813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 5101813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 5111813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 5121813087dSJoe Perches qr{int\s+(?:un)?signed}, 5131813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 5141813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 5151813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 5161813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 5171813087dSJoe Perches qr{long\s+(?:un)?signed}, 5181813087dSJoe Perches); 5191813087dSJoe Perches 5208905a67cSAndy Whitcroftour @typeList = ( 5218905a67cSAndy Whitcroft qr{void}, 5220c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 5230c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 5240c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 5250c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 5260c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 5270c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 5280c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 5290c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 5300c773d9dSJoe Perches qr{(?:un)?signed}, 5318905a67cSAndy Whitcroft qr{float}, 5328905a67cSAndy Whitcroft qr{double}, 5338905a67cSAndy Whitcroft qr{bool}, 5348905a67cSAndy Whitcroft qr{struct\s+$Ident}, 5358905a67cSAndy Whitcroft qr{union\s+$Ident}, 5368905a67cSAndy Whitcroft qr{enum\s+$Ident}, 5378905a67cSAndy Whitcroft qr{${Ident}_t}, 5388905a67cSAndy Whitcroft qr{${Ident}_handler}, 5398905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 5401813087dSJoe Perches @typeListMisordered, 5418905a67cSAndy Whitcroft); 542938224b5SJoe Perches 543938224b5SJoe Perchesour $C90_int_types = qr{(?x: 544938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 545938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 546938224b5SJoe Perches long\s+long\s+(?:un)?signed| 547938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 548938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 549938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 550938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 551938224b5SJoe Perches 552938224b5SJoe Perches long\s+int\s+(?:un)?signed| 553938224b5SJoe Perches long\s+(?:un)?signed\s+int| 554938224b5SJoe Perches long\s+(?:un)?signed| 555938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 556938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 557938224b5SJoe Perches int\s+long\s+(?:un)?signed| 558938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 559938224b5SJoe Perches 560938224b5SJoe Perches int\s+(?:un)?signed| 561938224b5SJoe Perches (?:(?:un)?signed\s+)?int 562938224b5SJoe Perches)}; 563938224b5SJoe Perches 564485ff23eSAlex Dowadour @typeListFile = (); 5658716de38SJoe Perchesour @typeListWithAttr = ( 5668716de38SJoe Perches @typeList, 5678716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 5688716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 5698716de38SJoe Perches); 5708716de38SJoe Perches 571c45dcabdSAndy Whitcroftour @modifierList = ( 572c45dcabdSAndy Whitcroft qr{fastcall}, 573c45dcabdSAndy Whitcroft); 574485ff23eSAlex Dowadour @modifierListFile = (); 5758905a67cSAndy Whitcroft 5762435880fSJoe Perchesour @mode_permission_funcs = ( 5772435880fSJoe Perches ["module_param", 3], 5782435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 5792435880fSJoe Perches ["module_param_array_named", 5], 5802435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 5812435880fSJoe Perches ["proc_create(?:_data|)", 2], 582459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 583459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 584459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 585459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 586459cf0aeSJoe Perches ["__ATTR", 2], 5872435880fSJoe Perches); 5882435880fSJoe Perches 589515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 590515a235eSJoe Perchesour $mode_perms_search = ""; 591515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 592515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 593515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 594515a235eSJoe Perches} 59500180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 596515a235eSJoe Perches 5979189c7e7SJoe Perchesour %deprecated_apis = ( 5989189c7e7SJoe Perches "synchronize_rcu_bh" => "synchronize_rcu", 5999189c7e7SJoe Perches "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 6009189c7e7SJoe Perches "call_rcu_bh" => "call_rcu", 6019189c7e7SJoe Perches "rcu_barrier_bh" => "rcu_barrier", 6029189c7e7SJoe Perches "synchronize_sched" => "synchronize_rcu", 6039189c7e7SJoe Perches "synchronize_sched_expedited" => "synchronize_rcu_expedited", 6049189c7e7SJoe Perches "call_rcu_sched" => "call_rcu", 6059189c7e7SJoe Perches "rcu_barrier_sched" => "rcu_barrier", 6069189c7e7SJoe Perches "get_state_synchronize_sched" => "get_state_synchronize_rcu", 6079189c7e7SJoe Perches "cond_synchronize_sched" => "cond_synchronize_rcu", 6089189c7e7SJoe Perches); 6099189c7e7SJoe Perches 6109189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 6119189c7e7SJoe Perchesour $deprecated_apis_search = ""; 6129189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 6139189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 6149189c7e7SJoe Perches $deprecated_apis_search .= $entry; 6159189c7e7SJoe Perches} 6169189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 6179189c7e7SJoe Perches 618b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 619b392c64fSJoe Perches S_IWUGO | 620b392c64fSJoe Perches S_IWOTH | 621b392c64fSJoe Perches S_IRWXUGO | 622b392c64fSJoe Perches S_IALLUGO | 623b392c64fSJoe Perches 0[0-7][0-7][2367] 624b392c64fSJoe Perches}x; 625b392c64fSJoe Perches 626f90774e1SJoe Perchesour %mode_permission_string_types = ( 627f90774e1SJoe Perches "S_IRWXU" => 0700, 628f90774e1SJoe Perches "S_IRUSR" => 0400, 629f90774e1SJoe Perches "S_IWUSR" => 0200, 630f90774e1SJoe Perches "S_IXUSR" => 0100, 631f90774e1SJoe Perches "S_IRWXG" => 0070, 632f90774e1SJoe Perches "S_IRGRP" => 0040, 633f90774e1SJoe Perches "S_IWGRP" => 0020, 634f90774e1SJoe Perches "S_IXGRP" => 0010, 635f90774e1SJoe Perches "S_IRWXO" => 0007, 636f90774e1SJoe Perches "S_IROTH" => 0004, 637f90774e1SJoe Perches "S_IWOTH" => 0002, 638f90774e1SJoe Perches "S_IXOTH" => 0001, 639f90774e1SJoe Perches "S_IRWXUGO" => 0777, 640f90774e1SJoe Perches "S_IRUGO" => 0444, 641f90774e1SJoe Perches "S_IWUGO" => 0222, 642f90774e1SJoe Perches "S_IXUGO" => 0111, 643f90774e1SJoe Perches); 644f90774e1SJoe Perches 645f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 646f90774e1SJoe Perchesour $mode_perms_string_search = ""; 647f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 648f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 649f90774e1SJoe Perches $mode_perms_string_search .= $entry; 650f90774e1SJoe Perches} 65100180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 65200180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 65300180468SJoe Perches ${single_mode_perms_string_search} 65400180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 65500180468SJoe Perches}x; 65600180468SJoe Perches 65700180468SJoe Perchessub perms_to_octal { 65800180468SJoe Perches my ($string) = @_; 65900180468SJoe Perches 66000180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 66100180468SJoe Perches 66200180468SJoe Perches my $val = ""; 66300180468SJoe Perches my $oval = ""; 66400180468SJoe Perches my $to = 0; 66500180468SJoe Perches my $curpos = 0; 66600180468SJoe Perches my $lastpos = 0; 66700180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 66800180468SJoe Perches $curpos = pos($string); 66900180468SJoe Perches my $match = $2; 67000180468SJoe Perches my $omatch = $1; 67100180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 67200180468SJoe Perches $lastpos = $curpos; 67300180468SJoe Perches $to |= $mode_permission_string_types{$match}; 67400180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 67500180468SJoe Perches $val .= $match; 67600180468SJoe Perches $oval .= $omatch; 67700180468SJoe Perches } 67800180468SJoe Perches $oval =~ s/^\s*\|\s*//; 67900180468SJoe Perches $oval =~ s/\s*\|\s*$//; 68000180468SJoe Perches return sprintf("%04o", $to); 68100180468SJoe Perches} 682f90774e1SJoe Perches 6837840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 6847840a94cSWolfram Sang irq| 685cdcee686SSergey Ryazanov memory| 686cdcee686SSergey Ryazanov time| 687cdcee686SSergey Ryazanov reboot 6887840a94cSWolfram Sang)}; 6897840a94cSWolfram Sang# memory.h: ARM has a custom one 6907840a94cSWolfram Sang 69166b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 69266b47b4aSKees Cookmy $misspellings; 69366b47b4aSKees Cookmy %spelling_fix; 69436061e38SJoe Perches 69536061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 69666b47b4aSKees Cook while (<$spelling>) { 69766b47b4aSKees Cook my $line = $_; 69866b47b4aSKees Cook 69966b47b4aSKees Cook $line =~ s/\s*\n?$//g; 70066b47b4aSKees Cook $line =~ s/^\s*//g; 70166b47b4aSKees Cook 70266b47b4aSKees Cook next if ($line =~ m/^\s*#/); 70366b47b4aSKees Cook next if ($line =~ m/^\s*$/); 70466b47b4aSKees Cook 70566b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 70666b47b4aSKees Cook 70766b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 70866b47b4aSKees Cook } 70966b47b4aSKees Cook close($spelling); 71036061e38SJoe Perches} else { 71136061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 71236061e38SJoe Perches} 71366b47b4aSKees Cook 714ebfd7d62SJoe Perchesif ($codespell) { 715ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 716ebfd7d62SJoe Perches while (<$spelling>) { 717ebfd7d62SJoe Perches my $line = $_; 718ebfd7d62SJoe Perches 719ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 720ebfd7d62SJoe Perches $line =~ s/^\s*//g; 721ebfd7d62SJoe Perches 722ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 723ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 724ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 725ebfd7d62SJoe Perches 726ebfd7d62SJoe Perches $line =~ s/,.*$//; 727ebfd7d62SJoe Perches 728ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 729ebfd7d62SJoe Perches 730ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 731ebfd7d62SJoe Perches } 732ebfd7d62SJoe Perches close($spelling); 733ebfd7d62SJoe Perches } else { 734ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 735ebfd7d62SJoe Perches } 736ebfd7d62SJoe Perches} 737ebfd7d62SJoe Perches 738ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 739ebfd7d62SJoe Perches 74075ad8c57SJerome Forissiersub read_words { 74175ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 74275ad8c57SJerome Forissier 74375ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 74475ad8c57SJerome Forissier while (<$words>) { 745bf1fa1daSJoe Perches my $line = $_; 746bf1fa1daSJoe Perches 747bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 748bf1fa1daSJoe Perches $line =~ s/^\s*//g; 749bf1fa1daSJoe Perches 750bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 751bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 752bf1fa1daSJoe Perches if ($line =~ /\s/) { 75375ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 754bf1fa1daSJoe Perches next; 755bf1fa1daSJoe Perches } 756bf1fa1daSJoe Perches 75775ad8c57SJerome Forissier $$wordsRef .= '|' if ($$wordsRef ne ""); 75875ad8c57SJerome Forissier $$wordsRef .= $line; 759bf1fa1daSJoe Perches } 76075ad8c57SJerome Forissier close($file); 76175ad8c57SJerome Forissier return 1; 762bf1fa1daSJoe Perches } 763bf1fa1daSJoe Perches 76475ad8c57SJerome Forissier return 0; 76575ad8c57SJerome Forissier} 76675ad8c57SJerome Forissier 76775ad8c57SJerome Forissiermy $const_structs = ""; 76875ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile) 76975ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 77075ad8c57SJerome Forissier 77175ad8c57SJerome Forissiermy $typeOtherTypedefs = ""; 77275ad8c57SJerome Forissierif (length($typedefsfile)) { 77375ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 77475ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 77575ad8c57SJerome Forissier} 77675ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); 77775ad8c57SJerome Forissier 7788905a67cSAndy Whitcroftsub build_types { 779485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 780485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 7811813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 7828716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 783c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 784ab7e23f3SJoe Perches $BasicType = qr{ 785ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 786ab7e23f3SJoe Perches (?:${all}\b) 787ab7e23f3SJoe Perches }x; 7888905a67cSAndy Whitcroft $NonptrType = qr{ 789d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 790cf655043SAndy Whitcroft (?: 7916b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 7928ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 793c45dcabdSAndy Whitcroft (?:${all}\b) 794cf655043SAndy Whitcroft ) 795c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 7968905a67cSAndy Whitcroft }x; 7971813087dSJoe Perches $NonptrTypeMisordered = qr{ 7981813087dSJoe Perches (?:$Modifier\s+|const\s+)* 7991813087dSJoe Perches (?: 8001813087dSJoe Perches (?:${Misordered}\b) 8011813087dSJoe Perches ) 8021813087dSJoe Perches (?:\s+$Modifier|\s+const)* 8031813087dSJoe Perches }x; 8048716de38SJoe Perches $NonptrTypeWithAttr = qr{ 8058716de38SJoe Perches (?:$Modifier\s+|const\s+)* 8068716de38SJoe Perches (?: 8078716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 8088716de38SJoe Perches (?:$typeTypedefs\b)| 8098716de38SJoe Perches (?:${allWithAttr}\b) 8108716de38SJoe Perches ) 8118716de38SJoe Perches (?:\s+$Modifier|\s+const)* 8128716de38SJoe Perches }x; 8138905a67cSAndy Whitcroft $Type = qr{ 814c45dcabdSAndy Whitcroft $NonptrType 8157b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 816c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 8178905a67cSAndy Whitcroft }x; 8181813087dSJoe Perches $TypeMisordered = qr{ 8191813087dSJoe Perches $NonptrTypeMisordered 8207b18496cSAntonio Borneo (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} 8211813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 8221813087dSJoe Perches }x; 82391cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 8241813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 8258905a67cSAndy Whitcroft} 8268905a67cSAndy Whitcroftbuild_types(); 8276c72ffaaSAndy Whitcroft 8287d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 829d1fe9c09SJoe Perches 830d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 831d1fe9c09SJoe Perches# requires at least perl version v5.10.0 832d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 833d1fe9c09SJoe Perches 834d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 8352435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 836c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 8377d2367afSJoe Perches 838f8422308SJoe Perchesour $declaration_macros = qr{(?x: 8393e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 840fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 8413d102fc0SGilad Ben-Yossef (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(| 8423d102fc0SGilad Ben-Yossef (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( 843f8422308SJoe Perches)}; 844f8422308SJoe Perches 8457d2367afSJoe Perchessub deparenthesize { 8467d2367afSJoe Perches my ($string) = @_; 8477d2367afSJoe Perches return "" if (!defined($string)); 8485b9553abSJoe Perches 8495b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 8505b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 8515b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 8525b9553abSJoe Perches } 8535b9553abSJoe Perches 8547d2367afSJoe Perches $string =~ s@\s+@ @g; 8555b9553abSJoe Perches 8567d2367afSJoe Perches return $string; 8577d2367afSJoe Perches} 8587d2367afSJoe Perches 8593445686aSJoe Perchessub seed_camelcase_file { 8603445686aSJoe Perches my ($file) = @_; 8613445686aSJoe Perches 8623445686aSJoe Perches return if (!(-f $file)); 8633445686aSJoe Perches 8643445686aSJoe Perches local $/; 8653445686aSJoe Perches 8663445686aSJoe Perches open(my $include_file, '<', "$file") 8673445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 8683445686aSJoe Perches my $text = <$include_file>; 8693445686aSJoe Perches close($include_file); 8703445686aSJoe Perches 8713445686aSJoe Perches my @lines = split('\n', $text); 8723445686aSJoe Perches 8733445686aSJoe Perches foreach my $line (@lines) { 8743445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 8753445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 8763445686aSJoe Perches $camelcase{$1} = 1; 87711ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 87811ea516aSJoe Perches $camelcase{$1} = 1; 87911ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 8803445686aSJoe Perches $camelcase{$1} = 1; 8813445686aSJoe Perches } 8823445686aSJoe Perches } 8833445686aSJoe Perches} 8843445686aSJoe Perches 885cd28b119SJoe Perchesour %maintained_status = (); 886cd28b119SJoe Perches 88785b0ee18SJoe Perchessub is_maintained_obsolete { 88885b0ee18SJoe Perches my ($filename) = @_; 88985b0ee18SJoe Perches 890f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 89185b0ee18SJoe Perches 892cd28b119SJoe Perches if (!exists($maintained_status{$filename})) { 893cd28b119SJoe Perches $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 894cd28b119SJoe Perches } 89585b0ee18SJoe Perches 896cd28b119SJoe Perches return $maintained_status{$filename} =~ /obsolete/i; 89785b0ee18SJoe Perches} 89885b0ee18SJoe Perches 8993b6e8ac9SJoe Perchessub is_SPDX_License_valid { 9003b6e8ac9SJoe Perches my ($license) = @_; 9013b6e8ac9SJoe Perches 90256294112SJoe Perches return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git")); 9033b6e8ac9SJoe Perches 90456294112SJoe Perches my $root_path = abs_path($root); 90556294112SJoe Perches my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`; 9063b6e8ac9SJoe Perches return 0 if ($status ne ""); 9073b6e8ac9SJoe Perches return 1; 9083b6e8ac9SJoe Perches} 9093b6e8ac9SJoe Perches 9103445686aSJoe Perchesmy $camelcase_seeded = 0; 9113445686aSJoe Perchessub seed_camelcase_includes { 9123445686aSJoe Perches return if ($camelcase_seeded); 9133445686aSJoe Perches 9143445686aSJoe Perches my $files; 915c707a81dSJoe Perches my $camelcase_cache = ""; 916c707a81dSJoe Perches my @include_files = (); 917c707a81dSJoe Perches 918c707a81dSJoe Perches $camelcase_seeded = 1; 919351b2a1fSJoe Perches 9203645e328SRichard Genoud if (-e ".git") { 921dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 922351b2a1fSJoe Perches chomp $git_last_include_commit; 923c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 924c707a81dSJoe Perches } else { 925c707a81dSJoe Perches my $last_mod_date = 0; 926c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 927c707a81dSJoe Perches @include_files = split('\n', $files); 928c707a81dSJoe Perches foreach my $file (@include_files) { 929c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 930c707a81dSJoe Perches localtime((stat $file)[9])); 931c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 932c707a81dSJoe Perches } 933c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 934c707a81dSJoe Perches } 935c707a81dSJoe Perches 936c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 937c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 938c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 939351b2a1fSJoe Perches while (<$camelcase_file>) { 940351b2a1fSJoe Perches chomp; 941351b2a1fSJoe Perches $camelcase{$_} = 1; 942351b2a1fSJoe Perches } 943351b2a1fSJoe Perches close($camelcase_file); 944351b2a1fSJoe Perches 945351b2a1fSJoe Perches return; 946351b2a1fSJoe Perches } 947c707a81dSJoe Perches 9483645e328SRichard Genoud if (-e ".git") { 949dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 950c707a81dSJoe Perches @include_files = split('\n', $files); 9513445686aSJoe Perches } 952c707a81dSJoe Perches 9533445686aSJoe Perches foreach my $file (@include_files) { 9543445686aSJoe Perches seed_camelcase_file($file); 9553445686aSJoe Perches } 956351b2a1fSJoe Perches 957c707a81dSJoe Perches if ($camelcase_cache ne "") { 958351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 959c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 960c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 961351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 962351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 963351b2a1fSJoe Perches } 964351b2a1fSJoe Perches close($camelcase_file); 965351b2a1fSJoe Perches } 9663445686aSJoe Perches} 9673445686aSJoe Perches 968d311cd44SJoe Perchessub git_commit_info { 969d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 970d311cd44SJoe Perches 971d311cd44SJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); 972d311cd44SJoe Perches 973dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 974d311cd44SJoe Perches $output =~ s/^\s*//gm; 975d311cd44SJoe Perches my @lines = split("\n", $output); 976d311cd44SJoe Perches 9770d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 9780d7835fcSJoe Perches 9795a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 980d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 981d311cd44SJoe Perches# all matching commit ids, but it's very slow... 982d311cd44SJoe Perches# 983d311cd44SJoe Perches# echo "checking commits $1..." 984d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 985d311cd44SJoe Perches# while read line ; do 986d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 987d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 988d311cd44SJoe Perches# done 989d311cd44SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { 990948b133aSHeinrich Schuchardt $id = undef; 991d311cd44SJoe Perches } else { 992d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 993d311cd44SJoe Perches $desc = substr($lines[0], 41); 994d311cd44SJoe Perches } 995d311cd44SJoe Perches 996d311cd44SJoe Perches return ($id, $desc); 997d311cd44SJoe Perches} 998d311cd44SJoe Perches 9996c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 10000a920b5bSAndy Whitcroft 100100df344fSAndy Whitcroftmy @rawlines = (); 1002c2fdda0dSAndy Whitcroftmy @lines = (); 10033705ce5bSJoe Perchesmy @fixed = (); 1004d752fcc8SJoe Perchesmy @fixed_inserted = (); 1005d752fcc8SJoe Perchesmy @fixed_deleted = (); 1006194f66fcSJoe Perchesmy $fixlinenr = -1; 1007194f66fcSJoe Perches 10084a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 10094a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 10104a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git"); 10114a593c34SDu, Changbin 10124a593c34SDu, Changbinif ($git) { 10134a593c34SDu, Changbin my @commits = (); 10140dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 10154a593c34SDu, Changbin my $git_range; 101628898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 101728898fd1SJoe Perches $git_range = "-$2 $1"; 10184a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 10194a593c34SDu, Changbin $git_range = "$commit_expr"; 10204a593c34SDu, Changbin } else { 10210dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 10220dea9f1eSJoe Perches } 1023dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 10240dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 102528898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 102628898fd1SJoe Perches next if (!defined($1) || !defined($2)); 10270dea9f1eSJoe Perches my $sha1 = $1; 10280dea9f1eSJoe Perches my $subject = $2; 10290dea9f1eSJoe Perches unshift(@commits, $sha1); 10300dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 10314a593c34SDu, Changbin } 10324a593c34SDu, Changbin } 10334a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 10344a593c34SDu, Changbin @ARGV = @commits; 10354a593c34SDu, Changbin} 10364a593c34SDu, Changbin 1037c2fdda0dSAndy Whitcroftmy $vname; 103898005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 10396c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 104021caa13cSAndy Whitcroft my $FILE; 10414a593c34SDu, Changbin if ($git) { 10424a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 10434a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 10444a593c34SDu, Changbin } elsif ($file) { 104521caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 10466c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 104721caa13cSAndy Whitcroft } elsif ($filename eq '-') { 104821caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 10496c72ffaaSAndy Whitcroft } else { 105021caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 10516c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 10526c72ffaaSAndy Whitcroft } 1053c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1054c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 10554a593c34SDu, Changbin } elsif ($git) { 10560dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1057c2fdda0dSAndy Whitcroft } else { 1058c2fdda0dSAndy Whitcroft $vname = $filename; 1059c2fdda0dSAndy Whitcroft } 106021caa13cSAndy Whitcroft while (<$FILE>) { 10610a920b5bSAndy Whitcroft chomp; 106200df344fSAndy Whitcroft push(@rawlines, $_); 10636c72ffaaSAndy Whitcroft } 106421caa13cSAndy Whitcroft close($FILE); 1065d8469f16SJoe Perches 1066d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1067d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1068d8469f16SJoe Perches print "$vname\n"; 1069d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1070d8469f16SJoe Perches } 1071d8469f16SJoe Perches 1072c2fdda0dSAndy Whitcroft if (!process($filename)) { 10730a920b5bSAndy Whitcroft $exit = 1; 10740a920b5bSAndy Whitcroft } 107500df344fSAndy Whitcroft @rawlines = (); 107613214adfSAndy Whitcroft @lines = (); 10773705ce5bSJoe Perches @fixed = (); 1078d752fcc8SJoe Perches @fixed_inserted = (); 1079d752fcc8SJoe Perches @fixed_deleted = (); 1080194f66fcSJoe Perches $fixlinenr = -1; 1081485ff23eSAlex Dowad @modifierListFile = (); 1082485ff23eSAlex Dowad @typeListFile = (); 1083485ff23eSAlex Dowad build_types(); 10840a920b5bSAndy Whitcroft} 10850a920b5bSAndy Whitcroft 1086d8469f16SJoe Perchesif (!$quiet) { 10873c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 10883c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 10893c816e49SJoe Perches 10905b57980dSJoe Perches if (!$perl_version_ok) { 1091d8469f16SJoe Perches print << "EOM" 1092d8469f16SJoe Perches 1093d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 10945b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1095d8469f16SJoe PerchesEOM 1096d8469f16SJoe Perches } 1097d8469f16SJoe Perches if ($exit) { 1098d8469f16SJoe Perches print << "EOM" 1099d8469f16SJoe Perches 1100d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1101d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1102d8469f16SJoe PerchesEOM 1103d8469f16SJoe Perches } 1104d8469f16SJoe Perches} 1105d8469f16SJoe Perches 11060a920b5bSAndy Whitcroftexit($exit); 11070a920b5bSAndy Whitcroft 11080a920b5bSAndy Whitcroftsub top_of_kernel_tree { 11096c72ffaaSAndy Whitcroft my ($root) = @_; 11106c72ffaaSAndy Whitcroft 11116c72ffaaSAndy Whitcroft my @tree_check = ( 11126c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 11136c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 11146c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 11156c72ffaaSAndy Whitcroft ); 11166c72ffaaSAndy Whitcroft 11176c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 11186c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 11190a920b5bSAndy Whitcroft return 0; 11200a920b5bSAndy Whitcroft } 11216c72ffaaSAndy Whitcroft } 11226c72ffaaSAndy Whitcroft return 1; 11236c72ffaaSAndy Whitcroft} 11240a920b5bSAndy Whitcroft 112520112475SJoe Perchessub parse_email { 112620112475SJoe Perches my ($formatted_email) = @_; 112720112475SJoe Perches 112820112475SJoe Perches my $name = ""; 1129dfa05c28SJoe Perches my $name_comment = ""; 113020112475SJoe Perches my $address = ""; 113120112475SJoe Perches my $comment = ""; 113220112475SJoe Perches 113320112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 113420112475SJoe Perches $name = $1; 113520112475SJoe Perches $address = $2; 113620112475SJoe Perches $comment = $3 if defined $3; 113720112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 113820112475SJoe Perches $address = $1; 113920112475SJoe Perches $comment = $2 if defined $2; 114020112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 114120112475SJoe Perches $address = $1; 114220112475SJoe Perches $comment = $2 if defined $2; 114385e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 114420112475SJoe Perches $name = $formatted_email; 11453705ce5bSJoe Perches $name = trim($name); 114620112475SJoe Perches $name =~ s/^\"|\"$//g; 114720112475SJoe Perches # If there's a name left after stripping spaces and 114820112475SJoe Perches # leading quotes, and the address doesn't have both 114920112475SJoe Perches # leading and trailing angle brackets, the address 115020112475SJoe Perches # is invalid. ie: 115120112475SJoe Perches # "joe smith [email protected]" bad 115220112475SJoe Perches # "joe smith <[email protected]" bad 115320112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 115420112475SJoe Perches $name = ""; 115520112475SJoe Perches $address = ""; 115620112475SJoe Perches $comment = ""; 115720112475SJoe Perches } 115820112475SJoe Perches } 115920112475SJoe Perches 11603705ce5bSJoe Perches $name = trim($name); 116120112475SJoe Perches $name =~ s/^\"|\"$//g; 1162dfa05c28SJoe Perches $name =~ s/(\s*\([^\)]+\))\s*//; 1163dfa05c28SJoe Perches if (defined($1)) { 1164dfa05c28SJoe Perches $name_comment = trim($1); 1165dfa05c28SJoe Perches } 11663705ce5bSJoe Perches $address = trim($address); 116720112475SJoe Perches $address =~ s/^\<|\>$//g; 116820112475SJoe Perches 116920112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 117020112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 117120112475SJoe Perches $name = "\"$name\""; 117220112475SJoe Perches } 117320112475SJoe Perches 1174dfa05c28SJoe Perches return ($name, $name_comment, $address, $comment); 117520112475SJoe Perches} 117620112475SJoe Perches 117720112475SJoe Perchessub format_email { 117820112475SJoe Perches my ($name, $address) = @_; 117920112475SJoe Perches 118020112475SJoe Perches my $formatted_email; 118120112475SJoe Perches 11823705ce5bSJoe Perches $name = trim($name); 118320112475SJoe Perches $name =~ s/^\"|\"$//g; 11843705ce5bSJoe Perches $address = trim($address); 118520112475SJoe Perches 118620112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 118720112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 118820112475SJoe Perches $name = "\"$name\""; 118920112475SJoe Perches } 119020112475SJoe Perches 119120112475SJoe Perches if ("$name" eq "") { 119220112475SJoe Perches $formatted_email = "$address"; 119320112475SJoe Perches } else { 119420112475SJoe Perches $formatted_email = "$name <$address>"; 119520112475SJoe Perches } 119620112475SJoe Perches 119720112475SJoe Perches return $formatted_email; 119820112475SJoe Perches} 119920112475SJoe Perches 1200dfa05c28SJoe Perchessub reformat_email { 1201dfa05c28SJoe Perches my ($email) = @_; 1202dfa05c28SJoe Perches 1203dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 1204dfa05c28SJoe Perches return format_email($email_name, $email_address); 1205dfa05c28SJoe Perches} 1206dfa05c28SJoe Perches 1207dfa05c28SJoe Perchessub same_email_addresses { 1208dfa05c28SJoe Perches my ($email1, $email2) = @_; 1209dfa05c28SJoe Perches 1210dfa05c28SJoe Perches my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); 1211dfa05c28SJoe Perches my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); 1212dfa05c28SJoe Perches 1213dfa05c28SJoe Perches return $email1_name eq $email2_name && 1214dfa05c28SJoe Perches $email1_address eq $email2_address; 1215dfa05c28SJoe Perches} 1216dfa05c28SJoe Perches 1217d311cd44SJoe Perchessub which { 1218d311cd44SJoe Perches my ($bin) = @_; 1219d311cd44SJoe Perches 1220d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1221d311cd44SJoe Perches if (-e "$path/$bin") { 1222d311cd44SJoe Perches return "$path/$bin"; 1223d311cd44SJoe Perches } 1224d311cd44SJoe Perches } 1225d311cd44SJoe Perches 1226d311cd44SJoe Perches return ""; 1227d311cd44SJoe Perches} 1228d311cd44SJoe Perches 1229000d1cc1SJoe Perchessub which_conf { 1230000d1cc1SJoe Perches my ($conf) = @_; 1231000d1cc1SJoe Perches 1232000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1233000d1cc1SJoe Perches if (-e "$path/$conf") { 1234000d1cc1SJoe Perches return "$path/$conf"; 1235000d1cc1SJoe Perches } 1236000d1cc1SJoe Perches } 1237000d1cc1SJoe Perches 1238000d1cc1SJoe Perches return ""; 1239000d1cc1SJoe Perches} 1240000d1cc1SJoe Perches 12410a920b5bSAndy Whitcroftsub expand_tabs { 12420a920b5bSAndy Whitcroft my ($str) = @_; 12430a920b5bSAndy Whitcroft 12440a920b5bSAndy Whitcroft my $res = ''; 12450a920b5bSAndy Whitcroft my $n = 0; 12460a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 12470a920b5bSAndy Whitcroft if ($c eq "\t") { 12480a920b5bSAndy Whitcroft $res .= ' '; 12490a920b5bSAndy Whitcroft $n++; 1250713a09deSAntonio Borneo for (; ($n % $tabsize) != 0; $n++) { 12510a920b5bSAndy Whitcroft $res .= ' '; 12520a920b5bSAndy Whitcroft } 12530a920b5bSAndy Whitcroft next; 12540a920b5bSAndy Whitcroft } 12550a920b5bSAndy Whitcroft $res .= $c; 12560a920b5bSAndy Whitcroft $n++; 12570a920b5bSAndy Whitcroft } 12580a920b5bSAndy Whitcroft 12590a920b5bSAndy Whitcroft return $res; 12600a920b5bSAndy Whitcroft} 12616c72ffaaSAndy Whitcroftsub copy_spacing { 1262773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 12636c72ffaaSAndy Whitcroft return $res; 12646c72ffaaSAndy Whitcroft} 12650a920b5bSAndy Whitcroft 12664a0df2efSAndy Whitcroftsub line_stats { 12674a0df2efSAndy Whitcroft my ($line) = @_; 12684a0df2efSAndy Whitcroft 12694a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 12704a0df2efSAndy Whitcroft $line =~ s/^.//; 12714a0df2efSAndy Whitcroft $line = expand_tabs($line); 12724a0df2efSAndy Whitcroft 12734a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 12744a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 12754a0df2efSAndy Whitcroft 12764a0df2efSAndy Whitcroft return (length($line), length($white)); 12774a0df2efSAndy Whitcroft} 12784a0df2efSAndy Whitcroft 1279773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1280773647a0SAndy Whitcroft 1281773647a0SAndy Whitcroftsub sanitise_line_reset { 1282773647a0SAndy Whitcroft my ($in_comment) = @_; 1283773647a0SAndy Whitcroft 1284773647a0SAndy Whitcroft if ($in_comment) { 1285773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1286773647a0SAndy Whitcroft } else { 1287773647a0SAndy Whitcroft $sanitise_quote = ''; 1288773647a0SAndy Whitcroft } 1289773647a0SAndy Whitcroft} 129000df344fSAndy Whitcroftsub sanitise_line { 129100df344fSAndy Whitcroft my ($line) = @_; 129200df344fSAndy Whitcroft 129300df344fSAndy Whitcroft my $res = ''; 129400df344fSAndy Whitcroft my $l = ''; 129500df344fSAndy Whitcroft 1296c2fdda0dSAndy Whitcroft my $qlen = 0; 1297773647a0SAndy Whitcroft my $off = 0; 1298773647a0SAndy Whitcroft my $c; 129900df344fSAndy Whitcroft 1300773647a0SAndy Whitcroft # Always copy over the diff marker. 1301773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1302773647a0SAndy Whitcroft 1303773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1304773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1305773647a0SAndy Whitcroft 13068d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1307773647a0SAndy Whitcroft # and end, all to $;. 1308773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1309773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1310773647a0SAndy Whitcroft 1311773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1312773647a0SAndy Whitcroft $off++; 131300df344fSAndy Whitcroft next; 1314773647a0SAndy Whitcroft } 131581bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1316773647a0SAndy Whitcroft $sanitise_quote = ''; 1317773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1318773647a0SAndy Whitcroft $off++; 1319773647a0SAndy Whitcroft next; 1320773647a0SAndy Whitcroft } 1321113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1322113f04a8SDaniel Walker $sanitise_quote = '//'; 1323113f04a8SDaniel Walker 1324113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1325113f04a8SDaniel Walker $off++; 1326113f04a8SDaniel Walker next; 1327113f04a8SDaniel Walker } 1328773647a0SAndy Whitcroft 1329773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1330773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1331773647a0SAndy Whitcroft $c eq "\\") { 1332773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1333773647a0SAndy Whitcroft $off++; 1334773647a0SAndy Whitcroft next; 1335773647a0SAndy Whitcroft } 1336773647a0SAndy Whitcroft # Regular quotes. 1337773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1338773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1339773647a0SAndy Whitcroft $sanitise_quote = $c; 1340773647a0SAndy Whitcroft 1341773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1342773647a0SAndy Whitcroft next; 1343773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1344773647a0SAndy Whitcroft $sanitise_quote = ''; 134500df344fSAndy Whitcroft } 134600df344fSAndy Whitcroft } 1347773647a0SAndy Whitcroft 1348fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1349773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1350773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1351113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1352113f04a8SDaniel Walker substr($res, $off, 1, $;); 1353773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1354773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 135500df344fSAndy Whitcroft } else { 1356773647a0SAndy Whitcroft substr($res, $off, 1, $c); 135700df344fSAndy Whitcroft } 1358c2fdda0dSAndy Whitcroft } 1359c2fdda0dSAndy Whitcroft 1360113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1361113f04a8SDaniel Walker $sanitise_quote = ''; 1362113f04a8SDaniel Walker } 1363113f04a8SDaniel Walker 1364c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1365c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1366c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1367c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1368c2fdda0dSAndy Whitcroft 1369c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1370c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1371c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1372c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1373c2fdda0dSAndy Whitcroft } 1374c2fdda0dSAndy Whitcroft 1375dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1376dadf680dSJoe Perches my $match = $1; 1377dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1378dadf680dSJoe Perches } 1379dadf680dSJoe Perches 138000df344fSAndy Whitcroft return $res; 138100df344fSAndy Whitcroft} 138200df344fSAndy Whitcroft 1383a6962d72SJoe Perchessub get_quoted_string { 1384a6962d72SJoe Perches my ($line, $rawline) = @_; 1385a6962d72SJoe Perches 1386478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 138733acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1388a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1389a6962d72SJoe Perches} 1390a6962d72SJoe Perches 13918905a67cSAndy Whitcroftsub ctx_statement_block { 13928905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 13938905a67cSAndy Whitcroft my $line = $linenr - 1; 13948905a67cSAndy Whitcroft my $blk = ''; 13958905a67cSAndy Whitcroft my $soff = $off; 13968905a67cSAndy Whitcroft my $coff = $off - 1; 1397773647a0SAndy Whitcroft my $coff_set = 0; 13988905a67cSAndy Whitcroft 139913214adfSAndy Whitcroft my $loff = 0; 140013214adfSAndy Whitcroft 14018905a67cSAndy Whitcroft my $type = ''; 14028905a67cSAndy Whitcroft my $level = 0; 1403a2750645SAndy Whitcroft my @stack = (); 1404cf655043SAndy Whitcroft my $p; 14058905a67cSAndy Whitcroft my $c; 14068905a67cSAndy Whitcroft my $len = 0; 140713214adfSAndy Whitcroft 140813214adfSAndy Whitcroft my $remainder; 14098905a67cSAndy Whitcroft while (1) { 1410a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1411a2750645SAndy Whitcroft 1412773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 14138905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 14148905a67cSAndy Whitcroft # context. 14158905a67cSAndy Whitcroft if ($off >= $len) { 14168905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1417dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1418c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 14198905a67cSAndy Whitcroft $remain--; 142013214adfSAndy Whitcroft $loff = $len; 1421c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 14228905a67cSAndy Whitcroft $len = length($blk); 14238905a67cSAndy Whitcroft $line++; 14248905a67cSAndy Whitcroft last; 14258905a67cSAndy Whitcroft } 14268905a67cSAndy Whitcroft # Bail if there is no further context. 14278905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 142813214adfSAndy Whitcroft if ($off >= $len) { 14298905a67cSAndy Whitcroft last; 14308905a67cSAndy Whitcroft } 1431f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1432f74bd194SAndy Whitcroft $level++; 1433f74bd194SAndy Whitcroft $type = '#'; 1434f74bd194SAndy Whitcroft } 14358905a67cSAndy Whitcroft } 1436cf655043SAndy Whitcroft $p = $c; 14378905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 143813214adfSAndy Whitcroft $remainder = substr($blk, $off); 14398905a67cSAndy Whitcroft 1440773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 14414635f4fbSAndy Whitcroft 14424635f4fbSAndy Whitcroft # Handle nested #if/#else. 14434635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 14444635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 14454635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 14464635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 14474635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 14484635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 14494635f4fbSAndy Whitcroft } 14504635f4fbSAndy Whitcroft 14518905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 14528905a67cSAndy Whitcroft # outermost level. 14538905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 14548905a67cSAndy Whitcroft last; 14558905a67cSAndy Whitcroft } 14568905a67cSAndy Whitcroft 145713214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1458773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1459773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1460773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1461773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1462773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1463773647a0SAndy Whitcroft $coff_set = 1; 1464773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1465773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 146613214adfSAndy Whitcroft } 146713214adfSAndy Whitcroft 14688905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 14698905a67cSAndy Whitcroft $level++; 14708905a67cSAndy Whitcroft $type = '('; 14718905a67cSAndy Whitcroft } 14728905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 14738905a67cSAndy Whitcroft $level--; 14748905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 14758905a67cSAndy Whitcroft 14768905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 14778905a67cSAndy Whitcroft $coff = $off; 1478773647a0SAndy Whitcroft $coff_set = 1; 1479773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 14808905a67cSAndy Whitcroft } 14818905a67cSAndy Whitcroft } 14828905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 14838905a67cSAndy Whitcroft $level++; 14848905a67cSAndy Whitcroft $type = '{'; 14858905a67cSAndy Whitcroft } 14868905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 14878905a67cSAndy Whitcroft $level--; 14888905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 14898905a67cSAndy Whitcroft 14908905a67cSAndy Whitcroft if ($level == 0) { 1491b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1492b998e001SPatrick Pannuto $off++; 1493b998e001SPatrick Pannuto } 14948905a67cSAndy Whitcroft last; 14958905a67cSAndy Whitcroft } 14968905a67cSAndy Whitcroft } 1497f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1498f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1499f74bd194SAndy Whitcroft $level--; 1500f74bd194SAndy Whitcroft $type = ''; 1501f74bd194SAndy Whitcroft $off++; 1502f74bd194SAndy Whitcroft last; 1503f74bd194SAndy Whitcroft } 15048905a67cSAndy Whitcroft $off++; 15058905a67cSAndy Whitcroft } 1506a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 150713214adfSAndy Whitcroft if ($off == $len) { 1508a3bb97a7SAndy Whitcroft $loff = $len + 1; 150913214adfSAndy Whitcroft $line++; 151013214adfSAndy Whitcroft $remain--; 151113214adfSAndy Whitcroft } 15128905a67cSAndy Whitcroft 15138905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 15148905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 15158905a67cSAndy Whitcroft 15168905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 15178905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 15188905a67cSAndy Whitcroft 1519773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 152013214adfSAndy Whitcroft 152113214adfSAndy Whitcroft return ($statement, $condition, 152213214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 152313214adfSAndy Whitcroft} 152413214adfSAndy Whitcroft 1525cf655043SAndy Whitcroftsub statement_lines { 1526cf655043SAndy Whitcroft my ($stmt) = @_; 1527cf655043SAndy Whitcroft 1528cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1529cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1530cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1531cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1532cf655043SAndy Whitcroft 1533cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1534cf655043SAndy Whitcroft 1535cf655043SAndy Whitcroft return $#stmt_lines + 2; 1536cf655043SAndy Whitcroft} 1537cf655043SAndy Whitcroft 1538cf655043SAndy Whitcroftsub statement_rawlines { 1539cf655043SAndy Whitcroft my ($stmt) = @_; 1540cf655043SAndy Whitcroft 1541cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1542cf655043SAndy Whitcroft 1543cf655043SAndy Whitcroft return $#stmt_lines + 2; 1544cf655043SAndy Whitcroft} 1545cf655043SAndy Whitcroft 1546cf655043SAndy Whitcroftsub statement_block_size { 1547cf655043SAndy Whitcroft my ($stmt) = @_; 1548cf655043SAndy Whitcroft 1549cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1550cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1551cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1552cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1553cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1554cf655043SAndy Whitcroft 1555cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1556cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1557cf655043SAndy Whitcroft 1558cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1559cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1560cf655043SAndy Whitcroft 1561cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1562cf655043SAndy Whitcroft return $stmt_lines; 1563cf655043SAndy Whitcroft } else { 1564cf655043SAndy Whitcroft return $stmt_statements; 1565cf655043SAndy Whitcroft } 1566cf655043SAndy Whitcroft} 1567cf655043SAndy Whitcroft 156813214adfSAndy Whitcroftsub ctx_statement_full { 156913214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 157013214adfSAndy Whitcroft my ($statement, $condition, $level); 157113214adfSAndy Whitcroft 157213214adfSAndy Whitcroft my (@chunks); 157313214adfSAndy Whitcroft 1574cf655043SAndy Whitcroft # Grab the first conditional/block pair. 157513214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 157613214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1577773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 157813214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1579cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1580cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1581cf655043SAndy Whitcroft } 1582cf655043SAndy Whitcroft 1583cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1584cf655043SAndy Whitcroft # could continue the statement. 1585cf655043SAndy Whitcroft for (;;) { 158613214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 158713214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1588cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1589773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1590cf655043SAndy Whitcroft #print "C: push\n"; 1591cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 159213214adfSAndy Whitcroft } 159313214adfSAndy Whitcroft 159413214adfSAndy Whitcroft return ($level, $linenr, @chunks); 15958905a67cSAndy Whitcroft} 15968905a67cSAndy Whitcroft 15974a0df2efSAndy Whitcroftsub ctx_block_get { 1598f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 15994a0df2efSAndy Whitcroft my $line; 16004a0df2efSAndy Whitcroft my $start = $linenr - 1; 16014a0df2efSAndy Whitcroft my $blk = ''; 16024a0df2efSAndy Whitcroft my @o; 16034a0df2efSAndy Whitcroft my @c; 16044a0df2efSAndy Whitcroft my @res = (); 16054a0df2efSAndy Whitcroft 1606f0a594c1SAndy Whitcroft my $level = 0; 16074635f4fbSAndy Whitcroft my @stack = ($level); 160800df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 160900df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 161000df344fSAndy Whitcroft $remain--; 161100df344fSAndy Whitcroft 161200df344fSAndy Whitcroft $blk .= $rawlines[$line]; 16134635f4fbSAndy Whitcroft 16144635f4fbSAndy Whitcroft # Handle nested #if/#else. 161501464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 16164635f4fbSAndy Whitcroft push(@stack, $level); 161701464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 16184635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 161901464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 16204635f4fbSAndy Whitcroft $level = pop(@stack); 16214635f4fbSAndy Whitcroft } 16224635f4fbSAndy Whitcroft 162301464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1624f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1625f0a594c1SAndy Whitcroft if ($off > 0) { 1626f0a594c1SAndy Whitcroft $off--; 1627f0a594c1SAndy Whitcroft next; 1628f0a594c1SAndy Whitcroft } 16294a0df2efSAndy Whitcroft 1630f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1631f0a594c1SAndy Whitcroft $level--; 1632f0a594c1SAndy Whitcroft last if ($level == 0); 1633f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1634f0a594c1SAndy Whitcroft $level++; 1635f0a594c1SAndy Whitcroft } 1636f0a594c1SAndy Whitcroft } 16374a0df2efSAndy Whitcroft 1638f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 163900df344fSAndy Whitcroft push(@res, $rawlines[$line]); 16404a0df2efSAndy Whitcroft } 16414a0df2efSAndy Whitcroft 1642f0a594c1SAndy Whitcroft last if ($level == 0); 16434a0df2efSAndy Whitcroft } 16444a0df2efSAndy Whitcroft 1645f0a594c1SAndy Whitcroft return ($level, @res); 16464a0df2efSAndy Whitcroft} 16474a0df2efSAndy Whitcroftsub ctx_block_outer { 16484a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 16494a0df2efSAndy Whitcroft 1650f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1651f0a594c1SAndy Whitcroft return @r; 16524a0df2efSAndy Whitcroft} 16534a0df2efSAndy Whitcroftsub ctx_block { 16544a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 16554a0df2efSAndy Whitcroft 1656f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1657f0a594c1SAndy Whitcroft return @r; 1658653d4876SAndy Whitcroft} 1659653d4876SAndy Whitcroftsub ctx_statement { 1660f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1661f0a594c1SAndy Whitcroft 1662f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1663f0a594c1SAndy Whitcroft return @r; 1664f0a594c1SAndy Whitcroft} 1665f0a594c1SAndy Whitcroftsub ctx_block_level { 1666653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1667653d4876SAndy Whitcroft 1668f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 16694a0df2efSAndy Whitcroft} 16709c0ca6f9SAndy Whitcroftsub ctx_statement_level { 16719c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 16729c0ca6f9SAndy Whitcroft 16739c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 16749c0ca6f9SAndy Whitcroft} 16754a0df2efSAndy Whitcroft 16764a0df2efSAndy Whitcroftsub ctx_locate_comment { 16774a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 16784a0df2efSAndy Whitcroft 16794a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1680beae6332SAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 16814a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 16824a0df2efSAndy Whitcroft 16834a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 16844a0df2efSAndy Whitcroft # comment. 16854a0df2efSAndy Whitcroft my $in_comment = 0; 16864a0df2efSAndy Whitcroft $current_comment = ''; 16874a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 168800df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 168900df344fSAndy Whitcroft #warn " $line\n"; 16904a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 16914a0df2efSAndy Whitcroft $in_comment = 1; 16924a0df2efSAndy Whitcroft } 16934a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 16944a0df2efSAndy Whitcroft $in_comment = 1; 16954a0df2efSAndy Whitcroft } 16964a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 16974a0df2efSAndy Whitcroft $current_comment = ''; 16984a0df2efSAndy Whitcroft } 16994a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 17004a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 17014a0df2efSAndy Whitcroft $in_comment = 0; 17024a0df2efSAndy Whitcroft } 17034a0df2efSAndy Whitcroft } 17044a0df2efSAndy Whitcroft 17054a0df2efSAndy Whitcroft chomp($current_comment); 17064a0df2efSAndy Whitcroft return($current_comment); 17074a0df2efSAndy Whitcroft} 17084a0df2efSAndy Whitcroftsub ctx_has_comment { 17094a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 17104a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 17114a0df2efSAndy Whitcroft 171200df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 17134a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 17144a0df2efSAndy Whitcroft 17154a0df2efSAndy Whitcroft return ($cmt ne ''); 17164a0df2efSAndy Whitcroft} 17174a0df2efSAndy Whitcroft 17184d001e4dSAndy Whitcroftsub raw_line { 17194d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 17204d001e4dSAndy Whitcroft 17214d001e4dSAndy Whitcroft my $offset = $linenr - 1; 17224d001e4dSAndy Whitcroft $cnt++; 17234d001e4dSAndy Whitcroft 17244d001e4dSAndy Whitcroft my $line; 17254d001e4dSAndy Whitcroft while ($cnt) { 17264d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 17274d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 17284d001e4dSAndy Whitcroft $cnt--; 17294d001e4dSAndy Whitcroft } 17304d001e4dSAndy Whitcroft 17314d001e4dSAndy Whitcroft return $line; 17324d001e4dSAndy Whitcroft} 17334d001e4dSAndy Whitcroft 17342a9f9d85STobin C. Hardingsub get_stat_real { 17352a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 17362a9f9d85STobin C. Harding 17372a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 17382a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 17392a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 17402a9f9d85STobin C. Harding } 17412a9f9d85STobin C. Harding 17422a9f9d85STobin C. Harding return $stat_real; 17432a9f9d85STobin C. Harding} 17442a9f9d85STobin C. Harding 1745e3d95a2aSTobin C. Hardingsub get_stat_here { 1746e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 1747e3d95a2aSTobin C. Harding 1748e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 1749e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 1750e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 1751e3d95a2aSTobin C. Harding } 1752e3d95a2aSTobin C. Harding 1753e3d95a2aSTobin C. Harding return $herectx; 1754e3d95a2aSTobin C. Harding} 1755e3d95a2aSTobin C. Harding 17560a920b5bSAndy Whitcroftsub cat_vet { 17570a920b5bSAndy Whitcroft my ($vet) = @_; 17589c0ca6f9SAndy Whitcroft my ($res, $coded); 17590a920b5bSAndy Whitcroft 17609c0ca6f9SAndy Whitcroft $res = ''; 17616c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 17626c72ffaaSAndy Whitcroft $res .= $1; 17636c72ffaaSAndy Whitcroft if ($2 ne '') { 17649c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 17656c72ffaaSAndy Whitcroft $res .= $coded; 17666c72ffaaSAndy Whitcroft } 17679c0ca6f9SAndy Whitcroft } 17689c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 17690a920b5bSAndy Whitcroft 17709c0ca6f9SAndy Whitcroft return $res; 17710a920b5bSAndy Whitcroft} 17720a920b5bSAndy Whitcroft 1773c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1774cf655043SAndy Whitcroftmy $av_pending; 1775c2fdda0dSAndy Whitcroftmy @av_paren_type; 17761f65f947SAndy Whitcroftmy $av_pend_colon; 1777c2fdda0dSAndy Whitcroft 1778c2fdda0dSAndy Whitcroftsub annotate_reset { 1779c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1780cf655043SAndy Whitcroft $av_pending = '_'; 1781cf655043SAndy Whitcroft @av_paren_type = ('E'); 17821f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1783c2fdda0dSAndy Whitcroft} 1784c2fdda0dSAndy Whitcroft 17856c72ffaaSAndy Whitcroftsub annotate_values { 17866c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 17876c72ffaaSAndy Whitcroft 17886c72ffaaSAndy Whitcroft my $res; 17891f65f947SAndy Whitcroft my $var = '_' x length($stream); 17906c72ffaaSAndy Whitcroft my $cur = $stream; 17916c72ffaaSAndy Whitcroft 1792c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 17936c72ffaaSAndy Whitcroft 17946c72ffaaSAndy Whitcroft while (length($cur)) { 1795773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1796cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1797171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 17986c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1799c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1800c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1801cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1802c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 18036c72ffaaSAndy Whitcroft } 18046c72ffaaSAndy Whitcroft 1805c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 18069446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 18079446ef56SAndy Whitcroft push(@av_paren_type, $type); 1808addcdceaSAndy Whitcroft $type = 'c'; 18099446ef56SAndy Whitcroft 1810e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1811c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 18126c72ffaaSAndy Whitcroft $type = 'T'; 18136c72ffaaSAndy Whitcroft 1814389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1815389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1816389a2fe5SAndy Whitcroft $type = 'T'; 1817389a2fe5SAndy Whitcroft 1818c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1819171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1820c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1821171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1822171ae1a4SAndy Whitcroft if ($2 ne '') { 1823cf655043SAndy Whitcroft $av_pending = 'N'; 1824171ae1a4SAndy Whitcroft } 1825171ae1a4SAndy Whitcroft $type = 'E'; 1826171ae1a4SAndy Whitcroft 1827c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1828171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1829171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1830171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 18316c72ffaaSAndy Whitcroft 1832c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1833cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1834c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1835cf655043SAndy Whitcroft 1836cf655043SAndy Whitcroft push(@av_paren_type, $type); 1837cf655043SAndy Whitcroft push(@av_paren_type, $type); 1838171ae1a4SAndy Whitcroft $type = 'E'; 1839cf655043SAndy Whitcroft 1840c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1841cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1842cf655043SAndy Whitcroft $av_preprocessor = 1; 1843cf655043SAndy Whitcroft 1844cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1845cf655043SAndy Whitcroft 1846171ae1a4SAndy Whitcroft $type = 'E'; 1847cf655043SAndy Whitcroft 1848c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1849cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1850cf655043SAndy Whitcroft 1851cf655043SAndy Whitcroft $av_preprocessor = 1; 1852cf655043SAndy Whitcroft 1853cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1854cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1855cf655043SAndy Whitcroft pop(@av_paren_type); 1856cf655043SAndy Whitcroft push(@av_paren_type, $type); 1857171ae1a4SAndy Whitcroft $type = 'E'; 18586c72ffaaSAndy Whitcroft 18596c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1860c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 18616c72ffaaSAndy Whitcroft 1862171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1863171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 1864171ae1a4SAndy Whitcroft $av_pending = $type; 1865171ae1a4SAndy Whitcroft $type = 'N'; 1866171ae1a4SAndy Whitcroft 18676c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1868c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 18696c72ffaaSAndy Whitcroft if (defined $2) { 1870cf655043SAndy Whitcroft $av_pending = 'V'; 18716c72ffaaSAndy Whitcroft } 18726c72ffaaSAndy Whitcroft $type = 'N'; 18736c72ffaaSAndy Whitcroft 187414b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 1875c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 187614b111c1SAndy Whitcroft $av_pending = 'E'; 18776c72ffaaSAndy Whitcroft $type = 'N'; 18786c72ffaaSAndy Whitcroft 18791f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 18801f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 18811f65f947SAndy Whitcroft $av_pend_colon = 'C'; 18821f65f947SAndy Whitcroft $type = 'N'; 18831f65f947SAndy Whitcroft 188414b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1885c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 18866c72ffaaSAndy Whitcroft $type = 'N'; 18876c72ffaaSAndy Whitcroft 18886c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 1889c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 1890cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 1891cf655043SAndy Whitcroft $av_pending = '_'; 18926c72ffaaSAndy Whitcroft $type = 'N'; 18936c72ffaaSAndy Whitcroft 18946c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 1895cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 1896cf655043SAndy Whitcroft if ($new_type ne '_') { 1897cf655043SAndy Whitcroft $type = $new_type; 1898c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 1899c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 19006c72ffaaSAndy Whitcroft } else { 1901c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 19026c72ffaaSAndy Whitcroft } 19036c72ffaaSAndy Whitcroft 1904c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 1905c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 1906c8cb2ca3SAndy Whitcroft $type = 'V'; 1907cf655043SAndy Whitcroft $av_pending = 'V'; 19086c72ffaaSAndy Whitcroft 19098e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 19108e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 19111f65f947SAndy Whitcroft $av_pend_colon = 'B'; 19128e761b04SAndy Whitcroft } elsif ($type eq 'E') { 19138e761b04SAndy Whitcroft $av_pend_colon = 'L'; 19141f65f947SAndy Whitcroft } 19151f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 19161f65f947SAndy Whitcroft $type = 'V'; 19171f65f947SAndy Whitcroft 19186c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 1919c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 19206c72ffaaSAndy Whitcroft $type = 'V'; 19216c72ffaaSAndy Whitcroft 19226c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 1923c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 19246c72ffaaSAndy Whitcroft $type = 'N'; 19256c72ffaaSAndy Whitcroft 1926cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 1927c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 192813214adfSAndy Whitcroft $type = 'E'; 19291f65f947SAndy Whitcroft $av_pend_colon = 'O'; 193013214adfSAndy Whitcroft 19318e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 19328e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 19338e761b04SAndy Whitcroft $type = 'C'; 19348e761b04SAndy Whitcroft 19351f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 19361f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 19371f65f947SAndy Whitcroft $type = 'N'; 19381f65f947SAndy Whitcroft 19391f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 19401f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 19411f65f947SAndy Whitcroft 19421f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 19431f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 19441f65f947SAndy Whitcroft $type = 'E'; 19451f65f947SAndy Whitcroft } else { 19461f65f947SAndy Whitcroft $type = 'N'; 19471f65f947SAndy Whitcroft } 19481f65f947SAndy Whitcroft $av_pend_colon = 'O'; 19491f65f947SAndy Whitcroft 19508e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 195113214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 19526c72ffaaSAndy Whitcroft $type = 'N'; 19536c72ffaaSAndy Whitcroft 19540d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 195574048ed8SAndy Whitcroft my $variant; 195674048ed8SAndy Whitcroft 195774048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 195874048ed8SAndy Whitcroft if ($type eq 'V') { 195974048ed8SAndy Whitcroft $variant = 'B'; 196074048ed8SAndy Whitcroft } else { 196174048ed8SAndy Whitcroft $variant = 'U'; 196274048ed8SAndy Whitcroft } 196374048ed8SAndy Whitcroft 196474048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 196574048ed8SAndy Whitcroft $type = 'N'; 196674048ed8SAndy Whitcroft 19676c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 1968c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 19696c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 19706c72ffaaSAndy Whitcroft $type = 'N'; 19716c72ffaaSAndy Whitcroft } 19726c72ffaaSAndy Whitcroft 19736c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 1974c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 19756c72ffaaSAndy Whitcroft } 19766c72ffaaSAndy Whitcroft if (defined $1) { 19776c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 19786c72ffaaSAndy Whitcroft $res .= $type x length($1); 19796c72ffaaSAndy Whitcroft } 19806c72ffaaSAndy Whitcroft } 19816c72ffaaSAndy Whitcroft 19821f65f947SAndy Whitcroft return ($res, $var); 19836c72ffaaSAndy Whitcroft} 19846c72ffaaSAndy Whitcroft 19858905a67cSAndy Whitcroftsub possible { 198613214adfSAndy Whitcroft my ($possible, $line) = @_; 19879a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 19880776e594SAndy Whitcroft ^(?: 19890776e594SAndy Whitcroft $Modifier| 19900776e594SAndy Whitcroft $Storage| 19910776e594SAndy Whitcroft $Type| 19929a974fdbSAndy Whitcroft DEFINE_\S+ 19939a974fdbSAndy Whitcroft )$| 19949a974fdbSAndy Whitcroft ^(?: 19950776e594SAndy Whitcroft goto| 19960776e594SAndy Whitcroft return| 19970776e594SAndy Whitcroft case| 19980776e594SAndy Whitcroft else| 19990776e594SAndy Whitcroft asm|__asm__| 200089a88353SAndy Whitcroft do| 200189a88353SAndy Whitcroft \#| 200289a88353SAndy Whitcroft \#\#| 20039a974fdbSAndy Whitcroft )(?:\s|$)| 20040776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 20059a974fdbSAndy Whitcroft )}x; 20069a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 20079a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 2008c45dcabdSAndy Whitcroft # Check for modifiers. 2009c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 2010c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 2011c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 2012c45dcabdSAndy Whitcroft 2013c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 2014c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 2015d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 20169a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 2017d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 2018485ff23eSAlex Dowad push(@modifierListFile, $modifier); 2019d2506586SAndy Whitcroft } 20209a974fdbSAndy Whitcroft } 2021c45dcabdSAndy Whitcroft 2022c45dcabdSAndy Whitcroft } else { 202313214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 2024485ff23eSAlex Dowad push(@typeListFile, $possible); 2025c45dcabdSAndy Whitcroft } 20268905a67cSAndy Whitcroft build_types(); 20270776e594SAndy Whitcroft } else { 20280776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 20298905a67cSAndy Whitcroft } 20308905a67cSAndy Whitcroft} 20318905a67cSAndy Whitcroft 20326c72ffaaSAndy Whitcroftmy $prefix = ''; 20336c72ffaaSAndy Whitcroft 2034000d1cc1SJoe Perchessub show_type { 2035cbec18afSJoe Perches my ($type) = @_; 203691bfe484SJoe Perches 2037522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2038522b837cSAlexey Dobriyan 2039cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2040cbec18afSJoe Perches 2041cbec18afSJoe Perches return !defined $ignore_type{$type}; 2042000d1cc1SJoe Perches} 2043000d1cc1SJoe Perches 2044f0a594c1SAndy Whitcroftsub report { 2045cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2046cbec18afSJoe Perches 2047cbec18afSJoe Perches if (!show_type($type) || 2048cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2049773647a0SAndy Whitcroft return 0; 2050773647a0SAndy Whitcroft } 205157230297SJoe Perches my $output = ''; 2052737c0767SJohn Brooks if ($color) { 205357230297SJoe Perches if ($level eq 'ERROR') { 205457230297SJoe Perches $output .= RED; 205557230297SJoe Perches } elsif ($level eq 'WARNING') { 205657230297SJoe Perches $output .= YELLOW; 2057000d1cc1SJoe Perches } else { 205857230297SJoe Perches $output .= GREEN; 2059000d1cc1SJoe Perches } 206057230297SJoe Perches } 206157230297SJoe Perches $output .= $prefix . $level . ':'; 206257230297SJoe Perches if ($show_types) { 2063737c0767SJohn Brooks $output .= BLUE if ($color); 206457230297SJoe Perches $output .= "$type:"; 206557230297SJoe Perches } 2066737c0767SJohn Brooks $output .= RESET if ($color); 206757230297SJoe Perches $output .= ' ' . $msg . "\n"; 206834d8815fSJoe Perches 206934d8815fSJoe Perches if ($showfile) { 207034d8815fSJoe Perches my @lines = split("\n", $output, -1); 207134d8815fSJoe Perches splice(@lines, 1, 1); 207234d8815fSJoe Perches $output = join("\n", @lines); 207334d8815fSJoe Perches } 207457230297SJoe Perches $output = (split('\n', $output))[0] . "\n" if ($terse); 20758905a67cSAndy Whitcroft 207657230297SJoe Perches push(our @report, $output); 2077773647a0SAndy Whitcroft 2078773647a0SAndy Whitcroft return 1; 2079f0a594c1SAndy Whitcroft} 2080cbec18afSJoe Perches 2081f0a594c1SAndy Whitcroftsub report_dump { 208213214adfSAndy Whitcroft our @report; 2083f0a594c1SAndy Whitcroft} 2084000d1cc1SJoe Perches 2085d752fcc8SJoe Perchessub fixup_current_range { 2086d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2087d752fcc8SJoe Perches 2088d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2089d752fcc8SJoe Perches my $o = $1; 2090d752fcc8SJoe Perches my $l = $2; 2091d752fcc8SJoe Perches my $no = $o + $offset; 2092d752fcc8SJoe Perches my $nl = $l + $length; 2093d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2094d752fcc8SJoe Perches } 2095d752fcc8SJoe Perches} 2096d752fcc8SJoe Perches 2097d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2098d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2099d752fcc8SJoe Perches 2100d752fcc8SJoe Perches my $range_last_linenr = 0; 2101d752fcc8SJoe Perches my $delta_offset = 0; 2102d752fcc8SJoe Perches 2103d752fcc8SJoe Perches my $old_linenr = 0; 2104d752fcc8SJoe Perches my $new_linenr = 0; 2105d752fcc8SJoe Perches 2106d752fcc8SJoe Perches my $next_insert = 0; 2107d752fcc8SJoe Perches my $next_delete = 0; 2108d752fcc8SJoe Perches 2109d752fcc8SJoe Perches my @lines = (); 2110d752fcc8SJoe Perches 2111d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2112d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2113d752fcc8SJoe Perches 2114d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2115d752fcc8SJoe Perches my $save_line = 1; 2116d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2117323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2118d752fcc8SJoe Perches $delta_offset = 0; 2119d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2120d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2121d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2122d752fcc8SJoe Perches } 2123d752fcc8SJoe Perches 2124d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2125d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2126d752fcc8SJoe Perches $save_line = 0; 2127d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2128d752fcc8SJoe Perches } 2129d752fcc8SJoe Perches 2130d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2131d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2132d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2133d752fcc8SJoe Perches $new_linenr++; 2134d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2135d752fcc8SJoe Perches } 2136d752fcc8SJoe Perches 2137d752fcc8SJoe Perches if ($save_line) { 2138d752fcc8SJoe Perches push(@lines, $line); 2139d752fcc8SJoe Perches $new_linenr++; 2140d752fcc8SJoe Perches } 2141d752fcc8SJoe Perches 2142d752fcc8SJoe Perches $old_linenr++; 2143d752fcc8SJoe Perches } 2144d752fcc8SJoe Perches 2145d752fcc8SJoe Perches return @lines; 2146d752fcc8SJoe Perches} 2147d752fcc8SJoe Perches 2148f2d7e4d4SJoe Perchessub fix_insert_line { 2149f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2150f2d7e4d4SJoe Perches 2151f2d7e4d4SJoe Perches my $inserted = { 2152f2d7e4d4SJoe Perches LINENR => $linenr, 2153f2d7e4d4SJoe Perches LINE => $line, 2154f2d7e4d4SJoe Perches }; 2155f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2156f2d7e4d4SJoe Perches} 2157f2d7e4d4SJoe Perches 2158f2d7e4d4SJoe Perchessub fix_delete_line { 2159f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2160f2d7e4d4SJoe Perches 2161f2d7e4d4SJoe Perches my $deleted = { 2162f2d7e4d4SJoe Perches LINENR => $linenr, 2163f2d7e4d4SJoe Perches LINE => $line, 2164f2d7e4d4SJoe Perches }; 2165f2d7e4d4SJoe Perches 2166f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2167f2d7e4d4SJoe Perches} 2168f2d7e4d4SJoe Perches 2169de7d4f0eSAndy Whitcroftsub ERROR { 2170cbec18afSJoe Perches my ($type, $msg) = @_; 2171cbec18afSJoe Perches 2172cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2173de7d4f0eSAndy Whitcroft our $clean = 0; 21746c72ffaaSAndy Whitcroft our $cnt_error++; 21753705ce5bSJoe Perches return 1; 2176de7d4f0eSAndy Whitcroft } 21773705ce5bSJoe Perches return 0; 2178773647a0SAndy Whitcroft} 2179de7d4f0eSAndy Whitcroftsub WARN { 2180cbec18afSJoe Perches my ($type, $msg) = @_; 2181cbec18afSJoe Perches 2182cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2183de7d4f0eSAndy Whitcroft our $clean = 0; 21846c72ffaaSAndy Whitcroft our $cnt_warn++; 21853705ce5bSJoe Perches return 1; 2186de7d4f0eSAndy Whitcroft } 21873705ce5bSJoe Perches return 0; 2188773647a0SAndy Whitcroft} 2189de7d4f0eSAndy Whitcroftsub CHK { 2190cbec18afSJoe Perches my ($type, $msg) = @_; 2191cbec18afSJoe Perches 2192cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2193de7d4f0eSAndy Whitcroft our $clean = 0; 21946c72ffaaSAndy Whitcroft our $cnt_chk++; 21953705ce5bSJoe Perches return 1; 21966c72ffaaSAndy Whitcroft } 21973705ce5bSJoe Perches return 0; 2198de7d4f0eSAndy Whitcroft} 2199de7d4f0eSAndy Whitcroft 22006ecd9674SAndy Whitcroftsub check_absolute_file { 22016ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 22026ecd9674SAndy Whitcroft my $file = $absolute; 22036ecd9674SAndy Whitcroft 22046ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 22056ecd9674SAndy Whitcroft 22066ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 22076ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 22086ecd9674SAndy Whitcroft if (-f "$root/$file") { 22096ecd9674SAndy Whitcroft ##print "file<$file>\n"; 22106ecd9674SAndy Whitcroft last; 22116ecd9674SAndy Whitcroft } 22126ecd9674SAndy Whitcroft } 22136ecd9674SAndy Whitcroft if (! -f _) { 22146ecd9674SAndy Whitcroft return 0; 22156ecd9674SAndy Whitcroft } 22166ecd9674SAndy Whitcroft 22176ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 22186ecd9674SAndy Whitcroft my $prefix = $absolute; 22196ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 22206ecd9674SAndy Whitcroft 22216ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 22226ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2223000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2224000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 22256ecd9674SAndy Whitcroft } 22266ecd9674SAndy Whitcroft} 22276ecd9674SAndy Whitcroft 22283705ce5bSJoe Perchessub trim { 22293705ce5bSJoe Perches my ($string) = @_; 22303705ce5bSJoe Perches 2231b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2232b34c648bSJoe Perches 2233b34c648bSJoe Perches return $string; 2234b34c648bSJoe Perches} 2235b34c648bSJoe Perches 2236b34c648bSJoe Perchessub ltrim { 2237b34c648bSJoe Perches my ($string) = @_; 2238b34c648bSJoe Perches 2239b34c648bSJoe Perches $string =~ s/^\s+//; 2240b34c648bSJoe Perches 2241b34c648bSJoe Perches return $string; 2242b34c648bSJoe Perches} 2243b34c648bSJoe Perches 2244b34c648bSJoe Perchessub rtrim { 2245b34c648bSJoe Perches my ($string) = @_; 2246b34c648bSJoe Perches 2247b34c648bSJoe Perches $string =~ s/\s+$//; 22483705ce5bSJoe Perches 22493705ce5bSJoe Perches return $string; 22503705ce5bSJoe Perches} 22513705ce5bSJoe Perches 225252ea8506SJoe Perchessub string_find_replace { 225352ea8506SJoe Perches my ($string, $find, $replace) = @_; 225452ea8506SJoe Perches 225552ea8506SJoe Perches $string =~ s/$find/$replace/g; 225652ea8506SJoe Perches 225752ea8506SJoe Perches return $string; 225852ea8506SJoe Perches} 225952ea8506SJoe Perches 22603705ce5bSJoe Perchessub tabify { 22613705ce5bSJoe Perches my ($leading) = @_; 22623705ce5bSJoe Perches 2263713a09deSAntonio Borneo my $source_indent = $tabsize; 22643705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 22653705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 22663705ce5bSJoe Perches 22673705ce5bSJoe Perches #convert leading spaces to tabs 22683705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 22693705ce5bSJoe Perches #Remove spaces before a tab 22703705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 22713705ce5bSJoe Perches 22723705ce5bSJoe Perches return "$leading"; 22733705ce5bSJoe Perches} 22743705ce5bSJoe Perches 2275d1fe9c09SJoe Perchessub pos_last_openparen { 2276d1fe9c09SJoe Perches my ($line) = @_; 2277d1fe9c09SJoe Perches 2278d1fe9c09SJoe Perches my $pos = 0; 2279d1fe9c09SJoe Perches 2280d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2281d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2282d1fe9c09SJoe Perches 2283d1fe9c09SJoe Perches my $last_openparen = 0; 2284d1fe9c09SJoe Perches 2285d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2286d1fe9c09SJoe Perches return -1; 2287d1fe9c09SJoe Perches } 2288d1fe9c09SJoe Perches 2289d1fe9c09SJoe Perches my $len = length($line); 2290d1fe9c09SJoe Perches 2291d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2292d1fe9c09SJoe Perches my $string = substr($line, $pos); 2293d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2294d1fe9c09SJoe Perches $pos += length($1) - 1; 2295d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2296d1fe9c09SJoe Perches $last_openparen = $pos; 2297d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2298d1fe9c09SJoe Perches last; 2299d1fe9c09SJoe Perches } 2300d1fe9c09SJoe Perches } 2301d1fe9c09SJoe Perches 230291cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2303d1fe9c09SJoe Perches} 2304d1fe9c09SJoe Perches 2305f36d3eb8SJoe Perchessub get_raw_comment { 2306f36d3eb8SJoe Perches my ($line, $rawline) = @_; 2307f36d3eb8SJoe Perches my $comment = ''; 2308f36d3eb8SJoe Perches 2309f36d3eb8SJoe Perches for my $i (0 .. (length($line) - 1)) { 2310f36d3eb8SJoe Perches if (substr($line, $i, 1) eq "$;") { 2311f36d3eb8SJoe Perches $comment .= substr($rawline, $i, 1); 2312f36d3eb8SJoe Perches } 2313f36d3eb8SJoe Perches } 2314f36d3eb8SJoe Perches 2315f36d3eb8SJoe Perches return $comment; 2316f36d3eb8SJoe Perches} 2317f36d3eb8SJoe Perches 23180a920b5bSAndy Whitcroftsub process { 23190a920b5bSAndy Whitcroft my $filename = shift; 23200a920b5bSAndy Whitcroft 23210a920b5bSAndy Whitcroft my $linenr=0; 23220a920b5bSAndy Whitcroft my $prevline=""; 2323c2fdda0dSAndy Whitcroft my $prevrawline=""; 23240a920b5bSAndy Whitcroft my $stashline=""; 2325c2fdda0dSAndy Whitcroft my $stashrawline=""; 23260a920b5bSAndy Whitcroft 23274a0df2efSAndy Whitcroft my $length; 23280a920b5bSAndy Whitcroft my $indent; 23290a920b5bSAndy Whitcroft my $previndent=0; 23300a920b5bSAndy Whitcroft my $stashindent=0; 23310a920b5bSAndy Whitcroft 2332de7d4f0eSAndy Whitcroft our $clean = 1; 23330a920b5bSAndy Whitcroft my $signoff = 0; 2334cd261496SGeert Uytterhoeven my $author = ''; 2335cd261496SGeert Uytterhoeven my $authorsignoff = 0; 23360a920b5bSAndy Whitcroft my $is_patch = 0; 2337133712a2SRob Herring my $is_binding_patch = -1; 233829ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 233915662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 234044d303ebSJoe Perches my $has_patch_separator = 0; #Found a --- line 2341ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2342490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2343bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 23442a076f40SJoe Perches my $commit_log_long_line = 0; 2345e518e9a5SJoe Perches my $commit_log_has_diff = 0; 234613f1937eSJoe Perches my $reported_maintainer_file = 0; 2347fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2348fa64205dSPasi Savanainen 2349365dd4eaSJoe Perches my $last_blank_line = 0; 23505e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2351365dd4eaSJoe Perches 235213214adfSAndy Whitcroft our @report = (); 23536c72ffaaSAndy Whitcroft our $cnt_lines = 0; 23546c72ffaaSAndy Whitcroft our $cnt_error = 0; 23556c72ffaaSAndy Whitcroft our $cnt_warn = 0; 23566c72ffaaSAndy Whitcroft our $cnt_chk = 0; 23576c72ffaaSAndy Whitcroft 23580a920b5bSAndy Whitcroft # Trace the real file/line as we go. 23590a920b5bSAndy Whitcroft my $realfile = ''; 23600a920b5bSAndy Whitcroft my $realline = 0; 23610a920b5bSAndy Whitcroft my $realcnt = 0; 23620a920b5bSAndy Whitcroft my $here = ''; 236377cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 23640a920b5bSAndy Whitcroft my $in_comment = 0; 2365c2fdda0dSAndy Whitcroft my $comment_edge = 0; 23660a920b5bSAndy Whitcroft my $first_line = 0; 23671e855726SWolfram Sang my $p1_prefix = ''; 23680a920b5bSAndy Whitcroft 236913214adfSAndy Whitcroft my $prev_values = 'E'; 237013214adfSAndy Whitcroft 237113214adfSAndy Whitcroft # suppression flags 2372773647a0SAndy Whitcroft my %suppress_ifbraces; 2373170d3a22SAndy Whitcroft my %suppress_whiletrailers; 23742b474a1aSAndy Whitcroft my %suppress_export; 23753e469cdcSAndy Whitcroft my $suppress_statement = 0; 2376653d4876SAndy Whitcroft 23777e51f197SJoe Perches my %signatures = (); 2378323c1260SJoe Perches 2379c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2380de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2381c2fdda0dSAndy Whitcroft # 2382de7d4f0eSAndy Whitcroft my @setup_docs = (); 2383de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2384773647a0SAndy Whitcroft 2385d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2386d8b07710SJoe Perches 23879f3a8992SRob Herring my $checklicenseline = 1; 23889f3a8992SRob Herring 2389773647a0SAndy Whitcroft sanitise_line_reset(); 2390c2fdda0dSAndy Whitcroft my $line; 2391c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2392773647a0SAndy Whitcroft $linenr++; 2393773647a0SAndy Whitcroft $line = $rawline; 2394c2fdda0dSAndy Whitcroft 23953705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 23963705ce5bSJoe Perches 2397773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2398de7d4f0eSAndy Whitcroft $setup_docs = 0; 23998c27ceffSMauro Carvalho Chehab if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { 2400de7d4f0eSAndy Whitcroft $setup_docs = 1; 2401de7d4f0eSAndy Whitcroft } 2402773647a0SAndy Whitcroft #next; 2403de7d4f0eSAndy Whitcroft } 240474fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2405773647a0SAndy Whitcroft $realline=$1-1; 2406773647a0SAndy Whitcroft if (defined $2) { 2407773647a0SAndy Whitcroft $realcnt=$3+1; 2408773647a0SAndy Whitcroft } else { 2409773647a0SAndy Whitcroft $realcnt=1+1; 2410773647a0SAndy Whitcroft } 2411c45dcabdSAndy Whitcroft $in_comment = 0; 2412773647a0SAndy Whitcroft 2413773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2414773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2415773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2416773647a0SAndy Whitcroft # at context start. 2417773647a0SAndy Whitcroft my $edge; 241801fa9147SAndy Whitcroft my $cnt = $realcnt; 241901fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 242001fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 242101fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 242201fa9147SAndy Whitcroft $cnt--; 242301fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2424721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2425fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2426fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2427fae17daeSAndy Whitcroft ($edge) = $1; 2428fae17daeSAndy Whitcroft last; 2429fae17daeSAndy Whitcroft } 2430773647a0SAndy Whitcroft } 2431773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2432773647a0SAndy Whitcroft $in_comment = 1; 2433773647a0SAndy Whitcroft } 2434773647a0SAndy Whitcroft 2435773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2436773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2437773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2438773647a0SAndy Whitcroft if (!defined $edge && 243983242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2440773647a0SAndy Whitcroft { 2441773647a0SAndy Whitcroft $in_comment = 1; 2442773647a0SAndy Whitcroft } 2443773647a0SAndy Whitcroft 2444773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2445773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2446773647a0SAndy Whitcroft 2447171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2448773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2449171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2450773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2451773647a0SAndy Whitcroft } 2452773647a0SAndy Whitcroft push(@lines, $line); 2453773647a0SAndy Whitcroft 2454773647a0SAndy Whitcroft if ($realcnt > 1) { 2455773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2456773647a0SAndy Whitcroft } else { 2457773647a0SAndy Whitcroft $realcnt = 0; 2458773647a0SAndy Whitcroft } 2459773647a0SAndy Whitcroft 2460773647a0SAndy Whitcroft #print "==>$rawline\n"; 2461773647a0SAndy Whitcroft #print "-->$line\n"; 2462de7d4f0eSAndy Whitcroft 2463de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2464de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2465de7d4f0eSAndy Whitcroft } 2466de7d4f0eSAndy Whitcroft } 2467de7d4f0eSAndy Whitcroft 24686c72ffaaSAndy Whitcroft $prefix = ''; 24696c72ffaaSAndy Whitcroft 2470773647a0SAndy Whitcroft $realcnt = 0; 2471773647a0SAndy Whitcroft $linenr = 0; 2472194f66fcSJoe Perches $fixlinenr = -1; 24730a920b5bSAndy Whitcroft foreach my $line (@lines) { 24740a920b5bSAndy Whitcroft $linenr++; 2475194f66fcSJoe Perches $fixlinenr++; 24761b5539b1SJoe Perches my $sline = $line; #copy of $line 24771b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 24780a920b5bSAndy Whitcroft 2479c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 2480f36d3eb8SJoe Perches my $raw_comment = get_raw_comment($line, $rawline); 24816c72ffaaSAndy Whitcroft 248212c253abSJoe Perches# check if it's a mode change, rename or start of a patch 248312c253abSJoe Perches if (!$in_commit_log && 248412c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 248512c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 248612c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 248712c253abSJoe Perches $is_patch = 1; 248812c253abSJoe Perches } 248912c253abSJoe Perches 24900a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2491e518e9a5SJoe Perches if (!$in_commit_log && 249274fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 249374fd4f34SJoe Perches my $context = $4; 24940a920b5bSAndy Whitcroft $is_patch = 1; 24954a0df2efSAndy Whitcroft $first_line = $linenr + 1; 24960a920b5bSAndy Whitcroft $realline=$1-1; 24970a920b5bSAndy Whitcroft if (defined $2) { 24980a920b5bSAndy Whitcroft $realcnt=$3+1; 24990a920b5bSAndy Whitcroft } else { 25000a920b5bSAndy Whitcroft $realcnt=1+1; 25010a920b5bSAndy Whitcroft } 2502c2fdda0dSAndy Whitcroft annotate_reset(); 250313214adfSAndy Whitcroft $prev_values = 'E'; 250413214adfSAndy Whitcroft 2505773647a0SAndy Whitcroft %suppress_ifbraces = (); 2506170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 25072b474a1aSAndy Whitcroft %suppress_export = (); 25083e469cdcSAndy Whitcroft $suppress_statement = 0; 250974fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 251074fd4f34SJoe Perches $context_function = $1; 251174fd4f34SJoe Perches } else { 251274fd4f34SJoe Perches undef $context_function; 251374fd4f34SJoe Perches } 25140a920b5bSAndy Whitcroft next; 25150a920b5bSAndy Whitcroft 25164a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 25174a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 25184a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2519773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 25200a920b5bSAndy Whitcroft $realline++; 2521d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 25220a920b5bSAndy Whitcroft 25234a0df2efSAndy Whitcroft # Measure the line length and indent. 2524c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 25250a920b5bSAndy Whitcroft 25260a920b5bSAndy Whitcroft # Track the previous line. 25270a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 25280a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2529c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2530c2fdda0dSAndy Whitcroft 2531773647a0SAndy Whitcroft #warn "line<$line>\n"; 25326c72ffaaSAndy Whitcroft 2533d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2534d8aaf121SAndy Whitcroft $realcnt--; 25350a920b5bSAndy Whitcroft } 25360a920b5bSAndy Whitcroft 2537cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2538cc77cdcaSAndy Whitcroft 25396c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 25406c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2541773647a0SAndy Whitcroft 25422ac73b4fSJoe Perches my $found_file = 0; 2543773647a0SAndy Whitcroft # extract the filename as it passes 25443bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 25453bf9a009SRabin Vincent $realfile = $1; 25462b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2547270c49a0SJoe Perches $in_commit_log = 0; 25482ac73b4fSJoe Perches $found_file = 1; 25493bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2550773647a0SAndy Whitcroft $realfile = $1; 25512b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2552270c49a0SJoe Perches $in_commit_log = 0; 25531e855726SWolfram Sang 25541e855726SWolfram Sang $p1_prefix = $1; 2555e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2556e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2557000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2558000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 25591e855726SWolfram Sang } 2560773647a0SAndy Whitcroft 2561c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2562000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2563000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2564773647a0SAndy Whitcroft } 25652ac73b4fSJoe Perches $found_file = 1; 25662ac73b4fSJoe Perches } 25672ac73b4fSJoe Perches 256834d8815fSJoe Perches#make up the handle for any error we report on this line 256934d8815fSJoe Perches if ($showfile) { 257034d8815fSJoe Perches $prefix = "$realfile:$realline: " 257134d8815fSJoe Perches } elsif ($emacs) { 25727d3a9f67SJoe Perches if ($file) { 25737d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 25747d3a9f67SJoe Perches } else { 257534d8815fSJoe Perches $prefix = "$filename:$linenr: "; 257634d8815fSJoe Perches } 25777d3a9f67SJoe Perches } 257834d8815fSJoe Perches 25792ac73b4fSJoe Perches if ($found_file) { 258085b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 258185b0ee18SJoe Perches WARN("OBSOLETE", 258285b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 258385b0ee18SJoe Perches } 25847bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 25852ac73b4fSJoe Perches $check = 1; 25862ac73b4fSJoe Perches } else { 25872ac73b4fSJoe Perches $check = $check_orig; 25882ac73b4fSJoe Perches } 25899f3a8992SRob Herring $checklicenseline = 1; 2590133712a2SRob Herring 2591133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2592133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2593133712a2SRob Herring 2594133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2595133712a2SRob Herring 2596133712a2SRob Herring if (($last_binding_patch != -1) && 2597133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2598133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2599133712a2SRob Herring "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n"); 2600133712a2SRob Herring } 2601133712a2SRob Herring } 2602133712a2SRob Herring 2603773647a0SAndy Whitcroft next; 2604773647a0SAndy Whitcroft } 2605773647a0SAndy Whitcroft 2606389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 26070a920b5bSAndy Whitcroft 2608c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2609c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2610c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 26110a920b5bSAndy Whitcroft 26126c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 26136c72ffaaSAndy Whitcroft 2614490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2615490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2616490b292cSJoe Perches if ($in_commit_log) { 2617490b292cSJoe Perches if ($line !~ /^\s*$/) { 2618490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2619490b292cSJoe Perches } 2620490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2621490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2622490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2623490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2624490b292cSJoe Perches } 2625490b292cSJoe Perches 2626e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2627e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 2628e518e9a5SJoe Perches (($line =~ m@^\s+diff\b.*a/[\w/]+@ && 2629e518e9a5SJoe Perches $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || 2630e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2631e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2632e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2633e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2634e518e9a5SJoe Perches $commit_log_has_diff = 1; 2635e518e9a5SJoe Perches } 2636e518e9a5SJoe Perches 26373bf9a009SRabin Vincent# Check for incorrect file permissions 26383bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 26393bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 264004db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 264104db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2642000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2643000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 26443bf9a009SRabin Vincent } 26453bf9a009SRabin Vincent } 26463bf9a009SRabin Vincent 2647cd261496SGeert Uytterhoeven# Check the patch for a From: 2648cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2649cd261496SGeert Uytterhoeven $author = $1; 2650cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2651cd261496SGeert Uytterhoeven $author =~ s/"//g; 2652dfa05c28SJoe Perches $author = reformat_email($author); 2653cd261496SGeert Uytterhoeven } 2654cd261496SGeert Uytterhoeven 265520112475SJoe Perches# Check the patch for a signoff: 2656dfa05c28SJoe Perches if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { 26574a0df2efSAndy Whitcroft $signoff++; 265815662b3eSJoe Perches $in_commit_log = 0; 2659cd261496SGeert Uytterhoeven if ($author ne '') { 2660dfa05c28SJoe Perches if (same_email_addresses($1, $author)) { 2661cd261496SGeert Uytterhoeven $authorsignoff = 1; 2662cd261496SGeert Uytterhoeven } 2663cd261496SGeert Uytterhoeven } 26640a920b5bSAndy Whitcroft } 266520112475SJoe Perches 266644d303ebSJoe Perches# Check for patch separator 266744d303ebSJoe Perches if ($line =~ /^---$/) { 266844d303ebSJoe Perches $has_patch_separator = 1; 266944d303ebSJoe Perches $in_commit_log = 0; 267044d303ebSJoe Perches } 267144d303ebSJoe Perches 2672e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2673e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2674e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2675e0d975b1SJoe Perches $reported_maintainer_file = 1; 2676e0d975b1SJoe Perches } 2677e0d975b1SJoe Perches 267820112475SJoe Perches# Check signature styles 2679270c49a0SJoe Perches if (!$in_header_lines && 2680ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 268120112475SJoe Perches my $space_before = $1; 268220112475SJoe Perches my $sign_off = $2; 268320112475SJoe Perches my $space_after = $3; 268420112475SJoe Perches my $email = $4; 268520112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 268620112475SJoe Perches 2687ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2688ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2689ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2690ce0338dfSJoe Perches } 269120112475SJoe Perches if (defined $space_before && $space_before ne "") { 26923705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 26933705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 26943705ce5bSJoe Perches $fix) { 2695194f66fcSJoe Perches $fixed[$fixlinenr] = 26963705ce5bSJoe Perches "$ucfirst_sign_off $email"; 26973705ce5bSJoe Perches } 269820112475SJoe Perches } 269920112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 27003705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 27013705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 27023705ce5bSJoe Perches $fix) { 2703194f66fcSJoe Perches $fixed[$fixlinenr] = 27043705ce5bSJoe Perches "$ucfirst_sign_off $email"; 27053705ce5bSJoe Perches } 27063705ce5bSJoe Perches 270720112475SJoe Perches } 270820112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 27093705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 27103705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 27113705ce5bSJoe Perches $fix) { 2712194f66fcSJoe Perches $fixed[$fixlinenr] = 27133705ce5bSJoe Perches "$ucfirst_sign_off $email"; 27143705ce5bSJoe Perches } 271520112475SJoe Perches } 271620112475SJoe Perches 2717dfa05c28SJoe Perches my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); 271820112475SJoe Perches my $suggested_email = format_email(($email_name, $email_address)); 271920112475SJoe Perches if ($suggested_email eq "") { 2720000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 2721000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 272220112475SJoe Perches } else { 272320112475SJoe Perches my $dequoted = $suggested_email; 272420112475SJoe Perches $dequoted =~ s/^"//; 272520112475SJoe Perches $dequoted =~ s/" </ </; 272620112475SJoe Perches # Don't force email to have quotes 272720112475SJoe Perches # Allow just an angle bracketed address 2728dfa05c28SJoe Perches if (!same_email_addresses($email, $suggested_email)) { 2729000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 2730000d1cc1SJoe Perches "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 273120112475SJoe Perches } 27320a920b5bSAndy Whitcroft } 27337e51f197SJoe Perches 27347e51f197SJoe Perches# Check for duplicate signatures 27357e51f197SJoe Perches my $sig_nospace = $line; 27367e51f197SJoe Perches $sig_nospace =~ s/\s//g; 27377e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 27387e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 27397e51f197SJoe Perches WARN("BAD_SIGN_OFF", 27407e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 27417e51f197SJoe Perches } else { 27427e51f197SJoe Perches $signatures{$sig_nospace} = 1; 27437e51f197SJoe Perches } 27446c5d24eeSSean Christopherson 27456c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 27466c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 27476c5d24eeSSean Christopherson if ($email eq $author) { 27486c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 27496c5d24eeSSean Christopherson "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); 27506c5d24eeSSean Christopherson } 27516c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 27526c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 27536c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); 27546c5d24eeSSean Christopherson } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { 27556c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 27566c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 27576c5d24eeSSean Christopherson } elsif ($1 ne $email) { 27586c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 27596c5d24eeSSean Christopherson "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 27606c5d24eeSSean Christopherson } 27616c5d24eeSSean Christopherson } 27620a920b5bSAndy Whitcroft } 27630a920b5bSAndy Whitcroft 2764a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 2765a2fe16b9SJoe Perches if ($in_header_lines && 2766a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 2767a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 2768a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 2769a2fe16b9SJoe Perches } 2770a2fe16b9SJoe Perches 277144d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context 277244d303ebSJoe Perches if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) { 27737ebd05efSChristopher Covington ERROR("GERRIT_CHANGE_ID", 277444d303ebSJoe Perches "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr); 27757ebd05efSChristopher Covington } 27767ebd05efSChristopher Covington 2777369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 2778369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2779369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 2780369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 2781369c8dd3SJoe Perches # timestamp 2782634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 2783634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 2784634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 2785634cffccSJoe Perches # stack dump address styles 2786369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 2787369c8dd3SJoe Perches } 2788369c8dd3SJoe Perches 27892a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 27902a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 2791bf4daf12SJoe Perches length($line) > 75 && 2792bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 2793bf4daf12SJoe Perches # file delta changes 2794bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 2795bf4daf12SJoe Perches # filename then : 2796bf4daf12SJoe Perches $line =~ /^\s*(?:Fixes:|Link:)/i || 2797bf4daf12SJoe Perches # A Fixes: or Link: line 2798bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 27992a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 28002a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 28012a076f40SJoe Perches $commit_log_long_line = 1; 28022a076f40SJoe Perches } 28032a076f40SJoe Perches 2804bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 2805bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 2806bf4daf12SJoe Perches $line =~ /^\s*$/) { 2807bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 2808bf4daf12SJoe Perches } 2809bf4daf12SJoe Perches 28100d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 2811369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2812a8972573SJohn Hubbard $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && 2813e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 2814fe043ea1SJoe Perches ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 2815aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 2816369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 2817bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 2818fe043ea1SJoe Perches my $init_char = "c"; 2819fe043ea1SJoe Perches my $orig_commit = ""; 28200d7835fcSJoe Perches my $short = 1; 28210d7835fcSJoe Perches my $long = 0; 28220d7835fcSJoe Perches my $case = 1; 28230d7835fcSJoe Perches my $space = 1; 28240d7835fcSJoe Perches my $hasdesc = 0; 282519c146a6SJoe Perches my $hasparens = 0; 28260d7835fcSJoe Perches my $id = '0123456789ab'; 28270d7835fcSJoe Perches my $orig_desc = "commit description"; 28280d7835fcSJoe Perches my $description = ""; 28290d7835fcSJoe Perches 2830fe043ea1SJoe Perches if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 2831fe043ea1SJoe Perches $init_char = $1; 2832fe043ea1SJoe Perches $orig_commit = lc($2); 2833fe043ea1SJoe Perches } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { 2834fe043ea1SJoe Perches $orig_commit = lc($1); 2835fe043ea1SJoe Perches } 2836fe043ea1SJoe Perches 28370d7835fcSJoe Perches $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 28380d7835fcSJoe Perches $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 28390d7835fcSJoe Perches $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 28400d7835fcSJoe Perches $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 28410d7835fcSJoe Perches if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 28420d7835fcSJoe Perches $orig_desc = $1; 284319c146a6SJoe Perches $hasparens = 1; 28440d7835fcSJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 28450d7835fcSJoe Perches defined $rawlines[$linenr] && 28460d7835fcSJoe Perches $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 28470d7835fcSJoe Perches $orig_desc = $1; 284819c146a6SJoe Perches $hasparens = 1; 2849b671fde0SJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 2850b671fde0SJoe Perches defined $rawlines[$linenr] && 2851b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 2852b671fde0SJoe Perches $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 2853b671fde0SJoe Perches $orig_desc = $1; 2854b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 2855b671fde0SJoe Perches $orig_desc .= " " . $1; 285619c146a6SJoe Perches $hasparens = 1; 28570d7835fcSJoe Perches } 28580d7835fcSJoe Perches 28590d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 28600d7835fcSJoe Perches $id, $orig_desc); 28610d7835fcSJoe Perches 2862948b133aSHeinrich Schuchardt if (defined($id) && 2863948b133aSHeinrich Schuchardt ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { 2864d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 28650d7835fcSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 28660d7835fcSJoe Perches } 2867d311cd44SJoe Perches } 2868d311cd44SJoe Perches 286913f1937eSJoe Perches# Check for added, moved or deleted files 287013f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 287113f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 287213f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 287313f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 287413f1937eSJoe Perches (defined($1) || defined($2))))) { 2875a82603a8SAndrew Jeffery $is_patch = 1; 287613f1937eSJoe Perches $reported_maintainer_file = 1; 287713f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 287813f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 287913f1937eSJoe Perches } 288013f1937eSJoe Perches 2881e400edb1SRob Herring# Check for adding new DT bindings not in schema format 2882e400edb1SRob Herring if (!$in_commit_log && 2883e400edb1SRob Herring ($line =~ /^new file mode\s*\d+\s*$/) && 2884e400edb1SRob Herring ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { 2885e400edb1SRob Herring WARN("DT_SCHEMA_BINDING_PATCH", 2886e400edb1SRob Herring "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n"); 2887e400edb1SRob Herring } 2888e400edb1SRob Herring 288900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 28908905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 2891000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 2892000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 28936c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 2894de7d4f0eSAndy Whitcroft } 2895de7d4f0eSAndy Whitcroft 2896de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 2897de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 2898171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 2899171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 2900171ae1a4SAndy Whitcroft 2901171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 2902171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 2903171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 2904171ae1a4SAndy Whitcroft 290534d99219SJoe Perches CHK("INVALID_UTF8", 2906000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 290700df344fSAndy Whitcroft } 29080a920b5bSAndy Whitcroft 290915662b3eSJoe Perches# Check if it's the start of a commit log 291015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 291115662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 2912eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 2913eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 291415662b3eSJoe Perches $in_header_lines = 0; 291515662b3eSJoe Perches $in_commit_log = 1; 2916ed43c4e5SAllen Hubbe $has_commit_log = 1; 291715662b3eSJoe Perches } 291815662b3eSJoe Perches 2919fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 2920fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 2921fa64205dSPasi Savanainen if ($in_header_lines && 2922fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 2923fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 2924fa64205dSPasi Savanainen $non_utf8_charset = 1; 2925fa64205dSPasi Savanainen } 2926fa64205dSPasi Savanainen 2927fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 292815662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 2929fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 293015662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 293115662b3eSJoe Perches } 293215662b3eSJoe Perches 2933d6430f71SJoe Perches# Check for absolute kernel paths in commit message 2934d6430f71SJoe Perches if ($tree && $in_commit_log) { 2935d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 2936d6430f71SJoe Perches my $file = $1; 2937d6430f71SJoe Perches 2938d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 2939d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 2940d6430f71SJoe Perches # 2941d6430f71SJoe Perches } else { 2942d6430f71SJoe Perches check_absolute_file($file, $herecurr); 2943d6430f71SJoe Perches } 2944d6430f71SJoe Perches } 2945d6430f71SJoe Perches } 2946d6430f71SJoe Perches 294766b47b4aSKees Cook# Check for various typo / spelling mistakes 294866d7a382SJoe Perches if (defined($misspellings) && 294966d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 2950ebfd7d62SJoe Perches while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { 295166b47b4aSKees Cook my $typo = $1; 295266b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 295366b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 295466b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 29550675a8fbSJean Delvare my $msg_level = \&WARN; 29560675a8fbSJean Delvare $msg_level = \&CHK if ($file); 29570675a8fbSJean Delvare if (&{$msg_level}("TYPO_SPELLING", 295866b47b4aSKees Cook "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && 295966b47b4aSKees Cook $fix) { 296066b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 296166b47b4aSKees Cook } 296266b47b4aSKees Cook } 296366b47b4aSKees Cook } 296466b47b4aSKees Cook 2965a8dd86bfSMatteo Croce# check for invalid commit id 2966a8dd86bfSMatteo Croce if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 2967a8dd86bfSMatteo Croce my $id; 2968a8dd86bfSMatteo Croce my $description; 2969a8dd86bfSMatteo Croce ($id, $description) = git_commit_info($2, undef, undef); 2970a8dd86bfSMatteo Croce if (!defined($id)) { 2971a8dd86bfSMatteo Croce WARN("UNKNOWN_COMMIT_ID", 2972a8dd86bfSMatteo Croce "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 2973a8dd86bfSMatteo Croce } 2974a8dd86bfSMatteo Croce } 2975a8dd86bfSMatteo Croce 297630670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 297730670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 297800df344fSAndy Whitcroft 29790a920b5bSAndy Whitcroft#trailing whitespace 29809c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 2981c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2982d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 2983d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 2984d5e616fcSJoe Perches $fix) { 2985194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 2986d5e616fcSJoe Perches } 2987c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 2988c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 29893705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 29903705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 29913705ce5bSJoe Perches $fix) { 2992194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 29933705ce5bSJoe Perches } 29943705ce5bSJoe Perches 2995d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 29960a920b5bSAndy Whitcroft } 29975368df20SAndy Whitcroft 29984783f894SJosh Triplett# Check for FSF mailing addresses. 2999109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 30001bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 30013e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 30023e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 30034783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 30040675a8fbSJean Delvare my $msg_level = \&ERROR; 30050675a8fbSJean Delvare $msg_level = \&CHK if ($file); 30060675a8fbSJean Delvare &{$msg_level}("FSF_MAILING_ADDRESS", 30074783f894SJosh Triplett "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) 30084783f894SJosh Triplett } 30094783f894SJosh Triplett 30103354957aSAndi Kleen# check for Kconfig help text having a real description 30119fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 30129fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 30133354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 3014678ae162SUlf Magnusson # 'choice' is usually the last thing on the line (though 3015678ae162SUlf Magnusson # Kconfig supports named choices), so use a word boundary 3016678ae162SUlf Magnusson # (\b) rather than a whitespace character (\s) 3017678ae162SUlf Magnusson $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 30183354957aSAndi Kleen my $length = 0; 30199fe287d7SAndy Whitcroft my $cnt = $realcnt; 30209fe287d7SAndy Whitcroft my $ln = $linenr + 1; 30219fe287d7SAndy Whitcroft my $f; 3022a1385803SAndy Whitcroft my $is_start = 0; 30239fe287d7SAndy Whitcroft my $is_end = 0; 3024a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 30259fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 30269fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 30279fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 30289fe287d7SAndy Whitcroft 30299fe287d7SAndy Whitcroft next if ($f =~ /^-/); 30308d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 3031a1385803SAndy Whitcroft 303286adf1a0SUlf Magnusson if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 3033a1385803SAndy Whitcroft $is_start = 1; 303484af7a61SUlf Magnusson } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) { 303584af7a61SUlf Magnusson if ($lines[$ln - 1] =~ "---help---") { 303684af7a61SUlf Magnusson WARN("CONFIG_DESCRIPTION", 303784af7a61SUlf Magnusson "prefer 'help' over '---help---' for new help texts\n" . $herecurr); 303884af7a61SUlf Magnusson } 3039a1385803SAndy Whitcroft $length = -1; 3040a1385803SAndy Whitcroft } 3041a1385803SAndy Whitcroft 30429fe287d7SAndy Whitcroft $f =~ s/^.//; 30433354957aSAndi Kleen $f =~ s/#.*//; 30443354957aSAndi Kleen $f =~ s/^\s+//; 30453354957aSAndi Kleen next if ($f =~ /^$/); 3046678ae162SUlf Magnusson 3047678ae162SUlf Magnusson # This only checks context lines in the patch 3048678ae162SUlf Magnusson # and so hopefully shouldn't trigger false 3049678ae162SUlf Magnusson # positives, even though some of these are 3050678ae162SUlf Magnusson # common words in help texts 3051678ae162SUlf Magnusson if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| 3052678ae162SUlf Magnusson if|endif|menu|endmenu|source)\b/x) { 30539fe287d7SAndy Whitcroft $is_end = 1; 30549fe287d7SAndy Whitcroft last; 30559fe287d7SAndy Whitcroft } 30563354957aSAndi Kleen $length++; 30573354957aSAndi Kleen } 305856193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 3059000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 306056193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 306156193274SVadim Bendebury } 3062a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 30633354957aSAndi Kleen } 30643354957aSAndi Kleen 3065628f91a2SJoe Perches# check for MAINTAINERS entries that don't have the right form 3066628f91a2SJoe Perches if ($realfile =~ /^MAINTAINERS$/ && 3067628f91a2SJoe Perches $rawline =~ /^\+[A-Z]:/ && 3068628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3069628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3070628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3071628f91a2SJoe Perches $fix) { 3072628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3073628f91a2SJoe Perches } 3074628f91a2SJoe Perches } 3075628f91a2SJoe Perches 3076327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options 3077327953e9SChristoph Jaeger if ($realfile =~ /Kconfig/ && 3078327953e9SChristoph Jaeger $line =~ /^\+\s*\bboolean\b/) { 3079327953e9SChristoph Jaeger WARN("CONFIG_TYPE_BOOLEAN", 3080327953e9SChristoph Jaeger "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 3081327953e9SChristoph Jaeger } 3082327953e9SChristoph Jaeger 3083c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3084c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3085c68e5878SArnaud Lacombe my $flag = $1; 3086c68e5878SArnaud Lacombe my $replacement = { 3087c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 3088c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 3089c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 3090c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 3091c68e5878SArnaud Lacombe }; 3092c68e5878SArnaud Lacombe 3093c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 3094c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3095c68e5878SArnaud Lacombe } 3096c68e5878SArnaud Lacombe 3097bff5da43SRob Herring# check for DT compatible documentation 30987dd05b38SFlorian Vaussard if (defined $root && 30997dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 31007dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 31017dd05b38SFlorian Vaussard 3102bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3103bff5da43SRob Herring 3104cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3105852d095dSRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3106cc93319bSFlorian Vaussard 3107bff5da43SRob Herring foreach my $compat (@compats) { 3108bff5da43SRob Herring my $compat2 = $compat; 3109185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3110185d566bSRob Herring my $compat3 = $compat; 3111185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3112185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3113bff5da43SRob Herring if ( $? >> 8 ) { 3114bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3115bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3116bff5da43SRob Herring } 3117bff5da43SRob Herring 31184fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 31194fbf32a6SFlorian Vaussard my $vendor = $1; 3120852d095dSRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3121bff5da43SRob Herring if ( $? >> 8 ) { 3122bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3123cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3124bff5da43SRob Herring } 3125bff5da43SRob Herring } 3126bff5da43SRob Herring } 3127bff5da43SRob Herring 31289f3a8992SRob Herring# check for using SPDX license tag at beginning of files 31299f3a8992SRob Herring if ($realline == $checklicenseline) { 31309f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 31319f3a8992SRob Herring $checklicenseline = 2; 31329f3a8992SRob Herring } elsif ($rawline =~ /^\+/) { 31339f3a8992SRob Herring my $comment = ""; 31349f3a8992SRob Herring if ($realfile =~ /\.(h|s|S)$/) { 31359f3a8992SRob Herring $comment = '/*'; 31369f3a8992SRob Herring } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { 31379f3a8992SRob Herring $comment = '//'; 3138c8df0ab6SLubomir Rintel } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 31399f3a8992SRob Herring $comment = '#'; 31409f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 31419f3a8992SRob Herring $comment = '..'; 31429f3a8992SRob Herring } 31439f3a8992SRob Herring 3144fdf13693SJoe Perches# check SPDX comment style for .[chsS] files 3145fdf13693SJoe Perches if ($realfile =~ /\.[chsS]$/ && 3146fdf13693SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 3147ffbce897SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 3148fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3149fdf13693SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3150fdf13693SJoe Perches } 3151fdf13693SJoe Perches 31529f3a8992SRob Herring if ($comment !~ /^$/ && 3153ffbce897SJoe Perches $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 31549f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 31559f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 31563b6e8ac9SJoe Perches } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 31573b6e8ac9SJoe Perches my $spdx_license = $1; 31583b6e8ac9SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 31593b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 31603b6e8ac9SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 31613b6e8ac9SJoe Perches } 316250c92900SLubomir Rintel if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 316350c92900SLubomir Rintel not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { 316450c92900SLubomir Rintel my $msg_level = \&WARN; 316550c92900SLubomir Rintel $msg_level = \&CHK if ($file); 316650c92900SLubomir Rintel if (&{$msg_level}("SPDX_LICENSE_TAG", 316750c92900SLubomir Rintel 316850c92900SLubomir Rintel "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 316950c92900SLubomir Rintel $fix) { 317050c92900SLubomir Rintel $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 317150c92900SLubomir Rintel } 317250c92900SLubomir Rintel } 31739f3a8992SRob Herring } 31749f3a8992SRob Herring } 31759f3a8992SRob Herring } 31769f3a8992SRob Herring 31775368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 3178d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 31795368df20SAndy Whitcroft 3180a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3181a8da38a9SJoe Perches if ($realline != $checklicenseline && 3182a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3183a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3184a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3185a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3186a8da38a9SJoe Perches } 3187a8da38a9SJoe Perches 318847e0c88bSJoe Perches# line length limit (with some exclusions) 318947e0c88bSJoe Perches# 319047e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 319147e0c88bSJoe Perches# logging functions like pr_info that end in a string 319247e0c88bSJoe Perches# lines with a single string 319347e0c88bSJoe Perches# #defines that are a single string 31942e4bbbc5SAndreas Brauchli# lines with an RFC3986 like URL 319547e0c88bSJoe Perches# 319647e0c88bSJoe Perches# There are 3 different line length message types: 3197ab1ecabfSJean Delvare# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 319847e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 319947e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 320047e0c88bSJoe Perches# 320147e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 320247e0c88bSJoe Perches# 320347e0c88bSJoe Perches 3204b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 320547e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 320647e0c88bSJoe Perches 320747e0c88bSJoe Perches # Check the allowed long line types first 320847e0c88bSJoe Perches 320947e0c88bSJoe Perches # logging functions that end in a string that starts 321047e0c88bSJoe Perches # before $max_line_length 321147e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 321247e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 321347e0c88bSJoe Perches $msg_type = ""; 321447e0c88bSJoe Perches 321547e0c88bSJoe Perches # lines with only strings (w/ possible termination) 321647e0c88bSJoe Perches # #defines with only strings 321747e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 321847e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 321947e0c88bSJoe Perches $msg_type = ""; 322047e0c88bSJoe Perches 3221cc147506SJoe Perches # More special cases 3222cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3223cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3224d560a5f8SJoe Perches $msg_type = ""; 3225d560a5f8SJoe Perches 32262e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 32272e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 32282e4bbbc5SAndreas Brauchli $msg_type = ""; 32292e4bbbc5SAndreas Brauchli 323047e0c88bSJoe Perches # Otherwise set the alternate message types 323147e0c88bSJoe Perches 323247e0c88bSJoe Perches # a comment starts before $max_line_length 323347e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 323447e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 323547e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 323647e0c88bSJoe Perches 323747e0c88bSJoe Perches # a quoted string starts before $max_line_length 323847e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 323947e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 324047e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 324147e0c88bSJoe Perches } 324247e0c88bSJoe Perches 324347e0c88bSJoe Perches if ($msg_type ne "" && 324447e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 3245*bdc48fa1SJoe Perches my $msg_level = \&WARN; 3246*bdc48fa1SJoe Perches $msg_level = \&CHK if ($file); 3247*bdc48fa1SJoe Perches &{$msg_level}($msg_type, 3248*bdc48fa1SJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 32490a920b5bSAndy Whitcroft } 325047e0c88bSJoe Perches } 32510a920b5bSAndy Whitcroft 32528905a67cSAndy Whitcroft# check for adding lines without a newline. 32538905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 3254000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 3255000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 32568905a67cSAndy Whitcroft } 32578905a67cSAndy Whitcroft 3258b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3259de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 32600a920b5bSAndy Whitcroft 32610a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 3262713a09deSAntonio Borneo# more than $tabsize must use tabs. 3263c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3264c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3265c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3266d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 32673705ce5bSJoe Perches if (ERROR("CODE_INDENT", 32683705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 32693705ce5bSJoe Perches $fix) { 3270194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 32713705ce5bSJoe Perches } 32720a920b5bSAndy Whitcroft } 32730a920b5bSAndy Whitcroft 327408e44365SAlberto Panizzo# check for space before tabs. 327508e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 327608e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 32773705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 32783705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 32793705ce5bSJoe Perches $fix) { 3280194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3281713a09deSAntonio Borneo s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 3282194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3283c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 32843705ce5bSJoe Perches } 328508e44365SAlberto Panizzo } 328608e44365SAlberto Panizzo 32876a487211SJoe Perches# check for assignments on the start of a line 32886a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 32896a487211SJoe Perches CHK("ASSIGNMENT_CONTINUATIONS", 32906a487211SJoe Perches "Assignment operator '$1' should be on the previous line\n" . $hereprev); 32916a487211SJoe Perches } 32926a487211SJoe Perches 3293d1fe9c09SJoe Perches# check for && or || at the start of a line 3294d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 3295d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 3296d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 3297d1fe9c09SJoe Perches } 3298d1fe9c09SJoe Perches 3299a91e8994SJoe Perches# check indentation starts on a tab stop 33005b57980dSJoe Perches if ($perl_version_ok && 3301bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3302a91e8994SJoe Perches my $indent = length($1); 3303713a09deSAntonio Borneo if ($indent % $tabsize) { 3304a91e8994SJoe Perches if (WARN("TABSTOP", 3305a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3306a91e8994SJoe Perches $fix) { 3307713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 3308a91e8994SJoe Perches } 3309a91e8994SJoe Perches } 3310a91e8994SJoe Perches } 3311a91e8994SJoe Perches 3312d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 33135b57980dSJoe Perches if ($perl_version_ok && 3314fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3315d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3316d1fe9c09SJoe Perches my $oldindent = $1; 3317d1fe9c09SJoe Perches my $rest = $2; 3318d1fe9c09SJoe Perches 3319d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3320d1fe9c09SJoe Perches if ($pos >= 0) { 3321b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3322b34a26f3SJoe Perches my $newindent = $2; 3323d1fe9c09SJoe Perches 3324d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3325713a09deSAntonio Borneo "\t" x ($pos / $tabsize) . 3326713a09deSAntonio Borneo " " x ($pos % $tabsize); 3327d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3328d1fe9c09SJoe Perches 3329d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3330d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 33313705ce5bSJoe Perches 33323705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 33333705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 33343705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3335194f66fcSJoe Perches $fixed[$fixlinenr] =~ 33363705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 33373705ce5bSJoe Perches } 3338d1fe9c09SJoe Perches } 3339d1fe9c09SJoe Perches } 3340d1fe9c09SJoe Perches } 3341d1fe9c09SJoe Perches 33426ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 33436ab3a970SJoe Perches# avoid checking a few false positives: 33446ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 33456ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 33466ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 33476ab3a970SJoe Perches# multiline macros that define functions 33486ab3a970SJoe Perches# known attributes or the __attribute__ keyword 33496ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 33506ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 33513705ce5bSJoe Perches if (CHK("SPACING", 3352f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 33533705ce5bSJoe Perches $fix) { 3354194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3355f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 33563705ce5bSJoe Perches } 3357aad4f614SJoe Perches } 3358aad4f614SJoe Perches 335986406b1cSJoe Perches# Block comment styles 336086406b1cSJoe Perches# Networking with an initial /* 336105880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3362fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 336385ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 336485ad978cSJoe Perches $realline > 2) { 336505880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 336605880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 336705880600SJoe Perches } 336805880600SJoe Perches 336986406b1cSJoe Perches# Block comments use * on subsequent lines 337086406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 337186406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3372a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 337361135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3374a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 337586406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 337686406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3377a605e32eSJoe Perches } 3378a605e32eSJoe Perches 337986406b1cSJoe Perches# Block comments use */ on trailing lines 338086406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3381c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3382c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3383c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 338486406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 338586406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 338605880600SJoe Perches } 338705880600SJoe Perches 338808eb9b80SJoe Perches# Block comment * alignment 338908eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3390af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3391af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3392af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 339308eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3394af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3395af207524SJoe Perches my $oldindent; 339608eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3397af207524SJoe Perches if (defined($1)) { 3398af207524SJoe Perches $oldindent = expand_tabs($1); 3399af207524SJoe Perches } else { 3400af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3401af207524SJoe Perches $oldindent = expand_tabs($1); 3402af207524SJoe Perches } 340308eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 340408eb9b80SJoe Perches my $newindent = $1; 340508eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3406af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 340708eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 340808eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 340908eb9b80SJoe Perches } 341008eb9b80SJoe Perches } 341108eb9b80SJoe Perches 34127f619191SJoe Perches# check for missing blank lines after struct/union declarations 34137f619191SJoe Perches# with exceptions for various attributes and macros 34147f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 34157f619191SJoe Perches $line =~ /^\+/ && 34167f619191SJoe Perches !($line =~ /^\+\s*$/ || 34177f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 34187f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 34197f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 34207f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 34217f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 34227f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 34230bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 34247f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3425d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3426d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3427d752fcc8SJoe Perches $fix) { 3428f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3429d752fcc8SJoe Perches } 34307f619191SJoe Perches } 34317f619191SJoe Perches 3432365dd4eaSJoe Perches# check for multiple consecutive blank lines 3433365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3434365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3435365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3436d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3437d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3438d752fcc8SJoe Perches $fix) { 3439f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3440d752fcc8SJoe Perches } 3441d752fcc8SJoe Perches 3442365dd4eaSJoe Perches $last_blank_line = $linenr; 3443365dd4eaSJoe Perches } 3444365dd4eaSJoe Perches 34453b617e3bSJoe Perches# check for missing blank lines after declarations 34463f7bac03SJoe Perches if ($sline =~ /^\+\s+\S/ && #Not at char 1 34473f7bac03SJoe Perches # actual declarations 34483f7bac03SJoe Perches ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 34495a4e1fd3SJoe Perches # function pointer declarations 34505a4e1fd3SJoe Perches $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 34513f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 34523f7bac03SJoe Perches $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 34533f7bac03SJoe Perches # known declaration macros 34543f7bac03SJoe Perches $prevline =~ /^\+\s+$declaration_macros/) && 34553f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 34563f7bac03SJoe Perches !($prevline =~ /^\+\s+$c90_Keywords\b/ || 34573f7bac03SJoe Perches # other possible extensions of declaration lines 34583f7bac03SJoe Perches $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 34593f7bac03SJoe Perches # not starting a section or a macro "\" extended line 34603f7bac03SJoe Perches $prevline =~ /(?:\{\s*|\\)$/) && 34613f7bac03SJoe Perches # looks like a declaration 34623f7bac03SJoe Perches !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 34635a4e1fd3SJoe Perches # function pointer declarations 34645a4e1fd3SJoe Perches $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 34653f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 34663f7bac03SJoe Perches $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 34673f7bac03SJoe Perches # known declaration macros 34683f7bac03SJoe Perches $sline =~ /^\+\s+$declaration_macros/ || 34693f7bac03SJoe Perches # start of struct or union or enum 3470328b5f41SJoe Perches $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 34713f7bac03SJoe Perches # start or end of block or continuation of declaration 34723f7bac03SJoe Perches $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 34733f7bac03SJoe Perches # bitfield continuation 34743f7bac03SJoe Perches $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 34753f7bac03SJoe Perches # other possible extensions of declaration lines 34763f7bac03SJoe Perches $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 34773f7bac03SJoe Perches # indentation of previous and current line are the same 34783f7bac03SJoe Perches (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 3479d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3480d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3481d752fcc8SJoe Perches $fix) { 3482f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3483d752fcc8SJoe Perches } 34843b617e3bSJoe Perches } 34853b617e3bSJoe Perches 34865f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 34876b4c5bebSAndy Whitcroft# Exceptions: 34886b4c5bebSAndy Whitcroft# 1) within comments 34896b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 34906b4c5bebSAndy Whitcroft# 3) hanging labels 34913705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 34925f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 34933705ce5bSJoe Perches if (WARN("LEADING_SPACE", 34943705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 34953705ce5bSJoe Perches $fix) { 3496194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 34973705ce5bSJoe Perches } 34985f7ddae6SRaffaele Recalcati } 34995f7ddae6SRaffaele Recalcati 3500b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3501b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3502b9ea10d6SAndy Whitcroft 35035751a24eSJoe Perches# check for unusual line ending [ or ( 35045751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 35055751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 35065751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 35075751a24eSJoe Perches } 35085751a24eSJoe Perches 35094dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 35104dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 35114dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 35124dbed76fSJoe Perches $context_function = $1; 35134dbed76fSJoe Perches } 35144dbed76fSJoe Perches 35154dbed76fSJoe Perches# check if this appears to be the end of function declaration 35164dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 35174dbed76fSJoe Perches undef $context_function; 35184dbed76fSJoe Perches } 35194dbed76fSJoe Perches 3520032a4c0fSJoe Perches# check indentation of any line with a bare else 3521840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3522032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3523032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3524032a4c0fSJoe Perches my $tabs = length($1) + 1; 3525840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3526840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3527840080a0SJoe Perches defined $lines[$linenr] && 3528840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3529032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3530032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3531032a4c0fSJoe Perches } 3532032a4c0fSJoe Perches } 3533032a4c0fSJoe Perches 3534c00df19aSJoe Perches# check indentation of a line with a break; 3535c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs 3536c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3537c00df19aSJoe Perches my $tabs = $1; 3538c00df19aSJoe Perches if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 3539c00df19aSJoe Perches WARN("UNNECESSARY_BREAK", 3540c00df19aSJoe Perches "break is not useful after a goto or return\n" . $hereprev); 3541c00df19aSJoe Perches } 3542c00df19aSJoe Perches } 3543c00df19aSJoe Perches 3544c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3545cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3546000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3547000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3548c2fdda0dSAndy Whitcroft } 354922f2a2efSAndy Whitcroft 355056e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 355156e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 355256e77d70SJoe Perches WARN("HOTPLUG_SECTION", 355356e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 355456e77d70SJoe Perches } 355556e77d70SJoe Perches 35569c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 35572b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 35582b474a1aSAndy Whitcroft $realline_next); 35593e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 3560ca819864SJoe Perches if ($linenr > $suppress_statement && 35611b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3562170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3563f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3564171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3565171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3566171ae1a4SAndy Whitcroft 35673e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 35683e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 35693e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 35703e469cdcSAndy Whitcroft # until we hit end of it. 35713e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 35723e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 35733e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 35743e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 35753e469cdcSAndy Whitcroft } 3576f74bd194SAndy Whitcroft 35772b474a1aSAndy Whitcroft # Find the real next line. 35782b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 35792b474a1aSAndy Whitcroft if (defined $realline_next && 35802b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 35812b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 35822b474a1aSAndy Whitcroft $realline_next++; 35832b474a1aSAndy Whitcroft } 35842b474a1aSAndy Whitcroft 3585171ae1a4SAndy Whitcroft my $s = $stat; 3586171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3587cf655043SAndy Whitcroft 3588c2fdda0dSAndy Whitcroft # Ignore goto labels. 3589171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3590c2fdda0dSAndy Whitcroft 3591c2fdda0dSAndy Whitcroft # Ignore functions being called 3592171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3593c2fdda0dSAndy Whitcroft 3594463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3595463f2864SAndy Whitcroft 3596c45dcabdSAndy Whitcroft # declarations always start with types 3597d2506586SAndy 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) { 3598c45dcabdSAndy Whitcroft my $type = $1; 3599c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3600c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3601c45dcabdSAndy Whitcroft 36026c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3603a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3604c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3605c2fdda0dSAndy Whitcroft } 36068905a67cSAndy Whitcroft 36076c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 360865863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3609c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 36109c0ca6f9SAndy Whitcroft } 36118905a67cSAndy Whitcroft 36128905a67cSAndy Whitcroft # Check for any sort of function declaration. 36138905a67cSAndy Whitcroft # int foo(something bar, other baz); 36148905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3615171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 36168905a67cSAndy Whitcroft my ($name_len) = length($1); 36178905a67cSAndy Whitcroft 3618cf655043SAndy Whitcroft my $ctx = $s; 3619773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 36208905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 3621cf655043SAndy Whitcroft 36228905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 3623c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 36248905a67cSAndy Whitcroft 3625c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 36268905a67cSAndy Whitcroft } 36278905a67cSAndy Whitcroft } 36288905a67cSAndy Whitcroft } 36298905a67cSAndy Whitcroft 36309c0ca6f9SAndy Whitcroft } 36319c0ca6f9SAndy Whitcroft 363200df344fSAndy Whitcroft# 363300df344fSAndy Whitcroft# Checks which may be anchored in the context. 363400df344fSAndy Whitcroft# 363500df344fSAndy Whitcroft 363600df344fSAndy Whitcroft# Check for switch () and associated case and default 363700df344fSAndy Whitcroft# statements should be at the same indent. 363800df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 363900df344fSAndy Whitcroft my $err = ''; 364000df344fSAndy Whitcroft my $sep = ''; 364100df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 364200df344fSAndy Whitcroft shift(@ctx); 364300df344fSAndy Whitcroft for my $ctx (@ctx) { 364400df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 364500df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 364600df344fSAndy Whitcroft $indent != $cindent) { 364700df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 364800df344fSAndy Whitcroft $sep = ''; 364900df344fSAndy Whitcroft } else { 365000df344fSAndy Whitcroft $sep = "[...]\n"; 365100df344fSAndy Whitcroft } 365200df344fSAndy Whitcroft } 365300df344fSAndy Whitcroft if ($err ne '') { 3654000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 3655000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 3656de7d4f0eSAndy Whitcroft } 3657de7d4f0eSAndy Whitcroft } 3658de7d4f0eSAndy Whitcroft 3659de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 3660de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 36610fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 3662773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 3663773647a0SAndy Whitcroft 36649c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 36658eef05ddSJoe Perches 36668eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 36678eef05ddSJoe Perches WARN("DEEP_INDENTATION", 36688eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 36698eef05ddSJoe Perches } 36708eef05ddSJoe Perches 3671de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 3672de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 3673de7d4f0eSAndy Whitcroft 3674548596d5SAndy Whitcroft my $ctx_ln = $linenr; 3675548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 3676de7d4f0eSAndy Whitcroft 3677548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 3678548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 3679548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 3680548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 3681548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 3682773647a0SAndy Whitcroft $ctx_ln++; 3683773647a0SAndy Whitcroft } 3684548596d5SAndy Whitcroft 368553210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 368653210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 3687773647a0SAndy Whitcroft 3688773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 3689000d1cc1SJoe Perches ERROR("OPEN_BRACE", 3690000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 369101464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 369200df344fSAndy Whitcroft } 3693773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 3694773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 3695773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 3696773647a0SAndy Whitcroft { 36979c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 36989c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 3699000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 3700000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 370101464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 37029c0ca6f9SAndy Whitcroft } 37039c0ca6f9SAndy Whitcroft } 370400df344fSAndy Whitcroft } 370500df344fSAndy Whitcroft 37064d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 3707f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 37083e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 37093e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 37103e469cdcSAndy Whitcroft if (!defined $stat); 37114d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 37124d001e4dSAndy Whitcroft 37134d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 37144d001e4dSAndy Whitcroft 37159f5af480SJoe Perches # remove inline comments 37169f5af480SJoe Perches $s =~ s/$;/ /g; 37179f5af480SJoe Perches $c =~ s/$;/ /g; 37184d001e4dSAndy Whitcroft 37194d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 37206f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 37216f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 37224d001e4dSAndy Whitcroft 37239f5af480SJoe Perches # Make sure we remove the line prefixes as we have 37249f5af480SJoe Perches # none on the first line, and are going to readd them 37259f5af480SJoe Perches # where necessary. 37269f5af480SJoe Perches $s =~ s/\n./\n/gs; 37279f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 37289f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 37299f5af480SJoe Perches } 37309f5af480SJoe Perches 37314d001e4dSAndy Whitcroft # We want to check the first line inside the block 37324d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 37334d001e4dSAndy Whitcroft # 1) any blank line termination 37344d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 37354d001e4dSAndy Whitcroft # 3) any do (...) { 37364d001e4dSAndy Whitcroft my $continuation = 0; 37374d001e4dSAndy Whitcroft my $check = 0; 37384d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 37394d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 37404d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 37414d001e4dSAndy Whitcroft $continuation = 1; 37424d001e4dSAndy Whitcroft } 37439bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 37444d001e4dSAndy Whitcroft $check = 1; 37454d001e4dSAndy Whitcroft $cond_lines++; 37464d001e4dSAndy Whitcroft } 37474d001e4dSAndy Whitcroft 37484d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 37494d001e4dSAndy Whitcroft # preprocessor statement. 37504d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 37514d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 37524d001e4dSAndy Whitcroft $check = 0; 37534d001e4dSAndy Whitcroft } 37544d001e4dSAndy Whitcroft 37559bd49efeSAndy Whitcroft my $cond_ptr = -1; 3756740504c6SAndy Whitcroft $continuation = 0; 37579bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 37589bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 37594d001e4dSAndy Whitcroft 3760f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 3761f16fa28fSAndy Whitcroft # is not linear. 3762f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3763f16fa28fSAndy Whitcroft $check = 0; 3764f16fa28fSAndy Whitcroft } 3765f16fa28fSAndy Whitcroft 37669bd49efeSAndy Whitcroft # Ignore: 37679bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 37689bd49efeSAndy Whitcroft # 2) preprocessor lines, and 37699bd49efeSAndy Whitcroft # 3) labels. 3770740504c6SAndy Whitcroft if ($continuation || 3771740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 37729bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 37739bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 3774740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 377530dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 37769bd49efeSAndy Whitcroft $cond_lines++; 37779bd49efeSAndy Whitcroft } 37784d001e4dSAndy Whitcroft } 377930dad6ebSAndy Whitcroft } 37804d001e4dSAndy Whitcroft 37814d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 37824d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 37834d001e4dSAndy Whitcroft 37844d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 37854d001e4dSAndy Whitcroft # this is not this patch's fault. 37864d001e4dSAndy Whitcroft if (!defined($stat_real) || 37874d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 37884d001e4dSAndy Whitcroft $check = 0; 37894d001e4dSAndy Whitcroft } 37904d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 37914d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 37924d001e4dSAndy Whitcroft } 37934d001e4dSAndy Whitcroft 37949bd49efeSAndy 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"; 37954d001e4dSAndy Whitcroft 37969f5af480SJoe Perches if ($check && $s ne '' && 3797713a09deSAntonio Borneo (($sindent % $tabsize) != 0 || 37989f5af480SJoe Perches ($sindent < $indent) || 3799f6950a73SJoe Perches ($sindent == $indent && 3800f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 3801713a09deSAntonio Borneo ($sindent > $indent + $tabsize))) { 3802000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3803000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 38044d001e4dSAndy Whitcroft } 38054d001e4dSAndy Whitcroft } 38064d001e4dSAndy Whitcroft 38076c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 38086c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 38091f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 38101f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 38116c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3812c2fdda0dSAndy Whitcroft if ($dbg_values) { 3813c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3814cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3815cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 38161f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3817c2fdda0dSAndy Whitcroft } 38186c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 38196c72ffaaSAndy Whitcroft 382000df344fSAndy Whitcroft#ignore lines not being added 38213705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 382200df344fSAndy Whitcroft 382311ca40a0SJoe Perches# check for dereferences that span multiple lines 382411ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 382511ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 382611ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 382711ca40a0SJoe Perches my $ref = $1; 382811ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 382911ca40a0SJoe Perches $ref .= $1; 383011ca40a0SJoe Perches $ref =~ s/\s//g; 383111ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 383211ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 383311ca40a0SJoe Perches } 383411ca40a0SJoe Perches 3835a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 3836c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 3837a1ce18e4SJoe Perches my $type = $1; 3838a1ce18e4SJoe Perches my $var = $2; 3839207a8e84SJoe Perches $var = "" if (!defined $var); 3840207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 3841a1ce18e4SJoe Perches my $sign = $1; 3842a1ce18e4SJoe Perches my $pointer = $2; 3843a1ce18e4SJoe Perches 3844a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 3845a1ce18e4SJoe Perches 3846a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 3847a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 3848a1ce18e4SJoe Perches $fix) { 3849a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 3850207a8e84SJoe Perches my $comp_pointer = $pointer; 3851207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 3852207a8e84SJoe Perches $decl .= $comp_pointer; 3853207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 3854207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 3855a1ce18e4SJoe Perches } 3856a1ce18e4SJoe Perches } 3857a1ce18e4SJoe Perches } 3858a1ce18e4SJoe Perches 3859653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 38607429c690SAndy Whitcroft if ($dbg_type) { 38617429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3862000d1cc1SJoe Perches ERROR("TEST_TYPE", 3863000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 38647429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3865000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3866000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 38677429c690SAndy Whitcroft } 3868653d4876SAndy Whitcroft next; 3869653d4876SAndy Whitcroft } 3870a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3871a1ef277eSAndy Whitcroft if ($dbg_attr) { 38729360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3873000d1cc1SJoe Perches ERROR("TEST_ATTR", 3874000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 38759360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3876000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3877000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3878a1ef277eSAndy Whitcroft } 3879a1ef277eSAndy Whitcroft next; 3880a1ef277eSAndy Whitcroft } 3881653d4876SAndy Whitcroft 3882f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 388399423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 388499423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3885d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3886d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3887f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3888f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3889f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3890d752fcc8SJoe Perches my $fixedline = $prevrawline; 3891d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3892f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3893d752fcc8SJoe Perches $fixedline = $line; 38948d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 3895f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3896d752fcc8SJoe Perches } 3897f0a594c1SAndy Whitcroft } 3898f0a594c1SAndy Whitcroft 389900df344fSAndy Whitcroft# 390000df344fSAndy Whitcroft# Checks which are anchored on the added line. 390100df344fSAndy Whitcroft# 390200df344fSAndy Whitcroft 3903653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3904c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3905653d4876SAndy Whitcroft my $path = $1; 3906653d4876SAndy Whitcroft if ($path =~ m{//}) { 3907000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3908495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3909495e9d84SJoe Perches } 3910495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3911495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3912495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3913653d4876SAndy Whitcroft } 3914653d4876SAndy Whitcroft } 3915653d4876SAndy Whitcroft 391600df344fSAndy Whitcroft# no C99 // comments 391700df344fSAndy Whitcroft if ($line =~ m{//}) { 39183705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 39193705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 39203705ce5bSJoe Perches $fix) { 3921194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 39223705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 39233705ce5bSJoe Perches my $comment = trim($1); 3924194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 39253705ce5bSJoe Perches } 39263705ce5bSJoe Perches } 392700df344fSAndy Whitcroft } 392800df344fSAndy Whitcroft # Remove C99 comments. 39290a920b5bSAndy Whitcroft $line =~ s@//.*@@; 39306c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 39310a920b5bSAndy Whitcroft 39322b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 39332b474a1aSAndy Whitcroft# the whole statement. 39342b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 39352b474a1aSAndy Whitcroft if (defined $realline_next && 39362b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 39372b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 39382b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 39392b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 39403cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 39413cbf62dfSAndy Whitcroft # a prefix: 39423cbf62dfSAndy Whitcroft # XXX(foo); 39433cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3944653d4876SAndy Whitcroft my $name = $1; 394587a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 39463cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 39473cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 39483cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 39493cbf62dfSAndy Whitcroft 39503cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 39512b474a1aSAndy Whitcroft \n.}\s*$| 395248012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 395348012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 395448012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 39552b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 39562b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 395748012058SAndy Whitcroft )/x) { 39582b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 39592b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 39602b474a1aSAndy Whitcroft } else { 39612b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 39620a920b5bSAndy Whitcroft } 39630a920b5bSAndy Whitcroft } 39642b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 39652b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 39662b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 39672b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 39682b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 39692b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 39702b474a1aSAndy Whitcroft } 39712b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 39722b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 3973000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 3974000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 39752b474a1aSAndy Whitcroft } 39760a920b5bSAndy Whitcroft 39775150bda4SJoe Eloff# check for global initialisers. 39786d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 3979d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 39806d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 3981d5e616fcSJoe Perches $fix) { 39826d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 3983d5e616fcSJoe Perches } 3984f0a594c1SAndy Whitcroft } 39850a920b5bSAndy Whitcroft# check for static initialisers. 39866d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 3987d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 39886d32f7a3SJoe Perches "do not initialise statics to $1\n" . 3989d5e616fcSJoe Perches $herecurr) && 3990d5e616fcSJoe Perches $fix) { 39916d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 3992d5e616fcSJoe Perches } 39930a920b5bSAndy Whitcroft } 39940a920b5bSAndy Whitcroft 39951813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 39961813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 39971813087dSJoe Perches my $tmp = trim($1); 39981813087dSJoe Perches WARN("MISORDERED_TYPE", 39991813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 40001813087dSJoe Perches } 40011813087dSJoe Perches 4002809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4003809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4004809e082eSJoe Perches my $type = trim($1); 4005809e082eSJoe Perches next if ($type !~ /\bint\b/); 4006809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 4007809e082eSJoe Perches my $new_type = $type; 4008809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 4009809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 4010809e082eSJoe Perches $new_type =~ s/^const\s+//; 4011809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 4012809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 4013809e082eSJoe Perches $new_type =~ s/\s+/ /g; 4014809e082eSJoe Perches $new_type = trim($new_type); 4015809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 4016809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4017809e082eSJoe Perches $fix) { 4018809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4019809e082eSJoe Perches } 4020809e082eSJoe Perches } 4021809e082eSJoe Perches 4022cb710ecaSJoe Perches# check for static const char * arrays. 4023cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4024000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4025000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 4026cb710ecaSJoe Perches $herecurr); 4027cb710ecaSJoe Perches } 4028cb710ecaSJoe Perches 402977b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 403077b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 403177b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 403277b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 403377b8c0a8SJoe Perches $fix) { 403477b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 403577b8c0a8SJoe Perches } 403677b8c0a8SJoe Perches } 403777b8c0a8SJoe Perches 4038cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 4039cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4040000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4041000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 4042cb710ecaSJoe Perches $herecurr); 4043cb710ecaSJoe Perches } 4044cb710ecaSJoe Perches 4045ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 4046ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 4047ab7e23f3SJoe Perches my $found = $1; 4048ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 4049ab7e23f3SJoe Perches WARN("CONST_CONST", 4050ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 4051ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4052ab7e23f3SJoe Perches WARN("CONST_CONST", 4053ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4054ab7e23f3SJoe Perches } 4055ab7e23f3SJoe Perches } 4056ab7e23f3SJoe Perches 40579b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 40589b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 40599b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 40609b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 40619b0fa60dSJoe Perches $herecurr); 40629b0fa60dSJoe Perches } 40639b0fa60dSJoe Perches 4064b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 4065b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 4066b598b670SJoe Perches my $array = $1; 4067b598b670SJoe 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*\))@) { 4068b598b670SJoe Perches my $array_div = $1; 4069b598b670SJoe Perches if (WARN("ARRAY_SIZE", 4070b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 4071b598b670SJoe Perches $fix) { 4072b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4073b598b670SJoe Perches } 4074b598b670SJoe Perches } 4075b598b670SJoe Perches } 4076b598b670SJoe Perches 4077b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 407816b7f3c8SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4079b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4080b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4081b36190c5SJoe Perches $fix) { 4082194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4083b36190c5SJoe Perches } 4084b36190c5SJoe Perches } 4085b36190c5SJoe Perches 4086653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4087653d4876SAndy Whitcroft# make sense. 4088653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 40898054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4090c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 40918ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 409246d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4093000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4094000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 40950a920b5bSAndy Whitcroft } 40960a920b5bSAndy Whitcroft 40970a920b5bSAndy Whitcroft# * goes on variable not on type 409865863862SAndy Whitcroft # (char*[ const]) 4099bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4100bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 41013705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4102d8aaf121SAndy Whitcroft 410365863862SAndy Whitcroft # Should start with a space. 410465863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 410565863862SAndy Whitcroft # Should not end with a space. 410665863862SAndy Whitcroft $to =~ s/\s+$//; 410765863862SAndy Whitcroft # '*'s should not have spaces between. 4108f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 410965863862SAndy Whitcroft } 4110d8aaf121SAndy Whitcroft 41113705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 411265863862SAndy Whitcroft if ($from ne $to) { 41133705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 41143705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 41153705ce5bSJoe Perches $fix) { 41163705ce5bSJoe Perches my $sub_from = $ident; 41173705ce5bSJoe Perches my $sub_to = $ident; 41183705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4119194f66fcSJoe Perches $fixed[$fixlinenr] =~ 41203705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 41213705ce5bSJoe Perches } 412265863862SAndy Whitcroft } 4123bfcb2cc7SAndy Whitcroft } 4124bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4125bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 41263705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4127d8aaf121SAndy Whitcroft 412865863862SAndy Whitcroft # Should start with a space. 412965863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 413065863862SAndy Whitcroft # Should not end with a space. 413165863862SAndy Whitcroft $to =~ s/\s+$//; 413265863862SAndy Whitcroft # '*'s should not have spaces between. 4133f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 413465863862SAndy Whitcroft } 413565863862SAndy Whitcroft # Modifiers should have spaces. 413665863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 413765863862SAndy Whitcroft 41383705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4139667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 41403705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 41413705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 41423705ce5bSJoe Perches $fix) { 41433705ce5bSJoe Perches 41443705ce5bSJoe Perches my $sub_from = $match; 41453705ce5bSJoe Perches my $sub_to = $match; 41463705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4147194f66fcSJoe Perches $fixed[$fixlinenr] =~ 41483705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 41493705ce5bSJoe Perches } 415065863862SAndy Whitcroft } 41510a920b5bSAndy Whitcroft } 41520a920b5bSAndy Whitcroft 41539d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 41549d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 41550675a8fbSJean Delvare my $msg_level = \&WARN; 41560675a8fbSJean Delvare $msg_level = \&CHK if ($file); 41570675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 41589d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 41599d3e3c70SJoe Perches } 41600a920b5bSAndy Whitcroft 41619d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 41628905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4163000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4164000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 41658905a67cSAndy Whitcroft } 41668905a67cSAndy Whitcroft 416717441227SJoe Perches# check for uses of printk_ratelimit 416817441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4169000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4170000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 417117441227SJoe Perches } 417217441227SJoe Perches 4173eeef5733SJoe Perches# printk should use KERN_* levels 4174eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4175000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4176eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 417700df344fSAndy Whitcroft } 41780a920b5bSAndy Whitcroft 4179243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 4180243f3803SJoe Perches my $orig = $1; 4181243f3803SJoe Perches my $level = lc($orig); 4182243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 41838f26b837SJoe Perches my $level2 = $level; 41848f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4185243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4186daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 4187243f3803SJoe Perches } 4188243f3803SJoe Perches 4189dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4190dc139313SJoe Perches my $orig = $1; 4191dc139313SJoe Perches my $level = lc($orig); 4192dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4193dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4194dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4195dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4196dc139313SJoe Perches } 4197dc139313SJoe Perches 419891c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 419991c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 420091c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 420191c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 420291c9afafSAndy Lutomirski WARN("ENOSYS", 420391c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 420491c9afafSAndy Lutomirski } 420591c9afafSAndy Lutomirski 4206653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4207653d4876SAndy Whitcroft# or if closed on same line 42085b57980dSJoe Perches if ($perl_version_ok && 42092d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 42102d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 42112d453e3bSJoe Perches $sline !~ /}/) { 42128d182478SJoe Perches if (ERROR("OPEN_BRACE", 42132d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 42148d182478SJoe Perches $fix) { 42158d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 42168d182478SJoe Perches my $fixed_line = $rawline; 42178d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 42188d182478SJoe Perches my $line1 = $1; 42198d182478SJoe Perches my $line2 = $2; 42208d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 42218d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 42228d182478SJoe Perches if ($line2 !~ /^\s*$/) { 42238d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 42248d182478SJoe Perches } 42258d182478SJoe Perches } 42260a920b5bSAndy Whitcroft } 4227653d4876SAndy Whitcroft 42288905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 42298905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 42308905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 42318d182478SJoe Perches if (ERROR("OPEN_BRACE", 42328d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 42338d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 42348d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 42358d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 42368d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 42378d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 42388d182478SJoe Perches $fixedline = $rawline; 42398d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 42408d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 42418d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 42428d182478SJoe Perches } 42438d182478SJoe Perches } 42448905a67cSAndy Whitcroft } 42458905a67cSAndy Whitcroft 42460c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 42473705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 42483705ce5bSJoe Perches if (WARN("SPACING", 42493705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 42503705ce5bSJoe Perches $fix) { 4251194f66fcSJoe Perches $fixed[$fixlinenr] =~ 42523705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 42533705ce5bSJoe Perches } 42540c73b4ebSAndy Whitcroft } 42550c73b4ebSAndy Whitcroft 425631070b5dSJoe Perches# Function pointer declarations 425731070b5dSJoe Perches# check spacing between type, funcptr, and args 425831070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 425991f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 426031070b5dSJoe Perches my $declare = $1; 426131070b5dSJoe Perches my $pre_pointer_space = $2; 426231070b5dSJoe Perches my $post_pointer_space = $3; 426331070b5dSJoe Perches my $funcname = $4; 426431070b5dSJoe Perches my $post_funcname_space = $5; 426531070b5dSJoe Perches my $pre_args_space = $6; 426631070b5dSJoe Perches 426791f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 426891f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 426991f72e9cSJoe Perches# don't need a space so don't warn for those. 427091f72e9cSJoe Perches my $post_declare_space = ""; 427191f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 427291f72e9cSJoe Perches $post_declare_space = $1; 427391f72e9cSJoe Perches $declare = rtrim($declare); 427491f72e9cSJoe Perches } 427591f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 427631070b5dSJoe Perches WARN("SPACING", 427731070b5dSJoe Perches "missing space after return type\n" . $herecurr); 427891f72e9cSJoe Perches $post_declare_space = " "; 427931070b5dSJoe Perches } 428031070b5dSJoe Perches 428131070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 428291f72e9cSJoe Perches# This test is not currently implemented because these declarations are 428391f72e9cSJoe Perches# equivalent to 428491f72e9cSJoe Perches# int foo(int bar, ...) 428591f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 428691f72e9cSJoe Perches# 428791f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 428891f72e9cSJoe Perches# WARN("SPACING", 428991f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 429091f72e9cSJoe Perches# } 429131070b5dSJoe Perches 429231070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 429331070b5dSJoe Perches if (defined $pre_pointer_space && 429431070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 429531070b5dSJoe Perches WARN("SPACING", 429631070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 429731070b5dSJoe Perches } 429831070b5dSJoe Perches 429931070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 430031070b5dSJoe Perches if (defined $post_pointer_space && 430131070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 430231070b5dSJoe Perches WARN("SPACING", 430331070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 430431070b5dSJoe Perches } 430531070b5dSJoe Perches 430631070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 430731070b5dSJoe Perches if (defined $post_funcname_space && 430831070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 430931070b5dSJoe Perches WARN("SPACING", 431031070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 431131070b5dSJoe Perches } 431231070b5dSJoe Perches 431331070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 431431070b5dSJoe Perches if (defined $pre_args_space && 431531070b5dSJoe Perches $pre_args_space =~ /^\s/) { 431631070b5dSJoe Perches WARN("SPACING", 431731070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 431831070b5dSJoe Perches } 431931070b5dSJoe Perches 432031070b5dSJoe Perches if (show_type("SPACING") && $fix) { 4321194f66fcSJoe Perches $fixed[$fixlinenr] =~ 432291f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 432331070b5dSJoe Perches } 432431070b5dSJoe Perches } 432531070b5dSJoe Perches 43268d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 43278d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 4328fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4329fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 43308d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 43318d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 43328d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 4333fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 433438dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 43353705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 43363705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 43373705ce5bSJoe Perches $fix) { 4338194f66fcSJoe Perches $fixed[$fixlinenr] =~ 43393705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 43403705ce5bSJoe Perches } 43418d31cfceSAndy Whitcroft } 43428d31cfceSAndy Whitcroft } 43438d31cfceSAndy Whitcroft 4344f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 43456c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4346c2fdda0dSAndy Whitcroft my $name = $1; 4347773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4348773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4349c2fdda0dSAndy Whitcroft 4350c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4351773647a0SAndy Whitcroft if ($name =~ /^(?: 4352773647a0SAndy Whitcroft if|for|while|switch|return|case| 4353773647a0SAndy Whitcroft volatile|__volatile__| 4354773647a0SAndy Whitcroft __attribute__|format|__extension__| 4355773647a0SAndy Whitcroft asm|__asm__)$/x) 4356773647a0SAndy Whitcroft { 4357c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4358c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4359c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4360c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4361773647a0SAndy Whitcroft 4362773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4363c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4364c2fdda0dSAndy Whitcroft 4365c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4366c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4367773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4368c2fdda0dSAndy Whitcroft 4369c2fdda0dSAndy Whitcroft } else { 43703705ce5bSJoe Perches if (WARN("SPACING", 43713705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 43723705ce5bSJoe Perches $fix) { 4373194f66fcSJoe Perches $fixed[$fixlinenr] =~ 43743705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 43753705ce5bSJoe Perches } 4376f0a594c1SAndy Whitcroft } 43776c72ffaaSAndy Whitcroft } 43789a4cad4eSEric Nelson 4379653d4876SAndy Whitcroft# Check operator spacing. 43800a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 43813705ce5bSJoe Perches my $fixed_line = ""; 43823705ce5bSJoe Perches my $line_fixed = 0; 43833705ce5bSJoe Perches 43849c0ca6f9SAndy Whitcroft my $ops = qr{ 43859c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 43869c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 43879c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 43881f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 438984731623SJoe Perches \?:|\?|: 43909c0ca6f9SAndy Whitcroft }x; 4391cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 43923705ce5bSJoe Perches 43933705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 43943705ce5bSJoe Perches## foreach my $el (@elements) { 43953705ce5bSJoe Perches## print("el: <$el>\n"); 43963705ce5bSJoe Perches## } 43973705ce5bSJoe Perches 43983705ce5bSJoe Perches my @fix_elements = (); 439900df344fSAndy Whitcroft my $off = 0; 44006c72ffaaSAndy Whitcroft 44013705ce5bSJoe Perches foreach my $el (@elements) { 44023705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 44033705ce5bSJoe Perches $off += length($el); 44043705ce5bSJoe Perches } 44053705ce5bSJoe Perches 44063705ce5bSJoe Perches $off = 0; 44073705ce5bSJoe Perches 44086c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4409b34c648bSJoe Perches my $last_after = -1; 44106c72ffaaSAndy Whitcroft 44110a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 44123705ce5bSJoe Perches 44133705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 44143705ce5bSJoe Perches 44153705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 44163705ce5bSJoe Perches 44174a0df2efSAndy Whitcroft $off += length($elements[$n]); 44184a0df2efSAndy Whitcroft 441925985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4420773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4421773647a0SAndy Whitcroft my $cc = ''; 4422773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4423773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4424773647a0SAndy Whitcroft } 4425773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4426773647a0SAndy Whitcroft 44274a0df2efSAndy Whitcroft my $a = ''; 44284a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 44294a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4430cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 44314a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 44324a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4433773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 44344a0df2efSAndy Whitcroft 44350a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 44364a0df2efSAndy Whitcroft 44374a0df2efSAndy Whitcroft my $c = ''; 44380a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 44394a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 44404a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4441cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 44424a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 44434a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 44448b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 44454a0df2efSAndy Whitcroft } else { 44464a0df2efSAndy Whitcroft $c = 'E'; 44470a920b5bSAndy Whitcroft } 44480a920b5bSAndy Whitcroft 44494a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 44504a0df2efSAndy Whitcroft 44514a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 44524a0df2efSAndy Whitcroft 44536c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4454de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 44550a920b5bSAndy Whitcroft 445674048ed8SAndy Whitcroft # Pull out the value of this operator. 44576c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 44580a920b5bSAndy Whitcroft 44591f65f947SAndy Whitcroft # Get the full operator variant. 44601f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 44611f65f947SAndy Whitcroft 446213214adfSAndy Whitcroft # Ignore operators passed as parameters. 446313214adfSAndy Whitcroft if ($op_type ne 'V' && 4464d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 446513214adfSAndy Whitcroft 4466cf655043SAndy Whitcroft# # Ignore comments 4467cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 446813214adfSAndy Whitcroft 4469d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 447013214adfSAndy Whitcroft } elsif ($op eq ';') { 4471cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4472cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 44733705ce5bSJoe Perches if (ERROR("SPACING", 44743705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4475b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 44763705ce5bSJoe Perches $line_fixed = 1; 44773705ce5bSJoe Perches } 4478d8aaf121SAndy Whitcroft } 4479d8aaf121SAndy Whitcroft 4480d8aaf121SAndy Whitcroft # // is a comment 4481d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 44820a920b5bSAndy Whitcroft 4483b00e4814SJoe Perches # : when part of a bitfield 4484b00e4814SJoe Perches } elsif ($opv eq ':B') { 4485b00e4814SJoe Perches # skip the bitfield test for now 4486b00e4814SJoe Perches 44871f65f947SAndy Whitcroft # No spaces for: 44881f65f947SAndy Whitcroft # -> 4489b00e4814SJoe Perches } elsif ($op eq '->') { 44904a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 44913705ce5bSJoe Perches if (ERROR("SPACING", 44923705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4493b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 44943705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 44953705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 44963705ce5bSJoe Perches } 4497b34c648bSJoe Perches $line_fixed = 1; 44983705ce5bSJoe Perches } 44990a920b5bSAndy Whitcroft } 45000a920b5bSAndy Whitcroft 45012381097bSJoe Perches # , must not have a space before and must have a space on the right. 45020a920b5bSAndy Whitcroft } elsif ($op eq ',') { 45032381097bSJoe Perches my $rtrim_before = 0; 45042381097bSJoe Perches my $space_after = 0; 45052381097bSJoe Perches if ($ctx =~ /Wx./) { 45062381097bSJoe Perches if (ERROR("SPACING", 45072381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 45082381097bSJoe Perches $line_fixed = 1; 45092381097bSJoe Perches $rtrim_before = 1; 45102381097bSJoe Perches } 45112381097bSJoe Perches } 4512cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 45133705ce5bSJoe Perches if (ERROR("SPACING", 45143705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 45153705ce5bSJoe Perches $line_fixed = 1; 4516b34c648bSJoe Perches $last_after = $n; 45172381097bSJoe Perches $space_after = 1; 45182381097bSJoe Perches } 45192381097bSJoe Perches } 45202381097bSJoe Perches if ($rtrim_before || $space_after) { 45212381097bSJoe Perches if ($rtrim_before) { 45222381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 45232381097bSJoe Perches } else { 45242381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 45252381097bSJoe Perches } 45262381097bSJoe Perches if ($space_after) { 45272381097bSJoe Perches $good .= " "; 45283705ce5bSJoe Perches } 45290a920b5bSAndy Whitcroft } 45300a920b5bSAndy Whitcroft 45319c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 453274048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 45339c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 45349c0ca6f9SAndy Whitcroft 45359c0ca6f9SAndy Whitcroft # unary operators should have a space before and 45369c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 45379c0ca6f9SAndy Whitcroft # unary operator, or a cast 45389c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 453974048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 45400d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4541cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 45423705ce5bSJoe Perches if (ERROR("SPACING", 45433705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4544b34c648bSJoe Perches if ($n != $last_after + 2) { 4545b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 45463705ce5bSJoe Perches $line_fixed = 1; 45473705ce5bSJoe Perches } 45480a920b5bSAndy Whitcroft } 4549b34c648bSJoe Perches } 4550a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4551171ae1a4SAndy Whitcroft # A unary '*' may be const 4552171ae1a4SAndy Whitcroft 4553171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 45543705ce5bSJoe Perches if (ERROR("SPACING", 45553705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4556b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 45573705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 45583705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 45593705ce5bSJoe Perches } 4560b34c648bSJoe Perches $line_fixed = 1; 45613705ce5bSJoe Perches } 45620a920b5bSAndy Whitcroft } 45630a920b5bSAndy Whitcroft 45640a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 45650a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4566773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 45673705ce5bSJoe Perches if (ERROR("SPACING", 45683705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4569b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 45703705ce5bSJoe Perches $line_fixed = 1; 45713705ce5bSJoe Perches } 45720a920b5bSAndy Whitcroft } 4573773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4574773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 45753705ce5bSJoe Perches if (ERROR("SPACING", 45763705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4577b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 45783705ce5bSJoe Perches $line_fixed = 1; 45793705ce5bSJoe Perches } 4580653d4876SAndy Whitcroft } 4581773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 45823705ce5bSJoe Perches if (ERROR("SPACING", 45833705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4584b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 45853705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 45863705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4587773647a0SAndy Whitcroft } 4588b34c648bSJoe Perches $line_fixed = 1; 45893705ce5bSJoe Perches } 45903705ce5bSJoe Perches } 45910a920b5bSAndy Whitcroft 45920a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 45939c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 45949c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 45959c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 4596c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 4597c2fdda0dSAndy Whitcroft $op eq '%') 45980a920b5bSAndy Whitcroft { 4599d2e025f3SJoe Perches if ($check) { 4600d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 4601d2e025f3SJoe Perches if (CHK("SPACING", 4602d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 4603d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4604d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4605d2e025f3SJoe Perches $line_fixed = 1; 4606d2e025f3SJoe Perches } 4607d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 4608d2e025f3SJoe Perches if (CHK("SPACING", 4609d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 4610d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 4611d2e025f3SJoe Perches $line_fixed = 1; 4612d2e025f3SJoe Perches } 4613d2e025f3SJoe Perches } 4614d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 46153705ce5bSJoe Perches if (ERROR("SPACING", 46163705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 4617b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4618b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4619b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4620b34c648bSJoe Perches } 46213705ce5bSJoe Perches $line_fixed = 1; 46223705ce5bSJoe Perches } 46230a920b5bSAndy Whitcroft } 46240a920b5bSAndy Whitcroft 46251f65f947SAndy Whitcroft # A colon needs no spaces before when it is 46261f65f947SAndy Whitcroft # terminating a case value or a label. 46271f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 46281f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 46293705ce5bSJoe Perches if (ERROR("SPACING", 46303705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4631b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 46323705ce5bSJoe Perches $line_fixed = 1; 46333705ce5bSJoe Perches } 46341f65f947SAndy Whitcroft } 46351f65f947SAndy Whitcroft 46360a920b5bSAndy Whitcroft # All the others need spaces both sides. 4637cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 46381f65f947SAndy Whitcroft my $ok = 0; 46391f65f947SAndy Whitcroft 464022f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 46411f65f947SAndy Whitcroft if (($op eq '<' && 46421f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 46431f65f947SAndy Whitcroft ($op eq '>' && 46441f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 46451f65f947SAndy Whitcroft { 46461f65f947SAndy Whitcroft $ok = 1; 46471f65f947SAndy Whitcroft } 46481f65f947SAndy Whitcroft 4649e0df7e1fSJoe Perches # for asm volatile statements 4650e0df7e1fSJoe Perches # ignore a colon with another 4651e0df7e1fSJoe Perches # colon immediately before or after 4652e0df7e1fSJoe Perches if (($op eq ':') && 4653e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 4654e0df7e1fSJoe Perches $ok = 1; 4655e0df7e1fSJoe Perches } 4656e0df7e1fSJoe Perches 465784731623SJoe Perches # messages are ERROR, but ?: are CHK 46581f65f947SAndy Whitcroft if ($ok == 0) { 46590675a8fbSJean Delvare my $msg_level = \&ERROR; 46600675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 466184731623SJoe Perches 46620675a8fbSJean Delvare if (&{$msg_level}("SPACING", 46633705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 4664b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4665b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4666b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4667b34c648bSJoe Perches } 46683705ce5bSJoe Perches $line_fixed = 1; 46693705ce5bSJoe Perches } 46700a920b5bSAndy Whitcroft } 467122f2a2efSAndy Whitcroft } 46724a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 46733705ce5bSJoe Perches 46743705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 46753705ce5bSJoe Perches 46763705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 46770a920b5bSAndy Whitcroft } 46783705ce5bSJoe Perches 46793705ce5bSJoe Perches if (($#elements % 2) == 0) { 46803705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 46813705ce5bSJoe Perches } 46823705ce5bSJoe Perches 4683194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 4684194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 46853705ce5bSJoe Perches } 46863705ce5bSJoe Perches 46873705ce5bSJoe Perches 46880a920b5bSAndy Whitcroft } 46890a920b5bSAndy Whitcroft 4690786b6326SJoe Perches# check for whitespace before a non-naked semicolon 4691d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 4692786b6326SJoe Perches if (WARN("SPACING", 4693786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 4694786b6326SJoe Perches $fix) { 4695194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 4696786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 4697786b6326SJoe Perches } 4698786b6326SJoe Perches } 4699786b6326SJoe Perches 4700f0a594c1SAndy Whitcroft# check for multiple assignments 4701f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4702000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 4703000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 4704f0a594c1SAndy Whitcroft } 4705f0a594c1SAndy Whitcroft 470622f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 470722f2a2efSAndy Whitcroft## # continuation. 470822f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 470922f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 471022f2a2efSAndy Whitcroft## 471122f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 471222f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 471322f2a2efSAndy Whitcroft## my $ln = $line; 471422f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 471522f2a2efSAndy Whitcroft## } 471622f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 4717000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 4718000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 471922f2a2efSAndy Whitcroft## } 472022f2a2efSAndy Whitcroft## } 4721f0a594c1SAndy Whitcroft 47220a920b5bSAndy Whitcroft#need space before brace following if, while, etc 47236b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 47246ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 47253705ce5bSJoe Perches if (ERROR("SPACING", 47263705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 47273705ce5bSJoe Perches $fix) { 47286ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 47293705ce5bSJoe Perches } 4730de7d4f0eSAndy Whitcroft } 4731de7d4f0eSAndy Whitcroft 4732c4a62ef9SJoe Perches## # check for blank lines before declarations 4733c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 4734c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 4735c4a62ef9SJoe Perches## WARN("SPACING", 4736c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 4737c4a62ef9SJoe Perches## } 4738c4a62ef9SJoe Perches## 4739c4a62ef9SJoe Perches 4740de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 4741de7d4f0eSAndy Whitcroft# on the line 474294fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 4743d5e616fcSJoe Perches if (ERROR("SPACING", 4744d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 4745d5e616fcSJoe Perches $fix) { 4746194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4747d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 4748d5e616fcSJoe Perches } 47490a920b5bSAndy Whitcroft } 47500a920b5bSAndy Whitcroft 475122f2a2efSAndy Whitcroft# check spacing on square brackets 475222f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 47533705ce5bSJoe Perches if (ERROR("SPACING", 47543705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 47553705ce5bSJoe Perches $fix) { 4756194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47573705ce5bSJoe Perches s/\[\s+/\[/; 47583705ce5bSJoe Perches } 475922f2a2efSAndy Whitcroft } 476022f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 47613705ce5bSJoe Perches if (ERROR("SPACING", 47623705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 47633705ce5bSJoe Perches $fix) { 4764194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47653705ce5bSJoe Perches s/\s+\]/\]/; 47663705ce5bSJoe Perches } 476722f2a2efSAndy Whitcroft } 476822f2a2efSAndy Whitcroft 4769c45dcabdSAndy Whitcroft# check spacing on parentheses 47709c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 47719c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 47723705ce5bSJoe Perches if (ERROR("SPACING", 47733705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 47743705ce5bSJoe Perches $fix) { 4775194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47763705ce5bSJoe Perches s/\(\s+/\(/; 47773705ce5bSJoe Perches } 477822f2a2efSAndy Whitcroft } 477913214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4780c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 4781c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 47823705ce5bSJoe Perches if (ERROR("SPACING", 47833705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 47843705ce5bSJoe Perches $fix) { 4785194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47863705ce5bSJoe Perches s/\s+\)/\)/; 47873705ce5bSJoe Perches } 478822f2a2efSAndy Whitcroft } 478922f2a2efSAndy Whitcroft 4790e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 4791e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 4792e2826fd0SJoe Perches 4793e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 4794ea4acbb1SJoe Perches my $var = $1; 4795ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4796ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4797ea4acbb1SJoe Perches $fix) { 4798ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4799ea4acbb1SJoe Perches } 4800ea4acbb1SJoe Perches } 4801ea4acbb1SJoe Perches 4802ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4803ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4804ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4805ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4806ea4acbb1SJoe Perches my $var = $2; 4807ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4808ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4809ea4acbb1SJoe Perches $fix) { 4810ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4811ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4812ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4813ea4acbb1SJoe Perches } 4814e2826fd0SJoe Perches } 4815e2826fd0SJoe Perches 481663b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 4817a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 4818a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 48195b57980dSJoe Perches $perl_version_ok && defined($stat) && 482063b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 482163b7c73eSJoe Perches my $if_stat = $1; 482263b7c73eSJoe Perches my $test = substr($2, 1, -1); 482363b7c73eSJoe Perches my $herectx; 482463b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 482563b7c73eSJoe Perches my $match = $1; 482663b7c73eSJoe Perches # avoid parentheses around potential macro args 482763b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 482863b7c73eSJoe Perches if (!defined($herectx)) { 482963b7c73eSJoe Perches $herectx = $here . "\n"; 483063b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 483163b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 483263b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 483363b7c73eSJoe Perches $herectx .= $rl . "\n"; 483463b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 483563b7c73eSJoe Perches } 483663b7c73eSJoe Perches } 483763b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 483863b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 483963b7c73eSJoe Perches } 484063b7c73eSJoe Perches } 484163b7c73eSJoe Perches 48420a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 48434a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 48440a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 48453705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 48463705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 48473705ce5bSJoe Perches $fix) { 4848194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48493705ce5bSJoe Perches s/^(.)\s+/$1/; 48503705ce5bSJoe Perches } 48510a920b5bSAndy Whitcroft } 48520a920b5bSAndy Whitcroft 48535b9553abSJoe Perches# return is not a function 4854507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4855c45dcabdSAndy Whitcroft my $spacing = $1; 48565b57980dSJoe Perches if ($perl_version_ok && 48575b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 48585b9553abSJoe Perches my $value = $1; 48595b9553abSJoe Perches $value = deparenthesize($value); 48605b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4861000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4862000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 48635b9553abSJoe Perches } 4864c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4865000d1cc1SJoe Perches ERROR("SPACING", 4866000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4867c45dcabdSAndy Whitcroft } 4868c45dcabdSAndy Whitcroft } 4869507e5141SJoe Perches 4870b43ae21bSJoe Perches# unnecessary return in a void function 4871b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4872b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4873b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4874b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4875b43ae21bSJoe Perches $linenr >= 3 && 4876b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4877b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 48789819cf25SJoe Perches WARN("RETURN_VOID", 4879b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 48809819cf25SJoe Perches } 48819819cf25SJoe Perches 4882189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 48835b57980dSJoe Perches if ($perl_version_ok && 4884189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4885189248d8SJoe Perches my $openparens = $1; 4886189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4887189248d8SJoe Perches my $msg = ""; 4888189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4889189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4890189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4891189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4892189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4893189248d8SJoe Perches } 4894189248d8SJoe Perches } 4895189248d8SJoe Perches 4896c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 4897c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 4898c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 4899c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 49005b57980dSJoe Perches if ($perl_version_ok && 4901c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4902c5595fa2SJoe Perches my $lead = $1; 4903c5595fa2SJoe Perches my $const = $2; 4904c5595fa2SJoe Perches my $comp = $3; 4905c5595fa2SJoe Perches my $to = $4; 4906c5595fa2SJoe Perches my $newcomp = $comp; 4907f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 4908c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 4909c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 4910c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 4911c5595fa2SJoe Perches $fix) { 4912c5595fa2SJoe Perches if ($comp eq "<") { 4913c5595fa2SJoe Perches $newcomp = ">"; 4914c5595fa2SJoe Perches } elsif ($comp eq "<=") { 4915c5595fa2SJoe Perches $newcomp = ">="; 4916c5595fa2SJoe Perches } elsif ($comp eq ">") { 4917c5595fa2SJoe Perches $newcomp = "<"; 4918c5595fa2SJoe Perches } elsif ($comp eq ">=") { 4919c5595fa2SJoe Perches $newcomp = "<="; 4920c5595fa2SJoe Perches } 4921c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 4922c5595fa2SJoe Perches } 4923c5595fa2SJoe Perches } 4924c5595fa2SJoe Perches 4925f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4926f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 492753a3c448SAndy Whitcroft my $name = $1; 492853a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4929000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4930f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 493153a3c448SAndy Whitcroft } 493253a3c448SAndy Whitcroft } 4933c45dcabdSAndy Whitcroft 49340a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 49354a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 49363705ce5bSJoe Perches if (ERROR("SPACING", 49373705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 49383705ce5bSJoe Perches $fix) { 4939194f66fcSJoe Perches $fixed[$fixlinenr] =~ 49403705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 49413705ce5bSJoe Perches } 49420a920b5bSAndy Whitcroft } 49430a920b5bSAndy Whitcroft 4944f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4945f5fe35ddSAndy Whitcroft# statements after the conditional. 4946170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 49473e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 49483e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 49493e469cdcSAndy Whitcroft if (!defined $stat); 4950170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4951170d3a22SAndy Whitcroft $remain_next, $off_next); 4952170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4953170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4954170d3a22SAndy Whitcroft 4955170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4956170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4957170d3a22SAndy Whitcroft # then count those as offsets. 4958170d3a22SAndy Whitcroft my ($whitespace) = 4959170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4960170d3a22SAndy Whitcroft my $offset = 4961170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 4962170d3a22SAndy Whitcroft 4963170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 4964170d3a22SAndy Whitcroft $offset} = 1; 4965170d3a22SAndy Whitcroft } 4966170d3a22SAndy Whitcroft } 4967170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 4968c11230f4SJoe Perches defined($stat) && defined($cond) && 4969170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4970171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 49718905a67cSAndy Whitcroft 4972b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4973000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 4974000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 49758905a67cSAndy Whitcroft } 49768905a67cSAndy Whitcroft 49778905a67cSAndy Whitcroft # Find out what is on the end of the line after the 49788905a67cSAndy Whitcroft # conditional. 4979773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 49808905a67cSAndy Whitcroft $s =~ s/\n.*//g; 498113214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 498253210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 498353210168SAndy Whitcroft $c !~ /}\s*while\s*/) 4984773647a0SAndy Whitcroft { 4985bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 4986bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4987bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 498842bdf74cSHidetoshi Seto my $stat_real = ''; 4989bb44ad39SAndy Whitcroft 499042bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 499142bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 4992bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 4993bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 4994bb44ad39SAndy Whitcroft } 4995bb44ad39SAndy Whitcroft 4996000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4997000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 49988905a67cSAndy Whitcroft } 49998905a67cSAndy Whitcroft } 50008905a67cSAndy Whitcroft 500113214adfSAndy Whitcroft# Check for bitwise tests written as boolean 500213214adfSAndy Whitcroft if ($line =~ / 500313214adfSAndy Whitcroft (?: 500413214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 500513214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 500613214adfSAndy Whitcroft (?:\&\&|\|\|) 500713214adfSAndy Whitcroft | 500813214adfSAndy Whitcroft (?:\&\&|\|\|) 500913214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 501013214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 501113214adfSAndy Whitcroft )/x) 501213214adfSAndy Whitcroft { 5013000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 5014000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 501513214adfSAndy Whitcroft } 501613214adfSAndy Whitcroft 50178905a67cSAndy Whitcroft# if and else should not have general statements after it 501813214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 501913214adfSAndy Whitcroft my $s = $1; 502013214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 502113214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 5022000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5023000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 50240a920b5bSAndy Whitcroft } 502513214adfSAndy Whitcroft } 502639667782SAndy Whitcroft# if should not continue a brace 502739667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 5028000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5029048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 503039667782SAndy Whitcroft $herecurr); 503139667782SAndy Whitcroft } 5032a1080bf8SAndy Whitcroft# case and default should not have general statements after them 5033a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 5034a1080bf8SAndy Whitcroft $line !~ /\G(?: 50353fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5036a1080bf8SAndy Whitcroft \s*return\s+ 5037a1080bf8SAndy Whitcroft )/xg) 5038a1080bf8SAndy Whitcroft { 5039000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5040000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 5041a1080bf8SAndy Whitcroft } 50420a920b5bSAndy Whitcroft 50430a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 50440a920b5bSAndy Whitcroft # indent level to be relevant to each other. 50458b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 50460a920b5bSAndy Whitcroft $previndent == $indent) { 50478b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 50488b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 50498b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 50508b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 50518b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 50528b8856f4SJoe Perches my $fixedline = $prevrawline; 50538b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 50548b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 50558b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 50568b8856f4SJoe Perches } 50578b8856f4SJoe Perches $fixedline = $rawline; 50588b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 50598b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 50608b8856f4SJoe Perches } 50610a920b5bSAndy Whitcroft } 50620a920b5bSAndy Whitcroft 50638b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5064c2fdda0dSAndy Whitcroft $previndent == $indent) { 5065c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5066c2fdda0dSAndy Whitcroft 5067c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5068c2fdda0dSAndy Whitcroft # conditional. 5069773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5070c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5071c2fdda0dSAndy Whitcroft 5072c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 50738b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 50748b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 50758b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 50768b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 50778b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 50788b8856f4SJoe Perches my $fixedline = $prevrawline; 50798b8856f4SJoe Perches my $trailing = $rawline; 50808b8856f4SJoe Perches $trailing =~ s/^\+//; 50818b8856f4SJoe Perches $trailing = trim($trailing); 50828b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 50838b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 50848b8856f4SJoe Perches } 5085c2fdda0dSAndy Whitcroft } 5086c2fdda0dSAndy Whitcroft } 5087c2fdda0dSAndy Whitcroft 508895e2c602SJoe Perches#Specific variable tests 5089323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5090323c1260SJoe Perches my $var = $1; 509195e2c602SJoe Perches 509295e2c602SJoe Perches#CamelCase 5093807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5094be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 509522735ce8SJoe Perches#Ignore Page<foo> variants 5096807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5097d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB 5098d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 5099d439e6a5SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5100f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5101f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 51027e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 51037e781f67SJoe Perches my $word = $1; 51047e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5105d8b07710SJoe Perches if ($check) { 5106d8b07710SJoe Perches seed_camelcase_includes(); 5107d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5108d8b07710SJoe Perches seed_camelcase_file($realfile); 5109d8b07710SJoe Perches $camelcase_file_seeded = 1; 5110d8b07710SJoe Perches } 5111d8b07710SJoe Perches } 51127e781f67SJoe Perches if (!defined $camelcase{$word}) { 51137e781f67SJoe Perches $camelcase{$word} = 1; 5114be79794bSJoe Perches CHK("CAMELCASE", 51157e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 51167e781f67SJoe Perches } 5117323c1260SJoe Perches } 5118323c1260SJoe Perches } 51193445686aSJoe Perches } 51200a920b5bSAndy Whitcroft 51210a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5122d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5123d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5124d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5125d5e616fcSJoe Perches $fix) { 5126194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5127d5e616fcSJoe Perches } 51280a920b5bSAndy Whitcroft } 51290a920b5bSAndy Whitcroft 51300e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 51310e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5132c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5133e09dec48SAndy Whitcroft my $file = "$1.h"; 5134e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5135e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5136e09dec48SAndy Whitcroft $realfile ne $checkfile && 51377840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5138c45dcabdSAndy Whitcroft { 51390e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 51400e212e0aSFabian Frederick if ($asminclude > 0) { 5141e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5142000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5143000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5144e09dec48SAndy Whitcroft } else { 5145000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5146000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5147e09dec48SAndy Whitcroft } 51480a920b5bSAndy Whitcroft } 51490a920b5bSAndy Whitcroft } 51500e212e0aSFabian Frederick } 51510a920b5bSAndy Whitcroft 5152653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5153653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5154cf655043SAndy Whitcroft# in a known good container 5155b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5156b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5157d8aaf121SAndy Whitcroft my $ln = $linenr; 5158d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5159c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5160c45dcabdSAndy Whitcroft my $ctx = ''; 516108a2843eSJoe Perches my $has_flow_statement = 0; 516208a2843eSJoe Perches my $has_arg_concat = 0; 5163c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5164f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5165f74bd194SAndy Whitcroft $ctx = $dstat; 5166c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5167a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5168c45dcabdSAndy Whitcroft 516908a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 517062e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 517108a2843eSJoe Perches 5172f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5173f59b64bfSJoe Perches my $define_args = $1; 5174f59b64bfSJoe Perches my $define_stmt = $dstat; 5175f59b64bfSJoe Perches my @def_args = (); 5176f59b64bfSJoe Perches 5177f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5178f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5179f59b64bfSJoe Perches $define_args =~ s/\s*//g; 51808c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5181f59b64bfSJoe Perches @def_args = split(",", $define_args); 5182f59b64bfSJoe Perches } 5183f59b64bfSJoe Perches 5184292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5185c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5186c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5187c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5188c45dcabdSAndy Whitcroft 5189c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 5190bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 5191bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 51926b10df42SVladimir Zapolskiy $dstat =~ s/.\[[^\[\]]*\]/1/) 5193bf30d6edSAndy Whitcroft { 5194c45dcabdSAndy Whitcroft } 5195c45dcabdSAndy Whitcroft 5196342d3d2fSAntonio Borneo # Flatten any obvious string concatenation. 519733acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 519833acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5199e45bab8eSAndy Whitcroft { 5200e45bab8eSAndy Whitcroft } 5201e45bab8eSAndy Whitcroft 520242e15293SJoe Perches # Make asm volatile uses seem like a generic function 520342e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 520442e15293SJoe Perches 5205c45dcabdSAndy Whitcroft my $exceptions = qr{ 5206c45dcabdSAndy Whitcroft $Declare| 5207c45dcabdSAndy Whitcroft module_param_named| 5208a0a0a7a9SKees Cook MODULE_PARM_DESC| 5209c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5210c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5211383099fdSAndy Whitcroft __typeof__\(| 521222fd2d3eSStefani Seibold union| 521322fd2d3eSStefani Seibold struct| 5214ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 52156b10df42SVladimir Zapolskiy ^\"|\"$| 52166b10df42SVladimir Zapolskiy ^\[ 5217c45dcabdSAndy Whitcroft }x; 52185eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5219f59b64bfSJoe Perches 5220f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5221f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5222e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5223f59b64bfSJoe Perches 5224f74bd194SAndy Whitcroft if ($dstat ne '' && 5225f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5226f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 52273cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5228356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5229f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5230f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5231e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 523272f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 5233f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5234f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5235f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 52364e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5237f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5238c45dcabdSAndy Whitcroft { 5239e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5240e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5241e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5242e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5243f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5244f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5245f74bd194SAndy Whitcroft } else { 5246000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 5247388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5248d8aaf121SAndy Whitcroft } 5249f59b64bfSJoe Perches 5250f59b64bfSJoe Perches } 52515207649bSJoe Perches 52525207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 52535207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 52545207649bSJoe Perches my $first = 1; 52555207649bSJoe Perches $define_stmt = ""; 52565207649bSJoe Perches foreach my $l (@stmt_array) { 52575207649bSJoe Perches $l =~ s/\\$//; 52585207649bSJoe Perches if ($first) { 52595207649bSJoe Perches $define_stmt = $l; 52605207649bSJoe Perches $first = 0; 52615207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 52625207649bSJoe Perches $define_stmt .= substr($l, 1); 52635207649bSJoe Perches } 52645207649bSJoe Perches } 52655207649bSJoe Perches $define_stmt =~ s/$;//g; 52665207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 52675207649bSJoe Perches $define_stmt = trim($define_stmt); 52685207649bSJoe Perches 5269f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 5270f59b64bfSJoe Perches foreach my $arg (@def_args) { 5271f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 52729192d41aSJoe Perches next if ($arg =~ /^type$/i); 52737fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 52746dba824eSBrendan Jackman $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 52757fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 52767fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5277d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 5278f59b64bfSJoe Perches if ($use_cnt > 1) { 5279f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 5280f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5281f59b64bfSJoe Perches } 52829192d41aSJoe Perches# check if any macro arguments may have other precedence issues 52837fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 52849192d41aSJoe Perches ((defined($1) && $1 ne ',') || 52859192d41aSJoe Perches (defined($2) && $2 ne ','))) { 52869192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 52879192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 52889192d41aSJoe Perches } 52890a920b5bSAndy Whitcroft } 52905023d347SJoe Perches 529108a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 529208a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 529308a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 529408a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 5295e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 529608a2843eSJoe Perches 529708a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 529808a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 529908a2843eSJoe Perches } 530008a2843eSJoe Perches 5301481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 53025023d347SJoe Perches 53035023d347SJoe Perches } else { 53045023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 5305481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 5306481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 53075023d347SJoe Perches $line =~ /^\+.*\\$/) { 53085023d347SJoe Perches WARN("LINE_CONTINUATIONS", 53095023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 53105023d347SJoe Perches } 5311653d4876SAndy Whitcroft } 53120a920b5bSAndy Whitcroft 5313b13edf7fSJoe Perches# do {} while (0) macro tests: 5314b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 5315b13edf7fSJoe Perches# macro should not end with a semicolon 53165b57980dSJoe Perches if ($perl_version_ok && 5317b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 5318b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5319b13edf7fSJoe Perches my $ln = $linenr; 5320b13edf7fSJoe Perches my $cnt = $realcnt; 5321b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 5322b13edf7fSJoe Perches my $ctx = ''; 5323b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 5324b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 5325b13edf7fSJoe Perches $ctx = $dstat; 5326b13edf7fSJoe Perches 5327b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 53281b36b201SJoe Perches $dstat =~ s/$;/ /g; 5329b13edf7fSJoe Perches 5330b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 5331b13edf7fSJoe Perches my $stmts = $2; 5332b13edf7fSJoe Perches my $semis = $3; 5333b13edf7fSJoe Perches 5334b13edf7fSJoe Perches $ctx =~ s/\n*$//; 5335b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 5336e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5337b13edf7fSJoe Perches 5338ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 5339ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 5340b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 5341b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 5342b13edf7fSJoe Perches } 5343b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 5344b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 5345b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5346b13edf7fSJoe Perches } 5347f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5348f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5349f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5350e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5351f5ef95b1SJoe Perches 5352f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5353f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5354b13edf7fSJoe Perches } 5355b13edf7fSJoe Perches } 5356b13edf7fSJoe Perches 5357f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 535813214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 535913214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5360cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 536113214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5362cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5363cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5364aad4f614SJoe Perches my @allowed = (); 5365aad4f614SJoe Perches my $allow = 0; 536613214adfSAndy Whitcroft my $seen = 0; 5367773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5368cf655043SAndy Whitcroft my $ln = $linenr - 1; 536913214adfSAndy Whitcroft for my $chunk (@chunks) { 537013214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 537113214adfSAndy Whitcroft 5372773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5373773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5374773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5375773647a0SAndy Whitcroft 5376aad4f614SJoe Perches $allowed[$allow] = 0; 5377773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5378773647a0SAndy Whitcroft 5379773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5380773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5381773647a0SAndy Whitcroft 5382773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5383cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5384cf655043SAndy Whitcroft 5385773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 538613214adfSAndy Whitcroft 538713214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 538813214adfSAndy Whitcroft 5389aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5390cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5391cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5392aad4f614SJoe Perches $allowed[$allow] = 1; 539313214adfSAndy Whitcroft } 539413214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5395cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5396aad4f614SJoe Perches $allowed[$allow] = 1; 539713214adfSAndy Whitcroft } 5398cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5399cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5400aad4f614SJoe Perches $allowed[$allow] = 1; 540113214adfSAndy Whitcroft } 5402aad4f614SJoe Perches $allow++; 540313214adfSAndy Whitcroft } 5404aad4f614SJoe Perches if ($seen) { 5405aad4f614SJoe Perches my $sum_allowed = 0; 5406aad4f614SJoe Perches foreach (@allowed) { 5407aad4f614SJoe Perches $sum_allowed += $_; 5408aad4f614SJoe Perches } 5409aad4f614SJoe Perches if ($sum_allowed == 0) { 5410000d1cc1SJoe Perches WARN("BRACES", 5411000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5412aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5413aad4f614SJoe Perches $seen != $allow) { 5414aad4f614SJoe Perches CHK("BRACES", 5415aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5416aad4f614SJoe Perches } 541713214adfSAndy Whitcroft } 541813214adfSAndy Whitcroft } 541913214adfSAndy Whitcroft } 5420773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 542113214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5422cf655043SAndy Whitcroft my $allowed = 0; 5423f0a594c1SAndy Whitcroft 5424cf655043SAndy Whitcroft # Check the pre-context. 5425cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5426cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5427cf655043SAndy Whitcroft $allowed = 1; 5428f0a594c1SAndy Whitcroft } 5429773647a0SAndy Whitcroft 5430773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5431773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5432773647a0SAndy Whitcroft 5433cf655043SAndy Whitcroft # Check the condition. 5434cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5435773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5436cf655043SAndy Whitcroft if (defined $cond) { 5437773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5438cf655043SAndy Whitcroft } 5439cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5440cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5441cf655043SAndy Whitcroft $allowed = 1; 5442cf655043SAndy Whitcroft } 5443cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5444cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5445cf655043SAndy Whitcroft $allowed = 1; 5446cf655043SAndy Whitcroft } 5447cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5448cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5449cf655043SAndy Whitcroft $allowed = 1; 5450cf655043SAndy Whitcroft } 5451cf655043SAndy Whitcroft # Check the post-context. 5452cf655043SAndy Whitcroft if (defined $chunks[1]) { 5453cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5454cf655043SAndy Whitcroft if (defined $cond) { 5455773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5456cf655043SAndy Whitcroft } 5457cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5458cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5459cf655043SAndy Whitcroft $allowed = 1; 5460cf655043SAndy Whitcroft } 5461cf655043SAndy Whitcroft } 5462cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 5463f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5464e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5465cf655043SAndy Whitcroft 5466000d1cc1SJoe Perches WARN("BRACES", 5467000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5468f0a594c1SAndy Whitcroft } 5469f0a594c1SAndy Whitcroft } 5470f0a594c1SAndy Whitcroft 5471e4c5babdSJoe Perches# check for single line unbalanced braces 547295330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 547395330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5474e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5475e4c5babdSJoe Perches } 5476e4c5babdSJoe Perches 54770979ae66SJoe Perches# check for unnecessary blank lines around braces 547877b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5479f8e58219SJoe Perches if (CHK("BRACES", 5480f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5481f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5482f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5483f8e58219SJoe Perches } 54840979ae66SJoe Perches } 548577b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5486f8e58219SJoe Perches if (CHK("BRACES", 5487f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5488f8e58219SJoe Perches $fix) { 5489f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5490f8e58219SJoe Perches } 54910979ae66SJoe Perches } 54920979ae66SJoe Perches 54934a0df2efSAndy Whitcroft# no volatiles please 54946c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 54956c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5496000d1cc1SJoe Perches WARN("VOLATILE", 54978c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 54984a0df2efSAndy Whitcroft } 54994a0df2efSAndy Whitcroft 55005e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 55015e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 55025e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 55035e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 550433acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 55055e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 55065e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 55075e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 55085e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 55095e4f6ba5SJoe Perches $fix && 55105e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 55115e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 55125e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 55135e4f6ba5SJoe Perches my $comma_close = ""; 55145e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 55155e4f6ba5SJoe Perches $comma_close = $1; 55165e4f6ba5SJoe Perches } 55175e4f6ba5SJoe Perches 55185e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 55195e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 55205e4f6ba5SJoe Perches my $fixedline = $prevrawline; 55215e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 55225e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 55235e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 55245e4f6ba5SJoe Perches $fixedline = $rawline; 55255e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 55265e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 55275e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 55285e4f6ba5SJoe Perches } 55295e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 55305e4f6ba5SJoe Perches } 55315e4f6ba5SJoe Perches } 55325e4f6ba5SJoe Perches 55335e4f6ba5SJoe Perches# check for missing a space in a string concatenation 55345e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 55355e4f6ba5SJoe Perches WARN('MISSING_SPACE', 55365e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 55375e4f6ba5SJoe Perches } 55385e4f6ba5SJoe Perches 553977cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5540e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5541e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5542e4b7d309SJoe Perches# function declarations 554377cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 554477cb8546SJoe Perches defined($context_function) && 5545e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 5546e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 554777cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 5548e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 554977cb8546SJoe Perches } 555077cb8546SJoe Perches 55515e4f6ba5SJoe Perches# check for spaces before a quoted newline 55525e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 55535e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 55545e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 55555e4f6ba5SJoe Perches $fix) { 55565e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 55575e4f6ba5SJoe Perches } 55585e4f6ba5SJoe Perches 55595e4f6ba5SJoe Perches } 55605e4f6ba5SJoe Perches 5561f17dba4fSJoe Perches# concatenated string without spaces between elements 556279682c0cSJoe Perches if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) { 556379682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 556479682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 556579682c0cSJoe Perches $fix) { 556679682c0cSJoe Perches while ($line =~ /($String)/g) { 556779682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 556879682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 556979682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 557079682c0cSJoe Perches } 557179682c0cSJoe Perches } 5572f17dba4fSJoe Perches } 5573f17dba4fSJoe Perches 557490ad30e5SJoe Perches# uncoalesced string fragments 557533acb54aSJoe Perches if ($line =~ /$String\s*"/) { 557679682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 557779682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 557879682c0cSJoe Perches $fix) { 557979682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 558079682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 558179682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 558279682c0cSJoe Perches } 558379682c0cSJoe Perches } 558490ad30e5SJoe Perches } 558590ad30e5SJoe Perches 5586522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 5587522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 5588522b837cSAlexey Dobriyan my $show_Z = 1; 55895e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 5590522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 55915e4f6ba5SJoe Perches $string =~ s/%%/__/g; 5592522b837cSAlexey Dobriyan # check for %L 5593522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 55945e4f6ba5SJoe Perches WARN("PRINTF_L", 5595522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 5596522b837cSAlexey Dobriyan $show_L = 0; 55975e4f6ba5SJoe Perches } 5598522b837cSAlexey Dobriyan # check for %Z 5599522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 5600522b837cSAlexey Dobriyan WARN("PRINTF_Z", 5601522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 5602522b837cSAlexey Dobriyan $show_Z = 0; 5603522b837cSAlexey Dobriyan } 5604522b837cSAlexey Dobriyan # check for 0x<decimal> 5605522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 5606522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 56076e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 56086e300757SJoe Perches } 56095e4f6ba5SJoe Perches } 56105e4f6ba5SJoe Perches 56115e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 56123f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 56135e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 56145e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 56155e4f6ba5SJoe Perches } 56165e4f6ba5SJoe Perches 561700df344fSAndy Whitcroft# warn about #if 0 5618c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 561960f89010SPrakruthi Deepak Heragu WARN("IF_0", 562060f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 562160f89010SPrakruthi Deepak Heragu } 562260f89010SPrakruthi Deepak Heragu 562360f89010SPrakruthi Deepak Heragu# warn about #if 1 562460f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 562560f89010SPrakruthi Deepak Heragu WARN("IF_1", 562660f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 56274a0df2efSAndy Whitcroft } 56284a0df2efSAndy Whitcroft 562903df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 563003df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 5631100425deSJoe Perches my $tested = quotemeta($1); 5632100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 5633100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 5634100425deSJoe Perches my $func = $1; 5635100425deSJoe Perches if (WARN('NEEDLESS_IF', 5636100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 5637100425deSJoe Perches $fix) { 5638100425deSJoe Perches my $do_fix = 1; 5639100425deSJoe Perches my $leading_tabs = ""; 5640100425deSJoe Perches my $new_leading_tabs = ""; 5641100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 5642100425deSJoe Perches $leading_tabs = $1; 5643100425deSJoe Perches } else { 5644100425deSJoe Perches $do_fix = 0; 5645100425deSJoe Perches } 5646100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 5647100425deSJoe Perches $new_leading_tabs = $1; 5648100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 5649100425deSJoe Perches $do_fix = 0; 5650100425deSJoe Perches } 5651100425deSJoe Perches } else { 5652100425deSJoe Perches $do_fix = 0; 5653100425deSJoe Perches } 5654100425deSJoe Perches if ($do_fix) { 5655100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5656100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 5657100425deSJoe Perches } 5658100425deSJoe Perches } 56594c432a8fSGreg Kroah-Hartman } 56604c432a8fSGreg Kroah-Hartman } 5661f0a594c1SAndy Whitcroft 5662ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 5663ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 5664ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 5665ebfdc409SJoe Perches (defined $1 || defined $3) && 5666ebfdc409SJoe Perches $linenr > 3) { 5667ebfdc409SJoe Perches my $testval = $2; 5668ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 5669ebfdc409SJoe Perches 5670ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 5671ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 5672ebfdc409SJoe Perches 5673e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 5674e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 5675ebfdc409SJoe Perches WARN("OOM_MESSAGE", 5676ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 5677ebfdc409SJoe Perches } 5678ebfdc409SJoe Perches } 5679ebfdc409SJoe Perches 5680f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 5681dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 5682f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 5683f78d98f6SJoe Perches my $level = $1; 5684f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 5685f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 5686f78d98f6SJoe Perches $fix) { 5687f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 5688f78d98f6SJoe Perches } 5689f78d98f6SJoe Perches } 5690f78d98f6SJoe Perches 569145c55e92SJoe Perches# check for logging continuations 569245c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 569345c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 569445c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 569545c55e92SJoe Perches } 569645c55e92SJoe Perches 5697abb08a53SJoe Perches# check for mask then right shift without a parentheses 56985b57980dSJoe Perches if ($perl_version_ok && 5699abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5700abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5701abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 5702abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 5703abb08a53SJoe Perches } 5704abb08a53SJoe Perches 5705b75ac618SJoe Perches# check for pointer comparisons to NULL 57065b57980dSJoe Perches if ($perl_version_ok) { 5707b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5708b75ac618SJoe Perches my $val = $1; 5709b75ac618SJoe Perches my $equal = "!"; 5710b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 5711b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 5712b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 5713b75ac618SJoe Perches $fix) { 5714b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 5715b75ac618SJoe Perches } 5716b75ac618SJoe Perches } 5717b75ac618SJoe Perches } 5718b75ac618SJoe Perches 57198716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 57208716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 57218716de38SJoe Perches my $attr = $1; 57228716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 57238716de38SJoe Perches my $ptr = $1; 57248716de38SJoe Perches my $var = $2; 57258716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 57268716de38SJoe Perches ERROR("MISPLACED_INIT", 57278716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 57288716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 57298716de38SJoe Perches WARN("MISPLACED_INIT", 57308716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 57318716de38SJoe Perches $fix) { 5732194f66fcSJoe 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; 57338716de38SJoe Perches } 57348716de38SJoe Perches } 57358716de38SJoe Perches } 57368716de38SJoe Perches 5737e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 5738e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 5739e970b884SJoe Perches my $attr = $1; 5740e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 5741e970b884SJoe Perches my $attr_prefix = $1; 5742e970b884SJoe Perches my $attr_type = $2; 5743e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5744e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 5745e970b884SJoe Perches $fix) { 5746194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5747e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 5748e970b884SJoe Perches } 5749e970b884SJoe Perches } 5750e970b884SJoe Perches 5751e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 5752e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 5753e970b884SJoe Perches my $attr = $1; 5754e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5755e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 5756e970b884SJoe Perches $fix) { 5757194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 5758e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 5759e970b884SJoe Perches $lead = rtrim($1); 5760e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 5761e970b884SJoe Perches $lead = "${lead}const "; 5762194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 5763e970b884SJoe Perches } 5764e970b884SJoe Perches } 5765e970b884SJoe Perches 5766c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 5767c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 5768c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 5769c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 5770c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 5771c17893c7SJoe Perches $fix) { 5772c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 5773c17893c7SJoe Perches } 5774c17893c7SJoe Perches } 5775c17893c7SJoe Perches 5776fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 5777fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 5778fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 5779fbdb8138SJoe Perches my $constant_func = $1; 5780fbdb8138SJoe Perches my $func = $constant_func; 5781fbdb8138SJoe Perches $func =~ s/^__constant_//; 5782fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 5783fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 5784fbdb8138SJoe Perches $fix) { 5785194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 5786fbdb8138SJoe Perches } 5787fbdb8138SJoe Perches } 5788fbdb8138SJoe Perches 57891a15a250SPatrick Pannuto# prefer usleep_range over udelay 579037581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 579143c1d77cSJoe Perches my $delay = $1; 57921a15a250SPatrick Pannuto # ignore udelay's < 10, however 579343c1d77cSJoe Perches if (! ($delay < 10) ) { 5794000d1cc1SJoe Perches CHK("USLEEP_RANGE", 5795458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 579643c1d77cSJoe Perches } 579743c1d77cSJoe Perches if ($delay > 2000) { 579843c1d77cSJoe Perches WARN("LONG_UDELAY", 579943c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 58001a15a250SPatrick Pannuto } 58011a15a250SPatrick Pannuto } 58021a15a250SPatrick Pannuto 580309ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 580409ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 580509ef8725SPatrick Pannuto if ($1 < 20) { 5806000d1cc1SJoe Perches WARN("MSLEEP", 5807458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 580809ef8725SPatrick Pannuto } 580909ef8725SPatrick Pannuto } 581009ef8725SPatrick Pannuto 581136ec1939SJoe Perches# check for comparisons of jiffies 581236ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 581336ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 581436ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 581536ec1939SJoe Perches } 581636ec1939SJoe Perches 58179d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 58189d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 58199d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 58209d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 58219d7a34a5SJoe Perches } 58229d7a34a5SJoe Perches 582300df344fSAndy Whitcroft# warn about #ifdefs in C files 5824c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 582500df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 582600df344fSAndy Whitcroft# print "$herecurr"; 582700df344fSAndy Whitcroft# $clean = 0; 582800df344fSAndy Whitcroft# } 582900df344fSAndy Whitcroft 583022f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 5831c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 58323705ce5bSJoe Perches if (ERROR("SPACING", 58333705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 58343705ce5bSJoe Perches $fix) { 5835194f66fcSJoe Perches $fixed[$fixlinenr] =~ 58363705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 58373705ce5bSJoe Perches } 58383705ce5bSJoe Perches 583922f2a2efSAndy Whitcroft } 584022f2a2efSAndy Whitcroft 58414a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 5842171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5843171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 58444a0df2efSAndy Whitcroft my $which = $1; 58454a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5846000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 5847000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 58484a0df2efSAndy Whitcroft } 58494a0df2efSAndy Whitcroft } 58504a0df2efSAndy Whitcroft# check for memory barriers without a comment. 5851402c2553SMichael S. Tsirkin 5852402c2553SMichael S. Tsirkin my $barriers = qr{ 5853402c2553SMichael S. Tsirkin mb| 5854402c2553SMichael S. Tsirkin rmb| 5855402c2553SMichael S. Tsirkin wmb| 5856402c2553SMichael S. Tsirkin read_barrier_depends 5857402c2553SMichael S. Tsirkin }x; 5858402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 5859402c2553SMichael S. Tsirkin mb__before_atomic| 5860402c2553SMichael S. Tsirkin mb__after_atomic| 5861402c2553SMichael S. Tsirkin store_release| 5862402c2553SMichael S. Tsirkin load_acquire| 5863402c2553SMichael S. Tsirkin store_mb| 5864402c2553SMichael S. Tsirkin (?:$barriers) 5865402c2553SMichael S. Tsirkin }x; 5866402c2553SMichael S. Tsirkin my $all_barriers = qr{ 5867402c2553SMichael S. Tsirkin (?:$barriers)| 586843e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 586943e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 5870402c2553SMichael S. Tsirkin }x; 5871402c2553SMichael S. Tsirkin 5872402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 58734a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5874c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 5875000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 58764a0df2efSAndy Whitcroft } 58774a0df2efSAndy Whitcroft } 58783ad81779SPaul E. McKenney 5879f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 5880f4073b0fSMichael S. Tsirkin 5881f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 5882f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 5883f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 5884f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 5885f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 5886f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 5887f4073b0fSMichael S. Tsirkin } 5888f4073b0fSMichael S. Tsirkin 5889cb426e99SJoe Perches# check for waitqueue_active without a comment. 5890cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 5891cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 5892cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 5893cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 5894cb426e99SJoe Perches } 5895cb426e99SJoe Perches } 58963ad81779SPaul E. McKenney 589791db2592SPaul E. McKenney# check for smp_read_barrier_depends and read_barrier_depends 589891db2592SPaul E. McKenney if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) { 589991db2592SPaul E. McKenney WARN("READ_BARRIER_DEPENDS", 590091db2592SPaul E. McKenney "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr); 590191db2592SPaul E. McKenney } 590291db2592SPaul E. McKenney 59034a0df2efSAndy Whitcroft# check of hardware specific defines 5904c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5905000d1cc1SJoe Perches CHK("ARCH_DEFINES", 5906000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 59070a920b5bSAndy Whitcroft } 5908653d4876SAndy Whitcroft 5909596ed45bSJoe Perches# check that the storage class is not after a type 5910596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 5911000d1cc1SJoe Perches WARN("STORAGE_CLASS", 5912596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 5913596ed45bSJoe Perches } 5914596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 5915596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 5916596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 5917596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 5918596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 5919596ed45bSJoe Perches WARN("STORAGE_CLASS", 5920596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 5921d4977c78STobias Klauser } 5922d4977c78STobias Klauser 5923de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 5924de7d4f0eSAndy Whitcroft# storage class and type. 59259c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 59269c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 5927000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 5928000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 5929de7d4f0eSAndy Whitcroft } 5930de7d4f0eSAndy Whitcroft 59318905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 59322b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59332b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 5934d5e616fcSJoe Perches if (WARN("INLINE", 5935d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 5936d5e616fcSJoe Perches $fix) { 5937194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 5938d5e616fcSJoe Perches 5939d5e616fcSJoe Perches } 59408905a67cSAndy Whitcroft } 59418905a67cSAndy Whitcroft 59423d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 59432b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59442b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5945000d1cc1SJoe Perches WARN("PREFER_PACKED", 5946000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 59473d130fd0SJoe Perches } 59483d130fd0SJoe Perches 594939b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 59502b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59512b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5952000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 5953000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 595439b7e287SJoe Perches } 595539b7e287SJoe Perches 5956462811d9SJoe Perches# Check for __attribute__ section, prefer __section 5957462811d9SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5958462811d9SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { 5959462811d9SJoe Perches my $old = substr($rawline, $-[1], $+[1] - $-[1]); 5960462811d9SJoe Perches my $new = substr($old, 1, -1); 5961462811d9SJoe Perches if (WARN("PREFER_SECTION", 5962462811d9SJoe Perches "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && 5963462811d9SJoe Perches $fix) { 5964462811d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; 5965462811d9SJoe Perches } 5966462811d9SJoe Perches } 5967462811d9SJoe Perches 59685f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 59692b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59702b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 5971d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 5972d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 5973d5e616fcSJoe Perches $fix) { 5974194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 5975d5e616fcSJoe Perches 5976d5e616fcSJoe Perches } 59775f14d3bdSJoe Perches } 59785f14d3bdSJoe Perches 59796061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 59802b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59812b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 5982d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 5983d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 5984d5e616fcSJoe Perches $fix) { 5985194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 5986d5e616fcSJoe Perches } 59876061d949SJoe Perches } 59886061d949SJoe Perches 5989619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 59905b57980dSJoe Perches if ($perl_version_ok && 5991619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 5992619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 5993619a908aSJoe Perches $line =~ /\b__weak\b/)) { 5994619a908aSJoe Perches ERROR("WEAK_DECLARATION", 5995619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 5996619a908aSJoe Perches } 5997619a908aSJoe Perches 5998fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 5999e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6000fd39f904STomas Winkler $realfile !~ m@\btools/@ && 6001e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 6002e6176fa4SJoe Perches my $type = $1; 6003e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 6004e6176fa4SJoe Perches $type = $1; 6005e6176fa4SJoe Perches my $kernel_type = 'u'; 6006e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6007e6176fa4SJoe Perches $type =~ /(\d+)/; 6008e6176fa4SJoe Perches $kernel_type .= $1; 6009e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6010e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6011e6176fa4SJoe Perches $fix) { 6012e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6013e6176fa4SJoe Perches } 6014e6176fa4SJoe Perches } 6015e6176fa4SJoe Perches } 6016e6176fa4SJoe Perches 6017938224b5SJoe Perches# check for cast of C90 native int or longer types constants 6018938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6019938224b5SJoe Perches my $cast = $1; 6020938224b5SJoe Perches my $const = $2; 6021938224b5SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 6022938224b5SJoe Perches "Unnecessary typecast of c90 int constant\n" . $herecurr) && 6023938224b5SJoe Perches $fix) { 6024938224b5SJoe Perches my $suffix = ""; 6025938224b5SJoe Perches my $newconst = $const; 6026938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 6027938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6028938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6029938224b5SJoe Perches $suffix .= 'LL'; 6030938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 6031938224b5SJoe Perches $suffix .= 'L'; 6032938224b5SJoe Perches } 6033938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6034938224b5SJoe Perches } 6035938224b5SJoe Perches } 6036938224b5SJoe Perches 60378f53a9b8SJoe Perches# check for sizeof(&) 60388f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6039000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 6040000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 60418f53a9b8SJoe Perches } 60428f53a9b8SJoe Perches 604366c80b60SJoe Perches# check for sizeof without parenthesis 604466c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 6045d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 6046d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6047d5e616fcSJoe Perches $fix) { 6048194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6049d5e616fcSJoe Perches } 605066c80b60SJoe Perches } 605166c80b60SJoe Perches 605288982feaSJoe Perches# check for struct spinlock declarations 605388982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 605488982feaSJoe Perches WARN("USE_SPINLOCK_T", 605588982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 605688982feaSJoe Perches } 605788982feaSJoe Perches 6058a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 605906668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6060a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 6061caac1d5fSHeba Aamer $fmt =~ s/%%//g; 6062caac1d5fSHeba Aamer if ($fmt !~ /%/) { 6063d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 6064d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6065d5e616fcSJoe Perches $fix) { 6066194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6067d5e616fcSJoe Perches } 6068a6962d72SJoe Perches } 6069a6962d72SJoe Perches } 6070a6962d72SJoe Perches 60710b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 60725b57980dSJoe Perches if ($perl_version_ok && 60730b523769SJoe Perches defined $stat && 60740b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 60750b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6076e3c6bc95STobin C. Harding my $stat_real; 6077e3c6bc95STobin C. Harding 60780b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 60790b523769SJoe Perches $lc = $lc + $linenr; 60800b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6081ffe07513SJoe Perches my $specifier; 6082ffe07513SJoe Perches my $extension; 60833bd32d6aSSakari Ailus my $qualifier; 6084ffe07513SJoe Perches my $bad_specifier = ""; 60850b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 60860b523769SJoe Perches $fmt =~ s/%%//g; 6087e3c6bc95STobin C. Harding 60883bd32d6aSSakari Ailus while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 6089e3c6bc95STobin C. Harding $specifier = $1; 6090e3c6bc95STobin C. Harding $extension = $2; 60913bd32d6aSSakari Ailus $qualifier = $3; 6092361b0d28SLinus Torvalds if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 60933bd32d6aSSakari Ailus ($extension eq "f" && 60943bd32d6aSSakari Ailus defined $qualifier && $qualifier !~ /^w/)) { 6095e3c6bc95STobin C. Harding $bad_specifier = $specifier; 60960b523769SJoe Perches last; 60970b523769SJoe Perches } 6098e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6099e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6100e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 61010b523769SJoe Perches } 6102e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6103e3c6bc95STobin C. Harding "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n"); 6104e3c6bc95STobin C. Harding } 6105e3c6bc95STobin C. Harding } 6106e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 61072a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 61081df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 61091df7338aSSergey Senozhatsky my $use = ""; 6110e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 61111df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6112e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 61131df7338aSSergey Senozhatsky } 61142a9f9d85STobin C. Harding 61150b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 6116e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6117e3c6bc95STobin C. Harding } 61180b523769SJoe Perches } 61190b523769SJoe Perches } 61200b523769SJoe Perches 6121554e165cSAndy Whitcroft# Check for misused memsets 61225b57980dSJoe Perches if ($perl_version_ok && 6123d1fe9c09SJoe Perches defined $stat && 61249e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6125554e165cSAndy Whitcroft 6126d7c76ba7SJoe Perches my $ms_addr = $2; 6127d1fe9c09SJoe Perches my $ms_val = $7; 6128d1fe9c09SJoe Perches my $ms_size = $12; 6129d7c76ba7SJoe Perches 6130554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6131554e165cSAndy Whitcroft ERROR("MEMSET", 6132d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6133554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6134554e165cSAndy Whitcroft WARN("MEMSET", 6135d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6136d7c76ba7SJoe Perches } 6137d7c76ba7SJoe Perches } 6138d7c76ba7SJoe Perches 613998a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 61405b57980dSJoe Perches# if ($perl_version_ok && 6141f333195dSJoe Perches# defined $stat && 6142f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6143f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6144f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6145f333195dSJoe Perches# $fix) { 6146f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6147f333195dSJoe Perches# } 6148f333195dSJoe Perches# } 614998a9bba5SJoe Perches 6150b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 61515b57980dSJoe Perches# if ($perl_version_ok && 6152f333195dSJoe Perches# defined $stat && 6153f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6154f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6155f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6156f333195dSJoe Perches# } 6157b6117d17SMateusz Kulikowski 61588617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 61598617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 61605b57980dSJoe Perches# if ($perl_version_ok && 6161f333195dSJoe Perches# defined $stat && 6162f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6163f333195dSJoe Perches# 6164f333195dSJoe Perches# my $ms_val = $7; 6165f333195dSJoe Perches# 6166f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6167f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6168f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6169f333195dSJoe Perches# $fix) { 6170f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6171f333195dSJoe Perches# } 6172f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6173f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6174f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6175f333195dSJoe Perches# $fix) { 6176f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6177f333195dSJoe Perches# } 6178f333195dSJoe Perches# } 6179f333195dSJoe Perches# } 61808617cd09SMateusz Kulikowski 6181d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 61825b57980dSJoe Perches if ($perl_version_ok && 6183d1fe9c09SJoe Perches defined $stat && 6184d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6185d1fe9c09SJoe Perches if (defined $2 || defined $7) { 6186d7c76ba7SJoe Perches my $call = $1; 6187d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 6188d7c76ba7SJoe Perches my $arg1 = $3; 6189d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 6190d1fe9c09SJoe Perches my $arg2 = $8; 6191d7c76ba7SJoe Perches my $cast; 6192d7c76ba7SJoe Perches 6193d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 6194d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 6195d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 6196d7c76ba7SJoe Perches $cast = $cast1; 6197d7c76ba7SJoe Perches } else { 6198d7c76ba7SJoe Perches $cast = $cast2; 6199d7c76ba7SJoe Perches } 6200d7c76ba7SJoe Perches WARN("MINMAX", 6201d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 6202554e165cSAndy Whitcroft } 6203554e165cSAndy Whitcroft } 6204554e165cSAndy Whitcroft 62054a273195SJoe Perches# check usleep_range arguments 62065b57980dSJoe Perches if ($perl_version_ok && 62074a273195SJoe Perches defined $stat && 62084a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 62094a273195SJoe Perches my $min = $1; 62104a273195SJoe Perches my $max = $7; 62114a273195SJoe Perches if ($min eq $max) { 62124a273195SJoe Perches WARN("USLEEP_RANGE", 6213458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 62144a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 62154a273195SJoe Perches $min > $max) { 62164a273195SJoe Perches WARN("USLEEP_RANGE", 6217458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 62184a273195SJoe Perches } 62194a273195SJoe Perches } 62204a273195SJoe Perches 6221823b794cSJoe Perches# check for naked sscanf 62225b57980dSJoe Perches if ($perl_version_ok && 6223823b794cSJoe Perches defined $stat && 62246c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 6225823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6226823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 6227823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6228823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 6229823b794cSJoe Perches $lc = $lc + $linenr; 62302a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6231823b794cSJoe Perches WARN("NAKED_SSCANF", 6232823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6233823b794cSJoe Perches } 6234823b794cSJoe Perches 6235afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 62365b57980dSJoe Perches if ($perl_version_ok && 6237afc819abSJoe Perches defined $stat && 6238afc819abSJoe Perches $line =~ /\bsscanf\b/) { 6239afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 6240afc819abSJoe Perches $lc = $lc + $linenr; 62412a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6242afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6243afc819abSJoe Perches my $format = $6; 6244afc819abSJoe Perches my $count = $format =~ tr@%@%@; 6245afc819abSJoe Perches if ($count == 1 && 6246afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 6247afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 6248afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 6249afc819abSJoe Perches } 6250afc819abSJoe Perches } 6251afc819abSJoe Perches } 6252afc819abSJoe Perches 625370dc8a48SJoe Perches# check for new externs in .h files. 625470dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 625570dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 6256d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 625770dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 625870dc8a48SJoe Perches $fix) { 6259194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 626070dc8a48SJoe Perches } 626170dc8a48SJoe Perches } 626270dc8a48SJoe Perches 6263de7d4f0eSAndy Whitcroft# check for new externs in .c files. 6264171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 6265c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 6266171ae1a4SAndy Whitcroft { 6267c45dcabdSAndy Whitcroft my $function_name = $1; 6268c45dcabdSAndy Whitcroft my $paren_space = $2; 6269171ae1a4SAndy Whitcroft 6270171ae1a4SAndy Whitcroft my $s = $stat; 6271171ae1a4SAndy Whitcroft if (defined $cond) { 6272171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 6273171ae1a4SAndy Whitcroft } 6274c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 6275c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 6276c45dcabdSAndy Whitcroft { 6277000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6278000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6279de7d4f0eSAndy Whitcroft } 6280de7d4f0eSAndy Whitcroft 6281171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 6282000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 6283000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 6284171ae1a4SAndy Whitcroft } 62859c9ba34eSAndy Whitcroft 62869c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 62879c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 62889c9ba34eSAndy Whitcroft { 6289000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6290000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6291171ae1a4SAndy Whitcroft } 6292171ae1a4SAndy Whitcroft 6293a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 629416b7f3c8SJoe Perches# while avoiding uninitialized_var(x) 6295a0ad7596SJoe Perches if (defined $stat && 629616b7f3c8SJoe Perches $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:($Ident)|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 629716b7f3c8SJoe Perches (!defined($1) || 629816b7f3c8SJoe Perches (defined($1) && $1 ne "uninitialized_var")) && 629916b7f3c8SJoe Perches $2 ne "void") { 630016b7f3c8SJoe Perches my $args = trim($2); 6301ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 6302ca0d8929SJoe Perches my $arg = trim($1); 630316b7f3c8SJoe Perches if ($arg =~ /^$Type$/ && 630416b7f3c8SJoe Perches $arg !~ /enum\s+$Ident$/) { 6305ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 6306ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 6307ca0d8929SJoe Perches } 6308ca0d8929SJoe Perches } 6309ca0d8929SJoe Perches } 6310ca0d8929SJoe Perches 6311a0ad7596SJoe Perches# check for function definitions 63125b57980dSJoe Perches if ($perl_version_ok && 6313a0ad7596SJoe Perches defined $stat && 6314a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 6315a0ad7596SJoe Perches $context_function = $1; 6316a0ad7596SJoe Perches 6317a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 6318a0ad7596SJoe Perches my $ok = 0; 6319a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 6320a0ad7596SJoe Perches my $herectx = $here . "\n"; 6321a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6322a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 6323a0ad7596SJoe Perches $herectx .= $rl . "\n"; 6324a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 6325a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 6326a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 6327a0ad7596SJoe Perches } 6328a0ad7596SJoe Perches if (!$ok) { 6329a0ad7596SJoe Perches ERROR("OPEN_BRACE", 6330a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 6331a0ad7596SJoe Perches } 6332a0ad7596SJoe Perches } 6333a0ad7596SJoe Perches 6334de7d4f0eSAndy Whitcroft# checks for new __setup's 6335de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 6336de7d4f0eSAndy Whitcroft my $name = $1; 6337de7d4f0eSAndy Whitcroft 6338de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 6339000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 63408c27ceffSMauro Carvalho Chehab "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 6341de7d4f0eSAndy Whitcroft } 6342653d4876SAndy Whitcroft } 63439c0ca6f9SAndy Whitcroft 6344e29a70f1SJoe Perches# check for pointless casting of alloc functions 6345e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 6346000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 6347000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 63489c0ca6f9SAndy Whitcroft } 634913214adfSAndy Whitcroft 6350a640d25cSJoe Perches# alloc style 6351a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 63525b57980dSJoe Perches if ($perl_version_ok && 6353e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 6354a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 6355a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 6356a640d25cSJoe Perches } 6357a640d25cSJoe Perches 635860a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 63595b57980dSJoe Perches if ($perl_version_ok && 63601b4a2ed4SJoe Perches defined $stat && 63611b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 636260a55369SJoe Perches my $oldfunc = $3; 636360a55369SJoe Perches my $a1 = $4; 636460a55369SJoe Perches my $a2 = $10; 636560a55369SJoe Perches my $newfunc = "kmalloc_array"; 636660a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 636760a55369SJoe Perches my $r1 = $a1; 636860a55369SJoe Perches my $r2 = $a2; 636960a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 637060a55369SJoe Perches $r1 = $a2; 637160a55369SJoe Perches $r2 = $a1; 637260a55369SJoe Perches } 6373e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 6374e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 63751b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 6376e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6377e3d95a2aSTobin C. Harding 6378e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 63791b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 63801b4a2ed4SJoe Perches $cnt == 1 && 6381e367455aSJoe Perches $fix) { 6382194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; 638360a55369SJoe Perches } 638460a55369SJoe Perches } 638560a55369SJoe Perches } 638660a55369SJoe Perches 6387972fdea2SJoe Perches# check for krealloc arg reuse 63885b57980dSJoe Perches if ($perl_version_ok && 63894cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 63904cab63ceSJoe Perches $1 eq $3) { 6391972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 6392972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 6393972fdea2SJoe Perches } 6394972fdea2SJoe Perches 63955ce59ae0SJoe Perches# check for alloc argument mismatch 63965ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 63975ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 63985ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 63995ce59ae0SJoe Perches } 64005ce59ae0SJoe Perches 6401caf2a54fSJoe Perches# check for multiple semicolons 6402caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 6403d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 6404d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 6405d5e616fcSJoe Perches $fix) { 6406194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 6407d5e616fcSJoe Perches } 6408d1e2ad07SJoe Perches } 6409d1e2ad07SJoe Perches 6410cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 6411cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 6412cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 64130ab90191SJoe Perches my $ull = ""; 64140ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 64150ab90191SJoe Perches if (CHK("BIT_MACRO", 64160ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 64170ab90191SJoe Perches $fix) { 64180ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 64190ab90191SJoe Perches } 64200ab90191SJoe Perches } 64210ab90191SJoe Perches 64222d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 64232d632745SJoe 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*$/) { 64242d632745SJoe Perches my $config = $1; 64252d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 64262d632745SJoe Perches "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 64272d632745SJoe Perches $fix) { 64282d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 64292d632745SJoe Perches } 64302d632745SJoe Perches } 64312d632745SJoe Perches 6432e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 6433c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 6434c34c09a8SJoe Perches my $has_break = 0; 6435c34c09a8SJoe Perches my $has_statement = 0; 6436c34c09a8SJoe Perches my $count = 0; 6437c34c09a8SJoe Perches my $prevline = $linenr; 6438e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 6439c34c09a8SJoe Perches $prevline--; 6440c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 6441c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 6442c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 6443c34c09a8SJoe Perches next if ($fline =~ /^\-/); 6444c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 6445c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 6446c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 6447c34c09a8SJoe Perches $has_statement = 1; 6448c34c09a8SJoe Perches $count++; 6449258f79d5SHeinrich Schuchardt $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/); 6450c34c09a8SJoe Perches } 6451c34c09a8SJoe Perches if (!$has_break && $has_statement) { 6452c34c09a8SJoe Perches WARN("MISSING_BREAK", 6453224236d9SAndrew Morton "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 6454c34c09a8SJoe Perches } 6455c34c09a8SJoe Perches } 6456c34c09a8SJoe Perches 6457f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 6458f36d3eb8SJoe Perches my @fallthroughs = ( 6459f36d3eb8SJoe Perches 'fallthrough', 6460f36d3eb8SJoe Perches '@fallthrough@', 6461f36d3eb8SJoe Perches 'lint -fallthrough[ \t]*', 6462f36d3eb8SJoe Perches 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 6463f36d3eb8SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 6464f36d3eb8SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 6465f36d3eb8SJoe Perches 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 6466f36d3eb8SJoe Perches ); 6467f36d3eb8SJoe Perches if ($raw_comment ne '') { 6468f36d3eb8SJoe Perches foreach my $ft (@fallthroughs) { 6469f36d3eb8SJoe Perches if ($raw_comment =~ /$ft/) { 6470f36d3eb8SJoe Perches my $msg_level = \&WARN; 6471f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 6472f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 6473f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 6474f36d3eb8SJoe Perches last; 6475f36d3eb8SJoe Perches } 6476f36d3eb8SJoe Perches } 6477f36d3eb8SJoe Perches } 6478f36d3eb8SJoe Perches 6479d1e2ad07SJoe Perches# check for switch/default statements without a break; 64805b57980dSJoe Perches if ($perl_version_ok && 6481d1e2ad07SJoe Perches defined $stat && 6482d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6483d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6484e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6485e3d95a2aSTobin C. Harding 6486d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6487d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6488caf2a54fSJoe Perches } 6489caf2a54fSJoe Perches 649013214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6491d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6492d5e616fcSJoe Perches if (WARN("USE_FUNC", 6493d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6494d5e616fcSJoe Perches $fix) { 6495194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6496d5e616fcSJoe Perches } 649713214adfSAndy Whitcroft } 6498773647a0SAndy Whitcroft 649962ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 650062ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 650162ec818fSJoe Perches ERROR("DATE_TIME", 650262ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 650362ec818fSJoe Perches } 650462ec818fSJoe Perches 65052c92488aSJoe Perches# check for use of yield() 65062c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 65072c92488aSJoe Perches WARN("YIELD", 65082c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 65092c92488aSJoe Perches } 65102c92488aSJoe Perches 6511179f8f40SJoe Perches# check for comparisons against true and false 6512179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 6513179f8f40SJoe Perches my $lead = $1; 6514179f8f40SJoe Perches my $arg = $2; 6515179f8f40SJoe Perches my $test = $3; 6516179f8f40SJoe Perches my $otype = $4; 6517179f8f40SJoe Perches my $trail = $5; 6518179f8f40SJoe Perches my $op = "!"; 6519179f8f40SJoe Perches 6520179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 6521179f8f40SJoe Perches 6522179f8f40SJoe Perches my $type = lc($otype); 6523179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 6524179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 6525179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 6526179f8f40SJoe Perches $op = ""; 6527179f8f40SJoe Perches } 6528179f8f40SJoe Perches 6529179f8f40SJoe Perches CHK("BOOL_COMPARISON", 6530179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 6531179f8f40SJoe Perches 6532179f8f40SJoe Perches## maybe suggesting a correct construct would better 6533179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 6534179f8f40SJoe Perches 6535179f8f40SJoe Perches } 6536179f8f40SJoe Perches } 6537179f8f40SJoe Perches 65384882720bSThomas Gleixner# check for semaphores initialized locked 65394882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6540000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 6541000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 6542773647a0SAndy Whitcroft } 65436712d858SJoe Perches 654467d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 654567d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6546000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 654767d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 6548773647a0SAndy Whitcroft } 65496712d858SJoe Perches 6550ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6551f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 6552000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 6553ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6554f3db6639SMichael Ellerman } 65556712d858SJoe Perches 65563d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 65573d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 65583d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 65593d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 65603d709ab5SPaul E. McKenney } 65613d709ab5SPaul E. McKenney 65629189c7e7SJoe Perches# check for deprecated apis 65639189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 65649189c7e7SJoe Perches my $deprecated_api = $1; 65659189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 65669189c7e7SJoe Perches WARN("DEPRECATED_API", 65679189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 65689189c7e7SJoe Perches } 65699189c7e7SJoe Perches 65700f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 6571d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 65726903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 6573d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6574000d1cc1SJoe Perches WARN("CONST_STRUCT", 6575d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 65762b6db5cbSAndy Whitcroft } 6577773647a0SAndy Whitcroft 6578773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 6579773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 6580773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 6581c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6582c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6583171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6584171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6585171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6586773647a0SAndy Whitcroft { 6587000d1cc1SJoe Perches WARN("NR_CPUS", 6588000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6589773647a0SAndy Whitcroft } 65909c9ba34eSAndy Whitcroft 659152ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 659252ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 659352ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 659452ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 659552ea8506SJoe Perches } 659652ea8506SJoe Perches 6597acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 65985b57980dSJoe Perches if ($perl_version_ok && 6599acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6600acd9362cSJoe Perches WARN("LIKELY_MISUSE", 6601acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6602acd9362cSJoe Perches } 6603acd9362cSJoe Perches 6604de3f186fSDenis Efremov# nested likely/unlikely calls 6605de3f186fSDenis Efremov if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 6606de3f186fSDenis Efremov WARN("LIKELY_MISUSE", 6607de3f186fSDenis Efremov "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 6608de3f186fSDenis Efremov } 6609de3f186fSDenis Efremov 6610691d77b6SAndy Whitcroft# whine mightly about in_atomic 6611691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 6612691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 6613000d1cc1SJoe Perches ERROR("IN_ATOMIC", 6614000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 6615f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 6616000d1cc1SJoe Perches WARN("IN_ATOMIC", 6617000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6618691d77b6SAndy Whitcroft } 6619691d77b6SAndy Whitcroft } 66201704f47bSPeter Zijlstra 66210f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage 66220f5225b0SPeter Zijlstra if ($line =~ /mutex_trylock_recursive/) { 66230f5225b0SPeter Zijlstra ERROR("LOCKING", 66240f5225b0SPeter Zijlstra "recursive locking is bad, do not use this ever.\n" . $herecurr); 66250f5225b0SPeter Zijlstra } 66260f5225b0SPeter Zijlstra 66271704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 66281704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 66291704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 66301704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 66311704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 66321704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 6633000d1cc1SJoe Perches ERROR("LOCKDEP", 6634000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 66351704f47bSPeter Zijlstra } 66361704f47bSPeter Zijlstra } 663788f8831cSDave Jones 6638b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 6639b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6640000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 6641000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 664288f8831cSDave Jones } 66432435880fSJoe Perches 664400180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 664500180468SJoe Perches# and whether or not function naming is typical and if 664600180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 66475b57980dSJoe Perches if ($perl_version_ok && 664800180468SJoe Perches defined $stat && 664900180468SJoe Perches $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) { 665000180468SJoe Perches my $var = $1; 665100180468SJoe Perches my $perms = $2; 665200180468SJoe Perches my $show = $3; 665300180468SJoe Perches my $store = $4; 665400180468SJoe Perches my $octal_perms = perms_to_octal($perms); 665500180468SJoe Perches if ($show =~ /^${var}_show$/ && 665600180468SJoe Perches $store =~ /^${var}_store$/ && 665700180468SJoe Perches $octal_perms eq "0644") { 665800180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 665900180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 666000180468SJoe Perches $fix) { 666100180468SJoe 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})/; 666200180468SJoe Perches } 666300180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 666400180468SJoe Perches $store =~ /^NULL$/ && 666500180468SJoe Perches $octal_perms eq "0444") { 666600180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 666700180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 666800180468SJoe Perches $fix) { 666900180468SJoe 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})/; 667000180468SJoe Perches } 667100180468SJoe Perches } elsif ($show =~ /^NULL$/ && 667200180468SJoe Perches $store =~ /^${var}_store$/ && 667300180468SJoe Perches $octal_perms eq "0200") { 667400180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 667500180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 667600180468SJoe Perches $fix) { 667700180468SJoe 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})/; 667800180468SJoe Perches } 667900180468SJoe Perches } elsif ($octal_perms eq "0644" || 668000180468SJoe Perches $octal_perms eq "0444" || 668100180468SJoe Perches $octal_perms eq "0200") { 668200180468SJoe Perches my $newshow = "$show"; 668300180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 668400180468SJoe Perches my $newstore = $store; 668500180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 668600180468SJoe Perches my $rename = ""; 668700180468SJoe Perches if ($show ne $newshow) { 668800180468SJoe Perches $rename .= " '$show' to '$newshow'"; 668900180468SJoe Perches } 669000180468SJoe Perches if ($store ne $newstore) { 669100180468SJoe Perches $rename .= " '$store' to '$newstore'"; 669200180468SJoe Perches } 669300180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 669400180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 669500180468SJoe Perches } else { 669600180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 669700180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 669800180468SJoe Perches } 669900180468SJoe Perches } 670000180468SJoe Perches 6701515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 6702515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 670373121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 670473121534SJoe Perches# specific definition of not visible in sysfs. 670573121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 670673121534SJoe Perches# use the default permissions 67075b57980dSJoe Perches if ($perl_version_ok && 6708459cf0aeSJoe Perches defined $stat && 6709515a235eSJoe Perches $line =~ /$mode_perms_search/) { 67102435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 67112435880fSJoe Perches my $func = $entry->[0]; 67122435880fSJoe Perches my $arg_pos = $entry->[1]; 67132435880fSJoe Perches 6714459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 6715459cf0aeSJoe Perches $lc = $lc + $linenr; 67162a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6717459cf0aeSJoe Perches 67182435880fSJoe Perches my $skip_args = ""; 67192435880fSJoe Perches if ($arg_pos > 1) { 67202435880fSJoe Perches $arg_pos--; 67212435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 67222435880fSJoe Perches } 6723f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 6724459cf0aeSJoe Perches if ($stat =~ /$test/) { 67252435880fSJoe Perches my $val = $1; 67262435880fSJoe Perches $val = $6 if ($skip_args ne ""); 672773121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 672873121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 672973121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 67302435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 6731459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 6732f90774e1SJoe Perches } 6733f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 6734c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 6735459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 67362435880fSJoe Perches } 6737459cf0aeSJoe Perches } 6738459cf0aeSJoe Perches } 6739459cf0aeSJoe Perches } 6740459cf0aeSJoe Perches 6741459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 6742bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 674300180468SJoe Perches my $oval = $1; 674400180468SJoe Perches my $octal = perms_to_octal($oval); 6745f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 6746459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 6747f90774e1SJoe Perches $fix) { 674800180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 67492435880fSJoe Perches } 675013214adfSAndy Whitcroft } 67515a6d20ceSBjorn Andersson 67525a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 67535a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 67545a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 67555a6d20ceSBjorn Andersson my $valid_licenses = qr{ 67565a6d20ceSBjorn Andersson GPL| 67575a6d20ceSBjorn Andersson GPL\ v2| 67585a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 67595a6d20ceSBjorn Andersson Dual\ BSD/GPL| 67605a6d20ceSBjorn Andersson Dual\ MIT/GPL| 67615a6d20ceSBjorn Andersson Dual\ MPL/GPL| 67625a6d20ceSBjorn Andersson Proprietary 67635a6d20ceSBjorn Andersson }x; 67645a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 67655a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 67665a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 67675a6d20ceSBjorn Andersson } 67685a6d20ceSBjorn Andersson } 67696a8d76cbSMatteo Croce 67706a8d76cbSMatteo Croce# check for sysctl duplicate constants 67716a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 67726a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 67736a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 67746a8d76cbSMatteo Croce } 6775515a235eSJoe Perches } 677613214adfSAndy Whitcroft 677713214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 677813214adfSAndy Whitcroft # so just keep quiet. 677913214adfSAndy Whitcroft if ($#rawlines == -1) { 678013214adfSAndy Whitcroft exit(0); 67810a920b5bSAndy Whitcroft } 67820a920b5bSAndy Whitcroft 67838905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 67848905a67cSAndy Whitcroft # things that appear to be patches. 67858905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 67868905a67cSAndy Whitcroft exit(0); 67878905a67cSAndy Whitcroft } 67888905a67cSAndy Whitcroft 67898905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 67908905a67cSAndy Whitcroft # just keep quiet. 67918905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 67928905a67cSAndy Whitcroft exit(0); 67938905a67cSAndy Whitcroft } 67948905a67cSAndy Whitcroft 6795a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 6796000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 6797000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 67980a920b5bSAndy Whitcroft } 6799cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 6800cd261496SGeert Uytterhoeven if ($signoff == 0) { 6801000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 6802000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 6803cd261496SGeert Uytterhoeven } elsif (!$authorsignoff) { 6804cd261496SGeert Uytterhoeven WARN("NO_AUTHOR_SIGN_OFF", 6805cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 6806cd261496SGeert Uytterhoeven } 68070a920b5bSAndy Whitcroft } 68080a920b5bSAndy Whitcroft 6809f0a594c1SAndy Whitcroft print report_dump(); 681013214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 681113214adfSAndy Whitcroft print "$filename " if ($summary_file); 68126c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 68136c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 68146c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 68156c72ffaaSAndy Whitcroft } 68168905a67cSAndy Whitcroft 6817d2c0a235SAndy Whitcroft if ($quiet == 0) { 6818ef212196SJoe Perches # If there were any defects found and not already fixing them 6819ef212196SJoe Perches if (!$clean and !$fix) { 6820ef212196SJoe Perches print << "EOM" 6821ef212196SJoe Perches 6822ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 6823ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 6824ef212196SJoe PerchesEOM 6825ef212196SJoe Perches } 6826d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 6827d2c0a235SAndy Whitcroft # then suggest that. 6828d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 6829b0781216SMike Frysinger $rpt_cleaners = 0; 6830d8469f16SJoe Perches print << "EOM" 6831d8469f16SJoe Perches 6832d8469f16SJoe PerchesNOTE: Whitespace errors detected. 6833d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 6834d8469f16SJoe PerchesEOM 6835d2c0a235SAndy Whitcroft } 6836d2c0a235SAndy Whitcroft } 6837d2c0a235SAndy Whitcroft 6838d752fcc8SJoe Perches if ($clean == 0 && $fix && 6839d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 6840d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 68419624b8d6SJoe Perches my $newfile = $filename; 68429624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 68433705ce5bSJoe Perches my $linecount = 0; 68443705ce5bSJoe Perches my $f; 68453705ce5bSJoe Perches 6846d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 6847d752fcc8SJoe Perches 68483705ce5bSJoe Perches open($f, '>', $newfile) 68493705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 68503705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 68513705ce5bSJoe Perches $linecount++; 68523705ce5bSJoe Perches if ($file) { 68533705ce5bSJoe Perches if ($linecount > 3) { 68543705ce5bSJoe Perches $fixed_line =~ s/^\+//; 68553705ce5bSJoe Perches print $f $fixed_line . "\n"; 68563705ce5bSJoe Perches } 68573705ce5bSJoe Perches } else { 68583705ce5bSJoe Perches print $f $fixed_line . "\n"; 68593705ce5bSJoe Perches } 68603705ce5bSJoe Perches } 68613705ce5bSJoe Perches close($f); 68623705ce5bSJoe Perches 68633705ce5bSJoe Perches if (!$quiet) { 68643705ce5bSJoe Perches print << "EOM"; 6865d8469f16SJoe Perches 68663705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 68673705ce5bSJoe Perches 68683705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 68693705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 68703705ce5bSJoe Perches 68713705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 68723705ce5bSJoe PerchesNo warranties, expressed or implied... 68733705ce5bSJoe PerchesEOM 68743705ce5bSJoe Perches } 68753705ce5bSJoe Perches } 68763705ce5bSJoe Perches 6877d8469f16SJoe Perches if ($quiet == 0) { 6878d8469f16SJoe Perches print "\n"; 6879d8469f16SJoe Perches if ($clean == 1) { 6880d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 6881d8469f16SJoe Perches } else { 6882d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 68830a920b5bSAndy Whitcroft } 68840a920b5bSAndy Whitcroft } 68850a920b5bSAndy Whitcroft return $clean; 68860a920b5bSAndy Whitcroft} 6887